From 2d805742ca5084f8a52d29d0bb5e8101d2122ebe Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Wed, 16 May 2012 08:01:35 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create tag 'merge_torque_to_head_after'. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Sprout from master 2012-05-16 08:01:34 UTC Michal Voců 'merge of branch michal_Torque' Delete: emi.canl.canl-c/Makefile emi.canl.canl-c/configure emi.canl.canl-c/doc/src/canl-abstract.tex emi.canl.canl-c/doc/src/canl-cs-auth-connection.tex emi.canl.canl-c/doc/src/canl-introduction.tex emi.canl.canl-c/doc/src/canl-proxy-cert.tex emi.canl.canl-c/doc/src/canl.tex emi.canl.canl-c/doc/src/copyright.tex emi.canl.canl-c/doc/src/definitions.tex emi.canl.canl-c/doc/src/emi.cls emi.canl.canl-c/doc/src/funding.tex emi.canl.canl-c/doc/src/images/EMI_Logo_std.pdf emi.canl.canl-c/doc/src/images/cesnet.pdf emi.canl.canl-c/examples/canl_sample_client.c emi.canl.canl-c/examples/canl_sample_server.c emi.canl.canl-c/examples/delegation.c emi.canl.canl-c/examples/grid-proxy-init.c emi.canl.canl-c/project/ChangeLog emi.canl.canl-c/project/canl-c.spec emi.canl.canl-c/project/debian.control emi.canl.canl-c/project/debian.copyright emi.canl.canl-c/project/debian.libcanl-c-dev.dirs emi.canl.canl-c/project/debian.libcanl-c-dev.install emi.canl.canl-c/project/debian.libcanl-c-examples.dirs emi.canl.canl-c/project/debian.libcanl-c-examples.install emi.canl.canl-c/project/debian.libcanl-c1.dirs emi.canl.canl-c/project/debian.libcanl-c1.install emi.canl.canl-c/project/debian.rules emi.canl.canl-c/project/package.description emi.canl.canl-c/project/package.summary emi.canl.canl-c/project/version.properties emi.canl.canl-c/src/canl.c emi.canl.canl-c/src/canl.h emi.canl.canl-c/src/canl_cert.c emi.canl.canl-c/src/canl_cred.c emi.canl.canl-c/src/canl_cred.h emi.canl.canl-c/src/canl_dns.c emi.canl.canl-c/src/canl_err.c emi.canl.canl-c/src/canl_error_codes emi.canl.canl-c/src/canl_error_desc emi.canl.canl-c/src/canl_locl.h emi.canl.canl-c/src/canl_mech_ssl.h emi.canl.canl-c/src/canl_ssl.c emi.canl.canl-c/src/canl_ssl.h emi.canl.canl-c/src/gen_err_codes.pl emi.canl.canl-c/src/gen_err_desc.pl emi.canl.canl-c/src/proxy/config.h emi.canl.canl-c/src/proxy/data.c emi.canl.canl-c/src/proxy/doio.c emi.canl.canl-c/src/proxy/doio.h emi.canl.canl-c/src/proxy/evaluate.c emi.canl.canl-c/src/proxy/list.c emi.canl.canl-c/src/proxy/listfunc.h emi.canl.canl-c/src/proxy/myproxycertinfo.h emi.canl.canl-c/src/proxy/namespaces_lex.c.in emi.canl.canl-c/src/proxy/namespaces_lex.l emi.canl.canl-c/src/proxy/namespaces_parse.y emi.canl.canl-c/src/proxy/normalize.c emi.canl.canl-c/src/proxy/normalize.h emi.canl.canl-c/src/proxy/parsertypes.h emi.canl.canl-c/src/proxy/proxy.c emi.canl.canl-c/src/proxy/proxycertinfo.c emi.canl.canl-c/src/proxy/scutils.c emi.canl.canl-c/src/proxy/scutils.h emi.canl.canl-c/src/proxy/signing_policy_lex.c.in emi.canl.canl-c/src/proxy/signing_policy_lex.l emi.canl.canl-c/src/proxy/signing_policy_parse.y emi.canl.canl-c/src/proxy/sslutils.c emi.canl.canl-c/src/proxy/sslutils.h emi.canl.canl-c/src/proxy/vomsproxy.h org.glite.deployment.jpis/build.xml org.glite.deployment.jpis/config/scripts/glite-jpis-config.py org.glite.deployment.jpis/config/templates/glite-jpis.cfg.xml org.glite.deployment.jpis/project/build.number org.glite.deployment.jpis/project/build.properties org.glite.deployment.jpis/project/glite-jp.sdf.xml.template org.glite.deployment.jpis/project/glite-jpis.sdf.xml.template org.glite.deployment.jpis/project/lxscript-rpm.xsl org.glite.deployment.jpis/project/lxscript-tgz.xsl org.glite.deployment.jpis/project/properties.xml org.glite.deployment.jpis/project/quattor-template.xsl org.glite.deployment.jpis/project/version.properties org.glite.deployment.jpps/build.xml org.glite.deployment.jpps/config/scripts/glite-jpps-config.py org.glite.deployment.jpps/config/templates/glite-jpps.cfg.xml org.glite.deployment.jpps/project/build.number org.glite.deployment.jpps/project/build.properties org.glite.deployment.jpps/project/glite-jpps.sdf.xml.template org.glite.deployment.jpps/project/lxscript-rpm.xsl org.glite.deployment.jpps/project/lxscript-tgz.xsl org.glite.deployment.jpps/project/properties.xml org.glite.deployment.jpps/project/quattor-template.xsl org.glite.deployment.jpps/project/version.properties org.glite.deployment.lb/.cvsignore org.glite.deployment.lb/CHANGELOG org.glite.deployment.lb/LICENSE org.glite.deployment.lb/build.xml org.glite.deployment.lb/config/scripts/glite-lb-config.py org.glite.deployment.lb/config/templates/glite-lb.cfg.xml org.glite.deployment.lb/doc/release_notes/release_notes.doc org.glite.deployment.lb/doc/release_notes/release_notes.html org.glite.deployment.lb/doc/release_notes/release_notes.pdf org.glite.deployment.lb/project/.cvsignore org.glite.deployment.lb/project/build.number org.glite.deployment.lb/project/build.properties org.glite.deployment.lb/project/glite-lb.sdf.xml.template org.glite.deployment.lb/project/lxscript-rpm.xsl org.glite.deployment.lb/project/lxscript-tgz.xsl org.glite.deployment.lb/project/properties.xml org.glite.deployment.lb/project/quattor-template.xsl org.glite.deployment.lb/project/version.properties org.glite.jobid.api-c/Makefile org.glite.jobid.api-c/configure org.glite.jobid.api-c/interface/cjobid.h org.glite.jobid.api-c/interface/strmd5.h org.glite.jobid.api-c/project/.post org.glite.jobid.api-c/project/.postun org.glite.jobid.api-c/project/ChangeLog org.glite.jobid.api-c/project/debian.control org.glite.jobid.api-c/project/debian.copyright org.glite.jobid.api-c/project/debian.libglite-jobid-api-c-dev.dirs org.glite.jobid.api-c/project/debian.libglite-jobid-api-c-dev.install org.glite.jobid.api-c/project/debian.libglite-jobid2.dirs org.glite.jobid.api-c/project/debian.libglite-jobid2.install org.glite.jobid.api-c/project/debian.rules org.glite.jobid.api-c/project/glite-jobid-api-c.spec org.glite.jobid.api-c/project/package.description org.glite.jobid.api-c/project/package.summary org.glite.jobid.api-c/project/version.properties org.glite.jobid.api-c/src/cjobid.c org.glite.jobid.api-c/src/md32_common.h org.glite.jobid.api-c/src/md5.h org.glite.jobid.api-c/src/md5_dgst.c org.glite.jobid.api-c/src/md5_locl.h org.glite.jobid.api-c/src/strmd5.c org.glite.jobid.api-c/test/base64_test.cpp org.glite.jobid.api-cpp/Makefile org.glite.jobid.api-cpp/configure org.glite.jobid.api-cpp/interface/JobId.h org.glite.jobid.api-cpp/project/ChangeLog org.glite.jobid.api-cpp/project/debian.control org.glite.jobid.api-cpp/project/debian.copyright org.glite.jobid.api-cpp/project/debian.libglite-jobid-api-cpp-dev.dirs org.glite.jobid.api-cpp/project/debian.libglite-jobid-api-cpp-dev.install org.glite.jobid.api-cpp/project/debian.rules org.glite.jobid.api-cpp/project/glite-jobid-api-cpp.spec org.glite.jobid.api-cpp/project/package.description org.glite.jobid.api-cpp/project/package.summary org.glite.jobid.api-cpp/project/version.properties org.glite.jobid.api-java/Makefile org.glite.jobid.api-java/build.xml org.glite.jobid.api-java/configure org.glite.jobid.api-java/nbproject/build-impl.xml org.glite.jobid.api-java/nbproject/genfiles.properties org.glite.jobid.api-java/nbproject/private/config.properties org.glite.jobid.api-java/nbproject/private/private.properties org.glite.jobid.api-java/nbproject/private/private.xml org.glite.jobid.api-java/nbproject/project.properties org.glite.jobid.api-java/nbproject/project.xml org.glite.jobid.api-java/project/ChangeLog org.glite.jobid.api-java/project/debian.control org.glite.jobid.api-java/project/debian.copyright org.glite.jobid.api-java/project/debian.glite-jobid-api-java.dirs org.glite.jobid.api-java/project/debian.glite-jobid-api-java.install org.glite.jobid.api-java/project/debian.rules org.glite.jobid.api-java/project/glite-jobid-api-java.spec org.glite.jobid.api-java/project/package.description org.glite.jobid.api-java/project/package.summary org.glite.jobid.api-java/project/version.properties org.glite.jobid.api-java/src/org/glite/jobid/ExampleJobid.java org.glite.jobid.api-java/src/org/glite/jobid/Jobid.java org.glite.jobid/project/version.properties org.glite.jp.client/.cvsignore org.glite.jp.client/Makefile org.glite.jp.client/build.xml org.glite.jp.client/config/startup org.glite.jp.client/configure org.glite.jp.client/doc/README.jpimporter org.glite.jp.client/examples/glite-jp-importer.sh org.glite.jp.client/examples/jpps_upload_files.c org.glite.jp.client/examples/mill_feed.c org.glite.jp.client/interface/jp_client.h org.glite.jp.client/interface/jpcl_ctx_int.h org.glite.jp.client/interface/jpimporter.h org.glite.jp.client/project/ChangeLog org.glite.jp.client/project/build.number org.glite.jp.client/project/build.properties org.glite.jp.client/project/configure.properties.xml org.glite.jp.client/project/properties.xml org.glite.jp.client/project/tar_exclude org.glite.jp.client/project/version.properties org.glite.jp.client/src/jpcl_ctx.c org.glite.jp.client/src/jpimp_lib.c org.glite.jp.client/src/jpimporter.c org.glite.jp.client/src/jptype_map.h org.glite.jp.client/src/typemap.dat org.glite.jp.common/.cvsignore org.glite.jp.common/Makefile org.glite.jp.common/build.xml org.glite.jp.common/interface/attr.h org.glite.jp.common/interface/backend.h org.glite.jp.common/interface/builtin_plugins.h org.glite.jp.common/interface/context.h org.glite.jp.common/interface/file_plugin.h org.glite.jp.common/interface/indexdb.h org.glite.jp.common/interface/known_attr.h org.glite.jp.common/interface/type_plugin.h org.glite.jp.common/interface/types.h org.glite.jp.common/project/build.number 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/attr.c org.glite.jp.common/src/context.c org.glite.jp.common/src/indexdb.c org.glite.jp.common/src/utils.c org.glite.jp.common/test/type_test.cpp org.glite.jp.doc/LICENSE org.glite.jp.doc/Makefile org.glite.jp.doc/configure org.glite.jp.doc/project/ChangeLog org.glite.jp.doc/project/version.properties org.glite.jp.doc/src/JPAG-Configuration.tex org.glite.jp.doc/src/JPAG-Installation.tex org.glite.jp.doc/src/JPAG-Introduction.tex org.glite.jp.doc/src/JPAG-Running.tex org.glite.jp.doc/src/JPAG-Testing.tex org.glite.jp.doc/src/JPAG-Troubleshooting.tex org.glite.jp.doc/src/JPAG.tex org.glite.jp.doc/src/JPDG-Introduction.tex org.glite.jp.doc/src/JPDG-WS.tex org.glite.jp.doc/src/JPDG.tex org.glite.jp.doc/src/JPUG-Introduction.tex org.glite.jp.doc/src/JPUG-Tools.tex org.glite.jp.doc/src/JPUG-UseCases.tex org.glite.jp.doc/src/JPUG.tex org.glite.jp.doc/src/LB-JP-interaction.tex org.glite.jp.doc/src/README org.glite.jp.doc/src/copyright.tex org.glite.jp.doc/src/definitions.tex org.glite.jp.doc/src/egee.cls org.glite.jp.doc/src/frontmatter.tex org.glite.jp.doc/src/glite-jpis-client.tex org.glite.jp.doc/src/glite_installation_guide_JP.doc org.glite.jp.doc/src/glite_installation_guide_LB.doc org.glite.jp.doc/src/gui.tex org.glite.jp.doc/src/images/JP-interactions.cdr org.glite.jp.doc/src/images/JP-interactions.pdf org.glite.jp.doc/src/images/JP-query.cdr org.glite.jp.doc/src/images/JP-query.pdf org.glite.jp.doc/src/images/LB-JP-interaction-details.cdr org.glite.jp.doc/src/images/LB-JP-interaction-details.pdf org.glite.jp.doc/src/images/LB-JP-interaction-drawing.pdf org.glite.jp.doc/src/images/egee.pdf org.glite.jp.doc/src/images/isi.pdf org.glite.jp.doc/src/jpimporter.tex org.glite.jp.doc/src/jpws.tex org.glite.jp.doc/src/lbjp.bib org.glite.jp.index/.cvsignore org.glite.jp.index/Makefile org.glite.jp.index/build.xml org.glite.jp.index/config/dbsetup.sh org.glite.jp.index/config/defaults/glite-jpis.pre org.glite.jp.index/config/functions/config_glite_jpis org.glite.jp.index/config/glite-jp-index-dbsetup.sql org.glite.jp.index/config/glite-jpis-config.xml org.glite.jp.index/config/glite-jpis-test-config.xml org.glite.jp.index/config/node-info.d/glite-jpis org.glite.jp.index/config/site-info.def.example org.glite.jp.index/config/startup org.glite.jp.index/configure org.glite.jp.index/doc/README org.glite.jp.index/doc/client_conf.xsd org.glite.jp.index/doc/glite-jp-indexd.sgml org.glite.jp.index/doc/glite-jpis-client.sgml org.glite.jp.index/doc/server_conf.xsd org.glite.jp.index/examples/jpis-client.c org.glite.jp.index/examples/jpis-db-internal.c org.glite.jp.index/examples/jpis-test.c org.glite.jp.index/examples/pch06/pch.pm org.glite.jp.index/examples/pch06/query1.pl org.glite.jp.index/examples/pch06/query2.pl org.glite.jp.index/examples/pch06/query3.pl org.glite.jp.index/examples/pch06/query4.pl org.glite.jp.index/examples/pch06/query5.pl org.glite.jp.index/examples/pch06/query6.pl org.glite.jp.index/examples/query-tests/authz.out org.glite.jp.index/examples/query-tests/complex_query.in org.glite.jp.index/examples/query-tests/complex_query.out org.glite.jp.index/examples/query-tests/dump1.sql org.glite.jp.index/examples/query-tests/exists_query.in org.glite.jp.index/examples/query-tests/exists_query.out org.glite.jp.index/examples/query-tests/jobid_query.in org.glite.jp.index/examples/query-tests/jobid_query.out org.glite.jp.index/examples/query-tests/origin_query.in org.glite.jp.index/examples/query-tests/origin_query.out org.glite.jp.index/examples/query-tests/run-test.sh org.glite.jp.index/examples/query-tests/simple_query.in org.glite.jp.index/examples/query-tests/simple_query.out org.glite.jp.index/examples/query-tests/within_query.in org.glite.jp.index/examples/query-tests/within_query.out org.glite.jp.index/interface/JobProvenanceISClient.xsd org.glite.jp.index/project/ChangeLog org.glite.jp.index/project/build.number 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/bones_server.c org.glite.jp.index/src/common.c org.glite.jp.index/src/common.h org.glite.jp.index/src/conf.c org.glite.jp.index/src/conf.h org.glite.jp.index/src/context.c org.glite.jp.index/src/context.h org.glite.jp.index/src/db_ops.c org.glite.jp.index/src/db_ops.h org.glite.jp.index/src/simple_server.c org.glite.jp.index/src/soap_ops.c org.glite.jp.index/src/soap_ps_calls.c org.glite.jp.index/src/soap_ps_calls.h org.glite.jp.index/src/type_plugin.c org.glite.jp.index/src/typemap.dat org.glite.jp.index/src/ws_is_typeref.c org.glite.jp.index/src/ws_is_typeref.h org.glite.jp.index/src/ws_ps_typeref.c org.glite.jp.index/src/ws_ps_typeref.h org.glite.jp.index/src/ws_typemap.h org.glite.jp.primary/.cvsignore org.glite.jp.primary/Makefile org.glite.jp.primary/build.xml org.glite.jp.primary/config/defaults/glite-jpps.pre org.glite.jp.primary/config/functions/config_glite_jpps org.glite.jp.primary/config/glite-jp-primary-dbsetup.sh org.glite.jp.primary/config/glite-jp-primary-dbsetup.sql org.glite.jp.primary/config/gsi_authz.conf.example org.glite.jp.primary/config/node-info.d/glite-jpps org.glite.jp.primary/config/site-info.def.example org.glite.jp.primary/config/startup org.glite.jp.primary/configure org.glite.jp.primary/doc/README.install org.glite.jp.primary/examples/README.test org.glite.jp.primary/examples/dag-deps.c org.glite.jp.primary/examples/getjobattr.pl org.glite.jp.primary/examples/job_template org.glite.jp.primary/examples/jpps-test.c org.glite.jp.primary/examples/jpps_store_test org.glite.jp.primary/examples/recordmultitags.pl org.glite.jp.primary/examples/sample_job_aborted org.glite.jp.primary/examples/sample_job_cleared org.glite.jp.primary/examples/sample_job_tagged_done org.glite.jp.primary/examples/sample_job_waiting org.glite.jp.primary/project/ChangeLog org.glite.jp.primary/project/build.number 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/attrs.c org.glite.jp.primary/src/attrs.h org.glite.jp.primary/src/authz.c org.glite.jp.primary/src/authz.h org.glite.jp.primary/src/backend.h org.glite.jp.primary/src/backend_private.h org.glite.jp.primary/src/bones_server.c org.glite.jp.primary/src/classad_plugin.c org.glite.jp.primary/src/feed.c org.glite.jp.primary/src/feed.h org.glite.jp.primary/src/file_plugin.c org.glite.jp.primary/src/ftpd_auth.c org.glite.jp.primary/src/is_client.c org.glite.jp.primary/src/is_client.h org.glite.jp.primary/src/jp_callouts.c org.glite.jp.primary/src/jp_callouts.h org.glite.jp.primary/src/jptype_map.h org.glite.jp.primary/src/mk_soap_switch.pl org.glite.jp.primary/src/new_ftp_backend.c org.glite.jp.primary/src/sandbox_plugin.c org.glite.jp.primary/src/simple_server.c org.glite.jp.primary/src/soap_ops.c org.glite.jp.primary/src/soap_util.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.server-common/Makefile org.glite.jp.server-common/build.xml org.glite.jp.server-common/configure org.glite.jp.server-common/examples/db-test-int.c org.glite.jp.server-common/interface/db.h org.glite.jp.server-common/project/ChangeLog org.glite.jp.server-common/project/build.number org.glite.jp.server-common/project/configure.properties.xml org.glite.jp.server-common/project/properties.xml org.glite.jp.server-common/project/tar_exclude org.glite.jp.server-common/project/version.properties org.glite.jp.server-common/src/db.c 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/configure org.glite.jp.ws-interface/project/ChangeLog org.glite.jp.ws-interface/project/build.number org.glite.jp.ws-interface/project/build.properties org.glite.jp.ws-interface/project/configure.properties.xml 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.ws-interface/src/JobProvenanceIS.xml org.glite.jp.ws-interface/src/JobProvenancePS.xml org.glite.jp.ws-interface/src/JobProvenanceTypes.xml org.glite.jp.ws-interface/src/doc.xml org.glite.jp.ws-interface/src/jpdev.sh org.glite.jp.ws-interface/src/jpdev.xml.sh org.glite.jp.ws-interface/src/puke-schema.xsl org.glite.jp.ws-interface/src/puke-ug.xsl org.glite.jp.ws-interface/src/puke-wsdl.xsl org.glite.jp.ws-interface/src/ws_fault.c org.glite.jp/.cvsignore org.glite.jp/build.xml org.glite.jp/configure org.glite.jp/doc/README org.glite.jp/project/build.number 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-utils.context/.cvsignore org.glite.lb-utils.context/LICENSE org.glite.lb-utils.context/build.xml org.glite.lb-utils.context/project/build.number org.glite.lb-utils.context/project/build.properties org.glite.lb-utils.context/project/configure.properties.xml org.glite.lb-utils.context/project/properties.xml org.glite.lb-utils.context/project/version.properties org.glite.lb-utils.db/.cvsignore org.glite.lb-utils.db/LICENSE org.glite.lb-utils.db/Makefile org.glite.lb-utils.db/build.xml org.glite.lb-utils.db/examples/db_expire.c org.glite.lb-utils.db/examples/db_test.c org.glite.lb-utils.db/interface/db.h org.glite.lb-utils.db/project/build.number org.glite.lb-utils.db/project/build.properties org.glite.lb-utils.db/project/configure.properties.xml org.glite.lb-utils.db/project/properties.xml org.glite.lb-utils.db/project/tar_exclude org.glite.lb-utils.db/project/version.properties org.glite.lb-utils.db/src/db.c org.glite.lb-utils.jobid/.cvsignore org.glite.lb-utils.jobid/LICENSE org.glite.lb-utils.jobid/Makefile org.glite.lb-utils.jobid/build.xml org.glite.lb-utils.jobid/interface/Exception.h org.glite.lb-utils.jobid/interface/JobId.h org.glite.lb-utils.jobid/interface/JobIdExceptions.h org.glite.lb-utils.jobid/interface/cjobid.h org.glite.lb-utils.jobid/interface/strmd5.h org.glite.lb-utils.jobid/project/build.number org.glite.lb-utils.jobid/project/build.properties org.glite.lb-utils.jobid/project/configure.properties.xml org.glite.lb-utils.jobid/project/properties.xml org.glite.lb-utils.jobid/project/tar_exclude org.glite.lb-utils.jobid/project/version.properties org.glite.lb-utils.jobid/src/cjobid.c org.glite.lb-utils.jobid/src/strmd5.c org.glite.lb-utils.server-bones/.cvsignore org.glite.lb-utils.server-bones/LICENSE org.glite.lb-utils.server-bones/build.xml org.glite.lb-utils.server-bones/project/build.number org.glite.lb-utils.server-bones/project/build.properties org.glite.lb-utils.server-bones/project/configure.properties.xml org.glite.lb-utils.server-bones/project/properties.xml org.glite.lb-utils.server-bones/project/version.properties org.glite.lb-utils.trio/.cvsignore org.glite.lb-utils.trio/LICENSE org.glite.lb-utils.trio/Makefile org.glite.lb-utils.trio/build.xml org.glite.lb-utils.trio/interface/escape.h org.glite.lb-utils.trio/interface/trio.h org.glite.lb-utils.trio/project/build.number org.glite.lb-utils.trio/project/build.properties org.glite.lb-utils.trio/project/configure.properties.xml org.glite.lb-utils.trio/project/properties.xml org.glite.lb-utils.trio/project/version.properties org.glite.lb-utils.trio/src/escape.c org.glite.lb-utils.trio/src/strio.c org.glite.lb-utils.trio/src/strio.h org.glite.lb-utils.trio/src/trio.c org.glite.lb-utils.trio/src/triop.h org.glite.lb-utils.trio/test/trio_test.cpp org.glite.lb-utils/.cvsignore org.glite.lb-utils/LICENSE org.glite.lb-utils/build.xml org.glite.lb-utils/project/build.number org.glite.lb-utils/project/build.properties org.glite.lb-utils/project/dependencies.properties org.glite.lb-utils/project/glite.lb-utils.csf.xml org.glite.lb-utils/project/properties.xml org.glite.lb-utils/project/taskdefs.xml org.glite.lb-utils/project/version.properties org.glite.lb.client-interface/.cvsignore org.glite.lb.client-interface/IMPORTANT-README org.glite.lb.client-interface/LICENSE org.glite.lb.client-interface/Makefile org.glite.lb.client-interface/build.xml org.glite.lb.client-interface/project/build.number org.glite.lb.client-interface/project/build.properties org.glite.lb.client-interface/project/configure.properties.xml org.glite.lb.client-interface/project/properties.xml org.glite.lb.client-interface/project/tar_exclude org.glite.lb.client-interface/project/version.properties org.glite.lb.client-java/Makefile org.glite.lb.client-java/configure org.glite.lb.client-java/examples/CreamTest.java org.glite.lb.client-java/examples/NotificationExample.java org.glite.lb.client-java/examples/ProducerTestIL.java org.glite.lb.client-java/examples/ProducerTestLL.java org.glite.lb.client-java/examples/QueryDemo.java org.glite.lb.client-java/examples/SSLClient.java org.glite.lb.client-java/examples/SSLServer.java org.glite.lb.client-java/examples/SimpleLLTest.java org.glite.lb.client-java/examples/simple-ssl/ExampleSSLSocketFactory.java org.glite.lb.client-java/examples/simple-ssl/LBClientSSL.java org.glite.lb.client-java/examples/simple-ssl/MyX509KeyManager.java org.glite.lb.client-java/examples/simple-ssl/MyX509TrustManager.java org.glite.lb.client-java/examples/simple-trustmanager/LBClientTM.java org.glite.lb.client-java/project/ChangeLog org.glite.lb.client-java/project/debian.control org.glite.lb.client-java/project/debian.copyright org.glite.lb.client-java/project/debian.glite-lb-client-java.dirs org.glite.lb.client-java/project/debian.glite-lb-client-java.install org.glite.lb.client-java/project/debian.rules org.glite.lb.client-java/project/genEventTypes.pl org.glite.lb.client-java/project/glite-lb-client-java.spec org.glite.lb.client-java/project/list-jars.sh org.glite.lb.client-java/project/package.description org.glite.lb.client-java/project/package.summary org.glite.lb.client-java/project/version.properties org.glite.lb.client-java/src/org/glite/lb/Context.java org.glite.lb.client-java/src/org/glite/lb/ContextDirect.java org.glite.lb.client-java/src/org/glite/lb/ContextIL.java org.glite.lb.client-java/src/org/glite/lb/ContextLL.java org.glite.lb.client-java/src/org/glite/lb/Escape.java org.glite.lb.client-java/src/org/glite/lb/Event.java org.glite.lb.client-java/src/org/glite/lb/EventConvertor.java org.glite.lb.client-java/src/org/glite/lb/ILFileWriter.java org.glite.lb.client-java/src/org/glite/lb/ILProto.java org.glite.lb.client-java/src/org/glite/lb/Job.java org.glite.lb.client-java/src/org/glite/lb/LBCredentials.java org.glite.lb.client-java/src/org/glite/lb/LBException.java org.glite.lb.client-java/src/org/glite/lb/Level.java org.glite.lb.client-java/src/org/glite/lb/NotifParser.java org.glite.lb.client-java/src/org/glite/lb/Notification.java org.glite.lb.client-java/src/org/glite/lb/SSL.java org.glite.lb.client-java/src/org/glite/lb/SSLSend.java org.glite.lb.client-java/src/org/glite/lb/SeqCode.java org.glite.lb.client-java/src/org/glite/lb/ServerConnection.java org.glite.lb.client-java/src/org/glite/lb/Sources.java org.glite.lb.client-java/src/org/glite/lb/Timeval.java org.glite.lb.client-java/src_c/Makefile org.glite.lb.client-java/src_c/send_via_proxy.c org.glite.lb.client-java/src_c/send_via_socket.c org.glite.lb.doc/GGUS19469-reply.txt org.glite.lb.doc/LICENSE org.glite.lb.doc/Makefile org.glite.lb.doc/configure org.glite.lb.doc/examples/Makefile org.glite.lb.doc/examples/README org.glite.lb.doc/examples/README.queries org.glite.lb.doc/examples/cons_example1.c org.glite.lb.doc/examples/cons_example1.cpp org.glite.lb.doc/examples/cons_example2.c org.glite.lb.doc/examples/cons_example2.cpp org.glite.lb.doc/examples/cons_example3.c org.glite.lb.doc/examples/cons_example3.cpp org.glite.lb.doc/examples/example1.c org.glite.lb.doc/examples/notif_example.c org.glite.lb.doc/examples/prod_example1.c org.glite.lb.doc/examples/util.C org.glite.lb.doc/examples/util.c org.glite.lb.doc/project/ChangeLog org.glite.lb.doc/project/debian.control org.glite.lb.doc/project/debian.copyright org.glite.lb.doc/project/debian.glite-lb-doc.dirs org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.ag org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.dg org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.tg org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.tp org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.ug org.glite.lb.doc/project/debian.glite-lb-doc.install org.glite.lb.doc/project/debian.rules org.glite.lb.doc/project/glite-lb-doc.spec org.glite.lb.doc/project/package.description org.glite.lb.doc/project/package.summary org.glite.lb.doc/project/version.properties org.glite.lb.doc/src/LBAG-Abstract.tex org.glite.lb.doc/src/LBAG-Installation.tex org.glite.lb.doc/src/LBAG-Introduction.tex org.glite.lb.doc/src/LBAG-Running.tex org.glite.lb.doc/src/LBAG-Troubleshooting.tex org.glite.lb.doc/src/LBAG.tex org.glite.lb.doc/src/LBDG-Abstract.tex org.glite.lb.doc/src/LBDG-Introduction.tex org.glite.lb.doc/src/LBDG.tex org.glite.lb.doc/src/LBTG-Abstract.tex org.glite.lb.doc/src/LBTG.tex org.glite.lb.doc/src/LBTP-Abstract.tex org.glite.lb.doc/src/LBTP-IntegrationTests.tex org.glite.lb.doc/src/LBTP-InterTests.tex org.glite.lb.doc/src/LBTP-Introduction.tex org.glite.lb.doc/src/LBTP-Nagios.tex org.glite.lb.doc/src/LBTP-PerfTests.tex org.glite.lb.doc/src/LBTP-Tests.tex org.glite.lb.doc/src/LBTP.tex org.glite.lb.doc/src/LBUG-Abstract.tex org.glite.lb.doc/src/LBUG-Appendix.tex org.glite.lb.doc/src/LBUG-Introduction.tex org.glite.lb.doc/src/LBUG-Tools.tex org.glite.lb.doc/src/LBUG-Troubleshooting.tex org.glite.lb.doc/src/LBUG.tex org.glite.lb.doc/src/README org.glite.lb.doc/src/README-standards.txt org.glite.lb.doc/src/change_acl.tex org.glite.lb.doc/src/components.tex org.glite.lb.doc/src/consumer_api.tex org.glite.lb.doc/src/copyright.tex org.glite.lb.doc/src/definitions.tex org.glite.lb.doc/src/doxygen.sty org.glite.lb.doc/src/doxyhack.tex org.glite.lb.doc/src/egee.cls org.glite.lb.doc/src/emi.cls org.glite.lb.doc/src/events.tex.T org.glite.lb.doc/src/faq.tex org.glite.lb.doc/src/frontmatter.tex org.glite.lb.doc/src/funding.tex org.glite.lb.doc/src/https_configuration.tex org.glite.lb.doc/src/images/EMI_Logo_std.pdf org.glite.lb.doc/src/images/LB-components-LB-WMS.pdf org.glite.lb.doc/src/images/LB-components-gather.pdf org.glite.lb.doc/src/images/LB-components-query.pdf org.glite.lb.doc/src/images/LB-components.pdf org.glite.lb.doc/src/images/cesnet.pdf org.glite.lb.doc/src/images/e-infra.pdf org.glite.lb.doc/src/images/egee.pdf org.glite.lb.doc/src/images/glite.pdf org.glite.lb.doc/src/images/isi.pdf org.glite.lb.doc/src/images/seqtree.pdf org.glite.lb.doc/src/images/wms2-jobstat.pdf org.glite.lb.doc/src/lbjp.bib org.glite.lb.doc/src/listings.sty org.glite.lb.doc/src/log_usertag.tex org.glite.lb.doc/src/logevent.tex org.glite.lb.doc/src/lstdoc.sty org.glite.lb.doc/src/lstlang1.sty org.glite.lb.doc/src/lstlang2.sty org.glite.lb.doc/src/lstlang3.sty org.glite.lb.doc/src/lstmisc.sty org.glite.lb.doc/src/lstpatch.sty org.glite.lb.doc/src/notification_api.tex org.glite.lb.doc/src/notify.tex org.glite.lb.doc/src/producer_api.tex org.glite.lb.doc/src/status.tex.T org.glite.lb.doc/src/versions.tex org.glite.lb.doc/src/web_services.tex org.glite.lb.emi-lb/Makefile org.glite.lb.emi-lb/configure org.glite.lb.emi-lb/project/ChangeLog org.glite.lb.emi-lb/project/debian.control org.glite.lb.emi-lb/project/debian.copyright org.glite.lb.emi-lb/project/debian.rules org.glite.lb.emi-lb/project/emi-lb.spec org.glite.lb.emi-lb/project/package.description org.glite.lb.emi-lb/project/package.summary org.glite.lb.emi-lb/project/version.properties org.glite.lb.glite-LB/Makefile org.glite.lb.glite-LB/configure org.glite.lb.glite-LB/project/ChangeLog org.glite.lb.glite-LB/project/package.description org.glite.lb.glite-LB/project/package.summary org.glite.lb.glite-LB/project/version.properties org.glite.lb.harvester/Makefile org.glite.lb.harvester/config/startup org.glite.lb.harvester/configure org.glite.lb.harvester/doc/INSTALL org.glite.lb.harvester/doc/README org.glite.lb.harvester/doc/glite-lb-harvester.sgml org.glite.lb.harvester/examples/test.sh org.glite.lb.harvester/examples/test.sql org.glite.lb.harvester/project/.post org.glite.lb.harvester/project/.postun org.glite.lb.harvester/project/.pre org.glite.lb.harvester/project/.preun org.glite.lb.harvester/project/ChangeLog org.glite.lb.harvester/project/debian.control org.glite.lb.harvester/project/debian.copyright org.glite.lb.harvester/project/debian.glite-lb-harvester.dirs org.glite.lb.harvester/project/debian.glite-lb-harvester.install org.glite.lb.harvester/project/debian.preinst org.glite.lb.harvester/project/debian.rules org.glite.lb.harvester/project/glite-lb-harvester.spec org.glite.lb.harvester/project/package.description org.glite.lb.harvester/project/package.summary org.glite.lb.harvester/project/version.properties org.glite.lb.harvester/src/harvester.c org.glite.lb.logger-msg/LICENSE org.glite.lb.logger-msg/Makefile org.glite.lb.logger-msg/config/msg.conf.example org.glite.lb.logger-msg/config/msg.cron.in org.glite.lb.logger-msg/configure org.glite.lb.logger-msg/examples/cmsclient.cpp org.glite.lb.logger-msg/project/ChangeLog org.glite.lb.logger-msg/project/debian.control org.glite.lb.logger-msg/project/debian.copyright org.glite.lb.logger-msg/project/debian.glite-lb-logger-msg.dirs org.glite.lb.logger-msg/project/debian.glite-lb-logger-msg.install org.glite.lb.logger-msg/project/debian.rules org.glite.lb.logger-msg/project/glite-lb-logger-msg.spec org.glite.lb.logger-msg/project/il.conf org.glite.lb.logger-msg/project/package.description org.glite.lb.logger-msg/project/package.summary org.glite.lb.logger-msg/project/version.properties org.glite.lb.logger-msg/src/activemq_cpp_plugin.cpp org.glite.lb.logger-msg/src/msg-brokers org.glite.lb.logger-msg/src/msg-config.in org.glite.lb.nagios/Makefile org.glite.lb.nagios/configure org.glite.lb.nagios/project/ChangeLog org.glite.lb.nagios/project/debian.control org.glite.lb.nagios/project/debian.copyright org.glite.lb.nagios/project/debian.emi-lb-nagios-plugins.dirs org.glite.lb.nagios/project/debian.emi-lb-nagios-plugins.install org.glite.lb.nagios/project/debian.postinst org.glite.lb.nagios/project/debian.rules org.glite.lb.nagios/project/emi-lb-nagios-plugins.spec org.glite.lb.nagios/project/package.description org.glite.lb.nagios/project/package.summary org.glite.lb.nagios/project/version.properties org.glite.lb.nagios/src/LB-probe org.glite.lb.proxy/.cvsignore org.glite.lb.proxy/LICENSE org.glite.lb.proxy/Makefile org.glite.lb.proxy/build.xml org.glite.lb.proxy/config/glite-lb-dbsetup-proxy.sql org.glite.lb.proxy/config/startup org.glite.lb.proxy/doc/README org.glite.lb.proxy/doc/README.deploy org.glite.lb.proxy/examples/test.sh org.glite.lb.proxy/examples/test1.sh org.glite.lb.proxy/examples/test2.sh org.glite.lb.proxy/examples/test3.sh org.glite.lb.proxy/project/build.number org.glite.lb.proxy/project/build.properties org.glite.lb.proxy/project/configure.properties.xml org.glite.lb.proxy/project/properties.xml org.glite.lb.proxy/project/tar_exclude org.glite.lb.proxy/project/version.properties org.glite.lb.proxy/src/fake_write2rgma.c org.glite.lb.proxy/src/lbproxy.c org.glite.lb.proxy/src/perftest_proxy.sh org.glite.lb.server-bones/.cvsignore org.glite.lb.server-bones/Makefile org.glite.lb.server-bones/build.xml org.glite.lb.server-bones/examples/cnt_example.c org.glite.lb.server-bones/examples/srv_example.c org.glite.lb.server-bones/interface/srvbones.h org.glite.lb.server-bones/project/build.number org.glite.lb.server-bones/project/build.properties org.glite.lb.server-bones/project/configure.properties.xml org.glite.lb.server-bones/project/properties.xml org.glite.lb.server-bones/project/tar_exclude org.glite.lb.server-bones/project/version.properties org.glite.lb.server-bones/src/srvbones.c org.glite.lb.utils/.cvsignore org.glite.lb.utils/LICENSE org.glite.lb.utils/Makefile org.glite.lb.utils/configure org.glite.lb.utils/doc/README.LB-monitoring org.glite.lb.utils/doc/README.LB-statistics org.glite.lb.utils/doc/glite-lb-mon.1 org.glite.lb.utils/doc/glite-lb-purge.8 org.glite.lb.utils/examples/glite-lb-index.conf org.glite.lb.utils/examples/glite-lb-statistics-gsi.sh org.glite.lb.utils/examples/glite-lb-statistics-rsync.sh org.glite.lb.utils/examples/glite-lb-statistics-sftp.sh org.glite.lb.utils/examples/glite-lb-statistics.sh org.glite.lb.utils/project/ChangeLog org.glite.lb.utils/project/debian.control org.glite.lb.utils/project/debian.copyright org.glite.lb.utils/project/debian.glite-lb-utils.dirs org.glite.lb.utils/project/debian.glite-lb-utils.install org.glite.lb.utils/project/debian.rules org.glite.lb.utils/project/glite-lb-utils.spec org.glite.lb.utils/project/package.description org.glite.lb.utils/project/package.summary org.glite.lb.utils/project/version.properties org.glite.lb.utils/src/dump.c org.glite.lb.utils/src/dump_exporter.c org.glite.lb.utils/src/glite-lb-bkpurge-offline.sh org.glite.lb.utils/src/load.c org.glite.lb.utils/src/mon.c org.glite.lb.utils/src/notif-keeper.sh org.glite.lb.utils/src/process_attrs.c org.glite.lb.utils/src/process_attrs2.c.T org.glite.lb.utils/src/purge.c org.glite.lb.utils/src/state_history.c org.glite.lb.utils/src/statistics.c org.glite.lb.ws-test/Makefile org.glite.lb.ws-test/configure org.glite.lb.ws-test/examples/ws_comlex.pl org.glite.lb.ws-test/examples/ws_fault.c org.glite.lb.ws-test/examples/ws_fault.h org.glite.lb.ws-test/examples/ws_getversion.c org.glite.lb.ws-test/examples/ws_getversion.pl org.glite.lb.ws-test/examples/ws_joblog.c org.glite.lb.ws-test/examples/ws_joblog.pl org.glite.lb.ws-test/examples/ws_jobstat.c org.glite.lb.ws-test/examples/ws_jobstat.pl org.glite.lb.ws-test/examples/ws_lb4agu_GetActivityInfo.c org.glite.lb.ws-test/examples/ws_lb4agu_GetActivityStatus.c org.glite.lb.ws-test/examples/ws_lb4agu_GetActivityStatus.pl org.glite.lb.ws-test/examples/ws_query_ex.c org.glite.lb.ws-test/examples/ws_status_history_test.sh org.glite.lb.ws-test/examples/ws_typemap.dat org.glite.lb.ws-test/project/ChangeLog org.glite.lb.ws-test/project/debian.control org.glite.lb.ws-test/project/debian.copyright org.glite.lb.ws-test/project/debian.glite-lb-ws-test.dirs org.glite.lb.ws-test/project/debian.glite-lb-ws-test.install org.glite.lb.ws-test/project/debian.rules org.glite.lb.ws-test/project/glite-lb-ws-test.spec org.glite.lb.ws-test/project/package.description org.glite.lb.ws-test/project/package.summary org.glite.lb.ws-test/project/version.properties org.glite.lb.ws-test/tests/sizeof_soap_test.c org.glite.lb.yaim/Makefile org.glite.lb.yaim/config/defaults/glite-lb.pre org.glite.lb.yaim/config/functions/config_gip_lb org.glite.lb.yaim/config/functions/config_glite_lb.in org.glite.lb.yaim/config/functions/config_info_service_lb org.glite.lb.yaim/config/functions/emi/config_info_service_lb org.glite.lb.yaim/config/node-info.d/emi/glite-lb org.glite.lb.yaim/config/node-info.d/glite-lb org.glite.lb.yaim/configure org.glite.lb.yaim/project/ChangeLog org.glite.lb.yaim/project/debian.control org.glite.lb.yaim/project/debian.copyright org.glite.lb.yaim/project/debian.glite-lb-yaim.dirs org.glite.lb.yaim/project/debian.glite-lb-yaim.install org.glite.lb.yaim/project/debian.rules org.glite.lb.yaim/project/glite-lb-yaim.spec org.glite.lb.yaim/project/package.description org.glite.lb.yaim/project/package.summary org.glite.lb.yaim/project/version.properties org.glite.lb/.cvsignore org.glite.lb/LICENSE org.glite.lb/configure org.glite.lb/deployment/README org.glite.lb/deployment/deploy_all.diff org.glite.lb/deployment/deploy_jp.diff org.glite.lb/deployment/deploy_lb.diff org.glite.lb/doc/README.lb4vdt org.glite.lb/doc/perf_clear_proxy org.glite.lb/doc/perf_purge org.glite.lb/doc/perf_reg_jobs org.glite.lb/doc/perf_results/il_sci_09062006.txt org.glite.lb/doc/perf_results/il_sci_09062006_01.txt org.glite.lb/doc/perf_results/il_sci_12062006.txt org.glite.lb/doc/perf_results/ll_michal_21062006.txt org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_22062006.txt org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_23062006.txt org.glite.lb/doc/perf_results/proxy_sci_09062006.txt org.glite.lb/doc/perf_run_interlogd org.glite.lb/doc/perf_run_proxy org.glite.lb/doc/perf_run_server org.glite.lb/doc/perf_run_test org.glite.lb/egee_license_check.sh org.glite.lb/etics-tag-branch.pl org.glite.lb/etics-tag-consistency.pl org.glite.lb/etics-tag-gridsite.pl org.glite.lb/etics-tag-with-subsystems-branch.pl org.glite.lb/etics-tag-with-subsystems.pl org.glite.lb/etics-tag.pl org.glite.lb/generate-properties.pl org.glite.lb/lb4vdt/LB_install.sh org.glite.lb/lb4vdt/Makefile.inc org.glite.lb/lb4vdt/scripts/org.gridsite.core.build org.glite.lb/project/package.description org.glite.lb/project/package.summary org.glite.lb/project/version.properties org.glite.lbjp-common.db/.cvsignore org.glite.lbjp-common.db/LICENSE org.glite.lbjp-common.db/Makefile org.glite.lbjp-common.db/configure org.glite.lbjp-common.db/doc/C.dox org.glite.lbjp-common.db/examples/db_expire.c org.glite.lbjp-common.db/examples/db_test.c org.glite.lbjp-common.db/interface/db-int.h org.glite.lbjp-common.db/interface/db.h org.glite.lbjp-common.db/project/.post org.glite.lbjp-common.db/project/.postun org.glite.lbjp-common.db/project/ChangeLog org.glite.lbjp-common.db/project/debian.control org.glite.lbjp-common.db/project/debian.copyright org.glite.lbjp-common.db/project/debian.libglite-lbjp-common-db-dev.dirs org.glite.lbjp-common.db/project/debian.libglite-lbjp-common-db-dev.install org.glite.lbjp-common.db/project/debian.libglite-lbu-db3.dirs org.glite.lbjp-common.db/project/debian.libglite-lbu-db3.install org.glite.lbjp-common.db/project/debian.rules org.glite.lbjp-common.db/project/glite-lbjp-common-db.spec org.glite.lbjp-common.db/project/package.description org.glite.lbjp-common.db/project/package.summary org.glite.lbjp-common.db/project/version.properties org.glite.lbjp-common.db/src/db-mysql.c org.glite.lbjp-common.db/src/db-pg.c org.glite.lbjp-common.db/src/db.c org.glite.lbjp-common.db/test/timezone.cpp org.glite.lbjp-common.gsoap-plugin/LICENSE org.glite.lbjp-common.gsoap-plugin/Makefile org.glite.lbjp-common.gsoap-plugin/configure org.glite.lbjp-common.gsoap-plugin/examples/calc.h.S org.glite.lbjp-common.gsoap-plugin/examples/wscalc_clt_ex.c org.glite.lbjp-common.gsoap-plugin/examples/wscalc_srv_ex.c org.glite.lbjp-common.gsoap-plugin/examples/wscalc_srv_ex2.c org.glite.lbjp-common.gsoap-plugin/interface/glite_gscompat.h.in org.glite.lbjp-common.gsoap-plugin/interface/glite_gsplugin-int.h org.glite.lbjp-common.gsoap-plugin/interface/glite_gsplugin.h org.glite.lbjp-common.gsoap-plugin/project/.post org.glite.lbjp-common.gsoap-plugin/project/.postun org.glite.lbjp-common.gsoap-plugin/project/ChangeLog org.glite.lbjp-common.gsoap-plugin/project/debian.control org.glite.lbjp-common.gsoap-plugin/project/debian.copyright org.glite.lbjp-common.gsoap-plugin/project/debian.libglite-lbjp-common-gsoap-plugin-dev.dirs org.glite.lbjp-common.gsoap-plugin/project/debian.libglite-lbjp-common-gsoap-plugin-dev.install org.glite.lbjp-common.gsoap-plugin/project/debian.libglite-lbjp-common-gsoap-plugin.dirs org.glite.lbjp-common.gsoap-plugin/project/debian.libglite-lbjp-common-gsoap-plugin.install org.glite.lbjp-common.gsoap-plugin/project/debian.rules org.glite.lbjp-common.gsoap-plugin/project/glite-lbjp-common-gsoap-plugin.spec org.glite.lbjp-common.gsoap-plugin/project/gsoap-plugin++.pc.in org.glite.lbjp-common.gsoap-plugin/project/gsoap-plugin.pc.in org.glite.lbjp-common.gsoap-plugin/project/libtoolhack/gcc org.glite.lbjp-common.gsoap-plugin/project/package.description org.glite.lbjp-common.gsoap-plugin/project/package.summary org.glite.lbjp-common.gsoap-plugin/project/version.properties org.glite.lbjp-common.gsoap-plugin/src/glite_gsplugin.c org.glite.lbjp-common.gsoap-plugin/src/sizeof_soap.c org.glite.lbjp-common.gsoap-plugin/test/test_gsplugin_cxx.cpp org.glite.lbjp-common.jp-interface/Makefile org.glite.lbjp-common.jp-interface/configure org.glite.lbjp-common.jp-interface/interface/attr.h org.glite.lbjp-common.jp-interface/interface/backend.h org.glite.lbjp-common.jp-interface/interface/builtin_plugins.h org.glite.lbjp-common.jp-interface/interface/context.h org.glite.lbjp-common.jp-interface/interface/file_plugin.h org.glite.lbjp-common.jp-interface/interface/indexdb.h org.glite.lbjp-common.jp-interface/interface/known_attr.h org.glite.lbjp-common.jp-interface/interface/type_plugin.h org.glite.lbjp-common.jp-interface/interface/types.h org.glite.lbjp-common.jp-interface/project/.post org.glite.lbjp-common.jp-interface/project/.postun org.glite.lbjp-common.jp-interface/project/ChangeLog org.glite.lbjp-common.jp-interface/project/debian.control org.glite.lbjp-common.jp-interface/project/debian.copyright org.glite.lbjp-common.jp-interface/project/debian.libglite-jp-common2.dirs org.glite.lbjp-common.jp-interface/project/debian.libglite-jp-common2.install org.glite.lbjp-common.jp-interface/project/debian.libglite-lbjp-common-jp-interface-dev.dirs org.glite.lbjp-common.jp-interface/project/debian.libglite-lbjp-common-jp-interface-dev.install org.glite.lbjp-common.jp-interface/project/debian.rules org.glite.lbjp-common.jp-interface/project/glite-lbjp-common-jp-interface.spec org.glite.lbjp-common.jp-interface/project/package.description org.glite.lbjp-common.jp-interface/project/package.summary org.glite.lbjp-common.jp-interface/project/version.properties org.glite.lbjp-common.jp-interface/src/attr.c org.glite.lbjp-common.jp-interface/src/context.c org.glite.lbjp-common.jp-interface/src/indexdb.c org.glite.lbjp-common.jp-interface/src/utils.c org.glite.lbjp-common.jp-interface/test/type_test.cpp org.glite.lbjp-common.log/LICENSE org.glite.lbjp-common.log/Makefile org.glite.lbjp-common.log/README org.glite.lbjp-common.log/config/log4crc org.glite.lbjp-common.log/config/log4crc.debugging org.glite.lbjp-common.log/configure org.glite.lbjp-common.log/project/.post org.glite.lbjp-common.log/project/.postun org.glite.lbjp-common.log/project/ChangeLog org.glite.lbjp-common.log/project/debian.control org.glite.lbjp-common.log/project/debian.copyright org.glite.lbjp-common.log/project/debian.libglite-lbjp-common-log-dev.dirs org.glite.lbjp-common.log/project/debian.libglite-lbjp-common-log-dev.install org.glite.lbjp-common.log/project/debian.libglite-lbu-log1.dirs org.glite.lbjp-common.log/project/debian.libglite-lbu-log1.install org.glite.lbjp-common.log/project/debian.rules org.glite.lbjp-common.log/project/glite-lbjp-common-log.spec org.glite.lbjp-common.log/project/package.description org.glite.lbjp-common.log/project/package.summary org.glite.lbjp-common.log/project/version.properties org.glite.lbjp-common.log/src/log.c org.glite.lbjp-common.log/src/log.h org.glite.lbjp-common.log/tests/log4crc org.glite.lbjp-common.log/tests/test.c org.glite.lbjp-common.maildir/.cvsignore org.glite.lbjp-common.maildir/Makefile org.glite.lbjp-common.maildir/configure org.glite.lbjp-common.maildir/interface/maildir.h org.glite.lbjp-common.maildir/project/.post org.glite.lbjp-common.maildir/project/.postun org.glite.lbjp-common.maildir/project/ChangeLog org.glite.lbjp-common.maildir/project/debian.control org.glite.lbjp-common.maildir/project/debian.copyright org.glite.lbjp-common.maildir/project/debian.libglite-lbjp-common-maildir-dev.dirs org.glite.lbjp-common.maildir/project/debian.libglite-lbjp-common-maildir-dev.install org.glite.lbjp-common.maildir/project/debian.libglite-lbu-maildir2.dirs org.glite.lbjp-common.maildir/project/debian.libglite-lbu-maildir2.install org.glite.lbjp-common.maildir/project/debian.rules org.glite.lbjp-common.maildir/project/glite-lbjp-common-maildir.spec org.glite.lbjp-common.maildir/project/package.description org.glite.lbjp-common.maildir/project/package.summary org.glite.lbjp-common.maildir/project/version.properties org.glite.lbjp-common.maildir/src/maildir.c org.glite.lbjp-common.server-bones/.cvsignore org.glite.lbjp-common.server-bones/Makefile org.glite.lbjp-common.server-bones/configure org.glite.lbjp-common.server-bones/examples/cnt_example.c org.glite.lbjp-common.server-bones/examples/run_test.sh org.glite.lbjp-common.server-bones/examples/srv_example.c org.glite.lbjp-common.server-bones/interface/srvbones.h org.glite.lbjp-common.server-bones/project/.post org.glite.lbjp-common.server-bones/project/.postun org.glite.lbjp-common.server-bones/project/ChangeLog org.glite.lbjp-common.server-bones/project/debian.control org.glite.lbjp-common.server-bones/project/debian.copyright org.glite.lbjp-common.server-bones/project/debian.libglite-lbjp-common-server-bones-dev.dirs org.glite.lbjp-common.server-bones/project/debian.libglite-lbjp-common-server-bones-dev.install org.glite.lbjp-common.server-bones/project/debian.libglite-lbu-server-bones2.dirs org.glite.lbjp-common.server-bones/project/debian.libglite-lbu-server-bones2.install org.glite.lbjp-common.server-bones/project/debian.rules org.glite.lbjp-common.server-bones/project/glite-lbjp-common-server-bones.spec org.glite.lbjp-common.server-bones/project/package.description org.glite.lbjp-common.server-bones/project/package.summary org.glite.lbjp-common.server-bones/project/version.properties org.glite.lbjp-common.server-bones/src/srvbones.c org.glite.lbjp-common.trio/.cvsignore org.glite.lbjp-common.trio/LICENSE org.glite.lbjp-common.trio/Makefile org.glite.lbjp-common.trio/configure org.glite.lbjp-common.trio/interface/escape.h org.glite.lbjp-common.trio/interface/trio.h org.glite.lbjp-common.trio/project/.post org.glite.lbjp-common.trio/project/.postun org.glite.lbjp-common.trio/project/ChangeLog org.glite.lbjp-common.trio/project/debian.control org.glite.lbjp-common.trio/project/debian.copyright org.glite.lbjp-common.trio/project/debian.libglite-lbjp-common-trio-dev.dirs org.glite.lbjp-common.trio/project/debian.libglite-lbjp-common-trio-dev.install org.glite.lbjp-common.trio/project/debian.libglite-lbu-trio2.dirs org.glite.lbjp-common.trio/project/debian.libglite-lbu-trio2.install org.glite.lbjp-common.trio/project/debian.rules org.glite.lbjp-common.trio/project/glite-lbjp-common-trio.spec org.glite.lbjp-common.trio/project/package.description org.glite.lbjp-common.trio/project/package.summary org.glite.lbjp-common.trio/project/version.properties org.glite.lbjp-common.trio/src/escape.c org.glite.lbjp-common.trio/src/strio.c org.glite.lbjp-common.trio/src/strio.h org.glite.lbjp-common.trio/src/trio.c org.glite.lbjp-common.trio/src/triop.h org.glite.lbjp-common.trio/test/trio_test.cpp org.glite.lbjp-common/project/version.properties org.glite.lbjp-utils.db/.cvsignore org.glite.lbjp-utils.db/LICENSE org.glite.lbjp-utils.db/Makefile org.glite.lbjp-utils.db/examples/db_expire.c org.glite.lbjp-utils.db/examples/db_test.c org.glite.lbjp-utils.db/interface/db.h org.glite.lbjp-utils.db/src/db.c org.glite.lbjp-utils.jobid/.cvsignore org.glite.lbjp-utils.jobid/LICENSE org.glite.lbjp-utils.jobid/Makefile org.glite.lbjp-utils.jobid/interface/Exception.h org.glite.lbjp-utils.jobid/interface/JobId.h org.glite.lbjp-utils.jobid/interface/JobIdExceptions.h org.glite.lbjp-utils.jobid/interface/cjobid.h org.glite.lbjp-utils.jobid/interface/strmd5.h org.glite.lbjp-utils.jobid/src/cjobid.c org.glite.lbjp-utils.jobid/src/strmd5.c org.glite.lbjp-utils.server-bones/.cvsignore org.glite.lbjp-utils.server-bones/Makefile org.glite.lbjp-utils.server-bones/examples/cnt_example.c org.glite.lbjp-utils.server-bones/examples/srv_example.c org.glite.lbjp-utils.server-bones/interface/srvbones.h org.glite.lbjp-utils.server-bones/src/srvbones.c org.glite.lbjp-utils.trio/.cvsignore org.glite.lbjp-utils.trio/LICENSE org.glite.lbjp-utils.trio/Makefile org.glite.lbjp-utils.trio/interface/escape.h org.glite.lbjp-utils.trio/interface/trio.h org.glite.lbjp-utils.trio/src/escape.c org.glite.lbjp-utils.trio/src/strio.c org.glite.lbjp-utils.trio/src/strio.h org.glite.lbjp-utils.trio/src/trio.c org.glite.lbjp-utils.trio/src/triop.h org.glite.lbjp-utils.trio/test/trio_test.cpp org.glite.myproxy-config/.cvsignore org.glite.myproxy-config/Makefile org.glite.myproxy-config/myproxy-config.spec org.glite.myproxy-config/myproxy-initd org.glite.px.emi-px/Makefile org.glite.px.emi-px/configure org.glite.px.emi-px/project/ChangeLog org.glite.px.emi-px/project/debian.control org.glite.px.emi-px/project/debian.copyright org.glite.px.emi-px/project/debian.rules org.glite.px.emi-px/project/emi-px.spec org.glite.px.emi-px/project/package.description org.glite.px.emi-px/project/package.summary org.glite.px.emi-px/project/version.properties org.glite.px.glite-PX/Makefile org.glite.px.glite-PX/configure org.glite.px.glite-PX/project/ChangeLog org.glite.px.glite-PX/project/package.description org.glite.px.glite-PX/project/package.summary org.glite.px.glite-PX/project/version.properties org.glite.px.myproxy-yaim/Makefile org.glite.px.myproxy-yaim/config/defaults/glite-px.pre org.glite.px.myproxy-yaim/config/functions/config_gip_px org.glite.px.myproxy-yaim/config/functions/config_info_service_px org.glite.px.myproxy-yaim/config/functions/config_proxy_server org.glite.px.myproxy-yaim/config/functions/emi/config_info_service_px org.glite.px.myproxy-yaim/config/man/myproxy-yaim.1 org.glite.px.myproxy-yaim/config/node-info.d/emi/glite-px org.glite.px.myproxy-yaim/config/node-info.d/glite-px org.glite.px.myproxy-yaim/config/node-info.d/glite-px_30 org.glite.px.myproxy-yaim/config/services/glite-px org.glite.px.myproxy-yaim/configure org.glite.px.myproxy-yaim/project/ChangeLog org.glite.px.myproxy-yaim/project/debian.control org.glite.px.myproxy-yaim/project/debian.copyright org.glite.px.myproxy-yaim/project/debian.glite-px-myproxy-yaim.dirs org.glite.px.myproxy-yaim/project/debian.glite-px-myproxy-yaim.install org.glite.px.myproxy-yaim/project/debian.rules org.glite.px.myproxy-yaim/project/glite-px-myproxy-yaim.spec org.glite.px.myproxy-yaim/project/package.description org.glite.px.myproxy-yaim/project/package.summary org.glite.px.myproxy-yaim/project/version.properties org.glite.px.proxyrenewal/LICENSE org.glite.px.proxyrenewal/Makefile org.glite.px.proxyrenewal/README org.glite.px.proxyrenewal/config/startup org.glite.px.proxyrenewal/configure org.glite.px.proxyrenewal/examples/renew_core.c org.glite.px.proxyrenewal/interface/renewal.h org.glite.px.proxyrenewal/interface/renewal_core.h org.glite.px.proxyrenewal/project/.post org.glite.px.proxyrenewal/project/.postun org.glite.px.proxyrenewal/project/.pre org.glite.px.proxyrenewal/project/.preun org.glite.px.proxyrenewal/project/ChangeLog org.glite.px.proxyrenewal/project/debian.control org.glite.px.proxyrenewal/project/debian.copyright org.glite.px.proxyrenewal/project/debian.glite-px-proxyrenewal-progs.dirs org.glite.px.proxyrenewal/project/debian.glite-px-proxyrenewal-progs.install org.glite.px.proxyrenewal/project/debian.libglite-security-proxyrenewal-dev.dirs org.glite.px.proxyrenewal/project/debian.libglite-security-proxyrenewal-dev.install org.glite.px.proxyrenewal/project/debian.libglite-security-proxyrenewal1.dirs org.glite.px.proxyrenewal/project/debian.libglite-security-proxyrenewal1.install org.glite.px.proxyrenewal/project/debian.preinst org.glite.px.proxyrenewal/project/debian.rules org.glite.px.proxyrenewal/project/doc_proxyrenewal.pl org.glite.px.proxyrenewal/project/glite-px-proxyrenewal.spec org.glite.px.proxyrenewal/project/package.description org.glite.px.proxyrenewal/project/package.summary org.glite.px.proxyrenewal/project/version.properties org.glite.px.proxyrenewal/src/api.c org.glite.px.proxyrenewal/src/client.c org.glite.px.proxyrenewal/src/commands.c org.glite.px.proxyrenewal/src/common.c org.glite.px.proxyrenewal/src/glite-proxy-renew.1 org.glite.px.proxyrenewal/src/glite-proxy-renewd.8 org.glite.px.proxyrenewal/src/renew.c org.glite.px.proxyrenewal/src/renewal_core.c org.glite.px.proxyrenewal/src/renewal_locl.h org.glite.px.proxyrenewal/src/renewd.c org.glite.px.proxyrenewal/src/renewd_locl.h org.glite.px.proxyrenewal/src/voms.c org.glite.px/project/version.properties org.glite.security.gsoap-plugin/LICENSE org.glite.security.gsoap-plugin/Makefile org.glite.security.gsoap-plugin/build.xml org.glite.security.gsoap-plugin/configure 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_gscompat.h org.glite.security.gsoap-plugin/interface/glite_gsplugin-int.h org.glite.security.gsoap-plugin/interface/glite_gsplugin.h org.glite.security.gsoap-plugin/project/ChangeLog org.glite.security.gsoap-plugin/project/build.number org.glite.security.gsoap-plugin/project/build.properties org.glite.security.gsoap-plugin/project/configure.properties.xml org.glite.security.gsoap-plugin/project/libtoolhack/gcc org.glite.security.gsoap-plugin/project/package.description org.glite.security.gsoap-plugin/project/package.summary org.glite.security.gsoap-plugin/project/properties.xml org.glite.security.gsoap-plugin/project/tar_exclude 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 org.glite.security.gsoap-plugin/src/stdsoap2_2.6.2.h org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0.c org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0.h org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.c org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.h org.glite.security.gsoap-plugin/src/stdsoap2_2.7.10.c org.glite.security.gsoap-plugin/src/stdsoap2_2.7.10.h org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.c org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.h org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6d.c org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6d.h org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.c org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.h org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9d.c org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9d.h org.glite.security.gsoap-plugin/test/test_gsplugin_cxx.cpp org.glite.security.gss/LICENSE org.glite.security.gss/Makefile org.glite.security.gss/configure org.glite.security.gss/interface/glite_gss.h org.glite.security.gss/project/ChangeLog org.glite.security.gss/project/package.description org.glite.security.gss/project/package.summary org.glite.security.gss/project/version.properties org.glite.security.gss/src/glite_gss.c org.glite.security.gss/test/test_gss.cpp org.glite.security.proxyrenewal/.cvsignore org.glite.security.proxyrenewal/LICENSE org.glite.security.proxyrenewal/Makefile org.glite.security.proxyrenewal/build.xml org.glite.security.proxyrenewal/config/startup org.glite.security.proxyrenewal/examples/renew_core.c org.glite.security.proxyrenewal/interface/renewal.h org.glite.security.proxyrenewal/interface/renewal_core.h org.glite.security.proxyrenewal/project/build.number org.glite.security.proxyrenewal/project/build.properties org.glite.security.proxyrenewal/project/configure.properties.xml org.glite.security.proxyrenewal/project/properties.xml org.glite.security.proxyrenewal/project/tar_exclude org.glite.security.proxyrenewal/project/taskdefs.xml org.glite.security.proxyrenewal/project/version.properties org.glite.security.proxyrenewal/src/api.c org.glite.security.proxyrenewal/src/client.c org.glite.security.proxyrenewal/src/commands.c org.glite.security.proxyrenewal/src/common.c org.glite.security.proxyrenewal/src/renew.c org.glite.security.proxyrenewal/src/renewal_core.c org.glite.security.proxyrenewal/src/renewal_locl.h org.glite.security.proxyrenewal/src/renewd.c org.glite.security.proxyrenewal/src/renewd_locl.h org.glite.security.proxyrenewal/src/voms.c org.glite.testsuites.ctb/CANL-C/tests/Makefile org.glite.testsuites.ctb/CANL-C/tests/canl-autonomous-test.sh org.glite.testsuites.ctb/CANL-C/tests/canl-common-testbeds.sh org.glite.testsuites.ctb/CANL-C/tests/canl-common.sh org.glite.testsuites.ctb/CANL-C/tests/canl-generate-fake-proxy.sh org.glite.testsuites.ctb/CANL-C/tests/canl-test-cert-handle.sh org.glite.testsuites.ctb/CANL-C/tests/canl-test-cs-openssl.sh org.glite.testsuites.ctb/CANL-C/tests/canl-test-sec-connection.sh org.glite.testsuites.ctb/CANL-C/tests/canl-test-sha2.sh org.glite.testsuites.ctb/CANL-C/tests/test-common.sh org.glite.testsuites.ctb/LB/LB-certconfig org.glite.testsuites.ctb/LB/LB-certtest.sh org.glite.testsuites.ctb/LB/Makefile org.glite.testsuites.ctb/LB/manual/Readme.txt org.glite.testsuites.ctb/LB/manual/Readme2.txt.old org.glite.testsuites.ctb/LB/tests/Makefile org.glite.testsuites.ctb/LB/tests/lb-autonomous-test.sh org.glite.testsuites.ctb/LB/tests/lb-common-testbeds.sh org.glite.testsuites.ctb/LB/tests/lb-common.sh org.glite.testsuites.ctb/LB/tests/lb-generate-events.sh org.glite.testsuites.ctb/LB/tests/lb-generate-fake-proxy.sh org.glite.testsuites.ctb/LB/tests/lb-l2.sh org.glite.testsuites.ctb/LB/tests/lb-l2ILR.sh org.glite.testsuites.ctb/LB/tests/lb-l2Stat.sh org.glite.testsuites.ctb/LB/tests/lb-run-tests.sh org.glite.testsuites.ctb/LB/tests/lb-test-acl-authz.sh org.glite.testsuites.ctb/LB/tests/lb-test-bdii.sh org.glite.testsuites.ctb/LB/tests/lb-test-binaries.sh org.glite.testsuites.ctb/LB/tests/lb-test-changeacl.sh org.glite.testsuites.ctb/LB/tests/lb-test-collections.sh org.glite.testsuites.ctb/LB/tests/lb-test-cream.sh org.glite.testsuites.ctb/LB/tests/lb-test-event-delivery.sh org.glite.testsuites.ctb/LB/tests/lb-test-harvester.sh org.glite.testsuites.ctb/LB/tests/lb-test-https.sh org.glite.testsuites.ctb/LB/tests/lb-test-il-recovery.sh org.glite.testsuites.ctb/LB/tests/lb-test-job-registration.sh org.glite.testsuites.ctb/LB/tests/lb-test-job-states.sh org.glite.testsuites.ctb/LB/tests/lb-test-logevent.sh org.glite.testsuites.ctb/LB/tests/lb-test-logger-local.sh org.glite.testsuites.ctb/LB/tests/lb-test-logger-remote.sh org.glite.testsuites.ctb/LB/tests/lb-test-nagios-probe.sh org.glite.testsuites.ctb/LB/tests/lb-test-notif-keeper.sh org.glite.testsuites.ctb/LB/tests/lb-test-notif-msg.sh org.glite.testsuites.ctb/LB/tests/lb-test-notif-recovery.sh org.glite.testsuites.ctb/LB/tests/lb-test-notif-stream.sh org.glite.testsuites.ctb/LB/tests/lb-test-notif-switch.sh org.glite.testsuites.ctb/LB/tests/lb-test-notif.sh org.glite.testsuites.ctb/LB/tests/lb-test-packaging.sh org.glite.testsuites.ctb/LB/tests/lb-test-permissions.sh org.glite.testsuites.ctb/LB/tests/lb-test-proxy-delivery.sh org.glite.testsuites.ctb/LB/tests/lb-test-purge.pl org.glite.testsuites.ctb/LB/tests/lb-test-sandbox-transfer.sh org.glite.testsuites.ctb/LB/tests/lb-test-server-local.sh org.glite.testsuites.ctb/LB/tests/lb-test-server-remote.sh org.glite.testsuites.ctb/LB/tests/lb-test-statistics.sh org.glite.testsuites.ctb/LB/tests/lb-test-switch-owner.sh org.glite.testsuites.ctb/LB/tests/lb-test-threaded.sh org.glite.testsuites.ctb/LB/tests/lb-test-wild.sh org.glite.testsuites.ctb/LB/tests/lb-test-ws.sh org.glite.testsuites.ctb/LB/tests/test-common.sh org.glite.testsuites.ctb/LB/tests/testSocket.c org.glite.testsuites.ctb/PX/tests/px-autonomous-test.sh org.glite.testsuites.ctb/PX/tests/px-common-testbeds.sh org.glite.testsuites.ctb/PX/tests/px-common.sh org.glite.testsuites.ctb/PX/tests/px-test-all.sh org.glite.testsuites.ctb/PX/tests/px-test-packaging.sh org.glite.testsuites.ctb/PX/tests/px-voms-install.sh org.glite.testsuites.ctb/PX/tests/test-common.sh org.glite.testsuites.ctb/gridsite/tests/gridsite-autonomous-test.sh org.glite.testsuites.ctb/gridsite/tests/gridsite-common-testbeds.sh org.glite.testsuites.ctb/gridsite/tests/gridsite-common.sh org.glite.testsuites.ctb/gridsite/tests/gridsite-test-all.sh org.glite.testsuites.ctb/gridsite/tests/gridsite-test-packaging.sh org.glite.testsuites.ctb/gridsite/tests/ping-local.sh org.glite.testsuites.ctb/gridsite/tests/ping-remote.sh org.glite.testsuites.ctb/gridsite/tests/test-common.sh org.glite.wms-utils.exception/.cvsignore org.glite.wms-utils.exception/LICENSE org.glite.wms-utils.exception/Makefile.am org.glite.wms-utils.exception/bootstrap org.glite.wms-utils.exception/build.xml org.glite.wms-utils.exception/configure.ac org.glite.wms-utils.exception/interface/Makefile.am org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h org.glite.wms-utils.exception/project/build.number org.glite.wms-utils.exception/project/build.properties org.glite.wms-utils.exception/project/configure.properties.xml org.glite.wms-utils.exception/project/properties.xml org.glite.wms-utils.exception/project/version.properties org.glite.wms-utils.exception/src/Exception.cpp org.glite.wms-utils.exception/src/Makefile.am org.glite.wms-utils.exception/test/Makefile.am org.glite.wms-utils.exception/test/exception_cu_main.cpp org.glite.wms-utils.exception/test/exception_cu_suite.cpp org.glite.wms-utils.exception/test/exception_cu_suite.h org.glite.wms-utils.jobid/.cvsignore org.glite.wms-utils.jobid/LICENSE org.glite.wms-utils.jobid/Makefile.am org.glite.wms-utils.jobid/bootstrap org.glite.wms-utils.jobid/build.xml org.glite.wms-utils.jobid/configure.ac org.glite.wms-utils.jobid/examples/Makefile.am org.glite.wms-utils.jobid/examples/testjobid.c org.glite.wms-utils.jobid/interface/Makefile.am org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h org.glite.wms-utils.jobid/project/build.number org.glite.wms-utils.jobid/project/build.properties org.glite.wms-utils.jobid/project/configure.properties.xml org.glite.wms-utils.jobid/project/properties.xml org.glite.wms-utils.jobid/project/version.properties org.glite.wms-utils.jobid/src/Makefile.am org.glite.wms-utils.jobid/src/jobid/JobId.cpp org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp org.glite.wms-utils.jobid/src/jobid/Makefile.am org.glite.wms-utils.jobid/src/jobid/cjobid.c org.glite.wms-utils.jobid/src/jobid/manipulation.cpp org.glite.wms-utils.jobid/src/jobid/strmd5.c org.glite.wms-utils.jobid/src/jobid/strmd5.h org.glite.wms-utils.jobid/test/Makefile.am org.glite.wms-utils.jobid/test/jobid_cu_main.cpp org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp org.glite.wms-utils.jobid/test/jobid_cu_suite.h org.glite.wms-utils.jobid/test/manipulation_cu_main.cpp org.glite.wms-utils.jobid/test/manipulation_cu_suite.cpp org.glite.wms-utils.jobid/test/manipulation_cu_suite.h org.glite.yaim.lb/.cvsignore org.glite.yaim.lb/LICENSE org.glite.yaim.lb/Makefile org.glite.yaim.lb/config/defaults/glite-lb.pre org.glite.yaim.lb/config/defaults/glite-lb_30.pre org.glite.yaim.lb/config/functions/config_gip_lb org.glite.yaim.lb/config/functions/config_gip_lb_30 org.glite.yaim.lb/config/functions/config_glite_lb org.glite.yaim.lb/config/functions/config_glite_lb_30 org.glite.yaim.lb/config/functions/config_info_service_lb org.glite.yaim.lb/config/functions/config_jobmon org.glite.yaim.lb/config/node-info.d/glite-lb org.glite.yaim.lb/config/node-info.d/glite-lb_30 org.glite.yaim.lb/glite-yaim-lb.spec org.glite.yaim.myproxy/.cvsignore org.glite.yaim.myproxy/Changelog org.glite.yaim.myproxy/LICENSE org.glite.yaim.myproxy/Makefile org.glite.yaim.myproxy/config/functions/config_gip_px org.glite.yaim.myproxy/config/functions/config_info_service_px org.glite.yaim.myproxy/config/functions/config_proxy_server org.glite.yaim.myproxy/config/man/yaim-myproxy.1 org.glite.yaim.myproxy/config/node-info.d/glite-px org.glite.yaim.myproxy/config/node-info.d/glite-px_30 org.glite.yaim.myproxy/config/services/glite-px org.glite.yaim.myproxy/glite-yaim-myproxy.spec org.gridsite.core/.cvsignore org.gridsite.core/CHANGES org.gridsite.core/INSTALL org.gridsite.core/LICENSE org.gridsite.core/README org.gridsite.core/VERSION org.gridsite.core/build.xml org.gridsite.core/doc/README.htcp-bin org.gridsite.core/doc/build-apache2.sh org.gridsite.core/doc/delegation-1.1.0.wsdl org.gridsite.core/doc/doc_gridsite.pl org.gridsite.core/doc/findproxyfile.1 org.gridsite.core/doc/fuse.spec org.gridsite.core/doc/gridsite-delegation.8 org.gridsite.core/doc/gsexec.8 org.gridsite.core/doc/gsoap-devel.spec org.gridsite.core/doc/htcp.1 org.gridsite.core/doc/htfind.1 org.gridsite.core/doc/htll.1 org.gridsite.core/doc/htls.1 org.gridsite.core/doc/htmkdir.1 org.gridsite.core/doc/htmv.1 org.gridsite.core/doc/htping.1 org.gridsite.core/doc/htproxydestroy.1 org.gridsite.core/doc/htproxyinfo.1 org.gridsite.core/doc/htproxyput.1 org.gridsite.core/doc/htproxyrenew.1 org.gridsite.core/doc/htproxytime.1 org.gridsite.core/doc/htproxyunixtime.1 org.gridsite.core/doc/htrm.1 org.gridsite.core/doc/httpd-fileserver.conf org.gridsite.core/doc/httpd-storage.conf org.gridsite.core/doc/httpd-webserver.conf org.gridsite.core/doc/index.html org.gridsite.core/doc/mod_gridsite.8 org.gridsite.core/doc/slashgrid.8 org.gridsite.core/doc/urlencode.1 org.gridsite.core/interface/gridsite-gacl.h org.gridsite.core/interface/gridsite.h org.gridsite.core/project/build.number org.gridsite.core/project/build.properties org.gridsite.core/project/compat-1.5.patch org.gridsite.core/project/configure.properties.xml org.gridsite.core/project/debian.changelog org.gridsite.core/project/debian.control org.gridsite.core/project/debian.rules org.gridsite.core/project/dependencies.properties org.gridsite.core/project/gridsite.core.csf.xml org.gridsite.core/project/properties.xml org.gridsite.core/project/taskdefs.xml org.gridsite.core/project/version.properties org.gridsite.core/src/Doxyfile org.gridsite.core/src/Makefile org.gridsite.core/src/delegation.h org.gridsite.core/src/doxygen.css org.gridsite.core/src/doxyheader.html org.gridsite.core/src/findproxyfile.c org.gridsite.core/src/gaclexample.c org.gridsite.core/src/gridsite-copy.c org.gridsite.core/src/gridsite-globus.pc.in org.gridsite.core/src/gridsite-openssl.pc.in org.gridsite.core/src/gridsite-storage.c org.gridsite.core/src/grst-delegation.c org.gridsite.core/src/grst_admin.h org.gridsite.core/src/grst_admin_file.c org.gridsite.core/src/grst_admin_gacl.c org.gridsite.core/src/grst_admin_main.c org.gridsite.core/src/grst_asn1.c org.gridsite.core/src/grst_err.c org.gridsite.core/src/grst_gacl.c org.gridsite.core/src/grst_htcp.c org.gridsite.core/src/grst_http.c org.gridsite.core/src/grst_x509.c org.gridsite.core/src/grst_xacml.c org.gridsite.core/src/gsexec.c org.gridsite.core/src/gsexec.h org.gridsite.core/src/htcp.c org.gridsite.core/src/htproxyput.c org.gridsite.core/src/make-debian-files org.gridsite.core/src/make-gridsite-spec org.gridsite.core/src/mod_gridsite.c org.gridsite.core/src/mod_gridsite_example.c org.gridsite.core/src/mod_ssl-private.h org.gridsite.core/src/roffit org.gridsite.core/src/showx509exts.c org.gridsite.core/src/slashgrid.c org.gridsite.core/src/slashgrid.init org.gridsite.core/src/urlencode.c org.gridsite.core/src/xacmlexample.c --- emi.canl.canl-c/Makefile | 169 - emi.canl.canl-c/configure | 2058 --- emi.canl.canl-c/doc/src/canl-abstract.tex | 21 - .../doc/src/canl-cs-auth-connection.tex | 215 - emi.canl.canl-c/doc/src/canl-introduction.tex | 180 - emi.canl.canl-c/doc/src/canl-proxy-cert.tex | 251 - emi.canl.canl-c/doc/src/canl.tex | 102 - emi.canl.canl-c/doc/src/copyright.tex | 32 - emi.canl.canl-c/doc/src/definitions.tex | 55 - emi.canl.canl-c/doc/src/emi.cls | 491 - emi.canl.canl-c/doc/src/funding.tex | 3 - emi.canl.canl-c/doc/src/images/EMI_Logo_std.pdf | Bin 34764 -> 0 bytes emi.canl.canl-c/doc/src/images/cesnet.pdf | Bin 4518 -> 0 bytes emi.canl.canl-c/examples/canl_sample_client.c | 124 - emi.canl.canl-c/examples/canl_sample_server.c | 191 - emi.canl.canl-c/examples/delegation.c | 213 - emi.canl.canl-c/examples/grid-proxy-init.c | 153 - emi.canl.canl-c/project/ChangeLog | 40 - emi.canl.canl-c/project/canl-c.spec | 97 - emi.canl.canl-c/project/debian.control | 39 - emi.canl.canl-c/project/debian.copyright | 38 - emi.canl.canl-c/project/debian.libcanl-c-dev.dirs | 2 - .../project/debian.libcanl-c-dev.install | 3 - .../project/debian.libcanl-c-examples.dirs | 1 - .../project/debian.libcanl-c-examples.install | 1 - emi.canl.canl-c/project/debian.libcanl-c1.dirs | 1 - emi.canl.canl-c/project/debian.libcanl-c1.install | 1 - emi.canl.canl-c/project/debian.rules | 66 - emi.canl.canl-c/project/package.description | 1 - emi.canl.canl-c/project/package.summary | 1 - emi.canl.canl-c/project/version.properties | 3 - emi.canl.canl-c/src/canl.c | 520 - emi.canl.canl-c/src/canl.h | 82 - emi.canl.canl-c/src/canl_cert.c | 236 - emi.canl.canl-c/src/canl_cred.c | 636 - emi.canl.canl-c/src/canl_cred.h | 104 - emi.canl.canl-c/src/canl_dns.c | 149 - emi.canl.canl-c/src/canl_err.c | 253 - emi.canl.canl-c/src/canl_error_codes | 106 - emi.canl.canl-c/src/canl_error_desc | 194 - emi.canl.canl-c/src/canl_locl.h | 134 - emi.canl.canl-c/src/canl_mech_ssl.h | 33 - emi.canl.canl-c/src/canl_ssl.c | 1435 -- emi.canl.canl-c/src/canl_ssl.h | 37 - emi.canl.canl-c/src/gen_err_codes.pl | 23 - emi.canl.canl-c/src/gen_err_desc.pl | 70 - emi.canl.canl-c/src/proxy/config.h | 14 - emi.canl.canl-c/src/proxy/data.c | 17 - emi.canl.canl-c/src/proxy/doio.c | 73 - emi.canl.canl-c/src/proxy/doio.h | 34 - emi.canl.canl-c/src/proxy/evaluate.c | 400 - emi.canl.canl-c/src/proxy/list.c | 69 - emi.canl.canl-c/src/proxy/listfunc.h | 33 - emi.canl.canl-c/src/proxy/myproxycertinfo.h | 131 - emi.canl.canl-c/src/proxy/namespaces_lex.c.in | 2090 --- emi.canl.canl-c/src/proxy/namespaces_lex.l | 67 - emi.canl.canl-c/src/proxy/namespaces_parse.y | 126 - emi.canl.canl-c/src/proxy/normalize.c | 89 - emi.canl.canl-c/src/proxy/normalize.h | 39 - emi.canl.canl-c/src/proxy/parsertypes.h | 50 - emi.canl.canl-c/src/proxy/proxy.c | 884 -- emi.canl.canl-c/src/proxy/proxycertinfo.c | 511 - emi.canl.canl-c/src/proxy/scutils.c | 987 -- emi.canl.canl-c/src/proxy/scutils.h | 251 - emi.canl.canl-c/src/proxy/signing_policy_lex.c.in | 2118 --- emi.canl.canl-c/src/proxy/signing_policy_lex.l | 68 - emi.canl.canl-c/src/proxy/signing_policy_parse.y | 195 - emi.canl.canl-c/src/proxy/sslutils.c | 3968 ----- emi.canl.canl-c/src/proxy/sslutils.h | 539 - emi.canl.canl-c/src/proxy/vomsproxy.h | 103 - org.glite.deployment.jpis/build.xml | 94 - .../config/scripts/glite-jpis-config.py | 492 - .../config/templates/glite-jpis.cfg.xml | 92 - org.glite.deployment.jpis/project/build.number | 2 - org.glite.deployment.jpis/project/build.properties | 0 .../project/glite-jp.sdf.xml.template | 117 - .../project/glite-jpis.sdf.xml.template | 117 - org.glite.deployment.jpis/project/lxscript-rpm.xsl | 336 - org.glite.deployment.jpis/project/lxscript-tgz.xsl | 62 - org.glite.deployment.jpis/project/properties.xml | 63 - .../project/quattor-template.xsl | 64 - .../project/version.properties | 4 - org.glite.deployment.jpps/build.xml | 94 - .../config/scripts/glite-jpps-config.py | 500 - .../config/templates/glite-jpps.cfg.xml | 93 - org.glite.deployment.jpps/project/build.number | 2 - org.glite.deployment.jpps/project/build.properties | 0 .../project/glite-jpps.sdf.xml.template | 127 - org.glite.deployment.jpps/project/lxscript-rpm.xsl | 336 - org.glite.deployment.jpps/project/lxscript-tgz.xsl | 62 - org.glite.deployment.jpps/project/properties.xml | 63 - .../project/quattor-template.xsl | 64 - .../project/version.properties | 4 - org.glite.deployment.lb/.cvsignore | 1 - org.glite.deployment.lb/CHANGELOG | 40 - org.glite.deployment.lb/LICENSE | 69 - org.glite.deployment.lb/build.xml | 110 - .../config/scripts/glite-lb-config.py | 574 - .../config/templates/glite-lb.cfg.xml | 73 - .../doc/release_notes/release_notes.doc | Bin 192512 -> 0 bytes .../doc/release_notes/release_notes.html | 2712 ---- .../doc/release_notes/release_notes.pdf | Bin 157326 -> 0 bytes org.glite.deployment.lb/project/.cvsignore | 1 - org.glite.deployment.lb/project/build.number | 2 - org.glite.deployment.lb/project/build.properties | 0 .../project/glite-lb.sdf.xml.template | 157 - org.glite.deployment.lb/project/lxscript-rpm.xsl | 336 - org.glite.deployment.lb/project/lxscript-tgz.xsl | 62 - org.glite.deployment.lb/project/properties.xml | 73 - .../project/quattor-template.xsl | 64 - org.glite.deployment.lb/project/version.properties | 4 - org.glite.jobid.api-c/Makefile | 94 - org.glite.jobid.api-c/configure | 2058 --- org.glite.jobid.api-c/interface/cjobid.h | 154 - org.glite.jobid.api-c/interface/strmd5.h | 56 - org.glite.jobid.api-c/project/.post | 1 - org.glite.jobid.api-c/project/.postun | 1 - org.glite.jobid.api-c/project/ChangeLog | 84 - org.glite.jobid.api-c/project/debian.control | 34 - org.glite.jobid.api-c/project/debian.copyright | 38 - .../project/debian.libglite-jobid-api-c-dev.dirs | 2 - .../debian.libglite-jobid-api-c-dev.install | 2 - .../project/debian.libglite-jobid2.dirs | 1 - .../project/debian.libglite-jobid2.install | 1 - org.glite.jobid.api-c/project/debian.rules | 66 - .../project/glite-jobid-api-c.spec | 82 - org.glite.jobid.api-c/project/package.description | 1 - org.glite.jobid.api-c/project/package.summary | 1 - org.glite.jobid.api-c/project/version.properties | 3 - org.glite.jobid.api-c/src/cjobid.c | 301 - org.glite.jobid.api-c/src/md32_common.h | 640 - org.glite.jobid.api-c/src/md5.h | 135 - org.glite.jobid.api-c/src/md5_dgst.c | 315 - org.glite.jobid.api-c/src/md5_locl.h | 193 - org.glite.jobid.api-c/src/strmd5.c | 169 - org.glite.jobid.api-c/test/base64_test.cpp | 91 - org.glite.jobid.api-cpp/Makefile | 61 - org.glite.jobid.api-cpp/configure | 2058 --- org.glite.jobid.api-cpp/interface/JobId.h | 351 - org.glite.jobid.api-cpp/project/ChangeLog | 76 - org.glite.jobid.api-cpp/project/debian.control | 18 - org.glite.jobid.api-cpp/project/debian.copyright | 38 - .../project/debian.libglite-jobid-api-cpp-dev.dirs | 1 - .../debian.libglite-jobid-api-cpp-dev.install | 1 - org.glite.jobid.api-cpp/project/debian.rules | 62 - .../project/glite-jobid-api-cpp.spec | 67 - .../project/package.description | 1 - org.glite.jobid.api-cpp/project/package.summary | 1 - org.glite.jobid.api-cpp/project/version.properties | 3 - org.glite.jobid.api-java/Makefile | 26 - org.glite.jobid.api-java/build.xml | 69 - org.glite.jobid.api-java/configure | 2058 --- org.glite.jobid.api-java/nbproject/build-impl.xml | 627 - .../nbproject/genfiles.properties | 8 - .../nbproject/private/config.properties | 0 .../nbproject/private/private.properties | 6 - .../nbproject/private/private.xml | 4 - .../nbproject/project.properties | 63 - org.glite.jobid.api-java/nbproject/project.xml | 17 - org.glite.jobid.api-java/project/ChangeLog | 63 - org.glite.jobid.api-java/project/debian.control | 17 - org.glite.jobid.api-java/project/debian.copyright | 38 - .../project/debian.glite-jobid-api-java.dirs | 1 - .../project/debian.glite-jobid-api-java.install | 1 - org.glite.jobid.api-java/project/debian.rules | 60 - .../project/glite-jobid-api-java.spec | 61 - .../project/package.description | 1 - org.glite.jobid.api-java/project/package.summary | 1 - .../project/version.properties | 3 - .../src/org/glite/jobid/ExampleJobid.java | 60 - .../src/org/glite/jobid/Jobid.java | 245 - org.glite.jobid/project/version.properties | 3 - org.glite.jp.client/.cvsignore | 1 - org.glite.jp.client/Makefile | 188 - org.glite.jp.client/build.xml | 86 - org.glite.jp.client/config/startup | 115 - org.glite.jp.client/configure | 701 - org.glite.jp.client/doc/README.jpimporter | 115 - org.glite.jp.client/examples/glite-jp-importer.sh | 83 - org.glite.jp.client/examples/jpps_upload_files.c | 99 - org.glite.jp.client/examples/mill_feed.c | 334 - org.glite.jp.client/interface/jp_client.h | 48 - org.glite.jp.client/interface/jpcl_ctx_int.h | 40 - org.glite.jp.client/interface/jpimporter.h | 52 - org.glite.jp.client/project/ChangeLog | 6 - org.glite.jp.client/project/build.number | 2 - org.glite.jp.client/project/build.properties | 0 .../project/configure.properties.xml | 44 - org.glite.jp.client/project/properties.xml | 44 - org.glite.jp.client/project/tar_exclude | 10 - org.glite.jp.client/project/version.properties | 3 - org.glite.jp.client/src/jpcl_ctx.c | 93 - org.glite.jp.client/src/jpimp_lib.c | 134 - org.glite.jp.client/src/jpimporter.c | 1070 -- org.glite.jp.client/src/jptype_map.h | 35 - org.glite.jp.client/src/typemap.dat | 3 - org.glite.jp.common/.cvsignore | 1 - org.glite.jp.common/Makefile | 90 - org.glite.jp.common/build.xml | 97 - org.glite.jp.common/interface/attr.h | 49 - org.glite.jp.common/interface/backend.h | 131 - org.glite.jp.common/interface/builtin_plugins.h | 25 - org.glite.jp.common/interface/context.h | 43 - org.glite.jp.common/interface/file_plugin.h | 103 - org.glite.jp.common/interface/indexdb.h | 76 - org.glite.jp.common/interface/known_attr.h | 58 - org.glite.jp.common/interface/type_plugin.h | 91 - org.glite.jp.common/interface/types.h | 83 - org.glite.jp.common/project/build.number | 2 - org.glite.jp.common/project/build.properties | 0 .../project/configure.properties.xml | 62 - org.glite.jp.common/project/properties.xml | 52 - org.glite.jp.common/project/tar_exclude | 10 - org.glite.jp.common/project/version.properties | 2 - org.glite.jp.common/src/attr.c | 308 - org.glite.jp.common/src/context.c | 162 - org.glite.jp.common/src/indexdb.c | 88 - org.glite.jp.common/src/utils.c | 80 - org.glite.jp.common/test/type_test.cpp | 217 - org.glite.jp.doc/LICENSE | 69 - org.glite.jp.doc/Makefile | 79 - org.glite.jp.doc/configure | 701 - org.glite.jp.doc/project/ChangeLog | 6 - org.glite.jp.doc/project/version.properties | 3 - org.glite.jp.doc/src/JPAG-Configuration.tex | 36 - org.glite.jp.doc/src/JPAG-Installation.tex | 9 - org.glite.jp.doc/src/JPAG-Introduction.tex | 75 - org.glite.jp.doc/src/JPAG-Running.tex | 33 - org.glite.jp.doc/src/JPAG-Testing.tex | 545 - org.glite.jp.doc/src/JPAG-Troubleshooting.tex | 6 - org.glite.jp.doc/src/JPAG.tex | 48 - org.glite.jp.doc/src/JPDG-Introduction.tex | 4 - org.glite.jp.doc/src/JPDG-WS.tex | 34 - org.glite.jp.doc/src/JPDG.tex | 36 - org.glite.jp.doc/src/JPUG-Introduction.tex | 693 - org.glite.jp.doc/src/JPUG-Tools.tex | 25 - org.glite.jp.doc/src/JPUG-UseCases.tex | 159 - org.glite.jp.doc/src/JPUG.tex | 43 - org.glite.jp.doc/src/LB-JP-interaction.tex | 74 - org.glite.jp.doc/src/README | 12 - org.glite.jp.doc/src/copyright.tex | 24 - org.glite.jp.doc/src/definitions.tex | 24 - org.glite.jp.doc/src/egee.cls | 507 - org.glite.jp.doc/src/frontmatter.tex | 40 - org.glite.jp.doc/src/glite-jpis-client.tex | 93 - .../src/glite_installation_guide_JP.doc | Bin 349184 -> 0 bytes .../src/glite_installation_guide_LB.doc | Bin 174080 -> 0 bytes org.glite.jp.doc/src/gui.tex | 3 - org.glite.jp.doc/src/images/JP-interactions.cdr | Bin 49340 -> 0 bytes org.glite.jp.doc/src/images/JP-interactions.pdf | Bin 85708 -> 0 bytes org.glite.jp.doc/src/images/JP-query.cdr | Bin 37774 -> 0 bytes org.glite.jp.doc/src/images/JP-query.pdf | Bin 41756 -> 0 bytes .../src/images/LB-JP-interaction-details.cdr | Bin 42198 -> 0 bytes .../src/images/LB-JP-interaction-details.pdf | Bin 72334 -> 0 bytes .../src/images/LB-JP-interaction-drawing.pdf | Bin 167722 -> 0 bytes org.glite.jp.doc/src/images/egee.pdf | Bin 8922 -> 0 bytes org.glite.jp.doc/src/images/isi.pdf | Bin 19672 -> 0 bytes org.glite.jp.doc/src/jpimporter.tex | 4 - org.glite.jp.doc/src/jpws.tex | 599 - org.glite.jp.doc/src/lbjp.bib | 709 - org.glite.jp.index/.cvsignore | 1 - org.glite.jp.index/Makefile | 178 - org.glite.jp.index/build.xml | 98 - org.glite.jp.index/config/dbsetup.sh | 30 - org.glite.jp.index/config/defaults/glite-jpis.pre | 2 - .../config/functions/config_glite_jpis | 148 - .../config/glite-jp-index-dbsetup.sql | 96 - org.glite.jp.index/config/glite-jpis-config.xml | 541 - .../config/glite-jpis-test-config.xml | 105 - org.glite.jp.index/config/node-info.d/glite-jpis | 8 - org.glite.jp.index/config/site-info.def.example | 77 - org.glite.jp.index/config/startup | 135 - org.glite.jp.index/configure | 701 - org.glite.jp.index/doc/README | 41 - org.glite.jp.index/doc/client_conf.xsd | 84 - org.glite.jp.index/doc/glite-jp-indexd.sgml | 372 - org.glite.jp.index/doc/glite-jpis-client.sgml | 193 - org.glite.jp.index/doc/server_conf.xsd | 97 - org.glite.jp.index/examples/jpis-client.c | 538 - org.glite.jp.index/examples/jpis-db-internal.c | 151 - org.glite.jp.index/examples/jpis-test.c | 255 - org.glite.jp.index/examples/pch06/pch.pm | 237 - org.glite.jp.index/examples/pch06/query1.pl | 132 - org.glite.jp.index/examples/pch06/query2.pl | 147 - org.glite.jp.index/examples/pch06/query3.pl | 140 - org.glite.jp.index/examples/pch06/query4.pl | 150 - org.glite.jp.index/examples/pch06/query5.pl | 142 - org.glite.jp.index/examples/pch06/query6.pl | 172 - org.glite.jp.index/examples/query-tests/authz.out | 14 - .../examples/query-tests/complex_query.in | 36 - .../examples/query-tests/complex_query.out | 36 - org.glite.jp.index/examples/query-tests/dump1.sql | 594 - .../examples/query-tests/exists_query.in | 17 - .../examples/query-tests/exists_query.out | 28 - .../examples/query-tests/jobid_query.in | 19 - .../examples/query-tests/jobid_query.out | 23 - .../examples/query-tests/origin_query.in | 20 - .../examples/query-tests/origin_query.out | 23 - .../examples/query-tests/run-test.sh | 314 - .../examples/query-tests/simple_query.in | 19 - .../examples/query-tests/simple_query.out | 23 - .../examples/query-tests/within_query.in | 19 - .../examples/query-tests/within_query.out | 28 - .../interface/JobProvenanceISClient.xsd | 28 - org.glite.jp.index/project/ChangeLog | 6 - org.glite.jp.index/project/build.number | 2 - org.glite.jp.index/project/build.properties | 0 .../project/configure.properties.xml | 74 - org.glite.jp.index/project/properties.xml | 52 - org.glite.jp.index/project/tar_exclude | 10 - org.glite.jp.index/project/version.properties | 3 - org.glite.jp.index/src/bones_server.c | 560 - org.glite.jp.index/src/common.c | 77 - org.glite.jp.index/src/common.h | 36 - org.glite.jp.index/src/conf.c | 345 - org.glite.jp.index/src/conf.h | 85 - org.glite.jp.index/src/context.c | 55 - org.glite.jp.index/src/context.h | 45 - org.glite.jp.index/src/db_ops.c | 889 -- org.glite.jp.index/src/db_ops.h | 67 - org.glite.jp.index/src/simple_server.c | 56 - org.glite.jp.index/src/soap_ops.c | 738 - org.glite.jp.index/src/soap_ps_calls.c | 197 - org.glite.jp.index/src/soap_ps_calls.h | 29 - org.glite.jp.index/src/type_plugin.c | 75 - org.glite.jp.index/src/typemap.dat | 4 - org.glite.jp.index/src/ws_is_typeref.c | 231 - org.glite.jp.index/src/ws_is_typeref.h | 30 - org.glite.jp.index/src/ws_ps_typeref.c | 161 - org.glite.jp.index/src/ws_ps_typeref.h | 27 - org.glite.jp.index/src/ws_typemap.h | 45 - org.glite.jp.primary/.cvsignore | 1 - org.glite.jp.primary/Makefile | 223 - org.glite.jp.primary/build.xml | 116 - .../config/defaults/glite-jpps.pre | 2 - .../config/functions/config_glite_jpps | 126 - .../config/glite-jp-primary-dbsetup.sh | 30 - .../config/glite-jp-primary-dbsetup.sql | 63 - org.glite.jp.primary/config/gsi_authz.conf.example | 6 - org.glite.jp.primary/config/node-info.d/glite-jpps | 6 - org.glite.jp.primary/config/site-info.def.example | 64 - org.glite.jp.primary/config/startup | 169 - org.glite.jp.primary/configure | 701 - org.glite.jp.primary/doc/README.install | 59 - org.glite.jp.primary/examples/README.test | 94 - org.glite.jp.primary/examples/dag-deps.c | 194 - org.glite.jp.primary/examples/getjobattr.pl | 60 - org.glite.jp.primary/examples/job_template | 14 - org.glite.jp.primary/examples/jpps-test.c | 303 - org.glite.jp.primary/examples/jpps_store_test | 86 - org.glite.jp.primary/examples/recordmultitags.pl | 77 - org.glite.jp.primary/examples/sample_job_aborted | 9 - org.glite.jp.primary/examples/sample_job_cleared | 15 - .../examples/sample_job_tagged_done | 15 - org.glite.jp.primary/examples/sample_job_waiting | 8 - org.glite.jp.primary/project/ChangeLog | 6 - org.glite.jp.primary/project/build.number | 2 - org.glite.jp.primary/project/build.properties | 0 .../project/configure.properties.xml | 85 - org.glite.jp.primary/project/properties.xml | 51 - org.glite.jp.primary/project/tar_exclude | 10 - org.glite.jp.primary/project/version.properties | 2 - org.glite.jp.primary/src/attrs.c | 278 - org.glite.jp.primary/src/attrs.h | 19 - org.glite.jp.primary/src/authz.c | 102 - org.glite.jp.primary/src/authz.h | 35 - org.glite.jp.primary/src/backend.h | 180 - org.glite.jp.primary/src/backend_private.h | 93 - org.glite.jp.primary/src/bones_server.c | 436 - org.glite.jp.primary/src/classad_plugin.c | 232 - org.glite.jp.primary/src/feed.c | 995 -- org.glite.jp.primary/src/feed.h | 54 - org.glite.jp.primary/src/file_plugin.c | 142 - org.glite.jp.primary/src/ftpd_auth.c | 219 - org.glite.jp.primary/src/is_client.c | 499 - org.glite.jp.primary/src/is_client.h | 21 - org.glite.jp.primary/src/jp_callouts.c | 539 - org.glite.jp.primary/src/jp_callouts.h | 29 - org.glite.jp.primary/src/jptype_map.h | 51 - org.glite.jp.primary/src/mk_soap_switch.pl | 79 - org.glite.jp.primary/src/new_ftp_backend.c | 2145 --- org.glite.jp.primary/src/sandbox_plugin.c | 280 - org.glite.jp.primary/src/simple_server.c | 76 - org.glite.jp.primary/src/soap_ops.c | 620 - org.glite.jp.primary/src/soap_util.c | 91 - org.glite.jp.primary/src/tags.c | 476 - org.glite.jp.primary/src/tags.h | 27 - org.glite.jp.primary/src/typemap.dat | 3 - org.glite.jp.server-common/Makefile | 77 - org.glite.jp.server-common/build.xml | 101 - org.glite.jp.server-common/configure | 701 - org.glite.jp.server-common/examples/db-test-int.c | 129 - org.glite.jp.server-common/interface/db.h | 44 - org.glite.jp.server-common/project/ChangeLog | 6 - org.glite.jp.server-common/project/build.number | 2 - .../project/configure.properties.xml | 72 - org.glite.jp.server-common/project/properties.xml | 56 - org.glite.jp.server-common/project/tar_exclude | 10 - .../project/version.properties | 2 - org.glite.jp.server-common/src/db.c | 128 - org.glite.jp.ws-interface/.cvsignore | 2 - org.glite.jp.ws-interface/LICENSE | 69 - org.glite.jp.ws-interface/Makefile | 63 - org.glite.jp.ws-interface/build.xml | 120 - org.glite.jp.ws-interface/configure | 701 - org.glite.jp.ws-interface/project/ChangeLog | 6 - org.glite.jp.ws-interface/project/build.number | 2 - org.glite.jp.ws-interface/project/build.properties | 0 .../project/configure.properties.xml | 54 - org.glite.jp.ws-interface/project/properties.xml | 73 - org.glite.jp.ws-interface/project/tar_exclude | 0 .../project/version.properties | 2 - org.glite.jp.ws-interface/src/JobProvenanceIS.xml | 104 - org.glite.jp.ws-interface/src/JobProvenancePS.xml | 110 - .../src/JobProvenanceTypes.xml | 137 - org.glite.jp.ws-interface/src/doc.xml | 2 - org.glite.jp.ws-interface/src/jpdev.sh | 36 - org.glite.jp.ws-interface/src/jpdev.xml.sh | 38 - org.glite.jp.ws-interface/src/puke-schema.xsl | 161 - org.glite.jp.ws-interface/src/puke-ug.xsl | 170 - org.glite.jp.ws-interface/src/puke-wsdl.xsl | 292 - org.glite.jp.ws-interface/src/ws_fault.c | 209 - org.glite.jp/.cvsignore | 1 - org.glite.jp/build.xml | 410 - org.glite.jp/configure | 691 - org.glite.jp/doc/README | 1 - org.glite.jp/project/build.number | 2 - org.glite.jp/project/build.properties | 2 - org.glite.jp/project/dependencies.properties | 16 - org.glite.jp/project/glite.jp.csf.xml | 322 - org.glite.jp/project/properties.xml | 47 - org.glite.jp/project/run-workspace | 10 - org.glite.jp/project/taskdefs.xml | 24 - org.glite.jp/project/version.properties | 3 - org.glite.lb-utils.context/.cvsignore | 2 - org.glite.lb-utils.context/LICENSE | 69 - org.glite.lb-utils.context/build.xml | 122 - org.glite.lb-utils.context/project/build.number | 1 - .../project/build.properties | 0 .../project/configure.properties.xml | 37 - org.glite.lb-utils.context/project/properties.xml | 73 - .../project/version.properties | 2 - org.glite.lb-utils.db/.cvsignore | 5 - org.glite.lb-utils.db/LICENSE | 69 - org.glite.lb-utils.db/Makefile | 137 - org.glite.lb-utils.db/build.xml | 126 - org.glite.lb-utils.db/examples/db_expire.c | 115 - org.glite.lb-utils.db/examples/db_test.c | 196 - org.glite.lb-utils.db/interface/db.h | 344 - org.glite.lb-utils.db/project/build.number | 1 - org.glite.lb-utils.db/project/build.properties | 3 - .../project/configure.properties.xml | 81 - org.glite.lb-utils.db/project/properties.xml | 73 - org.glite.lb-utils.db/project/tar_exclude | 10 - org.glite.lb-utils.db/project/version.properties | 2 - org.glite.lb-utils.db/src/db.c | 1039 -- org.glite.lb-utils.jobid/.cvsignore | 2 - org.glite.lb-utils.jobid/LICENSE | 69 - org.glite.lb-utils.jobid/Makefile | 98 - org.glite.lb-utils.jobid/build.xml | 129 - org.glite.lb-utils.jobid/interface/Exception.h | 138 - org.glite.lb-utils.jobid/interface/JobId.h | 126 - .../interface/JobIdExceptions.h | 80 - org.glite.lb-utils.jobid/interface/cjobid.h | 109 - org.glite.lb-utils.jobid/interface/strmd5.h | 30 - org.glite.lb-utils.jobid/project/build.number | 1 - org.glite.lb-utils.jobid/project/build.properties | 4 - .../project/configure.properties.xml | 63 - org.glite.lb-utils.jobid/project/properties.xml | 73 - org.glite.lb-utils.jobid/project/tar_exclude | 10 - .../project/version.properties | 2 - org.glite.lb-utils.jobid/src/cjobid.c | 260 - org.glite.lb-utils.jobid/src/strmd5.c | 122 - org.glite.lb-utils.server-bones/.cvsignore | 2 - org.glite.lb-utils.server-bones/LICENSE | 69 - org.glite.lb-utils.server-bones/build.xml | 122 - .../project/build.number | 1 - .../project/build.properties | 0 .../project/configure.properties.xml | 37 - .../project/properties.xml | 73 - .../project/version.properties | 2 - org.glite.lb-utils.trio/.cvsignore | 2 - org.glite.lb-utils.trio/LICENSE | 69 - org.glite.lb-utils.trio/Makefile | 114 - org.glite.lb-utils.trio/build.xml | 126 - org.glite.lb-utils.trio/interface/escape.h | 59 - org.glite.lb-utils.trio/interface/trio.h | 187 - org.glite.lb-utils.trio/project/build.number | 1 - org.glite.lb-utils.trio/project/build.properties | 4 - .../project/configure.properties.xml | 59 - org.glite.lb-utils.trio/project/properties.xml | 73 - org.glite.lb-utils.trio/project/version.properties | 2 - org.glite.lb-utils.trio/src/escape.c | 224 - org.glite.lb-utils.trio/src/strio.c | 581 - org.glite.lb-utils.trio/src/strio.h | 227 - org.glite.lb-utils.trio/src/trio.c | 5706 ------- org.glite.lb-utils.trio/src/triop.h | 138 - org.glite.lb-utils.trio/test/trio_test.cpp | 85 - org.glite.lb-utils/.cvsignore | 1 - org.glite.lb-utils/LICENSE | 69 - org.glite.lb-utils/build.xml | 303 - org.glite.lb-utils/project/build.number | 1 - org.glite.lb-utils/project/build.properties | 0 org.glite.lb-utils/project/dependencies.properties | 13 - org.glite.lb-utils/project/glite.lb-utils.csf.xml | 218 - org.glite.lb-utils/project/properties.xml | 64 - org.glite.lb-utils/project/taskdefs.xml | 38 - org.glite.lb-utils/project/version.properties | 2 - org.glite.lb.client-interface/.cvsignore | 2 - org.glite.lb.client-interface/IMPORTANT-README | 39 - org.glite.lb.client-interface/LICENSE | 69 - org.glite.lb.client-interface/Makefile | 2 - org.glite.lb.client-interface/build.xml | 144 - org.glite.lb.client-interface/project/build.number | 2 - .../project/build.properties | 0 .../project/configure.properties.xml | 96 - .../project/properties.xml | 62 - org.glite.lb.client-interface/project/tar_exclude | 10 - .../project/version.properties | 4 - org.glite.lb.client-java/Makefile | 113 - org.glite.lb.client-java/configure | 2058 --- org.glite.lb.client-java/examples/CreamTest.java | 95 - .../examples/NotificationExample.java | 114 - .../examples/ProducerTestIL.java | 166 - .../examples/ProducerTestLL.java | 184 - org.glite.lb.client-java/examples/QueryDemo.java | 274 - org.glite.lb.client-java/examples/SSLClient.java | 34 - org.glite.lb.client-java/examples/SSLServer.java | 47 - .../examples/SimpleLLTest.java | 54 - .../simple-ssl/ExampleSSLSocketFactory.java | 125 - .../examples/simple-ssl/LBClientSSL.java | 96 - .../examples/simple-ssl/MyX509KeyManager.java | 81 - .../examples/simple-ssl/MyX509TrustManager.java | 100 - .../examples/simple-trustmanager/LBClientTM.java | 79 - org.glite.lb.client-java/project/ChangeLog | 96 - org.glite.lb.client-java/project/debian.control | 17 - org.glite.lb.client-java/project/debian.copyright | 38 - .../project/debian.glite-lb-client-java.dirs | 2 - .../project/debian.glite-lb-client-java.install | 2 - org.glite.lb.client-java/project/debian.rules | 66 - org.glite.lb.client-java/project/genEventTypes.pl | 148 - .../project/glite-lb-client-java.spec | 82 - org.glite.lb.client-java/project/list-jars.sh | 22 - .../project/package.description | 1 - org.glite.lb.client-java/project/package.summary | 1 - .../project/version.properties | 3 - .../src/org/glite/lb/Context.java | 370 - .../src/org/glite/lb/ContextDirect.java | 79 - .../src/org/glite/lb/ContextIL.java | 163 - .../src/org/glite/lb/ContextLL.java | 178 - .../src/org/glite/lb/Escape.java | 26 - .../src/org/glite/lb/Event.java | 179 - .../src/org/glite/lb/EventConvertor.java | 1101 -- .../src/org/glite/lb/ILFileWriter.java | 84 - .../src/org/glite/lb/ILProto.java | 255 - org.glite.lb.client-java/src/org/glite/lb/Job.java | 181 - .../src/org/glite/lb/LBCredentials.java | 135 - .../src/org/glite/lb/LBException.java | 30 - .../src/org/glite/lb/Level.java | 66 - .../src/org/glite/lb/NotifParser.java | 145 - .../src/org/glite/lb/Notification.java | 252 - org.glite.lb.client-java/src/org/glite/lb/SSL.java | 122 - .../src/org/glite/lb/SSLSend.java | 80 - .../src/org/glite/lb/SeqCode.java | 165 - .../src/org/glite/lb/ServerConnection.java | 536 - .../src/org/glite/lb/Sources.java | 74 - .../src/org/glite/lb/Timeval.java | 89 - org.glite.lb.client-java/src_c/Makefile | 34 - org.glite.lb.client-java/src_c/send_via_proxy.c | 297 - org.glite.lb.client-java/src_c/send_via_socket.c | 219 - org.glite.lb.doc/GGUS19469-reply.txt | 158 - org.glite.lb.doc/LICENSE | 69 - org.glite.lb.doc/Makefile | 139 - org.glite.lb.doc/configure | 2058 --- org.glite.lb.doc/examples/Makefile | 82 - org.glite.lb.doc/examples/README | 19 - org.glite.lb.doc/examples/README.queries | 511 - org.glite.lb.doc/examples/cons_example1.c | 137 - org.glite.lb.doc/examples/cons_example1.cpp | 111 - org.glite.lb.doc/examples/cons_example2.c | 151 - org.glite.lb.doc/examples/cons_example2.cpp | 119 - org.glite.lb.doc/examples/cons_example3.c | 136 - org.glite.lb.doc/examples/cons_example3.cpp | 112 - org.glite.lb.doc/examples/example1.c | 66 - org.glite.lb.doc/examples/notif_example.c | 144 - org.glite.lb.doc/examples/prod_example1.c | 125 - org.glite.lb.doc/examples/util.C | 160 - org.glite.lb.doc/examples/util.c | 71 - org.glite.lb.doc/project/ChangeLog | 178 - org.glite.lb.doc/project/debian.control | 17 - org.glite.lb.doc/project/debian.copyright | 38 - org.glite.lb.doc/project/debian.glite-lb-doc.dirs | 2 - .../project/debian.glite-lb-doc.doc-base.ag | 7 - .../project/debian.glite-lb-doc.doc-base.dg | 7 - .../project/debian.glite-lb-doc.doc-base.tg | 7 - .../project/debian.glite-lb-doc.doc-base.tp | 7 - .../project/debian.glite-lb-doc.doc-base.ug | 7 - .../project/debian.glite-lb-doc.install | 2 - org.glite.lb.doc/project/debian.rules | 64 - org.glite.lb.doc/project/glite-lb-doc.spec | 63 - org.glite.lb.doc/project/package.description | 1 - org.glite.lb.doc/project/package.summary | 1 - org.glite.lb.doc/project/version.properties | 3 - org.glite.lb.doc/src/LBAG-Abstract.tex | 21 - org.glite.lb.doc/src/LBAG-Installation.tex | 857 -- org.glite.lb.doc/src/LBAG-Introduction.tex | 123 - org.glite.lb.doc/src/LBAG-Running.tex | 683 - org.glite.lb.doc/src/LBAG-Troubleshooting.tex | 32 - org.glite.lb.doc/src/LBAG.tex | 70 - org.glite.lb.doc/src/LBDG-Abstract.tex | 22 - org.glite.lb.doc/src/LBDG-Introduction.tex | 623 - org.glite.lb.doc/src/LBDG.tex | 115 - org.glite.lb.doc/src/LBTG-Abstract.tex | 21 - org.glite.lb.doc/src/LBTG.tex | 58 - org.glite.lb.doc/src/LBTP-Abstract.tex | 23 - org.glite.lb.doc/src/LBTP-IntegrationTests.tex | 116 - org.glite.lb.doc/src/LBTP-InterTests.tex | 26 - org.glite.lb.doc/src/LBTP-Introduction.tex | 148 - org.glite.lb.doc/src/LBTP-Nagios.tex | 124 - org.glite.lb.doc/src/LBTP-PerfTests.tex | 552 - org.glite.lb.doc/src/LBTP-Tests.tex | 659 - org.glite.lb.doc/src/LBTP.tex | 74 - org.glite.lb.doc/src/LBUG-Abstract.tex | 22 - org.glite.lb.doc/src/LBUG-Appendix.tex | 142 - org.glite.lb.doc/src/LBUG-Introduction.tex | 978 -- org.glite.lb.doc/src/LBUG-Tools.tex | 142 - org.glite.lb.doc/src/LBUG-Troubleshooting.tex | 59 - org.glite.lb.doc/src/LBUG.tex | 67 - org.glite.lb.doc/src/README | 13 - org.glite.lb.doc/src/README-standards.txt | 293 - org.glite.lb.doc/src/change_acl.tex | 95 - org.glite.lb.doc/src/components.tex | 164 - org.glite.lb.doc/src/consumer_api.tex | 590 - org.glite.lb.doc/src/copyright.tex | 42 - org.glite.lb.doc/src/definitions.tex | 54 - org.glite.lb.doc/src/doxygen.sty | 64 - org.glite.lb.doc/src/doxyhack.tex | 47 - org.glite.lb.doc/src/egee.cls | 452 - org.glite.lb.doc/src/emi.cls | 491 - org.glite.lb.doc/src/events.tex.T | 35 - org.glite.lb.doc/src/faq.tex | 96 - org.glite.lb.doc/src/frontmatter.tex | 59 - org.glite.lb.doc/src/funding.tex | 1 - org.glite.lb.doc/src/https_configuration.tex | 31 - org.glite.lb.doc/src/images/EMI_Logo_std.pdf | Bin 34764 -> 0 bytes .../src/images/LB-components-LB-WMS.pdf | Bin 84385 -> 0 bytes .../src/images/LB-components-gather.pdf | Bin 48193 -> 0 bytes .../src/images/LB-components-query.pdf | Bin 56629 -> 0 bytes org.glite.lb.doc/src/images/LB-components.pdf | Bin 93972 -> 0 bytes org.glite.lb.doc/src/images/cesnet.pdf | Bin 4518 -> 0 bytes org.glite.lb.doc/src/images/e-infra.pdf | Bin 11649 -> 0 bytes org.glite.lb.doc/src/images/egee.pdf | Bin 449747 -> 0 bytes org.glite.lb.doc/src/images/glite.pdf | Bin 392014 -> 0 bytes org.glite.lb.doc/src/images/isi.pdf | Bin 19672 -> 0 bytes org.glite.lb.doc/src/images/seqtree.pdf | Bin 5715 -> 0 bytes org.glite.lb.doc/src/images/wms2-jobstat.pdf | Bin 7328 -> 0 bytes org.glite.lb.doc/src/lbjp.bib | 780 - org.glite.lb.doc/src/listings.sty | 2002 --- org.glite.lb.doc/src/log_usertag.tex | 82 - org.glite.lb.doc/src/logevent.tex | 93 - org.glite.lb.doc/src/lstdoc.sty | 451 - org.glite.lb.doc/src/lstlang1.sty | 1226 -- org.glite.lb.doc/src/lstlang2.sty | 1532 -- org.glite.lb.doc/src/lstlang3.sty | 1006 -- org.glite.lb.doc/src/lstmisc.sty | 2086 --- org.glite.lb.doc/src/lstpatch.sty | 393 - org.glite.lb.doc/src/notification_api.tex | 226 - org.glite.lb.doc/src/notify.tex | 331 - org.glite.lb.doc/src/producer_api.tex | 201 - org.glite.lb.doc/src/status.tex.T | 19 - org.glite.lb.doc/src/versions.tex | 71 - org.glite.lb.doc/src/web_services.tex | 42 - org.glite.lb.emi-lb/Makefile | 25 - org.glite.lb.emi-lb/configure | 2027 --- org.glite.lb.emi-lb/project/ChangeLog | 6 - org.glite.lb.emi-lb/project/debian.control | 18 - org.glite.lb.emi-lb/project/debian.copyright | 38 - org.glite.lb.emi-lb/project/debian.rules | 57 - org.glite.lb.emi-lb/project/emi-lb.spec | 59 - org.glite.lb.emi-lb/project/package.description | 1 - org.glite.lb.emi-lb/project/package.summary | 1 - org.glite.lb.emi-lb/project/version.properties | 3 - org.glite.lb.glite-LB/Makefile | 23 - org.glite.lb.glite-LB/configure | 1353 -- org.glite.lb.glite-LB/project/ChangeLog | 43 - org.glite.lb.glite-LB/project/package.description | 1 - org.glite.lb.glite-LB/project/package.summary | 1 - org.glite.lb.glite-LB/project/version.properties | 3 - org.glite.lb.harvester/Makefile | 106 - org.glite.lb.harvester/config/startup | 216 - org.glite.lb.harvester/configure | 2058 --- org.glite.lb.harvester/doc/INSTALL | 42 - org.glite.lb.harvester/doc/README | 87 - org.glite.lb.harvester/doc/glite-lb-harvester.sgml | 480 - org.glite.lb.harvester/examples/test.sh | 912 -- org.glite.lb.harvester/examples/test.sql | 55 - org.glite.lb.harvester/project/.post | 4 - org.glite.lb.harvester/project/.postun | 3 - org.glite.lb.harvester/project/.pre | 5 - org.glite.lb.harvester/project/.preun | 4 - org.glite.lb.harvester/project/ChangeLog | 122 - org.glite.lb.harvester/project/debian.control | 25 - org.glite.lb.harvester/project/debian.copyright | 38 - .../project/debian.glite-lb-harvester.dirs | 8 - .../project/debian.glite-lb-harvester.install | 6 - org.glite.lb.harvester/project/debian.preinst | 9 - org.glite.lb.harvester/project/debian.rules | 68 - .../project/glite-lb-harvester.spec | 101 - org.glite.lb.harvester/project/package.description | 1 - org.glite.lb.harvester/project/package.summary | 1 - org.glite.lb.harvester/project/version.properties | 2 - org.glite.lb.harvester/src/harvester.c | 2819 ---- org.glite.lb.logger-msg/LICENSE | 69 - org.glite.lb.logger-msg/Makefile | 133 - org.glite.lb.logger-msg/config/msg.conf.example | 11 - org.glite.lb.logger-msg/config/msg.cron.in | 1 - org.glite.lb.logger-msg/configure | 2058 --- org.glite.lb.logger-msg/examples/cmsclient.cpp | 320 - org.glite.lb.logger-msg/project/ChangeLog | 57 - org.glite.lb.logger-msg/project/debian.control | 25 - org.glite.lb.logger-msg/project/debian.copyright | 38 - .../project/debian.glite-lb-logger-msg.dirs | 5 - .../project/debian.glite-lb-logger-msg.install | 6 - org.glite.lb.logger-msg/project/debian.rules | 70 - .../project/glite-lb-logger-msg.spec | 72 - org.glite.lb.logger-msg/project/il.conf | 5 - .../project/package.description | 1 - org.glite.lb.logger-msg/project/package.summary | 1 - org.glite.lb.logger-msg/project/version.properties | 3 - .../src/activemq_cpp_plugin.cpp | 533 - org.glite.lb.logger-msg/src/msg-brokers | 357 - org.glite.lb.logger-msg/src/msg-config.in | 72 - org.glite.lb.nagios/Makefile | 35 - org.glite.lb.nagios/configure | 2058 --- org.glite.lb.nagios/project/ChangeLog | 21 - org.glite.lb.nagios/project/debian.control | 18 - org.glite.lb.nagios/project/debian.copyright | 38 - .../project/debian.emi-lb-nagios-plugins.dirs | 6 - .../project/debian.emi-lb-nagios-plugins.install | 2 - org.glite.lb.nagios/project/debian.postinst | 4 - org.glite.lb.nagios/project/debian.rules | 64 - .../project/emi-lb-nagios-plugins.spec | 69 - org.glite.lb.nagios/project/package.description | 1 - org.glite.lb.nagios/project/package.summary | 1 - org.glite.lb.nagios/project/version.properties | 3 - org.glite.lb.nagios/src/LB-probe | 420 - org.glite.lb.proxy/.cvsignore | 1 - org.glite.lb.proxy/LICENSE | 69 - org.glite.lb.proxy/Makefile | 142 - org.glite.lb.proxy/build.xml | 126 - .../config/glite-lb-dbsetup-proxy.sql | 112 - org.glite.lb.proxy/config/startup | 77 - org.glite.lb.proxy/doc/README | 68 - org.glite.lb.proxy/doc/README.deploy | 64 - org.glite.lb.proxy/examples/test.sh | 266 - org.glite.lb.proxy/examples/test1.sh | 295 - org.glite.lb.proxy/examples/test2.sh | 298 - org.glite.lb.proxy/examples/test3.sh | 326 - org.glite.lb.proxy/project/build.number | 2 - org.glite.lb.proxy/project/build.properties | 0 .../project/configure.properties.xml | 55 - org.glite.lb.proxy/project/properties.xml | 57 - org.glite.lb.proxy/project/tar_exclude | 10 - org.glite.lb.proxy/project/version.properties | 3 - org.glite.lb.proxy/src/fake_write2rgma.c | 21 - org.glite.lb.proxy/src/lbproxy.c | 652 - org.glite.lb.proxy/src/perftest_proxy.sh | 128 - org.glite.lb.server-bones/.cvsignore | 1 - org.glite.lb.server-bones/Makefile | 81 - org.glite.lb.server-bones/build.xml | 117 - org.glite.lb.server-bones/examples/cnt_example.c | 179 - org.glite.lb.server-bones/examples/srv_example.c | 224 - org.glite.lb.server-bones/interface/srvbones.h | 92 - org.glite.lb.server-bones/project/build.number | 2 - org.glite.lb.server-bones/project/build.properties | 0 .../project/configure.properties.xml | 56 - org.glite.lb.server-bones/project/properties.xml | 62 - org.glite.lb.server-bones/project/tar_exclude | 10 - .../project/version.properties | 3 - org.glite.lb.server-bones/src/srvbones.c | 680 - org.glite.lb.utils/.cvsignore | 2 - org.glite.lb.utils/LICENSE | 69 - org.glite.lb.utils/Makefile | 134 - org.glite.lb.utils/configure | 2058 --- org.glite.lb.utils/doc/README.LB-monitoring | 34 - org.glite.lb.utils/doc/README.LB-statistics | 41 - org.glite.lb.utils/doc/glite-lb-mon.1 | 51 - org.glite.lb.utils/doc/glite-lb-purge.8 | 103 - org.glite.lb.utils/examples/glite-lb-index.conf | 11 - .../examples/glite-lb-statistics-gsi.sh | 55 - .../examples/glite-lb-statistics-rsync.sh | 47 - .../examples/glite-lb-statistics-sftp.sh | 58 - org.glite.lb.utils/examples/glite-lb-statistics.sh | 66 - org.glite.lb.utils/project/ChangeLog | 114 - org.glite.lb.utils/project/debian.control | 25 - org.glite.lb.utils/project/debian.copyright | 38 - .../project/debian.glite-lb-utils.dirs | 4 - .../project/debian.glite-lb-utils.install | 4 - org.glite.lb.utils/project/debian.rules | 68 - org.glite.lb.utils/project/glite-lb-utils.spec | 75 - org.glite.lb.utils/project/package.description | 1 - org.glite.lb.utils/project/package.summary | 1 - org.glite.lb.utils/project/version.properties | 3 - org.glite.lb.utils/src/dump.c | 268 - org.glite.lb.utils/src/dump_exporter.c | 410 - org.glite.lb.utils/src/glite-lb-bkpurge-offline.sh | 190 - org.glite.lb.utils/src/load.c | 224 - org.glite.lb.utils/src/mon.c | 188 - org.glite.lb.utils/src/notif-keeper.sh | 112 - org.glite.lb.utils/src/process_attrs.c | 237 - org.glite.lb.utils/src/process_attrs2.c.T | 102 - org.glite.lb.utils/src/purge.c | 476 - org.glite.lb.utils/src/state_history.c | 98 - org.glite.lb.utils/src/statistics.c | 208 - org.glite.lb.ws-test/Makefile | 100 - org.glite.lb.ws-test/configure | 2058 --- org.glite.lb.ws-test/examples/ws_comlex.pl | 84 - org.glite.lb.ws-test/examples/ws_fault.c | 72 - org.glite.lb.ws-test/examples/ws_fault.h | 23 - org.glite.lb.ws-test/examples/ws_getversion.c | 121 - org.glite.lb.ws-test/examples/ws_getversion.pl | 50 - org.glite.lb.ws-test/examples/ws_joblog.c | 145 - org.glite.lb.ws-test/examples/ws_joblog.pl | 68 - org.glite.lb.ws-test/examples/ws_jobstat.c | 126 - org.glite.lb.ws-test/examples/ws_jobstat.pl | 64 - .../examples/ws_lb4agu_GetActivityInfo.c | 127 - .../examples/ws_lb4agu_GetActivityStatus.c | 127 - .../examples/ws_lb4agu_GetActivityStatus.pl | 60 - org.glite.lb.ws-test/examples/ws_query_ex.c | 231 - .../examples/ws_status_history_test.sh | 101 - org.glite.lb.ws-test/examples/ws_typemap.dat | 7 - org.glite.lb.ws-test/project/ChangeLog | 114 - org.glite.lb.ws-test/project/debian.control | 25 - org.glite.lb.ws-test/project/debian.copyright | 38 - .../project/debian.glite-lb-ws-test.dirs | 2 - .../project/debian.glite-lb-ws-test.install | 1 - org.glite.lb.ws-test/project/debian.rules | 64 - org.glite.lb.ws-test/project/glite-lb-ws-test.spec | 61 - org.glite.lb.ws-test/project/package.description | 1 - org.glite.lb.ws-test/project/package.summary | 1 - org.glite.lb.ws-test/project/version.properties | 3 - org.glite.lb.ws-test/tests/sizeof_soap_test.c | 29 - org.glite.lb.yaim/Makefile | 58 - org.glite.lb.yaim/config/defaults/glite-lb.pre | 68 - org.glite.lb.yaim/config/functions/config_gip_lb | 14 - .../config/functions/config_glite_lb.in | 366 - .../config/functions/config_info_service_lb | 92 - .../config/functions/emi/config_info_service_lb | 99 - org.glite.lb.yaim/config/node-info.d/emi/glite-lb | 9 - org.glite.lb.yaim/config/node-info.d/glite-lb | 14 - org.glite.lb.yaim/configure | 2058 --- org.glite.lb.yaim/project/ChangeLog | 104 - org.glite.lb.yaim/project/debian.control | 17 - org.glite.lb.yaim/project/debian.copyright | 38 - .../project/debian.glite-lb-yaim.dirs | 9 - .../project/debian.glite-lb-yaim.install | 5 - org.glite.lb.yaim/project/debian.rules | 60 - org.glite.lb.yaim/project/glite-lb-yaim.spec | 74 - org.glite.lb.yaim/project/package.description | 1 - org.glite.lb.yaim/project/package.summary | 1 - org.glite.lb.yaim/project/version.properties | 3 - org.glite.lb/.cvsignore | 2 - org.glite.lb/LICENSE | 69 - org.glite.lb/configure | 2062 --- org.glite.lb/deployment/README | 2 - org.glite.lb/deployment/deploy_all.diff | 551 - org.glite.lb/deployment/deploy_jp.diff | 222 - org.glite.lb/deployment/deploy_lb.diff | 281 - org.glite.lb/doc/README.lb4vdt | 16 - org.glite.lb/doc/perf_clear_proxy | 1 - org.glite.lb/doc/perf_purge | 1 - org.glite.lb/doc/perf_reg_jobs | 1 - org.glite.lb/doc/perf_results/il_sci_09062006.txt | 63 - .../doc/perf_results/il_sci_09062006_01.txt | 129 - org.glite.lb/doc/perf_results/il_sci_12062006.txt | 65 - .../doc/perf_results/ll_michal_21062006.txt | 20 - .../perf_results/proxy2serv_umbar2sci_22062006.txt | 20 - .../perf_results/proxy2serv_umbar2sci_23062006.txt | 25 - .../doc/perf_results/proxy_sci_09062006.txt | 21 - org.glite.lb/doc/perf_run_interlogd | 1 - org.glite.lb/doc/perf_run_proxy | 1 - org.glite.lb/doc/perf_run_server | 1 - org.glite.lb/doc/perf_run_test | 1 - org.glite.lb/egee_license_check.sh | 304 - org.glite.lb/etics-tag-branch.pl | 172 - org.glite.lb/etics-tag-consistency.pl | 136 - org.glite.lb/etics-tag-gridsite.pl | 195 - org.glite.lb/etics-tag-with-subsystems-branch.pl | 199 - org.glite.lb/etics-tag-with-subsystems.pl | 375 - org.glite.lb/etics-tag.pl | 416 - org.glite.lb/generate-properties.pl | 148 - org.glite.lb/lb4vdt/LB_install.sh | 129 - org.glite.lb/lb4vdt/Makefile.inc | 77 - .../lb4vdt/scripts/org.gridsite.core.build | 11 - org.glite.lb/project/package.description | 1 - org.glite.lb/project/package.summary | 1 - org.glite.lb/project/version.properties | 3 - org.glite.lbjp-common.db/.cvsignore | 3 - org.glite.lbjp-common.db/LICENSE | 69 - org.glite.lbjp-common.db/Makefile | 185 - org.glite.lbjp-common.db/configure | 2058 --- org.glite.lbjp-common.db/doc/C.dox | 16 - org.glite.lbjp-common.db/examples/db_expire.c | 164 - org.glite.lbjp-common.db/examples/db_test.c | 279 - org.glite.lbjp-common.db/interface/db-int.h | 79 - org.glite.lbjp-common.db/interface/db.h | 448 - org.glite.lbjp-common.db/project/.post | 1 - org.glite.lbjp-common.db/project/.postun | 1 - org.glite.lbjp-common.db/project/ChangeLog | 130 - org.glite.lbjp-common.db/project/debian.control | 34 - org.glite.lbjp-common.db/project/debian.copyright | 38 - .../debian.libglite-lbjp-common-db-dev.dirs | 2 - .../debian.libglite-lbjp-common-db-dev.install | 2 - .../project/debian.libglite-lbu-db3.dirs | 1 - .../project/debian.libglite-lbu-db3.install | 1 - org.glite.lbjp-common.db/project/debian.rules | 67 - .../project/glite-lbjp-common-db.spec | 87 - .../project/package.description | 1 - org.glite.lbjp-common.db/project/package.summary | 1 - .../project/version.properties | 3 - org.glite.lbjp-common.db/src/db-mysql.c | 1022 -- org.glite.lbjp-common.db/src/db-pg.c | 551 - org.glite.lbjp-common.db/src/db.c | 511 - org.glite.lbjp-common.db/test/timezone.cpp | 162 - org.glite.lbjp-common.gsoap-plugin/LICENSE | 69 - org.glite.lbjp-common.gsoap-plugin/Makefile | 384 - org.glite.lbjp-common.gsoap-plugin/configure | 2058 --- .../examples/calc.h.S | 13 - .../examples/wscalc_clt_ex.c | 69 - .../examples/wscalc_srv_ex.c | 127 - .../examples/wscalc_srv_ex2.c | 167 - .../interface/glite_gscompat.h.in | 119 - .../interface/glite_gsplugin-int.h | 45 - .../interface/glite_gsplugin.h | 51 - org.glite.lbjp-common.gsoap-plugin/project/.post | 1 - org.glite.lbjp-common.gsoap-plugin/project/.postun | 1 - .../project/ChangeLog | 117 - .../project/debian.control | 34 - .../project/debian.copyright | 38 - ...bian.libglite-lbjp-common-gsoap-plugin-dev.dirs | 3 - ...n.libglite-lbjp-common-gsoap-plugin-dev.install | 3 - .../debian.libglite-lbjp-common-gsoap-plugin.dirs | 1 - ...ebian.libglite-lbjp-common-gsoap-plugin.install | 1 - .../project/debian.rules | 67 - .../project/glite-lbjp-common-gsoap-plugin.spec | 94 - .../project/gsoap-plugin++.pc.in | 11 - .../project/gsoap-plugin.pc.in | 11 - .../project/libtoolhack/gcc | 1 - .../project/package.description | 1 - .../project/package.summary | 1 - .../project/version.properties | 3 - .../src/glite_gsplugin.c | 594 - .../src/sizeof_soap.c | 26 - .../test/test_gsplugin_cxx.cpp | 63 - org.glite.lbjp-common.jp-interface/Makefile | 115 - org.glite.lbjp-common.jp-interface/configure | 2058 --- .../interface/attr.h | 49 - .../interface/backend.h | 131 - .../interface/builtin_plugins.h | 25 - .../interface/context.h | 43 - .../interface/file_plugin.h | 103 - .../interface/indexdb.h | 76 - .../interface/known_attr.h | 58 - .../interface/type_plugin.h | 91 - .../interface/types.h | 83 - org.glite.lbjp-common.jp-interface/project/.post | 1 - org.glite.lbjp-common.jp-interface/project/.postun | 1 - .../project/ChangeLog | 97 - .../project/debian.control | 34 - .../project/debian.copyright | 38 - .../project/debian.libglite-jp-common2.dirs | 1 - .../project/debian.libglite-jp-common2.install | 1 - ...bian.libglite-lbjp-common-jp-interface-dev.dirs | 2 - ...n.libglite-lbjp-common-jp-interface-dev.install | 2 - .../project/debian.rules | 66 - .../project/glite-lbjp-common-jp-interface.spec | 90 - .../project/package.description | 1 - .../project/package.summary | 1 - .../project/version.properties | 3 - org.glite.lbjp-common.jp-interface/src/attr.c | 308 - org.glite.lbjp-common.jp-interface/src/context.c | 162 - org.glite.lbjp-common.jp-interface/src/indexdb.c | 88 - org.glite.lbjp-common.jp-interface/src/utils.c | 80 - .../test/type_test.cpp | 219 - org.glite.lbjp-common.log/LICENSE | 69 - org.glite.lbjp-common.log/Makefile | 96 - org.glite.lbjp-common.log/README | 18 - org.glite.lbjp-common.log/config/log4crc | 41 - org.glite.lbjp-common.log/config/log4crc.debugging | 38 - org.glite.lbjp-common.log/configure | 2058 --- org.glite.lbjp-common.log/project/.post | 1 - org.glite.lbjp-common.log/project/.postun | 1 - org.glite.lbjp-common.log/project/ChangeLog | 82 - org.glite.lbjp-common.log/project/debian.control | 34 - org.glite.lbjp-common.log/project/debian.copyright | 38 - .../debian.libglite-lbjp-common-log-dev.dirs | 2 - .../debian.libglite-lbjp-common-log-dev.install | 2 - .../project/debian.libglite-lbu-log1.dirs | 3 - .../project/debian.libglite-lbu-log1.install | 3 - org.glite.lbjp-common.log/project/debian.rules | 71 - .../project/glite-lbjp-common-log.spec | 87 - .../project/package.description | 1 - org.glite.lbjp-common.log/project/package.summary | 1 - .../project/version.properties | 3 - org.glite.lbjp-common.log/src/log.c | 146 - org.glite.lbjp-common.log/src/log.h | 122 - org.glite.lbjp-common.log/tests/log4crc | 17 - org.glite.lbjp-common.log/tests/test.c | 32 - org.glite.lbjp-common.maildir/.cvsignore | 1 - org.glite.lbjp-common.maildir/Makefile | 105 - org.glite.lbjp-common.maildir/configure | 2058 --- org.glite.lbjp-common.maildir/interface/maildir.h | 43 - org.glite.lbjp-common.maildir/project/.post | 1 - org.glite.lbjp-common.maildir/project/.postun | 1 - org.glite.lbjp-common.maildir/project/ChangeLog | 89 - .../project/debian.control | 35 - .../project/debian.copyright | 38 - .../debian.libglite-lbjp-common-maildir-dev.dirs | 2 - ...debian.libglite-lbjp-common-maildir-dev.install | 2 - .../project/debian.libglite-lbu-maildir2.dirs | 1 - .../project/debian.libglite-lbu-maildir2.install | 1 - org.glite.lbjp-common.maildir/project/debian.rules | 67 - .../project/glite-lbjp-common-maildir.spec | 79 - .../project/package.description | 1 - .../project/package.summary | 1 - .../project/version.properties | 3 - org.glite.lbjp-common.maildir/src/maildir.c | 417 - org.glite.lbjp-common.server-bones/.cvsignore | 1 - org.glite.lbjp-common.server-bones/Makefile | 100 - org.glite.lbjp-common.server-bones/configure | 2058 --- .../examples/cnt_example.c | 220 - .../examples/run_test.sh | 37 - .../examples/srv_example.c | 218 - .../interface/srvbones.h | 124 - org.glite.lbjp-common.server-bones/project/.post | 1 - org.glite.lbjp-common.server-bones/project/.postun | 1 - .../project/ChangeLog | 97 - .../project/debian.control | 34 - .../project/debian.copyright | 38 - ...bian.libglite-lbjp-common-server-bones-dev.dirs | 2 - ...n.libglite-lbjp-common-server-bones-dev.install | 2 - .../project/debian.libglite-lbu-server-bones2.dirs | 1 - .../debian.libglite-lbu-server-bones2.install | 1 - .../project/debian.rules | 67 - .../project/glite-lbjp-common-server-bones.spec | 80 - .../project/package.description | 1 - .../project/package.summary | 1 - .../project/version.properties | 3 - org.glite.lbjp-common.server-bones/src/srvbones.c | 853 -- org.glite.lbjp-common.trio/.cvsignore | 1 - org.glite.lbjp-common.trio/LICENSE | 69 - org.glite.lbjp-common.trio/Makefile | 124 - org.glite.lbjp-common.trio/configure | 2058 --- org.glite.lbjp-common.trio/interface/escape.h | 86 - org.glite.lbjp-common.trio/interface/trio.h | 187 - org.glite.lbjp-common.trio/project/.post | 1 - org.glite.lbjp-common.trio/project/.postun | 1 - org.glite.lbjp-common.trio/project/ChangeLog | 99 - org.glite.lbjp-common.trio/project/debian.control | 34 - .../project/debian.copyright | 38 - .../debian.libglite-lbjp-common-trio-dev.dirs | 2 - .../debian.libglite-lbjp-common-trio-dev.install | 2 - .../project/debian.libglite-lbu-trio2.dirs | 1 - .../project/debian.libglite-lbu-trio2.install | 1 - org.glite.lbjp-common.trio/project/debian.rules | 67 - .../project/glite-lbjp-common-trio.spec | 83 - .../project/package.description | 1 - org.glite.lbjp-common.trio/project/package.summary | 1 - .../project/version.properties | 3 - org.glite.lbjp-common.trio/src/escape.c | 312 - org.glite.lbjp-common.trio/src/strio.c | 581 - org.glite.lbjp-common.trio/src/strio.h | 227 - org.glite.lbjp-common.trio/src/trio.c | 5709 ------- org.glite.lbjp-common.trio/src/triop.h | 138 - org.glite.lbjp-common.trio/test/trio_test.cpp | 123 - org.glite.lbjp-common/project/version.properties | 3 - org.glite.lbjp-utils.db/.cvsignore | 3 - org.glite.lbjp-utils.db/LICENSE | 69 - org.glite.lbjp-utils.db/Makefile | 137 - org.glite.lbjp-utils.db/examples/db_expire.c | 115 - org.glite.lbjp-utils.db/examples/db_test.c | 196 - org.glite.lbjp-utils.db/interface/db.h | 344 - org.glite.lbjp-utils.db/src/db.c | 1039 -- org.glite.lbjp-utils.jobid/.cvsignore | 2 - org.glite.lbjp-utils.jobid/LICENSE | 69 - org.glite.lbjp-utils.jobid/Makefile | 98 - org.glite.lbjp-utils.jobid/interface/Exception.h | 138 - org.glite.lbjp-utils.jobid/interface/JobId.h | 126 - .../interface/JobIdExceptions.h | 80 - org.glite.lbjp-utils.jobid/interface/cjobid.h | 109 - org.glite.lbjp-utils.jobid/interface/strmd5.h | 30 - org.glite.lbjp-utils.jobid/src/cjobid.c | 260 - org.glite.lbjp-utils.jobid/src/strmd5.c | 122 - org.glite.lbjp-utils.server-bones/.cvsignore | 1 - org.glite.lbjp-utils.server-bones/Makefile | 95 - .../examples/cnt_example.c | 179 - .../examples/srv_example.c | 224 - .../interface/srvbones.h | 92 - org.glite.lbjp-utils.server-bones/src/srvbones.c | 661 - org.glite.lbjp-utils.trio/.cvsignore | 1 - org.glite.lbjp-utils.trio/LICENSE | 69 - org.glite.lbjp-utils.trio/Makefile | 114 - org.glite.lbjp-utils.trio/interface/escape.h | 59 - org.glite.lbjp-utils.trio/interface/trio.h | 187 - org.glite.lbjp-utils.trio/src/escape.c | 224 - org.glite.lbjp-utils.trio/src/strio.c | 581 - org.glite.lbjp-utils.trio/src/strio.h | 227 - org.glite.lbjp-utils.trio/src/trio.c | 5706 ------- org.glite.lbjp-utils.trio/src/triop.h | 138 - org.glite.lbjp-utils.trio/test/trio_test.cpp | 85 - org.glite.myproxy-config/.cvsignore | 1 - org.glite.myproxy-config/Makefile | 35 - org.glite.myproxy-config/myproxy-config.spec | 50 - org.glite.myproxy-config/myproxy-initd | 173 - org.glite.px.emi-px/Makefile | 25 - org.glite.px.emi-px/configure | 2062 --- org.glite.px.emi-px/project/ChangeLog | 6 - org.glite.px.emi-px/project/debian.control | 18 - org.glite.px.emi-px/project/debian.copyright | 38 - org.glite.px.emi-px/project/debian.rules | 57 - org.glite.px.emi-px/project/emi-px.spec | 52 - org.glite.px.emi-px/project/package.description | 1 - org.glite.px.emi-px/project/package.summary | 1 - org.glite.px.emi-px/project/version.properties | 2 - org.glite.px.glite-PX/Makefile | 25 - org.glite.px.glite-PX/configure | 1353 -- org.glite.px.glite-PX/project/ChangeLog | 30 - org.glite.px.glite-PX/project/package.description | 1 - org.glite.px.glite-PX/project/package.summary | 1 - org.glite.px.glite-PX/project/version.properties | 2 - org.glite.px.myproxy-yaim/Makefile | 62 - .../config/defaults/glite-px.pre | 3 - .../config/functions/config_gip_px | 52 - .../config/functions/config_info_service_px | 88 - .../config/functions/config_proxy_server | 137 - .../config/functions/emi/config_info_service_px | 95 - .../config/man/myproxy-yaim.1 | 86 - .../config/node-info.d/emi/glite-px | 38 - .../config/node-info.d/glite-px | 45 - .../config/node-info.d/glite-px_30 | 48 - org.glite.px.myproxy-yaim/config/services/glite-px | 55 - org.glite.px.myproxy-yaim/configure | 2058 --- org.glite.px.myproxy-yaim/project/ChangeLog | 48 - org.glite.px.myproxy-yaim/project/debian.control | 17 - org.glite.px.myproxy-yaim/project/debian.copyright | 38 - .../project/debian.glite-px-myproxy-yaim.dirs | 12 - .../project/debian.glite-px-myproxy-yaim.install | 6 - org.glite.px.myproxy-yaim/project/debian.rules | 60 - .../project/glite-px-myproxy-yaim.spec | 74 - .../project/package.description | 1 - org.glite.px.myproxy-yaim/project/package.summary | 1 - .../project/version.properties | 2 - org.glite.px.proxyrenewal/LICENSE | 15 - org.glite.px.proxyrenewal/Makefile | 213 - org.glite.px.proxyrenewal/README | 43 - org.glite.px.proxyrenewal/config/startup | 130 - org.glite.px.proxyrenewal/configure | 2058 --- org.glite.px.proxyrenewal/examples/renew_core.c | 85 - org.glite.px.proxyrenewal/interface/renewal.h | 181 - org.glite.px.proxyrenewal/interface/renewal_core.h | 93 - org.glite.px.proxyrenewal/project/.post | 6 - org.glite.px.proxyrenewal/project/.postun | 5 - org.glite.px.proxyrenewal/project/.pre | 5 - org.glite.px.proxyrenewal/project/.preun | 4 - org.glite.px.proxyrenewal/project/ChangeLog | 90 - org.glite.px.proxyrenewal/project/debian.control | 50 - org.glite.px.proxyrenewal/project/debian.copyright | 38 - .../debian.glite-px-proxyrenewal-progs.dirs | 4 - .../debian.glite-px-proxyrenewal-progs.install | 3 - .../debian.libglite-security-proxyrenewal-dev.dirs | 4 - ...bian.libglite-security-proxyrenewal-dev.install | 2 - .../debian.libglite-security-proxyrenewal1.dirs | 2 - .../debian.libglite-security-proxyrenewal1.install | 2 - org.glite.px.proxyrenewal/project/debian.preinst | 9 - org.glite.px.proxyrenewal/project/debian.rules | 71 - .../project/doc_proxyrenewal.pl | 1043 -- .../project/glite-px-proxyrenewal.spec | 154 - .../project/package.description | 1 - org.glite.px.proxyrenewal/project/package.summary | 1 - .../project/version.properties | 2 - org.glite.px.proxyrenewal/src/api.c | 569 - org.glite.px.proxyrenewal/src/client.c | 129 - org.glite.px.proxyrenewal/src/commands.c | 1395 -- org.glite.px.proxyrenewal/src/common.c | 334 - org.glite.px.proxyrenewal/src/glite-proxy-renew.1 | 85 - org.glite.px.proxyrenewal/src/glite-proxy-renewd.8 | 133 - org.glite.px.proxyrenewal/src/renew.c | 287 - org.glite.px.proxyrenewal/src/renewal_core.c | 383 - org.glite.px.proxyrenewal/src/renewal_locl.h | 167 - org.glite.px.proxyrenewal/src/renewd.c | 631 - org.glite.px.proxyrenewal/src/renewd_locl.h | 107 - org.glite.px.proxyrenewal/src/voms.c | 498 - org.glite.px/project/version.properties | 2 - org.glite.security.gsoap-plugin/LICENSE | 69 - org.glite.security.gsoap-plugin/Makefile | 338 - org.glite.security.gsoap-plugin/build.xml | 128 - org.glite.security.gsoap-plugin/configure | 975 -- org.glite.security.gsoap-plugin/examples/calc.h.S | 13 - .../examples/wscalc_clt_ex.c | 69 - .../examples/wscalc_srv_ex.c | 128 - .../examples/wscalc_srv_ex2.c | 167 - .../interface/glite_gscompat.h | 111 - .../interface/glite_gsplugin-int.h | 45 - .../interface/glite_gsplugin.h | 51 - org.glite.security.gsoap-plugin/project/ChangeLog | 45 - .../project/build.number | 1 - .../project/build.properties | 0 .../project/configure.properties.xml | 54 - .../project/libtoolhack/gcc | 1 - .../project/package.description | 1 - .../project/package.summary | 1 - .../project/properties.xml | 55 - .../project/tar_exclude | 10 - .../project/version.properties | 3 - .../src/glite_gsplugin.c | 594 - .../src/stdsoap2_2.6.2.c | 11020 -------------- .../src/stdsoap2_2.6.2.h | 1647 -- .../src/stdsoap2_2.7.0.c | 11692 --------------- .../src/stdsoap2_2.7.0.h | 1764 --- .../src/stdsoap2_2.7.0f.c | 12026 --------------- .../src/stdsoap2_2.7.0f.h | 1885 --- .../src/stdsoap2_2.7.10.c | 14890 ------------------- .../src/stdsoap2_2.7.10.h | 2281 --- .../src/stdsoap2_2.7.6b.c | 13101 ---------------- .../src/stdsoap2_2.7.6b.h | 2053 --- .../src/stdsoap2_2.7.6d.c | 13362 ----------------- .../src/stdsoap2_2.7.6d.h | 2075 --- .../src/stdsoap2_2.7.9b.c | 14172 ------------------ .../src/stdsoap2_2.7.9b.h | 2166 --- .../src/stdsoap2_2.7.9d.c | 14414 ------------------ .../src/stdsoap2_2.7.9d.h | 2184 --- .../test/test_gsplugin_cxx.cpp | 63 - org.glite.security.gss/LICENSE | 69 - org.glite.security.gss/Makefile | 170 - org.glite.security.gss/configure | 975 -- org.glite.security.gss/interface/glite_gss.h | 193 - org.glite.security.gss/project/ChangeLog | 39 - org.glite.security.gss/project/package.description | 1 - org.glite.security.gss/project/package.summary | 1 - org.glite.security.gss/project/version.properties | 3 - org.glite.security.gss/src/glite_gss.c | 1578 -- org.glite.security.gss/test/test_gss.cpp | 237 - org.glite.security.proxyrenewal/.cvsignore | 1 - org.glite.security.proxyrenewal/LICENSE | 69 - org.glite.security.proxyrenewal/Makefile | 167 - org.glite.security.proxyrenewal/build.xml | 128 - org.glite.security.proxyrenewal/config/startup | 80 - .../examples/renew_core.c | 63 - .../interface/renewal.h | 175 - .../interface/renewal_core.h | 62 - .../project/build.number | 1 - .../project/build.properties | 0 .../project/configure.properties.xml | 60 - .../project/properties.xml | 62 - .../project/tar_exclude | 10 - .../project/taskdefs.xml | 4 - .../project/version.properties | 2 - org.glite.security.proxyrenewal/src/api.c | 550 - org.glite.security.proxyrenewal/src/client.c | 111 - org.glite.security.proxyrenewal/src/commands.c | 1256 -- org.glite.security.proxyrenewal/src/common.c | 322 - org.glite.security.proxyrenewal/src/renew.c | 256 - org.glite.security.proxyrenewal/src/renewal_core.c | 283 - org.glite.security.proxyrenewal/src/renewal_locl.h | 148 - org.glite.security.proxyrenewal/src/renewd.c | 606 - org.glite.security.proxyrenewal/src/renewd_locl.h | 82 - org.glite.security.proxyrenewal/src/voms.c | 356 - org.glite.testsuites.ctb/CANL-C/tests/Makefile | 36 - .../CANL-C/tests/canl-autonomous-test.sh | 155 - .../CANL-C/tests/canl-common-testbeds.sh | 93 - .../CANL-C/tests/canl-common.sh | 414 - .../CANL-C/tests/canl-generate-fake-proxy.sh | 142 - .../CANL-C/tests/canl-test-cert-handle.sh | 150 - .../CANL-C/tests/canl-test-cs-openssl.sh | 283 - .../CANL-C/tests/canl-test-sec-connection.sh | 209 - .../CANL-C/tests/canl-test-sha2.sh | 193 - .../CANL-C/tests/test-common.sh | 260 - org.glite.testsuites.ctb/LB/LB-certconfig | 10 - org.glite.testsuites.ctb/LB/LB-certtest.sh | 153 - org.glite.testsuites.ctb/LB/Makefile | 14 - org.glite.testsuites.ctb/LB/manual/Readme.txt | 147 - org.glite.testsuites.ctb/LB/manual/Readme2.txt.old | 158 - org.glite.testsuites.ctb/LB/tests/Makefile | 14 - .../LB/tests/lb-autonomous-test.sh | 178 - .../LB/tests/lb-common-testbeds.sh | 372 - org.glite.testsuites.ctb/LB/tests/lb-common.sh | 437 - .../LB/tests/lb-generate-events.sh | 192 - .../LB/tests/lb-generate-fake-proxy.sh | 137 - org.glite.testsuites.ctb/LB/tests/lb-l2.sh | 280 - org.glite.testsuites.ctb/LB/tests/lb-l2ILR.sh | 278 - org.glite.testsuites.ctb/LB/tests/lb-l2Stat.sh | 239 - org.glite.testsuites.ctb/LB/tests/lb-run-tests.sh | 145 - .../LB/tests/lb-test-acl-authz.sh | 270 - org.glite.testsuites.ctb/LB/tests/lb-test-bdii.sh | 221 - .../LB/tests/lb-test-binaries.sh | 48 - .../LB/tests/lb-test-changeacl.sh | 255 - .../LB/tests/lb-test-collections.sh | 153 - org.glite.testsuites.ctb/LB/tests/lb-test-cream.sh | 374 - .../LB/tests/lb-test-event-delivery.sh | 345 - .../LB/tests/lb-test-harvester.sh | 207 - org.glite.testsuites.ctb/LB/tests/lb-test-https.sh | 378 - .../LB/tests/lb-test-il-recovery.sh | 251 - .../LB/tests/lb-test-job-registration.sh | 261 - .../LB/tests/lb-test-job-states.sh | 246 - .../LB/tests/lb-test-logevent.sh | 330 - .../LB/tests/lb-test-logger-local.sh | 151 - .../LB/tests/lb-test-logger-remote.sh | 137 - .../LB/tests/lb-test-nagios-probe.sh | 139 - .../LB/tests/lb-test-notif-keeper.sh | 331 - .../LB/tests/lb-test-notif-msg.sh | 254 - .../LB/tests/lb-test-notif-recovery.sh | 190 - .../LB/tests/lb-test-notif-stream.sh | 211 - .../LB/tests/lb-test-notif-switch.sh | 255 - org.glite.testsuites.ctb/LB/tests/lb-test-notif.sh | 210 - .../LB/tests/lb-test-packaging.sh | 95 - .../LB/tests/lb-test-permissions.sh | 222 - .../LB/tests/lb-test-proxy-delivery.sh | 276 - org.glite.testsuites.ctb/LB/tests/lb-test-purge.pl | 361 - .../LB/tests/lb-test-sandbox-transfer.sh | 766 - .../LB/tests/lb-test-server-local.sh | 190 - .../LB/tests/lb-test-server-remote.sh | 156 - .../LB/tests/lb-test-statistics.sh | 325 - .../LB/tests/lb-test-switch-owner.sh | 205 - .../LB/tests/lb-test-threaded.sh | 178 - org.glite.testsuites.ctb/LB/tests/lb-test-wild.sh | 515 - org.glite.testsuites.ctb/LB/tests/lb-test-ws.sh | 256 - org.glite.testsuites.ctb/LB/tests/test-common.sh | 260 - org.glite.testsuites.ctb/LB/tests/testSocket.c | 73 - .../PX/tests/px-autonomous-test.sh | 199 - .../PX/tests/px-common-testbeds.sh | 137 - org.glite.testsuites.ctb/PX/tests/px-common.sh | 180 - org.glite.testsuites.ctb/PX/tests/px-test-all.sh | 312 - .../PX/tests/px-test-packaging.sh | 105 - .../PX/tests/px-voms-install.sh | 140 - org.glite.testsuites.ctb/PX/tests/test-common.sh | 260 - .../gridsite/tests/gridsite-autonomous-test.sh | 179 - .../gridsite/tests/gridsite-common-testbeds.sh | 172 - .../gridsite/tests/gridsite-common.sh | 180 - .../gridsite/tests/gridsite-test-all.sh | 556 - .../gridsite/tests/gridsite-test-packaging.sh | 105 - .../gridsite/tests/ping-local.sh | 120 - .../gridsite/tests/ping-remote.sh | 117 - .../gridsite/tests/test-common.sh | 260 - org.glite.wms-utils.exception/.cvsignore | 1 - org.glite.wms-utils.exception/LICENSE | 69 - org.glite.wms-utils.exception/Makefile.am | 67 - org.glite.wms-utils.exception/bootstrap | 28 - org.glite.wms-utils.exception/build.xml | 104 - org.glite.wms-utils.exception/configure.ac | 56 - .../interface/Makefile.am | 14 - .../interface/glite/wmsutils/exception/Exception.h | 138 - .../glite/wmsutils/exception/exception_codes.h | 41 - org.glite.wms-utils.exception/project/build.number | 2 - .../project/build.properties | 2 - .../project/configure.properties.xml | 9 - .../project/properties.xml | 83 - .../project/version.properties | 2 - org.glite.wms-utils.exception/src/Exception.cpp | 124 - org.glite.wms-utils.exception/src/Makefile.am | 17 - org.glite.wms-utils.exception/test/Makefile.am | 33 - .../test/exception_cu_main.cpp | 33 - .../test/exception_cu_suite.cpp | 56 - .../test/exception_cu_suite.h | 29 - org.glite.wms-utils.jobid/.cvsignore | 2 - org.glite.wms-utils.jobid/LICENSE | 69 - org.glite.wms-utils.jobid/Makefile.am | 69 - org.glite.wms-utils.jobid/bootstrap | 9 - org.glite.wms-utils.jobid/build.xml | 104 - org.glite.wms-utils.jobid/configure.ac | 147 - org.glite.wms-utils.jobid/examples/Makefile.am | 28 - org.glite.wms-utils.jobid/examples/testjobid.c | 33 - org.glite.wms-utils.jobid/interface/Makefile.am | 16 - .../interface/glite/wmsutils/jobid/JobId.h | 126 - .../glite/wmsutils/jobid/JobIdExceptions.h | 80 - .../interface/glite/wmsutils/jobid/cjobid.h | 109 - .../interface/glite/wmsutils/jobid/manipulation.h | 24 - org.glite.wms-utils.jobid/project/build.number | 2 - org.glite.wms-utils.jobid/project/build.properties | 2 - .../project/configure.properties.xml | 9 - org.glite.wms-utils.jobid/project/properties.xml | 86 - .../project/version.properties | 2 - org.glite.wms-utils.jobid/src/Makefile.am | 12 - org.glite.wms-utils.jobid/src/jobid/JobId.cpp | 183 - .../src/jobid/JobIdExceptions.cpp | 58 - org.glite.wms-utils.jobid/src/jobid/Makefile.am | 30 - org.glite.wms-utils.jobid/src/jobid/cjobid.c | 258 - .../src/jobid/manipulation.cpp | 180 - org.glite.wms-utils.jobid/src/jobid/strmd5.c | 118 - org.glite.wms-utils.jobid/src/jobid/strmd5.h | 28 - org.glite.wms-utils.jobid/test/Makefile.am | 48 - org.glite.wms-utils.jobid/test/jobid_cu_main.cpp | 33 - org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp | 102 - org.glite.wms-utils.jobid/test/jobid_cu_suite.h | 34 - .../test/manipulation_cu_main.cpp | 33 - .../test/manipulation_cu_suite.cpp | 34 - .../test/manipulation_cu_suite.h | 29 - org.glite.yaim.lb/.cvsignore | 1 - org.glite.yaim.lb/LICENSE | 69 - org.glite.yaim.lb/Makefile | 46 - org.glite.yaim.lb/config/defaults/glite-lb.pre | 3 - org.glite.yaim.lb/config/defaults/glite-lb_30.pre | 3 - org.glite.yaim.lb/config/functions/config_gip_lb | 14 - .../config/functions/config_gip_lb_30 | 44 - org.glite.yaim.lb/config/functions/config_glite_lb | 253 - .../config/functions/config_glite_lb_30 | 141 - .../config/functions/config_info_service_lb | 92 - org.glite.yaim.lb/config/functions/config_jobmon | 87 - org.glite.yaim.lb/config/node-info.d/glite-lb | 14 - org.glite.yaim.lb/config/node-info.d/glite-lb_30 | 15 - org.glite.yaim.lb/glite-yaim-lb.spec | 39 - org.glite.yaim.myproxy/.cvsignore | 1 - org.glite.yaim.myproxy/Changelog | 38 - org.glite.yaim.myproxy/LICENSE | 69 - org.glite.yaim.myproxy/Makefile | 47 - .../config/functions/config_gip_px | 52 - .../config/functions/config_info_service_px | 88 - .../config/functions/config_proxy_server | 132 - org.glite.yaim.myproxy/config/man/yaim-myproxy.1 | 86 - org.glite.yaim.myproxy/config/node-info.d/glite-px | 45 - .../config/node-info.d/glite-px_30 | 48 - org.glite.yaim.myproxy/config/services/glite-px | 55 - org.glite.yaim.myproxy/glite-yaim-myproxy.spec | 41 - org.gridsite.core/.cvsignore | 1 - org.gridsite.core/CHANGES | 534 - org.gridsite.core/INSTALL | 37 - org.gridsite.core/LICENSE | 47 - org.gridsite.core/README | 6 - org.gridsite.core/VERSION | 5 - org.gridsite.core/build.xml | 294 - org.gridsite.core/doc/README.htcp-bin | 13 - org.gridsite.core/doc/build-apache2.sh | 79 - org.gridsite.core/doc/delegation-1.1.0.wsdl | 459 - org.gridsite.core/doc/doc_gridsite.pl | 1064 -- org.gridsite.core/doc/findproxyfile.1 | 63 - org.gridsite.core/doc/fuse.spec | 139 - org.gridsite.core/doc/gridsite-delegation.8 | 19 - org.gridsite.core/doc/gsexec.8 | 134 - org.gridsite.core/doc/gsoap-devel.spec | 52 - org.gridsite.core/doc/htcp.1 | 200 - org.gridsite.core/doc/htfind.1 | 1 - org.gridsite.core/doc/htll.1 | 1 - org.gridsite.core/doc/htls.1 | 1 - org.gridsite.core/doc/htmkdir.1 | 1 - org.gridsite.core/doc/htmv.1 | 1 - org.gridsite.core/doc/htping.1 | 1 - org.gridsite.core/doc/htproxydestroy.1 | 1 - org.gridsite.core/doc/htproxyinfo.1 | 1 - org.gridsite.core/doc/htproxyput.1 | 121 - org.gridsite.core/doc/htproxyrenew.1 | 1 - org.gridsite.core/doc/htproxytime.1 | 1 - org.gridsite.core/doc/htproxyunixtime.1 | 1 - org.gridsite.core/doc/htrm.1 | 1 - org.gridsite.core/doc/httpd-fileserver.conf | 155 - org.gridsite.core/doc/httpd-storage.conf | 220 - org.gridsite.core/doc/httpd-webserver.conf | 231 - org.gridsite.core/doc/index.html | 82 - org.gridsite.core/doc/mod_gridsite.8 | 356 - org.gridsite.core/doc/slashgrid.8 | 101 - org.gridsite.core/doc/urlencode.1 | 43 - org.gridsite.core/interface/gridsite-gacl.h | 196 - org.gridsite.core/interface/gridsite.h | 465 - org.gridsite.core/project/build.number | 2 - org.gridsite.core/project/build.properties | 0 org.gridsite.core/project/compat-1.5.patch | 85 - org.gridsite.core/project/configure.properties.xml | 9 - org.gridsite.core/project/debian.changelog | 6 - org.gridsite.core/project/debian.control | 86 - org.gridsite.core/project/debian.rules | 10 - org.gridsite.core/project/dependencies.properties | 9 - org.gridsite.core/project/gridsite.core.csf.xml | 221 - org.gridsite.core/project/properties.xml | 53 - org.gridsite.core/project/taskdefs.xml | 31 - org.gridsite.core/project/version.properties | 2 - org.gridsite.core/src/Doxyfile | 993 -- org.gridsite.core/src/Makefile | 626 - org.gridsite.core/src/delegation.h | 86 - org.gridsite.core/src/doxygen.css | 49 - org.gridsite.core/src/doxyheader.html | 1 - org.gridsite.core/src/findproxyfile.c | 122 - org.gridsite.core/src/gaclexample.c | 145 - org.gridsite.core/src/gridsite-copy.c | 168 - org.gridsite.core/src/gridsite-globus.pc.in | 11 - org.gridsite.core/src/gridsite-openssl.pc.in | 11 - org.gridsite.core/src/gridsite-storage.c | 269 - org.gridsite.core/src/grst-delegation.c | 337 - org.gridsite.core/src/grst_admin.h | 62 - org.gridsite.core/src/grst_admin_file.c | 1768 --- org.gridsite.core/src/grst_admin_gacl.c | 1034 -- org.gridsite.core/src/grst_admin_main.c | 391 - org.gridsite.core/src/grst_asn1.c | 565 - org.gridsite.core/src/grst_err.c | 40 - org.gridsite.core/src/grst_gacl.c | 1394 -- org.gridsite.core/src/grst_htcp.c | 311 - org.gridsite.core/src/grst_http.c | 475 - org.gridsite.core/src/grst_x509.c | 2648 ---- org.gridsite.core/src/grst_xacml.c | 566 - org.gridsite.core/src/gsexec.c | 1104 -- org.gridsite.core/src/gsexec.h | 126 - org.gridsite.core/src/htcp.c | 2069 --- org.gridsite.core/src/htproxyput.c | 684 - org.gridsite.core/src/make-debian-files | 147 - org.gridsite.core/src/make-gridsite-spec | 338 - org.gridsite.core/src/mod_gridsite.c | 4573 ------ org.gridsite.core/src/mod_gridsite_example.c | 262 - org.gridsite.core/src/mod_ssl-private.h | 211 - org.gridsite.core/src/roffit | 370 - org.gridsite.core/src/showx509exts.c | 134 - org.gridsite.core/src/slashgrid.c | 2734 ---- org.gridsite.core/src/slashgrid.init | 72 - org.gridsite.core/src/urlencode.c | 73 - org.gridsite.core/src/xacmlexample.c | 148 - 1511 files changed, 405461 deletions(-) delete mode 100644 emi.canl.canl-c/Makefile delete mode 100755 emi.canl.canl-c/configure delete mode 100644 emi.canl.canl-c/doc/src/canl-abstract.tex delete mode 100644 emi.canl.canl-c/doc/src/canl-cs-auth-connection.tex delete mode 100644 emi.canl.canl-c/doc/src/canl-introduction.tex delete mode 100644 emi.canl.canl-c/doc/src/canl-proxy-cert.tex delete mode 100644 emi.canl.canl-c/doc/src/canl.tex delete mode 100644 emi.canl.canl-c/doc/src/copyright.tex delete mode 100644 emi.canl.canl-c/doc/src/definitions.tex delete mode 100644 emi.canl.canl-c/doc/src/emi.cls delete mode 100644 emi.canl.canl-c/doc/src/funding.tex delete mode 100644 emi.canl.canl-c/doc/src/images/EMI_Logo_std.pdf delete mode 100644 emi.canl.canl-c/doc/src/images/cesnet.pdf delete mode 100644 emi.canl.canl-c/examples/canl_sample_client.c delete mode 100644 emi.canl.canl-c/examples/canl_sample_server.c delete mode 100644 emi.canl.canl-c/examples/delegation.c delete mode 100644 emi.canl.canl-c/examples/grid-proxy-init.c delete mode 100644 emi.canl.canl-c/project/ChangeLog delete mode 100644 emi.canl.canl-c/project/canl-c.spec delete mode 100644 emi.canl.canl-c/project/debian.control delete mode 100644 emi.canl.canl-c/project/debian.copyright delete mode 100644 emi.canl.canl-c/project/debian.libcanl-c-dev.dirs delete mode 100644 emi.canl.canl-c/project/debian.libcanl-c-dev.install delete mode 100644 emi.canl.canl-c/project/debian.libcanl-c-examples.dirs delete mode 100644 emi.canl.canl-c/project/debian.libcanl-c-examples.install delete mode 100644 emi.canl.canl-c/project/debian.libcanl-c1.dirs delete mode 100644 emi.canl.canl-c/project/debian.libcanl-c1.install delete mode 100644 emi.canl.canl-c/project/debian.rules delete mode 100644 emi.canl.canl-c/project/package.description delete mode 100644 emi.canl.canl-c/project/package.summary delete mode 100644 emi.canl.canl-c/project/version.properties delete mode 100644 emi.canl.canl-c/src/canl.c delete mode 100644 emi.canl.canl-c/src/canl.h delete mode 100644 emi.canl.canl-c/src/canl_cert.c delete mode 100644 emi.canl.canl-c/src/canl_cred.c delete mode 100644 emi.canl.canl-c/src/canl_cred.h delete mode 100644 emi.canl.canl-c/src/canl_dns.c delete mode 100644 emi.canl.canl-c/src/canl_err.c delete mode 100644 emi.canl.canl-c/src/canl_error_codes delete mode 100644 emi.canl.canl-c/src/canl_error_desc delete mode 100644 emi.canl.canl-c/src/canl_locl.h delete mode 100644 emi.canl.canl-c/src/canl_mech_ssl.h delete mode 100644 emi.canl.canl-c/src/canl_ssl.c delete mode 100644 emi.canl.canl-c/src/canl_ssl.h delete mode 100755 emi.canl.canl-c/src/gen_err_codes.pl delete mode 100755 emi.canl.canl-c/src/gen_err_desc.pl delete mode 100644 emi.canl.canl-c/src/proxy/config.h delete mode 100644 emi.canl.canl-c/src/proxy/data.c delete mode 100644 emi.canl.canl-c/src/proxy/doio.c delete mode 100644 emi.canl.canl-c/src/proxy/doio.h delete mode 100644 emi.canl.canl-c/src/proxy/evaluate.c delete mode 100644 emi.canl.canl-c/src/proxy/list.c delete mode 100644 emi.canl.canl-c/src/proxy/listfunc.h delete mode 100644 emi.canl.canl-c/src/proxy/myproxycertinfo.h delete mode 100644 emi.canl.canl-c/src/proxy/namespaces_lex.c.in delete mode 100644 emi.canl.canl-c/src/proxy/namespaces_lex.l delete mode 100644 emi.canl.canl-c/src/proxy/namespaces_parse.y delete mode 100644 emi.canl.canl-c/src/proxy/normalize.c delete mode 100644 emi.canl.canl-c/src/proxy/normalize.h delete mode 100644 emi.canl.canl-c/src/proxy/parsertypes.h delete mode 100644 emi.canl.canl-c/src/proxy/proxy.c delete mode 100644 emi.canl.canl-c/src/proxy/proxycertinfo.c delete mode 100644 emi.canl.canl-c/src/proxy/scutils.c delete mode 100644 emi.canl.canl-c/src/proxy/scutils.h delete mode 100644 emi.canl.canl-c/src/proxy/signing_policy_lex.c.in delete mode 100644 emi.canl.canl-c/src/proxy/signing_policy_lex.l delete mode 100644 emi.canl.canl-c/src/proxy/signing_policy_parse.y delete mode 100644 emi.canl.canl-c/src/proxy/sslutils.c delete mode 100644 emi.canl.canl-c/src/proxy/sslutils.h delete mode 100644 emi.canl.canl-c/src/proxy/vomsproxy.h delete mode 100644 org.glite.deployment.jpis/build.xml delete mode 100755 org.glite.deployment.jpis/config/scripts/glite-jpis-config.py delete mode 100644 org.glite.deployment.jpis/config/templates/glite-jpis.cfg.xml delete mode 100644 org.glite.deployment.jpis/project/build.number delete mode 100644 org.glite.deployment.jpis/project/build.properties delete mode 100644 org.glite.deployment.jpis/project/glite-jp.sdf.xml.template delete mode 100644 org.glite.deployment.jpis/project/glite-jpis.sdf.xml.template delete mode 100644 org.glite.deployment.jpis/project/lxscript-rpm.xsl delete mode 100644 org.glite.deployment.jpis/project/lxscript-tgz.xsl delete mode 100644 org.glite.deployment.jpis/project/properties.xml delete mode 100644 org.glite.deployment.jpis/project/quattor-template.xsl delete mode 100644 org.glite.deployment.jpis/project/version.properties delete mode 100644 org.glite.deployment.jpps/build.xml delete mode 100755 org.glite.deployment.jpps/config/scripts/glite-jpps-config.py delete mode 100644 org.glite.deployment.jpps/config/templates/glite-jpps.cfg.xml delete mode 100644 org.glite.deployment.jpps/project/build.number delete mode 100644 org.glite.deployment.jpps/project/build.properties delete mode 100644 org.glite.deployment.jpps/project/glite-jpps.sdf.xml.template delete mode 100644 org.glite.deployment.jpps/project/lxscript-rpm.xsl delete mode 100644 org.glite.deployment.jpps/project/lxscript-tgz.xsl delete mode 100644 org.glite.deployment.jpps/project/properties.xml delete mode 100644 org.glite.deployment.jpps/project/quattor-template.xsl delete mode 100644 org.glite.deployment.jpps/project/version.properties delete mode 100644 org.glite.deployment.lb/.cvsignore delete mode 100644 org.glite.deployment.lb/CHANGELOG delete mode 100644 org.glite.deployment.lb/LICENSE delete mode 100644 org.glite.deployment.lb/build.xml delete mode 100644 org.glite.deployment.lb/config/scripts/glite-lb-config.py delete mode 100644 org.glite.deployment.lb/config/templates/glite-lb.cfg.xml delete mode 100644 org.glite.deployment.lb/doc/release_notes/release_notes.doc delete mode 100644 org.glite.deployment.lb/doc/release_notes/release_notes.html delete mode 100644 org.glite.deployment.lb/doc/release_notes/release_notes.pdf delete mode 100644 org.glite.deployment.lb/project/.cvsignore delete mode 100644 org.glite.deployment.lb/project/build.number delete mode 100644 org.glite.deployment.lb/project/build.properties delete mode 100644 org.glite.deployment.lb/project/glite-lb.sdf.xml.template delete mode 100644 org.glite.deployment.lb/project/lxscript-rpm.xsl delete mode 100644 org.glite.deployment.lb/project/lxscript-tgz.xsl delete mode 100644 org.glite.deployment.lb/project/properties.xml delete mode 100644 org.glite.deployment.lb/project/quattor-template.xsl delete mode 100644 org.glite.deployment.lb/project/version.properties delete mode 100644 org.glite.jobid.api-c/Makefile delete mode 100755 org.glite.jobid.api-c/configure delete mode 100755 org.glite.jobid.api-c/interface/cjobid.h delete mode 100755 org.glite.jobid.api-c/interface/strmd5.h delete mode 100644 org.glite.jobid.api-c/project/.post delete mode 100644 org.glite.jobid.api-c/project/.postun delete mode 100644 org.glite.jobid.api-c/project/ChangeLog delete mode 100644 org.glite.jobid.api-c/project/debian.control delete mode 100644 org.glite.jobid.api-c/project/debian.copyright delete mode 100644 org.glite.jobid.api-c/project/debian.libglite-jobid-api-c-dev.dirs delete mode 100644 org.glite.jobid.api-c/project/debian.libglite-jobid-api-c-dev.install delete mode 100644 org.glite.jobid.api-c/project/debian.libglite-jobid2.dirs delete mode 100644 org.glite.jobid.api-c/project/debian.libglite-jobid2.install delete mode 100644 org.glite.jobid.api-c/project/debian.rules delete mode 100644 org.glite.jobid.api-c/project/glite-jobid-api-c.spec delete mode 100644 org.glite.jobid.api-c/project/package.description delete mode 100644 org.glite.jobid.api-c/project/package.summary delete mode 100644 org.glite.jobid.api-c/project/version.properties delete mode 100644 org.glite.jobid.api-c/src/cjobid.c delete mode 100644 org.glite.jobid.api-c/src/md32_common.h delete mode 100644 org.glite.jobid.api-c/src/md5.h delete mode 100644 org.glite.jobid.api-c/src/md5_dgst.c delete mode 100644 org.glite.jobid.api-c/src/md5_locl.h delete mode 100755 org.glite.jobid.api-c/src/strmd5.c delete mode 100644 org.glite.jobid.api-c/test/base64_test.cpp delete mode 100644 org.glite.jobid.api-cpp/Makefile delete mode 100755 org.glite.jobid.api-cpp/configure delete mode 100755 org.glite.jobid.api-cpp/interface/JobId.h delete mode 100644 org.glite.jobid.api-cpp/project/ChangeLog delete mode 100644 org.glite.jobid.api-cpp/project/debian.control delete mode 100644 org.glite.jobid.api-cpp/project/debian.copyright delete mode 100644 org.glite.jobid.api-cpp/project/debian.libglite-jobid-api-cpp-dev.dirs delete mode 100644 org.glite.jobid.api-cpp/project/debian.libglite-jobid-api-cpp-dev.install delete mode 100644 org.glite.jobid.api-cpp/project/debian.rules delete mode 100644 org.glite.jobid.api-cpp/project/glite-jobid-api-cpp.spec delete mode 100644 org.glite.jobid.api-cpp/project/package.description delete mode 100644 org.glite.jobid.api-cpp/project/package.summary delete mode 100644 org.glite.jobid.api-cpp/project/version.properties delete mode 100644 org.glite.jobid.api-java/Makefile delete mode 100755 org.glite.jobid.api-java/build.xml delete mode 100755 org.glite.jobid.api-java/configure delete mode 100755 org.glite.jobid.api-java/nbproject/build-impl.xml delete mode 100755 org.glite.jobid.api-java/nbproject/genfiles.properties delete mode 100644 org.glite.jobid.api-java/nbproject/private/config.properties delete mode 100755 org.glite.jobid.api-java/nbproject/private/private.properties delete mode 100644 org.glite.jobid.api-java/nbproject/private/private.xml delete mode 100755 org.glite.jobid.api-java/nbproject/project.properties delete mode 100755 org.glite.jobid.api-java/nbproject/project.xml delete mode 100644 org.glite.jobid.api-java/project/ChangeLog delete mode 100644 org.glite.jobid.api-java/project/debian.control delete mode 100644 org.glite.jobid.api-java/project/debian.copyright delete mode 100644 org.glite.jobid.api-java/project/debian.glite-jobid-api-java.dirs delete mode 100644 org.glite.jobid.api-java/project/debian.glite-jobid-api-java.install delete mode 100644 org.glite.jobid.api-java/project/debian.rules delete mode 100644 org.glite.jobid.api-java/project/glite-jobid-api-java.spec delete mode 100644 org.glite.jobid.api-java/project/package.description delete mode 100644 org.glite.jobid.api-java/project/package.summary delete mode 100644 org.glite.jobid.api-java/project/version.properties delete mode 100644 org.glite.jobid.api-java/src/org/glite/jobid/ExampleJobid.java delete mode 100644 org.glite.jobid.api-java/src/org/glite/jobid/Jobid.java delete mode 100644 org.glite.jobid/project/version.properties delete mode 100644 org.glite.jp.client/.cvsignore delete mode 100644 org.glite.jp.client/Makefile delete mode 100755 org.glite.jp.client/build.xml delete mode 100755 org.glite.jp.client/config/startup delete mode 100755 org.glite.jp.client/configure delete mode 100644 org.glite.jp.client/doc/README.jpimporter delete mode 100644 org.glite.jp.client/examples/glite-jp-importer.sh delete mode 100644 org.glite.jp.client/examples/jpps_upload_files.c delete mode 100644 org.glite.jp.client/examples/mill_feed.c delete mode 100644 org.glite.jp.client/interface/jp_client.h delete mode 100644 org.glite.jp.client/interface/jpcl_ctx_int.h delete mode 100644 org.glite.jp.client/interface/jpimporter.h delete mode 100644 org.glite.jp.client/project/ChangeLog delete mode 100644 org.glite.jp.client/project/build.number delete mode 100644 org.glite.jp.client/project/build.properties delete mode 100644 org.glite.jp.client/project/configure.properties.xml delete mode 100755 org.glite.jp.client/project/properties.xml delete mode 100644 org.glite.jp.client/project/tar_exclude delete mode 100644 org.glite.jp.client/project/version.properties delete mode 100644 org.glite.jp.client/src/jpcl_ctx.c delete mode 100644 org.glite.jp.client/src/jpimp_lib.c delete mode 100644 org.glite.jp.client/src/jpimporter.c delete mode 100644 org.glite.jp.client/src/jptype_map.h delete mode 100644 org.glite.jp.client/src/typemap.dat delete mode 100644 org.glite.jp.common/.cvsignore delete mode 100644 org.glite.jp.common/Makefile delete mode 100755 org.glite.jp.common/build.xml delete mode 100644 org.glite.jp.common/interface/attr.h delete mode 100644 org.glite.jp.common/interface/backend.h delete mode 100644 org.glite.jp.common/interface/builtin_plugins.h delete mode 100644 org.glite.jp.common/interface/context.h delete mode 100644 org.glite.jp.common/interface/file_plugin.h delete mode 100644 org.glite.jp.common/interface/indexdb.h delete mode 100644 org.glite.jp.common/interface/known_attr.h delete mode 100644 org.glite.jp.common/interface/type_plugin.h delete mode 100644 org.glite.jp.common/interface/types.h delete mode 100644 org.glite.jp.common/project/build.number delete mode 100644 org.glite.jp.common/project/build.properties delete mode 100644 org.glite.jp.common/project/configure.properties.xml delete mode 100755 org.glite.jp.common/project/properties.xml delete mode 100644 org.glite.jp.common/project/tar_exclude delete mode 100644 org.glite.jp.common/project/version.properties delete mode 100644 org.glite.jp.common/src/attr.c delete mode 100644 org.glite.jp.common/src/context.c delete mode 100644 org.glite.jp.common/src/indexdb.c delete mode 100644 org.glite.jp.common/src/utils.c delete mode 100644 org.glite.jp.common/test/type_test.cpp delete mode 100644 org.glite.jp.doc/LICENSE delete mode 100644 org.glite.jp.doc/Makefile delete mode 100755 org.glite.jp.doc/configure delete mode 100644 org.glite.jp.doc/project/ChangeLog delete mode 100644 org.glite.jp.doc/project/version.properties delete mode 100644 org.glite.jp.doc/src/JPAG-Configuration.tex delete mode 100644 org.glite.jp.doc/src/JPAG-Installation.tex delete mode 100644 org.glite.jp.doc/src/JPAG-Introduction.tex delete mode 100644 org.glite.jp.doc/src/JPAG-Running.tex delete mode 100644 org.glite.jp.doc/src/JPAG-Testing.tex delete mode 100644 org.glite.jp.doc/src/JPAG-Troubleshooting.tex delete mode 100644 org.glite.jp.doc/src/JPAG.tex delete mode 100644 org.glite.jp.doc/src/JPDG-Introduction.tex delete mode 100644 org.glite.jp.doc/src/JPDG-WS.tex delete mode 100644 org.glite.jp.doc/src/JPDG.tex delete mode 100644 org.glite.jp.doc/src/JPUG-Introduction.tex delete mode 100644 org.glite.jp.doc/src/JPUG-Tools.tex delete mode 100644 org.glite.jp.doc/src/JPUG-UseCases.tex delete mode 100644 org.glite.jp.doc/src/JPUG.tex delete mode 100644 org.glite.jp.doc/src/LB-JP-interaction.tex delete mode 100644 org.glite.jp.doc/src/README delete mode 100644 org.glite.jp.doc/src/copyright.tex delete mode 100644 org.glite.jp.doc/src/definitions.tex delete mode 100644 org.glite.jp.doc/src/egee.cls delete mode 100644 org.glite.jp.doc/src/frontmatter.tex delete mode 100644 org.glite.jp.doc/src/glite-jpis-client.tex delete mode 100644 org.glite.jp.doc/src/glite_installation_guide_JP.doc delete mode 100644 org.glite.jp.doc/src/glite_installation_guide_LB.doc delete mode 100644 org.glite.jp.doc/src/gui.tex delete mode 100644 org.glite.jp.doc/src/images/JP-interactions.cdr delete mode 100644 org.glite.jp.doc/src/images/JP-interactions.pdf delete mode 100644 org.glite.jp.doc/src/images/JP-query.cdr delete mode 100644 org.glite.jp.doc/src/images/JP-query.pdf delete mode 100644 org.glite.jp.doc/src/images/LB-JP-interaction-details.cdr delete mode 100644 org.glite.jp.doc/src/images/LB-JP-interaction-details.pdf delete mode 100644 org.glite.jp.doc/src/images/LB-JP-interaction-drawing.pdf delete mode 100644 org.glite.jp.doc/src/images/egee.pdf delete mode 100644 org.glite.jp.doc/src/images/isi.pdf delete mode 100644 org.glite.jp.doc/src/jpimporter.tex delete mode 100644 org.glite.jp.doc/src/jpws.tex delete mode 100644 org.glite.jp.doc/src/lbjp.bib delete mode 100644 org.glite.jp.index/.cvsignore delete mode 100644 org.glite.jp.index/Makefile delete mode 100755 org.glite.jp.index/build.xml delete mode 100755 org.glite.jp.index/config/dbsetup.sh delete mode 100644 org.glite.jp.index/config/defaults/glite-jpis.pre delete mode 100644 org.glite.jp.index/config/functions/config_glite_jpis delete mode 100644 org.glite.jp.index/config/glite-jp-index-dbsetup.sql delete mode 100644 org.glite.jp.index/config/glite-jpis-config.xml delete mode 100644 org.glite.jp.index/config/glite-jpis-test-config.xml delete mode 100644 org.glite.jp.index/config/node-info.d/glite-jpis delete mode 100644 org.glite.jp.index/config/site-info.def.example delete mode 100755 org.glite.jp.index/config/startup delete mode 100755 org.glite.jp.index/configure delete mode 100644 org.glite.jp.index/doc/README delete mode 100644 org.glite.jp.index/doc/client_conf.xsd delete mode 100644 org.glite.jp.index/doc/glite-jp-indexd.sgml delete mode 100644 org.glite.jp.index/doc/glite-jpis-client.sgml delete mode 100644 org.glite.jp.index/doc/server_conf.xsd delete mode 100644 org.glite.jp.index/examples/jpis-client.c delete mode 100644 org.glite.jp.index/examples/jpis-db-internal.c delete mode 100644 org.glite.jp.index/examples/jpis-test.c delete mode 100644 org.glite.jp.index/examples/pch06/pch.pm delete mode 100644 org.glite.jp.index/examples/pch06/query1.pl delete mode 100644 org.glite.jp.index/examples/pch06/query2.pl delete mode 100644 org.glite.jp.index/examples/pch06/query3.pl delete mode 100644 org.glite.jp.index/examples/pch06/query4.pl delete mode 100644 org.glite.jp.index/examples/pch06/query5.pl delete mode 100644 org.glite.jp.index/examples/pch06/query6.pl delete mode 100644 org.glite.jp.index/examples/query-tests/authz.out delete mode 100644 org.glite.jp.index/examples/query-tests/complex_query.in delete mode 100644 org.glite.jp.index/examples/query-tests/complex_query.out delete mode 100644 org.glite.jp.index/examples/query-tests/dump1.sql delete mode 100644 org.glite.jp.index/examples/query-tests/exists_query.in delete mode 100644 org.glite.jp.index/examples/query-tests/exists_query.out delete mode 100644 org.glite.jp.index/examples/query-tests/jobid_query.in delete mode 100644 org.glite.jp.index/examples/query-tests/jobid_query.out delete mode 100644 org.glite.jp.index/examples/query-tests/origin_query.in delete mode 100644 org.glite.jp.index/examples/query-tests/origin_query.out delete mode 100755 org.glite.jp.index/examples/query-tests/run-test.sh delete mode 100644 org.glite.jp.index/examples/query-tests/simple_query.in delete mode 100644 org.glite.jp.index/examples/query-tests/simple_query.out delete mode 100644 org.glite.jp.index/examples/query-tests/within_query.in delete mode 100644 org.glite.jp.index/examples/query-tests/within_query.out delete mode 100644 org.glite.jp.index/interface/JobProvenanceISClient.xsd delete mode 100644 org.glite.jp.index/project/ChangeLog delete mode 100644 org.glite.jp.index/project/build.number delete mode 100644 org.glite.jp.index/project/build.properties delete mode 100644 org.glite.jp.index/project/configure.properties.xml delete mode 100755 org.glite.jp.index/project/properties.xml delete mode 100644 org.glite.jp.index/project/tar_exclude delete mode 100644 org.glite.jp.index/project/version.properties delete mode 100644 org.glite.jp.index/src/bones_server.c delete mode 100644 org.glite.jp.index/src/common.c delete mode 100644 org.glite.jp.index/src/common.h delete mode 100644 org.glite.jp.index/src/conf.c delete mode 100644 org.glite.jp.index/src/conf.h delete mode 100644 org.glite.jp.index/src/context.c delete mode 100644 org.glite.jp.index/src/context.h delete mode 100644 org.glite.jp.index/src/db_ops.c delete mode 100644 org.glite.jp.index/src/db_ops.h delete mode 100644 org.glite.jp.index/src/simple_server.c delete mode 100644 org.glite.jp.index/src/soap_ops.c delete mode 100644 org.glite.jp.index/src/soap_ps_calls.c delete mode 100644 org.glite.jp.index/src/soap_ps_calls.h delete mode 100644 org.glite.jp.index/src/type_plugin.c delete mode 100644 org.glite.jp.index/src/typemap.dat delete mode 100644 org.glite.jp.index/src/ws_is_typeref.c delete mode 100644 org.glite.jp.index/src/ws_is_typeref.h delete mode 100644 org.glite.jp.index/src/ws_ps_typeref.c delete mode 100644 org.glite.jp.index/src/ws_ps_typeref.h delete mode 100644 org.glite.jp.index/src/ws_typemap.h delete mode 100644 org.glite.jp.primary/.cvsignore delete mode 100644 org.glite.jp.primary/Makefile delete mode 100755 org.glite.jp.primary/build.xml delete mode 100644 org.glite.jp.primary/config/defaults/glite-jpps.pre delete mode 100644 org.glite.jp.primary/config/functions/config_glite_jpps delete mode 100644 org.glite.jp.primary/config/glite-jp-primary-dbsetup.sh delete mode 100644 org.glite.jp.primary/config/glite-jp-primary-dbsetup.sql delete mode 100644 org.glite.jp.primary/config/gsi_authz.conf.example delete mode 100644 org.glite.jp.primary/config/node-info.d/glite-jpps delete mode 100755 org.glite.jp.primary/config/site-info.def.example delete mode 100644 org.glite.jp.primary/config/startup delete mode 100755 org.glite.jp.primary/configure delete mode 100644 org.glite.jp.primary/doc/README.install delete mode 100644 org.glite.jp.primary/examples/README.test delete mode 100644 org.glite.jp.primary/examples/dag-deps.c delete mode 100644 org.glite.jp.primary/examples/getjobattr.pl delete mode 100644 org.glite.jp.primary/examples/job_template delete mode 100644 org.glite.jp.primary/examples/jpps-test.c delete mode 100755 org.glite.jp.primary/examples/jpps_store_test delete mode 100755 org.glite.jp.primary/examples/recordmultitags.pl delete mode 100644 org.glite.jp.primary/examples/sample_job_aborted delete mode 100644 org.glite.jp.primary/examples/sample_job_cleared delete mode 100644 org.glite.jp.primary/examples/sample_job_tagged_done delete mode 100644 org.glite.jp.primary/examples/sample_job_waiting delete mode 100644 org.glite.jp.primary/project/ChangeLog delete mode 100644 org.glite.jp.primary/project/build.number delete mode 100644 org.glite.jp.primary/project/build.properties delete mode 100644 org.glite.jp.primary/project/configure.properties.xml delete mode 100755 org.glite.jp.primary/project/properties.xml delete mode 100644 org.glite.jp.primary/project/tar_exclude delete mode 100644 org.glite.jp.primary/project/version.properties delete mode 100644 org.glite.jp.primary/src/attrs.c delete mode 100644 org.glite.jp.primary/src/attrs.h delete mode 100644 org.glite.jp.primary/src/authz.c delete mode 100644 org.glite.jp.primary/src/authz.h delete mode 100644 org.glite.jp.primary/src/backend.h delete mode 100644 org.glite.jp.primary/src/backend_private.h delete mode 100644 org.glite.jp.primary/src/bones_server.c delete mode 100644 org.glite.jp.primary/src/classad_plugin.c delete mode 100644 org.glite.jp.primary/src/feed.c delete mode 100644 org.glite.jp.primary/src/feed.h delete mode 100644 org.glite.jp.primary/src/file_plugin.c delete mode 100644 org.glite.jp.primary/src/ftpd_auth.c delete mode 100644 org.glite.jp.primary/src/is_client.c delete mode 100644 org.glite.jp.primary/src/is_client.h delete mode 100644 org.glite.jp.primary/src/jp_callouts.c delete mode 100644 org.glite.jp.primary/src/jp_callouts.h delete mode 100644 org.glite.jp.primary/src/jptype_map.h delete mode 100755 org.glite.jp.primary/src/mk_soap_switch.pl delete mode 100644 org.glite.jp.primary/src/new_ftp_backend.c delete mode 100644 org.glite.jp.primary/src/sandbox_plugin.c delete mode 100644 org.glite.jp.primary/src/simple_server.c delete mode 100644 org.glite.jp.primary/src/soap_ops.c delete mode 100644 org.glite.jp.primary/src/soap_util.c delete mode 100644 org.glite.jp.primary/src/tags.c delete mode 100644 org.glite.jp.primary/src/tags.h delete mode 100644 org.glite.jp.primary/src/typemap.dat delete mode 100644 org.glite.jp.server-common/Makefile delete mode 100755 org.glite.jp.server-common/build.xml delete mode 100755 org.glite.jp.server-common/configure delete mode 100644 org.glite.jp.server-common/examples/db-test-int.c delete mode 100644 org.glite.jp.server-common/interface/db.h delete mode 100644 org.glite.jp.server-common/project/ChangeLog delete mode 100644 org.glite.jp.server-common/project/build.number delete mode 100644 org.glite.jp.server-common/project/configure.properties.xml delete mode 100755 org.glite.jp.server-common/project/properties.xml delete mode 100644 org.glite.jp.server-common/project/tar_exclude delete mode 100644 org.glite.jp.server-common/project/version.properties delete mode 100644 org.glite.jp.server-common/src/db.c delete mode 100755 org.glite.jp.ws-interface/.cvsignore delete mode 100755 org.glite.jp.ws-interface/LICENSE delete mode 100644 org.glite.jp.ws-interface/Makefile delete mode 100644 org.glite.jp.ws-interface/build.xml delete mode 100755 org.glite.jp.ws-interface/configure delete mode 100644 org.glite.jp.ws-interface/project/ChangeLog delete mode 100644 org.glite.jp.ws-interface/project/build.number delete mode 100755 org.glite.jp.ws-interface/project/build.properties delete mode 100644 org.glite.jp.ws-interface/project/configure.properties.xml delete mode 100644 org.glite.jp.ws-interface/project/properties.xml delete mode 100644 org.glite.jp.ws-interface/project/tar_exclude delete mode 100755 org.glite.jp.ws-interface/project/version.properties delete mode 100644 org.glite.jp.ws-interface/src/JobProvenanceIS.xml delete mode 100644 org.glite.jp.ws-interface/src/JobProvenancePS.xml delete mode 100644 org.glite.jp.ws-interface/src/JobProvenanceTypes.xml delete mode 100644 org.glite.jp.ws-interface/src/doc.xml delete mode 100755 org.glite.jp.ws-interface/src/jpdev.sh delete mode 100644 org.glite.jp.ws-interface/src/jpdev.xml.sh delete mode 100644 org.glite.jp.ws-interface/src/puke-schema.xsl delete mode 100644 org.glite.jp.ws-interface/src/puke-ug.xsl delete mode 100644 org.glite.jp.ws-interface/src/puke-wsdl.xsl delete mode 100644 org.glite.jp.ws-interface/src/ws_fault.c delete mode 100644 org.glite.jp/.cvsignore delete mode 100644 org.glite.jp/build.xml delete mode 100755 org.glite.jp/configure delete mode 100644 org.glite.jp/doc/README delete mode 100644 org.glite.jp/project/build.number delete mode 100644 org.glite.jp/project/build.properties delete mode 100644 org.glite.jp/project/dependencies.properties delete mode 100644 org.glite.jp/project/glite.jp.csf.xml delete mode 100755 org.glite.jp/project/properties.xml delete mode 100644 org.glite.jp/project/run-workspace delete mode 100755 org.glite.jp/project/taskdefs.xml delete mode 100644 org.glite.jp/project/version.properties delete mode 100755 org.glite.lb-utils.context/.cvsignore delete mode 100755 org.glite.lb-utils.context/LICENSE delete mode 100644 org.glite.lb-utils.context/build.xml delete mode 100644 org.glite.lb-utils.context/project/build.number delete mode 100755 org.glite.lb-utils.context/project/build.properties delete mode 100644 org.glite.lb-utils.context/project/configure.properties.xml delete mode 100644 org.glite.lb-utils.context/project/properties.xml delete mode 100755 org.glite.lb-utils.context/project/version.properties delete mode 100755 org.glite.lb-utils.db/.cvsignore delete mode 100755 org.glite.lb-utils.db/LICENSE delete mode 100644 org.glite.lb-utils.db/Makefile delete mode 100644 org.glite.lb-utils.db/build.xml delete mode 100644 org.glite.lb-utils.db/examples/db_expire.c delete mode 100644 org.glite.lb-utils.db/examples/db_test.c delete mode 100644 org.glite.lb-utils.db/interface/db.h delete mode 100644 org.glite.lb-utils.db/project/build.number delete mode 100755 org.glite.lb-utils.db/project/build.properties delete mode 100644 org.glite.lb-utils.db/project/configure.properties.xml delete mode 100644 org.glite.lb-utils.db/project/properties.xml delete mode 100644 org.glite.lb-utils.db/project/tar_exclude delete mode 100755 org.glite.lb-utils.db/project/version.properties delete mode 100644 org.glite.lb-utils.db/src/db.c delete mode 100755 org.glite.lb-utils.jobid/.cvsignore delete mode 100755 org.glite.lb-utils.jobid/LICENSE delete mode 100644 org.glite.lb-utils.jobid/Makefile delete mode 100644 org.glite.lb-utils.jobid/build.xml delete mode 100644 org.glite.lb-utils.jobid/interface/Exception.h delete mode 100644 org.glite.lb-utils.jobid/interface/JobId.h delete mode 100644 org.glite.lb-utils.jobid/interface/JobIdExceptions.h delete mode 100755 org.glite.lb-utils.jobid/interface/cjobid.h delete mode 100755 org.glite.lb-utils.jobid/interface/strmd5.h delete mode 100644 org.glite.lb-utils.jobid/project/build.number delete mode 100755 org.glite.lb-utils.jobid/project/build.properties delete mode 100644 org.glite.lb-utils.jobid/project/configure.properties.xml delete mode 100644 org.glite.lb-utils.jobid/project/properties.xml delete mode 100644 org.glite.lb-utils.jobid/project/tar_exclude delete mode 100755 org.glite.lb-utils.jobid/project/version.properties delete mode 100755 org.glite.lb-utils.jobid/src/cjobid.c delete mode 100755 org.glite.lb-utils.jobid/src/strmd5.c delete mode 100755 org.glite.lb-utils.server-bones/.cvsignore delete mode 100755 org.glite.lb-utils.server-bones/LICENSE delete mode 100644 org.glite.lb-utils.server-bones/build.xml delete mode 100644 org.glite.lb-utils.server-bones/project/build.number delete mode 100755 org.glite.lb-utils.server-bones/project/build.properties delete mode 100644 org.glite.lb-utils.server-bones/project/configure.properties.xml delete mode 100644 org.glite.lb-utils.server-bones/project/properties.xml delete mode 100755 org.glite.lb-utils.server-bones/project/version.properties delete mode 100755 org.glite.lb-utils.trio/.cvsignore delete mode 100755 org.glite.lb-utils.trio/LICENSE delete mode 100644 org.glite.lb-utils.trio/Makefile delete mode 100644 org.glite.lb-utils.trio/build.xml delete mode 100644 org.glite.lb-utils.trio/interface/escape.h delete mode 100644 org.glite.lb-utils.trio/interface/trio.h delete mode 100644 org.glite.lb-utils.trio/project/build.number delete mode 100755 org.glite.lb-utils.trio/project/build.properties delete mode 100644 org.glite.lb-utils.trio/project/configure.properties.xml delete mode 100644 org.glite.lb-utils.trio/project/properties.xml delete mode 100755 org.glite.lb-utils.trio/project/version.properties delete mode 100644 org.glite.lb-utils.trio/src/escape.c delete mode 100644 org.glite.lb-utils.trio/src/strio.c delete mode 100644 org.glite.lb-utils.trio/src/strio.h delete mode 100644 org.glite.lb-utils.trio/src/trio.c delete mode 100644 org.glite.lb-utils.trio/src/triop.h delete mode 100644 org.glite.lb-utils.trio/test/trio_test.cpp delete mode 100644 org.glite.lb-utils/.cvsignore delete mode 100755 org.glite.lb-utils/LICENSE delete mode 100644 org.glite.lb-utils/build.xml delete mode 100644 org.glite.lb-utils/project/build.number delete mode 100755 org.glite.lb-utils/project/build.properties delete mode 100644 org.glite.lb-utils/project/dependencies.properties delete mode 100644 org.glite.lb-utils/project/glite.lb-utils.csf.xml delete mode 100644 org.glite.lb-utils/project/properties.xml delete mode 100644 org.glite.lb-utils/project/taskdefs.xml delete mode 100755 org.glite.lb-utils/project/version.properties delete mode 100644 org.glite.lb.client-interface/.cvsignore delete mode 100644 org.glite.lb.client-interface/IMPORTANT-README delete mode 100644 org.glite.lb.client-interface/LICENSE delete mode 100644 org.glite.lb.client-interface/Makefile delete mode 100755 org.glite.lb.client-interface/build.xml delete mode 100644 org.glite.lb.client-interface/project/build.number delete mode 100644 org.glite.lb.client-interface/project/build.properties delete mode 100644 org.glite.lb.client-interface/project/configure.properties.xml delete mode 100755 org.glite.lb.client-interface/project/properties.xml delete mode 100644 org.glite.lb.client-interface/project/tar_exclude delete mode 100644 org.glite.lb.client-interface/project/version.properties delete mode 100644 org.glite.lb.client-java/Makefile delete mode 100755 org.glite.lb.client-java/configure delete mode 100644 org.glite.lb.client-java/examples/CreamTest.java delete mode 100644 org.glite.lb.client-java/examples/NotificationExample.java delete mode 100644 org.glite.lb.client-java/examples/ProducerTestIL.java delete mode 100644 org.glite.lb.client-java/examples/ProducerTestLL.java delete mode 100644 org.glite.lb.client-java/examples/QueryDemo.java delete mode 100644 org.glite.lb.client-java/examples/SSLClient.java delete mode 100644 org.glite.lb.client-java/examples/SSLServer.java delete mode 100644 org.glite.lb.client-java/examples/SimpleLLTest.java delete mode 100644 org.glite.lb.client-java/examples/simple-ssl/ExampleSSLSocketFactory.java delete mode 100644 org.glite.lb.client-java/examples/simple-ssl/LBClientSSL.java delete mode 100644 org.glite.lb.client-java/examples/simple-ssl/MyX509KeyManager.java delete mode 100644 org.glite.lb.client-java/examples/simple-ssl/MyX509TrustManager.java delete mode 100644 org.glite.lb.client-java/examples/simple-trustmanager/LBClientTM.java delete mode 100644 org.glite.lb.client-java/project/ChangeLog delete mode 100644 org.glite.lb.client-java/project/debian.control delete mode 100644 org.glite.lb.client-java/project/debian.copyright delete mode 100644 org.glite.lb.client-java/project/debian.glite-lb-client-java.dirs delete mode 100644 org.glite.lb.client-java/project/debian.glite-lb-client-java.install delete mode 100644 org.glite.lb.client-java/project/debian.rules delete mode 100644 org.glite.lb.client-java/project/genEventTypes.pl delete mode 100644 org.glite.lb.client-java/project/glite-lb-client-java.spec delete mode 100755 org.glite.lb.client-java/project/list-jars.sh delete mode 100644 org.glite.lb.client-java/project/package.description delete mode 100644 org.glite.lb.client-java/project/package.summary delete mode 100644 org.glite.lb.client-java/project/version.properties delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/Context.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/ContextDirect.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/ContextIL.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/ContextLL.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/Escape.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/Event.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/EventConvertor.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/ILFileWriter.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/ILProto.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/Job.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/LBCredentials.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/LBException.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/Level.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/NotifParser.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/Notification.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/SSL.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/SSLSend.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/SeqCode.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/ServerConnection.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/Sources.java delete mode 100644 org.glite.lb.client-java/src/org/glite/lb/Timeval.java delete mode 100755 org.glite.lb.client-java/src_c/Makefile delete mode 100755 org.glite.lb.client-java/src_c/send_via_proxy.c delete mode 100755 org.glite.lb.client-java/src_c/send_via_socket.c delete mode 100644 org.glite.lb.doc/GGUS19469-reply.txt delete mode 100644 org.glite.lb.doc/LICENSE delete mode 100644 org.glite.lb.doc/Makefile delete mode 100755 org.glite.lb.doc/configure delete mode 100644 org.glite.lb.doc/examples/Makefile delete mode 100644 org.glite.lb.doc/examples/README delete mode 100644 org.glite.lb.doc/examples/README.queries delete mode 100644 org.glite.lb.doc/examples/cons_example1.c delete mode 100644 org.glite.lb.doc/examples/cons_example1.cpp delete mode 100644 org.glite.lb.doc/examples/cons_example2.c delete mode 100644 org.glite.lb.doc/examples/cons_example2.cpp delete mode 100644 org.glite.lb.doc/examples/cons_example3.c delete mode 100644 org.glite.lb.doc/examples/cons_example3.cpp delete mode 100644 org.glite.lb.doc/examples/example1.c delete mode 100644 org.glite.lb.doc/examples/notif_example.c delete mode 100644 org.glite.lb.doc/examples/prod_example1.c delete mode 100644 org.glite.lb.doc/examples/util.C delete mode 100644 org.glite.lb.doc/examples/util.c delete mode 100644 org.glite.lb.doc/project/ChangeLog delete mode 100644 org.glite.lb.doc/project/debian.control delete mode 100644 org.glite.lb.doc/project/debian.copyright delete mode 100644 org.glite.lb.doc/project/debian.glite-lb-doc.dirs delete mode 100644 org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.ag delete mode 100644 org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.dg delete mode 100644 org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.tg delete mode 100644 org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.tp delete mode 100644 org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.ug delete mode 100644 org.glite.lb.doc/project/debian.glite-lb-doc.install delete mode 100644 org.glite.lb.doc/project/debian.rules delete mode 100644 org.glite.lb.doc/project/glite-lb-doc.spec delete mode 100644 org.glite.lb.doc/project/package.description delete mode 100644 org.glite.lb.doc/project/package.summary delete mode 100644 org.glite.lb.doc/project/version.properties delete mode 100644 org.glite.lb.doc/src/LBAG-Abstract.tex delete mode 100644 org.glite.lb.doc/src/LBAG-Installation.tex delete mode 100644 org.glite.lb.doc/src/LBAG-Introduction.tex delete mode 100644 org.glite.lb.doc/src/LBAG-Running.tex delete mode 100644 org.glite.lb.doc/src/LBAG-Troubleshooting.tex delete mode 100644 org.glite.lb.doc/src/LBAG.tex delete mode 100644 org.glite.lb.doc/src/LBDG-Abstract.tex delete mode 100644 org.glite.lb.doc/src/LBDG-Introduction.tex delete mode 100644 org.glite.lb.doc/src/LBDG.tex delete mode 100644 org.glite.lb.doc/src/LBTG-Abstract.tex delete mode 100644 org.glite.lb.doc/src/LBTG.tex delete mode 100644 org.glite.lb.doc/src/LBTP-Abstract.tex delete mode 100644 org.glite.lb.doc/src/LBTP-IntegrationTests.tex delete mode 100644 org.glite.lb.doc/src/LBTP-InterTests.tex delete mode 100644 org.glite.lb.doc/src/LBTP-Introduction.tex delete mode 100644 org.glite.lb.doc/src/LBTP-Nagios.tex delete mode 100644 org.glite.lb.doc/src/LBTP-PerfTests.tex delete mode 100644 org.glite.lb.doc/src/LBTP-Tests.tex delete mode 100644 org.glite.lb.doc/src/LBTP.tex delete mode 100644 org.glite.lb.doc/src/LBUG-Abstract.tex delete mode 100644 org.glite.lb.doc/src/LBUG-Appendix.tex delete mode 100644 org.glite.lb.doc/src/LBUG-Introduction.tex delete mode 100644 org.glite.lb.doc/src/LBUG-Tools.tex delete mode 100644 org.glite.lb.doc/src/LBUG-Troubleshooting.tex delete mode 100644 org.glite.lb.doc/src/LBUG.tex delete mode 100644 org.glite.lb.doc/src/README delete mode 100644 org.glite.lb.doc/src/README-standards.txt delete mode 100644 org.glite.lb.doc/src/change_acl.tex delete mode 100644 org.glite.lb.doc/src/components.tex delete mode 100644 org.glite.lb.doc/src/consumer_api.tex delete mode 100644 org.glite.lb.doc/src/copyright.tex delete mode 100644 org.glite.lb.doc/src/definitions.tex delete mode 100644 org.glite.lb.doc/src/doxygen.sty delete mode 100644 org.glite.lb.doc/src/doxyhack.tex delete mode 100644 org.glite.lb.doc/src/egee.cls delete mode 100644 org.glite.lb.doc/src/emi.cls delete mode 100644 org.glite.lb.doc/src/events.tex.T delete mode 100644 org.glite.lb.doc/src/faq.tex delete mode 100644 org.glite.lb.doc/src/frontmatter.tex delete mode 100644 org.glite.lb.doc/src/funding.tex delete mode 100644 org.glite.lb.doc/src/https_configuration.tex delete mode 100644 org.glite.lb.doc/src/images/EMI_Logo_std.pdf delete mode 100755 org.glite.lb.doc/src/images/LB-components-LB-WMS.pdf delete mode 100644 org.glite.lb.doc/src/images/LB-components-gather.pdf delete mode 100644 org.glite.lb.doc/src/images/LB-components-query.pdf delete mode 100755 org.glite.lb.doc/src/images/LB-components.pdf delete mode 100644 org.glite.lb.doc/src/images/cesnet.pdf delete mode 100644 org.glite.lb.doc/src/images/e-infra.pdf delete mode 100644 org.glite.lb.doc/src/images/egee.pdf delete mode 100644 org.glite.lb.doc/src/images/glite.pdf delete mode 100644 org.glite.lb.doc/src/images/isi.pdf delete mode 100644 org.glite.lb.doc/src/images/seqtree.pdf delete mode 100644 org.glite.lb.doc/src/images/wms2-jobstat.pdf delete mode 100644 org.glite.lb.doc/src/lbjp.bib delete mode 100644 org.glite.lb.doc/src/listings.sty delete mode 100644 org.glite.lb.doc/src/log_usertag.tex delete mode 100644 org.glite.lb.doc/src/logevent.tex delete mode 100644 org.glite.lb.doc/src/lstdoc.sty delete mode 100644 org.glite.lb.doc/src/lstlang1.sty delete mode 100644 org.glite.lb.doc/src/lstlang2.sty delete mode 100644 org.glite.lb.doc/src/lstlang3.sty delete mode 100644 org.glite.lb.doc/src/lstmisc.sty delete mode 100644 org.glite.lb.doc/src/lstpatch.sty delete mode 100644 org.glite.lb.doc/src/notification_api.tex delete mode 100644 org.glite.lb.doc/src/notify.tex delete mode 100644 org.glite.lb.doc/src/producer_api.tex delete mode 100644 org.glite.lb.doc/src/status.tex.T delete mode 100644 org.glite.lb.doc/src/versions.tex delete mode 100644 org.glite.lb.doc/src/web_services.tex delete mode 100644 org.glite.lb.emi-lb/Makefile delete mode 100755 org.glite.lb.emi-lb/configure delete mode 100644 org.glite.lb.emi-lb/project/ChangeLog delete mode 100644 org.glite.lb.emi-lb/project/debian.control delete mode 100644 org.glite.lb.emi-lb/project/debian.copyright delete mode 100644 org.glite.lb.emi-lb/project/debian.rules delete mode 100644 org.glite.lb.emi-lb/project/emi-lb.spec delete mode 100644 org.glite.lb.emi-lb/project/package.description delete mode 100644 org.glite.lb.emi-lb/project/package.summary delete mode 100644 org.glite.lb.emi-lb/project/version.properties delete mode 100644 org.glite.lb.glite-LB/Makefile delete mode 100755 org.glite.lb.glite-LB/configure delete mode 100644 org.glite.lb.glite-LB/project/ChangeLog delete mode 100644 org.glite.lb.glite-LB/project/package.description delete mode 100644 org.glite.lb.glite-LB/project/package.summary delete mode 100644 org.glite.lb.glite-LB/project/version.properties delete mode 100644 org.glite.lb.harvester/Makefile delete mode 100755 org.glite.lb.harvester/config/startup delete mode 100755 org.glite.lb.harvester/configure delete mode 100644 org.glite.lb.harvester/doc/INSTALL delete mode 100644 org.glite.lb.harvester/doc/README delete mode 100644 org.glite.lb.harvester/doc/glite-lb-harvester.sgml delete mode 100755 org.glite.lb.harvester/examples/test.sh delete mode 100644 org.glite.lb.harvester/examples/test.sql delete mode 100644 org.glite.lb.harvester/project/.post delete mode 100644 org.glite.lb.harvester/project/.postun delete mode 100644 org.glite.lb.harvester/project/.pre delete mode 100644 org.glite.lb.harvester/project/.preun delete mode 100644 org.glite.lb.harvester/project/ChangeLog delete mode 100644 org.glite.lb.harvester/project/debian.control delete mode 100644 org.glite.lb.harvester/project/debian.copyright delete mode 100644 org.glite.lb.harvester/project/debian.glite-lb-harvester.dirs delete mode 100644 org.glite.lb.harvester/project/debian.glite-lb-harvester.install delete mode 100644 org.glite.lb.harvester/project/debian.preinst delete mode 100644 org.glite.lb.harvester/project/debian.rules delete mode 100644 org.glite.lb.harvester/project/glite-lb-harvester.spec delete mode 100644 org.glite.lb.harvester/project/package.description delete mode 100644 org.glite.lb.harvester/project/package.summary delete mode 100644 org.glite.lb.harvester/project/version.properties delete mode 100644 org.glite.lb.harvester/src/harvester.c delete mode 100644 org.glite.lb.logger-msg/LICENSE delete mode 100644 org.glite.lb.logger-msg/Makefile delete mode 100644 org.glite.lb.logger-msg/config/msg.conf.example delete mode 100644 org.glite.lb.logger-msg/config/msg.cron.in delete mode 100755 org.glite.lb.logger-msg/configure delete mode 100644 org.glite.lb.logger-msg/examples/cmsclient.cpp delete mode 100644 org.glite.lb.logger-msg/project/ChangeLog delete mode 100644 org.glite.lb.logger-msg/project/debian.control delete mode 100644 org.glite.lb.logger-msg/project/debian.copyright delete mode 100644 org.glite.lb.logger-msg/project/debian.glite-lb-logger-msg.dirs delete mode 100644 org.glite.lb.logger-msg/project/debian.glite-lb-logger-msg.install delete mode 100644 org.glite.lb.logger-msg/project/debian.rules delete mode 100644 org.glite.lb.logger-msg/project/glite-lb-logger-msg.spec delete mode 100644 org.glite.lb.logger-msg/project/il.conf delete mode 100644 org.glite.lb.logger-msg/project/package.description delete mode 100644 org.glite.lb.logger-msg/project/package.summary delete mode 100644 org.glite.lb.logger-msg/project/version.properties delete mode 100644 org.glite.lb.logger-msg/src/activemq_cpp_plugin.cpp delete mode 100755 org.glite.lb.logger-msg/src/msg-brokers delete mode 100755 org.glite.lb.logger-msg/src/msg-config.in delete mode 100644 org.glite.lb.nagios/Makefile delete mode 100755 org.glite.lb.nagios/configure delete mode 100644 org.glite.lb.nagios/project/ChangeLog delete mode 100644 org.glite.lb.nagios/project/debian.control delete mode 100644 org.glite.lb.nagios/project/debian.copyright delete mode 100644 org.glite.lb.nagios/project/debian.emi-lb-nagios-plugins.dirs delete mode 100644 org.glite.lb.nagios/project/debian.emi-lb-nagios-plugins.install delete mode 100644 org.glite.lb.nagios/project/debian.postinst delete mode 100644 org.glite.lb.nagios/project/debian.rules delete mode 100644 org.glite.lb.nagios/project/emi-lb-nagios-plugins.spec delete mode 100644 org.glite.lb.nagios/project/package.description delete mode 100644 org.glite.lb.nagios/project/package.summary delete mode 100644 org.glite.lb.nagios/project/version.properties delete mode 100755 org.glite.lb.nagios/src/LB-probe delete mode 100644 org.glite.lb.proxy/.cvsignore delete mode 100644 org.glite.lb.proxy/LICENSE delete mode 100644 org.glite.lb.proxy/Makefile delete mode 100755 org.glite.lb.proxy/build.xml delete mode 100644 org.glite.lb.proxy/config/glite-lb-dbsetup-proxy.sql delete mode 100755 org.glite.lb.proxy/config/startup delete mode 100644 org.glite.lb.proxy/doc/README delete mode 100644 org.glite.lb.proxy/doc/README.deploy delete mode 100755 org.glite.lb.proxy/examples/test.sh delete mode 100644 org.glite.lb.proxy/examples/test1.sh delete mode 100644 org.glite.lb.proxy/examples/test2.sh delete mode 100755 org.glite.lb.proxy/examples/test3.sh delete mode 100644 org.glite.lb.proxy/project/build.number delete mode 100644 org.glite.lb.proxy/project/build.properties delete mode 100644 org.glite.lb.proxy/project/configure.properties.xml delete mode 100755 org.glite.lb.proxy/project/properties.xml delete mode 100644 org.glite.lb.proxy/project/tar_exclude delete mode 100644 org.glite.lb.proxy/project/version.properties delete mode 100755 org.glite.lb.proxy/src/fake_write2rgma.c delete mode 100644 org.glite.lb.proxy/src/lbproxy.c delete mode 100755 org.glite.lb.proxy/src/perftest_proxy.sh delete mode 100644 org.glite.lb.server-bones/.cvsignore delete mode 100644 org.glite.lb.server-bones/Makefile delete mode 100755 org.glite.lb.server-bones/build.xml delete mode 100644 org.glite.lb.server-bones/examples/cnt_example.c delete mode 100644 org.glite.lb.server-bones/examples/srv_example.c delete mode 100644 org.glite.lb.server-bones/interface/srvbones.h delete mode 100644 org.glite.lb.server-bones/project/build.number delete mode 100644 org.glite.lb.server-bones/project/build.properties delete mode 100644 org.glite.lb.server-bones/project/configure.properties.xml delete mode 100755 org.glite.lb.server-bones/project/properties.xml delete mode 100644 org.glite.lb.server-bones/project/tar_exclude delete mode 100644 org.glite.lb.server-bones/project/version.properties delete mode 100644 org.glite.lb.server-bones/src/srvbones.c delete mode 100755 org.glite.lb.utils/.cvsignore delete mode 100755 org.glite.lb.utils/LICENSE delete mode 100644 org.glite.lb.utils/Makefile delete mode 100755 org.glite.lb.utils/configure delete mode 100644 org.glite.lb.utils/doc/README.LB-monitoring delete mode 100644 org.glite.lb.utils/doc/README.LB-statistics delete mode 100644 org.glite.lb.utils/doc/glite-lb-mon.1 delete mode 100644 org.glite.lb.utils/doc/glite-lb-purge.8 delete mode 100644 org.glite.lb.utils/examples/glite-lb-index.conf delete mode 100755 org.glite.lb.utils/examples/glite-lb-statistics-gsi.sh delete mode 100755 org.glite.lb.utils/examples/glite-lb-statistics-rsync.sh delete mode 100755 org.glite.lb.utils/examples/glite-lb-statistics-sftp.sh delete mode 100755 org.glite.lb.utils/examples/glite-lb-statistics.sh delete mode 100644 org.glite.lb.utils/project/ChangeLog delete mode 100644 org.glite.lb.utils/project/debian.control delete mode 100644 org.glite.lb.utils/project/debian.copyright delete mode 100644 org.glite.lb.utils/project/debian.glite-lb-utils.dirs delete mode 100644 org.glite.lb.utils/project/debian.glite-lb-utils.install delete mode 100644 org.glite.lb.utils/project/debian.rules delete mode 100644 org.glite.lb.utils/project/glite-lb-utils.spec delete mode 100644 org.glite.lb.utils/project/package.description delete mode 100644 org.glite.lb.utils/project/package.summary delete mode 100755 org.glite.lb.utils/project/version.properties delete mode 100644 org.glite.lb.utils/src/dump.c delete mode 100644 org.glite.lb.utils/src/dump_exporter.c delete mode 100644 org.glite.lb.utils/src/glite-lb-bkpurge-offline.sh delete mode 100644 org.glite.lb.utils/src/load.c delete mode 100644 org.glite.lb.utils/src/mon.c delete mode 100755 org.glite.lb.utils/src/notif-keeper.sh delete mode 100644 org.glite.lb.utils/src/process_attrs.c delete mode 100644 org.glite.lb.utils/src/process_attrs2.c.T delete mode 100644 org.glite.lb.utils/src/purge.c delete mode 100644 org.glite.lb.utils/src/state_history.c delete mode 100644 org.glite.lb.utils/src/statistics.c delete mode 100644 org.glite.lb.ws-test/Makefile delete mode 100755 org.glite.lb.ws-test/configure delete mode 100755 org.glite.lb.ws-test/examples/ws_comlex.pl delete mode 100644 org.glite.lb.ws-test/examples/ws_fault.c delete mode 100644 org.glite.lb.ws-test/examples/ws_fault.h delete mode 100644 org.glite.lb.ws-test/examples/ws_getversion.c delete mode 100755 org.glite.lb.ws-test/examples/ws_getversion.pl delete mode 100644 org.glite.lb.ws-test/examples/ws_joblog.c delete mode 100755 org.glite.lb.ws-test/examples/ws_joblog.pl delete mode 100644 org.glite.lb.ws-test/examples/ws_jobstat.c delete mode 100755 org.glite.lb.ws-test/examples/ws_jobstat.pl delete mode 100644 org.glite.lb.ws-test/examples/ws_lb4agu_GetActivityInfo.c delete mode 100644 org.glite.lb.ws-test/examples/ws_lb4agu_GetActivityStatus.c delete mode 100755 org.glite.lb.ws-test/examples/ws_lb4agu_GetActivityStatus.pl delete mode 100644 org.glite.lb.ws-test/examples/ws_query_ex.c delete mode 100755 org.glite.lb.ws-test/examples/ws_status_history_test.sh delete mode 100644 org.glite.lb.ws-test/examples/ws_typemap.dat delete mode 100644 org.glite.lb.ws-test/project/ChangeLog delete mode 100644 org.glite.lb.ws-test/project/debian.control delete mode 100644 org.glite.lb.ws-test/project/debian.copyright delete mode 100644 org.glite.lb.ws-test/project/debian.glite-lb-ws-test.dirs delete mode 100644 org.glite.lb.ws-test/project/debian.glite-lb-ws-test.install delete mode 100644 org.glite.lb.ws-test/project/debian.rules delete mode 100644 org.glite.lb.ws-test/project/glite-lb-ws-test.spec delete mode 100644 org.glite.lb.ws-test/project/package.description delete mode 100644 org.glite.lb.ws-test/project/package.summary delete mode 100644 org.glite.lb.ws-test/project/version.properties delete mode 100644 org.glite.lb.ws-test/tests/sizeof_soap_test.c delete mode 100644 org.glite.lb.yaim/Makefile delete mode 100644 org.glite.lb.yaim/config/defaults/glite-lb.pre delete mode 100644 org.glite.lb.yaim/config/functions/config_gip_lb delete mode 100644 org.glite.lb.yaim/config/functions/config_glite_lb.in delete mode 100644 org.glite.lb.yaim/config/functions/config_info_service_lb delete mode 100644 org.glite.lb.yaim/config/functions/emi/config_info_service_lb delete mode 100644 org.glite.lb.yaim/config/node-info.d/emi/glite-lb delete mode 100644 org.glite.lb.yaim/config/node-info.d/glite-lb delete mode 100644 org.glite.lb.yaim/configure delete mode 100644 org.glite.lb.yaim/project/ChangeLog delete mode 100644 org.glite.lb.yaim/project/debian.control delete mode 100644 org.glite.lb.yaim/project/debian.copyright delete mode 100644 org.glite.lb.yaim/project/debian.glite-lb-yaim.dirs delete mode 100644 org.glite.lb.yaim/project/debian.glite-lb-yaim.install delete mode 100644 org.glite.lb.yaim/project/debian.rules delete mode 100644 org.glite.lb.yaim/project/glite-lb-yaim.spec delete mode 100644 org.glite.lb.yaim/project/package.description delete mode 100644 org.glite.lb.yaim/project/package.summary delete mode 100644 org.glite.lb.yaim/project/version.properties delete mode 100644 org.glite.lb/.cvsignore delete mode 100644 org.glite.lb/LICENSE delete mode 100755 org.glite.lb/configure delete mode 100644 org.glite.lb/deployment/README delete mode 100644 org.glite.lb/deployment/deploy_all.diff delete mode 100644 org.glite.lb/deployment/deploy_jp.diff delete mode 100644 org.glite.lb/deployment/deploy_lb.diff delete mode 100644 org.glite.lb/doc/README.lb4vdt delete mode 100644 org.glite.lb/doc/perf_clear_proxy delete mode 100644 org.glite.lb/doc/perf_purge delete mode 100644 org.glite.lb/doc/perf_reg_jobs delete mode 100644 org.glite.lb/doc/perf_results/il_sci_09062006.txt delete mode 100644 org.glite.lb/doc/perf_results/il_sci_09062006_01.txt delete mode 100644 org.glite.lb/doc/perf_results/il_sci_12062006.txt delete mode 100644 org.glite.lb/doc/perf_results/ll_michal_21062006.txt delete mode 100644 org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_22062006.txt delete mode 100644 org.glite.lb/doc/perf_results/proxy2serv_umbar2sci_23062006.txt delete mode 100644 org.glite.lb/doc/perf_results/proxy_sci_09062006.txt delete mode 100644 org.glite.lb/doc/perf_run_interlogd delete mode 100644 org.glite.lb/doc/perf_run_proxy delete mode 100644 org.glite.lb/doc/perf_run_server delete mode 100644 org.glite.lb/doc/perf_run_test delete mode 100644 org.glite.lb/egee_license_check.sh delete mode 100644 org.glite.lb/etics-tag-branch.pl delete mode 100755 org.glite.lb/etics-tag-consistency.pl delete mode 100644 org.glite.lb/etics-tag-gridsite.pl delete mode 100644 org.glite.lb/etics-tag-with-subsystems-branch.pl delete mode 100755 org.glite.lb/etics-tag-with-subsystems.pl delete mode 100755 org.glite.lb/etics-tag.pl delete mode 100644 org.glite.lb/generate-properties.pl delete mode 100755 org.glite.lb/lb4vdt/LB_install.sh delete mode 100644 org.glite.lb/lb4vdt/Makefile.inc delete mode 100644 org.glite.lb/lb4vdt/scripts/org.gridsite.core.build delete mode 100644 org.glite.lb/project/package.description delete mode 100644 org.glite.lb/project/package.summary delete mode 100644 org.glite.lb/project/version.properties delete mode 100644 org.glite.lbjp-common.db/.cvsignore delete mode 100644 org.glite.lbjp-common.db/LICENSE delete mode 100644 org.glite.lbjp-common.db/Makefile delete mode 100755 org.glite.lbjp-common.db/configure delete mode 100644 org.glite.lbjp-common.db/doc/C.dox delete mode 100644 org.glite.lbjp-common.db/examples/db_expire.c delete mode 100644 org.glite.lbjp-common.db/examples/db_test.c delete mode 100644 org.glite.lbjp-common.db/interface/db-int.h delete mode 100644 org.glite.lbjp-common.db/interface/db.h delete mode 100644 org.glite.lbjp-common.db/project/.post delete mode 100644 org.glite.lbjp-common.db/project/.postun delete mode 100644 org.glite.lbjp-common.db/project/ChangeLog delete mode 100644 org.glite.lbjp-common.db/project/debian.control delete mode 100644 org.glite.lbjp-common.db/project/debian.copyright delete mode 100644 org.glite.lbjp-common.db/project/debian.libglite-lbjp-common-db-dev.dirs delete mode 100644 org.glite.lbjp-common.db/project/debian.libglite-lbjp-common-db-dev.install delete mode 100644 org.glite.lbjp-common.db/project/debian.libglite-lbu-db3.dirs delete mode 100644 org.glite.lbjp-common.db/project/debian.libglite-lbu-db3.install delete mode 100644 org.glite.lbjp-common.db/project/debian.rules delete mode 100644 org.glite.lbjp-common.db/project/glite-lbjp-common-db.spec delete mode 100644 org.glite.lbjp-common.db/project/package.description delete mode 100644 org.glite.lbjp-common.db/project/package.summary delete mode 100644 org.glite.lbjp-common.db/project/version.properties delete mode 100644 org.glite.lbjp-common.db/src/db-mysql.c delete mode 100644 org.glite.lbjp-common.db/src/db-pg.c delete mode 100644 org.glite.lbjp-common.db/src/db.c delete mode 100644 org.glite.lbjp-common.db/test/timezone.cpp delete mode 100644 org.glite.lbjp-common.gsoap-plugin/LICENSE delete mode 100644 org.glite.lbjp-common.gsoap-plugin/Makefile delete mode 100755 org.glite.lbjp-common.gsoap-plugin/configure delete mode 100644 org.glite.lbjp-common.gsoap-plugin/examples/calc.h.S delete mode 100644 org.glite.lbjp-common.gsoap-plugin/examples/wscalc_clt_ex.c delete mode 100644 org.glite.lbjp-common.gsoap-plugin/examples/wscalc_srv_ex.c delete mode 100644 org.glite.lbjp-common.gsoap-plugin/examples/wscalc_srv_ex2.c delete mode 100644 org.glite.lbjp-common.gsoap-plugin/interface/glite_gscompat.h.in delete mode 100644 org.glite.lbjp-common.gsoap-plugin/interface/glite_gsplugin-int.h delete mode 100644 org.glite.lbjp-common.gsoap-plugin/interface/glite_gsplugin.h delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/.post delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/.postun delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/ChangeLog delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/debian.control delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/debian.copyright delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/debian.libglite-lbjp-common-gsoap-plugin-dev.dirs delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/debian.libglite-lbjp-common-gsoap-plugin-dev.install delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/debian.libglite-lbjp-common-gsoap-plugin.dirs delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/debian.libglite-lbjp-common-gsoap-plugin.install delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/debian.rules delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/glite-lbjp-common-gsoap-plugin.spec delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/gsoap-plugin++.pc.in delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/gsoap-plugin.pc.in delete mode 100755 org.glite.lbjp-common.gsoap-plugin/project/libtoolhack/gcc delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/package.description delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/package.summary delete mode 100644 org.glite.lbjp-common.gsoap-plugin/project/version.properties delete mode 100644 org.glite.lbjp-common.gsoap-plugin/src/glite_gsplugin.c delete mode 100644 org.glite.lbjp-common.gsoap-plugin/src/sizeof_soap.c delete mode 100644 org.glite.lbjp-common.gsoap-plugin/test/test_gsplugin_cxx.cpp delete mode 100644 org.glite.lbjp-common.jp-interface/Makefile delete mode 100755 org.glite.lbjp-common.jp-interface/configure delete mode 100644 org.glite.lbjp-common.jp-interface/interface/attr.h delete mode 100644 org.glite.lbjp-common.jp-interface/interface/backend.h delete mode 100644 org.glite.lbjp-common.jp-interface/interface/builtin_plugins.h delete mode 100644 org.glite.lbjp-common.jp-interface/interface/context.h delete mode 100644 org.glite.lbjp-common.jp-interface/interface/file_plugin.h delete mode 100644 org.glite.lbjp-common.jp-interface/interface/indexdb.h delete mode 100644 org.glite.lbjp-common.jp-interface/interface/known_attr.h delete mode 100644 org.glite.lbjp-common.jp-interface/interface/type_plugin.h delete mode 100644 org.glite.lbjp-common.jp-interface/interface/types.h delete mode 100644 org.glite.lbjp-common.jp-interface/project/.post delete mode 100644 org.glite.lbjp-common.jp-interface/project/.postun delete mode 100644 org.glite.lbjp-common.jp-interface/project/ChangeLog delete mode 100644 org.glite.lbjp-common.jp-interface/project/debian.control delete mode 100644 org.glite.lbjp-common.jp-interface/project/debian.copyright delete mode 100644 org.glite.lbjp-common.jp-interface/project/debian.libglite-jp-common2.dirs delete mode 100644 org.glite.lbjp-common.jp-interface/project/debian.libglite-jp-common2.install delete mode 100644 org.glite.lbjp-common.jp-interface/project/debian.libglite-lbjp-common-jp-interface-dev.dirs delete mode 100644 org.glite.lbjp-common.jp-interface/project/debian.libglite-lbjp-common-jp-interface-dev.install delete mode 100644 org.glite.lbjp-common.jp-interface/project/debian.rules delete mode 100644 org.glite.lbjp-common.jp-interface/project/glite-lbjp-common-jp-interface.spec delete mode 100644 org.glite.lbjp-common.jp-interface/project/package.description delete mode 100644 org.glite.lbjp-common.jp-interface/project/package.summary delete mode 100644 org.glite.lbjp-common.jp-interface/project/version.properties delete mode 100644 org.glite.lbjp-common.jp-interface/src/attr.c delete mode 100644 org.glite.lbjp-common.jp-interface/src/context.c delete mode 100644 org.glite.lbjp-common.jp-interface/src/indexdb.c delete mode 100644 org.glite.lbjp-common.jp-interface/src/utils.c delete mode 100644 org.glite.lbjp-common.jp-interface/test/type_test.cpp delete mode 100644 org.glite.lbjp-common.log/LICENSE delete mode 100644 org.glite.lbjp-common.log/Makefile delete mode 100644 org.glite.lbjp-common.log/README delete mode 100644 org.glite.lbjp-common.log/config/log4crc delete mode 100644 org.glite.lbjp-common.log/config/log4crc.debugging delete mode 100755 org.glite.lbjp-common.log/configure delete mode 100644 org.glite.lbjp-common.log/project/.post delete mode 100644 org.glite.lbjp-common.log/project/.postun delete mode 100644 org.glite.lbjp-common.log/project/ChangeLog delete mode 100644 org.glite.lbjp-common.log/project/debian.control delete mode 100644 org.glite.lbjp-common.log/project/debian.copyright delete mode 100644 org.glite.lbjp-common.log/project/debian.libglite-lbjp-common-log-dev.dirs delete mode 100644 org.glite.lbjp-common.log/project/debian.libglite-lbjp-common-log-dev.install delete mode 100644 org.glite.lbjp-common.log/project/debian.libglite-lbu-log1.dirs delete mode 100644 org.glite.lbjp-common.log/project/debian.libglite-lbu-log1.install delete mode 100644 org.glite.lbjp-common.log/project/debian.rules delete mode 100644 org.glite.lbjp-common.log/project/glite-lbjp-common-log.spec delete mode 100644 org.glite.lbjp-common.log/project/package.description delete mode 100644 org.glite.lbjp-common.log/project/package.summary delete mode 100644 org.glite.lbjp-common.log/project/version.properties delete mode 100644 org.glite.lbjp-common.log/src/log.c delete mode 100644 org.glite.lbjp-common.log/src/log.h delete mode 100644 org.glite.lbjp-common.log/tests/log4crc delete mode 100644 org.glite.lbjp-common.log/tests/test.c delete mode 100644 org.glite.lbjp-common.maildir/.cvsignore delete mode 100644 org.glite.lbjp-common.maildir/Makefile delete mode 100755 org.glite.lbjp-common.maildir/configure delete mode 100644 org.glite.lbjp-common.maildir/interface/maildir.h delete mode 100644 org.glite.lbjp-common.maildir/project/.post delete mode 100644 org.glite.lbjp-common.maildir/project/.postun delete mode 100644 org.glite.lbjp-common.maildir/project/ChangeLog delete mode 100644 org.glite.lbjp-common.maildir/project/debian.control delete mode 100644 org.glite.lbjp-common.maildir/project/debian.copyright delete mode 100644 org.glite.lbjp-common.maildir/project/debian.libglite-lbjp-common-maildir-dev.dirs delete mode 100644 org.glite.lbjp-common.maildir/project/debian.libglite-lbjp-common-maildir-dev.install delete mode 100644 org.glite.lbjp-common.maildir/project/debian.libglite-lbu-maildir2.dirs delete mode 100644 org.glite.lbjp-common.maildir/project/debian.libglite-lbu-maildir2.install delete mode 100644 org.glite.lbjp-common.maildir/project/debian.rules delete mode 100644 org.glite.lbjp-common.maildir/project/glite-lbjp-common-maildir.spec delete mode 100644 org.glite.lbjp-common.maildir/project/package.description delete mode 100644 org.glite.lbjp-common.maildir/project/package.summary delete mode 100644 org.glite.lbjp-common.maildir/project/version.properties delete mode 100644 org.glite.lbjp-common.maildir/src/maildir.c delete mode 100644 org.glite.lbjp-common.server-bones/.cvsignore delete mode 100644 org.glite.lbjp-common.server-bones/Makefile delete mode 100755 org.glite.lbjp-common.server-bones/configure delete mode 100644 org.glite.lbjp-common.server-bones/examples/cnt_example.c delete mode 100644 org.glite.lbjp-common.server-bones/examples/run_test.sh delete mode 100644 org.glite.lbjp-common.server-bones/examples/srv_example.c delete mode 100644 org.glite.lbjp-common.server-bones/interface/srvbones.h delete mode 100644 org.glite.lbjp-common.server-bones/project/.post delete mode 100644 org.glite.lbjp-common.server-bones/project/.postun delete mode 100644 org.glite.lbjp-common.server-bones/project/ChangeLog delete mode 100644 org.glite.lbjp-common.server-bones/project/debian.control delete mode 100644 org.glite.lbjp-common.server-bones/project/debian.copyright delete mode 100644 org.glite.lbjp-common.server-bones/project/debian.libglite-lbjp-common-server-bones-dev.dirs delete mode 100644 org.glite.lbjp-common.server-bones/project/debian.libglite-lbjp-common-server-bones-dev.install delete mode 100644 org.glite.lbjp-common.server-bones/project/debian.libglite-lbu-server-bones2.dirs delete mode 100644 org.glite.lbjp-common.server-bones/project/debian.libglite-lbu-server-bones2.install delete mode 100644 org.glite.lbjp-common.server-bones/project/debian.rules delete mode 100644 org.glite.lbjp-common.server-bones/project/glite-lbjp-common-server-bones.spec delete mode 100644 org.glite.lbjp-common.server-bones/project/package.description delete mode 100644 org.glite.lbjp-common.server-bones/project/package.summary delete mode 100644 org.glite.lbjp-common.server-bones/project/version.properties delete mode 100644 org.glite.lbjp-common.server-bones/src/srvbones.c delete mode 100644 org.glite.lbjp-common.trio/.cvsignore delete mode 100644 org.glite.lbjp-common.trio/LICENSE delete mode 100644 org.glite.lbjp-common.trio/Makefile delete mode 100755 org.glite.lbjp-common.trio/configure delete mode 100644 org.glite.lbjp-common.trio/interface/escape.h delete mode 100644 org.glite.lbjp-common.trio/interface/trio.h delete mode 100644 org.glite.lbjp-common.trio/project/.post delete mode 100644 org.glite.lbjp-common.trio/project/.postun delete mode 100644 org.glite.lbjp-common.trio/project/ChangeLog delete mode 100644 org.glite.lbjp-common.trio/project/debian.control delete mode 100644 org.glite.lbjp-common.trio/project/debian.copyright delete mode 100644 org.glite.lbjp-common.trio/project/debian.libglite-lbjp-common-trio-dev.dirs delete mode 100644 org.glite.lbjp-common.trio/project/debian.libglite-lbjp-common-trio-dev.install delete mode 100644 org.glite.lbjp-common.trio/project/debian.libglite-lbu-trio2.dirs delete mode 100644 org.glite.lbjp-common.trio/project/debian.libglite-lbu-trio2.install delete mode 100644 org.glite.lbjp-common.trio/project/debian.rules delete mode 100644 org.glite.lbjp-common.trio/project/glite-lbjp-common-trio.spec delete mode 100644 org.glite.lbjp-common.trio/project/package.description delete mode 100644 org.glite.lbjp-common.trio/project/package.summary delete mode 100644 org.glite.lbjp-common.trio/project/version.properties delete mode 100644 org.glite.lbjp-common.trio/src/escape.c delete mode 100644 org.glite.lbjp-common.trio/src/strio.c delete mode 100644 org.glite.lbjp-common.trio/src/strio.h delete mode 100644 org.glite.lbjp-common.trio/src/trio.c delete mode 100644 org.glite.lbjp-common.trio/src/triop.h delete mode 100644 org.glite.lbjp-common.trio/test/trio_test.cpp delete mode 100644 org.glite.lbjp-common/project/version.properties delete mode 100644 org.glite.lbjp-utils.db/.cvsignore delete mode 100644 org.glite.lbjp-utils.db/LICENSE delete mode 100644 org.glite.lbjp-utils.db/Makefile delete mode 100644 org.glite.lbjp-utils.db/examples/db_expire.c delete mode 100644 org.glite.lbjp-utils.db/examples/db_test.c delete mode 100644 org.glite.lbjp-utils.db/interface/db.h delete mode 100644 org.glite.lbjp-utils.db/src/db.c delete mode 100644 org.glite.lbjp-utils.jobid/.cvsignore delete mode 100644 org.glite.lbjp-utils.jobid/LICENSE delete mode 100644 org.glite.lbjp-utils.jobid/Makefile delete mode 100644 org.glite.lbjp-utils.jobid/interface/Exception.h delete mode 100644 org.glite.lbjp-utils.jobid/interface/JobId.h delete mode 100644 org.glite.lbjp-utils.jobid/interface/JobIdExceptions.h delete mode 100644 org.glite.lbjp-utils.jobid/interface/cjobid.h delete mode 100644 org.glite.lbjp-utils.jobid/interface/strmd5.h delete mode 100644 org.glite.lbjp-utils.jobid/src/cjobid.c delete mode 100644 org.glite.lbjp-utils.jobid/src/strmd5.c delete mode 100644 org.glite.lbjp-utils.server-bones/.cvsignore delete mode 100644 org.glite.lbjp-utils.server-bones/Makefile delete mode 100644 org.glite.lbjp-utils.server-bones/examples/cnt_example.c delete mode 100644 org.glite.lbjp-utils.server-bones/examples/srv_example.c delete mode 100644 org.glite.lbjp-utils.server-bones/interface/srvbones.h delete mode 100644 org.glite.lbjp-utils.server-bones/src/srvbones.c delete mode 100644 org.glite.lbjp-utils.trio/.cvsignore delete mode 100644 org.glite.lbjp-utils.trio/LICENSE delete mode 100644 org.glite.lbjp-utils.trio/Makefile delete mode 100644 org.glite.lbjp-utils.trio/interface/escape.h delete mode 100644 org.glite.lbjp-utils.trio/interface/trio.h delete mode 100644 org.glite.lbjp-utils.trio/src/escape.c delete mode 100644 org.glite.lbjp-utils.trio/src/strio.c delete mode 100644 org.glite.lbjp-utils.trio/src/strio.h delete mode 100644 org.glite.lbjp-utils.trio/src/trio.c delete mode 100644 org.glite.lbjp-utils.trio/src/triop.h delete mode 100644 org.glite.lbjp-utils.trio/test/trio_test.cpp delete mode 100644 org.glite.myproxy-config/.cvsignore delete mode 100644 org.glite.myproxy-config/Makefile delete mode 100644 org.glite.myproxy-config/myproxy-config.spec delete mode 100644 org.glite.myproxy-config/myproxy-initd delete mode 100644 org.glite.px.emi-px/Makefile delete mode 100755 org.glite.px.emi-px/configure delete mode 100644 org.glite.px.emi-px/project/ChangeLog delete mode 100644 org.glite.px.emi-px/project/debian.control delete mode 100644 org.glite.px.emi-px/project/debian.copyright delete mode 100644 org.glite.px.emi-px/project/debian.rules delete mode 100644 org.glite.px.emi-px/project/emi-px.spec delete mode 100644 org.glite.px.emi-px/project/package.description delete mode 100644 org.glite.px.emi-px/project/package.summary delete mode 100644 org.glite.px.emi-px/project/version.properties delete mode 100644 org.glite.px.glite-PX/Makefile delete mode 100755 org.glite.px.glite-PX/configure delete mode 100644 org.glite.px.glite-PX/project/ChangeLog delete mode 100644 org.glite.px.glite-PX/project/package.description delete mode 100644 org.glite.px.glite-PX/project/package.summary delete mode 100644 org.glite.px.glite-PX/project/version.properties delete mode 100644 org.glite.px.myproxy-yaim/Makefile delete mode 100644 org.glite.px.myproxy-yaim/config/defaults/glite-px.pre delete mode 100755 org.glite.px.myproxy-yaim/config/functions/config_gip_px delete mode 100644 org.glite.px.myproxy-yaim/config/functions/config_info_service_px delete mode 100644 org.glite.px.myproxy-yaim/config/functions/config_proxy_server delete mode 100644 org.glite.px.myproxy-yaim/config/functions/emi/config_info_service_px delete mode 100644 org.glite.px.myproxy-yaim/config/man/myproxy-yaim.1 delete mode 100644 org.glite.px.myproxy-yaim/config/node-info.d/emi/glite-px delete mode 100644 org.glite.px.myproxy-yaim/config/node-info.d/glite-px delete mode 100644 org.glite.px.myproxy-yaim/config/node-info.d/glite-px_30 delete mode 100644 org.glite.px.myproxy-yaim/config/services/glite-px delete mode 100755 org.glite.px.myproxy-yaim/configure delete mode 100644 org.glite.px.myproxy-yaim/project/ChangeLog delete mode 100644 org.glite.px.myproxy-yaim/project/debian.control delete mode 100644 org.glite.px.myproxy-yaim/project/debian.copyright delete mode 100644 org.glite.px.myproxy-yaim/project/debian.glite-px-myproxy-yaim.dirs delete mode 100644 org.glite.px.myproxy-yaim/project/debian.glite-px-myproxy-yaim.install delete mode 100644 org.glite.px.myproxy-yaim/project/debian.rules delete mode 100644 org.glite.px.myproxy-yaim/project/glite-px-myproxy-yaim.spec delete mode 100644 org.glite.px.myproxy-yaim/project/package.description delete mode 100644 org.glite.px.myproxy-yaim/project/package.summary delete mode 100644 org.glite.px.myproxy-yaim/project/version.properties delete mode 100644 org.glite.px.proxyrenewal/LICENSE delete mode 100644 org.glite.px.proxyrenewal/Makefile delete mode 100644 org.glite.px.proxyrenewal/README delete mode 100755 org.glite.px.proxyrenewal/config/startup delete mode 100755 org.glite.px.proxyrenewal/configure delete mode 100644 org.glite.px.proxyrenewal/examples/renew_core.c delete mode 100644 org.glite.px.proxyrenewal/interface/renewal.h delete mode 100644 org.glite.px.proxyrenewal/interface/renewal_core.h delete mode 100644 org.glite.px.proxyrenewal/project/.post delete mode 100644 org.glite.px.proxyrenewal/project/.postun delete mode 100644 org.glite.px.proxyrenewal/project/.pre delete mode 100644 org.glite.px.proxyrenewal/project/.preun delete mode 100644 org.glite.px.proxyrenewal/project/ChangeLog delete mode 100644 org.glite.px.proxyrenewal/project/debian.control delete mode 100644 org.glite.px.proxyrenewal/project/debian.copyright delete mode 100644 org.glite.px.proxyrenewal/project/debian.glite-px-proxyrenewal-progs.dirs delete mode 100644 org.glite.px.proxyrenewal/project/debian.glite-px-proxyrenewal-progs.install delete mode 100644 org.glite.px.proxyrenewal/project/debian.libglite-security-proxyrenewal-dev.dirs delete mode 100644 org.glite.px.proxyrenewal/project/debian.libglite-security-proxyrenewal-dev.install delete mode 100644 org.glite.px.proxyrenewal/project/debian.libglite-security-proxyrenewal1.dirs delete mode 100644 org.glite.px.proxyrenewal/project/debian.libglite-security-proxyrenewal1.install delete mode 100644 org.glite.px.proxyrenewal/project/debian.preinst delete mode 100644 org.glite.px.proxyrenewal/project/debian.rules delete mode 100755 org.glite.px.proxyrenewal/project/doc_proxyrenewal.pl delete mode 100644 org.glite.px.proxyrenewal/project/glite-px-proxyrenewal.spec delete mode 100644 org.glite.px.proxyrenewal/project/package.description delete mode 100644 org.glite.px.proxyrenewal/project/package.summary delete mode 100644 org.glite.px.proxyrenewal/project/version.properties delete mode 100644 org.glite.px.proxyrenewal/src/api.c delete mode 100644 org.glite.px.proxyrenewal/src/client.c delete mode 100644 org.glite.px.proxyrenewal/src/commands.c delete mode 100644 org.glite.px.proxyrenewal/src/common.c delete mode 100644 org.glite.px.proxyrenewal/src/glite-proxy-renew.1 delete mode 100644 org.glite.px.proxyrenewal/src/glite-proxy-renewd.8 delete mode 100644 org.glite.px.proxyrenewal/src/renew.c delete mode 100644 org.glite.px.proxyrenewal/src/renewal_core.c delete mode 100644 org.glite.px.proxyrenewal/src/renewal_locl.h delete mode 100644 org.glite.px.proxyrenewal/src/renewd.c delete mode 100644 org.glite.px.proxyrenewal/src/renewd_locl.h delete mode 100644 org.glite.px.proxyrenewal/src/voms.c delete mode 100644 org.glite.px/project/version.properties delete mode 100644 org.glite.security.gsoap-plugin/LICENSE delete mode 100644 org.glite.security.gsoap-plugin/Makefile delete mode 100755 org.glite.security.gsoap-plugin/build.xml delete mode 100755 org.glite.security.gsoap-plugin/configure delete mode 100644 org.glite.security.gsoap-plugin/examples/calc.h.S delete mode 100644 org.glite.security.gsoap-plugin/examples/wscalc_clt_ex.c delete mode 100644 org.glite.security.gsoap-plugin/examples/wscalc_srv_ex.c delete mode 100644 org.glite.security.gsoap-plugin/examples/wscalc_srv_ex2.c delete mode 100644 org.glite.security.gsoap-plugin/interface/glite_gscompat.h delete mode 100644 org.glite.security.gsoap-plugin/interface/glite_gsplugin-int.h delete mode 100644 org.glite.security.gsoap-plugin/interface/glite_gsplugin.h delete mode 100644 org.glite.security.gsoap-plugin/project/ChangeLog delete mode 100644 org.glite.security.gsoap-plugin/project/build.number delete mode 100644 org.glite.security.gsoap-plugin/project/build.properties delete mode 100644 org.glite.security.gsoap-plugin/project/configure.properties.xml delete mode 100644 org.glite.security.gsoap-plugin/project/libtoolhack/gcc delete mode 100644 org.glite.security.gsoap-plugin/project/package.description delete mode 100644 org.glite.security.gsoap-plugin/project/package.summary delete mode 100755 org.glite.security.gsoap-plugin/project/properties.xml delete mode 100644 org.glite.security.gsoap-plugin/project/tar_exclude delete mode 100644 org.glite.security.gsoap-plugin/project/version.properties delete mode 100644 org.glite.security.gsoap-plugin/src/glite_gsplugin.c delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.6.2.c delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.6.2.h delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0.c delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0.h delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.c delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.0f.h delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.10.c delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.10.h delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.c delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6b.h delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6d.c delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.6d.h delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.c delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9b.h delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9d.c delete mode 100644 org.glite.security.gsoap-plugin/src/stdsoap2_2.7.9d.h delete mode 100644 org.glite.security.gsoap-plugin/test/test_gsplugin_cxx.cpp delete mode 100644 org.glite.security.gss/LICENSE delete mode 100644 org.glite.security.gss/Makefile delete mode 100755 org.glite.security.gss/configure delete mode 100644 org.glite.security.gss/interface/glite_gss.h delete mode 100644 org.glite.security.gss/project/ChangeLog delete mode 100644 org.glite.security.gss/project/package.description delete mode 100644 org.glite.security.gss/project/package.summary delete mode 100644 org.glite.security.gss/project/version.properties delete mode 100644 org.glite.security.gss/src/glite_gss.c delete mode 100644 org.glite.security.gss/test/test_gss.cpp delete mode 100644 org.glite.security.proxyrenewal/.cvsignore delete mode 100644 org.glite.security.proxyrenewal/LICENSE delete mode 100644 org.glite.security.proxyrenewal/Makefile delete mode 100755 org.glite.security.proxyrenewal/build.xml delete mode 100755 org.glite.security.proxyrenewal/config/startup delete mode 100644 org.glite.security.proxyrenewal/examples/renew_core.c delete mode 100644 org.glite.security.proxyrenewal/interface/renewal.h delete mode 100644 org.glite.security.proxyrenewal/interface/renewal_core.h delete mode 100644 org.glite.security.proxyrenewal/project/build.number delete mode 100644 org.glite.security.proxyrenewal/project/build.properties delete mode 100644 org.glite.security.proxyrenewal/project/configure.properties.xml delete mode 100755 org.glite.security.proxyrenewal/project/properties.xml delete mode 100644 org.glite.security.proxyrenewal/project/tar_exclude delete mode 100755 org.glite.security.proxyrenewal/project/taskdefs.xml delete mode 100644 org.glite.security.proxyrenewal/project/version.properties delete mode 100644 org.glite.security.proxyrenewal/src/api.c delete mode 100644 org.glite.security.proxyrenewal/src/client.c delete mode 100644 org.glite.security.proxyrenewal/src/commands.c delete mode 100644 org.glite.security.proxyrenewal/src/common.c delete mode 100644 org.glite.security.proxyrenewal/src/renew.c delete mode 100644 org.glite.security.proxyrenewal/src/renewal_core.c delete mode 100644 org.glite.security.proxyrenewal/src/renewal_locl.h delete mode 100644 org.glite.security.proxyrenewal/src/renewd.c delete mode 100644 org.glite.security.proxyrenewal/src/renewd_locl.h delete mode 100644 org.glite.security.proxyrenewal/src/voms.c delete mode 100644 org.glite.testsuites.ctb/CANL-C/tests/Makefile delete mode 100755 org.glite.testsuites.ctb/CANL-C/tests/canl-autonomous-test.sh delete mode 100755 org.glite.testsuites.ctb/CANL-C/tests/canl-common-testbeds.sh delete mode 100755 org.glite.testsuites.ctb/CANL-C/tests/canl-common.sh delete mode 100755 org.glite.testsuites.ctb/CANL-C/tests/canl-generate-fake-proxy.sh delete mode 100755 org.glite.testsuites.ctb/CANL-C/tests/canl-test-cert-handle.sh delete mode 100755 org.glite.testsuites.ctb/CANL-C/tests/canl-test-cs-openssl.sh delete mode 100755 org.glite.testsuites.ctb/CANL-C/tests/canl-test-sec-connection.sh delete mode 100755 org.glite.testsuites.ctb/CANL-C/tests/canl-test-sha2.sh delete mode 100644 org.glite.testsuites.ctb/CANL-C/tests/test-common.sh delete mode 100644 org.glite.testsuites.ctb/LB/LB-certconfig delete mode 100755 org.glite.testsuites.ctb/LB/LB-certtest.sh delete mode 100644 org.glite.testsuites.ctb/LB/Makefile delete mode 100644 org.glite.testsuites.ctb/LB/manual/Readme.txt delete mode 100644 org.glite.testsuites.ctb/LB/manual/Readme2.txt.old delete mode 100644 org.glite.testsuites.ctb/LB/tests/Makefile delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-autonomous-test.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-common-testbeds.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-common.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-generate-events.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-generate-fake-proxy.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-l2.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-l2ILR.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-l2Stat.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-run-tests.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-acl-authz.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-bdii.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-binaries.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-changeacl.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-collections.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-cream.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-event-delivery.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-harvester.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-https.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-il-recovery.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-job-registration.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-job-states.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-logevent.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-logger-local.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-logger-remote.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-nagios-probe.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-notif-keeper.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-notif-msg.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-notif-recovery.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-notif-stream.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-notif-switch.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-notif.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-packaging.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-permissions.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-proxy-delivery.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-purge.pl delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-sandbox-transfer.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-server-local.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-server-remote.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-statistics.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-switch-owner.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-threaded.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-wild.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/lb-test-ws.sh delete mode 100644 org.glite.testsuites.ctb/LB/tests/test-common.sh delete mode 100755 org.glite.testsuites.ctb/LB/tests/testSocket.c delete mode 100755 org.glite.testsuites.ctb/PX/tests/px-autonomous-test.sh delete mode 100755 org.glite.testsuites.ctb/PX/tests/px-common-testbeds.sh delete mode 100755 org.glite.testsuites.ctb/PX/tests/px-common.sh delete mode 100755 org.glite.testsuites.ctb/PX/tests/px-test-all.sh delete mode 100755 org.glite.testsuites.ctb/PX/tests/px-test-packaging.sh delete mode 100755 org.glite.testsuites.ctb/PX/tests/px-voms-install.sh delete mode 100644 org.glite.testsuites.ctb/PX/tests/test-common.sh delete mode 100755 org.glite.testsuites.ctb/gridsite/tests/gridsite-autonomous-test.sh delete mode 100755 org.glite.testsuites.ctb/gridsite/tests/gridsite-common-testbeds.sh delete mode 100755 org.glite.testsuites.ctb/gridsite/tests/gridsite-common.sh delete mode 100755 org.glite.testsuites.ctb/gridsite/tests/gridsite-test-all.sh delete mode 100755 org.glite.testsuites.ctb/gridsite/tests/gridsite-test-packaging.sh delete mode 100755 org.glite.testsuites.ctb/gridsite/tests/ping-local.sh delete mode 100755 org.glite.testsuites.ctb/gridsite/tests/ping-remote.sh delete mode 100644 org.glite.testsuites.ctb/gridsite/tests/test-common.sh delete mode 100644 org.glite.wms-utils.exception/.cvsignore delete mode 100755 org.glite.wms-utils.exception/LICENSE delete mode 100755 org.glite.wms-utils.exception/Makefile.am delete mode 100755 org.glite.wms-utils.exception/bootstrap delete mode 100755 org.glite.wms-utils.exception/build.xml delete mode 100755 org.glite.wms-utils.exception/configure.ac delete mode 100755 org.glite.wms-utils.exception/interface/Makefile.am delete mode 100644 org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h delete mode 100755 org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h delete mode 100644 org.glite.wms-utils.exception/project/build.number delete mode 100755 org.glite.wms-utils.exception/project/build.properties delete mode 100644 org.glite.wms-utils.exception/project/configure.properties.xml delete mode 100755 org.glite.wms-utils.exception/project/properties.xml delete mode 100755 org.glite.wms-utils.exception/project/version.properties delete mode 100644 org.glite.wms-utils.exception/src/Exception.cpp delete mode 100755 org.glite.wms-utils.exception/src/Makefile.am delete mode 100755 org.glite.wms-utils.exception/test/Makefile.am delete mode 100644 org.glite.wms-utils.exception/test/exception_cu_main.cpp delete mode 100644 org.glite.wms-utils.exception/test/exception_cu_suite.cpp delete mode 100644 org.glite.wms-utils.exception/test/exception_cu_suite.h delete mode 100755 org.glite.wms-utils.jobid/.cvsignore delete mode 100755 org.glite.wms-utils.jobid/LICENSE delete mode 100755 org.glite.wms-utils.jobid/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/bootstrap delete mode 100755 org.glite.wms-utils.jobid/build.xml delete mode 100755 org.glite.wms-utils.jobid/configure.ac delete mode 100755 org.glite.wms-utils.jobid/examples/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/examples/testjobid.c delete mode 100755 org.glite.wms-utils.jobid/interface/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h delete mode 100755 org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h delete mode 100644 org.glite.wms-utils.jobid/project/build.number delete mode 100755 org.glite.wms-utils.jobid/project/build.properties delete mode 100644 org.glite.wms-utils.jobid/project/configure.properties.xml delete mode 100755 org.glite.wms-utils.jobid/project/properties.xml delete mode 100755 org.glite.wms-utils.jobid/project/version.properties delete mode 100755 org.glite.wms-utils.jobid/src/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/src/jobid/JobId.cpp delete mode 100755 org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp delete mode 100755 org.glite.wms-utils.jobid/src/jobid/Makefile.am delete mode 100755 org.glite.wms-utils.jobid/src/jobid/cjobid.c delete mode 100755 org.glite.wms-utils.jobid/src/jobid/manipulation.cpp delete mode 100755 org.glite.wms-utils.jobid/src/jobid/strmd5.c delete mode 100755 org.glite.wms-utils.jobid/src/jobid/strmd5.h delete mode 100755 org.glite.wms-utils.jobid/test/Makefile.am delete mode 100644 org.glite.wms-utils.jobid/test/jobid_cu_main.cpp delete mode 100644 org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp delete mode 100644 org.glite.wms-utils.jobid/test/jobid_cu_suite.h delete mode 100644 org.glite.wms-utils.jobid/test/manipulation_cu_main.cpp delete mode 100644 org.glite.wms-utils.jobid/test/manipulation_cu_suite.cpp delete mode 100644 org.glite.wms-utils.jobid/test/manipulation_cu_suite.h delete mode 100644 org.glite.yaim.lb/.cvsignore delete mode 100755 org.glite.yaim.lb/LICENSE delete mode 100644 org.glite.yaim.lb/Makefile delete mode 100644 org.glite.yaim.lb/config/defaults/glite-lb.pre delete mode 100644 org.glite.yaim.lb/config/defaults/glite-lb_30.pre delete mode 100644 org.glite.yaim.lb/config/functions/config_gip_lb delete mode 100644 org.glite.yaim.lb/config/functions/config_gip_lb_30 delete mode 100644 org.glite.yaim.lb/config/functions/config_glite_lb delete mode 100644 org.glite.yaim.lb/config/functions/config_glite_lb_30 delete mode 100644 org.glite.yaim.lb/config/functions/config_info_service_lb delete mode 100644 org.glite.yaim.lb/config/functions/config_jobmon delete mode 100644 org.glite.yaim.lb/config/node-info.d/glite-lb delete mode 100644 org.glite.yaim.lb/config/node-info.d/glite-lb_30 delete mode 100644 org.glite.yaim.lb/glite-yaim-lb.spec delete mode 100644 org.glite.yaim.myproxy/.cvsignore delete mode 100644 org.glite.yaim.myproxy/Changelog delete mode 100755 org.glite.yaim.myproxy/LICENSE delete mode 100644 org.glite.yaim.myproxy/Makefile delete mode 100755 org.glite.yaim.myproxy/config/functions/config_gip_px delete mode 100644 org.glite.yaim.myproxy/config/functions/config_info_service_px delete mode 100644 org.glite.yaim.myproxy/config/functions/config_proxy_server delete mode 100644 org.glite.yaim.myproxy/config/man/yaim-myproxy.1 delete mode 100644 org.glite.yaim.myproxy/config/node-info.d/glite-px delete mode 100644 org.glite.yaim.myproxy/config/node-info.d/glite-px_30 delete mode 100644 org.glite.yaim.myproxy/config/services/glite-px delete mode 100644 org.glite.yaim.myproxy/glite-yaim-myproxy.spec delete mode 100644 org.gridsite.core/.cvsignore delete mode 100644 org.gridsite.core/CHANGES delete mode 100644 org.gridsite.core/INSTALL delete mode 100644 org.gridsite.core/LICENSE delete mode 100644 org.gridsite.core/README delete mode 100644 org.gridsite.core/VERSION delete mode 100644 org.gridsite.core/build.xml delete mode 100644 org.gridsite.core/doc/README.htcp-bin delete mode 100644 org.gridsite.core/doc/build-apache2.sh delete mode 100644 org.gridsite.core/doc/delegation-1.1.0.wsdl delete mode 100755 org.gridsite.core/doc/doc_gridsite.pl delete mode 100644 org.gridsite.core/doc/findproxyfile.1 delete mode 100644 org.gridsite.core/doc/fuse.spec delete mode 100644 org.gridsite.core/doc/gridsite-delegation.8 delete mode 100644 org.gridsite.core/doc/gsexec.8 delete mode 100644 org.gridsite.core/doc/gsoap-devel.spec delete mode 100644 org.gridsite.core/doc/htcp.1 delete mode 100644 org.gridsite.core/doc/htfind.1 delete mode 100644 org.gridsite.core/doc/htll.1 delete mode 100644 org.gridsite.core/doc/htls.1 delete mode 100644 org.gridsite.core/doc/htmkdir.1 delete mode 100644 org.gridsite.core/doc/htmv.1 delete mode 100644 org.gridsite.core/doc/htping.1 delete mode 100644 org.gridsite.core/doc/htproxydestroy.1 delete mode 100644 org.gridsite.core/doc/htproxyinfo.1 delete mode 100644 org.gridsite.core/doc/htproxyput.1 delete mode 100644 org.gridsite.core/doc/htproxyrenew.1 delete mode 100644 org.gridsite.core/doc/htproxytime.1 delete mode 100644 org.gridsite.core/doc/htproxyunixtime.1 delete mode 100644 org.gridsite.core/doc/htrm.1 delete mode 100644 org.gridsite.core/doc/httpd-fileserver.conf delete mode 100644 org.gridsite.core/doc/httpd-storage.conf delete mode 100644 org.gridsite.core/doc/httpd-webserver.conf delete mode 100644 org.gridsite.core/doc/index.html delete mode 100644 org.gridsite.core/doc/mod_gridsite.8 delete mode 100644 org.gridsite.core/doc/slashgrid.8 delete mode 100644 org.gridsite.core/doc/urlencode.1 delete mode 100644 org.gridsite.core/interface/gridsite-gacl.h delete mode 100644 org.gridsite.core/interface/gridsite.h delete mode 100644 org.gridsite.core/project/build.number delete mode 100644 org.gridsite.core/project/build.properties delete mode 100644 org.gridsite.core/project/compat-1.5.patch delete mode 100644 org.gridsite.core/project/configure.properties.xml delete mode 100644 org.gridsite.core/project/debian.changelog delete mode 100644 org.gridsite.core/project/debian.control delete mode 100644 org.gridsite.core/project/debian.rules delete mode 100644 org.gridsite.core/project/dependencies.properties delete mode 100644 org.gridsite.core/project/gridsite.core.csf.xml delete mode 100644 org.gridsite.core/project/properties.xml delete mode 100644 org.gridsite.core/project/taskdefs.xml delete mode 100644 org.gridsite.core/project/version.properties delete mode 100644 org.gridsite.core/src/Doxyfile delete mode 100644 org.gridsite.core/src/Makefile delete mode 100644 org.gridsite.core/src/delegation.h delete mode 100644 org.gridsite.core/src/doxygen.css delete mode 100644 org.gridsite.core/src/doxyheader.html delete mode 100644 org.gridsite.core/src/findproxyfile.c delete mode 100644 org.gridsite.core/src/gaclexample.c delete mode 100644 org.gridsite.core/src/gridsite-copy.c delete mode 100644 org.gridsite.core/src/gridsite-globus.pc.in delete mode 100644 org.gridsite.core/src/gridsite-openssl.pc.in delete mode 100644 org.gridsite.core/src/gridsite-storage.c delete mode 100644 org.gridsite.core/src/grst-delegation.c delete mode 100644 org.gridsite.core/src/grst_admin.h delete mode 100644 org.gridsite.core/src/grst_admin_file.c delete mode 100644 org.gridsite.core/src/grst_admin_gacl.c delete mode 100644 org.gridsite.core/src/grst_admin_main.c delete mode 100644 org.gridsite.core/src/grst_asn1.c delete mode 100644 org.gridsite.core/src/grst_err.c delete mode 100644 org.gridsite.core/src/grst_gacl.c delete mode 100644 org.gridsite.core/src/grst_htcp.c delete mode 100644 org.gridsite.core/src/grst_http.c delete mode 100644 org.gridsite.core/src/grst_x509.c delete mode 100644 org.gridsite.core/src/grst_xacml.c delete mode 100644 org.gridsite.core/src/gsexec.c delete mode 100644 org.gridsite.core/src/gsexec.h delete mode 100644 org.gridsite.core/src/htcp.c delete mode 100644 org.gridsite.core/src/htproxyput.c delete mode 100644 org.gridsite.core/src/make-debian-files delete mode 100755 org.gridsite.core/src/make-gridsite-spec delete mode 100644 org.gridsite.core/src/mod_gridsite.c delete mode 100644 org.gridsite.core/src/mod_gridsite_example.c delete mode 100644 org.gridsite.core/src/mod_ssl-private.h delete mode 100755 org.gridsite.core/src/roffit delete mode 100644 org.gridsite.core/src/showx509exts.c delete mode 100644 org.gridsite.core/src/slashgrid.c delete mode 100755 org.gridsite.core/src/slashgrid.init delete mode 100644 org.gridsite.core/src/urlencode.c delete mode 100644 org.gridsite.core/src/xacmlexample.c diff --git a/emi.canl.canl-c/Makefile b/emi.canl.canl-c/Makefile deleted file mode 100644 index 39195fb..0000000 --- a/emi.canl.canl-c/Makefile +++ /dev/null @@ -1,169 +0,0 @@ -top_srcdir=. -stagedir=$(pwd) -PREFIX= -prefix=/usr -libdir=lib - --include Makefile.inc --include ${top_srcdir}/project/version.properties - -VPATH=${top_srcdir}/src/:${top_srcdir}/src/proxy/:${top_srcdir}/examples:${top_srcdir}/doc/src -KPATH = TEXINPUTS=".:${top_srcdir}/doc/src//:" -KPATHBIB = BIBINPUTS=".:$(VPATH)//:" -LIBCARES_LIBS?=-lcares -LIBSSL_LIBS?=-lssl - -CC=gcc -YACC=bison -y -LEX=flex -PDFLATEX = $(KPATH) pdflatex -BIBTEX = $(KPATHBIB) bibtex - -COMPILE=libtool --mode=compile ${CC} ${CFLAGS} -LINK=libtool --mode=link ${CC} ${LDFLAGS} -INSTALL=libtool --mode=install install - -CFLAGS_LIB=-fPIC -I${top_srcdir}/src ${LIBCARES_CFLAGS} ${LIBSSL_CFLAGS} -I. -LFLAGS_LIB=-shared ${LIBCARES_LIBS} ${LIBSSL_LIBS} - -CFLAGS_CLI=-I${top_srcdir}/src -I. -LFLAGS_CLI=-L. -lcanl_c - -CFLAGS_SER=-Wall -g -I${top_srcdir}/src -I. -LFLAGS_SER=-L. -lcanl_c - -CFLAGS_PRX=-Wall -g -I${top_srcdir}/src -I. -LFLAGS_PRX=-L. -lcanl_c - -CFLAGS_DEL=-Wall -g -I${top_srcdir}/src -I. -LFLAGS_DEL=-L. -lcanl_c -lcrypto - -HEAD_CANL=canl.h canl_locl.h canl_err.h canl_cred.h canl_ssl.h canl_mech_ssl.h - -SRC_CLI=canl_sample_client.c -HEAD_CLI=canl.h -OBJ_CLI=canl_sample_client.lo - -SRC_SER=canl_sample_server.c -HEAD_SER=canl.h -OBJ_SER=canl_sample_server.lo - -SRC_PRX=grid-proxy-init.c -HEAD_PRX=canl.h canl_cred.h -OBJ_PRX=canl_proxy_init.lo - -SRC_DEL=delegation.c -HEAD_DEL=canl.h canl_cred.h -OBJ_DEL=canl_delegation.lo - -CFLAGS:=-Wall -g -I${top_srcdir}/src/proxy -I. ${CFLAGS} - -LIBCANL=libcanl_c.la - -# In order to use libtool versioning correcty, we must have: -# -# current = major + minor + offset -# revision = patch -# age = minor -# -# where offset is a sum of maximal released minor's of all previous major's -# -offset=0 -version_info:=-version-info ${shell \ - perl -e '$$,=":"; @F=split "\\.","${module.version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } -major:=${shell \ - perl -e '$$,=":"; @F=split "\\.","${module.version}"; print $$F[0]+$$F[1]+${offset}' } - -all: ${LIBCANL} server client proxy delegation - -doc: canl.pdf - -${LIBCANL}:\ - canl.lo canl_err.lo canl_dns.lo canl_ssl.lo canl_cert.lo canl_cred.lo \ - canl_err_desc.lo doio.lo evaluate.lo list.lo normalize.lo proxycertinfo.lo \ - scutils.lo sslutils.lo data.lo namespaces_parse.lo namespaces_lex.lo \ - signing_policy_parse.lo signing_policy_lex.lo - ${LINK} -rpath ${stagedir}${prefix}/${libdir} ${version_info} $+ ${LFLAGS_LIB} -o $@ - -%.lo: %.y - ${YACC} -d ${YFLAGS} $< - mv y.tab.c $*.c - mv y.tab.h $*.h - ${COMPILE} -c ${CFLAGS_LIB} $*.c - -%.c: %.l -# ${LEX} -t $< > $@ - cp `echo $< | sed -e 's/\.l$$/.c.in/'` $@ - -%.lo: %.c ${HEAD_CANL} - ${COMPILE} -c $< ${CFLAGS_LIB} -o $@ - -%.pdf: %.tex - $(PDFLATEX) $< -# $(BIBTEX) `basename $< .tex` - $(PDFLATEX) $< - $(PDFLATEX) $< - -canl.tex: ver.tex - -client: ${OBJ_CLI} - ${LINK} $< ${LFLAGS_CLI} -o $@ - -${OBJ_CLI}: ${SRC_CLI} ${HEAD_CLI} ${LIBCANL} - ${COMPILE} -c ${top_srcdir}/examples/${SRC_CLI} ${CFLAGS_CLI} -o $@ - -server: ${OBJ_SER} - ${LINK} $< ${LFLAGS_SER} -o $@ - -${OBJ_SER}: ${SRC_SER} ${HEAD_SER} ${LIBCANL} - ${COMPILE} -c ${top_srcdir}/examples/${SRC_SER} ${CFLAGS_SER} -o $@ - -proxy: ${OBJ_PRX} - ${LINK} $< ${LFLAGS_PRX} -o $@ - -${OBJ_PRX}: ${SRC_PRX} ${HEAD_PRX} ${LIBCANL} - ${COMPILE} -c ${top_srcdir}/examples/${SRC_PRX} ${CFLAGS_PRX} -o $@ - -delegation: ${OBJ_DEL} - ${LINK} $< ${LFLAGS_DEL} -o $@ - -${OBJ_DEL}: ${SRC_DEL} ${HEAD_DEL} ${LIBCANL} - ${COMPILE} -c ${top_srcdir}/examples/${SRC_DEL} ${CFLAGS_DEL} -o $@ - -canl_err.h: canl_error_codes - ${top_srcdir}/src/gen_err_codes.pl < $^ > $@ - -canl_err_desc.c: canl_error_codes canl_error_desc - ${top_srcdir}/src/gen_err_desc.pl $^ > $@ - -ver.tex: - printf "\134def\134version{${module.version}}\n" > ver.tex - -check: - -install: all - mkdir -p ${DESTDIR}${PREFIX}${prefix}/bin - mkdir -p ${DESTDIR}${PREFIX}${prefix}/${libdir} - mkdir -p ${DESTDIR}${PREFIX}${prefix}/include - ${INSTALL} -m 755 server ${DESTDIR}${PREFIX}${prefix}/bin/emi-canl-server - ${INSTALL} -m 755 client ${DESTDIR}${PREFIX}${prefix}/bin/emi-canl-client - ${INSTALL} -m 755 proxy \ - ${DESTDIR}${PREFIX}${prefix}/bin/emi-canl-proxy-init - ${INSTALL} -m 755 delegation \ - ${DESTDIR}${PREFIX}${prefix}/bin/emi-canl-delegation - ${INSTALL} -m 755 ${LIBCANL} ${DESTDIR}${PREFIX}${prefix}/${libdir} - ${INSTALL} -m 644 ${top_srcdir}/src/canl.h \ - ${top_srcdir}/src/canl_ssl.h canl_err.h \ - ${DESTDIR}${PREFIX}${prefix}/include - -stage: all - $(MAKE) install PREFIX=${stagedir} - -clean: - rm -rfv *.o *.lo ${LIBCANL} .libs client server proxy delegation \ - ${top_srcdir}/*.c ${top_srcdir}/*.h lex.backup stage \ - canl.aux canl.log canl.pdf canl.out canl.toc ver.tex \ - canl.bbl canl.blg - -distclean: - rm -rvf Makefile.inc config.status project/changelog *.spec debian/ diff --git a/emi.canl.canl-c/configure b/emi.canl.canl-c/configure deleted file mode 100755 index bcb1531..0000000 --- a/emi.canl.canl-c/configure +++ /dev/null @@ -1,2058 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; -use POSIX qw(locale_h strftime); - -my $pwd = `pwd`; chomp $pwd; -my $prefix = '/usr'; -my $stagedir = undef; -my $root = $pwd.'/stage'; -my $sysroot = ''; -my $sysconfdir; -my $localstatedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my ($version, $force_version); -my $branch; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $jobid_tag = ''; -my $libdir = getlibdir(); -my $project = 'emi'; -my $project_version; -my (%projects, %project); -my $debug = 0; -my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : ''; - -my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal/; -my @default_nodes = qw/lb px proxyrenewal nagios/; -my %enable_nodes; -my %disable_nodes; -my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1); - -my %package = ( - 'maintainer' => 'CESNET Product Teams ', - 'uploaders' => 'FrantiÅ¡ek Dvořák ', - 'url' => 'http://glite.cern.ch', - 'debian_vcs' => 'Vcs-Cvs: :pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw -Vcs-Browser: http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi', -); - -# key: internal package name (arguments, ...) -# 'pkg': pkg-config name -# 'prefix': used when pkg-config fails -my %externs = ( - cares => { - prefix => '/opt/c-ares', - pkg => 'libcares' - }, - classads => { - prefix=> '/usr', - pkg => 'classads' - }, - cppunit => { - prefix=> '/usr', - pkg => 'cppunit' - }, - expat => { - prefix=> '/usr', - pkg => 'expat' - }, - globus => { - prefix=> '/opt/globus', - pkg => 'globus-gssapi-gsi' - }, - 'myproxy-devel' => { - prefix=> '/opt/globus', - pkg => 'myproxy' - }, - 'myproxy-server' => { - prefix=> '', - }, - 'myproxy-admin' => { - prefix=> '', - }, - gsoap => { - prefix=> '/usr', - pkg => 'gsoap' - }, - gsoapxx => { - prefix=> '/usr', - pkg => 'gsoap++' - }, - mysql => { - prefix=> '/usr' - }, - 'mysql-devel' => { - prefix=> '' - }, - 'mysql-server' => { - prefix => '' - }, - voms => { - prefix => '/opt/glite', - pkg => 'voms-2.0' - }, - gridsite => { - prefix => '/opt/glite' - }, - lcas => { - prefix => '/opt/glite', - pkg => 'lcas' - }, - trustmanager => { - prefix => '/opt/glite' - }, - trustmanager_axis => { - prefix => '/opt/glite' - }, - utiljava => { - prefix=> '/opt/glite' - }, - ant => { - prefix=> '/usr' - }, - jdk => { - prefix=> '/usr/java/latest', - locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ], - }, - libtar => { - prefix=> '/usr' - }, - axis => { - prefix=> '/usr' - }, - log4c => { - prefix=> '/usr' - }, - postgresql => { - prefix=> '/usr' - }, - activemq => { - prefix=>'/opt/activemq-cpp-library', - pkg => 'activemq-cpp' - }, -); - -my %jar = ( - 'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar', - 'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %buildroot; -my (%etics_externs, %etics_projects); - -# -# modules of the subsystems -# -# additional modules from $project{modules} are automatically added -# -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], - 'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/], - 'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - 'gridsite' => [ qw/apache libs commands core devel slashgrid services service-clients gsexec/ ], - 'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ], - 'canl' => [ qw/c c-devel/ ], - ); - -# -# sub-packages -# -# modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly -# -my %subpackages = ( - 'jobid.api-c-devel' => 'jobid.api-c', - 'jobid.api-cpp-devel' => 'jobid.api-cpp', - 'lbjp-common.db-devel' => 'lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'lbjp-common.log', - 'lbjp-common.maildir-devel' => 'lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'lbjp-common.trio', - 'lb.client-progs' => 'lb.client', - 'lb.client-devel' => 'lb.client', - 'lb.common-devel' => 'lb.common', - 'lb.logger-devel' => 'lb.logger', - 'lb.state-machine-devel' => 'lb.state-machine', - 'px.proxyrenewal-devel' => 'px.proxyrenewal', - 'px.proxyrenewal-progs' => 'px.proxyrenewal', - 'canl.c-devel' => 'canl.c', -); - -my @opts = ( - 'prefix:s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour:s' => \$thrflavour, - 'nothrflavour:s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$force_version, - 'branch=s' => \$branch, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'root:s' => \$root, - 'sysroot:s' => \$sysroot, - 'sysconfdir=s' => \$sysconfdir, - 'localstatedir=s' => \$localstatedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'jobid-tag=s' => \$jobid_tag, - 'canl-tag=s' => \$canl_tag, - 'help' => \$help, - 'libdir=s' => \$libdir, - 'project=s' => \$project, - 'debug' => \$debug, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; -$prefix=~s/\/$//; -$root=~s/\/$//; -$sysroot=~s/\/$//; -if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; } -if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; } -$sysconfdir=~s/\/$//; -$localstatedir=~s/\/$//; - -$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq ''; -$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq ''; -$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq ''; - -$externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq ''; -$externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq ''; -$externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq ''; - -if ($project =~ /^([^0-9]*)(.*)$/) { - $project = $1; - $project_version = $2; -} -%project = %{$projects{$project}}; -$project_version = $project{current_version} unless $project_version; -for my $platform (keys %{$project{etics_externs}}) { - for $_ (keys %{$project{etics_externs}{$platform}}) { - $etics_externs{$platform}{$_} = $project{etics_externs}{$platform}{$_}; - } -} -reshuffle_platforms(\%etics_externs, $project{supported_platforms}); -reshuffle_platforms(\%{$project{etics_externs_devel}}, $project{supported_platforms}); -for $_ (keys %{$project{etics_projects}}) { - $etics_projects{$_} = $project{etics_projects}{$_}; -} -for $_ (keys %{$project{need_externs_aux}}) { - $need_externs_aux{$_} = $project{need_externs_aux}{$_}; -} -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - my ($pkg, $type) =/([^:]*)(?::(.*))?/; - $type = 'BR' unless ($type); - - push @{$need_externs{$ext}},$pkg; - $need_externs_type{$ext}->{$pkg} = $type; - } -} -if ($project eq 'emi') { - $extranodmod{lb} = 'lb.emi-lb'; - $extranodmod{px} = 'px.emi-px'; -} -for $_ (keys %{$project{modules}}) { - push @{$lbmodules{$_}},@{$project{modules}{$_}}; -} - - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name}; - my @m; - - if (exists $lbmodules{$listmodules}) { - @m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}}; - } else { - if ($project eq 'emi' and $project_version == 1) { - # no sub-packages in EMI-1 - } else { - for my $sub (keys %subpackages) { - push @m, $sub if ($subpackages{$sub} eq $listmodules); - } - } - } - print map $_ eq "" ? "" : "$_ ", @m; - print "\n"; - exit 0; -} - -warn "$0: --branch and --output make sense only in --mode=etics\n" - if ($output || $branch) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_}); - } -} - -if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } }; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $root unless $stagedir; -$stagedir=~s/\/$// if ($stagedir); - -if ($mode eq 'build') { for my $ext (keys %externs) { - if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; } - elsif (defined $externs{$ext}{pkg}) { - my ($flag, $env, $cmd, $ret); - my $pkg = $externs{$ext}{pkg}; - my $flagname = uc $externs{$ext}{pkg}; - $flagname =~ s/-[0-9\.]*$//; - $flagname =~ y/-\+/_X/; - - print "Checking $pkg ... "; - $env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig"; - $cmd = "$env pkg-config $pkg --exists >/dev/null"; - `$cmd`; $ret = $?; - print "('$cmd' => $ret)\n" if ($debug); - if ($ret == 0) { - $externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`; - chomp $externs{$ext}{prefix}; - print "$externs{$ext}{prefix}\n"; - - $flag=`$env pkg-config $pkg --cflags`; - $externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag); - $flag=`$env pkg-config $pkg --libs`; - $externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag); - } else { - print "(using default $externs{$ext}{prefix})\n"; - } - print "\n" if ($debug); - } - elsif ($ext eq 'jdk') { - my $jdk_prefix; - - print "Looking for some caffein ... "; - if (defined $ENV{'JDK_HOME'}) { - $jdk_prefix = $ENV{'JDK_HOME'}; - print "JDK_HOME=$jdk_prefix\n"; - } elsif (defined $ENV{'JAVA_HOME'}) { - $jdk_prefix = $ENV{'JAVA_HOME'}; - print "JAVA_HOME=$jdk_prefix\n"; - } else { - foreach my $i (0..$#{$externs{$ext}{locations}}) { - if (-e $externs{$ext}{locations}[$i]) { - $jdk_prefix=$externs{$ext}{locations}[$i]; - print "(found directory $jdk_prefix)\n"; - last; - } - } - print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix); - } - $externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix); - } -} } - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') { - print CONF "$_=$ENV{$_} " if (defined $ENV{$_}); - } - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } }; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - if ($module) { - print "Not creating summary Makefile\n" if $debug; - } else { - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\n"; - print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n"; - print MAK "clean check install:\n"; - - for (@modules) { - my $full = full($_); - print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $buildroot{$_} eq '' ? - "\tcd $full && \${MAKE} distclean\n" : - "\trm -rf $full/$buildroot{$_}\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage'; - - my $full = full($_); - my $build = $buildroot{$_}; - - print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n"; - print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n"; - } - - close MAK; - } -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag) { - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - if ($canl_tag) { - for (@{$lbmodules{'canl'}}){ - if ("canl.".$_ eq $module){ - $tag = '-r '.$canl_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%etics_externs = ( - default => { - 'myproxy-devel'=>'myproxy-devel', - 'myproxy-server'=>'myproxy-server', - 'myproxy-admin'=>'myproxy-admin', - cares=>'c-ares', - utiljava=>'org.glite.security.util-java', - gpt=>'gpt', - fetchcrl=>'fetch-crl', - activemq=>'activemq-cpp-library', - }, -); - -%etics_projects = ( -); - -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads libtool:B globus:B/ ], - 'lb.common' => [ qw/expat cares:B cppunit:B classads libtool:B globus:B/ ], - 'lb.doc' => [ qw/tetex-latex:B/ ], - 'lb.logger' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B globus:B/ ], - 'lb.nagios' => [ qw/globus_proxy_utils:R/ ], - 'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql-server:R cppunit:B gsoap:B classads voms:B lcas gridsite:B bison:B libtool:B libxml2 flex:B/ ], - 'lb.state-machine' => [ qw/classads libtool:B libxslt:B expat:B globus:B/ ], - 'lb.utils' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ], - 'lb.ws-test' => [ qw/gsoap:B libtool:B globus:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/docbook-utils:B libtool:B globus:B/ ], - 'lbjp-common.db' => [ qw/mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.log' => [ qw/log4c libtool:B/ ], - 'lbjp-common.maildir' => [ qw/libtool:B/ ], - 'lbjp-common.server-bones' => [ qw/libtool:B/ ], - 'lbjp-common.trio' => [ qw/cppunit:B libtool:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.gss' => [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B/ ], - 'lbjp-common.gsoap-plugin' => [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B/ ], - 'jobid.api-c' => [ qw/cppunit:B libtool:B openssl:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B libtool:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus_essentials:R globus:B mysql-server:R/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B mysql-server:R/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], - 'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'gridsite.commands' => [ qw/curl:R openssl:R/ ], - 'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ], - 'gridsite.libs' => [ qw/libxml2:R openssl:R/ ], - 'gridsite.devel' => [ qw// ], - 'gridsite.slashgrid' => [ qw/curl:R fuse:R/], - 'gridsite.services' => [ qw/curl:R gsoap:R/ ], - 'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ], - 'gridsite.gsexec' => [ qw// ], - 'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B/ ], - 'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec - 'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B krb5-devel:B/ ], -); - -%need_jars = ( - 'jobid.api-java' => [ qw/jakarta-commons-codec/ ], - 'lb.client-java' => [ qw/jakarta-commons-lang/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp:B jobid.api-c - lbjp-common.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - lb.ws-interface:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp:B jobid.api-c - lb.types:B lbjp-common.trio lbjp-common.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - lbjp-common.log - jobid.api-c - lb.common - lbjp-common.gss - / ], - 'lb.logger-msg' => [ qw/ - lb.logger:B - / ], - 'lb.nagios' => [ qw/ - lb.client:R - lb.ws-test:R - lb.utils:R - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log - jobid.api-c - lbjp-common.gsoap-plugin lbjp-common.gss - / ], - 'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine lb.types:B - / ], - 'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/ - jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client - lbjp-common.gss lbjp-common.log - / ], - 'lb.yaim' => [ qw// ], - 'lb.glite-LB' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lb.emi-lb' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.log' => [ qw// ], - 'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ], - 'lbjp-common.trio' => [ qw// ], - 'lbjp-common.gss' => [ qw// ], - 'lbjp-common.gsoap-plugin' => [ qw/lbjp-common.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - lbjp-common.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], - - 'gridsite.core' => [ qw// ], - 'gridsite.commands' => [ qw/gridsite.core:B/ ], - 'gridsite.apache' => [ qw/gridsite.core:B/ ], - 'gridsite.libs' => [ qw/gridsite.core:B / ], - 'gridsite.devel' => [ qw/gridsite.core:B/ ], - 'gridsite.slashgrid' => [ qw/gridsite.core:B/], - 'gridsite.services' => [ qw/gridsite.core:B/ ], - 'gridsite.service-clients' => [ qw/gridsite.core:B/ ], - 'gridsite.gsexec' => [ qw/gridsite.core:B/ ], - - 'px.proxyrenewal' => [ qw// ], - 'px.glite-PX' => [qw/px.myproxy-yaim:R/], - 'px.emi-px' => [qw/px.myproxy-yaim:R/], - 'px.myproxy-yaim' => [ qw// ], - 'px.myproxy-config' => [], - - 'canl.c' => [], - - # sub-packages (virtual ETICS components depending on the main) - 'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ], - 'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ], - 'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ], - 'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ], - 'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ], - 'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ], - 'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ], - 'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ], - 'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ], - 'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ], - 'lb.client-progs' => [ qw/lb.client:B/ ], - 'lb.client-devel' => [ qw/lb.client:B/ ], - 'lb.common-devel' => [ qw/lb.common:B/ ], - 'lb.logger-devel' => [ qw/lb.logger:B/ ], - 'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ], - 'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ], - 'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ], - 'canl.c-devel' => [ qw/canl.c:B/ ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( - gridsite=>'org.gridsite.core', - 'canl.c' => 'emi.canl.canl-c', - 'canl.c-devel' => 'emi.canl.canl-c', - 'jobid.api-c-devel' => 'org.glite.jobid.api-c', - 'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp', - 'lbjp-common.db-devel' => 'org.glite.lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'org.glite.lbjp-common.log', - 'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio', - 'lb.client-devel' => 'org.glite.lb.client', - 'lb.client-progs' => 'org.glite.lb.client', - 'lb.common-devel' => 'org.glite.lb.common', - 'lb.logger-devel' => 'org.glite.lb.logger', - 'lb.state-machine-devel' => 'org.glite.lb.state-machine', - 'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal', - 'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal', -); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', - lb => 'lb.glite-LB', - px => 'px.glite-PX', - proxyrenewal => 'px.proxyrenewal', - canl => 'canl.c', -); - -%obsoletes = ( - 'lb.yaim' => [ qq/glite-yaim-lb/ ], - 'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ], - 'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ], - 'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], -); - -%conflicts = ( -); - -%provides = ( - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], - 'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ], -); - -%cvs_prefix = ( - 'lb' => 'org.glite', - 'jp' => 'org.glite', - 'jobid' => 'org.glite', - 'lbjp-common' => 'org.glite', - 'gridsite' => 'org', - 'px' => 'org.glite', - 'canl' => 'emi', -); - -%cvs_tag_prefix = ( - 'lb' => 'glite-', - 'jp' => 'glite-', - 'jobid' => 'glite-', - 'lbjp-common' => 'glite-', - 'gridsite' => '', - 'px' => 'glite-', - 'canl' => 'emi-', -); - -# ==== projects specification ==== -# etics_name ........... ETICS project name -# conf_prefix .......... ETICS configurations name prefix -# tag_prefix ........... VCS tag prefix -# local_prefix ......... prefix (relative to stage) -# etics_externs ........ ETICS modules names of externals -# (${NAME.location}, ETICS conf. dependencies) -# etics_projects ....... ETICS project names of externals -# etics_externs_devel .. ETICS modules names of devel versions of externals -# etics_locations ...... ETICS locations in ${NAME.location} properties -# need_externs_aux ..... project-specific external dependencies -# supported_platforms .. platforms supported by the project -# modules .............. additional modules in subsystems -%projects = ( - glite => { - current_version => 3, - etics_name => 'org.glite', - conf_prefix => { %cvs_tag_prefix }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}', - local_prefix => '', - etics_externs => { - default => { - globus_essentials=>'vdt_globus_essentials', - globus=>'globus', - globus_proxy_utils=>'vdt_globus_essentials', - gridsite=>'org.gridsite.libs', - yaim_core=>'org.glite.yaim.core', - gip_release=>'glite-info-provider-release', - gip_service=>'glite-info-provider-service', - bdii=>'bdii', - glite_version=>'glite-version', - glite_info_templates=>'glite-info-templates', - glue_schema=>'glue-schema', - trustmanager=>'org.glite.security.trustmanager', - axis=>'axis', - lcas=>'org.glite.security.lcas', - gsoapxx=>'-', - jdk=>'jdk', - voms=>'org.glite.security.voms-api-cpp', - }, - }, - etics_externs_devel => { - default => { - gridsite=>'org.gridsite.devel', - voms=>'org.glite.security.voms-api', - }, - }, - etics_projects => { - vdt=>[qw/globus globus_essentials globus_proxy_utils gpt/], - 'org.glite'=>[qw/voms gridsite lcas gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/], - }, - etics_locations => { - '*' => '', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ], - 'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R/ ], - 'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412 => 1, - sl5_ia32_gcc412 => 1, - deb5_x86_64_gcc432 => 1, - deb5_ia32_gcc432 => 1, - slc4_x86_64_gcc346 => 1, - slc4_ia32_gcc346 => 1, - }, - modules => { - 'lb' => [ qw/glite-LB/ ], - 'px' => [ qw/glite-PX/ ], - }, - }, - - emi => { - current_version => 2, - etics_name => 'emi', - conf_prefix => { - 'lb' => 'emi-', - 'jp' => 'emi-', - 'jobid' => 'emi-', - 'lbjp-common' => 'emi-', - 'gridsite' => 'emi-', - 'px' => 'emi-', - 'canl' => 'emi-', - }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour= --nothrflavour=', - local_prefix => '/usr', - etics_externs => { - default => { - globus_essentials=>'globus-gssapi-gsi', - globus=>'globus-gssapi-gsi-devel', - globus_proxy_utils=>'globus-proxy-utils', - gridsite=>'emi.gridsite.libs', - yaim_core=>'emi.yaim.yaim-core', - yaim_bdii=>'emi.bdii.yaim-bdii', - gip_service=>'emi.bdii.glite-info-provider-service', - bdii=>'emi.bdii.core', - glite_version=>'emi.emi-version', - glue_schema=>'emi.bdii.glue-schema', - trustmanager=>'emi.java-security.trustmanager', - trustmanager_axis=>'emi.java-security.trustmanager-axis', - axis=>'axis1.4', - lcas=>'emi.sac.lcas', - gsoapxx=>'-', - jdk=>'java', - voms => 'emi.voms.voms-api', - }, - sl5_x86_64_gcc412EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - sl6_x86_64_gcc446EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - deb6_x86_64_gcc445 => { - axis => 'axis1.4', - # mappings in ETICS project configuration - #globus_essentials => 'libglobus-gssapi-gsi4', - #globus => 'libglobus-gssapi-gsi-dev', - #axis => 'libaxis-java', - #cares => 'libc-ares2', - #cppunit => 'libcppunit', - #expat => 'libexpat1', - #log4c => 'liblog4c3', - #curl => 'libcurl3', - #'mysql' => 'libmysqlclient16', - #'mysql-devel' => 'libmysqlclient-dev', - #libxslt => 'xsltproc', - #'jakarta-commons-codec' => 'libcommons-codec-java', - #'jakarta-commons-lang' => 'libcommons-lang-java', - #'tetex-latex' => 'texlive-latex-extra', - #'perl-LDAP' => 'libnet-ldap-perl', - #'fuse-lib' => 'libfuse2', - #'fuse' => 'fuse-utils', - }, - }, - etics_externs_devel => { - default => { - cares => 'c-ares-devel', - classads => 'classads-devel', - cppunit => 'cppunit-devel', - expat => 'expat-devel', - gsoap => 'gsoap-devel', - voms => 'emi.voms.voms-api-devel', - libtar => 'libtar-devel', - log4c => 'log4c-devel', - postgresql => 'postgresql-devel', - curl => 'curl-devel', - libxml2 => 'libxml2-devel', - openssl => 'openssl-devel', - gridsite=>'emi.gridsite.devel', - jdk=>'java-devel', - }, - deb6_x86_64_gcc445 => { - # mappings in ETICS project configuration - #cares => 'libc-ares-dev', - #cppunit => 'libcppunit-dev', - #expat => 'libexpat1-dev', - #libtar => 'libtar-dev', - #log4c => 'liblog4c-dev', - #postgresql => 'libpq-dev', - #curl => 'libcurl4-openssl-dev', - #libxml2 => 'libxml2-dev', - #openssl => 'libssl-dev', - #'tetex-latex' => 'texlive-latex-extra', - #libxslt=>'xsltproc', - #'httpd-devel' => 'apache2-prefork-dev', - #'fuse-devel' => 'libfuse-dev', - #gsoap => 'gsoap', - #'krb5-devel' => 'libkrb5-dev', - }, - }, - etics_projects => { - 'emi'=>[qw/voms voms-devel gridsite lcas gip_service bdii glite_version glue_schema yaim_core yaim_bdii trustmanager trustmanager_axis/], - }, - etics_locations => { - axis => 'axis', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ], - 'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - 'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412EPEL => 1, - sl5_ia32_gcc412EPEL => 1, - sl6_x86_64_gcc446EPEL => 1, - deb6_x86_64_gcc445 => 1, - }, - modules => { - 'lb' => [ qw/emi-lb/ ], - 'px' => [ qw/emi-px/ ], - }, - }, -); - -%platform_properties = ( - 'jobid.api-java' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.types' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.doc' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.ws-interface' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.nagios' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.myproxy-config' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'gridsite.devel' => { - default => { 'packageName' => 'gridsite-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' }, - }, - 'jobid.api-c-devel' => { - default => { 'packageName' => 'glite-jobid-api-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' }, - }, - 'jobid.api-cpp-devel' => { - default => { 'packageName' => 'glite-jobid-api-cpp-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' }, - }, - 'lbjp-common.db-devel' => { - default => { 'packageName' => 'glite-lbjp-common-db-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' }, - }, - 'lbjp-common.gsoap-plugin-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' }, - }, - 'lbjp-common.gss-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gss-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' }, - }, - 'lbjp-common.jp-interface-devel' => { - default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' }, - }, - 'lbjp-common.log-devel' => { - default => { 'packageName' => 'glite-lbjp-common-log-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' }, - }, - 'lbjp-common.maildir-devel' => { - default => { 'packageName' => 'glite-lbjp-common-maildir-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' }, - }, - 'lbjp-common.server-bones-devel' => { - default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' }, - }, - 'lbjp-common.trio-devel' => { - default => { 'packageName' => 'glite-lbjp-common-trio-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' }, - }, - 'lb.client-devel' => { - default => { 'packageName' => 'glite-lb-client-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' }, - }, - 'lb.common-devel' => { - default => { 'packageName' => 'glite-lb-common-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' }, - }, - 'lb.state-machine-devel' => { - default => { 'packageName' => 'glite-lb-state-machine-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' }, - }, - 'lb.logger-devel' => { - default => { 'packageName' => 'glite-lb-logger-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' }, - }, - 'px.proxyrenewal-devel' => { - default => { 'packageName' => 'glite-px-proxyrenewal-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' }, - }, -); - -my @k = keys %deps_aux; -@buildroot{@k} = ('') x ($#k+1); - -$buildroot{'gridsite.core'} = 'src'; -} - -sub full -{ - my ($short) = @_; - my $subsys = $short; - $subsys =~ s/\..*//; - - my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite'; - return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short"; -} - -sub get_version -{ - my ($fmod, $top_srcdir) = @_; - - my ($subsys,$mod) = split /\./,$fmod,2; - my ($major,$minor,$rev,$age); - my $old_; - - if ($force_version) { - $force_version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - my $path = "$top_srcdir/project"; - if ($subsys eq 'gridsite') { - $path = "$cvs_prefix{$subsys}.$subsys.core/project"; - } - open V,"$path/version.properties" - or die "$path/version.properties: $!\n"; - - $old_ = $_; - while () { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - $_ = $old_; - } - $version = "$major.$minor.$rev-$age"; - - return ($major, $minor, $rev, $age); -} - -sub get_description -{ - my ($top_srcdir) = @_; - - my $cvs_module = $top_srcdir; - my $package_description = ""; - my $package_summary = ""; - - if (-e "$cvs_module/project/package.description") { - open V, "$cvs_module/project/package.description"; - $package_description = join ("", ); - close V; - chomp $package_description; - } - else { - print STDERR "package.description not found for $subsys.$module!\n"; } - - if (-e "$cvs_module/project/package.summary") { - open V, "$cvs_module/project/package.summary"; - $package_summary = join ("", ); - close V; - chomp $package_summary; - $package_summary =~ s/\n/\\n/g; - } - else { - print STDERR "package.summary not found for $subsys.$module!\n"; } - - return ($package_summary, $package_description); -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb -lbjp-common.gss lbjp-common.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px -canl.c -/; - @aux{@m} = (1) x ($#m+1); - - my ($short) = @_; - my $full = full $short; - my ($subsys,$mod) = split /\./,$short,2; - my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}"; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $top_srcdir = '.'; - my $abs_srcdir = ''; - my $build = ''; - - if ($module) { - $top_srcdir = $0; - $top_srcdir =~ s,/?[^/]*$,,; - $abs_srcdir = $top_srcdir; - $top_srcdir =~ s,^$,\.,; - } else { - $build = "$full/"; - $abs_srcdir = "$full/"; - unless ($buildroot{$_} eq '') { - $top_srcdir = '..'; - $build .= "$buildroot{$_}/"; - unless (-d "$build") { - mkdir "$build" or die "mkdir $build: $!\n"; - } - } - } - - my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir; - my ($package_summary, $package_description) = get_description $abs_srcdir; - if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; } - my $package_description_debian = $package_description; - $package_description_debian =~ s/^/ /mg; - - my ($old_locale, $specdate, $debdate); - - # files for ETICS always in root source directory - mkdir $abs_srcdir."project" unless (-d $abs_srcdir."project"); - open PKGCHL,">".$abs_srcdir."project/changelog" - or die $abs_srcdir."project/changelog: $!\n"; - $old_locale = setlocale(LC_TIME); - setlocale(LC_TIME, "C"); - $specdate = strftime("%a %b %d %Y", gmtime()); - $debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime()); - setlocale(LC_TIME, $old_locale); - print PKGCHL qq{* $specdate CESNET team -- automatically generated package -}; - close PKGCHL; - - unless ($top_srcdir eq '.') { - unlink $build."Makefile"; - symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n"; - } - - open MKINC,">".$build."Makefile.inc" - or die $build."Makefile.inc: $!\n"; - - print "Creating ".$build."Makefile.inc\n"; - - print MKINC qq{project = $project -PREFIX = $root -prefix = $prefix -stagedir = $stagedir -sysroot = $sysroot -sysconfdir = $sysconfdir -localstatedir = $localstatedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -libdir = $libdir -top_srcdir = $top_srcdir -}; - - for (@{$need_externs{$short}}) { - next unless defined $externs{$_} and defined $externs{$_}{prefix}; - print MKINC "${_}_prefix = $externs{$_}{prefix}\n"; - print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags}; - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; - - my $dh; - my $debian = 0; - - opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!"; - for my $dir (readdir $dh) { - if ($dir=~/^(.*)\.spec$/) { - if ($1 ne $packageName) { - printf STDERR "Changed RPM name: $packageName --> $1\n" if ($debug);; - $packageName=$1; - } - last; - } - } - closedir $dh; - - for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") { - if (-f "$abs_srcdir/project/$file") { - my $old_ = $_; - printf STDERR "Creating $build$file\n" if ($debug);; - open DST, ">$build$file"; - open SRC, "<$abs_srcdir/project/$file"; - while () { - if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; } - if (/\@URL\@/) { s/\@URL\@/$package{url}/g; } - if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; } - if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; } - if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; } - if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; } - if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; } - if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; } - if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; } - if (/\@AGE\@/) { s/\@AGE\@/$age/g; } - if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; } - if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; } - if (/\@DEBIAN_VCS\@/) { s/\@DEBIAN_VCS\@/$package{debian_vcs}/g; } - if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; } - if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; } - if (/^\s*.+\/configure\s/ and $force_version) { - print "Version forced to $version\n" if ($debug);; - s/--version\s+\S+\s?//; - s/$/ --version $version/; - } - printf DST "%s", "$_"; - } - close SRC; - close DST; - $_ = $old_; - } - } - - print "Creating ${build}debian/\n" if ($debug);; - - `rm -rfv ${build}debian`; - mkdir $build."debian" or die $!; - `cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`; - `mv ${build}debian.* ${build}debian/ 2>/dev/null`; - `rm -f ${build}debian/*.orig`; - opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!"; - for $_ (readdir $dh) { - if (/^debian\.(.*)/) { - `mv ${build}debian/$_ ${build}debian/$1`; - $debian = 1; - } - } - closedir $dh; - - if ($debian) { - my ($dir, $file); - - chmod 0755, "${build}debian/rules"; - $file="${build}debian/docs"; if (not -f $file) { `touch $file`; } - $dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; } - $file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` } - $file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` } - $file="${build}debian/changelog"; if (not -f $file) { - open FH, ">$file" or die $!; - print FH qq{$packageName ($major.$minor.$rev-$age) unstable; urgency=low - - * Automatically generated package - - -- $package{maintainer} $debdate -}; - close FH; - } - - } else { - `rm -rf ${build}debian`; - } -} - -BEGIN{ -}; - -sub mode_etics_packaging { - my ($fmod, $cmd, $rpmprepare, $debprepare) = @_; - my ($workspaceDir, $srcPackageName, $srcAge, $topDir); - - # old-school packaging by ETICS for EMI-1 - if ($project eq 'emi' and $project_version == 1) { return; } - - if ($fmod eq 'gridsite.core') { - $workspaceDir = '..'; - $srcPackageName = 'gridsite'; - $srcAge = ''; - $topDir = '../'; - } else { - $workspaceDir = '${workspaceDir}'; - $srcPackageName = '${packageName}'; - $srcAge = '-${age}'; - $topDir = ''; - } - - $cmd->{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SRPMSLocation}'; - $cmd->{default}{packaging} = $rpmprepare; - $cmd->{default}{packaging} .= "dir=\${workspaceDir}/rpm_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SRPMSLocation} \$dir/{BUILD,RPMS,SOURCES,SRPMS} 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/SOURCES/ - rpmbuild -bs --nodeps --define \"_topdir \$dir\" $srcPackageName.spec - cp -v \$dir/SRPMS/*.src.rpm \${package.SRPMSLocation}/ - rm -rf \$dir"; - - for my $p ('deb5_x86_64_gcc432', 'deb5_ia32_gcc432', 'deb6_x86_64_gcc445', 'deb6_ia32_gcc445') { - for my $c (keys %{$cmd->{default}}) { $cmd->{$p}{$c} = $cmd->{default}{$c}; } - $cmd->{$p}{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SDEBSLocation}'; - $cmd->{$p}{packaging} = $debprepare; - $cmd->{$p}{packaging} .= "dir=\${workspaceDir}/dpkg_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SDEBSLocation} \$dir 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/${srcPackageName}_\${version}.orig.tar.gz - tar xzf \$dir/${srcPackageName}_\${version}.orig.tar.gz -C \$dir - cp -rf ${topDir}debian/ \$dir/$srcPackageName-\${version}/ - cd \$dir/$srcPackageName-\${version} - dpkg-buildpackage -S -d -nc - cd - - cp -v \$dir/*.tar.gz \$dir/*.dsc \${package.SDEBSLocation}/ - rm -rf \$dir"; - } -} - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod,2; - my $full = full "$subsys.$module"; - - my ($major,$minor,$rev,$age) = get_version $fmod, $full; - - # XXX: --with ignored for platform-dependend packages - my @copts = (); - my %ge; - @ge{@{$etics_projects{$project{etics_name}}}} = (1) x ($#{$etics_projects{$project{etics_name}}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/ and (defined $externs{$_} or defined $jar{$_})) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - next if ($eext eq '-'); - if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}) { - $eext = $project{etics_locations}{$_} if ($project{etics_locations}{$_}); - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } else { - if ($ge{$_} and not defined $externs{$_}{pkg}) { - push @copts, "--with-$_=\${stageDir}"; - } - } - } - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}); - } - - my $conf; - my $conftag; - my ($confprefix, $nameprefix, $packageName); - - $dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n"; - - $confprefix = $project{conf_prefix}{$subsys}; - $nameprefix = $confprefix; - $nameprefix =~ s/-$//; - $nameprefix =~ s/-/\./g; - $packageName = "$project{tag_prefix}{$subsys}$subsys-${module}"; - - if ($branch) { - $conf = "$confprefix${subsys}-${module}_$branch"; - $conftag = $branch; - # forced low age number - $age = $branch eq 'HEAD' ? '0head' : '0dev'; - push @copts, '--version ${version}-${age}'; - } - else { - $conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; -# XXX: gridsite hack - $conftag = $subsys eq 'gridsite' ? "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : - "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - - # lowering age for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age - 1; - } - } - - # emi1 suffix for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age.$project.$project_version; - $conf = $conf.$project.$project_version; - } - - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"}; - - my $confdir = $buildroot{"$subsys.$module"} eq '' ? '.' : '..'; - - my $cvs_module = full "$subsys.$module"; - my ($package_summary, $package_description) = get_description $cvs_module; - if ($package_description) { - $package_description =~ s/\n/\\n/g; - $package_description = "package.description = $package_description\n"; - } - if ($package_summary) { - $package_summary = "package.summary = $package_summary\n"; - } - - my %cmd; - $cmd_vcs{checkout} = "cvs -d \${vcsroot} co -d \${moduleName} ".($conftag eq 'HEAD' ? '-A' : '-r ${tag}')." $cvs_module 2>/dev/null"; - #$cmd_vcs{checkout} = "((test -d jra1mw/.git && (cd jra1mw; git pull)) || (git clone -q http://scientific.zcu.cz/git/jra1mw.git"; - #$cmd_vcs{checkout} .= " && (cd jra1mw; git checkout -b \${tag} --track origin/\${tag})" unless ($conftag eq /HEAD/); - #$cmd_vcs{checkout} .= ")) && (test -d \${moduleName} || ln -s jra1mw/$cvs_module \${moduleName})"; - $cmd_vcs{checkout} .= "\n\ttest -f \${packageName}-\${version}-\${age}.src.tar.gz || (ln -s \${moduleName} \${packageName}-\${version}; tar -chf - \${packageName}-\${version} --exclude CVS --exclude .git --exclude .etics | gzip --best > \${packageName}-\${version}-\${age}.src.tar.gz; rm \${packageName}-\${version})"; - $cmd_vcs{tag} = "cvs -d \${vcsroot} tag -R \${tag} ${moduleName}"; - - $cmd{default}{init} = 'None'; - $cmd{default}{configure} = 'None'; - $cmd{default}{compile} = 'None'; - $cmd{default}{test} = 'None'; - $cmd{default}{install} = 'None'; - $cmd{default}{packaging} = 'None'; - $cmd{default}{clean} = 'make clean'; - - if (exists $subpackages{$fmod}) { - $cmd{default}{clean} = 'None'; - $cmd{default}{packaging} = "echo building nothing, $subpackages{$fmod} will build this package"; - $cmd_vcs{checkout} = "mkdir -v \${moduleName} 2>/dev/null || true"; - } elsif ($subsys eq 'gridsite') { - $cmd_vcs{tag} = 'None'; - - if ($module eq 'core') { - my $flags; - - if ($project ne 'glite') { - # don't evaluate pkg-config calls to get them into source package - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=\`pkg-config gsoap --variable=prefix\` - OPENSSL_GLOBUS_FLAGS=\`pkg-config globus-openssl --cflags\` - OPENSSL_GLOBUS_LIBS=\`pkg-config globus-openssl --libs\`'; - } else { - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=${gsoap.location} - OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor} - OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir} - HTTPD_FLAGS=-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-1 -I${httpd-devel.location}/include/apr-1.0 -I${httpd-devel.location}/include/apr-0 -I${httpd-devel.location}/include/pcre'; - } - - $cmd{default}{configure} = "cat > Makefile.inc </dev/null"; - $cmd{default}{init} = 'echo "/sbin/ldconfig" > project/.post - echo "/sbin/ldconfig" > project/.postun'; - $cmd{default}{configure} = "cat > src/Makefile.inc <{default}}) { - $defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n"; - } - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = $project{etics_name}.$subsys.$module -displayName = $conf -description = $cvs_prefix{$subsys}.$subsys.$module -projectName = $project{etics_name} -age = $age -deploymentType = None -vcsroot = :pserver:anonymous\@glite.cvs.cern.ch:/cvs/glite -tag = $conftag -version = $major.$minor.$rev -$dwpath -[Platform-default:VcsCommand] -displayName = None -description = None -tag = $cmd_vcs{tag} -branch = None -commit = None -checkout = $cmd_vcs{checkout} - -}; - - for my $p (keys %cmd) { - next if $p ne 'default' and exists $project{supported_platforms} and not exists $project{supported_platforms}{$p}; - - print C qq{[Platform-$p:BuildCommand] -postpublish = None -packaging = $cmd{$p}{packaging} -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = $cmd{$p}{compile} -init = $cmd{$p}{init} -install = $cmd{$p}{install} -clean = $cmd{$p}{clean} -test = $cmd{$p}{test} -configure = $cmd{$p}{configure} -checkstyle = None - -}; - } - - print C qq{[Platform-default:Property] -$buildroot -package.preserve.libtool = false -$package_description$package_summary$defprops}; - - for (@{$obsoletes{"$subsys.$module"}}) { - print C "package.obsoletes = $_\n"; - print C "package.replaces = $_\n"; - } - for (@{$conflicts{"$subsys.$module"}}) { - print C "package.conflicts = $_\n"; - } - for (@{$provides{"$subsys.$module"}}) { - print C "package.provides = $_\n"; - } - print C "\n"; - - for my $pp (keys %{$platform_properties{"$subsys.$module"}}) { - next if $pp eq 'default'; - next if exists $project{supported_platforms} and not exists $project{supported_platforms}{$pp}; - - print C "[Platform-$pp:Property]\n$buildroot\n"; - - for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) { - print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n"; - } - print C "$package_description$package_summary\n"; - } - - for my $platform ('default', keys %{$project{supported_platforms}}) { - my $used = 0; - my $output = ''; - - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$platform}{$_}; - my $edev = $project{etics_externs_devel}{$platform}{$_}; - - # for the default platform using package of the same - # name for runtime dependency - if (not $eext) { - if ($platform eq 'default') { -#print "default runtime $_ on default\n"; - $eext = $_; } - else { -#print "no runtime $_ on $platform\n"; - $eext = '-'; } - } - if ($eext eq '-' and $edev eq '-') { -#print "skipping $_ on $platform\n"; - next; - } - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - - if ($edev) { - if ($type eq 'B') { - # no runtime - change to devel pkg - $eext = $edev; - } elsif ($type eq 'BR' or $type eq 'RB') { - # additional devel pkg - if ($edev ne '-') { $output .= "$proj|$edev = B\n"; } - } - } - if ($eext ne '-') { $output .= "$proj|$eext = $type\n"; } - } - - if ($platform eq 'default') { - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - if (not $used) { - $used = 1; - } - $output .= "$project{etics_name}|$project{etics_name}.$_ = $type\n"; - } - } - - if ($output) { - print C qq{ -[Platform-$platform:DynamicDependency] -$output}; - } - } - - close C; - - for $file ("$cvs_module/project/debian.rules", "$cvs_module/project/$packageName.spec") { - my $lib; - my $main_module; - @copts = (); - - if ($file =~ /debian\.rules$/) { $lib = 'lib'; } - else { $lib = '%{_lib}'; } - - my $main_module = "$subsys.$module"; - if (exists $subpackages{$main_module}) { $main_module = $subpackages{$main_module}; } - - # locations hacks - if ($file =~ /$packageName\.spec$/) { - if ($fmod eq 'lb.client-java') { - push @copts, ''; - push @copts, '--with-axis=/usr/local/axis1.4'; - } - } - - if (-f $file) { - open DST,">$file.new" or die "$file.new: $!\n"; - open SRC,"<$file" or die "$file: $!\n"; - while () { - if (/^(\s*).+\/configure\s/) { - printf DST "%s", "$1"; - printf DST "/usr/bin/perl $confdir/configure $project{flavours} --root=/ --prefix=$project{local_prefix} --libdir=$lib --project=$project --module $main_module@copts\n"; - } else { - printf DST "%s", "$_"; - } - } - close SRC; - close DST; - - `diff -b "$file" "$file.new"`; - if ($? == 0) { - print STDERR "($file not changed)\n"; - unlink "$file.new"; - } else { - print STDERR "Writing $file\n"; - rename "$file", "$file.orig" unless -f "$file.orig"; - rename "$file.new", "$file"; - } - } - } -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - $gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - -sub getlibdir { - if ( -e "/etc/debian_version") { # We are on Debian - $lib64="lib"; - $lib32="lib32"; } - else { # Another distribution - $lib64="lib64"; - $lib32="lib"; } - $libdir=$lib32; - - open INP, "uname -s | "; # Check kernel name - $kname= ; - chomp($kname); - close INP; - - if ( $kname eq "Linux") { - $arch = ("x86_64\npowerpc\nppc64\n"); - - open INP, "uname -p | "; # Check processor type - $procname= ; - chomp($procname); - close INP; - - if ($arch =~/^$procname\n/) { - return ($lib64); } - - open INP, "uname -m | "; # Check machine hardware - $machname= ; - chomp($machname); - close INP; - - if ($arch =~/^$machname\n/) { - return ($lib64); } - - # special cases (hyperlink lib64, Debian) - if (-l "/usr/lib64") { - $libdir=$lib32; } - - # if /usr/lib64 doesn't exist at all (AIX) - unless ( -e "/usr/lib64" ) { - $libdir=$lib32; } - } - - if ( $kname eq "SunOS") { - if (-e "/usr/lib/64") { - $libdir="lib/64"; } - } - - return $libdir; -} - -sub reshuffle_platforms($$) { - my ($data, $platforms) = @_; - my ($platform, %blacklist, $value); - - return if not $platforms; - - for $platform (keys %$data) { -#print "plat: $platform: $data->{$platform}\n"; - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { -#print " blacklist: $_ = $data->{$platform}{$_}\n"; - $blacklist{$_} = 1; - } - } - - for $_ (keys %blacklist) { - $value = $data->{default}{$_} ? $data->{default}{$_} : $_; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - if (not defined $data->{$platform}{$_}) { - $data->{$platform}{$_} = $value; -#print "added $value to $platform\n" - } - } - $data->{default}{$_} = '-'; -#print "deleted $_ from default\n"; - } - - # merge dependencies across the supported platforms - %blacklist = []; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { - $blacklist{$_} = 1; - } - } - for $_ (keys %blacklist) { - $value = undef; - $same = 1; - for $platform (keys %$platforms) { - if (not $value) { $value = $data->{$platform}{$_}; } - if (not $data->{$platform}{$_} or $value ne $data->{$platform}{$_}) { - $same = 0; - last; - } - } - if ($same and $value) { -#print "merged dependency $_\n"; - $data->{default}{$_} = $value; - for $platform (keys %$platforms) { - delete $data->{$platform}{$_}; - } - } - } -} - -sub usage { - my @ext = keys %externs; - my @myjars = keys %jar; - - print STDERR qq{ -Usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --stage=DIR staging directory [./stage] - --root=DIR installation root (custom relocation root -> sysroot) [./stage] - --sysroot=DIR system root (custom relocation root -> sysroot) [] - --sysconfdir=DIR system configuration directory [PREFIX/etc] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - --listmodules=module list subpackages of a module - --version=maj.min.rev-age version used instead of reading version.properties - --branch=branch CVS branch/etics name suffix (HEAD, branch_2_1, ...) - --libdir=libdir typically [lib,lib64] postfix - --project=PROJECT build or generate etics for a project (glite/emi1/emi) [emi] - --debug print more details - -Mode of operation: - --mode=\{checkout|build|etics\} what to do [build] - -What to build: - --module=module build this module only - --enable-NODE build this "node" (set of modules) only - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - --canl-tag=tag checkout canl modules with specific tag - -Dependencies (summary of what will be used is always printed): - --with-EXTERNAL=PATH where to look for an external [autodetect] - --with-JAR=JAR where to look for jars - -Available nodes: - @nodes - -Default nodes: - @default_nodes - -Externals (not all for all modules) are: - @ext - -External jars are: - @myjars - -}; - -} diff --git a/emi.canl.canl-c/doc/src/canl-abstract.tex b/emi.canl.canl-c/doc/src/canl-abstract.tex deleted file mode 100644 index a8a80e7..0000000 --- a/emi.canl.canl-c/doc/src/canl-abstract.tex +++ /dev/null @@ -1,21 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% when changed, update also http://egee.cesnet.cz/en/JRA1/LB/lb.html -% (in CVSROOT=:gserver:lindir.ics.muni.cz:/cvs/edg, cvsweb/lb.html) -The Developer's Guide explains how to use the canl C (\CANL) -API. Main and Credentials API is described in details together with -programing examples. diff --git a/emi.canl.canl-c/doc/src/canl-cs-auth-connection.tex b/emi.canl.canl-c/doc/src/canl-cs-auth-connection.tex deleted file mode 100644 index a2f0bd2..0000000 --- a/emi.canl.canl-c/doc/src/canl-cs-auth-connection.tex +++ /dev/null @@ -1,215 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% -*- mode: latex -*- - -\section{Client-Server Authenticated Connection} -\label{s:cs-auth-conn} - -For client-server authenticated connection we just use \CANL -\textit{Main API} calls. In time of writing this paper -\CANL use \textit{openssl -- SSL/TLS and cryptography toolkit}. -However, core of the \CANL has been developed to be as independent - on any cryptography toolkit as possible, so it may support -other libraries in the future. - -\subsection{Main API Without Direct Calls To Openssl} -These are the functions of the \textit{Main API} that do not -use \textit{openssl API} calls or variable types directly - (as a parameter or in their definitions): - -\begin{itemize} - \item \verb'canl_ctx canl_create_ctx()' - - This function - returns an initialized \textit{authentication context} object - \item \verb'void CANL_CALLCONV canl_free_ctx(canl_ctx cc)' - - This function will free the \textit{authentication context}, releasing - all associated information. The context must not be used after this call. - \begin{itemize} - \item param cc -- the \textit{authentication context} to free - \end{itemize} - \item \textit{canl error code} - \verb'canl_create_io_handler(canl_ctx cc, canl_io_handler *io)' - - This function will create an \textit{i/o handler} from the -\textit{authentication context}. This handler shall be passed to -all I/O-related functions. - \begin{itemize} - \item param cc -- the \textit{authentication context} - \item param io -- return an initialized \textit{i/o context}, -or NULL if it did not succeed - \item return -- \CANL error code - \end{itemize} - - \item \verb'canl_err_code canl_io_close(canl_ctx cc, canl_io_handler io)' - - This function will close an existing connection. The 'io' object may - be reused by another connection. It is safe to call this - function on an io object which was connected. - \begin{itemize} - \item param cc -- the \textit{authentication context} - \item param io -- the \textit{i/o context} - \item return -- \textit{canl error code} - \end{itemize} - \item \begin{verbatim}canl_err_code canl_io_connect(canl_ctx cc, canl_io_handler io, -const char *host, const char *service, int port, gss_OID_set auth_mechs, - int flags, struct timeval *timeout)\end{verbatim} - This function will try to connect to a server object, - doing authentication (if not forbidden) - \begin{itemize} - \item param cc -- the \textit{authentication context} - \item param io -- the \textit{i/o context} - \item param host -- the server to which to connect - \item param service -- \TODO DK - \item param port -- the port on which the server is listening - \item param auth\_mechs -- authentication mechanism to use - \item flags -- TODO - \item param timeout -- the timeout after which to drop the connect attempt - \item return -- \textit{canl error code} - \end{itemize} - \item \begin{verbatim}canl_io_accept(canl_ctx cc, canl_io_handler io,int fd, - struct sockaddr s_addr, int flags,canl_principal *peer, - struct timeval *timeout)\end{verbatim} - This function will - setup a server to accept connections from clients, doing - authentication (if not forbidden) - \begin{itemize} - \item param cc -- the \textit{authentication context} - \item param io -- the \textit{i/o context} - \item param fd -- \TODO this param? - \item param port -- the port on which the server is listening - \end{itemize} - -\end{itemize} - -\subsection{Main API With Direct Calls To Openssl} - -\begin{itemize} - \item \begin{verbatim}canl_err_code canl_ctx_set_ssl_cred(canl_ctx cc, char *cert, char *key, -char *proxy, canl_password_callback clb, void *pass)\end{verbatim} - This function will set the credential to be associated to the - \textit{context}. These credentials will become the default ones - for all API calls depending on this \textit{context}. - \begin{itemize} - \item param cc -- the \textit{authentication context} - \item param cert -- the certificate to be set - \item param key -- its private key - \item param proxy -- the proxy certificate to be set - \item param clb -- a callback function which should return - the password to the private key, if needed - \item param pass -- user specified data that will be passed - as is to the callback function. Note that the content of this - pointer will not be copied internally, and will be passed - directly to the callback. This means that altering the - data pointed by it will have - a direct effect on the behavior of the function. - \item return -- \textit{canl error code} - \end{itemize} - \item \verb'canl_err_code' - \verb'canl_ctx_set_ca_dir(canl_ctx cc, const char *ca_dir)' - - Set certficate authority directory (openssl ca directory structure) - \begin{itemize} - \item param cc -- rhe \textit{authentication context} - \item ca\_dir -- rhe path that will be set. It will not be - checked whether this path actually contains the CAs or not - \item return -- \textit{canl error code} - \end{itemize} - \item \verb'canl_err_code' - \verb'canl_ctx_set_crl_dir(canl_ctx cc, const char *crl_dir)' - \begin{itemize} - \item param cc -- the \textit{authentication context} - \item crl\_dir -- the path that will be set. It will not be - checked whether this path actually contains the CRLs or not - \item return -- \textit{canl error code} - \end{itemize} - -\end{itemize} -\subsection{Secure Client-Server Connection Example} -We give an example of a caNl client that use \textit{Main API} -with openssl. We do not define variables in this example, unless -their type is \CANL defined. For complete sample see -{\tt canl\_samples\_server.c} in -\TODO Where to find sources (package?)- Frantisek? - -Include nesessary header files: -\begin{lstlisting} -#include -#include -\end{lstlisting} - -Initialize context and set parameters: -\begin{lstlisting} -canl_ctx my_ctx; -canl_io_handler my_io_h = NULL; -my_ctx = canl_create_ctx(); -err = canl_create_io_handler(my_ctx, &my_io_h); -err = canl_ctx_set_ssl_cred(my_ctx, serv_cert, serv_key, NULL, NULL); -\end{lstlisting} - -set user's credentials (X509 auth. mechanism) -\begin{lstlisting} -if (serv_cert || serv_key || proxy_cert){ - err = canl_ctx_set_ssl_cred(my_ctx, serv_cert, serv_key, proxy_cert, - NULL, NULL); - if (err) { - printf("[CLIENT] cannot set certificate or key to context: %s\n", - canl_get_error_message(my_ctx)); - goto end; - } -} -\end{lstlisting} - -If using X509 auth. mechanism, we might set \textit{CA directory} and/or - \textit{CRL directory} at this place. (If not set, default directories -will be used, \ie those in proper env. variables ) -. -. -. - -Connect to the server, send something then read the response: - -\begin{lstlisting} -err = canl_io_connect(my_ctx, my_io_h, p_server, NULL, port, NULL, 0, &timeout); -if (err) { - printf("[CLIENT] connection to %s cannot be established: %s\n", - p_server, canl_get_error_message(my_ctx)); - goto end; - } -err = canl_io_write (my_ctx, my_io_h, buf, buf_len, &timeout); -if (err <= 0) { - printf("can't write using ssl: %s\n", - canl_get_error_message(my_ctx)); - goto end; - } -err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, &timeout); -if (err > 0) { - buf[err] = '\0'; - printf ("[CLIENT] received: %s\n", buf); - err = 0; - } -\end{lstlisting} - -Free the allocated memory: - -\begin{lstlisting} -if (my_io_h) - canl_io_destroy(my_ctx, my_io_h); -canl_free_ctx(my_ctx); -\end{lstlisting} - diff --git a/emi.canl.canl-c/doc/src/canl-introduction.tex b/emi.canl.canl-c/doc/src/canl-introduction.tex deleted file mode 100644 index 95d4b4f..0000000 --- a/emi.canl.canl-c/doc/src/canl-introduction.tex +++ /dev/null @@ -1,180 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% -*- mode: latex -*- - -\section{Introduction} - -This document serves as a developer's guide and could be -seen as an API reference too, even though comments in -the header files may give the reader better insights into that matter. - -Common Authentication Library (\CANL for short) -was designed to provide common security layer support in grid -applications. It is largely based on existing code (VOMS, LB). Its -simple API can be devided by functionality into two parts: - -\begin{itemize} -\item \textit{\CANL Main API} is used to establish (secure) client-server -connection with one or both sides authenticated, send or receive data. -As will be described in~\ref{s:cs-auth-conn}, most of the \textit{Main API} -is not directly dependent on some chosen cryptography toolkit -(SSL implementation). It is -also internally plugin-based and therefore other security mechanisms support can -be added in future. -\item \textit{\CANL Certificate API} allows certificate and proxy management \eg -proxy creation, signing, etc. We may think of \textit{Certificate API} as the -second level of \textit{Main API} -\end{itemize} - -Currently there is EMI Product Team assigned to \CANL development with three -subgroups for each language binding. - -\subsection{Language Bindings} -\CANL is developed in C language as well as C++ and Java language bindings, -however this document covers only the C interface. - -\subsection{Getting and Building Library} -TODO package names - -external dependencies: -\begin{itemize} -\item c-ares -- asynchronous resolver library -\item openssl -- cryptography and SSL/TLS toolkit -\end{itemize} - -\subsection{General Guidelines} - -\marginpar{Naming conventions}% -All function names are prefixed with \verb'canl_' - -\marginpar{Input and output arguments}% -All structures and objects passed in output of functions -(even though pointers are used as a help) -are dynamically allocated, so proper functions to free the allocated -memory has to be called. e.g. \verb'canl_free_ctx()' -deallocates members of the structure \verb'canl_ctx'. - -\marginpar{Opaque types}% -Almost all types used in caNl are \textit{Opaque types} -- i.e. their structure is -not exposed to users. To use and/or modify these structures API call has -to be used. Example of opaque type is {\tt canl\_ctx}. - -\marginpar{Return values}% -The return type of most of the API functions is {\tt canl\_err\_code} which - in most cases can be interpreted as int. Unless specified otherwise, zero -return value means success, non-zero failure. Standard error codes from -{\tt errno.h} are used as much as possible. -TODO openssl mapping - -Few API functions return {\tt char *}. In such a~case -{\tt NULL} indicates an error, non-null value means success. - -\subsection{Context and Parameter Settings} -\label{s:context} -All the API functions use a \emph{context} parameter of type {\tt canl\_ctx} -to maintain state information like error message and code. -Some API functions also use an \emph{io context} of type {\tt canl\_io\_handler} -which keeps information about each particular connection -(\eg socket number, oid, SSL context).The caller can create as many -contexts as needed, all of them will be independent. When calling -\verb'canl_create_ctx()' or \verb'canl_create_io_handler()' all members -of the objects are initialized with default values which are often -NULL for pointer type and 0 in case of int and similar types. - -\section{\CANL Components} -\label{s:common} - -\subsection{Header Files} - -Header files for the common structures and functions are summarized in -table~\ref{t:cheaders}. - -\begin{table}[h] -\begin{tabularx}{\textwidth}{>{\tt}lX} -canl.h & Definition of context objects and \textit{Main API} common -functions declarations. \\ -canl\_ssl.h & Declaration of functions that use X509 certificates -based authentication mechanism (pretty much dependent on -openssl library functions).\\ -canl\_cred.h & Definition of context objects of the -\textit{Certificate API} and functions declarations.\\ -\end{tabularx} -\caption{Header files} -\label{t:cheaders} -\end{table} - -\subsection{Building Client Programs} -The easiest way to build programs using \CANL in C is to use -GNU's libtool to take care of all the dependencies: -\begin{verbatim} -libtool --mode=compile gcc -c example1.c -D_GNU_SOURCE -libtool --mode=link gcc -o example1 example1.o -lcanl_c -\end{verbatim} - -\subsection{Context} -\label{s:canl_ctx} -\marginpar{Context initialization}% -There are two opaque data structures representing -caNl \textit{Main API} context: {\tt canl\_ctx} and - {\tt canl\_io\_handler} (see section~\ref{s:context}). -{\tt canl\_ctx} must be initialized before any caNl API call. -{\tt canl\_io\_handler} must be initialized before calling function -representing io operation (\eg \verb'canl_io_connect()') and after -{\tt canl\_ctx} initialization. -\begin{lstlisting} -#include -#include - -canl_io_handler my_io_h = NULL; -canl_ctx my_ctx; -my_ctx = canl_create_ctx(); -err = canl_create_io_handler(my_ctx, &my_io_h); -\end{lstlisting} -There is one opaque data structure representing \CANL -\textit{Certificate API} context: {\tt canl\_cred}. -It must only be initialized before function calls -that use this context as a parameter. -\begin{lstlisting} -#include -#include - -canl_ctx ctx; -canl_cred c_cred; -ctx = canl_create_ctx(); -canl_cred_new(ctx, &c_cred); -\end{lstlisting} -\marginpar{Obtaining error description}% -{\tt canl\_ctx} stores details of all errors which has occurred since -context initialization, in human readable format. To obtain it use -\verb'canl_get_error_message()': -\begin{lstlisting} -printf("%s\n", canl_get_error_message(my_ctx)); -\end{lstlisting} - -\marginpar{Context deallocation}% -It is recommended to free the memory allocated to each -context if they are not needed anymore, in first case {\tt canl\_io\_handler} -, then {\tt canl\_ctx} in case of the \textit{Main API}: -\begin{lstlisting} -if (my_io_h) - canl_io_destroy(my_ctx, my_io_h); -canl_free_ctx(my_ctx); -\end{lstlisting} -as for the Certificate API: -\begin{lstlisting} -canl_cred_free(ctx, c_cred); -\end{lstlisting} diff --git a/emi.canl.canl-c/doc/src/canl-proxy-cert.tex b/emi.canl.canl-c/doc/src/canl-proxy-cert.tex deleted file mode 100644 index daf45c1..0000000 --- a/emi.canl.canl-c/doc/src/canl-proxy-cert.tex +++ /dev/null @@ -1,251 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% -*- mode: latex -*- - -\section{Credentials Handling} -\label{s:cs-auth-conn} - -If we want to create new proxy certificate or \eg delegate -credentials, we can use \CANL \textit{Certificate API}. -This part of API uses X509 authentication mechanism -(openssl library now) - -\subsection{Certificate API} -These are the functions of the \textit{Certificate API}, all of them use -{\tt canl\_ctx} as first parameter and {\tt canl\_err\_code} as a return -value, so we do not include them in following description: - -\begin{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_new(canl_ctx, canl_cred *cred)\end{verbatim} -This function creates new structure (context) to hold credentials. - \begin{itemize} - \item param cred -- a new object will be returned to this pointer after - success - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_free(canl_ctx, canl_cred *cred)\end{verbatim} - This function will free the credentials context, releasing - all associated information. The context must not be used after this call. - \begin{itemize} - \item param cred -- the credentials context to free - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_ctx_set_cred(canl_ctx, canl_cred cred)\end{verbatim} - This one sets users credentials to \CANL context. - \begin{itemize} - \item param cred -- credentials to set to global \CANL context - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_load_priv_key_file(canl_ctx, canl_cred cred, const -char * file, canl_password_callback clb, void *pass)\end{verbatim} - Load private key from specified file into the credentials context. - \begin{itemize} - \item param cred -- credentials which save private key to - \item param file -- the file to load private key from - \item param clb -- the callback function which should return - the password to the private key, if needed. - \item param pass -- User specified data that will be passed - as is to the callback function - \end{itemize} - \item \verb'canl_cred_load_chain(canl_ctx, canl_cred cred,' - \verb' STACK_OF(X509) *chain)' - This function loads the certificate chain out of an openssl structure. The - chain usually - consist of a proxy certificate and certificates forming - a chain of trust. - \begin{itemize} - \item param cred -- the credentials context to set chain to - \item param chain -- the openssl structure to load certificate chain from. - \end{itemize} - \item \verb'canl_cred_load_chain_file(canl_ctx, canl_cred cred,' - \verb' const char * file)' - This function loads the certificate chain out of a file. The chain usually - consists of a proxy certificate and certificates forming - a chain of trust. - \begin{itemize} - \item param cred -- credentials which save certificate chain to - \item param file -- the file to load certificate chain from - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_load_cert(canl_ctx, canl_cred cred, X509 *cert)\end{verbatim} - This function loads user certificate out of an openssl structure - \begin{itemize} - \item param cred -- the credentials context to set certificate to - \item param cert -- the openssl structure to load certificate from - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_load_cert_file(canl_ctx, canl_cred cred, -const char *file)\end{verbatim} - This function loads user certificate out of a file. - \begin{itemize} - \item param cred -- credentials which save certificate to - \item param file -- the file to load certificate from - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_set_lifetime(canl_ctx, canl_cred cred, const long lt)\end{verbatim} - This function sets the lifetime for a certificate which is going to - be created - \begin{itemize} - \item param cred -- the credentials context - \item param lt -- the lifetime in seconds - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_set_extension(canl_ctx, canl_cred cred, -X509_EXTENSION *ext)\end{verbatim} - This function sets the certificate extension to for the certificate - which is going to be created - \begin{itemize} - \item param cred -- the credentials context - \item param ext -- the openssl structure holding X509 certificate extension - \end{itemize} -\item \begin{verbatim} -canl_err_code canl_cred_set_cert_type(canl_ctx, canl_cred cred, -const enum canl_cert_type type)\end{verbatim} - This function sets the certificate type to for the certificate - which is going to be created. - \begin{itemize} - \item param cred -- the credentials context - \item param type -- a \CANL enum type ...\TODO type - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_sign_proxy(canl_ctx, canl_cred signer, -canl_cred proxy)\end{verbatim} - This function makes new proxy certificate based on information in - \textit{proxy} parameter. The new certificate is signed with private key - saved in \textit{signer}. A new certificate chain is saved - into \textit{proxy}. - \begin{itemize} - \item param signer -- the credentials context which holds signer's certificate - and key. - \item param proxy -- the credentials context with a certificate - signing request, public key and user certificate; optionally lifetime, - certificate type and extensions. - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_save_proxyfile(canl_ctx, canl_cred cred, -const char * file)\end{verbatim} - This function saves proxy certificate into a file. - \begin{itemize} - \item param cred -- the credentials context with certificate to save - \item param file -- save the certificate into - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_save_cert(canl_ctx, canl_cred cred, X509 **to)\end{verbatim} - This function saves certificate into openssl object of type \textit{X509} - \begin{itemize} - \item param cred -- the credentials context with certificate to save - \item param to -- save the certificate into - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_save_chain(canl_ctx, canl_cred cred, STACK_OF(X509) **to)\end{verbatim} - This function saves certificate chain of trust with proxy - certificate into openssl object of type \textit{STACK\_OF(X509)}. - \begin{itemize} - \item param cred -- the credentials context with certificate chain to save - \item param to -- save the certificate into - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_new_req(canl_ctx, canl_cred cred, unsigned int bits)\end{verbatim} - This function creates a new certificate signing request after a new key pair - is generated. - \begin{itemize} - \item param cred -- the credentials context, certificate signing request - is saved there - \item param bits -- the key length - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_save_req(canl_ctx, canl_cred cred, X509_REQ **to)\end{verbatim} - This function saves certificate signing request into openssl - object of type \textit{X509\_REQ}. - \begin{itemize} - \item param cred -- the credentials context with certificate request - \item param to -- save the certificate request into - \end{itemize} - \item \begin{verbatim} -canl_err_code canl_cred_save_req(canl_ctx, canl_cred cred, X509_REQ **to)\end{verbatim} - This function loads certificate signing request from openssl object of type \textit{X509\_REQ} into \CANL certificate context - \begin{itemize} - \item param cred -- the credentials context, the cert. request - will be stored there - \item param to -- load the certificate request from - \end{itemize} - -\end{itemize} - -\subsection{Make New Proxy Certificate -- Example} -We give an example of a proxy certificate creation. We do not -define variables in this example, unless -their type is \CANL defined. We do not check return values in most -cases as well. -For complete sample see \TODO source - -Include necessary header files: -\begin{lstlisting} -#include -#include -\end{lstlisting} -\CANL context variables -\begin{lstlisting} -canl_cred signer = NULL; -canl_cred proxy = NULL; -canl_ctx ctx = NULL; -\end{lstlisting} - -Initialize context: -\begin{lstlisting} -ctx = canl_create_ctx(); -ret = canl_cred_new(ctx, &proxy); -\end{lstlisting} - -Create a certificate request with a new key-pair. -\begin{lstlisting} -ret = canl_cred_new_req(ctx, proxy, bits); -\end{lstlisting} - -(Optional) Set cert. creation parameters -\begin{lstlisting} -ret = canl_cred_set_lifetime(ctx, proxy, lifetime); -ret = canl_cred_set_cert_type(ctx, proxy, CANL_RFC); -\end{lstlisting} - -Load the signing credentials -\begin{lstlisting} -ret = canl_cred_new(ctx, &signer); -ret = canl_cred_load_cert_file(ctx, signer, user_cert); -ret = canl_cred_load_priv_key_file(ctx, signer, user_key, NULL, NULL); -\end{lstlisting} - -Create the new proxy certificate -\begin{lstlisting} -ret = canl_cred_sign_proxy(ctx, signer, proxy); -\end{lstlisting} - -And store it in a file -\begin{lstlisting} -ret = canl_cred_save_proxyfile(ctx, proxy, output); -\end{lstlisting} - - -\begin{lstlisting} -if (signer) - canl_cred_free(ctx, signer); -if (proxy) - canl_cred_free(ctx, proxy); -if (ctx) - canl_free_ctx(ctx); -\end{lstlisting} diff --git a/emi.canl.canl-c/doc/src/canl.tex b/emi.canl.canl-c/doc/src/canl.tex deleted file mode 100644 index 39dfd5a..0000000 --- a/emi.canl.canl-c/doc/src/canl.tex +++ /dev/null @@ -1,102 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% -*- mode: latex -*- -\documentclass{emi} -\def\insideDG{} - -\input{definitions} -%\def\LB{LB\xspace} - -\title{Common Authentication Library -- Developer's Guide} -%\Subtitle{Developer's Guide} -\author{CESNET caNl team} -%\DocIdentifier{glite-lb-doc-dg-\version} -%\DeliverableId{} -\Date{\today} -%\Activity{JRA1: Middleware Engineering} -%\DocStatus{DRAFT} -\DocVersion{\version} -%\Dissemination{PUBLIC} -%\DocumentLink{\url{http://egee.cesnet.cz/cvsweb/LB/LBDG.pdf}} -\Abstract{\input{canl-abstract}} -\EMICompVersion{1.x} - -\usepackage{listings} -\usepackage{amsmath} - -%\setlength{\marginparwidth}{1.2in} -\let\oldmarginpar\marginpar -\renewcommand\marginpar[1]{\-\oldmarginpar[\raggedleft\footnotesize #1]% -{\raggedright\footnotesize #1}} - -\begin{document} -\reversemarginpar -\lstset{language=C,basicstyle=\footnotesize,numbers=none,breaklines=true} -%\lstset{title={\bf File: }\lstname} -\lstset{rangeprefix=/*,rangesuffix=*/,includerangemarker=false} -\lstset{escapeinside={//*}{\^^M}} - -% ----- BEGIN COPY ----- -% copied from org.glite.lb.client/doc/api/api.tex in hope it could be useful - -%\parindent=0pt -%\parskip=\smallskipamount - -\makeatletter -\def\jobid{\textit{JobId}\xspace} -\def\@tti[#1]{\item[{\normalfont\texttt{#1}}]\catcode`\_=8} -\def\tti{\catcode`\_=11\noexpand\@tti} -\newlength{\tw} - -\def\synopsis{\catcode`\_=11\noexpand\@synopsis} -\def\@synopsis#1#2{ -\tw=\linewidth -\advance\tw-2em -\texttt{#1(}\\ -\strut\hskip2em\begin{tabularx}\tw{>{\begingroup\tt}l<{\endgroup}lX} -#2 -\end{tabularx}\\ -\texttt) -\catcode`\_=8 -} - -\def\Synopsis{\subsubsection*{Synopsis}} -\def\Description{\subsubsection*{Description}} -\def\Return{\subsubsection*{Return values}} - -% ----- END COPY ----- - -%\input{frontmatter} -\input{funding} -\input{copyright} -\tableofcontents - -\newpage -\input{canl-introduction} - -\newpage -\input{canl-cs-auth-connection} - -\newpage -\input{canl-proxy-cert} - -%\newpage -%\bibliographystyle{unsrt} -%\bibliography{lbjp} - -\end{document} - diff --git a/emi.canl.canl-c/doc/src/copyright.tex b/emi.canl.canl-c/doc/src/copyright.tex deleted file mode 100644 index be11582..0000000 --- a/emi.canl.canl-c/doc/src/copyright.tex +++ /dev/null @@ -1,32 +0,0 @@ -% -%% Copyright (c) EMI. 2010-2013. -%% -%% 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. -~ -\vfill{} -{\bf Copyright} \copyright\ {\bf EMI. 2010-2013. - -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 - -\begin{center} -\href{http://www.apache.org/licenses/LICENSE-2.0}{http://www.apache.org/licenses/LICENSE-2.0} -\end{center} - -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. -} -\clearpage diff --git a/emi.canl.canl-c/doc/src/definitions.tex b/emi.canl.canl-c/doc/src/definitions.tex deleted file mode 100644 index 5d784c8..0000000 --- a/emi.canl.canl-c/doc/src/definitions.tex +++ /dev/null @@ -1,55 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% external packages -\usepackage{xspace} -\usepackage{ifthen} -\usepackage{comment} -\usepackage{listings} - -% useful definitions -\def\CANL{caNl\xspace} -\newcommand\LBver[1]{\textit{\LB version {#1}}} -\def\JP{JP\xspace} -%\def\eg{e.\,g.} -\def\eg{for example\xspace} -\def\Eg{For example\xspace} -%\def\ie{i.\,e.} -\def\ie{that is\xspace} -\def\Ie{That is\xspace} -\def\wrt{with respect to\xspace} -\def\Dash{---\penalty-1000} - -\def\req{\noindent\textbf{Prerequisities:}} -\def\how{\noindent\textbf{How to run:}} -\def\what{\noindent\textbf{What to test:}} -\def\result{\noindent\textbf{Expected result:}} -\def\note{\noindent\textbf{Note:}} -\def\path#1{{\normalfont\textsf{#1}}} -\def\code#1{\texttt{#1}} -\def\ctblb#1{\code{org.glite.testsuites.ctb/LB/tests/#1}} - -\specialcomment{hints}{\par\noindent\textbf{Hints: }\begingroup\slshape}{\endgroup} -%\includecomment{hints} - -\long\def\TODO#1{\par\noindent\textbf{TODO:} {\sl#1}\par} -\long\def\ludek#1{} - -\hyphenation{plug-in} - -\newcommand{\email}[1]{\href{mailto:#1}{#1}} - -\input{ver.tex} diff --git a/emi.canl.canl-c/doc/src/emi.cls b/emi.canl.canl-c/doc/src/emi.cls deleted file mode 100644 index e51e47b..0000000 --- a/emi.canl.canl-c/doc/src/emi.cls +++ /dev/null @@ -1,491 +0,0 @@ -% emi.cls: -% Branched from egee.cls 1.6 -% revision 2.0 [based on word template] -% Emidio Giorgio -- emidio.giorgio@ct.infn.it -% March 31, 2011 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% License -% -% This work is licensed under Creative Commons Attribution-ShareAlike 3.0. -% http://creativecommons.org/licenses/by/3.0/ -% You are free: -% * to Share Ñ to copy, distribute and transmit the work -% * to Remix Ñ to adapt the work -% -% Under the following conditions: -% * Attribution. You must attribute the work in the manner specified by the author or licensor -% (but not in any way that suggests that they endorse you or your use of the work). -% * Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting -% work only under the same, similar or a compatible license. -% -% * For any reuse or distribution, you must make clear to others the license terms of this work. -% The best way to do this is with a link to this web page : http://creativecommons.org/licenses/by/3.0/ -% * Any of the above conditions can be waived if you get permission from the copyright holder. -% * Nothing in this license impairs or restricts the author's moral rights. -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\NeedsTeXFormat{LaTeX2e} -\ProvidesClass{emi}[2011/03/24 EMI LaTeX Class] -\typeout{EMI LaTeX class -- 2011/03/24} -% -%% Interface - example of an option, should we want to use these later. -%\newif\ifmonotitle\monotitlefalse - -%\DeclareOption{mono}{\monotitletrue} - -\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} -\ProcessOptions - - -% Inherit! -\LoadClass[11pt]{article} - -% Necessary packages: -\RequirePackage{lastpage} -\RequirePackage{tabularx} -\RequirePackage{pslatex} -\RequirePackage{times} -\RequirePackage{verbatim} -\RequirePackage{geometry} -\RequirePackage{url} - -\usepackage[hang,bf,small]{caption} -\usepackage[T1]{fontenc} -\usepackage[scaled]{helvet} -\usepackage{multirow} -\renewcommand*\familydefault{\sfdefault} -% -% We now define a new \if command to test for PDF being enabled. -% It is important because loading graphicx overrides the definition -% of \pdfoutput and sets it to true even when PDF is not enabled. -% Use \ifpdf instead of \ifx\pdfoutput\undefined hereafter. -% - -\newif\ifpdf -\ifx\pdfoutput\undefined - \pdffalse - % \typeout{PDF _not_ defined} -\else - \pdfoutput=1 - \pdftrue - % \typeout{PDF _is_ defined} -\fi - -\ifpdf - \usepackage[pdftex, - pdfpagemode={UseOutlines},bookmarks=true,bookmarksopen=true, - bookmarksopenlevel=0,bookmarksnumbered=true, - hypertexnames=false,colorlinks,linkcolor={blue}, - citecolor={blue},urlcolor={red}, - pdfstartview={FitV}]{hyperref} -\else - \usepackage[hypertex]{hyperref} -\fi - -\ifpdf - \usepackage[pdftex]{graphicx} - \pdfcompresslevel 9 - \pdfadjustspacing 1 -\else - \usepackage[dvips]{graphicx} -\fi - -\usepackage{color} - -\def\footsize{5mm} - -%% -%% PAGE GEOMETRY DEFINITIONS -%% -% From Template file -\geometry{centering,includeheadfoot} -%\geometry{a4paper,top=12.5mm,headheight=12.5mm,headsep=5mm,foot=\footsize,footskip=13.3mm,bottom=12.5mm} -\geometry{a4paper,top=15.5mm,headheight=20mm,headsep=5mm,foot=\footsize,footskip=13.3mm,bottom=12.5mm} -\geometry{right=25mm,left=25mm} - - - -% APM -- I don't think these are right, my impression is above is correct -%\geometry{a4paper,margin=0.98in,headheight=0.72in} - - -%% -%% PAGE COLOUR DEFINITIONS -%% - - - -% paulm's prefered name ... -\def\bibname{References} - -\setlength{\parindent}{0pt} -\setlength{\parskip}{1.4mm plus 0.4mm minus 0.2mm} - -\def\@defaultfooter{ - \def\@oddfoot{\vbox to \footsize {% - {\color{blue}\hrule width \textwidth height 1pt depth 0pt}% - \vfil - %\small\hbox to \textwidth{\ISTNumber% - \small\hbox to \textwidth{% - %\hfil - %\hbox{\colorbox{yellow}{\MakeUppercase{\@Dissemination}}}% - \hfil - \hbox{\thepage/\pageref{LastPage}}}% - }% - }% -} - - -\def\ps@title{% - \@defaultfooter - \def\@oddhead{\hbox to \textwidth{\EMILogo\hfil\LargeCESNETLogo}} -} - -\def\ps@headings{% - \@defaultfooter - \def\@oddhead{\vbox to \headheight{% -%\hrule width \textwidth height 1pt\relax - \vbox to 0.75\headheight{% - \hbox to \textwidth{% - \hbox to 0pt{\EMILogo\hss}% - \hfil - -%% \hbox to 8cm{% -%% \vbox to 0.75\headheight{% -%% \vfil -%% \parbox{8cm}{% -%% \centering\color{blue}% -%% \textbf{\MakeUppercase{\@title}}% -%% %\ifx\@Subtitle\@empty\else -%% % \par\textbf{\scriptsize\@Subtitle}% -%% %\fi -%% }% -%% \vfil -%% }% -%% \hss}% - - \hfil -%\hbox to 0pt{\vrule width 1pt height 10pt depth 0pt \hss}% -%% {\scriptsize\setlength{\parskip}{0pt}\setlength{\topsep}{0pt}% -%% % \vbox to 0.75\headheight{% -%% \parbox{4cm}{x% -%% \begin{flushright}% -%% \textit{Doc. Identifier}:\\ -%% \textbf{\@DocIdentifier}\\ -%% \vfil -%% \textit{Date}: \textbf{\@Date} -%% \end{flushright}% -%% }% -%% % }% -%% }% - -\hbox to 0pt{\hss\vbox to 0.75\headheight{%\hrule -\small -\parfillskip0pt -\leftskip 0pt plus 1fil -\parskip0ex -\textsc{Title}: -\par -\textbf{\@title} - - -\textit{Date}: \textbf{\@Date} -\vfil -%\hrule -}}% -% \hbox to 4cm{\scriptsize -% \vbox to 0.75\headheight{% -% \parbox{4cm}{ -% \halign{\hfill####\cr -% \textit{Doc. Identifier}:\cr -% \textbf{\@DocIdentifier}\cr -% % \noalign{\vfil} -% \textit{Date}: \textbf{\@Date}\cr -% }}% -% \vfil -% }% -% }% - }% - }% -%\hrule width \textwidth height 1pt\relax - \vfil\vskip 2.5mm\relax - {\color{blue}\hrule width \textwidth height 1pt depth 0pt}% - }% - }% -} - -\pagestyle{headings} - -\setlength{\captionmargin}{1cm} - -% image file extensions respective to the output format -\ifpdf - \DeclareGraphicsExtensions{.jpg,.pdf,.png} - \pdfcompresslevel=9 - \pdfinfo{ /Title (EMI) } -\else - \DeclareGraphicsExtensions{.eps} -\fi - -\def\frontboxwidth{11cm}% - -\definecolor{MyTeal}{rgb}{0,0.46,0.46} -\definecolor{blue}{rgb}{0.05,0.26,0.5} -%\definecolor{blue}{rgb}{0.1,0.1,0.5} %% egee blue -\definecolor{lightgrey}{gray}{0.65} - -%% -%% Define our title page -%% -\AtBeginDocument{ -\pagestyle{title}% -\hbox{}% Force top of page -\vfill -{\centering - \fontsize{30}{50}{\textbf{\textsc{\textcolor{blue}{European Middleware Initiative}}}}\\[40mm]% - %\Huge{\textbf{\textsc{\textcolor{blue}{European Middleware Initiative}}}}\\[20mm]% - - \fontsize{22}{28}{\textbf{\textsc{\@title}}}\\[2mm]% - %\ifx\@Subtitle\@empty\else - % \normalsize\textsf{\@Subtitle}\\[10mm]% - %\fi -} -\vfill - -\begin{center} -\hbox to \textwidth{ - - \vbox{ - - {\color{MyTeal}\hrule width \frontboxwidth height 1mm depth 0pt} - - \hbox to \frontboxwidth{\sf - \begin{tabularx}{\frontboxwidth}{l>{\raggedright\arraybackslash}X} -\\ - Document version: & \textbf{\@DocVersion}\\[3mm] - EMI Component Version: & \textbf{\@EMICompVersion}\\[3mm] - Date: & \textbf{\@Date}\\[3mm] - %Document status: & \textbf{\@DocStatus}\\[3mm] - - \end{tabularx} - - } - - {\color{MyTeal}\hrule width \frontboxwidth height 1mm depth 0pt} - %}%centering - } - -} -\end{center} - -%\vfill -%{\sf\underline{Abstract}: \@Abstract} -\vfill -\newpage % end of the first page -\pagestyle{headings} -\setcounter{tocdepth}{3} -} % End of AtBeginningDocument - - -% -% EMI style small-capital section titles. -% -% The numbering is aligned with the WinWord style, -% although it is not common in the english typography... -% -\newcommand{\sectionbreak}{\newpage} -%\renewcommand{\thesection}{\arabic{section}.} -%\renewcommand{\thesubsection}{\thesection\arabic{subsection}.} -%\renewcommand{\thesubsubsection}{\thesubsection\arabic{subsubsection}.} - -\renewcommand\section{\@startsection {section}{1}{\z@}% - {-3.5ex \@plus -1ex \@minus -.2ex}% - {2.3ex \@plus.2ex}% - {\normalfont\Large\bfseries\sffamily\scshape}} - -\renewcommand\subsection{\@startsection{subsection}{2}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\normalfont\large\bfseries\sffamily\scshape}} -\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\normalfont\normalsize\bfseries\sffamily\scshape}} - - - -%% APM NEED TO REDEFINE section -%\titleformat{\section}{\Large\bfseries\sffamily\scshape}{\thesection}{1em}{} -%\titlecontents{section} [2em] {\vspace*{4pt}} -% {\large \sc \bfseries \contentslabel{2em}} -% {\large \sc \bfseries \hspace*{-2em}} -% {\large \textbf{\titlerule*[1ex]{.}\contentspage}} [\vspace*{4pt}] - -%\titleformat{\subsection}{\large\bfseries\sffamily\scshape}{\thesubsection}{1em}{} -%\titlecontents{subsection} [5em] {} -% {\sc \contentslabel{3em}} -% {\sc \hspace*{-3em}} -% {\titlerule*[1ex]{.}\contentspage} - - -% -% common constants -% -%\def\ISTNumber{INFSO-RI-508833} -\newsavebox{\@EMILogo} -%\savebox{\@EMILogo}{\includegraphics[height=0.75\headheight]{EMI_Logo_std}} -\savebox{\@EMILogo}{\includegraphics[height=0.95\headheight]{EMI_Logo_std}} -\def\EMILogo{\usebox{\@EMILogo}} -%\def\LargeEMILogo{\includegraphics[height=\headheight]{EMI_Logo_std}} -\def\SmallEMILogo{\includegraphics[height=\headheight]{EMI_Logo_std}} -\def\LargeCESNETLogo{\includegraphics[height=\headheight]{cesnet}} -% DEL \def\ISTLogo{\includegraphics[height=\headheight]{isi}} - -% -% parameters to be supplied by the author -% -% EG : subtitle seems no more needed -%\def\Subtitle#1{\gdef\@Subtitle{#1}} -%\gdef\@Subtitle{\@latex@warning@no@line{No \noexpand\Subtitle given}} - -%\def\DeliverableId#1{\gdef\@DeliverableId{#1}} -%\gdef\@DeliverableId{\@latex@warning@no@line{No \noexpand\DeliverableId given}} - - -\def\DocVersion#1{\gdef\@DocVersion{#1}} -\gdef\@DocVersion{\@latex@warning@no@line{No \noexpand\DocVersion given % - (e.g. 0.1.2)}} - -\def\EMICompVersion#1{\gdef\@EMICompVersion{#1}} -\gdef\@EMICompVersion{\@latex@warning@no@line{No \noexpand\EMICompVersion given % - (e.g. 1.2.3)}} - -\def\Date#1{\gdef\@Date{#1}} -\gdef\@Date{\@latex@warning@no@line{No \noexpand\Date given % - (e.g. 01/04/2010)}} - -%\def\Activity#1{\gdef\@Activity{#1}} -%\gdef\@Activity{\@latex@warning@no@line{No \noexpand\Activity given % -% (e.g. NA2 Dissemination and Outreach )}} - -%\def\LeadPartner#1{\gdef\@LeadPartner{#1}} -%\gdef\@LeadPartner{\@latex@warning@no@line{No \noexpand\LeadPartner given % -% (e.g. CERN, RAL )}} - -%\def\DocStatus#1{\gdef\@DocStatus{#1}} -%\gdef\@DocStatus{\@latex@warning@no@line{No \noexpand\DocStatus given % -% (e.g. DRAFT, WORKING, DELIVERED)}} - -%\def\Dissemination#1{\gdef\@Dissemination{#1}} -%\gdef\@Dissemination{\@latex@warning@no@line{No \noexpand\Dissemination given % -% (e.g. PUBLIC, INTERNAL, ...)}} - - -\long\def\Abstract#1{\gdef\@Abstract{#1}} -\gdef\@Abstract{\@latex@warning@no@line{No \noexpand\Abstract given}} - -%% -%% Define the abstract using an environment abstract - -% -% This will produce the mailto link in the PDF file -% -% -% We use the URL package, which does this nicely. The old way (\HTTP) was -% a bit buggy as it had problems with '~'s and '_'s -% -\urlstyle{sf} -\ifpdf - \newcommand{\Email}[1]{\href{mailto:#1}{<{#1}>}} - \newcommand{\HTTP}[1]{\href{#1}{\url{#1}}} -\else - \newcommand{\Email}[1]{\textsf{<{#1}>}} - \newcommand{\HTTP}[1]{\url{#1}} -\fi - - -% -% We now redifine \part and \section so that the table of contents -% has the sections/parts in upper case. -% -% Note: need to use \uppercase because \MakeUppercase is not robust -% -\def\@part[#1]#2{% - \ifnum \c@secnumdepth >\m@ne - \refstepcounter{part}% - \addcontentsline{toc}{part}{\thepart\hspace{1em}\uppercase{#1}}% - \else - \addcontentsline{toc}{part}{\uppercase{#1}}% - \fi - {\parindent \z@ \raggedright - \interlinepenalty \@M - \normalfont - \ifnum \c@secnumdepth >\m@ne - \Large\bfseries \partname\nobreakspace\thepart - \par\nobreak - \fi - \huge \bfseries #2% - \markboth{}{}\par}% - \nobreak - \vskip 3ex - \@afterheading} - -\def\@sect#1#2#3#4#5#6[#7]#8{% - \ifnum #2>\c@secnumdepth - \let\@svsec\@empty - \else - \refstepcounter{#1}% - \protected@edef\@svsec{\@seccntformat{#1}\relax}% - \fi - \@tempskipa #5\relax - \ifdim \@tempskipa>\z@ - \begingroup - #6{% - \@hangfrom{\hskip #3\relax\@svsec}% - \interlinepenalty \@M #8\@@par}% - \endgroup - \csname #1mark\endcsname{\uppercase{#7}}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - \texorpdfstring{\uppercase{#7}}{#7}}% - \else - \def\@svsechd{% - #6{\hskip #3\relax - \@svsec #8}% - \csname #1mark\endcsname{\uppercase{#7}}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - \texorpdfstring{\uppercase{#7}}{#7}}}% - \fi - \@xsect{#5}} - -% \addcontentsline{toc} expands to \contentsline{NAME} -% which in turn expands to \l@NAME. So, to specify -% the table of contents, we must define \l@chapter, \l@section, -% \l@subsection, ... ; to specify the list of figures, we must define -% \l@figure; and so on. Most of these can be defined with the -% \@dottedtocline command, which produces a contents line with dots -% between the title and the page number. It works as follows: -% -% \@dottedtocline{LEVEL}{INDENT}{NUMWIDTH} -% LEVEL : An entry is produced only if LEVEL < or = value of -% 'tocdepth' counter. Note, \chapter is level 0, \section -% is level 1, etc. -% INDENT : The indentation from the outer left margin of the start of -% the contents line. -% NUMWIDTH : The width of a box in which the section number is to go, -% if TITLE includes a \numberline command. -% - -\def\l@part{\@dottedtocline{1}{4em}{2.0em}} -\def\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}} -\def\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}} -\def\l@paragraph{\@dottedtocline{4}{7.0em}{4.1em}} -\def\l@subparagraph{\@dottedtocline{5}{10em}{5em}} - diff --git a/emi.canl.canl-c/doc/src/funding.tex b/emi.canl.canl-c/doc/src/funding.tex deleted file mode 100644 index e38009e..0000000 --- a/emi.canl.canl-c/doc/src/funding.tex +++ /dev/null @@ -1,3 +0,0 @@ -This work is co-funded by the European Commission as part of -the EMI project under -Grant Agreement INFSO-RI-261611. diff --git a/emi.canl.canl-c/doc/src/images/EMI_Logo_std.pdf b/emi.canl.canl-c/doc/src/images/EMI_Logo_std.pdf deleted file mode 100644 index 2e79001001bf2dba006668ab874cc789e55c7219..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34764 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 diff --git a/emi.canl.canl-c/doc/src/images/cesnet.pdf b/emi.canl.canl-c/doc/src/images/cesnet.pdf deleted file mode 100644 index 9b07738d8c962af32dcfad0e592bba658aff31e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4518 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 -#include -#include -#include - -#include -#include - -#define BUF_LEN 1000 - -int main(int argc, char *argv[]) -{ - canl_ctx my_ctx; - canl_io_handler my_io_h = NULL; - int err = 0; - char buf[BUF_LEN]; - int buf_len = 0; - char *p_server = NULL; - char *def_server = "www.linuxfoundation.org"; - int opt, port = 80; - struct timeval timeout; - char *serv_cert = NULL; - char *serv_key = NULL; - char *proxy_cert = NULL; - - while ((opt = getopt(argc, argv, "hp:s:c:k:")) != -1) { - switch (opt) { - case 'h': - fprintf(stderr, "Usage: %s [-p port] [-c certificate]" - " [-k private key] [-d ca_dir] [-h] " - " [-s server] [-x proxy certificate] \n", argv[0]); - exit(0); - case 'p': - port = atoi(optarg); - break; - case 's': - p_server = optarg; - break; - case 'c': - serv_cert = optarg; - break; - case 'k': - serv_key = optarg; - break; - case 'x': - proxy_cert = optarg; - break; - default: /* '?' */ - fprintf(stderr, "Usage: %s [-p port] [-c certificate]" - " [-k private key] [-d ca_dir] [-h] " - " [-s server] [-x proxy certificate] \n", argv[0]); - exit(-1); - } - } - - if (!p_server) - p_server = def_server; - - my_ctx = canl_create_ctx(); - if (!my_ctx){ - printf("CANL context cannot be created, exiting.\n"); - goto end; - } - - err = canl_create_io_handler(my_ctx, &my_io_h); - if (err) { - printf("io handler cannot be created: %s\n", - canl_get_error_message(my_ctx)); - goto end; - } - - if (serv_cert || serv_key || proxy_cert){ - err = canl_ctx_set_ssl_cred(my_ctx, serv_cert, serv_key, proxy_cert, - NULL, NULL); - if (err) { - printf("[CLIENT] cannot set certificate or key to context: %s\n", - canl_get_error_message(my_ctx)); - goto end; - } - } - - timeout.tv_sec = 150; - timeout.tv_usec = 0; - - err = canl_io_connect(my_ctx, my_io_h, p_server, NULL, port, NULL, 0, &timeout); - if (err) { - printf("[CLIENT] connection to %s cannot be established: %s\n", - p_server, canl_get_error_message(my_ctx)); - goto end; - } - else { - printf("[CLIENT] connection established\n"); - } - - strcpy(buf, "This is the testing message to send"); - buf_len = strlen(buf) + 1; - - printf("[CLIENT] Trying to send sth to the server\n"); - err = canl_io_write (my_ctx, my_io_h, buf, buf_len, &timeout); - if (err <= 0) { - printf("can't write using ssl: %s\n", - canl_get_error_message(my_ctx)); - goto end; - } - else { - buf[err] = '\0'; - printf("[CLIENT] message \"%s\" sent successfully\n", buf); - } - - err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, &timeout); - if (err > 0) { - buf[err] = '\0'; - printf ("[CLIENT] received: %s\n", buf); - err = 0; - } - -end: - if (my_io_h) - canl_io_destroy(my_ctx, my_io_h); - - canl_free_ctx(my_ctx); - - return err; -} diff --git a/emi.canl.canl-c/examples/canl_sample_server.c b/emi.canl.canl-c/examples/canl_sample_server.c deleted file mode 100644 index f1558be..0000000 --- a/emi.canl.canl-c/examples/canl_sample_server.c +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include - -#define BUF_LEN 1000 -#define BACKLOG 10 - -int main(int argc, char *argv[]) -{ - canl_ctx my_ctx; - canl_io_handler my_io_h = NULL; - int err = 0; - int opt, port = 4321; - char *serv_cert = NULL; - char *serv_key = NULL; - char *ca_dir = NULL; - char buf[BUF_LEN]; - int buf_len = 0; - struct timeval timeout; - canl_principal princ = NULL; - char *name = NULL; - - while ((opt = getopt(argc, argv, "hp:c:k:d:")) != -1) { - switch (opt) { - case 'h': - fprintf(stderr, "Usage: %s [-p port] [-c certificate]" - " [-k private key] [-d ca_dir] [-h] \n", argv[0]); - exit(0); - case 'p': - port = atoi(optarg); - break; - case 'c': - serv_cert = optarg; - break; - case 'k': - serv_key = optarg; - break; - case 'd': - ca_dir = optarg; - break; - default: /* '?' */ - fprintf(stderr, "Usage: %s [-p port] [-c certificate]" - " [-k private key] [-d ca_dir] [-h] \n", argv[0]); - exit(-1); - } - } - - my_ctx = canl_create_ctx(); - if (!my_ctx){ - printf("[SERVER] canl context cannot be created\n"); - return -1; - } - - err = canl_create_io_handler(my_ctx, &my_io_h); - if (err) { - printf("[SERVER] io handler cannot be created: %s\n", - canl_get_error_message(my_ctx)); - goto end; - } - - if (serv_cert || serv_key){ - err = canl_ctx_set_ssl_cred(my_ctx, serv_cert, serv_key, NULL, - NULL, NULL); - if (err) { - printf("[SERVER] cannot set certificate or key to context: %s\n", - canl_get_error_message(my_ctx)); - goto end; - } - } - - /* ACCEPT from canl_io_accept*/ - int sockfd = 0, new_fd = 0; - char str_port[8]; - struct addrinfo hints, *servinfo, *p; - struct sockaddr s_addr; - socklen_t sin_size; - int yes=1; - - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; // use my IP - - if (snprintf(str_port, 8, "%d", port) < 0) { - printf ("[SERVER] Wrong port request"); - return 1; - } - - /* XXX timeouts - use c-ares, too */ - if ((err = getaddrinfo(NULL, str_port, &hints, &servinfo)) != 0) { - printf("[SERVER] getaddrinfo: %s\n", gai_strerror(err)); - return 1; - } - - for (p = servinfo; p != NULL; p = p->ai_next) { - if ((sockfd = socket(p->ai_family, p->ai_socktype, - p->ai_protocol)) == -1) { - err = errno; - continue; - } - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, - sizeof(int)) == -1) { - err = errno; - continue; - } - if ((err = bind(sockfd, p->ai_addr, p->ai_addrlen))) { - err = errno; - close(sockfd); - continue; - } - if ((err = listen(sockfd, BACKLOG))) { - close(sockfd); - err = errno; - continue; - } - - break; - } - - freeaddrinfo(servinfo); // all done with this structure - if (p == NULL) { - /* Beware that only the last error is displayed here ... */ - printf("Failed to acquire a server socket: %s\n", - strerror(err)); - return 1; - } - - printf("server: waiting for connections...\n"); - sin_size = sizeof(s_addr); - new_fd = accept(sockfd, &s_addr, &sin_size); - if (new_fd == -1){ - printf("Failed to accept network connection: %s", strerror(errno)); - } - - timeout.tv_sec = 150; - timeout.tv_usec = 0; - - /* canl_create_io_handler has to be called for my_io_h*/ - /* TODO timeout in this function? and select around it*/ - err = canl_io_accept(my_ctx, my_io_h, new_fd, s_addr, 0, &princ, &timeout); - if (err) { - printf("[SERVER] connection cannot be established: %s\n", - canl_get_error_message(my_ctx)); - goto end; - } - - err = canl_princ_name(my_ctx, princ, &name); - printf("[SERVER] connection established with %s\n", name); - free(name); - canl_princ_free(my_ctx, princ); - - strncpy(buf, "This is a testing message to send", sizeof(buf)); - buf_len = strlen(buf) + 1; - - printf("[SERVER] Trying to send sth to the client\n"); - err = canl_io_write (my_ctx, my_io_h, buf, buf_len, &timeout); - if (err <= 0) { - printf("[SERVER] cannot send message to the client: %s\n", - canl_get_error_message(my_ctx)); - goto end; - } - else { - buf[err] = '\0'; - printf("[SERVER] message \"%s\" sent successfully\n", buf); - } - - err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, NULL); - if (err <= 0) { - printf("[SERVER] Failed to receive reply from client: %s\n", - canl_get_error_message(my_ctx)); - goto end; - } - - buf[err] = '\0'; - printf ("[SERVER] received: %s\n", buf); - err = 0; - -end: - if (my_io_h) - canl_io_destroy(my_ctx, my_io_h); - - canl_free_ctx(my_ctx); - - return err; -} diff --git a/emi.canl.canl-c/examples/delegation.c b/emi.canl.canl-c/examples/delegation.c deleted file mode 100644 index c3f5c3b..0000000 --- a/emi.canl.canl-c/examples/delegation.c +++ /dev/null @@ -1,213 +0,0 @@ -#include -#include -#include -#include - -#define BITS 1024 -#define LIFETIME 43200 /*12 hours*/ -#define OUTPUT "/tmp/x509_u99999" - -int -main(int argc, char *argv[]) -{ - canl_cred signer = NULL; - canl_cred proxy = NULL; - canl_cred proxy_cert = NULL; - canl_cred proxy_bob = NULL; - X509_REQ *req = NULL; - X509 *x509_cert = NULL; - STACK_OF(X509) *x509_chain= NULL; - canl_ctx ctx = NULL; - canl_err_code ret; - - char *user_cert = NULL; - char *output = NULL; - char *user_key = NULL; - long int lifetime = 0; - unsigned int bits = 0; - int opt = 0; - - while ((opt = getopt(argc, argv, "hc:k:l:b:o:")) != -1) { - switch (opt) { - case 'h': - fprintf(stderr, "Usage: %s [-c certificate]" - " [-k private key] [-h] [-l lifetime] [-b bits]" - " [-o output]" - "\n", argv[0]); - exit(0); - case 'c': - user_cert = optarg; - break; - case 'k': - user_key = optarg; - break; - case 'l': - lifetime = atoi(optarg); - break; - case 'b': - bits = atoi(optarg); - break; - case 'o': - output = optarg; - break; - default: /* '?' */ - fprintf(stderr, "Usage: %s [-c certificate]" - " [-k private key] [-h] [-l lifetime] [-b bits]" - " [-o output]" - "\n", argv[0]); - exit(-1); - } - } - - ctx = canl_create_ctx(); - if (ctx == NULL) { - fprintf(stderr, "[DELEGATION] Failed to create library context\n"); - return 1; - } - - /* Bob - after Alice has asked to delegate her credentials */ - ret = canl_cred_new(ctx, &proxy_bob); - if (ret){ - fprintf(stderr, "[DELEGATION] Proxy context cannot be created" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - - if (!bits) - bits = BITS; - ret = canl_cred_new_req(ctx, proxy_bob, bits); - if (ret) { - fprintf(stderr, "[DELEGATION] Failed to create certificate " - "request container: %s\n", canl_get_error_message(ctx)); - goto end; - } - ret = canl_cred_save_req(ctx, proxy_bob, &req); - if (ret) { - fprintf(stderr, "[DELEGATION] Failed to get certificate " - "request container: %s\n", canl_get_error_message(ctx)); - goto end; - } - - /* serialize 'req' and send it to Alice */ - -/* Alice - after receiving the CSR from Bob. (The private key stays with Bob.) */ - { - ret = canl_cred_new(ctx, &signer); - if (ret){ - fprintf(stderr, "[DELEGATION] Proxy context cannot be created" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - - ret = canl_cred_load_cert_file(ctx, signer, user_cert); - if (ret){ - fprintf(stderr, "[DELEGATION] Cannot load signer's certificate" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - ret = canl_cred_load_priv_key_file(ctx, signer, user_key, NULL, NULL); - if (ret){ - fprintf(stderr, "[DELEGATION] Cannot access signer's key" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - - /* deserialize 'req' from Bob */ - ret = canl_cred_new(ctx, &proxy_cert); - if (ret){ - fprintf(stderr, "[DELEGATION] Proxy context cannot be created" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - ret = canl_cred_load_req(ctx, proxy_cert, req); - if (ret) { - fprintf(stderr, "[DELEGATION] Failed to load certificate " - "request container: %s\n", canl_get_error_message(ctx)); - goto end; - } - - - if (!lifetime) - lifetime = LIFETIME; - ret = canl_cred_set_lifetime(ctx, proxy_cert, lifetime); - if (ret) - fprintf(stderr, "[DELEGATION] Failed set new cert lifetime" - ": %s\n", canl_get_error_message(ctx)); - - ret = canl_cred_set_cert_type(ctx, proxy_cert, CANL_RFC); - if (ret) - fprintf(stderr, "[DELEGATION] Failed set new cert type" - ": %s\n", canl_get_error_message(ctx)); - - ret = canl_cred_sign_proxy(ctx, signer, proxy_cert); - if (ret){ - fprintf(stderr, "[DELEGATION] Cannot sign new proxy" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - - ret = canl_cred_save_cert(ctx, proxy_cert, &x509_cert); - if (ret){ - fprintf(stderr, "[DELEGATION] Cannot save new cert file" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - - ret = canl_cred_save_chain(ctx, proxy_cert, &x509_chain); - if (ret){ - fprintf(stderr, "[DELEGATION] Cannot save cert chain" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - /* serialize the new proxy cert and chain and send it back to Bob */ - } - -/* Bob - on receiving the final certificate and chain */ - /* deserialize the new proxy cert and chain from Alice */ - - ret = canl_cred_load_cert(ctx, proxy_bob, x509_cert); - if (ret){ - fprintf(stderr, "[DELEGATION] Cannot load certificate" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - - ret = canl_cred_load_chain(ctx, proxy_bob, x509_chain); - if (ret){ - fprintf(stderr, "[DELEGATION] Cannot load cert. chain" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - - if (!output) - output = OUTPUT; - ret = canl_cred_save_proxyfile(ctx, proxy_bob, output); - if (ret){ - fprintf(stderr, "[PROXY-INIT] Cannot save new proxy" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - - ret = 0; -end: - if (signer) - canl_cred_free(ctx, signer); - if (proxy) - canl_cred_free(ctx, proxy); - if (proxy_cert) - canl_cred_free(ctx, proxy_cert); - if (proxy_bob) - canl_cred_free(ctx, proxy_bob); - if (req) - X509_REQ_free(req); - if (x509_cert) - X509_free(x509_cert); -/* TODO free stack - * if (x509_chain) - X509_free(x509_cert); -*/ - if (ctx) - canl_free_ctx(ctx); - - return ret; -} diff --git a/emi.canl.canl-c/examples/grid-proxy-init.c b/emi.canl.canl-c/examples/grid-proxy-init.c deleted file mode 100644 index c4a9a35..0000000 --- a/emi.canl.canl-c/examples/grid-proxy-init.c +++ /dev/null @@ -1,153 +0,0 @@ -#include -#include -#include -#include - -#define BITS 1024 -#define LIFETIME 43200 /*12 hours*/ -#define OUTPUT "/tmp/x509_u99999" - -int main(int argc, char *argv[]) -{ - canl_cred signer = NULL; - canl_cred proxy = NULL; - canl_ctx ctx = NULL; - canl_err_code ret = 0; - char *user_cert = NULL; - char *output = NULL; - char *user_key = NULL; - long int lifetime = 0; - unsigned int bits = 0; - int opt = 0; - - while ((opt = getopt(argc, argv, "hc:k:l:b:o:")) != -1) { - switch (opt) { - case 'h': - fprintf(stderr, "Usage: %s [-c certificate]" - " [-k private key] [-h] [-l lifetime] [-b bits]" - " [-o output]" - "\n", argv[0]); - exit(0); - case 'c': - user_cert = optarg; - break; - case 'k': - user_key = optarg; - break; - case 'l': - lifetime = atoi(optarg); - break; - case 'b': - bits = atoi(optarg); - break; - case 'o': - output = optarg; - break; - default: /* '?' */ - fprintf(stderr, "Usage: %s [-c certificate]" - " [-k private key] [-h] [-l lifetime] [-b bits]" - " [-o output]" - "\n", argv[0]); - exit(-1); - } - } - - ctx = canl_create_ctx(); - if (ctx == NULL) { - fprintf(stderr, "[PROXY-INIT] Failed to create library context\n"); - return 1; - } - - /* First create a certificate request with a brand-new keypair */ - ret = canl_cred_new(ctx, &proxy); - if (ret){ - fprintf(stderr, "[PROXY-INIT] Proxy context cannot be created" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - - if (!bits) - bits = BITS; - ret = canl_cred_new_req(ctx, proxy, bits); - if (ret) { - fprintf(stderr, "[PROXY-INIT] Failed to create certificate " - "request container: %s\n", canl_get_error_message(ctx)); - goto end; - } - - if (!lifetime) - lifetime = LIFETIME; - /*Create key-pairs implicitly*/ - ret = canl_cred_set_lifetime(ctx, proxy, lifetime); - if (ret) - fprintf(stderr, "[PROXY-INIT] Failed set new cert lifetime" - ": %s\n", canl_get_error_message(ctx)); - - ret = canl_cred_set_cert_type(ctx, proxy, CANL_RFC); - if (ret) - fprintf(stderr, "[PROXY-INIT] Failed set new cert type" - ": %s\n", canl_get_error_message(ctx)); - - /* Load the signing credentials */ - ret = canl_cred_new(ctx, &signer); - if (ret){ - fprintf(stderr, "[PROXY-INIT] Proxy context cannot be created" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - - ret = canl_cred_load_cert_file(ctx, signer, user_cert); - if (ret){ - fprintf(stderr, "[PROXY-INIT] Cannot load signer's certificate" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - ret = canl_cred_load_priv_key_file(ctx, signer, user_key, NULL, NULL); - if (ret){ - fprintf(stderr, "[PROXY-INIT] Cannot access signer's key" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - /*TODO? export lookup routines ?? */ - -#ifdef VOMS - GET_VOMS_EXTS(ctx, signer, STACK_OF(EXTS)); - foreach (EXTS) { - ret = canl_cred_set_extension(ctx, proxy, ext); - if (ret){ - fprintf(stderr, "[PROXY-INIT] Cannot set voms extension" - ": %s\n", canl_get_error_message(ctx)); - } - } -#endif - -/* Create the proxy certificate */ - ret = canl_cred_sign_proxy(ctx, signer, proxy); - if (ret){ - fprintf(stderr, "[PROXY-INIT] Cannot sign new proxy" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - -/* and store it in a file */ - if (!output) - output = OUTPUT; - ret = canl_cred_save_proxyfile(ctx, proxy, output); - if (ret){ - fprintf(stderr, "[PROXY-INIT] Cannot save new proxy" - ": %s\n", canl_get_error_message(ctx)); - goto end; - } - - ret = 0; - -end: - if (signer) - canl_cred_free(ctx, signer); - if (proxy) - canl_cred_free(ctx, proxy); - if (ctx) - canl_free_ctx(ctx); - - return ret; -} diff --git a/emi.canl.canl-c/project/ChangeLog b/emi.canl.canl-c/project/ChangeLog deleted file mode 100644 index edbc4cb..0000000 --- a/emi.canl.canl-c/project/ChangeLog +++ /dev/null @@ -1,40 +0,0 @@ -1.0.0-1 -- Initial version of the module - -1.0.1-1 -- Using pre-cooked lexical analyser instead of having it generated at build time -- Build cleanups -- Improvements throughout the code - -1.0.2-1 -- Building certificate delegation samples -- Making use of canl_mech_ssl to include openssl header files -- Examples added: canl-proxy-init -- Client can give cert and key paths explicitly -- Recognition of command line args -- License string as recognized by rpmlint and packaging guidelines -- Truly independent of auth. mechanism -- Cert, key in mech. context -- Writing proxy to file with restrictive permissions -- Duplicating only existing certificates -- Set CA directory and CRL directory to context -- Compatiblity with FIPS openssl releases - -1.0.3-1 -- Examples extended -- Storing certificate + chain of approp. certs in context -- Duplicate certificates instead of using pointers in cred handling -- Delegation sample made truly funcional -- Setting CA directory and CRL directory is X509 authn. mechanism specific -- Preparation for OCSP support -- Using proxy cert file (chain of certs) as easy as user cert - -1.0.4-1 -- Build dependency on krb5-devel added -- Better error codes -- Refuse to sign certificate if key size is not long enough -- Using default key size of 1024 bits -- canl_cert_req object not used anymore -- Preparing implementation of OCSP support -- Fixed Vulnerability in Voms CRL processing - diff --git a/emi.canl.canl-c/project/canl-c.spec b/emi.canl.canl-c/project/canl-c.spec deleted file mode 100644 index 97fd19d..0000000 --- a/emi.canl.canl-c/project/canl-c.spec +++ /dev/null @@ -1,97 +0,0 @@ -Summary: @SUMMARY@ -Name: canl-c -Version: @MAJOR@.@MINOR@.@REVISION@ -Release: @AGE@%{?dist} -Url: @URL@ -License: ASL 2.0 -Vendor: EMI -Group: System Environment/Libraries -BuildRequires: bison -BuildRequires: c-ares-devel%{?_isa} -BuildRequires: chrpath -BuildRequires: flex -BuildRequires: krb5-devel%{?_isa} -BuildRequires: libtool -BuildRequires: openssl-devel%{?_isa} -BuildRequires: pkgconfig -BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) -AutoReqProv: yes -Source: http://eticssoft.web.cern.ch/eticssoft/repository/emi/emi.canl.c/%{version}/src/%{name}-@VERSION@.src.tar.gz - - -%description -@DESCRIPTION@ - - -%package devel -Summary: Development files for EMI caNl -Group: Development/Libraries -Requires: %{name}%{?_isa} = %{version}-%{release} -Requires: krb5-devel%{?_isa} - - -%description devel -This package contains development libraries and header files for EMI caNL. - - -%package examples -Summary: Example programs of EMI caNl -Group: System Environment/Base - - -%description examples -This package contains client and server examples of EMI caNL. - - -%prep -%setup -q - - -%build -/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=%{_lib} --project=emi --module canl.c -make - - -%check -make check - - -%install -rm -rf $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT -make install DESTDIR=$RPM_BUILD_ROOT -find $RPM_BUILD_ROOT -name '*.la' -exec rm -rf {} \; -find $RPM_BUILD_ROOT -name '*.a' -exec rm -rf {} \; -find $RPM_BUILD_ROOT -name '*' -print | xargs -I {} -i bash -c "chrpath -d {} > /dev/null 2>&1" || echo 'Stripped RPATH' - - -%clean -rm -rf $RPM_BUILD_ROOT - - -%post -p /sbin/ldconfig - - -%postun -p /sbin/ldconfig - - -%files -%defattr(-,root,root) -/usr/%{_lib}/libcanl_c.so.@MAJOR@.@MINOR@.@REVISION@ -/usr/%{_lib}/libcanl_c.so.@MAJOR@ - - -%files devel -%defattr(-,root,root) -/usr/include/*.h -/usr/%{_lib}/libcanl_c.so - - -%files examples -%defattr(-,root,root) -/usr/bin/* - - -%changelog -* @SPEC_DATE@ @MAINTAINER@ - @MAJOR@.@MINOR@.@REVISION@-@AGE@%{?dist} -- automatically generated package diff --git a/emi.canl.canl-c/project/debian.control b/emi.canl.canl-c/project/debian.control deleted file mode 100644 index 6d30543..0000000 --- a/emi.canl.canl-c/project/debian.control +++ /dev/null @@ -1,39 +0,0 @@ -Source: canl-c -Priority: extra -Maintainer: @MAINTAINER@ -Uploaders: @UPLOADERS@ -Build-Depends: debhelper (>= 7.0.50~), bison, chrpath, flex, libc-ares-dev, libkrb5-dev, libssl-dev, libtool, pkg-config -Standards-Version: 3.9.1 -Section: libs -Homepage: @URL@ -DM-Upload-Allowed: yes -@DEBIAN_VCS@ - -Package: libcanl-c1 -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: @SUMMARY@ -@DEBIAN_DESCRIPTION@ - -Package: libcanl-c-dev -Section: libdevel -Architecture: any -Depends: libcanl-c1 (= ${binary:Version}), libkrb5-dev, ${misc:Depends} -Description: Development files for EMI caNl - This package contains development libraries and header files for EMI caNL. - -Package: libcanl-c-examples -Section: misc -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: Example programs of EMI caNl - This package contains client and server examples of EMI caNL. - -Package: canl-c-dbg -Section: debug -Architecture: any -Priority: extra -Depends: libcanl-c1 (= ${binary:Version}), ${misc:Depends} -Description: EMI caNl debugging symbols - This package contains debugging symbols for EMI caNl. diff --git a/emi.canl.canl-c/project/debian.copyright b/emi.canl.canl-c/project/debian.copyright deleted file mode 100644 index 3d762ae..0000000 --- a/emi.canl.canl-c/project/debian.copyright +++ /dev/null @@ -1,38 +0,0 @@ -This work was packaged for Debian by: - - @MAINTAINER@ on Thu, 08 Dec 2011 00:46:07 +0100 - -It was downloaded from: - - @URL@ - -Upstream Author(s): - - @MAINTAINER@ - -Copyright: - - - -License: - - 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. - -On Debian systems, the complete text of the Apache version 2.0 license -can be found in "/usr/share/common-licenses/Apache-2.0". - -The Debian packaging is: - - Copyright (C) 2004-2011 Members of the EGEE Collaboration - -and is licensed under the Apache License, Version 2.0. diff --git a/emi.canl.canl-c/project/debian.libcanl-c-dev.dirs b/emi.canl.canl-c/project/debian.libcanl-c-dev.dirs deleted file mode 100644 index da07fdd..0000000 --- a/emi.canl.canl-c/project/debian.libcanl-c-dev.dirs +++ /dev/null @@ -1,2 +0,0 @@ -usr/include -usr/lib diff --git a/emi.canl.canl-c/project/debian.libcanl-c-dev.install b/emi.canl.canl-c/project/debian.libcanl-c-dev.install deleted file mode 100644 index 354b178..0000000 --- a/emi.canl.canl-c/project/debian.libcanl-c-dev.install +++ /dev/null @@ -1,3 +0,0 @@ -usr/include/* -usr/lib/lib*.so - diff --git a/emi.canl.canl-c/project/debian.libcanl-c-examples.dirs b/emi.canl.canl-c/project/debian.libcanl-c-examples.dirs deleted file mode 100644 index e772481..0000000 --- a/emi.canl.canl-c/project/debian.libcanl-c-examples.dirs +++ /dev/null @@ -1 +0,0 @@ -usr/bin diff --git a/emi.canl.canl-c/project/debian.libcanl-c-examples.install b/emi.canl.canl-c/project/debian.libcanl-c-examples.install deleted file mode 100644 index 1df36c6..0000000 --- a/emi.canl.canl-c/project/debian.libcanl-c-examples.install +++ /dev/null @@ -1 +0,0 @@ -usr/bin/* diff --git a/emi.canl.canl-c/project/debian.libcanl-c1.dirs b/emi.canl.canl-c/project/debian.libcanl-c1.dirs deleted file mode 100644 index 6845771..0000000 --- a/emi.canl.canl-c/project/debian.libcanl-c1.dirs +++ /dev/null @@ -1 +0,0 @@ -usr/lib diff --git a/emi.canl.canl-c/project/debian.libcanl-c1.install b/emi.canl.canl-c/project/debian.libcanl-c1.install deleted file mode 100644 index d0dbfd1..0000000 --- a/emi.canl.canl-c/project/debian.libcanl-c1.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/lib*.so.* diff --git a/emi.canl.canl-c/project/debian.rules b/emi.canl.canl-c/project/debian.rules deleted file mode 100644 index 7a62171..0000000 --- a/emi.canl.canl-c/project/debian.rules +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- - --include /usr/share/dpkg/buildflags.mk - -# Uncomment this to turn on verbose mode. -export DH_VERBOSE=1 - -configure: configure-stamp -configure-stamp: - dh_testdir - /usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=lib --project=emi --module canl.c - touch $@ - -build: build-arch build-indep - -build-arch build-indep: build-stamp - -build-stamp: configure-stamp - dh_testdir - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) check - touch $@ - -clean: configure-stamp - dh_testdir - dh_testroot - rm -f configure-stamp build-stamp - $(MAKE) clean - rm -f Makefile.inc config.status - dh_clean - -install: build-stamp - dh_testdir - dh_testroot - dh_prep - dh_installdirs - $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp - rm -vf $(CURDIR)/debian/tmp/usr/lib/*.la - rm -vf $(CURDIR)/debian/tmp/usr/lib/*.a - find $(CURDIR)/debian/tmp -name '*' -print | xargs -I {} -i bash -c "chrpath -d {} > /dev/null 2>&1" || echo 'Stripped RPATH' - -binary-indep: - -binary-arch: install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_installexamples - dh_installman - dh_installlogrotate - dh_installcron - dh_install --fail-missing - dh_link - dh_strip --dbg-package=canl-c-dbg - dh_compress - dh_fixperms - dh_makeshlibs - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-arch binary-indep diff --git a/emi.canl.canl-c/project/package.description b/emi.canl.canl-c/project/package.description deleted file mode 100644 index b892391..0000000 --- a/emi.canl.canl-c/project/package.description +++ /dev/null @@ -1 +0,0 @@ -This is the c part of the EMI caNl -- the Common Authentication Library. diff --git a/emi.canl.canl-c/project/package.summary b/emi.canl.canl-c/project/package.summary deleted file mode 100644 index 6dc2694..0000000 --- a/emi.canl.canl-c/project/package.summary +++ /dev/null @@ -1 +0,0 @@ -EMI Common Authentication library - bindings for C diff --git a/emi.canl.canl-c/project/version.properties b/emi.canl.canl-c/project/version.properties deleted file mode 100644 index 94356e4..0000000 --- a/emi.canl.canl-c/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# $Header: -module.version=1.0.4 -module.age=1 diff --git a/emi.canl.canl-c/src/canl.c b/emi.canl.canl-c/src/canl.c deleted file mode 100644 index bbfdc10..0000000 --- a/emi.canl.canl-c/src/canl.c +++ /dev/null @@ -1,520 +0,0 @@ -#include "canl_locl.h" - -static struct canl_mech *mechs[] = { - &canl_mech_ssl, -}; - -static void io_destroy(glb_ctx *cc, io_handler *io); -static int init_io_content(glb_ctx *cc, io_handler *io); -static int try_connect(glb_ctx *glb_cc, io_handler *io_cc, char *addr, - int addrtype, int port, struct timeval *timeout); - -canl_ctx canl_create_ctx() -{ - glb_ctx *ctx = NULL; - int i; - - /*create context*/ - ctx = (glb_ctx *) calloc(1, sizeof(*ctx)); - if (!ctx) - return NULL; - - for (i = 0; i < sizeof(mechs)/sizeof(mechs[0]); i++) - mechs[i]->initialize(ctx, &mechs[i]->glb_ctx); - - return ctx; -} - -void canl_free_ctx(canl_ctx cc) -{ - glb_ctx *ctx = (glb_ctx*) cc; - - if (!cc) - return; - - /*delete content*/ - if (ctx->err_msg) { - free(ctx->err_msg); - ctx->err_msg = NULL; - } - /*TODO delete ctx content for real*/ - - free(ctx); -} - -canl_err_code -canl_create_io_handler(canl_ctx cc, canl_io_handler *io) -{ - io_handler *new_io_h = NULL; - glb_ctx *g_cc = cc; - int err = 0; - - if (!g_cc || io == NULL) - return EINVAL; - - /*create io handler*/ - new_io_h = (io_handler *) calloc(1, sizeof(*new_io_h)); - if (!new_io_h) - return set_error(g_cc, ENOMEM, POSIX_ERROR, "Not enough memory"); - - /* allocate memory and initialize io content*/ - if ((err = init_io_content(g_cc ,new_io_h))){ - free(new_io_h); - return err; - } - - *io = new_io_h; - return 0; -} - -static int init_io_content(glb_ctx *cc, io_handler *io) -{ - io->oid = GSS_C_NO_OID; - io->sock = -1; - return 0; -} - -canl_err_code -canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, const char *service, - int port, gss_OID_set auth_mechs, - int flags, struct timeval *timeout) -{ - int err = 0; - io_handler *io_cc = (io_handler*) io; - glb_ctx *glb_cc = (glb_ctx*) cc; - struct _asyn_result ar; - int i = 0, k; - int addr_types[] = {AF_INET, AF_INET6}; //TODO ip versions policy? - int ipver = AF_INET6; - int j = 0, done; - struct canl_mech *mech; - gss_OID oid; - - memset(&ar, 0, sizeof(ar)); - - if (!glb_cc) { - return EINVAL; - } - - if (!io_cc) - return set_error(glb_cc, EINVAL, POSIX_ERROR, - "IO handler not initialized"); - - done = 0; - for (k = 0; k < sizeof(addr_types)/sizeof(*addr_types); k++) { - ipver = addr_types[k]; - if (ar.ent) { - free_hostent(ar.ent); - memset(&ar, 0, sizeof(ar)); - } - - ar.ent = (struct hostent *) calloc (1, sizeof(struct hostent)); - if (ar.ent == NULL) - return set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory"); - - switch (err = asyn_getservbyname(ipver, &ar, host, NULL)) { - case NETDB_SUCCESS: - err = 0; - break; - case TRY_AGAIN: - err = update_error(glb_cc, ETIMEDOUT, POSIX_ERROR, - "Cannot resolve the server hostname (%s)", host); - goto end; - case NETDB_INTERNAL: - err = update_error(glb_cc, errno, POSIX_ERROR, - "Cannot resolve the server hostname (%s)", host); - continue; - default: - err = update_error(glb_cc, err, NETDB_ERROR, - "Cannot resolve the server hostname (%s)", host); - continue; - } - - j = 0; - do { - if (auth_mechs == GSS_C_NO_OID_SET || auth_mechs->count == 0) - oid = GSS_C_NO_OID; - else - oid = &auth_mechs->elements[j]; - - mech = find_mech(oid); - - err = 0; - for (i = 0; ar.ent->h_addr_list[i]; i++) { - void *ctx = NULL; - - if (err == ETIMEDOUT) - goto end; - - err = try_connect(glb_cc, io_cc, ar.ent->h_addr_list[i], - ar.ent->h_addrtype, port, timeout);//TODO timeout - if (err) - continue; - - err = mech->client_init(glb_cc, mech->glb_ctx, &ctx); - if (err) { - canl_io_close(glb_cc, io_cc); - continue; - } - - err = mech->connect(glb_cc, io_cc, ctx, timeout, host); //TODO timeout - if (err) { - canl_io_close(glb_cc, io_cc); - mech->free_ctx(glb_cc, ctx); - ctx = NULL; - continue; - } - io_cc->conn_ctx = ctx; - done = 1; - break; - } - if (err == ETIMEDOUT) - goto end; - j++; - } while (auth_mechs != GSS_C_NO_OID_SET && j < auth_mechs->count && !done); - - free_hostent(ar.ent); - ar.ent = NULL; - if (done) - break; - } - - if (!done) { - err = ECONNREFUSED; - goto end; - } - - err = 0; - -end: - if (err) /* XXX: rather invent own error */ - err = update_error(glb_cc, ECONNREFUSED, POSIX_ERROR, - "Failed to make network connection to server %s", host); - - if (ar.ent != NULL) - free_hostent(ar.ent); - - return err; -} -/* try to connect to addr with port (both ipv4 and 6) - * return 0 when successful - * errno otherwise*/ -/* XXX use set_error on errors and return a CANL return code */ -static int try_connect(glb_ctx *glb_cc, io_handler *io_cc, char *addr, - int addrtype, int port, struct timeval *timeout) -{ - //struct timeval before,after,to; - struct sockaddr_storage a; - struct sockaddr_storage *p_a=&a; - socklen_t a_len; - int sock; - int err = 0; - - struct sockaddr_in *p4 = (struct sockaddr_in *)p_a; - struct sockaddr_in6 *p6 = (struct sockaddr_in6 *)p_a; - - memset(p_a, 0, sizeof *p_a); - p_a->ss_family = addrtype; - switch (addrtype) { - case AF_INET: - memcpy(&p4->sin_addr, addr, sizeof(struct in_addr)); - p4->sin_port = htons(port); - a_len = sizeof (struct sockaddr_in); - break; - case AF_INET6: - memcpy(&p6->sin6_addr, addr, sizeof(struct in6_addr)); - p6->sin6_port = htons(port); - a_len = sizeof (struct sockaddr_in6); - break; - default: - return update_error(glb_cc, EINVAL, POSIX_ERROR, - "Unsupported address type (%d)", addrtype); - break; - } - - sock = socket(a.ss_family, SOCK_STREAM, 0); - if (sock == -1) - return update_error(glb_cc, errno, POSIX_ERROR, - "Failed to create network socket"); - - err = connect(sock,(struct sockaddr *) &a, a_len); - /* XXX timeouts missing */ - if (err) { - return update_error(glb_cc, errno, POSIX_ERROR, - "Failed to open network connection"); - } - - io_cc->sock = sock; - return 0; -} - -/*TODO select + timeout, EINTR!!! */ -canl_err_code -canl_io_accept(canl_ctx cc, canl_io_handler io, int new_fd, - struct sockaddr s_addr, int flags, canl_principal *peer, - struct timeval *timeout) -{ - int err = 0; - io_handler *io_cc = (io_handler*) io; - glb_ctx *glb_cc = (glb_ctx*) cc; - struct canl_mech *mech = find_mech(GSS_C_NO_OID); - void *conn_ctx = NULL; - - if (!glb_cc) - return EINVAL; /* XXX Should rather be a CANL error */ - - if (!io_cc) - return set_error(cc, EINVAL, POSIX_ERROR, "IO handler not initialized"); - - io_cc->sock = new_fd; - - err = mech->server_init(glb_cc, mech->glb_ctx, &conn_ctx); - if (err) - goto end; - - err = mech->accept(glb_cc, io_cc, conn_ctx, timeout); - if (err) - goto end; - - /*TODO Not mandatory peer certificate for now*/ -/* if (peer) { - err = mech->get_peer(glb_cc, io_cc, conn_ctx, peer); - if (err) - goto end; - } -*/ - io_cc->conn_ctx = conn_ctx; - io_cc->oid = GSS_C_NO_OID; - - err = 0; - -end: - if (err) { - (io_cc)->sock = -1; - mech->free_ctx(glb_cc, conn_ctx); - } - - return err; -} - -/* close connection, preserve some info for the future reuse */ -canl_err_code -canl_io_close(canl_ctx cc, canl_io_handler io) -{ - io_handler *io_cc = (io_handler*) io; - glb_ctx *glb_cc = (glb_ctx*) cc; - int err = 0; - canl_mech *mech; - - /*check cc and io*/ - if (!cc) { - return EINVAL; /* XXX Should rather be a CANL error */ - } - - if (!io) - return set_error(cc, EINVAL, POSIX_ERROR, "IO handler not initialized"); - - if (io_cc->conn_ctx) { - mech = find_mech(io_cc->oid); - mech->close(glb_cc, io, io_cc->conn_ctx); - /* XXX can it be safely reopened ?*/ - } - - if (io_cc->sock != -1) { - close (io_cc->sock); - io_cc->sock = -1; - } - - return err; -} - -static void io_destroy(glb_ctx *cc, io_handler *io) -{ - io_handler *io_cc = (io_handler*) io; - canl_mech *mech; - - if (io == NULL) - return; - - if (io_cc->conn_ctx) { - mech = find_mech(io->oid); - mech->free_ctx(cc, io_cc->conn_ctx); - io_cc->conn_ctx = NULL; - io_cc->oid = GSS_C_NO_OID; - } - - return; -} - - -canl_err_code -canl_io_destroy(canl_ctx cc, canl_io_handler io) -{ - int err = 0; - glb_ctx *glb_cc = (glb_ctx*) cc; - io_handler *io_cc = (io_handler*) io; - /*check cc and io*/ - - if (!glb_cc) { - return EINVAL; /* XXX Should rather be a CANL error */ - } - - if (!io_cc) - return set_error(glb_cc, EINVAL, POSIX_ERROR, "Invalid io handler"); - - canl_io_close(cc, io); - - io_destroy(glb_cc, io_cc); - free (io_cc); - - return err; -} - -/* XXX: 0 returned returned by ssl_read() means error or EOF ? */ -size_t canl_io_read(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, struct timeval *timeout) -{ - io_handler *io_cc = (io_handler*) io; - glb_ctx *glb_cc = (glb_ctx*) cc; - int b_recvd = 0; - struct canl_mech *mech; - - if (!cc) - return -1; - - if (!io) { - set_error(cc, EINVAL, POSIX_ERROR, "IO handler not initialized"); - return -1; - } - - if (io_cc->conn_ctx == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "Connection not secured"); - - if (!buffer || !size) { - set_error(cc, EINVAL, POSIX_ERROR, "No memory to write into"); - return -1; - } - - mech = find_mech(io_cc->oid); - - b_recvd = mech->read(glb_cc, io_cc, io_cc->conn_ctx, - buffer, size, timeout); - - return b_recvd; -} - -size_t canl_io_write(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, struct timeval *timeout) -{ - io_handler *io_cc = (io_handler*) io; - glb_ctx *glb_cc = (glb_ctx*) cc; - int b_written = 0; - struct canl_mech *mech; - - if (!cc) - return -1; - - if (!io) { - set_error(cc, EINVAL, POSIX_ERROR, "IO handler not initialized"); - return -1; - } - - if (io_cc->conn_ctx == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "Connection not secured"); - - if (!buffer || !size) { - set_error(cc, EINVAL, POSIX_ERROR, "No memory to read from"); - return -1; - } - - mech = find_mech(io_cc->oid); - - b_written = mech->write(glb_cc, io_cc, io_cc->conn_ctx, - buffer, size, timeout); - - return b_written; -} - -#if 0 -int canl_set_ctx_own_cert(canl_ctx cc, canl_x509 cert, - canl_stack_of_x509 chain, canl_pkey key) -{ - glb_ctx *glb_cc = (glb_ctx*) cc; - int err = 0; - - if (!cc) - return EINVAL; - if(!cert) - return set_error(glb_cc, EINVAL, POSIX_ERROR, "invalid" - "parameter value"); - - err = do_set_ctx_own_cert(glb_cc, cert, chain, key); - if(err) { - update_error(glb_cc, "can't set cert or key to context"); - } - return err; -} - -//TODO callback and userdata process -int canl_set_ctx_own_cert_file(canl_ctx cc, char *cert, char *key, - canl_password_callback cb, void *userdata) -{ - glb_ctx *glb_cc = (glb_ctx*) cc; - int err = 0; - - if (!cc) - return EINVAL; - if(!cert ) { - set_error(glb_cc, EINVAL, POSIX_ERROR, "invalid parameter value"); - return EINVAL; - } - - err = do_set_ctx_own_cert_file(glb_cc, cert, key); - if(err) { - update_error(glb_cc, "can't set cert or key to context"); - } - return err; -} -#endif - -struct canl_mech * -find_mech(gss_OID oid) -{ - /* XXX */ - return &canl_mech_ssl; -} - -canl_err_code -canl_princ_name(canl_ctx cc, const canl_principal princ, char **name) -{ - struct _principal_int *p = (struct _principal_int *) princ; - - if (cc == NULL) - return -1; - if (princ == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "Principal not initialized"); - - if (name == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "invalid parameter value"); - - *name = strdup(p->name); - if (*name == NULL) - return set_error(cc, ENOMEM, POSIX_ERROR, "not enough memory"); - - return 0; -} - -void -canl_princ_free(canl_ctx cc, canl_principal princ) -{ - struct _principal_int *p = (struct _principal_int *) princ; - - if (cc == NULL) - return; - if (princ == NULL) - return; - - if (p->name) - free(p->name); - free(princ); - - return; -} diff --git a/emi.canl.canl-c/src/canl.h b/emi.canl.canl-c/src/canl.h deleted file mode 100644 index 465d75d..0000000 --- a/emi.canl.canl-c/src/canl.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef _CANL_H -#define _CANL_H -#include -#include -#include /* for the OID structs */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifndef CANL_CALLCONV -#define CANL_CALLCONV -#endif - -typedef void *canl_io_handler; -typedef void *canl_ctx; -typedef void *canl_principal; - -typedef unsigned long canl_err_code; - -typedef char (*canl_password_callback)(canl_ctx cc, void *userdata); - -canl_ctx CANL_CALLCONV -canl_create_ctx(); - -void CANL_CALLCONV -canl_free_ctx(canl_ctx cc); - -canl_err_code CANL_CALLCONV -canl_create_io_handler(canl_ctx cc, canl_io_handler *io); - -canl_err_code CANL_CALLCONV -canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, - const char *service, int port, gss_OID_set auth_mechs, - int flags, struct timeval *timeout); - -canl_err_code CANL_CALLCONV -canl_io_accept(canl_ctx cc, canl_io_handler io, int fd, struct sockaddr s_addr, - int flags, canl_principal *peer, struct timeval *timeout); - -size_t CANL_CALLCONV -canl_io_read(canl_ctx cc, canl_io_handler io, void *buffer, - size_t size, struct timeval *timeout); - -size_t CANL_CALLCONV -canl_io_write(canl_ctx cc, canl_io_handler io, void *buffer, - size_t size, struct timeval *timeout); - -canl_err_code CANL_CALLCONV -canl_get_error_code(canl_ctx cc); - -char * CANL_CALLCONV -canl_get_error_message(canl_ctx); - -canl_err_code CANL_CALLCONV -canl_io_close(canl_ctx cc, canl_io_handler io); - -canl_err_code CANL_CALLCONV -canl_io_destroy(canl_ctx cc, canl_io_handler io); - -canl_err_code CANL_CALLCONV -canl_princ_name(canl_ctx, const canl_principal, char **); - -canl_err_code CANL_CALLCONV -canl_princ_mech(canl_ctx, const canl_principal, gss_OID *); - -void CANL_CALLCONV -canl_princ_free(canl_ctx, canl_principal); - -char * CANL_CALLCONV -canl_mech2str(canl_ctx, gss_OID); - -const gss_OID_desc * CANL_CALLCONV -canl_str2mech(canl_ctx, const char mech); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/emi.canl.canl-c/src/canl_cert.c b/emi.canl.canl-c/src/canl_cert.c deleted file mode 100644 index 867f096..0000000 --- a/emi.canl.canl-c/src/canl_cert.c +++ /dev/null @@ -1,236 +0,0 @@ -#include "canl_locl.h" -#include "canl_mech_ssl.h" - -#if 0 -static int set_cert(glb_ctx *cc, X509 *cert); -//TODO just stub -int do_set_ctx_own_cert(glb_ctx *cc, canl_x509 cert, canl_stack_of_x509 chain, - canl_pkey key) -{ - int err = 0; - X509 *l_cert = (X509 *) cert; - STACK_OF(X509*) *l_chain = (STACK_OF(X509*)*) chain; - EVP_PKEY *l_key = (EVP_PKEY *)key; - -/* if (cert) - set_cert(l_cert); - cert - if (chain) - is_chain = 1; - if (key) - is_key = 1; - if (!m_ctx->cert_key){ - m_ctx->cert_key = (cert_key_store *) calloc(1, - sizeof(*(m_ctx->cert_key))); - if (!m_ctx->cert_key) { - err = ENOMEM; - goto end; - } - } - - if (!m_ctx->cert_key->cert) { - } -*/ - return 0; -} - -static int set_cert(glb_ctx *cc, X509 *cert) -{ - int err = 0; - CANL_ERROR_ORIGIN err_orig = 0; - - if (m_ctx->cert_key->cert) { - free(m_ctx->cert_key->cert); - m_ctx->cert_key->cert = NULL; - } - m_ctx->cert_key->cert = (X509 *) malloc (sizeof(X509)); - if (!m_ctx->cert_key->cert) { - err = ENOMEM; - goto end; - } - -end: - if (err) - set_error(cc, err, err_orig, "cannot get certificate"); - return err; -} -#endif - -//TODO cert -int do_set_ctx_own_cert_file(glb_ctx *cc, mech_glb_ctx *m_ctx, - char *cert, char *key, char *proxy) -{ - int err = 0; - - if (!m_ctx->cert_key){ - m_ctx->cert_key = (cert_key_store *) calloc(1, - sizeof(*(m_ctx->cert_key))); - if (!m_ctx->cert_key) { - return set_error(cc, ENOMEM, POSIX_ERROR, "not enought memory" - " for the certificate storage"); - } - } - - if (key) { - err = set_key_file(cc, &m_ctx->cert_key->key, key); - if (err) - return err; - } - - if (cert) { - err = set_cert_file(cc, &m_ctx->cert_key->cert, cert); - if (err) - return err; - } - - if (proxy) { - err = load_credentials(proxy, proxy, &m_ctx->cert_key->cert, - &m_ctx->cert_key->chain, &m_ctx->cert_key->key, NULL); - if (!err) - return err; - } - return 0; -} - -int set_key_file(glb_ctx *cc, EVP_PKEY **to, const char *key) -{ - unsigned long ssl_err = 0; - int err = 0; - FILE * key_file = NULL; - - if (*to) { - EVP_PKEY_free(*to); - *to = NULL; - } - key_file = fopen(key, "rb"); - if (!key_file) { - err = errno; - set_error(cc, err, POSIX_ERROR, "cannot open file with key"); - return err; - } - - ERR_clear_error(); - - /*TODO NULL NULL, callback and user data*/ - *to = PEM_read_PrivateKey(key_file, NULL, NULL, NULL); - if (!(*to)) { - ssl_err = ERR_peek_error(); - err = set_error(cc, ssl_err, SSL_ERROR, "error while writing key to context"); - goto end; - } - if (fclose(key_file)){ - err = errno; - set_error(cc, err, POSIX_ERROR, "cannot close file with key"); - return errno; - } - return 0; - -end: - if (fclose(key_file)){ - err = errno; - update_error(cc, errno, POSIX_ERROR, "cannot close file with key"); - } - return err; -} - -int set_cert_file(glb_ctx *cc, X509 **to, const char *cert) -{ - unsigned long ssl_err = 0; - int err = 0; - FILE * cert_file = NULL; - - - if (*to) { - X509_free(*to); - *to = NULL; - } - cert_file = fopen(cert, "rb"); - if (!cert_file) { - err = errno; - set_error(cc, err, POSIX_ERROR, "cannot open file with cert"); - return err; - } - - ERR_clear_error(); - /*TODO NULL NULL, callback and user data*/ - *to = PEM_read_X509(cert_file, NULL, NULL, NULL); - if (!(*to)) { - ssl_err = ERR_get_error(); - err = set_error(cc, ssl_err, SSL_ERROR, "error while writing certificate" - " to context"); - goto end; - } - - if (fclose(cert_file)){ - err = errno; - set_error(cc, err, POSIX_ERROR, "cannot close file with certificate"); - return errno; - } - return 0; - -end: - if (fclose(cert_file)){ - err = errno; - update_error(cc, errno, POSIX_ERROR, "cannot close file with certificate"); - } - return err; -} - -int set_cert_chain_file(glb_ctx *cc, STACK_OF(X509) **to, const char *file) -{ - unsigned long ssl_err = 0; - FILE * cert_file = NULL; - int count = 0; - int ret = -1; - X509 *x = NULL; - - if (file == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "Cert. chain file" - "does not exist"); - - if (*to) { - sk_X509_pop_free(*to, X509_free); - *to = NULL; - } - - cert_file = fopen(file, "rb"); - if (!cert_file) - return set_error(cc, errno, POSIX_ERROR, "Cannot " - "open file with cert. chain"); - - for (;;) - { - /* TODO maybe callback can be specified*/ - x = PEM_read_X509(cert_file,NULL, NULL, NULL); - if (x == NULL) - { - ssl_err = ERR_peek_error(); - if ((ERR_GET_REASON(ssl_err) == - PEM_R_NO_START_LINE)) { - /*everything OK*/ - if ((count > 0)) { - ERR_clear_error(); - break; - } - else { - ret = set_error(cc, ssl_err, SSL_ERROR, "Cannot get" - "certificate out of file"); - goto end; - } - } - } - - (void)sk_X509_insert(*to, x, sk_X509_num(*to)); - x = NULL; - count++; - } - return 0; - -end: - if (fclose(cert_file)){ - ret = errno; - return update_error(cc, errno, POSIX_ERROR, "cannot close file with" - " the certificate"); - } - return ret; -} diff --git a/emi.canl.canl-c/src/canl_cred.c b/emi.canl.canl-c/src/canl_cred.c deleted file mode 100644 index 931fc5a..0000000 --- a/emi.canl.canl-c/src/canl_cred.c +++ /dev/null @@ -1,636 +0,0 @@ -#include "canl_locl.h" -#include "canl_cred.h" -#include "canl_mech_ssl.h" - -#define DEF_KEY_LEN 1024 -#define DEF_KEY_LEN_LONGER 2048 -#define LIFETIME_TRESHOLD 10*24*60*60 //10 days - -static STACK_OF(X509)* my_sk_X509_dup(glb_ctx *cc, STACK_OF(X509) *stack); - -static STACK_OF(X509)* my_sk_X509_dup(glb_ctx *cc, STACK_OF(X509) *stack) -{ - int count = 0; - X509 *cert_from_chain = NULL; - STACK_OF(X509) *new_chain = NULL; - int i = 0; - - if (!stack) - return NULL; - - count = sk_X509_num(stack); - if (!count) - return NULL; - - new_chain = sk_X509_new_null(); - if (!new_chain) - return NULL; - - for (i = 0; i < count; i++){ - cert_from_chain = sk_X509_value(stack, i); - if (cert_from_chain) { - sk_X509_push(new_chain, X509_dup(cert_from_chain)); - } - } - - return new_chain; -} - -canl_err_code CANL_CALLCONV -canl_cred_new(canl_ctx ctx, canl_cred * cred) -{ - glb_ctx *cc = ctx; - creds *crd = NULL; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - - /*create new cred. handler*/ - crd = (creds *) calloc(1, sizeof(*crd)); - if (!crd) - return set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory"); - - *cred = crd; - return 0; -} - -canl_err_code CANL_CALLCONV -canl_cred_free(canl_ctx ctx, canl_cred cred) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - - /* Delete contents*/ - if (crd->c_key) { - EVP_PKEY_free(crd->c_key); - crd->c_key = NULL; - } - if (crd->c_cert) { - X509_free(crd->c_cert); - crd->c_cert = NULL; - } - if (crd->c_cert_ext) { - sk_X509_EXTENSION_pop_free(crd->c_cert_ext, X509_EXTENSION_free); - crd->c_cert_ext = NULL; - } - if (crd->c_cert_chain) { - sk_X509_pop_free(crd->c_cert_chain, X509_free); - crd->c_cert_chain = NULL; - } - if (crd->c_req) { - X509_REQ_free(crd->c_req); - crd->c_req = NULL; - } - - free (crd); - crd = NULL; - - return 0; -} - -canl_err_code CANL_CALLCONV -canl_ctx_set_cred(canl_ctx ctx, canl_cred cred) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - int ret = 0; - mech_glb_ctx *m_ctx = (mech_glb_ctx*) canl_mech_ssl.glb_ctx; - - if (!ctx) - return EINVAL; - if (!crd || !m_ctx->cert_key) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - - if (!m_ctx->cert_key){ - m_ctx->cert_key = (cert_key_store *) calloc(1, - sizeof(*(m_ctx->cert_key))); - if (!m_ctx->cert_key) { - return set_error(cc, ENOMEM, POSIX_ERROR, "not enought memory" - " for the certificate storage"); - } - } - - if (crd->c_key) { - if ((ret = pkey_dup(&m_ctx->cert_key->key, crd->c_key))) { - return ret; - } - } - - if (crd->c_cert) - m_ctx->cert_key->cert = X509_dup(crd->c_cert); - if (crd->c_cert_chain) - m_ctx->cert_key->chain = my_sk_X509_dup(cc, crd->c_cert_chain); - return 0; -} - -int pkey_dup(EVP_PKEY **to, EVP_PKEY *from) -{ - CRYPTO_add(&from->references,1,CRYPTO_LOCK_EVP_PKEY); - *to = from; - return 0; -} - -canl_err_code CANL_CALLCONV -canl_cred_load_priv_key_file(canl_ctx ctx, canl_cred cred, const char *pkey_file, - canl_password_callback pass_clb, void *arg) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - int ret = 0; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - if (!pkey_file) - return set_error(cc, EINVAL, POSIX_ERROR, "Invalid filename"); - - ret = set_key_file(cc, &crd->c_key, pkey_file); - - return ret; -} - -canl_err_code CANL_CALLCONV -canl_cred_load_chain(canl_ctx ctx, canl_cred cred, STACK_OF(X509) *cert_stack) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - int count = 0; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - - if (!cert_stack) - return set_error(cc, EINVAL, POSIX_ERROR, "Invalid stack value"); - - count = sk_X509_num(cert_stack); - if (!count) - return 0; //TODO is empty cert_stack error? - - if (crd->c_cert_chain) { - sk_X509_pop_free(crd->c_cert_chain, X509_free); - crd->c_cert_chain = NULL; - } - crd->c_cert_chain = my_sk_X509_dup(cc, cert_stack); - if (!crd->c_cert_chain) - return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" - " certificate chain" ); //TODO check ret val - return 0; -} - -canl_err_code CANL_CALLCONV -canl_cred_load_chain_file(canl_ctx ctx, canl_cred cred, const char *chain_file) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - - if (!chain_file) - return set_error(cc, EINVAL, POSIX_ERROR, "Invalid chain filename"); - - if (crd->c_cert_chain) { - sk_X509_pop_free(crd->c_cert_chain, X509_free); - crd->c_cert_chain = NULL; - } - else - crd->c_cert_chain = sk_X509_new_null(); - - return set_cert_chain_file(cc, &crd->c_cert_chain, chain_file); -} - - canl_err_code CANL_CALLCONV -canl_cred_load_cert(canl_ctx ctx, canl_cred cred, X509 *cert) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - - if (!cert) - return set_error(cc, EINVAL, POSIX_ERROR, "Invalid cert. file name"); - - if (crd->c_cert) { - X509_free(crd->c_cert); - crd->c_cert = NULL; - } - - crd->c_cert = X509_dup(cert); - if (!crd->c_cert) - return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" - " certificate" ); //TODO check ret val - return 0; -} - -canl_err_code CANL_CALLCONV -canl_cred_load_cert_file(canl_ctx ctx, canl_cred cred, const char *cert_file) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - int ret = 0; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - if (!cert_file) - return set_error(cc, EINVAL, POSIX_ERROR, "Invalid filename"); - - ret = set_cert_file(cc, &crd->c_cert, cert_file); - - return ret; -} - -canl_err_code CANL_CALLCONV -canl_cred_set_lifetime(canl_ctx ctx, canl_cred cred, const long lifetime) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - crd->c_lifetime = lifetime; - return 0; -} - -/*TODO rather use STACK_OF(X509_EXTENSION) ???*/ -canl_err_code CANL_CALLCONV -canl_cred_set_extension(canl_ctx ctx, canl_cred cred, X509_EXTENSION *cert_ext) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - - if (!crd->c_cert_ext) - crd->c_cert_ext = sk_X509_EXTENSION_new_null(); - sk_X509_EXTENSION_push(crd->c_cert_ext, X509_EXTENSION_dup(cert_ext)); - return 0; -} - -canl_err_code CANL_CALLCONV -canl_cred_set_cert_type(canl_ctx ctx, canl_cred cred, - const enum canl_cert_type cert_type) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - crd->c_type = cert_type; - return 0; -} - -/*TODO use flags*/ -canl_err_code CANL_CALLCONV -canl_cred_sign_proxy(canl_ctx ctx, canl_cred signer_cred, canl_cred proxy_cred) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *signer_crd = (creds*) signer_cred; - creds *proxy_crd = (creds*) proxy_cred; - int err = 0; - int key_size = 0; - - if (!ctx) - return EINVAL; - - if (!signer_crd) - return set_error(cc, EINVAL, POSIX_ERROR, "Signer cred. handler" - " not initialized" ); - if (!proxy_crd) - return set_error(cc, EINVAL, POSIX_ERROR, "Proxy cred. handler" - " not initialized" ); - - if (proxy_crd->c_req) { - EVP_PKEY *tmp_key = X509_REQ_get_pubkey(proxy_crd->c_req); - if (!tmp_key) - return set_error(cc, CANL_ERR_unknown, CANL_ERROR, "Cannot" - "extract key out of the certificate request" ); - key_size = EVP_PKEY_size(tmp_key); - /*TODO free tmp_key? is it duplicate or poiter? */ - if ((proxy_crd->c_lifetime > LIFETIME_TRESHOLD) && - (key_size <= DEF_KEY_LEN_LONGER)) - return set_error(cc, CANL_ERR_unknown, CANL_ERROR, "Cannot" - "sign cert. request -the key is too short with " - " respect to cert. lifetime"); - } - - /*TODO flags - limited,version*/ - err = proxy_sign(signer_crd->c_cert, signer_crd->c_key, proxy_crd->c_req, - &proxy_crd->c_cert, proxy_crd->c_lifetime, - proxy_crd->c_cert_ext, 0, 2, NULL, NULL, 0, NULL, 0); - if (err) - return set_error(cc, CANL_ERR_unknown, CANL_ERROR, ""); - - /*concatenate new chain*/ - if (signer_crd->c_cert_chain) - proxy_crd->c_cert_chain = my_sk_X509_dup(cc, signer_crd->c_cert_chain); - if (!proxy_crd->c_cert_chain) - proxy_crd->c_cert_chain = sk_X509_new_null(); - sk_X509_push(proxy_crd->c_cert_chain, X509_dup(signer_crd->c_cert)); - - return 0; - -} - -canl_err_code CANL_CALLCONV -canl_cred_save_proxyfile(canl_ctx ctx, canl_cred cred, const char *proxy_file) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - FILE *cert_file = NULL; - int ret = 0; - int o_ret = 0; - unsigned long ssl_err = 0; - int n_certs = 0; - int i = 0; - X509 *cert_from_chain = NULL; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - if (!proxy_file) - return set_error(cc, EINVAL, POSIX_ERROR, "Invalid proxy file name"); - - /*posix compliant*/ - o_ret = open(proxy_file, O_CREAT | O_EXCL |O_WRONLY, S_IRUSR | S_IWUSR); - if (o_ret == -1){ - ret = errno; - set_error(cc, ret, POSIX_ERROR, "Cannot open file for writing"); - } - else { - ret = close(o_ret); - if (ret == -1){ - ret = errno; - set_error(cc, ret, POSIX_ERROR, "Cannot close file for writing"); - return ret; - } - } - if (o_ret) - cert_file = fopen(proxy_file, "wb"); - else - cert_file = fopen(proxy_file, "ab"); - if (!cert_file) { - ret = errno; - set_error(cc, ret, POSIX_ERROR, "cannot open file for writing"); - return ret; - } - - ERR_clear_error(); - - /*new cert + priv key + chain*/ - ret = PEM_write_X509(cert_file, crd->c_cert); - if (!ret) { - ssl_err = ERR_get_error(); - ret = set_error(cc, ssl_err, SSL_ERROR, "Error while writing" - " the certificate to the file"); - goto end; - } - ret = PEM_write_PrivateKey(cert_file, crd->c_key, NULL, NULL, 0, 0, NULL); - if (!ret) { - ssl_err = ERR_get_error(); - ret = set_error(cc, ssl_err, SSL_ERROR, "Error while writing" - " the key to the file"); - goto end; - } - - n_certs = sk_X509_num(crd->c_cert_chain); - for (i = 0; i < n_certs; i++){ - cert_from_chain = sk_X509_value(crd->c_cert_chain, i); - if (cert_from_chain) { - ret = PEM_write_X509(cert_file, cert_from_chain); - if (!ret) { - ssl_err = ERR_get_error(); - if (ssl_err) - ret = set_error(cc, ssl_err, SSL_ERROR, "Error " - " while writing the certificate to the file"); - goto end; - } - } - } - - if (fclose(cert_file)){ - ret = errno; - set_error(cc, ret, POSIX_ERROR, "cannot close file with certificate"); - return errno; - } - - return 0; - -end: - if (fclose(cert_file)){ - ret = errno; - update_error(cc, ret, POSIX_ERROR, "cannot close file with certificate"); - return errno; - } - - return ret; - -} - -canl_err_code CANL_CALLCONV -canl_cred_save_cert(canl_ctx ctx, canl_cred cred, X509 ** cert) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - if (!cert) - return set_error(cc, EINVAL, POSIX_ERROR, "Invalid cert." - " handler"); - - if (*cert) { - X509_free(*cert); - *cert = NULL; - } - - *cert = X509_dup(crd->c_cert); - if (!(*cert)) - return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" - " certificate" ); //TODO check ret val - - return 0; -} - -canl_err_code CANL_CALLCONV -canl_cred_save_chain(canl_ctx ctx, canl_cred cred, STACK_OF(X509) **cert_stack) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd = (creds*) cred; - int count = 0; - - if (!ctx) - return EINVAL; - - if (!cred) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - - if (!cert_stack) - return set_error(cc, EINVAL, POSIX_ERROR, "Invalid stack value"); - - if (!crd->c_cert_chain) - return 0; //TODO is empty cert_stack error? - - count = sk_X509_num(crd->c_cert_chain); - if (!count) - return 0; //TODO is empty cert_stack error? - - if (*cert_stack) { - sk_X509_pop_free(*cert_stack, X509_free); - *cert_stack = NULL; - } - *cert_stack = my_sk_X509_dup(cc, crd->c_cert_chain); - if (!(*cert_stack)) - return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" - " certificate chain" ); //TODO check ret val - return 0; -} - -/* handle requests*/ -canl_err_code CANL_CALLCONV -canl_cred_new_req(canl_ctx ctx, canl_cred ret_req, unsigned int bits) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *crd_req = (creds*) ret_req; - int ret = 0; - int in_bits = DEF_KEY_LEN; - - if (!ctx) - return EINVAL; - - - if (bits) - in_bits = bits; - /*set longer key if lifetime is long enough*/ - else if (crd_req->c_lifetime > LIFETIME_TRESHOLD) - in_bits = DEF_KEY_LEN_LONGER; - - if (!ret_req) - return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" - " not initialized" ); - - if (crd_req->c_req) { - X509_REQ_free(crd_req->c_req); - crd_req->c_req = NULL; - } - - /*TODO 1st NULL may invoke callback to ask user for new name*/ - ret = proxy_genreq(NULL, &crd_req->c_req, &crd_req->c_key, in_bits, - NULL, NULL); - if (ret) - return set_error(cc, CANL_ERR_unknown, CANL_ERROR, "Cannot make new" - "proxy certificate"); - - return 0; -} - -canl_err_code CANL_CALLCONV -canl_cred_save_req(canl_ctx ctx, canl_cred req_in, X509_REQ ** req_ret) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *req = (creds*) req_in; - - if (!ctx) - return EINVAL; - if (!req || !req->c_req) - return set_error(cc, EINVAL, POSIX_ERROR, "Request handler" - " not initialized" ); - if (!req_ret) - return set_error(cc, EINVAL, POSIX_ERROR, "Request handler" - " not initialized" ); - - /*TODO free REQ if req_ret full*/ - *req_ret = X509_REQ_dup(req->c_req); - if (!(*req_ret)) - return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" - " X509 request handler" ); //TODO check ret val - return 0; -} - -canl_err_code CANL_CALLCONV -canl_cred_load_req(canl_ctx ctx, canl_cred cred_out, const X509_REQ *req_in) -{ - glb_ctx *cc = (glb_ctx*) ctx; - creds *req = (creds*) cred_out; - - if (!ctx) - return EINVAL; - if (!req) - return set_error(cc, EINVAL, POSIX_ERROR, "Request handler" - " not initialized" ); - if (!req_in) - return set_error(cc, EINVAL, POSIX_ERROR, "Request handler" - " not initialized" ); - if (req->c_req) { - X509_REQ_free(req->c_req); - req->c_req = NULL; - } - - req->c_req = X509_REQ_dup(req_in); - if (!req->c_req) - return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" - " X509 request handler" ); //TODO check ret val - return 0; -} - - -#if 0 -canl_err_code CANL_CALLCONV -canl_req_get_pair(canl_ctx, canl_x509_req, EVP_PKEY **) -{ - return ENOSYS; -} -#endif - diff --git a/emi.canl.canl-c/src/canl_cred.h b/emi.canl.canl-c/src/canl_cred.h deleted file mode 100644 index 432ad9f..0000000 --- a/emi.canl.canl-c/src/canl_cred.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef _CANL_CRED_H -#define _CANL_CRED_H - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *canl_cred; - -typedef enum canl_cert_type { - CANL_EEC, - CANL_RFC, -} canl_cert_type; - -typedef struct _creds { - EVP_PKEY *c_key; - STACK_OF(X509) *c_cert_chain; - X509 *c_cert; - long c_lifetime; - STACK_OF(X509_EXTENSION) * c_cert_ext; - canl_cert_type c_type; - X509_REQ *c_req; -} creds; - -/* Routines to handle credentials */ - -canl_err_code CANL_CALLCONV -canl_cred_new(canl_ctx, canl_cred *); - -canl_err_code CANL_CALLCONV -canl_cred_free(canl_ctx, canl_cred); - -canl_err_code CANL_CALLCONV -canl_ctx_set_cred(canl_ctx, canl_cred); - -canl_err_code CANL_CALLCONV -canl_cred_load_priv_key_file(canl_ctx, canl_cred, const char *, - canl_password_callback, void *); - -canl_err_code CANL_CALLCONV -canl_cred_load_priv_key_pkcs11(canl_ctx, canl_cred, const char *, - canl_password_callback, void *); - -canl_err_code CANL_CALLCONV -canl_cred_load_chain(canl_ctx, canl_cred, STACK_OF(X509) *); - -canl_err_code CANL_CALLCONV -canl_cred_load_chain_file(canl_ctx, canl_cred, const char *); - -canl_err_code CANL_CALLCONV -canl_cred_load_cert(canl_ctx, canl_cred, X509 *); - -canl_err_code CANL_CALLCONV -canl_cred_load_cert_file(canl_ctx, canl_cred, const char *); - -canl_err_code CANL_CALLCONV -canl_cred_load_cert_pkcs11(canl_ctx, canl_cred, const char *); - -canl_err_code CANL_CALLCONV -canl_cred_set_lifetime(canl_ctx, canl_cred, const long); - -canl_err_code CANL_CALLCONV -canl_cred_set_extension(canl_ctx, canl_cred, X509_EXTENSION *); - -canl_err_code CANL_CALLCONV -canl_cred_set_cert_type(canl_ctx, canl_cred, const enum canl_cert_type); - -canl_err_code CANL_CALLCONV -canl_cred_sign_proxy(canl_ctx, canl_cred, canl_cred); - -canl_err_code CANL_CALLCONV -canl_cred_save_proxyfile(canl_ctx, canl_cred, const char *); - -canl_err_code CANL_CALLCONV -canl_cred_save_cert(canl_ctx, canl_cred, X509 **); - -canl_err_code CANL_CALLCONV -canl_cred_save_chain(canl_ctx, canl_cred, STACK_OF(X509) **); - -/* Routines to handle X.509 requests */ - -canl_err_code CANL_CALLCONV -canl_cred_new_req(canl_ctx, canl_cred, unsigned int); - -canl_err_code CANL_CALLCONV -canl_cred_save_req(canl_ctx, canl_cred, X509_REQ **); - -canl_err_code CANL_CALLCONV -canl_cred_load_req(canl_ctx, canl_cred, const X509_REQ *); - -#if 0 -canl_err_code CANL_CALLCONV -canl_req_get_pair(canl_ctx, canl_x509_req, EVP_PKEY **); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/emi.canl.canl-c/src/canl_dns.c b/emi.canl.canl-c/src/canl_dns.c deleted file mode 100644 index 3310cbd..0000000 --- a/emi.canl.canl-c/src/canl_dns.c +++ /dev/null @@ -1,149 +0,0 @@ -#include "canl_locl.h" - -static int decrement_timeout(struct timeval *timeout, struct timeval before, struct timeval after); - -//#if ARES_VERSION >= 0x010500 -static void callback_ares_gethostbyname(void *arg, int status, int timeouts, struct hostent *h) -//#else -//static void callback_ares_gethostbyname(void *arg, int status, struct hostent *h) -//#endif -{ - asyn_result *arp = (asyn_result *) arg; - int n_addr = 0; - int i = 0; - - switch (status) { - case ARES_SUCCESS: - if (h == NULL || h->h_addr_list[0] == NULL){ - arp->err = NO_DATA; - break; - } - /*how many addresses are there in h->h_addr_list*/ - while (h->h_addr_list[n_addr]) - n_addr++; - - arp->ent->h_addr_list = (char **) calloc((n_addr+1), sizeof(char *)); - if (arp->ent->h_addr_list == NULL) { - arp->err = NETDB_INTERNAL; - break; - } - for (i = 0; i < n_addr; i++) { - arp->ent->h_addr_list[i] = malloc(h->h_length); - if (arp->ent->h_addr_list[i] == NULL) { - free_hostent (arp->ent); - arp->ent = NULL; - arp->err = NETDB_INTERNAL; - break; - } - memcpy(arp->ent->h_addr_list[i], h->h_addr_list[i], - h->h_length); - } - /* rest of h members might be assigned here(name,aliases), not necessery now */ - arp->ent->h_addr_list[n_addr] = NULL; - arp->ent->h_addrtype = h->h_addrtype; - arp->ent->h_length = h->h_length; - arp->err = NETDB_SUCCESS; - 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 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); -} - - -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); - } -} - -int asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, - struct timeval *timeout) -{ - int err; - 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); //TODO return value... - - /* query DNS server asynchronously */ - ares_gethostbyname(channel, name, a_family, callback_ares_gethostbyname, - (void *) ares_result); - - /* wait for result */ - while (1) { - FD_ZERO(&readers); - FD_ZERO(&writers); - nfds = ares_fds(channel, &readers, &writers); - if (nfds == 0) - break; - - gettimeofday(&check_time,0); - if (timeout && decrement_timeout(timeout, start_time, check_time)) { - ares_destroy(channel); - 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); - return NETDB_INTERNAL; - } else - continue; - case 0: - FD_ZERO(&readers); - FD_ZERO(&writers); - /* fallthrough */ - default: ares_process(channel, &readers, &writers); - } - } - err = ares_result->err; - - ares_destroy(channel); - - return err; -} diff --git a/emi.canl.canl-c/src/canl_err.c b/emi.canl.canl-c/src/canl_err.c deleted file mode 100644 index c316c85..0000000 --- a/emi.canl.canl-c/src/canl_err.c +++ /dev/null @@ -1,253 +0,0 @@ -#include "canl_locl.h" - -#define ERR_CODE_LEN 512 - -static canl_err_code resolve_error_code(glb_ctx *cc, unsigned long err_code, - canl_err_origin err_orig); -static void get_error_string(glb_ctx *cc, char *code_str); -static canl_err_code update_error_msg(canl_ctx cc, const char *new_msg); - -/* Save error message into err_msg - * use NULL for empty err_format */ -canl_err_code update_error (glb_ctx *cc, unsigned long err_code, - canl_err_origin err_orig, - const char *err_format, ...) -{ - int err_format_len = 0; - va_list ap; - char *new_msg = NULL; - int ret = 0; - - if (!cc) - return EINVAL; - - if (err_format == NULL || err_format[0] == '\0') { - goto wo_msg; - } - - va_start(ap, err_format); - - /*TODO if vasprintf not successful?*/ - err_format_len = vasprintf(&new_msg, err_format, ap); - if (!err_format_len) { - va_end(ap); - return EINVAL; - } - va_end(ap); - -wo_msg: - ret = resolve_error_code(cc, err_code, err_orig); - update_error_msg(cc, new_msg); - if (new_msg) - free(new_msg); - - return ret; -} - -/* If there was some error message in ctx, delete it and make new */ -canl_err_code set_error (glb_ctx *cc, unsigned long err_code, - canl_err_origin err_orig, const char *err_format, ...) -{ - va_list ap; - char *new_msg = NULL; - int ret; - int err_format_len = 0; - - if (!cc) - return 1; - /* if message already exists, delete it */ - if (cc->err_msg) - reset_error(cc, err_code); - - if (err_format == NULL || err_format[0] == '\0') { - goto wo_msg; - } - - /* make new message */ - va_start(ap, err_format); - err_format_len = vasprintf(&new_msg, err_format, ap); - if (!err_format_len) { - va_end(ap); - return EINVAL; - } - va_end(ap); - -wo_msg: - ret = resolve_error_code(cc, err_code, err_orig); - update_error_msg(cc, new_msg); - if (new_msg) - free(new_msg); - - if (!err_code) //TODO ??? - return 0; - return ret; -} - -/* Delete error message in ctx, suppose msg is not empty.Set pointer to NULL*/ -void reset_error (glb_ctx *cc, unsigned long err_code) -{ - /*check cc*/ - if (!cc ) - return; - if (cc->err_msg) - free(cc->err_msg); - cc->err_msg = NULL; - cc->err_code = 0; - cc->err_orig = UNKNOWN_ERROR; -} - -/* Provide human readable information about errors */ -static canl_err_code -update_error_msg(canl_ctx cc, const char *new_msg) -{ - int error_length = 0; - char *new_error = NULL; - char code_str[ERR_CODE_LEN]; - int code_len = 0; - char *separ = ": "; - int separ_len = 0; - int err_old_msg_len = 0; - int err_new_msg_len = 0; - glb_ctx *ctx = (glb_ctx*) cc; - - code_str[0] = '\0'; - - /*check cc*/ - if (!ctx) { - return EINVAL; - } - - if (ctx->err_msg) - err_old_msg_len = strlen(ctx->err_msg); - - if (new_msg) - err_new_msg_len = strlen(new_msg); - - /* get human readable error code */ - get_error_string(cc, code_str); - code_len = strlen(code_str); - - separ_len = strlen(separ); - error_length = err_new_msg_len + err_old_msg_len + code_len + - (2*separ_len) + 1; - new_error = (char *) malloc ((error_length) * sizeof (char)); - if (!new_error) { - return set_error(ctx, ENOMEM, POSIX_ERROR, "cannot get error message"); - } - - new_error[0] = '\0'; - if (new_msg) { - strncpy(new_error, new_msg, err_new_msg_len + 1); - strncat(new_error, separ, separ_len + 1); - } - strncat(new_error, code_str, code_len + 1); - strncat(new_error, separ, separ_len + 1); - if (ctx->err_msg) { - strncat(new_error, ctx->err_msg, err_old_msg_len + 1); - } - - if (ctx->err_msg) - free(ctx->err_msg); - ctx->err_msg = new_error; - return 0; -} - -static void get_error_string(glb_ctx *cc, char *code_str) -{ - char *new_str = NULL; - - switch (cc->err_orig) { - case SSL_ERROR: - ERR_error_string_n(cc->err_code, code_str, - ERR_CODE_LEN); - break; - case POSIX_ERROR: - new_str = strerror(cc->err_code); - if (new_str) { - strncpy(code_str, new_str, - ERR_CODE_LEN); - code_str[ERR_CODE_LEN - 1] = '\0'; - } - break; - case NETDB_ERROR: - new_str = (char *) hstrerror(cc->err_code); - if (new_str) { - strncpy(code_str, new_str, - ERR_CODE_LEN); - code_str[ERR_CODE_LEN - 1] = '\0'; - } - break; - default: - snprintf(code_str, ERR_CODE_LEN, - "Unknown error origin (%u) of error %lu!", - cc->err_orig, cc->err_code); - break; - } -} - -canl_err_code -canl_get_error_code(canl_ctx cc) -{ - glb_ctx *ctx = (glb_ctx*) cc; - - if (ctx == NULL) - return -1; - - return ctx->err_code; -} - -char * -canl_get_error_message(canl_ctx cc) -{ - glb_ctx *ctx = (glb_ctx*) cc; - - if (ctx == NULL) - return "Context is not initialized"; - - return ctx->err_msg; -} - -/*if the error code is known to canl, assign appropriate canl code - TODO go through ssl errors and assign appr. canl code - ?preserve original one? */ -static canl_err_code resolve_error_code(glb_ctx *cc, unsigned long err_code, - canl_err_origin err_orig) -{ - cc->original_err_code = err_code; - cc->err_orig = err_orig; - - switch (err_orig) { - case UNKNOWN_ERROR: - cc->err_code = (err_code) ? CANL_ERR_unknown : 0; - break; - case POSIX_ERROR: - /* We don't use that many posix-like codes, perhaps we want to - * map them to CANL codes. */ - cc->err_code = err_code; - break; - case SSL_ERROR: - /* XXX Add mapping based on canl_err_desc.c */ - /* TODO use err_code until mechanism mapping ssl_codes to - * canl_code is implemented - * cc->err_code = CANL_ERR_GeneralSSLError; */ - cc->err_code = err_code; - break; - case CANL_ERROR: - cc->err_code = err_code; - break; - case NETDB_ERROR: - switch (cc->err_code) { - case HOST_NOT_FOUND: - cc->err_code = CANL_ERR_HostNotFound; - break; - default: - cc->err_code = CANL_ERR_ResolverError; - break; - } - break; - default: - cc->err_code = CANL_ERR_unknown; - } - - return cc->err_code; -} diff --git a/emi.canl.canl-c/src/canl_error_codes b/emi.canl.canl-c/src/canl_error_codes deleted file mode 100644 index 7795b38..0000000 --- a/emi.canl.canl-c/src/canl_error_codes +++ /dev/null @@ -1,106 +0,0 @@ -# -# Additional codes MUST be added to the end only! -# -unknown -unknownMsg -inputError -nsUndefinedAndRequired -nsDeny -nsNotAccepted -proxyEECInChain -proxyLength -proxyNoIssuer -proxyCASet -proxyIssuerAltNameSet -proxySubjectAltNameSet -proxyIssuedByCa -proxyNoIssuerSubject -proxySubjectInconsistent -proxyIssuerNoDsig -proxySubjectOneRDN -proxySubjectMultiLastRDN -proxySubjectLastRDNNotCN -proxySubjectBaseWrong -noIssuerPublicKey -noBasicConstraints -pathLenghtExtended -conflictingTrustAnchors -noTrustAnchorFound -trustButInvalidCert -signatureNotVerified -certificateNotYetValid -certificateExpired -noCACert -noCertSign -unknownCriticalExt -certRevoked -noBaseCRL -noValidCrlFound -certPathCheckerError -certPathValidDate -certWrongIssuer -criticalExtensionError -crlAuthInfoAccError -crlBCExtError -crlDistPoint -crlDistPtExtError -crlExtractionError -crlIssuerException -crlNbrExtError -crlNoIssuerPublicKey -crlOnlyAttrCert -crlOnlyCaCert -crlOnlyUserCert -crlReasonExtError -crlUpdateAvailable -crlVerifyFailed -deltaCrlExtError -distrPtExtError -emptyCertPath -errorProcesingBC -excludedDN -excludedEmail -excludedIP -explicitPolicy -invalidPolicy -invalidPolicyMapping -loadCrlDistPointError -localInvalidCRL -localValidCRL -ncExtError -ncSubjectNameError -noCrlInCertstore -noCrlSigningPermited -notPermittedDN -notPermittedEmail -notPermittedIP -notRevoked -noValidPolicyTree -ocspLocation -onlineCRLWrongCA -onlineInvalidCRL -onlineValidCRL -policyConstExtError -policyExtError -policyInhibitExtError -policyMapExtError -policyQualifierError -processLengthConstError -pubKeyError -QcEuCompliance -QcLimitValueAlpha -QcLimitValueNum -QcSSCD -QcStatementExtError -QcUnknownStatement -revokedAfterValidation -rootKeyIsValidButNotATrustAnchor -subjAltNameExtError -totalPathLength -trustAnchorIssuerError -trustDNInvalid -trustPubKeyError -GeneralSSLError -HostNotFound -ResolverError -NoClientCertificate diff --git a/emi.canl.canl-c/src/canl_error_desc b/emi.canl.canl-c/src/canl_error_desc deleted file mode 100644 index c33e51e..0000000 --- a/emi.canl.canl-c/src/canl_error_desc +++ /dev/null @@ -1,194 +0,0 @@ -# -# Generic errors -# - -unknown=Unknown error -unknown.category=OTHER - -unknownMsg={0} -unknownMsg.category=OTHER - -inputError=Input certificate chain processing error: {0} -inputError.category=GENERAL_INPUT - -# -# Namespace related errors -# - -nsUndefinedAndRequired=Namespace definition for the certificate issuer ({0}) is not defined, and namespaces are configured to be required. -nsUndefinedAndRequired.category=NAMESPACE - -nsDeny=The certificate subject {0} is denied by the namespace policy: {1} -nsDeny.category=NAMESPACE - -nsNotAccepted=The certificate subject {0} is not accepted by any rule of the the relevant namespace policies. Policies which matches the issuer are: {1} -nsNotAccepted.category=NAMESPACE - - -# -# Proxy certificate specific errors -# - -proxyEECInChain=Certificate issued by an end-entity certificate or a proxy certificate is not a proxy proxy certificate. -proxyEECInChain.category=INCONSISTENT_PROXY_CHAIN - -proxyLength=At the current position the proxy certificates chain exceeded its length limit. -proxyLength.category=INCONSISTENT_PROXY_CHAIN - -proxyNoIssuer=Issuing end entity certificate was not found in the chain with proxy certificates. -proxyNoIssuer.category=INCONSISTENT_PROXY_CHAIN - -proxyCASet=Proxy certificate has the cA field set -proxyCASet.category=INVALID_PROXY_CERT - -proxyIssuerAltNameSet=Proxy certificate has the IssuerAlternativeName set -proxyIssuerAltNameSet.category=INVALID_PROXY_CERT - -proxySubjectAltNameSet=Proxy certificate has the SubjectAlternativeName set -proxySubjectAltNameSet.category=INVALID_PROXY_CERT - -proxyIssuedByCa=Proxy certificate issuer has the cA field set -proxyIssuedByCa.category=INCONSISTENT_PROXY_CHAIN - -proxyNoIssuerSubject=Proxy certificate issuer has no Subject field set -proxyNoIssuerSubject.category=INVALID_PROXY_CERT - -proxySubjectInconsistent=Proxy certificate issuer field is different than the issuing certificate subject field set. -proxySubjectInconsistent.category=INCONSISTENT_PROXY_CHAIN - -proxyIssuerNoDsig=Proxy certificate issuer has no digital signature creation right -proxyIssuerNoDsig.category=INCONSISTENT_PROXY_CHAIN - -proxySubjectOneRDN=The proxy certificate subject name has less then two elements -proxySubjectOneRDN.category=INVALID_PROXY_CERT - -proxySubjectMultiLastRDN=The last RDN in proxy subject name is multivalued -proxySubjectMultiLastRDN.category=INVALID_PROXY_CERT - -proxySubjectLastRDNNotCN=The last RDN in proxy subject name is not a CN -proxySubjectLastRDNNotCN.category=INVALID_PROXY_CERT - -proxySubjectBaseWrong=The proxy subject without its last CN component is not equal to its issuer name -proxySubjectBaseWrong.category=INVALID_PROXY_CERT - - -# -# Regular X.509 path validation errors -# - -noIssuerPublicKey=Trusted issuer of this certificate was not established -noIssuerPublicKey.category=X509_CHAIN - -noBasicConstraints=The selected CA certificate does not contain the mandatory Basic Constraints extension -noBasicConstraints.category=X509_BASIC - -pathLenghtExtended=Total chain length exceeds the limit -pathLenghtExtended.category=X509_CHAIN - -conflictingTrustAnchors=More then one trusted CA certificate was found for the certificate chain -conflictingTrustAnchors.category=X509_CHAIN - -noTrustAnchorFound=No trusted CA certificate was found for the certificate chain -noTrustAnchorFound.category=X509_CHAIN -noTrustAnchorFound.openssl_code=ERR_LIB_X509V3,X509V3_R_NO_ISSUER_CERTIFICATE - -trustButInvalidCert=CA certificate was found for the certificate chain but the initial certificate in chain is not issued (correctly signed) by the CA certificate -trustButInvalidCert.category=X509_CHAIN - -signatureNotVerified=Unable to verify signature of certificates in the chain: {0} -signatureNotVerified.category=X509_BASIC - -certificateNotYetValid=Certificate is not yet valid. Will be from: {0} -certificateNotYetValid.category=X509_BASIC - -certificateExpired=Certificate has expired at: {0} -certificateExpired.category=X509_BASIC - -noCACert=CA certificate was not found for the chain -noCACert.category=X509_CHAIN - -noCertSign=Issuer of the certificate is not eligible to sign certificates as its certificate has no keyCertSign flag set in its KeyUsage extension. -noCertSign.category=X509_CHAIN - -unknownCriticalExt=Unknown critical extension was found: {0} -unknownCriticalExt.category=X509_BASIC - -certRevoked=Certificate was revoked at: {0}, the reason reported is: {1} -certRevoked.category=CRL - -noBaseCRL=Base CRL for the delta CRL was not found -noBaseCRL.category=CRL - -noValidCrlFound=No valid CRL was found for the CA which issued the chain -noValidCrlFound.category=CRL - -# -# Rare errors lacking "translations" and meta-information -# -# -# certPathCheckerError -# certPathValidDate -# certWrongIssuer -# criticalExtensionError -# crlAuthInfoAccError -# crlBCExtError -# crlDistPoint -# crlDistPtExtError -# crlExtractionError -# crlIssuerException -# crlNbrExtError -# crlNoIssuerPublicKey -# crlOnlyAttrCert -# crlOnlyCaCert -# crlOnlyUserCert -# crlReasonExtError -# crlUpdateAvailable -# crlVerifyFailed -# deltaCrlExtError -# distrPtExtError -# emptyCertPath -# errorProcesingBC -# excludedDN -# excludedEmail -# excludedIP -# explicitPolicy -# invalidPolicy -# invalidPolicyMapping -# loadCrlDistPointError -# localInvalidCRL -# localValidCRL -# ncExtError -# ncSubjectNameError -# noCrlInCertstore -# noCrlSigningPermited -# notPermittedDN -# notPermittedEmail -# notPermittedIP -# notRevoked -# noValidPolicyTree -# ocspLocation -# onlineCRLWrongCA -# onlineInvalidCRL -# onlineValidCRL -# policyConstExtError -# policyExtError -# policyInhibitExtError -# policyMapExtError -# policyQualifierError -# processLengthConstError -# pubKeyError -# QcEuCompliance -# QcLimitValueAlpha -# QcLimitValueNum -# QcSSCD -# QcStatementExtError -# QcUnknownStatement -# revokedAfterValidation -# rootKeyIsValidButNotATrustAnchor -# signatureNotVerified -# subjAltNameExtError -# totalPathLength -# trustAnchorIssuerError -# trustDNInvalid -# trustPubKeyError -# unknown diff --git a/emi.canl.canl-c/src/canl_locl.h b/emi.canl.canl-c/src/canl_locl.h deleted file mode 100644 index fe135d6..0000000 --- a/emi.canl.canl-c/src/canl_locl.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef _CANL_LOCL_H -#define _CANL_LOCL_H - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sslutils.h" -#include "canl.h" - -typedef struct canl_err_desc { - canl_error code; - const char *desc; - unsigned long openssl_lib; - unsigned long openssl_reason; -} canl_err_desc; - -typedef enum canl_err_origin { - UNKNOWN_ERROR = 0, - POSIX_ERROR, - SSL_ERROR, - CANL_ERROR, - NETDB_ERROR, -} canl_err_origin; - -typedef enum _CANL_AUTH_MECHANISM -{ - AUTH_UNDEF = -1, - x509 = 0, - KRB5 = 1, /* and others may be added*/ - TLS, - GSSAPI, -} CANL_AUTH_MECHANISM; - -typedef struct _glb_ctx -{ - char * err_msg; - canl_err_code err_code; - /* XXX Do we need to keep these two:? */ - canl_err_origin err_orig; - long original_err_code; -} glb_ctx; - -typedef struct _asyn_result { - struct hostent *ent; - int err; -} asyn_result; - -typedef struct _principal_int { - char *name; -// CANL_AUTH_MECHANISM mech_oid; -// char *raw; /* e.g. the PEM encoded cert/chain */ -} principal_int; - -typedef struct _io_handler -{ - int sock; - principal_int *princ_int; - void *conn_ctx; //like SSL * - gss_OID oid; -} io_handler; - -typedef struct canl_mech { - CANL_AUTH_MECHANISM mech; - void *glb_ctx; - - canl_err_code (*initialize) - (glb_ctx *, void **); - - canl_err_code (*set_flags) - (glb_ctx *cc, unsigned int *mech_flags, unsigned int flags); - - canl_err_code (*finish) - (glb_ctx *, void *); - - canl_err_code (*client_init) - (glb_ctx *, void *, void **); - - canl_err_code (*server_init) - (glb_ctx *, void *, void **); - - canl_err_code (*free_ctx) - (glb_ctx *, void *); - - canl_err_code (*connect) - (glb_ctx *, io_handler *, void *, struct timeval *, const char *); - - canl_err_code (*accept) - (glb_ctx *, io_handler *, void *, struct timeval *); - - canl_err_code (*close) - (glb_ctx *, io_handler *, void *); - - canl_err_code (*read) - (glb_ctx *, io_handler *, void *, void *, size_t, struct timeval *); - - canl_err_code (*write) - (glb_ctx *, io_handler *, void *, void *, size_t, struct timeval *); - - canl_err_code (*get_peer) - (glb_ctx *, io_handler *, void *, canl_principal *); - -} canl_mech; - -/* Mechanism specific */ -extern canl_mech canl_mech_ssl; - -struct canl_mech * -find_mech(gss_OID oid); - - -void reset_error (glb_ctx *cc, unsigned long err_code); -canl_err_code set_error (glb_ctx *cc, unsigned long err_code, - canl_err_origin err_orig, const char *err_format, ...); -canl_err_code update_error (glb_ctx *cc, unsigned long err_code, - canl_err_origin err_orig, const char *err_format, ...); -void free_hostent(struct hostent *h); //TODO is there some standard funcion to free hostent? -int asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, - struct timeval *timeout); - -#endif diff --git a/emi.canl.canl-c/src/canl_mech_ssl.h b/emi.canl.canl-c/src/canl_mech_ssl.h deleted file mode 100644 index 6b16fa0..0000000 --- a/emi.canl.canl-c/src/canl_mech_ssl.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _CANL_MECH_SSL_H -#define _CANL_MECH_SSL_H - -#include -#include -#include -#include -#include -#include - -typedef struct _cert_key_store { - X509 *cert; - EVP_PKEY *key; - STACK_OF(X509) *chain; -} cert_key_store; - -typedef struct _mech_glb_ctx -{ - void *mech_ctx; //like SSL_CTX * - unsigned int flags; - char *ca_dir; - char *crl_dir; - cert_key_store *cert_key; -} mech_glb_ctx; - -int do_set_ctx_own_cert_file(glb_ctx *cc, mech_glb_ctx *m_ctx, - char *cert, char *key, char * proxy); -int set_key_file(glb_ctx *cc, EVP_PKEY **to, const char *key); -int set_cert_file(glb_ctx *cc, X509 **to, const char *cert); -int set_cert_chain_file(glb_ctx *cc, STACK_OF(X509) **to, const char *cert); -int pkey_dup(EVP_PKEY **to, EVP_PKEY *from); - -#endif diff --git a/emi.canl.canl-c/src/canl_ssl.c b/emi.canl.canl-c/src/canl_ssl.c deleted file mode 100644 index a4f3d42..0000000 --- a/emi.canl.canl-c/src/canl_ssl.c +++ /dev/null @@ -1,1435 +0,0 @@ -#include "canl_locl.h" -#include "canl_ssl.h" -#include "canl_mech_ssl.h" -#include - -#define SSL_SERVER_METH SSLv23_server_method() -#define SSL_CLIENT_METH SSLv3_client_method() -#define DESTROY_TIMEOUT 10 -#define USENONCE 0 - -typedef struct { - char *ca_dir; - char *crl_dir; -} canl_x509store_t; - -typedef struct { - char *url; - X509 *cert; - X509 *issuer; - canl_x509store_t *store; - X509 *sign_cert; - EVP_PKEY *sign_key; - long skew; - long maxage; -} canl_ocsprequest_t; - - - -typedef enum { - CANL_OCSPRESULT_ERROR_NOTCONFIGURED = -14, - CANL_OCSPRESULT_ERROR_NOAIAOCSPURI = -13, - CANL_OCSPRESULT_ERROR_INVALIDRESPONSE = -12, - CANL_OCSPRESULT_ERROR_CONNECTFAILURE = -11, - CANL_OCSPRESULT_ERROR_SIGNFAILURE = -10, - CANL_OCSPRESULT_ERROR_BADOCSPADDRESS = -9, - CANL_OCSPRESULT_ERROR_OUTOFMEMORY = -8, - CANL_OCSPRESULT_ERROR_UNKNOWN = -7, - CANL_OCSPRESULT_ERROR_UNAUTHORIZED = -6, - CANL_OCSPRESULT_ERROR_SIGREQUIRED = -5, - CANL_OCSPRESULT_ERROR_TRYLATER = -3, - CANL_OCSPRESULT_ERROR_INTERNALERROR = -2, - CANL_OCSPRESULT_ERROR_MALFORMEDREQUEST = -1, - CANL_OCSPRESULT_CERTIFICATE_VALID = 0, - CANL_OCSPRESULT_CERTIFICATE_REVOKED = 1 -} canl_ocspresult_t; - -static int do_ssl_connect( glb_ctx *cc, io_handler *io, - SSL *ssl, struct timeval *timeout); -static int do_ssl_accept( glb_ctx *cc, io_handler *io, - SSL *ssl, struct timeval *timeout); -static int check_hostname_cert(glb_ctx *cc, io_handler *io, - SSL *ssl, const char *host); -static BIO *my_connect_ssl(char *host, int port, SSL_CTX **ctx); -static BIO *my_connect(char *host, int port, int ssl, SSL_CTX **ctx); -static int set_ocsp_sign_cert(X509 *sign_cert); -static int set_ocsp_sign_key(EVP_PKEY *sign_key); -static int set_ocsp_cert(X509 *cert); -static int set_ocsp_skew(int skew); -static int set_ocsp_maxage(int maxage); -static int set_ocsp_url(char *url); -static int set_ocsp_issuer(X509 *issuer); -static canl_x509store_t * store_dup(canl_x509store_t *store_from); -static X509_STORE * canl_create_x509store(canl_x509store_t *store); - -#ifdef DEBUG -static void dbg_print_ssl_error(int errorcode); -#endif - -static canl_ocsprequest_t *ocspreq = NULL; -/*static int set_ocsp_url(char *url, X509 *cert, X509 *issuer, - canl_x509store_t *store, X509 *sign_cert, EVP_PKEY *sign_key, - long skew, long maxage) { - */ - - static int -set_ocsp_cert(X509 *cert) -{ - - if (!ocspreq) - ocspreq = calloc(1, sizeof(*ocspreq)); - if (!ocspreq) - return 1; - - if (cert) { - if (!ocspreq->cert) { - X509_free(ocspreq->cert); - ocspreq->cert = NULL; - } - ocspreq->cert = X509_dup(cert); - if (!ocspreq->cert) - return 1; - } - return 0; -} - - static int -set_ocsp_url(char *url) -{ - - int len = 0; - if (!ocspreq) - ocspreq = calloc(1, sizeof(*ocspreq)); - if (!ocspreq) - return 1; - - if (url) { - if (!ocspreq->url) { - free (ocspreq->url); - ocspreq->url = NULL; - } - len = strlen(url); - ocspreq->url = (char *) malloc((len +1) * sizeof (char)); - if (!ocspreq->url) - return 1; - strncpy(ocspreq->url, url, len + 1); - } - return 0; -} - - static int -set_ocsp_issuer(X509 *issuer) -{ - - if (!ocspreq) - ocspreq = calloc(1, sizeof(*ocspreq)); - if (!ocspreq) - return 1; - if (issuer) { - if (!ocspreq->issuer) { - X509_free (ocspreq->issuer); - ocspreq->issuer = NULL; - } - ocspreq->issuer = X509_dup(issuer); - if (!ocspreq->issuer) - return 1; - } - return 0; -} - - static int -set_ocsp_sign_cert(X509 *sign_cert) -{ - - if (!ocspreq) - ocspreq = calloc(1, sizeof(*ocspreq)); - if (!ocspreq) - return 1; - if (sign_cert) { - if (!ocspreq->sign_cert) { - X509_free (ocspreq->sign_cert); - ocspreq->sign_cert = NULL; - } - ocspreq->sign_cert = X509_dup(sign_cert); - if (!ocspreq->sign_cert) - return 1; - } - return 0; -} - - static int -set_ocsp_sign_key(EVP_PKEY *sign_key) -{ - - if (!ocspreq) - ocspreq = calloc(1, sizeof(*ocspreq)); - if (!ocspreq) - return 1; - if (sign_key) { - if (!ocspreq->sign_key) { - EVP_PKEY_free (ocspreq->sign_key); - ocspreq->sign_key = NULL; - } - pkey_dup(&ocspreq->sign_key, sign_key); - if (!ocspreq->sign_key) - return 1; - } - return 0; -} - static int -set_ocsp_skew(int skew) -{ - - if (!ocspreq) - ocspreq = calloc(1, sizeof(*ocspreq)); - if (!ocspreq) - return 1; - if (skew) - ocspreq->skew = skew; - return 0; -} - static int -set_ocsp_maxage(int maxage) -{ - - if (!ocspreq) - ocspreq = calloc(1, sizeof(*ocspreq)); - if (!ocspreq) - return 1; - if (maxage) - ocspreq->maxage = maxage; - return 0; -} - -static canl_x509store_t * -store_dup(canl_x509store_t *store_from) -{ - canl_x509store_t *store_to = NULL; - if (!store_from) - return NULL; - - store_to = calloc(1, sizeof(*store_to)); - if (!store_to) - return NULL; - - if (store_from->ca_dir) { - int len = strlen(store_from->ca_dir); - store_to->ca_dir = (char *) malloc((len + 1) * sizeof (char)); - if (store_to->ca_dir) - return NULL; - strncpy (store_to->ca_dir, store_from->ca_dir, len + 1); - } - if (store_from->crl_dir) { - int len = strlen(store_from->crl_dir); - store_to->crl_dir = (char *) malloc((len + 1) * sizeof (char)); - if (store_to->crl_dir) - return NULL; - strncpy (store_to->crl_dir, store_from->crl_dir, len + 1); - } - return store_to; -} - - static int -set_ocsp_store(canl_x509store_t *store) -{ - - if (!ocspreq) - ocspreq = calloc(1, sizeof(*ocspreq)); - if (!ocspreq) - return 1; - if (store){ - ocspreq->store = store_dup(store); - if (!ocspreq->store) - return 1; - } - return 0; -} - - - static canl_err_code -ssl_initialize(glb_ctx *cc, void **v_glb_ctx) -{ - mech_glb_ctx **m_glb_ctx = (mech_glb_ctx **)v_glb_ctx; - int err = 0; - char *ca_cert_fn, *user_cert_fn, *user_key_fn, *user_proxy_fn; - char *ca_cert_dirn = NULL; - ca_cert_fn = user_cert_fn = user_key_fn = user_proxy_fn = NULL; - SSL_CTX *ssl_ctx = NULL; - - if (!cc) - return EINVAL; - - SSL_library_init(); - SSL_load_error_strings(); - OpenSSL_add_all_algorithms(); - ERR_clear_error(); - - ssl_ctx = SSL_CTX_new(SSLv23_method()); - if (!ssl_ctx) - return set_error(cc, ERR_get_error(), SSL_ERROR, - "Cannot initialize SSL context"); - - if (!*m_glb_ctx) - *m_glb_ctx = (mech_glb_ctx *) calloc(1, sizeof(**m_glb_ctx)); - if (!*m_glb_ctx) - return set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory"); - - err = proxy_get_filenames(0, &ca_cert_fn, &ca_cert_dirn, NULL, NULL, NULL); - if (!err && (ca_cert_fn || ca_cert_dirn)) - SSL_CTX_load_verify_locations(ssl_ctx, ca_cert_fn, ca_cert_dirn); - - if (ca_cert_fn) - free(ca_cert_fn); - if (ca_cert_dirn) - free(ca_cert_dirn); - - //err = SSL_CTX_set_cipher_list(ssl_ctx, "ALL:!LOW:!EXP:!MD5:!MD2"); - err = SSL_CTX_set_cipher_list(ssl_ctx, "ALL"); - if (!err) { - err = set_error(cc, ERR_get_error(), SSL_ERROR, - "No cipher to use"); - goto end; - } - /* XXX: should be only defined on the SSL level: */ - SSL_CTX_set_cert_verify_callback(ssl_ctx, proxy_app_verify_callback, 0); - - //SSL_CTX_set_purpose(ssl_ctx, X509_PURPOSE_ANY); - //SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY); - // TODO proxy_verify_callback, verify_none only for testing !!!!!!! - //SSL_CTX_set_verify_depth(ctx, 100); - - (*m_glb_ctx)->mech_ctx = ssl_ctx; - ssl_ctx = NULL; - err = 0; - -end: - if (ssl_ctx) - SSL_CTX_free(ssl_ctx); - - return err; -} - -static canl_err_code -ssl_set_flags(glb_ctx *cc, unsigned int *mech_flags, unsigned int flags) -{ - if (cc == NULL) - return EINVAL; - - - *mech_flags = (flags | *mech_flags); - - return 0; -} - -static canl_err_code -ssl_set_dir(glb_ctx *cc, char **target, const char *ca_dir) -{ - int fn_len = 0; - if (cc == NULL) - return EINVAL; - - if (ca_dir == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "CA dir. name NULL"); - - if (target && *target){ - free (*target); - *target = NULL; - } - fn_len = strlen(ca_dir); - *target = (char *) malloc ((fn_len + 1) * sizeof (char)); - if (!(*target)) { - return set_error(cc, ENOMEM, POSIX_ERROR, NULL); - } - strncpy (*target, ca_dir, fn_len + 1); - - return 0; -} - -static canl_err_code -ssl_server_init(glb_ctx *cc, void *v_ctx, void **ctx) -{ - mech_glb_ctx *m_ctx = (mech_glb_ctx *)v_ctx; - SSL_CTX *ssl_ctx = (SSL_CTX *) m_ctx->mech_ctx; - SSL *ssl = NULL; - char *user_cert_fn, *user_key_fn, *user_proxy_fn; - int err = 0; - user_cert_fn = user_key_fn = user_proxy_fn = NULL; - - if (cc == NULL) - return EINVAL; - - if (ssl_ctx == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); - - err = proxy_get_filenames(0, NULL, NULL, &user_proxy_fn, - &user_cert_fn, &user_key_fn); - if (!err && (!m_ctx->cert_key || !m_ctx->cert_key->cert || !m_ctx->cert_key->key)) { - if (user_cert_fn && user_key_fn && !access(user_cert_fn, R_OK) && - !access(user_key_fn, R_OK)) { - err = do_set_ctx_own_cert_file(cc, m_ctx, user_cert_fn, user_key_fn, NULL); - if (err) - return err; - } - } - - free(user_cert_fn); - user_cert_fn = NULL; - free(user_key_fn); - user_key_fn = NULL; - //TODO where to use proxy on server side - free(user_proxy_fn); - user_proxy_fn = NULL; - - ssl = SSL_new(ssl_ctx); - if (ssl == NULL) - return set_error(cc, ERR_get_error(), SSL_ERROR, - "Failed to create SSL connection context"); - - /* TODO !!!!!!!!!! - * if SSL_VERIFY_NONE, then we cannot extract peer cert. of ssl - * if SSL_VERIFY_PEER, then client cert verification is mandatory!!!*/ - SSL_set_verify(ssl, SSL_VERIFY_PEER, proxy_verify_callback); - - if (!(CANL_ACCEPT_SSLv2 & m_ctx->flags)) - SSL_set_options(ssl, SSL_OP_NO_SSLv2); - - -// SSL_use_certificate_file(ssl, "/etc/grid-security/hostcert.pem", SSL_FILETYPE_PEM); -// SSL_use_PrivateKey_file(ssl, "/etc/grid-security/hostkey.pem", SSL_FILETYPE_PEM); - - SSL_set_accept_state(ssl); - - if (m_ctx->cert_key) { - if (m_ctx->cert_key->cert) { - err = SSL_use_certificate(ssl, m_ctx->cert_key->cert); - if (err != 1) { - return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" - "use certificate"); - } - else - err = 0; - } - if (m_ctx->cert_key->key) { - err = SSL_use_PrivateKey(ssl, m_ctx->cert_key->key); - if (err != 1) { - return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" - "use private key"); - } - else - err = 0; - } - } - else { - set_error(cc, err, UNKNOWN_ERROR, "server key or certificate missing"); - return 1; - } - /*Make sure the key and certificate file match*/ - if ( (err = SSL_check_private_key(ssl)) != 1) - return set_error(cc, ERR_get_error(), SSL_ERROR, "Private key" - " does not match the certificate public key"); - - *ctx = ssl; - - return 0; -} - -static canl_err_code -ssl_client_init(glb_ctx *cc, void *v_ctx, void **ctx) -{ - mech_glb_ctx *m_ctx = (mech_glb_ctx *)v_ctx; - SSL_CTX *ssl_ctx = (SSL_CTX *) m_ctx->mech_ctx; - SSL *ssl = NULL; - int err = 0, i = 0; - char *user_cert_fn, *user_key_fn, *user_proxy_fn; - user_cert_fn = user_key_fn = user_proxy_fn = NULL; - - if (cc == NULL) - return EINVAL; - - if (ssl_ctx == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); - - err = proxy_get_filenames(0, NULL, NULL, &user_proxy_fn, - &user_cert_fn, &user_key_fn); - if (!err && (!m_ctx->cert_key || !m_ctx->cert_key->cert || !m_ctx->cert_key->key)) { - if (user_proxy_fn && !access(user_proxy_fn, R_OK)) { - err = do_set_ctx_own_cert_file(cc, m_ctx, NULL, NULL, user_proxy_fn); - if (err) - return err; - } - else { - if (user_cert_fn && !access(user_cert_fn, R_OK)) { - err = do_set_ctx_own_cert_file(cc, m_ctx, - user_cert_fn, NULL, NULL); - if (err) - return err; - } - if (user_key_fn && !access(user_key_fn, R_OK)) { - err = do_set_ctx_own_cert_file(cc, m_ctx, - NULL, user_key_fn, NULL); - if (err) - return err; - } - } - } - - free(user_cert_fn); - user_cert_fn = NULL; - free(user_key_fn); - user_key_fn = NULL; - free(user_proxy_fn); - user_proxy_fn = NULL; - - if (m_ctx->cert_key && m_ctx->cert_key->chain) { - /* - * Certificate was a proxy with a cert. chain. - * Add the certificates one by one to the chain. - */ - X509_STORE_add_cert(ssl_ctx->cert_store, m_ctx->cert_key->cert); - for (i = 0; i < sk_X509_num(m_ctx->cert_key->chain); ++i) { - X509 *cert = (sk_X509_value(m_ctx->cert_key->chain, i)); - - if (!X509_STORE_add_cert(ssl_ctx->cert_store, cert)) { - if (ERR_GET_REASON(ERR_peek_error()) == - X509_R_CERT_ALREADY_IN_HASH_TABLE) { - ERR_clear_error(); - continue; - } - else { - set_error(cc, 1, CANL_ERROR, "Cannot add certificate " - "to the SSL context's certificate store"); - } - } - } -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - X509_STORE_set_verify_cb(ssl_ctx->cert_store, proxy_verify_callback); -#endif - } - - ssl = SSL_new(ssl_ctx); - if (ssl == NULL) - return set_error(cc, ERR_get_error(), SSL_ERROR, - "Failed to create SSL connection context"); - - SSL_set_connect_state(ssl); - - - - SSL_set_verify(ssl, SSL_VERIFY_PEER, proxy_verify_callback); - if (!(CANL_ACCEPT_SSLv2 & m_ctx->flags)) - SSL_set_options(ssl, SSL_OP_NO_SSLv2); - - if (m_ctx->cert_key) { - if (m_ctx->cert_key->key) { - err = SSL_use_PrivateKey(ssl, m_ctx->cert_key->key); - if (err != 1) { - return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" - "use private key"); - } - } - if (m_ctx->cert_key->cert) { - err = SSL_use_certificate(ssl, m_ctx->cert_key->cert); - if (err != 1) { - return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" - "use certificate"); - } - } - /*Make sure the key and certificate file match - * not mandatory on client side*/ - if (m_ctx->cert_key->cert && m_ctx->cert_key->key) - if ( (err = SSL_check_private_key(ssl)) != 1) - return set_error(cc, ERR_get_error(), SSL_ERROR, "Private key" - " does not match the certificate public key"); - } - - *ctx = ssl; - return 0; -} - -static canl_err_code -ssl_connect(glb_ctx *cc, io_handler *io, void *auth_ctx, - struct timeval *timeout, const char * host) -{ - SSL *ssl = (SSL *) auth_ctx; - int err = 0, flags; - - if (!cc) { - return EINVAL; - } - if (!io) { - err = EINVAL; - goto end; - } - if (ssl == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); - - flags = fcntl(io->sock, F_GETFL, 0); - (void)fcntl(io->sock, F_SETFL, flags | O_NONBLOCK); - - //setup_SSL_proxy_handler(cc->ssl_ctx, cacertdir); - SSL_set_fd(ssl, io->sock); - - err = do_ssl_connect(cc, io, ssl, timeout); - if (err) { - goto end; - } - /*check server hostname on the certificate*/ - err = check_hostname_cert(cc, io, ssl, host); - -end: - return err; -} - -static int check_hostname_cert(glb_ctx *cc, io_handler *io, - SSL *ssl, const char *host) -{ - X509 * serv_cert = NULL; - X509_EXTENSION *ext = NULL; - int i = 0; - GENERAL_NAMES *ialt = NULL; - char *pBuffer = NULL; - int correspond = 0; - X509_NAME *sn = NULL; - - /*if extensions are present, hostname has to correspond - * to subj. alt. name*/ - serv_cert = SSL_get_peer_certificate(ssl); - if (!serv_cert) - return set_error(cc, CANL_ERR_unknownMsg, CANL_ERROR, - "Server certificate missing"); - i = X509_get_ext_by_NID(serv_cert, NID_subject_alt_name, -1); - if (i != -1) { - /* subj. alt. name extention present */ - if(!(ext = X509_get_ext(serv_cert, i)) || - !(ialt = X509V3_EXT_d2i(ext)) ) - goto end; - for(i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { - const GENERAL_NAME *gen = sk_GENERAL_NAME_value(ialt, i); - switch (gen->type) { - case GEN_DNS: - ASN1_STRING_to_UTF8((unsigned char**)&pBuffer, gen->d.ia5); -#ifdef DEBUG - printf(" %s",pBuffer); -#endif - if (!strcmp(pBuffer, host)) { - correspond = 1; - OPENSSL_free(pBuffer); - pBuffer = NULL; - goto end; - } - OPENSSL_free(pBuffer); - pBuffer = NULL; - break; - } - } - } - /*else hostname has to correspond to common name*/ - else { - sn = X509_get_subject_name(serv_cert); - i = X509_NAME_get_index_by_NID(sn, NID_commonName, -1); - if (i != -1) { - while (1) { - X509_NAME_ENTRY *cn = X509_NAME_get_entry(sn, i); - ASN1_STRING_to_UTF8((unsigned char**)&pBuffer, - X509_NAME_ENTRY_get_data(cn)); - if (!strcmp(pBuffer, host)) { //TODO substr maybe - correspond = 1; - OPENSSL_free(pBuffer); - pBuffer = NULL; - goto end; - } - i = X509_NAME_get_index_by_NID(sn, NID_commonName, i); - OPENSSL_free(pBuffer); - pBuffer = NULL; - if (i == -1) - break; - } - } - else - return set_error(cc, CANL_ERR_unknownMsg, CANL_ERROR, - "Common name entry does not exist"); //TODO check - } - -end: - X509_free(serv_cert); - if (correspond) - return 0; - else { - return set_error(cc, CANL_ERR_unknownMsg, CANL_ERROR, - "Cannot validate server hostname against its certificate" ); - //TODO check - } -} - -static canl_err_code -ssl_accept(glb_ctx *cc, io_handler *io, void *auth_ctx, struct timeval *timeout) -{ - SSL *ssl = (SSL *) auth_ctx; - int err = 0, flags; - - if (!cc) { - return EINVAL; - } - if (!io) { - err = EINVAL; - goto end; - } - if (auth_ctx == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); - - flags = fcntl(io->sock, F_GETFL, 0); - (void)fcntl(io->sock, F_SETFL, flags | O_NONBLOCK); - - //setup_SSL_proxy_handler(cc->ssl_ctx, cacertdir); - SSL_set_fd(ssl, io->sock); - - err = do_ssl_accept(cc, io, ssl, timeout); - if (err) { - goto end; - } - -end: - return err; -} - -/* - * Encapsulates select behaviour - * - * Returns: - * > 0 : Ready to read or write. - * = 0 : timeout reached. - * < 0 : error. - */ -int do_select(int fd, time_t starttime, int timeout, int wanted) -{ - int ret = 0; - fd_set rset; - fd_set wset; - - FD_ZERO(&rset); - FD_ZERO(&wset); - - if (wanted == 0 || wanted == SSL_ERROR_WANT_READ) - FD_SET(fd, &rset); - if (wanted == 0 || wanted == SSL_ERROR_WANT_WRITE) - FD_SET(fd, &wset); - - if (timeout != -1) { - struct timeval endtime; - - time_t curtime = time(NULL); - - if (curtime - starttime >= timeout) - return 0; - - endtime.tv_sec = timeout - (curtime - starttime); - endtime.tv_usec = 0; - - ret = select(fd+1, &rset, &wset, NULL, &endtime); - } - else { - ret = select(fd+1, &rset, &wset, NULL, NULL); - } - - if (ret == 0) - return 0; - - if ((wanted == SSL_ERROR_WANT_READ && !FD_ISSET(fd, &rset)) || - (wanted == SSL_ERROR_WANT_WRITE && !FD_ISSET(fd, &wset))) - return -1; - - if (ret < 0 && (!FD_ISSET(fd, &rset) || !FD_ISSET(fd, &wset))) - return 1; - - return ret; -} - -#define TEST_SELECT(ret, ret2, timeout, curtime, starttime, errorcode) \ - ((ret) > 0 && ((ret2) <= 0 && (((timeout) == -1) || \ - (((timeout) != -1) && \ - ((curtime) - (starttime)) < (timeout))) && \ - ((errorcode) == SSL_ERROR_WANT_READ || \ - (errorcode) == SSL_ERROR_WANT_WRITE))) - -static int do_ssl_connect(glb_ctx *cc, io_handler *io, - SSL *ssl, struct timeval *timeout) -{ - time_t starttime, curtime; - int ret = -1, ret2 = -1; - unsigned long ssl_err = 0; - int err = 0; - canl_err_origin e_orig = UNKNOWN_ERROR; - long errorcode = 0; - int expected = 0; - int locl_timeout = -1; - - /* do not take tv_usec into account in this function*/ - if (timeout) - locl_timeout = timeout->tv_sec; - else - locl_timeout = -1; - curtime = starttime = time(NULL); - ERR_clear_error(); - - do { - ret = do_select(io->sock, starttime, locl_timeout, expected); - if (ret > 0) { - ret2 = SSL_connect(ssl); - if (ret2 < 0) { - ssl_err = ERR_get_error(); - e_orig = SSL_ERROR; - } - expected = errorcode = SSL_get_error(ssl, ret2); - } - curtime = time(NULL); - } while (TEST_SELECT(ret, ret2, locl_timeout, curtime, starttime, errorcode)); - - //TODO split ret2 and ret into 2 ifs to set approp. err. msg and check ag. - if (ret2 <= 0 || ret <= 0) { - if (timeout && (curtime - starttime >= locl_timeout)){ - timeout->tv_sec=0; - timeout->tv_usec=0; - err = ETIMEDOUT; - update_error (cc, err, POSIX_ERROR, "Connection stuck during" - " handshake: timeout reached"); - } - else if (ret2 < 0 && ssl_err) - return update_error(cc, ssl_err, e_orig, "Error during SSL handshake"); - else if (ret2 == 0)//TODO is 0 (conn closed by the other side) error? - update_error (cc, ECONNREFUSED, POSIX_ERROR, "Connection closed" - " by the other side"); - else - update_error (cc, err, UNKNOWN_ERROR, "Error during SSL handshake"); - return 1; - } - return 0; -} - -static int do_ssl_accept(glb_ctx *cc, io_handler *io, - SSL *ssl, struct timeval *timeout) -{ - time_t starttime, curtime; - int ret = -1, ret2 = -1; - unsigned long ssl_err = 0; - int err = 0; - long errorcode = 0; - int expected = 0; - int locl_timeout = -1; - - /* do not take tv_usec into account in this function*/ - if (timeout) - locl_timeout = timeout->tv_sec; - else - locl_timeout = -1; - curtime = starttime = time(NULL); - ERR_clear_error(); - - do { - ret = do_select(io->sock, starttime, locl_timeout, expected); - if (ret > 0) { - ret2 = SSL_accept(ssl); - if (ret2 < 0) { - ssl_err = ERR_peek_error(); - } - expected = errorcode = SSL_get_error(ssl, ret2); - } - curtime = time(NULL); -#ifdef DEBUG - dbg_print_ssl_error(errorcode); -#endif - } while (ret > 0 && (ret2 <= 0 && ((locl_timeout == -1) || - ((locl_timeout != -1) && - (curtime - starttime) < locl_timeout)) && - (errorcode == SSL_ERROR_WANT_READ || - errorcode == SSL_ERROR_WANT_WRITE))); -#ifdef DEBUG -if (errorcode == SSL_ERROR_WANT_READ) - printf("SSL_ERR_WANT_READ"); -if (errorcode == SSL_ERROR_WANT_WRITE) - printf("SSL_ERR_WANT_WRITE"); -printf ("STR: %s \n",ERR_error_string(ssl_err,NULL)); -printf ("LIB: %s ;",ERR_lib_error_string(ssl_err)); -printf ("FUNC: %s ;",ERR_func_error_string(ssl_err)); -printf ("LIB: %s \n",ERR_reason_error_string(ssl_err)); -#endif - - //TODO split ret2 and ret into 2 ifs to set approp. error message - if (ret2 <= 0 || ret <= 0) { - if (timeout && (curtime - starttime >= locl_timeout)){ - timeout->tv_sec=0; - timeout->tv_usec=0; - err = ETIMEDOUT; - set_error (cc, err, POSIX_ERROR, "Connection stuck" - " during handshake: timeout reached"); - } - else if (ret2 == 0) - set_error (cc, ECONNREFUSED, POSIX_ERROR, "Connection closed by" - " the other side"); - else if (ret2 < 0 && ssl_err) - set_error (cc, ssl_err, SSL_ERROR, "Error during SSL handshake"); - else - set_error (cc, 0, UNKNOWN_ERROR, "Error during SSL handshake"); - return 1; - } - return 0; -} - -/* this function has to return # bytes written or ret < 0 when sth went wrong*/ -static canl_err_code -ssl_write(glb_ctx *cc, io_handler *io, void *auth_ctx, - void *buffer, size_t size, struct timeval *timeout) -{ - int err = 0; - int ret = 0, nwritten=0; - const char *str; - int fd = -1; - time_t starttime, curtime; - int do_continue = 0; - int expected = 0; - int locl_timeout; - int touted = 0; - int to = 0; // bool - SSL *ssl = (SSL *) auth_ctx; - - if (cc == NULL) - return EINVAL; - - if (io == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, - "Connection not established"); - - if (ssl == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); - - fd = BIO_get_fd(SSL_get_rbio(ssl), NULL); - str = buffer;//TODO !!!!!! text.c_str(); - - curtime = starttime = time(NULL); - if (timeout) { - locl_timeout = timeout->tv_sec; - to = 1; - } - else { - to = 0; - locl_timeout = -1; - } - ERR_clear_error(); - - do { - ret = do_select(fd, starttime, locl_timeout, expected); - - do_continue = 0; - if (ret > 0) { - int v; - errno = 0; - ret = SSL_write(ssl, str + nwritten, - strlen(str) - nwritten); - v = SSL_get_error(ssl, ret); - - switch (v) { - case SSL_ERROR_NONE: - nwritten += ret; - if ((size_t)nwritten == strlen(str)) - do_continue = 0; - else - do_continue = 1; - break; - - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - expected = v; - ret = 1; - do_continue = 1; - break; - - default: - do_continue = 0; - } - } - curtime = time(NULL); - if (to) - locl_timeout = locl_timeout - (curtime - starttime); - if (to && locl_timeout <= 0){ - touted = 1; - goto end; - } - } while (ret <= 0 && do_continue); - -end: - if (err) { - errno = err; - set_error (cc, err, POSIX_ERROR, "Error during SSL write"); - return -1; - } - if (touted){ - err = ETIMEDOUT; - set_error(cc, err, POSIX_ERROR, "Connection stuck during" - " write: timeout reached"); - return -1; - } - if (ret <=0){ - err = -1;//TODO what to assign?????? - set_error (cc, err, UNKNOWN_ERROR, "Error during SSL write"); - } - return ret; -} - -static canl_err_code -ssl_read(glb_ctx *cc, io_handler *io, void *auth_ctx, - void *buffer, size_t size, struct timeval *tout) -{ - int err = 0; - int ret = 0, nwritten=0, ret2 = 0; - char *str; - int fd = -1; - time_t starttime, curtime; - int expected = 0, error = 0; - int timeout; - SSL *ssl = (SSL *) auth_ctx; - - if (cc == NULL) - return EINVAL; - - if (io == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, - "Connection not established"); - - if (ssl == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); - - fd = BIO_get_fd(SSL_get_rbio(ssl), NULL); - str = buffer;//TODO !!!!!! text.c_str(); - - curtime = starttime = time(NULL); - if (tout) { - timeout = tout->tv_sec; - } - else - timeout = -1; - ERR_clear_error(); - - do { - ret = do_select(fd, starttime, timeout, expected); - curtime = time(NULL); - - if (ret > 0) { - ret2 = SSL_read(ssl, str + nwritten, - strlen(str) - nwritten); - - if (ret2 <= 0) { - expected = error = SSL_get_error(ssl, ret2); - } - } - } while (TEST_SELECT(ret, ret2, timeout, curtime, starttime, error)); - - if (ret <= 0 || ret2 <= 0) { // what if ret2 == 0? conn closed? - err = -1; //TODO what to assign - if (timeout != -1 && (curtime - starttime >= timeout)){ - set_error(cc, ETIMEDOUT, POSIX_ERROR, "Connection stuck" - " during read: timeout reached"); - } - else - set_error(cc, err, UNKNOWN_ERROR, "Error during SSL read"); - } - else - err = ret2; - return err; -} - -/* ret > 1 if connection does not exist or has been closed before - * ret = 0 connection closed successfully (one direction) - * ret = 1 connection closed successfully (both directions) - * ret < 0 error occured (e.g. timeout reached) */ -static canl_err_code -ssl_close(glb_ctx *cc, io_handler *io, void *auth_ctx) -{ - int timeout = DESTROY_TIMEOUT; - time_t starttime, curtime; - int expected = 0, error = 0, ret = 0, ret2 = 0; - int fd; - unsigned long ssl_err = 0; - SSL *ssl = (SSL *) auth_ctx; - - if (!cc) - return EINVAL; - if (!io) - return set_error(cc, EINVAL, POSIX_ERROR, - "Connection not initialized"); - if (ssl == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); - - fd = BIO_get_fd(SSL_get_rbio(ssl), NULL); - curtime = starttime = time(NULL); - - /* check the shutdown state*/ - ret = SSL_get_shutdown(ssl); - if (ret & SSL_SENT_SHUTDOWN) { - if (ret & SSL_RECEIVED_SHUTDOWN) - return 1; - else - return 0; - } - /* TODO check the proper states, maybe also call SSL_shutdown - if (ret & SSL_RECEIVED_SHUTDOWN) { - return 0; - } */ - - do { - ret = do_select(fd, starttime, timeout, expected); - curtime = time(NULL); - - if (ret > 0) { - ret2 = SSL_shutdown(ssl); - if (ret2 < 0) { - ssl_err = ERR_peek_error(); - expected = error = SSL_get_error(ssl, ret2); - } - } - } while (TEST_SELECT(ret, ret2, timeout, curtime, starttime, error)); - - if (timeout != -1 && (curtime - starttime >= timeout)){ - set_error(cc, ETIMEDOUT, POSIX_ERROR, "Connection stuck" - " during ssl shutdown : timeout reached"); - return -1; - } - /* TODO set_error*/ - if (ret < 0) { - set_error(cc, 0, UNKNOWN_ERROR, "Error during SSL shutdown"); - return -1; - } - /* successful shutdown (uni/bi directional)*/ - if (ret2 == 0 || ret2 == 1) - return ret2; - else { - set_error(cc, ssl_err, SSL_ERROR, "Error during SSL shutdown"); - return -1; - } -} - -static canl_err_code -ssl_free(glb_ctx *cc, void *ctx) -{ - SSL_free(ctx); - return 0; -} - -static canl_err_code -ssl_finish(glb_ctx *cc, void *ctx) -{ - SSL_CTX_free(ctx); - return 0; -} - -/*maybe move to better file*/ -canl_err_code -canl_ctx_set_ssl_cred(canl_ctx cc, char *cert, char *key, char *proxy, - canl_password_callback cb, void *userdata) -{ - glb_ctx *glb_cc = (glb_ctx*) cc; - int err = 0; - - mech_glb_ctx *m_ctx = canl_mech_ssl.glb_ctx; - - if (!cc) - return EINVAL; - if(!cert ) { - set_error(glb_cc, EINVAL, POSIX_ERROR, "invalid parameter value"); - return EINVAL; - } - - err = do_set_ctx_own_cert_file(glb_cc, m_ctx, cert, key, proxy); - if(err) { -// update_error(glb_cc, "can't set cert or key to context"); - } - return err; -} - -canl_err_code -canl_ctx_set_crl_dir(canl_ctx cc, const char *dir) -{ - glb_ctx *glb_cc = (glb_ctx*) cc; - struct canl_mech *mech = find_mech(GSS_C_NO_OID); //TODO for now - mech_glb_ctx *m_ctx = (mech_glb_ctx *)mech->glb_ctx; - - if (!cc) - return EINVAL; - - return ssl_set_dir(glb_cc, &m_ctx->crl_dir, dir); -} - -canl_err_code -canl_ctx_set_ca_dir(canl_ctx cc, const char *dir) -{ - glb_ctx *glb_cc = (glb_ctx*) cc; - struct canl_mech *mech = find_mech(GSS_C_NO_OID); //TODO for now - mech_glb_ctx *m_ctx = (mech_glb_ctx *)mech->glb_ctx; - - if (!cc) - return EINVAL; - - return ssl_set_dir(glb_cc, &m_ctx->ca_dir, dir); -} - -static canl_err_code -ssl_get_peer(glb_ctx *cc, io_handler *io, void *auth_ctx, canl_principal *peer) -{ - struct _principal_int *princ; - SSL *ssl = (SSL *) auth_ctx; - X509 *cert = NULL; - X509_NAME *subject = NULL; - int ret; - - if (peer == NULL) - return set_error(cc, EINVAL, POSIX_ERROR, "invalid parameter value"); - - cert = SSL_get_peer_certificate(ssl); - if (cert == NULL) - return set_error(cc, CANL_ERR_NoClientCertificate, CANL_ERROR, "No peer certificate"); - - princ = calloc(1, sizeof(*princ)); - if (princ == NULL) - return set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory"); - - subject = X509_get_subject_name(cert); - princ->name = strdup(X509_NAME_oneline(subject, NULL, 0)); - if (princ->name == NULL) { - ret = set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory"); - goto end; - } - - *peer = princ; - princ = NULL; - ret = 0; - -end: - if (princ) - free(princ); - - return ret; -} - -#ifdef DEBUG -static void dbg_print_ssl_error(int errorcode) -{ - printf("[DBG CANL] "); - switch (errorcode) { - case SSL_ERROR_NONE: - printf ("SSL_ERROR_NONE\n"); - break; - case SSL_ERROR_ZERO_RETURN: - printf("SSL_ERROR_ZERO_RETURN\n"); - break; - case SSL_ERROR_WANT_READ: - printf ("SSL_ERROR_WANT_READ\n"); - break; - case SSL_ERROR_WANT_WRITE: - printf ("SSL_ERROR_WANT_WRITE\n"); - break; - case SSL_ERROR_WANT_CONNECT: - printf ("SSL_ERROR_WANT_CONNECT\n"); - break; - case SSL_ERROR_WANT_ACCEPT: - printf ("SSL_ERROR_WANT_ACCEPT\n"); - break; - case SSL_ERROR_WANT_X509_LOOKUP: - printf ("SSL_ERROR_WANT_X509_LOOKUP\n"); - break; - case SSL_ERROR_SYSCALL: - printf ("SSL_ERROR_SYSCALL\n"); - break; - case SSL_ERROR_SSL: - printf ("SSL_ERROR_SSL\n"); - break; - default: - printf ("no known error\n"); - break; - } -} -#endif - -static X509_STORE * -canl_create_x509store(canl_x509store_t *store) -{ - return NULL; -} - -int do_ocsp_verify (canl_ocsprequest_t *data) -{ - OCSP_REQUEST *req = NULL; - OCSP_RESPONSE *resp = NULL; - OCSP_BASICRESP *basic = NULL; - X509_STORE *store = 0; - int rc = 0, reason = 0, ssl = 0, status = 0; - char *host = NULL, *path = NULL, *port = NULL; - OCSP_CERTID *id = NULL; - char *chosenurl = NULL; - BIO *bio = NULL; - SSL_CTX *ctx = NULL; - canl_ocspresult_t result = 0; - ASN1_GENERALIZEDTIME *producedAt, *thisUpdate, *nextUpdate; - /*get url from cert or use some implicit value*/ - - /*get connection parameters out of url*/ - if (!OCSP_parse_url(chosenurl, &host, &port, &path, &ssl)) { - result = CANL_OCSPRESULT_ERROR_BADOCSPADDRESS; - goto end; - } - if (!(req = OCSP_REQUEST_new())) { - result = CANL_OCSPRESULT_ERROR_OUTOFMEMORY; - goto end; - } - - id = OCSP_cert_to_id(0, data->cert, data->issuer); - - /* Add id and nonce*/ - if (!id || !OCSP_request_add0_id(req, id)) - goto end; - if (USENONCE) - OCSP_request_add1_nonce(req, 0, -1); - - /* sign the request */ - if (data->sign_cert && data->sign_key && - !OCSP_request_sign(req, data->sign_cert, data->sign_key, - EVP_sha1(), 0, 0)) { - result = CANL_OCSPRESULT_ERROR_SIGNFAILURE; - goto end; - } - - ctx = SSL_CTX_new(SSLv3_client_method()); - if (ctx == NULL) { - result = CANL_OCSPRESULT_ERROR_OUTOFMEMORY; - goto end; - } - //SSL_CTX_set_cert_store(ctx, store); - SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); - - /* establish a connection to the OCSP responder */ - if (!(bio = my_connect(host, atoi(port), ssl, &ctx))) { - result = CANL_OCSPRESULT_ERROR_CONNECTFAILURE; - goto end; - } - - /* send the request and get a response */ - resp = OCSP_sendreq_bio(bio, path, req); - if ((rc = OCSP_response_status(resp)) != OCSP_RESPONSE_STATUS_SUCCESSFUL) { - switch (rc) { - case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST: - result = CANL_OCSPRESULT_ERROR_MALFORMEDREQUEST; break; - case OCSP_RESPONSE_STATUS_INTERNALERROR: - result = CANL_OCSPRESULT_ERROR_INTERNALERROR; break; - case OCSP_RESPONSE_STATUS_TRYLATER: - result = CANL_OCSPRESULT_ERROR_TRYLATER; break; - case OCSP_RESPONSE_STATUS_SIGREQUIRED: - result = CANL_OCSPRESULT_ERROR_SIGREQUIRED; break; - case OCSP_RESPONSE_STATUS_UNAUTHORIZED: - result = CANL_OCSPRESULT_ERROR_UNAUTHORIZED; break; - } - goto end; - } - - /* verify the response */ - result = CANL_OCSPRESULT_ERROR_INVALIDRESPONSE; - if (!(basic = OCSP_response_get1_basic(resp))) - goto end; - if (USENONCE && OCSP_check_nonce(req, basic) <= 0) - goto end; - /*TODO make the store*/ - if (data->store && !(store = canl_create_x509store(data->store))) - goto end; - /*TODO check the second parametr (responder_cert) and the last one*/ - if ((rc = OCSP_basic_verify(basic, 0, store, 0)) <= 0) - if ((rc = OCSP_basic_verify(basic, NULL, store, 0)) <= 0) - goto end; - - if (!OCSP_resp_find_status(basic, id, &status, &reason, &producedAt, - &thisUpdate, &nextUpdate)) - goto end; - if (!OCSP_check_validity(thisUpdate, nextUpdate, data->skew, data->maxage)) - goto end; - - /* All done. Set the return code based on the status from the response. */ - if (status == V_OCSP_CERTSTATUS_REVOKED) { - result = CANL_OCSPRESULT_CERTIFICATE_REVOKED; - /*TODO myproxy_log("OCSP status revoked!"); */ - } else { - result = CANL_OCSPRESULT_CERTIFICATE_VALID; - /*TODO myproxy_log("OCSP status valid"); */ - } -end: - /*TODO check what's this - if (result < 0 && result != CANL_OCSPRESULT_ERROR_NOTCONFIGURED) { - ssl_error_to_verror(); - TODO myproxy_log("OCSP check failed"); - myproxy_log_verror(); - } */ - - if (host) OPENSSL_free(host); - if (port) OPENSSL_free(port); - if (path) OPENSSL_free(path); - if (req) OCSP_REQUEST_free(req); - if (resp) OCSP_RESPONSE_free(resp); - if (basic) OCSP_BASICRESP_free(basic); - if (ctx) SSL_CTX_free(ctx); /* this does X509_STORE_free(store) */ - - return 0; -} - -static BIO * -my_connect_ssl(char *host, int port, SSL_CTX **ctx) { - BIO *conn = 0; - - if (!(conn = BIO_new_ssl_connect(*ctx))) goto error_exit; - BIO_set_conn_hostname(conn, host); - BIO_set_conn_int_port(conn, &port); - - if (BIO_do_connect(conn) <= 0) goto error_exit; - return conn; - -error_exit: - if (conn) BIO_free_all(conn); - return 0; -} - -static BIO * -my_connect(char *host, int port, int ssl, SSL_CTX **ctx) { - BIO *conn; - SSL *ssl_ptr; - - if (ssl) { - if (!(conn = my_connect_ssl(host, port, ctx))) goto error_exit; - BIO_get_ssl(conn, &ssl_ptr); - /*TODO figure out, how to check cert without canl_ctx - if (!check_hostname_cert(SSL_get_peer_certificate(ssl_ptr), host)) - goto error_exit;*/ - if (SSL_get_verify_result(ssl_ptr) != X509_V_OK) goto error_exit; - return conn; - } - - if (!(conn = BIO_new_connect(host))) goto error_exit; - BIO_set_conn_int_port(conn, &port); - if (BIO_do_connect(conn) <= 0) goto error_exit; - return conn; - -error_exit: - if (conn) BIO_free_all(conn); - return 0; -} - -mech_glb_ctx ssl_glb_ctx; - -canl_mech canl_mech_ssl = { - TLS, - &ssl_glb_ctx, - ssl_initialize, - ssl_set_flags, - ssl_finish, - ssl_client_init, - ssl_server_init, - ssl_free, - ssl_connect, - ssl_accept, - ssl_close, - ssl_read, - ssl_write, - ssl_get_peer, -}; diff --git a/emi.canl.canl-c/src/canl_ssl.h b/emi.canl.canl-c/src/canl_ssl.h deleted file mode 100644 index 09f01fd..0000000 --- a/emi.canl.canl-c/src/canl_ssl.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _CANL_SSL_H -#define _CANL_SSL_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum canl_ctx_ssl_flags { - CANL_ACCEPT_SSLv2 = 0x0001, -} canl_ctx_ssl_flags; - -canl_ctx CANL_CALLCONV -canl_ctx_set_ssl_flags(canl_ctx, unsigned int); - -canl_err_code CANL_CALLCONV -canl_ctx_set_ssl_cred(canl_ctx, char *, char *key, char *proxy, - canl_password_callback, void *); - -canl_err_code CANL_CALLCONV -canl_ctx_set_ca_dir(canl_ctx, const char *); - -canl_err_code CANL_CALLCONV -canl_ctx_set_crl_dir(canl_ctx, const char *); - -canl_err_code CANL_CALLCONV -canl_ctx_set_pkcs11_lib(canl_ctx, const char *); - -canl_err_code CANL_CALLCONV -canl_ctx_set_pkcs11_init_args(canl_ctx, const char *); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/emi.canl.canl-c/src/gen_err_codes.pl b/emi.canl.canl-c/src/gen_err_codes.pl deleted file mode 100755 index 65eade3..0000000 --- a/emi.canl.canl-c/src/gen_err_codes.pl +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/perl - -$err_name = ""; - -$num = 0; - -print STDOUT qq (/* - * Automatically generated file. Don't edit. - */ - -typedef enum canl_error {); - -while () { - chomp; - next if /^\s*#/; - printf ("\n CANL_ERR_%s%s,", - $_, - (!$num++) ? " = 1024" : ""); -} - -print STDOUT qq ( -} canl_error; -); diff --git a/emi.canl.canl-c/src/gen_err_desc.pl b/emi.canl.canl-c/src/gen_err_desc.pl deleted file mode 100755 index c17c3a2..0000000 --- a/emi.canl.canl-c/src/gen_err_desc.pl +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/perl - -my $codes_file = $ARGV[0]; -my $desc_file = $ARGV[1]; - -my %codes; -my $err_name, $err_dsc, $openssl_err_lib, $openssl_err_reason; - -sub make_c_line -{ - my ($err_name, $err_dsc, $openssl_err_lib, $openssl_err_reason) = @_; - - printf("\n { CANL_ERR_%s, \"%s\", %s, %s },", - $err_name, $err_dsc, - ($openssl_err_lib) ? $openssl_err_lib : "ERR_LIB_NONE", - ($openssl_err_reason) ? $openssl_err_reason : 0); -} - -die ("Usage: $0 ") if (!$codes_file || !$desc_file); - -open (ERRS, $codes_file) or die ("Failed to open $codes_file: $!"); -while () { - chomp; - next if /^\s*#/; - $codes{$_} = 1; -} -close (ERRS); - -print qq (/* - * Automatically generated file. Don't edit. - */ - -#include "canl_locl.h" -#include "canl_mech_ssl.h" - -struct canl_err_desc canl_err_descs[] = {); - -open (DESC, $desc_file) or die ("Failed to open $desc_file: $!"); -while () { - chomp; - next if /^\s*#/; - - $line = $_; - if (!$line) { - make_c_line($err_name, $err_dsc, $openssl_err_lib, $openssl_err_reason) - if ($err_name); - $err_name = $err_dsc = $openssl_err_lib = $openssl_err_reason = ""; - next; - } - - if (!$err_name) { - ($err_name, $err_dsc) = split(/=/, $line, 2); - defined($codes{$err_name}) or die("Unknown error code ('$err_name') read"); - next; - } - - if ($line =~ m/(.+)\.openssl_code=(.+),(.+)/) { - ($name, $openssl_err_lib, $openssl_err_reason) = ($1,$2,$3); - die ("Parsing error (\"$line\")") if ($name != $err_name); - next; - } -} -close (DESC); - -make_c_line ($err_name, $err_dsc, $openssl_err_lib, $openssl_err_reason) - if ($err_name); - -print STDOUT qq ( -}; -); diff --git a/emi.canl.canl-c/src/proxy/config.h b/emi.canl.canl-c/src/proxy/config.h deleted file mode 100644 index 5841d88..0000000 --- a/emi.canl.canl-c/src/proxy/config.h +++ /dev/null @@ -1,14 +0,0 @@ -#if defined(__GNUC__) -#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -#define UNUSED(z) z __attribute__ ((unused)) -#else -#define UNUSED(z) z -#endif -#define PRIVATE __attribute__ ((visibility ("hidden"))) -#define PUBLIC __attribute__ ((visibility ("default"))) -#else -#define UNUSED(z) z -#define PRIVATE -#define PUBLIC -#endif - diff --git a/emi.canl.canl-c/src/proxy/data.c b/emi.canl.canl-c/src/proxy/data.c deleted file mode 100644 index f0c0113..0000000 --- a/emi.canl.canl-c/src/proxy/data.c +++ /dev/null @@ -1,17 +0,0 @@ -/* XXX from common/data.cc */ - -#include - -int hex2num(char c) -{ - if (isdigit(c)) - return c - '0'; - else { - char d = tolower(c); - - if (d >= 'a' && d <= 'f') - return d - 'a' + 10; - - return 0; - } -} diff --git a/emi.canl.canl-c/src/proxy/doio.c b/emi.canl.canl-c/src/proxy/doio.c deleted file mode 100644 index 9019328..0000000 --- a/emi.canl.canl-c/src/proxy/doio.c +++ /dev/null @@ -1,73 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ - -#include "config.h" - -#include -#include -#include -#include "doio.h" - -char *vsnprintf_wrap(const char *format, va_list v) -{ - va_list w; - - va_copy(w,v);; - char *str = NULL; - int plen = 0; - - plen = vsnprintf(str, 0, format, v); - - if (plen > 0) { - str = (char *)malloc(plen+1); - if (str) { - (void)vsnprintf(str, plen+1, format, w); - va_end(w); - } - } - - return str; -} - -char *snprintf_wrap(const char *format, ...) -{ - va_list v; - char *str = NULL; - - va_start(v, format); - str = vsnprintf_wrap(format, v); - va_end(v); - - return str; -} - -int fileexists(const char *file) -{ - FILE *f = fopen(file, "r"); - fclose(f); - - return f != NULL; -} - diff --git a/emi.canl.canl-c/src/proxy/doio.h b/emi.canl.canl-c/src/proxy/doio.h deleted file mode 100644 index de1d965..0000000 --- a/emi.canl.canl-c/src/proxy/doio.h +++ /dev/null @@ -1,34 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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 VOMS_DOIO_H -#define VOMS_DOIO_H - -#include - -extern char *snprintf_wrap(const char *format, ...); -extern char *vsnprintf_wrap(const char *format, va_list v); -extern int fileexists(const char*); -#endif diff --git a/emi.canl.canl-c/src/proxy/evaluate.c b/emi.canl.canl-c/src/proxy/evaluate.c deleted file mode 100644 index 09b8ba4..0000000 --- a/emi.canl.canl-c/src/proxy/evaluate.c +++ /dev/null @@ -1,400 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ -#include "config.h" -#include -#include "parsertypes.h" -#include "doio.h" -#include "listfunc.h" -#include "normalize.h" - -#include -#include -#include - -static char *gethash(X509 *cert, char *hash); -static int find_policy(struct policy **policies, X509 *cert, int current); -static int evaluate_match_namespace(char *pattern, char *subject, int type); -static int evaluate_match_signing(char *pattern, char *subject, int type); -static int restriction_evaluate_policy(X509 *cert, struct policy *policy); -static int evaluate_cert(X509 *cert, struct policy **namespaces); -static int restriction_evaluate_namespace(STACK_OF(X509) *chain, struct policy **namespaces); -static int restriction_evaluate_signing(STACK_OF(X509) *chain, struct policy **signings); -static FILE *open_from_dir(char *path, char *file); - -extern int signinglex_init (void** scanner); -extern void signingset_in (FILE * in_str ,void *yyscanner ); -extern int signinglex_destroy (void* yyscanner ); -extern int signingparse(struct policy ***policies, void *scanner); - -extern int namespaceslex_init (void** scanner); -extern void namespacesset_in (FILE * in_str ,void *yyscanner ); -extern int namespaceslex_destroy (void* yyscanner ); -extern int namespacesparse(struct policy ***policies, void *scanner); - -static int find_policy(struct policy **policies, X509 *cert, int current) -{ - int i = (current == -1 ? 0 : current + 1); - - char hash[EVP_MAX_MD_SIZE+1]; - - if (!policies || !(policies[0]) || !cert) - return -1; - - while (policies[i]) { - if (policies[i]->self) { - if (!strcmp(gethash(cert, hash), policies[i]->caname)) - return i; - } - else { - char *issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); - int ret = strcmp(issuer, policies[i]->caname); - OPENSSL_free(issuer); - - if (!ret) - return i; - } - i++; - } - - /* If code reaches here, no match was found. */ - return -1; -} - -static char *gethash(X509 *cert, char *hash) -{ - unsigned long hashvalue = X509_subject_name_hash(cert); - sprintf(hash, "%08lx", hashvalue); - return hash; -} - -static int evaluate_match_namespace(char *pattern, char *subject, int type) -{ - regex_t compiled; - regmatch_t match[1]; - int success = SUCCESS_UNDECIDED; - char *patterntmp = normalize(pattern); - char *subjecttmp = normalize(subject); - - if (!regcomp(&compiled, patterntmp, REG_NOSUB)) { - if (!regexec(&compiled, subjecttmp, 0, match, 0)) { - /* matched */ - if (type) - success = SUCCESS_PERMIT; - else - success = SUCCESS_DENY; - } - } - - regfree(&compiled); - free(patterntmp); - free(subjecttmp); - - return success; -} - -static int evaluate_match_signing(char *pattern, char *subject, int type) -{ - int success = SUCCESS_UNDECIDED; - int len = 0; - int compare; - char *patterntmp = normalize(pattern); - char *subjecttmp = normalize(subject); - - if (!pattern || !subject) - return success; - - len = strlen(pattern); - - if (pattern[len-1] == '*') - compare = strncmp(patterntmp, subjecttmp, len-1); - else - compare = strcmp(patterntmp, subjecttmp); - - free(patterntmp); - free(subjecttmp); - - if (!compare) { - if (type) - return SUCCESS_PERMIT; - else - return SUCCESS_DENY; - } - - return success; -} - -static int restriction_evaluate_policy(X509 *cert, struct policy *policy) -{ - int success = SUCCESS_UNDECIDED; - char *subject = NULL; - - struct condition **cond = NULL; - int condindex = 0; - int subjindex = 0; - - if (!policy || !cert || !policy->conds) - return success; - - subject = X509_NAME_oneline(X509_get_subject_name(cert), 0 ,0); - if (!subject) - return success; - - cond = policy->conds; - - while (cond[condindex]) { - if (cond[condindex]->subjects) { - char **subjects = cond[condindex]->subjects; - int tempsuccess; - - while (subjects[subjindex]) { - if (policy->type == TYPE_NAMESPACE) - tempsuccess = evaluate_match_namespace(subjects[subjindex], - subject, - cond[condindex]->positive); - else - tempsuccess = evaluate_match_signing(subjects[subjindex], - subject, - cond[condindex]->positive); - - - if (tempsuccess != SUCCESS_UNDECIDED) - success = tempsuccess; - - if (success == SUCCESS_DENY) - goto end; - - subjindex++; - } - } - condindex++; - } - -end: - OPENSSL_free(subject); - return success; -} - -static int isselfsigned(X509*cert) -{ - return !X509_NAME_cmp(X509_get_subject_name(cert), - X509_get_issuer_name(cert)); - -} - -static int evaluate_cert(X509 *cert, struct policy **namespaces) -{ - int result = SUCCESS_UNDECIDED; - int policyindex = -1, - currentindex = -1; - - /* self-signed certificates always pass */ - if (isselfsigned(cert)) { - char *subject = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); - OPENSSL_free(subject); - return SUCCESS_PERMIT; - } - while ((policyindex = find_policy(namespaces, cert, currentindex)) != -1) { - struct policy *policy = namespaces[policyindex]; - - result = restriction_evaluate_policy(cert, policy); - - if (result != SUCCESS_UNDECIDED) - break; - currentindex = policyindex; - } - - return result; -} - -static int restriction_evaluate_namespace(STACK_OF(X509) *chain, struct policy **namespaces) -{ - int size = sk_X509_num(chain); - int i = 0; - int result = 0; - int start = 0, end = 0; - int step = 0; - - if (size > 1 && isselfsigned(sk_X509_value(chain,0))) { - /* reverse certificate ordering. Reverse direction of visit */ - - start = size - 1; - end = -1; - step = -1; - } - else { - /* right order */ - start = 0; - end = size; - step = 1; - } - - for (i = start; i != end; i += step) { - int j; - X509 *cert = sk_X509_value(chain, i); - - for (j = i; j >= 0; j--) { - result = evaluate_cert(cert, namespaces); - - if (result != SUCCESS_UNDECIDED) - break; - } - } - - if (result == SUCCESS_UNDECIDED) { - result = SUCCESS_PERMIT; - } - - return result; -} - -static int restriction_evaluate_signing(STACK_OF(X509) *chain, struct policy **signings) -{ - int size = sk_X509_num(chain); - int i = 0; - int result = 0; - - for (i = 0; i < size; i++) { - X509 *cert = sk_X509_value(chain, i); - - result = evaluate_cert(cert, signings); - - if (result != SUCCESS_UNDECIDED) - break; - } - - if (result == SUCCESS_UNDECIDED) - result = SUCCESS_DENY; - - return result; -} - -int PRIVATE restriction_evaluate(STACK_OF(X509) *chain, struct policy **namespaces, - struct policy **signings) -{ - int result = 0; - - result = restriction_evaluate_namespace(chain, namespaces); - - if (result == SUCCESS_UNDECIDED) { - result = restriction_evaluate_signing(chain, signings); - } - return result; -} - -static void free_condition(struct condition *cond) -{ - free(cond->original); - free(cond->subjects); - free(cond); -} - -static void free_policy(struct policy *pol) -{ - free(pol->caname); - - listfree((char**)(pol->conds), (freefn)free_condition); - free(pol); -} - -void PRIVATE voms_free_policies(struct policy **policies) -{ - listfree((char**)policies, (freefn)free_policy); -} - -static FILE *open_from_dir(char *path, char *filename) -{ - char *realpath=snprintf_wrap("%s%s", path, filename); - FILE *file = NULL; - - file = fopen(realpath, "rb"); - - free(realpath); - - return file; -} - - -void PRIVATE read_pathrestriction(STACK_OF(X509) *chain, char *path, - struct policy ***names, - struct policy ***signs) -{ - int size = sk_X509_num(chain); - char hashed[9]; - char *hash; - char signing[25] = "/XXXXXXXX.signing_policy"; - char namespace[21] = "/XXXXXXXX.namespaces"; - int i = 0, j = 0; - FILE *file = NULL; - - for (i = 0; i < size; i++) { - X509 *cert = sk_X509_value(chain, i); - hash = gethash(cert, hashed); - - /* Determine file names */ - strncpy(signing + 1, hash, 8); - strncpy(namespace + 1, hash, 8); - - file = open_from_dir(path, signing); - if (file) { - void *scanner = NULL; - - signinglex_init(&scanner); - signingset_in(file, scanner); - (void)signingparse(signs, scanner); - signinglex_destroy(scanner); - fclose(file); - } - - j = 0; - if (*signs) { - while ((*signs)[j]) { - if ((*signs)[j]->self) - (*signs)[j]->caname = strdup(hash); - j++; - } - } - - file = open_from_dir(path, namespace); - if (file) { - void *scanner = NULL; - - namespaceslex_init(&scanner); - namespacesset_in(file, scanner); - (void)namespacesparse(names, scanner); - namespaceslex_destroy(scanner); - fclose(file); - } - - if (*names) { - int j = 0; - - while ((*names)[j]) { - if ((*names)[j]->self) - (*names)[j]->caname = strdup(hash); - j++; - } - } - } -} diff --git a/emi.canl.canl-c/src/proxy/list.c b/emi.canl.canl-c/src/proxy/list.c deleted file mode 100644 index 27b8246..0000000 --- a/emi.canl.canl-c/src/proxy/list.c +++ /dev/null @@ -1,69 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ -#include "config.h" - -#include -#include - -char **listadd(char **vect, char *data) -{ - int i = 0; - char **newvect; - - if (!data) - return vect; - - if (vect) - while (vect[i++]) ; - else - i=1; - - if ((newvect = (char **)malloc((i+1)*sizeof(char *)))) { - if (vect) { - memcpy(newvect, vect, (sizeof(char*)*(i-1))); - newvect[i-1] = data; - newvect[i] = NULL; - free(vect); - } - else { - newvect[0] = data; - newvect[1] = NULL; - } - return newvect; - } - return NULL; -} - -void listfree(char **vect, void (*f)(void *)) -{ - char **tmp = vect; - - if (tmp) { - int i = 0; - while (tmp[i]) - f(tmp[i++]); - free(vect); - } -} diff --git a/emi.canl.canl-c/src/proxy/listfunc.h b/emi.canl.canl-c/src/proxy/listfunc.h deleted file mode 100644 index bfc894f..0000000 --- a/emi.canl.canl-c/src/proxy/listfunc.h +++ /dev/null @@ -1,33 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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 VOMS_LISTFUNC_H -#define VOMS_LISTFUNC_H -#include - -typedef void (*freefn)(void *); - -extern char **listadd(char **vect, char *data); -extern void listfree(char **vect, freefn f); -#endif diff --git a/emi.canl.canl-c/src/proxy/myproxycertinfo.h b/emi.canl.canl-c/src/proxy/myproxycertinfo.h deleted file mode 100644 index 2840971..0000000 --- a/emi.canl.canl-c/src/proxy/myproxycertinfo.h +++ /dev/null @@ -1,131 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * Valerio Venturi - valerio.venturi@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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 VOMS_PROXYCERTINFO_H -#define VOMS_PROXYCERTINFO_H - -#include -#include -#include - -/* predefined policy language */ -#define IMPERSONATION_PROXY_OID "1.3.6.1.5.5.7.21.1" -#define IMPERSONATION_PROXY_SN "IMPERSONATION_PROXY" -#define IMPERSONATION_PROXY_LN "GSI impersonation proxy" - -#define INDEPENDENT_PROXY_OID "1.3.6.1.5.5.7.21.2" -#define INDEPENDENT_PROXY_SN "INDEPENDENT_PROXY" -#define INDEPENDENT_PROXY_LN "GSI independent proxy" - -/* generic policy language */ -#define GLOBUS_GSI_PROXY_GENERIC_POLICY_OID "1.3.6.1.4.1.3536.1.1.1.8" - -#define LIMITED_PROXY_OID "1.3.6.1.4.1.3536.1.1.1.9" -#define LIMITED_PROXY_SN "LIMITED_PROXY" -#define LIMITED_PROXY_LN "GSI limited proxy" - -#define PROXYCERTINFO_V3 "1.3.6.1.4.1.3536.1.222" -#define PROXYCERTINFO_V4 "1.3.6.1.5.5.7.1.14" - -/* error handling */ -#define ASN1_F_PROXYPOLICY_NEW 450 -#define ASN1_F_D2I_PROXYPOLICY 451 -#define ASN1_F_PROXYCERTINFO_NEW 430 -#define ASN1_F_D2I_PROXYCERTINFO 431 - -/* data structure */ - -typedef struct myPROXYPOLICY_st { - - ASN1_OBJECT * policy_language; - ASN1_OCTET_STRING * policy; - -} myPROXYPOLICY; - -typedef struct myPROXYCERTINFO_st { - - ASN1_INTEGER * path_length; - myPROXYPOLICY * proxypolicy; - int version; -} myPROXYCERTINFO; - - -/* myPROXYPOLICY function */ - -/* allocating and free memory */ -extern myPROXYPOLICY * myPROXYPOLICY_new(); -extern void myPROXYPOLICY_free(myPROXYPOLICY * proxypolicy); - -/* duplicate */ -extern myPROXYPOLICY * myPROXYPOLICY_dup(myPROXYPOLICY * policy); - -/* set policy language */ -extern int myPROXYPOLICY_set_policy_language(myPROXYPOLICY * policy, ASN1_OBJECT * policy_language); - -/* get policy language */ -extern ASN1_OBJECT * myPROXYPOLICY_get_policy_language(myPROXYPOLICY * policy); - -/* set policy contents */ -extern int myPROXYPOLICY_set_policy(myPROXYPOLICY * proxypolicy, unsigned char * policy, int length); - -/* get policy contents */ -extern unsigned char * myPROXYPOLICY_get_policy(myPROXYPOLICY * policy, int * length); - -/* internal to der conversion */ -extern int i2d_myPROXYPOLICY(myPROXYPOLICY * policy, unsigned char ** pp); - -/* der to internal conversion */ -extern myPROXYPOLICY * d2i_myPROXYPOLICY(myPROXYPOLICY ** policy, unsigned char ** pp, long length); - -/*myPROXYCERTINFO function */ - -/* allocating and free memory */ -extern myPROXYCERTINFO * myPROXYCERTINFO_new(); -extern void myPROXYCERTINFO_free(myPROXYCERTINFO * proxycertinfo); - -/* set path_length */ -extern int myPROXYCERTINFO_set_path_length(myPROXYCERTINFO * proxycertinfo, long path_length); - -/* get ptah length */ -extern long myPROXYCERTINFO_get_path_length(myPROXYCERTINFO * proxycertinfo); - -/* set proxypolicy */ -extern int myPROXYCERTINFO_set_proxypolicy(myPROXYCERTINFO * proxycertinfo, myPROXYPOLICY * proxypolicy); - -/* get proxypolicy */ -extern myPROXYPOLICY * myPROXYCERTINFO_get_proxypolicy(myPROXYCERTINFO * proxycertinfo); - -/* internal to der conversion */ -extern int i2d_myPROXYCERTINFO(myPROXYCERTINFO * proxycertinfo, unsigned char ** pp); - -/* der to internal conversion */ -extern myPROXYCERTINFO * d2i_myPROXYCERTINFO(myPROXYCERTINFO ** cert_info, unsigned char ** a, long length); - -extern int myPROXYCERTINFO_set_version(myPROXYCERTINFO *cert_info, int version); - -extern int proxynative(void); -extern void InitProxyCertInfoExtension(int full); - -#endif diff --git a/emi.canl.canl-c/src/proxy/namespaces_lex.c.in b/emi.canl.canl-c/src/proxy/namespaces_lex.c.in deleted file mode 100644 index f43764c..0000000 --- a/emi.canl.canl-c/src/proxy/namespaces_lex.c.in +++ /dev/null @@ -1,2090 +0,0 @@ - -#line 3 "" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yyg->yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yyg->yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE namespacesrestart(yyin ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = yyg->yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via namespacesrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ - ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void namespacesrestart (FILE *input_file ,yyscan_t yyscanner ); -void namespaces_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE namespaces_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void namespaces_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void namespaces_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void namespacespush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void namespacespop_buffer_state (yyscan_t yyscanner ); - -static void namespacesensure_buffer_stack (yyscan_t yyscanner ); -static void namespaces_load_buffer_state (yyscan_t yyscanner ); -static void namespaces_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER namespaces_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE namespaces_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE namespaces_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE namespaces_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); - -void *namespacesalloc (yy_size_t ,yyscan_t yyscanner ); -void *namespacesrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void namespacesfree (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer namespaces_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - namespacesensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - namespaces_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - namespacesensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - namespaces_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define namespaceswrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef int yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 15 -#define YY_END_OF_BUFFER 16 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[53] = - { 0, - 0, 0, 0, 0, 0, 0, 16, 14, 13, 4, - 1, 2, 14, 14, 14, 14, 14, 14, 15, 3, - 15, 5, 1, 0, 0, 0, 0, 0, 6, 12, - 0, 3, 0, 5, 0, 0, 0, 0, 0, 9, - 0, 0, 10, 0, 0, 0, 0, 7, 8, 0, - 11, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 4, 1, 1, 1, 5, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 6, 7, 8, 9, 10, - 1, 1, 11, 12, 1, 13, 14, 15, 16, 17, - 1, 18, 19, 20, 21, 1, 1, 1, 22, 1, - 1, 23, 1, 1, 1, 1, 1, 24, 25, 26, - - 27, 28, 1, 1, 29, 30, 1, 31, 32, 33, - 34, 35, 1, 36, 37, 38, 39, 1, 1, 1, - 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[41] = - { 0, - 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int16_t yy_base[59] = - { 0, - 0, 37, 79, 78, 79, 78, 80, 107, 107, 107, - 0, 107, 0, 6, 1, 23, 0, 20, 16, 107, - 11, 107, 0, 0, 12, 0, 33, 0, 107, 107, - 8, 107, 4, 107, 25, 30, 38, 2, 41, 107, - 46, 47, 107, 50, 43, 47, 61, 107, 107, 58, - 107, 107, 96, 98, 100, 0, 102, 104 - } ; - -static yyconst flex_int16_t yy_def[59] = - { 0, - 53, 53, 54, 54, 55, 55, 52, 52, 52, 52, - 56, 52, 52, 52, 52, 52, 52, 52, 57, 52, - 58, 52, 56, 52, 52, 52, 52, 52, 52, 52, - 57, 52, 58, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 0, 52, 52, 52, 52, 52, 52 - } ; - -static yyconst flex_int16_t yy_nxt[148] = - { 0, - 23, 9, 10, 11, 12, 39, 34, 13, 24, 26, - 14, 43, 32, 34, 35, 29, 15, 37, 16, 17, - 32, 30, 18, 39, 25, 13, 24, 26, 14, 43, - 36, 27, 35, 29, 15, 37, 16, 17, 9, 10, - 11, 12, 25, 28, 13, 38, 40, 14, 36, 27, - 41, 42, 44, 15, 45, 16, 17, 46, 47, 18, - 48, 28, 13, 38, 40, 14, 49, 50, 41, 42, - 44, 15, 45, 16, 17, 46, 47, 51, 48, 52, - 22, 22, 20, 20, 49, 50, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 51, 8, 8, 19, 19, - - 21, 21, 31, 31, 33, 33, 7, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52 - } ; - -static yyconst flex_int16_t yy_chk[148] = - { 0, - 56, 1, 1, 1, 1, 28, 33, 1, 13, 15, - 1, 38, 31, 21, 24, 17, 1, 26, 1, 1, - 19, 18, 1, 28, 14, 1, 13, 15, 1, 38, - 25, 16, 24, 17, 1, 26, 1, 1, 2, 2, - 2, 2, 14, 16, 2, 27, 35, 2, 25, 16, - 36, 37, 39, 2, 41, 2, 2, 42, 44, 2, - 45, 16, 2, 27, 35, 2, 46, 47, 36, 37, - 39, 2, 41, 2, 2, 42, 44, 50, 45, 7, - 6, 5, 4, 3, 46, 47, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 50, 53, 53, 54, 54, - - 55, 55, 57, 57, 58, 58, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52 - } ; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -#line 1 "./src/proxy/namespaces_lex.l" -#line 2 "./src/proxy/namespaces_lex.l" -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ -#include "config.h" -#include -#include - -#include - -#include "parsertypes.h" -#include "namespaces_parse.h" -extern char *strndup(const char*, size_t); - - -#line 515 "" - -#define INITIAL 0 -#define SINGLE_QUOTED 1 -#define DOUBLE_QUOTED 2 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - int yy_n_chars; - int yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - YYSTYPE * yylval_r; - - }; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - - /* This must go here because YYSTYPE and YYLTYPE are included - * from bison output in section 1.*/ - # define yylval yyg->yylval_r - -int namespaceslex_init (yyscan_t* scanner); - -int namespaceslex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int namespaceslex_destroy (yyscan_t yyscanner ); - -int namespacesget_debug (yyscan_t yyscanner ); - -void namespacesset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE namespacesget_extra (yyscan_t yyscanner ); - -void namespacesset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *namespacesget_in (yyscan_t yyscanner ); - -void namespacesset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *namespacesget_out (yyscan_t yyscanner ); - -void namespacesset_out (FILE * out_str ,yyscan_t yyscanner ); - -int namespacesget_leng (yyscan_t yyscanner ); - -char *namespacesget_text (yyscan_t yyscanner ); - -int namespacesget_lineno (yyscan_t yyscanner ); - -void namespacesset_lineno (int line_number ,yyscan_t yyscanner ); - -YYSTYPE * namespacesget_lval (yyscan_t yyscanner ); - -void namespacesset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int namespaceswrap (yyscan_t yyscanner ); -#else -extern int namespaceswrap (yyscan_t yyscanner ); -#endif -#endif - - static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - unsigned n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int namespaceslex \ - (YYSTYPE * yylval_param ,yyscan_t yyscanner); - -#define YY_DECL int namespaceslex \ - (YYSTYPE * yylval_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - -#line 45 "./src/proxy/namespaces_lex.l" - - -#line 753 "" - - yylval = yylval_param; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - namespacesensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - namespaces_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - namespaces_load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yyg->yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 53 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 107 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 47 "./src/proxy/namespaces_lex.l" -/* comment. Ignore */ - YY_BREAK -case 2: -YY_RULE_SETUP -#line 49 "./src/proxy/namespaces_lex.l" -BEGIN(SINGLE_QUOTED); - YY_BREAK -case 3: -/* rule 3 can match eol */ -YY_RULE_SETUP -#line 51 "./src/proxy/namespaces_lex.l" -yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECT; - YY_BREAK -case 4: -YY_RULE_SETUP -#line 53 "./src/proxy/namespaces_lex.l" -BEGIN(DOUBLE_QUOTED); - YY_BREAK -case 5: -/* rule 5 can match eol */ -YY_RULE_SETUP -#line 54 "./src/proxy/namespaces_lex.l" -yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECT; - YY_BREAK -case 6: -YY_RULE_SETUP -#line 57 "./src/proxy/namespaces_lex.l" -return TO; - YY_BREAK -case 7: -YY_RULE_SETUP -#line 58 "./src/proxy/namespaces_lex.l" -return ISSUER; - YY_BREAK -case 8: -YY_RULE_SETUP -#line 59 "./src/proxy/namespaces_lex.l" -return PERMIT; - YY_BREAK -case 9: -YY_RULE_SETUP -#line 60 "./src/proxy/namespaces_lex.l" -return DENY; - YY_BREAK -case 10: -YY_RULE_SETUP -#line 61 "./src/proxy/namespaces_lex.l" -return SELF; - YY_BREAK -case 11: -YY_RULE_SETUP -#line 62 "./src/proxy/namespaces_lex.l" -return SUBJECT_WORD; - YY_BREAK -case 12: -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 63 "./src/proxy/namespaces_lex.l" - - YY_BREAK -case 13: -/* rule 13 can match eol */ -YY_RULE_SETUP -#line 64 "./src/proxy/namespaces_lex.l" - - YY_BREAK -case 14: -YY_RULE_SETUP -#line 65 "./src/proxy/namespaces_lex.l" - - YY_BREAK -case 15: -YY_RULE_SETUP -#line 67 "./src/proxy/namespaces_lex.l" -ECHO; - YY_BREAK -#line 919 "" -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(SINGLE_QUOTED): -case YY_STATE_EOF(DOUBLE_QUOTED): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * namespaceslex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( namespaceswrap(yyscanner ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of namespaceslex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - namespacesrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - namespacesrestart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) namespacesrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - yyg->yy_n_chars += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yyg->yy_start; - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 53 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 53 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 52); - - return yy_is_jam ? 0 : yy_current_state; -} - - static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) -{ - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_cp = yyg->yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yyg->yy_hold_char; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yyg->yy_n_chars + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - yyg->yytext_ptr = yy_bp; - yyg->yy_hold_char = *yy_cp; - yyg->yy_c_buf_p = yy_cp; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) -#else - static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - namespacesrestart(yyin ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( namespaceswrap(yyscanner ) ) - return EOF; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ - void namespacesrestart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - namespacesensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - namespaces_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - namespaces_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - namespaces_load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ - void namespaces_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * namespacespop_buffer_state(); - * namespacespush_buffer_state(new_buffer); - */ - namespacesensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - namespaces_load_buffer_state(yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (namespaceswrap()) processing, but the only time this flag - * is looked at is after namespaceswrap() is called, so it's safe - * to go ahead and always set it. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void namespaces_load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ - YY_BUFFER_STATE namespaces_create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) namespacesalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in namespaces_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) namespacesalloc(b->yy_buf_size + 2 ,yyscanner ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in namespaces_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - namespaces_init_buffer(b,file ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with namespaces_create_buffer() - * @param yyscanner The scanner object. - */ - void namespaces_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - namespacesfree((void *) b->yy_ch_buf ,yyscanner ); - - namespacesfree((void *) b ,yyscanner ); -} - -#ifndef __cplusplus -extern int isatty (int ); -#endif /* __cplusplus */ - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a namespacesrestart() or at EOF. - */ - static void namespaces_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - namespaces_flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then namespaces_init_buffer was _probably_ - * called from namespacesrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ - void namespaces_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - namespaces_load_buffer_state(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void namespacespush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - namespacesensure_buffer_stack(yyscanner); - - /* This block is copied from namespaces_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from namespaces_switch_to_buffer. */ - namespaces_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void namespacespop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - namespaces_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - namespaces_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void namespacesensure_buffer_stack (yyscan_t yyscanner) -{ - int num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)namespacesalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in namespacesensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)namespacesrealloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in namespacesensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE namespaces_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) namespacesalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in namespaces_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - namespaces_switch_to_buffer(b ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to namespaceslex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * namespaces_scan_bytes() instead. - */ -YY_BUFFER_STATE namespaces_scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return namespaces_scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to namespaceslex() will - * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE namespaces_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) namespacesalloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in namespaces_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = namespaces_scan_buffer(buf,n ,yyscanner); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in namespaces_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = yyg->yy_hold_char; \ - yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ - yyg->yy_hold_char = *yyg->yy_c_buf_p; \ - *yyg->yy_c_buf_p = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE namespacesget_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int namespacesget_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int namespacesget_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *namespacesget_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *namespacesget_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -int namespacesget_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *namespacesget_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void namespacesset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void namespacesset_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "namespacesset_lineno called with no buffer" , yyscanner); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void namespacesset_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "namespacesset_column called with no buffer" , yyscanner); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see namespaces_switch_to_buffer - */ -void namespacesset_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void namespacesset_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int namespacesget_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void namespacesset_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -YYSTYPE * namespacesget_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; -} - -void namespacesset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylval = yylval_param; -} - -/* User-visible API */ - -/* namespaceslex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int namespaceslex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) namespacesalloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* namespaceslex_init_extra has the same functionality as namespaceslex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to namespacesalloc in - * the yyextra field. - */ - -int namespaceslex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - namespacesset_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) namespacesalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - namespacesset_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from namespaceslex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * namespaceslex_init() - */ - return 0; -} - -/* namespaceslex_destroy is for both reentrant and non-reentrant scanners. */ -int namespaceslex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - namespaces_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - namespacespop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - namespacesfree(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - namespacesfree(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * namespaceslex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - namespacesfree ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *namespacesalloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *namespacesrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void namespacesfree (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see namespacesrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 67 "./src/proxy/namespaces_lex.l" - - - diff --git a/emi.canl.canl-c/src/proxy/namespaces_lex.l b/emi.canl.canl-c/src/proxy/namespaces_lex.l deleted file mode 100644 index fe8e155..0000000 --- a/emi.canl.canl-c/src/proxy/namespaces_lex.l +++ /dev/null @@ -1,67 +0,0 @@ -%{ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ -#include "config.h" -#include -#include - -#include - -#include "parsertypes.h" -#include "namespaces_parse.h" -extern char *strndup(const char*, size_t); -%} - -%x SINGLE_QUOTED -%x DOUBLE_QUOTED - -%option reentrant -%option noyywrap -%option prefix="namespaces" -%option bison-bridge - -%% - -\#.* /* comment. Ignore */ - -\' BEGIN(SINGLE_QUOTED); - -[^']*\' yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECT; - -\" BEGIN(DOUBLE_QUOTED); -[^"]*\" yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECT; - - -(?i:TO) return TO; -(?i:ISSUER) return ISSUER; -(?i:PERMIT) return PERMIT; -(?i:DENY) return DENY; -(?i:SELF) return SELF; -(?i:SUBJECT) return SUBJECT_WORD; -\\$ -\n -. - -%% diff --git a/emi.canl.canl-c/src/proxy/namespaces_parse.y b/emi.canl.canl-c/src/proxy/namespaces_parse.y deleted file mode 100644 index 23e5193..0000000 --- a/emi.canl.canl-c/src/proxy/namespaces_parse.y +++ /dev/null @@ -1,126 +0,0 @@ -%{ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ -#include "config.h" -#include -#include -#include - -#include "parsertypes.h" -#include "listfunc.h" - -char **parse_subjects(char *string); -void namespaceserror(void *policies, void *scanner, char const *msg); -%} - -%error-verbose -%pure-parser -%name-prefix="namespaces" -%parse-param {struct policy ***policies} -%parse-param {void *scanner} -%lex-param {void *scanner} - -%union{ - char *string; - struct condition *cond; - struct policy *policy; - int integer; -} - -%token SUBJECT -%token TO -%token SELF -%token PERMIT -%token DENY -%token SUBJECT_WORD -%token ISSUER - -%type rule -%type condition -%type permit_or_deny - -%% - -eacl: rule { *policies = (struct policy**)listadd((char**)*policies, (char*)($1)); } -| eacl rule { *policies = (struct policy**)listadd((char**)*policies, (char*)($2)); } -; - -rule: TO ISSUER SUBJECT condition { - $$ = (struct policy *)calloc(1, sizeof(struct policy)); - if ($$) { - $$->self = 0; - $$->caname = strdup($3); - $$->conds = (struct condition**)listadd(NULL, (char*)($4)); - $$->type = TYPE_NAMESPACE; - } - - } -| TO ISSUER SELF condition { - $$ = (struct policy *)calloc(1, sizeof(struct policy)); - if ($$) { - $$->self = 1; - $$->caname = NULL; - $$->conds = (struct condition**)listadd(NULL, (char*)($4)); - $$->type = TYPE_NAMESPACE; - } - } -; - -condition: permit_or_deny SUBJECT_WORD SUBJECT { - $$ = (struct condition *)calloc(1, sizeof(struct condition)); - if ($$) { - $$->positive = $1; - $$->original = strdup($3); - $$->subjects = listadd(NULL, $$->original); - if (!$$->subjects) { - free($$->original); - free($$); - $$ = NULL; - } - } -} -; - -permit_or_deny: PERMIT { $$ = 1; } -| DENY { $$ = 0; } -; - -%% - -#if 0 -int main() -{ - namespacesdebug = 1; - struct policy **arg = NULL; - void *scanner=NULL; - namespaceslex_init(&scanner); - namespacesset_debug(1, scanner); - return namespacesparse(&arg, scanner); -} -#endif - -void namespaceserror(UNUSED(void *policies), UNUSED(void *scanner), UNUSED(char const *msg)) -{ -} diff --git a/emi.canl.canl-c/src/proxy/normalize.c b/emi.canl.canl-c/src/proxy/normalize.c deleted file mode 100644 index ce445e5..0000000 --- a/emi.canl.canl-c/src/proxy/normalize.c +++ /dev/null @@ -1,89 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ -#include "config.h" - -#include -#include - -#include "doio.h" - -static char *change(const char *str, char *from, char *to) -{ - char *copy = strdup(str); - - if (!copy) - return NULL; - - char *pos = strstr(copy, from); - char *tmp = NULL; - - while (pos) { - *pos = '\0'; - tmp = snprintf_wrap("%s%s%s", copy, to, pos + strlen(from)); - if (tmp) { - free(copy); - copy = tmp; - } - pos = strstr(copy + strlen(to), from); - } - - return copy; -} - -char *normalize(const char *str) -{ - char *tmp = NULL; - char *tmp2 = NULL; - - tmp = change(str, "/USERID=", "/UID="); - tmp2 = change(tmp, "/emailAddress=", "/Email="); - free(tmp); - tmp = change(tmp2, "/E=", "/Email="); - free(tmp2); - return tmp; -} - -#if 0 -int main(int argc, char *argv) -{ - char *str1="/prova/Email=frge/CN=op"; - char *str2="/prova/E=boh/emailAddress=mah/E=op/CN=fr"; - char *str3="/USERID=56/mah"; - - char *n1 = normalize(str1); - char *n2 = normalize(str2); - char *n3 = normalize(str3); - - printf("%s -> %s\n", str1, n1); - free(n1); - printf("%s -> %s\n", str2, n2); - free(n2); - printf("%s -> %s\n", str3, n3); - free(n3); - - exit(0); -} - -#endif diff --git a/emi.canl.canl-c/src/proxy/normalize.h b/emi.canl.canl-c/src/proxy/normalize.h deleted file mode 100644 index 0ad0ab5..0000000 --- a/emi.canl.canl-c/src/proxy/normalize.h +++ /dev/null @@ -1,39 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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 _VOMS_NORMALIZE_H -#define _VOMS_NORMALIZE_H - -#ifdef __cplusplus -extern "C" { -#endif - -extern char *normalize(const char *str); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/emi.canl.canl-c/src/proxy/parsertypes.h b/emi.canl.canl-c/src/proxy/parsertypes.h deleted file mode 100644 index 84bdbf8..0000000 --- a/emi.canl.canl-c/src/proxy/parsertypes.h +++ /dev/null @@ -1,50 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * Valerio Venturi - Valerio.Venturi@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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 _OLDGAA_PARSERTYPES_H -#define _OLDGAA_PARSERTYPES_H - -struct condition { - char **subjects; - char *original; - int positive; -}; - -#define TYPE_SIGNING 0 -#define TYPE_NAMESPACE 1 - -struct policy { - char *caname; - int self; - int type; - struct condition **conds; -}; - -#define SUCCESS_PERMIT 0 -#define SUCCESS_DENY 1 -#define SUCCESS_UNDECIDED 2 - -#endif diff --git a/emi.canl.canl-c/src/proxy/proxy.c b/emi.canl.canl-c/src/proxy/proxy.c deleted file mode 100644 index 62378bb..0000000 --- a/emi.canl.canl-c/src/proxy/proxy.c +++ /dev/null @@ -1,884 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "vomsproxy.h" -#include "myproxycertinfo.h" -#include "sslutils.h" -#include "doio.h" - -static char *readfromfile(char *file, int *size, int *warning); -static void setWarning(int *warning, int value); -static void setAdditional(void **additional, void *data); -static X509_EXTENSION *set_KeyUsageFlags(int flags); -static int get_KeyUsageFlags(X509 *cert); -static X509_EXTENSION *set_ExtendedKeyUsageFlags(char *flagnames); -static char *getBitName(char**string); -static int getBitValue(char *bitname); -static int convertMethod(char *bits, int *warning, void **additional); -static X509_EXTENSION *get_BasicConstraints(int ca); - -struct VOMSProxyArguments *VOMS_MakeProxyArguments() -{ - return (struct VOMSProxyArguments*)calloc(1, sizeof(struct VOMSProxyArguments)); -} - -void VOMS_FreeProxyArguments(struct VOMSProxyArguments *args) -{ - free(args); -} - -void VOMS_FreeProxy(struct VOMSProxy *proxy) -{ - if (proxy) { - X509_free(proxy->cert); - sk_X509_pop_free(proxy->chain, X509_free); - EVP_PKEY_free(proxy->key); - free(proxy); - } -} - -struct VOMSProxy *VOMS_AllocProxy() -{ - return (struct VOMSProxy*)calloc(1, sizeof(struct VOMSProxy)); -} - -int VOMS_WriteProxy(const char *filename, struct VOMSProxy *proxy) -{ - int ret = -1; - int fd = -1; - int retry = 3; - BIO *bp = NULL; - - while (fd < 0 && retry > 0) { - unlink(filename); - fd = open(filename, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600); - retry --; - } - -#ifndef WIN32 - if (fd != -1) { - if (fchmod(fd, S_IRUSR|S_IWUSR) < 0) { - close(fd); - return -1; - } - } -#endif - - if (fd != -1) { - if ((bp = BIO_new_fd(fd, BIO_NOCLOSE)) != NULL) { - ret = proxy_marshal_bp(bp, proxy->cert, proxy->key, NULL, proxy->chain); - BIO_free(bp); - } - close(fd); - } - - return ret; -} - - -static int kpcallback(int UNUSED(p), int UNUSED(n)) -{ - return 0; -} - -#define SET_EXT(ex) (!sk_X509_EXTENSION_push(extensions, (ex)) ? \ - (PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT), 0) : \ - ((ex = ((X509_EXTENSION*)NULL)), 1)) - -struct VOMSProxy *VOMS_MakeProxy(struct VOMSProxyArguments *args, int *warning, void **additional) -{ - char *value = NULL; - - X509 * ncert = NULL; - EVP_PKEY * npkey = NULL; - X509_REQ * req = NULL; - STACK_OF(X509_EXTENSION) * extensions = NULL; - int ku_flags = 0; - char *policy = NULL; - - X509_EXTENSION *ex1 = NULL, *ex2 = NULL, *ex3 = NULL, - *ex4 = NULL, *ex5 = NULL, *ex6 = NULL, *ex7 = NULL, - *ex8 = NULL, *ex9 = NULL, *ex10 = NULL, *ex11 = NULL, - *ex12 = NULL, *ex13 = NULL; - - int i = 0; - - struct VOMSProxy *proxy = NULL; - - static int init = 0; - - int (*cback)(); - - if (!init) { - InitProxyCertInfoExtension(1); - init = 1; - } - - setWarning(warning, PROXY_NO_ERROR); - - if (args->callback) - cback = args->callback; - else - cback = kpcallback; - - - if (args->proxyrequest == NULL) { - if (proxy_genreq(args->cert, &req, &npkey, args->bits, - args->newsubject ? args->newsubject : NULL, - (int (*)())cback)) - goto err; - } - else - req = args->proxyrequest; - - /* initialize extensions stack */ - - if ((extensions = sk_X509_EXTENSION_new_null()) == NULL) { - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - /* Add passed extensions */ - if (args->extensions) { - int proxyindex; - - for (proxyindex = 0; proxyindex < sk_X509_EXTENSION_num(args->extensions); proxyindex++) { - X509_EXTENSION *ext = X509_EXTENSION_dup(sk_X509_EXTENSION_value(args->extensions, i)); - if (ext) { - if (!sk_X509_EXTENSION_push(extensions, ext)) { - X509_EXTENSION_free(ext); - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - } - else { - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - } - } - /* Add proxy extensions */ - - /* voms extension */ - - if (args->datalen) { - if ((ex1 = CreateProxyExtension("voms", args->data, args->datalen, 0)) == NULL) { - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - if (!SET_EXT(ex1)) - goto err; - } - - /* include extension */ - - if (args->filename) { - - int filesize; - char *filedata = readfromfile(args->filename, &filesize, warning); - - if (filedata) { - if ((ex3 = CreateProxyExtension("incfile", filedata, filesize, 0)) == NULL) { - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); - free(filedata); - goto err; - } - - free(filedata); - if (!SET_EXT(ex3)) - goto err; - } - else { - setAdditional(additional, args->filename); - goto err; - } - } - - /* AC extension */ - - if (args->aclist) { - - if ((ex5 = X509V3_EXT_conf_nid(NULL, NULL, OBJ_txt2nid("acseq"), (char *)args->aclist)) == NULL) { - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - if (!SET_EXT(ex5)) - goto err; - } - - /* keyUsage extension */ - - if (args->keyusage) { - ku_flags = convertMethod(args->keyusage, warning, additional); - if (ku_flags == -1) { - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - } - else if (args->selfsigned) { - ku_flags = X509v3_KU_DIGITAL_SIGNATURE | X509v3_KU_KEY_CERT_SIGN | - X509v3_KU_CRL_SIGN; - } - else { - ku_flags = get_KeyUsageFlags(args->cert); - ku_flags &= ~X509v3_KU_KEY_CERT_SIGN; - ku_flags &= ~X509v3_KU_NON_REPUDIATION; - } - - if ((ex8 = set_KeyUsageFlags(ku_flags)) == NULL) { - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - X509_EXTENSION_set_critical(ex8, 1); - - if (!SET_EXT(ex8)) - goto err; - - /* netscapeCert extension */ - if (args->netscape) { - - if ((ex9 = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_cert_type, args->netscape)) == NULL) { - /* PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); */ - goto err; - } - - if (!SET_EXT(ex9)) - goto err; - } - - /* extended key usage */ - - if (args->exkusage) { - if ((ex10 = set_ExtendedKeyUsageFlags(args->exkusage)) == NULL) { - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); - setWarning(warning, PROXY_ERROR_UNKNOWN_EXTENDED_BIT); - setAdditional(additional,args->exkusage); - goto err; - } - - if (!SET_EXT(ex10)) - goto err; - } - - /* Basic Constraints */ - - if ((ex12 = get_BasicConstraints(args->selfsigned ? 1 : 0)) == NULL) { - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - X509_EXTENSION_set_critical(ex12, 1); - - if (!SET_EXT(ex12)) - goto err; - - /* vo extension */ - - if (strlen(args->voID)) { - if ((ex4 = CreateProxyExtension("vo", args->voID, strlen(args->voID), 0)) == NULL) { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - if (!SET_EXT(ex4)) - goto err; - } - - /* authority key identifier and subject key identifier extension */ - - { - X509V3_CTX ctx; - - X509V3_set_ctx(&ctx, (args->selfsigned ? NULL : args->cert), NULL, req, NULL, 0); - - if (args->selfsigned) { - X509 *tmpcert = NULL; - ex13 = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, "hash"); - - if (!ex13) { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - if (!SET_EXT(ex13)) - goto err; - - tmpcert = X509_new(); - if (tmpcert) { - EVP_PKEY *key = X509_REQ_get_pubkey(req); - X509_set_pubkey(tmpcert, key); - X509_add_ext(tmpcert, ex13, -1); - X509V3_set_ctx(&ctx, tmpcert, tmpcert, req, NULL, 0); - ex11 = X509V3_EXT_conf_nid(NULL, &ctx, NID_authority_key_identifier, "keyid"); - X509_free(tmpcert); - EVP_PKEY_free(key); - } - else - ex11 = NULL; - } - else { - ex11 = X509V3_EXT_conf_nid(NULL, &ctx, NID_authority_key_identifier, "keyid"); - } - - if (!ex11) { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - if (!SET_EXT(ex11)) - goto err; - } - - /* class_add extension */ - -#ifdef CLASS_ADD - - if (class_add_buf && class_add_buf_len > 0) { - if ((ex2 = proxy_extension_class_add_create((void *)args->class_add_buf, args->class_add_buf_len)) == NULL) { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - if (!SET_EXT(ex2)) - goto err; - } - -#endif - - /* PCI extension */ - - if (args->proxyversion>=3) { - myPROXYPOLICY * proxypolicy; - myPROXYCERTINFO * proxycertinfo = NULL; - ASN1_OBJECT * policy_language; - - /* getting contents of policy file */ - - int policysize = 0; - char *policylang = args->policylang; - - if (args->policyfile) { - policy = readfromfile(args->policyfile, &policysize, warning); - - if (!policy) { - setAdditional(additional, args->policyfile); - goto err; - } - } - - /* setting policy language field */ - - if (!policylang) { - if (!args->policyfile) { - policylang = IMPERSONATION_PROXY_OID; - setWarning(warning, PROXY_WARNING_GSI_ASSUMED); - } - else { - policylang = GLOBUS_GSI_PROXY_GENERIC_POLICY_OID; - setWarning(warning, PROXY_WARNING_GENERIC_LANGUAGE_ASSUMED); - } - } - - /* predefined policy language can be specified with simple name string */ - - else if (strcmp(policylang, IMPERSONATION_PROXY_SN) == 0) - policylang = IMPERSONATION_PROXY_OID; - else if (strcmp(policylang, INDEPENDENT_PROXY_SN) == 0) - policylang = INDEPENDENT_PROXY_OID; - - /* does limited prevail on others? don't know what does grid-proxy_init since if pl is given with - limited options it crash */ - if (args->limited) - policylang = LIMITED_PROXY_OID; - - OBJ_create(policylang, policylang, policylang); - - if (!(policy_language = OBJ_nid2obj(OBJ_sn2nid(policylang)))) { - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_OID); - goto err; - } - - int nativeopenssl = proxynative(); - - if (args->proxyversion == 3 || (args->proxyversion == 4 && !nativeopenssl)) { - /* proxypolicy */ - - proxypolicy = myPROXYPOLICY_new(); - - if (policy) { - myPROXYPOLICY_set_policy(proxypolicy, (unsigned char*)policy, policysize); - free(policy); - policy = NULL; - } - else if (args->policytext) - myPROXYPOLICY_set_policy(proxypolicy, - (unsigned char*)args->policytext, - strlen(args->policytext)); - - myPROXYPOLICY_set_policy_language(proxypolicy, policy_language); - - /* proxycertinfo */ - - proxycertinfo = myPROXYCERTINFO_new(); - myPROXYCERTINFO_set_version(proxycertinfo, args->proxyversion); - myPROXYCERTINFO_set_proxypolicy(proxycertinfo, proxypolicy); - - myPROXYPOLICY_free(proxypolicy); - - if (args->pathlength>=0) - myPROXYCERTINFO_set_path_length(proxycertinfo, args->pathlength); - - value = (char *)proxycertinfo; - } - else { - if (args->pathlength != -1) { - char *buffer = snprintf_wrap("%d", args->pathlength); - - if (policy) { - value = snprintf_wrap("language:%s,pathlen:%s,policy:text:%s", policylang, buffer, policy); - free(policy); - policy = NULL; - } - else if (args->policytext) - value = snprintf_wrap("language:%s,pathlen:%s,policy:text:%s", policylang, buffer, args->policytext); - else - value = snprintf_wrap("language:%s,pathlen:%s", policylang, buffer); - free(buffer); - } - else { - if (policy) - value = snprintf_wrap("language:%s,policy:text:%s", policylang, policy); - else if (args->policytext) - value = snprintf_wrap("language:%s,policy:text:%s", policylang, args->policytext); - else - value = snprintf_wrap("language:%s", policylang); - } - } - - if (args->proxyversion == 3) { - ex7 = X509V3_EXT_conf_nid(NULL, NULL, my_txt2nid(PROXYCERTINFO_V3), (char*)proxycertinfo); - value = NULL; - } else { - if (nativeopenssl) { - X509V3_CTX ctx; - X509V3_set_ctx(&ctx, NULL, NULL, NULL, NULL, 0L); - ctx.db = (void*)&ctx; - X509V3_CONF_METHOD method = { NULL, NULL, NULL, NULL }; - ctx.db_meth = &method; - ex7 = X509V3_EXT_conf_nid(NULL, &ctx, my_txt2nid(PROXYCERTINFO_V4), (char*)value); - free(value); - value = NULL; - } - else - ex7 = X509V3_EXT_conf_nid(NULL, NULL, my_txt2nid(PROXYCERTINFO_V4), (char*)value); - value = NULL; - } - - if (policy) { - free(policy); - policy = NULL; - } - - if (ex7 == NULL) { - PRXYerr(PRXYERR_F_PROXY_SIGN, PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - if (args->proxyversion == 4) { - X509_EXTENSION_set_critical(ex7, 1); - } - - if (!SET_EXT(ex7)) - goto err; - } - - if (!args->selfsigned) { - if (proxy_sign(args->cert, - args->key, - req, - &ncert, - args->hours*60*60 + args->minutes*60, - extensions, - args->limited, - args->proxyversion, - args->newsubject, - args->newissuer, - args->pastproxy, - args->newserial, - args->selfsigned)) { - goto err; - } - } - else { - if (proxy_sign(NULL, - npkey, - req, - &ncert, - args->hours*60*60 + args->minutes*60, - extensions, - args->limited, - 0, - args->newsubject, - args->newsubject, - args->pastproxy, - NULL, - args->selfsigned)) { - goto err; - } - } - - proxy = (struct VOMSProxy*)malloc(sizeof(struct VOMSProxy)); - - if (proxy) { - proxy->cert = ncert; - proxy->key = npkey; - proxy->chain = sk_X509_new_null(); - - if (args->cert) - sk_X509_push(proxy->chain, X509_dup(args->cert)); - - for (i = 0; i < sk_X509_num(args->chain); i++) - sk_X509_push(proxy->chain, X509_dup(sk_X509_value(args->chain, i))); - } - - err: - - if (!proxy) { - X509_free(ncert); - EVP_PKEY_free(npkey); - } - - if (extensions) { - sk_X509_EXTENSION_pop_free(extensions, X509_EXTENSION_free); - } - if (!args->proxyrequest) - X509_REQ_free(req); - - X509_EXTENSION_free(ex13); - X509_EXTENSION_free(ex12); - X509_EXTENSION_free(ex11); - X509_EXTENSION_free(ex10); - X509_EXTENSION_free(ex9); - X509_EXTENSION_free(ex8); - X509_EXTENSION_free(ex6); - X509_EXTENSION_free(ex7); - X509_EXTENSION_free(ex5); - X509_EXTENSION_free(ex2); - X509_EXTENSION_free(ex3); - X509_EXTENSION_free(ex4); - X509_EXTENSION_free(ex1); - free(policy); - free(value); - return proxy; -} - -X509_EXTENSION *CreateProxyExtension(char * name, char *data, int datalen, int crit) -{ - - X509_EXTENSION * ex = NULL; - ASN1_OBJECT * ex_obj = NULL; - ASN1_OCTET_STRING * ex_oct = NULL; - - int nid = OBJ_txt2nid(name); - - if (nid != 0) - ex_obj = OBJ_nid2obj(nid); - else - ex_obj = OBJ_txt2obj(name, 0); - - if (!ex_obj) { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_OID); - goto err; - } - - if (!(ex_oct = ASN1_OCTET_STRING_new())) { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - ex_oct->data = (unsigned char*)data; - ex_oct->length = datalen; - - if (!(ex = X509_EXTENSION_create_by_OBJ(NULL, ex_obj, crit, ex_oct))) { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_EXT); - } - - err: - - if (ex_oct) { - /* avoid spurious free of the contents. */ - ex_oct->length = 0; - ex_oct->data = NULL; - ASN1_OCTET_STRING_free(ex_oct); - } - - ASN1_OBJECT_free(ex_obj); - - return ex; - -} - - -static char *readfromfile(char *file, int *size, int *warning) -{ - int fd = open(file,O_RDONLY); - char *buffer = NULL; - - if (fd != -1) { - struct stat filestats; - - if (!fstat(fd, &filestats)) { - *size = filestats.st_size; - - buffer = (char *)malloc(*size); - - if (buffer) { - int offset = 0; - int ret = 0; - - do { - ret = read(fd, buffer+offset, *size - offset); - offset += ret; - } while ( ret > 0); - - if (ret < 0) { - free(buffer); - buffer = NULL; - setWarning(warning, PROXY_ERROR_FILE_READ); - } - } - else - setWarning(warning, PROXY_ERROR_OUT_OF_MEMORY); - } - else - setWarning(warning, PROXY_ERROR_STAT_FILE); - close(fd); - } - else - setWarning(warning, PROXY_ERROR_OPEN_FILE); - - - return buffer; -} - -static void setWarning(int *warning, int value) -{ - if (warning) - *warning = value; -} - -static void setAdditional(void **additional, void *data) -{ - if (additional) - *additional = data; -} - -static X509_EXTENSION *set_KeyUsageFlags(int flags) -{ - unsigned char data[2]; - - X509_EXTENSION *ext = NULL; - ASN1_BIT_STRING *str = ASN1_BIT_STRING_new(); - - if (str) { - int len =0; - - data[0] = flags & 0x00ff; - data[1] = (flags & 0xff00) >> 8; - - len = (data[1] ? 2 : 1); - - ASN1_BIT_STRING_set(str, data, len); - - ext = X509V3_EXT_i2d(NID_key_usage, 1, str); - ASN1_BIT_STRING_free(str); - - return ext; - } - - return NULL; -} - -static X509_EXTENSION *set_ExtendedKeyUsageFlags(char *flagnames) -{ - if (!flagnames) - return NULL; - - return X509V3_EXT_conf_nid(NULL, NULL, NID_ext_key_usage, flagnames); -} - -static X509_EXTENSION *get_BasicConstraints(int ca) -{ - return X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, (ca ? "CA:true" : "CA:false")); -} - -static int get_KeyUsageFlags(X509 *cert) -{ - int keyusage = 0; - - ASN1_BIT_STRING *usage = X509_get_ext_d2i(cert, NID_key_usage, NULL, NULL); - - if (usage) { - if (usage->length > 0) - keyusage = usage->data[0]; - if (usage->length > 1) - keyusage |= usage->data[1] << 8; - - ASN1_BIT_STRING_free(usage); - } - - return keyusage; -} - -static char *getBitName(char**string) -{ - char *div = NULL; - char *temp = NULL; - - if (!string || !(*string) || (*(*string) == '\0')) - return NULL; - - div = strchr(*string, ','); - - if (div) { - temp = *string; - *div++ = '\0'; - *string = div; - } - else { - temp = *string; - *string = *string + strlen(*string); - } - - return temp; -} - -static int getBitValue(char *bitname) -{ - if (!strcmp(bitname, "digitalSignature")) - return KU_DIGITAL_SIGNATURE; - else if (!strcmp(bitname, "nonRepudiation")) - return KU_NON_REPUDIATION; - else if (!strcmp(bitname, "keyEncipherment")) - return KU_KEY_ENCIPHERMENT; - else if (!strcmp(bitname, "dataEncipherment")) - return KU_DATA_ENCIPHERMENT; - else if (!strcmp(bitname, "keyAgreement")) - return KU_KEY_AGREEMENT; - else if (!strcmp(bitname, "keyCertSign")) - return KU_KEY_CERT_SIGN; - else if (!strcmp(bitname, "cRLSign")) - return KU_CRL_SIGN; - else if (!strcmp(bitname, "encipherOnly")) - return KU_ENCIPHER_ONLY; - else if (!strcmp(bitname, "decipherOnly")) - return KU_DECIPHER_ONLY; - - return 0; -} - - -static int convertMethod(char *bits, int *warning, void **additional) -{ - char *bitname = NULL; - int value = 0; - int total = 0; - - while ((bitname = getBitName(&bits))) { - value = getBitValue(bitname); - if (value == 0) { - setWarning(warning, PROXY_ERROR_UNKNOWN_BIT); - setAdditional(additional, bitname); - return -1; - } - total |= value; - } - - return total; -} - -char *ProxyCreationError(int error, void *additional) -{ - switch (error) { - case PROXY_NO_ERROR: - return NULL; - break; - - case PROXY_ERROR_OPEN_FILE: - return snprintf_wrap("Error: cannot open file: %s\n%s\n", additional, strerror(errno)); - break; - - case PROXY_ERROR_FILE_READ: - return snprintf_wrap("Error: cannot read from file: %s\n%s\n", additional, strerror(errno)); - break; - - case PROXY_ERROR_STAT_FILE: - return snprintf_wrap("Error: cannot stat file: %s\n%s\n", additional, strerror(errno)); - break; - - case PROXY_ERROR_OUT_OF_MEMORY: - return snprintf_wrap("Error: out of memory"); - break; - - case PROXY_ERROR_UNKNOWN_BIT: - return snprintf_wrap("KeyUsage bit: %s unknown\n", additional); - break; - - case PROXY_ERROR_UNKNOWN_EXTENDED_BIT: - return snprintf_wrap("ExtKeyUsage bit value: %s invalid. One or more of the bits are unknown\n", additional); - break; - - case PROXY_WARNING_GSI_ASSUMED: - return snprintf_wrap("\nNo policy language specified, Gsi impersonation proxy assumed."); - break; - - case PROXY_WARNING_GENERIC_LANGUAGE_ASSUMED: - return snprintf_wrap("\nNo policy language specified with policy file, assuming generic."); - break; - - default: - return snprintf_wrap("Unknown error"); - break; - } -} diff --git a/emi.canl.canl-c/src/proxy/proxycertinfo.c b/emi.canl.canl-c/src/proxy/proxycertinfo.c deleted file mode 100644 index a944ea1..0000000 --- a/emi.canl.canl-c/src/proxy/proxycertinfo.c +++ /dev/null @@ -1,511 +0,0 @@ -/********************************************************************* - * - * Authors: Valerio Venturi - Valerio.Venturi@cnaf.infn.it - * Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ -#include "config.h" - -#include - -#include -#include -#include - -#include "myproxycertinfo.h" -#include "doio.h" - -/* myPROXYPOLICY function */ - -myPROXYPOLICY * myPROXYPOLICY_new() -{ - ASN1_CTX c; - myPROXYPOLICY * ret; - - ret = NULL; - - M_ASN1_New_Malloc(ret, myPROXYPOLICY); - ret->policy_language = OBJ_nid2obj(OBJ_sn2nid(IMPERSONATION_PROXY_SN)); - ret->policy = NULL; - return (ret); - M_ASN1_New_Error(ASN1_F_PROXYPOLICY_NEW); -} - -void myPROXYPOLICY_free(myPROXYPOLICY * policy) -{ - if(policy == NULL) return; - - ASN1_OBJECT_free(policy->policy_language); - M_ASN1_OCTET_STRING_free(policy->policy); - OPENSSL_free(policy); -} - -/* duplicate */ -myPROXYPOLICY * myPROXYPOLICY_dup(myPROXYPOLICY * policy) -{ -#ifdef TYPEDEF_I2D_OF - return ((myPROXYPOLICY *) ASN1_dup((i2d_of_void *)i2d_myPROXYPOLICY, - (d2i_of_void *)d2i_myPROXYPOLICY, - (char *)policy)); -#else - return ((myPROXYPOLICY *) ASN1_dup((int (*)())i2d_myPROXYPOLICY, - (char *(*)())d2i_myPROXYPOLICY, - (char *)policy)); -#endif -} - -/* set policy language */ -int myPROXYPOLICY_set_policy_language(myPROXYPOLICY * policy, ASN1_OBJECT * policy_language) -{ - if(policy_language != NULL) { - ASN1_OBJECT_free(policy->policy_language); - policy->policy_language = OBJ_dup(policy_language); - return 1; - } - - return 0; -} - -/* get policy language */ -ASN1_OBJECT * myPROXYPOLICY_get_policy_language(myPROXYPOLICY * policy) -{ - return policy->policy_language; -} - -/* set policy */ -int myPROXYPOLICY_set_policy(myPROXYPOLICY * proxypolicy, unsigned char * policy, int length) -{ - if(policy != NULL) { - /* if member policy of proxypolicy non set */ - if(!proxypolicy->policy) - proxypolicy->policy = ASN1_OCTET_STRING_new(); - - /* set member policy of proxypolicy */ - ASN1_OCTET_STRING_set(proxypolicy->policy, policy, length); - } - else - ASN1_OCTET_STRING_free(proxypolicy->policy); - - return 1; -} - -/* get policy */ -unsigned char * myPROXYPOLICY_get_policy(myPROXYPOLICY * proxypolicy, int * length) -{ - /* assure field policy is set */ - - if(proxypolicy->policy) { - *length = proxypolicy->policy->length; - - /* assure ASN1_OCTET_STRING is full */ - if (*length>0 && proxypolicy->policy->data) { - unsigned char * copy = malloc(*length); - memcpy(copy, proxypolicy->policy->data, *length); - return copy; - } - } - return NULL; -} - -/* internal to der conversion */ -int i2d_myPROXYPOLICY(myPROXYPOLICY * policy, unsigned char ** pp) -{ - M_ASN1_I2D_vars(policy); - - M_ASN1_I2D_len(policy->policy_language, i2d_ASN1_OBJECT); - - if(policy->policy) { - M_ASN1_I2D_len(policy->policy, i2d_ASN1_OCTET_STRING); - } - - M_ASN1_I2D_seq_total(); - M_ASN1_I2D_put(policy->policy_language, i2d_ASN1_OBJECT); - - if(policy->policy) { - M_ASN1_I2D_put(policy->policy, i2d_ASN1_OCTET_STRING); - } - - M_ASN1_I2D_finish(); -} - -myPROXYPOLICY * d2i_myPROXYPOLICY(myPROXYPOLICY ** a, unsigned char ** pp, long length) -{ - M_ASN1_D2I_vars(a, myPROXYPOLICY *, myPROXYPOLICY_new); - - M_ASN1_D2I_Init(); - M_ASN1_D2I_start_sequence(); - M_ASN1_D2I_get(ret->policy_language, d2i_ASN1_OBJECT); - - /* need to try getting the policy using - * a) a call expecting no tags - * b) a call expecting tags - * one of which should succeed - */ - - M_ASN1_D2I_get_opt(ret->policy, - d2i_ASN1_OCTET_STRING, - V_ASN1_OCTET_STRING); - M_ASN1_D2I_get_IMP_opt(ret->policy, - d2i_ASN1_OCTET_STRING, - 0, - V_ASN1_OCTET_STRING); - M_ASN1_D2I_Finish(a, - myPROXYPOLICY_free, - ASN1_F_D2I_PROXYPOLICY); -} - - - -/* myPROXYCERTINFO function */ - -myPROXYCERTINFO * myPROXYCERTINFO_new() -{ - myPROXYCERTINFO * ret = NULL; - ASN1_CTX c; - - M_ASN1_New_Malloc(ret, myPROXYCERTINFO); - memset(ret, 0, sizeof(myPROXYCERTINFO)); - ret->path_length = NULL; - ret->proxypolicy = myPROXYPOLICY_new(); - return (ret); - M_ASN1_New_Error(ASN1_F_PROXYCERTINFO_NEW); -} - -void myPROXYCERTINFO_free(myPROXYCERTINFO * proxycertinfo) -{ - /* assure proxycertinfo not empty */ - if(proxycertinfo == NULL) return; - - ASN1_INTEGER_free(proxycertinfo->path_length); - myPROXYPOLICY_free(proxycertinfo->proxypolicy); - OPENSSL_free(proxycertinfo); -} - -/* set path_length */ -int myPROXYCERTINFO_set_path_length(myPROXYCERTINFO * proxycertinfo, long path_length) -{ - /* assure proxycertinfo is not empty */ - if(proxycertinfo != NULL) { - - if(path_length != -1) { - /* if member path_length is empty allocate memory then set */ - if(proxycertinfo->path_length == NULL) - proxycertinfo->path_length = ASN1_INTEGER_new(); - return ASN1_INTEGER_set(proxycertinfo->path_length, path_length); - } - else { - ASN1_INTEGER_free(proxycertinfo->path_length); - proxycertinfo->path_length = NULL; - } - - return 1; - } - - return 0; -} - -int myPROXYCERTINFO_set_version(myPROXYCERTINFO * proxycertinfo, int version) -{ - if (proxycertinfo != NULL) { - proxycertinfo->version = version; - return 1; - } - - return 0; -} - -int myPROXYCERTINFO_get_version(myPROXYCERTINFO * proxycertinfo) -{ - if (proxycertinfo) - return proxycertinfo->version; - return -1; -} - - -/* get path length */ -long myPROXYCERTINFO_get_path_length(myPROXYCERTINFO * proxycertinfo) -{ - if(proxycertinfo && proxycertinfo->path_length) - return ASN1_INTEGER_get(proxycertinfo->path_length); - else - return -1; -} - -/* set policy */ -int myPROXYCERTINFO_set_proxypolicy(myPROXYCERTINFO * proxycertinfo, myPROXYPOLICY * proxypolicy) -{ - myPROXYPOLICY_free(proxycertinfo->proxypolicy); - - if(proxypolicy != NULL) - proxycertinfo->proxypolicy = myPROXYPOLICY_dup(proxypolicy); - else - proxycertinfo->proxypolicy = NULL; - - return 1; -} - -/* get policy */ -myPROXYPOLICY * myPROXYCERTINFO_get_proxypolicy(myPROXYCERTINFO * proxycertinfo) -{ - if(proxycertinfo) - return proxycertinfo->proxypolicy; - - return NULL; -} - -/* internal to der conversion */ -static int i2d_myPROXYCERTINFO_v3(myPROXYCERTINFO * proxycertinfo, unsigned char ** pp) -{ - int v1; - - M_ASN1_I2D_vars(proxycertinfo); - - v1 = 0; - - M_ASN1_I2D_len(proxycertinfo->proxypolicy, i2d_myPROXYPOLICY); - - M_ASN1_I2D_len_EXP_opt(proxycertinfo->path_length,i2d_ASN1_INTEGER, 1, v1); - M_ASN1_I2D_seq_total(); - M_ASN1_I2D_put(proxycertinfo->proxypolicy, i2d_myPROXYPOLICY); - M_ASN1_I2D_put_EXP_opt(proxycertinfo->path_length, i2d_ASN1_INTEGER, 1, v1); - M_ASN1_I2D_finish(); -} - -static int i2d_myPROXYCERTINFO_v4(myPROXYCERTINFO * proxycertinfo, unsigned char ** pp) -{ - M_ASN1_I2D_vars(proxycertinfo); - - if(proxycertinfo->path_length) - { - M_ASN1_I2D_len(proxycertinfo->path_length, i2d_ASN1_INTEGER); - } - - M_ASN1_I2D_len(proxycertinfo->proxypolicy, i2d_myPROXYPOLICY); - - M_ASN1_I2D_seq_total(); - if(proxycertinfo->path_length) - { - M_ASN1_I2D_put(proxycertinfo->path_length, i2d_ASN1_INTEGER); - } - M_ASN1_I2D_put(proxycertinfo->proxypolicy, i2d_myPROXYPOLICY); - M_ASN1_I2D_finish(); -} - -int i2d_myPROXYCERTINFO(myPROXYCERTINFO * proxycertinfo, unsigned char ** pp) -{ - switch(proxycertinfo->version) { - case 3: - return i2d_myPROXYCERTINFO_v3(proxycertinfo, pp); - break; - - case 4: - return i2d_myPROXYCERTINFO_v4(proxycertinfo, pp); - break; - - default: - return -1; - break; - } -} - -static myPROXYCERTINFO * d2i_myPROXYCERTINFO_v3(myPROXYCERTINFO ** cert_info, unsigned char ** pp, long length) -{ - M_ASN1_D2I_vars(cert_info, myPROXYCERTINFO *, myPROXYCERTINFO_new); - - M_ASN1_D2I_Init(); - M_ASN1_D2I_start_sequence(); - - M_ASN1_D2I_get((ret->proxypolicy), d2i_myPROXYPOLICY); - - M_ASN1_D2I_get_EXP_opt(ret->path_length, d2i_ASN1_INTEGER, 1); - - ret->version = 3; - M_ASN1_D2I_Finish(cert_info, myPROXYCERTINFO_free, ASN1_F_D2I_PROXYCERTINFO); -} - -static myPROXYCERTINFO * d2i_myPROXYCERTINFO_v4(myPROXYCERTINFO ** cert_info, unsigned char ** pp, long length) -{ - M_ASN1_D2I_vars(cert_info, myPROXYCERTINFO *, myPROXYCERTINFO_new); - - M_ASN1_D2I_Init(); - M_ASN1_D2I_start_sequence(); - - M_ASN1_D2I_get_EXP_opt(ret->path_length, d2i_ASN1_INTEGER, 1); - - M_ASN1_D2I_get_opt(ret->path_length, d2i_ASN1_INTEGER, V_ASN1_INTEGER); - - M_ASN1_D2I_get((ret->proxypolicy),d2i_myPROXYPOLICY); - - ret->version = 4; - M_ASN1_D2I_Finish(cert_info, myPROXYCERTINFO_free, ASN1_F_D2I_PROXYCERTINFO); -} - -myPROXYCERTINFO * d2i_myPROXYCERTINFO(myPROXYCERTINFO ** cert_info, unsigned char ** pp, long length) -{ - myPROXYCERTINFO *info = d2i_myPROXYCERTINFO_v3(cert_info, pp, length); - if (!info) - info = d2i_myPROXYCERTINFO_v4(cert_info, pp, length); - return info; -} - - -static int nativeopenssl = 0; - -static char *norep() -{ - static char *buffer=""; - return buffer; -} - -static void *myproxycertinfo_s2i(UNUSED(struct v3_ext_method *method), UNUSED(struct v3_ext_ctx *ctx), UNUSED(char *data)) -{ - return (myPROXYCERTINFO*)data; -} - -static char *myproxycertinfo_i2s(UNUSED(struct v3_ext_method *method), void *ext) -{ - myPROXYCERTINFO *pci = NULL; - char *encoding = NULL; - char *output = NULL; - myPROXYPOLICY *pp; - int dooid = 0; - char oid[256]; - - pci = (myPROXYCERTINFO *)ext; - - if (!pci) - return norep(); - - if (pci->path_length) { - int j = ASN1_INTEGER_get(pci->path_length); - - char *buffer = snprintf_wrap("%X", j); - output = snprintf_wrap("Path Length Constraint: %s%s\n\n", strlen(buffer)%2 ? "0" : "", buffer); - free(buffer); - } - else - output = strdup("Path Length Constraint: unlimited\n"); - - pp = pci->proxypolicy; - - if (pp && i2t_ASN1_OBJECT(oid, 256, pp->policy_language)) { - dooid = 1; - } - - encoding = snprintf_wrap("%sPolicy Language: %s%s%s%s\n", - output, - ( dooid ? oid : ""), - ( (pp && pp->policy) ? "\nPolicy Text: " : ""), - ( (pp && pp->policy) ? (char*)ASN1_STRING_data(pp->policy) : ""), - ( (pp && pp->policy) ? "\n" : "")); - - free(output); - return encoding; -} - -void InitProxyCertInfoExtension(int full) -{ -#define PROXYCERTINFO_V3 "1.3.6.1.4.1.3536.1.222" -#define PROXYCERTINFO_V4 "1.3.6.1.5.5.7.1.14" -#define OBJC(c,n) OBJ_create(c,n,n) - - X509V3_EXT_METHOD *pcert; - static int set = 0; - ASN1_OBJECT *objv3; - ASN1_OBJECT *objv4; - - if (set) - return; - - set = 1; - - - objv3 = OBJ_txt2obj(PROXYCERTINFO_V3,1); - objv4 = OBJ_txt2obj(PROXYCERTINFO_V4,1); - - /* Proxy Certificate Extension's related objects */ - if (OBJ_obj2nid(objv3) == 0) { - ERR_clear_error(); - OBJC(PROXYCERTINFO_V3, "Proxy Certificate Information"); - if (full) { - pcert = (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)); - - if (pcert) { - memset(pcert, 0, sizeof(*pcert)); - pcert->ext_nid = OBJ_txt2nid(PROXYCERTINFO_V3); - pcert->ext_flags = 0; - pcert->ext_new = (X509V3_EXT_NEW) myPROXYCERTINFO_new; - pcert->ext_free = (X509V3_EXT_FREE)myPROXYCERTINFO_free; - pcert->d2i = (X509V3_EXT_D2I) d2i_myPROXYCERTINFO; - pcert->i2d = (X509V3_EXT_I2D) i2d_myPROXYCERTINFO; - pcert->i2s = (X509V3_EXT_I2S) myproxycertinfo_i2s; - pcert->s2i = (X509V3_EXT_S2I) myproxycertinfo_s2i; - pcert->v2i = (X509V3_EXT_V2I) NULL; - pcert->r2i = (X509V3_EXT_R2I) NULL; - pcert->i2v = (X509V3_EXT_I2V) NULL; - pcert->i2r = (X509V3_EXT_I2R) NULL; - - X509V3_EXT_add(pcert); - } - } - } - - if (OBJ_obj2nid(objv4) == 0) { - ERR_clear_error(); - OBJC(PROXYCERTINFO_V4, "Proxy Certificate Information"); - if (full) { - pcert = (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)); - - if (pcert) { - memset(pcert, 0, sizeof(*pcert)); - pcert->ext_nid = OBJ_txt2nid(PROXYCERTINFO_V4); - pcert->ext_flags = 0; - pcert->ext_new = (X509V3_EXT_NEW) myPROXYCERTINFO_new; - pcert->ext_free = (X509V3_EXT_FREE)myPROXYCERTINFO_free; - pcert->d2i = (X509V3_EXT_D2I) d2i_myPROXYCERTINFO; - pcert->i2d = (X509V3_EXT_I2D) i2d_myPROXYCERTINFO; - pcert->i2s = (X509V3_EXT_I2S) myproxycertinfo_i2s; - pcert->s2i = (X509V3_EXT_S2I) myproxycertinfo_s2i; - pcert->v2i = (X509V3_EXT_V2I) NULL; - pcert->r2i = (X509V3_EXT_R2I) NULL; - pcert->i2v = (X509V3_EXT_I2V) NULL; - pcert->i2r = (X509V3_EXT_I2R) NULL; - - X509V3_EXT_add(pcert); - } - } - } - -#ifdef X509_V_FLAG_ALLOW_PROXY_CERTS - nativeopenssl = 1; -#endif - - ASN1_OBJECT_free(objv3); - ASN1_OBJECT_free(objv4); - - return; -} - -int proxynative(void) -{ - return nativeopenssl; -} diff --git a/emi.canl.canl-c/src/proxy/scutils.c b/emi.canl.canl-c/src/proxy/scutils.c deleted file mode 100644 index 2bbad60..0000000 --- a/emi.canl.canl-c/src/proxy/scutils.c +++ /dev/null @@ -1,987 +0,0 @@ -/********************************************************************** - -scutils.c - -Description: - Routines used internally to work with smart card - using PKCS11 - -**********************************************************************/ - -/********************************************************************** - Include header files -**********************************************************************/ -//#include "config.h" - -#ifdef USE_PKCS11 - -#include "scutils.h" -#include "sslutils.h" - -#ifndef WIN32 -#define FILE_SEPERATOR "/" -#else -#define FILE_SEPERATOR "\\" -#include -#endif - -#include -#include -#include - -#ifdef USE_PKCS11_DL -#include -#endif -#include "buffer.h" -#include "crypto.h" -#include "objects.h" -#include "asn1.h" -#include "evp.h" -#include "x509.h" -#include "pem.h" -#include "ssl.h" -#include "rsa.h" - - -/********************************************************************** - Type definitions -**********************************************************************/ - -/********************************************************************** - Module specific prototypes -**********************************************************************/ - -static int -sc_RSA_eay_private_decrypt(int flen, - unsigned char * from, - unsigned char * to, - RSA * rsa, - int padding); - -static int -sc_RSA_eay_private_encrypt(int flen, - unsigned char * from, - unsigned char * to, - RSA * rsa, - int padding); - -/********************************************************************** - Define module specific variables -**********************************************************************/ - -static ERR_STRING_DATA scerr_str_functs[]= -{ - {ERR_PACK(0,SCERR_F_RSA_ENCRYPT,0),"sc_RSA_private_encrypt"}, - {ERR_PACK(0,SCERR_F_RSA_DECRYPT,0),"sc_RSA_private_decrypt"}, - {ERR_PACK(0,SCERR_F_SCINIT,0),"sc_init"}, - {ERR_PACK(0,SCERR_F_GET_RSA_PRIV_KEY_OBJ,0),"sc_get_rsa_priv_key_obj"}, - {ERR_PACK(0,SCERR_F_GET_PRIV_KEY_OBJ,0),"sc_get_priv_key_obj"}, - {ERR_PACK(0,SCERR_F_GET_PRIV_KEY_BY_LABEL,0),"sc_get_priv_key_by_label"}, - {ERR_PACK(0,SCERR_F_GET_CERT_OBJ,0),"sc_get_cert_obj"}, - {ERR_PACK(0,SCERR_F_FIND_ONE_OBJ,0),"sc_find_one_obj"}, - {ERR_PACK(0,SCERR_F_FIND_CERT_BY_LABEL,0),"sc_find_cert_by_label"}, - {ERR_PACK(0,SCERR_F_LOAD_DLL,0),"sc_get_function_list"}, - {0,NULL}, -}; - -static ERR_STRING_DATA scerr_str_reasons[]= -{ - {SCERR_R_PKCS11_ERROR, "PKCS11 error"}, - {SCERR_R_SIGNINIT, "C_SignInit"}, - {SCERR_R_SIGN, "C_Sign"}, - {SCERR_R_SIGNRECINIT, "C_SignRecoverInit"}, - {SCERR_R_SIGNREC, "C_SignRecover"}, - {SCERR_R_INITIALIZE, "C_Initialize"}, - {SCERR_R_GETSLOTLIST, "C-GetSlotList"}, - {SCERR_R_OPENSESSION, "C_OpenSession"}, - {SCERR_R_LOGIN, "C_Login"}, - {SCERR_R_CREATEOBJ, "C_CreateObject"}, - {SCERR_R_UNSUPPORTED, "Unsupported feature"}, - {SCERR_R_GETATTRVAL, "C_GetAttributeValue"}, - {SCERR_R_FINDOBJINIT, "C_FindObjectInit"}, - {SCERR_R_FINDOBJ, "C_FindObject"}, - {SCERR_R_FOUNDMANY, "Found more then one matching key"}, - {SCERR_R_FIND_FAILED, "Unable to find object on smart card"}, - {SCERR_R_NO_PKCS11_DLL,"Unable to load the PKCS11 support"}, - {0,NULL}, -}; - -CK_FUNCTION_LIST_PTR pFunctionList = NULL; - -#ifdef WIN32 -HMODULE h_m_pkcs11 = NULL; -#else -void * h_m_pkcs11 = NULL; -#endif - -/********************************************************************** -Function: sc_get_function_list() - -Description: - Get the name of the PKCS11 dll to use from the registry, - load it, get the entry for the C_GetFunctionList - call it to set the pFunctionList. - -Parameters: - -Returns: - the pFunctionList or NULL -**********************************************************************/ -CK_FUNCTION_LIST_PTR -sc_get_function_list() -{ - CK_RV status; -#if defined(USE_PKCS11_DL) || defined(WIN32) - CK_RV (*gfl)(CK_FUNCTION_LIST_PTR_PTR); -#endif - if (pFunctionList) { - return pFunctionList; - } -#if defined(USE_PKCS11_DL) || defined(WIN32) - - if (!h_m_pkcs11) { - char * dllname = NULL; -#ifdef WIN32 - HKEY hkDir = NULL; - char val_dllname[512] = {"NONE"}; - LONG lval; - DWORD type; - - if (!h_m_pkcs11) { - - RegOpenKey(HKEY_CURRENT_USER,GSI_REGISTRY_DIR,&hkDir); - lval = sizeof(val_dllname) -1; - if (hkDir && (RegQueryValueEx(hkDir, - "PKCS11.DLL", - 0, - &type, - val_dllname,&lval) == ERROR_SUCCESS)) { - h_m_pkcs11 = LoadLibrary(val_dllname); - } - - if (hkDir) { - RegCloseKey(hkDir); - } - if (!h_m_pkcs11) { - SCerr(SCERR_F_SCINIT,SCERR_R_NO_PKCS11_DLL); - ERR_add_error_data(2,"Name of DLL=", - dllname? dllname:"NONE"); - return NULL; - } - } - gfl = (CK_RV (*)(CK_FUNCTION_LIST_PTR *)) - GetProcAddress(h_m_pkcs11,"C_GetFunctionList"); -#else - if (!h_m_pkcs11) { - dllname = getenv("PKCS11_LIB"); - if (!dllname) { - dllname = "libDSPKCS.so"; - } - h_m_pkcs11 = dlopen("libDSPKCS.so",RTLD_LAZY); - } - if (!h_m_pkcs11) { - SCerr(SCERR_F_SCINIT,SCERR_R_NO_PKCS11_DLL); - ERR_add_error_data(2,"Name of shared library=", - dllname); - return NULL; - } - - gfl = (CK_RV(*)(CK_FUNCTION_LIST_PTR_PTR)) - dlsym(h_m_pkcs11,"C_GetFunctionList"); -#endif - if (!gfl) { - SCerr(SCERR_F_LOAD_DLL,SCERR_R_NO_PKCS11_DLL); - ERR_add_error_data(1,"Cant find C_GetFunctionList"); - return NULL; - } - } - status = (*gfl)(&pFunctionList); -#else - status = C_GetFunctionList(&pFunctionList); -#endif /* PKCS11_DYNLOAD */ - - if (status != CKR_OK) { - SCerr(SCERR_F_LOAD_DLL,SCERR_R_UNSUPPORTED); - ERR_add_error_data(1,sc_ERR_code(status)); - return NULL; - } - return pFunctionList; -} - -/********************************************************************** -Function: ERR_load_scerr_strings() - -Description: - Sets up the error tables used by SSL and adds ours - using the ERR_LIB_USER - Only the first call does anything. - -Parameters: - i should be zero the first time any of the ERR_load_.*_string functions is called and - non-zero for the rest of the calls. -Returns: -**********************************************************************/ - -int -ERR_load_scerr_strings( - int i) -{ - static int init=1; - - if (init) { - init=0; - - if (i == 0) { - SSL_load_error_strings(); - } - ERR_load_strings(ERR_USER_LIB_SCERR_NUMBER,scerr_str_functs); - ERR_load_strings(ERR_USER_LIB_SCERR_NUMBER,scerr_str_reasons); - i++; - } - return i; -} - -/********************************************************************/ -/*******************************************************************/ -/* Temporary function to reuten the error number. Should return char */ - -char * -sc_ERR_code( - CK_RV status) -{ - static char buf[256]; - - sprintf(buf,"PKCS#11 return=0x%8.8lx",status); - return buf; -} - -/********************************************************************/ - -int -sc_init( - CK_SESSION_HANDLE_PTR PsessionHandle, - char * card, - CK_SLOT_ID_PTR ppslot, - char * ppin, - CK_USER_TYPE userType, - int initialized) -{ - int rc; - CK_SLOT_ID rslot; - CK_SLOT_ID_PTR pslot; - CK_TOKEN_INFO tokeninfo; - - if (ppslot) { - pslot = ppslot; - } - else { - pslot = &rslot; - } - - if (!initialized) { - rc = sc_init_one(pslot); - if (rc) { - return rc; - } - } - -/* - rc = sc_init_info(pslot, &tokenInfo); - if (rc) { - return rc; - } -*/ - - rc = sc_init_open_login(PsessionHandle, pslot, ppin, userType); - if (rc) { - return rc; - } - return 0; -} - -/*********************************************************** -Function: sc_init_one - -Description: - get the function list pointer first. - initialize and find the slot with the card - - -***********************************************************/ -int -sc_init_one( - CK_SLOT_ID_PTR pslot) -{ - CK_RV status; - CK_SLOT_ID list[20]; - CK_SLOT_ID slot; - CK_SLOT_ID_PTR slotList = &list[0]; - CK_TOKEN_INFO tokeninfo; - CK_ULONG count = 0; - CK_C_Initialize pC_Initialize; - - if (!sc_get_function_list()) { - return SCERR_R_INITIALIZE; - } - - pC_Initialize = pFunctionList->C_Initialize; - status = (*pC_Initialize)(0); - - if (status != CKR_OK) { - SCerr(SCERR_F_SCINIT,SCERR_R_INITIALIZE); - ERR_add_error_data(1,sc_ERR_code(status)); - return SCERR_R_INITIALIZE; - } -/* - status = (*(pFunctionList->C_GetSlotList))(FALSE, NULL, &count); - if (status != CKR_OK) { - SCerr(SCERR_F_SCINIT,SCERR_R_GETSLOTLIST); - ERR_add_error_data(1,sc_ERR_code(status)); - return SCERR_R_GETSLOTLIST; - } - fprintf(stderr,"Slotlist count = %d\n",count); -*/ - count = 20; - - status = (*(pFunctionList->C_GetSlotList))(FALSE, slotList, &count); - if (status != CKR_OK) { - SCerr(SCERR_F_SCINIT,SCERR_R_GETSLOTLIST); - ERR_add_error_data(1,sc_ERR_code(status)); - return SCERR_R_GETSLOTLIST; - } - - if (count == 0) { - SCerr(SCERR_F_SCINIT,SCERR_R_OPENSESSION); - ERR_add_error_data(1,"\n No SmartCard readers found"); - return SCERR_R_OPENSESSION; - } - - /* - * need to look at all the slots. - * Maybe provide the card label then look for it - */ - - slot = list[0]; - if (pslot) { - *pslot = slot; - } - return 0; -} - - -/*************************************************************** -Function: sc_init_info - -Description: - Read the card info and print debuging - -**************************************************************/ - -int -sc_init_info( - CK_SLOT_ID_PTR pslot, - CK_TOKEN_INFO_PTR ptokenInfo) -{ - CK_RV status; - - status = (*(pFunctionList->C_GetTokenInfo))(*pslot, ptokenInfo); - if (status != CKR_OK) { - SCerr(SCERR_F_SCINIT,SCERR_R_LOGIN); - ERR_add_error_data(2, "While reading Smart Card Info", - sc_ERR_code(status)); - return SCERR_R_LOGIN; - } - - return 0; -} - -/***************************************************************** -Function: sc_init_open_login - -Description: - Open a session to the card, and login - -*****************************************************************/ - -int -sc_init_open_login( - CK_SESSION_HANDLE_PTR PsessionHandle, - CK_SLOT_ID_PTR pslot, - char * ppin, - CK_USER_TYPE userType) -{ - CK_RV status; - char * pin; - char rpin[256]; - /* could also add CKF_EXCLUSIVE_SESSION */ - int flags = - CKF_RW_SESSION | CKF_SERIAL_SESSION ; - - status = (*(pFunctionList->C_OpenSession))(*pslot, - flags, 0, NULL, PsessionHandle); - if (status != CKR_OK) { - SCerr(SCERR_F_SCINIT,SCERR_R_OPENSESSION); - ERR_add_error_data(1,sc_ERR_code(status)); - return SCERR_R_OPENSESSION; - } - - if (ppin) /* did user provide the pin? */ { - pin = ppin; - } - else { - pin = rpin; - memset(rpin,0,sizeof(rpin)); -#ifdef WIN32 - read_passphrase_win32_prompt( - (userType == CKU_USER) ? - "Smart Card User PIN:" : "Smart Card SO PIN:",0); - read_passphrase_win32(rpin,sizeof(rpin),0); -#else - des_read_pw_string(rpin,sizeof(rpin), - (userType == CKU_USER) ? - "Smart Card User PIN:" : "Smart Card SO PIN:",0); -#endif - /*DEE should test this too */ - } - - status = (*(pFunctionList->C_Login))(*PsessionHandle, userType, - (CK_CHAR_PTR)pin, strlen(pin)); - memset(rpin,0,sizeof(rpin)); - if (status != CKR_OK) { - SCerr(SCERR_F_SCINIT,SCERR_R_LOGIN); - ERR_add_error_data(1,sc_ERR_code(status)); - return SCERR_R_LOGIN; - } - - return 0; -} - - -/*********************************************************************/ -int -sc_final( - CK_SESSION_HANDLE sessionHandle) -{ - CK_RV status; - status = (*(pFunctionList->C_Logout))(sessionHandle); - status = (*(pFunctionList->C_CloseSession))(sessionHandle); - return 0; -} - - - - -/*******************************************************************/ -/* find and get data off the card */ -/*******************************************************************/ - -int -sc_get_rsa_priv_key_obj( - CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hPrivKey, - RSA ** nrkey) -{ - CK_RV sc_status; - CK_BYTE_PTR pModulus = NULL; - CK_BYTE_PTR pExponent = NULL; - CK_ATTRIBUTE template[] = { - {CKA_MODULUS, NULL_PTR, 0}, - {CKA_PUBLIC_EXPONENT, NULL_PTR, 0} - }; - RSA * rsa = NULL; - RSA_METHOD * ometh = NULL; - RSA_METHOD * nmeth = NULL; - - rsa = RSA_new(); - /* - * set to use our method for this key. i - * This will use the smart card for this key - * But to do this requires us to copy the RSA method, and - * replace two routines. This is done this way to avoid - * chanfges to the SSLeay, and since these routines are not - * exported in the Win32 DLL. - */ - - nmeth = (RSA_METHOD *)malloc(sizeof(RSA_METHOD)); - if (!nmeth) { - return 1; /* DEE need to fix */ - } - ometh = rsa->meth; - nmeth->name = ometh->name; - nmeth->rsa_pub_enc = ometh->rsa_pub_enc; - nmeth->rsa_pub_dec = ometh->rsa_pub_dec; - nmeth->rsa_priv_enc = sc_RSA_eay_private_encrypt; - nmeth->rsa_priv_dec = sc_RSA_eay_private_decrypt; - nmeth->rsa_mod_exp = ometh->rsa_mod_exp; - nmeth->bn_mod_exp = ometh->bn_mod_exp; - nmeth->init = ometh->init; - nmeth->finish = ometh->finish; - nmeth->flags = ometh->flags; - nmeth->app_data = ometh->app_data; - - rsa->meth = nmeth; - - RSA_set_ex_data(rsa,SC_RSA_EX_DATA_INDEX_SESSION,(char *) hSession); - RSA_set_ex_data(rsa,SC_RSA_EX_DATA_INDEX_OBJECT, (char *) hPrivKey); - - sc_status = (*(pFunctionList->C_GetAttributeValue)) - (hSession, hPrivKey, template, 2); - -/* - * HACK for the LITRONIC cards, as the RSA PKCS11 says - * Section 9.7.1, the card must return the Modulus - */ - if (sc_status == CKR_ATTRIBUTE_TYPE_INVALID) { - *nrkey = rsa; - return 0; - } - - if (sc_status == CKR_OK) { - pModulus = (CK_BYTE_PTR) malloc(template[0].ulValueLen); - template[0].pValue = pModulus; - pExponent = (CK_BYTE_PTR) malloc(template[1].ulValueLen); - template[1].pValue = pExponent; - - sc_status = (*(pFunctionList->C_GetAttributeValue))(hSession, - hPrivKey, - template, - 1); - } - - if (sc_status != CKR_OK) { - SCerr(SCERR_F_GET_RSA_PRIV_KEY_OBJ,SCERR_R_GETATTRVAL); - ERR_add_error_data(1,sc_ERR_code(sc_status)); - free(pModulus); - free(pExponent); - return 1; - } - - rsa->n = BN_bin2bn(pModulus,template[0].ulValueLen,NULL); - rsa->e = BN_bin2bn(pExponent,template[1].ulValueLen,NULL); - - free(pModulus); - free(pExponent); - - *nrkey = rsa; - return 0; -} -/*******************************************************************/ -int -sc_get_priv_key_obj( - CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hPrivKey, - EVP_PKEY ** npkey) -{ - int rc; - CK_RV sc_status; - CK_KEY_TYPE keyType = 0; - CK_ATTRIBUTE template[] = { - {CKA_KEY_TYPE, &keyType, sizeof(keyType)} - }; - RSA * newrkey = NULL; - EVP_PKEY * upkey=NULL; - - upkey = EVP_PKEY_new(); - - /* We should look at the attribute of the key found to - * deside if it is RSA or DSA, then call correct routine. - * For now only support RSA. - */ - - sc_status = (*(pFunctionList->C_GetAttributeValue))(hSession, - hPrivKey, template, 1); - if (sc_status != CKR_OK) { - SCerr(SCERR_F_GET_PRIV_KEY_OBJ,SCERR_R_GETATTRVAL); - ERR_add_error_data(1,sc_ERR_code(sc_status)); - return 1; - } - switch (keyType) { - case (CKK_RSA): - rc = sc_get_rsa_priv_key_obj(hSession, - hPrivKey, &newrkey); - if (rc) { - return rc; - } - EVP_PKEY_assign(upkey, EVP_PKEY_RSA, (char *)newrkey); - break; - - default: - SCerr(SCERR_F_GET_PRIV_KEY_OBJ,SCERR_R_UNSUPPORTED); - return 1; - } - - *npkey = upkey; - return 0; - -} -/*******************************************************************/ -int -sc_get_priv_key_obj_by_label( - CK_SESSION_HANDLE hSession, - char * mylabel, - EVP_PKEY ** npkey) -{ - int rc; - CK_OBJECT_HANDLE hKey; - - rc = sc_find_priv_key_obj_by_label(hSession,mylabel,&hKey); - if (rc) { - return rc; - } - return sc_get_priv_key_obj(hSession, hKey, npkey); -} - - -/*******************************************************************/ -int -sc_find_priv_key_obj_by_label( - CK_SESSION_HANDLE hSession, - char * mylabel, - CK_OBJECT_HANDLE_PTR phPrivKey) -{ - CK_RV status; - CK_KEY_TYPE keyType = CKK_RSA; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_BBOOL true = TRUE; - CK_BBOOL false = FALSE; - CK_ATTRIBUTE template[20]; - int ai; - int li = -1; - int rc; - - ai = 0; - template[ai].type = CKA_CLASS; - template[ai].pValue = &keyClass; - template[ai].ulValueLen = sizeof(keyClass); - ai++; - - template[ai].type = CKA_TOKEN; - template[ai].pValue = &true; - template[ai].ulValueLen = sizeof(true); - ai++; - - if (strlen(mylabel)) { - template[ai].type = CKA_LABEL; - template[ai].pValue = mylabel; - template[ai].ulValueLen = strlen(mylabel) + - HACK_PKCS11_LOCAL_STRING_NULL; - li = ai; - ai++; - } - - rc = sc_find_one_obj(hSession, template, ai, phPrivKey); - /* - * we may or may not have a null as part of the name, - * so we will try again this is a modified HACK - * If we added the NULL to the test, we wont this time. - * If we did not, we will this time. - */ - if (rc && li >= 0) { - template[li].ulValueLen += 1 - 2 * HACK_PKCS11_LOCAL_STRING_NULL; - rc = sc_find_one_obj(hSession, template, ai, phPrivKey); - } - - if (rc) { - SCerr(SCERR_F_GET_PRIV_KEY_BY_LABEL,SCERR_R_FIND_FAILED); - return 1; - } - return 0; -} - -/*****************************************************************/ -int -sc_find_one_obj( - CK_SESSION_HANDLE hSession, - CK_ATTRIBUTE_PTR template, - int ai, - CK_OBJECT_HANDLE_PTR phObject) -{ - CK_RV status; - CK_ULONG ulObjectCount; - - status = (*(pFunctionList->C_FindObjectsInit))(hSession,template,ai); - if (status != CKR_OK) { - SCerr(SCERR_F_FIND_ONE_OBJ,SCERR_R_FINDOBJINIT); - ERR_add_error_data(1,sc_ERR_code(status)); - return 1; - } - ulObjectCount = 0; - status = (*(pFunctionList->C_FindObjects))(hSession, - phObject, - 1, - &ulObjectCount); - (*(pFunctionList->C_FindObjectsFinal))(hSession); - if (status != CKR_OK) { - SCerr(SCERR_F_FIND_ONE_OBJ,SCERR_R_FINDOBJ); - ERR_add_error_data(1,sc_ERR_code(status)); - return 1; - } - - if (ulObjectCount != 1) { - SCerr(SCERR_F_FIND_ONE_OBJ,SCERR_R_FOUNDMANY); - return 1; - } - - return 0; -} - - -/*******************************************************************/ -/* find and get certificates off of card */ -/*******************************************************************/ -int -sc_get_cert_obj( - CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hCert, - X509 ** ncert) -{ - CK_RV sc_status; - CK_BYTE_PTR pCert = NULL; - unsigned char * tasn1; - CK_ATTRIBUTE template[] = { - {CKA_VALUE, NULL_PTR, 0} - }; - X509 * x509 = NULL; - - sc_status = (*(pFunctionList->C_GetAttributeValue))(hSession, - hCert, - template, - 1); - - if (sc_status == CKR_OK) { - pCert = (CK_BYTE_PTR) malloc(template[0].ulValueLen); - template[0].pValue = pCert; - } - - sc_status = (*(pFunctionList->C_GetAttributeValue))(hSession, - hCert, - template, - 1); - - if (sc_status != CKR_OK) { - SCerr(SCERR_F_GET_CERT_OBJ,SCERR_R_GETATTRVAL); - ERR_add_error_data(1,sc_ERR_code(sc_status)); - free(pCert); - return 1; - } - - tasn1 = pCert; - x509 = d2i_X509(NULL,&tasn1,template[0].ulValueLen); - if (x509 == NULL) { - SCerr(SCERR_F_GET_CERT_OBJ,SCERR_R_BAD_CERT_OBJ); - free(pCert); - return 1; - } - - *ncert = x509; - free(pCert); - return 0; -} - - -/*******************************************************************/ -int -sc_find_cert_obj_by_label( - CK_SESSION_HANDLE hSession, - char * mylabel, - CK_OBJECT_HANDLE_PTR phCert) -{ - CK_RV status; - CK_CERTIFICATE_TYPE certType = CKC_X_509; - CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; - CK_BBOOL true = TRUE; - CK_BBOOL false = FALSE; - CK_ULONG ulObjectCount; - CK_ATTRIBUTE template[20]; - int ai; - int li = -1; - int rc; - - ai = 0; - template[ai].type = CKA_CLASS; - template[ai].pValue = &certClass; - template[ai].ulValueLen = sizeof(certClass); - ai++; - - template[ai].type = CKA_CERTIFICATE_TYPE; - template[ai].pValue = &certType; - template[ai].ulValueLen = sizeof(certType); - ai++; - - template[ai].type = CKA_TOKEN; - template[ai].pValue = &true; - template[ai].ulValueLen = sizeof(true); - ai++; - - if (strlen(mylabel)) { - template[ai].type = CKA_LABEL; - template[ai].pValue = mylabel; - template[ai].ulValueLen = strlen(mylabel) + HACK_PKCS11_LOCAL_STRING_NULL; - li = ai; - ai++; - } - - rc = sc_find_one_obj(hSession, template, ai, phCert); - - /* - * we may or may not have a null as part of the name, - * so we will try again this is a modified HACK - * If we added the NULL to the test, we wont this time. - * If we did not, we will this time. - */ - if (rc && li >= 0) { - template[li].ulValueLen += 1 - 2 * HACK_PKCS11_LOCAL_STRING_NULL; - rc = sc_find_one_obj(hSession, template, ai, phCert); - } - - if (rc) { - SCerr(SCERR_F_FIND_CERT_BY_LABEL,SCERR_R_FIND_FAILED); - return 1; - } - return 0; -} - -/*******************************************************************/ -int -sc_get_cert_obj_by_label( - CK_SESSION_HANDLE hSession, - char * mylabel, - X509 ** ncert) -{ - int rc; - CK_OBJECT_HANDLE hCert; - - rc = sc_find_cert_obj_by_label(hSession,mylabel,&hCert); - if (rc) { - return rc; - } - return sc_get_cert_obj(hSession, hCert, ncert); -} - -/****************************************************************/ - -static int -sc_RSA_eay_private_encrypt( - int flen, - unsigned char * from, - unsigned char * to, - RSA * rsa, - int padding) -{ - CK_ULONG ulsiglen; - CK_MECHANISM_PTR pMech = NULL; - CK_MECHANISM m_rsa_pkcs = {CKM_RSA_PKCS, 0,0}; - CK_MECHANISM m_rsa_raw = {CKM_RSA_X_509, 0,0}; - CK_RV ck_status; - CK_SESSION_HANDLE hSession; - CK_OBJECT_HANDLE hObject; - - hSession = (CK_SESSION_HANDLE )RSA_get_ex_data( - rsa, - SC_RSA_EX_DATA_INDEX_SESSION); - - hObject = (CK_OBJECT_HANDLE) RSA_get_ex_data( - rsa, - SC_RSA_EX_DATA_INDEX_OBJECT); - - switch (padding) { - case RSA_PKCS1_PADDING: - pMech = &m_rsa_pkcs; - break; - case RSA_NO_PADDING: - pMech = &m_rsa_raw; - break; - case RSA_SSLV23_PADDING: - default: - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); - } - - if (pMech == NULL) { - return 0; - } - - ck_status = (*(pFunctionList->C_SignInit))(hSession, pMech, hObject); - if (ck_status != CKR_OK) { - SCerr(SCERR_F_RSA_ENCRYPT,SCERR_R_SIGNINIT); - ERR_add_error_data(1,sc_ERR_code(ck_status)); - return 0; - } - - ck_status = (*(pFunctionList->C_Sign))(hSession, - from, flen, to, &ulsiglen); - if (ck_status != CKR_OK) { - SCerr(SCERR_F_RSA_ENCRYPT,SCERR_R_SIGN); - ERR_add_error_data(1,sc_ERR_code(ck_status)); - return 0; - } - - return ulsiglen; -} - -/***************************************************************/ - -static int -sc_RSA_eay_private_decrypt( - int flen, - unsigned char * from, - unsigned char * to, - RSA * rsa, - int padding) -{ - CK_ULONG ulsiglen; - CK_MECHANISM_PTR pMech = NULL; - CK_MECHANISM m_rsa_pkcs = {CKM_RSA_PKCS, 0,0}; - CK_MECHANISM m_rsa_raw = {CKM_RSA_X_509, 0,0}; - CK_RV ck_status; - CK_SESSION_HANDLE hSession; - CK_OBJECT_HANDLE hObject; - - hSession = (CK_SESSION_HANDLE )RSA_get_ex_data( - rsa, - SC_RSA_EX_DATA_INDEX_SESSION); - - hObject = (CK_OBJECT_HANDLE) RSA_get_ex_data( - rsa, - SC_RSA_EX_DATA_INDEX_OBJECT); - - switch (padding) { - case RSA_PKCS1_PADDING: - pMech = &m_rsa_pkcs; - break; - case RSA_NO_PADDING: - pMech = &m_rsa_raw; - break; - case RSA_SSLV23_PADDING: - default: - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); - } - - if (pMech == NULL) { - return 0; - } - - ulsiglen = BN_num_bytes(rsa->n); - - ck_status = (*(pFunctionList->C_SignRecoverInit))(hSession, - pMech, hObject); - if (ck_status != CKR_OK) { - SCerr(SCERR_F_RSA_DECRYPT,SCERR_R_SIGNRECINIT); - ERR_add_error_data(1,sc_ERR_code(ck_status)); - return 0; - } - - ck_status = (*(pFunctionList->C_SignRecover))(hSession, - from, - flen, - to, - &ulsiglen); - if (ck_status != CKR_OK) { - SCerr(SCERR_F_RSA_DECRYPT,SCERR_R_SIGNREC); - ERR_add_error_data(1,sc_ERR_code(ck_status)); - return 0; - } - return ulsiglen; -} -#endif /*USE_PKCS11*/ - - diff --git a/emi.canl.canl-c/src/proxy/scutils.h b/emi.canl.canl-c/src/proxy/scutils.h deleted file mode 100644 index 1b0b311..0000000 --- a/emi.canl.canl-c/src/proxy/scutils.h +++ /dev/null @@ -1,251 +0,0 @@ -/********************************************************************** -scutils.h: - -Description: - This header file used internally for smart card access via PKCS11 - For windows we can dynamicly load, and so PKCS#11 support - can allways be compiled, as we now have the RSA header files - included from the PKCS#11 2.01 version - - -**********************************************************************/ - -#ifndef VOMS_SCUTILS_H -#define VOMS_SCUTILS_H - -/********************************************************************** - Include header files -**********************************************************************/ -#ifndef NO_GSSAPI_CONFIG_H -#include "gssapi_config.h" -#endif - -#include -#include "ssl.h" -#include "err.h" -#include "bio.h" -#include "pem.h" -#include "x509.h" -#include "stack.h" -#include "evp.h" -#include "rsa.h" - -#include "pkcs11.h" - -#ifdef USE_TYPEMAP -#include "typemap.h" -#endif - -/********************************************************************** - Define constants -**********************************************************************/ -/* RSA PKCS#11 says local strings donot include the null, - * but examples do. Litronics writes the null in their labels - * and expect them when formating. - * The following will be added when writing a label or - * other local string which might have this problem. - * If other cards dont require, or this gets fixed, - * set this to 0 - * - * This was with Litronic before NetSign 2.0 - * - * We have added code to try with and without the null, - * So set this to 0 for now. - */ -#define HACK_PKCS11_LOCAL_STRING_NULL 0 - -/* - * We need to store the session and object handles with the key. - * In order to avoid changes to SSLeay, for the RSA structire, - * we will use two of the ex_data fields, by grabing 3 and 4. - * This may be a problem in future versions. - * These are used by the _get_ key routines when creating - * the key structure below, and by the sc_RSA_eay routines when - * they go to use the key. - */ - -#define SC_RSA_EX_DATA_INDEX_SESSION 3 -#define SC_RSA_EX_DATA_INDEX_OBJECT 4 - - -/* Location where the SCERR library will be stored */ -#define ERR_USER_LIB_SCERR_NUMBER ((ERR_LIB_USER) + 1) - -/* - * Use the SSLeay error facility with the ERR_LIB_USER - */ - -#define SCerr(f,r) ERR_PUT_error(ERR_USER_LIB_SCERR_NUMBER,(f),(r),__FILE__,__LINE__) - -/* - * defines for function codes our minor error codes - */ - -#define SCERR_F_RSA_ENCRYPT 100 -#define SCERR_F_RSA_DECRYPT 101 -#define SCERR_F_SCINIT 102 -#define SCERR_F_CREATE_DATA_OBJ 103 -#define SCERR_F_CREATE_CERT_OBJ 104 -#define SCERR_F_CREATE_RSA_PRIV_KEY_OBJ 105 -#define SCERR_F_CREATE_PRIV_KEY_OBJ 106 -#define SCERR_F_GET_RSA_PRIV_KEY_OBJ 107 -#define SCERR_F_GET_PRIV_KEY_OBJ 108 -#define SCERR_F_GET_PRIV_KEY_BY_LABEL 109 -#define SCERR_F_GET_CERT_OBJ 110 -#define SCERR_F_FIND_ONE_OBJ 111 -#define SCERR_F_FIND_CERT_BY_LABEL 112 -#define SCERR_F_LOAD_DLL 113 - -/* - * defines for reasons - */ - -#define SCERR_R_BASE 1500 - -#define SCERR_R_PKCS11_ERROR SCERR_R_BASE + 1 -#define SCERR_R_SIGNINIT SCERR_R_BASE + 2 -#define SCERR_R_SIGN SCERR_R_BASE + 3 -#define SCERR_R_SIGNRECINIT SCERR_R_BASE + 4 -#define SCERR_R_SIGNREC SCERR_R_BASE + 5 -#define SCERR_R_INITIALIZE SCERR_R_BASE + 6 -#define SCERR_R_GETSLOTLIST SCERR_R_BASE + 7 -#define SCERR_R_OPENSESSION SCERR_R_BASE + 8 -#define SCERR_R_LOGIN SCERR_R_BASE + 9 -#define SCERR_R_CREATEOBJ SCERR_R_BASE + 10 -#define SCERR_R_UNSUPPORTED SCERR_R_BASE + 11 -#define SCERR_R_GETATTRVAL SCERR_R_BASE + 12 -#define SCERR_R_FINDOBJINIT SCERR_R_BASE + 13 -#define SCERR_R_FINDOBJ SCERR_R_BASE + 14 -#define SCERR_R_FOUNDMANY SCERR_R_BASE + 15 -#define SCERR_R_BAD_CERT_OBJ SCERR_R_BASE + 16 -#define SCERR_R_FIND_FAILED SCERR_R_BASE + 17 -#define SCERR_R_NO_PKCS11_DLL SCERR_R_BASE + 18 -/* NOTE: Reason codes are limited to <4096 by openssl error handler */ - -/********************************************************************** - Type definitions -**********************************************************************/ - -/********************************************************************** - Global variables -*********************************************************************/ - -/* The pFunctionList is a pointer to the PKCS11 list - * of functions which is in the lib or DLL. - * It is initialized once on the first call to the - * sc_init() by sc_get_funct_list() - */ - -extern CK_FUNCTION_LIST_PTR pFunctionList; - -/********************************************************************** - Function prototypes -**********************************************************************/ -int -ERR_load_scerr_strings(int i); - -char * -sc_ERR_code(CK_RV status); - -CK_FUNCTION_LIST_PTR -sc_get_function_list(); - -int -sc_init(CK_SESSION_HANDLE_PTR PsessionHandle, - char *card, - CK_SLOT_ID_PTR pslot, - char * ppin, - CK_USER_TYPE userType, - int initialized); - -int -sc_init_one(CK_SLOT_ID_PTR pslot); - -int -sc_init_info(CK_SLOT_ID_PTR pslot, - CK_TOKEN_INFO_PTR ptokenInfo); - -int -sc_init_open_login(CK_SESSION_HANDLE_PTR PsessionHandle, - CK_SLOT_ID_PTR pslot, - char * ppin, - CK_USER_TYPE userType); - -int -sc_final(CK_SESSION_HANDLE sessionHandle); - - -int -sc_create_data_obj(CK_SESSION_HANDLE sessionHandle, - char *mylabel, - char *myvalue, - int mylen); - -int -sc_create_rsa_priv_key_obj(CK_SESSION_HANDLE sessionHandle, - char *mylabel, - RSA *rkey); - -int -sc_create_priv_key_obj(CK_SESSION_HANDLE sessionHandle, - char *mylabel, - EVP_PKEY *key); - -int -sc_create_cert_obj(CK_SESSION_HANDLE sessionHandle, - char *mylabel, - X509 *ucert); - -/**********************/ -int -sc_get_rsa_priv_key_obj(CK_SESSION_HANDLE sessionHandle, - CK_OBJECT_HANDLE hPrivKey, - RSA ** nrkey); - -int -sc_get_priv_key_obj(CK_SESSION_HANDLE sessionHandle, - CK_OBJECT_HANDLE hPrivKey, - EVP_PKEY ** nkey); - -int -sc_get_priv_key_obj_by_label(CK_SESSION_HANDLE sessionHandle, - char *mylabel, - EVP_PKEY ** nkey); - -int -sc_get_cert_obj_by_label(CK_SESSION_HANDLE sessionHandle, - char *mylabel, - X509 ** ncert); - -int -sc_find_one_obj(CK_SESSION_HANDLE sessionHandle, - CK_ATTRIBUTE_PTR template, - int ai, - CK_OBJECT_HANDLE_PTR phObject); - -int -sc_find_priv_key_obj_by_label(CK_SESSION_HANDLE sessionHandle, - char * mylabel, - CK_OBJECT_HANDLE_PTR phPrivKey); - -int -sc_find_cert_obj_by_label(CK_SESSION_HANDLE hSession, - char * mylabel, - CK_OBJECT_HANDLE_PTR phCert); - -int -sc_find_cert_obj_by_subject(CK_SESSION_HANDLE hSession, - X509_NAME * x509name, - CK_OBJECT_HANDLE_PTR phCert); - - -/************************************************************************/ -/* replacement RSA_PKCS1_SSLeay routines which will use the key on the */ -/* smart card We have our own method which will call PKCS11 */ -/* These are in sc_rsa_ssleay.c */ -/************************************************************************/ - -RSA_METHOD * sc_RSA_PKCS1_SSLeay(); - - -#endif /* _SCUTILS_H */ diff --git a/emi.canl.canl-c/src/proxy/signing_policy_lex.c.in b/emi.canl.canl-c/src/proxy/signing_policy_lex.c.in deleted file mode 100644 index e3e229b..0000000 --- a/emi.canl.canl-c/src/proxy/signing_policy_lex.c.in +++ /dev/null @@ -1,2118 +0,0 @@ - -#line 3 "" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yyg->yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yyg->yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE signingrestart(yyin ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = yyg->yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via signingrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ - ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void signingrestart (FILE *input_file ,yyscan_t yyscanner ); -void signing_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE signing_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void signing_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void signing_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void signingpush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void signingpop_buffer_state (yyscan_t yyscanner ); - -static void signingensure_buffer_stack (yyscan_t yyscanner ); -static void signing_load_buffer_state (yyscan_t yyscanner ); -static void signing_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER signing_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE signing_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE signing_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE signing_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); - -void *signingalloc (yy_size_t ,yyscan_t yyscanner ); -void *signingrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void signingfree (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer signing_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - signingensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - signing_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - signingensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - signing_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -#define signingwrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef int yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 17 -#define YY_END_OF_BUFFER 18 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[107] = - { 0, - 0, 0, 0, 0, 0, 0, 18, 16, 15, 4, - 1, 2, 16, 16, 16, 16, 16, 16, 16, 17, - 3, 17, 5, 1, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, - 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 10, 9, 0, 0, 0, 0, 0, 12, 0, - 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, - - 13, 0, 0, 0, 7, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 4, 1, 1, 1, 5, 1, - 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, - 1, 1, 7, 1, 1, 1, 8, 9, 1, 1, - 1, 1, 1, 1, 10, 11, 12, 13, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 14, 15, 1, - 1, 1, 1, 1, 1, 1, 1, 16, 17, 1, - 1, 1, 1, 1, 18, 1, 19, 20, 21, 22, - - 23, 1, 24, 25, 26, 27, 1, 28, 1, 29, - 30, 31, 1, 32, 33, 34, 35, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[36] = - { 0, - 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int16_t yy_base[113] = - { 0, - 0, 30, 130, 129, 130, 129, 131, 136, 136, 136, - 0, 136, 120, 122, 107, 97, 98, 102, 94, 118, - 136, 119, 136, 0, 112, 114, 98, 89, 87, 92, - 82, 109, 136, 110, 136, 79, 103, 87, 87, 88, - 89, 88, 79, 136, 71, 85, 67, 69, 68, 75, - 65, 3, 64, 70, 69, 65, 75, 73, 56, 136, - 66, 65, 136, 62, 58, 66, 60, 59, 61, 53, - 54, 46, 45, 60, 54, 53, 42, 41, 1, 51, - 51, 136, 136, 46, 48, 39, 22, 38, 136, 20, - 19, 39, 13, 136, 32, 25, 31, 16, 24, 17, - - 136, 18, 4, 4, 136, 136, 61, 63, 65, 0, - 67, 69 - } ; - -static yyconst flex_int16_t yy_def[113] = - { 0, - 107, 107, 108, 108, 109, 109, 106, 106, 106, 106, - 110, 106, 106, 106, 106, 106, 106, 106, 106, 111, - 106, 112, 106, 110, 106, 106, 106, 106, 106, 106, - 106, 111, 106, 112, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - - 106, 106, 106, 106, 106, 0, 106, 106, 106, 106, - 106, 106 - } ; - -static yyconst flex_int16_t yy_nxt[172] = - { 0, - 24, 9, 10, 11, 12, 106, 106, 106, 106, 106, - 84, 13, 85, 106, 106, 14, 106, 106, 15, 106, - 16, 106, 58, 17, 106, 106, 106, 106, 18, 106, - 19, 9, 10, 11, 12, 59, 105, 104, 103, 102, - 101, 13, 100, 99, 98, 14, 97, 96, 15, 95, - 16, 94, 93, 17, 92, 91, 90, 89, 18, 88, - 19, 8, 8, 20, 20, 22, 22, 32, 32, 34, - 34, 87, 86, 83, 82, 81, 80, 79, 78, 77, - 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, - 66, 65, 64, 63, 62, 61, 60, 57, 56, 55, - - 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, - 44, 43, 35, 33, 42, 41, 40, 39, 38, 37, - 36, 35, 33, 31, 30, 29, 28, 27, 26, 25, - 106, 23, 23, 21, 21, 7, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106 - } ; - -static yyconst flex_int16_t yy_chk[172] = - { 0, - 110, 1, 1, 1, 1, 0, 0, 0, 0, 0, - 79, 1, 79, 0, 0, 1, 0, 0, 1, 0, - 1, 0, 52, 1, 0, 0, 0, 0, 1, 0, - 1, 2, 2, 2, 2, 52, 104, 103, 102, 100, - 99, 2, 98, 97, 96, 2, 95, 93, 2, 92, - 2, 91, 90, 2, 88, 87, 86, 85, 2, 84, - 2, 107, 107, 108, 108, 109, 109, 111, 111, 112, - 112, 81, 80, 78, 77, 76, 75, 74, 73, 72, - 71, 70, 69, 68, 67, 66, 65, 64, 62, 61, - 59, 58, 57, 56, 55, 54, 53, 51, 50, 49, - - 48, 47, 46, 45, 43, 42, 41, 40, 39, 38, - 37, 36, 34, 32, 31, 30, 29, 28, 27, 26, - 25, 22, 20, 19, 18, 17, 16, 15, 14, 13, - 7, 6, 5, 4, 3, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106 - } ; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -#line 1 "./src/proxy/signing_policy_lex.l" -#line 2 "./src/proxy/signing_policy_lex.l" -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ -#include "config.h" -#include -#include - -#include - -#include "parsertypes.h" -#include "signing_policy_parse.h" -extern char *strndup(const char*, size_t); - - -#line 539 "" - -#define INITIAL 0 -#define SINGLE_QUOTED 1 -#define DOUBLE_QUOTED 2 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - int yy_n_chars; - int yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - YYSTYPE * yylval_r; - - }; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - - /* This must go here because YYSTYPE and YYLTYPE are included - * from bison output in section 1.*/ - # define yylval yyg->yylval_r - -int signinglex_init (yyscan_t* scanner); - -int signinglex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int signinglex_destroy (yyscan_t yyscanner ); - -int signingget_debug (yyscan_t yyscanner ); - -void signingset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE signingget_extra (yyscan_t yyscanner ); - -void signingset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *signingget_in (yyscan_t yyscanner ); - -void signingset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *signingget_out (yyscan_t yyscanner ); - -void signingset_out (FILE * out_str ,yyscan_t yyscanner ); - -int signingget_leng (yyscan_t yyscanner ); - -char *signingget_text (yyscan_t yyscanner ); - -int signingget_lineno (yyscan_t yyscanner ); - -void signingset_lineno (int line_number ,yyscan_t yyscanner ); - -YYSTYPE * signingget_lval (yyscan_t yyscanner ); - -void signingset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int signingwrap (yyscan_t yyscanner ); -#else -extern int signingwrap (yyscan_t yyscanner ); -#endif -#endif - - static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - unsigned n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int signinglex \ - (YYSTYPE * yylval_param ,yyscan_t yyscanner); - -#define YY_DECL int signinglex \ - (YYSTYPE * yylval_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - -#line 45 "./src/proxy/signing_policy_lex.l" - - -#line 777 "" - - yylval = yylval_param; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - signingensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - signing_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - signing_load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yyg->yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 107 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 136 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 47 "./src/proxy/signing_policy_lex.l" -/* ignore comments */ - YY_BREAK -case 2: -YY_RULE_SETUP -#line 48 "./src/proxy/signing_policy_lex.l" -BEGIN(SINGLE_QUOTED); - YY_BREAK -case 3: -/* rule 3 can match eol */ -YY_RULE_SETUP -#line 50 "./src/proxy/signing_policy_lex.l" -yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECTS; - YY_BREAK -case 4: -YY_RULE_SETUP -#line 52 "./src/proxy/signing_policy_lex.l" -BEGIN(DOUBLE_QUOTED); - YY_BREAK -case 5: -/* rule 5 can match eol */ -YY_RULE_SETUP -#line 53 "./src/proxy/signing_policy_lex.l" -yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECTS; - YY_BREAK -case 6: -YY_RULE_SETUP -#line 56 "./src/proxy/signing_policy_lex.l" -return COND_SUBJECTS; - YY_BREAK -case 7: -YY_RULE_SETUP -#line 57 "./src/proxy/signing_policy_lex.l" -return COND_BANNED; - YY_BREAK -case 8: -YY_RULE_SETUP -#line 58 "./src/proxy/signing_policy_lex.l" -return GLOBUS; - YY_BREAK -case 9: -YY_RULE_SETUP -#line 59 "./src/proxy/signing_policy_lex.l" -return POS_RIGHTS; - YY_BREAK -case 10: -YY_RULE_SETUP -#line 60 "./src/proxy/signing_policy_lex.l" -return NEG_RIGHTS; - YY_BREAK -case 11: -YY_RULE_SETUP -#line 61 "./src/proxy/signing_policy_lex.l" -return CA_SIGN; - YY_BREAK -case 12: -YY_RULE_SETUP -#line 62 "./src/proxy/signing_policy_lex.l" -return ACCESS_ID_CA; - YY_BREAK -case 13: -YY_RULE_SETUP -#line 63 "./src/proxy/signing_policy_lex.l" -return ACCESS_ID_ANYBODY; - YY_BREAK -case 14: -YY_RULE_SETUP -#line 64 "./src/proxy/signing_policy_lex.l" -return X509; - YY_BREAK -case 15: -/* rule 15 can match eol */ -YY_RULE_SETUP -#line 66 "./src/proxy/signing_policy_lex.l" - - YY_BREAK -case 16: -YY_RULE_SETUP -#line 67 "./src/proxy/signing_policy_lex.l" - - YY_BREAK -case 17: -YY_RULE_SETUP -#line 69 "./src/proxy/signing_policy_lex.l" -ECHO; - YY_BREAK -#line 950 "" -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(SINGLE_QUOTED): -case YY_STATE_EOF(DOUBLE_QUOTED): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * signinglex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( signingwrap(yyscanner ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of signinglex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - signingrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - signingrestart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) signingrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - yyg->yy_n_chars += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yyg->yy_start; - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 107 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 107 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 106); - - return yy_is_jam ? 0 : yy_current_state; -} - - static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) -{ - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_cp = yyg->yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yyg->yy_hold_char; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yyg->yy_n_chars + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - yyg->yytext_ptr = yy_bp; - yyg->yy_hold_char = *yy_cp; - yyg->yy_c_buf_p = yy_cp; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) -#else - static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - signingrestart(yyin ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( signingwrap(yyscanner ) ) - return EOF; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ - void signingrestart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - signingensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - signing_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - signing_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - signing_load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ - void signing_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * signingpop_buffer_state(); - * signingpush_buffer_state(new_buffer); - */ - signingensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - signing_load_buffer_state(yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (signingwrap()) processing, but the only time this flag - * is looked at is after signingwrap() is called, so it's safe - * to go ahead and always set it. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void signing_load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ - YY_BUFFER_STATE signing_create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) signingalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in signing_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) signingalloc(b->yy_buf_size + 2 ,yyscanner ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in signing_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - signing_init_buffer(b,file ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with signing_create_buffer() - * @param yyscanner The scanner object. - */ - void signing_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - signingfree((void *) b->yy_ch_buf ,yyscanner ); - - signingfree((void *) b ,yyscanner ); -} - -#ifndef __cplusplus -extern int isatty (int ); -#endif /* __cplusplus */ - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a signingrestart() or at EOF. - */ - static void signing_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - signing_flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then signing_init_buffer was _probably_ - * called from signingrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ - void signing_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - signing_load_buffer_state(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void signingpush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - signingensure_buffer_stack(yyscanner); - - /* This block is copied from signing_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from signing_switch_to_buffer. */ - signing_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void signingpop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - signing_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - signing_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void signingensure_buffer_stack (yyscan_t yyscanner) -{ - int num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)signingalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in signingensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)signingrealloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in signingensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE signing_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) signingalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in signing_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - signing_switch_to_buffer(b ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to signinglex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * signing_scan_bytes() instead. - */ -YY_BUFFER_STATE signing_scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return signing_scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to signinglex() will - * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE signing_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) signingalloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in signing_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = signing_scan_buffer(buf,n ,yyscanner); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in signing_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = yyg->yy_hold_char; \ - yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ - yyg->yy_hold_char = *yyg->yy_c_buf_p; \ - *yyg->yy_c_buf_p = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE signingget_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int signingget_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int signingget_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *signingget_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *signingget_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -int signingget_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *signingget_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void signingset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void signingset_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "signingset_lineno called with no buffer" , yyscanner); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void signingset_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "signingset_column called with no buffer" , yyscanner); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see signing_switch_to_buffer - */ -void signingset_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void signingset_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int signingget_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void signingset_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -YYSTYPE * signingget_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; -} - -void signingset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylval = yylval_param; -} - -/* User-visible API */ - -/* signinglex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int signinglex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) signingalloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* signinglex_init_extra has the same functionality as signinglex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to signingalloc in - * the yyextra field. - */ - -int signinglex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - signingset_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) signingalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - signingset_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from signinglex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * signinglex_init() - */ - return 0; -} - -/* signinglex_destroy is for both reentrant and non-reentrant scanners. */ -int signinglex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - signing_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - signingpop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - signingfree(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - signingfree(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * signinglex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - signingfree ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *signingalloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *signingrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void signingfree (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see signingrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 69 "./src/proxy/signing_policy_lex.l" diff --git a/emi.canl.canl-c/src/proxy/signing_policy_lex.l b/emi.canl.canl-c/src/proxy/signing_policy_lex.l deleted file mode 100644 index 75d121d..0000000 --- a/emi.canl.canl-c/src/proxy/signing_policy_lex.l +++ /dev/null @@ -1,68 +0,0 @@ -%{ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ -#include "config.h" -#include -#include - -#include - -#include "parsertypes.h" -#include "signing_policy_parse.h" -extern char *strndup(const char*, size_t); -%} - -%x SINGLE_QUOTED -%x DOUBLE_QUOTED - -%option reentrant -%option noyywrap -%option prefix="signing" -%option bison-bridge - -%% - -#.* /* ignore comments */ -\' BEGIN(SINGLE_QUOTED); - -[^']*\' yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECTS; - -\" BEGIN(DOUBLE_QUOTED); -[^"]*\" yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECTS; - - -cond_subjects return COND_SUBJECTS; -cond_banned_subjects return COND_BANNED; -globus return GLOBUS; -pos_rights return POS_RIGHTS; -neg_rights return NEG_RIGHTS; -CA\:sign return CA_SIGN; -access_id_CA return ACCESS_ID_CA; -access_id_ANYBODY return ACCESS_ID_ANYBODY; -X509 return X509; - -\n -. - diff --git a/emi.canl.canl-c/src/proxy/signing_policy_parse.y b/emi.canl.canl-c/src/proxy/signing_policy_parse.y deleted file mode 100644 index 93fab4f..0000000 --- a/emi.canl.canl-c/src/proxy/signing_policy_parse.y +++ /dev/null @@ -1,195 +0,0 @@ -%{ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * Valerio Venturi - Valerio.Venturi@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ -#include "config.h" -#include -#include -#include -#include - -#include "parsertypes.h" -#include "listfunc.h" - -char **parse_subjects(char *string); -void signingerror(void *policies, void *scanner, char const *msg); -%} - -%error-verbose -%pure-parser -%name-prefix="signing" -%parse-param {struct policy ***policies} -%parse-param {void *scanner} -%lex-param {void *scanner} - -%union{ - char *string; - struct condition *cond; - struct policy *policy; - void *array; -} - -%token SUBJECTS -%token COND_SUBJECTS -%token COND_BANNED -%token GLOBUS -%token POS_RIGHTS -%token NEG_RIGHTS -%token CA_SIGN -%token ACCESS_ID_CA -%token ACCESS_ID_ANYBODY -%token X509 - -%type eacl_entry -%type access_identity -%type realcondition -%type restrictions -%type access_identities -%% - -eacl: eacl_entry { *policies = (struct policy **)listadd((char**)(*policies), (char*)($1)); } -| eacl eacl_entry { *policies = (struct policy **)listadd((char**)(*policies), (char*)($2)); } - -eacl_entry: access_identities POS_RIGHTS GLOBUS CA_SIGN restrictions { - if ($1) { - $$->conds = (struct condition**)($5); - } - $$ = $1; -} -| access_identities NEG_RIGHTS GLOBUS CA_SIGN restrictions { - /* Ignore this. Globus does. */ - free($1); - $$ = NULL; -} - -access_identities: access_identity { - $$ = $1; -} - -restrictions: realcondition { - $$ = listadd(NULL, (char*)($1)); -} -| realcondition restrictions { - $$ = listadd($2, (char*)($1)); -} - - -access_identity: ACCESS_ID_CA X509 SUBJECTS { - $$ = (struct policy *)calloc(1, sizeof(struct policy)); - - if ($$) { - char **subjects = parse_subjects($3); - $$->caname = strdup(subjects[0]); - free(subjects); - $$->type = TYPE_SIGNING; - } - - if ($$ && !$$->caname) { - free($$); - $$ = NULL; - } -} -| ACCESS_ID_ANYBODY { - $$ = (struct policy *)calloc(1, sizeof(struct policy)); -} - -realcondition: COND_SUBJECTS GLOBUS SUBJECTS { - $$ = (struct condition*)malloc(sizeof(struct condition)); - if ($$) { - $$->positive = 1; - $$->original = strdup($3); - $$->subjects = parse_subjects($$->original); - if (!$$->subjects) { - free($$->original); - free($$); - $$ = NULL; - } - } -} -| COND_BANNED GLOBUS SUBJECTS { - $$ = (struct condition*)malloc(sizeof(struct condition)); - - if ($$) { - $$->positive = 0; - $$->original = strdup($3); - $$->subjects = parse_subjects($$->original); - if (!$$->subjects) { - free($$->original); - free($$); - $$ = NULL; - } - } -} -; - -%% - -char **parse_subjects(char *string) -{ - char **list = NULL; - char divider; - - if (!string) - return NULL; - - do { - divider = string[0]; - - if (divider == '\'' || divider == '"') { - char *end = strchr(string + 1, divider); - if (!end) - return list; - *end = '\0'; - - list = (char**)listadd(list, string+1); - string = ++end; - while (isspace(*string)) - string++; - } - else if (divider == '\0') - break; - else { - list = (char**)listadd(list, string); - string += strlen(string); - } - } while (string && string[0] != '\0'); - - return list; -} - -#if 0 -int main() -{ - signingdebug = 1; - void **arg = NULL; - void *scanner=NULL; - signinglex_init(&scanner); - signingset_debug(1, scanner); - return signingparse(arg, scanner); -} -#endif -void signingerror(UNUSED(void *policies), UNUSED(void *scanner), UNUSED(char const *msg)) -{ -} diff --git a/emi.canl.canl-c/src/proxy/sslutils.c b/emi.canl.canl-c/src/proxy/sslutils.c deleted file mode 100644 index 8705ab8..0000000 --- a/emi.canl.canl-c/src/proxy/sslutils.c +++ /dev/null @@ -1,3968 +0,0 @@ -/********************************************************************* - * - * Authors: Valerio Venturi - Valerio.Venturi@cnaf.infn.it - * Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) 2002-2009 INFN-CNAF on behalf of the EU DataGrid - * and EGEE I, II and III - * For license conditions see LICENSE file or - * http://www.apache.org/licenses/LICENSE-2.0.txt - * - * 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. - * - *********************************************************************/ -/********************************************************************** - -sslutils.c - -Description: - Routines used internally to implement delegation and proxy - certificates for use with Globus The same file is also used - for the non-exportable sslk5 which allows Kerberos V5 to - accept SSLv3 with certificates as proof of identiy and - issue a TGT. - -**********************************************************************/ - -/********************************************************************** - Include header files -**********************************************************************/ -#define _GNU_SOURCE - -//#include "config.h" -//#include "replace.h" -#include "myproxycertinfo.h" -#include "sslutils.h" -#include "parsertypes.h" -#include "doio.h" -//#include "data.h" - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifndef DEFAULT_SECURE_TMP_DIR -#ifndef WIN32 -#define DEFAULT_SECURE_TMP_DIR "/tmp" -#else -#define DEFAULT_SECURE_TMP_DIR "c:\\tmp" -#endif -#endif - -#ifndef WIN32 -#define FILE_SEPERATOR "/" -#else -#define FILE_SEPERATOR "\\" -#endif - -#ifdef WIN32 -#include "winglue.h" -#include -#else -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "openssl/buffer.h" -#include "openssl/crypto.h" - -#include "openssl/objects.h" -#include "openssl/asn1.h" -#include "openssl/evp.h" -#include "openssl/pkcs12.h" - -#include "openssl/rsa.h" -#include "openssl/rand.h" -#if SSLEAY_VERSION_NUMBER >= 0x0090581fL -#include "openssl/x509v3.h" -#endif - -#ifndef X509_V_ERR_INVALID_PURPOSE -#define X509_V_ERR_INVALID_PURPOSE X509_V_ERR_CERT_CHAIN_TOO_LONG -#endif - -#ifdef USE_PKCS11 -#include "scutils.h" -#endif - -static int fix_add_entry_asn1_set_param = 0; - - -#define V1_ROOT (EXFLAG_V1|EXFLAG_SS) -#define ku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) -#define xku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) -#define ns_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) - -static X509_NAME *make_DN(const char *dnstring); - - -extern int restriction_evaluate(STACK_OF(X509) *chain, struct policy **namespaces, - struct policy **signings); -extern void voms_free_policies(struct policy **policies); -extern int read_pathrestriction(STACK_OF(X509) *chain, char *path, - struct policy ***namespaces, - struct policy ***signings); - -static int check_critical_extensions(X509 *cert, int itsaproxy); - -/********************************************************************** - Type definitions -**********************************************************************/ - -/********************************************************************** - Module specific prototypes -**********************************************************************/ - -/********************************************************************** - Define module specific variables -**********************************************************************/ -static ERR_STRING_DATA prxyerr_str_functs[]= -{ - {ERR_PACK(0,PRXYERR_F_PROXY_GENREQ ,0),"proxy_genreq"}, - {ERR_PACK(0,PRXYERR_F_PROXY_SIGN ,0),"proxy_sign"}, - {ERR_PACK(0,PRXYERR_F_VERIFY_CB ,0),"verify_callback"}, - {ERR_PACK(0,PRXYERR_F_PROXY_TMP ,0),"proxy_marshal_tmp"}, - {ERR_PACK(0,PRXYERR_F_INIT_CRED ,0),"proxy_init_cred"}, - {ERR_PACK(0,PRXYERR_F_LOCAL_CREATE, 0),"proxy_local_create"}, - {ERR_PACK(0,PRXYERR_F_CB_NO_PW, 0),"proxy_pw_cb"}, - {ERR_PACK(0,PRXYERR_F_GET_CA_SIGN_PATH, 0),"get_ca_signing_policy_path"}, - {ERR_PACK(0,PRXYERR_F_PROXY_SIGN_EXT ,0),"proxy_sign_ext"}, - {ERR_PACK(0,PRXYERR_F_PROXY_CHECK_SUBJECT_NAME,0), - "proxy_check_subject_name"}, - {ERR_PACK(0,PRXYERR_F_PROXY_CONSTRUCT_NAME ,0),"proxy_construct_name"}, - {0,NULL}, -}; - -static ERR_STRING_DATA prxyerr_str_reasons[]= -{ - {PRXYERR_R_PROCESS_PROXY_KEY, "processing proxy key"}, - {PRXYERR_R_PROCESS_REQ, "creating proxy req"}, - {PRXYERR_R_PROCESS_SIGN, "while signing proxy req"}, - {PRXYERR_R_MALFORM_REQ, "malformed proxy req"}, - {PRXYERR_R_SIG_VERIFY, "proxy req signature verification error"}, - {PRXYERR_R_SIG_BAD, "proxy req signature does not match"}, - {PRXYERR_R_PROCESS_PROXY, "processing user proxy cert"}, - {PRXYERR_R_PROXY_NAME_BAD, "proxy name does not match"}, - {PRXYERR_R_PROCESS_SIGNC, "while signing proxy cert"}, - {PRXYERR_R_BAD_PROXY_ISSUER, "proxy can only be signed by user"}, - {PRXYERR_R_SIGN_NOT_CA ,"user cert not signed by CA"}, - {PRXYERR_R_PROBLEM_PROXY_FILE ,"problems creating proxy file"}, - {PRXYERR_R_PROCESS_KEY, "processing key"}, - {PRXYERR_R_PROCESS_CERT, "processing cert"}, - {PRXYERR_R_PROCESS_CERTS, "unable to access trusted certificates in:"}, - {PRXYERR_R_PROCESS_PROXY, "processing user proxy cert"}, - {PRXYERR_R_NO_TRUSTED_CERTS, "check X509_CERT_DIR and X509_CERT_FILE"}, - {PRXYERR_R_PROBLEM_KEY_FILE, "bad file system permissions on private key\n" - " key must only be readable by the user"}, - {PRXYERR_R_SERVER_ZERO_LENGTH_KEY_FILE, "system key file is empty"}, - {PRXYERR_R_USER_ZERO_LENGTH_KEY_FILE, "user private key file is empty"}, - {PRXYERR_R_PROBLEM_SERVER_NOKEY_FILE, "system key cannot be accessed"}, - {PRXYERR_R_PROBLEM_USER_NOKEY_FILE, "user private key cannot be accessed"}, - {PRXYERR_R_PROBLEM_SERVER_NOCERT_FILE, "system certificate not found"}, - {PRXYERR_R_PROBLEM_USER_NOCERT_FILE, "user certificate not found"}, - {PRXYERR_R_INVALID_CERT, "no certificate in file"}, - {PRXYERR_R_REMOTE_CRED_EXPIRED, "remote certificate has expired"}, - {PRXYERR_R_USER_CERT_EXPIRED, "user certificate has expired"}, - {PRXYERR_R_SERVER_CERT_EXPIRED, "system certificate has expired"}, - {PRXYERR_R_PROXY_EXPIRED, "proxy expired: run grid-proxy-init or wgpi first"}, - {PRXYERR_R_NO_PROXY, "no proxy credentials: run grid-proxy-init or wgpi first"}, - {PRXYERR_R_CRL_SIGNATURE_FAILURE, "invalid signature on a CRL"}, - {PRXYERR_R_CRL_NEXT_UPDATE_FIELD, "invalid nextupdate field in CRL"}, - {PRXYERR_R_CRL_HAS_EXPIRED, "outdated CRL found, revoking all certs till you get new CRL"}, - {PRXYERR_R_CERT_REVOKED, "certificate revoked per CRL"}, - {PRXYERR_R_NO_HOME, "can't determine HOME directory"}, - {PRXYERR_R_KEY_CERT_MISMATCH, "user key and certificate don't match"}, - {PRXYERR_R_WRONG_PASSPHRASE, "wrong pass phrase"}, - {PRXYERR_R_CA_POLICY_VIOLATION, "remote certificate CA signature not allowed by policy"}, - {PRXYERR_R_CA_POLICY_ERR,"no matching CA found in file for remote certificate"}, - {PRXYERR_R_CA_NOFILE,"could not find CA policy file"}, - {PRXYERR_R_CA_NOPATH,"could not determine path to CA policy file"}, - {PRXYERR_R_CA_POLICY_RETRIEVE, "CA policy retrieve problems"}, - {PRXYERR_R_CA_POLICY_PARSE, "CA policy parse problems"}, - {PRXYERR_R_CA_UNKNOWN,"remote certificate signed by unknown CA"}, - {PRXYERR_R_PROBLEM_CLIENT_CA, "problems getting client_CA list"}, - {PRXYERR_R_CB_NO_PW, "no proxy credentials: run grid-proxy-init or wgpi first"}, - {PRXYERR_R_CB_CALLED_WITH_ERROR,"certificate failed verify:"}, - {PRXYERR_R_CB_ERROR_MSG, "certificate:"}, - {PRXYERR_R_CLASS_ADD_OID,"can't find CLASS_ADD OID"}, - {PRXYERR_R_CLASS_ADD_EXT,"problem adding CLASS_ADD Extension"}, - {PRXYERR_R_DELEGATE_VERIFY,"problem verifiying the delegate extension"}, - {PRXYERR_R_EXT_ADD,"problem adding extension"}, - {PRXYERR_R_DELEGATE_CREATE,"problem creating delegate extension"}, - {PRXYERR_R_DELEGATE_COPY,"problem copying delegate extension to proxy"}, - {PRXYERR_R_BUFFER_TOO_SMALL,"buffer too small"}, - {PRXYERR_R_CERT_NOT_YET_VALID,"remote certificate not yet valid"}, - {PRXYERR_R_LOCAL_CA_UNKNOWN,"cannot find CA certificate for local credential"}, - {PRXYERR_R_OUT_OF_MEMORY,"out of memory"}, - {PRXYERR_R_BAD_ARGUMENT,"bad argument"}, - {PRXYERR_R_BAD_MAGIC,"bad magic number"}, - {PRXYERR_R_UNKNOWN_CRIT_EXT,"unable to handle critical extension"}, - {0,NULL} -}; - -int my_txt2nid(char *name) -{ - ASN1_OBJECT *obj = OBJ_txt2obj(name,1); - int nid = OBJ_obj2nid(obj); - ASN1_OBJECT_free(obj); - - return nid; -} - -/********************************************************************* -Function: X509_NAME_cmp_no_set - -Description: - To circumvent a bug with adding X509_NAME_ENTRIES - with the wrong "set", we will compare names without - the set. - This is a temporary fix which will be removed when we - fix the creation of the names using the correct sets. - This is only being done this way for some compatability - while installing the these fixes. - This fix is needed in all previous versions of Globus. - -Parameters: - same as X509_NAME_cmp -Returns : - same as X509_NAME_cmp -********************************************************************/ -static int -X509_NAME_cmp_no_set( - X509_NAME * a, - X509_NAME * b) -{ - int i; - int j; - X509_NAME_ENTRY * na; - X509_NAME_ENTRY * nb; - - if (sk_X509_NAME_ENTRY_num(a->entries) != - sk_X509_NAME_ENTRY_num(b->entries)) - { - return(sk_X509_NAME_ENTRY_num(a->entries) - - sk_X509_NAME_ENTRY_num(b->entries)); - } - - for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) - { - na = sk_X509_NAME_ENTRY_value(a->entries,i); - nb = sk_X509_NAME_ENTRY_value(b->entries,i); - j = na->value->length-nb->value->length; - - if (j) - { - return(j); - } - - j = memcmp(na->value->data, - nb->value->data, - na->value->length); - if (j) - { - return(j); - } - } - - /* We will check the object types after checking the values - * since the values will more often be different than the object - * types. */ - for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--) - { - na = sk_X509_NAME_ENTRY_value(a->entries,i); - nb = sk_X509_NAME_ENTRY_value(b->entries,i); - j = OBJ_cmp(na->object,nb->object); - - if (j) - { - return(j); - } - } - return(0); -} - -#ifdef WIN32 -/********************************************************************* -Function: getuid, getpid - -Descriptions: - For Windows95, WIN32, we don't have these, so we will default - to using uid 0 and pid 0 Need to look at this better for NT. -******************************************************************/ -static unsigned long -getuid() -{ - return 0; -} - -static int -getpid() -{ - return 0; -} - -#endif /* WIN32 */ - - -#if SSLEAY_VERSION_NUMBER < 0x0900 - -/********************************************************************** -Function: ERR_add_error_data() - -Description: - Dummy routine only defined if running with SSLeay-0.8.x - this feature was introduced with SSLeay-0.9.0 - -Parameters: - -Returns: -**********************************************************************/ -void PRIVATE -ERR_add_error_data( VAR_PLIST( int, num )) - VAR_ALIST -{ - VAR_BDEFN(args, int, num); -} - -/********************************************************************** -Function: ERR_get_error_line_data() - -Description: - Dummy routine only defined if running with SSLeay-0.8.x - this feature was introduced with SSLeay-0.9.0. We will - simulate it for 0.8.1 - -Parameters: - -Returns: -**********************************************************************/ -unsigned long PRIVATE -ERR_get_error_line_data( - char ** file, - int * line, - char ** data, - int * flags) -{ - if (data) - { - *data = ""; - } - - if (flags) - { - *flags = 0; - } - - return (ERR_get_error_line(file, line)); -} - -#endif - -/********************************************************************** -Function: ERR_set_continue_needed() - -Description: - Sets state information which error display routines can use to - determine if the error just added is enough information to describe - the error or if further error information need displayed. - (By default gss_display_status will only show one user level error) - - note: This function must be called after (or instead of) the ssl add error - data functions. - -Parameters: - -Returns: -**********************************************************************/ - -void PRIVATE -ERR_set_continue_needed(void) -{ - ERR_STATE *es; - es = ERR_get_state(); - es->err_data_flags[es->top] = - es->err_data_flags[es->top] | ERR_DISPLAY_CONTINUE_NEEDED; -} - -/********************************************************************** -Function: ERR_load_prxyerr_strings() - -Description: - Sets up the error tables used by SSL and adds ours - using the ERR_LIB_USER - Only the first call does anything. - Will also add any builtin objects for SSLeay. - -Parameters: - i should be zero the first time one of the ERR_load functions - is called and non-zero for each additional call. - -Returns: -**********************************************************************/ - -int PRIVATE -ERR_load_prxyerr_strings( - int i) -{ - static int init = 1; - struct stat stx; - clock_t cputime; -#if SSLEAY_VERSION_NUMBER >= 0x00904100L - const char * randfile; -#else - char * randfile; -#endif -#if SSLEAY_VERSION_NUMBER >= 0x0090581fL - char * egd_path; -#endif - char buffer[200]; - - if (init) - { - init = 0; - -#ifndef RAND_DO_NOT_USE_CLOCK - clock(); -#endif - if (i == 0) - { - SSL_load_error_strings(); - } - - OBJ_create("1.3.6.1.4.1.3536.1.1.1.1","CLASSADD","ClassAdd"); - OBJ_create("1.3.6.1.4.1.3536.1.1.1.2","DELEGATE","Delegate"); - OBJ_create("1.3.6.1.4.1.3536.1.1.1.3","RESTRICTEDRIGHTS", - "RestrictedRights"); - OBJ_create("0.9.2342.19200300.100.1.1","USERID","userId"); - - ERR_load_strings(ERR_USER_LIB_PRXYERR_NUMBER,prxyerr_str_functs); - ERR_load_strings(ERR_USER_LIB_PRXYERR_NUMBER,prxyerr_str_reasons); - - /* - * We need to get a lot of randomness for good security - * OpenSSL will use /dev/urandom (if available), - * uid, time, and gid. - * - * If user has RANDFILE set, or $HOME/.rnd - * load it for extra random seed. - * This may also not be enough, so we will also add in - * the time it takes to run this routine, which includes - * reading the randfile. - * Later we will also add in some keys and some stats - * if we have them. - * look for RAND_add in this source file. - * - * Other methods we could use: - * * Librand from Don Mitchell and Matt Blaze - * * Doing a netstat -in - * * some form of pstat - * But /dev/random and/or egd should be enough. - */ - - randfile = RAND_file_name(buffer,200); - - if (randfile) - { - RAND_load_file(randfile,1024L*1024L); - } - -#if SSLEAY_VERSION_NUMBER >= 0x0090581fL - /* - * Try to use the Entropy Garthering Deamon - * See the OpenSSL crypto/rand/rand_egd.c - */ - egd_path = getenv("EGD_PATH"); - if (egd_path == NULL) - { - egd_path = "/etc/entropy"; - } - RAND_egd(egd_path); -#endif - - /* if still not enough entropy*/ - if (RAND_status() == 0) - { - stat("/tmp",&stx); /* get times /tmp was modified */ - RAND_add((void*)&stx,sizeof(stx),16); - } - -#ifndef RAND_DO_NOT_USE_CLOCK - cputime = clock(); - RAND_add((void*)&cputime, sizeof(cputime),8); -#endif - - i++; -#ifdef USE_PKCS11 - i = ERR_load_scerr_strings(i); -#endif - - } - return i; -} - -/********************************************************************** -Function: checkstat() -Description: check the status of a file -Parameters: -Returns: - 0 pass all the following tests - 1 does not exist - 2 not owned by user - 3 readable by someone else - 4 zero length -**********************************************************************/ -static int checkstat(const char* filename) -{ - struct stat stx; - - if (stat(filename,&stx) != 0) - { - return 1; - } - - /* - * use any stat output as random data, as it will - * have file sizes, and last use times in it. - */ - RAND_add((void*)&stx,sizeof(stx),2); - -#if !defined(WIN32) && !defined(TARGET_ARCH_CYGWIN) - if (stx.st_uid != getuid()) - { - return 2; - } - - if (stx.st_mode & 066) - { - return 3; - } - -#endif /* !WIN32 && !TARGET_ARCH_CYGWIN */ - - if (stx.st_size == 0) - { - return 4; - } - return 0; - -} - -/********************************************************************** -Function: proxy_load_user_proxy() - -Description: - Given the user_proxy file, skip the first cert, - and add any additional certs to the cert_chain. - These must be additional proxies, or the user's cert - which signed the proxy. - This is based on the X509_load_cert_file routine. - -Parameters: - -Returns: -**********************************************************************/ - -int PRIVATE -proxy_load_user_proxy( - STACK_OF(X509) * cert_chain, - const char * file) -{ - - int ret = -1; - BIO * in = NULL; - int count=0; - X509 * x = NULL; - - if (file == NULL) - return(1); - - in = BIO_new(BIO_s_file()); - - - if ((in == NULL) || (BIO_read_filename(in,file) <= 0)) - { - X509err(PRXYERR_F_PROXY_LOAD, PRXYERR_R_PROCESS_PROXY); - goto err; - } - - for (;;) - { - x = PEM_read_bio_X509(in,NULL, OPENSSL_PEM_CB(NULL,NULL)); - if (x == NULL) - { - if ((ERR_GET_REASON(ERR_peek_error()) == - PEM_R_NO_START_LINE) && (count > 0)) - { - ERR_clear_error(); - break; - } - else - { - X509err(PRXYERR_F_PROXY_LOAD, PRXYERR_R_PROCESS_PROXY); - goto err; - } - } - - if (count) { - (void)sk_X509_insert(cert_chain,x,sk_X509_num(cert_chain)); - - x = NULL; - } - - count++; - - if (x) - { - X509_free(x); - x = NULL; - } - } - ret = count; - -err: - if (x != NULL) - { - X509_free(x); - } - - if (in != NULL) - { - BIO_free(in); - } - return(ret); -} - - -/********************************************************************** -Function: proxy_genreq() - -Description: - generate certificate request for a proxy certificate. - This is based on using the current user certificate. - If the current user cert is NULL, we are asking fke the server - to fill this in, and give us a new cert. Used with k5cert. - -Parameters: - -Returns: -**********************************************************************/ - -int PRIVATE -proxy_genreq( - X509 * ucert, - X509_REQ ** reqp, - EVP_PKEY ** pkeyp, - int bits, - const char * newdn, - int (*callback)()) - -{ - RSA * rsa = NULL; - EVP_PKEY * pkey = NULL; - EVP_PKEY * upkey = NULL; - X509_NAME * name = NULL; - X509_REQ * req = NULL; - X509_NAME_ENTRY * ne = NULL; - int rbits; - - if (bits) - { - rbits = bits; - } - else if (ucert) - { - if ((upkey = X509_get_pubkey(ucert)) == NULL) - { - PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_PROXY_KEY); - goto err; - } - - if (upkey->type != EVP_PKEY_RSA) - { - PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_PROXY_KEY); - goto err; - } - - rbits = 8 * EVP_PKEY_size(upkey); - EVP_PKEY_free(upkey); - } - else - { - rbits = 512; - } - - if ((pkey = EVP_PKEY_new()) == NULL) - { - PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_PROXY_KEY); - goto err; - } - - /* - * Note: The cast of the callback function is consistent with - * the declaration of RSA_generate_key() in OpenSSL. It may - * trigger a warning if you compile with SSLeay. - */ - if ((rsa = RSA_generate_key(rbits, - RSA_F4, - (void (*)(int,int,void *))callback - ,NULL)) == NULL) - { - PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_PROXY_KEY); - goto err; - } - - if (!EVP_PKEY_assign_RSA(pkey,rsa)) - { - PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_PROXY_KEY); - goto err; - } - - if ((req = X509_REQ_new()) == NULL) - { - PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_REQ); - goto err; - } - - X509_REQ_set_version(req,0L); - - if (!newdn) { - if (ucert) { - - if ((name = X509_NAME_dup(X509_get_subject_name(ucert))) == NULL) { - PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_REQ); - goto err; - } - } - else { - name = X509_NAME_new(); - } - - - if ((ne = X509_NAME_ENTRY_create_by_NID(NULL,NID_commonName, - V_ASN1_APP_CHOOSE, - (unsigned char *)"proxy", - -1)) == NULL) { - PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_REQ); - goto err; - } - X509_NAME_add_entry(name, - ne, - X509_NAME_entry_count(name), - fix_add_entry_asn1_set_param); - } - else { - name = make_DN(newdn); - if (!name) { - PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_REQ); - goto err; - } - } - - X509_REQ_set_subject_name(req,name); - X509_NAME_free(name); - name = NULL; - X509_REQ_set_pubkey(req,pkey); - - if (!X509_REQ_sign(req,pkey,EVP_sha1())) - { - PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_SIGN); - goto err; - } - - if (ne) - { - X509_NAME_ENTRY_free(ne); - ne = NULL; - } - - *pkeyp = pkey; - *reqp = req; - return 0; - -err: - if (upkey) - EVP_PKEY_free(upkey); - - if(rsa) - { - RSA_free(rsa); - } - if (pkey) - { - EVP_PKEY_free(pkey); - } - if (name) - { - X509_NAME_free(name); - } - if (req) - { - X509_REQ_free(req); - } - if (ne) - { - X509_NAME_ENTRY_free(ne); - } - return 1; -} - - -/** - * Sign a certificate request - * - * This function is a wrapper function for proxy_sign_ext. The subject - * name of the resulting certificate is generated by adding either - * cn=proxy or cn=limited proxy to the subject name of user_cert. The - * issuer name is set to the subject name of user_cert. - * - * @param user_cert - * A certificate to be used for subject and issuer name - * information if that information isn't provided. - * @param user_private_key - * The private key to be used for signing the certificate - * request. - * @param req - * The certificate request - * @param new_cert - * This parameter will contain the signed certficate upon - * success. - * @param seconds - * The number of seconds the new cert is going to be - * valid. The validity should not exceed that of the issuing - * key pair. If this parameter is 0 the generated cert will - * have the same lifetime as the issuing key pair. - * @param extensions - * Extensions to be placed in the new certificate. - * @param limited_proxy - * If this value is non zero the resulting cert will be a - * limited proxy. - * - * @return - * This functions returns 0 upon success, 1 upon failure. It - * will also place a more detailed error on an error stack. - */ - -int PRIVATE -proxy_sign( - X509 * user_cert, - EVP_PKEY * user_private_key, - X509_REQ * req, - X509 ** new_cert, - int seconds, - STACK_OF(X509_EXTENSION) * extensions, - int limited_proxy, - int proxyver, - const char * newdn, - const char * newissuer, - int pastproxy, - const char * newserial, - int selfsigned -) -{ - char * newcn; - EVP_PKEY * user_public_key; - X509_NAME * subject_name = NULL; - X509_NAME * issuer_name = NULL; - int rc = 0; - - unsigned char md[SHA_DIGEST_LENGTH]; - unsigned int len; - - - if(proxyver>=3) { - long sub_hash; - - user_public_key = X509_get_pubkey(user_cert); -#ifdef TYPEDEF_I2D_OF - ASN1_digest((i2d_of_void*)i2d_PUBKEY, EVP_sha1(), (char *) user_public_key, md, &len); -#else - ASN1_digest(i2d_PUBKEY, EVP_sha1(), (char *) user_public_key, md, &len); -#endif - EVP_PKEY_free(user_public_key); - - sub_hash = md[0] + (md[1] + (md[2] + (md[3] >> 1) * 256) * 256) * 256; - - newcn = snprintf_wrap("%ld", sub_hash); - } - else { - if(limited_proxy) - newcn = "limited proxy"; - else - newcn = "proxy"; - } - - if (newdn == NULL) { - if(proxy_construct_name( - user_cert, - &subject_name, - newcn, -1)) { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_PROCESS_SIGN); - if (proxyver >= 3) - free(newcn); - return 1; - } - } - else - subject_name = make_DN(newdn); - - if (newissuer) - issuer_name = make_DN(newissuer); - else - issuer_name = NULL; - - if(proxy_sign_ext(user_cert, - user_private_key, - EVP_sha1(), - req, - new_cert, - subject_name, - issuer_name, - seconds, - extensions, - proxyver, - pastproxy, - newserial, - selfsigned)) - { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_PROCESS_SIGN); - rc = 1; - } - - X509_NAME_free(subject_name); - - if (issuer_name) - X509_NAME_free(issuer_name); - - if (proxyver >= 3) - free(newcn); - - return rc; -} - -/** - * Sign a certificate request - * - * This function signs the given certificate request. Before signing - * the certificate the certificate's subject and issuer names may be - * replaced and extensions may be added to the certificate. - * - * @param user_cert - * A certificate to be used for lifetime and serial number - * information if that information isn't provided. - * @param user_private_key - * The private key to be used for signing the certificate - * request. - * @param method - * The method to employ for signing - * @param req - * The certificate request - * @param new_cert - * This parameter will contain the signed certficate upon - * success. - * @param subject_name - * The subject name to be used for the new certificate. If no - * subject name is provided the subject name in the certificate - * request will remain untouched. - * @param issuer_name - * The issuer name to be used for the new certificate. If no - * issuer name is provided the issuer name will be set to the - * subject name of the user cert. - * @param seconds - * The number of seconds the new cert is going to be - * valid. The validity should not exceed that of the issuing - * key pair. If this parameter is 0 the generated cert will - * have the same lifetime as the issuing key pair. - * @param serial_num - * The serial number to be used for the new cert. If this - * parameter is 0 the serial number of the user_cert is used. - * @param extensions - * Extensions to be placed in the new certificate. - * - * @return - * This functions returns 0 upon success, 1 upon failure. It - * will also place a more detailed error on an error stack. - */ - -int PRIVATE -proxy_sign_ext( - X509 * user_cert, - EVP_PKEY * user_private_key, - const EVP_MD * method, - X509_REQ * req, - X509 ** new_cert, - X509_NAME * subject_name, - X509_NAME * issuer_name, - int seconds, - STACK_OF(X509_EXTENSION) *extensions, - int proxyver, - int pastproxy, - const char *newserial, - int selfsigned) -{ - EVP_PKEY * new_public_key = NULL; - EVP_PKEY * tmp_public_key = NULL; - X509_CINF * new_cert_info; - X509_CINF * user_cert_info; - X509_EXTENSION * extension = NULL; - time_t time_diff, time_now, time_after; - ASN1_UTCTIME * asn1_time = NULL; - int i; - unsigned char md[SHA_DIGEST_LENGTH]; - unsigned int len; - - if (!selfsigned) - user_cert_info = user_cert->cert_info; - - *new_cert = NULL; - - if ((req->req_info == NULL) || - (req->req_info->pubkey == NULL) || - (req->req_info->pubkey->public_key == NULL) || - (req->req_info->pubkey->public_key->data == NULL)) - { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_MALFORM_REQ); - goto err; - } - - if ((new_public_key=X509_REQ_get_pubkey(req)) == NULL) { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_MALFORM_REQ); - goto err; - } - - i = X509_REQ_verify(req,new_public_key); - EVP_PKEY_free(new_public_key); - new_public_key = NULL; - - if (i < 0) - { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_SIG_VERIFY); - goto err; - } - - if (i == 0) - { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_SIG_BAD); - goto err; - } - - /* signature ok. */ - - if ((*new_cert = X509_new()) == NULL) - { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_PROXY); - goto err; - } - - new_cert_info = (*new_cert)->cert_info; - - /* set the subject name */ - - if(subject_name && !X509_set_subject_name(*new_cert,subject_name)) - { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_PROXY); - goto err; - } - - /* DEE? will use same serial number, this may help - * with revocations, or may cause problems. - */ - - if (newserial) { - BIGNUM *bn = NULL; - if (BN_hex2bn(&bn, newserial) != 0) { - ASN1_INTEGER *a_int = BN_to_ASN1_INTEGER(bn, NULL); - ASN1_INTEGER_free((*new_cert)->cert_info->serialNumber); - - /* Note: The a_int == NULL case is handled below. */ - (*new_cert)->cert_info->serialNumber = a_int; - BN_free(bn); - } - } - else if (proxyver > 2) { - ASN1_INTEGER_free(X509_get_serialNumber(*new_cert)); - - new_public_key = X509_REQ_get_pubkey(req); -#ifdef TYPEDEF_I2D_OF - ASN1_digest((i2d_of_void*)i2d_PUBKEY, EVP_sha1(), (char *) new_public_key, md, &len); -#else - ASN1_digest(i2d_PUBKEY, EVP_sha1(), (char *) new_public_key, md, &len); -#endif - EVP_PKEY_free(new_public_key); - new_public_key = NULL; - - (*new_cert)->cert_info->serialNumber = ASN1_INTEGER_new(); - (*new_cert)->cert_info->serialNumber->length = len; - (*new_cert)->cert_info->serialNumber->data = malloc(len); - - if (!((*new_cert)->cert_info->serialNumber->data)) { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT, PRXYERR_R_PROCESS_PROXY); - goto err; - } - memcpy((*new_cert)->cert_info->serialNumber->data, md, SHA_DIGEST_LENGTH); - } - else if (selfsigned) { - ASN1_INTEGER *copy = ASN1_INTEGER_new(); - if (copy) { - ASN1_INTEGER_set(copy, 1); - ASN1_INTEGER_free((*new_cert)->cert_info->serialNumber); - - (*new_cert)->cert_info->serialNumber = copy; - } - else - goto err; - } - else { - ASN1_INTEGER *copy = ASN1_INTEGER_dup(X509_get_serialNumber(user_cert)); - ASN1_INTEGER_free((*new_cert)->cert_info->serialNumber); - - /* Note: The copy == NULL case is handled immediately below. */ - (*new_cert)->cert_info->serialNumber = copy; - } - - if (!(*new_cert)->cert_info->serialNumber) { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_PROXY); - goto err; - } - - - /* set the issuer name */ - - if (issuer_name) - { - if(!X509_set_issuer_name(*new_cert,issuer_name)) - { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_PROXY); - goto err; - } - } - else - { - if(!X509_set_issuer_name(*new_cert,X509_get_subject_name(user_cert))) - { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_PROXY); - goto err; - } - } - - /* Allow for a five minute clock skew here. */ - - X509_gmtime_adj(X509_get_notBefore(*new_cert),-5*60 -pastproxy); - - /* DEE? should accept an seconds parameter, and set to min of - * hours or the ucert notAfter - * for now use seconds if not zero. - */ - - if (selfsigned) { - X509_gmtime_adj(X509_get_notAfter(*new_cert),(long) seconds - pastproxy); - } - else { - /* doesn't create a proxy longer than the user cert */ - asn1_time = ASN1_UTCTIME_new(); - X509_gmtime_adj(asn1_time, -pastproxy); - time_now = ASN1_UTCTIME_mktime(asn1_time); - ASN1_UTCTIME_free(asn1_time); - time_after = ASN1_UTCTIME_mktime(X509_get_notAfter(user_cert)); - time_diff = time_after - time_now; - - if(time_diff > (seconds - pastproxy)) { - X509_gmtime_adj(X509_get_notAfter(*new_cert),(long) seconds - pastproxy); - } - else { - X509_set_notAfter(*new_cert, user_cert_info->validity->notAfter); - } - } - - /* transfer the public key from req to new cert */ - /* DEE? should this be a dup? */ - - X509_PUBKEY_free(new_cert_info->key); - new_cert_info->key = req->req_info->pubkey; - req->req_info->pubkey = NULL; - - /* - * We can now add additional extentions here - * such as to control the usage of the cert - */ - - if (new_cert_info->version == NULL) - { - if ((new_cert_info->version = ASN1_INTEGER_new()) == NULL) - { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_PROXY); - goto err; - } - } - - ASN1_INTEGER_set(new_cert_info->version,2); /* version 3 certificate */ - - /* Free the current entries if any, there should not - * be any I belive - */ - - if (new_cert_info->extensions != NULL) - { - sk_X509_EXTENSION_pop_free(new_cert_info->extensions, - X509_EXTENSION_free); - } - - /* Add extensions provided by the client */ - - if (extensions) - { - if ((new_cert_info->extensions = - sk_X509_EXTENSION_new_null()) == NULL) - { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_DELEGATE_COPY); - } - - /* Lets 'copy' the client extensions to the new proxy */ - /* we should look at the type, and only copy some */ - - for (i=0; iextensions, - extension)) - { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_DELEGATE_COPY); - goto err; - } - } - } - - /* new cert is built, now sign it */ - -#ifndef NO_DSA - /* DEE? not sure what this is doing, I think - * it is adding from the key to be used to sign to the - * new certificate any info DSA may need - */ - - tmp_public_key = X509_get_pubkey(*new_cert); - - if (EVP_PKEY_missing_parameters(tmp_public_key) && - !EVP_PKEY_missing_parameters(user_private_key)) - { - EVP_PKEY_copy_parameters(tmp_public_key,user_private_key); - } -#endif - - EVP_PKEY_free(tmp_public_key); - - if (!X509_sign(*new_cert,user_private_key,method)) - { - PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_SIGNC); - goto err; - } - - return 0; - -err: - /* free new_cert upon error */ - - if (*new_cert) - { - X509_free(*new_cert); - } - - if (new_public_key) - EVP_PKEY_free(new_public_key); - - return 1; -} - - - - -/** - * Construct a X509 name - * - * This function constructs a X509 name by taking the subject name of - * the certificate and adding a new CommonName field with value newcn - * (if this parameter is non NULL). The resulting name should be freed - * using X509_NAME_free. - * - * @param cert - * The certificate to extract the subject name from. - * @param name - * The resulting name - * @param newcn - * The value of the CommonName field to add. If this value is - * NULL this function just returns a copy of the subject name - * of the certificate. - * - * @return - * This functions returns 0 upon success, 1 upon failure. It - * will also place a more detailed error on an error stack. - */ - -int PRIVATE -proxy_construct_name( - X509 * cert, - X509_NAME ** name, - char * newcn, - unsigned int len) -{ - X509_NAME_ENTRY * name_entry = NULL; - *name = NULL; - - if ((*name = X509_NAME_dup(X509_get_subject_name(cert))) == NULL) - { - PRXYerr(PRXYERR_F_PROXY_CONSTRUCT_NAME,PRXYERR_R_PROCESS_PROXY); - goto err; - } - - if(newcn) - { - if ((name_entry = X509_NAME_ENTRY_create_by_NID(NULL, - NID_commonName, - V_ASN1_APP_CHOOSE, - (unsigned char *)newcn, - len)) == NULL) - { - PRXYerr(PRXYERR_F_PROXY_CONSTRUCT_NAME,PRXYERR_R_PROCESS_PROXY); - goto err; - } - - if (!X509_NAME_add_entry(*name, - name_entry, - X509_NAME_entry_count(*name), - fix_add_entry_asn1_set_param)) - { - PRXYerr(PRXYERR_F_PROXY_CONSTRUCT_NAME,PRXYERR_R_PROCESS_PROXY); - goto err; - } - X509_NAME_ENTRY_free(name_entry); - } - - return 0; - -err: - if (*name) - { - X509_NAME_free(*name); - } - - if (name_entry) - { - X509_NAME_ENTRY_free(name_entry); - } - - return 1; - -} - - - -/********************************************************************** -Function: proxy_marshal_bp() - -Description: - Write to a bio the proxy certificate, key, users certificate, - and any other certificates need to use the proxy. - -Parameters: - -Returns: -**********************************************************************/ -int PRIVATE -proxy_marshal_bp( - BIO * bp, - X509 * ncert, - EVP_PKEY * npkey, - X509 * ucert, - STACK_OF(X509) * cert_chain) -{ - X509 * cert; - - if (!PEM_write_bio_X509(bp,ncert)) - { - return 1; - } - - if (!PEM_write_bio_RSAPrivateKey(bp, - npkey->pkey.rsa, - NULL, - NULL, - 0, - OPENSSL_PEM_CB(NULL,NULL))) - { - return 2; - } - - if (ucert) - { - if (!PEM_write_bio_X509(bp,ucert)) - { - return 3; - } - } - - if (cert_chain) - { - /* - * add additional certs, but not our cert, or the - * proxy cert, or any self signed certs - */ - int i; - - for(i=0; i < sk_X509_num(cert_chain); i++) - { - cert = sk_X509_value(cert_chain,i); - if (!(!X509_NAME_cmp_no_set(X509_get_subject_name(cert), - X509_get_subject_name(ncert)) - || (ucert && - !X509_NAME_cmp_no_set(X509_get_subject_name(cert), - X509_get_subject_name(ucert))) - || !X509_NAME_cmp_no_set(X509_get_subject_name(cert), - X509_get_issuer_name(cert)))) - { - if (!PEM_write_bio_X509(bp,cert)) - { - return 4; - } - } - } - } - - return 0; -} - -/********************************************************************** -Function: proxy_verify_init() - -Description: - -Parameters: - -Returns: -**********************************************************************/ - -void -proxy_verify_init( - proxy_verify_desc * pvd, - proxy_verify_ctx_desc * pvxd) -{ - - pvd->magicnum = PVD_MAGIC_NUMBER; /* used for debuging */ - pvd->flags = 0; - pvd->previous = NULL; - pvd->pvxd = pvxd; - pvd->proxy_depth = 0; - pvd->cert_depth = 0; - pvd->cert_chain = NULL; - pvd->limited_proxy = 0; - pvd->multiple_limited_proxy_ok = 0; -} - -/********************************************************************** -Function: proxy_verify_ctx_init() - -Description: - -Parameters: - -Returns: -**********************************************************************/ - -void -proxy_verify_ctx_init( - proxy_verify_ctx_desc * pvxd) -{ - - pvxd->magicnum = PVXD_MAGIC_NUMBER; /* used for debuging */ - pvxd->certdir = NULL; - pvxd->goodtill = 0; - -} -/********************************************************************** -Function: proxy_verify_release() - -Description: - -Parameters: - -Returns: -**********************************************************************/ - -void -proxy_verify_release( - proxy_verify_desc * pvd) -{ - pvd->cert_chain = NULL; - pvd->pvxd = NULL; -} - -/********************************************************************** -Function: proxy_verify_ctx_release() - -Description: - -Parameters: - -Returns: -**********************************************************************/ - -void -proxy_verify_ctx_release( - proxy_verify_ctx_desc * pvxd) -{ - if (pvxd->certdir) - { - free(pvxd->certdir); - pvxd->certdir = NULL; - } -} - -#if SSLEAY_VERSION_NUMBER >= 0x0090600fL -/********************************************************************** -Function: proxy_app_verify_callback() - -Description: - SSL callback which lets us do the x509_verify_cert - ourself. We use this to set the ctx->check_issued routine - so we can override some of the tests if needed. - -Parameters: - -Returns: - Same as X509_verify_cert -**********************************************************************/ - -int -proxy_app_verify_callback(X509_STORE_CTX *ctx, UNUSED(void *empty)) -{ - /* - * OpenSSL-0.9.6 has a check_issued routine which - * we want to override so we can replace some of the checks. - */ - - ctx->check_issued = proxy_check_issued; - return X509_verify_cert(ctx); -} -#endif - -/* Ifdef out all extra code not needed for k5cert - * This includes the OLDGAA - */ - -#ifndef BUILD_FOR_K5CERT_ONLY -/********************************************************************** -Function: proxy_check_proxy_name() - -Description: - Check if the subject name is a proxy, and the issuer name - is the same as the subject name, but without the proxy - entry. - i.e. inforce the proxy signing requirement of - only a user or a user's proxy can sign a proxy. - Also pass back Rif this is a limited proxy. - -Parameters: - -Returns: - -1 if there was an error - 0 if not a proxy - 1 if a proxy - 2 if a limited proxy - -*********************************************************************/ - -int proxy_check_proxy_name( - X509 * cert) -{ - int ret = 0; - X509_NAME * subject; - X509_NAME * name = NULL; - X509_NAME_ENTRY * ne = NULL; - ASN1_STRING * data; - int nidv3, nidv4 = 0; - int indexv3 = -1, indexv4 = -1; - - nidv3 = my_txt2nid(PROXYCERTINFO_V3); - nidv4 = my_txt2nid(PROXYCERTINFO_V4); - - if (nidv3 == 0 || nidv4 == 0) - ERR_clear_error(); - - indexv3 = X509_get_ext_by_NID(cert, nidv3, -1); - indexv4 = X509_get_ext_by_NID(cert, nidv4, -1); - - if (indexv3 != -1 || indexv4 != -1) { - /* Its a proxy! */ - X509_EXTENSION *ext = X509_get_ext(cert, (indexv3 == -1 ? indexv4 : indexv3)); - - if (ext) { - myPROXYCERTINFO *certinfo = NULL; - - certinfo = (myPROXYCERTINFO *)X509V3_EXT_d2i(ext); - - if (certinfo) { - myPROXYPOLICY *policy = myPROXYCERTINFO_get_proxypolicy(certinfo); - - if (policy) { -/* ASN1_OBJECT *policylang; */ -/* policylang = myPROXYPOLICY_get_policy_language(policy); */ - - /* TO DO: discover exact type of proxy. */ - - } - myPROXYCERTINFO_free(certinfo); - } -#if OPENSSL_VERSION_NUMBER >= 0x00908010 -#ifdef EXFLAG_PROXY - cert->ex_flags |= EXFLAG_PROXY; -#endif -#endif - return 1; - } - } - subject = X509_get_subject_name(cert); - ne = X509_NAME_get_entry(subject, X509_NAME_entry_count(subject)-1); - - if (!OBJ_cmp(ne->object,OBJ_nid2obj(NID_commonName))) - { - data = X509_NAME_ENTRY_get_data(ne); - if ((data->length == 5 && - !memcmp(data->data,"proxy",5)) || - (data->length == 13 && - !memcmp(data->data,"limited proxy",13))) - { - - if (data->length == 13) - { - ret = 2; /* its a limited proxy */ - } - else - { - ret = 1; /* its a proxy */ - } - /* - * Lets dup the issuer, and add the CN=proxy. This should - * match the subject. i.e. proxy can only be signed by - * the owner. We do it this way, to double check - * all the ANS1 bits as well. - */ - - /* DEE? needs some more err processing here */ - - name = X509_NAME_dup(X509_get_issuer_name(cert)); - ne = X509_NAME_ENTRY_create_by_NID(NULL, - NID_commonName, - V_ASN1_APP_CHOOSE, - (ret == 2) ? - (unsigned char *) - "limited proxy" : - (unsigned char *)"proxy", - -1); - - X509_NAME_add_entry(name,ne,X509_NAME_entry_count(name),0); - X509_NAME_ENTRY_free(ne); - ne = NULL; - - if (X509_NAME_cmp_no_set(name,subject)) - { - /* - * Reject this certificate, only the user - * may sign the proxy - */ - ret = -1; - } - X509_NAME_free(name); - } - } - -#if OPENSSL_VERSION_NUMBER >= 0x00908010 -#ifdef EXFLAG_PROXY - if (ret > 0) { - cert->ex_flags |= EXFLAG_PROXY; - if (ret == 1) - cert->ex_pcpathlen = -1; /* unlimited */ - else if (ret == 2) - cert->ex_pcpathlen = 0; /* Only at top level if limited */ - } -#endif -#endif - - return ret; -} - -#if SSLEAY_VERSION_NUMBER >= 0x0090600fL -/********************************************************************** - Function: proxy_check_issued() - -Description: - Replace the OpenSSL check_issued in x509_vfy.c with our own, - so we can override the key usage checks if its a proxy. - We are only looking for X509_V_ERR_KEYUSAGE_NO_CERTSIGN - -Parameters:r - See OpenSSL check_issued - -Returns: - See OpenSSL check_issued - -**********************************************************************/ - -int PRIVATE -proxy_check_issued( - UNUSED(X509_STORE_CTX * ctx), - X509 * x, - X509 * issuer) -{ - int ret; - int ret_code = 1; - - ret = X509_check_issued(issuer, x); - if (ret != X509_V_OK) - { - ret_code = 0; - switch (ret) - { - case X509_V_ERR_AKID_SKID_MISMATCH: - /* - * If the proxy was created with a previous version of Globus - * where the extensions where copied from the user certificate - * This error could arise, as the akid will be the wrong key - * So if its a proxy, we will ignore this error. - * We should remove this in 12/2001 - * At which time we may want to add the akid extension to the proxy. - */ - - case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: - /* - * If this is a proxy certificate then the issuer - * does not need to have the key_usage set. - * So check if its a proxy, and ignore - * the error if so. - */ - if (proxy_check_proxy_name(x) >= 1) - { - ret_code = 1; - } - break; - default: - break; - } - } - return ret_code; -} -#endif - -/********************************************************************** -Function: proxy_verify_callback() - -Description: - verify callback for SSL. Used to check that proxy - certificates are only signed by the correct user, - and used for debuging. - - Also on the server side, the s3_srvr.c code does not appear - to save the peer cert_chain, like the client side does. - We need these for additional proxies, so we need to - copy the X509 to our own stack. - -Parameters: - ok 1 then we are given one last chance to check - this certificate. - 0 then this certificate has failed, and ctx->error has the - reason. We may want to override the failure. - ctx the X509_STORE_CTX which has as a user arg, our - proxy verify desc. - -Returns: - 1 - Passed the tests - 0 - failed. The x509_vfy.c will return a failed to caller. -**********************************************************************/ - -int -proxy_verify_callback( - int ok, - X509_STORE_CTX * ctx) -{ - X509_OBJECT obj; - X509 * cert = NULL; -#ifdef X509_V_ERR_CERT_REVOKED - X509_CRL * crl; - X509_CRL_INFO * crl_info; - X509_REVOKED * revoked; -#endif - SSL * ssl = NULL; - proxy_verify_desc * pvd; - int itsaproxy = 0; - int i; - int ret; - time_t goodtill; - char * ca_policy_file_path = NULL; - char * cert_dir = NULL; - EVP_PKEY *key = NULL; - int objset = 0; - - /* - * If we are being called recursivly to check delegate - * cert chains, or being called by the grid-proxy-init, - * a pointer to a proxy_verify_desc will be - * pased in the store. If we are being called by SSL, - * by a roundabout process, the app_data of the ctx points at - * the SSL. We have saved a pointer to the context handle - * in the SSL, and its magic number should be PVD_MAGIC_NUMBER - */ - if (!(pvd = (proxy_verify_desc *) - X509_STORE_CTX_get_ex_data(ctx, - PVD_STORE_EX_DATA_IDX))) - { - ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx); - if (ssl) - pvd = (proxy_verify_desc *)SSL_get_ex_data(ssl, - PVD_SSL_EX_DATA_IDX); - } - - /* - * For now we hardcode the ex_data. We could look at all - * ex_data to find ours. - * Double check that we are indeed pointing at the context - * handle. If not, we have an internal error, SSL may have changed - * how the callback and app_data are handled - */ - - if (pvd) { - if(pvd->magicnum != PVD_MAGIC_NUMBER) { - PRXYerr(PRXYERR_F_VERIFY_CB, PRXYERR_R_BAD_MAGIC); - return(0); - } - } - - /* - * We now check for some error conditions which - * can be disregarded. - */ - - if (!ok) - { - switch (ctx->error) - { -#if SSLEAY_VERSION_NUMBER >= 0x0090581fL - case X509_V_ERR_PATH_LENGTH_EXCEEDED: - /* - * Since OpenSSL does not know about proxies, - * it will count them against the path length - * So we will ignore the errors and do our - * own checks later on, when we check the last - * certificate in the chain we will check the chain. - */ - ok = 1; - break; - -#endif - -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: - /* - * OpenSSL 1.0 causes the cert to be added twice to - * the store. - */ - if (proxy_check_proxy_name(ctx->cert) && - !X509_cmp(ctx->cert, ctx->current_cert)) - ok = 1; - break; -#endif - - case X509_V_ERR_INVALID_CA: - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - /* - * This may happen since proxy issuers are not CAs - */ - if (proxy_check_proxy_name(ctx->cert) >= 1) { - if (proxy_check_issued(ctx, ctx->cert, ctx->current_cert)) { - ok = 1; - } - } - break; - - case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: - if (proxy_check_proxy_name(ctx->cert) >= 1) { - if (check_critical_extensions(ctx->cert, 1)) - /* Allows proxy specific extensions on proxies. */ - ok = 1; - } - break; - - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: - case X509_V_ERR_CERT_UNTRUSTED: - if (proxy_check_proxy_name(ctx->current_cert) > 0) { - /* Server side, needed to fully recognize a proxy. */ - ok = 1; - } - break; - -#ifdef X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED - case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: - /* Proxies ARE allowed */ - ok = 1; - break; -#endif - - default: - break; - } - /* if already failed, skip the rest, but add error messages */ - if (!ok) - { - if (ctx->error==X509_V_ERR_CERT_NOT_YET_VALID) - { - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CERT_NOT_YET_VALID); - ERR_set_continue_needed(); - } - else if (ctx->error==X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY) - { - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_LOCAL_CA_UNKNOWN); - ERR_set_continue_needed(); - } - else if (ctx->error==X509_V_ERR_CERT_HAS_EXPIRED) - { - PRXYerr(PRXYERR_F_VERIFY_CB, PRXYERR_R_REMOTE_CRED_EXPIRED); - ERR_set_continue_needed(); - } - - goto fail_verify; - } - ctx->error = 0; - return(ok); - } - - /* Note: OpenSSL will try to verify the client's chain on the client side - before sending it abroad. However, to properly verify proxy conditions, - we need access to pvd, which is not passed. For this reason, in this - scenario we assume that if the checks above passed, everything is ok. If - it is not, it will be discovered during server-side validation of the cert. - */ - if (!pvd) - return ok; - - /* - * All of the OpenSSL tests have passed and we now get to - * look at the certificate to verify the proxy rules, - * and ca-signing-policy rules. We will also do a CRL check - */ - - /* - * Test if the name ends in CN=proxy and if the issuer - * name matches the subject without the final proxy. - */ - - ret = proxy_check_proxy_name(ctx->current_cert); - if (ret < 0) - { - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_BAD_PROXY_ISSUER); - ERR_set_continue_needed(); - ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE; - goto fail_verify; - } - if (ret > 0) - { /* Its a proxy */ - if (ret == 2) - { - /* - * If its a limited proxy, it means it use has been limited - * during delegation. It can not sign other certs i.e. - * it must be the top cert in the chain. - * Depending on who we are, - * We may want to accept this for authentication. - * - * Globus gatekeeper -- don't accept - * sslk5d accept, but should check if from local site. - * globus user-to-user Yes, thats the purpose - * of this cert. - * - * We will set the limited_proxy flag, to show we found - * one. A Caller can then reject. - */ - - pvd->limited_proxy = 1; /* its a limited proxy */ - - if (ctx->error_depth && !pvd->multiple_limited_proxy_ok) { - /* tried to sign a cert with a limited proxy */ - /* i.e. there is still another cert on the chain */ - /* indicating we are trying to sign it! */ - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_LPROXY_MISSED_USED); - ERR_set_continue_needed(); - ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE; - goto fail_verify; - } - } - - pvd->proxy_depth++; - itsaproxy = 1; - } - - if (!itsaproxy) - { - -#ifdef X509_V_ERR_CERT_REVOKED - int n = 0; - /* - * SSLeay 0.9.0 handles CRLs but does not check them. - * We will check the crl for this cert, if there - * is a CRL in the store. - * If we find the crl is not valid, we will fail, - * as once the sysadmin indicates that CRLs are to - * be checked, he best keep it upto date. - * - * When future versions of SSLeay support this better, - * we can remove these tests. - * we come through this code for each certificate, - * starting with the CA's We will check for a CRL - * each time, but only check the signature if the - * subject name matches, and check for revoked - * if the issuer name matches. - * this allows the CA to revoke its own cert as well. - */ - - if (X509_STORE_get_by_subject(ctx, - X509_LU_CRL, - X509_get_subject_name(ctx->current_issuer), - &obj)) - { - objset = 1; - crl = obj.data.crl; - crl_info = crl->crl; - /* verify the signature on this CRL */ - - key = X509_get_pubkey(ctx->current_issuer); - if (X509_CRL_verify(crl, key) <= 0) - { - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CRL_SIGNATURE_FAILURE); - ERR_set_continue_needed(); - ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE; - goto fail_verify; - } - - /* Check date see if expired */ - - i = X509_cmp_current_time(crl_info->nextUpdate); - if (i == 0) - { - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CRL_NEXT_UPDATE_FIELD); - ERR_set_continue_needed(); - ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; - goto fail_verify; - } - - - if (i < 0) - { - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CRL_HAS_EXPIRED); - ERR_set_continue_needed(); - ctx->error = X509_V_ERR_CRL_HAS_EXPIRED; - goto fail_verify; - } - - /* check if this cert is revoked */ - - - n = sk_X509_REVOKED_num(crl_info->revoked); - for (i=0; irevoked,i); - - if(!ASN1_INTEGER_cmp(revoked->serialNumber, - X509_get_serialNumber(ctx->current_cert))) - { - long serial; - char buf[256]; - char *s; - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CERT_REVOKED); - serial = ASN1_INTEGER_get(revoked->serialNumber); - sprintf(buf,"%ld (0x%lX)",serial,serial); - s = X509_NAME_oneline(X509_get_subject_name( - ctx->current_cert),NULL,0); - - ERR_add_error_data(4,"Serial number = ",buf, - " Subject=",s); - - ctx->error = X509_V_ERR_CERT_REVOKED; - ERR_set_continue_needed(); - free(s); - s = NULL; - goto fail_verify; - } - } - } -#endif /* X509_V_ERR_CERT_REVOKED */ - - /* Do not need to check self signed certs against ca_policy_file */ - - if (X509_NAME_cmp(X509_get_subject_name(ctx->current_cert), - X509_get_issuer_name(ctx->current_cert))) - { - cert_dir = pvd->pvxd->certdir ? pvd->pvxd->certdir : - getenv(X509_CERT_DIR); - - { - char * error_string = NULL; - struct policy **signings = NULL; - struct policy **namespaces = NULL; - int result = SUCCESS_UNDECIDED; - - read_pathrestriction(ctx->chain, cert_dir, &namespaces, &signings); - - result = restriction_evaluate(ctx->chain, namespaces, signings); - - voms_free_policies(namespaces); - voms_free_policies(signings); - - if (result != SUCCESS_PERMIT) - { - PRXYerr(PRXYERR_F_VERIFY_CB, PRXYERR_R_CA_POLICY_VIOLATION); - - ctx->error = X509_V_ERR_INVALID_PURPOSE; - - if (error_string != NULL) - { - /* - * Seperate error message returned from policy check - * from above error message with colon - */ - - ERR_add_error_data(2, ": ", error_string); - free(error_string); - } - ERR_set_continue_needed(); - goto fail_verify; - } - else - { - if (error_string != NULL) - { - free(error_string); - } - } - } - } /* end of do not check self signed certs */ - } - - /* - * We want to determine the minimum amount of time - * any certificate in the chain is good till - * Will be used for lifetime calculations - */ - - goodtill = ASN1_UTCTIME_mktime(X509_get_notAfter(ctx->current_cert)); - if (pvd->pvxd->goodtill == 0 || goodtill < pvd->pvxd->goodtill) - { - pvd->pvxd->goodtill = goodtill; - } - - /* We need to make up a cert_chain if we are the server. - * The ssl code does not save this as I would expect. - * This is used to create a new proxy by delegation. - */ - - pvd->cert_depth++; - - if (ca_policy_file_path != NULL) - { - free(ca_policy_file_path); - } - - if (!check_critical_extensions(ctx->current_cert, itsaproxy)) { - PRXYerr(PRXYERR_F_VERIFY_CB, PRXYERR_R_UNKNOWN_CRIT_EXT); - ctx->error = X509_V_ERR_CERT_REJECTED; - goto fail_verify; - } - - /* - * We ignored any path length restrictions above because - * OpenSSL was counting proxies against the limit. - * If we are on the last cert in the chain, we - * know how many are proxies, so we can do the - * path length check now. - * See x509_vfy.c check_chain_purpose - * all we do is substract off the proxy_dpeth - */ - - if(ctx->current_cert == ctx->cert) - { - for (i=0; i < sk_X509_num(ctx->chain); i++) - { - cert = sk_X509_value(ctx->chain,i); - if (((i - pvd->proxy_depth) > 1) && (cert->ex_pathlen != -1) - && ((i - pvd->proxy_depth) > (cert->ex_pathlen + 1)) - && (cert->ex_flags & EXFLAG_BCONS)) - { - ctx->current_cert = cert; /* point at failing cert */ - ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; - goto fail_verify; - } - } - } - - EVP_PKEY_free(key); - - if (objset) - X509_OBJECT_free_contents(&obj); - - return(ok); - -fail_verify: - - if (key) - EVP_PKEY_free(key); - - if (objset) - X509_OBJECT_free_contents(&obj); - - if (ctx->current_cert) - { - char *subject_s = NULL; - char *issuer_s = NULL; - - subject_s = X509_NAME_oneline( - X509_get_subject_name(ctx->current_cert),NULL,0); - issuer_s = X509_NAME_oneline( - X509_get_issuer_name(ctx->current_cert),NULL,0); - - switch (ctx->error) - { - case X509_V_OK: - case X509_V_ERR_INVALID_PURPOSE: - case X509_V_ERR_APPLICATION_VERIFICATION: - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CB_ERROR_MSG); - ERR_add_error_data(6, - "\n File=", - ca_policy_file_path ? ca_policy_file_path : "UNKNOWN", - "\n subject=", - subject_s ? subject_s : "UNKNOWN", - "\n issuer =", - issuer_s ? issuer_s : "UNKNOWN"); - break; - case X509_V_ERR_CERT_NOT_YET_VALID: - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: - case X509_V_ERR_CERT_HAS_EXPIRED: - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CB_ERROR_MSG); - ERR_add_error_data(4, - "\n subject=", - subject_s ? subject_s : "UNKNOWN", - "\n issuer =", - issuer_s ? issuer_s : "UNKNOWN"); - break; - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CA_UNKNOWN); - ERR_add_error_data(2, "\n issuer =", - issuer_s ? issuer_s : "UNKNOWN"); - break; - - default: - PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CB_CALLED_WITH_ERROR); - ERR_add_error_data(6,"\n error =", - X509_verify_cert_error_string(ctx->error), - "\n subject=", - subject_s ? subject_s : "UNKNOWN", - "\n issuer =", - issuer_s ? issuer_s : "UNKNOWN"); - } - - free(subject_s); - free(issuer_s); - } - if (ca_policy_file_path != NULL) - { - free(ca_policy_file_path); - } - - return(0); - -} - -/********************************************************************** -Function: proxy_verify_cert_chain() - -Description: - -Parameters: - -Returns: -**********************************************************************/ - -int PRIVATE -proxy_verify_cert_chain( - X509 * ucert, - STACK_OF(X509) * cert_chain, - proxy_verify_desc * pvd) -{ - int retval = 0; - X509_STORE * cert_store = NULL; - X509_LOOKUP * lookup = NULL; - X509_STORE_CTX csc; - X509 * xcert = NULL; - X509 * scert = NULL; - int cscinitialized = 0; - - scert = ucert; - cert_store = X509_STORE_new(); - X509_STORE_set_verify_cb_func(cert_store, proxy_verify_callback); - if (cert_chain != NULL) - { - int i =0; - for (i=0;ipvxd->certdir,X509_FILETYPE_PEM); - X509_STORE_CTX_init(&csc,cert_store,scert,NULL); - cscinitialized = 1; -#if SSLEAY_VERSION_NUMBER >= 0x0090600fL - /* override the check_issued with our version */ - csc.check_issued = proxy_check_issued; -#endif - X509_STORE_CTX_set_ex_data(&csc, - PVD_STORE_EX_DATA_IDX, (void *)pvd); -#ifdef X509_V_FLAG_ALLOW_PROXY_CERTS - X509_STORE_CTX_set_flags(&csc, X509_V_FLAG_ALLOW_PROXY_CERTS); -#endif - if(!X509_verify_cert(&csc)) - { - goto err; - } - } - retval = 1; - -err: - if (cscinitialized) - X509_STORE_CTX_cleanup(&csc); - if (cert_store) - X509_STORE_free(cert_store); - return retval; -} -#endif /* NO_PROXY_VERIFY_CALLBACK */ - - -/********************************************************************** -Function: proxy_get_filenames() - -Description: - Gets the filenames for the various files used - to store the cert, key, cert_dir and proxy. - - - Environment variables to use: - X509_CERT_DIR Directory of trusted certificates - File names are hash values, see the SSLeay - c_hash script. - X509_CERT_FILE File of trusted certifiates - X509_USER_PROXY File with a proxy certificate, key, and - additional certificates to makeup a chain - of certificates used to sign the proxy. - X509_USER_CERT User long term certificate. - X509_USER_KEY private key for the long term certificate. - - All of these are assumed to be in PEM form. If there is a - X509_USER_PROXY, it will be searched first for the cert and key. - If not defined, but a file /tmp/x509up_u is - present, it will be used, otherwise the X509_USER_CERT - and X509_USER_KEY will be used to find the certificate - and key. If X509_USER_KEY is not defined, it will be assumed - that the key is is the same file as the certificate. - - If windows, look in the registry HKEY_CURRENT_USER for the - GSI_REGISTRY_DIR, then look for the x509_user_cert, etc. - - Then try $HOME/.globus/usercert.pem - and $HOME/.globus/userkey.pem - Unless it is being run as root, then look for - /etc/grid-security/hostcert.pem and /etc/grid-security/hostkey.pem - - X509_CERT_DIR and X509_CERT_FILE can point to world readable - shared director and file. One of these must be present. - if not use $HOME/.globus/certificates - or /etc/grid-security/certificates - or $GLOBUS_DEPLOY_PATH/share/certificates - or $GLOBUS_LOCATION/share/certificates - or $GSI_DEPLOY_PATH/share/certificates - or $GSI_INSTALL_PATH/share/certificates - - The file with the key must be owned by the user, - and readable only by the user. This could be the X509_USER_PROXY, - X509_USER_CERT or the X509_USER_KEY - - X509_USER_PROXY_FILE is used to generate the default - proxy file name. - - In other words: - - proxy_get_filenames() is used by grid-proxy-init, wgpi, grid-proxy-info and - Indirectly by gss_acquire_creds. For grid-proxy-init and wgpi, the proxy_in - is 0, for acquire_creds its 1. This is used to signal how the proxy file is - to be used, 1 for input 0 for output. - - The logic for output is to use the provided input parameter, registry, - environment, or default name for the proxy. Wgpi calls this multiple times - as the options window is updated. The file will be created if needed. - - The logic for input is to use the provided input parameter, registry, - environment variable. But only use the default file if it exists, is owned - by the user, and has something in it. But not when run as root. - - Then on input if there is a proxy, the user_cert and user_key are set to - use the proxy. - - Smart card support using PKCS#11 is controled by the USE_PKCS11 flag. - - If the filename for the user key starts with SC: then it is assumed to be - of the form SC:card:label where card is the name of a smart card, and label - is the label of the key on the card. The card must be using Cryptoki - (PKCS#11) This code has been developed using the DataKey implementation - under Windows 95. - - This will allow the cert to have the same form, with the same label as well - in the future. - - - -Parameters: - -Returns: -**********************************************************************/ - -int -proxy_get_filenames( - int proxy_in, - char ** p_cert_file, - char ** p_cert_dir, - char ** p_user_proxy, - char ** p_user_cert, - char ** p_user_key) -{ - - int status = -1; - char * cert_file = NULL; - char * cert_dir = NULL; - char * user_proxy = NULL; - char * user_cert = NULL; - char * user_key = NULL; - char * home = NULL; - char * default_user_proxy = NULL; - char * default_user_cert = NULL; - char * default_user_key = NULL; - char * default_cert_dir = NULL; - char * installed_cert_dir = NULL; -#ifdef WIN32 - HKEY hkDir = NULL; - char val_user_cert[512]; - char val_user_key[512]; - char val_user_proxy[512]; - char val_cert_dir[512]; - char val_cert_file[512]; - LONG lval; - DWORD type; -#endif - -#ifdef WIN32 - RegOpenKey(HKEY_CURRENT_USER,GSI_REGISTRY_DIR,&hkDir); -#endif - - /* setup some default values */ - if (p_cert_dir) - { - cert_dir = *p_cert_dir; - } - - - if (!cert_dir) - { - cert_dir = (char *)getenv(X509_CERT_DIR); - } -#ifdef WIN32 - if (!cert_dir) - { - lval = sizeof(val_cert_dir)-1; - if (hkDir && (RegQueryValueEx(hkDir,"x509_cert_dir",0,&type, - val_cert_dir,&lval) == ERROR_SUCCESS)) - { - cert_dir = val_cert_dir; - } - } -#endif - if (p_cert_file) - { - cert_file = *p_cert_file; - } - - if (!cert_file) - { - cert_file = (char *)getenv(X509_CERT_FILE); - } -#ifdef WIN32 - if (!cert_file) - { - lval = sizeof(val_cert_file)-1; - if (hkDir && (RegQueryValueEx(hkDir,"x509_cert_file",0,&type, - val_cert_file,&lval) == ERROR_SUCCESS)) - { - cert_file = val_cert_file; - } - } -#endif - - if (cert_dir == NULL) - { - - /* - * If ~/.globus/certificates exists, then use that - */ - home = getenv("HOME"); -#ifndef WIN32 - /* Under windows use c:\windows as default home */ - if (!home) - { - home = "c:\\windows"; - } -#endif /* WIN32 */ - - if (home) - { - default_cert_dir = snprintf_wrap("%s%s%s", - home, FILE_SEPERATOR, X509_DEFAULT_CERT_DIR); - - if (!default_cert_dir) - { - PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); - goto err; - } - - if (checkstat(default_cert_dir) != 1) - { - /* default_cert_dir exists */ - cert_dir = default_cert_dir; - } - } - - - /* - * Now check for host based default directory - */ - if (!cert_dir) - { - - if (checkstat(X509_INSTALLED_HOST_CERT_DIR) != 1) - { - /* default_cert_dir exists */ - cert_dir = X509_INSTALLED_HOST_CERT_DIR; - } - } - - if (!cert_dir) - { - /* - * ...else look for (in order) - * $GLOBUS_DEPLOY_PATH/share/certificates - * $GLOBUS_LOCATION/share/certficates - */ - char *globus_location; - - - globus_location = getenv("GLOBUS_DEPLOY_PATH"); - - if (!globus_location) - { - globus_location = getenv("GLOBUS_LOCATION"); - } - - if (!globus_location) - { - globus_location = getenv("GSI_DEPLOY_PATH"); - } - - if (!globus_location) - { - globus_location = getenv("GSI_INSTALL_PATH"); - } - - if (globus_location) - { - installed_cert_dir = snprintf_wrap("%s%s%s", - globus_location, - FILE_SEPERATOR, - X509_INSTALLED_CERT_DIR); - - if (!installed_cert_dir) - { - PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); - goto err; - } - - /* - * Previous code always set cert_dir to - * default_cert_dir without checking for its - * existance, so we'll also skip the existance - * check here. - */ - cert_dir = installed_cert_dir; - } - } - - if (!cert_dir) - { - cert_dir = X509_INSTALLED_HOST_CERT_DIR; - } - } - - if (cert_dir) - { - if (checkstat(cert_dir) == 1) - { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERTS); - ERR_add_error_data(2,"x509_cert_dir=",cert_dir); - goto err; - } - } - - if (cert_file) - { - if (checkstat(cert_file) == 1) - { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERTS); - ERR_add_error_data(2,"x509_cert_file=",cert_file); - goto err; - } - } - /* if X509_USER_PROXY is defined, use it for cert and key, - * and for additional certs. - * if not, and the default user_proxy file is present, - * use it. - * If not, get the X509_USER_CERT and X509_USER_KEY - * if not, use ~/.globus/usercert.pem ~/.globus/userkey.pem - */ - if (p_user_proxy) - { - user_proxy = *p_user_proxy; - } - - if (!user_proxy) - { - user_proxy = (char *)getenv(X509_USER_PROXY); - } -#ifdef WIN32 - if (!user_proxy) - { - lval = sizeof(val_user_proxy)-1; - if (hkDir && (RegQueryValueEx(hkDir,"x509_user_proxy",0,&type, - val_user_proxy,&lval) == ERROR_SUCCESS)) - { - user_proxy = val_user_proxy; - } - } -#endif - if (!user_proxy && !getenv("X509_RUN_AS_SERVER")) - { - default_user_proxy = snprintf_wrap("%s%s%s%lu", - DEFAULT_SECURE_TMP_DIR, - FILE_SEPERATOR, - X509_USER_PROXY_FILE, - getuid()); - - if (!default_user_proxy) - { - PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); - goto err; - } - -#ifndef WIN32 - if ((!proxy_in || getuid() != 0) - && checkstat(default_user_proxy) == 0) -#endif - { - user_proxy = default_user_proxy; - } - } - if (proxy_in && user_proxy) - { - user_cert = user_proxy; - user_key = user_proxy; - } - else - { - if (!user_proxy && !proxy_in) - { - user_proxy = default_user_proxy; - } - - if (p_user_cert) - { - user_cert = *p_user_cert; - } - - if(!user_cert) - { - user_cert = (char *)getenv(X509_USER_CERT); - } - -#ifdef WIN32 - if (!user_cert) - { - lval = sizeof(val_user_cert)-1; - if (hkDir && (RegQueryValueEx( - hkDir, - "x509_user_cert", - 0, - &type, - val_user_cert,&lval) == ERROR_SUCCESS)) - { - user_cert = val_user_cert; - } - } -#endif - if (user_cert) - { - if (p_user_key) - { - user_key = *p_user_key; - } - if (!user_key) - { - user_key = (char *)getenv(X509_USER_KEY); - } -#ifdef WIN32 - if (!user_key) - { - lval = sizeof(val_user_key)-1; - if (hkDir && (RegQueryValueEx( - hkDir, - "x509_user_key", - 0, - &type, - val_user_key,&lval) == ERROR_SUCCESS)) - { - user_key = val_user_key; - } - } -#endif - if (!user_key) - { - user_key = user_cert; - } - } - else - { -#ifndef WIN32 - if (getuid() == 0) - { - if (checkstat(X509_DEFAULT_HOST_CERT) != 1) - { - user_cert = X509_DEFAULT_HOST_CERT; - } - if (checkstat(X509_DEFAULT_HOST_KEY) != 1) - { - user_key = X509_DEFAULT_HOST_KEY; - } - } - else -#endif - { - if (!home) - { - home = getenv("HOME"); - } - if (!home) - { -#ifndef WIN32 - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_NO_HOME); - goto err; -#else - home = "c:\\"; -#endif - } - - default_user_cert = snprintf_wrap("%s%s%s", - home, FILE_SEPERATOR, X509_DEFAULT_USER_CERT); - - if (!default_user_cert) - { - PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); - goto err; - } - - default_user_key = snprintf_wrap("%s%s%s", - home,FILE_SEPERATOR, X509_DEFAULT_USER_KEY); - - if (!default_user_key) - { - PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); - goto err; - } - - user_cert = default_user_cert; - user_key = default_user_key; - - /* Support for pkcs12 credentials. */ - { - int fd = open(default_user_cert, O_RDONLY); - if (fd >= 0) - close(fd); - else { - /* Cannot open normal file -- look for pkcs12. */ - char *certname = NULL; - - free(default_user_cert); - free(default_user_key); - - - certname = getenv("X509_USER_CRED"); - - if (!certname) { - default_user_cert = snprintf_wrap("%s%s%s", - home, FILE_SEPERATOR, X509_DEFAULT_USER_CERT_P12); - - if (!default_user_cert) { - PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); - goto err; - } - - if (checkstat(default_user_cert) != 0) { - free(default_user_cert); - default_user_cert = snprintf_wrap("%s%s%s", - home, FILE_SEPERATOR, X509_DEFAULT_USER_CERT_P12_GT); - } - - if (!default_user_cert) { - PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); - goto err; - } - - } - else - strcpy(default_user_cert, certname); - - default_user_key = strndup(default_user_cert, strlen(default_user_cert)); - - if (!default_user_key) { - PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); - goto err; - } - - user_cert = default_user_cert; - user_key = default_user_key; - } - } - } - } - } - - status = 0; -err: - if (!status) { - if (p_cert_file && cert_file && !(*p_cert_file)) { - *p_cert_file = strdup(cert_file); - } - if (p_cert_dir && cert_dir && !(*p_cert_dir)) { - *p_cert_dir = strdup(cert_dir); - } - if (p_user_proxy && user_proxy && !(*p_user_proxy)) { - *p_user_proxy = strdup(user_proxy); - } - if (p_user_cert && user_cert && !(*p_user_cert)) { - free(*p_user_cert); - *p_user_cert = strdup(user_cert); - } - if (p_user_key && user_key && !(*p_user_key)) { - free(*p_user_key); - *p_user_key = strdup(user_key); - } - } -#ifdef WIN32 - if (hkDir) - { - RegCloseKey(hkDir); - } -#endif - - free(default_user_proxy); - free(installed_cert_dir); - free(default_cert_dir); - free(default_user_cert); - free(default_user_key); - - return status; -} -/********************************************************************** -Function: proxy_load_user_cert() - -Description: - loads the users cert. May need a pw callback for Smartcard PIN. - May use a smartcard too. - -Parameters: - -Returns: -**********************************************************************/ - -static int cert_load_pkcs12(BIO *bio, int (*pw_cb)(), X509 **cert, EVP_PKEY **key, STACK_OF(X509) **chain) -{ - PKCS12 *p12 = NULL; - char *password = NULL; - char buffer[1024]; - int ret = 0; - - p12 = d2i_PKCS12_bio(bio, NULL); - if (!p12) - return 0; - - if (!PKCS12_verify_mac(p12, "", 0)) { - - int sz = 0; - - if (pw_cb) - sz = pw_cb(buffer, 1024, 0); - else - if (EVP_read_pw_string(buffer, 1024, EVP_get_pw_prompt(), 0) != -1) - sz = strlen(buffer); - - if (sz) - password = buffer; - else - goto err; - } - else - password=""; - - ret = PKCS12_parse(p12, password, key, cert, chain); - - err: - memset(buffer, 0, 1024); - - if (p12) - PKCS12_free(p12); - - return ret; -} - -int PRIVATE proxy_load_user_cert_and_key_pkcs12(const char *user_cert, - X509 **cert, - STACK_OF(X509) **stack, - EVP_PKEY **pkey, - int (*pw_cb) ()) -{ - BIO *bio = BIO_new_file(user_cert, "rb"); - int res = cert_load_pkcs12(bio, pw_cb, cert, pkey, stack); - BIO_free(bio); - - if (res) - return 1; - else { - if (ERR_peek_error() == ERR_PACK(ERR_LIB_PEM,PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE)) { - ERR_clear_error(); - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_INVALID_CERT); - } - else { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERT); - } - ERR_add_error_data(2, "\n File=", user_cert); - return 0; - } -} - - - -int PRIVATE -proxy_load_user_cert( - const char * user_cert, - X509 ** certificate, - UNUSED(int (*pw_cb)()), - UNUSED(unsigned long * hSession)) -{ - int status = -1; - FILE * fp; - - /* Check arguments */ - if (!user_cert) - { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_USER_NOCERT_FILE); - status = PRXYERR_R_PROBLEM_USER_NOCERT_FILE; - - ERR_add_error_data(1, "\n No certificate file found"); - goto err; - } - - if (!strncmp(user_cert,"SC:",3)) - { -#ifdef USE_PKCS11 - char * cp; - char * kp; - int rc; - - cp = user_cert + 3; - kp = strchr(cp,':'); - if (kp == NULL) - { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_USER_NOCERT_FILE); - ERR_add_error_data(2, "\n SmartCard reference=", - user_cert); - status = PRXYERR_R_PROBLEM_USER_NOCERT_FILE; - goto err; - } - - kp++; /* skip the : */ - - if (*hSession == 0) - { - rc = sc_init(hSession, cp, NULL, NULL, CKU_USER, 0); - - if (rc) - { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERT); - ERR_add_error_data( - 1, - "\n Failed to open session to smartcard"); - status = PRXYERR_R_PROCESS_CERT; - goto err; - } - } - rc = sc_get_cert_obj_by_label(*hSession,kp, - certificate); - if (rc) - { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERT); - ERR_add_error_data( - 2, - "\n Could not find certificate on smartcard, label=", - kp); - status = PRXYERR_R_PROCESS_CERT; - goto err; - } -#else - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERT); - ERR_add_error_data( - 1, - "\n Smartcard support not compiled with this program"); - status = PRXYERR_R_PROCESS_CERT; - goto err; - - /* - * DEE? need to add a random number routine here, to use - * the random number generator on the card - */ - -#endif /* USE_PKCS11 */ - } - else - { - if((fp = fopen(user_cert,"rb")) == NULL) { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_USER_NOCERT_FILE); - status = PRXYERR_R_PROBLEM_USER_NOCERT_FILE; - - ERR_add_error_data(2, "\n Cert File=", user_cert); - goto err; - } - - if (PEM_read_X509(fp, - certificate, - OPENSSL_PEM_CB(NULL,NULL)) == NULL) { - if (ERR_peek_error() == ERR_PACK(ERR_LIB_PEM,PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE)) { - ERR_clear_error(); - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_INVALID_CERT); - status = PRXYERR_R_INVALID_CERT; - } - else { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERT); - status = PRXYERR_R_PROCESS_CERT; - } - - ERR_add_error_data(2, "\n File=", user_cert); - fclose(fp); - goto err; - } - fclose(fp); - } - status = 0; - err: - - return status; -} - - -/********************************************************************** -Function: proxy_load_user_key() - -Description: - loads the users key. Assumes the cert has been loaded, - and checks they match. - May use a smartcard too. - -Parameters: - -Returns: - an int specifying the error -**********************************************************************/ - -int PRIVATE -proxy_load_user_key( - EVP_PKEY ** private_key, - X509 * ucert, - const char * user_key, - int (*pw_cb)(), - UNUSED(unsigned long * hSession)) -{ - int status = -1; - FILE * fp; - EVP_PKEY * ucertpkey; - int (*xpw_cb)(); - - if (!private_key) - return 0; - - xpw_cb = pw_cb; -#ifdef WIN32 - if (!xpw_cb) - { - xpw_cb = read_passphrase_win32; - } -#endif - - /* Check arguments */ - if (!user_key) - { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_USER_NOKEY_FILE); - status = PRXYERR_R_PROBLEM_USER_NOKEY_FILE; - - ERR_add_error_data(1,"\n No key file found"); - goto err; - } - - - if (!strncmp(user_key,"SC:",3)) - { -#ifdef USE_PKCS11 - char *cp; - char *kp; - int rc; - - cp = user_key + 3; - kp = strchr(cp,':'); - if (kp == NULL) - { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_KEY_FILE); - ERR_add_error_data(2,"\n SmartCard reference=",user_key); - status = PRXYERR_R_PROBLEM_KEY_FILE; - goto err; - } - kp++; /* skip the : */ - if (*hSession == 0) - { - rc = sc_init(hSession, cp, NULL, NULL, CKU_USER, 0); - if (rc) - { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_KEY); - ERR_add_error_data( - 1, - "\n Failed to open session to smartcard"); - status = PRXYERR_R_PROCESS_KEY; - goto err; - } - } - rc = sc_get_priv_key_obj_by_label(hSession,kp, - private_key); - if (rc) - { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_KEY); - ERR_add_error_data( - 2, - "\n Could not find key on smartcard, label=", - kp); - status = PRXYERR_R_PROCESS_KEY; - goto err; - } -#else - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_KEY); - ERR_add_error_data( - 1, - "\n Smartcard support not compiled with this program"); - status = PRXYERR_R_PROCESS_KEY; - goto err; - - /* - * DEE? could add a random number routine here, to use - * the random number generator on the card - */ - -#endif /* USE_PKCS11 */ - } - else - { - int keystatus; - - if ((fp = fopen(user_key,"rb")) == NULL) { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_USER_NOKEY_FILE); - status = PRXYERR_R_PROBLEM_USER_NOKEY_FILE; - - ERR_add_error_data(2, "\n File=",user_key); - goto err; - } - - /* user key must be owned by the user, and readable - * only be the user - */ - - if ((keystatus = checkstat(user_key))) { - if (keystatus == 4) { - status = PRXYERR_R_USER_ZERO_LENGTH_KEY_FILE; - PRXYerr(PRXYERR_F_INIT_CRED, - PRXYERR_R_USER_ZERO_LENGTH_KEY_FILE); - } - else { - status = PRXYERR_R_PROBLEM_KEY_FILE; - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_KEY_FILE); - } - - ERR_add_error_data(2, "\n File=", user_key); - fclose(fp); - goto err; - } - - if (PEM_read_PrivateKey(fp, - private_key, - OPENSSL_PEM_CB(xpw_cb,NULL)) == NULL) { - unsigned long error = ERR_peek_error(); - fclose(fp); - -#ifdef PEM_F_PEM_DEF_CALLBACK - if (error == ERR_PACK(ERR_LIB_PEM, - PEM_F_PEM_DEF_CALLBACK, - PEM_R_PROBLEMS_GETTING_PASSWORD)) -#else - if (error == ERR_PACK(ERR_LIB_PEM, - PEM_F_DEF_CALLBACK, - PEM_R_PROBLEMS_GETTING_PASSWORD)) -#endif - { - ERR_clear_error(); - } -#ifdef EVP_F_EVP_DECRYPTFINAL_EX - else if (error == ERR_PACK(ERR_LIB_EVP, - EVP_F_EVP_DECRYPTFINAL_EX, - EVP_R_BAD_DECRYPT)) -#else - else if (error == ERR_PACK(ERR_LIB_EVP, - EVP_F_EVP_DECRYPTFINAL, - EVP_R_BAD_DECRYPT)) -#endif - { - ERR_clear_error(); - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_WRONG_PASSPHRASE); - status = PRXYERR_R_WRONG_PASSPHRASE; - } - else { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_KEY); - ERR_add_error_data(2, "\n File=", user_key); - status = PRXYERR_R_PROCESS_KEY; - } - goto err; - } - fclose(fp); - } - - /* - * check that the private key matches the certificate - * Dont want a mixup of keys and certs - * Will only check rsa type for now. - */ - if (ucert) - { - X509_PUBKEY *key = X509_get_X509_PUBKEY(ucert); - ucertpkey = X509_PUBKEY_get(key); - int mismatch = 0; - - if (ucertpkey!= NULL && ucertpkey->type == - (*private_key)->type) - { - if (ucertpkey->type == EVP_PKEY_RSA) - { - /* add in key as random data too */ - if (ucertpkey->pkey.rsa != NULL) - { - if(ucertpkey->pkey.rsa->p != NULL) - { - RAND_add((void*)ucertpkey->pkey.rsa->p->d, - BN_num_bytes(ucertpkey->pkey.rsa->p), - BN_num_bytes(ucertpkey->pkey.rsa->p)); - } - if(ucertpkey->pkey.rsa->q != NULL) - { - RAND_add((void*)ucertpkey->pkey.rsa->q->d, - BN_num_bytes(ucertpkey->pkey.rsa->q), - BN_num_bytes(ucertpkey->pkey.rsa->q)); - } - } - if ((ucertpkey->pkey.rsa != NULL) && - (ucertpkey->pkey.rsa->n != NULL) && - ((*private_key)->pkey.rsa != NULL) ) - { - if ((*private_key)->pkey.rsa->n != NULL - && BN_num_bytes((*private_key)->pkey.rsa->n)) - { - if (BN_cmp(ucertpkey->pkey.rsa->n, - (*private_key)->pkey.rsa->n)) - { - mismatch=1; - } - } - else - { - (*private_key)->pkey.rsa->n = - BN_dup(ucertpkey->pkey.rsa->n); - (*private_key)->pkey.rsa->e = - BN_dup(ucertpkey->pkey.rsa->e); - } - } - } - } - else - { - mismatch=1; - } - - EVP_PKEY_free(ucertpkey); - - if (mismatch) - { - PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_KEY_CERT_MISMATCH); - status = PRXYERR_R_KEY_CERT_MISMATCH; - goto err; - } - } - - status = 0; - -err: - /* DEE need more cleanup */ - return status; -} - - -/********************************************************************** -Function: ASN1_UTCTIME_mktime() - -Description: - SSLeay only has compare functions to the current - So we define a convert to time_t from which we can do differences - Much of this it taken from the X509_cmp_current_time() - routine. - -Parameters: - -Returns: - time_t -**********************************************************************/ - -time_t PRIVATE ASN1_TIME_mktime(ASN1_TIME *ctm) -{ - /* - * note: ASN1_TIME, ASN1_UTCTIME, ASN1_GENERALIZEDTIME are different - * typedefs of the same type. - */ - return ASN1_UTCTIME_mktime(ctm); -} - -time_t PRIVATE -ASN1_UTCTIME_mktime( - ASN1_UTCTIME * ctm) -{ - char *str; - time_t offset; - time_t newtime; - char buff1[32]; - char *p; - int i; - struct tm tm; - int size = 0; - - switch (ctm->type) { - case V_ASN1_UTCTIME: - size=10; - break; - case V_ASN1_GENERALIZEDTIME: - size=12; - break; - } - p = buff1; - i = ctm->length; - str = (char *)ctm->data; - if ((i < 11) || (i > 17)) { - return 0; - } - memcpy(p,str,size); - p += size; - str += size; - - if ((*str == 'Z') || (*str == '-') || (*str == '+')) { - *(p++)='0'; *(p++)='0'; - } - else { - *(p++)= *(str++); *(p++)= *(str++); - } - *(p++) = 'Z'; - *p = '\0'; - - if (*str == 'Z') { - offset=0; - } - else { - if ((*str != '+') && (str[5] != '-')) { - return 0; - } - offset=((str[1]-'0')*10+(str[2]-'0'))*60; - offset+=(str[3]-'0')*10+(str[4]-'0'); - if (*str == '-') { - offset=-offset; - } - } - - tm.tm_isdst = 0; - int index = 0; - if (ctm->type == V_ASN1_UTCTIME) { - tm.tm_year = (buff1[index++]-'0')*10; - tm.tm_year += (buff1[index++]-'0'); - } - else { - tm.tm_year = (buff1[index++]-'0')*1000; - tm.tm_year += (buff1[index++]-'0')*100; - tm.tm_year += (buff1[index++]-'0')*10; - tm.tm_year += (buff1[index++]-'0'); - } - - if (tm.tm_year < 70) { - tm.tm_year+=100; - } - - if (tm.tm_year > 1900) { - tm.tm_year -= 1900; - } - - tm.tm_mon = (buff1[index++]-'0')*10; - tm.tm_mon += (buff1[index++]-'0')-1; - tm.tm_mday = (buff1[index++]-'0')*10; - tm.tm_mday += (buff1[index++]-'0'); - tm.tm_hour = (buff1[index++]-'0')*10; - tm.tm_hour += (buff1[index++]-'0'); - tm.tm_min = (buff1[index++]-'0')*10; - tm.tm_min += (buff1[index++]-'0'); - tm.tm_sec = (buff1[index++]-'0')*10; - tm.tm_sec += (buff1[index]-'0'); - - /* - * mktime assumes local time, so subtract off - * timezone, which is seconds off of GMT. first - * we need to initialize it with tzset() however. - */ - - tzset(); -#if defined(HAVE_TIMEGM) - newtime = (timegm(&tm) + offset*60*60); -#elif defined(HAVE_TIME_T_TIMEZONE) - newtime = (mktime(&tm) + offset*60*60 - timezone); -#elif defined(HAVE_TIME_T__TIMEZONE) - newtime = (mktime(&tm) + offset*60*60 - _timezone); -#else - newtime = (mktime(&tm) + offset*60*60); -#endif - - return newtime; -} - - -#ifdef CLASS_ADD - -/********************************************************************** -Function: proxy_extension_class_add_create() - -Description: - create a X509_EXTENSION for the class_add info. - -Parameters: - A buffer and length. The date is added as - ANS1_OCTET_STRING to an extension with the - class_add OID. - -Returns: - -**********************************************************************/ - -X509_EXTENSION PRIVATE * -proxy_extension_class_add_create( - void * buffer, - size_t length) - -{ - X509_EXTENSION * ex = NULL; - ASN1_OBJECT * class_add_obj = NULL; - ASN1_OCTET_STRING * class_add_oct = NULL; - int crit = 0; - - if(!(class_add_obj = OBJ_nid2obj(OBJ_txt2nid("CLASSADD")))) - { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_OID); - goto err; - } - - if(!(class_add_oct = ASN1_OCTET_STRING_new())) - { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - - class_add_oct->data = buffer; - class_add_oct->length = length; - - if (!(ex = X509_EXTENSION_create_by_OBJ(NULL, class_add_obj, - crit, class_add_oct))) - { - PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_EXT); - goto err; - } - class_add_oct = NULL; - - return ex; - -err: - if (class_add_oct) - { - ASN1_OCTET_STRING_free(class_add_oct); - } - - if (class_add_obj) - { - ASN1_OBJECT_free(class_add_obj); - } - return NULL; -} -#endif - - -int PRIVATE determine_filenames(char **cacert, char **certdir, char **outfile, - char **certfile, char **keyfile, int noregen) -{ - char *oldoutfile = NULL; - - if (noregen) { - int modify = 0; - - if (*certfile == NULL && *keyfile == NULL) - modify = 1; - - if (proxy_get_filenames(0, NULL, NULL, &oldoutfile, certfile, keyfile)) - goto err; - - if (modify) { - free(*certfile); - free(*keyfile); - *certfile = strdup(oldoutfile); - *keyfile = oldoutfile; - } - else - free(oldoutfile); - - if (proxy_get_filenames(0, cacert, certdir, outfile, certfile, keyfile)) - goto err; - } - else if (proxy_get_filenames(0, cacert, certdir, outfile, certfile, keyfile)) - goto err; - - return 1; - -err: - return 0; -} - -int load_credentials(const char *certname, const char *keyname, - X509 **cert, STACK_OF(X509) **stack, EVP_PKEY **key, - int (*callback)()) -{ - STACK_OF(X509) *chain = NULL; - - if (!certname) - return 0; - - unsigned long hSession = 0; - - if (!strncmp(certname, "SC:", 3)) - EVP_set_pw_prompt("Enter card pin:"); - else - EVP_set_pw_prompt("Enter GRID pass phrase for this identity:"); - - if (strcmp(certname + strlen(certname) - 4, ".p12")) { - if(proxy_load_user_cert(certname, cert, callback, &hSession)) - goto err; - - EVP_set_pw_prompt("Enter GRID pass phrase:"); - - if (keyname) { - if (!strncmp(keyname, "SC:", 3)) - EVP_set_pw_prompt("Enter card pin:"); - - if (proxy_load_user_key(key, *cert, keyname, callback, &hSession)) - goto err; - } - - if (stack && (strncmp(certname, "SC:", 3) && (!keyname || !strcmp(certname, keyname)))) { - chain = sk_X509_new_null(); - if (proxy_load_user_proxy(chain, certname) < 0) - goto err; - *stack = chain; - } - } - else { - if (!proxy_load_user_cert_and_key_pkcs12(certname, cert, stack, key, callback)) - goto err; - } - - return 1; - -err: - if (chain) - sk_X509_free(chain); - if (cert) { - X509_free(*cert); - *cert = NULL; - } - if (key) { - EVP_PKEY_free(*key); - *key = NULL; - } - return 0; -} - -int PRIVATE load_certificate_from_file(FILE *file, X509 **cert, - STACK_OF(X509) **stack) -{ - BIO *in = NULL; - - if (!cert) - return 0; - - in = BIO_new_fp(file, BIO_NOCLOSE); - - if (in) { - *cert = PEM_read_bio_X509(in, NULL, 0, NULL); - - if(!*cert) - goto err; - - if (stack) { - *stack = load_chain(in, 0); - if (!(*stack)) - goto err; - } - } - BIO_free(in); - return 1; - - err: - BIO_free(in); - if (cert) - X509_free(*cert); - if (stack) - sk_X509_pop_free(*stack, X509_free); - return 0; - -} - -STACK_OF(X509) *load_chain(BIO *in, char *certfile) -{ - STACK_OF(X509_INFO) *sk=NULL; - STACK_OF(X509) *stack=NULL, *ret=NULL; - X509_INFO *xi; - int first = 1; - - if(!(stack = sk_X509_new_null())) { - if (certfile) - printf("memory allocation failure\n"); - goto end; - } - - /* This loads from a file, a stack of x509/crl/pkey sets */ - if(!(sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL))) { - if (certfile) - printf("error reading the file, %s\n",certfile); - goto end; - } - - /* scan over it and pull out the certs */ - while (sk_X509_INFO_num(sk)) { - /* skip first cert */ - if (first) { - first = 0; - continue; - } - xi=sk_X509_INFO_shift(sk); - if (xi->x509 != NULL) { - sk_X509_push(stack,xi->x509); - xi->x509=NULL; - } - X509_INFO_free(xi); - } - if(!sk_X509_num(stack)) { - if (certfile) - printf("no certificates in file, %s\n",certfile); - sk_X509_free(stack); - goto end; - } - ret=stack; -end: - sk_X509_INFO_free(sk); - return(ret); -} - -static char hextoint(char r, char s) -{ - int v = 0; - if (isxdigit(r) && isxdigit(s)) { - v = hex2num(r); - v <<= 4; - v += hex2num(s); - } - return v; -} - -static unsigned char *reencode_string(unsigned char *string, int *len) -{ - unsigned char *temp = string; - unsigned char *pos = string; - char t = '\0'; - char r = '\0'; - *len = 0; - - while(*string) { - switch (*string) { - case '\\': - t = *++string; - - if (t == '\\') { - *pos++ = '\\'; - ++(*len); - } - else if (isxdigit(t)) { - r = *++string; - *pos++ = hextoint(tolower(t), tolower(r)); - ++(*len); - ++string; - } - else { - *pos++ = t; - ++(*len); - ++string; - } - break; - - default: - ++(*len); - *pos++ = *string++; - break; - } - } - - return temp; -} - -static X509_NAME *make_DN(const char *dnstring) -{ - char *buffername = (char*)malloc(strlen(dnstring)+1); - unsigned char *buffervalue = (unsigned char*)malloc(strlen(dnstring)+1); - char *currentname; - unsigned char *currentvalue; - X509_NAME *name = NULL; - int valuelen = 0; - char next = 0; - - name = X509_NAME_new(); - - int status = 0; /* - * 0 = looking for /type - * 1 = looking for value - */ - do { - switch (status) { - case 0: - /* Parse for /Name= */ - currentname=buffername; - while (*dnstring) { - if (*dnstring == '\\') { - *currentname++ = *++dnstring; - if (*dnstring == '\0') { - break; - } - dnstring++; - } - else if (*dnstring == '=') { - *currentname='\0'; - break; - } - else if (*dnstring == '\0') { - break; - } - else - *currentname++ = *dnstring++; - } - /* now, if *dnstring == '\0' then error; */ - - if (*dnstring == '\0') - goto err; - /* else, we got a type, now look for a value. */ - status = 1; - dnstring++; - break; - case 1: - /* Parse for value */ - currentvalue=buffervalue; - while (*dnstring) { - if (*dnstring == '\\') { - next = *++dnstring; - if (next == '\0') { - break; - } - else if (next != '/') { - *currentvalue++ = '\\'; - *currentvalue++ = next; - } - else { - *currentvalue++ = '/'; - } - dnstring++; - } - else if (*dnstring == '/') { - *currentvalue='\0'; - break; - } - else if (*dnstring == '\0') { - *currentvalue='\0'; - break; - } - else - *currentvalue++ = *dnstring++; - } - - *currentvalue='\0'; - if (strlen((char*)buffervalue) == 0) - goto err; - - /* Now we have both type and value. Add to the X509_NAME_ENTRY */ - - buffervalue = reencode_string(buffervalue, &valuelen); - - X509_NAME_add_entry_by_txt(name, buffername+1, /* skip initial '/' */ - V_ASN1_APP_CHOOSE, - buffervalue, valuelen, X509_NAME_entry_count(name), - 0); - status = 0; - break; - } - } while (*dnstring); - - free(buffername); - free(buffervalue); - - return name; - err: - free(buffername); - free(buffervalue); - X509_NAME_free(name); - - return NULL; - -} - -static int check_critical_extensions(X509 *cert, int itsaproxy) -{ - int i = 0; - ASN1_OBJECT *extension_obj; - int nid; - X509_EXTENSION *ex; - - int nid_pci3 = my_txt2nid(PROXYCERTINFO_V3); - int nid_pci4 = my_txt2nid(PROXYCERTINFO_V4); - - STACK_OF(X509_EXTENSION) *extensions = cert->cert_info->extensions; - - for (i=0; i < sk_X509_EXTENSION_num(extensions); i++) { - ex = (X509_EXTENSION *) sk_X509_EXTENSION_value(extensions,i); - - if(X509_EXTENSION_get_critical(ex)) { - extension_obj = X509_EXTENSION_get_object(ex); - - nid = OBJ_obj2nid(extension_obj); - - if (itsaproxy) { - if (nid != NID_basic_constraints && - nid != NID_key_usage && - nid != NID_ext_key_usage && - nid != NID_netscape_cert_type && - nid != NID_subject_key_identifier && - nid != NID_authority_key_identifier && - nid != nid_pci3 && - nid != nid_pci4) { - return 0; - } - } - else { - if (nid != NID_basic_constraints && - nid != NID_key_usage && - nid != NID_ext_key_usage && - nid != NID_netscape_cert_type && - nid != NID_subject_key_identifier && - nid != NID_authority_key_identifier) { - return 0; - } - } - } - } - return 1; -} diff --git a/emi.canl.canl-c/src/proxy/sslutils.h b/emi.canl.canl-c/src/proxy/sslutils.h deleted file mode 100644 index 3a5725c..0000000 --- a/emi.canl.canl-c/src/proxy/sslutils.h +++ /dev/null @@ -1,539 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * Valerio Venturi - Valerio.Venturi@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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. - * - *********************************************************************/ -/********************************************************************** -sslutils.h: - -Description: - This header file used internally by the gssapi_ssleay - routines - -**********************************************************************/ - -#ifndef VOMS_SSLUTILS_H -#define VOMS_SSLUTILS_H - -#ifndef EXTERN_C_BEGIN -#ifdef __cplusplus -#define EXTERN_C_BEGIN extern "C" { -#define EXTERN_C_END } -#else -#define EXTERN_C_BEGIN -#define EXTERN_C_END -#endif -#endif - -EXTERN_C_BEGIN - -/********************************************************************** - Include header files -**********************************************************************/ -//#include "config.h" - -#include -#include -#include -#include -#include -#include "openssl/crypto.h" - - - -#if defined(__GNUC__) -#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -#define UNUSED(z) z __attribute__ ((unused)) -#else -#define UNUSED(z) z -#endif -#define PRIVATE __attribute__ ((visibility ("hidden"))) -#define PUBLIC __attribute__ ((visibility ("default"))) -#else -#define UNUSED(z) z -#define PRIVATE -#define PUBLIC -#endif - - - -#if SSLEAY_VERSION_NUMBER < 0x0090581fL -#define RAND_add(a,b,c) RAND_seed(a,b) -#define RAND_status() 1 -#endif - -#if SSLEAY_VERSION_NUMBER >= 0x00904100L -/* Support both OpenSSL 0.9.4 and SSLeay 0.9.0 */ -#define OPENSSL_PEM_CB(A,B) A, B -#else -#define RAND_add(a,b,c) RAND_seed(a,b) -#define OPENSSL_PEM_CB(A,B) A - -#define STACK_OF(A) STACK - -#define sk_X509_num sk_num -#define sk_X509_value (X509 *)sk_value -#define sk_X509_push(A, B) sk_push(A, (char *) B) -#define sk_X509_insert(A,B,C) sk_insert(A, (char *) B, C) -#define sk_X509_delete sk_delete -#define sk_X509_new_null sk_new_null -#define sk_X509_pop_free sk_pop_free - -#define sk_X509_NAME_ENTRY_num sk_num -#define sk_X509_NAME_ENTRY_value (X509_NAME_ENTRY *)sk_value - -#define sk_SSL_CIPHER_num sk_num -#define sk_SSL_CIPHER_value (SSL_CIPHER*)sk_value -#define sk_SSL_CIPHER_insert(A,B,C) sk_insert(A, (char *) B, C) -#define sk_SSL_CIPHER_delete sk_delete -#define sk_SSL_CIPHER_push(A, B) sk_push(A, (char *) B) -#define sk_SSL_CIPHER_shift(A) sk_shift(A) -#define sk_SSL_CIPHER_dup(A) sk_dup(A) -#define sk_SSL_CIPHER_unshift(A, B) sk_unshift(A, (char *) B) -#define sk_SSL_CIPHER_pop(A) sk_pop(A) -#define sk_SSL_CIPHER_delete_ptr(A, B) sk_delete_ptr(A, B) - -#define sk_X509_EXTENSION_num sk_num -#define sk_X509_EXTENSION_value (X509_EXTENSION *)sk_value -#define sk_X509_EXTENSION_push(A, B) sk_push(A, (char *) B) -#define sk_X509_EXTENSION_new_null sk_new_null -#define sk_X509_EXTENSION_pop_free sk_pop_free - -#define sk_X509_REVOKED_num sk_num -#define sk_X509_REVOKED_value (X509_REVOKED*)sk_value - -#endif - -#include "openssl/ssl.h" -#include "openssl/err.h" -#include "openssl/bio.h" -#include "openssl/pem.h" -#include "openssl/x509.h" -#include "openssl/stack.h" - -/********************************************************************** - Define constants -**********************************************************************/ - -#define X509_CERT_DIR "X509_CERT_DIR" -#define X509_CERT_FILE "X509_CERT_FILE" -#define X509_USER_PROXY "X509_USER_PROXY" -#define X509_USER_CERT "X509_USER_CERT" -#define X509_USER_KEY "X509_USER_KEY" -#define X509_USER_DELEG_PROXY "X509_USER_DELEG_PROXY" -#define X509_USER_DELEG_FILE "x509up_p" -#define X509_USER_PROXY_FILE "x509up_u" - -/* This is added after the CA name hash to make the policy filename */ -#define SIGNING_POLICY_FILE_EXTENSION ".signing_policy" - -#ifdef WIN32 -#define GSI_REGISTRY_DIR "software\\Globus\\GSI" -#define X509_DEFAULT_CERT_DIR ".globus\\certificates" -#define X509_DEFAULT_USER_CERT ".globus\\usercert.pem" -#define X509_DEFAULT_USER_CERT_P12 ".globus\\usercert.p12" -#define X509_DEFAULT_USER_CERT_P12_GT ".globus\\usercred.p12" -#define X509_DEFAULT_USER_KEY ".globus\\userkey.pem" -#define X509_INSTALLED_CERT_DIR "share\\certificates" -#define X509_INSTALLED_HOST_CERT_DIR "NEEDS_TO_BE_DETERMINED" -#define X509_DEFAULT_HOST_CERT "NEEDS_TO_BE_DETERMINED" -#define X509_DEFAULT_HOST_KEY "NEEDS_TO_BE_DETERMINED" -#else -#define X509_DEFAULT_CERT_DIR ".globus/certificates" -#define X509_DEFAULT_USER_CERT ".globus/usercert.pem" -#define X509_DEFAULT_USER_CERT_P12 ".globus/usercert.p12" -#define X509_DEFAULT_USER_CERT_P12_GT ".globus/usercred.p12" -#define X509_DEFAULT_USER_KEY ".globus/userkey.pem" -#define X509_INSTALLED_CERT_DIR "share/certificates" -#define X509_INSTALLED_HOST_CERT_DIR "/etc/grid-security/certificates" -#define X509_DEFAULT_HOST_CERT "/etc/grid-security/hostcert.pem" -#define X509_DEFAULT_HOST_KEY "/etc/grid-security/hostkey.pem" -#endif - -/* - * To allow the use of the proxy_verify_callback with - * applications which already use the SSL_set_app_data, - * we define here the index for use with the - * SSL_set_ex_data. This is hardcoded today, but - * if needed we could add ours at the highest available, - * then look at all of them for the magic number. - * To allow for recursive calls to proxy_verify_callback - * when verifing a delegate cert_chain, we also have - * PVD_STORE_EX_DATA_IDX - */ - -#define PVD_SSL_EX_DATA_IDX 5 -#define PVD_STORE_EX_DATA_IDX 6 - - -#define PVD_MAGIC_NUMBER 22222 -#define PVXD_MAGIC_NUMBER 33333 - -/* Used by ERR_set_continue_needed as a flag for error routines */ -#define ERR_DISPLAY_CONTINUE_NEEDED 64 - -/* Location relative to ERR_LIB_USER where PRXYERR library will be stored */ -#define ERR_USER_LIB_PRXYERR_NUMBER ERR_LIB_USER - -/* - * Use the SSLeay error facility with the ERR_LIB_USER - */ - -#define PRXYerr(f,r) ERR_PUT_error(ERR_USER_LIB_PRXYERR_NUMBER,(f),(r),__FILE__,__LINE__) - -/* - * SSLeay 0.9.0 added the error_data feature. We may be running - * with 0.8.1 which does not have it, if so, define a dummy - * ERR_add_error_data and ERR_get_error_line_data - -*/ - -#if SSLEAY_VERSION_NUMBER < 0x0900 -void ERR_add_error_data( VAR_PLIST( int, num ) ); - -unsigned long ERR_get_error_line_data(char **file,int *line, - char **data, int *flags); -#endif - -void -ERR_set_continue_needed(void); - -/* - * defines for function codes our minor error codes - * These match strings defined in gsserr.c. - */ - -#define PRXYERR_F_BASE 100 - -#define PRXYERR_F_PROXY_GENREQ PRXYERR_F_BASE + 0 -#define PRXYERR_F_PROXY_SIGN PRXYERR_F_BASE + 1 -#define PRXYERR_F_VERIFY_CB PRXYERR_F_BASE + 2 -#define PRXYERR_F_PROXY_LOAD PRXYERR_F_BASE + 3 -#define PRXYERR_F_PROXY_TMP PRXYERR_F_BASE + 4 -#define PRXYERR_F_INIT_CRED PRXYERR_F_BASE + 5 -#define PRXYERR_F_LOCAL_CREATE PRXYERR_F_BASE + 6 -#define PRXYERR_F_CB_NO_PW PRXYERR_F_BASE + 7 -#define PRXYERR_F_GET_CA_SIGN_PATH PRXYERR_F_BASE + 8 -#define PRXYERR_F_PROXY_SIGN_EXT PRXYERR_F_BASE + 9 -#define PRXYERR_F_PROXY_CHECK_SUBJECT_NAME PRXYERR_F_BASE + 10 -#define PRXYERR_F_PROXY_CONSTRUCT_NAME PRXYERR_F_BASE + 11 - -/* - * defines for reasons - * The match strings defined in gsserr.c - * These are also used for the minor_status codes. - * We want to make sure these don't overlap with the errors in - * gssapi_ssleay.h. - */ - -#define PRXYERR_R_BASE 1000 - -#define PRXYERR_R_PROCESS_PROXY_KEY PRXYERR_R_BASE + 1 -#define PRXYERR_R_PROCESS_REQ PRXYERR_R_BASE + 2 -#define PRXYERR_R_PROCESS_SIGN PRXYERR_R_BASE + 3 -#define PRXYERR_R_MALFORM_REQ PRXYERR_R_BASE + 4 -#define PRXYERR_R_SIG_VERIFY PRXYERR_R_BASE + 5 -#define PRXYERR_R_SIG_BAD PRXYERR_R_BASE + 6 -#define PRXYERR_R_PROCESS_PROXY PRXYERR_R_BASE + 7 -#define PRXYERR_R_PROXY_NAME_BAD PRXYERR_R_BASE + 8 -#define PRXYERR_R_PROCESS_SIGNC PRXYERR_R_BASE + 9 -#define PRXYERR_R_BAD_PROXY_ISSUER PRXYERR_R_BASE + 10 -#define PRXYERR_R_PROBLEM_PROXY_FILE PRXYERR_R_BASE + 11 -#define PRXYERR_R_SIGN_NOT_CA PRXYERR_R_BASE + 12 -#define PRXYERR_R_PROCESS_KEY PRXYERR_R_BASE + 13 -#define PRXYERR_R_PROCESS_CERT PRXYERR_R_BASE + 14 -#define PRXYERR_R_PROCESS_CERTS PRXYERR_R_BASE + 15 -#define PRXYERR_R_NO_TRUSTED_CERTS PRXYERR_R_BASE + 16 -#define PRXYERR_R_PROBLEM_KEY_FILE PRXYERR_R_BASE + 17 -#define PRXYERR_R_USER_ZERO_LENGTH_KEY_FILE PRXYERR_R_BASE + 18 -#define PRXYERR_R_SERVER_ZERO_LENGTH_KEY_FILE PRXYERR_R_BASE + 19 -#define PRXYERR_R_ZERO_LENGTH_CERT_FILE PRXYERR_R_BASE + 20 -#define PRXYERR_R_PROBLEM_USER_NOCERT_FILE PRXYERR_R_BASE + 21 -#define PRXYERR_R_PROBLEM_SERVER_NOCERT_FILE PRXYERR_R_BASE + 22 -#define PRXYERR_R_PROBLEM_USER_NOKEY_FILE PRXYERR_R_BASE + 23 -#define PRXYERR_R_PROBLEM_SERVER_NOKEY_FILE PRXYERR_R_BASE + 24 -#define PRXYERR_R_USER_CERT_EXPIRED PRXYERR_R_BASE + 25 -#define PRXYERR_R_SERVER_CERT_EXPIRED PRXYERR_R_BASE + 26 -#define PRXYERR_R_CRL_SIGNATURE_FAILURE PRXYERR_R_BASE + 27 -#define PRXYERR_R_CRL_NEXT_UPDATE_FIELD PRXYERR_R_BASE + 28 -#define PRXYERR_R_CRL_HAS_EXPIRED PRXYERR_R_BASE + 29 -#define PRXYERR_R_CERT_REVOKED PRXYERR_R_BASE + 30 -#define PRXYERR_R_NO_HOME PRXYERR_R_BASE + 31 -#define PRXYERR_R_LPROXY_MISSED_USED PRXYERR_R_BASE + 32 -#define PRXYERR_R_LPROXY_REJECTED PRXYERR_R_BASE + 33 -#define PRXYERR_R_KEY_CERT_MISMATCH PRXYERR_R_BASE + 34 -#define PRXYERR_R_WRONG_PASSPHRASE PRXYERR_R_BASE + 35 -#define PRXYERR_R_CA_POLICY_VIOLATION PRXYERR_R_BASE + 36 -#define PRXYERR_R_CA_POLICY_RETRIEVE PRXYERR_R_BASE + 37 -#define PRXYERR_R_CA_POLICY_PARSE PRXYERR_R_BASE + 38 -#define PRXYERR_R_PROBLEM_CLIENT_CA PRXYERR_R_BASE + 39 -#define PRXYERR_R_CB_NO_PW PRXYERR_R_BASE + 40 -#define PRXYERR_R_CB_CALLED_WITH_ERROR PRXYERR_R_BASE + 41 -#define PRXYERR_R_CB_ERROR_MSG PRXYERR_R_BASE + 42 -#define PRXYERR_R_CLASS_ADD_OID PRXYERR_R_BASE + 43 -#define PRXYERR_R_CLASS_ADD_EXT PRXYERR_R_BASE + 44 -#define PRXYERR_R_DELEGATE_VERIFY PRXYERR_R_BASE + 45 -#define PRXYERR_R_EXT_ADD PRXYERR_R_BASE + 46 -#define PRXYERR_R_DELEGATE_COPY PRXYERR_R_BASE + 47 -#define PRXYERR_R_DELEGATE_CREATE PRXYERR_R_BASE + 48 -#define PRXYERR_R_BUFFER_TOO_SMALL PRXYERR_R_BASE + 49 -#define PRXYERR_R_PROXY_EXPIRED PRXYERR_R_BASE + 50 -#define PRXYERR_R_NO_PROXY PRXYERR_R_BASE + 51 -#define PRXYERR_R_CA_UNKNOWN PRXYERR_R_BASE + 52 -#define PRXYERR_R_CA_NOPATH PRXYERR_R_BASE + 53 -#define PRXYERR_R_CA_NOFILE PRXYERR_R_BASE + 54 -#define PRXYERR_R_CA_POLICY_ERR PRXYERR_R_BASE + 55 -#define PRXYERR_R_INVALID_CERT PRXYERR_R_BASE + 56 -#define PRXYERR_R_CERT_NOT_YET_VALID PRXYERR_R_BASE + 57 -#define PRXYERR_R_LOCAL_CA_UNKNOWN PRXYERR_R_BASE + 58 -#define PRXYERR_R_REMOTE_CRED_EXPIRED PRXYERR_R_BASE + 59 -#define PRXYERR_R_OUT_OF_MEMORY PRXYERR_R_BASE + 60 -#define PRXYERR_R_BAD_ARGUMENT PRXYERR_R_BASE + 61 -#define PRXYERR_R_BAD_MAGIC PRXYERR_R_BASE + 62 -#define PRXYERR_R_UNKNOWN_CRIT_EXT PRXYERR_R_BASE + 63 -/* NOTE: Don't go over 1500 here or will conflict with errors in scutils.h */ - - -/********************************************************************** - Type definitions -**********************************************************************/ - -/* proxy_verify_ctx_desc - common to all verifys */ - -typedef struct proxy_verify_ctx_desc_struct { - int magicnum ; - char * certdir; - time_t goodtill; -} proxy_verify_ctx_desc ; - -/* proxy_verify_desc - allows for recursive verifys with delegation */ - -typedef struct proxy_verify_desc_struct proxy_verify_desc; - -struct proxy_verify_desc_struct { - int magicnum; - proxy_verify_desc * previous; - proxy_verify_ctx_desc * pvxd; - int flags; - X509_STORE_CTX * cert_store; - int recursive_depth; - int proxy_depth; - int cert_depth; - int limited_proxy; - STACK_OF(X509) * cert_chain; /* X509 */ - int multiple_limited_proxy_ok; -}; - -/********************************************************************** - Global variables -**********************************************************************/ - -/********************************************************************** - Function prototypes -**********************************************************************/ - -int -ERR_load_prxyerr_strings(int i); - -int proxy_load_user_cert_and_key_pkcs12(const char *user_cert, - X509 **cert, - STACK_OF(X509) **stack, - EVP_PKEY **pkey, - int (*pw_cb) ()); - -int -proxy_get_filenames( - int proxy_in, - char ** p_cert_file, - char ** p_cert_dir, - char ** p_user_proxy, - char ** p_user_cert, - char ** p_user_key); - -int -proxy_load_user_cert( - const char * user_cert, - X509 ** certificate, - int (*pw_cb)(), - unsigned long * hSession); - -int -proxy_load_user_key( - EVP_PKEY ** private_key, - X509 * ucert, - const char * user_key, - int (*pw_cb)(), - unsigned long * hSession); - -void -proxy_verify_init( - proxy_verify_desc * pvd, - proxy_verify_ctx_desc * pvxd); - -void -proxy_verify_release( - proxy_verify_desc * pvd); - -void -proxy_verify_ctx_init( - proxy_verify_ctx_desc *pvxd); -void -proxy_verify_ctx_release( - proxy_verify_ctx_desc *pvxd); - -int -proxy_check_proxy_name( - X509 *); - -int -proxy_check_issued( - X509_STORE_CTX * ctx, - X509 * x, - X509 * issuer); - -int -proxy_verify_certchain( - STACK_OF(X509) * certchain, - proxy_verify_desc * ppvd); - -int -proxy_verify_callback( - int ok, - X509_STORE_CTX * ctx); - -int -proxy_genreq( - X509 * ucert, - X509_REQ ** reqp, - EVP_PKEY ** pkeyp, - int bits, - const char * newdn, - int (*callback)()); - -int -proxy_sign( - X509 * user_cert, - EVP_PKEY * user_private_key, - X509_REQ * req, - X509 ** new_cert, - int seconds, - STACK_OF(X509_EXTENSION) * extensions, - int limited_proxy, - int proxyver, - const char * newdn, - const char * newissuer, - int pastproxy, - const char * newserial, - int selfsigned -); - -int -proxy_sign_ext( - X509 * user_cert, - EVP_PKEY * user_private_key, - const EVP_MD * method, - X509_REQ * req, - X509 ** new_cert, - X509_NAME * subject_name, - X509_NAME * issuer_name, - int seconds, - STACK_OF(X509_EXTENSION) * extensions, - int proxyver, - int pastproxy, - const char * newserial, - int selfsigned); - -int -proxy_check_subject_name( - X509_REQ * req, - X509_NAME * subject_name); - -int -proxy_construct_name( - X509 * cert, - X509_NAME ** name, - char * newcn, - unsigned int len); - -int -proxy_marshal_tmp( - X509 * ncert, - EVP_PKEY * npkey, - X509 * ucert, - STACK_OF(X509) * store_ctx, - char ** filename); - -int -proxy_marshal_bp( - BIO * bp, - X509 * ncert, - EVP_PKEY * npkey, - X509 * ucert, - STACK_OF(X509) * store_ctx); - -int -proxy_load_user_proxy( - STACK_OF(X509) * cert_chain, - const char * file); - -int -proxy_get_base_name( - X509_NAME * subject); - -X509_EXTENSION * -proxy_extension_class_add_create( - void * buffer, - size_t length); -/* - * SSLeay does not have a compare time function - * So we add a convert to time_t function - */ - -time_t -ASN1_UTCTIME_mktime( - ASN1_UTCTIME * ctm); - -time_t ASN1_TIME_mktime(ASN1_TIME *ctm); - -int PRIVATE determine_filenames(char **cacert, char **certdir, char **outfile, - char **certfile, char **keyfile, int noregen); -int load_credentials(const char *certname, const char *keyname, - X509 **cert, STACK_OF(X509) **stack, EVP_PKEY **key, - int (*callback)()); -int PRIVATE load_certificate_from_file(FILE *file, X509 **cert, - STACK_OF(X509) **stack); - -int -proxy_app_verify_callback(X509_STORE_CTX *ctx, UNUSED(void *empty)); - -STACK_OF(X509) *load_chain(BIO *in, char*); - -int my_txt2nid(char *name); - -int -hex2num(char c); - - -EXTERN_C_END - -#endif /* _SSLUTILS_H */ diff --git a/emi.canl.canl-c/src/proxy/vomsproxy.h b/emi.canl.canl-c/src/proxy/vomsproxy.h deleted file mode 100644 index 5284d18..0000000 --- a/emi.canl.canl-c/src/proxy/vomsproxy.h +++ /dev/null @@ -1,103 +0,0 @@ -/********************************************************************* - * - * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it - * - * Copyright (c) Members of the EGEE Collaboration. 2004-2010. - * See http://www.eu-egee.org/partners/ for details on the copyright holders. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * 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 VOMS_PROXY_H -#define VOMS_PROXY_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -#include "newformat.h" - -struct VOMSProxyArguments { - X509_REQ *proxyrequest; - char *proxyfilename; - char *filename; - AC **aclist; - int proxyversion; - char *data; - int datalen; - char *newsubject; - int newsubjectlen; - X509 *cert; - EVP_PKEY *key; - int bits; - char *policyfile; - char *policylang; - char *policytext; - int pathlength; - int hours; - int minutes; - int limited; - char *voID; - int (*callback)(); - STACK_OF(X509_EXTENSION) *extensions; - STACK_OF(X509) *chain; - int pastproxy; - char *keyusage; - char *netscape; - char *exkusage; - char *newissuer; - char *newserial; - int selfsigned; -}; - -struct VOMSProxy { - X509 *cert; - STACK_OF(X509) *chain; - EVP_PKEY *key; -}; - -struct VOMSProxyArguments *VOMS_MakeProxyArguments(); -void VOMS_FreeProxyArguments(struct VOMSProxyArguments *args); -void VOMS_FreeProxy(struct VOMSProxy *proxy); -struct VOMSProxy *VOMS_AllocProxy(); -int VOMS_WriteProxy(const char *filename, struct VOMSProxy *proxy); -struct VOMSProxy *VOMS_MakeProxy(struct VOMSProxyArguments *args, int *warning, void **additional); -X509_EXTENSION *CreateProxyExtension(char * name, char *data, int datalen, int crit); -char *ProxyCreationError(int error, void *additional); - -#define PROXY_ERROR_IS_WARNING(error) (error >= 1000) - -#define PROXY_NO_ERROR 0 -#define PROXY_ERROR_OPEN_FILE 1 -#define PROXY_ERROR_STAT_FILE 2 -#define PROXY_ERROR_OUT_OF_MEMORY 3 -#define PROXY_ERROR_FILE_READ 4 -#define PROXY_ERROR_UNKNOWN_BIT 5 -#define PROXY_ERROR_UNKNOWN_EXTENDED_BIT 6 -#define PROXY_WARNING_GSI_ASSUMED 1000 -#define PROXY_WARNING_GENERIC_LANGUAGE_ASSUMED 1001 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/org.glite.deployment.jpis/build.xml b/org.glite.deployment.jpis/build.xml deleted file mode 100644 index c2bf066..0000000 --- a/org.glite.deployment.jpis/build.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpis/config/scripts/glite-jpis-config.py b/org.glite.deployment.jpis/config/scripts/glite-jpis-config.py deleted file mode 100755 index eb75155..0000000 --- a/org.glite.deployment.jpis/config/scripts/glite-jpis-config.py +++ /dev/null @@ -1,492 +0,0 @@ -#!/usr/bin/env python -################################################################################ -# -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://eu-egee.org/partners/ for details on the copyright holders. -# For license conditions see the license file or http://eu-egee.org/license.html -# -################################################################################ -# glite-jpis-config v. 1.0.0 -# -# Post-installation script for configuring the gLite Job Provenance Servers -# Robert Harakaly < mmulac@cern.ch > -# -# Version info: $Id$ -# -# Usage: python glite-jpis-config [-c|-v|-h|--help] -# -c, --checkconf print configuration -# -v, --version print version -# -h,--help print usage info -# --configure configure the service -# --start start the service -# --stop stop the service -# --status show service status -# -# Return codes: 0 - Ok -# 1 - Configuration failed -# -################################################################################ - -import os,string,pwd -import sys, posix, getopt,time - -sys.path.append(".") -from gLiteInstallerLib import gLib -from gLiteInstallerLib import ConfigParams -import mysql as MySQL - -# Set global variables here -global params # all config values from the XML file - -class glite_jpis: - - def __init__(self): - self.mysql = MySQL.Mysql() - self.verbose = 0 - self.version = "1.0.0" - self.name = "glite-jpis" - self.friendly_name = "gLite Job Provenance Index Server" - - #------------------------------------------------------------------------------- - # Banner - #------------------------------------------------------------------------------- - - def banner(self): - - print "\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - print "Configuring the %s" % self.friendly_name - print "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" - - #------------------------------------------------------------------------------- - # Copyright - #------------------------------------------------------------------------------- - - def copyright(self): - - print '\nCopyright (c) Members of the EGEE Collaboration. 2004' - print 'See http://eu-egee.org/partners/ for details on the copyright holders' - print 'For license conditions see the license file or http://eu-egee.org/license.html' - - #------------------------------------------------------------------------------- - # Version - #------------------------------------------------------------------------------- - - def showVersion(self): - - print '\n%s-config v. %s\n' % (self.name,self.version) - - #------------------------------------------------------------------------------- - # Usage - #------------------------------------------------------------------------------- - - def usage(self,msg = ""): - - if msg: - print "\n%s" % (msg) - - self.copyright() - self.showVersion() - - print """Usage: \n -Edit the configuration file %s.cfg.xml in -%s/etc.config/templates\n -save it as %s/etc/config/%s.cfg.xml -and run the script as follows\n -python %s-config [OPTION...]""" % (self.name, os.environ['GLITE_LOCATION'], \ - os.environ['GLITE_LOCATION'], self.name, self.name) - - print ' -c, --checkconf print the service configuration' - print ' -v, --version print the version of the configuration script' - print ' -h, --help print this usage information' - print ' --configure configure the service' - print ' --start start the service' - print ' --stop stop the service' - print ' --status check service status' - print '\n' - - #------------------------------------------------------------------------------- - # All the configuration code goes here - #------------------------------------------------------------------------------- - - def start(self): - - self.mysql.start() - time.sleep(5) - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - #------------------------------------------------------------------- - # Start Index Server - #------------------------------------------------------------------- - - pid = glib.getPID('indexd') - if pid != 0: - print 'The gLite JP Index Server service is already running. Restarting...' - os.system('%s/etc/init.d/glite-jp-indexd stop' % os.environ['GLITE_LOCATION']) - else: - print 'Starting the gLite JP Index Server service...' - - os.system('%s/etc/init.d/glite-jp-indexd start' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('indexd') - - if (pid != 0): - print "The gLite JP Index Server service has been started ", - glib.printOkMessage() - else: - glib.printErrorMessage("Could not start the gLite JP Index Server service") - glib.printErrorMessage("Please verify and re-run the script "), - glib.printFailedMessage() - return 1 - - return 0 - - def stop(self): - - error_level = 0 - - #------------------------------------------------------------------- - # Stop Index Server - #------------------------------------------------------------------- - - pid = glib.getPID('indexd') - if (pid != 0): - os.system('%s/etc/init.d/glite-jp-indexd stop' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('indexd') - if (pid != 0): - print 'Could not stop the JP Index Server service ', - glib.printFailedMessage() - error_level = 1 - else: - print 'JP Index Server service has been stopped ', - glib.printOkMessage() - - #------------------------------------------------------------------- - # MySQL - #------------------------------------------------------------------- - - self.mysql.stop() - - return error_level - - def status(self): - - error_level = 0 - - retval = os.system('%s/etc/init.d/glite-jp-indexd status' % os.environ['GLITE_LOCATION']) - if retval != 0: - error_level = 1 - - return error_level - - def configure(self): - - #-------------------------------------------------------- - # Installs the Security Utilities - #-------------------------------------------------------- - - if os.system("python %s/glite-security-utils-config.py --subservice" % glib.getScriptPath()): - print "\nConfiguring gLite Security Utilities ", - glib.printFailedMessage() - else: - print "\nConfiguring gLite Security Utilities ", - glib.printOkMessage() - - # Create the GLITE_USER if it doesn't exists - print "\nCreating/Verifying the GLITE_USER account %s" % os.environ['GLITE_USER'] - (uid,gid) = glib.get_user_info(os.environ['GLITE_USER']) - glib.check_dir(os.environ['GLITE_LOCATION_VAR'],0755, uid, gid) - jpis_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.check_dir(jpis_cert_path ,0755, uid, gid) - glib.printOkMessage() - - # Create all directories needed - glib.check_dir(os.environ['GLITE_CERT_DIR']) - print "\nVerify CA certificates directory ", - glib.printOkMessage() - - # Copy certificates - print "\nCopy host certificates to GLITE_USER home directory as service certificates", - os.system("cp %s %s %s/" % (params['host.certificate.file'], params['host.key.file'], jpis_cert_path)) - os.chown("%s/hostcert.pem" % jpis_cert_path, uid,gid) - os.chmod("%s/hostcert.pem" % jpis_cert_path, 0644) - os.chown("%s/hostkey.pem" % jpis_cert_path, uid,gid) - os.chmod("%s/hostkey.pem" % jpis_cert_path, 0400) - glib.printOkMessage() - - #-------------------------------------------------------- - # Configure MySQL - #-------------------------------------------------------- - - # Set mysql parameters - #self.mysql.setConfiguration('client','max_allowed_packet',params['mysql.max_allowed_packet']) - self.mysql.setConfiguration('mysqld','max_allowed_packet',params['mysql.max_allowed_packet']) - - # start MySQL - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - # ------------------------------------------------------------ - # Check password of MySQL - # ------------------------------------------------------------ - - self.mysql_root_password = params['mysql.root.password'] - if not params.has_key('set.mysql.root.password'): - params['set.mysql.root.password'] = 'false' - setempty = params['set.mysql.root.password'] - if self.mysql.checkMySQLConfiguration(self.mysql_root_password,setempty): - return 1 - - # Create the MySQL database - print "\nCreate/Verify the %s database" % params['jpis.database.name'] - - # Check if database exists - if self.mysql.existsDB(params['jpis.database.name'],self.mysql_root_password) != 0: - # Create database - print ('\n==> Creating MySQL %s database\n' % params['jpis.database.name']) - - if os.path.exists('/bin/rm /tmp/mysql_ct'): - os.remove('/tmp/mysql_ct') - - file = open('/tmp/mysql_ct', 'w') - - self.mysql.add_user(params['jpis.database.name'],params['jpis.database.username'],"",self.mysql_root_password) - text = ['USE %s;\n' % params['jpis.database.name'], - '\. %s/etc/glite-jp-index-dbsetup.sql\n' % os.environ['GLITE_LOCATION']] - - file.writelines(text) - file.close() - os.system('/usr/bin/mysql -p%s < /tmp/mysql_ct' % self.mysql_root_password) - os.system('/bin/rm /tmp/mysql_ct') - - #Starting and stopping the database before the index creation - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - else: - print "\n==> MySQL database %s already exist\n" % params['jpis.database.name'] - - self.mysql.stop() - - return 0 - -#------------------------------------------------------------------------------- -# Set all environment variables -#------------------------------------------------------------------------------- - -def loadDefaults(params): - - params['GLITE_LOCATION'] = "/opt/glite" - params['mysql.root.password'] = "" - params['mysql.max_allowed_packet'] = "17" - params['jpis.serviceName'] = 'JP IS Server service at %s' % glib.fq_hostname - params['jpis.serviceType'] = 'org.glite.jp.index' - params['jpis.statusScript'] = '%s/etc/init.d/glite-jp-indexd status' % params['GLITE_LOCATION'] - params['jpis.endpoint'] = 'not available' - -def set_env(): - - # gLite - glib.export('GLITE_LOCATION'); - glib.export('GLITE_LOCATION_VAR'); - if not os.path.exists(os.environ['GLITE_LOCATION_VAR']): - os.mkdir(os.environ['GLITE_LOCATION_VAR'],0755) - glib.export('GLITE_LOCATION_LOG'); - if not os.path.exists(os.environ['GLITE_LOCATION_LOG']): - os.mkdir(os.environ['GLITE_LOCATION_LOG'],0755) - glib.export('GLITE_LOCATION_TMP'); - if not os.path.exists(os.environ['GLITE_LOCATION_TMP']): - os.mkdir(os.environ['GLITE_LOCATION_TMP'],0755) - - if not params.has_key('glite.user.group'): - params['glite.user.group'] = '' - (uid,gid) = glib.add_user(params['glite.user.name'],params['glite.user.group']) - glib.export('GLITE_USER',params['glite.user.name']) - jpis_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.export('GLITE_HOST_CERT',"%s/hostcert.pem" % jpis_cert_path) - glib.export('GLITE_HOST_KEY',"%s/hostkey.pem" % jpis_cert_path) - glib.export('GLITE_CERT_DIR',params['ca.certificates.dir']) - - glib.export('GLOBUS_LOCATION',params['GLOBUS_LOCATION']) - glib.export('GPT_LOCATION',params['GPT_LOCATION']) - - glib.export('JAVA_HOME') - - # bin and lib paths - glib.addEnvPath("PATH","/usr/bin/:%s/bin:%s/bin:%s/externals/bin:%s/bin" \ - % (os.environ['JAVA_HOME'],os.environ['GLOBUS_LOCATION'],os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - glib.addEnvPath("LD_LIBRARY_PATH","/usr/lib:%s/lib:%s/externals/lib:%s/lib" % (os.environ['GLOBUS_LOCATION'], os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - - # Perl - glib.addEnvPath("PERL5LIB", "%s/lib/perl:%s/lib/perl5" % (os.environ['GPT_LOCATION'],os.environ['GLITE_LOCATION'])) - - # JP IS configuration - glib.export('GLITE_JPIS_PS',params['jpis.ps']) - glib.export('GLITE_JPIS_DEBUG',params['jpis.debug']) - glib.export('GLITE_JPIS_QT',params['jpis.qt']) - glib.export('GLITE_JPIS_AUTH',params['jpis.auth']) - glib.export('GLITE_JPIS_DB',"%s/@localhost:%s" % (params['jpis.database.username'], params['jpis.database.name']) ) - glib.export('GLITE_JPIS_PORT',params['jpis.port']) - glib.export('GLITE_JPIS_PIDFILE',params['jpis.pid.file']) - glib.export('GLITE_JPIS_LOGFILE',params['jpis.log.file']) - - # Set environment - glib.setUserEnv() - -#------------------------------------------------------------------------------- -# Main program begins here -#------------------------------------------------------------------------------- - -if __name__ == '__main__': - - # The script must be run as root - if not os.geteuid()==0: - print '"\nThis script must be run as root\n' - sys.exit(1) - - # Get an instance of the ConfigParams class - params = ConfigParams() - - # Get an instance of the library class - glib = gLib() - - # Load parameters - loadDefaults(params) - try: - opts, args = glib.getopt(sys.argv[1:], '', ['siteconfig=']) - for o, a in opts: - if o == "--siteconfig": - params['site.config.url'] = a - break - except getopt.GetoptError: - pass - if glib.loadConfiguration("%s/../glite-jpis.cfg.xml" % glib.getScriptPath(),params): - print "An error occurred while configuring the service" - sys.exit(1) - - verbose = 0 - if params.has_key('glite.installer.verbose'): - if params['glite.installer.verbose'] == "true": - verbose = 1 - glib.verbose = verbose - - # Set up the environment - set_env() - - - # Instantiate the service classes - service = glite_jpis() - service.verbose = verbose - - # Command line opts if any - try: - opts, args = glib.getopt(sys.argv[1:], 'chv', ['checkconf', 'help', 'version','configure','stop','start','status','siteconfig=']) - except getopt.GetoptError: - service.usage(msg = "Unknown options(s)") - sys.exit(1) - - if len(opts) == 0: - service.usage() - sys.exit(0) - - # Check cli options - for o, a in opts: - if o in ("-h", "--help"): - service.usage() - sys.exit(0) - if o in ("-v", "--version"): - service.showVersion() - sys.exit(0) - if o in ("-c", "--checkconf"): - service.copyright() - service.showVersion() - glib.print_params(params) - sys.exit(0) - - if o == "--configure": - - - # Check certificates - if params.has_key('glite.installer.checkcerts'): - if params['glite.installer.checkcerts'] == "true": - if glib.check_certs(params) != 0: - print "An error occurred while configuring the %s service" \ - % service.friendly_name - sys.exit(1) - - # Print configuration parameters - if verbose: - glib.print_params(params) - - service.copyright() - service.showVersion() - service.banner() - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP IS services...") - service.stop() - - # Configure the service - return_result = service.configure() - - if return_result == 0: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP IS services...") - service.stop() - - print "\n\nThe %s configuration was successfully completed\n" % service.friendly_name - print "You can now start the service using the --start option of this script\n\n" - glib.registerService() - - sys.exit(0) - - elif return_result == 2: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP IS services...") - service.stop() - - print "\n\nThe %s configuration was completed,\n" % service.friendly_name - print "but warnings were issued. Please revise them and re-run the script\n" - print "or configure JP IS manually\n" - - sys.exit(2) - - else: - print "\n\nAn unrecoverable error occurred while configuring the %s" \ - % service.friendly_name - - sys.exit(1) - - if o in ("start", "--start"): - # Start the service - if service.start() == 0: - print "\n\nThe %s was successfully started " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn error occurred while starting the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - - if o in ("stop", "--stop"): - # Stop the service - if service.stop() == 0: - print "\n\nThe %s was successfully stopped " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn unrecoverable error occurred while stopping the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - if o == "--status": - sys.exit(service.status()) - diff --git a/org.glite.deployment.jpis/config/templates/glite-jpis.cfg.xml b/org.glite.deployment.jpis/config/templates/glite-jpis.cfg.xml deleted file mode 100644 index cd56a80..0000000 --- a/org.glite.deployment.jpis/config/templates/glite-jpis.cfg.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpis/project/build.number b/org.glite.deployment.jpis/project/build.number deleted file mode 100644 index 58569c4..0000000 --- a/org.glite.deployment.jpis/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Wed Apr 13 09:36:57 CEST 2005 -module.build=232 diff --git a/org.glite.deployment.jpis/project/build.properties b/org.glite.deployment.jpis/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.deployment.jpis/project/glite-jp.sdf.xml.template b/org.glite.deployment.jpis/project/glite-jp.sdf.xml.template deleted file mode 100644 index d27cdec..0000000 --- a/org.glite.deployment.jpis/project/glite-jp.sdf.xml.template +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpis/project/glite-jpis.sdf.xml.template b/org.glite.deployment.jpis/project/glite-jpis.sdf.xml.template deleted file mode 100644 index d27cdec..0000000 --- a/org.glite.deployment.jpis/project/glite-jpis.sdf.xml.template +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpis/project/lxscript-rpm.xsl b/org.glite.deployment.jpis/project/lxscript-rpm.xsl deleted file mode 100644 index 7b6c6e3..0000000 --- a/org.glite.deployment.jpis/project/lxscript-rpm.xsl +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - - - - - - - - -#!/bin/sh - -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html - -# glite-jpis_installer v. -# -# The glite-jpis_installer installs the gLite Job Provenance Index Server -# -# Usage: glite-jpis_installer [-u|-v|--help] -# -u uninstall -# -v print version -# --help print script usage info -# Return codes: 0 - Ok -# 1 - if a file could not be downloaded - -############################################################################### - -#Parse the RPMLIST to strip out the RPMS that are already installed -function parseRPMList() -{ - newRPMLIST="" - localRPMLIST=`rpm -qa` - for i in $RPMLIST - do - g=`echo $i | sed -e 's/\.i386\.rpm//g'` - g=`echo $g | sed -e 's/\.noarch\.rpm//g'` - if [ -z "`echo $localRPMLIST | grep $g`" ]; then - newRPMLIST="${newRPMLIST} $i" - else - echo "$i is already installed. It will be skipped." - fi - done - - RPMLIST=$newRPMLIST -} - -#Parse the SCRIPTLIST to execute all scripts -function parseScriptList() -{ - for i in $SCRIPTLIST - do - if [ "$INSTALL" = "true" ]; then - $i - else - $i -u - fi - done -} - -#Downloads and install the module RPMS -function install() -{ - - INSTALL=true - version - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, downloading the gLite Job Provenance Index Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - - mkdir -p glite-jpis - cd glite-jpis - - # Download global dependencies - - - true - - - - - - # Download scripts from repository - - - true - - - - - # Download dependencies RPMS from repository - - - true - - - - # Download RPMS from repository - - - true - - - - - - # Download and install subservices - parseScriptList - - - # Install all RPMS - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, installing the gLite Job Provenance Index Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - parseRPMList - if [ ! -z "$RPMLIST" ]; then - rpm -Uvh $RPMLIST - rpm_return=$? - else - echo All required RPMS are already installed - rpm_return=0 - fi - if [ "$rpm_return" == "0" ]; then - echo - echo Done! - echo - echo Before using the gLite JP, please create or update the configuration - echo files /opt/glite/etc/config/glite-jpis.cfg.xml - echo and /opt/glite/etc/config/glite-global.cfg.xml - echo and run the configuration script - echo /opt/glite/etc/config/scripts/glite-jpis-config.py. - echo A template is provided in - echo /opt/glite/etc/config/templates/glite-jpis.cfg.xml - echo Alternatively site configuration files can be used - else - echo - echo An error occurred while installing the JP RPMS. - echo Most likely one or more of the RPMS to be installed require - echo additional dependencies or are older than already installed packages. - echo Please refer to the rpm error message above for more details. - fi - echo - echo For more information refer to the gLite Installation and User Guides - echo or to the gLite web site \(http:\/\/www.glite.org\) - echo Please report problems and comments to the gLite Team at - echo glite-bugs@cern.ch - - cd .. -} - -############################################################################### -function uninstall() -{ - version - - # Global dependencies - - - false - - - - - - # dependencies RPMS from repository - - - false - - - - # RPMS from repository - - - false - - - - - - # Uninstall all RPMS - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, uninstalling the gLite Job Provenance Index Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - rpm -ev $RPMLIST - if [ "$?" == "0" ]; then - echo - echo Done! - else - echo - echo An error occurred while removing the JP RPMS. - echo Most likely one or more of the RPMS to be removed have - echo dependent packages. - echo Please refer to the rpm error message above for more details. - fi -} - -############################################################################### -function usage() -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-jpis_installer v. - echo - echo The glite-jpis_installer installs the gLite Job Provenance Index Server - echo - echo Usage: glite-jpis_installer \[-u\|-v\|--help\] - echo -u uninstall - echo -v print version - echo --help print script usage info - echo - echo Return codes: - echo 0 - Ok - echo 1 - if a file could not be downloaded - echo -} - -############################################################################### -function version -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-jpis_installer v. - echo -} - - -RPMLIST= - -############################################################################### -# Main - -while getopts uvh opt -do - case $opt in - 'u') uninstall - exit 0 - ;; - 'v') version - exit 0 - ;; - 'h') usage - exit 0 - ;; - esac -done - -install - -exit 0 - - - - - _installer.sh - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -chmod u+x -SCRIPTLIST="$SCRIPTLIST ./" - - -SCRIPTLISTUn="$SCRIPTLISTUn ./ -u " - - - - - - - - --..rpm - -- - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - - - --..rpm - -- - - -wget -N -nv /RPMS/ -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - diff --git a/org.glite.deployment.jpis/project/lxscript-tgz.xsl b/org.glite.deployment.jpis/project/lxscript-tgz.xsl deleted file mode 100644 index 8b1e0c0..0000000 --- a/org.glite.deployment.jpis/project/lxscript-tgz.xsl +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - -#!/bin/sh -# -# glite-jpis_tgz_installer -# usage: glite-jpis_tgz_installer [-u] -# -u uninstall -# -# glite-jpis_tgz_installer installs the gLite Deployment Unit from biniary tarballs -# - -PREFIX=/opt/glite - -############################################################################### -# Download global dependencies - - - -############################################################################### - - -############################################################################### -# Download dependencies RPMS from repository - - - -############################################################################### -# Download RPMS from repository - - - -############################################################################### - - - - - - --..rpm -wget - - - - -_bin.tar.gz -wget i386/tgz/ -tar -xzf $PREFIX - - - diff --git a/org.glite.deployment.jpis/project/properties.xml b/org.glite.deployment.jpis/project/properties.xml deleted file mode 100644 index 072dd67..0000000 --- a/org.glite.deployment.jpis/project/properties.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpis/project/quattor-template.xsl b/org.glite.deployment.jpis/project/quattor-template.xsl deleted file mode 100644 index d960582..0000000 --- a/org.glite.deployment.jpis/project/quattor-template.xsl +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - -template pro_software_glite_jpis; - -# -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html -# -# glite-jpis Quattor template v. -# - -## CAs - -include pro_software_glite_CA; - - - -# Global dependencies - - - - - - -# dependencies - - - - -# RPMS - - - - - -include pro_software_; - - - - - - - -"/software/packages"=pkg_repl("","-",""); - - - -"/software/packages"=pkg_repl("","-",""); - - - diff --git a/org.glite.deployment.jpis/project/version.properties b/org.glite.deployment.jpis/project/version.properties deleted file mode 100644 index 809be8c..0000000 --- a/org.glite.deployment.jpis/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ - -module.version = 2.2.0 -module.age = 2 - diff --git a/org.glite.deployment.jpps/build.xml b/org.glite.deployment.jpps/build.xml deleted file mode 100644 index c2bf066..0000000 --- a/org.glite.deployment.jpps/build.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpps/config/scripts/glite-jpps-config.py b/org.glite.deployment.jpps/config/scripts/glite-jpps-config.py deleted file mode 100755 index 3612d6b..0000000 --- a/org.glite.deployment.jpps/config/scripts/glite-jpps-config.py +++ /dev/null @@ -1,500 +0,0 @@ -#!/usr/bin/env python -################################################################################ -# -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://eu-egee.org/partners/ for details on the copyright holders. -# For license conditions see the license file or http://eu-egee.org/license.html -# -################################################################################ -# glite-jpps-config v. 1.0.0 -# -# Post-installation script for configuring the gLite Job Provenance Servers -# Robert Harakaly < mmulac@cern.ch > -# -# Version info: $Id$ -# -# Usage: python glite-jpps-config [-c|-v|-h|--help] -# -c, --checkconf print configuration -# -v, --version print version -# -h,--help print usage info -# --configure configure the service -# --start start the service -# --stop stop the service -# --status show service status -# -# Return codes: 0 - Ok -# 1 - Configuration failed -# -################################################################################ - -import os,string,pwd -import sys, posix, getopt,time - -sys.path.append(".") -from gLiteInstallerLib import gLib -from gLiteInstallerLib import ConfigParams -import mysql as MySQL - -# Set global variables here -global params # all config values from the XML file - -class glite_jpps: - - def __init__(self): - self.mysql = MySQL.Mysql() - self.verbose = 0 - self.version = "1.0.0" - self.name = "glite-jpps" - self.friendly_name = "gLite Job Provenance Primary Storage" - - #------------------------------------------------------------------------------- - # Banner - #------------------------------------------------------------------------------- - - def banner(self): - - print "\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - print "Configuring the %s" % self.friendly_name - print "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" - - #------------------------------------------------------------------------------- - # Copyright - #------------------------------------------------------------------------------- - - def copyright(self): - - print '\nCopyright (c) Members of the EGEE Collaboration. 2004' - print 'See http://eu-egee.org/partners/ for details on the copyright holders' - print 'For license conditions see the license file or http://eu-egee.org/license.html' - - #------------------------------------------------------------------------------- - # Version - #------------------------------------------------------------------------------- - - def showVersion(self): - - print '\n%s-config v. %s\n' % (self.name,self.version) - - #------------------------------------------------------------------------------- - # Usage - #------------------------------------------------------------------------------- - - def usage(self,msg = ""): - - if msg: - print "\n%s" % (msg) - - self.copyright() - self.showVersion() - - print """Usage: \n -Edit the configuration file %s.cfg.xml in -%s/etc.config/templates\n -save it as %s/etc/config/%s.cfg.xml -and run the script as follows\n -python %s-config [OPTION...]""" % (self.name, os.environ['GLITE_LOCATION'], \ - os.environ['GLITE_LOCATION'], self.name, self.name) - - print ' -c, --checkconf print the service configuration' - print ' -v, --version print the version of the configuration script' - print ' -h, --help print this usage information' - print ' --configure configure the service' - print ' --start start the service' - print ' --stop stop the service' - print ' --status check service status' - print '\n' - - #------------------------------------------------------------------------------- - # All the configuration code goes here - #------------------------------------------------------------------------------- - - def start(self): - - self.mysql.start() - time.sleep(5) - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - #------------------------------------------------------------------- - # Start Primary Storage - #------------------------------------------------------------------- - - pid = glib.getPID('primarystoraged') - if pid != 0: - print 'The gLite JP Primary Storage service is already running. Restarting...' - os.system('%s/etc/init.d/glite-jp-primary stop' % os.environ['GLITE_LOCATION']) - else: - print 'Starting the gLite JP Primary Storage service...' - - os.system('%s/etc/init.d/glite-jp-primary start' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('primarystoraged') - - if (pid != 0): - print "The gLite JP Primary Storage service has been started ", - glib.printOkMessage() - else: - glib.printErrorMessage("Could not start the gLite JP Primary Storage service") - glib.printErrorMessage("Please verify and re-run the script "), - glib.printFailedMessage() - return 1 - - return 0 - - def stop(self): - - error_level = 0 - - #------------------------------------------------------------------- - # Stop Primary Storage - #------------------------------------------------------------------- - - pid = glib.getPID('primarystoraged') - if (pid != 0): - os.system('%s/etc/init.d/glite-jp-primary stop' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('primarystoraged') - if (pid != 0): - print 'Could not stop the JP Primary Storage service ', - glib.printFailedMessage() - error_level = 1 - else: - print 'JP Primary Storage service has been stopped ', - glib.printOkMessage() - - #------------------------------------------------------------------- - # MySQL - #------------------------------------------------------------------- - - self.mysql.stop() - - return error_level - - def status(self): - - error_level = 0 - - retval = os.system('%s/etc/init.d/glite-jp-primary status' % os.environ['GLITE_LOCATION']) - if retval != 0: - error_level = 1 - - return error_level - - def configure(self): - - #-------------------------------------------------------- - # Installs the Security Utilities - #-------------------------------------------------------- - - if os.system("python %s/glite-security-utils-config.py --subservice" % glib.getScriptPath()): - print "\nConfiguring gLite Security Utilities ", - glib.printFailedMessage() - else: - print "\nConfiguring gLite Security Utilities ", - glib.printOkMessage() - - # Create the GLITE_USER if it doesn't exists - print "\nCreating/Verifying the GLITE_USER account %s" % os.environ['GLITE_USER'] - (uid,gid) = glib.get_user_info(os.environ['GLITE_USER']) - glib.check_dir(os.environ['GLITE_LOCATION_VAR'],0755, uid, gid) - jpps_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.check_dir(jpps_cert_path ,0755, uid, gid) - glib.printOkMessage() - - # Create all directories needed - glib.check_dir(os.environ['GLITE_CERT_DIR']) - print "\nVerify CA certificates directory ", - glib.printOkMessage() - - # Copy certificates - print "\nCopy host certificates to GLITE_USER home directory as service certificates", - os.system("cp %s %s %s/" % (params['host.certificate.file'], params['host.key.file'], jpps_cert_path)) - os.chown("%s/hostcert.pem" % jpps_cert_path, uid,gid) - os.chmod("%s/hostcert.pem" % jpps_cert_path, 0644) - os.chown("%s/hostkey.pem" % jpps_cert_path, uid,gid) - os.chmod("%s/hostkey.pem" % jpps_cert_path, 0400) - glib.printOkMessage() - - #-------------------------------------------------------- - # Configure MySQL - #-------------------------------------------------------- - - # Set mysql parameters - #self.mysql.setConfiguration('client','max_allowed_packet',params['mysql.max_allowed_packet']) - self.mysql.setConfiguration('mysqld','max_allowed_packet',params['mysql.max_allowed_packet']) - - # start MySQL - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - # ------------------------------------------------------------ - # Check password of MySQL - # ------------------------------------------------------------ - - self.mysql_root_password = params['mysql.root.password'] - if not params.has_key('set.mysql.root.password'): - params['set.mysql.root.password'] = 'false' - setempty = params['set.mysql.root.password'] - if self.mysql.checkMySQLConfiguration(self.mysql_root_password,setempty): - return 1 - - # Create the MySQL database - print "\nCreate/Verify the %s database" % params['jpps.database.name'] - - # Check if database exists - if self.mysql.existsDB(params['jpps.database.name'],self.mysql_root_password) != 0: - # Create database - print ('\n==> Creating MySQL %s database\n' % params['jpps.database.name']) - - if os.path.exists('/bin/rm /tmp/mysql_ct'): - os.remove('/tmp/mysql_ct') - - file = open('/tmp/mysql_ct', 'w') - - self.mysql.add_user(params['jpps.database.name'],params['jpps.database.username'],"",self.mysql_root_password) - text = ['USE %s;\n' % params['jpps.database.name'], - '\. %s/etc/glite-jp-primary-dbsetup.sql\n' % os.environ['GLITE_LOCATION']] - - file.writelines(text) - file.close() - os.system('/usr/bin/mysql -p%s < /tmp/mysql_ct' % self.mysql_root_password) - os.system('/bin/rm /tmp/mysql_ct') - - #Starting and stopping the database before the index creation - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - else: - print "\n==> MySQL database %s already exist\n" % params['jpps.database.name'] - - self.mysql.stop() - - return 0 - -#------------------------------------------------------------------------------- -# Set all environment variables -#------------------------------------------------------------------------------- - -def loadDefaults(params): - - params['GLITE_LOCATION'] = "/opt/glite" - params['mysql.root.password'] = "" - params['mysql.max_allowed_packet'] = "17" - params['jpps.serviceName'] = 'JP PS Server service at %s' % glib.fq_hostname - params['jpps.serviceType'] = 'org.glite.jp.primary' - params['jpps.statusScript'] = '%s/etc/init.d/glite-jp-primary status' % params['GLITE_LOCATION'] - params['jpps.endpoint'] = 'not available' - -def set_env(): - - # gLite - glib.export('GLITE_LOCATION'); - glib.export('GLITE_LOCATION_VAR'); - if not os.path.exists(os.environ['GLITE_LOCATION_VAR']): - os.mkdir(os.environ['GLITE_LOCATION_VAR'],0755) - glib.export('GLITE_LOCATION_LOG'); - if not os.path.exists(os.environ['GLITE_LOCATION_LOG']): - os.mkdir(os.environ['GLITE_LOCATION_LOG'],0755) - glib.export('GLITE_LOCATION_TMP'); - if not os.path.exists(os.environ['GLITE_LOCATION_TMP']): - os.mkdir(os.environ['GLITE_LOCATION_TMP'],0755) - - if not params.has_key('glite.user.group'): - params['glite.user.group'] = '' - (uid,gid) = glib.add_user(params['glite.user.name'],params['glite.user.group']) - glib.export('GLITE_USER',params['glite.user.name']) - jpps_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.export('GLITE_HOST_CERT',"%s/hostcert.pem" % jpps_cert_path) - glib.export('GLITE_HOST_KEY',"%s/hostkey.pem" % jpps_cert_path) - glib.export('GLITE_CERT_DIR',params['ca.certificates.dir']) - - glib.export('GLOBUS_LOCATION',params['GLOBUS_LOCATION']) - glib.export('GPT_LOCATION',params['GPT_LOCATION']) - - glib.export('JAVA_HOME') - - # bin and lib paths - glib.addEnvPath("PATH","/usr/bin/:%s/bin:%s/bin:%s/externals/bin:%s/bin" \ - % (os.environ['JAVA_HOME'],os.environ['GLOBUS_LOCATION'],os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - glib.addEnvPath("LD_LIBRARY_PATH","/usr/lib:%s/lib:%s/externals/lib:%s/lib" % (os.environ['GLOBUS_LOCATION'], os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - - # Perl - glib.addEnvPath("PERL5LIB", "%s/lib/perl:%s/lib/perl5" % (os.environ['GPT_LOCATION'],os.environ['GLITE_LOCATION'])) - - # JP PS configuration - glib.export('GLITE_JP_PRIMARY_PEERS',params['jpps.peers']) - glib.export('GLITE_JP_PRIMARY_FTP_PORT',params['jpps.ftp.port']) - glib.export('GLITE_JP_PRIMARY_INTERNAL',params['jpps.internal']) - if not os.path.exists(os.environ['GLITE_JP_PRIMARY_INTERNAL']): - os.mkdir(os.environ['GLITE_JP_PRIMARY_INTERNAL'],0755) - import socket - glib.export('GLITE_JP_PRIMARY_EXTERNAL',"gsiftp://%s:%s%s" % (socket.getfqdn(socket.gethostname()), params['jpps.ftp.port'], params['jpps.internal']) ) - if not os.path.exists(params['jpps.internal']): - os.mkdir(params['jpps.internal'],0755) - #glite_setenv.sh does not like variables with spaces, - #and su don't like variables with " - #glib.export('GLITE_JP_DEBUG',params['jpps.debug']) - os.environ['GLITE_JP_DEBUG']='%s' % params['jpps.debug'] - glib.export('GLITE_JP_PRIMARY_PORT',params['jpps.port']) - glib.export('GLITE_JP_PRIMARY_DBCS',"%s/@localhost:%s" % (params['jpps.database.username'], params['jpps.database.name']) ) - glib.export('GLITE_JP_PRIMARY_PIDFILE',params['jpps.pid.file']) - - # Set environment - glib.setUserEnv() - -#------------------------------------------------------------------------------- -# Main program begins here -#------------------------------------------------------------------------------- - -if __name__ == '__main__': - - # The script must be run as root - if not os.geteuid()==0: - print '"\nThis script must be run as root\n' - sys.exit(1) - - # Get an instance of the ConfigParams class - params = ConfigParams() - - # Get an instance of the library class - glib = gLib() - - # Load parameters - loadDefaults(params) - try: - opts, args = glib.getopt(sys.argv[1:], '', ['siteconfig=']) - for o, a in opts: - if o == "--siteconfig": - params['site.config.url'] = a - break - except getopt.GetoptError: - pass - if glib.loadConfiguration("%s/../glite-jpps.cfg.xml" % glib.getScriptPath(),params): - print "An error occurred while configuring the service" - sys.exit(1) - - verbose = 0 - if params.has_key('glite.installer.verbose'): - if params['glite.installer.verbose'] == "true": - verbose = 1 - glib.verbose = verbose - - # Set up the environment - set_env() - - - # Instantiate the service classes - service = glite_jpps() - service.verbose = verbose - - # Command line opts if any - try: - opts, args = glib.getopt(sys.argv[1:], 'chv', ['checkconf', 'help', 'version','configure','stop','start','status','siteconfig=']) - except getopt.GetoptError: - service.usage(msg = "Unknown options(s)") - sys.exit(1) - - if len(opts) == 0: - service.usage() - sys.exit(0) - - # Check cli options - for o, a in opts: - if o in ("-h", "--help"): - service.usage() - sys.exit(0) - if o in ("-v", "--version"): - service.showVersion() - sys.exit(0) - if o in ("-c", "--checkconf"): - service.copyright() - service.showVersion() - glib.print_params(params) - sys.exit(0) - - if o == "--configure": - - - # Check certificates - if params.has_key('glite.installer.checkcerts'): - if params['glite.installer.checkcerts'] == "true": - if glib.check_certs(params) != 0: - print "An error occurred while configuring the %s service" \ - % service.friendly_name - sys.exit(1) - - # Print configuration parameters - if verbose: - glib.print_params(params) - - service.copyright() - service.showVersion() - service.banner() - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP PS services...") - service.stop() - - # Configure the service - return_result = service.configure() - - if return_result == 0: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP PS services...") - service.stop() - - print "\n\nThe %s configuration was successfully completed\n" % service.friendly_name - print "You can now start the service using the --start option of this script\n\n" - glib.registerService() - - sys.exit(0) - - elif return_result == 2: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running JP PS services...") - service.stop() - - print "\n\nThe %s configuration was completed,\n" % service.friendly_name - print "but warnings were issued. Please revise them and re-run the script\n" - print "or configure JP PS manually\n" - - sys.exit(2) - - else: - print "\n\nAn unrecoverable error occurred while configuring the %s" \ - % service.friendly_name - - sys.exit(1) - - if o in ("start", "--start"): - # Start the service - if service.start() == 0: - print "\n\nThe %s was successfully started " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn error occurred while starting the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - - if o in ("stop", "--stop"): - # Stop the service - if service.stop() == 0: - print "\n\nThe %s was successfully stopped " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn unrecoverable error occurred while stopping the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - if o == "--status": - sys.exit(service.status()) - diff --git a/org.glite.deployment.jpps/config/templates/glite-jpps.cfg.xml b/org.glite.deployment.jpps/config/templates/glite-jpps.cfg.xml deleted file mode 100644 index ef13a02..0000000 --- a/org.glite.deployment.jpps/config/templates/glite-jpps.cfg.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpps/project/build.number b/org.glite.deployment.jpps/project/build.number deleted file mode 100644 index 58569c4..0000000 --- a/org.glite.deployment.jpps/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Wed Apr 13 09:36:57 CEST 2005 -module.build=232 diff --git a/org.glite.deployment.jpps/project/build.properties b/org.glite.deployment.jpps/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.deployment.jpps/project/glite-jpps.sdf.xml.template b/org.glite.deployment.jpps/project/glite-jpps.sdf.xml.template deleted file mode 100644 index ec2b692..0000000 --- a/org.glite.deployment.jpps/project/glite-jpps.sdf.xml.template +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpps/project/lxscript-rpm.xsl b/org.glite.deployment.jpps/project/lxscript-rpm.xsl deleted file mode 100644 index c9bec9a..0000000 --- a/org.glite.deployment.jpps/project/lxscript-rpm.xsl +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - - - - - - - - -#!/bin/sh - -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html - -# glite-jpps_installer v. -# -# The glite-jpps_installer installs the gLite Job Provenance Primary Storage -# -# Usage: glite-jpps_installer [-u|-v|--help] -# -u uninstall -# -v print version -# --help print script usage info -# Return codes: 0 - Ok -# 1 - if a file could not be downloaded - -############################################################################### - -#Parse the RPMLIST to strip out the RPMS that are already installed -function parseRPMList() -{ - newRPMLIST="" - localRPMLIST=`rpm -qa` - for i in $RPMLIST - do - g=`echo $i | sed -e 's/\.i386\.rpm//g'` - g=`echo $g | sed -e 's/\.noarch\.rpm//g'` - if [ -z "`echo $localRPMLIST | grep $g`" ]; then - newRPMLIST="${newRPMLIST} $i" - else - echo "$i is already installed. It will be skipped." - fi - done - - RPMLIST=$newRPMLIST -} - -#Parse the SCRIPTLIST to execute all scripts -function parseScriptList() -{ - for i in $SCRIPTLIST - do - if [ "$INSTALL" = "true" ]; then - $i - else - $i -u - fi - done -} - -#Downloads and install the module RPMS -function install() -{ - - INSTALL=true - version - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, downloading the gLite Job Provenance Primary Storage... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - - mkdir -p glite-jpps - cd glite-jpps - - # Download global dependencies - - - true - - - - - - # Download scripts from repository - - - true - - - - - # Download dependencies RPMS from repository - - - true - - - - # Download RPMS from repository - - - true - - - - - - # Download and install subservices - parseScriptList - - - # Install all RPMS - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, installing the gLite Job Provenance Primary Storage... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - parseRPMList - if [ ! -z "$RPMLIST" ]; then - rpm -Uvh $RPMLIST - rpm_return=$? - else - echo All required RPMS are already installed - rpm_return=0 - fi - if [ "$rpm_return" == "0" ]; then - echo - echo Done! - echo - echo Before using the gLite JP PS, please create or update the configuration - echo files /opt/glite/etc/config/glite-jpps.cfg.xml - echo and /opt/glite/etc/config/glite-global.cfg.xml - echo and run the configuration script - echo /opt/glite/etc/config/scripts/glite-jpps-config.py. - echo A template is provided in - echo /opt/glite/etc/config/templates/glite-jpps.cfg.xml - echo Alternatively site configuration files can be used - else - echo - echo An error occurred while installing the JP PS RPMS. - echo Most likely one or more of the RPMS to be installed require - echo additional dependencies or are older than already installed packages. - echo Please refer to the rpm error message above for more details. - fi - echo - echo For more information refer to the gLite Installation and User Guides - echo or to the gLite web site \(http:\/\/www.glite.org\) - echo Please report problems and comments to the gLite Team at - echo glite-bugs@cern.ch - - cd .. -} - -############################################################################### -function uninstall() -{ - version - - # Global dependencies - - - false - - - - - - # dependencies RPMS from repository - - - false - - - - # RPMS from repository - - - false - - - - - - # Uninstall all RPMS - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, uninstalling the gLite Job Provenance Primary Storage... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - rpm -ev $RPMLIST - if [ "$?" == "0" ]; then - echo - echo Done! - else - echo - echo An error occurred while removing the JP PS RPMS. - echo Most likely one or more of the RPMS to be removed have - echo dependent packages. - echo Please refer to the rpm error message above for more details. - fi -} - -############################################################################### -function usage() -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-jpps_installer v. - echo - echo The glite-jpps_installer installs the gLite Job Provenance Primary Storage - echo - echo Usage: glite-jpps_installer \[-u\|-v\|--help\] - echo -u uninstall - echo -v print version - echo --help print script usage info - echo - echo Return codes: - echo 0 - Ok - echo 1 - if a file could not be downloaded - echo -} - -############################################################################### -function version -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-jpps_installer v. - echo -} - - -RPMLIST= - -############################################################################### -# Main - -while getopts uvh opt -do - case $opt in - 'u') uninstall - exit 0 - ;; - 'v') version - exit 0 - ;; - 'h') usage - exit 0 - ;; - esac -done - -install - -exit 0 - - - - - _installer.sh - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -chmod u+x -SCRIPTLIST="$SCRIPTLIST ./" - - -SCRIPTLISTUn="$SCRIPTLISTUn ./ -u " - - - - - - - - --..rpm - -- - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - - - --..rpm - -- - - -wget -N -nv /RPMS/ -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - diff --git a/org.glite.deployment.jpps/project/lxscript-tgz.xsl b/org.glite.deployment.jpps/project/lxscript-tgz.xsl deleted file mode 100644 index 4589cf6..0000000 --- a/org.glite.deployment.jpps/project/lxscript-tgz.xsl +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - -#!/bin/sh -# -# glite-jpps_tgz_installer -# usage: glite-jpps_tgz_installer [-u] -# -u uninstall -# -# glite-jpps_tgz_installer installs the gLite Deployment Unit from biniary tarballs -# - -PREFIX=/opt/glite - -############################################################################### -# Download global dependencies - - - -############################################################################### - - -############################################################################### -# Download dependencies RPMS from repository - - - -############################################################################### -# Download RPMS from repository - - - -############################################################################### - - - - - - --..rpm -wget - - - - -_bin.tar.gz -wget i386/tgz/ -tar -xzf $PREFIX - - - diff --git a/org.glite.deployment.jpps/project/properties.xml b/org.glite.deployment.jpps/project/properties.xml deleted file mode 100644 index 41d9f99..0000000 --- a/org.glite.deployment.jpps/project/properties.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.jpps/project/quattor-template.xsl b/org.glite.deployment.jpps/project/quattor-template.xsl deleted file mode 100644 index d4dc67b..0000000 --- a/org.glite.deployment.jpps/project/quattor-template.xsl +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - -template pro_software_glite_jpps; - -# -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html -# -# glite-jpps Quattor template v. -# - -## CAs - -include pro_software_glite_CA; - - - -# Global dependencies - - - - - - -# dependencies - - - - -# RPMS - - - - - -include pro_software_; - - - - - - - -"/software/packages"=pkg_repl("","-",""); - - - -"/software/packages"=pkg_repl("","-",""); - - - diff --git a/org.glite.deployment.jpps/project/version.properties b/org.glite.deployment.jpps/project/version.properties deleted file mode 100644 index 809be8c..0000000 --- a/org.glite.deployment.jpps/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ - -module.version = 2.2.0 -module.age = 2 - diff --git a/org.glite.deployment.lb/.cvsignore b/org.glite.deployment.lb/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.deployment.lb/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.deployment.lb/CHANGELOG b/org.glite.deployment.lb/CHANGELOG deleted file mode 100644 index 882b0d8..0000000 --- a/org.glite.deployment.lb/CHANGELOG +++ /dev/null @@ -1,40 +0,0 @@ -DATE: 13-03-2006 16:20 -[flammer] Increased version to 2.3.0 after branching. - -DATE: 13-03-2006 16:15 -[flammer] Merge of HEAD with branch 2.1.0 -[flammer] Increased version to 2.2.0 - -DATE: 04-12-2005 21:15 -[dimeglio] Added configuration parameter for setting mysql max_allowed_packet - -DATE: 23-11-2005 23:50 -[dimeglio] Use ConfigParams class -[dimeglio] Removed servietool instabce config params, put instance creation in script - -DATE: 08-07-2005 15:20 -[dimeglio] Merged from branch 1.2.2 - -DATE: 25-05-2005 20:00 -[dimeglio] Merged from branch 1.2.2 - -DATE: 21-03-2005 17:21 -[dimeglio] Implemented status method - -DATE: 21-03-2005 00:32 -[dimeglio] Added PERL5LIB env var - -DATE: 17-03-2005 17:33 -[gdiez] Stopping and starting the database before the index creation (just after the database is created and the user granted) - -DATE: 09-03-2005 23:05 -[dimeglio] Moved creation of indices inside database creation (if database - exists indices are not recreated) - -DATE: 02-03-2005 11:05 -[dimeglio] Started CHANGELOG -[dimeglio] Fixed formatting, improved display of message using glib.printXxxMessage functions -[dimeglio] Fixed some problems when starting/stopping services -[dimeglio] GLITE_USER parameter not exposed anymore in config file, use same user parameters - as WMS to allow installation on same node -[dimeglio] Increased module version number to 1.2.0 \ No newline at end of file diff --git a/org.glite.deployment.lb/LICENSE b/org.glite.deployment.lb/LICENSE deleted file mode 100644 index 259a91f..0000000 --- a/org.glite.deployment.lb/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.deployment.lb/build.xml b/org.glite.deployment.lb/build.xml deleted file mode 100644 index 874c661..0000000 --- a/org.glite.deployment.lb/build.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.lb/config/scripts/glite-lb-config.py b/org.glite.deployment.lb/config/scripts/glite-lb-config.py deleted file mode 100644 index c0158ea..0000000 --- a/org.glite.deployment.lb/config/scripts/glite-lb-config.py +++ /dev/null @@ -1,574 +0,0 @@ -#!/usr/bin/env python -################################################################################ -# -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://eu-egee.org/partners/ for details on the copyright holders. -# For license conditions see the license file or http://eu-egee.org/license.html -# -################################################################################ -# glite-lb-config v. 2.3.0 -# -# Post-installation script for configuring the gLite Logging and Bookkeping Server -# Robert Harakaly < robert.harakaly@cern.ch > -# Diana Bosio -# Leanne Guy -# -# Version info: $Id$ -# -# Usage: python glite-lb-config [-c|-v|-h|--help] -# -c, --checkconf print configuration -# -v, --version print version -# -h,--help print usage info -# --configure configure the service -# --start start the service -# --stop stop the service -# --status show service status -# -# Return codes: 0 - Ok -# 1 - Configuration failed -# -################################################################################ - -import os,string,pwd -import sys, posix, getopt,time - -sys.path.append(".") -from gLiteInstallerLib import gLib -from gLiteInstallerLib import ConfigParams -from gliteRgmaServicetool import gliteRgmaServicetoolInstance -from gliteRgmaServicetool import gliteRgmaServicetool -import mysql as MySQL - -# Set global variables here -global params # all config values from the XML file -global rgmaServicetool - -class glite_lb: - - def __init__(self): - self.mysql = MySQL.Mysql() - self.verbose = 0 - self.version = "2.3.0" - self.name = "glite-lb" - self.friendly_name = "gLite Logging and Bookkeeping" - - #------------------------------------------------------------------------------- - # Banner - #------------------------------------------------------------------------------- - - def banner(self): - - print "\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - print "Configuring the %s" % self.friendly_name - print "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" - - #------------------------------------------------------------------------------- - # Copyright - #------------------------------------------------------------------------------- - - def copyright(self): - - print '\nCopyright (c) Members of the EGEE Collaboration. 2004' - print 'See http://eu-egee.org/partners/ for details on the copyright holders' - print 'For license conditions see the license file or http://eu-egee.org/license.html' - - #------------------------------------------------------------------------------- - # Version - #------------------------------------------------------------------------------- - - def showVersion(self): - - print '\n%s-config v. %s\n' % (self.name,self.version) - - #------------------------------------------------------------------------------- - # Usage - #------------------------------------------------------------------------------- - - def usage(self,msg = ""): - - if msg: - print "\n%s" % (msg) - - self.copyright() - self.showVersion() - - print """Usage: \n -Edit the configuration file %s.cfg.xml in -%s/etc.config/templates\n -save it as %s/etc/config/%s.cfg.xml -and run the script as follows\n -python %s-config [OPTION...]""" % (self.name, os.environ['GLITE_LOCATION'], \ - os.environ['GLITE_LOCATION'], self.name, self.name) - - print ' -c, --checkconf print the service configuration' - print ' -v, --version print the version of the configuration script' - print ' -h, --help print this usage information' - print ' --configure configure the service' - print ' --start start the service' - print ' --stop stop the service' - print ' --status check service status' - print '\n' - - #------------------------------------------------------------------------------- - # All the configuration code goes here - #------------------------------------------------------------------------------- - - def start(self): - - self.mysql.start() - time.sleep(5) - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - pid = glib.getPID('bkserverd') - if pid != 0: - print 'The gLite LB Server service is already running. Restarting...' - os.system('%s/etc/init.d/glite-lb-bkserverd stop' % os.environ['GLITE_LOCATION']) - else: - print 'Starting the gLite LB Server service...' - - os.system('%s/etc/init.d/glite-lb-bkserverd start' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('bkserverd') - - if (pid != 0): - print "The gLite LB Server service has been started ", - glib.printOkMessage() - else: - glib.printErrorMessage("Could not start the gLite LB Server service") - glib.printErrorMessage("Please verify and re-run the script "), - glib.printFailedMessage() - return 1 - - #------------------------------------------------------------------- - # Start Servicetool - #------------------------------------------------------------------- - - if params['rgma.servicetool.activate'] == "true": - - errorcode = rgmaServicetool.start() - if (errorcode != 0): - return 1 - - return 0 - - def stop(self): - - error_level = 0 - - pid = glib.getPID('bkserverd') - if (pid != 0): - os.system('%s/etc/init.d/glite-lb-bkserverd stop' % os.environ['GLITE_LOCATION']) - - pid = glib.getPID('bkserverd') - if (pid != 0): - print 'Could not stop the LB Server service ', - glib.printFailedMessage() - error_level = 1 - else: - print 'The LB Server service has been stopped ', - glib.printOkMessage() - - #------------------------------------------------------------------- - # MySQL - #------------------------------------------------------------------- - - self.mysql.stop() - - #------------------------------------------------------------------- - # Servicetool - #------------------------------------------------------------------- - - if params['rgma.servicetool.activate'] == "true": - - if rgmaServicetool.stop(): - error_level = 1 - - return error_level - - def status(self): - - error_level = 0 - - retval = os.system('%s/etc/init.d/glite-lb-bkserverd status' % os.environ['GLITE_LOCATION']) - if retval != 0: - error_level = 1 - - #------------------------------------------------------------------- - # Servicetool - #------------------------------------------------------------------- - - if params['rgma.servicetool.activate'] == "true": - - if rgmaServicetool.status() != 0: - error_level = 1 - - return error_level - - def configure(self): - - #-------------------------------------------------------- - # Installs the Security Utilities - #-------------------------------------------------------- - - if os.system("python %s/glite-security-utils-config.py --subservice" % glib.getScriptPath()): - print "\nConfiguring gLite Security Utilities ", - glib.printFailedMessage() - else: - print "\nConfiguring gLite Security Utilities ", - glib.printOkMessage() - - # Create the GLITE_USER if it doesn't exists - print "\nCreating/Verifying the GLITE_USER account %s" % os.environ['GLITE_USER'] - (uid,gid) = glib.get_user_info(os.environ['GLITE_USER']) - glib.check_dir(os.environ['GLITE_LOCATION_VAR'],0755, uid, gid) - lb_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.check_dir(lb_cert_path ,0755, uid, gid) - glib.printOkMessage() - - # Create all directories needed - glib.check_dir(os.environ['GLITE_CERT_DIR']) - print "\nVerify CA certificates directory ", - glib.printOkMessage() - - # Copy certificates - print "\nCopy host certificates to GLITE_USER home directory as service certificates", - os.system("cp %s %s %s/" % (params['host.certificate.file'], params['host.key.file'], lb_cert_path)) - os.chown("%s/hostcert.pem" % lb_cert_path, uid,gid) - os.chmod("%s/hostcert.pem" % lb_cert_path, 0644) - os.chown("%s/hostkey.pem" % lb_cert_path, uid,gid) - os.chmod("%s/hostkey.pem" % lb_cert_path, 0400) - glib.printOkMessage() - - #-------------------------------------------------------- - # Configure MySQL - #-------------------------------------------------------- - - # Set mysql parameters - #self.mysql.setConfiguration('mysql','loose-max_allowed_packet',params['mysql.max_allowed_packet']) - self.mysql.setConfiguration('mysqld','max_allowed_packet',params['mysql.max_allowed_packet']) - - # start MySQL - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - if not os.path.exists('/tmp/mysql.sock'): - os.symlink('/var/lib/mysql/mysql.sock', '/tmp/mysql.sock') - - # ------------------------------------------------------------ - # Check password of MySQL - # ------------------------------------------------------------ - - self.mysql_root_password = params['mysql.root.password'] - if not params.has_key('set.mysql.root.password'): - params['set.mysql.root.password'] = 'false' - setempty = params['set.mysql.root.password'] - if self.mysql.checkMySQLConfiguration(self.mysql_root_password,setempty): - return 1 - - # Create the MySQL database - print "\nCreate/Verify the %s database" % params['lb.database.name'] - - # Check if database exists - if self.mysql.existsDB(params['lb.database.name'],self.mysql_root_password) != 0: - # Create database - print ('\n==> Creating MySQL %s database\n' % params['lb.database.name']) - - if os.path.exists('/bin/rm /tmp/mysql_ct'): - os.remove('/tmp/mysql_ct') - - file = open('/tmp/mysql_ct', 'w') - - self.mysql.add_user(params['lb.database.name'],params['lb.database.username'],"",self.mysql_root_password) - text = ['USE %s;\n' % params['lb.database.name'], - '\. %s/etc/glite-lb-dbsetup.sql\n' % os.environ['GLITE_LOCATION']] - - file.writelines(text) - file.close() - os.system('/usr/bin/mysql -p%s < /tmp/mysql_ct' % self.mysql_root_password) - os.system('/bin/rm /tmp/mysql_ct') - - #Starting and stopping the database before the index creation - self.mysql.stop() - time.sleep(5) - self.mysql.start() - - #Creating the indexes - print 'Creating the index configuration file %s/etc/glite-lb-index.conf ' % os.environ['GLITE_LOCATION'], - path = "%s/etc/glite-lb-index.conf" % os.environ['GLITE_LOCATION'] - pathBak = "%s/etc/glite-lb-index.conf.bak" % os.environ['GLITE_LOCATION'] - - if os.path.exists(pathBak): - os.remove(pathBak) - if os.path.exists(path): - os.rename(path,pathBak) - file = open(path, 'w') - file.write("[\n") - file.write(" JobIndices = {\n") - for index in params['lb.index.list']: - file.write(" [ type = \"system\"; name = \"%s\" ],\n" % index) - file.write(" }\n") - file.write("]\n") - file.close() - glib.printOkMessage() - - print "Running glite-lb-bkindex ", - if os.system('%s/bin/glite-lb-bkindex -r %s/etc/glite-lb-index.conf' % (os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])): - glib.printFailedMessage() - return 1 - else: - glib.printOkMessage() - - else: - print "\n==> MySQL database %s already exist\n" % params['lb.database.name'] - - self.mysql.stop() - - #------------------------------------------------------------------- - # RGMA servicetool: configure servicetool - #------------------------------------------------------------------- - - if params['rgma.servicetool.activate'] == "true": - - # Instantiate the rgma-servicetool class - rgmaServicetool = gliteRgmaServicetool() - rgmaServicetool.verbose = self.verbose - - # Create Local Logger instance - serviceId = "%s_%s" % (glib.fq_hostname, params['lbserver.serviceType']) - servicetoolInstance = gliteRgmaServicetoolInstance(glib, serviceId) - - # set params - servicetoolInstance.setServiceName(params['lbserver.serviceName']) - servicetoolInstance.setServiceType(params['lbserver.serviceType']) - servicetoolInstance.setServiceVersion(self.version) - servicetoolInstance.setStatusScript(params['lbserver.statusScript']) - servicetoolInstance.setEndpoint(params['lbserver.endpoint']) - - # add instance to the gLite configuration - if servicetoolInstance.add() == 1: - return 1 - - # Configure servicetool - if rgmaServicetool.configure(glib): - # error in configuring servicetool - return 1 - - return 0 - -#------------------------------------------------------------------------------- -# Set all environment variables -#------------------------------------------------------------------------------- - -def loadDefaults(params): - - params['GLITE_LOCATION'] = "/opt/glite" - params['mysql.root.password'] = "" - params['lb.database.name'] = "lbserver20" - params['lb.database.username'] = "lbserver" - params['mysql.max_allowed_packet'] = "17" - - params['lbserver.serviceName'] = 'LB Server service at %s' % glib.fq_hostname - params['lbserver.serviceType'] = 'org.glite.lb.server' - params['lbserver.statusScript'] = '%s/etc/init.d/glite-lb-bkserverd status' % params['GLITE_LOCATION'] - params['lbserver.endpoint'] = 'not available' - -def set_env(): - - # gLite - glib.export('GLITE_LOCATION'); - glib.export('GLITE_LOCATION_VAR'); - if not os.path.exists(os.environ['GLITE_LOCATION_VAR']): - os.mkdir(os.environ['GLITE_LOCATION_VAR'],0755) - glib.export('GLITE_LOCATION_LOG'); - if not os.path.exists(os.environ['GLITE_LOCATION_LOG']): - os.mkdir(os.environ['GLITE_LOCATION_LOG'],0755) - glib.export('GLITE_LOCATION_TMP'); - if not os.path.exists(os.environ['GLITE_LOCATION_TMP']): - os.mkdir(os.environ['GLITE_LOCATION_TMP'],0755) - - if not params.has_key('glite.user.group'): - params['glite.user.group'] = '' - (uid,gid) = glib.add_user(params['glite.user.name'],params['glite.user.group']) - glib.export('GLITE_USER',params['glite.user.name']) - lb_cert_path = pwd.getpwnam(os.environ['GLITE_USER'])[5] + "/" + params['user.certificate.path'] - glib.export('GLITE_HOST_CERT',"%s/hostcert.pem" % lb_cert_path) - glib.export('GLITE_HOST_KEY',"%s/hostkey.pem" % lb_cert_path) - glib.export('GLITE_CERT_DIR',params['ca.certificates.dir']) - - glib.export('GLOBUS_LOCATION',params['GLOBUS_LOCATION']) - glib.export('GPT_LOCATION',params['GPT_LOCATION']) - - glib.export('JAVA_HOME') - - # bin and lib paths - glib.addEnvPath("PATH","/usr/bin/:%s/bin:%s/bin:%s/externals/bin:%s/bin" \ - % (os.environ['JAVA_HOME'],os.environ['GLOBUS_LOCATION'],os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - glib.addEnvPath("LD_LIBRARY_PATH","/usr/lib:%s/lib:%s/externals/lib:%s/lib" % (os.environ['GLOBUS_LOCATION'], os.environ['GLITE_LOCATION'],os.environ['GLITE_LOCATION'])) - - # Perl - glib.addEnvPath("PERL5LIB", "%s/lib/perl:%s/lib/perl5" % (os.environ['GPT_LOCATION'],os.environ['GLITE_LOCATION'])) - - # Set environment - glib.setUserEnv() - -#------------------------------------------------------------------------------- -# Main program begins here -#------------------------------------------------------------------------------- - -if __name__ == '__main__': - - # The script must be run as root - if not os.geteuid()==0: - print '"\nThis script must be run as root\n' - sys.exit(1) - - # Get an instance of the ConfigParams class - params = ConfigParams() - - # Get an instance of the library class - glib = gLib() - - # Load parameters - loadDefaults(params) - try: - opts, args = glib.getopt(sys.argv[1:], '', ['siteconfig=']) - for o, a in opts: - if o == "--siteconfig": - params['site.config.url'] = a - break - except getopt.GetoptError: - pass - if glib.loadConfiguration(["%s/../glite-lb.cfg.xml" % glib.getScriptPath(), \ - "%s/../glite-rgma-servicetool.cfg.xml" % glib.getScriptPath()],params): - print "An error occurred while configuring the service" - sys.exit(1) - - verbose = 0 - if params.has_key('glite.installer.verbose'): - if params['glite.installer.verbose'] == "true": - verbose = 1 - glib.verbose = verbose - - # Set up the environment - set_env() - - # Instantiate the service classes - service = glite_lb() - service.verbose = verbose - # Instantiate the rgma servicetool class - rgmaServicetool = gliteRgmaServicetool() - rgmaServicetool.verbose = verbose - - # Command line opts if any - try: - opts, args = glib.getopt(sys.argv[1:], 'chv', ['checkconf', 'help', 'version','configure','stop','start','status','siteconfig=']) - except getopt.GetoptError: - service.usage(msg = "Unknown options(s)") - sys.exit(1) - - if len(opts) == 0: - service.usage() - sys.exit(0) - - # Check cli options - for o, a in opts: - - if o in ("-h", "--help"): - service.usage() - sys.exit(0) - - if o in ("-v", "--version"): - service.showVersion() - sys.exit(0) - - if o in ("-c", "--checkconf"): - service.copyright() - service.showVersion() - glib.print_params(params) - print - rgmaServicetool.showServices() - sys.exit(0) - - if o == "--configure": - - # Check certificates - if params.has_key('glite.installer.checkcerts'): - if params['glite.installer.checkcerts'] == "true": - if glib.check_certs(params) != 0: - print "An error occurred while configuring the %s service" \ - % service.friendly_name - sys.exit(1) - - # Print configuration parameters - if verbose: - glib.print_params(params) - - service.copyright() - service.showVersion() - service.banner() - - # Stop all services - glib.printInfoMessage("\n\nStopping all running LB services...") - service.stop() - - # Configure the service - return_result = service.configure() - - if return_result == 0: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running LB services...") - service.stop() - - print "\n\nThe %s configuration was successfully completed\n" % service.friendly_name - print "You can now start the service using the --start option of this script\n\n" - glib.registerService() - - sys.exit(0) - - elif return_result == 2: - - # Stop all services - glib.printInfoMessage("\n\nStopping all running LB services...") - service.stop() - - print "\n\nThe %s configuration was completed,\n" % service.friendly_name - print "but warnings were issued. Please revise them and re-run the script\n" - print "or configure LB manually\n" - - sys.exit(2) - - else: - print "\n\nAn unrecoverable error occurred while configuring the %s" \ - % service.friendly_name - - sys.exit(1) - - if o in ("start", "--start"): - # Start the service - if service.start() == 0: - print "\n\nThe %s was successfully started " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn error occurred while starting the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - - if o in ("stop", "--stop"): - # Stop the service - if service.stop() == 0: - print "\n\nThe %s was successfully stopped " % service.friendly_name, - glib.printOkMessage() - sys.exit(0) - else: - print "\n\nAn unrecoverable error occurred while stopping the %s " % service.friendly_name, - glib.printFailedMessage() - sys.exit(1) - - if o == "--status": - sys.exit(service.status()) - diff --git a/org.glite.deployment.lb/config/templates/glite-lb.cfg.xml b/org.glite.deployment.lb/config/templates/glite-lb.cfg.xml deleted file mode 100644 index 4e11e33..0000000 --- a/org.glite.deployment.lb/config/templates/glite-lb.cfg.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - owner - location - destination - - - - - - diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.doc b/org.glite.deployment.lb/doc/release_notes/release_notes.doc deleted file mode 100644 index 2ad2d4d1bf359419707777ee266496f87aa65f73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 192512 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 diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.html b/org.glite.deployment.lb/doc/release_notes/release_notes.html deleted file mode 100644 index 01ee3f4..0000000 --- a/org.glite.deployment.lb/doc/release_notes/release_notes.html +++ /dev/null @@ -1,2712 +0,0 @@ - - - - - -gLite LB Server Release Notes - - - - - - -
- -

gLite Logging & Bookkeeping Server

- -

1. Release Description

- -

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

- -

2. Changes in this release

- -

2.1. Changes in functionality

- -

There are no functional changes in this -release.

- -

2.2. Changes in Configuration

- -

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

- -

 

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

Parameter name

-
-

Default value

-
-

Description

-
-

rgma.servicetool.activate

-
-

true

-
-

Turn on/off servicetool for the node.

-

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

-
-

set.mysql.root.password

-
-

false

-
-

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

-

[Example: false][Type: boolean]

-
-

mysql.max_allowed_packet

-
-

17

-
-

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

-

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

-
- -

 

- -

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

- -

 

- -

3. Release contents

- -

3.1. Glite sub-deployment modules

- -

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

- -

 

- -

-          -gLite Security Utilities

- -

-          -gLite R-GMA Servicetool

- -

 

- -

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

- -

3.2. Glite RPMS

- -

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

- -

 

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

Component name

-
-

Description

-
-

Version

-
-

File

-
-

glite-config

-
-

gLite configuration scripts

-
-

1.6.22

-
-

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

-
-

glite-jp-common

-
-

 

-
-

1.1.0

-
-

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

-
-

glite-jp-primary

-
-

 

-
-

1.1.1

-
-

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

-
-

glite-jp-server-common

-
-

 

-
-

1.0.0

-
-

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

-
-

glite-jp-ws-interface

-
-

 

-
-

1.1.0

-
-

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

-
-

glite-lb-client-interface

-
-

L&B client library header files

-
-

2.1.0

-
-

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

-
-

glite-lb-config

-
-

gLite LB Configuration files

-
-

2.1.1

-
-

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

-
-

glite-lb-common

-
-

L&B common subroutines library

-
-

3.0.1

-
-

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

-
-

glite-lb-logger

-
-

L&B local logger

-
-

1.2.1

-
-

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

-
-

glite-lb-server

-
-

L&B bookkeeping server

-
-

1.3.3

-
-

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

-
-

glite-lb-server-bones

-
-

L&B server bones

-
-

2.1.1

-
-

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

-
-

glite-lb-ws-interface

-
-

 

-
-

2.1.0

-
-

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

-
-

glite-rgma-servicetool-config

-
-

gLite R-GMA servicetool installation

-
-

5.2.2

-
-

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

-
-

glite-security-gsoap-plugin

-
-

gSOAP plugin and gss libraries

-
-

1.2.1

-
-

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

-
-

glite-security-utils-config

-
-

gLite Security Utilities configuration files

-
-

1.2.1

-
-

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

-
-

glite-security-voms-api-c

-
-

 

-
-

1.6.10

-
-

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

-
-

glite-wms-utils-exception

-
-

 

-
-

1.0.3

-
-

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

-
-

glite-wms-utils-jobid

-
-

 

-
-

1.0.2

-
-

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

-
- -

4. Dependencies

- -

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

- -

 

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

Component name

-
-

Description

-
-

Version

-
-

RPM file name

-
-

c-ares

-
-

A library that performs asynchronous DNS operations

-
-

1.3.0

-
-

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

-
-

gpt

-
-

The Grid Packaging Toolkit (GPT)

-
-

VDT1.2.2rh9

-
-

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

-
-

gridsite

-
-

GridSite

-
-

1.1.15

-
-

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

-
-

j2re

-
-

Java JRE

-
-

1.4.2

-
-

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

-
-

myproxy

-
-

Credential repository for the Grid.

-
-

1.14

-
-

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

-
-

MySQL-client

-
-

MySQL - Client

-
-

4.1.11

-
-

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

-
-

MySQL-server

-
-

MySQL

-
-

4.1.11

-
-

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

-
-

perl-Expect.pm

-
-

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

-
-

1.01

-
-

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

-
-

vdt_globus_essentials

-
-

Virtual Data Toolkit

-
-

VDT1.2.2rh9

-
-

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

-
- -

 

- -

5. Known bugs and issues

- -

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

- -

 

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

 

- -

Known open bugs:

- -

 

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

Bug number

-
-

Description

-
-

 

-
-

 #7324

-
-

lb-bkserver is running with no - pid

-
-

 

-
-

 #9701

-
-

erroneous rpath in several - shared objects

-
-

 

-
-

 #9777

-
-

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

-
-

 

-
-

 #10781

-
-

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

-
-

 

-
-

 #11535

-
-

Job submission extremely slow

-
-

 

-
-

 #13418

-
-

problem in computing status (of - resubmitted jobs)

-
-

 

-
-

 #13492

-
-

Job State Information Log File

-
-

 

-
-

 #13832

-
-

Default mysql configuration - imposes unnecessary limits on LB server

-
-

 

-
-

 #13879

-
-

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

-
-

 

-
-

 #13929

-
-

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

-
-

 

-
-

 #13951

-
-

lb proxy sends garbage response - on error

-
-

 

-
-

 #13988

-
-

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

-
-

 

-
-

 #14247

-
-

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

-
-

 

-
-

 #14339

-
-

Wrong computing state when - proxy expires

-
-

 

-
- -

 

- -

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

- -

 

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

Bug number

-
-

Description

-
-

 

-
-

 #7307

-
-

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

-
-

 

-
-

 #7305

-
-

lb.database.username paramenter in - config file

-
-

 

-
-

 #7300

-
-

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

-
-

 

-
-

 #7053

-
-

LB configuration fails if the - mysql root pwd is set

-
-

 

-
-

 #13928

-
-

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

-
-

 

-
-

 #13048

-
-

interlogger does not handle errors - from bookkeeping server

-
-

 

-
-

 #12648

-
-

The memory usage of one LB process - keeps growing

-
-

 

-
-

 #11387

-
-

LBProxy SIGSEGV

-
-

 

-
-

 #11050

-
-

Too heavy locallogger retry - strategy

-
-

 

-
-

 #9183

-
-

Broken connections in LB contect - connection pool

-
-

 

-
-

 #9135

-
-

The interlogd has problem sending - event to the LB server

-
-

 

-
-

 #8630

-
-

EDG_WL_* variables in LB library

-
-

 

-
-

 #7910

-
-

Duplicate apostroph in MySQL calls

-
-

 

-
-

 #11509

-
-

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

-
-

 

-
-

 #10686

-
-

MySQL library fails on hostnames - containing dashes

-
-

 

-
- -

 

- -

6. Bugs closed since last release

- -

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

- -

 

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

Bug number

-
-

Description

-
-

 

-
-

 #6722

-
-

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

-
-

 

-
-

 #7237

-
-

Intermittent errors with job - submission

-
-

 

-
-

 #9148

-
-

Job stays 'Submitted' forever

-
-

 

-
-

 #10730

-
-

Error on glite-job-submit

-
-

 

-
- -

 

- -
- - - - diff --git a/org.glite.deployment.lb/doc/release_notes/release_notes.pdf b/org.glite.deployment.lb/doc/release_notes/release_notes.pdf deleted file mode 100644 index c512e91ddfd865b103c95e44d4642062ba7b9b67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157326 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š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 Sa^rAhUhZ}4w2gFlx&If#fv92t diff --git a/org.glite.deployment.lb/project/.cvsignore b/org.glite.deployment.lb/project/.cvsignore deleted file mode 100644 index caf4eaa..0000000 --- a/org.glite.deployment.lb/project/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -glite-lb.sdf.xml diff --git a/org.glite.deployment.lb/project/build.number b/org.glite.deployment.lb/project/build.number deleted file mode 100644 index 306b97f..0000000 --- a/org.glite.deployment.lb/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Mon Mar 13 07:52:27 CET 2006 -module.build=0326 diff --git a/org.glite.deployment.lb/project/build.properties b/org.glite.deployment.lb/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.deployment.lb/project/glite-lb.sdf.xml.template b/org.glite.deployment.lb/project/glite-lb.sdf.xml.template deleted file mode 100644 index 48d94a7..0000000 --- a/org.glite.deployment.lb/project/glite-lb.sdf.xml.template +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.lb/project/lxscript-rpm.xsl b/org.glite.deployment.lb/project/lxscript-rpm.xsl deleted file mode 100644 index c661ad7..0000000 --- a/org.glite.deployment.lb/project/lxscript-rpm.xsl +++ /dev/null @@ -1,336 +0,0 @@ - - - - - - - - - - - - - -#!/bin/sh - -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html - -# glite-lb_installer v. -# -# The glite-lb_installer installs the gLite Logging and Bookkeeping Server -# -# Usage: glite-lb_installer [-u|-v|--help] -# -u uninstall -# -v print version -# --help print script usage info -# Return codes: 0 - Ok -# 1 - if a file could not be downloaded - -############################################################################### - -#Parse the RPMLIST to strip out the RPMS that are already installed -function parseRPMList() -{ - newRPMLIST="" - localRPMLIST=`rpm -qa` - for i in $RPMLIST - do - g=`echo $i | sed -e 's/\.i386\.rpm//g'` - g=`echo $g | sed -e 's/\.noarch\.rpm//g'` - if [ -z "`echo $localRPMLIST | grep $g`" ]; then - newRPMLIST="${newRPMLIST} $i" - else - echo "$i is already installed. It will be skipped." - fi - done - - RPMLIST=$newRPMLIST -} - -#Parse the SCRIPTLIST to execute all scripts -function parseScriptList() -{ - for i in $SCRIPTLIST - do - if [ "$INSTALL" = "true" ]; then - $i - else - $i -u - fi - done -} - -#Downloads and install the module RPMS -function install() -{ - - INSTALL=true - version - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, downloading the gLite Logging and Bookkeeping Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - - mkdir -p glite-lb - cd glite-lb - - # Download global dependencies - - - true - - - - - - # Download scripts from repository - - - true - - - - - # Download dependencies RPMS from repository - - - true - - - - # Download RPMS from repository - - - true - - - - - - # Download and install subservices - parseScriptList - - - # Install all RPMS - echo - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, installing the gLite Logging and Bookkeeping Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - parseRPMList - if [ ! -z "$RPMLIST" ]; then - rpm -Uvh $RPMLIST - rpm_return=$? - else - echo All required RPMS are already installed - rpm_return=0 - fi - if [ "$rpm_return" == "0" ]; then - echo - echo Done! - echo - echo Before using the gLite LB, please create or update the configuration - echo files /opt/glite/etc/config/glite-lb.cfg.xml - echo and /opt/glite/etc/config/glite-global.cfg.xml - echo and run the configuration script - echo /opt/glite/etc/config/scripts/glite-lb-config.py. - echo A template is provided in - echo /opt/glite/etc/config/templates/glite-lb.cfg.xml - echo Alternatively site configuration files can be used - else - echo - echo An error occurred while installing the LB RPMS. - echo Most likely one or more of the RPMS to be installed require - echo additional dependencies or are older than already installed packages. - echo Please refer to the rpm error message above for more details. - fi - echo - echo For more information refer to the gLite Installation and User Guides - echo or to the gLite web site \(http:\/\/www.glite.org\) - echo Please report problems and comments to the gLite Team at - echo glite-bugs@cern.ch - - cd .. -} - -############################################################################### -function uninstall() -{ - version - - # Global dependencies - - - false - - - - - - # dependencies RPMS from repository - - - false - - - - # RPMS from repository - - - false - - - - - - # Uninstall all RPMS - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo x Please wait, uninstalling the gLite Logging and Bookkeeping Server... x - echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - echo - rpm -ev $RPMLIST - if [ "$?" == "0" ]; then - echo - echo Done! - else - echo - echo An error occurred while removing the LB RPMS. - echo Most likely one or more of the RPMS to be removed have - echo dependent packages. - echo Please refer to the rpm error message above for more details. - fi -} - -############################################################################### -function usage() -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-lb_installer v. - echo - echo The glite-lb_installer installs the gLite Logging and Bookkeeping Server - echo - echo Usage: glite-lb_installer \[-u\|-v\|--help\] - echo -u uninstall - echo -v print version - echo --help print script usage info - echo - echo Return codes: - echo 0 - Ok - echo 1 - if a file could not be downloaded - echo -} - -############################################################################### -function version -{ - echo - echo Copyright \(c\) Members of the EGEE Collaboration. 2004 - echo See http://eu-egee.org/partners/ for details on the copyright holders - echo For license conditions see the license file or http://eu-egee.org/license.html - echo - echo glite-lb_installer v. - echo -} - - -RPMLIST= - -############################################################################### -# Main - -while getopts uvh opt -do - case $opt in - 'u') uninstall - exit 0 - ;; - 'v') version - exit 0 - ;; - 'h') usage - exit 0 - ;; - esac -done - -install - -exit 0 - - - - - _installer.sh - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -chmod u+x -SCRIPTLIST="$SCRIPTLIST ./" - - -SCRIPTLISTUn="$SCRIPTLISTUn ./ -u " - - - - - - - - --..rpm - -- - - -wget -N -nv -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - - - --..rpm - -- - - -wget -N -nv /RPMS/ -if [ ! -f "" ] -then - echo - echo ERROR: could not be downloaded! - exit 1 -fi -RPMLIST="$RPMLIST " - - -RPMLIST="$RPMLIST " - - - - - diff --git a/org.glite.deployment.lb/project/lxscript-tgz.xsl b/org.glite.deployment.lb/project/lxscript-tgz.xsl deleted file mode 100644 index 5b55e40..0000000 --- a/org.glite.deployment.lb/project/lxscript-tgz.xsl +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - -#!/bin/sh -# -# glite-lb_tgz_installer -# usage: glite-lb_tgz_installer [-u] -# -u uninstall -# -# glite-lb_tgz_installer installs the gLite Deployment Unit from biniary tarballs -# - -PREFIX=/opt/glite - -############################################################################### -# Download global dependencies - - - -############################################################################### - - -############################################################################### -# Download dependencies RPMS from repository - - - -############################################################################### -# Download RPMS from repository - - - -############################################################################### - - - - - - --..rpm -wget - - - - -_bin.tar.gz -wget i386/tgz/ -tar -xzf $PREFIX - - - diff --git a/org.glite.deployment.lb/project/properties.xml b/org.glite.deployment.lb/project/properties.xml deleted file mode 100644 index ef87369..0000000 --- a/org.glite.deployment.lb/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.deployment.lb/project/quattor-template.xsl b/org.glite.deployment.lb/project/quattor-template.xsl deleted file mode 100644 index 74f841d..0000000 --- a/org.glite.deployment.lb/project/quattor-template.xsl +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - -template pro_software_glite_lb; - -# -# Copyright (c) Members of the EGEE Collaboration. 2004 -# See http://eu-egee.org/partners/ for details on the copyright holders -# For license conditions see the license file or http://eu-egee.org/license.html -# -# glite-lb Quattor template v. -# - -## CAs - -include pro_software_glite_CA; - - - -# Global dependencies - - - - - - -# dependencies - - - - -# RPMS - - - - - -include pro_software_; - - - - - - - -"/software/packages"=pkg_repl("","-",""); - - - -"/software/packages"=pkg_repl("","-",""); - - - diff --git a/org.glite.deployment.lb/project/version.properties b/org.glite.deployment.lb/project/version.properties deleted file mode 100644 index bb1d337..0000000 --- a/org.glite.deployment.lb/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ - -module.version = 2.3.0 -module.age = 0 - \ No newline at end of file diff --git a/org.glite.jobid.api-c/Makefile b/org.glite.jobid.api-c/Makefile deleted file mode 100644 index 8c1cbde..0000000 --- a/org.glite.jobid.api-c/Makefile +++ /dev/null @@ -1,94 +0,0 @@ -# Default values -top_srcdir=.. -stagedir=. -globalprefix=glite -jobidprefix=jobid -package=glite-jobid-api-c -version=0.0.0 - -CC:=gcc -CXX:=g++ - --include Makefile.inc --include ${top_srcdir}/project/version.properties - -version=${module.version} - -VPATH=${top_srcdir}/src:${top_srcdir}/interface:${top_srcdir}/test - -DEBUG:=-g -O0 -Wall - -CFLAGS:=${DEBUG} \ - -I${top_srcdir}/interface -I${top_srcdir}/src \ - ${COVERAGE_FLAGS} \ - -D_GNU_SOURCE ${CFLAGS} - -COMPILE:=libtool --mode=compile ${CC} ${CFLAGS} -CXXCOMPILE:=libtool --mode=compile ${CXX} ${CXXFLAGS} -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install - -LIBOBJS:=cjobid.o strmd5.o -HDRS:=cjobid.h strmd5.h - -LIBLOBJS:=${LIBOBJS:.o=.lo} - -LIB:=libglite_jobid.la - -os=${shell uname} -DL_LIBS:= -ifeq (${os},Linux) - DL_LIBS:=-ldl -endif -TEST_LIBS:=-L${cppunit_prefix}/${libdir} -lcppunit ${DL_LIBS} -TEST_INC:=-I${cppunit_prefix}/include - -compile all: ${LIB} - -# In order to use libtool versioning correcty, we must have: -# -# current = major + minor + offset -# revision = patch -# age = minor -# -# where offset is a sum of maximal released minor's of all previous major's -# - -# counted minors: 1.0 -offset=0 -version_info:=-version-info ${shell \ - perl -e '$$,=":"; @F=split /\./,"${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } - -${LIB}: ${LIBOBJS} - ${LINK} ${version_info} -o $@ ${LIBLOBJS} -rpath ${stagedir}${prefix}/${libdir} - -check: compile base64_test - ./base64_test base64_test.xml - -base64_test: %: %.cpp compile - ${CXX} -c ${CFLAGS} ${TEST_INC} $< - ${LINKXX} -o $@ $@.o ${LIB} ${TEST_LIBS} - -clean: - rm -rvf *.o *.lo .libs/ lib* *.c *.cpp *.h - rm -vf base64_test base64_test.xml - -distclean: - rm -rvf Makefile.inc *.spec debian/ - -stage: - $(MAKE) install PREFIX=${stagedir} - -install: ${LIB} - mkdir -p ${DESTDIR}${PREFIX}${prefix}/${libdir} - mkdir -p ${DESTDIR}${PREFIX}${prefix}/include/${globalprefix}/${jobidprefix} - ${INSTALL} -m 755 ${LIB} ${DESTDIR}${PREFIX}${prefix}/${libdir} - (cd ${top_srcdir}/interface; ${INSTALL} -m 644 ${HDRS} ${DESTDIR}${PREFIX}${prefix}/include/${globalprefix}/${jobidprefix}) - - -%.lo %.o: %.c - ${COMPILE} -o $@ -c $< - - -.PHONY: default all compile check stage install clean distclean diff --git a/org.glite.jobid.api-c/configure b/org.glite.jobid.api-c/configure deleted file mode 100755 index bcb1531..0000000 --- a/org.glite.jobid.api-c/configure +++ /dev/null @@ -1,2058 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; -use POSIX qw(locale_h strftime); - -my $pwd = `pwd`; chomp $pwd; -my $prefix = '/usr'; -my $stagedir = undef; -my $root = $pwd.'/stage'; -my $sysroot = ''; -my $sysconfdir; -my $localstatedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my ($version, $force_version); -my $branch; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $jobid_tag = ''; -my $libdir = getlibdir(); -my $project = 'emi'; -my $project_version; -my (%projects, %project); -my $debug = 0; -my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : ''; - -my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal/; -my @default_nodes = qw/lb px proxyrenewal nagios/; -my %enable_nodes; -my %disable_nodes; -my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1); - -my %package = ( - 'maintainer' => 'CESNET Product Teams ', - 'uploaders' => 'FrantiÅ¡ek Dvořák ', - 'url' => 'http://glite.cern.ch', - 'debian_vcs' => 'Vcs-Cvs: :pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw -Vcs-Browser: http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi', -); - -# key: internal package name (arguments, ...) -# 'pkg': pkg-config name -# 'prefix': used when pkg-config fails -my %externs = ( - cares => { - prefix => '/opt/c-ares', - pkg => 'libcares' - }, - classads => { - prefix=> '/usr', - pkg => 'classads' - }, - cppunit => { - prefix=> '/usr', - pkg => 'cppunit' - }, - expat => { - prefix=> '/usr', - pkg => 'expat' - }, - globus => { - prefix=> '/opt/globus', - pkg => 'globus-gssapi-gsi' - }, - 'myproxy-devel' => { - prefix=> '/opt/globus', - pkg => 'myproxy' - }, - 'myproxy-server' => { - prefix=> '', - }, - 'myproxy-admin' => { - prefix=> '', - }, - gsoap => { - prefix=> '/usr', - pkg => 'gsoap' - }, - gsoapxx => { - prefix=> '/usr', - pkg => 'gsoap++' - }, - mysql => { - prefix=> '/usr' - }, - 'mysql-devel' => { - prefix=> '' - }, - 'mysql-server' => { - prefix => '' - }, - voms => { - prefix => '/opt/glite', - pkg => 'voms-2.0' - }, - gridsite => { - prefix => '/opt/glite' - }, - lcas => { - prefix => '/opt/glite', - pkg => 'lcas' - }, - trustmanager => { - prefix => '/opt/glite' - }, - trustmanager_axis => { - prefix => '/opt/glite' - }, - utiljava => { - prefix=> '/opt/glite' - }, - ant => { - prefix=> '/usr' - }, - jdk => { - prefix=> '/usr/java/latest', - locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ], - }, - libtar => { - prefix=> '/usr' - }, - axis => { - prefix=> '/usr' - }, - log4c => { - prefix=> '/usr' - }, - postgresql => { - prefix=> '/usr' - }, - activemq => { - prefix=>'/opt/activemq-cpp-library', - pkg => 'activemq-cpp' - }, -); - -my %jar = ( - 'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar', - 'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %buildroot; -my (%etics_externs, %etics_projects); - -# -# modules of the subsystems -# -# additional modules from $project{modules} are automatically added -# -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], - 'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/], - 'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - 'gridsite' => [ qw/apache libs commands core devel slashgrid services service-clients gsexec/ ], - 'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ], - 'canl' => [ qw/c c-devel/ ], - ); - -# -# sub-packages -# -# modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly -# -my %subpackages = ( - 'jobid.api-c-devel' => 'jobid.api-c', - 'jobid.api-cpp-devel' => 'jobid.api-cpp', - 'lbjp-common.db-devel' => 'lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'lbjp-common.log', - 'lbjp-common.maildir-devel' => 'lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'lbjp-common.trio', - 'lb.client-progs' => 'lb.client', - 'lb.client-devel' => 'lb.client', - 'lb.common-devel' => 'lb.common', - 'lb.logger-devel' => 'lb.logger', - 'lb.state-machine-devel' => 'lb.state-machine', - 'px.proxyrenewal-devel' => 'px.proxyrenewal', - 'px.proxyrenewal-progs' => 'px.proxyrenewal', - 'canl.c-devel' => 'canl.c', -); - -my @opts = ( - 'prefix:s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour:s' => \$thrflavour, - 'nothrflavour:s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$force_version, - 'branch=s' => \$branch, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'root:s' => \$root, - 'sysroot:s' => \$sysroot, - 'sysconfdir=s' => \$sysconfdir, - 'localstatedir=s' => \$localstatedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'jobid-tag=s' => \$jobid_tag, - 'canl-tag=s' => \$canl_tag, - 'help' => \$help, - 'libdir=s' => \$libdir, - 'project=s' => \$project, - 'debug' => \$debug, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; -$prefix=~s/\/$//; -$root=~s/\/$//; -$sysroot=~s/\/$//; -if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; } -if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; } -$sysconfdir=~s/\/$//; -$localstatedir=~s/\/$//; - -$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq ''; -$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq ''; -$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq ''; - -$externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq ''; -$externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq ''; -$externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq ''; - -if ($project =~ /^([^0-9]*)(.*)$/) { - $project = $1; - $project_version = $2; -} -%project = %{$projects{$project}}; -$project_version = $project{current_version} unless $project_version; -for my $platform (keys %{$project{etics_externs}}) { - for $_ (keys %{$project{etics_externs}{$platform}}) { - $etics_externs{$platform}{$_} = $project{etics_externs}{$platform}{$_}; - } -} -reshuffle_platforms(\%etics_externs, $project{supported_platforms}); -reshuffle_platforms(\%{$project{etics_externs_devel}}, $project{supported_platforms}); -for $_ (keys %{$project{etics_projects}}) { - $etics_projects{$_} = $project{etics_projects}{$_}; -} -for $_ (keys %{$project{need_externs_aux}}) { - $need_externs_aux{$_} = $project{need_externs_aux}{$_}; -} -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - my ($pkg, $type) =/([^:]*)(?::(.*))?/; - $type = 'BR' unless ($type); - - push @{$need_externs{$ext}},$pkg; - $need_externs_type{$ext}->{$pkg} = $type; - } -} -if ($project eq 'emi') { - $extranodmod{lb} = 'lb.emi-lb'; - $extranodmod{px} = 'px.emi-px'; -} -for $_ (keys %{$project{modules}}) { - push @{$lbmodules{$_}},@{$project{modules}{$_}}; -} - - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name}; - my @m; - - if (exists $lbmodules{$listmodules}) { - @m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}}; - } else { - if ($project eq 'emi' and $project_version == 1) { - # no sub-packages in EMI-1 - } else { - for my $sub (keys %subpackages) { - push @m, $sub if ($subpackages{$sub} eq $listmodules); - } - } - } - print map $_ eq "" ? "" : "$_ ", @m; - print "\n"; - exit 0; -} - -warn "$0: --branch and --output make sense only in --mode=etics\n" - if ($output || $branch) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_}); - } -} - -if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } }; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $root unless $stagedir; -$stagedir=~s/\/$// if ($stagedir); - -if ($mode eq 'build') { for my $ext (keys %externs) { - if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; } - elsif (defined $externs{$ext}{pkg}) { - my ($flag, $env, $cmd, $ret); - my $pkg = $externs{$ext}{pkg}; - my $flagname = uc $externs{$ext}{pkg}; - $flagname =~ s/-[0-9\.]*$//; - $flagname =~ y/-\+/_X/; - - print "Checking $pkg ... "; - $env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig"; - $cmd = "$env pkg-config $pkg --exists >/dev/null"; - `$cmd`; $ret = $?; - print "('$cmd' => $ret)\n" if ($debug); - if ($ret == 0) { - $externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`; - chomp $externs{$ext}{prefix}; - print "$externs{$ext}{prefix}\n"; - - $flag=`$env pkg-config $pkg --cflags`; - $externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag); - $flag=`$env pkg-config $pkg --libs`; - $externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag); - } else { - print "(using default $externs{$ext}{prefix})\n"; - } - print "\n" if ($debug); - } - elsif ($ext eq 'jdk') { - my $jdk_prefix; - - print "Looking for some caffein ... "; - if (defined $ENV{'JDK_HOME'}) { - $jdk_prefix = $ENV{'JDK_HOME'}; - print "JDK_HOME=$jdk_prefix\n"; - } elsif (defined $ENV{'JAVA_HOME'}) { - $jdk_prefix = $ENV{'JAVA_HOME'}; - print "JAVA_HOME=$jdk_prefix\n"; - } else { - foreach my $i (0..$#{$externs{$ext}{locations}}) { - if (-e $externs{$ext}{locations}[$i]) { - $jdk_prefix=$externs{$ext}{locations}[$i]; - print "(found directory $jdk_prefix)\n"; - last; - } - } - print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix); - } - $externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix); - } -} } - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') { - print CONF "$_=$ENV{$_} " if (defined $ENV{$_}); - } - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } }; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - if ($module) { - print "Not creating summary Makefile\n" if $debug; - } else { - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\n"; - print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n"; - print MAK "clean check install:\n"; - - for (@modules) { - my $full = full($_); - print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $buildroot{$_} eq '' ? - "\tcd $full && \${MAKE} distclean\n" : - "\trm -rf $full/$buildroot{$_}\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage'; - - my $full = full($_); - my $build = $buildroot{$_}; - - print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n"; - print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n"; - } - - close MAK; - } -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag) { - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - if ($canl_tag) { - for (@{$lbmodules{'canl'}}){ - if ("canl.".$_ eq $module){ - $tag = '-r '.$canl_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%etics_externs = ( - default => { - 'myproxy-devel'=>'myproxy-devel', - 'myproxy-server'=>'myproxy-server', - 'myproxy-admin'=>'myproxy-admin', - cares=>'c-ares', - utiljava=>'org.glite.security.util-java', - gpt=>'gpt', - fetchcrl=>'fetch-crl', - activemq=>'activemq-cpp-library', - }, -); - -%etics_projects = ( -); - -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads libtool:B globus:B/ ], - 'lb.common' => [ qw/expat cares:B cppunit:B classads libtool:B globus:B/ ], - 'lb.doc' => [ qw/tetex-latex:B/ ], - 'lb.logger' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B globus:B/ ], - 'lb.nagios' => [ qw/globus_proxy_utils:R/ ], - 'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql-server:R cppunit:B gsoap:B classads voms:B lcas gridsite:B bison:B libtool:B libxml2 flex:B/ ], - 'lb.state-machine' => [ qw/classads libtool:B libxslt:B expat:B globus:B/ ], - 'lb.utils' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ], - 'lb.ws-test' => [ qw/gsoap:B libtool:B globus:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/docbook-utils:B libtool:B globus:B/ ], - 'lbjp-common.db' => [ qw/mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.log' => [ qw/log4c libtool:B/ ], - 'lbjp-common.maildir' => [ qw/libtool:B/ ], - 'lbjp-common.server-bones' => [ qw/libtool:B/ ], - 'lbjp-common.trio' => [ qw/cppunit:B libtool:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.gss' => [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B/ ], - 'lbjp-common.gsoap-plugin' => [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B/ ], - 'jobid.api-c' => [ qw/cppunit:B libtool:B openssl:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B libtool:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus_essentials:R globus:B mysql-server:R/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B mysql-server:R/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], - 'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'gridsite.commands' => [ qw/curl:R openssl:R/ ], - 'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ], - 'gridsite.libs' => [ qw/libxml2:R openssl:R/ ], - 'gridsite.devel' => [ qw// ], - 'gridsite.slashgrid' => [ qw/curl:R fuse:R/], - 'gridsite.services' => [ qw/curl:R gsoap:R/ ], - 'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ], - 'gridsite.gsexec' => [ qw// ], - 'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B/ ], - 'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec - 'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B krb5-devel:B/ ], -); - -%need_jars = ( - 'jobid.api-java' => [ qw/jakarta-commons-codec/ ], - 'lb.client-java' => [ qw/jakarta-commons-lang/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp:B jobid.api-c - lbjp-common.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - lb.ws-interface:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp:B jobid.api-c - lb.types:B lbjp-common.trio lbjp-common.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - lbjp-common.log - jobid.api-c - lb.common - lbjp-common.gss - / ], - 'lb.logger-msg' => [ qw/ - lb.logger:B - / ], - 'lb.nagios' => [ qw/ - lb.client:R - lb.ws-test:R - lb.utils:R - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log - jobid.api-c - lbjp-common.gsoap-plugin lbjp-common.gss - / ], - 'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine lb.types:B - / ], - 'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/ - jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client - lbjp-common.gss lbjp-common.log - / ], - 'lb.yaim' => [ qw// ], - 'lb.glite-LB' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lb.emi-lb' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.log' => [ qw// ], - 'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ], - 'lbjp-common.trio' => [ qw// ], - 'lbjp-common.gss' => [ qw// ], - 'lbjp-common.gsoap-plugin' => [ qw/lbjp-common.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - lbjp-common.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], - - 'gridsite.core' => [ qw// ], - 'gridsite.commands' => [ qw/gridsite.core:B/ ], - 'gridsite.apache' => [ qw/gridsite.core:B/ ], - 'gridsite.libs' => [ qw/gridsite.core:B / ], - 'gridsite.devel' => [ qw/gridsite.core:B/ ], - 'gridsite.slashgrid' => [ qw/gridsite.core:B/], - 'gridsite.services' => [ qw/gridsite.core:B/ ], - 'gridsite.service-clients' => [ qw/gridsite.core:B/ ], - 'gridsite.gsexec' => [ qw/gridsite.core:B/ ], - - 'px.proxyrenewal' => [ qw// ], - 'px.glite-PX' => [qw/px.myproxy-yaim:R/], - 'px.emi-px' => [qw/px.myproxy-yaim:R/], - 'px.myproxy-yaim' => [ qw// ], - 'px.myproxy-config' => [], - - 'canl.c' => [], - - # sub-packages (virtual ETICS components depending on the main) - 'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ], - 'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ], - 'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ], - 'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ], - 'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ], - 'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ], - 'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ], - 'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ], - 'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ], - 'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ], - 'lb.client-progs' => [ qw/lb.client:B/ ], - 'lb.client-devel' => [ qw/lb.client:B/ ], - 'lb.common-devel' => [ qw/lb.common:B/ ], - 'lb.logger-devel' => [ qw/lb.logger:B/ ], - 'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ], - 'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ], - 'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ], - 'canl.c-devel' => [ qw/canl.c:B/ ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( - gridsite=>'org.gridsite.core', - 'canl.c' => 'emi.canl.canl-c', - 'canl.c-devel' => 'emi.canl.canl-c', - 'jobid.api-c-devel' => 'org.glite.jobid.api-c', - 'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp', - 'lbjp-common.db-devel' => 'org.glite.lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'org.glite.lbjp-common.log', - 'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio', - 'lb.client-devel' => 'org.glite.lb.client', - 'lb.client-progs' => 'org.glite.lb.client', - 'lb.common-devel' => 'org.glite.lb.common', - 'lb.logger-devel' => 'org.glite.lb.logger', - 'lb.state-machine-devel' => 'org.glite.lb.state-machine', - 'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal', - 'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal', -); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', - lb => 'lb.glite-LB', - px => 'px.glite-PX', - proxyrenewal => 'px.proxyrenewal', - canl => 'canl.c', -); - -%obsoletes = ( - 'lb.yaim' => [ qq/glite-yaim-lb/ ], - 'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ], - 'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ], - 'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], -); - -%conflicts = ( -); - -%provides = ( - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], - 'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ], -); - -%cvs_prefix = ( - 'lb' => 'org.glite', - 'jp' => 'org.glite', - 'jobid' => 'org.glite', - 'lbjp-common' => 'org.glite', - 'gridsite' => 'org', - 'px' => 'org.glite', - 'canl' => 'emi', -); - -%cvs_tag_prefix = ( - 'lb' => 'glite-', - 'jp' => 'glite-', - 'jobid' => 'glite-', - 'lbjp-common' => 'glite-', - 'gridsite' => '', - 'px' => 'glite-', - 'canl' => 'emi-', -); - -# ==== projects specification ==== -# etics_name ........... ETICS project name -# conf_prefix .......... ETICS configurations name prefix -# tag_prefix ........... VCS tag prefix -# local_prefix ......... prefix (relative to stage) -# etics_externs ........ ETICS modules names of externals -# (${NAME.location}, ETICS conf. dependencies) -# etics_projects ....... ETICS project names of externals -# etics_externs_devel .. ETICS modules names of devel versions of externals -# etics_locations ...... ETICS locations in ${NAME.location} properties -# need_externs_aux ..... project-specific external dependencies -# supported_platforms .. platforms supported by the project -# modules .............. additional modules in subsystems -%projects = ( - glite => { - current_version => 3, - etics_name => 'org.glite', - conf_prefix => { %cvs_tag_prefix }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}', - local_prefix => '', - etics_externs => { - default => { - globus_essentials=>'vdt_globus_essentials', - globus=>'globus', - globus_proxy_utils=>'vdt_globus_essentials', - gridsite=>'org.gridsite.libs', - yaim_core=>'org.glite.yaim.core', - gip_release=>'glite-info-provider-release', - gip_service=>'glite-info-provider-service', - bdii=>'bdii', - glite_version=>'glite-version', - glite_info_templates=>'glite-info-templates', - glue_schema=>'glue-schema', - trustmanager=>'org.glite.security.trustmanager', - axis=>'axis', - lcas=>'org.glite.security.lcas', - gsoapxx=>'-', - jdk=>'jdk', - voms=>'org.glite.security.voms-api-cpp', - }, - }, - etics_externs_devel => { - default => { - gridsite=>'org.gridsite.devel', - voms=>'org.glite.security.voms-api', - }, - }, - etics_projects => { - vdt=>[qw/globus globus_essentials globus_proxy_utils gpt/], - 'org.glite'=>[qw/voms gridsite lcas gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/], - }, - etics_locations => { - '*' => '', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ], - 'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R/ ], - 'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412 => 1, - sl5_ia32_gcc412 => 1, - deb5_x86_64_gcc432 => 1, - deb5_ia32_gcc432 => 1, - slc4_x86_64_gcc346 => 1, - slc4_ia32_gcc346 => 1, - }, - modules => { - 'lb' => [ qw/glite-LB/ ], - 'px' => [ qw/glite-PX/ ], - }, - }, - - emi => { - current_version => 2, - etics_name => 'emi', - conf_prefix => { - 'lb' => 'emi-', - 'jp' => 'emi-', - 'jobid' => 'emi-', - 'lbjp-common' => 'emi-', - 'gridsite' => 'emi-', - 'px' => 'emi-', - 'canl' => 'emi-', - }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour= --nothrflavour=', - local_prefix => '/usr', - etics_externs => { - default => { - globus_essentials=>'globus-gssapi-gsi', - globus=>'globus-gssapi-gsi-devel', - globus_proxy_utils=>'globus-proxy-utils', - gridsite=>'emi.gridsite.libs', - yaim_core=>'emi.yaim.yaim-core', - yaim_bdii=>'emi.bdii.yaim-bdii', - gip_service=>'emi.bdii.glite-info-provider-service', - bdii=>'emi.bdii.core', - glite_version=>'emi.emi-version', - glue_schema=>'emi.bdii.glue-schema', - trustmanager=>'emi.java-security.trustmanager', - trustmanager_axis=>'emi.java-security.trustmanager-axis', - axis=>'axis1.4', - lcas=>'emi.sac.lcas', - gsoapxx=>'-', - jdk=>'java', - voms => 'emi.voms.voms-api', - }, - sl5_x86_64_gcc412EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - sl6_x86_64_gcc446EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - deb6_x86_64_gcc445 => { - axis => 'axis1.4', - # mappings in ETICS project configuration - #globus_essentials => 'libglobus-gssapi-gsi4', - #globus => 'libglobus-gssapi-gsi-dev', - #axis => 'libaxis-java', - #cares => 'libc-ares2', - #cppunit => 'libcppunit', - #expat => 'libexpat1', - #log4c => 'liblog4c3', - #curl => 'libcurl3', - #'mysql' => 'libmysqlclient16', - #'mysql-devel' => 'libmysqlclient-dev', - #libxslt => 'xsltproc', - #'jakarta-commons-codec' => 'libcommons-codec-java', - #'jakarta-commons-lang' => 'libcommons-lang-java', - #'tetex-latex' => 'texlive-latex-extra', - #'perl-LDAP' => 'libnet-ldap-perl', - #'fuse-lib' => 'libfuse2', - #'fuse' => 'fuse-utils', - }, - }, - etics_externs_devel => { - default => { - cares => 'c-ares-devel', - classads => 'classads-devel', - cppunit => 'cppunit-devel', - expat => 'expat-devel', - gsoap => 'gsoap-devel', - voms => 'emi.voms.voms-api-devel', - libtar => 'libtar-devel', - log4c => 'log4c-devel', - postgresql => 'postgresql-devel', - curl => 'curl-devel', - libxml2 => 'libxml2-devel', - openssl => 'openssl-devel', - gridsite=>'emi.gridsite.devel', - jdk=>'java-devel', - }, - deb6_x86_64_gcc445 => { - # mappings in ETICS project configuration - #cares => 'libc-ares-dev', - #cppunit => 'libcppunit-dev', - #expat => 'libexpat1-dev', - #libtar => 'libtar-dev', - #log4c => 'liblog4c-dev', - #postgresql => 'libpq-dev', - #curl => 'libcurl4-openssl-dev', - #libxml2 => 'libxml2-dev', - #openssl => 'libssl-dev', - #'tetex-latex' => 'texlive-latex-extra', - #libxslt=>'xsltproc', - #'httpd-devel' => 'apache2-prefork-dev', - #'fuse-devel' => 'libfuse-dev', - #gsoap => 'gsoap', - #'krb5-devel' => 'libkrb5-dev', - }, - }, - etics_projects => { - 'emi'=>[qw/voms voms-devel gridsite lcas gip_service bdii glite_version glue_schema yaim_core yaim_bdii trustmanager trustmanager_axis/], - }, - etics_locations => { - axis => 'axis', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ], - 'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - 'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412EPEL => 1, - sl5_ia32_gcc412EPEL => 1, - sl6_x86_64_gcc446EPEL => 1, - deb6_x86_64_gcc445 => 1, - }, - modules => { - 'lb' => [ qw/emi-lb/ ], - 'px' => [ qw/emi-px/ ], - }, - }, -); - -%platform_properties = ( - 'jobid.api-java' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.types' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.doc' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.ws-interface' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.nagios' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.myproxy-config' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'gridsite.devel' => { - default => { 'packageName' => 'gridsite-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' }, - }, - 'jobid.api-c-devel' => { - default => { 'packageName' => 'glite-jobid-api-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' }, - }, - 'jobid.api-cpp-devel' => { - default => { 'packageName' => 'glite-jobid-api-cpp-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' }, - }, - 'lbjp-common.db-devel' => { - default => { 'packageName' => 'glite-lbjp-common-db-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' }, - }, - 'lbjp-common.gsoap-plugin-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' }, - }, - 'lbjp-common.gss-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gss-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' }, - }, - 'lbjp-common.jp-interface-devel' => { - default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' }, - }, - 'lbjp-common.log-devel' => { - default => { 'packageName' => 'glite-lbjp-common-log-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' }, - }, - 'lbjp-common.maildir-devel' => { - default => { 'packageName' => 'glite-lbjp-common-maildir-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' }, - }, - 'lbjp-common.server-bones-devel' => { - default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' }, - }, - 'lbjp-common.trio-devel' => { - default => { 'packageName' => 'glite-lbjp-common-trio-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' }, - }, - 'lb.client-devel' => { - default => { 'packageName' => 'glite-lb-client-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' }, - }, - 'lb.common-devel' => { - default => { 'packageName' => 'glite-lb-common-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' }, - }, - 'lb.state-machine-devel' => { - default => { 'packageName' => 'glite-lb-state-machine-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' }, - }, - 'lb.logger-devel' => { - default => { 'packageName' => 'glite-lb-logger-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' }, - }, - 'px.proxyrenewal-devel' => { - default => { 'packageName' => 'glite-px-proxyrenewal-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' }, - }, -); - -my @k = keys %deps_aux; -@buildroot{@k} = ('') x ($#k+1); - -$buildroot{'gridsite.core'} = 'src'; -} - -sub full -{ - my ($short) = @_; - my $subsys = $short; - $subsys =~ s/\..*//; - - my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite'; - return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short"; -} - -sub get_version -{ - my ($fmod, $top_srcdir) = @_; - - my ($subsys,$mod) = split /\./,$fmod,2; - my ($major,$minor,$rev,$age); - my $old_; - - if ($force_version) { - $force_version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - my $path = "$top_srcdir/project"; - if ($subsys eq 'gridsite') { - $path = "$cvs_prefix{$subsys}.$subsys.core/project"; - } - open V,"$path/version.properties" - or die "$path/version.properties: $!\n"; - - $old_ = $_; - while () { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - $_ = $old_; - } - $version = "$major.$minor.$rev-$age"; - - return ($major, $minor, $rev, $age); -} - -sub get_description -{ - my ($top_srcdir) = @_; - - my $cvs_module = $top_srcdir; - my $package_description = ""; - my $package_summary = ""; - - if (-e "$cvs_module/project/package.description") { - open V, "$cvs_module/project/package.description"; - $package_description = join ("", ); - close V; - chomp $package_description; - } - else { - print STDERR "package.description not found for $subsys.$module!\n"; } - - if (-e "$cvs_module/project/package.summary") { - open V, "$cvs_module/project/package.summary"; - $package_summary = join ("", ); - close V; - chomp $package_summary; - $package_summary =~ s/\n/\\n/g; - } - else { - print STDERR "package.summary not found for $subsys.$module!\n"; } - - return ($package_summary, $package_description); -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb -lbjp-common.gss lbjp-common.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px -canl.c -/; - @aux{@m} = (1) x ($#m+1); - - my ($short) = @_; - my $full = full $short; - my ($subsys,$mod) = split /\./,$short,2; - my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}"; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $top_srcdir = '.'; - my $abs_srcdir = ''; - my $build = ''; - - if ($module) { - $top_srcdir = $0; - $top_srcdir =~ s,/?[^/]*$,,; - $abs_srcdir = $top_srcdir; - $top_srcdir =~ s,^$,\.,; - } else { - $build = "$full/"; - $abs_srcdir = "$full/"; - unless ($buildroot{$_} eq '') { - $top_srcdir = '..'; - $build .= "$buildroot{$_}/"; - unless (-d "$build") { - mkdir "$build" or die "mkdir $build: $!\n"; - } - } - } - - my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir; - my ($package_summary, $package_description) = get_description $abs_srcdir; - if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; } - my $package_description_debian = $package_description; - $package_description_debian =~ s/^/ /mg; - - my ($old_locale, $specdate, $debdate); - - # files for ETICS always in root source directory - mkdir $abs_srcdir."project" unless (-d $abs_srcdir."project"); - open PKGCHL,">".$abs_srcdir."project/changelog" - or die $abs_srcdir."project/changelog: $!\n"; - $old_locale = setlocale(LC_TIME); - setlocale(LC_TIME, "C"); - $specdate = strftime("%a %b %d %Y", gmtime()); - $debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime()); - setlocale(LC_TIME, $old_locale); - print PKGCHL qq{* $specdate CESNET team -- automatically generated package -}; - close PKGCHL; - - unless ($top_srcdir eq '.') { - unlink $build."Makefile"; - symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n"; - } - - open MKINC,">".$build."Makefile.inc" - or die $build."Makefile.inc: $!\n"; - - print "Creating ".$build."Makefile.inc\n"; - - print MKINC qq{project = $project -PREFIX = $root -prefix = $prefix -stagedir = $stagedir -sysroot = $sysroot -sysconfdir = $sysconfdir -localstatedir = $localstatedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -libdir = $libdir -top_srcdir = $top_srcdir -}; - - for (@{$need_externs{$short}}) { - next unless defined $externs{$_} and defined $externs{$_}{prefix}; - print MKINC "${_}_prefix = $externs{$_}{prefix}\n"; - print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags}; - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; - - my $dh; - my $debian = 0; - - opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!"; - for my $dir (readdir $dh) { - if ($dir=~/^(.*)\.spec$/) { - if ($1 ne $packageName) { - printf STDERR "Changed RPM name: $packageName --> $1\n" if ($debug);; - $packageName=$1; - } - last; - } - } - closedir $dh; - - for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") { - if (-f "$abs_srcdir/project/$file") { - my $old_ = $_; - printf STDERR "Creating $build$file\n" if ($debug);; - open DST, ">$build$file"; - open SRC, "<$abs_srcdir/project/$file"; - while () { - if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; } - if (/\@URL\@/) { s/\@URL\@/$package{url}/g; } - if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; } - if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; } - if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; } - if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; } - if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; } - if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; } - if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; } - if (/\@AGE\@/) { s/\@AGE\@/$age/g; } - if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; } - if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; } - if (/\@DEBIAN_VCS\@/) { s/\@DEBIAN_VCS\@/$package{debian_vcs}/g; } - if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; } - if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; } - if (/^\s*.+\/configure\s/ and $force_version) { - print "Version forced to $version\n" if ($debug);; - s/--version\s+\S+\s?//; - s/$/ --version $version/; - } - printf DST "%s", "$_"; - } - close SRC; - close DST; - $_ = $old_; - } - } - - print "Creating ${build}debian/\n" if ($debug);; - - `rm -rfv ${build}debian`; - mkdir $build."debian" or die $!; - `cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`; - `mv ${build}debian.* ${build}debian/ 2>/dev/null`; - `rm -f ${build}debian/*.orig`; - opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!"; - for $_ (readdir $dh) { - if (/^debian\.(.*)/) { - `mv ${build}debian/$_ ${build}debian/$1`; - $debian = 1; - } - } - closedir $dh; - - if ($debian) { - my ($dir, $file); - - chmod 0755, "${build}debian/rules"; - $file="${build}debian/docs"; if (not -f $file) { `touch $file`; } - $dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; } - $file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` } - $file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` } - $file="${build}debian/changelog"; if (not -f $file) { - open FH, ">$file" or die $!; - print FH qq{$packageName ($major.$minor.$rev-$age) unstable; urgency=low - - * Automatically generated package - - -- $package{maintainer} $debdate -}; - close FH; - } - - } else { - `rm -rf ${build}debian`; - } -} - -BEGIN{ -}; - -sub mode_etics_packaging { - my ($fmod, $cmd, $rpmprepare, $debprepare) = @_; - my ($workspaceDir, $srcPackageName, $srcAge, $topDir); - - # old-school packaging by ETICS for EMI-1 - if ($project eq 'emi' and $project_version == 1) { return; } - - if ($fmod eq 'gridsite.core') { - $workspaceDir = '..'; - $srcPackageName = 'gridsite'; - $srcAge = ''; - $topDir = '../'; - } else { - $workspaceDir = '${workspaceDir}'; - $srcPackageName = '${packageName}'; - $srcAge = '-${age}'; - $topDir = ''; - } - - $cmd->{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SRPMSLocation}'; - $cmd->{default}{packaging} = $rpmprepare; - $cmd->{default}{packaging} .= "dir=\${workspaceDir}/rpm_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SRPMSLocation} \$dir/{BUILD,RPMS,SOURCES,SRPMS} 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/SOURCES/ - rpmbuild -bs --nodeps --define \"_topdir \$dir\" $srcPackageName.spec - cp -v \$dir/SRPMS/*.src.rpm \${package.SRPMSLocation}/ - rm -rf \$dir"; - - for my $p ('deb5_x86_64_gcc432', 'deb5_ia32_gcc432', 'deb6_x86_64_gcc445', 'deb6_ia32_gcc445') { - for my $c (keys %{$cmd->{default}}) { $cmd->{$p}{$c} = $cmd->{default}{$c}; } - $cmd->{$p}{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SDEBSLocation}'; - $cmd->{$p}{packaging} = $debprepare; - $cmd->{$p}{packaging} .= "dir=\${workspaceDir}/dpkg_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SDEBSLocation} \$dir 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/${srcPackageName}_\${version}.orig.tar.gz - tar xzf \$dir/${srcPackageName}_\${version}.orig.tar.gz -C \$dir - cp -rf ${topDir}debian/ \$dir/$srcPackageName-\${version}/ - cd \$dir/$srcPackageName-\${version} - dpkg-buildpackage -S -d -nc - cd - - cp -v \$dir/*.tar.gz \$dir/*.dsc \${package.SDEBSLocation}/ - rm -rf \$dir"; - } -} - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod,2; - my $full = full "$subsys.$module"; - - my ($major,$minor,$rev,$age) = get_version $fmod, $full; - - # XXX: --with ignored for platform-dependend packages - my @copts = (); - my %ge; - @ge{@{$etics_projects{$project{etics_name}}}} = (1) x ($#{$etics_projects{$project{etics_name}}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/ and (defined $externs{$_} or defined $jar{$_})) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - next if ($eext eq '-'); - if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}) { - $eext = $project{etics_locations}{$_} if ($project{etics_locations}{$_}); - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } else { - if ($ge{$_} and not defined $externs{$_}{pkg}) { - push @copts, "--with-$_=\${stageDir}"; - } - } - } - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}); - } - - my $conf; - my $conftag; - my ($confprefix, $nameprefix, $packageName); - - $dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n"; - - $confprefix = $project{conf_prefix}{$subsys}; - $nameprefix = $confprefix; - $nameprefix =~ s/-$//; - $nameprefix =~ s/-/\./g; - $packageName = "$project{tag_prefix}{$subsys}$subsys-${module}"; - - if ($branch) { - $conf = "$confprefix${subsys}-${module}_$branch"; - $conftag = $branch; - # forced low age number - $age = $branch eq 'HEAD' ? '0head' : '0dev'; - push @copts, '--version ${version}-${age}'; - } - else { - $conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; -# XXX: gridsite hack - $conftag = $subsys eq 'gridsite' ? "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : - "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - - # lowering age for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age - 1; - } - } - - # emi1 suffix for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age.$project.$project_version; - $conf = $conf.$project.$project_version; - } - - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"}; - - my $confdir = $buildroot{"$subsys.$module"} eq '' ? '.' : '..'; - - my $cvs_module = full "$subsys.$module"; - my ($package_summary, $package_description) = get_description $cvs_module; - if ($package_description) { - $package_description =~ s/\n/\\n/g; - $package_description = "package.description = $package_description\n"; - } - if ($package_summary) { - $package_summary = "package.summary = $package_summary\n"; - } - - my %cmd; - $cmd_vcs{checkout} = "cvs -d \${vcsroot} co -d \${moduleName} ".($conftag eq 'HEAD' ? '-A' : '-r ${tag}')." $cvs_module 2>/dev/null"; - #$cmd_vcs{checkout} = "((test -d jra1mw/.git && (cd jra1mw; git pull)) || (git clone -q http://scientific.zcu.cz/git/jra1mw.git"; - #$cmd_vcs{checkout} .= " && (cd jra1mw; git checkout -b \${tag} --track origin/\${tag})" unless ($conftag eq /HEAD/); - #$cmd_vcs{checkout} .= ")) && (test -d \${moduleName} || ln -s jra1mw/$cvs_module \${moduleName})"; - $cmd_vcs{checkout} .= "\n\ttest -f \${packageName}-\${version}-\${age}.src.tar.gz || (ln -s \${moduleName} \${packageName}-\${version}; tar -chf - \${packageName}-\${version} --exclude CVS --exclude .git --exclude .etics | gzip --best > \${packageName}-\${version}-\${age}.src.tar.gz; rm \${packageName}-\${version})"; - $cmd_vcs{tag} = "cvs -d \${vcsroot} tag -R \${tag} ${moduleName}"; - - $cmd{default}{init} = 'None'; - $cmd{default}{configure} = 'None'; - $cmd{default}{compile} = 'None'; - $cmd{default}{test} = 'None'; - $cmd{default}{install} = 'None'; - $cmd{default}{packaging} = 'None'; - $cmd{default}{clean} = 'make clean'; - - if (exists $subpackages{$fmod}) { - $cmd{default}{clean} = 'None'; - $cmd{default}{packaging} = "echo building nothing, $subpackages{$fmod} will build this package"; - $cmd_vcs{checkout} = "mkdir -v \${moduleName} 2>/dev/null || true"; - } elsif ($subsys eq 'gridsite') { - $cmd_vcs{tag} = 'None'; - - if ($module eq 'core') { - my $flags; - - if ($project ne 'glite') { - # don't evaluate pkg-config calls to get them into source package - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=\`pkg-config gsoap --variable=prefix\` - OPENSSL_GLOBUS_FLAGS=\`pkg-config globus-openssl --cflags\` - OPENSSL_GLOBUS_LIBS=\`pkg-config globus-openssl --libs\`'; - } else { - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=${gsoap.location} - OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor} - OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir} - HTTPD_FLAGS=-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-1 -I${httpd-devel.location}/include/apr-1.0 -I${httpd-devel.location}/include/apr-0 -I${httpd-devel.location}/include/pcre'; - } - - $cmd{default}{configure} = "cat > Makefile.inc </dev/null"; - $cmd{default}{init} = 'echo "/sbin/ldconfig" > project/.post - echo "/sbin/ldconfig" > project/.postun'; - $cmd{default}{configure} = "cat > src/Makefile.inc <{default}}) { - $defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n"; - } - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = $project{etics_name}.$subsys.$module -displayName = $conf -description = $cvs_prefix{$subsys}.$subsys.$module -projectName = $project{etics_name} -age = $age -deploymentType = None -vcsroot = :pserver:anonymous\@glite.cvs.cern.ch:/cvs/glite -tag = $conftag -version = $major.$minor.$rev -$dwpath -[Platform-default:VcsCommand] -displayName = None -description = None -tag = $cmd_vcs{tag} -branch = None -commit = None -checkout = $cmd_vcs{checkout} - -}; - - for my $p (keys %cmd) { - next if $p ne 'default' and exists $project{supported_platforms} and not exists $project{supported_platforms}{$p}; - - print C qq{[Platform-$p:BuildCommand] -postpublish = None -packaging = $cmd{$p}{packaging} -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = $cmd{$p}{compile} -init = $cmd{$p}{init} -install = $cmd{$p}{install} -clean = $cmd{$p}{clean} -test = $cmd{$p}{test} -configure = $cmd{$p}{configure} -checkstyle = None - -}; - } - - print C qq{[Platform-default:Property] -$buildroot -package.preserve.libtool = false -$package_description$package_summary$defprops}; - - for (@{$obsoletes{"$subsys.$module"}}) { - print C "package.obsoletes = $_\n"; - print C "package.replaces = $_\n"; - } - for (@{$conflicts{"$subsys.$module"}}) { - print C "package.conflicts = $_\n"; - } - for (@{$provides{"$subsys.$module"}}) { - print C "package.provides = $_\n"; - } - print C "\n"; - - for my $pp (keys %{$platform_properties{"$subsys.$module"}}) { - next if $pp eq 'default'; - next if exists $project{supported_platforms} and not exists $project{supported_platforms}{$pp}; - - print C "[Platform-$pp:Property]\n$buildroot\n"; - - for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) { - print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n"; - } - print C "$package_description$package_summary\n"; - } - - for my $platform ('default', keys %{$project{supported_platforms}}) { - my $used = 0; - my $output = ''; - - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$platform}{$_}; - my $edev = $project{etics_externs_devel}{$platform}{$_}; - - # for the default platform using package of the same - # name for runtime dependency - if (not $eext) { - if ($platform eq 'default') { -#print "default runtime $_ on default\n"; - $eext = $_; } - else { -#print "no runtime $_ on $platform\n"; - $eext = '-'; } - } - if ($eext eq '-' and $edev eq '-') { -#print "skipping $_ on $platform\n"; - next; - } - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - - if ($edev) { - if ($type eq 'B') { - # no runtime - change to devel pkg - $eext = $edev; - } elsif ($type eq 'BR' or $type eq 'RB') { - # additional devel pkg - if ($edev ne '-') { $output .= "$proj|$edev = B\n"; } - } - } - if ($eext ne '-') { $output .= "$proj|$eext = $type\n"; } - } - - if ($platform eq 'default') { - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - if (not $used) { - $used = 1; - } - $output .= "$project{etics_name}|$project{etics_name}.$_ = $type\n"; - } - } - - if ($output) { - print C qq{ -[Platform-$platform:DynamicDependency] -$output}; - } - } - - close C; - - for $file ("$cvs_module/project/debian.rules", "$cvs_module/project/$packageName.spec") { - my $lib; - my $main_module; - @copts = (); - - if ($file =~ /debian\.rules$/) { $lib = 'lib'; } - else { $lib = '%{_lib}'; } - - my $main_module = "$subsys.$module"; - if (exists $subpackages{$main_module}) { $main_module = $subpackages{$main_module}; } - - # locations hacks - if ($file =~ /$packageName\.spec$/) { - if ($fmod eq 'lb.client-java') { - push @copts, ''; - push @copts, '--with-axis=/usr/local/axis1.4'; - } - } - - if (-f $file) { - open DST,">$file.new" or die "$file.new: $!\n"; - open SRC,"<$file" or die "$file: $!\n"; - while () { - if (/^(\s*).+\/configure\s/) { - printf DST "%s", "$1"; - printf DST "/usr/bin/perl $confdir/configure $project{flavours} --root=/ --prefix=$project{local_prefix} --libdir=$lib --project=$project --module $main_module@copts\n"; - } else { - printf DST "%s", "$_"; - } - } - close SRC; - close DST; - - `diff -b "$file" "$file.new"`; - if ($? == 0) { - print STDERR "($file not changed)\n"; - unlink "$file.new"; - } else { - print STDERR "Writing $file\n"; - rename "$file", "$file.orig" unless -f "$file.orig"; - rename "$file.new", "$file"; - } - } - } -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - $gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - -sub getlibdir { - if ( -e "/etc/debian_version") { # We are on Debian - $lib64="lib"; - $lib32="lib32"; } - else { # Another distribution - $lib64="lib64"; - $lib32="lib"; } - $libdir=$lib32; - - open INP, "uname -s | "; # Check kernel name - $kname= ; - chomp($kname); - close INP; - - if ( $kname eq "Linux") { - $arch = ("x86_64\npowerpc\nppc64\n"); - - open INP, "uname -p | "; # Check processor type - $procname= ; - chomp($procname); - close INP; - - if ($arch =~/^$procname\n/) { - return ($lib64); } - - open INP, "uname -m | "; # Check machine hardware - $machname= ; - chomp($machname); - close INP; - - if ($arch =~/^$machname\n/) { - return ($lib64); } - - # special cases (hyperlink lib64, Debian) - if (-l "/usr/lib64") { - $libdir=$lib32; } - - # if /usr/lib64 doesn't exist at all (AIX) - unless ( -e "/usr/lib64" ) { - $libdir=$lib32; } - } - - if ( $kname eq "SunOS") { - if (-e "/usr/lib/64") { - $libdir="lib/64"; } - } - - return $libdir; -} - -sub reshuffle_platforms($$) { - my ($data, $platforms) = @_; - my ($platform, %blacklist, $value); - - return if not $platforms; - - for $platform (keys %$data) { -#print "plat: $platform: $data->{$platform}\n"; - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { -#print " blacklist: $_ = $data->{$platform}{$_}\n"; - $blacklist{$_} = 1; - } - } - - for $_ (keys %blacklist) { - $value = $data->{default}{$_} ? $data->{default}{$_} : $_; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - if (not defined $data->{$platform}{$_}) { - $data->{$platform}{$_} = $value; -#print "added $value to $platform\n" - } - } - $data->{default}{$_} = '-'; -#print "deleted $_ from default\n"; - } - - # merge dependencies across the supported platforms - %blacklist = []; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { - $blacklist{$_} = 1; - } - } - for $_ (keys %blacklist) { - $value = undef; - $same = 1; - for $platform (keys %$platforms) { - if (not $value) { $value = $data->{$platform}{$_}; } - if (not $data->{$platform}{$_} or $value ne $data->{$platform}{$_}) { - $same = 0; - last; - } - } - if ($same and $value) { -#print "merged dependency $_\n"; - $data->{default}{$_} = $value; - for $platform (keys %$platforms) { - delete $data->{$platform}{$_}; - } - } - } -} - -sub usage { - my @ext = keys %externs; - my @myjars = keys %jar; - - print STDERR qq{ -Usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --stage=DIR staging directory [./stage] - --root=DIR installation root (custom relocation root -> sysroot) [./stage] - --sysroot=DIR system root (custom relocation root -> sysroot) [] - --sysconfdir=DIR system configuration directory [PREFIX/etc] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - --listmodules=module list subpackages of a module - --version=maj.min.rev-age version used instead of reading version.properties - --branch=branch CVS branch/etics name suffix (HEAD, branch_2_1, ...) - --libdir=libdir typically [lib,lib64] postfix - --project=PROJECT build or generate etics for a project (glite/emi1/emi) [emi] - --debug print more details - -Mode of operation: - --mode=\{checkout|build|etics\} what to do [build] - -What to build: - --module=module build this module only - --enable-NODE build this "node" (set of modules) only - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - --canl-tag=tag checkout canl modules with specific tag - -Dependencies (summary of what will be used is always printed): - --with-EXTERNAL=PATH where to look for an external [autodetect] - --with-JAR=JAR where to look for jars - -Available nodes: - @nodes - -Default nodes: - @default_nodes - -Externals (not all for all modules) are: - @ext - -External jars are: - @myjars - -}; - -} diff --git a/org.glite.jobid.api-c/interface/cjobid.h b/org.glite.jobid.api-c/interface/cjobid.h deleted file mode 100755 index 0945d24..0000000 --- a/org.glite.jobid.api-c/interface/cjobid.h +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef _GLITE_JOBID_H -#define _GLITE_JOBID_H - -/*! - * \file cjobid.h - * \brief L&B consumer API - */ - -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _edg_wlc_JobId *glite_jobid_t; -typedef const struct _edg_wlc_JobId *glite_jobid_const_t; -typedef glite_jobid_t edg_wlc_JobId; - -#define edg_wlc_JobIdCreate glite_jobid_create -#define edg_wlc_JobIdRecreate glite_jobid_recreate -#define edg_wlc_JobIdDup glite_jobid_dup -#define edg_wlc_JobIdFree glite_jobid_free -#define edg_wlc_JobIdParse glite_jobid_parse -#define edg_wlc_JobIdUnparse glite_jobid_unparse -#define edg_wlc_JobIdGetServer glite_jobid_getServer -#define edg_wlc_JobIdGetServerParts glite_jobid_getServerParts -#define edg_wlc_JobIdGetUnique glite_jobid_getUnique - -#define GLITE_JOBID_DEFAULT_PORT 9000 /**< Default port where bookkeeping server listens */ -#define GLITE_JOBID_PROTO_PREFIX "https://" /**< JobId protocol prefix */ - - -/* All the pointer functions return malloc'ed objects (or NULL on error) */ - -/** - * Create a Job ID. - * See the lb_draft document for details on its construction and components - * \param bkserver book keeping server hostname - * \param port port for the bk service - * \param jobid new created job id - * \ret al 0 success - * \retval EINVAL invalid bkserver - * \retval ENOMEM if memory allocation fails - */ -int glite_jobid_create(const char * bkserver, int port, glite_jobid_t * jobid); - -/** - * Recreate a Job ID - * \param bkserver bookkeeping server hostname - * \param port port for the bk service - * \param unique string which represent created jobid (if NULL then new - * one is created) - * \param jobid new created job id - * \retval 0 success - * \retval EINVAL invalid bkserver - * \retval ENOMEM if memory allocation fails - */ -int glite_jobid_recreate(const char *bkserver, int port, const char * unique, edg_wlc_JobId * jobid); - -/** - * Create copy of Job ID - * \param in jobid for duplication - * \param jobid duplicated jobid - * \retval 0 for success - * \retval EINVAL invalid jobid - * \retval ENOMEM if memory allocation fails - */ -int glite_jobid_dup(glite_jobid_const_t in, glite_jobid_t * jobid); - -/* - * Free jobid structure - * \param jobid for dealocation - */ -void glite_jobid_free(glite_jobid_t jobid); - -/** - * Parse Job ID string and creates jobid structure - * \param jobidstr string representation of jobid - * \param jobid parsed job id - * \retval 0 for success - * \retval EINVAL jobidstr can't be parsed - * \retval ENOMEM if memory allocation fails - */ -int glite_jobid_parse(const char* jobidstr, glite_jobid_t * jobid); - -/** - * Unparse Job ID (produce the string form of JobId). - * \param jobid to be converted to string - * \return allocated string which represents jobid - */ -char* glite_jobid_unparse(glite_jobid_const_t jobid); - -/** - * Extract bookkeeping server address (address:port) - * \param jobid from which the bkserver address should be extracted - * \retval pointer to allocated string with bkserver address - * \retval NULL if jobid is 0 or memory allocation fails - */ -char* glite_jobid_getServer(glite_jobid_const_t jobid); - -/** - * Extract bookkeeping server address and port - * \param jobid from which the bkserver address should be extracted - * \param srvName pointer where to return server name - * \param srvPort pointer where to return server port - * */ -void glite_jobid_getServerParts(glite_jobid_const_t jobid, char **srvName, unsigned int *srvPort); - -/** - * Extract bookkeeping server address and port - * \param jobid from which the bkserver address should be extracted - * \param srvName pointer where to return server name - * \param srvPort pointer where to return server port - * */ -void glite_jobid_getServerParts_internal(glite_jobid_const_t jobid, char **srvName, unsigned int *srvPort); - -/** - * Extract unique string - * \param jobid - * \retval pointer to allocated unique string representing jobid - * \retval NULL if jobid is 0 or memory allocation fails - */ -char* glite_jobid_getUnique(glite_jobid_const_t jobid); - -/** - * Extract unique string - * \param jobid - * \retval pointer to allocated unique string representing jobid - * \retval NULL if jobid is 0 or memory allocation fails - */ -char* glite_jobid_getUnique_internal(glite_jobid_const_t jobid); - -#ifdef __cplusplus -} -#endif - -#endif /* _GLITE_JOBID_H */ diff --git a/org.glite.jobid.api-c/interface/strmd5.h b/org.glite.jobid.api-c/interface/strmd5.h deleted file mode 100755 index 3da25f5..0000000 --- a/org.glite.jobid.api-c/interface/strmd5.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef _GLITE_STRMD5_H -#define _GLITE_STRMD5_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -/* 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); - -int base64_encode(const void *enc, int enc_size, char *out, int out_max_size); -int base64_decode(const char *enc,char *out,int out_size); - -#ifdef __cplusplus -}; -#endif - -#endif /* _GLITE_STRMD5_H */ diff --git a/org.glite.jobid.api-c/project/.post b/org.glite.jobid.api-c/project/.post deleted file mode 100644 index 8b0c822..0000000 --- a/org.glite.jobid.api-c/project/.post +++ /dev/null @@ -1 +0,0 @@ -/sbin/ldconfig diff --git a/org.glite.jobid.api-c/project/.postun b/org.glite.jobid.api-c/project/.postun deleted file mode 100644 index 8b0c822..0000000 --- a/org.glite.jobid.api-c/project/.postun +++ /dev/null @@ -1 +0,0 @@ -/sbin/ldconfig diff --git a/org.glite.jobid.api-c/project/ChangeLog b/org.glite.jobid.api-c/project/ChangeLog deleted file mode 100644 index fc7334a..0000000 --- a/org.glite.jobid.api-c/project/ChangeLog +++ /dev/null @@ -1,84 +0,0 @@ -1.0.0-1 -- ChangeLog created - -1.0.0-2 -- fixes in etics' invocation of configure - -1.0.0-4 -- configure script update - -1.0.0-5 -- install libraries into $libdir - -1.0.1-1 -- additional includes in base64_test to fix build on Deb5 - -1.0.2-1 -- Generic lbdir settings in the Makefile -- Fixed package description and summary - -1.0.3-1 -- Fix library versioning - -1.0.4-1 -- Fixed libtool version numbering - -1.0.5-1 -- Fixed target 'clean' in the Makefile - -1.0.6-1 -- Support for IPv6 literal addresses -- Fixed notification ID parsing - -1.0.7-1 -- Handling error returned by gethostbyname() (Savannah Bug #67627) - -2.0.0-1 -- Version numbering fixed - -2.0.0-2 -- Module rebuilt - -2.0.1-1 -- Root directory option (ETICS performs own files relocation) -- Prefix option as prefix inside stage -- Sysconfdir option (for /etc vs /usr) -- DESTDIR in makefiles - -2.0.2-1 -- Relocatable build directory. - -2.0.2-2 -- Module rebuilt - -2.0.2-3 -- Module rebuilt - -2.0.2-4 -- Module rebuilt - -2.0.2-5 -- Module rebuilt - -2.0.3-1 -- Handling error returned by gethostbyname() (Savannah Bug #67627) - -2.0.3-2 -- Module rebuilt - -2.1.0-1 -- Preparation for a new multiplatform release - -2.1.0-2 -- Module rebuilt - -2.1.1-1 -- Packaging improvements (rpmlint and lintian checks): -- License string as recognized by rpmlint and packaging guidelines. - -2.1.2-1 -- EMI-2-supported-platform adjustment - -2.1.2-2 -- Module rebuilt - diff --git a/org.glite.jobid.api-c/project/debian.control b/org.glite.jobid.api-c/project/debian.control deleted file mode 100644 index b0685f8..0000000 --- a/org.glite.jobid.api-c/project/debian.control +++ /dev/null @@ -1,34 +0,0 @@ -Source: glite-jobid-api-c -Priority: extra -Maintainer: @MAINTAINER@ -Uploaders: @UPLOADERS@ -Build-Depends: debhelper (>= 7.0.50~), chrpath, libcppunit-dev, libtool, libssl-dev -Standards-Version: 3.9.1 -Section: libs -Homepage: @URL@ -DM-Upload-Allowed: yes -@DEBIAN_VCS@ - -Package: libglite-jobid2 -Section: libs -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: @SUMMARY@ -@DEBIAN_DESCRIPTION@ - -Package: libglite-jobid-api-c-dev -Section: libdevel -Architecture: any -Provides: glite-jobid-api-c -Depends: libglite-jobid2 (= ${binary:Version}), ${misc:Depends} -Description: Development files for gLite jobid C library - This package contains development libraries and header files for gLite jobid - C library. - -Package: glite-jobid-api-c-dbg -Section: debug -Architecture: any -Priority: extra -Depends: libglite-jobid2 (= ${binary:Version}), ${misc:Depends} -Description: gLite jobid library debugging symbols - This package contains debugging symbols for gLite jobid library. diff --git a/org.glite.jobid.api-c/project/debian.copyright b/org.glite.jobid.api-c/project/debian.copyright deleted file mode 100644 index 3d762ae..0000000 --- a/org.glite.jobid.api-c/project/debian.copyright +++ /dev/null @@ -1,38 +0,0 @@ -This work was packaged for Debian by: - - @MAINTAINER@ on Thu, 08 Dec 2011 00:46:07 +0100 - -It was downloaded from: - - @URL@ - -Upstream Author(s): - - @MAINTAINER@ - -Copyright: - - - -License: - - 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. - -On Debian systems, the complete text of the Apache version 2.0 license -can be found in "/usr/share/common-licenses/Apache-2.0". - -The Debian packaging is: - - Copyright (C) 2004-2011 Members of the EGEE Collaboration - -and is licensed under the Apache License, Version 2.0. diff --git a/org.glite.jobid.api-c/project/debian.libglite-jobid-api-c-dev.dirs b/org.glite.jobid.api-c/project/debian.libglite-jobid-api-c-dev.dirs deleted file mode 100644 index b0cf754..0000000 --- a/org.glite.jobid.api-c/project/debian.libglite-jobid-api-c-dev.dirs +++ /dev/null @@ -1,2 +0,0 @@ -usr/lib -usr/include/glite/jobid diff --git a/org.glite.jobid.api-c/project/debian.libglite-jobid-api-c-dev.install b/org.glite.jobid.api-c/project/debian.libglite-jobid-api-c-dev.install deleted file mode 100644 index 7367086..0000000 --- a/org.glite.jobid.api-c/project/debian.libglite-jobid-api-c-dev.install +++ /dev/null @@ -1,2 +0,0 @@ -usr/include/glite/jobid/*.h -usr/lib/lib*.so diff --git a/org.glite.jobid.api-c/project/debian.libglite-jobid2.dirs b/org.glite.jobid.api-c/project/debian.libglite-jobid2.dirs deleted file mode 100644 index 6845771..0000000 --- a/org.glite.jobid.api-c/project/debian.libglite-jobid2.dirs +++ /dev/null @@ -1 +0,0 @@ -usr/lib diff --git a/org.glite.jobid.api-c/project/debian.libglite-jobid2.install b/org.glite.jobid.api-c/project/debian.libglite-jobid2.install deleted file mode 100644 index d0dbfd1..0000000 --- a/org.glite.jobid.api-c/project/debian.libglite-jobid2.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/lib*.so.* diff --git a/org.glite.jobid.api-c/project/debian.rules b/org.glite.jobid.api-c/project/debian.rules deleted file mode 100644 index 22b9b46..0000000 --- a/org.glite.jobid.api-c/project/debian.rules +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- - --include /usr/share/dpkg/buildflags.mk - -# Uncomment this to turn on verbose mode. -export DH_VERBOSE=1 - -configure: configure-stamp -configure-stamp: - dh_testdir - /usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=lib --project=emi --module jobid.api-c - touch $@ - -build: build-arch build-indep - -build-arch build-indep: build-stamp - -build-stamp: configure-stamp - dh_testdir - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) check - touch $@ - -clean: configure-stamp - dh_testdir - dh_testroot - rm -f configure-stamp build-stamp - $(MAKE) clean - rm -f Makefile.inc config.status - dh_clean - -install: build-stamp - dh_testdir - dh_testroot - dh_prep - dh_installdirs - $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp - rm -f $(CURDIR)/debian/tmp/usr/lib/*.la - rm -f $(CURDIR)/debian/tmp/usr/lib/*.a - find $(CURDIR)/debian/tmp -name '*' -print | xargs -I {} -i bash -c "chrpath -d {} > /dev/null 2>&1" || echo 'Stripped RPATH' - -binary-indep: - -binary-arch: install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_installexamples - dh_installman - dh_installlogrotate - dh_installcron - dh_install --fail-missing - dh_link - dh_strip --dbg-package=glite-jobid-api-c-dbg - dh_compress - dh_fixperms - dh_makeshlibs - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-arch binary-indep diff --git a/org.glite.jobid.api-c/project/glite-jobid-api-c.spec b/org.glite.jobid.api-c/project/glite-jobid-api-c.spec deleted file mode 100644 index 090b292..0000000 --- a/org.glite.jobid.api-c/project/glite-jobid-api-c.spec +++ /dev/null @@ -1,82 +0,0 @@ -Summary: @SUMMARY@ -Name: glite-jobid-api-c -Version: @MAJOR@.@MINOR@.@REVISION@ -Release: @AGE@%{?dist} -Url: @URL@ -License: ASL 2.0 -Vendor: EMI -Group: System Environment/Libraries -BuildRequires: chrpath -BuildRequires: libtool -BuildRequires: cppunit-devel -BuildRequires: openssl-devel -BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) -AutoReqProv: yes -Source: http://eticssoft.web.cern.ch/eticssoft/repository/emi/emi.jobid.api-c/%{version}/src/%{name}-@VERSION@.src.tar.gz - - -%description -@DESCRIPTION@ - - -%package devel -Summary: Development files for gLite jobid C library -Group: Development/Libraries -Requires: %{name}%{?_isa} = %{version}-%{release} - - -%description devel -This package contains development libraries and header files for gLite jobid -C library. - - -%prep -%setup -q - - -%build -/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=%{_lib} --project=emi --module jobid.api-c -make - - -%check -make check - - -%install -rm -rf $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT -make install DESTDIR=$RPM_BUILD_ROOT -find $RPM_BUILD_ROOT -name '*.la' -exec rm -rf {} \; -find $RPM_BUILD_ROOT -name '*.a' -exec rm -rf {} \; -find $RPM_BUILD_ROOT -name '*' -print | xargs -I {} -i bash -c "chrpath -d {} > /dev/null 2>&1" || echo 'Stripped RPATH' - - -%clean -rm -rf $RPM_BUILD_ROOT - - -%post -p /sbin/ldconfig - - -%postun -p /sbin/ldconfig - - -%files -%defattr(-,root,root) -/usr/%{_lib}/libglite_jobid.so.@MAJOR@.@MINOR@.@REVISION@ -/usr/%{_lib}/libglite_jobid.so.@MAJOR@ - - -%files devel -%defattr(-,root,root) -%dir /usr/include/glite -%dir /usr/include/glite/jobid -/usr/include/glite/jobid/strmd5.h -/usr/include/glite/jobid/cjobid.h -/usr/%{_lib}/libglite_jobid.so - - -%changelog -* @SPEC_DATE@ @MAINTAINER@ - @MAJOR@.@MINOR@.@REVISION@-@AGE@%{?dist} -- automatically generated package diff --git a/org.glite.jobid.api-c/project/package.description b/org.glite.jobid.api-c/project/package.description deleted file mode 100644 index 9c326af..0000000 --- a/org.glite.jobid.api-c/project/package.description +++ /dev/null @@ -1 +0,0 @@ -C library handling gLite jobid. diff --git a/org.glite.jobid.api-c/project/package.summary b/org.glite.jobid.api-c/project/package.summary deleted file mode 100644 index 53293ca..0000000 --- a/org.glite.jobid.api-c/project/package.summary +++ /dev/null @@ -1 +0,0 @@ -C library handling gLite jobid diff --git a/org.glite.jobid.api-c/project/version.properties b/org.glite.jobid.api-c/project/version.properties deleted file mode 100644 index c695353..0000000 --- a/org.glite.jobid.api-c/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# : /cvs/jra1mw/org.glite.jobid.api-c/project/version.properties,v 1.1 2009/01/16 08:48:52 zsustr Exp $ -module.version=2.1.2 -module.age=2 diff --git a/org.glite.jobid.api-c/src/cjobid.c b/org.glite.jobid.api-c/src/cjobid.c deleted file mode 100644 index 5ef0715..0000000 --- a/org.glite.jobid.api-c/src/cjobid.c +++ /dev/null @@ -1,301 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cjobid.h" -#include "strmd5.h" - -struct _edg_wlc_JobId { - char *id; /* unique job identification */ - /* additional information */ - char *BShost;/* bookkeeping server hostname */ - unsigned int BSport; /* bookkeeping server port */ - char *info; /* additional information (after ? in URI) */ -}; - -int glite_jobid_create(const char *bkserver, int port, glite_jobid_t *jobId) -{ - return glite_jobid_recreate(bkserver, port, NULL, jobId); -} - - -int glite_jobid_recreate(const char* bkserver, int port, const char *unique, glite_jobid_t *jobId) -{ - glite_jobid_t out; - char hostname[200]; /* used to hold string for encrypt */ - struct timeval tv; - int skip; - char* portbeg; - int rndaddr = 0; - - struct hostent* he; - - if (!bkserver) - return EINVAL; - - if (unique == NULL) { - gettimeofday(&tv, NULL); - srandom(tv.tv_usec); - gethostname(hostname, 100); - he = gethostbyname(hostname); - if (he) rndaddr = *((uint32_t *)he->h_addr_list[0]); - else { -#define RAND8 (rand() & 0xFF) -#define RAND16 (RAND8 << 8 | RAND8) - rndaddr = RAND16 << 16 | RAND16; - } - - skip = strlen(hostname); - skip += sprintf(hostname + skip, "-IP:0x%x-pid:%d-rnd:%d-time:%d:%d", - rndaddr, - getpid(), (int)random(), (int)tv.tv_sec, (int)tv.tv_usec); - } - - *jobId = NULL; - out = (glite_jobid_t) malloc (sizeof(*out)); - if (!out) - return ENOMEM; - - memset(out, 0, sizeof(*out)); - - /* check if it begins with prefix */ - /* unsupported */ - /* FIXME: fill in PROTO_PREFIX if missing */ - if (strncmp(bkserver, GLITE_JOBID_PROTO_PREFIX, sizeof(GLITE_JOBID_PROTO_PREFIX)-1) == 0) - return EINVAL; - - out->BShost = strdup(bkserver); - portbeg = strrchr(out->BShost, ':'); - if (portbeg) { - *portbeg = 0; - /* try to get port number */ - if (port == 0) - port = atoi(portbeg + 1); - } - - if (port == 0) - port = GLITE_JOBID_DEFAULT_PORT; - - out->BSport = port; - - out->id = (unique) ? strdup(unique) : str2md5base64(hostname); - //printf("Encrypt: %s\nBASE64 %s\n", hostname, out->id); - - if (!out->id || !out->BShost) { - glite_jobid_free(out); - return ENOMEM; - } - - *jobId = out; - return 0; -} - - -int glite_jobid_dup(glite_jobid_const_t in, glite_jobid_t *out) -{ - glite_jobid_t jid; - *out = NULL; - if (in == NULL) - return 0; - - jid = malloc(sizeof(*jid)); - if (!jid) - return ENOMEM; - - memset(jid, 0,sizeof(*jid)); - jid->BShost = strdup(in->BShost); - jid->id = strdup(in->id); - if (in->info) - jid->info = strdup(in->info); - - if (jid->BShost == NULL || jid->id == NULL) { - glite_jobid_free(jid); - return ENOMEM; - } - - jid->BSport = in->BSport; - *out = jid; - return 0; -} - - -// XXX -// use recreate -// parse name, port, unique -int glite_jobid_parse(const char *idString, glite_jobid_t *jobId) -{ - char *pom, *pom1, *pom2; - glite_jobid_t out; - - *jobId = NULL; - - out = (glite_jobid_t) malloc (sizeof(*out)); - if (out == NULL ) - return ENOMEM; - - memset(out,0,sizeof(*out)); - - if (strncmp(idString, GLITE_JOBID_PROTO_PREFIX, sizeof(GLITE_JOBID_PROTO_PREFIX) - 1)) { - out->BShost = (char *) NULL; - out->BSport = 0; - - free(out); - return EINVAL; - } - - pom = strdup(idString + sizeof(GLITE_JOBID_PROTO_PREFIX) - 1); - pom1 = strchr(pom, '/'); - - if (!pom1) { free(pom); free(out); return EINVAL; } - pom1[0] = '\0'; - - pom2 = strrchr(pom, ':'); - if (pom2 && strchr(pom2,']')) pom2 = NULL; - - if ( pom2 ) { - pom[pom2-pom] = '\0'; - out->BShost = strdup(pom); - pom[pom1-pom] = '\0'; - out->BSport = (unsigned int) strtoul(pom2 + 1,NULL,10); - } else { - pom[pom1-pom] = '\0'; - out->BShost = strdup(pom); - out->BSport = GLITE_JOBID_DEFAULT_PORT; - } - - /* XXX: localhost not supported in jobid - if (!strncmp(out->BShost,"localhost",9) { - free(pom); - free(out->BShost); - free(out); - return EINVAL; - } - */ - - /* additional info from URI */ - pom2 = strchr(pom1+1,'?'); - if (pom2) { - *pom2 = 0; - out->info = strdup(pom2+1); - } - - /* extract the unique part */ - out->id = strdup(pom1+1); - - for (pom1 = out->BShost; *pom1; pom1++) - if (isspace(*pom1)) break; - - for (pom2 = out->id; *pom2; pom2++) - if (isspace(*pom2)) break; - - if (*pom1 || *pom2) { - free(pom); - glite_jobid_free(out); - return EINVAL; - } - - free(pom); - *jobId = out; - return 0; -} - - -void glite_jobid_free(glite_jobid_t job) -{ - if (job) { - free(job->id); - free(job->BShost); - free(job->info); - free(job); - } -} - - -char* glite_jobid_unparse(glite_jobid_const_t jobid) -{ - char *out, port[40]; - - if (!jobid) - return NULL; - - if (jobid->BSport) - sprintf(port,":%d",jobid->BSport); - else - *port = 0; - - asprintf(&out, GLITE_JOBID_PROTO_PREFIX"%s%s/%s%s%s", - jobid->BShost,port, - jobid->id, - (jobid->info ? "?" : ""), - (jobid->info ? jobid->info : "")); - - return out; -} - - -char* glite_jobid_getServer(glite_jobid_const_t jobid) -{ - char *bs = NULL; - - if (jobid) - asprintf(&bs, "%s:%u", jobid->BShost, - jobid->BSport ? jobid->BSport : GLITE_JOBID_DEFAULT_PORT); - - return bs; -} - - -void glite_jobid_getServerParts(glite_jobid_const_t jobid, char **srvName, unsigned int *srvPort) -{ - if (jobid) { - *srvName = strdup(jobid->BShost); - *srvPort = jobid->BSport ? jobid->BSport : GLITE_JOBID_DEFAULT_PORT; - } -} - - -char* glite_jobid_getUnique(glite_jobid_const_t jobid) -{ - return jobid ? strdup(jobid->id) : NULL; -} - - -void glite_jobid_getServerParts_internal(glite_jobid_const_t jobid, char **srvName, unsigned int *srvPort) -{ - if (jobid) { - *srvName = jobid->BShost; - *srvPort = jobid->BSport ? jobid->BSport : GLITE_JOBID_DEFAULT_PORT; - } -} - - -char* glite_jobid_getUnique_internal(glite_jobid_const_t jobid) -{ - return jobid ? jobid->id : NULL; -} diff --git a/org.glite.jobid.api-c/src/md32_common.h b/org.glite.jobid.api-c/src/md32_common.h deleted file mode 100644 index a8a539b..0000000 --- a/org.glite.jobid.api-c/src/md32_common.h +++ /dev/null @@ -1,640 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* crypto/md32_common.h */ -/* ==================================================================== - * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``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 THE OpenSSL 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 product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * This is a generic 32 bit "collector" for message digest algorithms. - * Whenever needed it collects input character stream into chunks of - * 32 bit values and invokes a block function that performs actual hash - * calculations. - * - * Porting guide. - * - * Obligatory macros: - * - * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN - * this macro defines byte order of input stream. - * HASH_CBLOCK - * size of a unit chunk HASH_BLOCK operates on. - * HASH_LONG - * has to be at lest 32 bit wide, if it's wider, then - * HASH_LONG_LOG2 *has to* be defined along - * HASH_CTX - * context structure that at least contains following - * members: - * typedef struct { - * ... - * HASH_LONG Nl,Nh; - * HASH_LONG data[HASH_LBLOCK]; - * unsigned int num; - * ... - * } HASH_CTX; - * HASH_UPDATE - * name of "Update" function, implemented here. - * HASH_TRANSFORM - * name of "Transform" function, implemented here. - * HASH_FINAL - * name of "Final" function, implemented here. - * HASH_BLOCK_HOST_ORDER - * name of "block" function treating *aligned* input message - * in host byte order, implemented externally. - * HASH_BLOCK_DATA_ORDER - * name of "block" function treating *unaligned* input message - * in original (data) byte order, implemented externally (it - * actually is optional if data and host are of the same - * "endianess"). - * HASH_MAKE_STRING - * macro convering context variables to an ASCII hash string. - * - * Optional macros: - * - * B_ENDIAN or L_ENDIAN - * defines host byte-order. - * HASH_LONG_LOG2 - * defaults to 2 if not states otherwise. - * HASH_LBLOCK - * assumed to be HASH_CBLOCK/4 if not stated otherwise. - * HASH_BLOCK_DATA_ORDER_ALIGNED - * alternative "block" function capable of treating - * aligned input message in original (data) order, - * implemented externally. - * - * MD5 example: - * - * #define DATA_ORDER_IS_LITTLE_ENDIAN - * - * #define HASH_LONG MD5_LONG - * #define HASH_LONG_LOG2 MD5_LONG_LOG2 - * #define HASH_CTX MD5_CTX - * #define HASH_CBLOCK MD5_CBLOCK - * #define HASH_LBLOCK MD5_LBLOCK - * #define HASH_UPDATE MD5_Update - * #define HASH_TRANSFORM MD5_Transform - * #define HASH_FINAL MD5_Final - * #define HASH_BLOCK_HOST_ORDER md5_block_host_order - * #define HASH_BLOCK_DATA_ORDER md5_block_data_order - * - * - */ - -#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) -#error "DATA_ORDER must be defined!" -#endif - -#ifndef HASH_CBLOCK -#error "HASH_CBLOCK must be defined!" -#endif -#ifndef HASH_LONG -#error "HASH_LONG must be defined!" -#endif -#ifndef HASH_CTX -#error "HASH_CTX must be defined!" -#endif - -#ifndef HASH_UPDATE -#error "HASH_UPDATE must be defined!" -#endif -#ifndef HASH_TRANSFORM -#error "HASH_TRANSFORM must be defined!" -#endif -#ifndef HASH_FINAL -#error "HASH_FINAL must be defined!" -#endif - -#ifndef HASH_BLOCK_HOST_ORDER -#error "HASH_BLOCK_HOST_ORDER must be defined!" -#endif - -#if 0 -/* - * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED - * isn't defined. - */ -#ifndef HASH_BLOCK_DATA_ORDER -#error "HASH_BLOCK_DATA_ORDER must be defined!" -#endif -#endif - -#ifndef HASH_LBLOCK -#define HASH_LBLOCK (HASH_CBLOCK/4) -#endif - -#ifndef HASH_LONG_LOG2 -#define HASH_LONG_LOG2 2 -#endif - -/* - * Engage compiler specific rotate intrinsic function if available. - */ -#undef ROTATE -#ifndef PEDANTIC -# if defined(_MSC_VER) || defined(__ICC) -# define ROTATE(a,n) _lrotl(a,n) -# elif defined(__MWERKS__) -# if defined(__POWERPC__) -# define ROTATE(a,n) __rlwinm(a,n,0,31) -# elif defined(__MC68K__) - /* Motorola specific tweak. */ -# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) ) -# else -# define ROTATE(a,n) __rol(a,n) -# endif -# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) - /* - * Some GNU C inline assembler templates. Note that these are - * rotates by *constant* number of bits! But that's exactly - * what we need here... - * - */ -# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) -# define ROTATE(a,n) ({ register unsigned int ret; \ - asm ( \ - "roll %1,%0" \ - : "=r"(ret) \ - : "I"(n), "0"(a) \ - : "cc"); \ - ret; \ - }) -# elif defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) -# define ROTATE(a,n) ({ register unsigned int ret; \ - asm ( \ - "rlwinm %0,%1,%2,0,31" \ - : "=r"(ret) \ - : "r"(a), "I"(n)); \ - ret; \ - }) -# endif -# endif -#endif /* PEDANTIC */ - -#if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */ -/* A nice byte order reversal from Wei Dai */ -#ifdef ROTATE -/* 5 instructions with rotate instruction, else 9 */ -#define REVERSE_FETCH32(a,l) ( \ - l=*(const HASH_LONG *)(a), \ - ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \ - ) -#else -/* 6 instructions with rotate instruction, else 8 */ -#define REVERSE_FETCH32(a,l) ( \ - l=*(const HASH_LONG *)(a), \ - l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \ - ROTATE(l,16) \ - ) -/* - * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|... - * It's rewritten as above for two reasons: - * - RISCs aren't good at long constants and have to explicitely - * compose 'em with several (well, usually 2) instructions in a - * register before performing the actual operation and (as you - * already realized:-) having same constant should inspire the - * compiler to permanently allocate the only register for it; - * - most modern CPUs have two ALUs, but usually only one has - * circuitry for shifts:-( this minor tweak inspires compiler - * to schedule shift instructions in a better way... - * - * - */ -#endif -#endif - -#ifndef ROTATE -#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) -#endif - -/* - * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED - * and HASH_BLOCK_HOST_ORDER ought to be the same if input data - * and host are of the same "endianess". It's possible to mask - * this with blank #define HASH_BLOCK_DATA_ORDER though... - * - * - */ -#if defined(B_ENDIAN) -# if defined(DATA_ORDER_IS_BIG_ENDIAN) -# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 -# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER -# endif -# endif -#elif defined(L_ENDIAN) -# if defined(DATA_ORDER_IS_LITTLE_ENDIAN) -# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 -# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER -# endif -# endif -#endif - -#if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) -#ifndef HASH_BLOCK_DATA_ORDER -#error "HASH_BLOCK_DATA_ORDER must be defined!" -#endif -#endif - -#if defined(DATA_ORDER_IS_BIG_ENDIAN) - -#ifndef PEDANTIC -# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) -# if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \ - (defined(__x86_64) || defined(__x86_64__)) - /* - * This gives ~30-40% performance improvement in SHA-256 compiled - * with gcc [on P4]. Well, first macro to be frank. We can pull - * this trick on x86* platforms only, because these CPUs can fetch - * unaligned data without raising an exception. - */ -# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \ - asm ("bswapl %0":"=r"(r):"0"(r)); \ - (c)+=4; (l)=r; }) -# define HOST_l2c(l,c) ({ unsigned int r=(l); \ - asm ("bswapl %0":"=r"(r):"0"(r)); \ - *((unsigned int *)(c))=r; (c)+=4; r; }) -# endif -# endif -#endif - -#ifndef HOST_c2l -#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ - l|=(((unsigned long)(*((c)++)))<<16), \ - l|=(((unsigned long)(*((c)++)))<< 8), \ - l|=(((unsigned long)(*((c)++))) ), \ - l) -#endif -#define HOST_p_c2l(c,l,n) { \ - switch (n) { \ - case 0: l =((unsigned long)(*((c)++)))<<24; \ - case 1: l|=((unsigned long)(*((c)++)))<<16; \ - case 2: l|=((unsigned long)(*((c)++)))<< 8; \ - case 3: l|=((unsigned long)(*((c)++))); \ - } } -#define HOST_p_c2l_p(c,l,sc,len) { \ - switch (sc) { \ - case 0: l =((unsigned long)(*((c)++)))<<24; \ - if (--len == 0) break; \ - case 1: l|=((unsigned long)(*((c)++)))<<16; \ - if (--len == 0) break; \ - case 2: l|=((unsigned long)(*((c)++)))<< 8; \ - } } -/* NOTE the pointer is not incremented at the end of this */ -#define HOST_c2l_p(c,l,n) { \ - l=0; (c)+=n; \ - switch (n) { \ - case 3: l =((unsigned long)(*(--(c))))<< 8; \ - case 2: l|=((unsigned long)(*(--(c))))<<16; \ - case 1: l|=((unsigned long)(*(--(c))))<<24; \ - } } -#ifndef HOST_l2c -#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff), \ - l) -#endif - -#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) - -#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) -# ifndef B_ENDIAN - /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */ -# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l) -# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l) -# endif -#endif - -#ifndef HOST_c2l -#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ - l|=(((unsigned long)(*((c)++)))<< 8), \ - l|=(((unsigned long)(*((c)++)))<<16), \ - l|=(((unsigned long)(*((c)++)))<<24), \ - l) -#endif -#define HOST_p_c2l(c,l,n) { \ - switch (n) { \ - case 0: l =((unsigned long)(*((c)++))); \ - case 1: l|=((unsigned long)(*((c)++)))<< 8; \ - case 2: l|=((unsigned long)(*((c)++)))<<16; \ - case 3: l|=((unsigned long)(*((c)++)))<<24; \ - } } -#define HOST_p_c2l_p(c,l,sc,len) { \ - switch (sc) { \ - case 0: l =((unsigned long)(*((c)++))); \ - if (--len == 0) break; \ - case 1: l|=((unsigned long)(*((c)++)))<< 8; \ - if (--len == 0) break; \ - case 2: l|=((unsigned long)(*((c)++)))<<16; \ - } } -/* NOTE the pointer is not incremented at the end of this */ -#define HOST_c2l_p(c,l,n) { \ - l=0; (c)+=n; \ - switch (n) { \ - case 3: l =((unsigned long)(*(--(c))))<<16; \ - case 2: l|=((unsigned long)(*(--(c))))<< 8; \ - case 1: l|=((unsigned long)(*(--(c)))); \ - } } -#ifndef HOST_l2c -#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff), \ - l) -#endif - -#endif - -/* - * Time for some action:-) - */ - -MD5_JOBID_PROTO int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len) - { - const unsigned char *data=data_; - register HASH_LONG * p; - register HASH_LONG l; - size_t sw,sc,ew,ec; - - if (len==0) return 1; - - l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL; - /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to - * Wei Dai for pointing it out. */ - if (l < c->Nl) /* overflow */ - c->Nh++; - c->Nh+=(len>>29); /* might cause compiler warning on 16-bit */ - c->Nl=l; - - if (c->num != 0) - { - p=c->data; - sw=c->num>>2; - sc=c->num&0x03; - - if ((c->num+len) >= HASH_CBLOCK) - { - l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l; - for (; swnum); - c->num=0; - /* drop through and do the rest */ - } - else - { - c->num+=(unsigned int)len; - if ((sc+len) < 4) /* ugly, add char's to a word */ - { - l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l; - } - else - { - ew=(c->num>>2); - ec=(c->num&0x03); - if (sc) - l=p[sw]; - HOST_p_c2l(data,l,sc); - p[sw++]=l; - for (; sw < ew; sw++) - { - HOST_c2l(data,l); p[sw]=l; - } - if (ec) - { - HOST_c2l_p(data,l,ec); p[sw]=l; - } - } - return 1; - } - } - - sw=len/HASH_CBLOCK; - if (sw > 0) - { -#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) - /* - * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined - * only if sizeof(HASH_LONG)==4. - */ - if ((((size_t)data)%4) == 0) - { - /* data is properly aligned so that we can cast it: */ - HASH_BLOCK_DATA_ORDER_ALIGNED (c,(const HASH_LONG *)data,sw); - sw*=HASH_CBLOCK; - data+=sw; - len-=sw; - } - else -#if !defined(HASH_BLOCK_DATA_ORDER) - while (sw--) - { - memcpy (p=c->data,data,HASH_CBLOCK); - HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1); - data+=HASH_CBLOCK; - len-=HASH_CBLOCK; - } -#endif -#endif -#if defined(HASH_BLOCK_DATA_ORDER) - { - HASH_BLOCK_DATA_ORDER(c,data,sw); - sw*=HASH_CBLOCK; - data+=sw; - len-=sw; - } -#endif - } - - if (len!=0) - { - p = c->data; - c->num = len; - ew=len>>2; /* words to copy */ - ec=len&0x03; - for (; ew; ew--,p++) - { - HOST_c2l(data,l); *p=l; - } - HOST_c2l_p(data,l,ec); - *p=l; - } - return 1; - } - - -MD5_JOBID_PROTO void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data) - { -#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) - if ((((size_t)data)%4) == 0) - /* data is properly aligned so that we can cast it: */ - HASH_BLOCK_DATA_ORDER_ALIGNED (c,(const HASH_LONG *)data,1); - else -#if !defined(HASH_BLOCK_DATA_ORDER) - { - - HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1); - } -#endif -#endif -#if defined(HASH_BLOCK_DATA_ORDER) - HASH_BLOCK_DATA_ORDER (c,data,1); -#endif - } - - -MD5_JOBID_PROTO int HASH_FINAL (unsigned char *md, HASH_CTX *c) - { - register HASH_LONG *p; - register unsigned long l; - register int i,j; - static const unsigned char end[4]={0x80,0x00,0x00,0x00}; - const unsigned char *cp=end; - - /* c->num should definitly have room for at least one more byte. */ - p=c->data; - i=c->num>>2; - j=c->num&0x03; - -#if 0 - /* purify often complains about the following line as an - * Uninitialized Memory Read. While this can be true, the - * following p_c2l macro will reset l when that case is true. - * This is because j&0x03 contains the number of 'valid' bytes - * already in p[i]. If and only if j&0x03 == 0, the UMR will - * occur but this is also the only time p_c2l will do - * l= *(cp++) instead of l|= *(cp++) - * Many thanks to Alex Tang for pickup this - * 'potential bug' */ -#ifdef PURIFY - if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */ -#endif - l=p[i]; -#else - l = (j==0) ? 0 : p[i]; -#endif - HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */ - - if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */ - { - if (iNh; - p[HASH_LBLOCK-1]=c->Nl; -#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) - p[HASH_LBLOCK-2]=c->Nl; - p[HASH_LBLOCK-1]=c->Nh; -#endif - HASH_BLOCK_HOST_ORDER (c,p,1); - -#ifndef HASH_MAKE_STRING -#error "HASH_MAKE_STRING must be defined!" -#else - HASH_MAKE_STRING(c,md); -#endif - - c->num=0; - /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack - * but I'm not worried :-) - OPENSSL_cleanse((void *)c,sizeof(HASH_CTX)); - */ - return 1; - } - -#ifndef MD32_REG_T -#define MD32_REG_T long -/* - * This comment was originaly written for MD5, which is why it - * discusses A-D. But it basically applies to all 32-bit digests, - * which is why it was moved to common header file. - * - * In case you wonder why A-D are declared as long and not - * as MD5_LONG. Doing so results in slight performance - * boost on LP64 architectures. The catch is we don't - * really care if 32 MSBs of a 64-bit register get polluted - * with eventual overflows as we *save* only 32 LSBs in - * *either* case. Now declaring 'em long excuses the compiler - * from keeping 32 MSBs zeroed resulting in 13% performance - * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. - * Well, to be honest it should say that this *prevents* - * performance degradation. - * - * Apparently there're LP64 compilers that generate better - * code if A-D are declared int. Most notably GCC-x86_64 - * generates better code. - * - */ -#endif diff --git a/org.glite.jobid.api-c/src/md5.h b/org.glite.jobid.api-c/src/md5.h deleted file mode 100644 index faec0fc..0000000 --- a/org.glite.jobid.api-c/src/md5.h +++ /dev/null @@ -1,135 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* crypto/md5/md5.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_MD5_H -#define HEADER_MD5_H - -/* ljocha -#include -*/ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef OPENSSL_NO_MD5 -#error MD5 is disabled. -#endif - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then ! - * ! MD5_LONG_LOG2 has to be defined along. ! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - -#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__) -#define MD5_LONG unsigned long -#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) -#define MD5_LONG unsigned long -#define MD5_LONG_LOG2 3 - -/* _CRAY note. I could declare short, but I have no idea what impact - * does it have on performance on none-T3E machines. I could declare - * int, but at least on C90 sizeof(int) can be chosen at compile time. - * So I've chosen long... * - */ -#else -#define MD5_LONG unsigned int -#endif - -#define MD5_CBLOCK 64 -#define MD5_LBLOCK (MD5_CBLOCK/4) -#define MD5_DIGEST_LENGTH 16 - -typedef struct MD5state_st - { - MD5_LONG A,B,C,D; - MD5_LONG Nl,Nh; - MD5_LONG data[MD5_LBLOCK]; - unsigned int num; - } MD5_CTX; - -MD5_JOBID_PROTO int MD5_Init(MD5_CTX *c); -MD5_JOBID_PROTO int MD5_Update(MD5_CTX *c, const void *data, size_t len); -MD5_JOBID_PROTO int MD5_Final(unsigned char *md, MD5_CTX *c); -MD5_JOBID_PROTO unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md); -MD5_JOBID_PROTO void MD5_Transform(MD5_CTX *c, const unsigned char *b); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/org.glite.jobid.api-c/src/md5_dgst.c b/org.glite.jobid.api-c/src/md5_dgst.c deleted file mode 100644 index c00fee8..0000000 --- a/org.glite.jobid.api-c/src/md5_dgst.c +++ /dev/null @@ -1,315 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* crypto/md5/md5_dgst.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef MD5_JOBID_PROTO -#define MD5_JOBID_PROTO -#endif - -#include -#include "md5_locl.h" -/* ljocha -#include - -const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT; -*/ - -/* Implemented from RFC1321 The MD5 Message-Digest Algorithm - */ - -#define INIT_DATA_A (unsigned long)0x67452301L -#define INIT_DATA_B (unsigned long)0xefcdab89L -#define INIT_DATA_C (unsigned long)0x98badcfeL -#define INIT_DATA_D (unsigned long)0x10325476L - -MD5_JOBID_PROTO int MD5_Init(MD5_CTX *c) - { - c->A=INIT_DATA_A; - c->B=INIT_DATA_B; - c->C=INIT_DATA_C; - c->D=INIT_DATA_D; - c->Nl=0; - c->Nh=0; - c->num=0; - return 1; - } - -#ifndef md5_block_host_order -MD5_JOBID_PROTO void md5_block_host_order (MD5_CTX *c, const void *data, size_t num) - { - const MD5_LONG *X=data; - register unsigned MD32_REG_T A,B,C,D; - - A=c->A; - B=c->B; - C=c->C; - D=c->D; - - for (;num--;X+=HASH_LBLOCK) - { - /* Round 0 */ - R0(A,B,C,D,X[ 0], 7,0xd76aa478L); - R0(D,A,B,C,X[ 1],12,0xe8c7b756L); - R0(C,D,A,B,X[ 2],17,0x242070dbL); - R0(B,C,D,A,X[ 3],22,0xc1bdceeeL); - R0(A,B,C,D,X[ 4], 7,0xf57c0fafL); - R0(D,A,B,C,X[ 5],12,0x4787c62aL); - R0(C,D,A,B,X[ 6],17,0xa8304613L); - R0(B,C,D,A,X[ 7],22,0xfd469501L); - R0(A,B,C,D,X[ 8], 7,0x698098d8L); - R0(D,A,B,C,X[ 9],12,0x8b44f7afL); - R0(C,D,A,B,X[10],17,0xffff5bb1L); - R0(B,C,D,A,X[11],22,0x895cd7beL); - R0(A,B,C,D,X[12], 7,0x6b901122L); - R0(D,A,B,C,X[13],12,0xfd987193L); - R0(C,D,A,B,X[14],17,0xa679438eL); - R0(B,C,D,A,X[15],22,0x49b40821L); - /* Round 1 */ - R1(A,B,C,D,X[ 1], 5,0xf61e2562L); - R1(D,A,B,C,X[ 6], 9,0xc040b340L); - R1(C,D,A,B,X[11],14,0x265e5a51L); - R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL); - R1(A,B,C,D,X[ 5], 5,0xd62f105dL); - R1(D,A,B,C,X[10], 9,0x02441453L); - R1(C,D,A,B,X[15],14,0xd8a1e681L); - R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L); - R1(A,B,C,D,X[ 9], 5,0x21e1cde6L); - R1(D,A,B,C,X[14], 9,0xc33707d6L); - R1(C,D,A,B,X[ 3],14,0xf4d50d87L); - R1(B,C,D,A,X[ 8],20,0x455a14edL); - R1(A,B,C,D,X[13], 5,0xa9e3e905L); - R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L); - R1(C,D,A,B,X[ 7],14,0x676f02d9L); - R1(B,C,D,A,X[12],20,0x8d2a4c8aL); - /* Round 2 */ - R2(A,B,C,D,X[ 5], 4,0xfffa3942L); - R2(D,A,B,C,X[ 8],11,0x8771f681L); - R2(C,D,A,B,X[11],16,0x6d9d6122L); - R2(B,C,D,A,X[14],23,0xfde5380cL); - R2(A,B,C,D,X[ 1], 4,0xa4beea44L); - R2(D,A,B,C,X[ 4],11,0x4bdecfa9L); - R2(C,D,A,B,X[ 7],16,0xf6bb4b60L); - R2(B,C,D,A,X[10],23,0xbebfbc70L); - R2(A,B,C,D,X[13], 4,0x289b7ec6L); - R2(D,A,B,C,X[ 0],11,0xeaa127faL); - R2(C,D,A,B,X[ 3],16,0xd4ef3085L); - R2(B,C,D,A,X[ 6],23,0x04881d05L); - R2(A,B,C,D,X[ 9], 4,0xd9d4d039L); - R2(D,A,B,C,X[12],11,0xe6db99e5L); - R2(C,D,A,B,X[15],16,0x1fa27cf8L); - R2(B,C,D,A,X[ 2],23,0xc4ac5665L); - /* Round 3 */ - R3(A,B,C,D,X[ 0], 6,0xf4292244L); - R3(D,A,B,C,X[ 7],10,0x432aff97L); - R3(C,D,A,B,X[14],15,0xab9423a7L); - R3(B,C,D,A,X[ 5],21,0xfc93a039L); - R3(A,B,C,D,X[12], 6,0x655b59c3L); - R3(D,A,B,C,X[ 3],10,0x8f0ccc92L); - R3(C,D,A,B,X[10],15,0xffeff47dL); - R3(B,C,D,A,X[ 1],21,0x85845dd1L); - R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL); - R3(D,A,B,C,X[15],10,0xfe2ce6e0L); - R3(C,D,A,B,X[ 6],15,0xa3014314L); - R3(B,C,D,A,X[13],21,0x4e0811a1L); - R3(A,B,C,D,X[ 4], 6,0xf7537e82L); - R3(D,A,B,C,X[11],10,0xbd3af235L); - R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL); - R3(B,C,D,A,X[ 9],21,0xeb86d391L); - - A = c->A += A; - B = c->B += B; - C = c->C += C; - D = c->D += D; - } - } -#endif - -#ifndef md5_block_data_order -#ifdef X -#undef X -#endif -MD5_JOBID_PROTO void md5_block_data_order (MD5_CTX *c, const void *data_, size_t num) - { - const unsigned char *data=data_; - register unsigned MD32_REG_T A,B,C,D,l; -#ifndef MD32_XARRAY - /* See comment in crypto/sha/sha_locl.h for details. */ - unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, - XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; -# define X(i) XX##i -#else - MD5_LONG XX[MD5_LBLOCK]; -# define X(i) XX[i] -#endif - - A=c->A; - B=c->B; - C=c->C; - D=c->D; - - for (;num--;) - { - HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l; - /* Round 0 */ - R0(A,B,C,D,X( 0), 7,0xd76aa478L); HOST_c2l(data,l); X( 2)=l; - R0(D,A,B,C,X( 1),12,0xe8c7b756L); HOST_c2l(data,l); X( 3)=l; - R0(C,D,A,B,X( 2),17,0x242070dbL); HOST_c2l(data,l); X( 4)=l; - R0(B,C,D,A,X( 3),22,0xc1bdceeeL); HOST_c2l(data,l); X( 5)=l; - R0(A,B,C,D,X( 4), 7,0xf57c0fafL); HOST_c2l(data,l); X( 6)=l; - R0(D,A,B,C,X( 5),12,0x4787c62aL); HOST_c2l(data,l); X( 7)=l; - R0(C,D,A,B,X( 6),17,0xa8304613L); HOST_c2l(data,l); X( 8)=l; - R0(B,C,D,A,X( 7),22,0xfd469501L); HOST_c2l(data,l); X( 9)=l; - R0(A,B,C,D,X( 8), 7,0x698098d8L); HOST_c2l(data,l); X(10)=l; - R0(D,A,B,C,X( 9),12,0x8b44f7afL); HOST_c2l(data,l); X(11)=l; - R0(C,D,A,B,X(10),17,0xffff5bb1L); HOST_c2l(data,l); X(12)=l; - R0(B,C,D,A,X(11),22,0x895cd7beL); HOST_c2l(data,l); X(13)=l; - R0(A,B,C,D,X(12), 7,0x6b901122L); HOST_c2l(data,l); X(14)=l; - R0(D,A,B,C,X(13),12,0xfd987193L); HOST_c2l(data,l); X(15)=l; - R0(C,D,A,B,X(14),17,0xa679438eL); - R0(B,C,D,A,X(15),22,0x49b40821L); - /* Round 1 */ - R1(A,B,C,D,X( 1), 5,0xf61e2562L); - R1(D,A,B,C,X( 6), 9,0xc040b340L); - R1(C,D,A,B,X(11),14,0x265e5a51L); - R1(B,C,D,A,X( 0),20,0xe9b6c7aaL); - R1(A,B,C,D,X( 5), 5,0xd62f105dL); - R1(D,A,B,C,X(10), 9,0x02441453L); - R1(C,D,A,B,X(15),14,0xd8a1e681L); - R1(B,C,D,A,X( 4),20,0xe7d3fbc8L); - R1(A,B,C,D,X( 9), 5,0x21e1cde6L); - R1(D,A,B,C,X(14), 9,0xc33707d6L); - R1(C,D,A,B,X( 3),14,0xf4d50d87L); - R1(B,C,D,A,X( 8),20,0x455a14edL); - R1(A,B,C,D,X(13), 5,0xa9e3e905L); - R1(D,A,B,C,X( 2), 9,0xfcefa3f8L); - R1(C,D,A,B,X( 7),14,0x676f02d9L); - R1(B,C,D,A,X(12),20,0x8d2a4c8aL); - /* Round 2 */ - R2(A,B,C,D,X( 5), 4,0xfffa3942L); - R2(D,A,B,C,X( 8),11,0x8771f681L); - R2(C,D,A,B,X(11),16,0x6d9d6122L); - R2(B,C,D,A,X(14),23,0xfde5380cL); - R2(A,B,C,D,X( 1), 4,0xa4beea44L); - R2(D,A,B,C,X( 4),11,0x4bdecfa9L); - R2(C,D,A,B,X( 7),16,0xf6bb4b60L); - R2(B,C,D,A,X(10),23,0xbebfbc70L); - R2(A,B,C,D,X(13), 4,0x289b7ec6L); - R2(D,A,B,C,X( 0),11,0xeaa127faL); - R2(C,D,A,B,X( 3),16,0xd4ef3085L); - R2(B,C,D,A,X( 6),23,0x04881d05L); - R2(A,B,C,D,X( 9), 4,0xd9d4d039L); - R2(D,A,B,C,X(12),11,0xe6db99e5L); - R2(C,D,A,B,X(15),16,0x1fa27cf8L); - R2(B,C,D,A,X( 2),23,0xc4ac5665L); - /* Round 3 */ - R3(A,B,C,D,X( 0), 6,0xf4292244L); - R3(D,A,B,C,X( 7),10,0x432aff97L); - R3(C,D,A,B,X(14),15,0xab9423a7L); - R3(B,C,D,A,X( 5),21,0xfc93a039L); - R3(A,B,C,D,X(12), 6,0x655b59c3L); - R3(D,A,B,C,X( 3),10,0x8f0ccc92L); - R3(C,D,A,B,X(10),15,0xffeff47dL); - R3(B,C,D,A,X( 1),21,0x85845dd1L); - R3(A,B,C,D,X( 8), 6,0x6fa87e4fL); - R3(D,A,B,C,X(15),10,0xfe2ce6e0L); - R3(C,D,A,B,X( 6),15,0xa3014314L); - R3(B,C,D,A,X(13),21,0x4e0811a1L); - R3(A,B,C,D,X( 4), 6,0xf7537e82L); - R3(D,A,B,C,X(11),10,0xbd3af235L); - R3(C,D,A,B,X( 2),15,0x2ad7d2bbL); - R3(B,C,D,A,X( 9),21,0xeb86d391L); - - A = c->A += A; - B = c->B += B; - C = c->C += C; - D = c->D += D; - } - } -#endif - -#ifdef undef -int printit(unsigned long *l) - { - int i,ii; - - for (i=0; i<2; i++) - { - for (ii=0; ii<8; ii++) - { - fprintf(stderr,"%08lx ",l[i*8+ii]); - } - fprintf(stderr,"\n"); - } - } -#endif diff --git a/org.glite.jobid.api-c/src/md5_locl.h b/org.glite.jobid.api-c/src/md5_locl.h deleted file mode 100644 index e9e5b08..0000000 --- a/org.glite.jobid.api-c/src/md5_locl.h +++ /dev/null @@ -1,193 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* crypto/md5/md5_locl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * 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 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include - -#ifndef MD5_LONG_LOG2 -#define MD5_LONG_LOG2 2 /* default to 32 bits */ -#endif - -#ifdef MD5_ASM -# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || defined(__x86_64) || defined(__x86_64__) -# if !defined(B_ENDIAN) -# define md5_block_host_order md5_block_asm_host_order -# endif -# elif defined(__sparc) && defined(OPENSSL_SYS_ULTRASPARC) - void md5_block_asm_data_order_aligned (MD5_CTX *c, const MD5_LONG *p,size_t num); -# define HASH_BLOCK_DATA_ORDER_ALIGNED md5_block_asm_data_order_aligned -# endif -#endif - -MD5_JOBID_PROTO void md5_block_host_order (MD5_CTX *c, const void *p,size_t num); -MD5_JOBID_PROTO void md5_block_data_order (MD5_CTX *c, const void *p,size_t num); - -#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || defined(__x86_64) || defined(__x86_64__) -# if !defined(B_ENDIAN) -/* - * *_block_host_order is expected to handle aligned data while - * *_block_data_order - unaligned. As algorithm and host (x86) - * are in this case of the same "endianness" these two are - * otherwise indistinguishable. But normally you don't want to - * call the same function because unaligned access in places - * where alignment is expected is usually a "Bad Thing". Indeed, - * on RISCs you get punished with BUS ERROR signal or *severe* - * performance degradation. Intel CPUs are in turn perfectly - * capable of loading unaligned data without such drastic side - * effect. Yes, they say it's slower than aligned load, but no - * exception is generated and therefore performance degradation - * is *incomparable* with RISCs. What we should weight here is - * costs of unaligned access against costs of aligning data. - * According to my measurements allowing unaligned access results - * in ~9% performance improvement on Pentium II operating at - * 266MHz. I won't be surprised if the difference will be higher - * on faster systems:-) - * - * - */ -# define md5_block_data_order md5_block_host_order -# endif -#endif - -#define DATA_ORDER_IS_LITTLE_ENDIAN - -#define HASH_LONG MD5_LONG -#define HASH_LONG_LOG2 MD5_LONG_LOG2 -#define HASH_CTX MD5_CTX -#define HASH_CBLOCK MD5_CBLOCK -#define HASH_LBLOCK MD5_LBLOCK -#define HASH_UPDATE MD5_Update -#define HASH_TRANSFORM MD5_Transform -#define HASH_FINAL MD5_Final -#define HASH_MAKE_STRING(c,s) do { \ - unsigned long ll; \ - ll=(c)->A; HOST_l2c(ll,(s)); \ - ll=(c)->B; HOST_l2c(ll,(s)); \ - ll=(c)->C; HOST_l2c(ll,(s)); \ - ll=(c)->D; HOST_l2c(ll,(s)); \ - } while (0) -#define HASH_BLOCK_HOST_ORDER md5_block_host_order -#if !defined(L_ENDIAN) || defined(md5_block_data_order) -#define HASH_BLOCK_DATA_ORDER md5_block_data_order -/* - * Little-endians (Intel and Alpha) feel better without this. - * It looks like memcpy does better job than generic - * md5_block_data_order on copying-n-aligning input data. - * But frankly speaking I didn't expect such result on Alpha. - * On the other hand I've got this with egcs-1.0.2 and if - * program is compiled with another (better?) compiler it - * might turn out other way around. - * - * - */ -#endif - -#include "md32_common.h" - -/* -#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) -#define G(x,y,z) (((x) & (z)) | ((y) & (~(z)))) -*/ - -/* As pointed out by Wei Dai , the above can be - * simplified to the code below. Wei attributes these optimizations - * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. - */ -#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) -#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c)) -#define H(b,c,d) ((b) ^ (c) ^ (d)) -#define I(b,c,d) (((~(d)) | (b)) ^ (c)) - -#define R0(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+F((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; };\ - -#define R1(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+G((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; }; - -#define R2(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+H((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; }; - -#define R3(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+I((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; }; diff --git a/org.glite.jobid.api-c/src/strmd5.c b/org.glite.jobid.api-c/src/strmd5.c deleted file mode 100755 index 8543cea..0000000 --- a/org.glite.jobid.api-c/src/strmd5.c +++ /dev/null @@ -1,169 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - - -#include -#include -#include - -#define MD5_JOBID_PROTO static -#include "md5.h" -#include "strmd5.h" - -#include "md5_dgst.c" - - -static char mbuf[33]; -static const char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; -static char *b64r; - -int base64_encode(const void *enc, int enc_size, char *out, int out_max_size) -{ - - 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; -} - -int base64_decode(const char *enc,char *out,int max_out_size) -{ - unsigned int bits = 0; - int shift = 0; - int out_size = 0; - - if (!b64r) { - int i; - b64r = calloc(128,1); - - for (i=0; b64[i]; i++) b64r[(int)b64[i]] = i; - } - - while (*enc && *enc != '=') { - bits <<= 6; - bits |= b64r[(int)*enc++]; - shift += 6; - - while (shift >= 8) { - if (out_size >= max_out_size) return -1; - shift -= 8; - *out++ = (bits >> shift) & 0xff; - out_size++; - } - } - - return out_size; -} - -char *strmd5(const char *s, unsigned char *digest) -{ - MD5_CTX md5; - unsigned char d[16]; - int i; - - MD5_Init(&md5); - MD5_Update(&md5,s,strlen(s)); - MD5_Final(d,&md5); - - if (digest) memcpy(digest,d,sizeof(d)); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - mbuf[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - mbuf[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - mbuf[32] = 0; - return (char *) mbuf; -} - -char *str2md5(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char* ret = malloc(33); - int i; - - if (!ret) - return NULL; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - ret[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - ret[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - ret[32] = 0; - return ret; -} - -char *str2md5base64(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char buf[50]; - int l; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - l = base64_encode(d, 16, buf, sizeof(buf) - 1); - if (l < 1) - return NULL; - buf[l - 1] = 0; - return strdup(buf); -} diff --git a/org.glite.jobid.api-c/test/base64_test.cpp b/org.glite.jobid.api-c/test/base64_test.cpp deleted file mode 100644 index b7003a7..0000000 --- a/org.glite.jobid.api-c/test/base64_test.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "strmd5.h" - -class Base64Test: public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(Base64Test); - CPPUNIT_TEST(test); - CPPUNIT_TEST_SUITE_END(); -public: - void test(); -}; - -void Base64Test::test() -{ - int i; - unsigned char in[2000], b[4000], out[2000]; - - srandom(0xDEAD); - in[0] = 'x'; - for (i=1; i<2000; i++) { - char s[20]; - int len; - sprintf(s,"%d",i); - in[i] = random() % 256; - - std::cerr << '.'; - - base64_encode(in,i,(char *) b,sizeof b); - len = base64_decode((const char *) b,(char *) out,sizeof out); - - CPPUNIT_ASSERT_MESSAGE(std::string("len"),i == len); - CPPUNIT_ASSERT_MESSAGE(std::string(s),!memcmp(in,out,i)); - } - std::cerr << std::endl; -} - -CPPUNIT_TEST_SUITE_REGISTRATION(Base64Test); - - -int main (int argc,const char *argv[]) -{ - CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); - - assert(argc == 2); - std::ofstream xml(argv[1]); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - CppUnit::TestRunner runner; - runner.addTest(suite); - runner.run(controller); - - CppUnit::XmlOutputter xout( &result, xml ); - CppUnit::CompilerOutputter tout( &result, std::cout); - xout.write(); - tout.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} diff --git a/org.glite.jobid.api-cpp/Makefile b/org.glite.jobid.api-cpp/Makefile deleted file mode 100644 index 7586462..0000000 --- a/org.glite.jobid.api-cpp/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# Default values -top_srcdir=.. -stagedir=. -globalprefix=glite -jobidprefix=jobid -package=glite-jobid-api-cpp -version=0.0.0 - -CC:=gcc -CXX:=g++ - --include Makefile.inc - -version=${module.version} - -VPATH=${top_srcdir}/src:${top_srcdir}/interface:${top_srcdir}/test - -DEBUG:=-g -O0 -Wall - -CFLAGS:=${DEBUG} \ - -I${top_srcdir}/interface -I${top_srcdir}/src \ - ${COVERAGE_FLAGS} \ - -D_GNU_SOURCE - -COMPILE:=libtool --mode=compile ${CC} ${CFLAGS} -CXXCOMPILE:=libtool --mode=compile ${CXX} ${CXXFLAGS} -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install - -LIBOBJS:= -HDRS:=JobId.h - -LIBLOBJS:=${LIBOBJS:.o=.lo} - -LIB:= - -compile all: - - -check: compile -# - -clean: - rm -rvf *.o *.lo .libs lib* *.c *.cpp *.h - -distclean: - rm -rvf Makefile.inc *.spec debian/ - -install: - mkdir -p ${DESTDIR}${PREFIX}${prefix}/include/${globalprefix}/${jobidprefix} - (cd ${top_srcdir}/interface; ${INSTALL} -m 644 ${HDRS} ${DESTDIR}${PREFIX}${prefix}/include/${globalprefix}/${jobidprefix}) - -stage: - ${MAKE} install PREFIX=${stagedir} staging=1 - -%.o: %.c - ${COMPILE} -o $@ -c $< - - -.PHONY: default all compile check install clean distclean diff --git a/org.glite.jobid.api-cpp/configure b/org.glite.jobid.api-cpp/configure deleted file mode 100755 index bcb1531..0000000 --- a/org.glite.jobid.api-cpp/configure +++ /dev/null @@ -1,2058 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; -use POSIX qw(locale_h strftime); - -my $pwd = `pwd`; chomp $pwd; -my $prefix = '/usr'; -my $stagedir = undef; -my $root = $pwd.'/stage'; -my $sysroot = ''; -my $sysconfdir; -my $localstatedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my ($version, $force_version); -my $branch; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $jobid_tag = ''; -my $libdir = getlibdir(); -my $project = 'emi'; -my $project_version; -my (%projects, %project); -my $debug = 0; -my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : ''; - -my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal/; -my @default_nodes = qw/lb px proxyrenewal nagios/; -my %enable_nodes; -my %disable_nodes; -my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1); - -my %package = ( - 'maintainer' => 'CESNET Product Teams ', - 'uploaders' => 'FrantiÅ¡ek Dvořák ', - 'url' => 'http://glite.cern.ch', - 'debian_vcs' => 'Vcs-Cvs: :pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw -Vcs-Browser: http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi', -); - -# key: internal package name (arguments, ...) -# 'pkg': pkg-config name -# 'prefix': used when pkg-config fails -my %externs = ( - cares => { - prefix => '/opt/c-ares', - pkg => 'libcares' - }, - classads => { - prefix=> '/usr', - pkg => 'classads' - }, - cppunit => { - prefix=> '/usr', - pkg => 'cppunit' - }, - expat => { - prefix=> '/usr', - pkg => 'expat' - }, - globus => { - prefix=> '/opt/globus', - pkg => 'globus-gssapi-gsi' - }, - 'myproxy-devel' => { - prefix=> '/opt/globus', - pkg => 'myproxy' - }, - 'myproxy-server' => { - prefix=> '', - }, - 'myproxy-admin' => { - prefix=> '', - }, - gsoap => { - prefix=> '/usr', - pkg => 'gsoap' - }, - gsoapxx => { - prefix=> '/usr', - pkg => 'gsoap++' - }, - mysql => { - prefix=> '/usr' - }, - 'mysql-devel' => { - prefix=> '' - }, - 'mysql-server' => { - prefix => '' - }, - voms => { - prefix => '/opt/glite', - pkg => 'voms-2.0' - }, - gridsite => { - prefix => '/opt/glite' - }, - lcas => { - prefix => '/opt/glite', - pkg => 'lcas' - }, - trustmanager => { - prefix => '/opt/glite' - }, - trustmanager_axis => { - prefix => '/opt/glite' - }, - utiljava => { - prefix=> '/opt/glite' - }, - ant => { - prefix=> '/usr' - }, - jdk => { - prefix=> '/usr/java/latest', - locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ], - }, - libtar => { - prefix=> '/usr' - }, - axis => { - prefix=> '/usr' - }, - log4c => { - prefix=> '/usr' - }, - postgresql => { - prefix=> '/usr' - }, - activemq => { - prefix=>'/opt/activemq-cpp-library', - pkg => 'activemq-cpp' - }, -); - -my %jar = ( - 'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar', - 'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %buildroot; -my (%etics_externs, %etics_projects); - -# -# modules of the subsystems -# -# additional modules from $project{modules} are automatically added -# -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], - 'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/], - 'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - 'gridsite' => [ qw/apache libs commands core devel slashgrid services service-clients gsexec/ ], - 'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ], - 'canl' => [ qw/c c-devel/ ], - ); - -# -# sub-packages -# -# modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly -# -my %subpackages = ( - 'jobid.api-c-devel' => 'jobid.api-c', - 'jobid.api-cpp-devel' => 'jobid.api-cpp', - 'lbjp-common.db-devel' => 'lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'lbjp-common.log', - 'lbjp-common.maildir-devel' => 'lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'lbjp-common.trio', - 'lb.client-progs' => 'lb.client', - 'lb.client-devel' => 'lb.client', - 'lb.common-devel' => 'lb.common', - 'lb.logger-devel' => 'lb.logger', - 'lb.state-machine-devel' => 'lb.state-machine', - 'px.proxyrenewal-devel' => 'px.proxyrenewal', - 'px.proxyrenewal-progs' => 'px.proxyrenewal', - 'canl.c-devel' => 'canl.c', -); - -my @opts = ( - 'prefix:s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour:s' => \$thrflavour, - 'nothrflavour:s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$force_version, - 'branch=s' => \$branch, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'root:s' => \$root, - 'sysroot:s' => \$sysroot, - 'sysconfdir=s' => \$sysconfdir, - 'localstatedir=s' => \$localstatedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'jobid-tag=s' => \$jobid_tag, - 'canl-tag=s' => \$canl_tag, - 'help' => \$help, - 'libdir=s' => \$libdir, - 'project=s' => \$project, - 'debug' => \$debug, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; -$prefix=~s/\/$//; -$root=~s/\/$//; -$sysroot=~s/\/$//; -if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; } -if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; } -$sysconfdir=~s/\/$//; -$localstatedir=~s/\/$//; - -$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq ''; -$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq ''; -$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq ''; - -$externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq ''; -$externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq ''; -$externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq ''; - -if ($project =~ /^([^0-9]*)(.*)$/) { - $project = $1; - $project_version = $2; -} -%project = %{$projects{$project}}; -$project_version = $project{current_version} unless $project_version; -for my $platform (keys %{$project{etics_externs}}) { - for $_ (keys %{$project{etics_externs}{$platform}}) { - $etics_externs{$platform}{$_} = $project{etics_externs}{$platform}{$_}; - } -} -reshuffle_platforms(\%etics_externs, $project{supported_platforms}); -reshuffle_platforms(\%{$project{etics_externs_devel}}, $project{supported_platforms}); -for $_ (keys %{$project{etics_projects}}) { - $etics_projects{$_} = $project{etics_projects}{$_}; -} -for $_ (keys %{$project{need_externs_aux}}) { - $need_externs_aux{$_} = $project{need_externs_aux}{$_}; -} -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - my ($pkg, $type) =/([^:]*)(?::(.*))?/; - $type = 'BR' unless ($type); - - push @{$need_externs{$ext}},$pkg; - $need_externs_type{$ext}->{$pkg} = $type; - } -} -if ($project eq 'emi') { - $extranodmod{lb} = 'lb.emi-lb'; - $extranodmod{px} = 'px.emi-px'; -} -for $_ (keys %{$project{modules}}) { - push @{$lbmodules{$_}},@{$project{modules}{$_}}; -} - - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name}; - my @m; - - if (exists $lbmodules{$listmodules}) { - @m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}}; - } else { - if ($project eq 'emi' and $project_version == 1) { - # no sub-packages in EMI-1 - } else { - for my $sub (keys %subpackages) { - push @m, $sub if ($subpackages{$sub} eq $listmodules); - } - } - } - print map $_ eq "" ? "" : "$_ ", @m; - print "\n"; - exit 0; -} - -warn "$0: --branch and --output make sense only in --mode=etics\n" - if ($output || $branch) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_}); - } -} - -if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } }; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $root unless $stagedir; -$stagedir=~s/\/$// if ($stagedir); - -if ($mode eq 'build') { for my $ext (keys %externs) { - if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; } - elsif (defined $externs{$ext}{pkg}) { - my ($flag, $env, $cmd, $ret); - my $pkg = $externs{$ext}{pkg}; - my $flagname = uc $externs{$ext}{pkg}; - $flagname =~ s/-[0-9\.]*$//; - $flagname =~ y/-\+/_X/; - - print "Checking $pkg ... "; - $env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig"; - $cmd = "$env pkg-config $pkg --exists >/dev/null"; - `$cmd`; $ret = $?; - print "('$cmd' => $ret)\n" if ($debug); - if ($ret == 0) { - $externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`; - chomp $externs{$ext}{prefix}; - print "$externs{$ext}{prefix}\n"; - - $flag=`$env pkg-config $pkg --cflags`; - $externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag); - $flag=`$env pkg-config $pkg --libs`; - $externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag); - } else { - print "(using default $externs{$ext}{prefix})\n"; - } - print "\n" if ($debug); - } - elsif ($ext eq 'jdk') { - my $jdk_prefix; - - print "Looking for some caffein ... "; - if (defined $ENV{'JDK_HOME'}) { - $jdk_prefix = $ENV{'JDK_HOME'}; - print "JDK_HOME=$jdk_prefix\n"; - } elsif (defined $ENV{'JAVA_HOME'}) { - $jdk_prefix = $ENV{'JAVA_HOME'}; - print "JAVA_HOME=$jdk_prefix\n"; - } else { - foreach my $i (0..$#{$externs{$ext}{locations}}) { - if (-e $externs{$ext}{locations}[$i]) { - $jdk_prefix=$externs{$ext}{locations}[$i]; - print "(found directory $jdk_prefix)\n"; - last; - } - } - print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix); - } - $externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix); - } -} } - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') { - print CONF "$_=$ENV{$_} " if (defined $ENV{$_}); - } - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } }; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - if ($module) { - print "Not creating summary Makefile\n" if $debug; - } else { - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\n"; - print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n"; - print MAK "clean check install:\n"; - - for (@modules) { - my $full = full($_); - print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $buildroot{$_} eq '' ? - "\tcd $full && \${MAKE} distclean\n" : - "\trm -rf $full/$buildroot{$_}\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage'; - - my $full = full($_); - my $build = $buildroot{$_}; - - print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n"; - print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n"; - } - - close MAK; - } -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag) { - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - if ($canl_tag) { - for (@{$lbmodules{'canl'}}){ - if ("canl.".$_ eq $module){ - $tag = '-r '.$canl_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%etics_externs = ( - default => { - 'myproxy-devel'=>'myproxy-devel', - 'myproxy-server'=>'myproxy-server', - 'myproxy-admin'=>'myproxy-admin', - cares=>'c-ares', - utiljava=>'org.glite.security.util-java', - gpt=>'gpt', - fetchcrl=>'fetch-crl', - activemq=>'activemq-cpp-library', - }, -); - -%etics_projects = ( -); - -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads libtool:B globus:B/ ], - 'lb.common' => [ qw/expat cares:B cppunit:B classads libtool:B globus:B/ ], - 'lb.doc' => [ qw/tetex-latex:B/ ], - 'lb.logger' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B globus:B/ ], - 'lb.nagios' => [ qw/globus_proxy_utils:R/ ], - 'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql-server:R cppunit:B gsoap:B classads voms:B lcas gridsite:B bison:B libtool:B libxml2 flex:B/ ], - 'lb.state-machine' => [ qw/classads libtool:B libxslt:B expat:B globus:B/ ], - 'lb.utils' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ], - 'lb.ws-test' => [ qw/gsoap:B libtool:B globus:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/docbook-utils:B libtool:B globus:B/ ], - 'lbjp-common.db' => [ qw/mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.log' => [ qw/log4c libtool:B/ ], - 'lbjp-common.maildir' => [ qw/libtool:B/ ], - 'lbjp-common.server-bones' => [ qw/libtool:B/ ], - 'lbjp-common.trio' => [ qw/cppunit:B libtool:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.gss' => [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B/ ], - 'lbjp-common.gsoap-plugin' => [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B/ ], - 'jobid.api-c' => [ qw/cppunit:B libtool:B openssl:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B libtool:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus_essentials:R globus:B mysql-server:R/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B mysql-server:R/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], - 'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'gridsite.commands' => [ qw/curl:R openssl:R/ ], - 'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ], - 'gridsite.libs' => [ qw/libxml2:R openssl:R/ ], - 'gridsite.devel' => [ qw// ], - 'gridsite.slashgrid' => [ qw/curl:R fuse:R/], - 'gridsite.services' => [ qw/curl:R gsoap:R/ ], - 'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ], - 'gridsite.gsexec' => [ qw// ], - 'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B/ ], - 'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec - 'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B krb5-devel:B/ ], -); - -%need_jars = ( - 'jobid.api-java' => [ qw/jakarta-commons-codec/ ], - 'lb.client-java' => [ qw/jakarta-commons-lang/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp:B jobid.api-c - lbjp-common.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - lb.ws-interface:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp:B jobid.api-c - lb.types:B lbjp-common.trio lbjp-common.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - lbjp-common.log - jobid.api-c - lb.common - lbjp-common.gss - / ], - 'lb.logger-msg' => [ qw/ - lb.logger:B - / ], - 'lb.nagios' => [ qw/ - lb.client:R - lb.ws-test:R - lb.utils:R - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log - jobid.api-c - lbjp-common.gsoap-plugin lbjp-common.gss - / ], - 'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine lb.types:B - / ], - 'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/ - jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client - lbjp-common.gss lbjp-common.log - / ], - 'lb.yaim' => [ qw// ], - 'lb.glite-LB' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lb.emi-lb' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.log' => [ qw// ], - 'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ], - 'lbjp-common.trio' => [ qw// ], - 'lbjp-common.gss' => [ qw// ], - 'lbjp-common.gsoap-plugin' => [ qw/lbjp-common.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - lbjp-common.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], - - 'gridsite.core' => [ qw// ], - 'gridsite.commands' => [ qw/gridsite.core:B/ ], - 'gridsite.apache' => [ qw/gridsite.core:B/ ], - 'gridsite.libs' => [ qw/gridsite.core:B / ], - 'gridsite.devel' => [ qw/gridsite.core:B/ ], - 'gridsite.slashgrid' => [ qw/gridsite.core:B/], - 'gridsite.services' => [ qw/gridsite.core:B/ ], - 'gridsite.service-clients' => [ qw/gridsite.core:B/ ], - 'gridsite.gsexec' => [ qw/gridsite.core:B/ ], - - 'px.proxyrenewal' => [ qw// ], - 'px.glite-PX' => [qw/px.myproxy-yaim:R/], - 'px.emi-px' => [qw/px.myproxy-yaim:R/], - 'px.myproxy-yaim' => [ qw// ], - 'px.myproxy-config' => [], - - 'canl.c' => [], - - # sub-packages (virtual ETICS components depending on the main) - 'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ], - 'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ], - 'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ], - 'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ], - 'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ], - 'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ], - 'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ], - 'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ], - 'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ], - 'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ], - 'lb.client-progs' => [ qw/lb.client:B/ ], - 'lb.client-devel' => [ qw/lb.client:B/ ], - 'lb.common-devel' => [ qw/lb.common:B/ ], - 'lb.logger-devel' => [ qw/lb.logger:B/ ], - 'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ], - 'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ], - 'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ], - 'canl.c-devel' => [ qw/canl.c:B/ ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( - gridsite=>'org.gridsite.core', - 'canl.c' => 'emi.canl.canl-c', - 'canl.c-devel' => 'emi.canl.canl-c', - 'jobid.api-c-devel' => 'org.glite.jobid.api-c', - 'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp', - 'lbjp-common.db-devel' => 'org.glite.lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'org.glite.lbjp-common.log', - 'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio', - 'lb.client-devel' => 'org.glite.lb.client', - 'lb.client-progs' => 'org.glite.lb.client', - 'lb.common-devel' => 'org.glite.lb.common', - 'lb.logger-devel' => 'org.glite.lb.logger', - 'lb.state-machine-devel' => 'org.glite.lb.state-machine', - 'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal', - 'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal', -); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', - lb => 'lb.glite-LB', - px => 'px.glite-PX', - proxyrenewal => 'px.proxyrenewal', - canl => 'canl.c', -); - -%obsoletes = ( - 'lb.yaim' => [ qq/glite-yaim-lb/ ], - 'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ], - 'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ], - 'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], -); - -%conflicts = ( -); - -%provides = ( - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], - 'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ], -); - -%cvs_prefix = ( - 'lb' => 'org.glite', - 'jp' => 'org.glite', - 'jobid' => 'org.glite', - 'lbjp-common' => 'org.glite', - 'gridsite' => 'org', - 'px' => 'org.glite', - 'canl' => 'emi', -); - -%cvs_tag_prefix = ( - 'lb' => 'glite-', - 'jp' => 'glite-', - 'jobid' => 'glite-', - 'lbjp-common' => 'glite-', - 'gridsite' => '', - 'px' => 'glite-', - 'canl' => 'emi-', -); - -# ==== projects specification ==== -# etics_name ........... ETICS project name -# conf_prefix .......... ETICS configurations name prefix -# tag_prefix ........... VCS tag prefix -# local_prefix ......... prefix (relative to stage) -# etics_externs ........ ETICS modules names of externals -# (${NAME.location}, ETICS conf. dependencies) -# etics_projects ....... ETICS project names of externals -# etics_externs_devel .. ETICS modules names of devel versions of externals -# etics_locations ...... ETICS locations in ${NAME.location} properties -# need_externs_aux ..... project-specific external dependencies -# supported_platforms .. platforms supported by the project -# modules .............. additional modules in subsystems -%projects = ( - glite => { - current_version => 3, - etics_name => 'org.glite', - conf_prefix => { %cvs_tag_prefix }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}', - local_prefix => '', - etics_externs => { - default => { - globus_essentials=>'vdt_globus_essentials', - globus=>'globus', - globus_proxy_utils=>'vdt_globus_essentials', - gridsite=>'org.gridsite.libs', - yaim_core=>'org.glite.yaim.core', - gip_release=>'glite-info-provider-release', - gip_service=>'glite-info-provider-service', - bdii=>'bdii', - glite_version=>'glite-version', - glite_info_templates=>'glite-info-templates', - glue_schema=>'glue-schema', - trustmanager=>'org.glite.security.trustmanager', - axis=>'axis', - lcas=>'org.glite.security.lcas', - gsoapxx=>'-', - jdk=>'jdk', - voms=>'org.glite.security.voms-api-cpp', - }, - }, - etics_externs_devel => { - default => { - gridsite=>'org.gridsite.devel', - voms=>'org.glite.security.voms-api', - }, - }, - etics_projects => { - vdt=>[qw/globus globus_essentials globus_proxy_utils gpt/], - 'org.glite'=>[qw/voms gridsite lcas gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/], - }, - etics_locations => { - '*' => '', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ], - 'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R/ ], - 'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412 => 1, - sl5_ia32_gcc412 => 1, - deb5_x86_64_gcc432 => 1, - deb5_ia32_gcc432 => 1, - slc4_x86_64_gcc346 => 1, - slc4_ia32_gcc346 => 1, - }, - modules => { - 'lb' => [ qw/glite-LB/ ], - 'px' => [ qw/glite-PX/ ], - }, - }, - - emi => { - current_version => 2, - etics_name => 'emi', - conf_prefix => { - 'lb' => 'emi-', - 'jp' => 'emi-', - 'jobid' => 'emi-', - 'lbjp-common' => 'emi-', - 'gridsite' => 'emi-', - 'px' => 'emi-', - 'canl' => 'emi-', - }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour= --nothrflavour=', - local_prefix => '/usr', - etics_externs => { - default => { - globus_essentials=>'globus-gssapi-gsi', - globus=>'globus-gssapi-gsi-devel', - globus_proxy_utils=>'globus-proxy-utils', - gridsite=>'emi.gridsite.libs', - yaim_core=>'emi.yaim.yaim-core', - yaim_bdii=>'emi.bdii.yaim-bdii', - gip_service=>'emi.bdii.glite-info-provider-service', - bdii=>'emi.bdii.core', - glite_version=>'emi.emi-version', - glue_schema=>'emi.bdii.glue-schema', - trustmanager=>'emi.java-security.trustmanager', - trustmanager_axis=>'emi.java-security.trustmanager-axis', - axis=>'axis1.4', - lcas=>'emi.sac.lcas', - gsoapxx=>'-', - jdk=>'java', - voms => 'emi.voms.voms-api', - }, - sl5_x86_64_gcc412EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - sl6_x86_64_gcc446EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - deb6_x86_64_gcc445 => { - axis => 'axis1.4', - # mappings in ETICS project configuration - #globus_essentials => 'libglobus-gssapi-gsi4', - #globus => 'libglobus-gssapi-gsi-dev', - #axis => 'libaxis-java', - #cares => 'libc-ares2', - #cppunit => 'libcppunit', - #expat => 'libexpat1', - #log4c => 'liblog4c3', - #curl => 'libcurl3', - #'mysql' => 'libmysqlclient16', - #'mysql-devel' => 'libmysqlclient-dev', - #libxslt => 'xsltproc', - #'jakarta-commons-codec' => 'libcommons-codec-java', - #'jakarta-commons-lang' => 'libcommons-lang-java', - #'tetex-latex' => 'texlive-latex-extra', - #'perl-LDAP' => 'libnet-ldap-perl', - #'fuse-lib' => 'libfuse2', - #'fuse' => 'fuse-utils', - }, - }, - etics_externs_devel => { - default => { - cares => 'c-ares-devel', - classads => 'classads-devel', - cppunit => 'cppunit-devel', - expat => 'expat-devel', - gsoap => 'gsoap-devel', - voms => 'emi.voms.voms-api-devel', - libtar => 'libtar-devel', - log4c => 'log4c-devel', - postgresql => 'postgresql-devel', - curl => 'curl-devel', - libxml2 => 'libxml2-devel', - openssl => 'openssl-devel', - gridsite=>'emi.gridsite.devel', - jdk=>'java-devel', - }, - deb6_x86_64_gcc445 => { - # mappings in ETICS project configuration - #cares => 'libc-ares-dev', - #cppunit => 'libcppunit-dev', - #expat => 'libexpat1-dev', - #libtar => 'libtar-dev', - #log4c => 'liblog4c-dev', - #postgresql => 'libpq-dev', - #curl => 'libcurl4-openssl-dev', - #libxml2 => 'libxml2-dev', - #openssl => 'libssl-dev', - #'tetex-latex' => 'texlive-latex-extra', - #libxslt=>'xsltproc', - #'httpd-devel' => 'apache2-prefork-dev', - #'fuse-devel' => 'libfuse-dev', - #gsoap => 'gsoap', - #'krb5-devel' => 'libkrb5-dev', - }, - }, - etics_projects => { - 'emi'=>[qw/voms voms-devel gridsite lcas gip_service bdii glite_version glue_schema yaim_core yaim_bdii trustmanager trustmanager_axis/], - }, - etics_locations => { - axis => 'axis', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ], - 'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - 'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412EPEL => 1, - sl5_ia32_gcc412EPEL => 1, - sl6_x86_64_gcc446EPEL => 1, - deb6_x86_64_gcc445 => 1, - }, - modules => { - 'lb' => [ qw/emi-lb/ ], - 'px' => [ qw/emi-px/ ], - }, - }, -); - -%platform_properties = ( - 'jobid.api-java' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.types' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.doc' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.ws-interface' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.nagios' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.myproxy-config' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'gridsite.devel' => { - default => { 'packageName' => 'gridsite-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' }, - }, - 'jobid.api-c-devel' => { - default => { 'packageName' => 'glite-jobid-api-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' }, - }, - 'jobid.api-cpp-devel' => { - default => { 'packageName' => 'glite-jobid-api-cpp-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' }, - }, - 'lbjp-common.db-devel' => { - default => { 'packageName' => 'glite-lbjp-common-db-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' }, - }, - 'lbjp-common.gsoap-plugin-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' }, - }, - 'lbjp-common.gss-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gss-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' }, - }, - 'lbjp-common.jp-interface-devel' => { - default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' }, - }, - 'lbjp-common.log-devel' => { - default => { 'packageName' => 'glite-lbjp-common-log-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' }, - }, - 'lbjp-common.maildir-devel' => { - default => { 'packageName' => 'glite-lbjp-common-maildir-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' }, - }, - 'lbjp-common.server-bones-devel' => { - default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' }, - }, - 'lbjp-common.trio-devel' => { - default => { 'packageName' => 'glite-lbjp-common-trio-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' }, - }, - 'lb.client-devel' => { - default => { 'packageName' => 'glite-lb-client-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' }, - }, - 'lb.common-devel' => { - default => { 'packageName' => 'glite-lb-common-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' }, - }, - 'lb.state-machine-devel' => { - default => { 'packageName' => 'glite-lb-state-machine-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' }, - }, - 'lb.logger-devel' => { - default => { 'packageName' => 'glite-lb-logger-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' }, - }, - 'px.proxyrenewal-devel' => { - default => { 'packageName' => 'glite-px-proxyrenewal-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' }, - }, -); - -my @k = keys %deps_aux; -@buildroot{@k} = ('') x ($#k+1); - -$buildroot{'gridsite.core'} = 'src'; -} - -sub full -{ - my ($short) = @_; - my $subsys = $short; - $subsys =~ s/\..*//; - - my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite'; - return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short"; -} - -sub get_version -{ - my ($fmod, $top_srcdir) = @_; - - my ($subsys,$mod) = split /\./,$fmod,2; - my ($major,$minor,$rev,$age); - my $old_; - - if ($force_version) { - $force_version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - my $path = "$top_srcdir/project"; - if ($subsys eq 'gridsite') { - $path = "$cvs_prefix{$subsys}.$subsys.core/project"; - } - open V,"$path/version.properties" - or die "$path/version.properties: $!\n"; - - $old_ = $_; - while () { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - $_ = $old_; - } - $version = "$major.$minor.$rev-$age"; - - return ($major, $minor, $rev, $age); -} - -sub get_description -{ - my ($top_srcdir) = @_; - - my $cvs_module = $top_srcdir; - my $package_description = ""; - my $package_summary = ""; - - if (-e "$cvs_module/project/package.description") { - open V, "$cvs_module/project/package.description"; - $package_description = join ("", ); - close V; - chomp $package_description; - } - else { - print STDERR "package.description not found for $subsys.$module!\n"; } - - if (-e "$cvs_module/project/package.summary") { - open V, "$cvs_module/project/package.summary"; - $package_summary = join ("", ); - close V; - chomp $package_summary; - $package_summary =~ s/\n/\\n/g; - } - else { - print STDERR "package.summary not found for $subsys.$module!\n"; } - - return ($package_summary, $package_description); -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb -lbjp-common.gss lbjp-common.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px -canl.c -/; - @aux{@m} = (1) x ($#m+1); - - my ($short) = @_; - my $full = full $short; - my ($subsys,$mod) = split /\./,$short,2; - my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}"; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $top_srcdir = '.'; - my $abs_srcdir = ''; - my $build = ''; - - if ($module) { - $top_srcdir = $0; - $top_srcdir =~ s,/?[^/]*$,,; - $abs_srcdir = $top_srcdir; - $top_srcdir =~ s,^$,\.,; - } else { - $build = "$full/"; - $abs_srcdir = "$full/"; - unless ($buildroot{$_} eq '') { - $top_srcdir = '..'; - $build .= "$buildroot{$_}/"; - unless (-d "$build") { - mkdir "$build" or die "mkdir $build: $!\n"; - } - } - } - - my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir; - my ($package_summary, $package_description) = get_description $abs_srcdir; - if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; } - my $package_description_debian = $package_description; - $package_description_debian =~ s/^/ /mg; - - my ($old_locale, $specdate, $debdate); - - # files for ETICS always in root source directory - mkdir $abs_srcdir."project" unless (-d $abs_srcdir."project"); - open PKGCHL,">".$abs_srcdir."project/changelog" - or die $abs_srcdir."project/changelog: $!\n"; - $old_locale = setlocale(LC_TIME); - setlocale(LC_TIME, "C"); - $specdate = strftime("%a %b %d %Y", gmtime()); - $debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime()); - setlocale(LC_TIME, $old_locale); - print PKGCHL qq{* $specdate CESNET team -- automatically generated package -}; - close PKGCHL; - - unless ($top_srcdir eq '.') { - unlink $build."Makefile"; - symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n"; - } - - open MKINC,">".$build."Makefile.inc" - or die $build."Makefile.inc: $!\n"; - - print "Creating ".$build."Makefile.inc\n"; - - print MKINC qq{project = $project -PREFIX = $root -prefix = $prefix -stagedir = $stagedir -sysroot = $sysroot -sysconfdir = $sysconfdir -localstatedir = $localstatedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -libdir = $libdir -top_srcdir = $top_srcdir -}; - - for (@{$need_externs{$short}}) { - next unless defined $externs{$_} and defined $externs{$_}{prefix}; - print MKINC "${_}_prefix = $externs{$_}{prefix}\n"; - print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags}; - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; - - my $dh; - my $debian = 0; - - opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!"; - for my $dir (readdir $dh) { - if ($dir=~/^(.*)\.spec$/) { - if ($1 ne $packageName) { - printf STDERR "Changed RPM name: $packageName --> $1\n" if ($debug);; - $packageName=$1; - } - last; - } - } - closedir $dh; - - for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") { - if (-f "$abs_srcdir/project/$file") { - my $old_ = $_; - printf STDERR "Creating $build$file\n" if ($debug);; - open DST, ">$build$file"; - open SRC, "<$abs_srcdir/project/$file"; - while () { - if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; } - if (/\@URL\@/) { s/\@URL\@/$package{url}/g; } - if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; } - if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; } - if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; } - if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; } - if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; } - if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; } - if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; } - if (/\@AGE\@/) { s/\@AGE\@/$age/g; } - if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; } - if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; } - if (/\@DEBIAN_VCS\@/) { s/\@DEBIAN_VCS\@/$package{debian_vcs}/g; } - if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; } - if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; } - if (/^\s*.+\/configure\s/ and $force_version) { - print "Version forced to $version\n" if ($debug);; - s/--version\s+\S+\s?//; - s/$/ --version $version/; - } - printf DST "%s", "$_"; - } - close SRC; - close DST; - $_ = $old_; - } - } - - print "Creating ${build}debian/\n" if ($debug);; - - `rm -rfv ${build}debian`; - mkdir $build."debian" or die $!; - `cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`; - `mv ${build}debian.* ${build}debian/ 2>/dev/null`; - `rm -f ${build}debian/*.orig`; - opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!"; - for $_ (readdir $dh) { - if (/^debian\.(.*)/) { - `mv ${build}debian/$_ ${build}debian/$1`; - $debian = 1; - } - } - closedir $dh; - - if ($debian) { - my ($dir, $file); - - chmod 0755, "${build}debian/rules"; - $file="${build}debian/docs"; if (not -f $file) { `touch $file`; } - $dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; } - $file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` } - $file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` } - $file="${build}debian/changelog"; if (not -f $file) { - open FH, ">$file" or die $!; - print FH qq{$packageName ($major.$minor.$rev-$age) unstable; urgency=low - - * Automatically generated package - - -- $package{maintainer} $debdate -}; - close FH; - } - - } else { - `rm -rf ${build}debian`; - } -} - -BEGIN{ -}; - -sub mode_etics_packaging { - my ($fmod, $cmd, $rpmprepare, $debprepare) = @_; - my ($workspaceDir, $srcPackageName, $srcAge, $topDir); - - # old-school packaging by ETICS for EMI-1 - if ($project eq 'emi' and $project_version == 1) { return; } - - if ($fmod eq 'gridsite.core') { - $workspaceDir = '..'; - $srcPackageName = 'gridsite'; - $srcAge = ''; - $topDir = '../'; - } else { - $workspaceDir = '${workspaceDir}'; - $srcPackageName = '${packageName}'; - $srcAge = '-${age}'; - $topDir = ''; - } - - $cmd->{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SRPMSLocation}'; - $cmd->{default}{packaging} = $rpmprepare; - $cmd->{default}{packaging} .= "dir=\${workspaceDir}/rpm_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SRPMSLocation} \$dir/{BUILD,RPMS,SOURCES,SRPMS} 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/SOURCES/ - rpmbuild -bs --nodeps --define \"_topdir \$dir\" $srcPackageName.spec - cp -v \$dir/SRPMS/*.src.rpm \${package.SRPMSLocation}/ - rm -rf \$dir"; - - for my $p ('deb5_x86_64_gcc432', 'deb5_ia32_gcc432', 'deb6_x86_64_gcc445', 'deb6_ia32_gcc445') { - for my $c (keys %{$cmd->{default}}) { $cmd->{$p}{$c} = $cmd->{default}{$c}; } - $cmd->{$p}{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SDEBSLocation}'; - $cmd->{$p}{packaging} = $debprepare; - $cmd->{$p}{packaging} .= "dir=\${workspaceDir}/dpkg_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SDEBSLocation} \$dir 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/${srcPackageName}_\${version}.orig.tar.gz - tar xzf \$dir/${srcPackageName}_\${version}.orig.tar.gz -C \$dir - cp -rf ${topDir}debian/ \$dir/$srcPackageName-\${version}/ - cd \$dir/$srcPackageName-\${version} - dpkg-buildpackage -S -d -nc - cd - - cp -v \$dir/*.tar.gz \$dir/*.dsc \${package.SDEBSLocation}/ - rm -rf \$dir"; - } -} - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod,2; - my $full = full "$subsys.$module"; - - my ($major,$minor,$rev,$age) = get_version $fmod, $full; - - # XXX: --with ignored for platform-dependend packages - my @copts = (); - my %ge; - @ge{@{$etics_projects{$project{etics_name}}}} = (1) x ($#{$etics_projects{$project{etics_name}}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/ and (defined $externs{$_} or defined $jar{$_})) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - next if ($eext eq '-'); - if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}) { - $eext = $project{etics_locations}{$_} if ($project{etics_locations}{$_}); - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } else { - if ($ge{$_} and not defined $externs{$_}{pkg}) { - push @copts, "--with-$_=\${stageDir}"; - } - } - } - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}); - } - - my $conf; - my $conftag; - my ($confprefix, $nameprefix, $packageName); - - $dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n"; - - $confprefix = $project{conf_prefix}{$subsys}; - $nameprefix = $confprefix; - $nameprefix =~ s/-$//; - $nameprefix =~ s/-/\./g; - $packageName = "$project{tag_prefix}{$subsys}$subsys-${module}"; - - if ($branch) { - $conf = "$confprefix${subsys}-${module}_$branch"; - $conftag = $branch; - # forced low age number - $age = $branch eq 'HEAD' ? '0head' : '0dev'; - push @copts, '--version ${version}-${age}'; - } - else { - $conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; -# XXX: gridsite hack - $conftag = $subsys eq 'gridsite' ? "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : - "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - - # lowering age for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age - 1; - } - } - - # emi1 suffix for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age.$project.$project_version; - $conf = $conf.$project.$project_version; - } - - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"}; - - my $confdir = $buildroot{"$subsys.$module"} eq '' ? '.' : '..'; - - my $cvs_module = full "$subsys.$module"; - my ($package_summary, $package_description) = get_description $cvs_module; - if ($package_description) { - $package_description =~ s/\n/\\n/g; - $package_description = "package.description = $package_description\n"; - } - if ($package_summary) { - $package_summary = "package.summary = $package_summary\n"; - } - - my %cmd; - $cmd_vcs{checkout} = "cvs -d \${vcsroot} co -d \${moduleName} ".($conftag eq 'HEAD' ? '-A' : '-r ${tag}')." $cvs_module 2>/dev/null"; - #$cmd_vcs{checkout} = "((test -d jra1mw/.git && (cd jra1mw; git pull)) || (git clone -q http://scientific.zcu.cz/git/jra1mw.git"; - #$cmd_vcs{checkout} .= " && (cd jra1mw; git checkout -b \${tag} --track origin/\${tag})" unless ($conftag eq /HEAD/); - #$cmd_vcs{checkout} .= ")) && (test -d \${moduleName} || ln -s jra1mw/$cvs_module \${moduleName})"; - $cmd_vcs{checkout} .= "\n\ttest -f \${packageName}-\${version}-\${age}.src.tar.gz || (ln -s \${moduleName} \${packageName}-\${version}; tar -chf - \${packageName}-\${version} --exclude CVS --exclude .git --exclude .etics | gzip --best > \${packageName}-\${version}-\${age}.src.tar.gz; rm \${packageName}-\${version})"; - $cmd_vcs{tag} = "cvs -d \${vcsroot} tag -R \${tag} ${moduleName}"; - - $cmd{default}{init} = 'None'; - $cmd{default}{configure} = 'None'; - $cmd{default}{compile} = 'None'; - $cmd{default}{test} = 'None'; - $cmd{default}{install} = 'None'; - $cmd{default}{packaging} = 'None'; - $cmd{default}{clean} = 'make clean'; - - if (exists $subpackages{$fmod}) { - $cmd{default}{clean} = 'None'; - $cmd{default}{packaging} = "echo building nothing, $subpackages{$fmod} will build this package"; - $cmd_vcs{checkout} = "mkdir -v \${moduleName} 2>/dev/null || true"; - } elsif ($subsys eq 'gridsite') { - $cmd_vcs{tag} = 'None'; - - if ($module eq 'core') { - my $flags; - - if ($project ne 'glite') { - # don't evaluate pkg-config calls to get them into source package - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=\`pkg-config gsoap --variable=prefix\` - OPENSSL_GLOBUS_FLAGS=\`pkg-config globus-openssl --cflags\` - OPENSSL_GLOBUS_LIBS=\`pkg-config globus-openssl --libs\`'; - } else { - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=${gsoap.location} - OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor} - OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir} - HTTPD_FLAGS=-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-1 -I${httpd-devel.location}/include/apr-1.0 -I${httpd-devel.location}/include/apr-0 -I${httpd-devel.location}/include/pcre'; - } - - $cmd{default}{configure} = "cat > Makefile.inc </dev/null"; - $cmd{default}{init} = 'echo "/sbin/ldconfig" > project/.post - echo "/sbin/ldconfig" > project/.postun'; - $cmd{default}{configure} = "cat > src/Makefile.inc <{default}}) { - $defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n"; - } - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = $project{etics_name}.$subsys.$module -displayName = $conf -description = $cvs_prefix{$subsys}.$subsys.$module -projectName = $project{etics_name} -age = $age -deploymentType = None -vcsroot = :pserver:anonymous\@glite.cvs.cern.ch:/cvs/glite -tag = $conftag -version = $major.$minor.$rev -$dwpath -[Platform-default:VcsCommand] -displayName = None -description = None -tag = $cmd_vcs{tag} -branch = None -commit = None -checkout = $cmd_vcs{checkout} - -}; - - for my $p (keys %cmd) { - next if $p ne 'default' and exists $project{supported_platforms} and not exists $project{supported_platforms}{$p}; - - print C qq{[Platform-$p:BuildCommand] -postpublish = None -packaging = $cmd{$p}{packaging} -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = $cmd{$p}{compile} -init = $cmd{$p}{init} -install = $cmd{$p}{install} -clean = $cmd{$p}{clean} -test = $cmd{$p}{test} -configure = $cmd{$p}{configure} -checkstyle = None - -}; - } - - print C qq{[Platform-default:Property] -$buildroot -package.preserve.libtool = false -$package_description$package_summary$defprops}; - - for (@{$obsoletes{"$subsys.$module"}}) { - print C "package.obsoletes = $_\n"; - print C "package.replaces = $_\n"; - } - for (@{$conflicts{"$subsys.$module"}}) { - print C "package.conflicts = $_\n"; - } - for (@{$provides{"$subsys.$module"}}) { - print C "package.provides = $_\n"; - } - print C "\n"; - - for my $pp (keys %{$platform_properties{"$subsys.$module"}}) { - next if $pp eq 'default'; - next if exists $project{supported_platforms} and not exists $project{supported_platforms}{$pp}; - - print C "[Platform-$pp:Property]\n$buildroot\n"; - - for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) { - print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n"; - } - print C "$package_description$package_summary\n"; - } - - for my $platform ('default', keys %{$project{supported_platforms}}) { - my $used = 0; - my $output = ''; - - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$platform}{$_}; - my $edev = $project{etics_externs_devel}{$platform}{$_}; - - # for the default platform using package of the same - # name for runtime dependency - if (not $eext) { - if ($platform eq 'default') { -#print "default runtime $_ on default\n"; - $eext = $_; } - else { -#print "no runtime $_ on $platform\n"; - $eext = '-'; } - } - if ($eext eq '-' and $edev eq '-') { -#print "skipping $_ on $platform\n"; - next; - } - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - - if ($edev) { - if ($type eq 'B') { - # no runtime - change to devel pkg - $eext = $edev; - } elsif ($type eq 'BR' or $type eq 'RB') { - # additional devel pkg - if ($edev ne '-') { $output .= "$proj|$edev = B\n"; } - } - } - if ($eext ne '-') { $output .= "$proj|$eext = $type\n"; } - } - - if ($platform eq 'default') { - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - if (not $used) { - $used = 1; - } - $output .= "$project{etics_name}|$project{etics_name}.$_ = $type\n"; - } - } - - if ($output) { - print C qq{ -[Platform-$platform:DynamicDependency] -$output}; - } - } - - close C; - - for $file ("$cvs_module/project/debian.rules", "$cvs_module/project/$packageName.spec") { - my $lib; - my $main_module; - @copts = (); - - if ($file =~ /debian\.rules$/) { $lib = 'lib'; } - else { $lib = '%{_lib}'; } - - my $main_module = "$subsys.$module"; - if (exists $subpackages{$main_module}) { $main_module = $subpackages{$main_module}; } - - # locations hacks - if ($file =~ /$packageName\.spec$/) { - if ($fmod eq 'lb.client-java') { - push @copts, ''; - push @copts, '--with-axis=/usr/local/axis1.4'; - } - } - - if (-f $file) { - open DST,">$file.new" or die "$file.new: $!\n"; - open SRC,"<$file" or die "$file: $!\n"; - while () { - if (/^(\s*).+\/configure\s/) { - printf DST "%s", "$1"; - printf DST "/usr/bin/perl $confdir/configure $project{flavours} --root=/ --prefix=$project{local_prefix} --libdir=$lib --project=$project --module $main_module@copts\n"; - } else { - printf DST "%s", "$_"; - } - } - close SRC; - close DST; - - `diff -b "$file" "$file.new"`; - if ($? == 0) { - print STDERR "($file not changed)\n"; - unlink "$file.new"; - } else { - print STDERR "Writing $file\n"; - rename "$file", "$file.orig" unless -f "$file.orig"; - rename "$file.new", "$file"; - } - } - } -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - $gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - -sub getlibdir { - if ( -e "/etc/debian_version") { # We are on Debian - $lib64="lib"; - $lib32="lib32"; } - else { # Another distribution - $lib64="lib64"; - $lib32="lib"; } - $libdir=$lib32; - - open INP, "uname -s | "; # Check kernel name - $kname= ; - chomp($kname); - close INP; - - if ( $kname eq "Linux") { - $arch = ("x86_64\npowerpc\nppc64\n"); - - open INP, "uname -p | "; # Check processor type - $procname= ; - chomp($procname); - close INP; - - if ($arch =~/^$procname\n/) { - return ($lib64); } - - open INP, "uname -m | "; # Check machine hardware - $machname= ; - chomp($machname); - close INP; - - if ($arch =~/^$machname\n/) { - return ($lib64); } - - # special cases (hyperlink lib64, Debian) - if (-l "/usr/lib64") { - $libdir=$lib32; } - - # if /usr/lib64 doesn't exist at all (AIX) - unless ( -e "/usr/lib64" ) { - $libdir=$lib32; } - } - - if ( $kname eq "SunOS") { - if (-e "/usr/lib/64") { - $libdir="lib/64"; } - } - - return $libdir; -} - -sub reshuffle_platforms($$) { - my ($data, $platforms) = @_; - my ($platform, %blacklist, $value); - - return if not $platforms; - - for $platform (keys %$data) { -#print "plat: $platform: $data->{$platform}\n"; - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { -#print " blacklist: $_ = $data->{$platform}{$_}\n"; - $blacklist{$_} = 1; - } - } - - for $_ (keys %blacklist) { - $value = $data->{default}{$_} ? $data->{default}{$_} : $_; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - if (not defined $data->{$platform}{$_}) { - $data->{$platform}{$_} = $value; -#print "added $value to $platform\n" - } - } - $data->{default}{$_} = '-'; -#print "deleted $_ from default\n"; - } - - # merge dependencies across the supported platforms - %blacklist = []; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { - $blacklist{$_} = 1; - } - } - for $_ (keys %blacklist) { - $value = undef; - $same = 1; - for $platform (keys %$platforms) { - if (not $value) { $value = $data->{$platform}{$_}; } - if (not $data->{$platform}{$_} or $value ne $data->{$platform}{$_}) { - $same = 0; - last; - } - } - if ($same and $value) { -#print "merged dependency $_\n"; - $data->{default}{$_} = $value; - for $platform (keys %$platforms) { - delete $data->{$platform}{$_}; - } - } - } -} - -sub usage { - my @ext = keys %externs; - my @myjars = keys %jar; - - print STDERR qq{ -Usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --stage=DIR staging directory [./stage] - --root=DIR installation root (custom relocation root -> sysroot) [./stage] - --sysroot=DIR system root (custom relocation root -> sysroot) [] - --sysconfdir=DIR system configuration directory [PREFIX/etc] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - --listmodules=module list subpackages of a module - --version=maj.min.rev-age version used instead of reading version.properties - --branch=branch CVS branch/etics name suffix (HEAD, branch_2_1, ...) - --libdir=libdir typically [lib,lib64] postfix - --project=PROJECT build or generate etics for a project (glite/emi1/emi) [emi] - --debug print more details - -Mode of operation: - --mode=\{checkout|build|etics\} what to do [build] - -What to build: - --module=module build this module only - --enable-NODE build this "node" (set of modules) only - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - --canl-tag=tag checkout canl modules with specific tag - -Dependencies (summary of what will be used is always printed): - --with-EXTERNAL=PATH where to look for an external [autodetect] - --with-JAR=JAR where to look for jars - -Available nodes: - @nodes - -Default nodes: - @default_nodes - -Externals (not all for all modules) are: - @ext - -External jars are: - @myjars - -}; - -} diff --git a/org.glite.jobid.api-cpp/interface/JobId.h b/org.glite.jobid.api-cpp/interface/JobId.h deleted file mode 100755 index 7c96993..0000000 --- a/org.glite.jobid.api-cpp/interface/JobId.h +++ /dev/null @@ -1,351 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JOBID_JOBID_H -#define GLITE_JOBID_JOBID_H - -#include -#include -#include -#include -#include -#include - -#include "glite/jobid/cjobid.h" - - -namespace glite { -namespace jobid { - - -/** - * class glite::jobid::JobIdError - */ - -class JobIdError : public std::runtime_error { -public: - /** Constructor for mandatory fields. - * - * Updates all the mandatory fields and names the exception. - * \param[in] exception Error message describing the exception. - */ - JobIdError(std::string const& exception) - : std::runtime_error(std::string("JobId: bad argument (") + exception + ")") - {} - - virtual ~JobIdError() throw() - {} - -}; - - -/** - * class glite::jobid::JobId - */ - -class JobId -{ -public: - class Hostname { - public: - std::string const& name; - Hostname(std::string const& n) : name(n) - {} - }; - - //@name Constructors/Destructor - //@{ - - /** - * Constructor from string format. - * @param job_id_string - * @throws Exception When a string is passed in a wrong format - */ - JobId(std::string const& job_id_string); - - /** - * Constructor from job id components. - * \param host - * \param port - * \param unique - */ - explicit JobId(Hostname const& host = Hostname("localhost"), - int port = GLITE_JOBID_DEFAULT_PORT, - std::string const& unique = std::string("")); - - /** - * Destructor. - */ - ~JobId(); - - //@} - - //@ Conversions, assignments, comparisons - //@{ - - /** - * Copy constructor. - */ - JobId(JobId const&); - - /** - * Constructor from C jobid. - * \param src C API job id - */ - explicit JobId(glite_jobid_const_t src); - - /** - * Assignment operator. - * Create a deep copy of the JobId instance. - */ - JobId& operator=(JobId const& src); - - /** - * Casting operator. - */ - glite_jobid_const_t c_jobid() const; - - /** - * Returns the string representing the job id - * @return String representation of a JobId - */ - std::string toString() const; - - - /** - * Comparison given by lexicographical ordering of string representations. - * @return Result of comparison. - */ - int operator< (const JobId &j) const; - //@} - - - /**@name Member access - * @{ - */ - - /** - * Get server:port. - * @return hostname and port - */ - std::string server() const; - - /** - * Get host. - * @return hostname - */ - std::string host() const; - - /** - * Get port. - * @return port - */ - int port() const; - - /** - * Get unique. - * @return unique string - */ - std::string unique() const; - - //@} - -private: - glite_jobid_t m_jobid; -}; - - - -// -------------------- implementation ------------------------ - -inline -JobId::JobId(std::string const& job_id_string) -{ - int ret = glite_jobid_parse(job_id_string.c_str(), - &m_jobid); - switch(ret) { - case EINVAL: - throw JobIdError(job_id_string); - - case ENOMEM: - throw std::bad_alloc(); - - default: - break; - } -} - - -inline -JobId::JobId(JobId::Hostname const& host, int port, std::string const& unique) -{ - if(port < 0) { - throw JobIdError("negative port"); - } - - int ret = glite_jobid_recreate(host.name.c_str(), port, - unique.empty() ? NULL : unique.c_str(), - &m_jobid); - switch(ret) { - case EINVAL: - throw JobIdError(host.name); - - case ENOMEM: - throw std::bad_alloc(); - - default: - break; - } -} - - -inline -JobId::~JobId() { - glite_jobid_free(m_jobid); -} - - -inline -JobId::JobId(JobId const& src) -{ - int ret = glite_jobid_dup(src.m_jobid, - &m_jobid); - if(ret) { - // we rely on dup returning only ENOMEM on error - assert(ret == ENOMEM); - throw std::bad_alloc(); - } -} - - -inline -JobId::JobId(glite_jobid_const_t src) -{ - if(src == NULL) { - throw JobIdError("null"); - } - - int ret = glite_jobid_dup(src, - &m_jobid); - if(ret) { - throw std::bad_alloc(); - } -} - - -inline -JobId& -JobId::operator=(JobId const& src) -{ - if(this == &src) { - return *this; - } - - glite_jobid_free(m_jobid); - int ret = glite_jobid_dup(src.m_jobid, - &m_jobid); - if(ret) { - throw std::bad_alloc(); - } - return *this; -} - - -inline -glite_jobid_const_t -JobId::c_jobid() const -{ - return m_jobid; -} - - -inline -std::string -JobId::toString() const -{ - char *out = glite_jobid_unparse(m_jobid); - std::string res(out); - - free(out); - return res; -} - - -inline -int -JobId::operator< (const JobId &j) const -{ - std::string me(toString()); - std::string js(j.toString()); - - return(me < js); -} - - -inline -std::string -JobId::server() const -{ - char *server = glite_jobid_getServer(m_jobid); - std::string res(server); - - free(server); - return res; -} - - -inline -std::string -JobId::host() const -{ - char *name; - unsigned int port; - - glite_jobid_getServerParts_internal(m_jobid, - &name, &port); - return std::string(name); -} - - -inline -int -JobId::port() const -{ - char *name; - unsigned int port; - - glite_jobid_getServerParts_internal(m_jobid, - &name, &port); - return port; -} - - -inline -std::string -JobId::unique() const -{ - char *unique = glite_jobid_getUnique_internal(m_jobid); - std::string res(unique); - - return res; -} - - -} // namespace jobid -} // namespace glite - -#endif // GLITE_JOBID_JOBID_H diff --git a/org.glite.jobid.api-cpp/project/ChangeLog b/org.glite.jobid.api-cpp/project/ChangeLog deleted file mode 100644 index 66bcc1d..0000000 --- a/org.glite.jobid.api-cpp/project/ChangeLog +++ /dev/null @@ -1,76 +0,0 @@ -1.0.0-1 -- initial release - -1.0.0-2 -- fixes in etics' invocation of configure - -1.0.0-4 -- configure script update -- compatibility with g++ 4.3.2 - -1.0.0-5 -- module rebuilt - -1.0.0-6 -- module rebuilt - -1.0.1-1 -- Fixed target 'clean' in the Makefile - -1.0.1-2 -- Module rebuilt - -1.0.1-3 -- Module rebuilt - -1.1.0-1 -- Fixes for parallel release in EMI & gLite - -1.1.0-2 -- Module rebuilt - -1.1.1-1 -- Root directory option (ETICS performs own files relocation) -- Prefix option as prefix inside stage -- Sysconfdir option (for /etc vs /usr) -- DESTDIR in makefiles - -1.1.2-1 -- Relocatable build directory. - -1.1.2-2 -- Module rebuilt - -1.1.2-3 -- Module rebuilt - -1.1.2-4 -- Module rebuilt - -1.1.2-5 -- Module rebuilt - -1.1.2-6 -- Module rebuilt - -1.1.3-1 -- experiments with staging in summary Makefile in etics-less build - -1.1.3-2 -- Module rebuilt - -1.2.0-1 -- Preparation for a new multiplatform release - -1.2.0-2 -- Module rebuilt - -1.2.0-3 -- Module rebuilt - -1.2.0-4 -- Module rebuilt - -1.2.0-5 -- Module rebuilt - diff --git a/org.glite.jobid.api-cpp/project/debian.control b/org.glite.jobid.api-cpp/project/debian.control deleted file mode 100644 index 4d4c2be..0000000 --- a/org.glite.jobid.api-cpp/project/debian.control +++ /dev/null @@ -1,18 +0,0 @@ -Source: glite-jobid-api-cpp -Priority: extra -Maintainer: @MAINTAINER@ -Uploaders: @UPLOADERS@ -Build-Depends: debhelper (>= 7.0.50~), libglite-jobid-api-c-dev, libcppunit-dev, libtool -Standards-Version: 3.9.1 -Section: libs -Homepage: @URL@ -DM-Upload-Allowed: yes -@DEBIAN_VCS@ - -Package: libglite-jobid-api-cpp-dev -Section: libdevel -Architecture: any -Depends: libglite-jobid2, ${misc:Depends} -Provides: glite-jobid-api-cpp -Description: @SUMMARY@ -@DEBIAN_DESCRIPTION@ diff --git a/org.glite.jobid.api-cpp/project/debian.copyright b/org.glite.jobid.api-cpp/project/debian.copyright deleted file mode 100644 index 3d762ae..0000000 --- a/org.glite.jobid.api-cpp/project/debian.copyright +++ /dev/null @@ -1,38 +0,0 @@ -This work was packaged for Debian by: - - @MAINTAINER@ on Thu, 08 Dec 2011 00:46:07 +0100 - -It was downloaded from: - - @URL@ - -Upstream Author(s): - - @MAINTAINER@ - -Copyright: - - - -License: - - 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. - -On Debian systems, the complete text of the Apache version 2.0 license -can be found in "/usr/share/common-licenses/Apache-2.0". - -The Debian packaging is: - - Copyright (C) 2004-2011 Members of the EGEE Collaboration - -and is licensed under the Apache License, Version 2.0. diff --git a/org.glite.jobid.api-cpp/project/debian.libglite-jobid-api-cpp-dev.dirs b/org.glite.jobid.api-cpp/project/debian.libglite-jobid-api-cpp-dev.dirs deleted file mode 100644 index 59ad749..0000000 --- a/org.glite.jobid.api-cpp/project/debian.libglite-jobid-api-cpp-dev.dirs +++ /dev/null @@ -1 +0,0 @@ -usr/include/glite/jobid diff --git a/org.glite.jobid.api-cpp/project/debian.libglite-jobid-api-cpp-dev.install b/org.glite.jobid.api-cpp/project/debian.libglite-jobid-api-cpp-dev.install deleted file mode 100644 index 80a80c9..0000000 --- a/org.glite.jobid.api-cpp/project/debian.libglite-jobid-api-cpp-dev.install +++ /dev/null @@ -1 +0,0 @@ -usr/include/glite/jobid/*.h diff --git a/org.glite.jobid.api-cpp/project/debian.rules b/org.glite.jobid.api-cpp/project/debian.rules deleted file mode 100644 index 6242229..0000000 --- a/org.glite.jobid.api-cpp/project/debian.rules +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- - --include /usr/share/dpkg/buildflags.mk - -# Uncomment this to turn on verbose mode. -export DH_VERBOSE=1 - -configure: configure-stamp -configure-stamp: - dh_testdir - /usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=lib --project=emi --module jobid.api-cpp - touch $@ - -build: build-arch build-indep - -build-arch build-indep: build-stamp - -build-stamp: configure-stamp - dh_testdir - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) check - touch $@ - -clean: configure-stamp - dh_testdir - dh_testroot - rm -f configure-stamp build-stamp - $(MAKE) clean - rm -f Makefile.inc config.status - dh_clean - -install: build-stamp - dh_testdir - dh_testroot - dh_prep - dh_installdirs - $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp - -binary-indep: - -binary-arch: install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_installexamples - dh_installman - dh_installlogrotate - dh_installcron - dh_install --fail-missing - dh_link - dh_compress - dh_fixperms - dh_makeshlibs - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-arch binary-indep diff --git a/org.glite.jobid.api-cpp/project/glite-jobid-api-cpp.spec b/org.glite.jobid.api-cpp/project/glite-jobid-api-cpp.spec deleted file mode 100644 index ea4299c..0000000 --- a/org.glite.jobid.api-cpp/project/glite-jobid-api-cpp.spec +++ /dev/null @@ -1,67 +0,0 @@ -Summary: Virtual package for development with gLite jobid C++ API -Name: glite-jobid-api-cpp -Version: @MAJOR@.@MINOR@.@REVISION@ -Release: @AGE@%{?dist} -Url: @URL@ -License: ASL 2.0 -Vendor: EMI -Group: Development/Libraries -BuildRequires: glite-jobid-api-c-devel -BuildRequires: libtool -BuildRequires: cppunit-devel -BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) -AutoReqProv: yes -Source: http://eticssoft.web.cern.ch/eticssoft/repository/emi/emi.jobid.api-c/%{version}/src/%{name}-@VERSION@.src.tar.gz - - -%description -This is a virtual package providing runtime and development files for gLite -jobid C++ API. - - -%package devel -Summary: @SUMMARY@ -Group: Development/Libraries -Requires: glite-jobid-api-c%{?_isa} -Provides: %{name} = %{version}-%{release} - - -%description devel -@DESCRIPTION@ - - -%prep -%setup -q - - -%build -/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=%{_lib} --project=emi --module jobid.api-cpp -make - - -%check -make check - - -%install -rm -rf $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT -make install DESTDIR=$RPM_BUILD_ROOT -find $RPM_BUILD_ROOT -name '*.la' -exec rm -rf {} \; -find $RPM_BUILD_ROOT -name '*.a' -exec rm -rf {} \; - - -%clean -rm -rf $RPM_BUILD_ROOT - - -%files devel -%defattr(-,root,root) -%dir /usr/include/glite -%dir /usr/include/glite/jobid -/usr/include/glite/jobid/JobId.h - - -%changelog -* @SPEC_DATE@ @MAINTAINER@ - @MAJOR@.@MINOR@.@REVISION@-@AGE@%{?dist} -- automatically generated package diff --git a/org.glite.jobid.api-cpp/project/package.description b/org.glite.jobid.api-cpp/project/package.description deleted file mode 100644 index e140a25..0000000 --- a/org.glite.jobid.api-cpp/project/package.description +++ /dev/null @@ -1 +0,0 @@ -C++ API handling gLite jobid. It is a thin wrapper of the C implementation (glite-jobid-api-c). diff --git a/org.glite.jobid.api-cpp/project/package.summary b/org.glite.jobid.api-cpp/project/package.summary deleted file mode 100644 index e73220a..0000000 --- a/org.glite.jobid.api-cpp/project/package.summary +++ /dev/null @@ -1 +0,0 @@ -C++ API handling gLite jobid diff --git a/org.glite.jobid.api-cpp/project/version.properties b/org.glite.jobid.api-cpp/project/version.properties deleted file mode 100644 index a741e96..0000000 --- a/org.glite.jobid.api-cpp/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# : /cvs/glite/org.glite.jobid.api-cpp/project/version.properties,v 1.1 2009/01/16 08:48:52 zsustr Exp $ -module.version=1.2.0 -module.age=5 diff --git a/org.glite.jobid.api-java/Makefile b/org.glite.jobid.api-java/Makefile deleted file mode 100644 index 9f11d6b..0000000 --- a/org.glite.jobid.api-java/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -top_srcdir=. -stagedir=../stage - --include Makefile.inc - -ANT_ARGS=-f ${top_srcdir}/build.xml -Dfile.reference.commons-codec.jar=${jakarta-commons-codec_jar} -Dsrc.dir=${top_srcdir}/src -Dbuild.dir=$(shell pwd)/build -Ddist.dir=$(shell pwd)/dist - -all compile: - ${ant_prefix}/bin/ant ${ANT_ARGS} - -stage: - $(MAKE) install PREFIX=${stagedir} - -install: - mkdir -p ${DESTDIR}${PREFIX}${prefix}/share/java - cp dist/jobid-api-java.jar ${DESTDIR}${PREFIX}${prefix}/share/java - -check: - -clean: - ${ant_prefix}/bin/ant ${ANT_ARGS} clean - -distclean: - rm -rvf Makefile.inc *.spec debian/ - -.PHONY: all compile stage install check clean distclean diff --git a/org.glite.jobid.api-java/build.xml b/org.glite.jobid.api-java/build.xml deleted file mode 100755 index 90e26a7..0000000 --- a/org.glite.jobid.api-java/build.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - Builds, tests, and runs the project jobid-api-java. - - - diff --git a/org.glite.jobid.api-java/configure b/org.glite.jobid.api-java/configure deleted file mode 100755 index bcb1531..0000000 --- a/org.glite.jobid.api-java/configure +++ /dev/null @@ -1,2058 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; -use POSIX qw(locale_h strftime); - -my $pwd = `pwd`; chomp $pwd; -my $prefix = '/usr'; -my $stagedir = undef; -my $root = $pwd.'/stage'; -my $sysroot = ''; -my $sysconfdir; -my $localstatedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my ($version, $force_version); -my $branch; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $jobid_tag = ''; -my $libdir = getlibdir(); -my $project = 'emi'; -my $project_version; -my (%projects, %project); -my $debug = 0; -my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : ''; - -my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal/; -my @default_nodes = qw/lb px proxyrenewal nagios/; -my %enable_nodes; -my %disable_nodes; -my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1); - -my %package = ( - 'maintainer' => 'CESNET Product Teams ', - 'uploaders' => 'FrantiÅ¡ek Dvořák ', - 'url' => 'http://glite.cern.ch', - 'debian_vcs' => 'Vcs-Cvs: :pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw -Vcs-Browser: http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi', -); - -# key: internal package name (arguments, ...) -# 'pkg': pkg-config name -# 'prefix': used when pkg-config fails -my %externs = ( - cares => { - prefix => '/opt/c-ares', - pkg => 'libcares' - }, - classads => { - prefix=> '/usr', - pkg => 'classads' - }, - cppunit => { - prefix=> '/usr', - pkg => 'cppunit' - }, - expat => { - prefix=> '/usr', - pkg => 'expat' - }, - globus => { - prefix=> '/opt/globus', - pkg => 'globus-gssapi-gsi' - }, - 'myproxy-devel' => { - prefix=> '/opt/globus', - pkg => 'myproxy' - }, - 'myproxy-server' => { - prefix=> '', - }, - 'myproxy-admin' => { - prefix=> '', - }, - gsoap => { - prefix=> '/usr', - pkg => 'gsoap' - }, - gsoapxx => { - prefix=> '/usr', - pkg => 'gsoap++' - }, - mysql => { - prefix=> '/usr' - }, - 'mysql-devel' => { - prefix=> '' - }, - 'mysql-server' => { - prefix => '' - }, - voms => { - prefix => '/opt/glite', - pkg => 'voms-2.0' - }, - gridsite => { - prefix => '/opt/glite' - }, - lcas => { - prefix => '/opt/glite', - pkg => 'lcas' - }, - trustmanager => { - prefix => '/opt/glite' - }, - trustmanager_axis => { - prefix => '/opt/glite' - }, - utiljava => { - prefix=> '/opt/glite' - }, - ant => { - prefix=> '/usr' - }, - jdk => { - prefix=> '/usr/java/latest', - locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ], - }, - libtar => { - prefix=> '/usr' - }, - axis => { - prefix=> '/usr' - }, - log4c => { - prefix=> '/usr' - }, - postgresql => { - prefix=> '/usr' - }, - activemq => { - prefix=>'/opt/activemq-cpp-library', - pkg => 'activemq-cpp' - }, -); - -my %jar = ( - 'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar', - 'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %buildroot; -my (%etics_externs, %etics_projects); - -# -# modules of the subsystems -# -# additional modules from $project{modules} are automatically added -# -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], - 'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/], - 'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - 'gridsite' => [ qw/apache libs commands core devel slashgrid services service-clients gsexec/ ], - 'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ], - 'canl' => [ qw/c c-devel/ ], - ); - -# -# sub-packages -# -# modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly -# -my %subpackages = ( - 'jobid.api-c-devel' => 'jobid.api-c', - 'jobid.api-cpp-devel' => 'jobid.api-cpp', - 'lbjp-common.db-devel' => 'lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'lbjp-common.log', - 'lbjp-common.maildir-devel' => 'lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'lbjp-common.trio', - 'lb.client-progs' => 'lb.client', - 'lb.client-devel' => 'lb.client', - 'lb.common-devel' => 'lb.common', - 'lb.logger-devel' => 'lb.logger', - 'lb.state-machine-devel' => 'lb.state-machine', - 'px.proxyrenewal-devel' => 'px.proxyrenewal', - 'px.proxyrenewal-progs' => 'px.proxyrenewal', - 'canl.c-devel' => 'canl.c', -); - -my @opts = ( - 'prefix:s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour:s' => \$thrflavour, - 'nothrflavour:s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$force_version, - 'branch=s' => \$branch, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'root:s' => \$root, - 'sysroot:s' => \$sysroot, - 'sysconfdir=s' => \$sysconfdir, - 'localstatedir=s' => \$localstatedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'jobid-tag=s' => \$jobid_tag, - 'canl-tag=s' => \$canl_tag, - 'help' => \$help, - 'libdir=s' => \$libdir, - 'project=s' => \$project, - 'debug' => \$debug, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; -$prefix=~s/\/$//; -$root=~s/\/$//; -$sysroot=~s/\/$//; -if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; } -if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; } -$sysconfdir=~s/\/$//; -$localstatedir=~s/\/$//; - -$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq ''; -$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq ''; -$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq ''; - -$externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq ''; -$externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq ''; -$externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq ''; - -if ($project =~ /^([^0-9]*)(.*)$/) { - $project = $1; - $project_version = $2; -} -%project = %{$projects{$project}}; -$project_version = $project{current_version} unless $project_version; -for my $platform (keys %{$project{etics_externs}}) { - for $_ (keys %{$project{etics_externs}{$platform}}) { - $etics_externs{$platform}{$_} = $project{etics_externs}{$platform}{$_}; - } -} -reshuffle_platforms(\%etics_externs, $project{supported_platforms}); -reshuffle_platforms(\%{$project{etics_externs_devel}}, $project{supported_platforms}); -for $_ (keys %{$project{etics_projects}}) { - $etics_projects{$_} = $project{etics_projects}{$_}; -} -for $_ (keys %{$project{need_externs_aux}}) { - $need_externs_aux{$_} = $project{need_externs_aux}{$_}; -} -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - my ($pkg, $type) =/([^:]*)(?::(.*))?/; - $type = 'BR' unless ($type); - - push @{$need_externs{$ext}},$pkg; - $need_externs_type{$ext}->{$pkg} = $type; - } -} -if ($project eq 'emi') { - $extranodmod{lb} = 'lb.emi-lb'; - $extranodmod{px} = 'px.emi-px'; -} -for $_ (keys %{$project{modules}}) { - push @{$lbmodules{$_}},@{$project{modules}{$_}}; -} - - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name}; - my @m; - - if (exists $lbmodules{$listmodules}) { - @m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}}; - } else { - if ($project eq 'emi' and $project_version == 1) { - # no sub-packages in EMI-1 - } else { - for my $sub (keys %subpackages) { - push @m, $sub if ($subpackages{$sub} eq $listmodules); - } - } - } - print map $_ eq "" ? "" : "$_ ", @m; - print "\n"; - exit 0; -} - -warn "$0: --branch and --output make sense only in --mode=etics\n" - if ($output || $branch) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_}); - } -} - -if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } }; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $root unless $stagedir; -$stagedir=~s/\/$// if ($stagedir); - -if ($mode eq 'build') { for my $ext (keys %externs) { - if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; } - elsif (defined $externs{$ext}{pkg}) { - my ($flag, $env, $cmd, $ret); - my $pkg = $externs{$ext}{pkg}; - my $flagname = uc $externs{$ext}{pkg}; - $flagname =~ s/-[0-9\.]*$//; - $flagname =~ y/-\+/_X/; - - print "Checking $pkg ... "; - $env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig"; - $cmd = "$env pkg-config $pkg --exists >/dev/null"; - `$cmd`; $ret = $?; - print "('$cmd' => $ret)\n" if ($debug); - if ($ret == 0) { - $externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`; - chomp $externs{$ext}{prefix}; - print "$externs{$ext}{prefix}\n"; - - $flag=`$env pkg-config $pkg --cflags`; - $externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag); - $flag=`$env pkg-config $pkg --libs`; - $externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag); - } else { - print "(using default $externs{$ext}{prefix})\n"; - } - print "\n" if ($debug); - } - elsif ($ext eq 'jdk') { - my $jdk_prefix; - - print "Looking for some caffein ... "; - if (defined $ENV{'JDK_HOME'}) { - $jdk_prefix = $ENV{'JDK_HOME'}; - print "JDK_HOME=$jdk_prefix\n"; - } elsif (defined $ENV{'JAVA_HOME'}) { - $jdk_prefix = $ENV{'JAVA_HOME'}; - print "JAVA_HOME=$jdk_prefix\n"; - } else { - foreach my $i (0..$#{$externs{$ext}{locations}}) { - if (-e $externs{$ext}{locations}[$i]) { - $jdk_prefix=$externs{$ext}{locations}[$i]; - print "(found directory $jdk_prefix)\n"; - last; - } - } - print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix); - } - $externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix); - } -} } - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') { - print CONF "$_=$ENV{$_} " if (defined $ENV{$_}); - } - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } }; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - if ($module) { - print "Not creating summary Makefile\n" if $debug; - } else { - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\n"; - print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n"; - print MAK "clean check install:\n"; - - for (@modules) { - my $full = full($_); - print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $buildroot{$_} eq '' ? - "\tcd $full && \${MAKE} distclean\n" : - "\trm -rf $full/$buildroot{$_}\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage'; - - my $full = full($_); - my $build = $buildroot{$_}; - - print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n"; - print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n"; - } - - close MAK; - } -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag) { - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - if ($canl_tag) { - for (@{$lbmodules{'canl'}}){ - if ("canl.".$_ eq $module){ - $tag = '-r '.$canl_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%etics_externs = ( - default => { - 'myproxy-devel'=>'myproxy-devel', - 'myproxy-server'=>'myproxy-server', - 'myproxy-admin'=>'myproxy-admin', - cares=>'c-ares', - utiljava=>'org.glite.security.util-java', - gpt=>'gpt', - fetchcrl=>'fetch-crl', - activemq=>'activemq-cpp-library', - }, -); - -%etics_projects = ( -); - -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads libtool:B globus:B/ ], - 'lb.common' => [ qw/expat cares:B cppunit:B classads libtool:B globus:B/ ], - 'lb.doc' => [ qw/tetex-latex:B/ ], - 'lb.logger' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B globus:B/ ], - 'lb.nagios' => [ qw/globus_proxy_utils:R/ ], - 'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql-server:R cppunit:B gsoap:B classads voms:B lcas gridsite:B bison:B libtool:B libxml2 flex:B/ ], - 'lb.state-machine' => [ qw/classads libtool:B libxslt:B expat:B globus:B/ ], - 'lb.utils' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ], - 'lb.ws-test' => [ qw/gsoap:B libtool:B globus:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/docbook-utils:B libtool:B globus:B/ ], - 'lbjp-common.db' => [ qw/mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.log' => [ qw/log4c libtool:B/ ], - 'lbjp-common.maildir' => [ qw/libtool:B/ ], - 'lbjp-common.server-bones' => [ qw/libtool:B/ ], - 'lbjp-common.trio' => [ qw/cppunit:B libtool:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.gss' => [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B/ ], - 'lbjp-common.gsoap-plugin' => [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B/ ], - 'jobid.api-c' => [ qw/cppunit:B libtool:B openssl:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B libtool:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus_essentials:R globus:B mysql-server:R/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B mysql-server:R/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], - 'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'gridsite.commands' => [ qw/curl:R openssl:R/ ], - 'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ], - 'gridsite.libs' => [ qw/libxml2:R openssl:R/ ], - 'gridsite.devel' => [ qw// ], - 'gridsite.slashgrid' => [ qw/curl:R fuse:R/], - 'gridsite.services' => [ qw/curl:R gsoap:R/ ], - 'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ], - 'gridsite.gsexec' => [ qw// ], - 'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B/ ], - 'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec - 'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B krb5-devel:B/ ], -); - -%need_jars = ( - 'jobid.api-java' => [ qw/jakarta-commons-codec/ ], - 'lb.client-java' => [ qw/jakarta-commons-lang/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp:B jobid.api-c - lbjp-common.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - lb.ws-interface:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp:B jobid.api-c - lb.types:B lbjp-common.trio lbjp-common.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - lbjp-common.log - jobid.api-c - lb.common - lbjp-common.gss - / ], - 'lb.logger-msg' => [ qw/ - lb.logger:B - / ], - 'lb.nagios' => [ qw/ - lb.client:R - lb.ws-test:R - lb.utils:R - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log - jobid.api-c - lbjp-common.gsoap-plugin lbjp-common.gss - / ], - 'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine lb.types:B - / ], - 'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/ - jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client - lbjp-common.gss lbjp-common.log - / ], - 'lb.yaim' => [ qw// ], - 'lb.glite-LB' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lb.emi-lb' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.log' => [ qw// ], - 'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ], - 'lbjp-common.trio' => [ qw// ], - 'lbjp-common.gss' => [ qw// ], - 'lbjp-common.gsoap-plugin' => [ qw/lbjp-common.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - lbjp-common.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], - - 'gridsite.core' => [ qw// ], - 'gridsite.commands' => [ qw/gridsite.core:B/ ], - 'gridsite.apache' => [ qw/gridsite.core:B/ ], - 'gridsite.libs' => [ qw/gridsite.core:B / ], - 'gridsite.devel' => [ qw/gridsite.core:B/ ], - 'gridsite.slashgrid' => [ qw/gridsite.core:B/], - 'gridsite.services' => [ qw/gridsite.core:B/ ], - 'gridsite.service-clients' => [ qw/gridsite.core:B/ ], - 'gridsite.gsexec' => [ qw/gridsite.core:B/ ], - - 'px.proxyrenewal' => [ qw// ], - 'px.glite-PX' => [qw/px.myproxy-yaim:R/], - 'px.emi-px' => [qw/px.myproxy-yaim:R/], - 'px.myproxy-yaim' => [ qw// ], - 'px.myproxy-config' => [], - - 'canl.c' => [], - - # sub-packages (virtual ETICS components depending on the main) - 'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ], - 'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ], - 'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ], - 'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ], - 'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ], - 'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ], - 'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ], - 'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ], - 'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ], - 'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ], - 'lb.client-progs' => [ qw/lb.client:B/ ], - 'lb.client-devel' => [ qw/lb.client:B/ ], - 'lb.common-devel' => [ qw/lb.common:B/ ], - 'lb.logger-devel' => [ qw/lb.logger:B/ ], - 'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ], - 'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ], - 'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ], - 'canl.c-devel' => [ qw/canl.c:B/ ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( - gridsite=>'org.gridsite.core', - 'canl.c' => 'emi.canl.canl-c', - 'canl.c-devel' => 'emi.canl.canl-c', - 'jobid.api-c-devel' => 'org.glite.jobid.api-c', - 'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp', - 'lbjp-common.db-devel' => 'org.glite.lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'org.glite.lbjp-common.log', - 'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio', - 'lb.client-devel' => 'org.glite.lb.client', - 'lb.client-progs' => 'org.glite.lb.client', - 'lb.common-devel' => 'org.glite.lb.common', - 'lb.logger-devel' => 'org.glite.lb.logger', - 'lb.state-machine-devel' => 'org.glite.lb.state-machine', - 'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal', - 'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal', -); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', - lb => 'lb.glite-LB', - px => 'px.glite-PX', - proxyrenewal => 'px.proxyrenewal', - canl => 'canl.c', -); - -%obsoletes = ( - 'lb.yaim' => [ qq/glite-yaim-lb/ ], - 'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ], - 'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ], - 'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], -); - -%conflicts = ( -); - -%provides = ( - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], - 'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ], -); - -%cvs_prefix = ( - 'lb' => 'org.glite', - 'jp' => 'org.glite', - 'jobid' => 'org.glite', - 'lbjp-common' => 'org.glite', - 'gridsite' => 'org', - 'px' => 'org.glite', - 'canl' => 'emi', -); - -%cvs_tag_prefix = ( - 'lb' => 'glite-', - 'jp' => 'glite-', - 'jobid' => 'glite-', - 'lbjp-common' => 'glite-', - 'gridsite' => '', - 'px' => 'glite-', - 'canl' => 'emi-', -); - -# ==== projects specification ==== -# etics_name ........... ETICS project name -# conf_prefix .......... ETICS configurations name prefix -# tag_prefix ........... VCS tag prefix -# local_prefix ......... prefix (relative to stage) -# etics_externs ........ ETICS modules names of externals -# (${NAME.location}, ETICS conf. dependencies) -# etics_projects ....... ETICS project names of externals -# etics_externs_devel .. ETICS modules names of devel versions of externals -# etics_locations ...... ETICS locations in ${NAME.location} properties -# need_externs_aux ..... project-specific external dependencies -# supported_platforms .. platforms supported by the project -# modules .............. additional modules in subsystems -%projects = ( - glite => { - current_version => 3, - etics_name => 'org.glite', - conf_prefix => { %cvs_tag_prefix }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}', - local_prefix => '', - etics_externs => { - default => { - globus_essentials=>'vdt_globus_essentials', - globus=>'globus', - globus_proxy_utils=>'vdt_globus_essentials', - gridsite=>'org.gridsite.libs', - yaim_core=>'org.glite.yaim.core', - gip_release=>'glite-info-provider-release', - gip_service=>'glite-info-provider-service', - bdii=>'bdii', - glite_version=>'glite-version', - glite_info_templates=>'glite-info-templates', - glue_schema=>'glue-schema', - trustmanager=>'org.glite.security.trustmanager', - axis=>'axis', - lcas=>'org.glite.security.lcas', - gsoapxx=>'-', - jdk=>'jdk', - voms=>'org.glite.security.voms-api-cpp', - }, - }, - etics_externs_devel => { - default => { - gridsite=>'org.gridsite.devel', - voms=>'org.glite.security.voms-api', - }, - }, - etics_projects => { - vdt=>[qw/globus globus_essentials globus_proxy_utils gpt/], - 'org.glite'=>[qw/voms gridsite lcas gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/], - }, - etics_locations => { - '*' => '', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ], - 'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R/ ], - 'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412 => 1, - sl5_ia32_gcc412 => 1, - deb5_x86_64_gcc432 => 1, - deb5_ia32_gcc432 => 1, - slc4_x86_64_gcc346 => 1, - slc4_ia32_gcc346 => 1, - }, - modules => { - 'lb' => [ qw/glite-LB/ ], - 'px' => [ qw/glite-PX/ ], - }, - }, - - emi => { - current_version => 2, - etics_name => 'emi', - conf_prefix => { - 'lb' => 'emi-', - 'jp' => 'emi-', - 'jobid' => 'emi-', - 'lbjp-common' => 'emi-', - 'gridsite' => 'emi-', - 'px' => 'emi-', - 'canl' => 'emi-', - }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour= --nothrflavour=', - local_prefix => '/usr', - etics_externs => { - default => { - globus_essentials=>'globus-gssapi-gsi', - globus=>'globus-gssapi-gsi-devel', - globus_proxy_utils=>'globus-proxy-utils', - gridsite=>'emi.gridsite.libs', - yaim_core=>'emi.yaim.yaim-core', - yaim_bdii=>'emi.bdii.yaim-bdii', - gip_service=>'emi.bdii.glite-info-provider-service', - bdii=>'emi.bdii.core', - glite_version=>'emi.emi-version', - glue_schema=>'emi.bdii.glue-schema', - trustmanager=>'emi.java-security.trustmanager', - trustmanager_axis=>'emi.java-security.trustmanager-axis', - axis=>'axis1.4', - lcas=>'emi.sac.lcas', - gsoapxx=>'-', - jdk=>'java', - voms => 'emi.voms.voms-api', - }, - sl5_x86_64_gcc412EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - sl6_x86_64_gcc446EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - deb6_x86_64_gcc445 => { - axis => 'axis1.4', - # mappings in ETICS project configuration - #globus_essentials => 'libglobus-gssapi-gsi4', - #globus => 'libglobus-gssapi-gsi-dev', - #axis => 'libaxis-java', - #cares => 'libc-ares2', - #cppunit => 'libcppunit', - #expat => 'libexpat1', - #log4c => 'liblog4c3', - #curl => 'libcurl3', - #'mysql' => 'libmysqlclient16', - #'mysql-devel' => 'libmysqlclient-dev', - #libxslt => 'xsltproc', - #'jakarta-commons-codec' => 'libcommons-codec-java', - #'jakarta-commons-lang' => 'libcommons-lang-java', - #'tetex-latex' => 'texlive-latex-extra', - #'perl-LDAP' => 'libnet-ldap-perl', - #'fuse-lib' => 'libfuse2', - #'fuse' => 'fuse-utils', - }, - }, - etics_externs_devel => { - default => { - cares => 'c-ares-devel', - classads => 'classads-devel', - cppunit => 'cppunit-devel', - expat => 'expat-devel', - gsoap => 'gsoap-devel', - voms => 'emi.voms.voms-api-devel', - libtar => 'libtar-devel', - log4c => 'log4c-devel', - postgresql => 'postgresql-devel', - curl => 'curl-devel', - libxml2 => 'libxml2-devel', - openssl => 'openssl-devel', - gridsite=>'emi.gridsite.devel', - jdk=>'java-devel', - }, - deb6_x86_64_gcc445 => { - # mappings in ETICS project configuration - #cares => 'libc-ares-dev', - #cppunit => 'libcppunit-dev', - #expat => 'libexpat1-dev', - #libtar => 'libtar-dev', - #log4c => 'liblog4c-dev', - #postgresql => 'libpq-dev', - #curl => 'libcurl4-openssl-dev', - #libxml2 => 'libxml2-dev', - #openssl => 'libssl-dev', - #'tetex-latex' => 'texlive-latex-extra', - #libxslt=>'xsltproc', - #'httpd-devel' => 'apache2-prefork-dev', - #'fuse-devel' => 'libfuse-dev', - #gsoap => 'gsoap', - #'krb5-devel' => 'libkrb5-dev', - }, - }, - etics_projects => { - 'emi'=>[qw/voms voms-devel gridsite lcas gip_service bdii glite_version glue_schema yaim_core yaim_bdii trustmanager trustmanager_axis/], - }, - etics_locations => { - axis => 'axis', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ], - 'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - 'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412EPEL => 1, - sl5_ia32_gcc412EPEL => 1, - sl6_x86_64_gcc446EPEL => 1, - deb6_x86_64_gcc445 => 1, - }, - modules => { - 'lb' => [ qw/emi-lb/ ], - 'px' => [ qw/emi-px/ ], - }, - }, -); - -%platform_properties = ( - 'jobid.api-java' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.types' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.doc' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.ws-interface' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.nagios' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.myproxy-config' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'gridsite.devel' => { - default => { 'packageName' => 'gridsite-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' }, - }, - 'jobid.api-c-devel' => { - default => { 'packageName' => 'glite-jobid-api-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' }, - }, - 'jobid.api-cpp-devel' => { - default => { 'packageName' => 'glite-jobid-api-cpp-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' }, - }, - 'lbjp-common.db-devel' => { - default => { 'packageName' => 'glite-lbjp-common-db-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' }, - }, - 'lbjp-common.gsoap-plugin-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' }, - }, - 'lbjp-common.gss-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gss-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' }, - }, - 'lbjp-common.jp-interface-devel' => { - default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' }, - }, - 'lbjp-common.log-devel' => { - default => { 'packageName' => 'glite-lbjp-common-log-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' }, - }, - 'lbjp-common.maildir-devel' => { - default => { 'packageName' => 'glite-lbjp-common-maildir-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' }, - }, - 'lbjp-common.server-bones-devel' => { - default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' }, - }, - 'lbjp-common.trio-devel' => { - default => { 'packageName' => 'glite-lbjp-common-trio-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' }, - }, - 'lb.client-devel' => { - default => { 'packageName' => 'glite-lb-client-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' }, - }, - 'lb.common-devel' => { - default => { 'packageName' => 'glite-lb-common-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' }, - }, - 'lb.state-machine-devel' => { - default => { 'packageName' => 'glite-lb-state-machine-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' }, - }, - 'lb.logger-devel' => { - default => { 'packageName' => 'glite-lb-logger-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' }, - }, - 'px.proxyrenewal-devel' => { - default => { 'packageName' => 'glite-px-proxyrenewal-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' }, - }, -); - -my @k = keys %deps_aux; -@buildroot{@k} = ('') x ($#k+1); - -$buildroot{'gridsite.core'} = 'src'; -} - -sub full -{ - my ($short) = @_; - my $subsys = $short; - $subsys =~ s/\..*//; - - my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite'; - return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short"; -} - -sub get_version -{ - my ($fmod, $top_srcdir) = @_; - - my ($subsys,$mod) = split /\./,$fmod,2; - my ($major,$minor,$rev,$age); - my $old_; - - if ($force_version) { - $force_version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - my $path = "$top_srcdir/project"; - if ($subsys eq 'gridsite') { - $path = "$cvs_prefix{$subsys}.$subsys.core/project"; - } - open V,"$path/version.properties" - or die "$path/version.properties: $!\n"; - - $old_ = $_; - while () { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - $_ = $old_; - } - $version = "$major.$minor.$rev-$age"; - - return ($major, $minor, $rev, $age); -} - -sub get_description -{ - my ($top_srcdir) = @_; - - my $cvs_module = $top_srcdir; - my $package_description = ""; - my $package_summary = ""; - - if (-e "$cvs_module/project/package.description") { - open V, "$cvs_module/project/package.description"; - $package_description = join ("", ); - close V; - chomp $package_description; - } - else { - print STDERR "package.description not found for $subsys.$module!\n"; } - - if (-e "$cvs_module/project/package.summary") { - open V, "$cvs_module/project/package.summary"; - $package_summary = join ("", ); - close V; - chomp $package_summary; - $package_summary =~ s/\n/\\n/g; - } - else { - print STDERR "package.summary not found for $subsys.$module!\n"; } - - return ($package_summary, $package_description); -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb -lbjp-common.gss lbjp-common.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px -canl.c -/; - @aux{@m} = (1) x ($#m+1); - - my ($short) = @_; - my $full = full $short; - my ($subsys,$mod) = split /\./,$short,2; - my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}"; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $top_srcdir = '.'; - my $abs_srcdir = ''; - my $build = ''; - - if ($module) { - $top_srcdir = $0; - $top_srcdir =~ s,/?[^/]*$,,; - $abs_srcdir = $top_srcdir; - $top_srcdir =~ s,^$,\.,; - } else { - $build = "$full/"; - $abs_srcdir = "$full/"; - unless ($buildroot{$_} eq '') { - $top_srcdir = '..'; - $build .= "$buildroot{$_}/"; - unless (-d "$build") { - mkdir "$build" or die "mkdir $build: $!\n"; - } - } - } - - my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir; - my ($package_summary, $package_description) = get_description $abs_srcdir; - if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; } - my $package_description_debian = $package_description; - $package_description_debian =~ s/^/ /mg; - - my ($old_locale, $specdate, $debdate); - - # files for ETICS always in root source directory - mkdir $abs_srcdir."project" unless (-d $abs_srcdir."project"); - open PKGCHL,">".$abs_srcdir."project/changelog" - or die $abs_srcdir."project/changelog: $!\n"; - $old_locale = setlocale(LC_TIME); - setlocale(LC_TIME, "C"); - $specdate = strftime("%a %b %d %Y", gmtime()); - $debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime()); - setlocale(LC_TIME, $old_locale); - print PKGCHL qq{* $specdate CESNET team -- automatically generated package -}; - close PKGCHL; - - unless ($top_srcdir eq '.') { - unlink $build."Makefile"; - symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n"; - } - - open MKINC,">".$build."Makefile.inc" - or die $build."Makefile.inc: $!\n"; - - print "Creating ".$build."Makefile.inc\n"; - - print MKINC qq{project = $project -PREFIX = $root -prefix = $prefix -stagedir = $stagedir -sysroot = $sysroot -sysconfdir = $sysconfdir -localstatedir = $localstatedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -libdir = $libdir -top_srcdir = $top_srcdir -}; - - for (@{$need_externs{$short}}) { - next unless defined $externs{$_} and defined $externs{$_}{prefix}; - print MKINC "${_}_prefix = $externs{$_}{prefix}\n"; - print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags}; - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; - - my $dh; - my $debian = 0; - - opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!"; - for my $dir (readdir $dh) { - if ($dir=~/^(.*)\.spec$/) { - if ($1 ne $packageName) { - printf STDERR "Changed RPM name: $packageName --> $1\n" if ($debug);; - $packageName=$1; - } - last; - } - } - closedir $dh; - - for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") { - if (-f "$abs_srcdir/project/$file") { - my $old_ = $_; - printf STDERR "Creating $build$file\n" if ($debug);; - open DST, ">$build$file"; - open SRC, "<$abs_srcdir/project/$file"; - while () { - if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; } - if (/\@URL\@/) { s/\@URL\@/$package{url}/g; } - if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; } - if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; } - if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; } - if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; } - if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; } - if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; } - if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; } - if (/\@AGE\@/) { s/\@AGE\@/$age/g; } - if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; } - if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; } - if (/\@DEBIAN_VCS\@/) { s/\@DEBIAN_VCS\@/$package{debian_vcs}/g; } - if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; } - if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; } - if (/^\s*.+\/configure\s/ and $force_version) { - print "Version forced to $version\n" if ($debug);; - s/--version\s+\S+\s?//; - s/$/ --version $version/; - } - printf DST "%s", "$_"; - } - close SRC; - close DST; - $_ = $old_; - } - } - - print "Creating ${build}debian/\n" if ($debug);; - - `rm -rfv ${build}debian`; - mkdir $build."debian" or die $!; - `cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`; - `mv ${build}debian.* ${build}debian/ 2>/dev/null`; - `rm -f ${build}debian/*.orig`; - opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!"; - for $_ (readdir $dh) { - if (/^debian\.(.*)/) { - `mv ${build}debian/$_ ${build}debian/$1`; - $debian = 1; - } - } - closedir $dh; - - if ($debian) { - my ($dir, $file); - - chmod 0755, "${build}debian/rules"; - $file="${build}debian/docs"; if (not -f $file) { `touch $file`; } - $dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; } - $file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` } - $file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` } - $file="${build}debian/changelog"; if (not -f $file) { - open FH, ">$file" or die $!; - print FH qq{$packageName ($major.$minor.$rev-$age) unstable; urgency=low - - * Automatically generated package - - -- $package{maintainer} $debdate -}; - close FH; - } - - } else { - `rm -rf ${build}debian`; - } -} - -BEGIN{ -}; - -sub mode_etics_packaging { - my ($fmod, $cmd, $rpmprepare, $debprepare) = @_; - my ($workspaceDir, $srcPackageName, $srcAge, $topDir); - - # old-school packaging by ETICS for EMI-1 - if ($project eq 'emi' and $project_version == 1) { return; } - - if ($fmod eq 'gridsite.core') { - $workspaceDir = '..'; - $srcPackageName = 'gridsite'; - $srcAge = ''; - $topDir = '../'; - } else { - $workspaceDir = '${workspaceDir}'; - $srcPackageName = '${packageName}'; - $srcAge = '-${age}'; - $topDir = ''; - } - - $cmd->{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SRPMSLocation}'; - $cmd->{default}{packaging} = $rpmprepare; - $cmd->{default}{packaging} .= "dir=\${workspaceDir}/rpm_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SRPMSLocation} \$dir/{BUILD,RPMS,SOURCES,SRPMS} 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/SOURCES/ - rpmbuild -bs --nodeps --define \"_topdir \$dir\" $srcPackageName.spec - cp -v \$dir/SRPMS/*.src.rpm \${package.SRPMSLocation}/ - rm -rf \$dir"; - - for my $p ('deb5_x86_64_gcc432', 'deb5_ia32_gcc432', 'deb6_x86_64_gcc445', 'deb6_ia32_gcc445') { - for my $c (keys %{$cmd->{default}}) { $cmd->{$p}{$c} = $cmd->{default}{$c}; } - $cmd->{$p}{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SDEBSLocation}'; - $cmd->{$p}{packaging} = $debprepare; - $cmd->{$p}{packaging} .= "dir=\${workspaceDir}/dpkg_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SDEBSLocation} \$dir 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/${srcPackageName}_\${version}.orig.tar.gz - tar xzf \$dir/${srcPackageName}_\${version}.orig.tar.gz -C \$dir - cp -rf ${topDir}debian/ \$dir/$srcPackageName-\${version}/ - cd \$dir/$srcPackageName-\${version} - dpkg-buildpackage -S -d -nc - cd - - cp -v \$dir/*.tar.gz \$dir/*.dsc \${package.SDEBSLocation}/ - rm -rf \$dir"; - } -} - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod,2; - my $full = full "$subsys.$module"; - - my ($major,$minor,$rev,$age) = get_version $fmod, $full; - - # XXX: --with ignored for platform-dependend packages - my @copts = (); - my %ge; - @ge{@{$etics_projects{$project{etics_name}}}} = (1) x ($#{$etics_projects{$project{etics_name}}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/ and (defined $externs{$_} or defined $jar{$_})) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - next if ($eext eq '-'); - if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}) { - $eext = $project{etics_locations}{$_} if ($project{etics_locations}{$_}); - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } else { - if ($ge{$_} and not defined $externs{$_}{pkg}) { - push @copts, "--with-$_=\${stageDir}"; - } - } - } - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}); - } - - my $conf; - my $conftag; - my ($confprefix, $nameprefix, $packageName); - - $dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n"; - - $confprefix = $project{conf_prefix}{$subsys}; - $nameprefix = $confprefix; - $nameprefix =~ s/-$//; - $nameprefix =~ s/-/\./g; - $packageName = "$project{tag_prefix}{$subsys}$subsys-${module}"; - - if ($branch) { - $conf = "$confprefix${subsys}-${module}_$branch"; - $conftag = $branch; - # forced low age number - $age = $branch eq 'HEAD' ? '0head' : '0dev'; - push @copts, '--version ${version}-${age}'; - } - else { - $conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; -# XXX: gridsite hack - $conftag = $subsys eq 'gridsite' ? "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : - "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - - # lowering age for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age - 1; - } - } - - # emi1 suffix for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age.$project.$project_version; - $conf = $conf.$project.$project_version; - } - - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"}; - - my $confdir = $buildroot{"$subsys.$module"} eq '' ? '.' : '..'; - - my $cvs_module = full "$subsys.$module"; - my ($package_summary, $package_description) = get_description $cvs_module; - if ($package_description) { - $package_description =~ s/\n/\\n/g; - $package_description = "package.description = $package_description\n"; - } - if ($package_summary) { - $package_summary = "package.summary = $package_summary\n"; - } - - my %cmd; - $cmd_vcs{checkout} = "cvs -d \${vcsroot} co -d \${moduleName} ".($conftag eq 'HEAD' ? '-A' : '-r ${tag}')." $cvs_module 2>/dev/null"; - #$cmd_vcs{checkout} = "((test -d jra1mw/.git && (cd jra1mw; git pull)) || (git clone -q http://scientific.zcu.cz/git/jra1mw.git"; - #$cmd_vcs{checkout} .= " && (cd jra1mw; git checkout -b \${tag} --track origin/\${tag})" unless ($conftag eq /HEAD/); - #$cmd_vcs{checkout} .= ")) && (test -d \${moduleName} || ln -s jra1mw/$cvs_module \${moduleName})"; - $cmd_vcs{checkout} .= "\n\ttest -f \${packageName}-\${version}-\${age}.src.tar.gz || (ln -s \${moduleName} \${packageName}-\${version}; tar -chf - \${packageName}-\${version} --exclude CVS --exclude .git --exclude .etics | gzip --best > \${packageName}-\${version}-\${age}.src.tar.gz; rm \${packageName}-\${version})"; - $cmd_vcs{tag} = "cvs -d \${vcsroot} tag -R \${tag} ${moduleName}"; - - $cmd{default}{init} = 'None'; - $cmd{default}{configure} = 'None'; - $cmd{default}{compile} = 'None'; - $cmd{default}{test} = 'None'; - $cmd{default}{install} = 'None'; - $cmd{default}{packaging} = 'None'; - $cmd{default}{clean} = 'make clean'; - - if (exists $subpackages{$fmod}) { - $cmd{default}{clean} = 'None'; - $cmd{default}{packaging} = "echo building nothing, $subpackages{$fmod} will build this package"; - $cmd_vcs{checkout} = "mkdir -v \${moduleName} 2>/dev/null || true"; - } elsif ($subsys eq 'gridsite') { - $cmd_vcs{tag} = 'None'; - - if ($module eq 'core') { - my $flags; - - if ($project ne 'glite') { - # don't evaluate pkg-config calls to get them into source package - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=\`pkg-config gsoap --variable=prefix\` - OPENSSL_GLOBUS_FLAGS=\`pkg-config globus-openssl --cflags\` - OPENSSL_GLOBUS_LIBS=\`pkg-config globus-openssl --libs\`'; - } else { - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=${gsoap.location} - OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor} - OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir} - HTTPD_FLAGS=-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-1 -I${httpd-devel.location}/include/apr-1.0 -I${httpd-devel.location}/include/apr-0 -I${httpd-devel.location}/include/pcre'; - } - - $cmd{default}{configure} = "cat > Makefile.inc </dev/null"; - $cmd{default}{init} = 'echo "/sbin/ldconfig" > project/.post - echo "/sbin/ldconfig" > project/.postun'; - $cmd{default}{configure} = "cat > src/Makefile.inc <{default}}) { - $defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n"; - } - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = $project{etics_name}.$subsys.$module -displayName = $conf -description = $cvs_prefix{$subsys}.$subsys.$module -projectName = $project{etics_name} -age = $age -deploymentType = None -vcsroot = :pserver:anonymous\@glite.cvs.cern.ch:/cvs/glite -tag = $conftag -version = $major.$minor.$rev -$dwpath -[Platform-default:VcsCommand] -displayName = None -description = None -tag = $cmd_vcs{tag} -branch = None -commit = None -checkout = $cmd_vcs{checkout} - -}; - - for my $p (keys %cmd) { - next if $p ne 'default' and exists $project{supported_platforms} and not exists $project{supported_platforms}{$p}; - - print C qq{[Platform-$p:BuildCommand] -postpublish = None -packaging = $cmd{$p}{packaging} -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = $cmd{$p}{compile} -init = $cmd{$p}{init} -install = $cmd{$p}{install} -clean = $cmd{$p}{clean} -test = $cmd{$p}{test} -configure = $cmd{$p}{configure} -checkstyle = None - -}; - } - - print C qq{[Platform-default:Property] -$buildroot -package.preserve.libtool = false -$package_description$package_summary$defprops}; - - for (@{$obsoletes{"$subsys.$module"}}) { - print C "package.obsoletes = $_\n"; - print C "package.replaces = $_\n"; - } - for (@{$conflicts{"$subsys.$module"}}) { - print C "package.conflicts = $_\n"; - } - for (@{$provides{"$subsys.$module"}}) { - print C "package.provides = $_\n"; - } - print C "\n"; - - for my $pp (keys %{$platform_properties{"$subsys.$module"}}) { - next if $pp eq 'default'; - next if exists $project{supported_platforms} and not exists $project{supported_platforms}{$pp}; - - print C "[Platform-$pp:Property]\n$buildroot\n"; - - for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) { - print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n"; - } - print C "$package_description$package_summary\n"; - } - - for my $platform ('default', keys %{$project{supported_platforms}}) { - my $used = 0; - my $output = ''; - - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$platform}{$_}; - my $edev = $project{etics_externs_devel}{$platform}{$_}; - - # for the default platform using package of the same - # name for runtime dependency - if (not $eext) { - if ($platform eq 'default') { -#print "default runtime $_ on default\n"; - $eext = $_; } - else { -#print "no runtime $_ on $platform\n"; - $eext = '-'; } - } - if ($eext eq '-' and $edev eq '-') { -#print "skipping $_ on $platform\n"; - next; - } - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - - if ($edev) { - if ($type eq 'B') { - # no runtime - change to devel pkg - $eext = $edev; - } elsif ($type eq 'BR' or $type eq 'RB') { - # additional devel pkg - if ($edev ne '-') { $output .= "$proj|$edev = B\n"; } - } - } - if ($eext ne '-') { $output .= "$proj|$eext = $type\n"; } - } - - if ($platform eq 'default') { - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - if (not $used) { - $used = 1; - } - $output .= "$project{etics_name}|$project{etics_name}.$_ = $type\n"; - } - } - - if ($output) { - print C qq{ -[Platform-$platform:DynamicDependency] -$output}; - } - } - - close C; - - for $file ("$cvs_module/project/debian.rules", "$cvs_module/project/$packageName.spec") { - my $lib; - my $main_module; - @copts = (); - - if ($file =~ /debian\.rules$/) { $lib = 'lib'; } - else { $lib = '%{_lib}'; } - - my $main_module = "$subsys.$module"; - if (exists $subpackages{$main_module}) { $main_module = $subpackages{$main_module}; } - - # locations hacks - if ($file =~ /$packageName\.spec$/) { - if ($fmod eq 'lb.client-java') { - push @copts, ''; - push @copts, '--with-axis=/usr/local/axis1.4'; - } - } - - if (-f $file) { - open DST,">$file.new" or die "$file.new: $!\n"; - open SRC,"<$file" or die "$file: $!\n"; - while () { - if (/^(\s*).+\/configure\s/) { - printf DST "%s", "$1"; - printf DST "/usr/bin/perl $confdir/configure $project{flavours} --root=/ --prefix=$project{local_prefix} --libdir=$lib --project=$project --module $main_module@copts\n"; - } else { - printf DST "%s", "$_"; - } - } - close SRC; - close DST; - - `diff -b "$file" "$file.new"`; - if ($? == 0) { - print STDERR "($file not changed)\n"; - unlink "$file.new"; - } else { - print STDERR "Writing $file\n"; - rename "$file", "$file.orig" unless -f "$file.orig"; - rename "$file.new", "$file"; - } - } - } -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - $gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - -sub getlibdir { - if ( -e "/etc/debian_version") { # We are on Debian - $lib64="lib"; - $lib32="lib32"; } - else { # Another distribution - $lib64="lib64"; - $lib32="lib"; } - $libdir=$lib32; - - open INP, "uname -s | "; # Check kernel name - $kname= ; - chomp($kname); - close INP; - - if ( $kname eq "Linux") { - $arch = ("x86_64\npowerpc\nppc64\n"); - - open INP, "uname -p | "; # Check processor type - $procname= ; - chomp($procname); - close INP; - - if ($arch =~/^$procname\n/) { - return ($lib64); } - - open INP, "uname -m | "; # Check machine hardware - $machname= ; - chomp($machname); - close INP; - - if ($arch =~/^$machname\n/) { - return ($lib64); } - - # special cases (hyperlink lib64, Debian) - if (-l "/usr/lib64") { - $libdir=$lib32; } - - # if /usr/lib64 doesn't exist at all (AIX) - unless ( -e "/usr/lib64" ) { - $libdir=$lib32; } - } - - if ( $kname eq "SunOS") { - if (-e "/usr/lib/64") { - $libdir="lib/64"; } - } - - return $libdir; -} - -sub reshuffle_platforms($$) { - my ($data, $platforms) = @_; - my ($platform, %blacklist, $value); - - return if not $platforms; - - for $platform (keys %$data) { -#print "plat: $platform: $data->{$platform}\n"; - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { -#print " blacklist: $_ = $data->{$platform}{$_}\n"; - $blacklist{$_} = 1; - } - } - - for $_ (keys %blacklist) { - $value = $data->{default}{$_} ? $data->{default}{$_} : $_; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - if (not defined $data->{$platform}{$_}) { - $data->{$platform}{$_} = $value; -#print "added $value to $platform\n" - } - } - $data->{default}{$_} = '-'; -#print "deleted $_ from default\n"; - } - - # merge dependencies across the supported platforms - %blacklist = []; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { - $blacklist{$_} = 1; - } - } - for $_ (keys %blacklist) { - $value = undef; - $same = 1; - for $platform (keys %$platforms) { - if (not $value) { $value = $data->{$platform}{$_}; } - if (not $data->{$platform}{$_} or $value ne $data->{$platform}{$_}) { - $same = 0; - last; - } - } - if ($same and $value) { -#print "merged dependency $_\n"; - $data->{default}{$_} = $value; - for $platform (keys %$platforms) { - delete $data->{$platform}{$_}; - } - } - } -} - -sub usage { - my @ext = keys %externs; - my @myjars = keys %jar; - - print STDERR qq{ -Usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --stage=DIR staging directory [./stage] - --root=DIR installation root (custom relocation root -> sysroot) [./stage] - --sysroot=DIR system root (custom relocation root -> sysroot) [] - --sysconfdir=DIR system configuration directory [PREFIX/etc] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - --listmodules=module list subpackages of a module - --version=maj.min.rev-age version used instead of reading version.properties - --branch=branch CVS branch/etics name suffix (HEAD, branch_2_1, ...) - --libdir=libdir typically [lib,lib64] postfix - --project=PROJECT build or generate etics for a project (glite/emi1/emi) [emi] - --debug print more details - -Mode of operation: - --mode=\{checkout|build|etics\} what to do [build] - -What to build: - --module=module build this module only - --enable-NODE build this "node" (set of modules) only - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - --canl-tag=tag checkout canl modules with specific tag - -Dependencies (summary of what will be used is always printed): - --with-EXTERNAL=PATH where to look for an external [autodetect] - --with-JAR=JAR where to look for jars - -Available nodes: - @nodes - -Default nodes: - @default_nodes - -Externals (not all for all modules) are: - @ext - -External jars are: - @myjars - -}; - -} diff --git a/org.glite.jobid.api-java/nbproject/build-impl.xml b/org.glite.jobid.api-java/nbproject/build-impl.xml deleted file mode 100755 index 7e87743..0000000 --- a/org.glite.jobid.api-java/nbproject/build-impl.xml +++ /dev/null @@ -1,627 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set src.dir - Must set test.src.dir - Must set build.dir - Must set dist.dir - Must set build.classes.dir - Must set dist.javadoc.dir - Must set build.test.classes.dir - Must set build.test.results.dir - Must set build.classes.excludes - Must set dist.jar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - - - - - - java -cp "${run.classpath.with.dist.jar}" ${main.class} - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - java -jar "${dist.jar.resolved}" - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set debug.class - - - - - Must set fix.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - Some tests failed; see details above. - - - - - - - - - Must select some files in the IDE or set test.includes - - - - Some tests failed; see details above. - - - - - Must select one file in the IDE or set test.class - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jobid.api-java/nbproject/genfiles.properties b/org.glite.jobid.api-java/nbproject/genfiles.properties deleted file mode 100755 index bb605a8..0000000 --- a/org.glite.jobid.api-java/nbproject/genfiles.properties +++ /dev/null @@ -1,8 +0,0 @@ -build.xml.data.CRC32=dbd878b7 -build.xml.script.CRC32=3fb96f09 -build.xml.stylesheet.CRC32=be360661 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=dbd878b7 -nbproject/build-impl.xml.script.CRC32=02cb42d1 -nbproject/build-impl.xml.stylesheet.CRC32=f1d9da08 diff --git a/org.glite.jobid.api-java/nbproject/private/config.properties b/org.glite.jobid.api-java/nbproject/private/config.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jobid.api-java/nbproject/private/private.properties b/org.glite.jobid.api-java/nbproject/private/private.properties deleted file mode 100755 index b6aa80e..0000000 --- a/org.glite.jobid.api-java/nbproject/private/private.properties +++ /dev/null @@ -1,6 +0,0 @@ -do.depend=false -do.jar=true -javac.debug=true -javadoc.preview=true -jaxws.endorsed.dir=/home/pavel/netbeans-6.0.1/java1/modules/ext/jaxws21/api -user.properties.file=/home/pavel/.netbeans/6.0/build.properties diff --git a/org.glite.jobid.api-java/nbproject/private/private.xml b/org.glite.jobid.api-java/nbproject/private/private.xml deleted file mode 100644 index c1f155a..0000000 --- a/org.glite.jobid.api-java/nbproject/private/private.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/org.glite.jobid.api-java/nbproject/project.properties b/org.glite.jobid.api-java/nbproject/project.properties deleted file mode 100755 index 7b4b8be..0000000 --- a/org.glite.jobid.api-java/nbproject/project.properties +++ /dev/null @@ -1,63 +0,0 @@ -application.title=jobid-api-java -application.vendor=xpiskac -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -debug.classpath=\ - ${run.classpath} -debug.test.classpath=\ - ${run.test.classpath} -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/jobid-api-java.jar -dist.javadoc.dir=${dist.dir}/javadoc -excludes= -# file.reference.commons-codec-1.3.jar=/home/etics/repository/externals/commons-codec/1.3.0/noarch/ -includes=** -jar.compress=false -jar.index=true -javac.classpath=\ - ${file.reference.commons-codec.jar} -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.source= -javac.target= -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle= -main.class=org.glite.test.Test -manifest.file=manifest.mf -meta.inf.dir=${src.dir}/META-INF -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project -# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value -# or test-sys-prop.name=value to set system properties for unit tests): -run.jvmargs= -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -source.encoding=UTF-8 -src.dir=src -test.src.dir=test -javac.compilerargs.jaxws= diff --git a/org.glite.jobid.api-java/nbproject/project.xml b/org.glite.jobid.api-java/nbproject/project.xml deleted file mode 100755 index 0db31a3..0000000 --- a/org.glite.jobid.api-java/nbproject/project.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - org.netbeans.modules.java.j2seproject - - - jobid-api-java - 1.6.5 - - - - - - - - - - diff --git a/org.glite.jobid.api-java/project/ChangeLog b/org.glite.jobid.api-java/project/ChangeLog deleted file mode 100644 index df1cd8f..0000000 --- a/org.glite.jobid.api-java/project/ChangeLog +++ /dev/null @@ -1,63 +0,0 @@ -1.0.1-1 -- Initial release of the api-java module - -1.0.2-1 -- Fixed target 'clean' in the Makefile - -1.0.3-1 -- Target 'clean' fixed to handle debian builds as well - -1.0.3-2 -- Module rebuilt - -1.0.4-1 -- Makefile using external modules jakarta-commons-* - -1.1.0-1 -- Fixes for parallel release in EMI & gLite - -1.1.0-2 -- Module rebuilt - -1.1.1-1 -- DESTDIR in makefiles - -1.1.2-1 -- Building JAR file indexes - -1.1.3-1 -- Relocatable build directory. - -1.1.3-2 -- Module rebuilt - -1.1.3-3 -- Module rebuilt - -1.1.3-4 -- Module rebuilt - -1.1.3-5 -- Module rebuilt - -1.1.3-6 -- Module rebuilt - -1.1.3-7 -- Module rebuilt - -1.2.0-1 -- Preparation for a new multiplatform release - -1.2.0-2 -- Module rebuilt - -1.2.0-3 -- Module rebuilt - -1.2.0-4 -- Module rebuilt - -1.2.0-5 -- Module rebuilt - diff --git a/org.glite.jobid.api-java/project/debian.control b/org.glite.jobid.api-java/project/debian.control deleted file mode 100644 index a81cd56..0000000 --- a/org.glite.jobid.api-java/project/debian.control +++ /dev/null @@ -1,17 +0,0 @@ -Source: glite-jobid-api-java -Priority: extra -Maintainer: @MAINTAINER@ -Uploaders: @UPLOADERS@ -Build-Depends: debhelper (>= 7.0.50~), ant, libcommons-codec-java, default-jdk -Standards-Version: 3.9.1 -Section: libs -Homepage: @URL@ -DM-Upload-Allowed: yes -@DEBIAN_VCS@ - -Package: glite-jobid-api-java -Section: libs -Architecture: all -Depends: libcommons-codec-java, ${misc:Depends} -Description: @SUMMARY@ -@DEBIAN_DESCRIPTION@ diff --git a/org.glite.jobid.api-java/project/debian.copyright b/org.glite.jobid.api-java/project/debian.copyright deleted file mode 100644 index 3d762ae..0000000 --- a/org.glite.jobid.api-java/project/debian.copyright +++ /dev/null @@ -1,38 +0,0 @@ -This work was packaged for Debian by: - - @MAINTAINER@ on Thu, 08 Dec 2011 00:46:07 +0100 - -It was downloaded from: - - @URL@ - -Upstream Author(s): - - @MAINTAINER@ - -Copyright: - - - -License: - - 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. - -On Debian systems, the complete text of the Apache version 2.0 license -can be found in "/usr/share/common-licenses/Apache-2.0". - -The Debian packaging is: - - Copyright (C) 2004-2011 Members of the EGEE Collaboration - -and is licensed under the Apache License, Version 2.0. diff --git a/org.glite.jobid.api-java/project/debian.glite-jobid-api-java.dirs b/org.glite.jobid.api-java/project/debian.glite-jobid-api-java.dirs deleted file mode 100644 index 13c9f03..0000000 --- a/org.glite.jobid.api-java/project/debian.glite-jobid-api-java.dirs +++ /dev/null @@ -1 +0,0 @@ -usr/share/java diff --git a/org.glite.jobid.api-java/project/debian.glite-jobid-api-java.install b/org.glite.jobid.api-java/project/debian.glite-jobid-api-java.install deleted file mode 100644 index 455798a..0000000 --- a/org.glite.jobid.api-java/project/debian.glite-jobid-api-java.install +++ /dev/null @@ -1 +0,0 @@ -usr/share/java/* diff --git a/org.glite.jobid.api-java/project/debian.rules b/org.glite.jobid.api-java/project/debian.rules deleted file mode 100644 index f362021..0000000 --- a/org.glite.jobid.api-java/project/debian.rules +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- - --include /usr/share/dpkg/buildflags.mk - -# Uncomment this to turn on verbose mode. -export DH_VERBOSE=1 - -configure: configure-stamp -configure-stamp: - dh_testdir - /usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=lib --project=emi --module jobid.api-java - touch $@ - -build: build-indep - -build-indep: build-stamp - -build-stamp: configure-stamp - dh_testdir - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) check - touch $@ - -clean: configure-stamp - dh_testdir - dh_testroot - rm -f configure-stamp build-stamp - $(MAKE) clean - rm -f Makefile.inc config.status - dh_clean - -install: build-stamp - dh_testdir - dh_testroot - dh_prep - dh_installdirs - $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp - -binary-indep: install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_installexamples - dh_installman - dh_installlogrotate - dh_installcron - dh_install --fail-missing - dh_link - dh_compress - dh_fixperms - dh_makeshlibs - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep diff --git a/org.glite.jobid.api-java/project/glite-jobid-api-java.spec b/org.glite.jobid.api-java/project/glite-jobid-api-java.spec deleted file mode 100644 index ab3fb45..0000000 --- a/org.glite.jobid.api-java/project/glite-jobid-api-java.spec +++ /dev/null @@ -1,61 +0,0 @@ -%global distver %(rpm -q --quiet redhat-release && rpm -q --queryformat "%{VERSION}" redhat-release || rpm -q --quiet centos-release && rpm -q --queryformat "%{VERSION}" centos-release || rpm -q --quiet sl-release && rpm -q --queryformat "%{VERSION}" sl-release | sed 's/^\\([0-9]*\\).*/\\1/') - -Summary: @SUMMARY@ -Name: glite-jobid-api-java -Version: @MAJOR@.@MINOR@.@REVISION@ -Release: @AGE@%{?dist} -Url: @URL@ -License: ASL 2.0 -Vendor: EMI -Group: System Environment/Libraries -BuildArch: noarch -BuildRequires: ant -BuildRequires: jakarta-commons-codec -%if 0%{?distver} >= 6 -BuildRequires: java-1.6.0-openjdk-devel%{?_isa} -%else -BuildRequires: java-devel -%endif -Requires: jakarta-commons-codec -BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) -AutoReqProv: yes -Source: http://eticssoft.web.cern.ch/eticssoft/repository/emi/emi.jobid.api-java/%{version}/src/%{name}-@VERSION@.src.tar.gz - - -%description -@DESCRIPTION@ - - -%prep -%setup -q - - -%build -/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=%{_lib} --project=emi --module jobid.api-java -make - - -%check -make check - - -%install -rm -rf $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT -make install DESTDIR=$RPM_BUILD_ROOT -find $RPM_BUILD_ROOT -name '*.la' -exec rm -rf {} \; -find $RPM_BUILD_ROOT -name '*.a' -exec rm -rf {} \; - - -%clean -rm -rf $RPM_BUILD_ROOT - - -%files -%defattr(-,root,root) -/usr/share/java/jobid-api-java.jar - - -%changelog -* @SPEC_DATE@ @MAINTAINER@ - @MAJOR@.@MINOR@.@REVISION@-@AGE@%{?dist} -- automatically generated package diff --git a/org.glite.jobid.api-java/project/package.description b/org.glite.jobid.api-java/project/package.description deleted file mode 100644 index 860d7dd..0000000 --- a/org.glite.jobid.api-java/project/package.description +++ /dev/null @@ -1 +0,0 @@ -JAVA implementation of handling gLite jobid diff --git a/org.glite.jobid.api-java/project/package.summary b/org.glite.jobid.api-java/project/package.summary deleted file mode 100644 index 860d7dd..0000000 --- a/org.glite.jobid.api-java/project/package.summary +++ /dev/null @@ -1 +0,0 @@ -JAVA implementation of handling gLite jobid diff --git a/org.glite.jobid.api-java/project/version.properties b/org.glite.jobid.api-java/project/version.properties deleted file mode 100644 index 21ead51..0000000 --- a/org.glite.jobid.api-java/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# : /cvs/glite/org.glite.jobid.api-java/project/version.properties,v 1.5 2009/01/20 17:25:13 akrenek Exp $ -module.version=1.2.0 -module.age=5 diff --git a/org.glite.jobid.api-java/src/org/glite/jobid/ExampleJobid.java b/org.glite.jobid.api-java/src/org/glite/jobid/ExampleJobid.java deleted file mode 100644 index 2f061b9..0000000 --- a/org.glite.jobid.api-java/src/org/glite/jobid/ExampleJobid.java +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.jobid; - -/** - * This class shows how Jobid works and how to work with it. - * @author Pavel Piskac - */ -public class ExampleJobid { - - public static void main(String[] args) { - //how Jobid class works - //unique part is automatically generated - Jobid jobid1 = new Jobid("https://somewhere.cz", 5000); - System.out.println("bkserver "+ jobid1.getBkserver()); - System.out.println("port "+ jobid1.getPort()); - System.out.println("unique "+ jobid1.getUnique()); - System.out.println("-------------------"); - - //unique part is set by user - Jobid jobid2 = new Jobid("https://somewhere.cz", 5000, "my_unique_part"); - System.out.println("bkserver "+ jobid2.getBkserver()); - System.out.println("port "+ jobid2.getPort()); - System.out.println("unique "+ jobid2.getUnique()); - System.out.println("-------------------"); - - //whole jobid is set by user and then parsed - Jobid jobid3 = new Jobid("https://somewhere.cz:5000/my_unique_part"); - System.out.println("bkserver "+ jobid3.getBkserver()); - System.out.println("port "+ jobid3.getPort()); - System.out.println("unique "+ jobid3.getUnique()); - System.out.println("-------------------"); - - //each part is set separately - Jobid jobid4 = new Jobid(); - jobid4.setBkserver("https://somewhere.cz"); - jobid4.setPort(5000); - jobid4.setUnique("my_unique_part"); - System.out.println("bkserver "+ jobid4.getBkserver()); - System.out.println("port "+ jobid4.getPort()); - System.out.println("unique "+ jobid4.getUnique()); - System.out.println("-------------------"); - } - -} diff --git a/org.glite.jobid.api-java/src/org/glite/jobid/Jobid.java b/org.glite.jobid.api-java/src/org/glite/jobid/Jobid.java deleted file mode 100644 index 840f661..0000000 --- a/org.glite.jobid.api-java/src/org/glite/jobid/Jobid.java +++ /dev/null @@ -1,245 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.jobid; - -import java.net.UnknownHostException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Calendar; -import java.util.Random; -//import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.binary.Base64; - -/** - * Class representing jobId - * - * @author Pavel Piskac (173297@mail.muni.cz) - * @version 15. 3. 2008 - */ -public class Jobid { - - String unique; - String bkserver; - int port; - - /** - * Creates new instance of Jobid class. - */ - public Jobid() { - } - - /** - * Creates new instace of JobId with BK server address and port number, unique part - * is generated. If some exception is catched during generating the unique part, then - * System.exit(-1); is called. - * - * @param bkserver BK server address - * @param port BK server port - * @throws java.land.IllegalArgumentException if bkserver is null - * @throws java.lang.IllegalArgumentException if port is lower than 1 or - * bigger than 65535 - */ - - public Jobid(String bkserver, int port) { - if (bkserver == null) { - throw new IllegalArgumentException("Jobid bkserver"); - } - - if (port < 1 || port > 65535) { - throw new IllegalArgumentException("Jobid port"); - } - - if (bkserver.indexOf("https://") == -1) - this.bkserver = "https://" + bkserver; - else this.bkserver = bkserver; - - this.port = port; - - MessageDigest digest = null; - - try { - String hostname = ""; - try { - hostname = java.net.InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException ex) { - System.err.println(ex); - } - - digest = java.security.MessageDigest.getInstance("MD5"); - unique = hostname + bkserver + port + Calendar.getInstance().getTimeInMillis() + - new Random().nextInt(999999); - - digest.update(unique.getBytes(),0,unique.length()); - Base64 base64 = new Base64(); - byte[] tmp = base64.encode(digest.digest()); - unique = new String(tmp, 0, tmp.length-2); - unique = unique.replaceAll("/", "_"); - unique = unique.replaceAll("\\+", "-"); - } catch (NoSuchAlgorithmException ex) { - System.err.println(ex); - System.exit(-1); - } - } - - /** - * Creates new instace of Jobid with BK server address, port number and - * unique part as parameters. - * - * @param bkserver BK server address - * @param port BK server port - * @param unique unique part of jobid - * @throws java.lang.IllegalArgumentException if bkserver is null - * @throws java.lang.IllegalArgumentException if port is lower than 1 or - * bigger than 65535 - * @throws java.lang.IllegalArgumentException if unique is null - */ - public Jobid(String bkserver, int port, String unique) { - if (bkserver == null) { - throw new IllegalArgumentException("Jobid bkserver"); - } - - if (port < 1 || port > 65535) { - throw new IllegalArgumentException("Jobid port"); - } - - if (unique == null) { - throw new IllegalArgumentException("Jobid unique"); - } - - if (bkserver.indexOf("https://") == -1) - this.bkserver = "https://" + bkserver; - else this.bkserver = bkserver; - - this.port = port; - this.unique = unique; - } - - /** - * Creates new instace of Jobid from string which represents jobid - * - * @param jobidString jobid string representation - * @throws java.lang.IllegalArgumentException if jobidString is null - */ - public Jobid(String jobidString) { - if (jobidString == null) { - throw new IllegalArgumentException("Jobid jobidString"); - } - - int doubleSlashPosition = jobidString.indexOf("https://"); - if (doubleSlashPosition == -1) { - throw new IllegalArgumentException("wrong jobid https"); - } - - int colonPosition = jobidString.indexOf(":", doubleSlashPosition + 8); - if (colonPosition == -1) { - throw new IllegalArgumentException("wrong jobid colon"); - } - - int dashAfterPort = jobidString.indexOf("/", colonPosition); - String bkserverS = jobidString.substring(0, colonPosition); - Integer portS = new Integer(jobidString.substring(colonPosition+1, - dashAfterPort)); - String uniqueS = jobidString.substring(dashAfterPort+1, jobidString.length()); - - this.bkserver = bkserverS; - this.port = portS.intValue(); - this.unique = uniqueS; - } - - /** - * Returns BK server address - * - * @return bkserver BK server address - */ - public String getBkserver() { - return bkserver; - } - - /** - * Sets BK server address - * - * @param bkserver BK server address - * @throws java.lang.IllegalArgumentException if bkserver is null - */ - public void setBkserver(String bkserver) { - - if (bkserver == null) { - throw new IllegalArgumentException("Jobid bkserver"); - } - - this.bkserver = bkserver; - } - - /** - * Returns unique part of jobId - * - * @return unique part of jobId - */ - public String getUnique() { - return unique; - } - - /** - * Sets unique part of jobId - * - * @param unique - * @throws java.lang.IllegalArgumentException if unique is null - */ - public void setUnique(String unique) { - - if (unique == null) { - throw new IllegalArgumentException("Jobid unique"); - } - - this.unique = unique; - } - - /** - * Returns port number - * - * @return port number - */ - public int getPort() { - return port; - } - - /** - * Sets port number - * - * @param port number - * @throws java.lang.IllegalArgumentException if port is lower than 0 or - * bigger than 65535 - */ - public void setPort(int port) { - - if (port <= 0 || port >= 65536) { - throw new IllegalArgumentException("Jobid port"); - } - - this.port = port; - } - - /** - * Returns Jobid string representation in format bkserver:port/unique - * - * @return Jobid string representation in format bkserver:port/unique - */ - public String toString() { - return bkserver + ":" + port + "/" + unique; - } -} diff --git a/org.glite.jobid/project/version.properties b/org.glite.jobid/project/version.properties deleted file mode 100644 index c695353..0000000 --- a/org.glite.jobid/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# : /cvs/jra1mw/org.glite.jobid.api-c/project/version.properties,v 1.1 2009/01/16 08:48:52 zsustr Exp $ -module.version=2.1.2 -module.age=2 diff --git a/org.glite.jp.client/.cvsignore b/org.glite.jp.client/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp.client/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp.client/Makefile b/org.glite.jp.client/Makefile deleted file mode 100644 index 4ae5e84..0000000 --- a/org.glite.jp.client/Makefile +++ /dev/null @@ -1,188 +0,0 @@ -# defaults -top_srcdir=.. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -jpprefix=jp -package=glite-jp-client -version=0.0.0 -PREFIX=/opt/glite - -glite_location=/opt/glite -globus_prefix=/opt/globus -nothrflavour=gcc32 -thrflavour=gcc32pthr -gsoap_prefix=/software/gsoap-2.6 - -CC=gcc - --include Makefile.inc - -STAGETO=include/${globalprefix}/${jpprefix} - -VPATH=${top_srcdir}/src:${top_srcdir}/examples:${top_srcdir}/project$:${top_srcdir}/interface:${stagedir}/interface:${top_srcdir}/build - -ifdef JP_PERF - JP_PERF_CFLAGS:=-DJP_PERF=1 -endif - -GLOBUS_LIBS:=-L${globus_prefix}/lib \ - -lglobus_ftp_client_${nothrflavour} \ - -lglobus_ftp_control_${nothrflavour} - -GLOBUS_CFLAGS:=-I${globus_prefix}/include/${nothrflavour} - -DEBUG:=-g -O0 -DDEBUG - -CFLAGS:=${DEBUG} -I. -I${top_srcdir}/interface -I${top_srcdir}/src -I${gsoap_prefix}/include -I${gsoap_prefix} -I${stagedir}/include ${GLOBUS_CFLAGS} -I${libtar}/include ${JP_PERF_CFLAGS} -W -Wall -Wno-unused-parameter -D_GNU_SOURCE -LDFLAGS:=-L${stagedir}/lib -L${libtar}/lib - -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -LTCOMPILE:=libtool --mode=compile ${CC} ${CFLAGS} -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install - -LIBTAR:=-L${libtar}/lib -ltar - -STAGE_HDRS:=jpcl_ctx_int.h -HDRS:=jp_client.h jpimporter.h - -EXAMPLES:=jpps_upload_files mill_feed - -LIBOBJS:=jpcl_ctx.o jpimp_lib.o -LIBTHROBJS:=${LIBOBJS:.o=.thr.o} -LIBLOBJS:=${LIBOBJS:.o=.lo} - -LIB:=libglite_jp_importer_${nothrflavour}.la -THRLIB:=libglite_jp_importer_${thrflavour}.la - -daemon:=glite-jp-importer - -wsprefix:=jpps_ - -SRCS:=jpimporter.c ${wsprefix}ClientLib.c ${wsprefix}C.c -OBJS:=${SRCS:.c=.o} - -gsoap_bin_prefix:=${shell if [ -x ${gsoap_prefix}/bin/soapcpp2 ]; then echo ${gsoap_prefix}/bin; else echo ${gsoap_prefix}; fi } -dotless_gsoap_ver:=${shell echo ${gsoap_default_version} | tr -d . } -ifeq ($(shell test -f ${stagedir}/lib/libglite_security_gsoap_plugin_${dotless_gsoap_ver}_${nothrflavour}_c.la && echo ok),ok) - langflavour:=_c -endif -GSOAPLIB:=-lglite_security_gsoap_plugin_${dotless_gsoap_ver}_${nothrflavour}${langflavour} -# static linking may be useful for LB/JP compatibility from different glite -# releases if we want to have the same prefix -ifdef GSOAP_STATIC -GSOAPLIB+=$(GSOAP_LIB) -static -endif - -LBMAILDIRLIB:=-lglite_lbu_maildir - -offset=0 -version_info:=-version-info ${shell \ - perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } - - -default all: compile - -compile: ${daemon} ${LIB} ${EXAMPLES} - -examples: ${EXAMPLES} - -${LIB}: ${LIBOBJS} - ${LINK} ${version_info} -o $@ ${LIBLOBJS} -rpath ${glite_location}/lib ${LBMAILDIRLIB} ${LIBTAR} - -${daemon}: ${OBJS} - ${LINK} -o $@ ${OBJS} ${LBMAILDIRLIB} ${GSOAPLIB} ${GLOBUS_LIBS} - -${EXAMPLES}: ${LIB} - -jpps_upload_files: %: %.o - ${LINK} -o $@ $< ${LIB} ${LBMAILDIRLIB} - -mill_feed: %: %.o - ${LINK} -o $@ $< ${LBMAILDIRLIB} -lglite_jobid - - - -JobProvenancePS.xh: %.xh: %.wsdl JobProvenanceTypes.wsdl typemap.dat - cp ${stagedir}/interface/JobProvenanceTypes.wsdl . - ${gsoap_bin_prefix}/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $< - rm -f JobProvenanceTypes.wsdl - -${wsprefix}Client.c ${wsprefix}ClientLib.c \ -${wsprefix}C.c ${wsprefix}H.h: JobProvenancePS.xh - ${gsoap_bin_prefix}/soapcpp2 -n -w -c -p ${wsprefix} JobProvenancePS.xh - -env_C.c env_Server.c: - touch env.xh - cp ${jpproject}/JobProvenanceTypes.wsdl . - ${gsoap_bin_prefix}/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o env.xh JobProvenanceTypes.wsdl - rm -f JobProvenanceTypes.wsdl - ${gsoap_bin_prefix}/soapcpp2 -w -c -p env_ env.xh - -${OBJS}: ${wsprefix}H.h soap_version.h - -soap_version.h: - ${gsoap_bin_prefix}/soapcpp2 /dev/null - perl -ne '$$. == 2 && /.*([0-9]+)\.([0-9]+)\.([0-9]+)([a-z]).*/ && printf "#define GSOAP_VERSION %d%02d%02d\n#define GSOAP_VERSION_LETTER '\''$$4'\''\n",$$1,$$2,$$3' soapH.h >$@ - -rm soapC.cpp soapH.h soapStub.h soapClient.cpp soapServer.cpp soapClientLib.cpp soapServerLib.cpp - - - - -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}/${STAGETO} - -mkdir -p ${PREFIX}/bin - -mkdir -p ${PREFIX}/lib - -mkdir -p ${PREFIX}/examples - -mkdir -p ${PREFIX}/etc/init.d - ${INSTALL} -m 755 ${daemon} ${PREFIX}/bin - ${INSTALL} -m 644 ${LIB} ${PREFIX}/lib - ${INSTALL} -m 644 jpps_upload_files ${PREFIX}/examples/glite-jp-primary-upload_files - ${INSTALL} -m 755 mill_feed ${PREFIX}/examples/glite-jp-mill_feed - cd ${top_srcdir}/examples && ${INSTALL} -m 755 glite-jp-importer.sh ${PREFIX}/examples/ - ${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/glite-jp-importer - cd ${top_srcdir}/interface && ${INSTALL} -m 644 ${HDRS} ${PREFIX}/${STAGETO} - if [ x${DOSTAGE} = xyes ]; then \ - cd ${top_srcdir}/interface && ${INSTALL} -m 644 ${STAGE_HDRS} ${PREFIX}/${STAGETO} ; \ - fi - - -clean: - -# 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 - - -%.lo: %.c - ${LTCOMPILE} -o $@ -c $< - -%.o: %.c - ${LTCOMPILE} -o $@ -c $< diff --git a/org.glite.jp.client/build.xml b/org.glite.jp.client/build.xml deleted file mode 100755 index 8a40155..0000000 --- a/org.glite.jp.client/build.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.client/config/startup b/org.glite.jp.client/config/startup deleted file mode 100755 index 036fbd8..0000000 --- a/org.glite.jp.client/config/startup +++ /dev/null @@ -1,115 +0,0 @@ -#! /bin/sh - -GLITE_LOCATION=${GLITE_LOCATION:-/opt/glite} -GLITE_LOCATION_VAR=${GLITE_LOCATION_VAR:-/var/glite} - -[ -f /etc/glite.conf ] && . /etc/glite.conf -[ -f $GLITE_LOCATION/etc/glite-wms.conf ] && . $GLITE_LOCATION/etc/glite-wms.conf - -[ -f $GLITE_LOCATION/etc/lb.conf ] && . $GLITE_LOCATION/etc/lb.conf -[ -f $GLITE_LOCATION_VAR/etc/lb.conf ] && . $GLITE_LOCATION_VAR/etc/lb.conf - -[ -f $HOME/.glite.conf ] && . $HOME/.glite.conf - -[ -n "$GLITE_JP_IMPORTER_PIDFILE" ] && pidfile=$GLITE_JP_IMPORTER_PIDFILE || - pidfile=$GLITE_LOCATION_VAR/glite-jp-importer.pid - -unset creds port - -start() -{ - if test -z "$GLITE_USER" ;then - echo 'Error: GLITE_USER is not set' - echo FAILED - return 1 - fi - - [ -n "$GLITE_HOST_CERT" -a -n "$GLITE_HOST_KEY" ] && - creds="-c $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="-c /etc/grid-security/hostcert.pem -k /etc/grid-security/hostkey.pem" - fi - fi - - [ -z "$creds" ] && echo $0: WARNING: No credentials specified. Using default lookup which is dangerous. >&2 - - [ -z "$GLITE_LB_EXPORT_JPREG_MAILDIR" ] && GLITE_LB_EXPORT_JPREG_MAILDIR=$GLITE_LOCATION_VAR/jpreg - jpreg_maildir="--reg-mdir $GLITE_LB_EXPORT_JPREG_MAILDIR " - [ -d "$GLITE_LB_EXPORT_JPREG_MAILDIR" ] || mkdir -p "$GLITE_LB_EXPORT_JPREG_MAILDIR" && chown $GLITE_USER:$GLITE_GROUP -R "$GLITE_LB_EXPORT_JPREG_MAILDIR" - [ -z "$GLITE_LB_EXPORT_JPDUMP_MAILDIR" ] && GLITE_LB_EXPORT_JPDUMP_MAILDIR=$GLITE_LOCATION_VAR/jpdump - jpdump_maildir="--dump-mdir $GLITE_LB_EXPORT_JPDUMP_MAILDIR " - [ -d "$GLITE_LB_EXPORT_JPDUMP_MAILDIR" ] || mkdir -p "$GLITE_LB_EXPORT_JPDUMP_MAILDIR" && chown $GLITE_USER:$GLITE_GROUP "$GLITE_LB_EXPORT_JPDUMP_MAILDIR" - [ -n "$GLITE_LB_EXPORT_JPPS" ] && jpps="--jpps $GLITE_LB_EXPORT_JPPS " - - [ -n "$GLITE_LB_EXPORT_SANDBOX_MAILDIR" ] && sandbox_maildir="--sandbox-mdir $GLITE_LB_EXPORT_SANDBOX_MAILDIR " - - if [ -n "$GLITE_LB_EXPORT_JOBSDIR_KEEP" ]; then - keep_jobs="--store ${GLITE_LB_EXPORT_JOBSDIR_KEEP} " - [ -d $GLITE_LB_EXPORT_JOBSDIR_KEEP ] || mkdir -p $GLITE_LB_EXPORT_JOBSDIR_KEEP - fi - - echo -n Starting glite-jp-importer ... - -# XXX: HEAD -# -i $pidfile $jpreg_maildir $jpdump_maildir $jpps $sandbox_maildir $creds" \ - - su - $GLITE_USER -c "$GLITE_LOCATION/bin/glite-jp-importer \ - -i $pidfile $jpreg_maildir $jpdump_maildir $jpps $sandbox_maildir $keep_jobs \ - $creds $GLITE_JP_IMPORTER_ARGS" \ - && echo " done" || echo " FAILED" -} - -stop() -{ - if [ -f $pidfile ]; then - pid=`cat $pidfile` - kill $pid - echo -n Stopping glite-jp-importer \($pid\) ... - try=0 - while ps p $pid >/dev/null 2>&1; do - sleep 1; - try=`expr $try + 1` - if [ $try = 20 ]; then - echo " giving up after $try retries" - return 1 - fi - done - echo " done" - rm -f $pidfile - else - echo $pidfile does not exist - glite-jp-importer not running? >&2 - return 1 - fi -} - -status() -{ - retval=0 - - if [ -f $pidfile ]; then - pid=`cat $pidfile` - if ps p $pid >/dev/null 2>&1; then - echo glite-jp-importer running as $pid - else - echo glite-jp-importer not running - retval=1 - fi - else - echo glite-jp-importer not running - retval=1 - fi - - return $retval -} - -case x$1 in - xstart) start;; - xstop) stop;; - xrestart) stop; start;; - xstatus) status;; - x*) echo usage: $0 start,stop,restart,status >&2 - exit 1;; -esac diff --git a/org.glite.jp.client/configure b/org.glite.jp.client/configure deleted file mode 100755 index 0bf1a3f..0000000 --- a/org.glite.jp.client/configure +++ /dev/null @@ -1,701 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; - -my $pwd = `pwd`; chomp $pwd; -my $prefix = $pwd.'/stage'; -my $stagedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my $version; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $sec_tag = ''; -my $jobid_tag = ''; - -my @nodes = qw/client server logger utils client-java doc ws-test db jpprimary jpindex jpclient/; -my %enable_nodes; -my %disable_nodes; - -my %extern_prefix = ( - cares => '/opt/c-ares', - classads => '/opt/classads', - cppunit => '/usr', - expat => '/usr', - globus => '/opt/globus', - gsoap => '/usr', - mysql => '/usr', - voms => '/opt/glite', - gridsite => '/opt/glite', - lcas => '/opt/glite', - ant => '/usr', - jdk => '/usr', - libtar => '/usr', -); - -my %jar = ( - 'commons-codec' => '/usr/share/java/commons-codec-1.3.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %topbuild; - -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test/], - 'security' => [qw/gss gsoap-plugin/], - 'lbjp-common' => [qw/db maildir server-bones trio jp-interface/], - 'jobid' => [qw/api-c api-cpp api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - ); - - -my @opts = ( - 'prefix=s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour=s' => \$thrflavour, - 'nothrflavour=s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$version, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'security-tag=s' => \$sec_tag, - 'jobid-tag=s' => \$jobid_tag, - 'help' => \$help, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$extern_prefix{$_} for keys %extern_prefix; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my @m = map "org.glite.$listmodules.$_",@{$lbmodules{$listmodules}}; - print "@m\n"; - exit 0; -} - -warn "$0: --version and --output make sense only in --mode=etics\n" - if ($version || $output) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},@{$lbmodules{security}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless $disable_nodes{$_}; - } -} - -if (!$en && !$dis) { $enable_nodes{$_} = 1 for (@nodes) } ; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $prefix unless $stagedir; - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: $extern_prefix{$_}\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\nclean:\n"; - - for (@modules) { - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - print MAK "\tcd $full$build && \${MAKE} clean\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $topbuild{$_} ? - "\tcd $full$build && \${MAKE} distclean\n" : - "\trm -rf $full$build\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - - print MAK "$_: @dnames\n\tcd $full$build && \${MAKE} && \${MAKE} install\n\n"; - } - - close MAK; -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag){ - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($sec_tag){ - for (@{$lbmodules{security}}){ - if ("security.".$_ eq $module){ - $tag = '-r '.$sec_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads/ ], - 'lb.client-java' => [ qw/ant:B/ ], - 'lb.common' => [ qw/expat cppunit:B classads/ ], - 'lb.doc' => [], - 'lb.logger' => [ qw/cppunit:B/ ], - 'lb.server' => [ qw/globus expat cares mysql cppunit:B gsoap:B classads voms lcas gridsite/ ], - 'lb.state-machine' => [ qw/classads/ ], - 'lb.utils' => [ qw/cppunit:B/ ], - 'lb.ws-interface' => [], - 'lb.ws-test' => [ qw/gsoap:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/mysql/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw/cppunit:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B/ ], - 'security.gss' => [ qw/globus cares cppunit:B/ ], - 'security.gsoap-plugin' => [ qw/cppunit:B globus cares gsoap:B/ ], - 'jobid.api-c' => [ qw/cppunit:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], -); - -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$need_externs{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $need_externs_type{$ext}->{$1} = $type; - } -} - -%need_jars = ( - 'jobid.api-java' => [ qw/commons-codec/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp jobid.api-c - security.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp jobid.api-c - lb.types:B lbjp-common.trio security.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - jobid.api-c - lb.common - security.gss - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir - jobid.api-c - security.gsoap-plugin security.gss - / ], - 'lb.state-machine' => [ qw/lb.common lbjp-common.jp-interface security.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine - / ], - 'lb.ws-test' => [ qw/security.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/lbjp-common.trio/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw// ], - 'security.gss' => [ qw// ], - 'security.gsoap-plugin' => [ qw/security.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - security.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( gridsite=>'org.gridsite.core'); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', -); - -my @t = qw/lb.client-java jobid.api-java lb.types/; -@topbuild{@t} = (1) x ($#t+1); -} - -sub full -{ - my $short = shift; - return $extrafull{$short} ? $extrafull{$short} : 'org.glite.'.$short; -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java -security.gss security.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -/; - @aux{@m} = (1) x ($#m+1); - - my $short = shift; - my $full = full $short; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $build = ''; - - unless ($topbuild{$_}) { - $build = '/build'; - unless (-d "$full/build") { - mkdir "$full/build" or die "mkdir $full/build: $!\n"; - } - unlink "$full/build/Makefile"; - symlink "../Makefile","$full/build/Makefile" or die "symlink ../Makefile $full/build/Makefile: $!\n"; - } - - open MKINC,">$full$build/Makefile.inc" - or die "$full$build/Makefile.inc: $!\n"; - - print "Creating $full$build/Makefile.inc\n"; - - print MKINC qq{ -PREFIX = $prefix -stagedir = $stagedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -}; - - for (@{$need_externs{$short}}) { - print MKINC "${_}_prefix = $extern_prefix{$_}\n" - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; -} - -my %etics_externs; -my %etics_projects; -BEGIN{ - %etics_externs = ( - globus=>'vdt_globus_essentials', - cares=>'c-ares', - voms=>'org.glite.security.voms-api-cpp', - gridsite=>'org.gridsite.shared', - lcas=>'org.glite.security.lcas', - ); - %etics_projects = ( - vdt=>[qw/globus/], - 'org.glite'=>[qw/voms gridsite lcas/], - ); -}; - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod; - - my ($major,$minor,$rev,$age); - - if ($version) { - $version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - open V,"org.glite.$subsys.$module/project/version.properties" - or die "org.glite.$subsys.$module/project/version.properties: $!\n"; - - while ($_ = ) { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - } - - my @copts = (); - my %ge; - @ge{@{$etics_projects{'org.glite'}}} = (1) x ($#{$etics_projects{'org.glite'}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}/$_*.jar"; - } - - - my $conf = "glite-$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $topbuild{"$subsys.$module"} ? '' : "build.root = build\n"; - - my $confdir = $topbuild{"$subsys.$module"} ? '..' : '../..'; - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = org.glite.$subsys.$module -displayName = $conf -description = org.glite.$subsys.$module -projectName = org.glite -age = $age -deploymentType = None -tag = $conf -version = $major.$minor.$rev -path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz - -[Platform-default:VcsCommand] -displayName = None -description = None -tag = cvs -d \${vcsroot} tag -R \${tag} \${moduleName} -branch = None -commit = None -checkout = cvs -d \${vcsroot} co -r \${tag} \${moduleName} - -[Platform-default:BuildCommand] -postpublish = None -packaging = None -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = make -init = None -install = make install -clean = make clean -test = make check -configure = cd $confdir && \${moduleName}/configure --thrflavour=\${globus.thr.flavor} --nothrflavour=\${globus.nothr.flavor} --prefix=\${prefix} --stage=\${stageDir} --module $subsys.$module @copts -checkstyle = None - -[Platform-default:Property] -$buildroot - -[Platform-default:DynamicDependency] - -}; - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - print C "$proj|$eext = $type\n"; - } - - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - print C "org.glite|org.glite.$_ = $type\n"; - } - - close C; -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$extern_prefix{gsoap}/bin/soapcpp2 -v 2>&1 |" or die "$extern_prefix{gsoap}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - - -sub usage { - my @ext = keys %extern_prefix; - my @myjars, keys %jar; - - print STDERR qq{ -usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - -Mode of operation: - --mode={checkout|build|etics} what to do [build] - -What to build: - --module=module build this module only (mostly in-Etics operation) - --enable-NODE build this "node" (set of modules) only. Available nodes are - @{$lbmodules{lb}},@{$lbmodules{security}} - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --security-tag=tag checkout security modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - -Dependencies: - --with-EXTERNAL=PATH where to look for an external. Required externals - (not all for all modules) are: - @ext - --with-JAR=JAR where to look for jars. Required jars are: - @myjars - Summary of what will be used is always printed - -}; - -} diff --git a/org.glite.jp.client/doc/README.jpimporter b/org.glite.jp.client/doc/README.jpimporter deleted file mode 100644 index 3e8bb2d..0000000 --- a/org.glite.jp.client/doc/README.jpimporter +++ /dev/null @@ -1,115 +0,0 @@ -jpimporter is a daemon which take care of all job registration from particular -LB server, forwarding them to the JP primary service and also file uploads, which -means sending LB dumps, sendbox files etc. to ftp server dedicated by JP PS. - -The daemon runs two proceses, one for registrations and another for file uploads. -Both processes reads the local directory which has a given structure and are -handled by glite-lb-maildir library calls. - - - -Namely for the registrations, LB server creates the message describing job, its -owner and JP primary server address and stores it into given maildir location -(i.e. /tmp/lb_server_jpreg/). The jpimporter daemon which is running on the same -host is periodicaly scanning this directory and whenever new messages appears, -attempts to register this described job to JP PS. - -For the file upload is the jpimporter behavior almost the same except the -message has different structure and a file to deliver must be placed in the -filesystem. - -For LB dumps, there is another utility, which parses common LB dump files -(created when purging the LB server), creates one file per every job and stores -message describing the location, destination etc. to local directory. This -message directory should be obviously monitored by the jpimporter again. - -lb_dump_exporter utility usage: lt-lb_dump_exporter [option] - -h, --help Shows this screen. - -d, --dump Dump file location. - File generated by the glite-lb-purge - -s, --store New dump files storage. - Directory, where to store all dump files - -j, --jpps Target JPPS. - jpps where should the file be uploaded - -m, --lbmaildir LB maildir path. - Directory, where should be stored the message - describing the file upload (read by jpimporter) - -jpimporter daemon usage: glite-jp-importer [option] - -h, --help displays this screen - -k, --key private key file - -c, --cert certificate file - -C, --CAdir trusted certificates directory - -g, --debug don't run as daemon, additional diagnostics - -p, --jpps JP primary service server - this JPPS server is used by default, when user/lb/... - does not specifies one - -r, --reg-mdir path to the 'LB maildir' subtree for registrations - This directory is scanned for the job registration - messages. - -d, --dump-mdir path to the 'LB maildir' subtree for LB dumps - This directory is scanned for the file upload msgs. - -s, --sandbox-mdir path to the 'LB maildir' subtree for input/output sandboxes - -i, --pidfile file to store master pid - -t, --poll maildir polling interval (in seconds) - Specifies the time interval for which the process - JobRegistration/FileUpload sleeps after the unsuccessful - scan (find no new messages) -Examples: - -So, for the job registration and dump upload from the LB server, you should run the -LB server like this: -./glite_lb_bkserverd -c -k -S /var/tmp/purge -D /var/tmp/dump -J /tmp/lb_server_jpreg - -(Whenever the job is registered to the LB server, the message for jpimporter -is stored in the /tmp/lb_server_jpreg directory.) - -Then you should run the jpimporter daemon on the same host: -./glite-jp-importer -c -k -p jpps.server.address:8900 -r /tmp/lb_server_jpreg -d /tmp/lb_server_jpdump - -(Every job registration anounced in /tmp/lb_server_jpreg directory will be sent -to the JP PS at the address jpps.server.address:8900.) - -According the dump files - on the same host should be periodicaly ran the -glite-lb-purge utility. (Usually started by cron) Let say, that it stores the -LB dump file /var/tmp/purge/dump_file. - -Then you should run (most likely in the same cron job) -./lb_dump_exporter -d /var/tmp/purge/dump_file -s /var/tmp/dumps_per_job -j jpps.server.address:8900 -m /tmp/lb_server_jpdump - -(Then there is created a set of LB dump file - one per job - and according to them -lb_dump_exporter will also notify the glite-jp-importer) - - - - -For the sandbox files, you should use the JP client API to create messages for -jpimporter. The function glite_jpimporter_upload_files() do the job. It takes -one ore more files and create one tarball. Then everything works like with -LB dumps. - -There is an example utility in org.glite.jp.client/examples/jpps_upload_files.c -(staged as glite-jp-primary-upload_files). - -The glite_jpimporter_upload_files funftion prototype: - -int glite_jpimporter_upload_files( - /* JP client context. - * stores the error code/description - * user can set default JP PS address there and - * LB directory for jpimporter announcements - */ - glite_jpcl_context_t ctx, - - /* JobId - */ - const char *jobid, - /* File list. Stored in the array of string. - * Last item has to be NULL - */ - const char **files, - /* Location of the user proxy file - */ - const char *proxy); - - diff --git a/org.glite.jp.client/examples/glite-jp-importer.sh b/org.glite.jp.client/examples/glite-jp-importer.sh deleted file mode 100644 index 8b525da..0000000 --- a/org.glite.jp.client/examples/glite-jp-importer.sh +++ /dev/null @@ -1,83 +0,0 @@ -#! /bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# all-in-one example script for purging LB and importing the dumps to JP -# -# uses helper purging script glite-lb-export.sh from glite.lb.client -# - -GLITE_LOCATION=${GLITE_LOCATION:-/opt/glite} -GLITE_LOCATION_VAR=${GLITE_LOCATION_VAR:-${GLITE_LOCATION}/var} - -[ -f /etc/glite.conf ] && . /etc/glite.conf -[ -f $GLITE_LOCATION/etc/glite-wms.conf ] && . $GLITE_LOCATION/etc/glite-wms.conf - -[ -f $GLITE_LOCATION/etc/jp.conf ] && . $GLITE_LOCATION/etc/jp.conf -[ -f $GLITE_LOCATION_VAR/etc/jp.conf ] && . $GLITE_LOCATION_VAR/etc/jp.conf - -[ -f $HOME/.glite.conf ] && . $HOME/.glite.conf - -# get default values for purge and export -PREFIX=${GLITE_LOCATION:-`dirname $0`/..} -GLITE_LB_EXPORT_ENABLED="false" GLITE_LB_PURGE_ENABLED="false" . $PREFIX/bin/glite-lb-export.sh - -# job provenance server -if [ -z "$GLITE_LB_EXPORT_JPPS" ]; then - echo "Please specify the Job Provanance Primary Storage server." - exit 1 -fi -# certificates -if [ -z "$X509_USER_CERT" -o -z "$X509_USER_KEY" ]; then - echo "Please set X509_USER_CERT and X509_USER_KEY." - exit 1 -fi -# LB maildir for job registration -if [ -z "$GLITE_LB_EXPORT_JPREG_MAILDIR" ]; then - GLITE_LB_EXPORT_JPREG_MAILDIR=$GLITE_LOCATION_VAR/jpreg - echo "GLITE_LB_EXPORT_JPREG_MAILDIR not specified (-J arguent of the bkserver), used $GLITE_LB_EXPORT_JPREG_MAILDIR" -fi -if [ -n "$GLITE_LB_EXPORT_SANDBOX_MAILDIR" ]; then - sandbox_maildir="--sandbox-mdir $GLITE_LB_EXPORT_SANDBOX_MAILDIR " -fi -# pidfile -[ -n "$GLITE_JP_IMPORTER_PIDFILE" ] && pidfile="-i $GLITE_JP_IMPORTER_PIDFILE " - -CERT_ARGS="-c $X509_USER_CERT -k $X509_USER_KEY" -LOGDIR=$GLITE_LOCATION_VAR -GLITE_LB_EXPORT_PURGE_ARGS=${GLITE_LB_EXPORT_PURGE_ARGS:---cleared 2d --aborted 2w --cancelled 2w --other 2m} - -if [ -n "$GLITE_LB_EXPORT_JOBSDIR_KEEP" ]; then - keep_jobs="--store ${GLITE_LB_EXPORT_JOBSDIR_KEEP} " - [ -d $GLITE_LB_EXPORT_JOBSDIR_KEEP ] || mkdir -p $GLITE_LB_EXPORT_JOBSDIR_KEEP -fi - -[ -d $LOGDIR ] || mkdir -p $LOGDIR - -echo "Using cert args $CERT_ARGS" - -$PREFIX/bin/glite-jp-importer --reg-mdir $GLITE_LB_EXPORT_JPREG_MAILDIR --dump-mdir $GLITE_LB_EXPORT_JPDUMP_MAILDIR $CERT_ARGS ${sandbox_maildir}-g --jpps $GLITE_LB_EXPORT_JPPS $pidfile$keep_jobs$GLITE_JP_IMPORTER_ARGS > $LOGDIR/jp-importer.log 2>&1 & - -JP_PID=$! -trap "kill $JP_PID; exit 0" SIGINT - -while [ 1 ]; do - GLITE_LB_EXPORT_ENABLED="true" GLITE_LB_PURGE_ENABLED="true" $PREFIX/bin/glite-lb-export.sh - - sleep 30 -done diff --git a/org.glite.jp.client/examples/jpps_upload_files.c b/org.glite.jp.client/examples/jpps_upload_files.c deleted file mode 100644 index e4f4294..0000000 --- a/org.glite.jp.client/examples/jpps_upload_files.c +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include - -#include "jp_client.h" -#include "jpimporter.h" - -static char *myname; - -void usage(void) -{ - fprintf(stderr, - "Usage: %s [-h][-p user_proxy][-j jobid] file [file ...]\n" - " -h show this help\n" - " -p path to the proxy filename\n" - " -j jobid string\n" - " -m location of the lb maildir structure\n" - " -s JP PS server address and port\n" - , myname); -} - -int main(int argc, char **argv) -{ - glite_jpcl_context_t ctx; - char **files, - *jobid = NULL, - *proxy = NULL, - *lbmd = NULL, - *jpps = NULL; - int i, j; - - - myname = strrchr(argv[0],'/'); - if ( myname ) myname++; else myname = argv[0]; - - if ( argc < 2 ) { usage(); return 1; } - for ( i = 1; i < argc; i++ ) { - if ( argv[i][0] != '-' ) break; - if ( argv[i][1] == 'j' ) jobid = argv[++i]; - else if ( argv[i][1] == 'p' ) proxy = argv[++i]; - else if ( argv[i][1] == 'm' ) lbmd = argv[++i]; - else if ( argv[i][1] == 's' ) jpps = argv[++i]; - else if ( argv[i][1] == 'h' || argv[i][1] == '?' ) {usage();return 0;} - else {usage();return 1;} - } - - if ( i >= argc ) { usage(); return 1; } - - if ( !proxy && !(proxy = getenv("X509_USER_PROXY")) ) { - perror("-p or X509_USER_PROXY must be set!\n"); - return 1; - } - - if ( !(files = calloc(argc-i+1, sizeof(*files))) ) { - perror("calloc()"); - return 1; - } - j = 0; - while ( i < argc ) files[j++] = argv[i++]; - - if ( glite_jpcl_InitContext(&ctx) ) { - perror("glite_jpcl_InitContext()"); - return 1; - } - - if ( lbmd ) glite_jpcl_SetParam(ctx, GLITE_JPCL_PARAM_LBMAILDIR, lbmd); - if ( jpps ) glite_jpcl_SetParam(ctx, GLITE_JPCL_PARAM_JPPS, jpps); - - if ( glite_jpimporter_upload_files(ctx, jobid, (const char **)files, proxy) ) { - char *errt, *errd; - - glite_jpcl_Error(ctx, &errt, &errd); - printf("Error calling glite_jpimporter_upload_files()\n\t%s: %s\n", - errt, errd); - glite_jpcl_FreeContext(ctx); - return 1; - } - - glite_jpcl_FreeContext(ctx); - return 0; -} diff --git a/org.glite.jp.client/examples/mill_feed.c b/org.glite.jp.client/examples/mill_feed.c deleted file mode 100644 index 3a415f3..0000000 --- a/org.glite.jp.client/examples/mill_feed.c +++ /dev/null @@ -1,334 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "jp_client.h" -#include "jpimporter.h" -#include "glite/lbu/maildir.h" -#include "glite/jobid/cjobid.h" - - -#define USER "Job Generator Buddy" -#define BKSERVER "funny.zcu.cz" -#define BKPORT 9000 -#ifndef EDG_DUMP_STORAGE -#define EDG_DUMP_STORAGE "/tmp/dump" -#endif -#ifndef EDG_PURGE_STORAGE -#define EDG_PURGE_STORAGE "/tmp/purge" -#endif - - -char *jpreg_dir; -char *dump_dir; -char *user; -int do_exit = 0; -int perf_regs, perf_dumps; -char perf_ts[100]; -char *dump; char **dump_index; size_t dump_tokens; -int speed = 0; -double duration = 0.0; - -static struct option opts[] = { - { "help", 0, NULL, 'h'}, - { "reg-mdir", 1, NULL, 'R'}, - { "dump-mdir", 1, NULL, 'D'}, - { "break", 1, NULL, 'b'}, - { "dump", 1, NULL, 'd'}, -// { "sandbox-mdir",1, NULL, 's'}, - { NULL, 0, NULL, 0} -}; -static const char *get_opt_string = "hR:D:b:d:"; - -static int register_init(); -static int register_add(const char *jobid, char **new_jobid); -static void get_time(char *s, size_t maxs, double *t); -static int dump_init(const char *start_jobid, const char *filenmae); -static int dump_add(const char *filename, const char *jobid); -static void dump_done(); - - -static void handler(int sig) { - do_exit = sig; - signal(sig, SIG_DFL); -} - - -static void usage(const char *program) { - fprintf(stderr, "Usage: %s [OPTIONS]\n" - "\t-R,--reg-mdir\n" - "\t-D,--dump-mdir\n" -// "\t-s,--sandbox-mdir\n" - "\t-b,--break speed (jobs/day)\n" - "\t-d,--dump dump file\n" - , program); -} - - -int main(int argc, char *argv[]) { - char start_jobid[256], stop_jobid[256], *fn; - double ts, ts2, last, now; - int ret, opt; - FILE *f; - char *jobid, *dumpfile = NULL; - - while ((opt = getopt_long(argc, argv, get_opt_string, opts, NULL)) != EOF) - switch (opt) { - case 'h': usage(argv[0]); return 0; - case 'R': jpreg_dir = strdup(optarg); break; - case 'D': dump_dir = strdup(optarg); break; - case 'b': speed = atoi(optarg); if (speed) duration = 24.0*3600.0*1000000.0/speed; break; - case 'd': dumpfile = optarg; break; - default: printf("opt: %c\n", opt); usage(argv[0]); return 1; - } - - get_time(perf_ts, sizeof(perf_ts), &ts); - snprintf(start_jobid, sizeof(start_jobid), PERF_JOBID_START_PREFIX "%s", perf_ts); - snprintf(stop_jobid, sizeof(stop_jobid), PERF_JOBID_STOP_PREFIX "%s", perf_ts); - - if ((ret = register_init()) != 0) return ret; - if ((ret = dump_init(start_jobid, dumpfile)) != 0) return ret; - if ((ret = register_add(start_jobid, NULL)) != 0) return ret; - if (signal(SIGINT, handler) == SIG_ERR) { - ret = errno; - fprintf(stderr, "%s: can't set signal handler: %s\n", __FUNCTION__, strerror(errno)); - return ret; - } - if (speed) printf("speed: %d jobs/day (delay %lf)\n", speed, duration / 1000000.0); - else printf("speed: unlimited\n"); - printf("dump: %s\n", dumpfile ? dumpfile : "(none)"); - printf("reg-mdir: %s\n", jpreg_dir); - printf("dump-mdir: %s\n", dump_dir); - printf("start: %lf\n", ts); - printf("%s\n", start_jobid); - last = ts; - while (!do_exit) { - struct timeval tv; - - if ((ret = register_add(NULL, &jobid)) != 0) return ret; -// printf("%s\n", jobid); - if (dumpfile) { - if ((ret = dump_add(dumpfile, jobid)) != 0) return ret; -// printf(" dumped %s\n", dumpfile); - } - free(jobid); - gettimeofday(&tv, NULL); - now = tv.tv_sec + (double)tv.tv_usec / 1000000.0; - if (now < last + duration) usleep(last + duration - now); - last = now; - } - if ((ret = register_add(stop_jobid, NULL)) != 0) return ret; - asprintf(&fn, PERF_STOP_FILE_FORMAT, perf_ts); - if ((f = fopen(fn, "wt")) == NULL) { - ret = errno; - free(fn); - fprintf(stderr, "Can' create file '%s': %s\n", fn, strerror(errno)); - return ret; - } - free(fn); - fprintf(f, "reg-imp\t%d\n", perf_regs); - fprintf(f, "dump-imp\t%d\n", perf_dumps); - fclose(f); - dump_done(); - - get_time(NULL, -1, &ts2); - printf("stop: %lf\n", ts2); - printf("regs: %d (%lf jobs/day)\n", perf_regs, 86400.0 * perf_regs / (ts2-ts)); - printf("dumps: %d (%lf jobs/day)\n", perf_dumps, 86400.0 * perf_dumps / (ts2-ts)); - printf("%s\n", stop_jobid); - - return 0; -} - - -static void get_time(char *s, size_t maxs, double *t) { - struct timeval tv; - struct tm tm; - - gettimeofday(&tv, NULL); - if (t) *t = tv.tv_sec + (double)tv.tv_usec / 1000000.0; - gmtime_r(&tv.tv_sec, &tm); - if (s && maxs > 0) strftime(s, maxs, "%FT%TZ", &tm); -} - - -static int register_init() { - char *env; - - if (!jpreg_dir) { - env = getenv("GLITE_LB_EXPORT_JPREG_MAILDIR"); - if (env) jpreg_dir = strdup(env); - else jpreg_dir = strdup(GLITE_REG_IMPORTER_MDIR); - } - - - // TODO: better from certificate - env = getenv("GLITE_USER"); - if (!env) env = USER; - user = strdup(env); - - if (glite_lbu_MaildirInit(jpreg_dir) != 0) { - fprintf(stderr, "maildir init on %s failed\n", jpreg_dir); - return EIO; - } - - perf_regs = 0; - return 0; -} - - -static int register_add(const char *jobid, char **new_jobid) { - glite_jobid_t j; - char *tmpjobid, *msg; - - if (!jobid) { - if (glite_jobid_create(BKSERVER, BKPORT, &j) != 0 || (tmpjobid = glite_jobid_unparse(j)) == NULL) { - fprintf(stderr, "Can't create jobid\n"); - return EIO; - } - glite_jobid_free(j); - } else tmpjobid = strdup(jobid); - asprintf(&msg, "%s\n%s", tmpjobid, user); - if (new_jobid) *new_jobid = tmpjobid; - else free(tmpjobid); - if (glite_lbu_MaildirStoreMsg(jpreg_dir, BKSERVER, msg) != 0) { - fprintf(stderr, "Can't store message: %s\n", lbm_errdesc); - return EIO; - } - free(msg); - - perf_regs++; - return 0; -} - - -static int dump_init(const char *start_jobid, const char *filename) { - char *env, *ptr, *delim; - FILE *f; - long ssize; - size_t i, dump_maxtokens, size; - int ret; - - unlink(PERF_START_FILE); - - dump = NULL; - dump_index = NULL; - dump_tokens = 0; - if (filename) { - if ((f = fopen(filename, "rt")) == NULL) { - fprintf(stderr, "Can't open '%s': %s\n", filename, strerror(errno)); - return EIO; - } - if (fseek(f, 0, SEEK_END) == -1 || (ssize = ftell(f)) == -1 || fseek(f, 0, SEEK_SET) == -1) { - fprintf(stderr, "Can't get position in '%s': %s\n", filename, strerror(errno)); - return EIO; - } - dump = malloc(size = ssize); - if (fread(dump, size, 1, f) != 1) { - ret = errno; - fprintf(stderr, "Error reading %ld bytes from file: %s\n", ssize, strerror(errno)); - return ret; - } - fclose(f); - - dump_maxtokens = 1024; - dump_index = malloc(sizeof(char *) * dump_maxtokens); - i = 0; - ptr = dump; - do { - if (dump_tokens >= dump_maxtokens) { - dump_maxtokens *= 2; - dump_index = realloc(dump_index, sizeof(char *) * dump_maxtokens); - } - delim = strstr(ptr, "DG.JOBID=\""); - if (delim != ptr) { - dump_index[dump_tokens++] = ptr; - if (delim) { - delim[10] = '\0'; - ptr = delim + 11; - } else ptr = NULL; - } - if (ptr) ptr = strchr(ptr, '\"'); - } while (ptr && ptr[0]); - } -//for (i = 0; i < dump_tokens; i++) printf("####%s\n", dump_index[i]); - - if (!dump_dir) { - // wrong purging to GLITE_LB_EXPORT_DUMPDIR on older versions - env = getenv("GLITE_LB_EXPORT_PURGEDIR"); - if (env) dump_dir = strdup(env); - else dump_dir = strdup(EDG_DUMP_STORAGE); - } - mkdir(dump_dir, 0755); - perf_dumps = 0; - - if ((f = fopen(PERF_START_FILE, "wt")) == NULL) { - fprintf(stderr, "Can't create file '" PERF_START_FILE "': %s\n", strerror(errno)); - return EIO; - } - if (start_jobid) fprintf(f, "%s\n", start_jobid); - fclose(f); - - return 0; -} - - -static int dump_add(const char *filename, const char *jobid) { - char *fn; - int ret; - size_t i; - FILE *f; - - ret = 0; - asprintf(&fn, "%s/mill-test-%s-%06d", dump_dir, perf_ts, perf_dumps); - if ((f = fopen(fn , "wt")) == NULL) { - ret = errno; - fprintf(stderr, "Can't create file '%s': %s\n", fn, strerror(errno)); - goto err; - } - for (i = 0; i < dump_tokens; i++) { - if (fputs(dump_index[i], f) == EOF || (i + 1 < dump_tokens && (fputs(jobid, f) == EOF))) { - ret = errno; - fprintf(stderr, "Can't write to '%s': %s\n", fn, strerror(errno)); - goto err_close; - } - } - - perf_dumps++; -err_close: - fclose(f); -err: - free(fn); - return ret; -} - - -static void dump_done() { - free(dump_index); - free(dump); - dump_tokens = 0; -} diff --git a/org.glite.jp.client/interface/jp_client.h b/org.glite.jp.client/interface/jp_client.h deleted file mode 100644 index c6a4bf7..0000000 --- a/org.glite.jp.client/interface/jp_client.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef __GLITE_JP_CLIENT__ -#define __GLITE_JP_CLIENT__ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _glite_jpcl_context_t *glite_jpcl_context_t; - -typedef enum _glite_jpcl_ctx_param_t { - GLITE_JPCL_PARAM_JPPS, - GLITE_JPCL_PARAM_LBMAILDIR -} glite_jpcl_ctx_param_t; - -extern int glite_jpcl_InitContext(glite_jpcl_context_t *); -extern void glite_jpcl_FreeContext(glite_jpcl_context_t); - -extern int glite_jpcl_SetParam( - glite_jpcl_context_t ctx, - int param, ... ); - -extern int glite_jpcl_Error( - glite_jpcl_context_t ctx, - char **errt, - char **errd); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/org.glite.jp.client/interface/jpcl_ctx_int.h b/org.glite.jp.client/interface/jpcl_ctx_int.h deleted file mode 100644 index d22f29b..0000000 --- a/org.glite.jp.client/interface/jpcl_ctx_int.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef __GLITE_JPCLIENT_CONTEXT_INT -#define __GLITE_JPCLIENT_CONTEXT_INT - -#ifdef __cplusplus -extern "C" { -#endif - -struct _glite_jpcl_context_t { - int errCode; - char *errDesc; - - char *jpps; - char *lbmd_dir; -}; - -extern int glite_jpcl_SetError(glite_jpcl_context_t, int, const char *); -extern int glite_jpcl_ResetError(glite_jpcl_context_t); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/org.glite.jp.client/interface/jpimporter.h b/org.glite.jp.client/interface/jpimporter.h deleted file mode 100644 index 3948ff0..0000000 --- a/org.glite.jp.client/interface/jpimporter.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef __GLITE_JPIMPORTER__ -#define __GLITE_JPIMPORTER__ - -#ifndef GLITE_REG_IMPORTER_MDIR -#define GLITE_REG_IMPORTER_MDIR "/var/glite/jpreg" -#endif - -#ifndef GLITE_DUMP_IMPORTER_MDIR -#define GLITE_DUMP_IMPORTER_MDIR "/var/glite/jpdump" -#endif - -#ifndef GLITE_SANDBOX_IMPORTER_MDIR -#define GLITE_SANDBOX_IMPORTER_MDIR "/var/glite/jpsandbox" -#endif - -#define PERF_JOBID_START_PREFIX "https://start.megajob/START-" -#define PERF_JOBID_STOP_PREFIX "https://stop.megajob/STOP-" -#define PERF_START_FILE "/tmp/jp_megajob_start" -#define PERF_STOP_FILE_FORMAT "/tmp/jp_megajob_%s" - -#ifdef __cplusplus -extern "C" { -#endif - -extern int glite_jpimporter_upload_files( - glite_jpcl_context_t ctx, - const char *jobid, - const char **files, - const char *proxy); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/org.glite.jp.client/project/ChangeLog b/org.glite.jp.client/project/ChangeLog deleted file mode 100644 index ecdcffd..0000000 --- a/org.glite.jp.client/project/ChangeLog +++ /dev/null @@ -1,6 +0,0 @@ -1.3.0-1 -- Initial Release - -1.3.0-2 -- configure updated - diff --git a/org.glite.jp.client/project/build.number b/org.glite.jp.client/project/build.number deleted file mode 100644 index 39605c5..0000000 --- a/org.glite.jp.client/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Thu Dec 15 09:23:26 CET 2005 -module.build=0 diff --git a/org.glite.jp.client/project/build.properties b/org.glite.jp.client/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp.client/project/configure.properties.xml b/org.glite.jp.client/project/configure.properties.xml deleted file mode 100644 index b475ce3..0000000 --- a/org.glite.jp.client/project/configure.properties.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - -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} -gsoap_version=${ext.gsoap.version} -mysql_prefix=${with.mysql.prefix} -mysql_version=${ext.mysql.version} -libtar=${with.libtar.prefix} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -cppunit=${with.cppunit.prefix} -jpproject=${subsystem.project.dir} -project=${component.project.dir} - - - diff --git a/org.glite.jp.client/project/properties.xml b/org.glite.jp.client/project/properties.xml deleted file mode 100755 index e2a32d0..0000000 --- a/org.glite.jp.client/project/properties.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.client/project/tar_exclude b/org.glite.jp.client/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.jp.client/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.jp.client/project/version.properties b/org.glite.jp.client/project/version.properties deleted file mode 100644 index c23c2eb..0000000 --- a/org.glite.jp.client/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# $Header$ -module.version=1.3.0 -module.age=2 diff --git a/org.glite.jp.client/src/jpcl_ctx.c b/org.glite.jp.client/src/jpcl_ctx.c deleted file mode 100644 index ecac72a..0000000 --- a/org.glite.jp.client/src/jpcl_ctx.c +++ /dev/null @@ -1,93 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include - -#include "jp_client.h" -#include "jpcl_ctx_int.h" -#include "jpimporter.h" - - -int glite_jpcl_InitContext(glite_jpcl_context_t *ctx) -{ - glite_jpcl_context_t out = (glite_jpcl_context_t) malloc(sizeof(*out)); - if (!out) return ENOMEM; - memset(out, 0, sizeof(*out)); - assert(out->errDesc == NULL); - - *ctx = out; - return 0; -} - -void glite_jpcl_FreeContext(glite_jpcl_context_t ctx) -{ - free(ctx->jpps); - free(ctx->lbmd_dir); -} - -int glite_jpcl_SetParam(glite_jpcl_context_t ctx, int param, ...) -{ - va_list ap; - - va_start(ap, param); - switch ( param ) { - case GLITE_JPCL_PARAM_JPPS: - if ( ctx->jpps ) free(ctx->jpps); - ctx->jpps = va_arg(ap, char *); - ctx->jpps = strdup(ctx->jpps); - break; - case GLITE_JPCL_PARAM_LBMAILDIR: - if ( ctx->lbmd_dir ) free(ctx->lbmd_dir); - ctx->lbmd_dir = strdup(va_arg(ap, char *)); - break; - default: - return glite_jpcl_SetError(ctx, EINVAL, "unknown parameter"); - } - - return 0; -} - -int glite_jpcl_Error( glite_jpcl_context_t ctx, char **errt, char **errd) -{ - if ( errt ) *errt = strdup(strerror(ctx->errCode)); - if ( errd ) *errd = (ctx->errDesc)? strdup(ctx->errDesc): NULL; - return ctx->errCode; -} - -int glite_jpcl_SetError(glite_jpcl_context_t ctx, int code, const char *desc) -{ - glite_jpcl_ResetError(ctx); - if ( code ) { - ctx->errCode = code; - if ( desc ) ctx->errDesc = (char *) strdup(desc); - } - - return ctx->errCode; -} - -int glite_jpcl_ResetError(glite_jpcl_context_t ctx) -{ - if ( ctx->errDesc ) free(ctx->errDesc); - ctx->errDesc = NULL; - ctx->errCode = 0; - - return ctx->errCode; -} diff --git a/org.glite.jp.client/src/jpimp_lib.c b/org.glite.jp.client/src/jpimp_lib.c deleted file mode 100644 index d4986b7..0000000 --- a/org.glite.jp.client/src/jpimp_lib.c +++ /dev/null @@ -1,134 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define COMPILE_WITH_LIBTAR -#ifdef COMPILE_WITH_LIBTAR -# include -#endif - -#include "glite/lbu/maildir.h" - -#include "jp_client.h" -#include "jpimporter.h" -#include "jpcl_ctx_int.h" - -#define TEMP_FILE_PREFIX "/tmp/jpimporter" - -int glite_jpimporter_upload_files( - glite_jpcl_context_t ctx, - const char *jobid, - const char **files, - const char *proxy) -{ -#ifdef COMPILE_WITH_LIBTAR - TAR *t = NULL; -#endif - char *msg = NULL, - *errs = NULL; - char archive[PATH_MAX]; - int fd = -1, - rv = 0, - i; - - - assert((files != NULL) && (files[0] != NULL)); - assert(jobid != NULL); - /* TODO: get the user proxy if it is not specified and find its location */ - assert(proxy != NULL); - - if ( glite_lbu_MaildirInit(ctx->lbmd_dir) ) { - asprintf(&errs, "glite_lbu_MaildirInit(): %s", lbm_errdesc); - glite_jpcl_SetError(ctx, errno, errs); - free(errs); - return -1; - } - - i = 0; - do { - if ( ++i > 10 ) { - glite_jpcl_SetError(ctx, ECANCELED, "Can't create temporary tar file"); - return -1; - } - snprintf(archive, PATH_MAX, "%s_%d_%ld.tar", - TEMP_FILE_PREFIX, getpid(), time(NULL)); - if ( (fd = open(archive, O_CREAT|O_EXCL|O_WRONLY, 00600)) < 0 ) { - if ( errno == EEXIST ) { sleep(2); continue; } - asprintf(&errs, "Can't create tar file %s", archive); - glite_jpcl_SetError(ctx, ECANCELED, errs); - free(errs); - return -1; - } - } while ( fd < 0 ); - -#ifdef COMPILE_WITH_LIBTAR - if ( tar_fdopen(&t, fd, archive, NULL, O_WRONLY, 0, TAR_GNU) < 0 ) { - asprintf(&errs, "Can't create tar archive %s", archive); - glite_jpcl_SetError(ctx, errno, errs); - rv = -1; - goto cleanup; - } - - for ( i = 0; files[i]; i++ ) { - char *s = (char *)files[i]; - if ( tar_append_file(t, s, (s[0]=='/')? s+1: s) < 0 ) { - asprintf(&errs, "Can't append file into tar archive %s", archive); - glite_jpcl_SetError(ctx, errno, errs); - rv = -1; - goto cleanup; - } - } -#endif - - if ( ctx->jpps ) - asprintf(&msg, "jobid\t%s\nfile\t%s\nproxy\t%s\njpps\t%s\n", - jobid, archive, proxy, ctx->jpps); - else - asprintf(&msg, "jobid\t%s\nfile\t%s\nproxy\t%s\n", - jobid, archive, proxy); - - if ( glite_lbu_MaildirStoreMsg(ctx->lbmd_dir, "localhost", msg) ) { - asprintf(&errs, "glite_lbu_MaildirStoreMsg(): %s", lbm_errdesc); - glite_jpcl_SetError(ctx, errno, errs); - rv = -1; - goto cleanup; - } - - -cleanup: -#ifdef COMPILE_WITH_LIBTAR - if ( t ) tar_close(t); - else close(fd); -#else - close(fd); -#endif - if ( rv ) unlink(archive); - free(errs); - free(msg); - - return rv; -} diff --git a/org.glite.jp.client/src/jpimporter.c b/org.glite.jp.client/src/jpimporter.c deleted file mode 100644 index 961abe7..0000000 --- a/org.glite.jp.client/src/jpimporter.c +++ /dev/null @@ -1,1070 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "glite/lbu/maildir.h" - -#include "jpps_H.h" -#include "jpps_.nsmap" - -#include "jptype_map.h" -#include "glite/security/glite_gsplugin.h" -#include "glite/security/glite_gscompat.h" -#include "glite/jp/known_attr.h" - -#include "globus_ftp_client.h" -#include "jp_client.h" -#include "jpimporter.h" - -#if GSOAP_VERSION <= 20602 -#define soap_call___jpsrv__RegisterJob soap_call___ns1__RegisterJob -#endif - - -typedef struct { - char *key; - char *val; -} msg_pattern_t; - -#ifndef dprintf -#define dprintf(FMT, ARGS...) { if (debug) printf(FMT, ##ARGS); } -#endif - -#define check_soap_fault(SOAP, ERR) glite_jp_clientCheckFault((SOAP), (ERR), name, 1) - -#ifndef GLITE_JPIMPORTER_PIDFILE -#define GLITE_JPIMPORTER_PIDFILE "/var/run/glite-jpimporter.pid" -#endif - -#ifndef GLITE_JPPS -#define GLITE_JPPS "http://localhost:8901" -#endif - -#define MAX_REG_CONNS 500 -#define JPPS_NO_RESPONSE_TIMEOUT 120 -#define JPREG_REPEAT_TIMEOUT 300 -#define JPREG_GIVUP_TIMEOUT 3000 -#define JP_REPEAT_TIMEOUT 360 -#define JP_GIVUP_TIMEOUT 3600 -#define PID_POOL_SIZE 20 -#define DEFAULT_DUMP_SLAVES_NUMBER 1 - - -static int debug = 0; -static int die = 0; -static int child_died = 0; -static int poll = 2; -static char *name; -static char *jpps = GLITE_JPPS; -static char reg_mdir[PATH_MAX] = GLITE_REG_IMPORTER_MDIR; -static char dump_mdir[PATH_MAX] = GLITE_DUMP_IMPORTER_MDIR; -static char sandbox_mdir[PATH_MAX] = GLITE_SANDBOX_IMPORTER_MDIR; -static char *store = NULL; -static struct soap *soap; - -static time_t cert_mtime = 0; -static char *server_cert = NULL, - *server_key = NULL, - *cadir = NULL; -static edg_wll_GssCred mycred = NULL; -#ifdef JP_PERF -typedef struct { - char *id, *name; - long int count, limit; - double start, end; -} perf_t; - -int sink = 0; -perf_t perf = {name:NULL,}; -#endif -static int gftp_initialized = 0; -static globus_ftp_client_handle_t hnd; - - -static struct option opts[] = { - { "help", 0, NULL, 'h'}, - { "cert", 1, NULL, 'c'}, - { "key", 1, NULL, 'k'}, - { "CAdir", 1, NULL, 'C'}, - { "debug", 0, NULL, 'g'}, - { "jpps", 1, NULL, 'p'}, - { "reg-mdir", 1, NULL, 'r'}, - { "dump-mdir", 1, NULL, 'd'}, - { "dump-slaves", 1, NULL, 'D'}, - { "sandbox-mdir",1, NULL, 's'}, - { "pidfile", 1, NULL, 'i'}, - { "poll", 1, NULL, 't'}, - { "store", 1, NULL, 'S'}, - { "store", 1, NULL, 'S'}, -#ifdef JP_PERF - { "perf-sink", 1, NULL, 'K'}, -#endif - { NULL, 0, NULL, 0} -}; - -static const char *get_opt_string = "hgp:r:d:D:s:i:t:c:k:C:" -#ifdef JP_PERF - "K:" -#endif -; - -#include "glite/jp/ws_fault.c" - -#ifdef JP_PERF -static void stats_init(perf_t *perf, const char *name); -static void stats_set_jobid(perf_t *perf, const char *jobid); -static void stats_get_limit(perf_t *perf, const char *name); -static void stats_done(perf_t *perf); -#endif - -static void usage(char *me) -{ - fprintf(stderr,"usage: %s [option]\n" - "\t-h, --help displays this screen\n" - "\t-k, --key private key file\n" - "\t-c, --cert certificate file\n" - "\t-C, --CAdir trusted certificates directory\n" - "\t-g, --debug don't run as daemon, additional diagnostics\n" - "\t-p, --jpps JP primary service server\n" - "\t-r, --reg-mdir path to the 'LB maildir' subtree for registrations\n" - "\t-d, --dump-mdir path to the 'LB maildir' subtree for LB dumps\n" - "\t-D, --dump-slaves number of slaves processing LB dumps\n" - "\t-s, --sandbox-mdir path to the 'LB maildir' subtree for input/output sandboxes\n" - "\t-i, --pidfile file to store master pid\n" - "\t-t, --poll maildir polling interval (in seconds)\n" - "\t-S, --store keep uploaded jobs in this directory\n" -#ifdef JP_PERF - "\t-K, --perf-sink 1=stats, 2=without WS calls, 3=stats+without WS\n" -#endif - , me); -} - -static void catchsig(int sig) -{ - die = sig; -} - -static void catch_chld(int sig __attribute__((unused))) -{ - child_died = 1; -} - - -static int slave(int (*)(void), const char *); -static int reg_importer(void); -static int dump_importer(void); -static int sandbox_importer(void); -static int parse_msg(char *, msg_pattern_t []); -static int gftp_put_file(const char *, int); -static int refresh_connection(struct soap *soap); - - -int main(int argc, char *argv[]) -{ - edg_wll_GssStatus gss_code; - struct sigaction sa; - sigset_t sset; - FILE *fpid; - pid_t reg_pid, sandbox_pid; - pid_t dump_pids[PID_POOL_SIZE]; - int dump_slaves = DEFAULT_DUMP_SLAVES_NUMBER, i; - int opt; - char *name, - pidfile[PATH_MAX] = GLITE_JPIMPORTER_PIDFILE; - glite_gsplugin_Context plugin_ctx; - - name = strrchr(argv[0],'/'); - if (name) name++; else name = argv[0]; - - if ( geteuid() ) - snprintf(pidfile, sizeof pidfile, "%s/glite_jpimporter.pid", getenv("HOME")); - - while ( (opt = getopt_long(argc, argv, get_opt_string, opts, NULL)) != EOF ) - switch ( opt ) { - case 'g': debug = 1; break; - case 'h': usage(name); return 0; - case 'c': server_cert = optarg; break; - case 'k': server_key = optarg; break; - case 'C': cadir = optarg; break; - case 'p': jpps = optarg; break; - case 't': poll = atoi(optarg); break; - case 'S': store = optarg; break; - case 'r': strcpy(reg_mdir, optarg); break; - case 'd': strcpy(dump_mdir, optarg); break; - case 'D': dump_slaves = atoi(optarg); break; - case 's': strcpy(sandbox_mdir, optarg); break; - case 'i': strcpy(pidfile, optarg); break; -#ifdef JP_PERF - case 'K': sink = atoi(optarg); break; -#endif - case '?': usage(name); return 1; - } - if ( optind < argc ) { usage(name); return 1; } - - if (dump_slaves > PID_POOL_SIZE) { - fprintf(stderr,"Maximum number of dump slaves is %d\n", PID_POOL_SIZE); - return(1); - } - - memset(&dump_pids,0,sizeof(dump_pids)); - - setlinebuf(stdout); - setlinebuf(stderr); - - fpid = fopen(pidfile,"r"); - if ( fpid ) { - int opid = -1; - - if ( fscanf(fpid,"%d",&opid) == 1 ) { - if ( !kill(opid,0) ) { - fprintf(stderr,"%s: another instance running, pid = %d\n",argv[0],opid); - return 1; - } - else if (errno != ESRCH) { perror("kill()"); return 1; } - } - fclose(fpid); - } else if (errno != ENOENT) { perror(pidfile); return 1; } - fpid = fopen(pidfile, "w"); - if ( !fpid ) { perror(pidfile); return 1; } - fprintf(fpid, "%d", getpid()); - fclose(fpid); - - glite_lbu_MaildirInit(reg_mdir); - glite_lbu_MaildirInit(dump_mdir); - glite_lbu_MaildirInit(sandbox_mdir); - if (store && *store) { - if (mkdir(store, 0750) != 0 && errno != EEXIST) { - fprintf(stderr, "Can't create directory %s: %s\n", store, strerror(errno)); - store = NULL; - } - } - - if ( !debug ) { - if ( daemon(1,0) == -1 ) { perror("deamon()"); exit(1); } - - fpid = fopen(pidfile,"w"); - if ( !fpid ) { perror(pidfile); return 1; } - fprintf(fpid, "%d", getpid()); - fclose(fpid); - openlog(name, LOG_PID, LOG_DAEMON); - } else { setpgid(0, getpid()); } - - dprintf("Master pid %d\n", getpid()); - - if ( globus_module_activate(GLOBUS_FTP_CLIENT_MODULE) != GLOBUS_SUCCESS ) { - dprintf("[master] Could not activate ftp client module\n"); - if (!debug) syslog(LOG_INFO, "Could not activate ftp client module\n"); - exit(1); - } else dprintf("[master] Ftp client module activated\n"); - - if ( !server_cert || !server_key ) - fprintf(stderr, "%s: key or certificate file not specified" - " - unable to watch them for changes!\n", argv[0]); - if ( cadir ) setenv("X509_CERT_DIR", cadir, 1); - edg_wll_gss_watch_creds(server_cert, &cert_mtime); - if ( !edg_wll_gss_acquire_cred_gsi(server_cert, server_key, &mycred, &gss_code) ) { - dprintf("[master] Server identity: %s\n", mycred->name); - } else { - char *errmsg; - edg_wll_gss_get_error(&gss_code, "edg_wll_gss_acquire_cred_gsi()", &errmsg); - dprintf("[master] %s\n", errmsg); - free(errmsg); - dprintf("[master] Running unauthenticated\n"); - } - - memset(&sa, 0, sizeof(sa)); assert(sa.sa_handler == NULL); - sa.sa_handler = catchsig; - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); - - sa.sa_handler = catch_chld; - sigaction(SIGCHLD, &sa, NULL); - - sa.sa_handler = SIG_IGN; - sigaction(SIGUSR1, &sa, NULL); - - sigemptyset(&sset); - sigaddset(&sset, SIGCHLD); - sigaddset(&sset, SIGTERM); - sigaddset(&sset, SIGINT); - sigprocmask(SIG_BLOCK, &sset, NULL); - - soap = calloc(1, sizeof *soap); - soap_init2(soap, SOAP_IO_KEEPALIVE, SOAP_IO_KEEPALIVE); - soap_set_omode(soap, SOAP_IO_BUFFER); - soap_set_namespaces(soap, jpps__namespaces); - - glite_gsplugin_init_context(&plugin_ctx); - glite_gsplugin_use_credential(plugin_ctx, mycred); - soap_register_plugin_arg(soap, glite_gsplugin,plugin_ctx); - - if ( (reg_pid = slave(reg_importer, "reg-imp")) < 0 ) { - perror("starting reg importer slave"); - exit(1); - } - for (i=0; i < dump_slaves; i++) { - if ( (dump_pids[i] = slave(dump_importer, "dump-imp")) < 0 ) { - perror("starting dump importer slave"); - exit(1); - } - } - if ( (sandbox_pid = slave(sandbox_importer, "sandbox-imp")) < 0 ) { - perror("starting sandbox importer slave"); - exit(1); - } - - while ( !die ) { - - sigprocmask(SIG_UNBLOCK, &sset, NULL); - sleep(5); - sigprocmask(SIG_BLOCK, &sset, NULL); - - if ( child_died ) { - int pid; - - while ( (pid = waitpid(-1, NULL, WNOHANG)) > 0 ) { - if ( !die ) { - if ( pid == reg_pid ) { - dprintf("[master] reg importer slave died [%d]\n", pid); - if (!debug) syslog(LOG_INFO, "reg importer slave died [%d]\n", die); - if ( (reg_pid = slave(reg_importer, "reg-imp")) < 0 ) { - perror("starting reg importer slave"); - kill(0, SIGINT); - exit(1); - } - dprintf("[master] reg importer slave restarted [%d]\n", reg_pid); - } else if ( pid == sandbox_pid ) { - dprintf("[master] sandbox importer slave died [%d]\n", pid); - if (!debug) syslog(LOG_INFO, "sandbox importer slave died [%d]\n", die); - if ( (sandbox_pid = slave(sandbox_importer, "sandbox-imp")) < 0 ) { - perror("starting sandbox importer slave"); - kill(0, SIGINT); - exit(1); - } - dprintf("[master] sandbox importer slave restarted [%d]\n", sandbox_pid); - } else /* must be in dump_pids */ { - dprintf("[master] dump importer slave died [%d]\n", pid); - if (!debug) syslog(LOG_INFO, "dump importer slave died [%d]\n", die); - for (i=0; (i < dump_slaves) && (pid != dump_pids[i]); i++); - assert(i < dump_slaves); // pid should be in pool - - if ( (dump_pids[i] = slave(dump_importer, "dump-imp")) < 0 ) { - perror("starting dump importer slave"); - kill(0, SIGINT); - exit(1); - } - dprintf("[master] dump importer slave restarted [%d]\n", dump_pids[i]); - - } - - } - } - child_died = 0; - continue; - } - } - - dprintf("[master] Terminating on signal %d\n", die); - if (!debug) syslog(LOG_INFO, "Terminating on signal %d\n", die); - kill(0, die); - - globus_module_deactivate_all(); - unlink(pidfile); - - return 0; -} - -static int slave(int (*fn)(void), const char *nm) -{ - struct sigaction sa; - sigset_t sset; - int pid, - conn_cnt = 0; - - - if ( (pid = fork()) ) return pid; - - asprintf(&name,"%s %d",nm,getpid()); - memset(&sa, 0, sizeof(sa)); assert(sa.sa_handler == NULL); - sa.sa_handler = catchsig; - sigaction(SIGUSR1, &sa, NULL); - - sigemptyset(&sset); - sigaddset(&sset, SIGTERM); - sigaddset(&sset, SIGINT); - sigaddset(&sset, SIGUSR1); - sigprocmask(SIG_BLOCK, &sset, NULL); - - dprintf("[%s] slave started - pid [%d]\n", name, getpid()); - -#ifdef JP_PERF - while ( !die && (conn_cnt < MAX_REG_CONNS || (sink & 1)) ) { -#else - while ( !die && (conn_cnt < MAX_REG_CONNS) ) { -#endif - int ret = fn(); - - if ( ret > 0 ) conn_cnt++; - else if ( ret < 0 ) exit(1); - else if ( ret == 0 ) { - sigprocmask(SIG_UNBLOCK, &sset, NULL); - sleep(poll); - sigprocmask(SIG_BLOCK, &sset, NULL); - } - } - - if ( die ) { - dprintf("[%s] %d: Terminating on signal %d\n", name, getpid(), die); - if ( !debug ) syslog(LOG_INFO, "Terminating on signal %d", die); - } - dprintf("[%s] Terminating after %d connections\n", name, conn_cnt); - if ( !debug ) syslog(LOG_INFO, "Terminating after %d connections", conn_cnt); - - if (gftp_initialized--) - globus_ftp_client_handle_destroy(&hnd); - - exit(0); -} - - -static int reg_importer(void) -{ - struct _jpelem__RegisterJob in; - struct _jpelem__RegisterJobResponse empty; - int ret; - static int readnew = 1; - char *msg = NULL, - *fname = NULL, - *aux; - - if ( readnew ) ret = glite_lbu_MaildirTransStart(reg_mdir, &msg, &fname); - else ret = glite_lbu_MaildirRetryTransStart(reg_mdir, (time_t)JPREG_REPEAT_TIMEOUT, (time_t)JPREG_GIVUP_TIMEOUT, &msg, &fname); - if ( !ret ) { - readnew = !readnew; - if ( readnew ) ret = glite_lbu_MaildirTransStart(reg_mdir, &msg, &fname); - else ret = glite_lbu_MaildirRetryTransStart(reg_mdir, (time_t)JPREG_REPEAT_TIMEOUT, (time_t)JPREG_GIVUP_TIMEOUT, &msg, &fname); - if ( !ret ) { - readnew = !readnew; - return 0; - } - } - - if ( ret < 0 ) { - dprintf("[%s] glite_lbu_MaildirTransStart: %s (%s)\n", name, strerror(errno), lbm_errdesc); - if ( !debug ) syslog(LOG_ERR, "glite_lbu_MaildirTransStart: %s (%s)", strerror(errno), lbm_errdesc); - return -1; - } else if ( ret > 0 ) { - dprintf("[%s] JP registration request received\n", name); - if ( !debug ) syslog(LOG_INFO, "JP registration request received\n"); - - ret = 0; - if ( !(aux = strchr(msg, '\n')) ) { - dprintf("[%s] Wrong format of message!\n", name); - if ( !debug ) syslog(LOG_ERR, "Wrong format of message\n"); - ret = 0; - } else do { - *aux++ = '\0'; - in.job = msg; - in.owner = aux; - dprintf("[%s] Registering '%s'\n", name, msg); - if ( !debug ) syslog(LOG_INFO, "Registering '%s'\n", msg); -#ifdef JP_PERF - if ((sink & 1)) { - if (strncasecmp(msg, PERF_JOBID_START_PREFIX, sizeof(PERF_JOBID_START_PREFIX) - 1) == 0) { - stats_init(&perf, name); - stats_set_jobid(&perf, msg); - } - if (perf.name && !perf.limit) stats_get_limit(&perf, name); - } - if (!(sink & 2)) { -#endif - refresh_connection(soap); - ret = soap_call___jpsrv__RegisterJob(soap, jpps, "", &in, &empty); - if ( (ret = check_soap_fault(soap, ret)) ) break; -#ifdef JP_PERF - } else ret = 0; - if (perf.name && ret == 0) { - perf.count++; - if (perf.limit) { - dprintf("[%s statistics] done %ld/%ld\n", name, perf.count, perf.limit); - if (perf.count >= perf.limit) stats_done(&perf); - } else - dprintf("[%s statistics] done %ld/no limit\n", name, perf.count); - } -#endif - } while (0); - glite_lbu_MaildirTransEnd(reg_mdir, fname, ret? LBMD_TRANS_FAILED_RETRY: LBMD_TRANS_OK); - free(fname); - free(msg); - return 1; - } - - return 0; -} - -static int dump_importer(void) -{ - struct _jpelem__StartUpload su_in; - struct _jpelem__StartUploadResponse su_out; - struct _jpelem__CommitUpload cu_in; - struct _jpelem__CommitUploadResponse empty; - struct _jpelem__RegisterJob rj_in; - struct _jpelem__RegisterJobResponse rj_empty; - struct _jpelem__GetJobAttributes gja_in; - struct _jpelem__GetJobAttributesResponse gja_out; - static int readnew = 1; - char *msg = NULL, - *fname = NULL, - *bname; - char fspec[PATH_MAX]; - int ret, retry_upload, jperrno; - int fhnd; - msg_pattern_t tab[] = { - {"jobid", NULL}, - {"file", NULL}, - {"jpps", NULL}, - {"proxy", NULL}, - {NULL, NULL}}; -#define _job 0 -#define _file 1 -#define _jpps 2 -#define _proxy 3 - - - if ( readnew ) ret = glite_lbu_MaildirTransStart(dump_mdir, &msg, &fname); - else ret = glite_lbu_MaildirRetryTransStart(dump_mdir, (time_t)JP_REPEAT_TIMEOUT, (time_t)JP_GIVUP_TIMEOUT, &msg, &fname); - if ( !ret ) { - readnew = !readnew; - if ( readnew ) ret = glite_lbu_MaildirTransStart(dump_mdir, &msg, &fname); - else ret = glite_lbu_MaildirRetryTransStart(dump_mdir, (time_t)JP_REPEAT_TIMEOUT, (time_t)JP_GIVUP_TIMEOUT, &msg, &fname); - if ( !ret ) { - readnew = !readnew; - return 0; - } - } - - if ( ret < 0 ) { - dprintf("[%s] glite_lbu_MaildirTransStart: %s (%s)\n", name, strerror(errno), lbm_errdesc); - if ( !debug ) syslog(LOG_ERR, "glite_lbu_MaildirTransStart: %s (%s)", strerror(errno), lbm_errdesc); - return -1; - } - - dprintf("[%s] dump JP import request received\n", name); - if ( !debug ) syslog(LOG_INFO, "dump JP import request received"); - - soap_begin(soap); - - ret = 0; - if ( parse_msg(msg, tab) < 0 ) { - dprintf("[%s] Wrong format of message!\n", name); - if ( !debug ) syslog(LOG_ERR, "Wrong format of message"); - ret = 0; - } else do { - su_in.job = tab[_job].val; - su_in.class_ = "urn:org.glite.jp.primary:lb"; - su_in.name = NULL; - su_in.commitBefore = 1000 + time(NULL); - su_in.contentType = "text/lb"; -#ifdef JP_PERF - if ((sink & 1)) { - /* statistics started by file, ended by count limit (from the appropriate result fikle) */ - FILE *f; - char item[200]; - - /* starter */ - if (!perf.name) { - f = fopen(PERF_START_FILE, "rt"); - if (f) { - stats_init(&perf, name); - fscanf(f, "%s", item); - fclose(f); - unlink(PERF_START_FILE); - stats_set_jobid(&perf, item); - } else - dprintf("[%s statistics]: not started/too much dumps: %s\n", name, strerror(errno)); - } - if (perf.name && !perf.limit) stats_get_limit(&perf, name); - } - if (!(sink & 2)) { -#endif - retry_upload = 2; - do { - dprintf("[%s] Importing LB dump file '%s'\n", name, tab[_file].val); - if ( !debug ) syslog(LOG_INFO, "Importing LB dump file '%s'\n", msg); - refresh_connection(soap); - ret = soap_call___jpsrv__StartUpload(soap, tab[_jpps].val?:jpps, "", &su_in, &su_out); - if ( (ret = check_soap_fault(soap, ret)) ) { - /* unsuccessful dump, register job */ - refresh_connection(soap); - /* check job existence */ - memset(&gja_in, 0, sizeof gja_in); - memset(&gja_out, 0, sizeof gja_out); - gja_in.jobid = su_in.job; - gja_in.attributes = soap_malloc(soap, sizeof(char *)); - gja_in.__sizeattributes = 1; - gja_in.attributes[0] = GLITE_JP_ATTR_REGTIME; - ret = soap_call___jpsrv__GetJobAttributes(soap, jpps, "", &gja_in, &gja_out); - jperrno = glite_jp_clientGetErrno(soap, ret); - gja_in.attributes[0] = NULL; - /* no error ==> some application fault from JP */ - if (jperrno == 0) { - dprintf("[%s] Dump failed when job %s exists\n", name, su_in.job); - ret = -1; - break; - } - /* other then "job not found" error ==> other problem, don't register */ - if (jperrno != ENOENT && jperrno != -2) { - ret = check_soap_fault(soap, ret); - break; - } - /* "job not found" error ==> register job */ - refresh_connection(soap); - rj_in.job = su_in.job; - rj_in.owner = mycred->name; - dprintf("[%s] Failsafe registration\n", name); - dprintf("[%s] \tjobid: %s\n[%s] \towner: %s\n", name, rj_in.job, name, rj_in.owner); - if ( !debug ) syslog(LOG_INFO, "Failsafe registration '%s'\n",rj_in.job); - ret = soap_call___jpsrv__RegisterJob(soap, tab[_jpps].val?:jpps, "", &rj_in, &rj_empty); - if ( (ret = check_soap_fault(soap, ret)) ) break; - retry_upload--; - ret = 1; - } - } while (ret != 0 && retry_upload > 0); - if (ret) break; - dprintf("[%s] Destination: %s\n\tCommit before: %s\n", name, su_out.destination, ctime(&su_out.commitBefore)); - if (su_out.destination == NULL) { - dprintf("[%s] StartUpload returned NULL destination\n", name); - if ( !debug ) syslog(LOG_ERR, "StartUpload returned NULL destination"); - ret = 1; - break; - } - - if ( (fhnd = open(tab[_file].val, O_RDONLY)) < 0 ) { - dprintf("[%s] Can't open dump file: %s\n", name, tab[_file].val); - if ( !debug ) syslog(LOG_ERR, "Can't open dump file: %s", tab[_file].val); - ret = 1; - break; - } - if ( (ret = gftp_put_file(su_out.destination, fhnd)) ) break; - close(fhnd); - dprintf("[%s] File sent, commiting the upload\n", name); - cu_in.destination = su_out.destination; - refresh_connection(soap); - ret = soap_call___jpsrv__CommitUpload(soap, tab[_jpps].val?:jpps, "", &cu_in, &empty); - if ( (ret = check_soap_fault(soap, ret)) ) break; - dprintf("[%s] Dump upload succesfull\n", name); -#ifdef JP_PERF - } else ret = 0; - if (perf.name && ret == 0) { - perf.count++; - if (perf.limit) { - dprintf("[%s statistics] done %ld/%ld\n", name, perf.count, perf.limit); - if (perf.count >= perf.limit) stats_done(&perf); - } else - dprintf("[%s statistics] done %ld/no limit\n", name, perf.count); - } -#endif - if (store && *store) { - bname = strdup(tab[_file].val); - snprintf(fspec, sizeof fspec, "%s/%s", store, basename(bname)); - free(bname); - if (rename(tab[_file].val, fspec) != 0) - fprintf(stderr, "moving %s to %s failed: %s\n", tab[_file].val, fspec, strerror(errno)); - else - dprintf("[%s] moving %s to %s OK\n", name, tab[_file].val, fspec); - } else { - if (unlink(tab[_file].val) != 0) - fprintf(stderr, "removing %s failed: %s\n", tab[_file].val, strerror(errno)); - else - dprintf("[%s] %s removed\n", name, tab[_file].val); - } - } while (0); - soap_end(soap); - - glite_lbu_MaildirTransEnd(dump_mdir, fname, ret? LBMD_TRANS_FAILED_RETRY: LBMD_TRANS_OK); - free(fname); - free(msg); - - return 1; -} - - -static int sandbox_importer(void) -{ - struct _jpelem__StartUpload su_in; - struct _jpelem__StartUploadResponse su_out; - struct _jpelem__CommitUpload cu_in; - struct _jpelem__CommitUploadResponse empty; - static int readnew = 1; - char *msg = NULL, - *fname = NULL; - int ret; - int fhnd; - msg_pattern_t tab[] = { - {"jobid", NULL}, - {"file", NULL}, - {"jpps", NULL}, - {"proxy", NULL}, - {NULL, NULL}}; - -#define _job 0 -#define _file 1 -#define _jpps 2 -#define _proxy 3 - - - if ( readnew ) ret = glite_lbu_MaildirTransStart(sandbox_mdir, &msg, &fname); - else ret = glite_lbu_MaildirRetryTransStart(sandbox_mdir, (time_t)JP_REPEAT_TIMEOUT, (time_t)JP_GIVUP_TIMEOUT ,&msg, &fname); - if ( !ret ) { - readnew = !readnew; - if ( readnew ) ret = glite_lbu_MaildirTransStart(sandbox_mdir, &msg, &fname); - else ret = glite_lbu_MaildirRetryTransStart(sandbox_mdir, (time_t)JP_REPEAT_TIMEOUT, (time_t)JP_GIVUP_TIMEOUT ,&msg, &fname); - if ( !ret ) { - readnew = !readnew; - return 0; - } - } - - if ( ret < 0 ) { - dprintf("[%s] glite_lbu_MaildirTransStart: %s (%s)\n", name, strerror(errno), lbm_errdesc); - if ( !debug ) syslog(LOG_ERR, "glite_lbu_MaildirTransStart: %s (%s)", strerror(errno), lbm_errdesc); - return -1; - } - - dprintf("[%s] sandbox JP import request received\n", name); - if ( !debug ) syslog(LOG_INFO, "sandbox JP import request received"); - - ret = 0; - if ( parse_msg(msg, tab) < 0 ) { - dprintf("[%s] Wrong format of message!\n", name); - if ( !debug ) syslog(LOG_ERR, "Wrong format of message"); - ret = 0; - } else do { - su_in.job = tab[_job].val; - // XXX: defined in org.glite.jp.primary/src/builtin_plugins.h - // shloud use symbolic const... - // do not distinquish between ibs and obs now - su_in.class_ = "urn:org.glite.jp.primary:isb"; - su_in.name = NULL; - su_in.commitBefore = 1000 + time(NULL); - su_in.contentType = "tar/lb"; - dprintf("[%s] Importing LB sandbox tar file '%s'\n", name, tab[_file].val); - if ( !debug ) syslog(LOG_INFO, "Importing LB sandbox tar file '%s'\n", msg); -#ifdef JP_PERF - if (!(sink & 2)) { -#endif - refresh_connection(soap); - ret = soap_call___jpsrv__StartUpload(soap, tab[_jpps].val?:jpps, "", &su_in, &su_out); - ret = check_soap_fault(soap, ret); - /* XXX: grrrrrrr! test it!!!*/ -// if ( (ret = check_soap_fault(soap, ret)) ) break; - dprintf("[%s] Destination: %s\n\tCommit before: %s\n", name, su_out.destination, ctime(&su_out.commitBefore)); - - if ( (fhnd = open(tab[_file].val, O_RDONLY)) < 0 ) { - dprintf("[%s] Can't open sandbox tar file: %s\n", name, tab[_file].val); - if ( !debug ) syslog(LOG_ERR, "Can't open sandbox tar file: %s", tab[_file].val); - ret = 1; - break; - } - if ( (ret = gftp_put_file(su_out.destination, fhnd)) ) break; - close(fhnd); - dprintf("[%s] File sent, commiting the upload\n", name); - cu_in.destination = su_out.destination; - refresh_connection(soap); - ret = soap_call___jpsrv__CommitUpload(soap, tab[_jpps].val?:jpps, "", &cu_in, &empty); - if ( (ret = check_soap_fault(soap, ret)) ) break; - dprintf("[%s] Dump upload succesfull\n", name); -#ifdef JP_PERF - } else ret = 0; -#endif - } while (0); - - glite_lbu_MaildirTransEnd(sandbox_mdir, fname, ret? LBMD_TRANS_FAILED_RETRY: LBMD_TRANS_OK); - free(fname); - free(msg); - - return 1; -} - - -/** Parses every line looking for pattern string and stores the value into - * the given variable - * - * line format is: key[space(s)]+val - */ -int parse_msg(char *msg, msg_pattern_t tab[]) -{ - char *eol = msg, - *key, *val; - - while ( eol && *eol != '\0' ) { - int i; - - key = eol; - if ( (eol = strchr(key, '\n')) ) *eol++ = '\0'; - while ( isblank(*key) ) key++; - if ( *key == '\0' ) continue; - val = key; - while ( !isblank(*val) ) val++; - if ( *val == '\0' ) return -1; - *val++ = '\0'; - while ( isblank(*val) ) val++; - if ( *val == '\0' ) return -1; - - for ( i = 0; tab[i].key; i++ ) { - if ( !strcmp(tab[i].key, key) ) { - tab[i].val = val; - break; - } - } - } - - return 0; -} - - -#define BUFSZ 1024 - -static globus_mutex_t gLock; -static globus_cond_t gCond; -static globus_bool_t gDone; -static globus_bool_t gError = GLOBUS_FALSE; -static globus_byte_t gBuffer[BUFSZ]; -static int gOffset; - - -static void gftp_done_cb( - void *user_arg, - globus_ftp_client_handle_t *handle, - globus_object_t *err) -{ - if ( err != GLOBUS_SUCCESS ) { - char *tmp = globus_object_printable_to_string(err); - dprintf("[%s] Error in callback: %s\n", name, tmp); - if ( !debug ) syslog(LOG_ERR, "Error in callback: %s", tmp); - gError = GLOBUS_TRUE; - globus_libc_free(tmp); - } - globus_mutex_lock(&gLock); - gDone = GLOBUS_TRUE; - globus_cond_signal(&gCond); - globus_mutex_unlock(&gLock); -} - -static void gftp_data_cb( - void *user_arg, - globus_ftp_client_handle_t *handle, - globus_object_t *error, - globus_byte_t *buffer, - globus_size_t length, - globus_off_t offset, - globus_bool_t eof) -{ - if ( !eof ) { - int rc; - globus_mutex_lock(&gLock); - if ( (rc = read(*((int *)user_arg), gBuffer, BUFSZ)) < 0 ) { - dprintf("[%s] Error reading dump file\n", name); - if ( !debug ) syslog(LOG_ERR, "Error reading dump file"); - gDone = GLOBUS_TRUE; - gError = GLOBUS_TRUE; - globus_cond_signal(&gCond); - } else { - globus_ftp_client_register_write( - handle, gBuffer, rc, gOffset, rc == 0, gftp_data_cb, user_arg); - gOffset += rc; - } - globus_mutex_unlock(&gLock); - } -} - -static int gftp_put_file(const char *url, int fhnd) -{ - static globus_ftp_client_operationattr_t op_attr; - static globus_ftp_client_handleattr_t hnd_attr; - int gftp_retried = 0; - - globus_mutex_init(&gLock, GLOBUS_NULL); - globus_cond_init(&gCond, GLOBUS_NULL); - - /* one lost connection survival cycle */ - do { - - if (!gftp_initialized++) { -#define put_file_err(errs) { \ - dprintf("[%s] %s\n", name, errs); \ - if ( !debug ) syslog(LOG_ERR, errs); \ - return 1; \ -} - if ( globus_ftp_client_handleattr_init(&hnd_attr) != GLOBUS_SUCCESS ) - put_file_err("Could not initialise handle attributes"); - - if ( globus_ftp_client_handleattr_set_cache_all(&hnd_attr, GLOBUS_TRUE) != GLOBUS_SUCCESS) - put_file_err("Could not set connection caching"); - - if ( globus_ftp_client_operationattr_init(&op_attr) != GLOBUS_SUCCESS ) - put_file_err("Could not initialise operation attributes"); - - if ( globus_ftp_client_handle_init(&hnd, &hnd_attr) != GLOBUS_SUCCESS ) - put_file_err("Could not initialise ftp client handle"); - } - if ( globus_ftp_client_operationattr_set_authorization( - &op_attr, server_cert? mycred->gss_cred: GSS_C_NO_CREDENTIAL, - NULL, "", 0, NULL) != GLOBUS_SUCCESS ) - put_file_err("Could not set authorization procedure"); -#undef put_file_err - - gDone = GLOBUS_FALSE; - gError = GLOBUS_FALSE; - - /* do the op */ - if ( globus_ftp_client_put( - &hnd, url, &op_attr, - GLOBUS_NULL, gftp_done_cb, (void *)&fhnd) != GLOBUS_SUCCESS) { - dprintf("[%s] Could not start file put\n", name); - if ( !debug ) syslog(LOG_ERR, "Could not start file put"); - gError = GLOBUS_TRUE; - gDone = GLOBUS_TRUE; - } else { - int rc; - globus_mutex_lock(&gLock); - if ( (rc = read(fhnd, gBuffer, BUFSZ)) < 0 ) { - dprintf("[%s] Error reading dump file\n", name); - if ( !debug ) syslog(LOG_ERR, "Error reading dump file"); - gDone = GLOBUS_TRUE; - gError = GLOBUS_TRUE; - globus_cond_signal(&gCond); - } else { - globus_ftp_client_register_write(&hnd, - gBuffer, rc, gOffset, rc == 0, gftp_data_cb, (void *)&fhnd); - gOffset += rc; - } - globus_mutex_unlock(&gLock); - } - - globus_mutex_lock(&gLock); - while ( !gDone ) globus_cond_wait(&gCond, &gLock); - globus_mutex_unlock(&gLock); - - if (gError == GLOBUS_TRUE) { - gftp_retried++; - gftp_initialized = 0; - globus_ftp_client_handle_destroy(&hnd); - dprintf("[%s] %s: FTP upload failed\n", name, gftp_retried <= 1 ? "Warning" : "Error"); - } - } while (gError == GLOBUS_TRUE && gftp_retried <= 1); - - return (gError == GLOBUS_TRUE)? 1: 0; -} - - -static int refresh_connection(struct soap *soap) { - struct timeval to = {JPPS_NO_RESPONSE_TIMEOUT, 0}; - edg_wll_GssCred newcred; - edg_wll_GssStatus gss_code; - glite_gsplugin_Context gp_ctx; - - gp_ctx = glite_gsplugin_get_context(soap); - glite_gsplugin_set_timeout(gp_ctx, &to); - - switch ( edg_wll_gss_watch_creds(server_cert, &cert_mtime) ) { - case 0: break; - case 1: - if ( !edg_wll_gss_acquire_cred_gsi(server_cert, server_key, &newcred, &gss_code) ) { - dprintf("[%s] reloading credentials successful\n", name); - edg_wll_gss_release_cred(&mycred, &gss_code); - mycred = newcred; - glite_gsplugin_use_credential(gp_ctx, newcred); - } else { dprintf("[%s] reloading credentials failed, using old ones\n", name); } - break; - case -1: dprintf("[%s] edg_wll_gss_watch_creds failed\n", name); break; - } - - return 0; -} - - -#ifdef JP_PERF -static void stats_init(perf_t *perf, const char *name) { - struct timeval tv; - - memset(perf, 0, sizeof *perf); - perf->count = 0; - perf->name = strdup(name); - gettimeofday(&tv, NULL); - perf->start = tv.tv_sec + (double)tv.tv_usec / 1000000.0; - dprintf("[%s statistics] start detected\n", name); -} - -static void stats_set_jobid(perf_t *perf, const char *jobid) { - perf->id = strdup(jobid + sizeof(PERF_JOBID_START_PREFIX) - 1); - dprintf("[%s statistics] ID %s\n", perf->name, perf->id); -} - -static void stats_get_limit(perf_t *perf, const char *name) { - FILE *f; - char *fn, item[200]; - int count; - - /* stopper */ - asprintf(&fn, PERF_STOP_FILE_FORMAT, perf->id); - f = fopen(fn, "rt"); - free(fn); - if (f) { - fscanf(f, "%s\t%d", item, &count); - if (strcasecmp(item, name) != 0) fscanf(f, "%s\t%d", item, &count); - dprintf("[%s statistics] expected %d %s\n", name, count, item); - fclose(f); - perf->limit = count; - } -} - -static void stats_done(perf_t *perf) { - struct timeval tv; - - gettimeofday(&tv, NULL); - perf->end = tv.tv_sec + (double)tv.tv_usec / 1000000.0; - dprintf("[%s statistics] %s\n", perf->name, perf->id); - dprintf("[%s statistics] start: %lf\n", perf->name, perf->start); - dprintf("[%s statistics] stop: %lf\n", perf->name, perf->end); - dprintf("[%s statistics] count: %ld (%lf job/day)\n", perf->name, perf->count, 86400.0 * perf->count / (perf->end - perf->start)); - free(perf->id); - free(perf->name); - memset(perf, 0, sizeof *perf); -} -#endif - -/* XXX: we don't use it */ -SOAP_NMAC struct Namespace namespaces[] = { {NULL,NULL} }; - diff --git a/org.glite.jp.client/src/jptype_map.h b/org.glite.jp.client/src/jptype_map.h deleted file mode 100644 index ee64f9d..0000000 --- a/org.glite.jp.client/src/jptype_map.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "soap_version.h" - -#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 - diff --git a/org.glite.jp.client/src/typemap.dat b/org.glite.jp.client/src/typemap.dat deleted file mode 100644 index 72f515f..0000000 --- a/org.glite.jp.client/src/typemap.dat +++ /dev/null @@ -1,3 +0,0 @@ -jpsrv = http://glite.org/wsdl/services/jp -jptype = http://glite.org/wsdl/types/jp -jpelem = http://glite.org/wsdl/elements/jp diff --git a/org.glite.jp.common/.cvsignore b/org.glite.jp.common/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp.common/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp.common/Makefile b/org.glite.jp.common/Makefile deleted file mode 100644 index 62f05a3..0000000 --- a/org.glite.jp.common/Makefile +++ /dev/null @@ -1,90 +0,0 @@ -# defaults -top_srcdir=.. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -globalprefix=glite -jpprefix=jp -package=glite-jp-common -version=0.0.0 -PREFIX=/opt/glite - -globus_prefix=/opt/globus -nothrflavour=gcc32 -thrflavour=gcc32pthr -expat_prefix=/opt/expat -gsoap_prefix=/software/gsoap-2.6 - -CC=gcc - --include Makefile.inc - - -VPATH=${top_srcdir}/src:${top_srcdir}/test:${top_srcdir}/project:${jpproject} - -DEBUG:=-g -O0 -W -Wno-sign-compare -CFLAGS:=${DEBUG} -D_GNU_SOURCE -I. -I${top_srcdir}/interface -I${stagedir}/include - -offset=0 -version_info:=-version-info ${shell \ - perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } - - -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -rpath ${stagedir}/lib ${version_info} -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install -COMPILE:=libtool --mode=compile ${CC} ${CFLAGS} - -HDRS:=types.h context.h attr.h known_attr.h backend.h builtin_plugins.h file_plugin.h indexdb.h type_plugin.h - -SRCS:=context.c attr.c utils.c indexdb.c -OBJS:=${SRCS:.c=.lo} -THROBJS:=${OBJS:.o=.thr.lo} -LIBS:=-L${stagedir}/lib -lglite_jobid -lglite_lbu_db -THRLIBS:=${LIBS} - -commonlib:= libglite_jp_common_${nothrflavour}.la -commonlib_thr:= libglite_jp_common_${thrflavour}.la - -TEST_LIBS:=-L${cppunit}/lib -lcppunit -ldl -TEST_INC:=-I${cppunit}/include - - -default all: compile - -compile: ${commonlib} ${commonlib_thr} - -${commonlib}: ${OBJS} - ${LINK} -o $@ ${OBJS} ${LIBS} - -${commonlib_thr}: ${THROBJS} - ${LINK} -o $@ ${THROBJS} ${THRLIBS} - -check: type_test - ./type_test type_test.xml - -type_test: %: %.cpp compile - ${CXX} -c ${CFLAGS} ${TEST_INC} $< - ${LINKXX} -o $@ $@.o ${commonlib} ${TEST_LIBS} - -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} ${commonlib_thr} ${PREFIX}/lib - -clean: - rm -rvf *.o *.lo .libs lib* - rm -rvf log.xml project/ rpmbuild/ RPMS/ tgz/ - rm -f glite jp - -%.thr.lo: %.c - ${COMPILE} -o $@ -c $< - -%.lo: %.c - ${COMPILE} -o $@ -c $< diff --git a/org.glite.jp.common/build.xml b/org.glite.jp.common/build.xml deleted file mode 100755 index 6e50854..0000000 --- a/org.glite.jp.common/build.xml +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.common/interface/attr.h b/org.glite.jp.common/interface/attr.h deleted file mode 100644 index aa35d09..0000000 --- a/org.glite.jp.common/interface/attr.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_ATTR_H -#define GLITE_JP_ATTR_H - -#ifdef __cplusplus -extern "C" { -#endif - -void glite_jp_attrval_free(glite_jp_attrval_t *,int); -void glite_jp_attrval_copy(glite_jp_attrval_t *,const glite_jp_attrval_t *); - -/* Search through registered type plugins and call appropriate plugin method. - * See type_plugin.h for detailed description. - */ - -int glite_jp_attrval_cmp(glite_jp_context_t ctx,const glite_jp_attrval_t *a,const glite_jp_attrval_t *b,int *result); - -char *glite_jp_attrval_to_db_full(glite_jp_context_t ctx,const glite_jp_attrval_t *attr); -char *glite_jp_attrval_to_db_index(glite_jp_context_t ctx,const glite_jp_attrval_t *attr,int len); - -int glite_jp_attrval_from_db(glite_jp_context_t ctx,const char *str,glite_jp_attrval_t *attr); -const char *glite_jp_attrval_db_type_full(glite_jp_context_t ctx,const char *attr); -const char *glite_jp_attrval_db_type_index(glite_jp_context_t ctx,const char *attr,int len); - -time_t glite_jp_attr2time(const char *); -char * glite_jp_time2attr(time_t); - -#ifdef __cplusplus -}; -#endif - - -#endif /* GLITE_JP_ATTR_H */ diff --git a/org.glite.jp.common/interface/backend.h b/org.glite.jp.common/interface/backend.h deleted file mode 100644 index 47df2b5..0000000 --- a/org.glite.jp.common/interface/backend.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_BACKEND_H -#define GLITE_JP_BACKEND_H - -/* do we need it? -#include -#include -#include -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -int glite_jppsbe_get_names( - glite_jp_context_t ctx, - const char *job, - const char * /* class */, - char ***names_out -); - -int glite_jppsbe_destination_info( - glite_jp_context_t ctx, - const char *destination, - char **job_out, - char **class_out, - char **name_out -); - -int glite_jppsbe_get_job_url( - glite_jp_context_t ctx, - const char *job, - const char * /* class */, - const char *name, /* optional within class */ - char **url_out -); - -int glite_jppsbe_open_file( - glite_jp_context_t ctx, - const char *job, - const char * /* class */, - const char *name, /* optional within class */ - int mode, - void **handle_out -); - -int glite_jppsbe_close_file( - glite_jp_context_t ctx, - void *handle -); - -int glite_jppsbe_file_attrs( - glite_jp_context_t ctx, - void *handle, - struct stat *buf -); - -int glite_jppsbe_pread( - glite_jp_context_t ctx, - void *handle, - 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_is_metadata( - glite_jp_context_t ctx, - const char *attr -); - -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[], - char *attrs[], - void *arg, - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[], - void *arg - ) -); - -char* glite_jpps_get_namespace( - const char* attr -); - -#ifdef __cplusplus -}; -#endif - -#endif /* GLITE_JP_BACKEND_H */ - diff --git a/org.glite.jp.common/interface/builtin_plugins.h b/org.glite.jp.common/interface/builtin_plugins.h deleted file mode 100644 index a8b659d..0000000 --- a/org.glite.jp.common/interface/builtin_plugins.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#define GLITE_JP_FILETYPE_TAGS "urn:org.glite.jp.primary:tags" -#define GLITE_JP_FILETYPE_LB "urn:org.glite.jp.primary:lb" -#define GLITE_JP_FILETYPE_CLASSAD "urn:org.glite.jp.primary:classad" -#define GLITE_JP_FILETYPE_ISB "urn:org.glite.jp.primary:isb" -#define GLITE_JP_FILETYPE_OSB "urn:org.glite.jp.primary:osb" - -#define GLITE_JP_FPLUG_TAGS_APPEND 0 diff --git a/org.glite.jp.common/interface/context.h b/org.glite.jp.common/interface/context.h deleted file mode 100644 index ba702bc..0000000 --- a/org.glite.jp.common/interface/context.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_CONTEXT_H -#define GLITE_JP_CONTEXT_H - -#ifdef __cplusplus -extern "C" { -#endif - -int glite_jp_init_context(glite_jp_context_t *); -void glite_jp_free_context(glite_jp_context_t); -void glite_jp_free_query_rec(glite_jp_query_rec_t *); - -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); - - -#ifdef __cplusplus -}; -#endif - -#endif /* GLITE_JP_CONTEXT_H */ diff --git a/org.glite.jp.common/interface/file_plugin.h b/org.glite.jp.common/interface/file_plugin.h deleted file mode 100644 index 52f0a37..0000000 --- a/org.glite.jp.common/interface/file_plugin.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_FILEPLUGIN_H -#define GLITE_JP_FILEPLUGIN_H - -/** Methods of the file plugin. */ - -typedef struct _glite_jpps_fplug_op_t { - -/** Open a file. -\param[in] fpctx Context of the plugin, returned by its init. -\param[in] bhandle Handle of the file via JPPS backend. -\param[in] uri URI (type) of the opened file. -\param[out] handle Handle to the opened file structure, to be passed to other plugin functions. -*/ - int (*open)(void *fpctx,void *bhandle,const char *uri,void **handle); -/** Open from a string. -\param[in] fpctx Context of the plugin, returned by its init. -\param[in] str The string to use. -\param[in] uri URI (type) of the string -\param[in] ns namespace to handle -\param[out] handle Handle to the opened file structure, to be passed to other plugin functions. -*/ - - int (*open_str)(void *fpctx,const char *str,const char *uri,const char *ns,void **handle); - -/** Close the file. Free data associated to a handle */ - int (*close)(void *fpctx,void *handle); - -/** "Preprocess" the file -- this function is called once after the file is commited */ - int (*filecom)(void *fpctx,void *handle); - -/** Retrieve value(s) of an attribute. -\param[in] fpctx Plugin context. -\param[in] handle Handle of the opened file. -\param[in] ns Namespace of queried attribute. -\param[in] attr Queried attribute. -\param[out] attrval GLITE_JP_ATTR_UNDEF-terminated list of value(s) of the attribute. - If there are more and there is an interpretation of their order - they must be sorted, eg. current value of tag is the last one. -\retval 0 success -\retval ENOSYS this attribute is not defined by this type of file -\retval ENOENT no value is present -*/ - int (*attr)(void *fpctx,void *handle, const char *attr,glite_jp_attrval_t **attrval); - -/** File type specific operation. -\param[in] fpctx Plugin context. -\param[in] handle Handle of the opened file. -\param[in] oper Code of the operation, specific for a concrete plugin. -*/ - int (*generic)(void *fpctx,void *handle,int oper,...); - -} glite_jpps_fplug_op_t; - -/** Data describing a plugin. */ -typedef struct _glite_jpps_fplug_data_t { - void *fpctx; /**< Context passed to plugin operations. */ - char **uris; /**< NULL-terminated list of file types (URIs) - handled by the plugin. */ - char **classes; /**< The same as uris but filesystem-friendly - (can be used to construct file names).*/ - char **namespaces; /**< Which attribute namespaces this plugin handles. */ - - glite_jpps_fplug_op_t ops; /**< Plugin operations. */ -} glite_jpps_fplug_data_t; - -/** Initialisation function of the plugin. - Called after dlopen(), must be named "init". -\param[in] ctx JPPS context -\param[out] data filled-in plugin data -*/ - -typedef int (*glite_jpps_fplug_init_t)( - glite_jp_context_t ctx, - glite_jpps_fplug_data_t *plugin_data -); - - - - -/* XXX: not really public interface follows */ - -int glite_jpps_fplug_load(glite_jp_context_t ctx,int argc,char **argv); -int glite_jpps_fplug_lookup(glite_jp_context_t ctx,const char *uri, glite_jpps_fplug_data_t ***plugin_data); -int glite_jpps_fplug_lookup_byclass(glite_jp_context_t, const char *class,glite_jpps_fplug_data_t ***plugin_data); - -#endif /* GLITE_JP_FILEPLUGIN_H */ diff --git a/org.glite.jp.common/interface/indexdb.h b/org.glite.jp.common/interface/indexdb.h deleted file mode 100644 index 06761d3..0000000 --- a/org.glite.jp.common/interface/indexdb.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_INDEXDB_H -#define GLITE_JP_INDEXDB_H - -/** - * \file indexdb.h - * \brief Helper functions for accessing Job Provenance Index Server database. - */ - -#include "glite/lbu/db.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifdef GLITE_JP_INDEX_COMPILE - -/** - * For generating table names. - */ -#define GLITE_JP_INDEXDB_TABLE_ATTR_PREFIX "attr_" - -#endif - - -/** - * Returns internal id from attribute name. - * - * The attribute id is used in some places in the database schema. Because of the future possible changes in the schema, you should rather use other functions to get SQL commands (table names and where conditions). - * - * \param[in] name attribute name - * \return attribute id string - */ -char *glite_jp_indexdb_attr2id(const char *name); - -/** - * Get parts of the SQL SELECT command to the given attribute: - * - * SELECT column, full_value_column FROM table WHERE where; - * - * This is quick version requiring additional information about indexing of the attribute. - */ -int glite_jp_indexdb_attr2select_from_index(const char *name, int indexed, char **column, char **full_value_column, char **table, char **where); - -/** - * Get parts of the SQL SELECT command to the given attribute: - * - * SELECT column, full_value_column FROM table WHERE where; - * - * This is the most portable way - it will peep to the DB for information about indexing. - */ -int glite_jp_indexdb_attr2select_from_db(const char *name, glite_lbu_DBContext dbctx, char **column, char **full_value_column, char **table, char **where); - -#ifdef __cplusplus -}; -#endif - - -#endif /* GLITE_JP_INDEXDB_H */ diff --git a/org.glite.jp.common/interface/known_attr.h b/org.glite.jp.common/interface/known_attr.h deleted file mode 100644 index 196eb93..0000000 --- a/org.glite.jp.common/interface/known_attr.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_KNOWN_ATTR_H -#define GLITE_JP_KNOWN_ATTR_H - -/** Namespace of JP system attributes */ -#define GLITE_JP_SYSTEM_NS "http://egee.cesnet.cz/en/Schema/JP/System" -#define GLITE_JP_WORKFLOW_NS "http://egee.cesnet.cz/en/Schema/JP/Workflow" - -/** Job owner, as specified with RegisterJob JPPS operation */ -#define GLITE_JP_ATTR_OWNER GLITE_JP_SYSTEM_NS ":owner" - -/** JobId */ -#define GLITE_JP_ATTR_JOBID GLITE_JP_SYSTEM_NS ":jobId" - -/** Timestamp of job registration in JP. - * Should be almost the same time as registration with LB. */ -#define GLITE_JP_ATTR_REGTIME GLITE_JP_SYSTEM_NS ":regtime" - -/** Workflow node relationships. */ -#define GLITE_JP_ATTR_WF_ANCESTOR GLITE_JP_WORKFLOW_NS ":ancestor" -#define GLITE_JP_ATTR_WF_SUCCESSOR GLITE_JP_WORKFLOW_NS ":successor" - -/** Attributes derived from LB system data - * \see jp_job_attrs.h */ - -/** Namespace for LB user tags, schemaless, all values are strings */ -#define GLITE_JP_LBTAG_NS "http://egee.cesnet.cz/en/WSDL/jp-lbtag" -#define GLITE_JP_JDL_NS "http://jdl" - -/** Namespace for Sandboxes */ -#define GLITE_JP_ISB_NS "http://egee.cesnet.cz/en/Schema/JP/ISB" -#define GLITE_JP_OSB_NS "http://egee.cesnet.cz/en/Schema/JP/OSB" - -/** Namespace for file names listed from tar */ -#define GLITE_JP_ATTR_ISB_FILENAME GLITE_JP_ISB_NS ":filename" -#define GLITE_JP_ATTR_OSB_FILENAME GLITE_JP_OSB_NS ":filename" - -/** Namespace for filenames to be unpacked from sanbox tar */ -#define GLITE_JP_ISB_CONTENT_NS GLITE_JP_ISB_NS ":content" -#define GLITE_JP_OSB_CONTENT_NS GLITE_JP_OSB_NS ":content" - -#endif /* GLITE_JP_KNOWN_ATTR_H */ diff --git a/org.glite.jp.common/interface/type_plugin.h b/org.glite.jp.common/interface/type_plugin.h deleted file mode 100644 index 8442ce8..0000000 --- a/org.glite.jp.common/interface/type_plugin.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_TYPEPLUGIN_H -#define GLITE_JP_TYPEPLUGIN_H - -typedef struct _glite_jp_tplug_data_t { - - char *namespace; - void *pctx; - -/** Compare attribute values. - * \param[in] a value to compare - * \param[in] b value to compare - * \param[out] result like strcmp() - * \param[out] err set if the values cannot be compared - * \retval 0 OK - * \retval other error - */ - int (*cmp)( - void *ctx, - const glite_jp_attrval_t *a, - const glite_jp_attrval_t *b, - int *result); - -/** Convert to database string representation. - * It is guaranteed the returned value can be converted back with - * from_db(). - * The resulting value may not be suitable for indexing with db engine. - * - * \param[in] attr the attribute value to convert - * \retval NULL can't be converted - * \retval other the string representation. - * */ - char * (*to_db_full)(void *ctx,const glite_jp_attrval_t *attr); - -/** Convert to a database string representation suitable for indexing. - * The function is non-decreasing (wrt. cmp() above and strcmp()), however it - * is not guaranteed to be one-to-one. - * - * \param[in] attr the value to convert - * \param[in] len maximum length of the converted value. - * \retval NULL can't be converted - * \retval other the string representation - */ - char * (*to_db_index)(void *ctx,const glite_jp_attrval_t *attr,int len); - -/** Convert from the database format. - * \param[in] str the string value - * \param[inout] attr name contains the name of the attribute to be converted - * the rest of attr is filled in. - */ - int (*from_db)(void *ctx,const char *str,glite_jp_attrval_t *attr); - -/** Query for database types suitable to store values returned by - * to_db_full() and to_db_index(). - * Useful for db column dynamic creation etc. - * Return pointer to internal static data, non-reentrant. - */ - const char * (*db_type_full)(void *ctx,const char *attr); - const char * (*db_type_index)(void *ctx,const char *attr,int len); - -} glite_jp_tplug_data_t; - -/** Plugin init function. - Must be called init, supposed to be called as many times as required - for different param's (e.g. xsd files). - Registers the plugin in ctx. - */ - -typedef int (*glite_jp_tplug_init_t)( - glite_jp_context_t ctx, - const char *param, - glite_jp_tplug_data_t *plugin_data -); - -#endif /* GLITE_JP_TYPEPLUGIN_H */ diff --git a/org.glite.jp.common/interface/types.h b/org.glite.jp.common/interface/types.h deleted file mode 100644 index 97e8281..0000000 --- a/org.glite.jp.common/interface/types.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_TYPES_H -#define GLITE_JP_TYPES_H - -#include - -typedef struct _glite_jp_error_t { - int code; - const char *desc; - const 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; - char *peer; - void **plugins; - void **type_plugins; - void *dbhandle; - char **trusted_peers; - char *myURL; - int noauth; -} *glite_jp_context_t; - -typedef enum { - GLITE_JP_ATTR_ORIG_ANY, /**< for queries: don't care about origin */ - GLITE_JP_ATTR_ORIG_SYSTEM, /**< JP internal, e.g. job owner */ - GLITE_JP_ATTR_ORIG_USER, /**< inserted by user explicitely */ - GLITE_JP_ATTR_ORIG_FILE /**< coming from uploaded file */ -} glite_jp_attr_orig_t; - -typedef struct { - char *name; /**< including namespace */ - char *value; - int binary; /**< value is binary */ - size_t size; /**< in case of binary value */ - glite_jp_attr_orig_t origin; - char *origin_detail; /**< where it came from, i.e. file URI:name */ - time_t timestamp; -} 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_EXISTS, - GLITE_JP_QUERYOP__LAST, -} glite_jp_queryop_t; - -typedef struct { - char *attr; - glite_jp_queryop_t op; - char *value, *value2; - int binary; - size_t size,size2; - glite_jp_attr_orig_t origin; -} glite_jp_query_rec_t; - -#endif /* GLITE_JP_TYPES_H */ diff --git a/org.glite.jp.common/project/build.number b/org.glite.jp.common/project/build.number deleted file mode 100644 index 8717663..0000000 --- a/org.glite.jp.common/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Mon Jan 16 06:46:39 CET 2006 -module.build=39 diff --git a/org.glite.jp.common/project/build.properties b/org.glite.jp.common/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp.common/project/configure.properties.xml b/org.glite.jp.common/project/configure.properties.xml deleted file mode 100644 index d4e6f4f..0000000 --- a/org.glite.jp.common/project/configure.properties.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - -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} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -cppunit=${with.cppunit.prefix} -jpproject=${subsystem.project.dir} -project=${component.project.dir} - - - diff --git a/org.glite.jp.common/project/properties.xml b/org.glite.jp.common/project/properties.xml deleted file mode 100755 index b9d669d..0000000 --- a/org.glite.jp.common/project/properties.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.common/project/tar_exclude b/org.glite.jp.common/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.jp.common/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.jp.common/project/version.properties b/org.glite.jp.common/project/version.properties deleted file mode 100644 index 1441742..0000000 --- a/org.glite.jp.common/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.3.0 -module.age=1 diff --git a/org.glite.jp.common/src/attr.c b/org.glite.jp.common/src/attr.c deleted file mode 100644 index 0e9eee1..0000000 --- a/org.glite.jp.common/src/attr.c +++ /dev/null @@ -1,308 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include - -#include "glite/jobid/strmd5.h" -#include "types.h" -#include "attr.h" -#include "type_plugin.h" -#include "context.h" - -void glite_jp_attrval_free(glite_jp_attrval_t *a,int f) -{ - free(a->name); - free(a->value); - free(a->origin_detail); - memset(a,0,sizeof *a); - if (f) free(a); -} - -void glite_jp_attrval_copy(glite_jp_attrval_t *dst,const glite_jp_attrval_t *src) -{ - dst->name = strdup(src->name); - dst->origin = src->origin; - dst->size = src->size; - dst->timestamp = src->timestamp; - dst->origin_detail = src->origin_detail ? - strdup(src->origin_detail) : NULL; - if ((dst->binary = src->binary)) { - dst->value = malloc(src->size); - memcpy(dst->value,src->value,src->size); - } - else dst->value = strdup(src->value); -} - - -#define min(x,y) ((x) > (y) ? (y) : (x)) - -static int fb_cmp(void *ctx,const glite_jp_attrval_t *a,const glite_jp_attrval_t *b,int *result) -{ - if (a->binary != b->binary) return EINVAL; - if (a->binary) { - *result = memcmp(a->value,b->value,min(a->size,b->size)); - if (!*result && a->size != b->size) - *result = a->size > b->size ? 1 : -1; - } - else *result = strcmp(a->value,b->value); - return 0; -} - -/* XXX: depends on specific definition of glite_jp_attr_orig_t */ -static char orig_char[] = "ASUF"; - -/* XXX: don't allocate memory, don't grow more than twice */ -static int escape_colon(const char *in, char *out) -{ - int i,o; - - for (i=o=0; in[i]; i++) switch (in[i]) { - case ':': out[o++] = '\\'; out[o++] = ':'; break; - case '\\': out[o++] = '\\'; out[o++] = '\\'; break; - default: out[o++] = in[i]; break; - } - out[o] = 0; - return o; -} - -/* XXX: read until unescaped colon is found - * allocates output */ -static char * unescape_colon(const char *in,int *rd) -{ - int i,o; - char *out; - - for (i=o=0; in[i] && in[i] != ':'; i++,o++) - if (in[i] == '\\') i++; - - out = malloc(o+1); - - for (i=o=0; in[i] && in[i] != ':'; i++) - if (in[i] == '\\') out[o++] = in[++i]; - else out[o++] = in[i]; - - out[o] = 0; - *rd = i; - return out; -} - -static char * fb_to_db_full(void *ctx,const glite_jp_attrval_t *attr) -{ - - int vsize = attr->binary ? attr->size * 4/3 + 6 : strlen(attr->value)+1, - len; - - /* 4x: + \0 + ASUF + BS + %12d */ - char *db = malloc(19 + (attr->origin_detail ? 2*strlen(attr->origin_detail) : 0) + vsize); - - if (attr->origin < 0 || attr->origin > GLITE_JP_ATTR_ORIG_FILE) { - free(db); return NULL; - } - len = sprintf(db,"%c:%d:%c:",attr->binary ? 'B' : 'S', - attr->timestamp,orig_char[attr->origin]); - - if (attr->origin_detail) len += escape_colon(attr->origin_detail,db+len); - db[len++] = ':'; - - if (attr->binary) { - vsize = base64_encode(attr->value,attr->size,db+len,vsize-1); - if (vsize < 0) { free(db); return NULL; } - db[len+vsize] = 0; - } - else strcpy(db+len,attr->value); - - return db; -} - -static char * fb_to_db_index(void *ctx,const glite_jp_attrval_t *attr,int len) -{ - char *s; - -/* XXX: binary values not really handled. Though the formal semantics is not broken */ - if (attr->binary) return strdup("XXX"); - - s = strdup(attr->value); - if (len < strlen(s)) s[len] = 0; - return s; -} - -static int fb_from_db(void *ctx,const char *str,glite_jp_attrval_t *attr) -{ - int p = 2; - char *colon,*cp; - - if (str[0] != 'B' && str[0] != 'S') return EINVAL; - attr->binary = str[0] == 'B'; - cp = attr->value = strdup(str); - - colon = strchr(cp+p,':'); - if (!colon) return EINVAL; - - *colon++ = 0; - attr->timestamp = (time_t) atol(cp+p); - p = colon-cp; - - for (attr->origin = GLITE_JP_ATTR_ORIG_ANY; orig_char[attr->origin] && orig_char[attr->origin] != cp[p]; attr->origin++); - if (!orig_char[attr->origin]) return EINVAL; - - p += 2; - if (cp[p] == ':') attr->origin_detail = NULL; - else { - int r; - attr->origin_detail = unescape_colon(cp+p,&r); - p += r; - } - if (cp[p++] != ':') return EINVAL; - - if (attr->binary) { - attr->size = base64_decode(str+p,attr->value,strlen(str)); - if (attr->size < 0) return EINVAL; - } - else strcpy(attr->value,str+p); - - return 0; -} - -static const char * fb_type_full(void *ctx,const char *attr) -{ - return "mediumblob"; -} - -static const char * fb_type_index(void *ctx,const char *attr,int len) -{ - static char tbuf[100]; - sprintf(tbuf,"varchar(%d)",len); - return tbuf; -} - - - -static glite_jp_tplug_data_t fallback_plugin = { - "", - NULL, - fb_cmp, - fb_to_db_full, - fb_to_db_index, - fb_from_db, - fb_type_full, - fb_type_index, -}; - -static glite_jp_tplug_data_t *get_plugin(glite_jp_context_t ctx,const char *aname) -{ - void **cp = ctx->type_plugins; - char *colon,*ns; - - if (!cp) return &fallback_plugin; - glite_jp_clear_error(ctx); - ns = strdup(aname); - colon = strrchr(ns,':'); - if (colon) *colon = 0; else *ns = 0; - - while (*cp) { - glite_jp_tplug_data_t *p = *cp; - if (!strcmp(ns,p->namespace)) { - free(ns); - return p; - } - cp++; - } - free(ns); - return &fallback_plugin; /* XXX: is it always desirable? */ -} - -int glite_jp_attrval_cmp(glite_jp_context_t ctx,const glite_jp_attrval_t *a,const glite_jp_attrval_t *b,int *result) -{ - glite_jp_tplug_data_t *ap = get_plugin(ctx,a->name); - glite_jp_error_t err; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - glite_jp_clear_error(ctx); - - if (strcmp(a->name,b->name)) { - err.code = EINVAL; - err.desc = "Can't compare different attributes"; - return glite_jp_stack_error(ctx,&err); - } - - return ap->cmp ? ap->cmp(ap->pctx,a,b,result) : fb_cmp(ap->pctx,a,b,result); -} - -char *glite_jp_attrval_to_db_full(glite_jp_context_t ctx,const glite_jp_attrval_t *attr) -{ - glite_jp_tplug_data_t *ap = get_plugin(ctx,attr->name); - - glite_jp_clear_error(ctx); - return ap->to_db_full ? ap->to_db_full(ap->pctx,attr) : fb_to_db_full(ap->pctx,attr); -} - -char *glite_jp_attrval_to_db_index(glite_jp_context_t ctx,const glite_jp_attrval_t *attr,int len) -{ - glite_jp_tplug_data_t *ap = get_plugin(ctx,attr->name); - - glite_jp_clear_error(ctx); - return ap->to_db_index ? ap->to_db_index(ap->pctx,attr,len) : fb_to_db_index(ap->pctx,attr,len); -} - - -int glite_jp_attrval_from_db(glite_jp_context_t ctx,const char *str,glite_jp_attrval_t *attr) -{ - glite_jp_tplug_data_t *ap = get_plugin(ctx,attr->name); - - glite_jp_clear_error(ctx); - return ap->from_db ? ap->from_db(ap->pctx,str,attr) : fb_from_db(ap->pctx,str,attr); -} - -const char *glite_jp_attrval_db_type_full(glite_jp_context_t ctx,const char *attr) -{ - glite_jp_tplug_data_t *ap = get_plugin(ctx,attr); - - glite_jp_clear_error(ctx); - return ap->db_type_full ? ap->db_type_full(ap->pctx,attr) : fb_type_full(ap->pctx,attr); -} - -const char *glite_jp_attrval_db_type_index(glite_jp_context_t ctx,const char *attr,int len) -{ - glite_jp_tplug_data_t *ap = get_plugin(ctx,attr); - - glite_jp_clear_error(ctx); - return ap->db_type_index ? ap->db_type_index(ap->pctx,attr,len) : fb_type_index(ap->pctx,attr,len); -} - -/* XXX: UNIX time, should be ISO blahblah */ -time_t glite_jp_attr2time(const char *a) -{ - long t; - - sscanf(a,"%ld",&t); - return t; -} - -/* XXX: UNIX time, should be ISO blahblah */ -char * glite_jp_time2attr(time_t t) -{ - char *r; - - asprintf(&r,"%ld",(long) t); - return r; -} - diff --git a/org.glite.jp.common/src/context.c b/org.glite.jp.common/src/context.c deleted file mode 100644 index c30214e..0000000 --- a/org.glite.jp.common/src/context.c +++ /dev/null @@ -1,162 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include - -#include "types.h" -#include "context.h" - -int glite_jp_init_context(glite_jp_context_t *ctx) -{ - return (*ctx = calloc(1,sizeof **ctx)) != NULL; -} - -void glite_jp_free_context(glite_jp_context_t ctx) -{ - glite_jp_clear_error(ctx); - free(ctx); -} - -char *glite_jp_peer_name(glite_jp_context_t ctx) -{ - return strdup(ctx->peer ? ctx->peer : "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((char *) e->source); - free((char *) 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); - free(q->value); - free(q->value2); - memset(q,0,sizeof *q); -} - -int glite_jp_queryrec_copy(glite_jp_query_rec_t *dst, const glite_jp_query_rec_t *src) -{ - memcpy(dst,src,sizeof *src); - if (src->attr) dst->attr = strdup(src->attr); - if (src->value) dst->value = strdup(src->value); - if (src->value2) dst->value2 = strdup(src->value2); - 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; ideferred_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]; i++); - - ctx->deferred_func = realloc(ctx->deferred_func, (i+2) * sizeof *ctx->deferred_func); - ctx->deferred_func[i] = func; - ctx->deferred_func[i+1] = NULL; - - ctx->deferred_arg = realloc(ctx->deferred_arg,(i+2) * sizeof *ctx->deferred_arg); - ctx->deferred_arg[i] = arg; - ctx->deferred_arg[i+1] = NULL; - - return 0; -} diff --git a/org.glite.jp.common/src/indexdb.c b/org.glite.jp.common/src/indexdb.c deleted file mode 100644 index 86f4e85..0000000 --- a/org.glite.jp.common/src/indexdb.c +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ident "$Header:" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#define GLITE_JP_INDEX_COMPILE 1 - -#include "indexdb.h" - -char *glite_jp_indexdb_attr2id(const char *name) { - size_t i, len; - char *lname, *id; - - len = strlen(name); - lname = malloc(len + 1); - for (i = 0; i < len + 1; i++) lname[i] = tolower(name[i]); - id = str2md5(lname); - free(lname); - - return id; -} - - -int glite_jp_indexdb_attr2select_from_index(const char *name, int indexed __attribute__((unused)), char **column, char **full_value_column, char **table, char **where) { - char *id; - - if (column) *column = strdup("value"); - if (full_value_column) *full_value_column = strdup("full_value"); - if (table) { - id = glite_jp_indexdb_attr2id(name); - asprintf(table, GLITE_JP_INDEXDB_TABLE_ATTR_PREFIX "%s", id); - free(id); - } - if (where) *where = strdup(""); - - return 0; -} - - -int glite_jp_indexdb_attr2select_from_db(const char *name, glite_lbu_DBContext dbctx, char **column, char **full_value_column, char **table, char **where) { - char *sql, *id; - glite_lbu_Statement stmt; - int ret; - - if (table) { - trio_asprintf(&sql, "SELECT attrid FROM attrs WHERE name='%|Ss'", name); - ret = glite_lbu_ExecSQL(dbctx, sql, &stmt); - free(sql); - switch (ret) { - case -1: return glite_lbu_DBError(dbctx, NULL, NULL); - case 1: break; - default: return EINVAL; - } - if (glite_lbu_FetchRow(stmt, 1, NULL, &id) < 0) return glite_lbu_DBError(dbctx, NULL, NULL); - asprintf(table, GLITE_JP_INDEXDB_TABLE_ATTR_PREFIX "%s", id); - free(id); - glite_lbu_FreeStmt(&stmt); - } - if (column) *column = strdup("value"); - if (full_value_column) *full_value_column = strdup("full_value"); - if (where) *where = strdup(""); - - return 0; -} diff --git a/org.glite.jp.common/src/utils.c b/org.glite.jp.common/src/utils.c deleted file mode 100644 index d27d606..0000000 --- a/org.glite.jp.common/src/utils.c +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "glite/jobid/strmd5.h" -#include "types.h" -#include "context.h" -#include "known_attr.h" -#include "attr.h" - -/* -#include "feed.h" -#include "tags.h" -*/ - -#include "backend.h" - - -typedef struct _rl_buffer_t { - char *buf; - size_t pos, size; - off_t offset; -} rl_buffer_t; - -/* - * realloc the line to double size if needed - * - * \return 0 if failed, did nothing - * \return 1 if success - */ -int check_realloc_line(char **line, size_t *maxlen, size_t len) { - void *tmp; - - if (len > *maxlen) { - *maxlen <<= 1; - tmp = realloc(*line, *maxlen); - if (!tmp) return 0; - *line = tmp; - } - - return 1; -} - - -char* glite_jpps_get_namespace(const char* attr){ - char* namespace = strdup(attr); - char* colon = strrchr(namespace, ':'); - if (colon) - namespace[strrchr(namespace, ':') - namespace] = 0; - else - namespace[0] = 0; - return namespace; -} - diff --git a/org.glite.jp.common/test/type_test.cpp b/org.glite.jp.common/test/type_test.cpp deleted file mode 100644 index 532fc95..0000000 --- a/org.glite.jp.common/test/type_test.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "types.h" -#include "attr.h" -#include "context.h" -#include "backend.h" - - -class TypePluginTest: public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(TypePluginTest); - CPPUNIT_TEST(simple); - CPPUNIT_TEST(binary); - CPPUNIT_TEST(origin); - CPPUNIT_TEST(origin2); - CPPUNIT_TEST(index); - CPPUNIT_TEST_SUITE_END(); -public: - void simple(); - void binary(); - void origin(); - void origin2(); - void index(); -}; - -void TypePluginTest::simple() -{ - glite_jp_context_t ctx; - - glite_jp_attrval_t attr = { - "myattr", - "short string", - 0,0, - GLITE_JP_ATTR_ORIG_USER, - NULL, - 0 - },attr2; - - char *db; - - glite_jp_init_context(&ctx); - attr.timestamp = time(NULL); - - db = glite_jp_attrval_to_db_full(ctx,&attr); - - CPPUNIT_ASSERT_MESSAGE(std::string("glite_jp_attrval_to_db_full()"),db); - std::cerr << db << std::endl; - - glite_jp_attrval_from_db(ctx,db,&attr2); - CPPUNIT_ASSERT_MESSAGE(std::string("value"),!strcmp(attr.value,attr2.value)); - CPPUNIT_ASSERT_MESSAGE(std::string("origin"),attr.origin == attr2.origin); - CPPUNIT_ASSERT_MESSAGE(std::string("timestamp"),attr.timestamp == attr2.timestamp); -} - -void TypePluginTest::binary() -{ - glite_jp_context_t ctx; - - glite_jp_attrval_t attr = { - "myattr", - NULL, - 1,1000, - GLITE_JP_ATTR_ORIG_USER, - NULL, - 0 - },attr2; - - char *db; - - glite_jp_init_context(&ctx); - attr.timestamp = time(NULL); - attr.value = (char *) malloc(attr.size); - - db = glite_jp_attrval_to_db_full(ctx,&attr); - - CPPUNIT_ASSERT_MESSAGE(std::string("glite_jp_attrval_to_db_full()"),db); - std::cerr << db << std::endl; - - glite_jp_attrval_from_db(ctx,db,&attr2); - CPPUNIT_ASSERT_MESSAGE(std::string("size"),attr.size == attr2.size); - CPPUNIT_ASSERT_MESSAGE(std::string("value"),!memcmp(attr.value,attr2.value,attr.size)); -} - -void TypePluginTest::origin() -{ - glite_jp_context_t ctx; - - glite_jp_attrval_t attr = { - "myattr", - NULL, - 0,0, - GLITE_JP_ATTR_ORIG_USER, - NULL, - 0 - },attr2; - - char *db; - - glite_jp_init_context(&ctx); - attr.timestamp = time(NULL); - attr.value = "origin test"; - attr.origin_detail = "simple origin"; - - db = glite_jp_attrval_to_db_full(ctx,&attr); - - CPPUNIT_ASSERT_MESSAGE(std::string("glite_jp_attrval_to_db_full()"),db); - std::cerr << db << std::endl; - - glite_jp_attrval_from_db(ctx,db,&attr2); - CPPUNIT_ASSERT_MESSAGE(std::string("origin detail"),!strcmp(attr.origin_detail,attr2.origin_detail)); -} - -void TypePluginTest::origin2() -{ - glite_jp_context_t ctx; - - glite_jp_attrval_t attr = { - "myattr", - NULL, - 0,0, - GLITE_JP_ATTR_ORIG_USER, - NULL, - 0 - },attr2; - - char *db; - - glite_jp_init_context(&ctx); - attr.timestamp = time(NULL); - attr.value = "origin:test"; - attr.origin_detail = "ftp://some.server:1234/ugly \\file"; - - db = glite_jp_attrval_to_db_full(ctx,&attr); - - CPPUNIT_ASSERT_MESSAGE(std::string("glite_jp_attrval_to_db_full()"),db); - std::cerr << db << std::endl; - - glite_jp_attrval_from_db(ctx,db,&attr2); - CPPUNIT_ASSERT_MESSAGE(std::string("origin detail"),!strcmp(attr.origin_detail,attr2.origin_detail)); - CPPUNIT_ASSERT_MESSAGE(std::string("value"),!strcmp(attr.value,attr2.value)); -} - -void TypePluginTest::index() -{ - /* TODO: check monotonity */ -} - -CPPUNIT_TEST_SUITE_REGISTRATION(TypePluginTest); - - -int main (int argc,const char *argv[]) -{ - CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); - - assert(argc == 2); - std::ofstream xml(argv[1]); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - CppUnit::TestRunner runner; - runner.addTest(suite); - runner.run(controller); - - CppUnit::XmlOutputter xout( &result, xml ); - CppUnit::CompilerOutputter tout( &result, std::cout); - xout.write(); - tout.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} - - - - -/* fake to link */ -int glite_jppsbe_pread( - glite_jp_context_t ctx, - void *handle, - void *buf, - size_t nbytes, - off_t offset, - ssize_t *nbytes_ret -) -{ - abort(); -} - - diff --git a/org.glite.jp.doc/LICENSE b/org.glite.jp.doc/LICENSE deleted file mode 100644 index 259a91f..0000000 --- a/org.glite.jp.doc/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.jp.doc/Makefile b/org.glite.jp.doc/Makefile deleted file mode 100644 index d15495a..0000000 --- a/org.glite.jp.doc/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -# Default values -top_srcdir=. -stagedir=. -globalprefix=glite -lbprefix=lb -package=glite-jp-doc -version=0.0.0 -PREFIX=/opt/glite - --include Makefile.inc - -VPATH = ${top_srcdir}/src -KPATH = TEXINPUTS=".:$(VPATH)//:" -KPATHBIB = BIBINPUTS=".:$(VPATH)//:" - -LATEX = $(KPATH) latex -PDFLATEX = $(KPATH) pdflatex -BIBTEX = $(KPATHBIB) bibtex -DVIPS = $(KPATH) dvips -AT3=${stagedir}/sbin/glite-lb-at3 -INSTALL=install - -default all: generate JPUG.pdf JPAG.pdf JPDG.pdf - -generate: - -# %.dvi: %.tex -# $(LATEX) $< -# $(BIBTEX) `basename $< .tex` -# $(LATEX) $< -# $(LATEX) $< -# -# %.ps: %.dvi -# $(DVIPS) -ta4 -o $@ $< - -%.pdf: %.tex - $(PDFLATEX) $< - $(BIBTEX) `basename $< .tex` - $(PDFLATEX) $< - $(PDFLATEX) $< - -%.tex: %.tex.T - rm -f $@ - ${AT3} $< >$@ || rm -f $@ - chmod -w $@ >/dev/null - -install: - -mkdir -p ${PREFIX}/share/doc/${package}-${version} - $(INSTALL) -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - $(INSTALL) -m 644 ${top_srcdir}/src/README ${PREFIX}/share/doc/${package}-${version} - $(INSTALL) -m 644 JPUG.pdf ${PREFIX}/share/doc/${package}-${version} - $(INSTALL) -m 644 JPAG.pdf ${PREFIX}/share/doc/${package}-${version} - $(INSTALL) -m 644 JPDG.pdf ${PREFIX}/share/doc/${package}-${version} - -clean: - rm -rvf JPUG* JPAG* JPDG* - rm -rvf log.xml project/ rpmbuild/ RPMS/ tgz/ - - -# dependencies: - -JPUG.pdf: JPUG.tex \ - JPUG-Introduction.tex \ - JPUG-Tools.tex glite-jpis-client.tex jpimporter.tex gui.tex \ - JPUG-UseCases.tex - -JPAG.pdf: JPAG.tex \ - JPAG-Introduction.tex LB-JP-interaction.tex \ - JPAG-Installation.tex \ - JPAG-Configuration.tex \ - JPAG-Running.tex \ - JPAG-Testing.tex \ - JPAG-Troubleshooting.tex - -JPDG.pdf: JPDG.tex \ - JPDG-Introduction.tex \ - JPDG-WS.tex - -.PHONY: all clean diff --git a/org.glite.jp.doc/configure b/org.glite.jp.doc/configure deleted file mode 100755 index 0bf1a3f..0000000 --- a/org.glite.jp.doc/configure +++ /dev/null @@ -1,701 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; - -my $pwd = `pwd`; chomp $pwd; -my $prefix = $pwd.'/stage'; -my $stagedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my $version; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $sec_tag = ''; -my $jobid_tag = ''; - -my @nodes = qw/client server logger utils client-java doc ws-test db jpprimary jpindex jpclient/; -my %enable_nodes; -my %disable_nodes; - -my %extern_prefix = ( - cares => '/opt/c-ares', - classads => '/opt/classads', - cppunit => '/usr', - expat => '/usr', - globus => '/opt/globus', - gsoap => '/usr', - mysql => '/usr', - voms => '/opt/glite', - gridsite => '/opt/glite', - lcas => '/opt/glite', - ant => '/usr', - jdk => '/usr', - libtar => '/usr', -); - -my %jar = ( - 'commons-codec' => '/usr/share/java/commons-codec-1.3.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %topbuild; - -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test/], - 'security' => [qw/gss gsoap-plugin/], - 'lbjp-common' => [qw/db maildir server-bones trio jp-interface/], - 'jobid' => [qw/api-c api-cpp api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - ); - - -my @opts = ( - 'prefix=s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour=s' => \$thrflavour, - 'nothrflavour=s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$version, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'security-tag=s' => \$sec_tag, - 'jobid-tag=s' => \$jobid_tag, - 'help' => \$help, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$extern_prefix{$_} for keys %extern_prefix; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my @m = map "org.glite.$listmodules.$_",@{$lbmodules{$listmodules}}; - print "@m\n"; - exit 0; -} - -warn "$0: --version and --output make sense only in --mode=etics\n" - if ($version || $output) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},@{$lbmodules{security}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless $disable_nodes{$_}; - } -} - -if (!$en && !$dis) { $enable_nodes{$_} = 1 for (@nodes) } ; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $prefix unless $stagedir; - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: $extern_prefix{$_}\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\nclean:\n"; - - for (@modules) { - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - print MAK "\tcd $full$build && \${MAKE} clean\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $topbuild{$_} ? - "\tcd $full$build && \${MAKE} distclean\n" : - "\trm -rf $full$build\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - - print MAK "$_: @dnames\n\tcd $full$build && \${MAKE} && \${MAKE} install\n\n"; - } - - close MAK; -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag){ - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($sec_tag){ - for (@{$lbmodules{security}}){ - if ("security.".$_ eq $module){ - $tag = '-r '.$sec_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads/ ], - 'lb.client-java' => [ qw/ant:B/ ], - 'lb.common' => [ qw/expat cppunit:B classads/ ], - 'lb.doc' => [], - 'lb.logger' => [ qw/cppunit:B/ ], - 'lb.server' => [ qw/globus expat cares mysql cppunit:B gsoap:B classads voms lcas gridsite/ ], - 'lb.state-machine' => [ qw/classads/ ], - 'lb.utils' => [ qw/cppunit:B/ ], - 'lb.ws-interface' => [], - 'lb.ws-test' => [ qw/gsoap:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/mysql/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw/cppunit:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B/ ], - 'security.gss' => [ qw/globus cares cppunit:B/ ], - 'security.gsoap-plugin' => [ qw/cppunit:B globus cares gsoap:B/ ], - 'jobid.api-c' => [ qw/cppunit:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], -); - -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$need_externs{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $need_externs_type{$ext}->{$1} = $type; - } -} - -%need_jars = ( - 'jobid.api-java' => [ qw/commons-codec/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp jobid.api-c - security.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp jobid.api-c - lb.types:B lbjp-common.trio security.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - jobid.api-c - lb.common - security.gss - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir - jobid.api-c - security.gsoap-plugin security.gss - / ], - 'lb.state-machine' => [ qw/lb.common lbjp-common.jp-interface security.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine - / ], - 'lb.ws-test' => [ qw/security.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/lbjp-common.trio/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw// ], - 'security.gss' => [ qw// ], - 'security.gsoap-plugin' => [ qw/security.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - security.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( gridsite=>'org.gridsite.core'); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', -); - -my @t = qw/lb.client-java jobid.api-java lb.types/; -@topbuild{@t} = (1) x ($#t+1); -} - -sub full -{ - my $short = shift; - return $extrafull{$short} ? $extrafull{$short} : 'org.glite.'.$short; -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java -security.gss security.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -/; - @aux{@m} = (1) x ($#m+1); - - my $short = shift; - my $full = full $short; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $build = ''; - - unless ($topbuild{$_}) { - $build = '/build'; - unless (-d "$full/build") { - mkdir "$full/build" or die "mkdir $full/build: $!\n"; - } - unlink "$full/build/Makefile"; - symlink "../Makefile","$full/build/Makefile" or die "symlink ../Makefile $full/build/Makefile: $!\n"; - } - - open MKINC,">$full$build/Makefile.inc" - or die "$full$build/Makefile.inc: $!\n"; - - print "Creating $full$build/Makefile.inc\n"; - - print MKINC qq{ -PREFIX = $prefix -stagedir = $stagedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -}; - - for (@{$need_externs{$short}}) { - print MKINC "${_}_prefix = $extern_prefix{$_}\n" - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; -} - -my %etics_externs; -my %etics_projects; -BEGIN{ - %etics_externs = ( - globus=>'vdt_globus_essentials', - cares=>'c-ares', - voms=>'org.glite.security.voms-api-cpp', - gridsite=>'org.gridsite.shared', - lcas=>'org.glite.security.lcas', - ); - %etics_projects = ( - vdt=>[qw/globus/], - 'org.glite'=>[qw/voms gridsite lcas/], - ); -}; - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod; - - my ($major,$minor,$rev,$age); - - if ($version) { - $version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - open V,"org.glite.$subsys.$module/project/version.properties" - or die "org.glite.$subsys.$module/project/version.properties: $!\n"; - - while ($_ = ) { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - } - - my @copts = (); - my %ge; - @ge{@{$etics_projects{'org.glite'}}} = (1) x ($#{$etics_projects{'org.glite'}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}/$_*.jar"; - } - - - my $conf = "glite-$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $topbuild{"$subsys.$module"} ? '' : "build.root = build\n"; - - my $confdir = $topbuild{"$subsys.$module"} ? '..' : '../..'; - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = org.glite.$subsys.$module -displayName = $conf -description = org.glite.$subsys.$module -projectName = org.glite -age = $age -deploymentType = None -tag = $conf -version = $major.$minor.$rev -path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz - -[Platform-default:VcsCommand] -displayName = None -description = None -tag = cvs -d \${vcsroot} tag -R \${tag} \${moduleName} -branch = None -commit = None -checkout = cvs -d \${vcsroot} co -r \${tag} \${moduleName} - -[Platform-default:BuildCommand] -postpublish = None -packaging = None -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = make -init = None -install = make install -clean = make clean -test = make check -configure = cd $confdir && \${moduleName}/configure --thrflavour=\${globus.thr.flavor} --nothrflavour=\${globus.nothr.flavor} --prefix=\${prefix} --stage=\${stageDir} --module $subsys.$module @copts -checkstyle = None - -[Platform-default:Property] -$buildroot - -[Platform-default:DynamicDependency] - -}; - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - print C "$proj|$eext = $type\n"; - } - - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - print C "org.glite|org.glite.$_ = $type\n"; - } - - close C; -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$extern_prefix{gsoap}/bin/soapcpp2 -v 2>&1 |" or die "$extern_prefix{gsoap}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - - -sub usage { - my @ext = keys %extern_prefix; - my @myjars, keys %jar; - - print STDERR qq{ -usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - -Mode of operation: - --mode={checkout|build|etics} what to do [build] - -What to build: - --module=module build this module only (mostly in-Etics operation) - --enable-NODE build this "node" (set of modules) only. Available nodes are - @{$lbmodules{lb}},@{$lbmodules{security}} - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --security-tag=tag checkout security modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - -Dependencies: - --with-EXTERNAL=PATH where to look for an external. Required externals - (not all for all modules) are: - @ext - --with-JAR=JAR where to look for jars. Required jars are: - @myjars - Summary of what will be used is always printed - -}; - -} diff --git a/org.glite.jp.doc/project/ChangeLog b/org.glite.jp.doc/project/ChangeLog deleted file mode 100644 index 0b26ff7..0000000 --- a/org.glite.jp.doc/project/ChangeLog +++ /dev/null @@ -1,6 +0,0 @@ -1.0.0-1 -- Initial version - -1.0.0-2 -- configure updated - diff --git a/org.glite.jp.doc/project/version.properties b/org.glite.jp.doc/project/version.properties deleted file mode 100644 index b7186ff..0000000 --- a/org.glite.jp.doc/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# $Header$ -module.version=1.0.0 -module.age=2 diff --git a/org.glite.jp.doc/src/JPAG-Configuration.tex b/org.glite.jp.doc/src/JPAG-Configuration.tex deleted file mode 100644 index 9e5759f..0000000 --- a/org.glite.jp.doc/src/JPAG-Configuration.tex +++ /dev/null @@ -1,36 +0,0 @@ -\section{Configuration} -\TODO{} - -\subsection{JPPS} -\subsubsection{Setting up the MySQL database} - - -\subsection{JPIS} - -\begin{alltt} -The JP-IS server daemon assume prior creation of its database. Simple tool - for database creation is org.glite.jp.index/config/dbsetup.sh - -customize startup script /etc/init.d/glite-jp-indexd (see below) - and set up service startup using this script - - -Currently, configuration is done by command line options, and -some hard-coded options. - - -The index server takes the following options: - -./glite-jp-indexd [option] - -d, --debug don't run as daemon, additional diagnostics - -q, --query-type hist/cont/both (default history) - -n, --noauth don't check user identity with result owner - -m, --mysql database connect string - -p, --port port to listen - -i, --pidfile file to store master pid - -o, --logfile file to store logs - -x, --config file with server configuration - -The config file parameter is required. There is the example configuration in -$GLITE_LOCATION/etc/glite-jpis-config.xml. -\end{alltt} diff --git a/org.glite.jp.doc/src/JPAG-Installation.tex b/org.glite.jp.doc/src/JPAG-Installation.tex deleted file mode 100644 index ff638c3..0000000 --- a/org.glite.jp.doc/src/JPAG-Installation.tex +++ /dev/null @@ -1,9 +0,0 @@ -\section{Installation} -\TODO{Import the content of \texttt{glite\_installation\_guide\_\[LB\|JP\].doc}.} - -\subsection{Complete RPMs description} - -\subsection{Daemons description} - -\subsection{CLI tools description} -% admin (sbin) tools diff --git a/org.glite.jp.doc/src/JPAG-Introduction.tex b/org.glite.jp.doc/src/JPAG-Introduction.tex deleted file mode 100644 index bb356c9..0000000 --- a/org.glite.jp.doc/src/JPAG-Introduction.tex +++ /dev/null @@ -1,75 +0,0 @@ -\section{Introduction} -\TODO{Do a reasonable merge with the JPUG-Introduction, do not duplicate text...} - - -\subsection{Job Provenance service overview} -The information about jobs submitted to gLite Workload Management -System is collected by the Logging and Bookkeeping (LB) service. -LB tracks jobs in terms of events and processes them in -a~real time to give overall view on the actual job state. The user may -query the bookkeeping server to obtain either the raw events or the -computed job state, she may also register for receiving notifications -on particular job state changes. - -While the LB is intended to keep track of jobs during its lifetime, it -is not supposed to be used for long term archival of such data. The -Job Provenance (JP) service is designed to provide long-term storage -of all data related to job life and allow the end user to perform -data-mining in this data. -The JP is supposed to provide the permanent storage of -the job related information as stored within the \LB, to couple it with -the input sandboxes and other system oriented information necessary to -reproduce the environment where a~particular job run. - -\subsubsection{Gathering data into Job Provenance} -Fig.~\ref{fig:psinter} depicts basic gLite middleware components and -their interaction with the Job Provenance. - -\begin{figure}[htpb] - \centering - \includegraphics[scale=0.7]{JP-interactions} - \caption{Data flow into gLite Job Provenance} - \label{fig:psinter} -\end{figure} - -JP is formed of two classes of services: permanent \emph{Primary -Storage} (JPPS) accepts and stores job data while possibly volatile -and configurable \emph{Index Servers} (JPIS) provide an optimized -querying and data-mining interface to the end-users. The only direct -data retrieval scenario supported by JPPS is the case when user know exact ID -of jobs in the interest. - -\subsubsection{Getting data from Job Provenance} - -The role of \emph{Index Servers} (JPIS) is processing and re-arranging the data -from Primary Storage(s) into a~form suitable for frequent and complex user -queries. A user query part of JP is shown in Fig.~\ref{fig:query}. - -\begin{figure}[htpb] - \centering - \includegraphics[scale=0.8]{JP-query} - \caption{Index Server interactions} - \label{fig:query} -\end{figure} - -Index Servers are created, configured, and populated semi-dynamically -according to particular user community needs. It is responsibility of -its administrator to setup the JPIS with appropriate configuration. There -is no prescribed relationship between Primary Storage and Index Server -installations. An Index Server may retrieve data from multiple -Primary Storages and vice versa. - -% TODO: update -% The interface exposed by JPIS to the end user is described in the -% chapter~\ref{reference}. Command line interface tool for end-user -% interface to the JPIS is described in the chapter~\ref{CLI}. See the -% next chapter (use cases) for futher description of JP to user -% interactions. - - -% LB-JP-interaction -\input{LB-JP-interaction} - -% -\subsection{Deployment scenarios} - diff --git a/org.glite.jp.doc/src/JPAG-Running.tex b/org.glite.jp.doc/src/JPAG-Running.tex deleted file mode 100644 index 69fefc2..0000000 --- a/org.glite.jp.doc/src/JPAG-Running.tex +++ /dev/null @@ -1,33 +0,0 @@ -\section{Running and stopping the services} -\TODO{} - - -\subsection{JPPS} - - -\subsection{JPIS} - -\begin{alltt} -Preferred way of starting the daemon is using start-up script -(config/startup). It loads glite.conf file (personal version may be stored -in ~/.glite.conf) where many variables may be set to configure the daemon. -The script takes following variables: - -GLITE_JPIS_CONFIG - server config file specification - (default is $GLITE_LOCATION//etc/glite-jpis-config.xml) -GLITE_JPIS_DEBUG - setting to '-d' forces the daemon not to daemonize -GLITE_JPIS_QT - defines query type - 'hist' ... history query - 'cont' ... continuous query - 'both' ... combination of previous types -GLITE_JPIS_AUTH - setting to '-n' forces the daemon not to check - authorisation -GLITE_JPIS_PORT - used port (default 8902) -GLITE_JPIS_DB - database connection string - (default jpis/@localhost:jpis) -GLITE_JPIS_LOGFILE - log file - (default is $GLITE_LOCATION_VAR/log/glite-jp-indexd.log) -GLITE_JPIS_PIDFILE - pid file - (default is $GLITE_LOCATION_VAR/run/glite-jp-indexd.log) - -\end{alltt} diff --git a/org.glite.jp.doc/src/JPAG-Testing.tex b/org.glite.jp.doc/src/JPAG-Testing.tex deleted file mode 100644 index 1055b71..0000000 --- a/org.glite.jp.doc/src/JPAG-Testing.tex +++ /dev/null @@ -1,545 +0,0 @@ -\section{Testing JP functionality} -% AKA Testplan - -\def\req{\noindent\textbf{Prerequisities: }} -\def\how{\noindent\textbf{How to run: }} -\def\result{\noindent\textbf{Expected result: }} -\def\jpps{\noindent\textbf{JP PS log should contain: }} -\def\jpis{\noindent\textbf{JP IS log should contain: }} - - -\subsection{JPPS standalone tests} - -\subsubsection{Job registration} - -\paragraph{Basic functionality} -\label{regjob} -\req\ Running JPPS - -\how -\begin{itemize} -\item call RegisterJob operation: -\begin{verbatim} -$ jpps-test RegisterJob JOBID OWNER -\end{verbatim} -where JOBID and OWNER should be replaced with real values, JOBID should not have -been registered with JP before. - -\item call GetJobAttributes to verify: -\begin{verbatim} -$ jpps-test GetJobAttr JOBID http://egee.cesnet.cz/en/Schema/JP/System:owner -\end{verbatim} -\end{itemize} -\result Should print the OWNER value supplied. - -\paragraph{AuthZ check} -\req\ JPPS running, a~job registered with the procedure in~\ref{regjob} - -\how\ -Call GetJobAttributes using different user credentials - -\result\ -Should fail with ``Permission denied'' error - -\subsubsection{Tag recording} -\label{tagreg} - -\paragraph{Basic functionality} -\req\ -JPPS running, a~job registered with the procedure in~\ref{regjob} - -\how -\begin{itemize} -\item Call RecordTag operation: -\begin{verbatim} -$ jpps-test RecordTag JOBID TAGNAME STRINGVALUE -\end{verbatim} -\item Call GetJobAttributes to verify -\begin{verbatim} -$ jpps-test GetJobAttr JOBID TAGNAME -\end{verbatim} -\end{itemize} -\result -The recorded value should be returned. - -\how\ Record another values(s) of the same tag by repeating the RecordTag call - -\result\ GetJobAttr should return all the recorded values - - -\paragraph{AuthZ check} -\req\ JPPS running, a~job registered with the procedure in~\ref{tagreg} \\ -\how\ Call RecordTag using different user credentials \\ -\result\ Should fail with ``Permission denied'' error \\ - - -\subsubsection{File upload} - - -\paragraph{Basic functionality} -\req\ JPPS running, my certificate subject amont JPPS trusted peers, -\verb'globus-url-copy' in PATH - -\how -Run the aggregate test script from \verb'org.glite.jp.primary/build' - -\begin{verbatim} -$ ../examples/jpps_store_test -o 'OWNER' -d ../examples/job_template -\end{verbatim} -(substitute real cert.\ subject for OWNER) - -\result\ -The script calls JPPS operations RegisterJob and StartUpload, -uploads an \LB\ job log generated from the template file, -calls CommitUpload. - -Finally, the upload is checked by retrieving two attribute -values: LB/Attributes:user and LB/Attributes:finalStatusk via the GetJobAttr -call. -Both calls should return OK and print reasonable values. - -%- call StartUpload, LB dump file type -%* check with GetJobFiles -- shoud return nothing -%- upload via ftp -%- call CommitUpload -%* check with GetJobFiles -- should return URL -%- retrieve and check the file - -\paragraph{Phase checks} -\TODO{salvet} -% soubor nelze zapsat pred otevrenim operaci StartUpload -% nelze cist pred Commitem -% nelze zapsat po Commitu - -\paragraph{AuthZ checks} -(should fail) - -\TODO{salvet} -%* call GetJobFiles with different credentials -% -%* StartUpload with different credentials -% -%- StartUpload -%* ftp upload with different credentials -% -%* ftp GET with different credentials - - -\paragraph{Cleanup} -(Foreseen test for feature which is not implemented yet) -%- call StartUpload, short timeout -%- upload via ftp -%(don't call CommitUpload) -%* uploaded file should be purged after timeout - -\subsection{\LB\ plugin} -%\TODO{honik} -\LB\ plugin is a component integrating the \LB\ functionality into JP. - - -\subsubsection{Standalone tests} -\LB\ plugin as a standalone component is used for example in the \texttt{glite-lb-statistics} -program (part of org.glite.lb.utils). This program reads a dump file of events related to -one particular job and using the \LB\ plugin it computes the job state and many other job -statistics. See the \LB\ testplan for more details. - -\subsubsection{Integrated tests} -\req JPPS running with the \texttt{-P/path/to/the/glite\_lb\_plugin.so} - -\how -\begin{itemize} -\item call GetJobAttributes to get the LB attributes -\begin{verbatim} -$ jpps-test GetJobAttr JOBID ATTRIBUTE - -where ATTRIBUTE is one of the -http://egee.cesnet.cz/en/Schema/LB/Attributes:jobId -http://egee.cesnet.cz/en/Schema/LB/Attributes:user -http://egee.cesnet.cz/en/Schema/LB/Attributes:VO -http://egee.cesnet.cz/en/Schema/LB/Attributes:eNodes -http://egee.cesnet.cz/en/Schema/LB/Attributes:eProc -http://egee.cesnet.cz/en/Schema/LB/Attributes:RB -http://egee.cesnet.cz/en/Schema/LB/Attributes:CE -http://egee.cesnet.cz/en/Schema/LB/Attributes:host -http://egee.cesnet.cz/en/Schema/LB/Attributes:UIHost -http://egee.cesnet.cz/en/Schema/LB/Attributes:CPUTime -http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus -http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusDate -http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusReason -http://egee.cesnet.cz/en/Schema/LB/Attributes:LRMSDoneStatus -http://egee.cesnet.cz/en/Schema/LB/Attributes:LRMSStatusReason -http://egee.cesnet.cz/en/Schema/LB/Attributes:retryCount -http://egee.cesnet.cz/en/Schema/LB/Attributes:additionalReason -http://egee.cesnet.cz/en/Schema/LB/Attributes:jobType -http://egee.cesnet.cz/en/Schema/LB/Attributes:nsubjobs -http://egee.cesnet.cz/en/Schema/LB/Attributes:lastStatusHistory -http://egee.cesnet.cz/en/Schema/LB/Attributes:fullStatusHistory -\end{verbatim} -\end{itemize} - -\result Should print the corresponding LB attributes - -\subsection{JPPS-JPIS interaction (feeds)} - - -%set of queries (how many?) with different "triggering conditions": -%- on job registration -%- on LB file upload -%- on RecordTag - -%corresponding sets of jobs to each query, each containing jobs which match -%and which don't - -%- initial IS release -- single query, so just one set of jobs -%- due to 3.2 no point in pre-loading PS database, use 1.3.1 - -\subsubsection{Batch feed} -%- upload jobs to PS -%- start feed -%* check IS contents (jobs and expected attr values) - -\req\ Clean JP-PS and JP-IS database. - -\how\ -\begin{enumerate} - \item \emph{Start JP primary server} - \item \emph{Register job to PS} - \begin{alltt} - for j in `seq 1 10`; - do - for i in glite-jp-primary-sample_job*.lb; - do - ./glite-jp-primary-store-test -o \emph{CERT_DN} - -t "my_tag=car" -s https://localhost:8901 -d $i; - done; - done - \end{alltt} - You should see something like: - \begin{alltt} - ** ./glite-jp-primary-test -s https://localhost:8901 RegisterJob - https://nonexistent.test.server/jpps_store_test_7199 - /O=CESNET/O=Masaryk University/CN=Milos Mulac - OK - ** ./glite-jp-primary-test -s https://localhost:8901 GetJobAttr - https://nonexistent.test.server/jpps_store_test_7199 - http://egee.cesnet.cz/en/Schema/JP/System:owner - OK - Attribute values: /O=CESNET/O=Masaryk University/CN=Milos Mulac - SYSTEM Thu Feb 16 14:40:02 2006 - .... - Attribute values: - car FILE Thu Feb 16 14:40:02 2006 - \end{alltt} - \item \emph{Start JP index server, using history query}\\ - \item \emph{Check content of IS database}\\ - \begin{alltt} - mysql -u jpis -e "select * from jobs;" jpis - \end{alltt} - You should get 50 results, similar to: - \begin{alltt} -| jobid | dg_jobid -| ownerid | aclid | ps -+----------------------------------+---------------------------------+ -| 7bd73b18b33410ba605fba99dbdd803f | https://nonexistent.test.server/jpps_store_test_5993 -| 5864429d57da18e4ecf9ea366c6b2c9c | NULL | https://localhost:18950 | -... -50 rows in set (0.00 sec) - \end{alltt} -\end{enumerate} -\result{} Expected results in the IS database content check (last step). - - -\subsubsection{Incremental feed - simple tests} -%- register feed -%- upload job to PS -%* check PS and IS output - -\req\ Clean JP-PS and JP-IS database. - -\how\ -\begin{enumerate} - \item \emph{Start JP primary server} - \item \emph{Start JP index server, using continuous query} - \item \emph{Registerjob} - \begin{alltt} - ./jpps-test -s https://localhost:18950 RegisterJob - https://nonexistent.test.server/jpps_store_test_6880 "/O=CESNET/O=Masaryk - University/CN=Milos Mulac" - OK - \end{alltt} - \jpps\ - \begin{alltt} - [22004] client DN: /O=CESNET/O=Masaryk University/CN=Milos Mulac - __jpsrv__RegisterJob https://nonexistent.test.server/jpps_store_test_6881 - /O=CESNET/O=Masaryk University/CN=Milos Mulac - feed to https://scientific.civ.zcu.cz:8902, job https://nonexistent.test.server/ - jpps_store_test_6881 - \end{alltt} - \jpis\ - \begin{alltt} - ... - [21984] incoming request - __jpsrv__UpdateJobs - ... - glite_jpis_lazyInsertJob: owner '/O=CESNET/O=Masaryk University/CN=Milos Mulac' - found - glite_jpis_insertAttrVal: (http://egee.cesnet.cz/en/Schema/JP/System:owner) - sql=INSERT INTO attr_52942b8c70bab8491ab5d3b9713d79f5 (jobid, value, full_value, - origin) VALUES ( - '6e436919404778b75cd27eef266190bb', - 'S:/O=CESNET/O=Masaryk University/CN=Milos Mulac', - 'S:/O=CESNET/O=Masaryk University/CN=Milos Mulac', - '1' -) - glite_jpis_insertAttrVal: (http://egee.cesnet.cz/en/Schema/JP/System:regtime) ... - ... - \end{alltt} - - \item \emph{Start upload} - \begin{alltt} - ./jpps-test -s https://localhost:18950 StartUpload - https://nonexistent.test.server/jpps_store_test_6880 - urn:org.glite.jp.primary:lb 1234 text/plain - OK - Destination: gsiftp://scientific.civ.zcu.cz:8960//home/mulac/jp/internal/ - data/5864429d57da18e4ecf9ea366c6b2c9c/1889/jpps_store_test_6880/lb - Commit before: Sat Mar 17 10:12:48 2007 - \end{alltt} - \jpps\ - \begin{alltt} - [22004] client DN: /O=CESNET/O=Masaryk University/CN=Milos Mulac - data_basename: (null) - \end{alltt} - \jpis\ - nothing - \item \emph{globus-url-copy} - \begin{alltt} - globus-url-copy file:/home/mulac/src/ORG/org.glite.jp.primary/build/job.6880 - gsiftp://scientific.civ.zcu.cz:8960//home/mulac/jp/internal/ - data/5864429d57da18e4ecf9ea366c6b2c9c/1889/jpps_store_test_6880/lb - \end{alltt} - \jpps\ - nothing \\ - \jpis\ - nothing \\ - \noindent\textbf{Other:} - File specified in gsiftp URL should be created. - \item \emph{Commit upload} - \begin{alltt} - ./jpps-test -s https://localhost:18950 CommitUpload - gsiftp://scientific.civ.zcu.cz:8960//home/mulac/jp/internal/data/ - 5864429d57da18e4ecf9ea366c6b2c9c/1889/jpps_store_test_6880/lb - OK - \end{alltt} - \jpps\ - \begin{alltt} - [22004] client DN: /O=CESNET/O=Masaryk University/CN=Milos Mulac - glite_jpps_match_file: https://nonexistent.test.server/jpps_store_test_6880 lb (null) - lb_plugin: opened 8 events - lb_plugin: close OK - feed to https://scientific.civ.zcu.cz:8902, job https://nonexistent.test.server/ - jpps_store_test_6880 - \end{alltt} - \jpis\ - \begin{alltt} - ... - __jpsrv__UpdateJobs - ... - glite_jpis_insertAttrVal: (http://egee.cesnet.cz/en/Schema/LB/Attributes:CE) - sql=INSERT INTO attr_c47f78255056386d2b3da6d506d1f244 (jobid, value, - full_value, origin) VALUES ( - '39a0a14f4fc084fbb466728986e5ea2f', - 'S:destination CE/queue', - 'S:destination CE/queue', - '3' - ) - ... - \end{alltt} - \end{enumerate} - -\result{} Expected results in logs. - - -\subsubsection{Incremental feed} -%- register feed -%- upload jobs to PS one by one -%* check IS contents (matching jobs should turn up, others not) - -\req\ Clean JP-PS and JP-IS database. - -\how\ -\begin{enumerate} - \item \emph{Start JP primary server} - \item \emph{Start JP index server, using continuous query} - \item \emph{Register job to PS} - The same as in previous test case. - - \item \emph{Check output of IS}\\ - You should see incomming connection logs, and among them - several times something like: - \begin{alltt} - - INSERT INTO attr_52942b8c70bab8491ab5d3b9713d79f5 (jobid, value, - full_value, origin) VALUES ( - '6f4866f3e4f8204c269449e6924d73c0', - 'S:/O=CESNET/O=Masaryk University/CN=Milos Mulac', - 'S:/O=CESNET/O=Masaryk University/CN=Milos Mulac', - '1') - .... - \end{alltt} - \item \emph{Check content of IS database}\\ - Do the same test as in previous test case. It must give you the same - result. You can also look whether the insert from previous step was - successful: - \begin{alltt} - mysql -u jpis -e "select * from - attr_52942b8c70bab8491ab5d3b9713d79f5;" jpis - \end{alltt} - should return: - \begin{alltt} -| jobid | value -| full_value | origin | -+----------------------------------+-----------------------------------+ -| 76698aabbf5d60dfa5b42c279e1f0e8c | S:/O=CESNET/O=Masaryk University/CN=Milos -Mulac -| S:/O=CESNET/O=Masaryk University/CN=Milos Mulac | 1 | - \end{alltt} -\end{enumerate} -\result{} Expected database INSERTs in the JP-IS (last two steps). - -\subsubsection{Multiple feeds at time} -\TODO{TBD} - -\subsubsection{Advanced feed features (to be implemented)} -- remove (not implemented in PS yet) -- splitted info about one job (check that the PS doesn't duplicate - attribute values) - probably covered in 3.2 - - -\subsubsection{PS-IS AuthZ} -\TODO{Not implemented yet} - -\subsection{IS queries} - - -%TBD: insert job sets via JP-IS interaction or directly? -% - better to populate database directly, independent on previous chain -% -%All basic tests: -%- clear IS database -%- insert prepared job set -%- ask queries and check answers -%- clear database -% -%TBD: Is one job set enough? -% - better to have one complete set -% - -A majority of test from this chapter is automated by shell -script. The script is located in \texttt{org.glite.jp.index} module -under \texttt{example/query-tests} directory and called \texttt{run-test.sh}. -It is available as a part of JP index server RPM package. - -\begin{hints} -The testing shell script is highly configurable via -environmental varibles. Please, run the script (run-test.sh) with -'-?' option to get list of all variables and their meaning, if you are -not satisfied with default setting. -\end{hints} - -\subsubsection{Simple query} -This test starts new index server instance, creates testing DB -and populate it with prepared data sample. Then simple query is given -to server, answer is checked with supposed return output and -cleanup is done. - - -\how\ Run \texttt{run-test.sh} - -\begin{hints} -The query is in file test/simple\_query.in and has following - form: (status=Ready) -\end{hints} - -\subsubsection{Complex query test} -This is similar to simple query test, only tested query is more complicated. - -\how\ Run \texttt{run-test.sh} - -\begin{hints} -The query is in file test/complex\_query.in and has followhing - form: (status=Done OR status=READY) AND (user!=God) -\end{hints} - -\subsubsection{Feed \& query test} -This test starts testing index server, feeds it by -mimicing bahaviour of primary storage server by sending data -via soap call, and then asks the index server using a complex -query. After that it checks the responce and does cleanup. - -More precise description of steps: -\begin{enumerate} - \item Simulation of response from a primary storage, making appropriate - changes in JP-IS database (inserts feedid). - \item Invocation of updateJobs wsdl call, normally invoked by JP-PS, and - sending this way some data to the JP-IS which stores them in its database. - \item Invocation of queryJobs wsdl call, normally called by user - program, obtaining previously inserted data. Test query used here has form - (status=Done OR status=Ready) AND (user!=God). -\end{enumerate} - -\how\ Run \texttt{run-test.sh} - -\subsubsection{AuthZ checks} -This test verifies that qeury responses are properly restricted by -authorization checks. Currently only implicit ACLs are implemented -inside JP-IS server, so explicit ACLs and its evaluation is to be implemented. - -There are 3 scenarios to be verified: -\begin{itemize} - \item Authorization (checking ownership) is swithed off (IS with -n - option). This scenario is tested by simple query test described above. - \item Only user jobs are returned and jobs not owned by the user posing - the query are not covered by the query response. This scenario is - covered by Feed \& query test described above. - \item Check that queries to jobs not owned by the IS user are - returning empty response. The same behaviour as simple query test - described above but with user credential not matching job - owner. This test is implemented by \texttt{run-test.sh} under AuthZ - check part. -\end{itemize} - -\subsubsection{Another supposed tests not implemented yet} - -\begin{itemize} - \item Check "origin" behaviour -- queries with origin tag - \item IS CLI tests -- use prepared config files and command line parameters - and check expected QueryJobs contents -\end{itemize} - - -\subsection{IS standalone advanced features} -\TODO{Not implemented yet} - -\subsubsection{Server startup} - -\paragraph{Reboot persistency / configuration vs. database content} - situations handling -- prepared config files -- checking behaviour (how?) after reboot with different config file - -\paragraph{Registration of PS feeds} -! already covered by 3 -- prepared config files -- checking appropriate FeedIndex calls - -\subsubsection{Admin interface} -\TODO{Admin interface not implemented yet} - -\subsubsection{Type plugin} -\TODO{type plugin tests -- to be designed, future type plugin implementation} - -\subsection{Deployment} -\TODO{tests on JP deployment process} -\TODO{TBD} - diff --git a/org.glite.jp.doc/src/JPAG-Troubleshooting.tex b/org.glite.jp.doc/src/JPAG-Troubleshooting.tex deleted file mode 100644 index c4397a4..0000000 --- a/org.glite.jp.doc/src/JPAG-Troubleshooting.tex +++ /dev/null @@ -1,6 +0,0 @@ -\section{Troubleshooting} -\TODO{} - -\subsection{Debugging} -\subsection{Fine tuning the performance} - diff --git a/org.glite.jp.doc/src/JPAG.tex b/org.glite.jp.doc/src/JPAG.tex deleted file mode 100644 index ba6d840..0000000 --- a/org.glite.jp.doc/src/JPAG.tex +++ /dev/null @@ -1,48 +0,0 @@ -\documentclass{egee} -%\usepackage{doxygen} - -\input{definitions} - -\title{Job Provenance} -\Subtitle{Administrator's Guide} -\author{CESNET EGEE II JRA1 team} -\DocIdentifier{EGEE-II....} -\Date{\today} -\Activity{JRA1: Middleware Engineering and Integration} -\DocStatus{DRAFT} -\Dissemination{PUBLIC} -\DocumentLink{http://...} - -\Abstract{ This administrator's guide explains how to administer the Job -Provenance (\JP) service. Several deployment scenarios are described together -with the installation, configuration, running and troubleshooting steps. } - -\begin{document} - -\input{frontmatter} -\newpage -\tableofcontents - -\newpage -\input{JPAG-Introduction} - -\newpage -\input{JPAG-Installation} - -\newpage -\input{JPAG-Configuration} - -\newpage -\input{JPAG-Running} - -\newpage -\input{JPAG-Testing} - -\newpage -\input{JPAG-Troubleshooting} - -\nocite{jgc} -\bibliographystyle{unsrt} -\bibliography{lbjp} - -\end{document} diff --git a/org.glite.jp.doc/src/JPDG-Introduction.tex b/org.glite.jp.doc/src/JPDG-Introduction.tex deleted file mode 100644 index a1edd45..0000000 --- a/org.glite.jp.doc/src/JPDG-Introduction.tex +++ /dev/null @@ -1,4 +0,0 @@ -\section{Introduction} - -\TODO{Best practices :)} - diff --git a/org.glite.jp.doc/src/JPDG-WS.tex b/org.glite.jp.doc/src/JPDG-WS.tex deleted file mode 100644 index 80d84cf..0000000 --- a/org.glite.jp.doc/src/JPDG-WS.tex +++ /dev/null @@ -1,34 +0,0 @@ -\section{Web Service Interface} - -In source code tree the WSDLs are located in these files:\\ -\texttt{org.glite.jp.ws-interface/src/JobProvenanceIS.xml,\\ -org.glite.jp.ws-interface/src/JobProvenancePS.xml,\\ -org.glite.jp.ws-interface/src/JobProvenanceTypes.xml -} - -\TODO{Add more info about the Web Service Interface...} - -% JPWS reference: -{ -\parindent0pt -\def\chapter#1{} -\def\section#1{\subsection{#1}} -\def\subsection#1{\par\medskip\textbf{#1}\par} - -\let\odesc=\description -\let\oedesc=\enddescription -\renewenvironment{description}{\odesc\itemindent=1em -\listparindent=2em -}{\oedesc} -%\renewenvironment{description}{\list{}{\labelwidth 5cm\leftmargin 5cm}} -%{\endlist} - -\let\null=\relax - -% this file was manually generated using db2latex (http://db2latex.sourceforge.net) -% from org.glite.jp.ws-interface/build/doc-html.xml -% TODO: generate it automatically here in Makefile - -\input{jpws} -} - diff --git a/org.glite.jp.doc/src/JPDG.tex b/org.glite.jp.doc/src/JPDG.tex deleted file mode 100644 index c591987..0000000 --- a/org.glite.jp.doc/src/JPDG.tex +++ /dev/null @@ -1,36 +0,0 @@ -\documentclass{egee} - -\input{definitions} - -\title{Job Provenance} -\Subtitle{Developer's Guide} -\author{CESNET EGEE II JRA1 team} -\DocIdentifier{EGEE-II....} -\Date{\today} -\Activity{JRA1: Middleware Engineering and Integration} -\DocStatus{DRAFT} -\Dissemination{PUBLIC} -\DocumentLink{http://...} - -\Abstract{This developer's guide explains how to use the Job Provenance (\JP) -service API, namely the Web Services Interface is described in details together with -programing examples. } - -\begin{document} - -\input{frontmatter} -\tableofcontents - -\newpage -\input{JPDG-Introduction} - -\newpage -\input{JPDG-WS} - -\newpage -\nocite{jgc} -\bibliographystyle{unsrt} -\bibliography{lbjp} - -\end{document} - diff --git a/org.glite.jp.doc/src/JPUG-Introduction.tex b/org.glite.jp.doc/src/JPUG-Introduction.tex deleted file mode 100644 index 36b8e6b..0000000 --- a/org.glite.jp.doc/src/JPUG-Introduction.tex +++ /dev/null @@ -1,693 +0,0 @@ -\section{Introduction} - -The Job Provenance (\JP) service is primarily designed to provide a permanent -storage and advanced querying interface to the data about Grid jobs and -the environment they were run in. This information is to be used for -statistical purposes, lookup for patterns in the Grid behavior and also -for job re-submission. - -The Job Provenance extends the data model specified by the \LB service -with additional information about each job---most specifically the input -and output data files---and also information about the run time -environment. - -The Job Provenance must fulfill rather contradictory requirements. It -must keep detailed information about each job, the environment the job -run in and the affected files, as possible. On the other hand, being a -permanent service, the job records must be kept reasonably small -to fit into reasonable sized storage system. Given the expected number of -jobs on large scale Grids---\eg the EGEE already -reports\footnote{\url{http://egee-jra2.web.cern.ch/EGEE-JRA2/QoS/JobsMetrics/JobMetrics.htm}} -20k jobs per day, that is 7.5M jobs per year, a number of jobs before the -large experiments will be deployed---the \JP must also support very -efficient searching and querying features. Another problem is associated -with the long life span of the \JP service. It must be expected that the -data formats will change over the time, while the \JP is expected to deal -with old and new data formats in a uniform way. They can be achieved via -extensibility of the JP data model. - -As the data collection serviced by the JP will extensively grow, it is -impossible to rely only on the primary data when navigating through it. -Users must be able to add annotations to individual job records and these -annotations serve two primary purposes---to help in organizing the \JP -data and to be a source of additional information, not provided directly -by the automated collection of primary data. Even annotations must follow -the WORM (write once read many times) semantics, as they are always added -on top of the already stored data, never re-writing the old annotations. -Work with the most recent set of annotations as well as ability to -inspect the history of annotations must be supported. - -Fig.~\ref{fig:psinter} depicts interaction between Job Provenance and -other Grid middleware components (on the example of the gLite -infrastructure). -\begin{figure}[ht] - \centering - \includegraphics[scale=0.5]{images/JP-interactions} - \caption{Data flow into gLite Job Provenance} - \label{fig:psinter} -\end{figure} - -\subsection{Concepts} -\ludek{\TODO{Obrazky moc nezapadaji do soucasne struktury textu :-(}} - -\subsubsection{Data gathering}% -\label{data} -%\begin{comment} -%\todo{job record, job attributes} \todo{open design, scalable} -%\todo{we have very small persistent record (jobid, owner, timescale), -% set of associated files and we maintain corresponding plugins (by what?) to -% interpret them; metadata are mined, indexed and provided on demand} -%\todo{attribute namespaces---a glue to source of metadata} -%\end{comment} - -The primary data organization in \JP is on a per job basis, a concept -taken from the \LB data organization. Every data item stored in JP is -associated to a~particular Grid job. As the overall storage capacity -requirements may become enormous, we store only volatile data which are -neither stored reliably elsewhere nor are reproducible by the job. -The data gathered from the gLite middleware fall into the following categories: -\begin{itemize} -\item job inputs, directly required for job re-running -\begin{itemize} -\item complete job description (JDL) as submitted to WMS -\item miscellaneous input files (gLite WMS input sandbox) provided by the user -(but job input files from remote storage \emph{are not} copied to JP) -\end{itemize} -\item job execution track, witnessing the environment of job execution -\begin{itemize} -\item complete \LB data, for example when and where the job was - planned and executed, how many times and for what reasons it was - resubmitted etc. -\item ``measurements'' on computing elements, \eg versions of installed -software, environment settings etc. -\end{itemize} -\end{itemize} -In addition, the service allows the user to add arbitrary annotations to -a~job in a form of ``name = value'' pairs. -These annotations can be recorded either during the job execution or at any time -afterward. -Besides providing information on the job (\eg it was a~production-phase -job of a particular experiment) these annotations may carry -information on relationships between the job and other entities -like external datasets, forming the desired data provenance record. - -%\TODO{zduraznit WORM semantiku + citace na IPAW} -Once a~piece of data is recorded for a~job, it can be never updated or -replaced. -New values can be recorded% -\footnote{It seems to make sense only for the annotations, not the -middleware data, and the current implementation makes this restriction. -However, it can be relaxed without principal impact.} -but the old values are always preserved. -Consequently the recorded history cannot be lost. - - -\subsubsection{Data representation}% -\label{attrib} - -The \JP concept distinguishes between two views on the processed data. -The data are stored in the \JP in the \emph{raw representation}. -Two input modes are assumed, depending mainly on the size -and structure of the data: -\begin{itemize} -\item Small size \emph{tags} in a form of ``name = value'' pairs, -enter the system via its primary interface (as a~web service operation -in the current implementation). -``Value'' is assumed to be a literal, without any structure that \JP should -be aware of. - -\item \emph{Bulk files}, \eg the complete dump of \LB data or the job input -sandbox, are uploaded via a~suitable transfer protocol% -\footnote{The current implementation supports \texttt{gsiftp://} only but -other protocols can be easily added.}. -Files are supposed to be structured. -However, they are stored ``as is'', and upon upload they are annotated with -format identification, including version of the format. -JP allows installing plugins that handle particular file formats (see bellow), -understanding the file structure and extracting required information. -\end{itemize} - -Most data manipulation is done using the \emph{logical view}. -Any piece of information stored in JP is represented -as a~value of a particular named \emph{attribute}. Tags (user -annotations) map to attributes in a~straightforward way, name and value -of the tags becoming name and value of an attribute. An uploaded file is -usually a~source of multiple attributes, which are automatically extracted -via \emph{plugins}. JP defines a~\emph{file-type plugin interface API}. The -task of the plugin is parsing a~particular file type and providing calls -to retrieve attribute values. - -To avoid naming conflicts even with future attributes, -an attribute name always falls into a~namespace. -Currently we declare three different namespaces: for JP system attributes -(\eg job owner or -registration time), attributes inherited from \LB, and unqualified user tags. - -\ludek{ -This representation unifies the user annotations, the ``system'' -middleware data and information extracted from uploaded files into -a~single view.} - -\iffalse -An attribute value must be always representable in the form of a~printable -string. -If it is not the case for a~native attribute type, -converting rules must be provided by a~plugin (dynamically loadable library) -implementing a~specified API. -\fi - -We keep the scheme symmetric, which means that none of the currently declared attribute -namespaces is privileged in any sense. -However, it may present a~vulnerability\Dash a~malicious user may try -to override a~\JP system attribute using the user annotation interface. -Therefore each attribute value carries a~further \emph{origin classification}: -currently \emph{system}, \emph{user} (recorded as tag), and -\emph{file} (found in an uploaded file). - -Finally, as JP does not support updating data intentionally -(see Sect~\ref{data}), multiple values of an attribute are allowed. -The order in which the values were recorded can be reconstructed from -timestamps attached to each value, getting the ``attribute update'' semantics -if it is required. - -Attributes, representing the logical view, is the only way to specify queries on JP. -However, once the user knows an~actual jobid, bulk files can be retrieved -in the raw form, too (assumed to be useful in the case of input sandboxes -reused for job re-execution). - -\subsubsection{Layered architecture}% -\label{layered} -\JP is formed of two classes of services: the permanent \emph{Primary Storage} -(JPPS) accepts and stores job data -while possibly volatile and configurable \emph{Index Servers} (JPIS) -provide an optimized querying and data-mining interface to the end-users. - -The expected large amount of stored data yields a requirement on -maximal compactness of the storage. -The raw data should be compressed, -and the set of metadata kept with each job must be minimal. -\JP defines a~set of \emph{primary attributes} which are maintained -by JPPS for each job. -Jobid is the only mandatory primary attribute, -other suggested ones are the job owner, submission time, -and the virtual organization. -All other attributes are retrieved from the raw data only when requested. - -The restricted set of primary attributes prohibits user queries to be served -by the JPPS directly (with the only exception of the known jobid). -Due to the expected low selectivity of primary attributes such queries -would result in processing large number of job records, overloading -the server when the queries became frequent. - -These contradictory requirements (compactness vs. performance) had to be -resolved at another component layer. -The main idea is preprocessing the huge \JP dataset with several queries, -each of them covering a~superset of one expected class of user queries -(\eg jobs of particular VO, submitted in certain period). -If these super-queries are chosen carefully, they retrieve only a~small -fraction of the primary data. Their results can thus be stored (or cached) -in a~richer form, including various indices, hence being suitable -for fast response to user queries. -Querying JPPS in this way and maintaining the cache of the query result -is the task of Index Servers in the \JP architecture. - -Relationship of JPPS and JPIS is a many-to-many---a~single JPIS can query -multiple JPPS's and vice versa, a~single JPPS is ready to feed multiple JPIS's. - -The query conditions restrict the dataset in terms of the matching job records. -Similarly, the query specifies a~set of attributes to retrieve, -reducing also considerably the amount of retrieved data per each matching job. - -Index Servers query JPPS in two modes: in \emph{batch mode} JPIS is populated -with all JPPS content matching the query. In this way JPIS can be created -from scratch, despite the ope-ration is rather heavy for JPPS. -On the other hand, the \emph{incremental mode} allows JPIS to subscribe with -JPPS to receive new matching records as well as updates to already stored -records whenever new data arrive to JPPS. -This mode allows existing JPIS to be kept up to date while it is -still lightweight for JPPS. - -Finally, the described layer of JPIS's needn't be the only one. -The architecture (despite not the current implementation) allows -building another layer of JPIS's with many-to-many relationship with -the previous layer instances, combining their data, providing support -for other specific user queries etc. - -\subsection{Prototype implementation} - -The \JP prototype implementation% -\footnote{a part of the gLite middleware 3.x} -follows the described architecture. - -\subsubsection{Primary Storage}% -\label{primary} -\iffalse -The JP \emph{Primary Storage} (JPPS) is a~permanent service responsible -for gathering the job data and their long-term archival. -The primary data are kept in as compact form as possible, and -only minimal metadata (jobid and owner, registration time) are maintained -and indexed. -\fi - -A~single instance of JPPS, shown in Fig.~\ref{fig:psinter}, -is formed by a~front-end, exposing -its operations via a~web-service interface% -\footnote{Described in detail in ``EGEE Middleware -Design'',\\ \url{https://edms.cern.ch/document/487871/}, -documented web service definitions can be found at \\ -\url{http://egee.cesnet.cz/en/WSDL/}}% -, and a~back-end, responsible -for actual data storage and providing the bulk file transfer interface. -The front-end metadata (the primary attributes for each job, -authorization information, and JPIS subscription data) -are stored in a~relational database (currently MySQL). - -The back-end uses Globus \texttt{gridftp} server enriched with authorization -callbacks accessing the same database to check whether a~user -is allowed to upload or retrieve a~given file. -Both the front- and back-ends share a~filesystem so that the file-type plugins -linked into the front-end access their files via POSIX~I/O. - -JPPS operations fall into the following categories: -\begin{itemize} -\item\emph{Job registration.} -Each job has to be explicitly registered with JP. -Currently the registration is done transparently by the \LB server -upon job submission (in parallel with the job registration in \LB, -though not blocking the job submission). - -\item\emph{Tag recording.} -Add user tags (annotations) in the ``name = value'' form to JP job records. - -\item\emph{Bulk file upload.} -File properties (type, optional name etc.) -are specified via the front-end interface, the upload itself goes -directly to the back-end (using \texttt{gridftp} transfer). - -\item\emph{Index Server feed} allows JPIS to ask for batch feed -as well as register for incremental updates. - -\item\emph{Data retrieval.} -The only direct data retrieval supported by JPPS is keyed by -the jobid. -Both individual attributes and the whole files can be retrieved. -\end{itemize} - -Primary Storage covers the first set of requirements specified -for a Job Provenance (see Sect.~\ref{jp:req}), \ie storing a~compact job -record, allowing the user to add annotations, and providing elementary -access to the data. - -\subsubsection{Index Server} -Index Servers are created, configured, and populated semi-dynamically -according to particular user community needs. -The configuration is formed by: -\begin{itemize} -\item one or more Primary Storages to contact, -\item conditions (expressed in terms of \JP attributes) -on jobs that should be retrieved, -\item list of attributes to be retrieved, -\item list of attributes to be indexed\Dash a~user query must refer -to at least one of these for performance reasons. -\end{itemize} -The set of attributes and the conditions specify the set of data that -is retrieved from JPPS, and they reflect the assumed pattern -of user queries. - -The current JPIS implementation keeps the data also in a~MySQL database. -Its schema is flexible, reflecting the server configuration -(columns are created to hold particular attribute value, as well as indices). - -The JPIS interface operations fall into the following categories: -\begin{itemize} -\item\emph{Responses to user queries.} -A~query specifies a~set of attributes to retrieve and -conditions determining the set of matching jobs. -The structure of the query language is identical to~\LB---% -it allows two-level nesting of comparisons of an attribute -with a~constant value. - -\item\emph{JPIS-JPPS communication} implements the data flow from JPPS to JPIS. - -\item\emph{Administrative} calls to change JPIS configuration -without interfering with its normal operation. -\end{itemize} - - -\iffalse % puvodni text, pouzity jen jako zdroj materialu v predchozim - -The role of \emph{Index Servers} (JPIS) is processing and re-arranging the data -from Primary Storage(s) into a~form suitable for frequent and complex user -queries. - -We can divide implemented operation into three categories: -\begin{description} -\item[Responses to user queries.] -The main purpose of JPIS is to enable user complex queries. - -\begin{itemize} -\item The \texttt{QueryJobs} operation enables to ask the user query and -specify which attributes of matched jobs are returned. -\end{itemize} - -\item[JPIS-JPPS communication.] Internal call enabling data exchange between. -JPIS and JPPS. -\begin{itemize} -\item The \texttt{UpdateJobs} Called by JPPS as a response to \texttt{FeedIndex} -request. Updates information on jobs in JPIS, according to what JPPS -currently knows. -\end{itemize} - -\item[Administration.] Admin calls for changing configuration on the fly. -\begin{itemize} -\item The \texttt{AddFeed} Called by JPIS admin tool to ask new primary storage server to feed it. Updates information on JPPS in index server, according to what JPPS currently knows. -\item The \texttt{GetFeedIDs} Called by JPIS admin tool to find out its open feeds. -\item The \texttt{DeleteFeed} Called by JPIS admin tool to remove one feed session. -\end{itemize} - -\end{description} - - -\subsubsection{Index Server} -\label{index} -%\begin{wrapfigure}{r}{.5\hsize} -\begin{figure} - \centering - \includegraphics[scale=0.5]{images/JP-query} - \caption{Index Server interactions} - \label{fig:query} -\end{figure} -%\end{wrapfigure} - - - -A~typical interaction is shown in Fig.~\ref{fig:query}.%\\[-8mm] - -\begin{enumerate} -\item The user queries one or more JPIS, receiving a~list of ID's -of matching jobs. -\item JPPS is directly queried for additional job attributes or URL's of -stored files. -\item The required files are retrieved. -\end{enumerate} - -The current format of the user query is a~list of lists of conditions. -A~condition is comparison (less, greater, equal) of an attribute -\wrt\ a~constant. Items of an~inner list must refer to the same attribute -and they are logically or-ed. -Finally the inner lists are logically and-ed. -According to our experience with the \LB\ service, -this query language is powerful enough to satisfy user needs -while simple enough to allow efficient implementation. - -Index Servers are created, configured, and populated semi-dynamically -according to particular user community needs. -The configuration is formed by: -\begin{itemize} -\item one or more Primary Storages to contact, -\item conditions on jobs that should be retrieved, -\item list of attributes to be retrieved, -\item list of attributes to be indexed\Dash a~user query must refer -to at least one of these for performance reasons. -\end{itemize} -The set of attributes and the conditions specify the set of data that -is retrieved from JPPS, and it reflects the assumed pattern -of user queries. -The amount of data fed into a~single JPIS instance is assumed to be -only a~fraction of data in JPPS, -both regarding the number of jobs, and the number of distinct attributes. - -Communication between JPIS and JPPS involves two -complementary web-service operations: -JPIS calls the \texttt{FeedIndex} operation of JPPS, -specifying the list of attributes and conditions. -Unlike the user queries, the query on JPPS is a~single and-ed list, -allowing less complex processing on JPPS where significantly larger -data set are involved. -JPPS responds by calling the \texttt{UpdateJobs} operation of JPIS -(repeatedly to split up large dataset). - -The following flags in the \texttt{FeedIndex} call specify the query mode: -\begin{itemize} -\item \emph{history}\Dash JPPS should process all its stored data, -giving the user the guaranty that if -her query is a~logical restriction of the JPIS configuration, -it returns a~complete result. -This type of query is usually necessary to populate JPIS but it imposes -rather high load on JPPS. -\item \emph{continuous}\Dash JPIS registers with JPPS for receiving -\emph{future updates} when data matching the query arrive. -This type of query allows JPIS to be kept up to date while imposing minimal -load on JPPS. -\end{itemize} - -The current JPIS implementation keeps the data also in a~MySQL database. -Its schema is flexible, reflecting the Server configuration -(columns are created to hold particular attribute value, as well as indices). -There is no prescribed relationship between Primary Storage and Index Server -installations. -An Index Server may retrieve data from multiple Primary Storages -and vice versa. - -\fi % konec materialu - -\subsubsection{Scalability and deployment} -Having evaluated a~random sample of \LB data on approx. 1000 jobs, -we claim that the usual size of a~complete \LB data dump varies -from 2\,kB to 100\,kB, with very rare exceptions (less than 1\,\%) -of sizes up to 5\,MB. -However, these plain text files contain repeating patterns and they can -be compressed with the ratio of 1:4--1:20 in the typical cases -and even higher for the large files. -Therefore the assumption of 10\,kB compressed \LB dump per job is a~fairly -safe upper limit. -Unfortunately, we were not able to do a~similar assessment for job sandbox -sizes. Expecting the sandboxes to contain only miscellaneous input files -we work with the hypothesis of 100\,kB--1\,MB sandbox size. - -The current statistics for the entire infrastructure of the EGEE project -report the rate of 20,000 jobs per day, while the middleware -performance challenges aim at one million jobs per day. - -\begin{table} -\begin{tabular}{r|c|c|c} -\textbf{job rate $\backslash$ size} & \textbf{10\,kB \LB} & \textbf{100\,kB sandbox} & \textbf{1\,MB sandbox} \\ -\hline -current 20\,k/day & 73\,GB/year & 730\,GB/year & 7.3\,TB/year \\ -challenge 1\,M/day & 3.6\,TB/year & (36\,TB/year) & (360\,TB/year) -\end{tabular} -\caption{Expected aggregate storage size (whole EGEE)} -\label{t:jpsize} -\end{table} - -\begin{table} -\begin{tabular}{r|c|c|c} -\textbf{job rate $\backslash$ size} & \textbf{10\,kB \LB} & \textbf{100\,kB sandbox} & \textbf{1\,MB sandbox} \\ -\hline -current 20\,k/day & 2.3\,kB/s & 23\,kB/s & 230\,kB/s \\ -challenge 1\,M/day & 115\,kB/s & (1.15\,MB/s) & (11.5\,MB/s) -\end{tabular} -\caption{Expected aggregate incoming data rate (whole EGEE)} -\label{t:jprate} -\end{table} - - -Tables~\ref{t:jpsize} and \ref{t:jprate} use the discussed numbers to derive -the per-year storage size and per-second incoming data rate requirements on Job -Provenance. -The sandbox numbers for the 1\,M job challenge are shown in parentheses -because of being rather hypothetical\Dash -in order to achieve the required job throughput at WMS side, -the jobs must be submitted in fairly large \emph{collections} -(chunks of approx. 100--10,000 individual jobs) that share a~single input -sandbox% -\footnote{This statement is based on informal discussions with WMS developers. -The targeted WMS instance throughput at the time of this manuscript preparation -was 1 sandbox-less job per second, \ie\ 84.6\,k such jobs per day (achieving -the 1\,M job rate with WMS clustering only), -while the sandbox handling overhead is considered -to be unsustainable at this rate.}. -Therefore the real aggregate storage and throughput requirements on \JP can be -reduced by the factor of at least 100. - -Despite these figures are aggregate for the whole huge EGEE infrastructure, -they clearly show that the requirements could be met even with a~single -reasonably sized server. - -JP is designed to support many-to-many relationship of JPPS and JPIS -instances. Therefore there are no strict design requirements on the -number and structure of installations. -However, for practical reasons (some emerge from Sect.~\ref{jpusage}), -it is desirable to keep just small number of well known -JPPS's permanent services. -Typical setup can be one \JP per a~larger virtual organization, or even -one \JP shared by several smaller ones. -The outlined numbers show that this approach should not face technical -limits. -On the other hand, JPIS's are expected to be set up and configured -semi-dynamically, according to the varying needs of even small user -communities. - - -\iffalse -Only limited number of JPPS installations must be deployed even on -a~large Grid to concentrate the provenance data. At most one JPPS per -a~virtual organization is envisaged for the EGEE environment. -This mean each JPPS must be able to deal with data on millions of jobs. The -typical size of an \LB\ dump is around 10\,kB per compressed record, -and gLite users are encouraged not to use large job sandboxes, too. -Consequently, the back-end storage requirements are at the order of 10-100\,GB. -JPPS metadata are formed by a~single tuple for -each job and for each file, with unique indices on jobid and file name. -The used MySQL database engine is capable to handle millions of such records. -\fi - - -\subsection{Use patterns}% -\label{jpusage} - -\subsubsection{Storing data} -Propagation of data from other middleware components to \JP is done -transparently. -The user may affect it indirectly by -specifying the destination JPPS and gathered data extent -(\eg whether to store the job to \JP at all, or which sandbox files to keep) -via parameters in the job description. These settings -may be overridden by the WMS or CE policies. - -The user stores data to \JP directly when recording annotations -(Sects.~\ref{data} and~\ref{primary}). \ludek{JPPS instance which stores -the information on the job must be known, see bellow.} - -\subsubsection{Single job processing} -When full information on a~particular job is required (\eg for the -job re-execution), -the JPPS instance which keeps the job data must be contacted. -If it is known (\eg the only JPPS serving particular VO), the data retrieval -is straightforward using JPPS interfaces, as the jobid is the primary -key to access JPPS data. - -However, if JPPS for the job is not known, it must be looked up -using JPIS query. -Depending on the amount of the user's knowledge of the job details -\wrt\ JPIS configurations (\eg JPIS configured to request information -on jobs submitted in a~certain time interval is aware of the user's -job only if its submission time falls into this interval) -it may be necessary to query multiple JPIS's to find the particular job. - -\subsubsection{Job information retrieval} -Besides preserving the job data -the principal purpose of the \JP is to provide job information -according to some criteria, -freeing the user of the burden to keep complete records on her jobs. - -As discussed in Sect.~\ref{layered} the searches cannot be served -directly by the JPPS. -Therefore, the search must be done with querying a~particular JPIS -which configuration matches the user query: -\begin{itemize} -\item The user query criteria overlap with the JPIS configuration. -\Eg it makes little sense to look for -jobs submitted in May 2005 at a~JPIS restricted to be fed with data on -jobs submitted in 2006 only. - -\item The criteria trigger a~configured index at JPIS, avoiding -full scan through its data. -\end{itemize} -Again, it may be necessary to query multiple JPIS's and concatenate -the partial results. -Currently we do not address the potentially non-trivial problem of finding -suitable JPIS's. -It falls out of the scope of the \JP level, and should be preferably -solved at the service discovery level. - -\iffalse -Such a~search would result in scanning through all data stored in JP -which are expected to be huge, being unacceptable for frequent user queries. -Instead we define an architecture that allows -batch pre-processing of configurable queries. -The result of such query, a~superset of certain user query type, is further -indexed in order to provide fast response to concrete user queries. - - -We foreseen the following typical user queries: -\begin{itemize} -\item The user knows a jobid, job isn't longer in the \LB. He will ask the - JPPS to get all or selected attributes of job. -\item The user knows a jobid, job is in a terminal state. The user wants - all files (LB event dump, sandbox) stored by JP for further processing. -\item The user is looking for jobs with specific properties. In this case - (no jobid known) a JPIS must be used. There are the same query interface - provided by any JPIS but if a particular query can be answered by - the given JPIS depends on its configuration. - The user should know the proper JPIS to use for its particular - needs. -\item The user wants to add a user tag (annotation) to a job. He must know - the jobid(s). -\end{itemize} -\fi - - -\subsection{Security} - -The data stored in the \JP are in fact potentially more -sensitive as they also include information about the inputs and are kept -for eternity. All the interaction between components is -authenticated and only encrypted channels are used to transfer data. The -basic security model is inherited from the \LB, thus user and server -certificates are used for encryption and TLS is used for channel -encryption. - -The data in JPPS and JPIS are not encrypted as this would create a -problem with permanent depository of encryption keys. We also cannot use -users' public keys to encrypt the data as this would complicate sharing -and also endanger the data in case of private key loss. Instead, with a -very limited number of JPPS's deployed, we trust the \JP servers. Each -JPPS keeps list of authorized components (\LB, Resource Brokers,~\ldots) -that are allowed to upload data to the \JP server. - -The sensitive nature of data requires also strong authorization support. -While currently only implicit ACLs (only the job owner has access to -the data) are supported, we plan to use the VOMS -based authorization service to provide a fine grained (at the user/group -level) of authorization control. In the same way as in the \LB, users -will be able to specify who is authorized to access the data stored in -the \JP. In the current model, we plan to support read-only sharing, the -annotations should be always stored by the job owner only. However, a~way -to transfer ownership of the data to another person must be also -developed, to cover employees leave and even a death. - -\iffalse -\subsubsection{Internal and external interactions} - -Fig.~\ref{fig:psinter} shows interaction of \JP with other gLite components, -Fig.~\ref{fig:query} shows internal data flow in \JP as well as interaction -with the end-user (JP client). -In this section we discuss the involved operations and data transfers. -Unless specified otherwise, the communication occurs as web-service calls -over SSL-authenticated connections. -The interfaces are described in detail in~document ``EGEE Middleware Design'' -\footnote{https://edms.cern.ch/document/487871/}, -documented web service definitions can be found at \url{http://egee.cesnet.cz/en/WSDL/}. - -\emph{Search for jobs.} -The user does not known actual jobid's and searches for a~set of -jobs matching particular conditions (see Sect.~\ref{user}). -Such query cannot be served directly by \JP Primary Storage due to performance -reasons\Dash it would typically require sweep through a~large set of primary data. -On the contrary, the query must be directed to an Index Server that was -already populated with jobs matching a~broader condition. -By calling -the Index Server \texttt{QueryJobs} operation, the user -retrieves -a~set of jobid's with addresses of Primary Storage -where the data on the jobs are stored. - - -\subsubsection{Scalability and extensibility} -\todo{configuration, describe index server administrator role} -\todo{modularity (plug-ins), type plugin IS?} -\todo{najit kompromis pro rozdeleni informaci sem a do Service and - administrators view dole, nebo jedno zrusit} -\fi - diff --git a/org.glite.jp.doc/src/JPUG-Tools.tex b/org.glite.jp.doc/src/JPUG-Tools.tex deleted file mode 100644 index 2dbf1f7..0000000 --- a/org.glite.jp.doc/src/JPUG-Tools.tex +++ /dev/null @@ -1,25 +0,0 @@ -\section{Tools description} - -In this section we give a description of the tools that are installed -together with the \verb'glite-jp-client'. These are the only \JP\ tools that a -regular grid user may need to use. - - -% This file was manually generated using db2latex (http://db2latex.sourceforge.net) -% from org.glite.jp.index/doc/glite-jpis-client.sgml -% TODO: update the original file -% TODO: generate it automatically here in Makefile -{ -\parindent0pt -\def\section#1{\subsection{#1}} -\newcommand{\dbz}{} -\newcommand{\docbooktolatexpipe}{\ensuremath{|}} -\newskip\docbooktolatexoldparskip -\input{glite-jpis-client} -} - - -\input{jpimporter} - - -\input{gui} diff --git a/org.glite.jp.doc/src/JPUG-UseCases.tex b/org.glite.jp.doc/src/JPUG-UseCases.tex deleted file mode 100644 index 0218f4a..0000000 --- a/org.glite.jp.doc/src/JPUG-UseCases.tex +++ /dev/null @@ -1,159 +0,0 @@ -\section{Job Provenance use cases} - -\subsection{Prerequisities} - -\subsubsection{LB/JP relationship} -When JP deployed, any job in a terminal state will disappear from LB -after preconfigured timeout (one week for example). If a user wants -any information about such a job before this timeout (or before it -reach a terminal state) he must use the LB service (please refer to LB -user's guide). After that timeout he must use the JP service. - -% TODO: update -% For LB configuration please see gLite installation guide. For a -% technical description of LB-JP interactions please see -% \texttt{http://egee.cesnet.cz/en/JRA1/LB-JP-interaction-guide.pdf}. - -\subsubsection{JP service location} -To call JP you need to know JP services address. There are two services: -\begin{itemize} -\item JP primary storage (JPPS)\\ - From JP design point of view there are only few PS in the - grid. Expected implementation is that these JPPS locations - are preconfigured in a UI instance while one of them is configured as - default JPPS. -\item JP index server (JPIS)\\ - Each index server is build (configured and started) by site/VO/user - group administrator (or even "senior user") based on given - community needs (expected queries and its optimization). So in - principle the index server location for a given query is to be - provided by the user. We expect that the UI instance will provide - mechanism allowing selection from preconfigured JPIS servers list. -\end{itemize} - -\subsection{JP use case 1 -- get job info} - -The scenario: -\begin{itemize} -\item The user wants information about a particular job. He knows a - job id. Job isn't longer in the LB. Procedure: Ask the JPPS to get all - or selected attributes of job. -\end{itemize} - -The implementation: -\begin{itemize} - \item Let a user to specify attributes to be returned. See section - \ref{attributes}. - \item Call GetJobAttributes operation of a JPPS and display the values - returned. -\end{itemize} - -Examples and hints: -\begin{itemize} - \item \texttt{org.glite.jp.primary/examples/jpps-test.c}\\ - This utility is used for all JPPS operations. Some hints how to use it - can be find in the test plan document. -\end{itemize} - -\subsection{JP use case 2 -- get job files} - -The scenario: -\begin{itemize} - \item The user knows a job id, job is in a terminal state. The user wants - all files (LB event dump, sandbox) stored by JP for futher processing. -\end{itemize} - -The implementation: -\begin{itemize} - \item Call GetJobFiles operation of a JPPS. You will get a list of URLs - which can be used to download the files. -\end{itemize} - -Examples and hints: -\begin{itemize} - \item The same as use case 1. -\end{itemize} - -\subsection{JP use case 3 -- job lookup} - -The scenario: -\begin{itemize} - \item The user is looking for jobs with specific properties. In this case - (no job id known) a JPIS must be used. There are the same query interface - provided by any JPIS but if a particular query can be answered by - the given JPIS depends on its configuration (configuration - determines which attributes are uploaded by PS to IS, and which of - them are indexed). - \item The user should know the proper JPIS to use for its particular - needs. - \item The scenario can continue by the JP use cases number 1 and 2 described - above (JPIS answer will contain job ids and identification of JPPSs - to ask for all available JP data about the jobs). -\end{itemize} - -The implementation: -\begin{itemize} - \item The user will select a JPIS and provide query. The JPIS operation - QueryJobs is called and list of jobs matching the query is returned. -\end{itemize} - -Examples and hints: -\begin{itemize} - \item JPIS CLI tool\\ - org.glite.jp.index/examples/jpis-client.c - - \item example in org.glite.jp.index/examples/jpis-test.c (starting - from line 161) -\end{itemize} - -\subsection{JP use case 4 -- job annotation} - -The scenario: -\begin{itemize} - \item The user wants to add a user tag (annotation) to a job. He must know - the job id(s) (or use the JP use case number 3 to find it). -\end{itemize} - -The implementation: -\begin{itemize} - \item Call RecordTag operation of JPPS for the job(s) to add requested - user tag. -\end{itemize} - -Examples and hints: -\begin{itemize} - \item The same as use case 1. -\end{itemize} - - -\subsection{Job attributes} -\label{attributes} -Job attributes are referenced by its names. Each attribute belongs to -one namespace (represented by a prefix in the attribute name). - -A namespace is defined by a service (currently we have one for LB and -one for JP) providing its data to the JP or a user group/experiment -who wants to attach its own data to the job. - -It is expected that UI have preconfigured list of available namespaces -and XML schema for each namespace (the schema can be automatically -retrieved based on the namespace name). A list of available attributes -is generated from these schemas when user have to select attributes to -be retrieved from JP. - -\begin{itemize} - \item The namespaces (schema is available at the URL representing namespace):\\ - http://egee.cesnet.cz/en/Schema/LB/Attributes\\ - http://egee.cesnet.cz/en/Schema/JP/System <<<<<<<(NOT YET)\\ - \item There are header files with known names of attributes generated from - these schema files in our build procedure:\\ - org.glite.lb.server/build/jp\_job\_attrs.h\\ - org.glite.jp.common/interface/known\_attr.h <<<<<<<\\ -\end{itemize} - - -\subsection{Authentication and authorization} -All the calls must be authenticated by user credentials. In the -current JP release only implicit ACLs are available -- the job -information is available for job owner only. - diff --git a/org.glite.jp.doc/src/JPUG.tex b/org.glite.jp.doc/src/JPUG.tex deleted file mode 100644 index afa410f..0000000 --- a/org.glite.jp.doc/src/JPUG.tex +++ /dev/null @@ -1,43 +0,0 @@ -\documentclass{egee} - -\input{definitions} - -\title{Job Provenance} -\Subtitle{User's Guide} -\author{CESNET EGEE II JRA1 team} -\DocIdentifier{EGEE-II....} -\Date{\today} -\Activity{JRA1: Middleware Engineering and Integration} -\DocStatus{DRAFT} -\Dissemination{PUBLIC} -\DocumentLink{http://...} - -\Abstract{This user's guide explains how to use the Job Provenance (\JP) -service from the user's point of view. The service architecture is described -thoroughly. Examples on using \JP\ are given... } - -\begin{document} - -\input{frontmatter} -\tableofcontents - -\newpage -\input{JPUG-Introduction} - -\newpage -\input{JPUG-Tools} - -\newpage -\input{JPUG-UseCases} - -%\appendix -%\newpage -%\input{JPUG-Appendix} - -\newpage -\nocite{jgc} -\bibliographystyle{unsrt} -\bibliography{lbjp} - -\end{document} - diff --git a/org.glite.jp.doc/src/LB-JP-interaction.tex b/org.glite.jp.doc/src/LB-JP-interaction.tex deleted file mode 100644 index f8dae21..0000000 --- a/org.glite.jp.doc/src/LB-JP-interaction.tex +++ /dev/null @@ -1,74 +0,0 @@ -\subsection{Interaction with Logging and Bookeeping (\LB)} - -In this section we describe the interaction of JP with Logging and Bookkeeping -(\LB) service. The data flows between LB and JP services are displayed in -Figure~\ref{fig:LB-JP-interactions}. These flows are numbered and one can use -this numbers to find additional information about each flow in -table~\ref{tab:LB-JP-interactions}. - -\begin{figure}[htpb] - \centering - \includegraphics[width=0.9\hsize]{LB-JP-interaction-details} - \caption{LB to JP interactions detail overview} - \label{fig:LB-JP-interactions} -\end{figure} - -\begin{table}[htpb] - \centering - \begin{tabular}{|c|p{3cm}|l|p{9cm}|} - \hline - &spool directory&initiated by&description\\ - \hline - \hline - 1&lb.export.dump, - lb.export.dump.keep&lb-exporter& - Export of LB job records into spool directory. It uses glite-lb-purge utility. LB-exporter reads this spool directory in a regular manner and implement next processing of LB dumps. Optionally it can keep handled dumps in lb.export.dump.keep.\\ - \hline - 2&lb.export.jpreg&LB server&When new job come to the LB server - it stores its - registration into the spool directory. It is responsibility of - JP-importer process to handle such registrations.\\ - \hline - 3&lb.export.jpdump, - lb.export.jobs, - lb.export.jobs.keep&lb-exporter& - LB-exporter do its processing of LB dumps (they are in per job form) and passes on it to the JP-importer using the spool directory lb.export.jpdump and temporary storage lb.export.jobs. It can keep the job files for futher usage.\\ - \hline - 4&none&jp-importer&JP importer handles registrations received from LB - server and sends it to the JP primary server front-end (using its WS - interface).\\ - \hline - 5&none&jp-importer&JP importer handles LB dumps received from LB - exporter and sends it to the JP primary server back-end using its - gridftp interface.\\ - \hline - \end{tabular} - \caption{LB to JP data flows description} - \label{tab:LB-JP-interactions} -\end{table} - - -Notes: -\begin{itemize} - \item Only JP Primary Storage (JPPS) server is involved in described - data flows. JP Index Servers are not part of this picture (they are - feeded via corresponding JPPS). - \item Only flows number 4 and 5 are designed to be inter-host. All - the other interactions assume the components are on the same host and - do use access to a shared filesystem. - \item Data flow number 1 use glite-lb-purge utility (see its - documentation) and passes to it argument from lb.export.purgeargs - clause of the deployment configuration file. This argument contain - the timeouts controlling after how long period of time a job - staying in a terminal state is to be purged from the LB server. - \item The LB exporter have a feature to store LB job event dumps in a - directory for further handling (e.g. for job statistic tool). This behaviour - is controled by lb.export.jobs.keep deployment config file clause (leave - this clause empty if you don't use dumps for futher handling). - \item The LB exporter also have a feature to keep all handled LB - dumps (in glite-lb-purge format) in filesystem. This feature is - controlled by lb.export.dump.keep. - \item LB exporter is not a deamon, it's periodic invocation is - provided by cron deamon. -\end{itemize} - diff --git a/org.glite.jp.doc/src/README b/org.glite.jp.doc/src/README deleted file mode 100644 index 663de30..0000000 --- a/org.glite.jp.doc/src/README +++ /dev/null @@ -1,12 +0,0 @@ -This is the official documentation for Job Provenance Service. -It consists of the following documents: - -JPUG.pdf - Job Provenance User's Guide -JPAG.pdf - Job Provenance Admin's Guide -JPDG.pdf - Job Provenance Developer's Guide - -Please, report all bugs to EU EGEE Bug Tracking System located at -https://savannah.cern.ch/bugs/?func=additem&group=jra1mdw - -Feel free to send us your non-bugs comments to email -egee-jra1@lindir.ics.muni.cz diff --git a/org.glite.jp.doc/src/copyright.tex b/org.glite.jp.doc/src/copyright.tex deleted file mode 100644 index 981ab62..0000000 --- a/org.glite.jp.doc/src/copyright.tex +++ /dev/null @@ -1,24 +0,0 @@ -% Taken from: -% https://twiki.cern.ch/twiki/bin/view/EGEE/EGEEgLiteSoftwareLicense -% -\vfill{} - -{\bf -Copyright} \copyright\ {\bf Members of the EGEE Collaboration. 2004. See -\href{http://www.eu-egee.org/partners/}{http://www.eu-egee.org/partners/} for -details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at - -\begin{center} -\href{http://www.apache.org/licenses/LICENSE-2.0}{http://www.apache.org/licenses/LICENSE-2.0} -\end{center} - -Unless required by applicable law or agreed to in writing, software distributed -under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR -CONDITIONS OF ANY KIND, either express or implied. See the License for the -specific language governing permissions and limitations under the License. -} - diff --git a/org.glite.jp.doc/src/definitions.tex b/org.glite.jp.doc/src/definitions.tex deleted file mode 100644 index 34a61ed..0000000 --- a/org.glite.jp.doc/src/definitions.tex +++ /dev/null @@ -1,24 +0,0 @@ -\usepackage{xspace} -%\usepackage{doxygen} -\usepackage{alltt} -\usepackage{comment} - -\def\LB{L\&B\xspace} -\def\JP{JP\xspace} -%\def\eg{e.\,g.} -\def\eg{for example\xspace} -\def\Eg{For example\xspace} -%\def\ie{i.\,e.} -\def\ie{that is\xspace} -\def\wrt{with respect to\xspace} -\def\Dash{---\penalty-1000} - -\long\def\TODO#1{\par\noindent\textbf{TODO:} {\sl#1}\par} -\long\def\ludek#1{} - -\def\path#1{{\normalfont\textsf{#1}}} -\def\code#1{\texttt{#1}} - -\specialcomment{hints}{\par\noindent\textbf{Hints: }\begingroup\slshape}{\endgroup} - -\hyphenation{plug-in} diff --git a/org.glite.jp.doc/src/egee.cls b/org.glite.jp.doc/src/egee.cls deleted file mode 100644 index e0a03bf..0000000 --- a/org.glite.jp.doc/src/egee.cls +++ /dev/null @@ -1,507 +0,0 @@ -% egee.cls: -% -% $Id$ -% -% $Log$ -% Revision 1.1.1.1 2007/11/13 17:42:10 jpospi -% initial import -% -% Revision 1.13 2004/08/31 19:24:27 szamsu -% Fixing overfull problem in page headers. Saving the logo and reusing it later, instead of loading in again. -% -% Revision 1.12 2004/08/09 14:03:54 szamsu -% proper IST number -% -% Revision 1.11 2004/08/03 17:02:21 szamsu -% Information Society Infrastrcutures logo replacing the old IST logo -% -% Revision 1.10 2004/08/03 13:34:37 szamsu -% Removed 'compat2' option on geometry, because it has also specified -% 'scale{0.8,0.9}' for page size, which we define otherwise. Added the -% 'centering' and 'includeheadfoot' options, which were defined in -% 'compat2'. -% -% Revision 1.9 2004/07/09 16:06:52 leanne -% Removed the Lead partner which is not used in egee -% -% Revision 1.8 2004/06/03 09:56:11 leanne -% removed lead partner - -% Revision 1.8 2004/06/03 09:56:11 diana -% updated the front page -% -% Revision 1.7 2004/05/26 09:38:55 leanne -% Removed DocumentLink in pdfinfo - it was causing errors -% -% Revision 1.6 2004/05/26 08:36:58 leanne -% Updated IST number in template -% -% Revision 1.5 2004/05/24 13:25:04 diana -% added template for egee latex documents -% -% Revision 1.4 2004/05/17 10:56:51 diana -% added compat2 option to geometry and hypertex option to hyperref to get logo and links back on the page -% -% Revision 1.3 2004/02/18 18:08:48 leanne -% Modified Document identifiers to mauch the EGEE Word templates -% -% Revision 1.2 2004/02/18 17:23:21 leanne -% Changed Work Package to Activity. Included definition of Document Link. -% -% Revision 1.1.1.1 2004/02/18 11:17:44 leanne -% Initial version of EGGE LaTeX Style files based on the EDG LaTeX Style -% -% -% Revision 1.0 2004/02/17 leanne -% Took the datagrid.cls file and modified it for the EGEE project -% Original Authors: -% Frohner Akos -% Diana Bosio -% Paul Millar -% Thanks are due to Norman Gray -% -\NeedsTeXFormat{LaTeX2e} -\ProvidesClass{egee}[2002/06/20 EGEE LaTeX Class] -\typeout{EGEE LaTeX class -- 2002/06/13 Rock Lobster!} -% -%% Notes: This class file tries, as largely as possible, to copy the Microsoft -%% Word template document EDMS 2098656 v2.2. Differences and notes are listed -%% below: -%% o The Word Template uses 11pt for the main body, but 12 point -%% occasionally. Any such occurrence of 12pt is mapped into 11pt in this -%% class-file. -%% o This class inherits 11pt article. In that class Huge=30pt and -%% LARGE=22pt, which matches the required point-size for the title page. -%% o The parskip in the Word doc is exactly 1.4mm (0.7mm above and below). -%% Here we've taken the liberty of adding some glue to make things fit -%% better. -%% o The Word Template shows all the (sub)sections on the contents page in -%% capitals and subsubsections in italics. The LateX class doesn't. - -%% Interface - example of an option, should we want to use these later. -%\newif\ifmonotitle\monotitlefalse - -%\DeclareOption{mono}{\monotitletrue} - -\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} -\ProcessOptions - - -% Inherit! -\LoadClass[11pt]{article} - -% Necessary packages: -\RequirePackage{lastpage} -\RequirePackage{tabularx} -\RequirePackage{pslatex} -\RequirePackage{times} -\RequirePackage{verbatim} -\RequirePackage{geometry} -\RequirePackage{url} - -\usepackage[hang,bf,small]{caption} - -% -% We now define a new \if command to test for PDF being enabled. -% It is important because loading graphicx overrides the definition -% of \pdfoutput and sets it to true even when PDF is not enabled. -% Use \ifpdf instead of \ifx\pdfoutput\undefined hereafter. -% - -\newif\ifpdf -\ifx\pdfoutput\undefined - \pdffalse - % \typeout{PDF _not_ defined} -\else - \pdfoutput=1 - \pdftrue - % \typeout{PDF _is_ defined} -\fi - -\ifpdf - \usepackage[pdftex, - pdfpagemode={UseOutlines},bookmarks=true,bookmarksopen=true, - bookmarksopenlevel=0,bookmarksnumbered=true, - hypertexnames=false,colorlinks,linkcolor={blue}, - citecolor={blue},urlcolor={red}, - pdfstartview={FitV}]{hyperref} -\else - \usepackage[hypertex]{hyperref} -\fi - -\ifpdf - \usepackage[pdftex]{graphicx} - \pdfcompresslevel 9 - \pdfadjustspacing 1 -\else - \usepackage[dvips]{graphicx} -\fi - -\usepackage{color} - -\def\footsize{5mm} - -%% -%% PAGE GEOMETRY DEFINITIONS -%% -% From Template file -\geometry{centering,includeheadfoot} -\geometry{a4paper,top=12.5mm,headheight=12.5mm,headsep=5mm,foot=\footsize,footskip=13.3mm,bottom=12.5mm} -\geometry{right=25mm,left=25mm} - - -% APM -- I don't think these are right, my impression is above is correct -%\geometry{a4paper,margin=0.98in,headheight=0.72in} - - -%% -%% PAGE COLOUR DEFINITIONS -%% -\definecolor{blue}{rgb}{0.1,0.1,0.5} -\definecolor{lightgrey}{gray}{0.65} - - -% paulm's prefered name ... -\def\bibname{References} - -\setlength{\parindent}{0pt} -\setlength{\parskip}{1.4mm plus 0.4mm minus 0.2mm} - -\def\@defaultfooter{ - \def\@oddfoot{\vbox to \footsize {% - {\color{blue}\hrule width \textwidth height 1pt depth 0pt}% - \vfil - \small\hbox to \textwidth{\ISTNumber% - \hfil - \hbox{\colorbox{yellow}{\MakeUppercase{\@Dissemination}}}% - \hfil - \hbox{\thepage/\pageref{LastPage}}}% - }% - }% -} - - -\def\ps@title{% - \@defaultfooter - \def\@oddhead{\hbox to \textwidth{\LargeEGEELogo\hfil\ISTLogo}} -} - -\def\ps@headings{% - \@defaultfooter - \def\@oddhead{\vbox to \headheight{% -%\hrule width \textwidth height 1pt\relax - \vbox to 0.75\headheight{% - \hbox to \textwidth{% - \hbox to 0pt{\EGEELogo\hss}% - \hfil - \hbox to 8cm{% - \vbox to 0.75\headheight{% - \vfil - \parbox{8cm}{% - \centering\color{blue}% - \textbf{\MakeUppercase{\@title}}% -\ifx\@Subtitle\@empty\else - \par\textbf{\scriptsize\@Subtitle}% -\fi - }% - \vfil - }% - \hss}% - \hfil -%\hbox to 0pt{\vrule width 1pt height 10pt depth 0pt \hss}% -%% {\scriptsize\setlength{\parskip}{0pt}\setlength{\topsep}{0pt}% -%% % \vbox to 0.75\headheight{% -%% \parbox{4cm}{x% -%% \begin{flushright}% -%% \textit{Doc. Identifier}:\\ -%% \textbf{\@DocIdentifier}\\ -%% \vfil -%% \textit{Date}: \textbf{\@Date} -%% \end{flushright}% -%% }% -%% % }% -%% }% -\hbox to 0pt{\hss\vbox to 0.75\headheight{%\hrule -\tiny%\scriptsize -\parfillskip0pt -\leftskip 0pt plus 1fil -\parskip0ex -\textit{Doc.\ Identifier}: -\par -\textbf{\@DocIdentifier} -\vfil -\textit{Date}: \textbf{\@Date} -%\hrule -}}% -% \hbox to 4cm{\scriptsize -% \vbox to 0.75\headheight{% -% \parbox{4cm}{ -% \halign{\hfill####\cr -% \textit{Doc. Identifier}:\cr -% \textbf{\@DocIdentifier}\cr -% % \noalign{\vfil} -% \textit{Date}: \textbf{\@Date}\cr -% }}% -% \vfil -% }% -% }% - }% - }% -%\hrule width \textwidth height 1pt\relax - \vfil\vskip 2.5mm\relax - {\color{blue}\hrule width \textwidth height 1pt depth 0pt}% - }% - }% -} - -\pagestyle{headings} - -\setlength{\captionmargin}{1cm} - -% image file extensions respective to the output format -\ifpdf - \DeclareGraphicsExtensions{.jpg,.pdf,.png} - \pdfcompresslevel=9 -% \pdfinfo{ /Title (\@DocumentLink) } - \pdfinfo{ /Title (EGEE) } -\else - \DeclareGraphicsExtensions{.eps} -\fi - -\def\frontboxwidth{10.6cm}% - - - -%% -%% Define our title page -%% -\AtBeginDocument{ -\pagestyle{title}% -\hbox{}% Force top of page -\vfill -{\centering - \Huge\bf\textsf{\textcolor{blue}{EGEE}}\\[20mm]% - \LARGE\sc\textsf{\bf \@title}\\[5mm]% - \ifx\@Subtitle\@empty\else - \normalsize\textsf{\@Subtitle}\\[10mm]% - \fi - \ifx\@DeliverableId\@empty\else - \LARGE\sc\textsf{\bf \@DeliverableId}\\[5mm]% - \fi -}% -\vfill -\hbox to \textwidth{ - \hfil - \vbox{ - {\color{blue}\hrule width \frontboxwidth height 1mm depth 0pt} - \hbox to \frontboxwidth{\sf - \begin{tabularx}{\frontboxwidth}{l>{\raggedright\arraybackslash}X} - Document identifier: & \textbf{\@DocIdentifier}\\[3mm] - Date: & \textbf{\@Date}\\[3mm] - Activity:& \textbf{\@Activity}\\[3mm] - Document status: & \textbf{\@DocStatus}\\[3mm] - Document link:& \textbf{\@DocumentLink}\\[3mm] - \end{tabularx} - } - {\color{blue}\hrule width \frontboxwidth height 1mm depth 0pt} - } -} -\vfill -{\sf\underline{Abstract}: \@Abstract} -\vfill -\newpage % end of the first page -\pagestyle{headings} -\setcounter{tocdepth}{3} -} % End of AtBeginningDocument - - -% -% EGEE style small-capital section titles. -% -% The numbering is aligned with the WinWord style, -% although it is not common in the english typography... -% -\newcommand{\sectionbreak}{\newpage} -\renewcommand{\thesection}{\arabic{section}.} -\renewcommand{\thesubsection}{\thesection\arabic{subsection}.} -\renewcommand{\thesubsubsection}{\thesubsection\arabic{subsubsection}.} - -\renewcommand\section{\@startsection {section}{1}{\z@}% - {-3.5ex \@plus -1ex \@minus -.2ex}% - {2.3ex \@plus.2ex}% - {\normalfont\Large\bfseries\sffamily\scshape}} - -\renewcommand\subsection{\@startsection{subsection}{2}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\normalfont\large\bfseries\sffamily\scshape}} -\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\normalfont\normalsize\bfseries\sffamily\scshape}} - - - -%% APM NEED TO REDEFINE section -%\titleformat{\section}{\Large\bfseries\sffamily\scshape}{\thesection}{1em}{} -%\titlecontents{section} [2em] {\vspace*{4pt}} -% {\large \sc \bfseries \contentslabel{2em}} -% {\large \sc \bfseries \hspace*{-2em}} -% {\large \textbf{\titlerule*[1ex]{.}\contentspage}} [\vspace*{4pt}] - -%\titleformat{\subsection}{\large\bfseries\sffamily\scshape}{\thesubsection}{1em}{} -%\titlecontents{subsection} [5em] {} -% {\sc \contentslabel{3em}} -% {\sc \hspace*{-3em}} -% {\titlerule*[1ex]{.}\contentspage} - - -% -% common constants -% -\def\ISTNumber{INFSO-RI-508833} -\newsavebox{\@EGEELogo} -\savebox{\@EGEELogo}{\includegraphics[height=0.75\headheight]{egee}} -\def\EGEELogo{\usebox{\@EGEELogo}} -\def\LargeEGEELogo{\includegraphics[height=\headheight]{egee}} -\def\ISTLogo{\includegraphics[height=\headheight]{isi}} - -% -% parameters to be supplied by the author -% -\def\Subtitle#1{\gdef\@Subtitle{#1}} -\gdef\@Subtitle{\@latex@warning@no@line{No \noexpand\Subtitle given}} - -\def\DeliverableId#1{\gdef\@DeliverableId{#1}} -\gdef\@DeliverableId{\@latex@warning@no@line{No \noexpand\DeliverableId given}} - -\def\DocIdentifier#1{\gdef\@DocIdentifier{#1}} -\gdef\@DocIdentifier{\@latex@warning@no@line{No \noexpand\DocIdentifier given % - (e.g. EGEE-JRA1-TEC-edmsId-v0-1)}} - -\def\Date#1{\gdef\@Date{#1}} -\gdef\@Date{\@latex@warning@no@line{No \noexpand\Date given % - (e.g. 01/01/2004)}} - -\def\Activity#1{\gdef\@Activity{#1}} -\gdef\@Activity{\@latex@warning@no@line{No \noexpand\Activity given % - (e.g. JRA1 Middleware Engineering and Integration )}} - -\def\DocStatus#1{\gdef\@DocStatus{#1}} -\gdef\@DocStatus{\@latex@warning@no@line{No \noexpand\DocStatus given % - (e.g. DRAFT, WORKING, DELIVERED)}} - -\def\Dissemination#1{\gdef\@Dissemination{#1}} -\gdef\@Dissemination{\@latex@warning@no@line{No \noexpand\Dissemination given % - (e.g. PUBLIC, INTERNAL, ...)}} - -\def\DocumentLink#1{\gdef\@DocumentLink{#1}} -\gdef\@DocumentLink{\@latex@warning@no@line{No \noexpand\DocumentLink given % - (e.g. http://cern.ch)}} - -\long\def\Abstract#1{\gdef\@Abstract{#1}} -\gdef\@Abstract{\@latex@warning@no@line{No \noexpand\Abstract given}} - -%% -%% Define the abstract using an environment abstract - -% -% This will produce the mailto link in the PDF file -% -% -% We use the URL package, which does this nicely. The old way (\HTTP) was -% a bit buggy as it had problems with '~'s and '_'s -% -\urlstyle{sf} -\ifpdf - \newcommand{\Email}[1]{\href{mailto:#1}{<{#1}>}} - \newcommand{\HTTP}[1]{\href{#1}{\url{#1}}} -\else - \newcommand{\Email}[1]{\textsf{<{#1}>}} - \newcommand{\HTTP}[1]{\url{#1}} -\fi - - -% -% We now redifine \part and \section so that the table of contents -% has the sections/parts in upper case. -% -% Note: need to use \uppercase because \MakeUppercase is not robust -% -\def\@part[#1]#2{% - \ifnum \c@secnumdepth >\m@ne - \refstepcounter{part}% - \addcontentsline{toc}{part}{\thepart\hspace{1em}\uppercase{#1}}% - \else - \addcontentsline{toc}{part}{\uppercase{#1}}% - \fi - {\parindent \z@ \raggedright - \interlinepenalty \@M - \normalfont - \ifnum \c@secnumdepth >\m@ne - \Large\bfseries \partname\nobreakspace\thepart - \par\nobreak - \fi - \huge \bfseries #2% - \markboth{}{}\par}% - \nobreak - \vskip 3ex - \@afterheading} - -\def\@sect#1#2#3#4#5#6[#7]#8{% - \ifnum #2>\c@secnumdepth - \let\@svsec\@empty - \else - \refstepcounter{#1}% - \protected@edef\@svsec{\@seccntformat{#1}\relax}% - \fi - \@tempskipa #5\relax - \ifdim \@tempskipa>\z@ - \begingroup - #6{% - \@hangfrom{\hskip #3\relax\@svsec}% - \interlinepenalty \@M #8\@@par}% - \endgroup - \csname #1mark\endcsname{\uppercase{#7}}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - \texorpdfstring{\uppercase{#7}}{#7}}% - \else - \def\@svsechd{% - #6{\hskip #3\relax - \@svsec #8}% - \csname #1mark\endcsname{\uppercase{#7}}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - \texorpdfstring{\uppercase{#7}}{#7}}}% - \fi - \@xsect{#5}} - -% \addcontentsline{toc} expands to \contentsline{NAME} -% which in turn expands to \l@NAME. So, to specify -% the table of contents, we must define \l@chapter, \l@section, -% \l@subsection, ... ; to specify the list of figures, we must define -% \l@figure; and so on. Most of these can be defined with the -% \@dottedtocline command, which produces a contents line with dots -% between the title and the page number. It works as follows: -% -% \@dottedtocline{LEVEL}{INDENT}{NUMWIDTH} -% LEVEL : An entry is produced only if LEVEL < or = value of -% 'tocdepth' counter. Note, \chapter is level 0, \section -% is level 1, etc. -% INDENT : The indentation from the outer left margin of the start of -% the contents line. -% NUMWIDTH : The width of a box in which the section number is to go, -% if TITLE includes a \numberline command. -% - -\def\l@part{\@dottedtocline{1}{4em}{2.0em}} -\def\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}} -\def\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}} -\def\l@paragraph{\@dottedtocline{4}{7.0em}{4.1em}} -\def\l@subparagraph{\@dottedtocline{5}{10em}{5em}} - diff --git a/org.glite.jp.doc/src/frontmatter.tex b/org.glite.jp.doc/src/frontmatter.tex deleted file mode 100644 index 732dcec..0000000 --- a/org.glite.jp.doc/src/frontmatter.tex +++ /dev/null @@ -1,40 +0,0 @@ -\begin{center} -{\bf Delivery Slip} -\end{center} -\begin{tabularx}{\textwidth}{|l|l|l|X|X|} -\hline - & {\bf Name} & {\bf Partner} & {\bf Date} & {\bf Signature} \\ -\hline -{\bf From} & & & & \\ -\hline -{\bf Reviewed by} & & & & \\ - -\hline -{\bf Approved by} & & & & \\ -\hline -\end{tabularx} - -\begin{center} -{\bf Document Change Log} -\end{center} - -\begin{tabularx}{\textwidth}{|l|l|X|X|} -\hline -{\bf Issue } & {\bf Date } & {\bf Comment } & {\bf Author } \\ \hline - -\hline -\end{tabularx} - -\begin{center} -{\bf Document Change Record} -\end{center} - -\begin{tabularx}{\textwidth}{|l|l|X|} -\hline -{\bf Issue } & {\bf Item } & {\bf Reason for Change } \\ \hline - -\hline -\end{tabularx} - -\input{copyright} -\clearpage diff --git a/org.glite.jp.doc/src/glite-jpis-client.tex b/org.glite.jp.doc/src/glite-jpis-client.tex deleted file mode 100644 index 7f6ba81..0000000 --- a/org.glite.jp.doc/src/glite-jpis-client.tex +++ /dev/null @@ -1,93 +0,0 @@ -% -% ------------------------------------------------------------- -% Refentry -% ------------------------------------------------------------- -\section{glite-jpis-client} -\label{glitejpisclient}\hypertarget{glitejpisclient}{}% -\label{name} - -%\section*{Nom} -glite-jpis-client --- client interface for JP IS\label{synopsis} -\subsection*{Synopsis} -\label{id2455104} -\begin{list}{}{\setlength{\itemindent}{-\leftmargin}\setlength{\parsep}{0mm}} -\item\raggedright\texttt{glite-jpis-client [ -h | --help ] [ -i | --index-server \textit{JPIS:PORT}] [ -q | --query-file \textit{IN\_FILE.XML}] [ -t | --test-file \textit{IN\_FILE.XML}] [ -e | --example-file \textit{OUT\_FILE.XML}] [ -f | --format {xml | human}]} -\end{list} - -\subsection*{DESCRIPTION} -\label{id2417458} - -{\bfseries{glite-jpis-client}} is command line interface for querying the Job Provenance Index Server. It takes the XML input, process the QueryJobs operation and returns the result in specified format. - -\subsection*{OPTIONS} -\label{id2417597} - -With no options you get simple usage message as with {\texttt{{-h}}}. - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\texttt{{-h}}}\docbooktolatexpipe{}{\texttt{{--help}}}}]\null{} -Displays usage message. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\texttt{{-i}}}\docbooktolatexpipe{}{\texttt{{--index-server}}}}]\null{} -Specifies Job Provenance Index Server as {\ttfamily\itshape{{HOST:PORT}}}. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\texttt{{-q}}}\docbooktolatexpipe{}{\texttt{{--query-file}}}}]\null{} -Process the QueryJobs operation. Requires input data in file {\ttfamily\itshape{{IN\_FILE.XML}}}, for using stdin specify {\texttt{{-}}}. - -The input and output data are in XML format with XSD schema, which can be found in {\texttt{{JobProvenanceISClient.\dbz{}xsd}}} (element QueryJobs for input and QueryJobsResponse for output). -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\texttt{{-t}}}\docbooktolatexpipe{}{\texttt{{--test-file}}}}]\null{} -Test the input data from {\ttfamily\itshape{{IN\_FILE.XML}}} (or from stdin if {\texttt{{-}}} is specified) and prints the found content. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\texttt{{-e}}}\docbooktolatexpipe{}{\texttt{{--example-file}}}}]\null{} -Write the example input data to file {\ttfamily\itshape{{OUT\_FILE.XML}}} (or to stdout if {\texttt{{-}}} is specified). The XML is valid against XSD schema in {\texttt{{JobProvananceISClient.\dbz{}xsd}}}, formating may vary according to used gsoap version. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\texttt{{-f}}}\docbooktolatexpipe{}{\texttt{{--format}}}}]\null{} -Use {\ttfamily\itshape{{FORMAT}}} as output format type. You can specify {\texttt{{xml}}} for interchangeable XML output or {\texttt{{human}}} for nice looking human readable output. -\end{description} -\noindent -\subsection*{RETURN VALUE} -\label{id2417767} - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{0}]\null{} -Success. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{-1}]\null{} -Communication error or error from the remote server. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{EINVAL}]\null{} -In most cases XML parsing error. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{other error}]\null{} -Other error from errno. -\end{description} -\noindent -\subsection*{EXAMPLES} -\label{id2417822} - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\bfseries{glite-jpis-client --example-file query.xml}}}]\null{} -Save the example query parameters to file {\texttt{{query.\dbz{}xml}}}. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\bfseries{glite-jpis-client --query-file query.xml}}}]\null{} -Queries the local index server running on default port with the query parameters specified in the file {\texttt{{query.\dbz{}xml}}}. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\bfseries{glite-jpis-client -i localhost:8902 -q - -f human}}}]\null{} -Queries the index server running on local host on the port 8902 with the query parameters from stdin and show results in non-XML form. -\end{description} -\noindent - - -\subsection*{SEE ALSO} -\label{id2418102} - -glite-jp-indexd(8) - -\subsection*{AUTHOR} -\label{id2418112} - -EU DataGrid Work Package 1, CESNET group. diff --git a/org.glite.jp.doc/src/glite_installation_guide_JP.doc b/org.glite.jp.doc/src/glite_installation_guide_JP.doc deleted file mode 100644 index a69f348fed7878f61698927cb17da7abf62fdbb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 349184 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Ì|P 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 LpSArD?}7gXNC0X* diff --git a/org.glite.jp.doc/src/glite_installation_guide_LB.doc b/org.glite.jp.doc/src/glite_installation_guide_LB.doc deleted file mode 100644 index 8dcc46478bdbdd959e2078be3b1d0c79a8868be9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174080 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�GE|oa1S(v=_!U86~cU37C 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 diff --git a/org.glite.jp.doc/src/gui.tex b/org.glite.jp.doc/src/gui.tex deleted file mode 100644 index dae3aec..0000000 --- a/org.glite.jp.doc/src/gui.tex +++ /dev/null @@ -1,3 +0,0 @@ -\subsection{GUI} - -\TODO{GUI description} diff --git a/org.glite.jp.doc/src/images/JP-interactions.cdr b/org.glite.jp.doc/src/images/JP-interactions.cdr deleted file mode 100644 index 80db3f8bf5a2bf193412d82c2e2ed043b4527ad1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49340 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

~7sT=qILC|PR?f#-da0>r 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 diff --git a/org.glite.jp.doc/src/images/JP-query.pdf b/org.glite.jp.doc/src/images/JP-query.pdf deleted file mode 100644 index e2f5c791970283b6d7d423789dabc324e4715114..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41756 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%0DK;W4)a>$E5A@IVK>A{-v`vOu!K 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 diff --git a/org.glite.jp.doc/src/images/LB-JP-interaction-details.pdf b/org.glite.jp.doc/src/images/LB-JP-interaction-details.pdf deleted file mode 100644 index 3241d856dca9bb163dde0ad68d95179d08ab0e80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72334 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ΜG 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 P082^%czLyq?*je@toEPF diff --git a/org.glite.jp.doc/src/images/LB-JP-interaction-drawing.pdf b/org.glite.jp.doc/src/images/LB-JP-interaction-drawing.pdf deleted file mode 100644 index c5826e1bf32a384ae3df94d8d3cfe189377e2f3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167722 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

*hD|(;uN|VcwwUQnf;7N}YZbjO^lpxuPcmTj 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

    aoBI={?*Tr|@o6_u$9!^c>>b0jS&Q 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%0DbbtXA2Obs1@-i?(wZ0y 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 diff --git a/org.glite.jp.doc/src/images/isi.pdf b/org.glite.jp.doc/src/images/isi.pdf deleted file mode 100644 index 4ff331cbe7bf18fb7ded3fc20ca7e25c9d9ca6ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19672 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 F!e4Asw7LKQ diff --git a/org.glite.jp.doc/src/jpimporter.tex b/org.glite.jp.doc/src/jpimporter.tex deleted file mode 100644 index cdc1945..0000000 --- a/org.glite.jp.doc/src/jpimporter.tex +++ /dev/null @@ -1,4 +0,0 @@ -\subsection{glite-jp-importer} - -\TODO{glite-jp-importer description} - diff --git a/org.glite.jp.doc/src/jpws.tex b/org.glite.jp.doc/src/jpws.tex deleted file mode 100644 index 7d36708..0000000 --- a/org.glite.jp.doc/src/jpws.tex +++ /dev/null @@ -1,599 +0,0 @@ - -% ------------------------------------------------------------- -% Chapter Job Provenance -% ------------------------------------------------------------- -\chapter{Job Provenance} -\label{id271738}\hypertarget{id271738}{}% - -% ------------------------ -% Section -\section{Primary Storage -- Overview} -\label{id271094}\hypertarget{id271094}{}% - -The Job Provenance (JP) Primary Storage Service is responsible to keep the JP data (definition of submitted jobs, execution conditions and environment, and important points of the job life cycle) in a compact and economic form. - -The JP Primary storage, as described in section 8.4 of the Architecture deliverable DJRA1.1 {\textless}\url{https://edms.cern.ch/document/594698/}{\textgreater} provides public interfaces for data storing, retrieval based on basic metadata, and registration of Index servers for incremental feed. - -Command interface to JP is completely covered by the WS interface covered here. Bulk file transfers are done via specialised protocols, currently gsiftp only. - -% ------------------------ -% Section -\section{Primary Storage -- Operations} -\label{id271756}\hypertarget{id271756}{}% - -{ -\let\dollar=\$ -\catcode`\$=\active -\let$=\dollar -\em{CVS revision: $Header$}} -\subsection{CommitUpload} -\label{op:CommitUpload}\hypertarget{op:CommitUpload}{}% - -Confirm a successfully finished file apload. - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{destination}}}}]\null{} -Destination URL returned by StartUpload before. -\end{description} -\noindent - -Outputs: N/A -\subsection{FeedIndex} -\label{op:FeedIndex}\hypertarget{op:FeedIndex}{}% - -Request for feeding a JP Index server (issued by this server). - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{destination}}}}]\null{} -Endpoint of the listening index server. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of xsd:string{\ttfamily\itshape{{attributes}}}}]\null{} -Which attributes of jobs is the index server interested in. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of \hyperlink{type:primaryQuery}{primaryQuery}{\ttfamily\itshape{{conditions}}}}]\null{} -Which jobs is the server interested in. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:boolean{\ttfamily\itshape{{history}}}}]\null{} -Data on jobs stored at PS in the past are required. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:boolean{\ttfamily\itshape{{continuous}}}}]\null{} -Data on jobs that will arrive in future are required. -\end{description} -\noindent - -Outputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{feedId}}}}]\null{} -Unique ID of the created feed session. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:dateTime{\ttfamily\itshape{{feedExpires}}}}]\null{} -When the session expires. -\end{description} -\noindent -\subsection{FeedIndexRefresh} -\label{op:FeedIndexRefresh}\hypertarget{op:FeedIndexRefresh}{}% - -Refresh an existing feed session. - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{feedId}}}}]\null{} -Existing feed session ID to be refreshed. -\end{description} -\noindent - -Outputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:dateTime{\ttfamily\itshape{{feedExpires}}}}]\null{} -New session expiration time. -\end{description} -\noindent -\subsection{GetJobAttributes} -\label{op:GetJobAttributes}\hypertarget{op:GetJobAttributes}{}% - -Query concrete attributes of a given job. - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{jobid}}}}]\null{} -The job. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of xsd:string{\ttfamily\itshape{{attributes}}}}]\null{} -Which attributes should be retrieved. -\end{description} -\noindent - -Outputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of \hyperlink{type:attrValue}{attrValue}{\ttfamily\itshape{{attrValues}}}}]\null{} -Values of the queried attributes. -\end{description} -\noindent -\subsection{GetJobFiles} -\label{op:GetJobFiles}\hypertarget{op:GetJobFiles}{}% - -Return URL's of files for a given single job. - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{jobid}}}}]\null{} -The job. -\end{description} -\noindent - -Outputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of \hyperlink{type:jppsFile}{jppsFile}{\ttfamily\itshape{{files}}}}]\null{} -List of the stored files. -\end{description} -\noindent -\subsection{RecordTag} -\label{op:RecordTag}\hypertarget{op:RecordTag}{}% - -Record an additional user tag. - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{jobid}}}}]\null{} -Job to which the tag is added. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:tagValue}{tagValue}{\ttfamily\itshape{{tag}}}}]\null{} -Name and value of the tag. -\end{description} -\noindent - -Outputs: N/A -\subsection{RegisterJob} -\label{op:RegisterJob}\hypertarget{op:RegisterJob}{}% - -Register job with the JP primary storage. - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{job}}}}]\null{} -Jobid of the registered job. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{owner}}}}]\null{} -Owner of the job (DN of X509 certificate). -\end{description} -\noindent - -Outputs: N/A -\subsection{StartUpload} -\label{op:StartUpload}\hypertarget{op:StartUpload}{}% - -Start uploading a file. - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{job}}}}]\null{} -Jobid to which this file is related. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{class}}}}]\null{} -Type of the file (URI). The server must have a plugin handing this type. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{name}}}}]\null{} -Name of the file (used to distinguish among more files of the same type). -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:dateTime{\ttfamily\itshape{{commitBefore}}}}]\null{} -The client promisses to finish the upload before this time. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{contentType}}}}]\null{} -MIME type of the file. -\end{description} -\noindent - -Outputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{destination}}}}]\null{} -URL where the client should upload the file. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:dateTime{\ttfamily\itshape{{commitBefore}}}}]\null{} -Server's view on when the upload must be finished. -\end{description} -\noindent - -% ------------------------ -% Section -\section{Index Server -- Overview} -\label{id214261}\hypertarget{id214261}{}% - -The Job Provenance (JP) Index Server is a volatile counterpart to the permanent JP Primary Storage. Index servers are populated with subsets of data from Primary storage(s) and indexed according to particular user needs. - -The interface to Index server contains three logical parts: administraive (control), system and user. The administrative part is used by run-time index server configuration tool, the system one allows Primary storage(s) to feed data into the Index server, and the user one is available to users for queries. - -% ------------------------ -% Section -\section{Index Server -- Operations} -\label{id214279}\hypertarget{id214279}{}% - -{ -\let\dollar=\$ -\catcode`\$=\active -\let$=\dollar -\em{CVS revision: $Header$}} -\subsection{AddFeed} -\label{op:AddFeed}\hypertarget{op:AddFeed}{}% - -Called by JP index serve admin tool to ask new primary storage server to feed it. Updates information on PS in index server, according to what JPPS currently knows. - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:feedSession}{feedSession}{\ttfamily\itshape{{feed}}}}]\null{} -New feed IS URL, filter and query type. -\end{description} -\noindent - -Outputs: N/A -\subsection{DeleteFeed} -\label{op:DeleteFeed}\hypertarget{op:DeleteFeed}{}% - -Called by JP index serve admin tool to remove one feed session. - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{feedId}}}}]\null{} -ID of feed to be removed. -\end{description} -\noindent - -Outputs: N/A -\subsection{GetFeedIDs} -\label{op:GetFeedIDs}\hypertarget{op:GetFeedIDs}{}% - -Called by JP index serve admin tool to find out IS open feeds - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of \hyperlink{type:feedSession}{feedSession}{\ttfamily\itshape{{feeds}}}}]\null{} -List of active feeds on IS. -\end{description} -\noindent - -Outputs: N/A -\subsection{QueryJobs} -\label{op:QueryJobs}\hypertarget{op:QueryJobs}{}% - -User query to index server. - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of \hyperlink{type:indexQuery}{indexQuery}{\ttfamily\itshape{{conditions}}}}]\null{} -Query conditions, similar to LB. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of xsd:string{\ttfamily\itshape{{attributes}}}}]\null{} -Set of attributes to be retrieved directly from index server (if any). -\end{description} -\noindent - -Outputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of \hyperlink{type:jobRecord}{jobRecord}{\ttfamily\itshape{{jobs}}}}]\null{} -List of jobs matching the query. -\end{description} -\noindent -\subsection{UpdateJobs} -\label{op:UpdateJobs}\hypertarget{op:UpdateJobs}{}% - -Called by JP primary storage as a response to FeedIndex request. Updates information on jobs in index server, according to what JPPS currently knows. - -Inputs: -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string{\ttfamily\itshape{{feedId}}}}]\null{} -Id of the feed, as returned by JPPS FeedIndex operation. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:boolean{\ttfamily\itshape{{feedDone}}}}]\null{} -Flag of completed batch feed. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of \hyperlink{type:jobRecord}{jobRecord}{\ttfamily\itshape{{jobAttributes}}}}]\null{} -Attributes per job. -\end{description} -\noindent - -Outputs: N/A - -% ------------------------ -% Section -\section{JP Common Types} -\label{id214548}\hypertarget{id214548}{}% - -{ -\let\dollar=\$ -\catcode`\$=\active -\let$=\dollar -\em{CVS revision: $Header$}} -\subsection{attrOrig} -\label{type:attrOrig}\hypertarget{type:attrOrig}{}% - -Specification of attribute origin. - -{\em{Enumeration}} (restriction of xsd:string in WSDL), exactly one of the values must be specified. - -Values: - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\frenchspacing\texttt{{SYSTEM}}}}]\null{} -JP system value, e.g. job owner. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\frenchspacing\texttt{{USER}}}}]\null{} -Explicitely stored by the user via RecordTag operation. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\frenchspacing\texttt{{FILE}}}}]\null{} -Coming from uploaded file. -\end{description} -\noindent \subsection{attrValue} -\label{type:attrValue}\hypertarget{type:attrValue}{}% - -Single value of an attribute. - -{\em{Structure}} (sequence complex type in WSDL) - -Fields: ( type{\ttfamily\itshape{{name}}} description ) - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{name}}}}]\null{} -Name of the attribute, including namespace. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:stringOrBlob}{stringOrBlob} {\ttfamily\itshape{{value}}}}]\null{} -(optional) String value. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:dateTime {\ttfamily\itshape{{timestamp}}}}]\null{} -When this value was recorded. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:attrOrig}{attrOrig} {\ttfamily\itshape{{origin}}}}]\null{} -Where this value came from. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{originDetail}}}}]\null{} -(optional) -\end{description} -\noindent \subsection{feedSession} -\label{type:feedSession}\hypertarget{type:feedSession}{}% - -One session between IS and PS (aka feed) charactetristics. - -{\em{Structure}} (sequence complex type in WSDL) - -Fields: ( type{\ttfamily\itshape{{name}}} description ) - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{primaryServer}}}}]\null{} -URL of primary server. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of \hyperlink{type:primaryQuery}{primaryQuery} {\ttfamily\itshape{{condition}}}}]\null{} -Filter conditions. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:int {\ttfamily\itshape{{history}}}}]\null{} -Query type. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:int {\ttfamily\itshape{{continuous}}}}]\null{} -Query type -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{feedId}}}}]\null{} -(optional) Unique ID of the feed session. -\end{description} -\noindent \subsection{genericFault} -\label{type:genericFault}\hypertarget{type:genericFault}{}% - - - -{\em{Structure}} (sequence complex type in WSDL) - -Fields: ( type{\ttfamily\itshape{{name}}} description ) - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{source}}}}]\null{} - -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:int {\ttfamily\itshape{{code}}}}]\null{} - -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{text}}}}]\null{} - -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{description}}}}]\null{} -(optional) -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:genericFault}{genericFault} {\ttfamily\itshape{{reason}}}}]\null{} -(optional) -\end{description} -\noindent \subsection{indexQuery} -\label{type:indexQuery}\hypertarget{type:indexQuery}{}% - -Single query condition on a job. Similarly to LB, these outer conditions are logically ANDed. - -{\em{Structure}} (sequence complex type in WSDL) - -Fields: ( type{\ttfamily\itshape{{name}}} description ) - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{attr}}}}]\null{} -Which attribute the condition refers to. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:attrOrig}{attrOrig} {\ttfamily\itshape{{origin}}}}]\null{} -(optional) Specific attribute origin (if we do care). -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of \hyperlink{type:indexQueryRecord}{indexQueryRecord} {\ttfamily\itshape{{record}}}}]\null{} -List of conditions on attribute attr. These conditions are logically ORed. -\end{description} -\noindent \subsection{indexQueryRecord} -\label{type:indexQueryRecord}\hypertarget{type:indexQueryRecord}{}% - -Single condition on an attribute. - -{\em{Structure}} (sequence complex type in WSDL) - -Fields: ( type{\ttfamily\itshape{{name}}} description ) - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:queryOp}{queryOp} {\ttfamily\itshape{{op}}}}]\null{} -Query operation. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:stringOrBlob}{stringOrBlob} {\ttfamily\itshape{{value}}}}]\null{} -(optional) Value to compare attribute with. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:stringOrBlob}{stringOrBlob} {\ttfamily\itshape{{value2}}}}]\null{} -(optional) Value to compare attribute with. -\end{description} -\noindent \subsection{jobRecord} -\label{type:jobRecord}\hypertarget{type:jobRecord}{}% - -Information on a single job. Used for both feeding JP index server from primary storage and to answer user queries on index server. - -{\em{Structure}} (sequence complex type in WSDL) - -Fields: ( type{\ttfamily\itshape{{name}}} description ) - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{jobid}}}}]\null{} -ID of the job. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{owner}}}}]\null{} -Job owner. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of \hyperlink{type:attrValue}{attrValue} {\ttfamily\itshape{{attributes}}}}]\null{} -(optional) Attribute values, required by query/feed and available right now. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{list of xsd:string {\ttfamily\itshape{{primaryStorage}}}}]\null{} -(optional) User query only: which primary storage(s) have data on this job. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:boolean {\ttfamily\itshape{{remove}}}}]\null{} -(optional) UpdateJobs only: this job no longer belongs to the feed. Attribute values are those which caused the change. -\end{description} -\noindent \subsection{jppsFile} -\label{type:jppsFile}\hypertarget{type:jppsFile}{}% - -JP primary storage file identification. - -{\em{Structure}} (sequence complex type in WSDL) - -Fields: ( type{\ttfamily\itshape{{name}}} description ) - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{class}}}}]\null{} -Type of the file (as set on StartUpload). -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{name}}}}]\null{} -Name of the file (if there are more of the same type per job). -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{url}}}}]\null{} -Where the file is stored on JP primary storage. -\end{description} -\noindent \subsection{primaryQuery} -\label{type:primaryQuery}\hypertarget{type:primaryQuery}{}% - -A single condition on job. - -{\em{Structure}} (sequence complex type in WSDL) - -Fields: ( type{\ttfamily\itshape{{name}}} description ) - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{attr}}}}]\null{} -Attribute name to query. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:queryOp}{queryOp} {\ttfamily\itshape{{op}}}}]\null{} -Operation. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:attrOrig}{attrOrig} {\ttfamily\itshape{{origin}}}}]\null{} -(optional) Where the attribute value came from. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:stringOrBlob}{stringOrBlob} {\ttfamily\itshape{{value}}}}]\null{} -Value to compare the job attribute with. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:stringOrBlob}{stringOrBlob} {\ttfamily\itshape{{value2}}}}]\null{} -(optional) Another value (for op = WITHIN). -\end{description} -\noindent \subsection{queryOp} -\label{type:queryOp}\hypertarget{type:queryOp}{}% - -Operators used in queries. Most are self-explanatory. - -{\em{Enumeration}} (restriction of xsd:string in WSDL), exactly one of the values must be specified. - -Values: - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\frenchspacing\texttt{{EQUAL}}}}]\null{} - -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\frenchspacing\texttt{{UNEQUAL}}}}]\null{} - -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\frenchspacing\texttt{{LESS}}}}]\null{} - -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\frenchspacing\texttt{{GREATER}}}}]\null{} - -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\frenchspacing\texttt{{WITHIN}}}}]\null{} -The attribute is between two specified values. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{{\frenchspacing\texttt{{EXISTS}}}}]\null{} -The attribute exists (even having a NULL value). -\end{description} -\noindent \subsection{stringOrBlob} -\label{type:stringOrBlob}\hypertarget{type:stringOrBlob}{}% - - - -{\em{Union}} (choice complex type in WSDL) - -Fields: ( type{\ttfamily\itshape{{name}}} description ) - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{string}}}}]\null{} -String value. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:base64Binary {\ttfamily\itshape{{blob}}}}]\null{} -Binary value. -\end{description} -\noindent \subsection{tagValue} -\label{type:tagValue}\hypertarget{type:tagValue}{}% - -A single user-recorded value for a job attribute. - -{\em{Structure}} (sequence complex type in WSDL) - -Fields: ( type{\ttfamily\itshape{{name}}} description ) - -\begin{description} -% \null and \mbox are tricks to induce different typesetting decisions -\item[{xsd:string {\ttfamily\itshape{{name}}}}]\null{} -Name of the attribute, including namespace. -% \null and \mbox are tricks to induce different typesetting decisions -\item[{\hyperlink{type:stringOrBlob}{stringOrBlob} {\ttfamily\itshape{{value}}}}]\null{} -(optional) Value. -\end{description} -\noindent diff --git a/org.glite.jp.doc/src/lbjp.bib b/org.glite.jp.doc/src/lbjp.bib deleted file mode 100644 index dd164b4..0000000 --- a/org.glite.jp.doc/src/lbjp.bib +++ /dev/null @@ -1,709 +0,0 @@ - -@InProceedings{ condor, - author = "Michael Litzkow and Miron Livny and Matthew Mutka", - title = "{C}ondor - A Hunter of Idle Workstations", - booktitle = "Proceedings of the 8th International Conference of - Distributed Computing Systems", - year = "1988", - month = "June" -} - -@InProceedings{ gram, - author = "K. Czajkowski and I. Foster and N. Karonis and C. - Kesselman and Martin S. Smith and S. Tuecke", - title = "A resource management architecture for metacomputing - systems.", - booktitle = "Proceedings of the IPPS/SPDP Workshop on Job Scheduling - Strategies for Parallel Processing", - year = "1988", - pages = "62-82" -} - -@InProceedings{ lsf, - author = "S. Zhou", - title = "LSF: Load sharing in large-scale heterogenous distributed - systems", - booktitle = "Proceedings of the Workshop on Cluster Computing", - year = "1992" -} - -@Misc{ dce, - author = "Open Group CAE Specification", - title = "DCE: Remote Procedure Call", - howpublished = "ISBN 1-85912-041-5", - year = "1994" -} - -@Misc{ pbs, - author = "Henderson, R. and Tweten, D", - title = "Portable Batch System: External reference Specification", - howpublished = "NASA, Ames Research Center", - year = "1996" -} - -@Article{ globus, - author = "I. Foster and C. Kesselman", - title = "Globus: a metacomputing infrastructure toolkit.", - journal = "International Journal of Supercomputer Applications", - year = "1997", - volume = "11", - number = "2", - pages = "115-128" -} - -@Misc{ ulm, - author = "J. Abela and T. Debeaupuis", - title = "Universal Format for Logger Messages", - howpublished = "IETF Internet Draft", - year = "1997" -} - -@InProceedings{ autopilot, - author = "R.L. Ribler and J.S. Vetter and H. Simitci and D.A. Reed", - title = "Autopilot: adaptive control of distributed applications", - booktitle = "Proceedings of the Seventh IEEE Symposium on - High-Performance Distributed Computing", - year = "1998", - pages = "172-179" -} - -@InProceedings{ gsi, - author = "I. Foster and C. Kesselman and G. Tsudik and S. Tuecke", - title = "{A Security Architecture for Computational Grids}", - booktitle = "Proceedings of the 5th ACM Conference on Computer and - Communications Security Conference", - year = 1998, - pages = "83-92" -} - -@InProceedings{ classad, - author = "Rajesh Raman and Miron Livny and Marvin Solomon", - title = "Matchmaking: Distributed Resource Management for High - Throughput Computing", - booktitle = "Proceedings of the Seventh IEEE International Symposium on - High Performance Distributed Computing", - year = "1998" -} - -@Article{ nws, - author = "R.Wolski and N. Spring and J. Hayes", - title = "The network weather service: a distributed resource - performance forecasting service for metacomputing", - journal = "J. Future Generation Comput. Syst.", - year = "1999", - volume = "15", - number = "(5/6)", - pages = "757-768" -} - -@Misc{ tls, - author = "T. Dierks and C. Allen", - title = "The {TLS} {P}rotocol {V}ersion 1.0", - howpublished = "IETF RFC 2246 (Standards Track)", - year = 1999, - month = "January" -} - -@Misc{ gssapi, - author = "{J. Linn}", - title = "{Generic Security Service Application Program Interface - Version 2, Update 1}", - howpublished = "IETF RFC 2743", - year = "2000", - month = "January" -} - -@TechReport{ lbdraft, - author = {M. Ruda and A. Krenek and L. Matyska and J. Pospisil and - M. Vocu and J. Sitera}, - title = {Logging and bookkeeping architecture}, - institution = {EU DataGrid}, - year = {2001}, - note = {Part of Deliverable D1.1 WP1 Report on current - technology} -} - -@InProceedings{ mds2, - author = "K. Czajkowski and S. Fitzgerald and I. Foster and C. - Kesselman.", - title = "Grid Information Services for Distributed Resource - Sharing.", - booktitle = " Proceedings of the Tenth IEEE International Symposium on - High-Performance Distributed Computing (HPDC-10)", - year = "2001", - month = "August", - publisher = "IEEE Press" -} - -@Misc{ gma, - author = "B. Tierney and R. Aydt and D. Gunter and W. Smith and - Valerie Taylor and R. Wolski and M. Swany.", - title = "A Grid Monitoring Service Architecture.", - howpublished = "Global Grid Forum Performance Working Group", - year = "2001" -} - -@Misc{ rgma, - author = "S. Fisher", - title = "Relational Model for Information and Monitoring", - howpublished = "Technical Report GWD-Perf-7-1, GGF", - year = "2001" -} - -@InProceedings{ mercury, - author = "Zoltan Balaton and Peter Kacsuk and Norbert Podhorszki and - Ferenc Vajda.", - title = "From Cluster Monitoring to Grid Monitoring Based on GRM", - booktitle = "In proceedings 7th EuroPar2001 Parallel Processings, - Manchester, UK.", - year = "2001", - pages = "874-881" -} - -@Article{ siena, - author = "Antonio Carzaniga and others", - title = "Design and evaluation of a wide-area event notification - service", - journal = "ACM Transactions on Computer Systems", - year = "2001", - volume = "19", - number = "3", - pages = "332-383" -} - -@InProceedings{ maui, - author = "D. Jackson and Q. Snell and M. Clement", - title = "Core algorithms of the Maui scheduler", - booktitle = "Proceedings of the 7th Workshop on Job Scheduling - Strategies for Parallel Processing", - year = "2001" -} - -@Misc{ ggfxml, - author = "W. Smith and D. Gunther and D. Quesnel", - title = "A simple xml producer-consumer protocol", - howpublished = "Grid Working Document GWD-Perf-8-2, Global Grid Forum, - Performance Working Group", - year = "2001" -} - -@TechReport{ lbdraft2, - author = {M. Ruda and A. Krenek and L. Matyska and J. Pospisil and - M. Vocu and J. Sitera}, - title = {Logging and bookkeeping architecture for {D}ata{G}rid - {R}elease 2}, - institution = {EU DataGrid}, - year = {2002}, - note = {Part of Deliverable D1.2 Definition of architecture, - technical plan and evaluation criteria for scheduling, - resource management, security and job description} -} - -@InProceedings{ code, - author = "W. Smith", - title = "A System for Monitoring and Management of Computational - Grids.", - booktitle = "In Proceedings of the 2002 International Conference on - Parallel Processing", - year = "2002" -} - -@Misc{ hawkeye, - title = "HawkEye: A Monitoring and Management Tool for Distributed - Systems", - howpublished = "\url{http://www.cs.wisc.edu/condor/hawkeye}", - year = "2002" -} - -@InProceedings{ chep03, - author = {G. Avellino et.al.}, - title = {{The first deployment of workload management services on - the EU DataGrid testbed: feedback on design and - implementation}}, - booktitle = {Computing in High Energy and Nuclear Physics (CHEP03)}, - year = {2003}, - note = {La Jolla, Ca, USA, March 2003}, - fauthor = {G. Avellino, S. Beco, B. Cantalupo, F. Pacini, A. - Terracina, A. Maraschini, D. Colling, S. Monforte, M. - Pappalardo, L. Salconi, F. Giacomini, E. Ronchieri, D. - Kouril, A. Krenek, L. Matyska, M. Mulac, J. Pospisil, M. - Ruda, Z. Salvet, J. Sitera, M. Vocu, M. Mezzadri, F. Prelz, - A. Gianelle, R. Peluso, M. Sgaravatto, S. Barale, A. - Guarise, A. Werbrouck} -} - -@Article{ alien, - author = "P. Saiz and others", - title = "{AliEn - ALICE environment on the GRID}", - journal = "{Nuclear Instruments and Methods in Physics Research, - Section A}", - year = "2003", - volume = "502", - number = "2-3", - pages = "437-440", - fauthor = { P. Saiz, L. Aphecetche, P. Buncic, R. Piskac, J.E. - Revsbech, V. Sego} -} - -@InProceedings{ rgma2, - author = "A. Cooke and others", - title = "R-GMA: An information integration system for grid - monitoring", - booktitle = "Proc. of the 11th International Conference on Cooperative - Information Systems", - year = "2003" -} - -@InProceedings{ netlogger, - author = "B. Tierney and D. Gunter", - title = "NetLogger: a toolkit for distributed system performance - tuning and debugging", - booktitle = "Proceedings of the IFIP/IEEE Eighth International - Symposium on Integrated Network Management (IM 2003)", - year = "2003", - pages = "97-100", - publisher = "Kluwer", - bolume = "246 of IFIP Conference Proceedings" -} - -@InProceedings{ monalisa, - author = "H.B. Newman and I.C. Legrand and P. Galvez and R. Voicu - and C. Cirstoiu", - title = "MonALISA: a distributed monitoring service architecture", - booktitle = "Computing in High Energy and Nuclear Physics (CHEP03), La - Jolla, CA", - year = "2003" -} - -@InProceedings{ gridrm, - author = "M.A. Baker and G.C. Smith", - title = "GridRM: an extensible resource monitoring system", - booktitle = "Proceedings of the IEEE International Cluster Computing - Conference", - year = "2003", - pages = "207-214" -} - -@InProceedings{ gridlab, - author = "Zoltan Balaton and Gabor Gombas", - title = "Resource and Job Monitoring in the Grid", - booktitle = "Proc. of the Euro-Par 2003 International Conference, - Klagenfurt", - year = 2003 -} - -@Misc{ rgmacms, - author = "D. Bonacorsi and D. Colling and L. Field and S. Fisher and - C. Grandi and P. R. Hobson and P. Kyberd and B. MacEvoy and - J. J. Nebrensky and H. Tallini and S. Traylen", - title = "Scalability Tests of R-GMA Based Grid Job Monitoring - System for CMS Monte Carlo Data Production", - howpublished = "IEEE NSS Conference, Oregon, USA", - year = "2003", - month = "21-24 October" -} - -@Misc{ xacml, - author = "{OASIS Standard}", - title = "{eXtensible Access Control Markup Language (XACML), - Version 1.0}", - year = 2003, - month = "February" -} - -@InProceedings{ gacl1, - author = "L. Cornwall and J. Jensen and D. Kelsey and A. McNab", - title = "{EU DataGrid and GridPP authorization and access control}", - booktitle = "Proceedings of the UK e-Science All Hands Meeting", - year = "2003", - pages = "382--384" -} - -@Misc{ glue, - author = "S. Andreozzi and M. Sgaravatto and C. Vistoli", - title = "Sharing a conceptual model of Grid resources and services", - howpublished = "Proceedings of the Conference for Computing in High Energy - and Nuclear Physics (CHEP03)", - year = "2003" -} - -@InProceedings{ perf, - author = "Xuehai Zhang and Jeffrey L. Freschl and Jennifer M. - Schopf", - title = "A Performance Study of Monitoring and Information Services - for Distributed Systems", - booktitle = "12th IEEE International Symposium on High Performance - Distributed Computing (HPDC-12 '03)", - year = "2003" -} - -@InProceedings{ glite, - author = "E. Laure and F. Hemmer and F. Prelz and S. Beco and S. - Fisher and M. Livny and L. Guy and M. Barroso and P. Buncic - and P. Kunszt and A. {Di Meglio} and A. Aimar and A. Edlund - and D. Groep and F. Pacini and M. Sgaravatto and O. Mulmo", - title = "Middleware for the next generation Grid infrastructure", - booktitle = "Computing in High Energy Physics and Nuclear Physics (CHEP - 2004)", - year = 2004 -} - -@Article{ jgc, - author = {G. Avellino and others}, - title = {{The DataGrid Workload Management System: Challenges and - Results}}, - journal = {Journal of Grid Computing}, - year = {Dec 2004}, - volume = {2}, - number = {4}, - pages = {353--367}, - fauthor = { G. Avellino, S. Beco, B. Cantalupo, A. Maraschini, F. - Pacini, M. Sottilaro, A. Terracina, D. Colling, F. - Giacomini, E. Ronchieri, A. Gianelle, M. Mazzucato, R. - Peluso, M. Sgaravatto, A. Guarise, R. Piro, A. Werbrouck, - D. Kouøil, A. Køenek, L. Matyska, M. Mulaè, J. Pospí¹il, M. - Ruda, Z. Salvet, J. Sitera, J. ©krabal, M. Vocù, M. - Mezzadri, F. Prelz, S. Monforte, M. Pappalardo} -} - -@Misc{ apart, - author = "M. Gerndt and others", - title = "Performance Tools for the {Grid}: State of the Art and - Future", - howpublished = "Tech. Rep. Lehrstuhl fuer Rechnertechnik und - Rechnerorganisation, Technische Universitaet Muenchen - (LRR-TUM). - \url{http://www.lpds.sztaki.hu/~zsnemeth/apart/}", - year = "2004" -} - -@InProceedings{ ahm04194, - author = {Shrija Rajbhandari and David W. Walker}, - title = "{Support for Provenance in a Service-based Computing - Grid}", - booktitle = "{Proceedings of the third UK e-Science All Hands Meeting, - Nottingham, UK}", - year = {2004} -} - -@TechReport{ gro04, - author = {Paul T. Groth}, - title = "{Recording provenance in service-oriented architectures}", - institution = "{University of Southampton; Faculty of Engineering, - Science and Mathematics; School of Electronics and Computer - Science}", - year = {2004} -} - -@InProceedings{ glm04b, - author = {Paul Groth and Michael Luck and Luc Moreau}, - title = "{A protocol for recording provenance in service-oriented - grids}", - booktitle = "{Proceedings of the 8th International Conference on - Principles of Distributed Systems (OPODIS04)}", - year = {2004} -} - -@Article{ ganglia, - author = "M.L. Massie and B.N. Chun and D.E. Culler", - title = "Ganglia Distributed Monitoring System: Design, - Implementation, and Experience", - journal = "Parallel Computing", - year = "2004", - volume = "30", - pages = "817-840" -} - -@Misc{ gae, - author = "Arshad Ali and Ashiq Anjum and Julian Bunn and Richard - Cavanaugh and Frank van Lingen and Richard McClatchey and - Harvey Newman and Waqas ur Rehman and Conrad Steenberg and - Michael Thomas and Ian Willers", - title = "Job Monitoring in an Interactive Grid Analysis - Environment", - howpublished = "Computing in High Energy Physics 2004", - year = "2004" -} - -@InProceedings{ voms1, - author = "R. Alfieri and R. Cecchini and V. Ciaschini and L. - dell'Agnello and \'{A}. Frohner and A. Gianoli and K. - L\H{o}rentey and F. Spataro", - title = "{VOMS}, an {A}uthorization {S}ystem for {V}irtual - {O}rganizations", - booktitle = "Grid Computing: First European Across Grids Conference", - year = "2004" -} - -@InProceedings{ delegation, - author = "V. Welch and I. Foster and C. Kesselman and O. Mulmo and - L. Pearlman and S. Tuecke and J. Gawor and S. Meder and F. - Siebenlist", - title = "{X.509 Proxy Certificates for Dynamic Delegation}", - booktitle = "Proceedings of the 3rd Annual PKI R\&D Workshop", - year = 2004, - month = "April" -} - -@Misc{ proxycert, - author = "S. Tuecke and V. Welch and D. Engert and L. Pearlman and - M. Thompson", - title = "Internet {X}.509 {P}ublic {K}ey {I}nfrastructure ({PKI}) - proxy certificate profile", - howpublished = "IETF RFC 3820", - year = 2004, - month = "June" -} - -@InProceedings{ chep, - author = "D. Kouøil and others", - title = "Distributed Tracking, Storage, and Re-use of Job State - Information on the Grid", - booktitle = "Computing in High Energy and Nuclear Physics (CHEP04)", - year = "2004" -} - -@Misc{ genericlb, - author = "{CESNET JRA1 team}", - title = "Current and Foreseen {\LB}\ Design", - howpublished = "3rd EGEE Conference, Athens, - \url{http://indico.cern.ch/contributionDisplay.py?contribId=201&sessionId=73&confId=0513}" - , - year = 2005 -} - -@InProceedings{ eup1, - author = "Liming Chen and Victor Tan and Fenglian Xu and Alexis - Biller and Paul Groth and Simon Miles and John Ibbotson and - Michael Luck and Luc Moreau", - title = "{A proof of concept: Provenance in a Service Oriented - Architecture}", - booktitle = "{Proceedings of the fourth UK e-Science All Hands Meeting, - Nottingham, UK}", - year = {2005} -} - -@InProceedings{ tgx05, - author = {Paul Townend and Paul Groth and Jie Xu}, - title = "{A provenance-aware weighted fault tolerance scheme for - service-based applications}", - booktitle = "{Proceedings of the $8^{th}$ IEEE International Symposium - on Object-oriented Real-time distributed Computing (ISORC - 2005)}", - year = {2005} -} - -@InProceedings{ mygrid, - author = "M. Nedim Alpdemir and Arijit Mukherjee and Norman W. Paton - and Alvaro A.A. Fernandes and Paul Watson and Kevin Glover - and Chris Greenhalgh and Tom Oinn and Hannah Tipney", - title = "Contextualised Workflow Execution in myGrid", - booktitle = " Proc European Grid Conference , Springer-Verlag LNCS - 3470", - year = 2005, - pages = "444-453" -} - -@Article{ condor2, - author = "Douglas Thain and Todd Tannenbaum and Miron Livny", - title = "Distributed computing in practice: the Condor experience.", - journal = "Concurrency - Practice and Experience", - year = "2005", - volume = "17", - number = "2-4", - pages = "323-356" -} - -@InProceedings{ globus4, - author = "I. Foster", - title = "Globus Toolkit Version 4: Software for Service-Oriented - Systems.", - booktitle = "IFIP International Conference on Network and Parallel - Computing, Springer-Verlag LNCS 3779,", - year = "2005", - pages = "2-13" -} - -@InProceedings{ cgmapisa, - author = "Andrea Ceccanti and Ond\v{r}ej Kraj\'{\i}\v{c}ek and - Ale\v{s} K\v{r}enek and Lud\v{e}k Matyska and Miroslav - Ruda.", - title = "Towards Scalable and Interoperable Grid Monitoring - Infrastructure.", - booktitle = "Proceedings of the first CoreGRID Integration Workshop", - year = "2005", - pages = "10-18" -} - -@InProceedings{ cgma, - author = "Ondøej Krajíèek and Ale¹ Køenek and Ludìk Matyska and - Miroslav Ruda and Jiøí Sitera", - title = "Capability Languages in C-GMA", - booktitle = "Proceedings of Cracow Grid Workshop (CGW05)", - year = "2005" -} - -@Article{ taxonomy, - author = {Serafeim Zanikolas and Rizos Sakellariou}, - title = {A taxonomy of grid monitoring systems}, - journal = {Future Gener. Comput. Syst.}, - year = {2005}, - volume = {21}, - number = {1}, - pages = {163--188}, - issn = {0167-739X}, - doi = {http://dx.doi.org/10.1016/j.future.2004.07.002}, - publisher = {Elsevier Science Publishers B. V.}, - address = {Amsterdam, The Netherlands, The Netherlands} -} - -@Article{ unicore, - author = "Achim Streit and Dietmar Erwin and Thomas Lippert and - Daniel Mallmann and Roger Menday and Michael Rambadt and - Morris Riedel and Mathilde Romberg and Bernd Schuller and - Philipp Wieder", - title = "UNICORE - From Project Results to Production Grids", - journal = "Grid Computing : New Frontiers of High Performance - Computing", - year = "2005", - pages = "357 - 376" -} - -@Article{ voms2, - author = "R. Alfieri and R. Cecchini and V. Ciaschini and L. - dell'Agnello and \'{A}. Frohner and K. L\H{o}rentey and F. - Spataro", - title = "{From gridmap-file to VOMS: managing authorization in a - Grid environment}", - journal = "Future Generation Computer Systems", - year = "2005", - pages = "549-558", - month = "April" -} - -@InProceedings{ cgw05, - author = "F. Dvoøák and D. Kouøil and A. Køenek and L. Matyska and - M. Mulaè and J.Pospi¹il and M. Ruda and Z. Salvet and J. - Sitera and J. ©krabal and M. Vocù ", - title = "Services for Tracking and Archival of Grid Job - Information", - booktitle = "Proceeding of Cracow Grid Workshop", - year = "2005" -} - -@Misc{ rfc4122, - author = "P. Leach and M. Mealling and R. Salz", - title = "A Universally Unique IDentifier (UUID) URN Namespace", - howpublished = "IETF RFC 4122", - year = "2005" -} - -@Misc{ euprovenance, - title = "{EU FP6 Programme Enabling and Supporting Provenance in - Grids for Complex Problems}", - howpublished = "\url{http://twiki.gridprovenance.org/bin/view/Provenance/ProjectInformation}" - , - year = 2006 -} - -@Misc{ atlas, - author = "TODO - predelat na neco poradneho", - title = "{The ATLAS Experiment}", - howpublished = "\url{http://atlas.ch/}", - year = 2006 -} - -@Misc{ ami, - author = "TODO - predelat na neco poradneho", - title = "{The Atlas Metadata Interface}", - howpublished = "\url{https://atlastagcollector.in2p3.fr:8443/AMI/}", - year = 2006 -} - -@Misc{ alice, - author = "TODO - predelat na neco poradneho", - title = "{A Large Ion Collider Experiment}", - howpublished = "\url{http://aliceinfo.cern.ch/Public}", - year = 2006 -} - -@Misc{ sam, - author = "TODO - predelat na neco poradneho", - title = "{SAM (Sequential data Access via Meta-data)}", - howpublished = "\url{http://d0db.fnal.gov/sam/}", - year = 2006 -} - -@InProceedings{ gacl2, - author = "A. McNab and S. Kaushal", - title = "Web services with gridsite and C/C++/scripts", - booktitle = "Computing in High Energy and Nuclear Physics (CHEP 2006)", - year = "2006" -} - -@Misc{ crossgrid, - author = "CrossGrid", - title = "{CrossGrid Project}", - howpublished = "\url{http://www.crossgrid.org}" -} - -@Misc{ dgas, - author = "DGAS", - title = "{The Distributed Grid Accounting System}", - howpublished = "\url{http://www.to.infn.it/grid/accounting/main.html}" -} - -@Misc{ egee, - author = "EGEE", - title = "{Enabling Grids for E-sciencE (EGEE) Project}", - howpublished = "\url{http://lcg.web.cern.ch/LCG/}" -} - -@Misc{ gridice, - author = "EGEE", - title = "{GridIce, the eyes of the Grid}", - howpublished = "\url{http://gridice2.cnaf.infn.it:50080/gridice/}" -} - -@Misc{ djra1.2, - author = {{EGEE JRA1}}, - title = {{EGEE Middleware Design---Release 1}}, - howpublished = {\url{https://edms.cern.ch/document/487871/}} -} - -@Misc{ djra1.3, - author = {{EGEE JRA1}}, - title = {{EGEE Middleware Release 1}}, - howpublished = {\url{https://edms.cern.ch/document/567624/}} -} - -@Misc{ djra1.4, - author = {{EGEE JRA1}}, - title = {{EGEE Middleware Architecture---Release 2}}, - howpublished = {\url{https://edms.cern.ch/document/594698/}} -} - -@Misc{ jra2jobmetrics, - author = "EGEE JRA2", - title = "{Job Metrics}", - howpublished = "\url{http://egee-jra2.web.cern.ch/EGEE-JRA2/QoS/JobsMetrics/JobMetrics.htm}" - -} - -@Misc{ lbug, - author = "A. K\v{r}enek and others", - title = "{L\&B Users Guide}", - howpublished = "\url{https://edms.cern.ch/file/571273/1/LB-guide.pdf}" -} - -@Misc{ lcg, - author = "LCG", - title = "{LHC Computing Project (LCG)}", - howpublished = "\url{http://lcg.web.cern.ch/LCG/}" -} - -@Misc{ pasoa, - title = "{PASOA: Provenance Aware Service Oriented Architecture}", - howpublished = "\url{http://twiki.pasoa.ecs.soton.ac.uk/bin/view/PASOA/AboutPasoa}" - -} diff --git a/org.glite.jp.index/.cvsignore b/org.glite.jp.index/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp.index/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp.index/Makefile b/org.glite.jp.index/Makefile deleted file mode 100644 index ce2b8f0..0000000 --- a/org.glite.jp.index/Makefile +++ /dev/null @@ -1,178 +0,0 @@ -# defaults -top_srcdir=.. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -jpprefix=jp -package=glite-jp-index -version=0.0.0 -PREFIX=/opt/glite - -glite_location=/opt/glite -nothrflavour=gcc32 -thrflavour=gcc32pthr -gsoap_prefix=/software/gsoap-2.6 - -CC=gcc - --include Makefile.inc - - -VPATH=${top_srcdir}/src:${top_srcdir}/examples:${top_srcdir}/project:${top_srcdir}/doc:${jpproject}:${stagedir}/interface - -DEBUG:=-W -Wall -g -O0 -CPPFLAGS:=-DDEBUG -D_GNU_SOURCE -I. -I${top_srcdir}/interface -I${top_srcdir}/src -I${gsoap_prefix}/include -I${gsoap_prefix} -I${stagedir}/include -I${gsoap_prefix}/include -CFLAGS:=${DEBUG} ${CFLAGS} -LDFLAGS:=-L${stagedir}/lib - -dotless_gsoap_ver:=${shell echo ${gsoap_default_version} | tr -d . } -ifeq ($(shell test -f ${stagedir}/lib/libglite_security_gsoap_plugin_${dotless_gsoap_ver}_${nothrflavour}_c.so && echo ok),ok) - langflavour:=_c -endif -GSOAPLIB:=-L${stagedir}/lib -lglite_security_gsoap_plugin_${dotless_gsoap_ver}_${nothrflavour}${langflavour} - -gsoap_bin_prefix:=${shell if [ -x ${gsoap_prefix}/bin/soapcpp2 ]; then echo ${gsoap_prefix}/bin; else echo ${gsoap_prefix}; fi } - - -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install - - -daemon:=glite-jp-indexd -examples:=glite-jpis-test glite-jpis-client -test:=run-test.sh -test_files:=dump1.sql simple_query.in simple_query.out complex_query.in complex_query.out authz.out jobid_query.in jobid_query.out origin_query.in origin_query.out exists_query.in exists_query.out within_query.in within_query.out - -MANS1:=glite-jpis-client.1 -MANS8:=glite-jp-indexd.8 -MANS:=${MANS1} ${MANS8} -HTMLS:=glite-jpis-client.html glite-jp-indexd.html -ws_prefix:=jp_ -is_prefix:=${ws_prefix} -ps_prefix:=${ws_prefix} - -SRCS:= conf.c bones_server.c soap_ops.c soap_ps_calls.c common.c \ - ${is_prefix}Server.c ${ps_prefix}Client.c ${ws_prefix}C.c \ - ws_ps_typeref.c ws_is_typeref.c db_ops.c context.c type_plugin.c - -EXA_TEST_SRCS:=jpis-test.c ${is_prefix}Client.c ${is_prefix}C.c context.c db_ops.c conf.c ws_is_typeref.c common.c -EXA_DB_SRCS:=jpis-db-internal.c db_ops.c conf.c context.c ws_is_typeref.c common.c -EXA_CLIENT_SRCS:=jpis-client.c ${is_prefix}Client.c ${is_prefix}C.c common.c - -OBJS:=${SRCS:.c=.o} -EXA_TEST_OBJS:=${EXA_TEST_SRCS:.c=.o} -EXA_DB_OBJS:=${EXA_DB_SRCS:.c=.o} -EXA_CLIENT_OBJS:=${EXA_CLIENT_SRCS:.c=.o} - - -COMMONLIB:=-lglite_jp_common_${nothrflavour} -SRVCOMMONLIB:=-lglite_jp_server_common -BONESLIB:=-lglite_lbu_server_bones -TRIOLIB:=-lglite_lbu_trio -GSSLIB:=-lglite_security_gss_${nothrflavour} - -default all: compile doc - -compile: ${daemon} ${examples} - -${daemon}: ${OBJS} - ${LINK} -o $@ -export-dynamic ${OBJS} ${BONESLIB} ${TRIOLIB} ${COMMONLIB} ${GSOAPLIB} ${SRVCOMMONLIB} ${GSSLIB} - -glite-jpis-test: ${EXA_TEST_OBJS} - ${LINK} -o $@ $+ ${GSOAPLIB} ${COMMONLIB} ${TRIOLIB} ${SRVCOMMONLIB} - -jpis-db-internal: ${EXA_DB_OBJS} - ${LINK} -o $@ $+ ${COMMONLIB} ${SRVCOMMONLIB} - -glite-jpis-client: ${EXA_CLIENT_OBJS} - ${LINK} -o $@ $+ ${GSOAPLIB} ${COMMONLIB} ${TRIOLIB} - -${ws_prefix}Client.c ${ws_prefix}Server.c \ -${ws_prefix}C.c ${ws_prefix}H.h ${ws_prefix}Stub.h: JobProvenance.xh - ${gsoap_bin_prefix}/soapcpp2 -n -w -c -p ${ws_prefix} $< - -JobProvenance.xh: jpdev.wsdl - cp ${stagedir}/interface/JobProvenanceTypes.wsdl . - ${gsoap_bin_prefix}/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $< - rm -f JobProvenanceTypes.wsdl - -check: - # ../test/run-test.sh - -doc: ${MANS} ${HTMLS} - -stage: compile doc - ${MAKE} PREFIX=${stagedir} DOSTAGE=yes install - -install: - -mkdir -p ${PREFIX}/bin ${PREFIX}/etc ${PREFIX}/etc/init.d - -mkdir -p ${PREFIX}/share/doc/${package}-${version} - -mkdir -p ${PREFIX}/examples ${PREFIX}/examples/query-tests - -mkdir -p ${PREFIX}/interface - -mkdir -p ${PREFIX}/share/man/man1 - -mkdir -p ${PREFIX}/share/man/man8 - ${INSTALL} -m 755 ${daemon} ${PREFIX}/bin - ${INSTALL} -m 755 ${examples} ${PREFIX}/examples - ${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/glite-jp-indexd - ${INSTALL} -m 755 ${top_srcdir}/config/glite-jp-index-dbsetup.sql ${PREFIX}/etc - ${INSTALL} -m 755 ${top_srcdir}/config/glite-jpis-config.xml ${PREFIX}/etc - ${INSTALL} -m 755 ${top_srcdir}/config/glite-jpis-test-config.xml ${PREFIX}/etc - ${INSTALL} -m 644 ${top_srcdir}/doc/README ${HTMLS} ${PREFIX}/share/doc/${package}-${version} - ${INSTALL} -m 644 ${MANS1} ${PREFIX}/share/man/man1 - ${INSTALL} -m 644 ${MANS8} ${PREFIX}/share/man/man8 - ${INSTALL} -m 755 ../examples/query-tests/${test} ${PREFIX}/examples/query-tests - for i in ${test_files}; do \ - ${INSTALL} -m 644 ../examples/query-tests/$$i ${PREFIX}/examples/query-tests; \ - done - ${INSTALL} -m 644 ${top_srcdir}/interface/JobProvenanceISClient.xsd ${PREFIX}/interface - -mkdir -p ${PREFIX}/yaim/functions/ - -mkdir -p ${PREFIX}/yaim/node-info.d - -mkdir -p ${PREFIX}/yaim/defaults - -mkdir -m 0700 -p ${PREFIX}/yaim/examples/siteinfo/services - ${INSTALL} -m 0644 ${top_srcdir}/config/functions/config* ${PREFIX}/yaim/functions - ${INSTALL} -m 0644 ${top_srcdir}/config/node-info.d/glite* ${PREFIX}/yaim/node-info.d - ${INSTALL} -m 0644 ${top_srcdir}/config/defaults/glite* ${PREFIX}/yaim/defaults - ${INSTALL} -m 0600 ${top_srcdir}/config/site-info.def.example ${PREFIX}/yaim/examples/siteinfo/services/glite_jpis - -clean: - rm -rvf *.c *.h *.ch *.xh *.xml *.nsmap *.o *.lo .libs glite-jp* - rm -rvf log.xml project/ rpmbuild/ RPMS/ tgz/ - -soap_ops.o bones_server.o simple_server.o: ${is_prefix}H.h ${ps_prefix}H.h - -soap_ops.o bones_server.o: soap_version.h - -soap_version.h: - ${gsoap_bin_prefix}/soapcpp2 /dev/null - perl -ne '$$. == 2 && /.*([0-9]+)\.([0-9]+)\.([0-9]+)([a-z])?.*/ && printf "#define GSOAP_VERSION %d%02d%02d\n#define GSOAP_VERSION_LETTER '\''".($$4?$$4:"\\0")."'\''\n",$$1,$$2,$$3' soapH.h >$@ - -rm soapC.cpp soapH.h soapStub.h soapClient.cpp soapServer.cpp soapClientLib.cpp soapServerLib.cpp - -db_ops.h: context.h -context.h: conf.h -db_ops.o: db_ops.c conf.h context.h db_ops.h -context.o: context.c conf.h context.h -soap_ps_calls.o: soap_ps_calls.c ${ps_prefix}H.h ${ps_prefix}.nsmap soap_version.h conf.h db_ops.h ws_ps_typeref.h context.h -soap_ops.o: soap_ops.c jp_H.h ${is_prefix}.nsmap soap_version.h db_ops.h ws_ps_typeref.h ws_is_typeref.h context.h -ws_ps_typeref.o: ws_ps_typeref.c ${ps_prefix}H.h ws_typemap.h ws_ps_typeref.h soap_version.h -ws_is_typeref.o: ws_is_typeref.c ${is_prefix}H.h ws_typemap.h ws_is_typeref.h soap_version.h -jpis-client.o: jpis-client.c ${is_prefix}H.h soap_version.h -jpis-test.o: jpis-client.c ${is_prefix}H.h soap_version.h -conf.o: conf.c ${is_prefix}H.h soap_version.h -common.o: common.h common.c - -${ws_prefix}C.o: ${ws_prefix}C.c - $(CC) -c $(CPPFLAGS) $(CFLAGS) -Wno-unused-parameter $< - -%.1: %.sgml - docbook2man $< - -%.8: %.sgml - docbook2man $< - -%.html: %.sgml - docbook2html $< --nochunks - -.PHONY: default all compile check doc stage dist distsrc distbin install clean diff --git a/org.glite.jp.index/build.xml b/org.glite.jp.index/build.xml deleted file mode 100755 index 3a97943..0000000 --- a/org.glite.jp.index/build.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.index/config/dbsetup.sh b/org.glite.jp.index/config/dbsetup.sh deleted file mode 100755 index 3f7a1f9..0000000 --- a/org.glite.jp.index/config/dbsetup.sh +++ /dev/null @@ -1,30 +0,0 @@ -#! /bin/sh -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# Shell example of preparing the database for JP Index Server -# - -# database -mysqladmin -u root -p create jpis - -# user -mysql -u root -p -e 'GRANT ALL on jpis.* to jpis@localhost' - -# tables -mysql -u jpis jpis < `dirname $0`/glite-jp-index-dbsetup.sql diff --git a/org.glite.jp.index/config/defaults/glite-jpis.pre b/org.glite.jp.index/config/defaults/glite-jpis.pre deleted file mode 100644 index 0bb7e71..0000000 --- a/org.glite.jp.index/config/defaults/glite-jpis.pre +++ /dev/null @@ -1,2 +0,0 @@ -### Default values to some glite-JPIS variables -GLITE_USER=glite diff --git a/org.glite.jp.index/config/functions/config_glite_jpis b/org.glite.jp.index/config/functions/config_glite_jpis deleted file mode 100644 index 0735a32..0000000 --- a/org.glite.jp.index/config/functions/config_glite_jpis +++ /dev/null @@ -1,148 +0,0 @@ -############################################################################## -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://www.eu-egee.org/partners/ for details on the copyright -# holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS -# OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## -# -# NAME : config_jpis -# -# DESCRIPTION : This function configures Job Provenance Index Server. -# -# AUTHORS : LB/JP team, heavily based on glite-yaim-lb -# -# NOTES : -# -# YAIM MODULE: glite-yaim-jpis -# -############################################################################## - - -function config_glite_jpis_check(){ - requires MYSQL_PASSWORD -} - -function config_glite_jpis_setenv(){ - - yaimgridenv_set GLITE_LOCATION ${INSTALL_ROOT:-opt}/glite - yaimgridenv_set GLITE_LOCATION_VAR ${GLITE_LOCATION_VAR:-/var/glite} - yaimgridenv_set GLITE_USER ${GLITE_USER:-glite} - yaimgridenv_set GLITE_HOST_CERT ${GLITE_USER_HOME:-/home/glite}/.certs/hostcert.pem - yaimgridenv_set GLITE_HOST_KEY ${GLITE_USER_HOME:-/home/glite}/.certs/hostkey.pem - yaimgridenv_set X509_CERT_DIR /etc/grid-security/certificates - yaimgridenv_set GLITE_JPIS_PIDFILE ${GLITE_JPIS_PIDFILE:-$GLITE_LOCATION_VAR/glite-jp-indexd.pid} - yaimgridenv_set GLITE_JPIS_LOGFILE ${GLITE_JPIS_LOGFILE:-$GLITE_LOCATION_VAR/glite-jp-indexd.log} - yaimgridenv_set GLITE_JPIS_CONFIG ${GLITE_JPIS_CONFIG:-$GLITE_LOCATION/etc/glite-jpis-config.xml} - yaimgridenv_set GLITE_JPIS_PORT ${GLITE_JPIS_PORT:-8902} - yaimgridenv_set GLITE_JPIS_DB ${GLITE_JPIS_DB:-jpis/@localhost:jpis} - yaimgridenv_set GLITE_JPIS_QT ${GLITE_JPIS_QT:-both} - yaimgridenv_set GLITE_JPIS_AUTH ${GLITE_JPIS_AUTH} - yaimgridenv_set GLITE_JPIS_DEBUG ${GLITE_JPIS_DEBUG} - - yaimgridpath_append LD_LIBRARY_PATH ${INSTALL_ROOT:-opt}/glite/lib - yaimgridpath_append LD_LIBRARY_PATH ${INSTALL_ROOT:-opt}/globus/lib - yaimgridpath_append LD_LIBRARY_PATH ${INSTALL_ROOT:-opt}/c-ares/lib -} - -function config_glite_jpis() { - - ################################################# - # Job Provenance Index Server configuration # - ################################################# - - HOSTNAME=`hostname -f` - - chmod og+rx /var/lib/mysql/ - chown mysql:mysql /var/run/mysqld/ - - # add option --max_allowed_packet=17M - if [ ! -f /etc/my.cnf ]; then - echo "[mysqld]" >> /etc/my.cnf - echo "max_allowed_packet=17M" >> /etc/my.cnf - else - grep "^[mysqld]" /etc/my.cnf > /dev/null - if [ ! $? = 0 ]; then - echo "[mysqld]" >> /etc/my.cnf - echo "max_allowed_packet=17M" >> /etc/my.cnf - fi - fi - - /sbin/chkconfig mysqld on - ps ax | grep -v grep |grep mysqld_safe > /dev/null 2>&1 - if [ ! $? = 0 ] ; then - /etc/init.d/mysqld start - sleep 1 - fi - - ls /tmp/mysql.sock > /dev/null 2>&1 - if [ ! $? = 0 ]; then - ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock - fi - - # set mysql password - set_mysql_passwd || return 1 # the function uses $MYSQL_PASSWORD - - # Check if database exist - mysqlshow --password="$MYSQL_PASSWORD" | grep "jpis" > /dev/null 2>&1 - - if [ ! $? = 0 ]; then - mysql -u root --password="$MYSQL_PASSWORD" -e "CREATE DATABASE jpis" - mysql --password="$MYSQL_PASSWORD" jpis < ${INSTALL_ROOT}/glite/etc/glite-jp-index-dbsetup.sql - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on jpis.* to jpis IDENTIFIED BY '' WITH GRANT OPTION;" - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on jpis.* to jpis@'$HOSTNAME' IDENTIFIED BY '' WITH GRANT OPTION;" - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on jpis.* to jpis@localhost IDENTIFIED BY '' WITH GRANT OPTION;" - else - yaimlog "Database jpis already exists" - fi - - . /opt/glite/etc/profile.d/grid-env.sh - mkdir -p $GLITE_LOCATION_VAR # Needed to store PID of JP IS server - chown $GLITE_USER:$GLITE_USER $GLITE_LOCATION_VAR - chmod 0755 $GLITE_LOCATION_VAR - - mkdir -p $GLITE_USER_HOME/.certs - chown $GLITE_USER:$GLITE_USER $GLITE_USER_HOME/.certs - chmod 0755 $GLITE_USER_HOME/.certs - cp -f /etc/grid-security/hostcert.pem /etc/grid-security/hostkey.pem $GLITE_USER_HOME/.certs/ - if [ ! $? = 0 ] ; then - echo "Please copy host certificate and key into /etc/grid-security and" - echo " $GLITE_USER_HOME/.certs/, change the owner of the ones in" - echo " $GLITE_USER_HOME/.certs/ to $GLITE_USER" - fi - chown $GLITE_USER:$GLITE_USER $GLITE_USER_HOME/.certs/hostcert.pem $GLITE_USER_HOME/.certs/hostkey.pem - chmod 0644 $GLITE_USER_HOME/.certs/hostcert.pem - chmod 0400 $GLITE_USER_HOME/.certs/hostkey.pem - - # Start services - if [ ! -f ${GLITE_LOCATION}/etc/gLiteservices ] ; then - touch ${GLITE_LOCATION}/etc/gLiteservices - fi - - grep glite-jp-indexd ${GLITE_LOCATION}/etc/gLiteservices > /dev/null - if [ ! $? = 0 ] ; then - echo "${GLITE_LOCATION}/etc/init.d/glite-jp-indexd" >> ${GLITE_LOCATION}/etc/gLiteservices - fi - - ${GLITE_LOCATION}/etc/init.d/glite-jp-indexd stop - ${GLITE_LOCATION}/etc/init.d/glite-jp-indexd start - - if [ ! $? = 0 ] ; then - yaimlog ABORT "Service glite-jp-indexd failed to start!" - return 1 - fi - - return 0 - -} diff --git a/org.glite.jp.index/config/glite-jp-index-dbsetup.sql b/org.glite.jp.index/config/glite-jp-index-dbsetup.sql deleted file mode 100644 index 34e7565..0000000 --- a/org.glite.jp.index/config/glite-jp-index-dbsetup.sql +++ /dev/null @@ -1,96 +0,0 @@ -create table jobs ( - `jobid` char(32) binary not null, - `dg_jobid` varchar(255) binary not null, - `ownerid` char(32) binary not null, - `aclid` char(32) binary null, - `ps` varchar(255) not null, - - primary key (jobid), - unique (dg_jobid), - index (jobid), - index (dg_jobid) -) character set utf8 collate utf8_bin engine=innodb; - -create table attrs ( - `attrid` char(32) binary not null, - `name` varchar(255) binary not null, - `indexed` int not null, - `type` char(32) binary null, - - primary key (attrid), - index (attrid), - index (name) -) character set utf8 collate utf8_bin engine=innodb; - -create table feeds ( - `uniqueid` int auto_increment not null, - `feedid` char(32) binary unique, - `state` int not null, - `locked` int not null, - `source` varchar(255) not null, - `expires` datetime, - `condition` mediumblob null, - - primary key (uniqueid), - index (uniqueid), - index (feedid), - index (state) -) character set utf8 collate utf8_bin engine=innodb; - -create table acls ( - `aclid` char(32) binary not null, - `value` mediumblob not null, - `refcnt` int not null, - - primary key (aclid) -) character set utf8 collate utf8_bin engine=innodb; - -create table users ( - `userid` char(32) binary not null, - `cert_subj` varchar(255) binary not null, - - primary key (userid), - unique (cert_subj) -) character set utf8 collate utf8_bin engine=innodb; - -# data tables - created one for each configured and indexed attribute, -# in future values of the non-indexed attributes will be stored in attr_values -# -#create table attr_ ( -# `jobid` char(32) binary not null, -# `value` varchar(255) binary not null, -# `full_value` mediumblob not null, -# `origin` int not null, -# -# index (jobid), -# index (value) -#) character set utf8 collate utf8_bin engine=innodb; - - -# ---- future schema improvements ---- - -#create table attr_values ( -# `jobid` char(32), -# `attrid` char(32) binary not null, -# `value` varchar(255) binary not null, -# `full_value` mediumblob not null, -# `origin` int not null, -## `is_multival` int, -# -## primary key (jobid, attrid) -# index (jobid), -# index (attrid), -# index (value) -#) character set utf8 collate utf8_bin engine=innodb; - -#create table attr_multivalues ( -# `jobid` char(32), -# `attrid` char(32) binary not null, -# `value` varchar(255) binary not null, -# `full_value` mediumblob not null, -# `origin` int not null, -# -# index (jobid), -# index (attrid) -# index (value) -#) character set utf8 collate utf8_bin engine=innodb; diff --git a/org.glite.jp.index/config/glite-jpis-config.xml b/org.glite.jp.index/config/glite-jpis-config.xml deleted file mode 100644 index 4c679f5..0000000 --- a/org.glite.jp.index/config/glite-jpis-config.xml +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - - - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:status - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:jobId - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:owner - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:jobtype - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:parentJob - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:seed - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:childrenNum - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:children - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:childrenHist - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:childrenStates - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorId - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:globusId - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:localId - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:jdl - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:matchedJdl - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:destination - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorJdl - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:rsl - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:reason - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:location - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:ceNode - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:networkServer - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:subjobFailed - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:doneCode - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:exitCode - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:resubmitted - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:cancelling - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:cancelReason - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:cpuTime - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:userTags - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:stateEnterTime - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:lastUpdateTime - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:stateEnterTimes - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:expectUpdate - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:expectFrom - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:acl - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:payloadRunning - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:possibleDestinations - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:possibleCeNodes - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:suspended - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:suspendReason - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:failureReasons - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:removeFromProxy - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:uiHost - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:userFqans - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:sandboxRetrieved - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:pbsState - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:pbsQueue - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:pbsOwner - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:pbsName - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:pbsReason - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:pbsScheduler - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:pbsDestHost - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:pbsPid - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:pbsResourceUsage - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:pbsExitStatus - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:pbsErrorDesc - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorStatus - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorUniverse - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorOwner - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorPreempting - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorShadowPid - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorShadowExitStatus - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorStarterPid - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorStarterExitStatus - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorJobPid - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorJobExitStatus - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorDestHost - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorReason - YES - YES - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:condorErrorDesc - YES - YES - - - - - - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:owner - http://egee.cesnet.cz/en/Schema/LB/Attributes:ceNode - http://egee.cesnet.cz/en/Schema/LB/Attributes:status - - - - - - - - - https://localhost:8901 - - - http://egee.cesnet.cz/en/Schema/JP/System:regtime - GREATER - - 0 - - - 1 - 1 - - diff --git a/org.glite.jp.index/config/glite-jpis-test-config.xml b/org.glite.jp.index/config/glite-jpis-test-config.xml deleted file mode 100644 index c5a4d78..0000000 --- a/org.glite.jp.index/config/glite-jpis-test-config.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - http://egee.cesnet.cz/en/Schema/JP/System:owner - NO - YES - - - http://egee.cesnet.cz/en/Schema/JP/System:jobId - NO - YES - - - http://egee.cesnet.cz/en/Schema/JP/System:regtime - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:aTag - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:eNodes - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:RB - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:UIHost - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:CPUTime - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:NProc - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusDate - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:retryCount - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:jobType - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:nsubjobs - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:lastStatusHistory - NO - YES - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:fullStatusHistory - NO - YES - - - - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - - - - diff --git a/org.glite.jp.index/config/node-info.d/glite-jpis b/org.glite.jp.index/config/node-info.d/glite-jpis deleted file mode 100644 index 46e4052..0000000 --- a/org.glite.jp.index/config/node-info.d/glite-jpis +++ /dev/null @@ -1,8 +0,0 @@ -JPIS_FUNCTIONS=" -config_add_pool_env -config_crl -config_host_certs -config_edgusers -config_globus_clients -config_glite_jpis -config_glite_initd" diff --git a/org.glite.jp.index/config/site-info.def.example b/org.glite.jp.index/config/site-info.def.example deleted file mode 100644 index 69a571a..0000000 --- a/org.glite.jp.index/config/site-info.def.example +++ /dev/null @@ -1,77 +0,0 @@ -# -# site-info.def example, part for org.glite.jp.index -# -# options configured by YAIM can be overriden by: -# - /etc/glite.conf -# - $GLITE_LOCATION/etc/glite-wms.conf -# - $HOME/.glite.conf # of root user -# - - -# -# required minimum set of YAIM options given from -# /opt/glite/yaim/examples/siteinfo/site-info.def -# -YAIM_LOGGING_LEVEL=INFO -MY_DOMAIN=civ.zcu.cz -INSTALL_ROOT=/opt -CRON_DIR=/etc/cron.d -GLOBUS_TCP_PORT_RANGE="20000,25000" -MYSQL_PASSWORD=set_this_to_a_good_password - - -# -# default values of basic options -# - -#GLITE_LOCATION=${INSTALL_ROOT:-opt}/glite -#GLITE_LOCATION_VAR=${GLITE_LOCATION_VAR:-/var/glite} -#GLITE_USER=${GLITE_USER:-glite} -#GLITE_HOST_CERT=${GLITE_USER_HOME:-/home/glite}/.certs/hostcert.pem -#GLITE_HOST_KEY=${GLITE_USER_HOME:-/home/glite}/.certs/hostkey.pem -#X509_CERT_DIR=/etc/grid-security/certificates - - -# -# required external options -# - -#GLOBUS_LOCATION=/opt/globus - - -# -# JPIS configuration default values -# - -# pidfile -#GLITE_JPIS_PIDFILE=$GLITE_LOCATION_VAR/glite-jp-indexd.pid - -# logfile -#GLITE_JPIS_LOGFILE=$GLITE_LOCATION_VAR/glite-jp-indexd.log - -# configuration file -# -# Before launching YAIM you should configure there: -# - feeds (data streams) - contains primary storage and filter -# - attribute set -# - indices set -# -#GLITE_JPIS_CONFIG=$GLITE_LOCATION/etc/glite-jpis-config.xml - -# port -#GLITE_JPIS_PORT=8902 - -# connection string to database (USER/PASSWORD@HOST:DBNAME) -# If the default is changed, the database has to be created manually ! -#GLITE_JPIS_DB=jpis/@localhost:jpis - -# used types of feeds -#GLITE_JPIS_QT="both" - -# Index server returns only jobs owned by given user. -# Use '-n' value to force indexd not to check authentization. -#GLITE_JPIS_AUTH="" - -# Can have '-d' value to force indexd not to deamonize. -# Never use it here. -#GLITE_JPIS_DEBUG="" diff --git a/org.glite.jp.index/config/startup b/org.glite.jp.index/config/startup deleted file mode 100755 index 4680b41..0000000 --- a/org.glite.jp.index/config/startup +++ /dev/null @@ -1,135 +0,0 @@ -#! /bin/sh - -# -# startup script for JP index server -# - -GLITE_LOCATION=${GLITE_LOCATION:-/opt/glite} -GLITE_LOCATION_VAR=${GLITE_LOCATION_VAR:-${GLITE_LOCATION}/var} - -[ -f /etc/glite.conf ] && . /etc/glite.conf -[ -f $GLITE_LOCATION/etc/glite-wms.conf ] && . $GLITE_LOCATION/etc/glite-wms.conf -[ -f $HOME/.glite.conf ] && . $HOME/.glite.conf - -[ -f $GLITE_LOCATION/etc/jpis.conf ] && . $GLITE_LOCATION/etc/jpis.conf -[ -f $GLITE_LOCATION_VAR/etc/jpis.conf ] && . $GLITE_LOCATION_VAR/etc/jpis.conf - -[ -n "$GLITE_JPIS_PIDFILE" ] || export GLITE_JPIS_PIDFILE=$GLITE_LOCATION_VAR/glite-jp-indexd.pid -[ -n "$GLITE_JPIS_LOGFILE" ] || export GLITE_JPIS_LOGFILE=$GLITE_LOCATION_VAR/glite-jp-indexd.log -pidfile="$GLITE_JPIS_PIDFILE" - -test -n "$GLITE_JPIS_CONFIG" || GLITE_JPIS_CONFIG="$GLITE_LOCATION/etc/glite-jpis-config.xml" -test -n "$GLITE_JPIS_PORT" || GLITE_JPIS_PORT=8902 -test -n "$GLITE_JPIS_DB" || GLITE_JPIS_DB=jpis/@localhost:jpis -test -n "$GLITE_JPIS_QT" || GLITE_JPIS_QT="both" -#GLITE_JPIS_AUTH can have '-n' value to force indexd not to check auth -#GLITE_JPIS_DEBUG can have '-d' value to force indexd not to deamonize - -unset creds port - -start() -{ - if test -z "$GLITE_USER" ;then - echo 'Error: GLITE_USER is not set' - echo FAILED - return 1 - fi - if test -z "$GLOBUS_LOCATION" ;then - echo 'Error: GLOBUS_LOCATION is not set' - echo FAILED - return 1 - fi - if [ -n "$GLITE_HOST_CERT" -a -n "$GLITE_HOST_KEY" ] ;then - creds="-c '$GLITE_HOST_CERT' -k '$GLITE_HOST_KEY'" - X509_USER_CERT="$GLITE_HOST_CERT" - X509_USER_KEY="$GLITE_HOST_KEY" - fi - 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="-c /etc/grid-security/hostcert.pem -k /etc/grid-security/hostkey.pem" - X509_USER_CERT=/etc/grid-security/hostcert.pem - X509_USER_KEY=/etc/grid-security/hostkey.pem - fi - fi - - - [ -z "$creds" ] && echo $0: WARNING: No credentials specified. Using default lookup which is dangerous. >&2 - - if [ ! -d "`dirname $GLITE_JPIS_PIDFILE`" ] - then - echo "Directory `dirname $GLITE_JPIS_PIDFILE` does not exist!" - exit 1 - fi - if [ ! -d "`dirname $GLITE_JPIS_LOGFILE`" ] - then - echo "Directory `dirname $GLITE_JPIS_LOGFILE` does not exist!" - exit 1 - fi - - - echo -n Starting glite-jp-indexd ... - #su " $GLITE_LOCATION/bin/glite-jp-indexd \ - su - $GLITE_USER -c " $GLITE_LOCATION/bin/glite-jp-indexd \ - $GLITE_JPIS_DEBUG \ - -q $GLITE_JPIS_QT $creds $GLITE_JPIS_AUTH \ - -m $GLITE_JPIS_DB -p $GLITE_JPIS_PORT \ - -i $GLITE_JPIS_PIDFILE -o $GLITE_JPIS_LOGFILE \ - -x $GLITE_JPIS_CONFIG - " && echo " done" || echo " FAILED" -} - -stop() -{ - if [ -f $pidfile ]; then - pid=`cat $pidfile` - kill $pid - echo -n Stopping glite-jp-indexd \($pid\) ... - try=0 - while ps p $pid >/dev/null 2>&1; do - sleep 1; - try=`expr $try + 1` - if [ $try = 20 ]; then - echo " giving up after $try retries" - return 1 - fi - done - echo " done" - rm -f $pidfile - else - echo $pidfile does not exist - glite-jp-indexd not running? >&2 - return 1 - fi - - return 0 -} - -status() -{ -# if [ -f $pidfile ]; then -# pid=`cat $pidfile` -# if ps p $pid >/dev/null 2>&1; then -# echo glite-jp-indexd running as $pid -# return 0 -# fi -# fi - - retval=0 - if netstat -an --inet | grep "^tcp .* 0.0.0.0:${GLITE_JPIS_PORT} .*LISTEN" >/dev/null 2>&1 ;then - echo glite-jp-indexd running - else - echo glite-jp-indexd not running - retval=1 - fi - - return $retval -} - -case x$1 in - xstart) start;; - xstop) stop;; - xrestart) stop; start;; - xstatus) status;; - x*) echo usage: $0 start,stop,restart,status >&2 - exit 1;; -esac diff --git a/org.glite.jp.index/configure b/org.glite.jp.index/configure deleted file mode 100755 index 0bf1a3f..0000000 --- a/org.glite.jp.index/configure +++ /dev/null @@ -1,701 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; - -my $pwd = `pwd`; chomp $pwd; -my $prefix = $pwd.'/stage'; -my $stagedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my $version; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $sec_tag = ''; -my $jobid_tag = ''; - -my @nodes = qw/client server logger utils client-java doc ws-test db jpprimary jpindex jpclient/; -my %enable_nodes; -my %disable_nodes; - -my %extern_prefix = ( - cares => '/opt/c-ares', - classads => '/opt/classads', - cppunit => '/usr', - expat => '/usr', - globus => '/opt/globus', - gsoap => '/usr', - mysql => '/usr', - voms => '/opt/glite', - gridsite => '/opt/glite', - lcas => '/opt/glite', - ant => '/usr', - jdk => '/usr', - libtar => '/usr', -); - -my %jar = ( - 'commons-codec' => '/usr/share/java/commons-codec-1.3.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %topbuild; - -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test/], - 'security' => [qw/gss gsoap-plugin/], - 'lbjp-common' => [qw/db maildir server-bones trio jp-interface/], - 'jobid' => [qw/api-c api-cpp api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - ); - - -my @opts = ( - 'prefix=s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour=s' => \$thrflavour, - 'nothrflavour=s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$version, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'security-tag=s' => \$sec_tag, - 'jobid-tag=s' => \$jobid_tag, - 'help' => \$help, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$extern_prefix{$_} for keys %extern_prefix; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my @m = map "org.glite.$listmodules.$_",@{$lbmodules{$listmodules}}; - print "@m\n"; - exit 0; -} - -warn "$0: --version and --output make sense only in --mode=etics\n" - if ($version || $output) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},@{$lbmodules{security}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless $disable_nodes{$_}; - } -} - -if (!$en && !$dis) { $enable_nodes{$_} = 1 for (@nodes) } ; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $prefix unless $stagedir; - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: $extern_prefix{$_}\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\nclean:\n"; - - for (@modules) { - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - print MAK "\tcd $full$build && \${MAKE} clean\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $topbuild{$_} ? - "\tcd $full$build && \${MAKE} distclean\n" : - "\trm -rf $full$build\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - - print MAK "$_: @dnames\n\tcd $full$build && \${MAKE} && \${MAKE} install\n\n"; - } - - close MAK; -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag){ - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($sec_tag){ - for (@{$lbmodules{security}}){ - if ("security.".$_ eq $module){ - $tag = '-r '.$sec_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads/ ], - 'lb.client-java' => [ qw/ant:B/ ], - 'lb.common' => [ qw/expat cppunit:B classads/ ], - 'lb.doc' => [], - 'lb.logger' => [ qw/cppunit:B/ ], - 'lb.server' => [ qw/globus expat cares mysql cppunit:B gsoap:B classads voms lcas gridsite/ ], - 'lb.state-machine' => [ qw/classads/ ], - 'lb.utils' => [ qw/cppunit:B/ ], - 'lb.ws-interface' => [], - 'lb.ws-test' => [ qw/gsoap:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/mysql/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw/cppunit:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B/ ], - 'security.gss' => [ qw/globus cares cppunit:B/ ], - 'security.gsoap-plugin' => [ qw/cppunit:B globus cares gsoap:B/ ], - 'jobid.api-c' => [ qw/cppunit:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], -); - -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$need_externs{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $need_externs_type{$ext}->{$1} = $type; - } -} - -%need_jars = ( - 'jobid.api-java' => [ qw/commons-codec/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp jobid.api-c - security.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp jobid.api-c - lb.types:B lbjp-common.trio security.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - jobid.api-c - lb.common - security.gss - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir - jobid.api-c - security.gsoap-plugin security.gss - / ], - 'lb.state-machine' => [ qw/lb.common lbjp-common.jp-interface security.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine - / ], - 'lb.ws-test' => [ qw/security.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/lbjp-common.trio/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw// ], - 'security.gss' => [ qw// ], - 'security.gsoap-plugin' => [ qw/security.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - security.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( gridsite=>'org.gridsite.core'); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', -); - -my @t = qw/lb.client-java jobid.api-java lb.types/; -@topbuild{@t} = (1) x ($#t+1); -} - -sub full -{ - my $short = shift; - return $extrafull{$short} ? $extrafull{$short} : 'org.glite.'.$short; -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java -security.gss security.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -/; - @aux{@m} = (1) x ($#m+1); - - my $short = shift; - my $full = full $short; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $build = ''; - - unless ($topbuild{$_}) { - $build = '/build'; - unless (-d "$full/build") { - mkdir "$full/build" or die "mkdir $full/build: $!\n"; - } - unlink "$full/build/Makefile"; - symlink "../Makefile","$full/build/Makefile" or die "symlink ../Makefile $full/build/Makefile: $!\n"; - } - - open MKINC,">$full$build/Makefile.inc" - or die "$full$build/Makefile.inc: $!\n"; - - print "Creating $full$build/Makefile.inc\n"; - - print MKINC qq{ -PREFIX = $prefix -stagedir = $stagedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -}; - - for (@{$need_externs{$short}}) { - print MKINC "${_}_prefix = $extern_prefix{$_}\n" - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; -} - -my %etics_externs; -my %etics_projects; -BEGIN{ - %etics_externs = ( - globus=>'vdt_globus_essentials', - cares=>'c-ares', - voms=>'org.glite.security.voms-api-cpp', - gridsite=>'org.gridsite.shared', - lcas=>'org.glite.security.lcas', - ); - %etics_projects = ( - vdt=>[qw/globus/], - 'org.glite'=>[qw/voms gridsite lcas/], - ); -}; - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod; - - my ($major,$minor,$rev,$age); - - if ($version) { - $version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - open V,"org.glite.$subsys.$module/project/version.properties" - or die "org.glite.$subsys.$module/project/version.properties: $!\n"; - - while ($_ = ) { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - } - - my @copts = (); - my %ge; - @ge{@{$etics_projects{'org.glite'}}} = (1) x ($#{$etics_projects{'org.glite'}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}/$_*.jar"; - } - - - my $conf = "glite-$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $topbuild{"$subsys.$module"} ? '' : "build.root = build\n"; - - my $confdir = $topbuild{"$subsys.$module"} ? '..' : '../..'; - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = org.glite.$subsys.$module -displayName = $conf -description = org.glite.$subsys.$module -projectName = org.glite -age = $age -deploymentType = None -tag = $conf -version = $major.$minor.$rev -path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz - -[Platform-default:VcsCommand] -displayName = None -description = None -tag = cvs -d \${vcsroot} tag -R \${tag} \${moduleName} -branch = None -commit = None -checkout = cvs -d \${vcsroot} co -r \${tag} \${moduleName} - -[Platform-default:BuildCommand] -postpublish = None -packaging = None -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = make -init = None -install = make install -clean = make clean -test = make check -configure = cd $confdir && \${moduleName}/configure --thrflavour=\${globus.thr.flavor} --nothrflavour=\${globus.nothr.flavor} --prefix=\${prefix} --stage=\${stageDir} --module $subsys.$module @copts -checkstyle = None - -[Platform-default:Property] -$buildroot - -[Platform-default:DynamicDependency] - -}; - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - print C "$proj|$eext = $type\n"; - } - - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - print C "org.glite|org.glite.$_ = $type\n"; - } - - close C; -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$extern_prefix{gsoap}/bin/soapcpp2 -v 2>&1 |" or die "$extern_prefix{gsoap}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - - -sub usage { - my @ext = keys %extern_prefix; - my @myjars, keys %jar; - - print STDERR qq{ -usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - -Mode of operation: - --mode={checkout|build|etics} what to do [build] - -What to build: - --module=module build this module only (mostly in-Etics operation) - --enable-NODE build this "node" (set of modules) only. Available nodes are - @{$lbmodules{lb}},@{$lbmodules{security}} - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --security-tag=tag checkout security modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - -Dependencies: - --with-EXTERNAL=PATH where to look for an external. Required externals - (not all for all modules) are: - @ext - --with-JAR=JAR where to look for jars. Required jars are: - @myjars - Summary of what will be used is always printed - -}; - -} diff --git a/org.glite.jp.index/doc/README b/org.glite.jp.index/doc/README deleted file mode 100644 index 9b79e28..0000000 --- a/org.glite.jp.index/doc/README +++ /dev/null @@ -1,41 +0,0 @@ -Job Provenance Index Server README -================================== - -JPIS is ... - -For comprehensive documentation about JP see org.glite.jp.doc. - -Source code, executables, dependences -------------------------------------- - -JP-IS CVS module name is org.glite.jp.index. It depends on common JP libraries -(module org.glite.jp.common, org.glite.jp.server-common) and implements -interfaces defined in org.glite.jp.ws-interface. It is also based on -org.glite.lb.server-bones. - -JP-IS consist from one stand-alone daemon (glite-jp-indexd) which is -using MySQL database. Default db name is jpis, all access is granted to -user jpis. - -JP-IS interactions: - -- JP primary storage - feedings data from primary storage to the IS according - to particular IS instance administrator needs (expressed by IS configuration) - -- IS user query interface - implements IS service for end users - -- admin interface - intended for admin tools (management and - on-the-fly configuration changes) - - -Release notes -------------- - -- In this release configuration of JP-IS is rather limited. Parts of - configuration are hard-coded (src/conf.c) - -- Debug outputs are on and directed to /opt/glite/var/log/glite-jp-index.log - file. - -- No admin tools are implemented yet. - diff --git a/org.glite.jp.index/doc/client_conf.xsd b/org.glite.jp.index/doc/client_conf.xsd deleted file mode 100644 index 4101567..0000000 --- a/org.glite.jp.index/doc/client_conf.xsd +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.index/doc/glite-jp-indexd.sgml b/org.glite.jp.index/doc/glite-jp-indexd.sgml deleted file mode 100644 index 4b9ad37..0000000 --- a/org.glite.jp.index/doc/glite-jp-indexd.sgml +++ /dev/null @@ -1,372 +0,0 @@ - - - - - - glite-jp-indexd - 8 - EU EGEE Project - - - - glite-jp-indexd - daemon providing subset of data from Job Provenance - - - - - glite-jp-indexd - - - -h - --help - - - -d - - - -q - --query-type - - hist - cont - both - - - - -k - --key - - - - -c - --cert - - - - - - -n - --no-auth - - - - -m - --mysql - USER/PASSWORD@HOST:DBNAME - - - -p - --port - PORT - - - -i - --pidfile - FILE.PID - - - -o - --logfile - FILE.LOG - - - -x - --config - CONFIG.XML - - - -s - --slaves - N - - - -D - --delete-db - - - - -f - --feeding - FILE - - - -F - --force-feed - - - - - - - DESCRIPTION - -glite-jp-index is stand-alone daemon which is using MySQL database. It provides subset of attributes and jobs from Job Provenance. - - - - - OPTIONS - - -With no options you get simple usage message as with . - - - - - | - -Don't run as daemon, additional diagnostics. - - - - - | - -Type of query: , or (default: ). - - - - hist - history query - - - cont - continuous query - - - both - combination of previous types - - - - - - - | - -Private key file. - - - - - | - -Certification file. - - - - - - - | - -Don't check user identity with result owner. - - - - - | - -Database connect string: USER/PASSWORD@HOST:DBNAME (default: ). - - - - - | - -Port to listen (default: ). - - - - - | - -File to store master pid (default: /var/run/glite-jp-indexd.pid or $HOME/glite-jp-indexd.pid). - - - - - | - -File to store logs (default: /var/run/glite-jp-indexd.log or $HOME/glite-jp-indexd.log). - - - - - | - -Configuration file containing information about feeds, primary storages, ... Structure is defined in server_conf.xsd (default: $GLITE_LOCATION/etc/glite-jpis-config.xml). - - - - - | - -Number of slave processes for responses (default: number of feeds, max. 20). - - - - - | - -Delete and refetch the data in the database. You need use this parameter when feeds from primary storage are already expired. - - - - - | - -Feed the index server from the local file. Format of the file is job per line with attribute values using ";" separator. Attributes go in order according to server configuration file (possible attributes with jobid and owner in configuration file are ignored). - - - - - | - -By default old feeds in the database are untouched when JP index server is restarted, and further used and refreshed. This option forces dropping and reloading feeds from the configuration file. - - - - - - - - - Starting the daemon - -Preferred way of starting the daemon is using start-up script (config/startup). It loads glite.conf file (personal version may be stored in ~/.glite.conf) where many variables may be set to configure the daemon. The script takes following variables: - - - - - GLITE_JPIS_CONFIG - -Specifying config file. Default is $GLITE_LOCATION/etc/glite-jpis-config.xml - - - - - GLITE_JPIS_DEBUG - -Setting to '-d' forces the daemon not to daemonize. - - - - - GLITE_JPIS_QT - -Defines query type (see parameter). - - - - - GLITE_JPIS_AUTH - -Setting to '-n' forces the daemon not to check authorisation. - - - - - GLITE_JPIS_PORT - -Used port (default is 8902). - - - - - GLITE_JPIS_DB - -Database connection string, see parameter. - - - - - GLITE_JPIS_LOGFILE - -Log file (default in startup script is $GLITE_LOCATION_VAR/log/glite-jp-indexd.log). - - - - - GLITE_JPIS_PIDFILE - -Pid file (default is in startup script is $GLITE_LOCATION_VAR/run/glite-jp-indexd.pid). - - - - - - - RETURN VALUE - - - 0 - Success start. - - - - 1 - -Error (database or network initialisation for example). - - - - - - - EXAMPLES - - - configure file for startup script - GLITE_LOCATION_VAR=/opt/glite/var -GLITE_JPIS_DB=jpis/@localhost:jpis -GLITE_JPIS_PORT=8902 -GLITE_JPIS_LOGFILE=$GLITE_LOCATION_VAR/run/glite-jp-indexd.log -GLITE_JPIS_PIDFILE=$GLITE_LOCATION_VAR/run/glite-jp-indexd.pid -GLITE_JPIS_DEBUG=0 -GLITE_JPIS_PS=JPPS:8901 -GLITE_JPIS_QT=cont - - - - - glite-jp-indexd -x /opt/glite/etc/glite-jpis-config-custom.xml -i $HOME/jpis.log -o $HOME/jpis.pid - -Manual run of the JP index server. Use local MySQL database, feeds from job provenances and attributes configured in /opt/glite/etc/glite-jpis-config-custom.xml, listen on default port, store logs and pid to given files. - - - - - - - SEE ALSO - glite-jpis-client(1) - - - - AUTHOR - EU DataGrid Work Package 1, CESNET group. - - - diff --git a/org.glite.jp.index/doc/glite-jpis-client.sgml b/org.glite.jp.index/doc/glite-jpis-client.sgml deleted file mode 100644 index 0593485..0000000 --- a/org.glite.jp.index/doc/glite-jpis-client.sgml +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - glite-jpis-client - 1 - EU EGEE Project - - - - glite-jpis-client - client interface for JP IS - - - - - glite-jpis-client - - - -h - --help - - - - -i - --index-server - JPIS:PORT - - - -q - --query-file - IN_FILE.XML - - - -t - --test-file - IN_FILE.XML - - - -e - --example-file - OUT_FILE.XML - - - -f - --format - - xml - human - - - - - - - DESCRIPTION - -glite-jpis-client is command line interface for querying -the Job Provenance Index Server. It takes the XML input, process the QueryJobs -operation and returns the result in specified format. - - - - - OPTIONS - - -With no options you get simple usage message as with . - - - - - | - -Displays usage message. - - - - - | - -Specifies Job Provenance Index Server as HOST:PORT. - - - - - | - -Process the QueryJobs operation. Requires input data in file -IN_FILE.XML, for using stdin specify -. - -The input and output data are in XML format with XSD schema, which can be found -in JobProvenanceISClient.xsd (element QueryJobs for input -and QueryJobsResponse for output). - - - - - | - -Test the input data from IN_FILE.XML (or from stdin -if is specified) and prints the found content. - - - - - | - -Write the example input data to file OUT_FILE.XML -(or to stdout if is specified). The XML is valid against XSD -schema in JobProvananceISClient.xsd, formating may vary -according to used gsoap version. - - - - - | - -Use FORMAT as output format type. You can specify - for interchangeable XML output or -for nice looking human readable output. - - - - - - - RETURN VALUE - - - 0 - Success. - - - - -1 - Communication error or error from the remote server. - - - - EINVAL - In most cases XML parsing error. - - - - other error - Other error from errno. - - - - - - EXAMPLES - - - glite-jpis-client --example-file query.xml - -Save the example query parameters to file query.xml. - - - - - glite-jpis-client --query-file query.xml - -Queries the local index server running on default port with the query -parameters specified in the file query.xml. - - - - - glite-jpis-client -i localhost:8902 -q - -f human - -Queries the index server running on local host on the port 8902 with the query -parameters from stdin and show results in non-XML form. - - - - - - - - SEE ALSO - glite-jp-indexd(8) - - - - AUTHOR - EU DataGrid Work Package 1, CESNET group. - - - diff --git a/org.glite.jp.index/doc/server_conf.xsd b/org.glite.jp.index/doc/server_conf.xsd deleted file mode 100644 index 16f464d..0000000 --- a/org.glite.jp.index/doc/server_conf.xsd +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.index/examples/jpis-client.c b/org.glite.jp.index/examples/jpis-client.c deleted file mode 100644 index 102d1f0..0000000 --- a/org.glite.jp.index/examples/jpis-client.c +++ /dev/null @@ -1,538 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include - -#include "soap_version.h" - -#include -#include -#include - -#include "jp_.nsmap" -#include "common.h" -#define dprintf(FMT, ARGS...) fprintf(stderr, FMT, ##ARGS); -#include - - -#define DEFAULT_JPIS "http://localhost:8902" -#define USE_GMT 1 - - -static struct option opts[] = { - {"index-server",required_argument, NULL, 'i'}, - {"example-file",required_argument, NULL, 'e'}, - {"query-file", required_argument, NULL, 'q'}, - {"test-file", required_argument, NULL, 't'}, - {"format", required_argument, NULL, 'f'}, - {NULL, 0, NULL, 0} -}; -static const char *get_opt_string = "i:q:e:t:f:"; - -#define NUMBER_OP 6 -struct { - enum jptype__queryOp op; - const char *name; -} operations[] = { - {jptype__queryOp__EQUAL, "=="}, - {jptype__queryOp__UNEQUAL, "<>"}, - {jptype__queryOp__LESS, "<"}, - {jptype__queryOp__GREATER, ">"}, - {jptype__queryOp__WITHIN, "WITHIN"}, - {jptype__queryOp__EXISTS, "EXISTS"}, - {0, "unknown"} -}; - -#define NUMBER_ORIG 3 -struct { - enum jptype__attrOrig orig; - const char *name; -} origins[] = { - {jptype__attrOrig__SYSTEM, "SYSTEM"}, - {jptype__attrOrig__USER, "USER"}, - {jptype__attrOrig__FILE_, "FILE"}, - {0, "unknown"} -}; - -typedef enum {FORMAT_XML, FORMAT_STRIPPEDXML, FORMAT_HR} format_t; - - -/* - * set the value - */ -static void value_set(struct soap *soap, struct jptype__stringOrBlob **value, const char *str) { - *value = soap_malloc(soap, sizeof(**value)); - memset(*value, 0, sizeof(*value)); - GSOAP_SETSTRING(*value, soap_strdup(soap, str)); -} - - -/* - * print the query data in the soap structre - */ -static void value_print(FILE *out, const struct jptype__stringOrBlob *value) { - int i, size, maxsize; - unsigned char *ptr; - - if (value) { - if (GSOAP_ISSTRING(value)) fprintf(out, "%s", GSOAP_STRING(value)); - else if (GSOAP_ISBLOB(value)) { - fprintf(out, "BLOB("); - ptr = GSOAP_BLOB(value)->__ptr; - size = GSOAP_BLOB(value)->__size; - - maxsize = 10; - if (ptr) { - maxsize = size < 10 ? size : 10; - for (i = 0; i < maxsize; i++) fprintf(out, "%02X ", ptr[i]); - if (maxsize < size) fprintf(out, "..."); - } else fprintf(out, "NULL"); - fprintf(out, ")"); - } - } else { - fprintf(out, "-"); - } -} - - -/* - * fill the query soap structure with some example data - */ -static void query_example_fill(struct soap *soap, struct _jpelem__QueryJobs *in) { - struct jptype__indexQuery *cond; - struct jptype__indexQueryRecord *rec; - - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, in, conditions, struct jptype__indexQuery, 2); - - // query status - cond = GLITE_SECURITY_GSOAP_LIST_GET(in->conditions, 0); - memset(cond, 0, sizeof(*cond)); - cond->attr = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus"); - cond->origin = soap_malloc(soap, sizeof(*(cond->origin))); - *(cond->origin) = jptype__attrOrig__SYSTEM; - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, cond, record, struct jptype__indexQueryRecord, 2); - - // equal to Done - rec = GLITE_SECURITY_GSOAP_LIST_GET(cond->record, 0); - memset(rec, 0, sizeof(*rec)); - rec->op = jptype__queryOp__EQUAL; - value_set(soap, &rec->value, "Done"); - - // OR equal to Ready - rec = GLITE_SECURITY_GSOAP_LIST_GET(cond->record, 1); - memset(rec, 0, sizeof(*rec)); - rec->op = jptype__queryOp__EQUAL; - value_set(soap, &rec->value, "Ready"); - - - // AND - // owner - cond = GLITE_SECURITY_GSOAP_LIST_GET(in->conditions, 1); - memset(cond, 0, sizeof(*cond)); - cond->attr = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:user"); - cond->origin = NULL; - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, cond, record, struct jptype__indexQueryRecord, 1); - - // not equal to CertSubj - rec = GLITE_SECURITY_GSOAP_LIST_GET(cond->record, 0); - memset(rec, 0, sizeof(*rec)); - rec->op = jptype__queryOp__UNEQUAL; - value_set(soap, &rec->value, "God"); - - - in->__sizeattributes = 4; - in->attributes = soap_malloc(soap, - in->__sizeattributes * - sizeof(*(in->attributes))); - in->attributes[0] = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/JP/System:owner"); - in->attributes[1] = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/JP/System:jobId"); - in->attributes[2] = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus"); - in->attributes[3] = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:user"); - -} - - -/* - * read the XML query - */ -static int query_recv(struct soap *soap, int fd, struct _jpelem__QueryJobs *qj) { - int i; - - memset(qj, 0, sizeof(*qj)); - - soap->recvfd = fd; - soap_begin_recv(soap); - soap_default__jpelem__QueryJobs(soap, qj); - if (!soap_get__jpelem__QueryJobs(soap, qj, "jpelem:QueryJobs", NULL)) { - soap_end_recv(soap); - soap_end(soap); - return EINVAL; - } - soap_end_recv(soap); - - /* strip white-space characters from attributes */ - for (i = 0; i < qj->__sizeattributes; i++) - glite_jpis_trim(qj->attributes[i]); - for (i = 0; i < qj->__sizeconditions; i++) - glite_jpis_trim(GLITE_SECURITY_GSOAP_LIST_GET(qj->conditions, i)->attr); - - return 0; -} - - -/* - * print info from the query soap structure - */ -static void query_print(FILE *out, const struct _jpelem__QueryJobs *in) { - struct jptype__indexQuery *cond; - struct jptype__indexQueryRecord *rec; - int i, j, k; - - fprintf(out, "Conditions:\n"); - for (i = 0; i < in->__sizeconditions; i++) { - cond = GLITE_SECURITY_GSOAP_LIST_GET(in->conditions, i); - fprintf(out, "\t%s\n", cond->attr); - if (cond->origin) { - for (k = 0; k <= NUMBER_ORIG; k++) - if (origins[k].orig == *(cond->origin)) break; - fprintf(out, "\t\torigin == %s\n", origins[k].name); - } else { - fprintf(out, "\t\torigin IS ANY\n"); - } - for (j = 0; j < cond->__sizerecord; j++) { - rec = GLITE_SECURITY_GSOAP_LIST_GET(cond->record, j); - for (k = 0; k <= NUMBER_OP; k++) - if (operations[k].op == rec->op) break; - fprintf(out, "\t\tvalue %s", operations[k].name); - if (rec->value) { - fprintf(out, " "); - value_print(out, rec->value); - } - if (rec->value2) { - if (!rec->value) fprintf(out, "-"); - fprintf(out, " AND "); - value_print(out, rec->value2); - } - fprintf(out, "\n"); - } - } - fprintf(out, "Attributes:\n"); - for (i = 0; i < in->__sizeattributes; i++) - fprintf(out, "\t%s\n", in->attributes[i]); -} - - -/* - * dump the XML query - */ -static int query_dump(struct soap *soap, int fd, struct _jpelem__QueryJobs *qj) { - int retval; - - soap->sendfd = fd; - soap_begin_send(soap); - soap_serialize__jpelem__QueryJobs(soap, qj); - retval = soap_put__jpelem__QueryJobs(soap, qj, "jpelem:QueryJobs", NULL); - soap_end_send(soap); - write(fd, "\n", strlen("\n")); - - return retval; -} - - -static int query_format(struct soap *soap, format_t format, FILE *f, struct _jpelem__QueryJobs *qj) { - switch (format) { - case FORMAT_XML: - case FORMAT_STRIPPEDXML: - return query_dump(soap, fileno(f), qj); - case FORMAT_HR: query_print(f, qj); return 0; - default: return EINVAL; - } -} - - -/* - * dump the XML query with the example data - */ -static int query_example_dump(struct soap *soap, int fd) { - struct _jpelem__QueryJobs qj; - int retval; - - memset(&qj, 0, sizeof(qj)); - - soap_begin(soap); - query_example_fill(soap, &qj); - retval = query_dump(soap, fd, &qj); - soap_end(soap); - - return retval; -} - - -/* - * dump the data returned from JP IS - */ -static int queryresult_dump(struct soap *soap, int fd, const struct _jpelem__QueryJobsResponse *qjr) { - int retval; - - soap->sendfd = fd; - soap_begin_send(soap); - soap_serialize__jpelem__QueryJobsResponse(soap, qjr); - retval = soap_put__jpelem__QueryJobsResponse(soap, qjr, "QueryJobsResponse", NULL); - soap_end_send(soap); - write(fd, "\n", strlen("\n")); - - return retval; -} - - -/* - * print the data returned from JP IS - */ -static void queryresult_print(FILE *out, const struct _jpelem__QueryJobsResponse *in) { - struct jptype__jobRecord *job; - struct jptype__attrValue *attr; - int i, j, k; - -#if USE_GMT - setenv("TZ","UTC",1); tzset(); -#endif - fprintf(out, "Result %d jobs:\n", in->__sizejobs); - for (j=0; j__sizejobs; j++) { - job = GLITE_SECURITY_GSOAP_LIST_GET(in->jobs, j); - fprintf(out, "\tjobid = %s, owner = %s\n", job->jobid, job->owner); - for (i=0; i__sizeattributes; i++) { - attr = GLITE_SECURITY_GSOAP_LIST_GET(job->attributes, i); - fprintf(out, "\t\t%s\n", attr->name); - fprintf(out, "\t\t\tvalue = "); - value_print(out, attr->value); - fprintf(out, "\n"); - - for (k = 0; k <= NUMBER_ORIG; k++) - if (origins[k].orig == attr->origin) break; - fprintf(out, "\t\t\torigin = %s", origins[k].name); - if (attr->originDetail) fprintf(out, ", %s\n", attr->originDetail); - else fprintf(out, " (no detail)\n"); - if (attr->timestamp != (time_t)0) - fprintf(out, "\t\t\ttime = %s", ctime(&attr->timestamp)); - } - } -} - - -static int queryresult_format(struct soap *soap, format_t format, FILE *f, const struct _jpelem__QueryJobsResponse *qj) { - switch (format) { - case FORMAT_XML: - case FORMAT_STRIPPEDXML: - return queryresult_dump(soap, fileno(f), qj); - case FORMAT_HR: queryresult_print(f, qj); return 0; - default: return EINVAL; - } -} - - -/* - * help screen - */ -static void usage(const char *prog_name) { - fprintf(stderr, "Usage: %s OPTIONS\n", prog_name); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -h|--help\n"); - fprintf(stderr, " -i|--index-server JPIS:PORT (default: " DEFAULT_JPIS ")\n"); - fprintf(stderr, " -q|--query-file IN_FILE.XML\n"); - fprintf(stderr, " -t|--test-file IN_FILE.XML\n"); - fprintf(stderr, " -e|--example-file OUT_FILE.XML\n"); - fprintf(stderr, " -f|--format xml | strippedxml | human\n"); -} - - -/* - * process the result after calling soap - */ -#define check_fault(SOAP, ERR) glite_jp_clientCheckFault((SOAP), (ERR), NULL, 0) - - -int main(int argc, char * const argv[]) { - struct soap soap, soap_comm; - struct _jpelem__QueryJobs qj; - char *server, *example_file, *query_file, *test_file; - const char *prog_name; - int retval, opt, example_fd, query_fd, test_fd; - format_t format = FORMAT_XML; - - prog_name = server = NULL; - example_file = query_file = test_file = NULL; - query_fd = example_fd = test_fd = -1; - retval = 1; - - soap_init(&soap); - soap_set_namespaces(&soap, jp__namespaces); - - /* - * Soap with registered plugin can't be used for reading XML. - * For communications with JP IS glite_gsplugin needs to be registered yet. - */ - soap_init(&soap_comm); - soap_set_namespaces(&soap_comm, jp__namespaces); - soap_register_plugin(&soap_comm, glite_gsplugin); - - /* program name */ - prog_name = strrchr(argv[0], '/'); - if (prog_name) prog_name++; - else prog_name = argv[0]; - - if (argc <= 1) { - usage(prog_name); - goto cleanup; - } - - /* handle arguments */ - while ((opt = getopt_long(argc, argv, get_opt_string, opts, NULL)) != EOF) switch (opt) { - case 'i': - free(server); - server = strdup(optarg); - break; - case 'e': - free(example_file); - example_file = strdup(optarg); - break; - case 'q': - free(query_file); - query_file = strdup(optarg); - break; - case 't': - free(test_file); - test_file = strdup(optarg); - break; - case 'f': - if (strcasecmp(optarg, "xml") == 0) format = FORMAT_XML; - else if (strcasecmp(optarg, "strippedxml") == 0) format = FORMAT_STRIPPEDXML; - else format = FORMAT_HR; - break; - default: - usage(prog_name); - goto cleanup; - } - if (optind < argc) { - usage(prog_name); - goto cleanup; - } - if (!server) server = strdup(DEFAULT_JPIS); -#ifdef SOAP_XML_INDENT - if (format != FORMAT_STRIPPEDXML) soap_omode(&soap, SOAP_XML_INDENT); -#endif - - - /* prepare steps according to the arguments */ - if (query_file) { - if (strcmp(query_file, "-") == 0) query_fd = STDIN_FILENO; - else if ((query_fd = open(query_file, 0)) < 0) { - fprintf(stderr, "error opening %s: %s\n", query_file, strerror(errno)); - goto cleanup; - } - free(query_file); - query_file = NULL; - } - if (example_file) { - if (strcmp(example_file, "-") == 0) example_fd = STDOUT_FILENO; - else if ((example_fd = creat(example_file, S_IREAD | S_IWRITE | S_IRGRP)) < 0) { - fprintf(stderr, "error creating %s: %s\n", example_file, strerror(errno)); - goto cleanup; - } - free(example_file); - example_file = NULL; - } - if (test_file) { - if (strcmp(test_file, "-") == 0) test_fd = STDIN_FILENO; - else if ((test_fd = open(test_file, 0)) < 0) { - fprintf(stderr, "error opening %s: %s\n", test_file, strerror(errno)); - goto cleanup; - } - free(test_file); - test_file = NULL; - } - - /* the dump action */ - if (example_fd >= 0) { - if (query_example_dump(&soap, example_fd) != 0) { - fprintf(stderr, "Error dumping example query XML.\n"); - } - } - - /* the test XML file action */ - if (test_fd >= 0) { - soap_begin(&soap); - if (query_recv(&soap, test_fd, &qj) != 0) { - fprintf(stderr, "test: Error getting query XML\n"); - } else { - query_format(&soap, format, stdout, &qj); - } - soap_end(&soap); - } - - /* query action */ - if (query_fd >= 0) { - struct _jpelem__QueryJobs in; - struct _jpelem__QueryJobsResponse out; - int ret; - - soap_begin(&soap); - memset(&in, 0, sizeof(in)); - memset(&out, 0, sizeof(out)); - /* - * Right way would be copy data from client query structure to IS query - * structure. Just ugly retype to client here. - */ - if (query_recv(&soap, query_fd, (struct _jpelem__QueryJobs *)&in) != 0) { - fprintf(stderr, "query: Error getting query XML\n"); - } else { - fprintf(stderr, "query: using JPIS %s\n\n", server); - query_print(stderr, &in); - fprintf(stderr, "\n"); - soap_begin(&soap_comm); - ret = check_fault(&soap_comm, soap_call___jpsrv__QueryJobs(&soap_comm, server, "", &in, &out)); - if (ret == 0) { - queryresult_format(&soap, format, stdout, (struct _jpelem__QueryJobsResponse *)&out); - } else { - soap_end(&soap_comm); - soap_end(&soap); - goto cleanup; - } - soap_end(&soap_comm); - } - soap_end(&soap); - } - - retval = 0; - -cleanup: - soap_done(&soap); - soap_done(&soap_comm); - if (example_fd > STDERR_FILENO) close(example_fd); - if (query_fd > STDERR_FILENO) close(query_fd); - if (test_fd > STDERR_FILENO) close(test_fd); - free(server); - free(example_file); - free(query_file); - free(test_file); - - return retval; -} diff --git a/org.glite.jp.index/examples/jpis-db-internal.c b/org.glite.jp.index/examples/jpis-db-internal.c deleted file mode 100644 index 45a9b42..0000000 --- a/org.glite.jp.index/examples/jpis-db-internal.c +++ /dev/null @@ -1,151 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include - -#include - -#include "db_ops.h" - - -static void print_err(glite_jp_context_t ctx) { - glite_jp_error_t *e; - - e = ctx->error; - while(e) { - printf("%s (%s)\n", e->desc, e->source); - e = e->reason; - } - printf("\n"); -} - - -int glite_jpis_db_queries_serialize(void **blob, size_t *len, glite_jp_query_rec_t **queries); -int glite_jpis_db_queries_deserialize(glite_jp_query_rec_t ***queries, void *blob, size_t blob_size); - -int main(int argc, char *argv[]) { -#if 1 - glite_jp_context_t jpctx; - glite_jp_is_conf *conf; - glite_jpis_context_t isctx; - int ret; - long int uniqueid; - char *ps, *feedid; - - jpctx = NULL; - isctx = NULL; - conf = NULL; - glite_jp_init_context(&jpctx); - if (glite_jp_get_conf(argc, argv, NULL, &conf) != 0) goto fail; - if (glite_jpis_init_context(&isctx, jpctx, conf) != 0) goto fail; - if (glite_jpis_init_db(isctx) != 0) goto fail; - - printf("dropping...\n"); - if (glite_jpis_dropDatabase(isctx) != 0) goto faildb; - - printf("initializing...\n"); - if (glite_jpis_initDatabase(isctx) != 0) goto faildb; - - printf("locking...\n"); - do { - if ((ret = glite_jpis_lockUninitializedFeed(isctx, &uniqueid, &ps)) == ENOLCK) goto faildb; - if (ret == 0) { - printf("locked: uniqueid=%li, ps=%s\n", uniqueid, ps); - free(ps); - - asprintf(&feedid, "feed://%lu", uniqueid + 3); - if (glite_jpis_initFeed(isctx, uniqueid, feedid, (time_t)10000) != 0) { - free(feedid); - goto faildb; - } - free(feedid); - - if (glite_jpis_unlockFeed(isctx, uniqueid) != 0) goto faildb; - } - } while (ret == 0); - - if (glite_jpis_tryReconnectFeed(isctx, uniqueid, time(NULL) + 10) != 0) goto faildb; - - glite_jpis_free_db(isctx); - glite_jpis_free_context(isctx); - glite_jp_free_conf(conf); - glite_jp_free_context(jpctx); - - return 0; - -faildb: - glite_jpis_free_db(isctx); -fail: - printf("failed\n"); - glite_jpis_free_context(isctx); - glite_jp_free_conf(conf); - if (jpctx) { - print_err(jpctx); - glite_jp_free_context(jpctx); - } - - return 1; -#endif -#if 0 - glite_jp_context_t ctx; - glite_jp_is_conf *conf; - void *blob; - size_t len; - int ret, i; - glite_jp_query_rec_t **queries; - - ret = 0; - glite_jp_init_context(&ctx); - - if (glite_jp_get_conf(argc, argv, NULL, &conf) != 0) goto fail_ctx; - if ((ret = glite_jpis_db_queries_serialize(&blob, &len, conf->feeds[0]->query)) != 0) goto fail; - - if (write(1, blob, len) != len) { - ret = errno; - free(blob); - goto fail; - } - - if ((ret = glite_jpis_db_queries_deserialize(&queries, blob, len)) != 0) goto fail_blob; - i = 0; - while (queries[i] && queries[i]->attr) { - printf("query: attr=%s, op=%d, value=%s, value2=%s, bin=%d\n", queries[i]->attr, queries[i]->op, queries[i]->value, queries[i]->value2, queries[i]->binary); - free(queries[i]->attr); - free(queries[i]->value); - free(queries[i]->value2); - free(queries[i]); - i++; - } - free(queries); - - free(blob); - glite_jp_free_context(ctx); - return 0; - -fail_blob: - free(blob); -fail: - fprintf(stderr, "fail: %s\n", strerror(ret)); -fail_ctx: - glite_jp_free_context(ctx); - return 1; -#endif -} diff --git a/org.glite.jp.index/examples/jpis-test.c b/org.glite.jp.index/examples/jpis-test.c deleted file mode 100644 index d6ddcb9..0000000 --- a/org.glite.jp.index/examples/jpis-test.c +++ /dev/null @@ -1,255 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include - -#include -#include -#include "glite/jobid/strmd5.h" - -#include "jp_H.h" -#include "jp_.nsmap" -#include "db_ops.h" -#include "conf.h" - - -#include "soap_version.h" -#if GSOAP_VERSION <= 20602 -#define soap_call___jpsrv__UpdateJobs soap_call___ns1__UpdateJobs -#define soap_call___jpsrv__QueryJobs soap_call___ns1__QueryJobs -#endif -#define dprintf(FMT, ARGS...) fprintf(stderr, FMT, ##ARGS); -#define check_fault(SOAP, ERR) glite_jp_clientCheckFault((SOAP), (ERR), NULL, 0) -#include "glite/jp/ws_fault.c" - - -/* insert simulating FeedIndex call */ -#define INSERT "insert into feeds value ('93', '12345', '8', '0' , 'http://localhost:8901', '2005-10-14 10:48:27', 'COND2');" -#define DELETE "delete from feeds where feedid = '12345';" - - -int main(int argc,char *argv[]) -{ - char *default_server = NULL; - char server[512]; - struct soap *soap = soap_new(); - - soap_init(soap); - soap_set_namespaces(soap, jp__namespaces); - soap_register_plugin(soap,glite_gsplugin); - -/*---------------------------------------------------------------------------*/ - // simulate FeedIndex PS response - { - glite_jp_context_t ctx; - glite_jpis_context_t isctx = NULL; - glite_jp_is_conf *conf; - - - glite_jp_init_context(&ctx); - glite_jp_get_conf(argc, argv, &conf); - if (!conf) { - fprintf(stderr, "Can't gather configuration\n"); - goto end; - } - if (default_server) strcpy(server, default_server); - else snprintf(server, sizeof(server), "http://localhost:%s", conf->port ? conf->port : GLITE_JPIS_DEFAULT_PORT_STR); - printf("JP index server: %s\n", server); - - glite_jpis_init_context(&isctx, ctx, conf); - if (glite_jpis_init_db(isctx) != 0) { - fprintf(stderr, "Connect DB failed: %s (%s)\n", - ctx->error->desc, ctx->error->source); - goto end; - } - - if (glite_jp_db_ExecSQL(ctx, DELETE, NULL) < 0) goto end; - if (glite_jp_db_ExecSQL(ctx, INSERT, NULL) < 0) goto end; - end: - glite_jpis_free_context(isctx); - glite_jp_free_context(ctx); - glite_jp_free_conf(conf); - } - -/*---------------------------------------------------------------------------*/ - // test calls of server functions - // this call is issued by JPPS - { - struct jptype__jobRecord *rec; - struct _jpelem__UpdateJobs in; - struct _jpelem__UpdateJobsResponse out; - struct jptype__attrValue *a; - - memset(&in, 0, sizeof(in)); - memset(&out, 0, sizeof(out)); - - in.feedId = soap_strdup(soap, "12345"); - in.feedDone = GLITE_SECURITY_GSOAP_FALSE; - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, &in, jobAttributes, struct jptype__jobRecord, 2); - rec = GLITE_SECURITY_GSOAP_LIST_GET(in.jobAttributes, 0); - { - memset(rec, 0, sizeof(*rec)); - rec->jobid = soap_strdup(soap, "https://localhost:7846/pokus1"); - { - edg_wll_GssCred cred = NULL; - edg_wll_GssStatus gss_code; - - if ( edg_wll_gss_acquire_cred_gsi(NULL, NULL, &cred, &gss_code) ) { - printf("Cannot obtain credentials - exiting.\n"); - return EINVAL; - } - rec->owner = soap_strdup(soap, cred->name); - } - rec->__sizeprimaryStorage = 0; - rec->primaryStorage = NULL; - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, rec, attributes, struct jptype__attrValue, 2); - a = GLITE_SECURITY_GSOAP_LIST_GET(rec->attributes, 0); - a->name = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:user"); - a->value = soap_malloc(soap, sizeof(*(a->value))); - memset(a->value, 0, sizeof(a->value)); - GSOAP_SETSTRING(a->value, soap_strdup(soap, "CertSubj")); - a->timestamp = 333; - a->origin = jptype__attrOrig__SYSTEM; - a->originDetail = NULL; - - a = GLITE_SECURITY_GSOAP_LIST_GET(rec->attributes, 1); - a->name = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus"); - a->value = soap_malloc(soap, sizeof(*(a->value))); - memset(a->value, 0, sizeof(a->value)); - GSOAP_SETSTRING(a->value, soap_strdup(soap, "Done")); - a->timestamp = 333; - a->origin = jptype__attrOrig__SYSTEM; - a->originDetail = NULL; - - } - - rec = GLITE_SECURITY_GSOAP_LIST_GET(in.jobAttributes, 1); - { - memset(rec, 0, sizeof(*rec)); - rec->jobid = soap_strdup(soap, "https://localhost:7846/pokus2"); - rec->owner = soap_strdup(soap, "OwnerName"); - rec->__sizeprimaryStorage = 0; - rec->primaryStorage = NULL; - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, rec, attributes, struct jptype__jobRecord, 2); - a = GLITE_SECURITY_GSOAP_LIST_GET(rec->attributes, 0); - a->name = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:user"); - a->value = soap_malloc(soap, sizeof(*(a->value))); - memset(a->value, 0, sizeof(a->value)); - GSOAP_SETSTRING(a->value, soap_strdup(soap, "CertSubj")); - a->timestamp = 333; - a->origin = jptype__attrOrig__USER; - a->originDetail = NULL; - - a = GLITE_SECURITY_GSOAP_LIST_GET(rec->attributes, 1); - a->name = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus"); - a->value = soap_malloc(soap, sizeof(*(a->value))); - memset(a->value, 0, sizeof(a->value)); - GSOAP_SETSTRING(a->value, soap_strdup(soap, "Ready")); - a->timestamp = 333; - a->origin = jptype__attrOrig__SYSTEM; - a->originDetail = NULL; - } - - check_fault(soap, - soap_call___jpsrv__UpdateJobs(soap,server,"",&in,&out)); - } - -/*---------------------------------------------------------------------------*/ - // this query call issued by user - { - struct _jpelem__QueryJobs in; - struct jptype__indexQuery *cond; - struct jptype__indexQueryRecord *rec; - struct _jpelem__QueryJobsResponse out; - struct jptype__jobRecord *job; - struct jptype__attrValue *attr; - int i, j; - - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, &in, conditions, struct jptype__indexQuery, 2); - - // query status - cond = GLITE_SECURITY_GSOAP_LIST_GET(in.conditions, 0); - memset(cond, 0, sizeof(*cond)); - cond->attr = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus"); - cond->origin = NULL; - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, cond, record, struct jptype__indexQueryRecord, 2); - - // equal to Done - rec = GLITE_SECURITY_GSOAP_LIST_GET(cond->record, 0); - memset(rec, 0, sizeof(*rec)); - rec->op = jptype__queryOp__EQUAL; - rec->value = soap_malloc(soap, sizeof(*(rec->value))); - memset(rec->value, 0, sizeof(*rec->value)); - GSOAP_SETSTRING(rec->value, soap_strdup(soap, "Done")); - - // OR equal to Ready - rec = GLITE_SECURITY_GSOAP_LIST_GET(cond->record, 1); - memset(rec, 0, sizeof(*rec)); - rec->op = jptype__queryOp__EQUAL; - rec->value = soap_malloc(soap, sizeof(*(rec->value))); - memset(rec->value, 0, sizeof(*rec->value)); - GSOAP_SETSTRING(rec->value, soap_strdup(soap, "Ready")); - - - // AND - // owner - cond = GLITE_SECURITY_GSOAP_LIST_GET(in.conditions, 1); - memset(cond, 0, sizeof(*cond)); - cond->attr = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:user"); - cond->origin = NULL; - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, cond, record, struct jptype__indexQueryRecord, 1); - - // not equal to CertSubj - rec = GLITE_SECURITY_GSOAP_LIST_GET(cond->record, 0); - memset(rec, 0, sizeof(*rec)); - rec->op = jptype__queryOp__UNEQUAL; - rec->value = soap_malloc(soap, sizeof(*(rec->value))); - memset(rec->value, 0, sizeof(*rec->value)); - GSOAP_SETSTRING(rec->value, soap_strdup(soap, "God")); - - - in.__sizeattributes = 4; - in.attributes = soap_malloc(soap, - in.__sizeattributes * - sizeof(*(in.attributes))); - in.attributes[0] = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/JP/System:owner"); - in.attributes[1] = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/JP/System:jobId"); - in.attributes[2] = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus"); - in.attributes[3] = soap_strdup(soap, "http://egee.cesnet.cz/en/Schema/LB/Attributes:user"); - - memset(&out, 0, sizeof(out)); - - check_fault(soap, - soap_call___jpsrv__QueryJobs(soap, server, "",&in,&out)); - - for (j=0; jjobid); - for (i=0; i__sizeattributes; i++) { - attr = GLITE_SECURITY_GSOAP_LIST_GET(job->attributes, i); - printf("\t%s = %s\n", - attr->name, - GSOAP_ISSTRING(attr->value) ? GSOAP_STRING(attr->value) : "binary"); - } - } - } - - return 0; -} diff --git a/org.glite.jp.index/examples/pch06/pch.pm b/org.glite.jp.index/examples/pch06/pch.pm deleted file mode 100644 index 46e5be2..0000000 --- a/org.glite.jp.index/examples/pch06/pch.pm +++ /dev/null @@ -1,237 +0,0 @@ -# -# Job Provenance queries wrapper (Primary and Index queries) -# -# $debug - trace calls -# $err - error status from last query -# - -package pch; - -use strict; -use warnings; -use XML::Twig; -use Data::Dumper; - -our $ps='https://skurut1.cesnet.cz:8901'; -our $is='https://scientific.civ.zcu.cz:8904'; - -our $lbattr='http://egee.cesnet.cz/en/Schema/LB/Attributes'; -our $jpsys='http://egee.cesnet.cz/en/Schema/JP/System'; -our $jpwf='http://egee.cesnet.cz/en/Schema/JP/Workflow'; -our $jplbtag='http://egee.cesnet.cz/en/WSDL/jp-lbtag'; - -our @view_attributes=("$pch::jplbtag:IPAW_STAGE", "$pch::jplbtag:IPAW_PROGRAM", "$pch::jplbtag:IPAW_PARAM", "$pch::jplbtag:IPAW_INPUT", "$pch::jplbtag:IPAW_OUTPUT", "$pch::lbattr:CE", "$pch::lbattr:parent", "$pch::lbattr:host", "$pch::jpsys:regtime"); - - -our $debug = 0; -our $err = 0; - -my $jpis_client_program = "./glite-jpis-client"; -my $jpps_client_program = "./glite-jp-primary-test"; -my @default_is_attributes = ( - "http://egee.cesnet.cz/en/Schema/JP/System:owner", - "http://egee.cesnet.cz/en/Schema/JP/System:jobId", - "http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus", - "http://egee.cesnet.cz/en/Schema/LB/Attributes:user", - "http://egee.cesnet.cz/en/WSDL/jp-lbtag:IPAW_PROGRAM", - "http://egee.cesnet.cz/en/Schema/JP/Workflow:ancestor" -); -my @isquery = ( -' - -', -' -' -); - - -my @jobs; - - -# -# query to Job Provenance Index Server -# -sub isquery { - my ($server, $queries, $attributes, $origin) = @_; - my ($s, @jobs); - my $args = ''; - my @attributes; - my $fh; - - $err = 0; - if ($attributes) { @attributes = @$attributes; } - else { @attributes = @default_is_attributes; } - - $s = $isquery[0]; - foreach my $query (@$queries) { - my @query = @$query; - my $i = 1; - $s .= "\n"; - $s .= "\t$query[0]\n"; - while ($i <= $#query) { - my @record = @{$query[$i]}; - $s .= "\t$origin\n" if $origin; - $s .= "\t\n"; - $s .= "\t\t$record[0]\n"; - $s .= "\t\t$record[1]\n"; - $s .= "\t\t$record[2]\n" if ($record[2]); - $s .= "\t\n"; - $i++; - } - $s .= "\n"; - } - - foreach my $attribute (@attributes) { - $s .= "$attribute\n"; - } - $s .= $isquery[1]; - - $args .= "-i $server " if ($server); - $args .= '-q -'; - - if ($debug) { - print STDERR "calling 'echo '$s' | $jpis_client_program $args |'\n"; - } - if (!open($fh, "echo '$s' | $jpis_client_program $args |")) { - print STDERR "Can't execute '$jpis_client_program $args'\n"; - $err = 1; - return (); - } - @jobs = parse_is($fh); -# print STDERR <$fh>; print STDERR "\n"; - close $fh; - if ($?) { - print STDERR "Error returned from $jpis_client_program $args\n"; - $err = 1; - return (); - } - - return @jobs; -} - - -sub parse_is { - my ($fh) = @_; - my $twig; - - @jobs = (); - - $twig = new XML::Twig(TwigHandlers => { jobs => \&jobs_handler }); - if (!$twig->safe_parse($fh)) { $err = 1; return (); } - else { return @jobs; } -} - - -sub jobs_handler { - my($twig, $xmljobs)= @_; - my (%attributes, $xmljobid, $xmlattribute, %job); - %attributes = (); - - $xmljobid = $xmljobs->first_child('jobid'); - die "No jobid on '".$xmljobs->text."'" if (!$xmljobid); - $job{jobid} = $xmljobid->text; - - $xmlattribute = $xmljobs->first_child('attributes'); - while ($xmlattribute) { - my ($xmlname, $xmlvalue, $xmlorigin); - my @values = (); - my @origins = (); - my %attribute = (); - my $nvalues = 0; - - $xmlname = $xmlattribute->first_child('name'); - die "No name on '".$xmlattribute->text."'" if (!$xmlname); -#print $xmljobid->text.": ".$xmlname->text.":\n"; - if (exists $attributes{$xmlname->text}) { - %attribute = %{$attributes{$xmlname->text}}; - } -#print " prev attr: ".Dumper(%attribute)."\n"; - if (exists $attribute{value}) { - @values = @{$attribute{value}}; - } -#print " prev values: ".Dumper(@values)."\n"; - if (exists $attribute{origin}) { - @origins = @{$attribute{origin}}; - } -#print " prev origins: ".Dumper(@origins)."\n"; - $xmlvalue = $xmlattribute->first_child('value'); - while ($xmlvalue) { -#print " to add: ".$xmlvalue->text."\n"; - push @values, $xmlvalue->text; - $xmlvalue = $xmlvalue->next_sibling('value'); - $nvalues = $nvalues + 1; - } - @{$attribute{value}} = @values; -#print " new values: ".Dumper($attribute{value})."\n"; - $xmlorigin = $xmlattribute->first_child('origin'); - for ($nvalues..1) { - if ($xmlorigin and $xmlorigin->text) { push @origins, $xmlorigin->text; } - else { push @origins, undef; } - } - @{$attribute{origin}} = @origins; -#print " new origins: ".Dumper($attribute{origin})."\n"; - $attribute{timestamp} = $xmlattribute->first_child('timestamp')->text; - $xmlattribute = $xmlattribute->next_sibling('attributes'); - - $attributes{$xmlname->text} = \%attribute; - } - $job{attributes} = \%attributes; - - push @jobs, \%job; -} - -# -# query to Job Provenance Primary Storage -# ==> array of string -# -sub psquery { - my ($server, $jobid, $attribute) = @_; - my $args = ''; - my @attrs = (); - my $fh; - - $err = 0; - $args .= "-s $server " if ($server); - $args .= "GetJobAttr $jobid $attribute"; - if ($debug) { - print STDERR "calling '$jpps_client_program $args |'\n"; - } - if (!open($fh, "$jpps_client_program $args |")) { - print STDERR "Can't execute '$jpps_client_program $args'\n"; - $err = 1; - return (); - } - @attrs = parse_ps($fh); - close $fh; - if ($?) { - print STDERR "Error returned from $jpps_client_program $args\n"; - $err = 1; - return (); - } - - return @attrs; -} - - -sub parse_ps { - my ($fh) = @_; - my @attrs = (); - my $attr; - - while (<$fh>) { - chomp; - next if (!$_); - next if (/^OK$/); - next if (/^Attribute values:$/); -# print STDERR "$_\n"; - $attr = $_; - $attr =~ s/\t*//; - $attr =~ s/\t.*//; - push @attrs, $attr; - } - - return @attrs; -} - - -1; diff --git a/org.glite.jp.index/examples/pch06/query1.pl b/org.glite.jp.index/examples/pch06/query1.pl deleted file mode 100644 index 3b48708..0000000 --- a/org.glite.jp.index/examples/pch06/query1.pl +++ /dev/null @@ -1,132 +0,0 @@ -#! /usr/bin/perl -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# 1. query: -# -# Find the process that led to Atlas X Graphic / everything that caused Atlas X -# Graphic to be as it is. This should tell us the new brain images from which -# the averaged atlas was generated, the warping performed etc. -# -# call: -# ./query1.pl OUTPUT_FILE_NAME 2>/dev/null -# - -use strict; -use pch; -use Data::Dumper; - -my $ps=$pch::ps; -my $is=$pch::is; - -my @according_jobs = (); # sequencially jobid list -my %according_jobs = (); # hash jobid list -my $according_count = 0; -my $output; - - -if ($#ARGV + 1 != 1) { - print STDERR "Usage: $0 OUTPUT_FILE\n"; - exit 1 -} -$output = $ARGV[0]; - -# debug calls -$pch::debug = 0; -my $debug = 0; - -# -# find out processes with given output -# -my @jobs = pch::isquery($is, [ - ["$pch::jplbtag:IPAW_OUTPUT", ['EQUAL', "$output"]], -], ["$pch::jpsys:jobId", "$pch::jpwf:ancestor"]); -print Dumper(@jobs) if ($debug); -die "...so exit on error" if ($pch::err); - -# -# initial set from index server -# -foreach my $job (@jobs) { - my %job = %$job; - my %attributes = %{$job{attributes}}; - - if (!exists $according_jobs{$job{jobid}}) { - push @according_jobs, $job{jobid}; - $according_jobs{$job{jobid}} = 1; - } -} -undef @jobs; - - -# -# collect all jobids (tree browsing) -# -# better implementation will be: using children attribute on LB:parent -# -$according_count = 0; -foreach my $jobid (@according_jobs) { - my @attrs; - - print "Handling $jobid (position $according_count)\n" if ($debug); - @attrs = pch::psquery($ps, $jobid, "$pch::jpwf:ancestor"); - - for my $anc_jobid (@attrs) { - print "Considered: $anc_jobid\n" if ($debug); - if (!exists $according_jobs{$anc_jobid}) { - $according_jobs{$anc_jobid} = 1; - push @according_jobs, $anc_jobid; - print "Added $anc_jobid to $#according_jobs\n" if ($debug); - } - else { - print "Already existing $anc_jobid\n" if ($debug); - } - } - $according_count++; -} - -foreach my $jobid (@according_jobs) { - my @attrs2 = pch::psquery($ps, $jobid, "$pch::jplbtag:IPAW_STAGE"); - $according_jobs{$jobid} = $attrs2[0]; -} - -# -# queries on result set -# -print "Results\n"; -print "=======\n"; -print "\n"; -foreach my $jobid (sort { $according_jobs{$b} <=> $according_jobs{$a} } keys %according_jobs) { - print "jobid $jobid:\n"; - - # query & output all desired atributes - foreach my $attr (@pch::view_attributes) { - my @attrs; - my $attr_name = $attr; $attr_name =~ s/.*://; - - @attrs = pch::psquery($ps, $jobid, $attr); - print " attr $attr_name: "; - if ($attr eq "$pch::jpsys:regtime") { - print gmtime(@attrs[0])." (".join(", ", @attrs).")\n"; - } else { - print join(", ", @attrs)."\n"; - } - } - - print "\n"; -} diff --git a/org.glite.jp.index/examples/pch06/query2.pl b/org.glite.jp.index/examples/pch06/query2.pl deleted file mode 100644 index 767fe15..0000000 --- a/org.glite.jp.index/examples/pch06/query2.pl +++ /dev/null @@ -1,147 +0,0 @@ -#! /usr/bin/perl -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# 2. query: -# -# Find the process that led to Atlas X Graphic, excluding everything prior to -# the averaging of images with softmean. -# -# call: -# ./query2.pl OUTPUT_FILE_NAME [SOFTMEAN_PROGRAM] 2>/dev/null -# - -use strict; -use pch; -use Data::Dumper; - -my $ps=$pch::ps; -my $is=$pch::is; -my %program_names = (softmean => 1); - -my @according_jobs = (); # sequencially jobid list -my %according_jobs = (); # hash jobid list -my $according_count = 0; -my $output; - - -if ($#ARGV + 1 < 1) { - print STDERR "Usage: $0 OUTPUT_FILE [PROGRAM]\n"; - exit 1 -} -$output = $ARGV[0]; -if ($#ARGV + 1 > 1) { - %program_names = (); - foreach (split(/ */,$ARGV[1])) { - $program_names{$_} = 1; - } -} - -# debug calls -$pch::debug = 0; -my $debug = 0; - -# -# find out processes with given output -# -my @jobs = pch::isquery($is, [ - ["$pch::jplbtag:IPAW_OUTPUT", ['EQUAL', "$output"]], -], ["$pch::jpsys:jobId", "$pch::jpwf:ancestor"]); -print Dumper(@jobs) if ($debug); -die "...so exit on error" if ($pch::err); - -# -# initial set from index server -# -foreach my $job (@jobs) { - my %job = %$job; - my %attributes = %{$job{attributes}}; - - if (!exists $according_jobs{$job{jobid}}) { - push @according_jobs, $job{jobid}; - $according_jobs{$job{jobid}} = 1; - } -} -undef @jobs; - - -# -# collect all jobids (tree browsing), stop on softmean program -# -# note, the browsing tree is really needed here since we explore the workflow -# -$according_count = 0; -foreach my $jobid (@according_jobs) { - my (@attrs, @program); - - print "Handling $jobid (position $according_count)\n" if ($debug); - - # stop on given program name - @program = pch::psquery($ps, $jobid, "$pch::jplbtag:IPAW_PROGRAM"); - die "More program names of $jobid?" if ($#program > 0); - if (exists $program_names{$program[0]}) { - print "$jobid is $program[0], stop here\n" if $debug; - next; - } - - # else browse up - @attrs = pch::psquery($ps, $jobid, "$pch::jpwf:ancestor"); - for my $anc_jobid (@attrs) { - print "Considered: $anc_jobid\n" if ($debug); - if (!exists $according_jobs{$anc_jobid}) { - $according_jobs{$anc_jobid} = 1; - push @according_jobs, $anc_jobid; - print "Added $anc_jobid to $#according_jobs\n" if ($debug); - } - else { - print "Already existing $anc_jobid\n" if ($debug); - } - } - $according_count++; -} - -foreach my $jobid (@according_jobs) { - my @attrs2 = pch::psquery($ps, $jobid, "$pch::jplbtag:IPAW_STAGE"); - $according_jobs{$jobid} = $attrs2[0]; -} - -# -# queries on result set -# -print "Results\n"; -print "=======\n"; -print "\n"; -foreach my $jobid (sort { $according_jobs{$b} <=> $according_jobs{$a} } keys %according_jobs) { - print "jobid $jobid:\n"; - - # query & output all desired atributes - foreach my $attr (@pch::view_attributes) { - my @attrs; - my $attr_name = $attr; $attr_name =~ s/.*://; - - @attrs = pch::psquery($ps, $jobid, $attr); - print " attr $attr_name: "; - if ($attr eq "$pch::jpsys:regtime") { - print gmtime(@attrs[0])." (".join(", ", @attrs).")\n"; - } else { - print join(", ", @attrs)."\n"; - } - } - - print "\n"; -} diff --git a/org.glite.jp.index/examples/pch06/query3.pl b/org.glite.jp.index/examples/pch06/query3.pl deleted file mode 100644 index 90695d7..0000000 --- a/org.glite.jp.index/examples/pch06/query3.pl +++ /dev/null @@ -1,140 +0,0 @@ -#! /usr/bin/perl -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# 3. query: -# -# Find the Stage 3, 4 and 5 details of the process that led to Atlas X Graphic. -# -# call: -# ./query3.pl OUTPUT_FILE_NAME 2>/dev/null -# - -use strict; -use pch; -use Data::Dumper; - -my $ps=$pch::ps; -my $is=$pch::is; -my @attributes = ("$pch::jpsys:jobId", "$pch::jpwf:ancestor", @pch::view_attributes); - -my @according_jobs = (); # sequencially jobid list -my %according_jobs = (); # hash jobid list -my $according_count = 0; -my $output; - - -if ($#ARGV + 1 != 1) { - print STDERR "Usage: $0 OUTPUT_FILE\n"; - exit 1 -} -$output = $ARGV[0]; - -# debug calls -$pch::debug = 0; -my $debug = 0; - -# -# find out processes with given output -# -my @jobs = pch::isquery($is, [ - ["$pch::jplbtag:IPAW_OUTPUT", ['EQUAL', "$output"]], -], \@attributes); -die "...so exit on error" if ($pch::err); -print Dumper(@jobs) if ($debug); - -# -# initial set from index server -# -foreach my $job (@jobs) { - my %job = %$job; - my %attributes = %{$job{attributes}}; - - if (!exists $according_jobs{$job{jobid}}) { - push @according_jobs, $job{jobid}; - $according_jobs{$job{jobid}} = \%job; - } -} -undef @jobs; - - -# -# collect all jobs (tree browsing) -# -$according_count = 0; -foreach my $jobid (@according_jobs) { - my @ancs; - - print "Handling $jobid (position $according_count)\n" if ($debug); - @ancs = pch::isquery($is, [["$pch::jpwf:successor", ['EQUAL', "$jobid"]]], \@attributes); - die "...so exit on error" if ($pch::err); - - for my $anc (@ancs) { - my %anc = %$anc; - print "Considered: $anc{jobid}\n" if ($debug); - if (!exists $according_jobs{$anc{jobid}}) { - $according_jobs{$anc{jobid}} = \%anc; - push @according_jobs, $anc{jobid}; - print "Added $anc{jobid} to $#according_jobs\n" if ($debug); - } - else { - print "Already existing $anc{jobid}\n" if ($debug); - } - } - $according_count++; -} - - -# -# queries on result set -# -print "Results\n"; -print "=======\n"; -print "\n"; -foreach my $jobid (sort { $according_jobs{$b}{attributes}{"$pch::jplbtag:IPAW_STAGE"}{value}[0] <=> $according_jobs{$a}{attributes}{"$pch::jplbtag:IPAW_STAGE"}{value}[0] } keys %according_jobs) { - my %job = %{$according_jobs{$jobid}}; - my %attributes = %{$job{attributes}}; - my $stage = $attributes{"$pch::jplbtag:IPAW_STAGE"}{value}[0]; - -# if ( $stage == 3 || $stage == 4 || $stage == 5) { - if ( $stage == 2 || $stage == 3) { - print "jobid $jobid:\n"; - - # query & output all desired atributes - foreach my $attr (@pch::view_attributes) { - my $attr_name = $attr; $attr_name =~ s/.*://; - - print " attr $attr_name: "; - if (exists $attributes{$attr}) { - my %attr = %{$attributes{$attr}}; - - if ($attr eq "$pch::jpsys:regtime") { - print gmtime($attr{value}[0])." (".join(", ", @{$attr{value}}).")\n"; - } else { - print join(", ", @{$attr{value}})."\n"; - } - } else { - print "N/A\n"; - } - } - - print "\n"; - } else { - print "(ignored $jobid with stage $stage)\n" if $debug; - } -} diff --git a/org.glite.jp.index/examples/pch06/query4.pl b/org.glite.jp.index/examples/pch06/query4.pl deleted file mode 100644 index b3c96c8..0000000 --- a/org.glite.jp.index/examples/pch06/query4.pl +++ /dev/null @@ -1,150 +0,0 @@ -#! /usr/bin/perl -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# 4. query: -# -# Find all invocations of procedure align_warp using a twelfth order nonlinear -# 1365 parameter model (see model menu describing possible values of parameter -# "-m 12" of align_warp) that ran on a Monday. -# -# call: -# ./query4.pl [PROGRAMS [PARAMS]] 2>/dev/null -# - -use strict; -use pch; -use Data::Dumper; - -my $ps=$pch::ps; -my $is=$pch::is; -my %program_names=(align_warp => 1); -my $program_params='-m 12'; -my $runday=3; -#my $runday=4; -my @attributes = ("$pch::jpsys:jobId", @pch::view_attributes); - -my %according_jobs = (); # hash jobid list -my $according_count = 0; - - -# debug calls -$pch::debug = 0; -my $debug = 0; - -if ($#ARGV + 1 >= 1) { - %program_names = (); - foreach (split(/ */, $ARGV[0])) { - $program_names{$_} = 1; - } -} -if ($#ARGV + 1 >= 2) { - $program_params=$ARGV[1]; -} - - -# -# find out processes with given name ant parameters -# -my @query_programs = (); -foreach (keys %program_names) { - my @qitem = ['EQUAL', "$_"]; - push @query_programs, @qitem; -} -my @jobs = pch::isquery($is, [ - ["$pch::jplbtag:IPAW_PROGRAM", @query_programs], - ["$pch::jplbtag:IPAW_PARAM", ['EQUAL', "$program_params"]], -], \@attributes); -print Dumper(@jobs) if ($debug); -die "...so exit on error" if ($pch::err); - - -# -# check found all jobs -# -$according_count = 0; -foreach my $job (@jobs) { - my %job = %$job; - my (@time, @timesep, @origin); - my $itime; - - print "Handling $job{jobid} ($according_count.)\n" if ($debug); - - # search first regtime with origin USER, - # be satisfied with first regime too if no value has USER origin - @time = @{$job{attributes}{"$pch::jpsys:regtime"}{value}}; - @origin = @{$job{attributes}{"$pch::jpsys:regtime"}{origin}}; - @timesep = (); - foreach $itime (0..$#time) { -#print "check ".$time[$itime]." ".$origin[$itime]."\n"; - if ($origin[$itime] eq 'USER') { - @timesep = gmtime($time[$itime]); - last; - } - } - if ($#timesep == -1) { @timesep = gmtime($time[0]); } -#print join(',', @timesep)."\n"; - - if ($timesep[6] == $runday) { - if (!exists $according_jobs{$job{jobid}}) { - $according_jobs{$job{jobid}} = \%job; - print "Added $job{jobid}\n" if $debug; - } else { - print "Already existing $job{jobid}\n" if $debug; - } - } else { - print "Job $job{jobid} ran at day $timesep[6] (0=Sun, ...): ".gmtime($time[0])."\n" if $debug; - } - - $according_count++; -} -undef @jobs; - - -# -# print the result set -# -print "Results\n"; -print "=======\n"; -print "\n"; -foreach my $jobid (sort { $according_jobs{$b}{attributes}{"$pch::jplbtag:IPAW_STAGE"}{value}[0] <=> $according_jobs{$a}{attributes}{"$pch::jplbtag:IPAW_STAGE"}{value}[0] } keys %according_jobs) { - my %job = %{$according_jobs{$jobid}}; - my %attributes = %{$job{attributes}}; - - print "jobid $jobid:\n"; - - # output all desired atributes - foreach my $attr (@pch::view_attributes) { - my $attr_name = $attr; $attr_name =~ s/.*://; - - print " attr $attr_name: "; - if (exists $attributes{$attr}) { - my %attr = %{$attributes{$attr}}; - - if ($attr eq "$pch::jpsys:regtime") { - print gmtime($attr{value}[0])." (".join(", ", @{$attr{value}}).")\n"; - } else { - print join(", ", @{$attr{value}})."\n"; - } - } else { - print "N/A\n"; - } - } - - print "\n"; -} diff --git a/org.glite.jp.index/examples/pch06/query5.pl b/org.glite.jp.index/examples/pch06/query5.pl deleted file mode 100644 index 604d735..0000000 --- a/org.glite.jp.index/examples/pch06/query5.pl +++ /dev/null @@ -1,142 +0,0 @@ -#! /usr/bin/perl -W -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# 5. query: -# -# Find all Atlas Graphic images outputted from workflows where at least one of -# the input Anatomy Headers had an entry global maximum=4095. The contents of -# a header file can be extracted as text using the scanheader AIR utility. -# -# call: -# ./query5.pl [PROGRAMS] [END_PROGRAMS] [HEADER] 2>/dev/null -# - -use strict; -use pch; -use Data::Dumper; - -my $ps=$pch::ps; -my $is=$pch::is; -my %program_names=(align_warp => 1); -my %end_program_names=(convert => 1); -my $header="GLOBAL_MAXIMUM=4095"; # test for exact equal (scripts already prepared it) - -my @according_jobs = (); # sequencially jobid list -my %according_jobs = (); # hash jobid list - - -# debug calls -$pch::debug = 0; -my $debug = 0; - -if ($#ARGV + 1 >= 1) { - %program_names = (); - foreach (split(/ */, $ARGV[0])) { - $program_names{$_} = 1; - } -} -if ($#ARGV + 1 >= 2) { - %end_program_names = (); - foreach (split(/ */, $ARGV[1])) { - $end_program_names{$_} = 1; - } -} -if ($#ARGV + 1 >= 3) { - $header = $ARGV[2]; -} - - -# -# find out processes with given name and parameters -# -my @query_programs = (); -foreach (keys %program_names) { - my @qitem = ['EQUAL', "$_"]; - push @query_programs, @qitem; -} -my @jobs = pch::isquery($is, [ - ["$pch::jplbtag:IPAW_PROGRAM", @query_programs], - ["$pch::jplbtag:IPAW_HEADER", ['EQUAL', "$header"]], -], \@pch::view_attributes); -print STDERR Dumper(@jobs) if ($debug); -die "...so exit on error" if ($pch::err); - -# -# collect all jobs (tree browsing down) -# -foreach my $job (@jobs) { - my %job = %$job; - my $jobid = $job{jobid}; - my @succs; - my $pname; - - $pname = $job{attributes}{"$pch::jplbtag:IPAW_PROGRAM"}{value}[0]; - print "Handling $jobid ($pname)\n" if ($debug); - - if (exists $end_program_names{$pname}) { - print "It's $pname\n" if $debug; - if (!exists $according_jobs{$jobid}) { - $according_jobs{$jobid} = \%job; - push @according_jobs, $jobid; - print "Added $jobid to $#according_jobs\n" if ($debug); - } - else { - print "Already existing $jobid\n" if ($debug); - } - next; - } - - @succs = pch::isquery($is, [["$pch::jpwf:ancestor", ['EQUAL', "$jobid"]]], \@pch::view_attributes); - die "...so exit on error" if ($pch::err); - push @jobs, @succs; -} - - -# -# print the result set -# -print "Results\n"; -print "=======\n"; -print "\n"; -foreach my $jobid (sort { $according_jobs{$b}{attributes}{"$pch::jplbtag:IPAW_STAGE"}{value}[0] <=> $according_jobs{$a}{attributes}{"$pch::jplbtag:IPAW_STAGE"}{value}[0] } keys %according_jobs) { - my %job = %{$according_jobs{$jobid}}; - my %attributes = %{$job{attributes}}; - - print "jobid $jobid:\n"; - - # output all desired atributes - foreach my $attr (@pch::view_attributes) { - my $attr_name = $attr; $attr_name =~ s/.*://; - - print " attr $attr_name: "; - if (exists $attributes{$attr}) { - my %attr = %{$attributes{$attr}}; - - if ($attr eq "$pch::jpsys:regtime") { - print gmtime($attr{value}[0])." (".join(", ", @{$attr{value}}).")\n"; - } else { - print join(", ", @{$attr{value}})."\n"; - } - } else { - print "N/A\n"; - } - } - - print "\n"; -} diff --git a/org.glite.jp.index/examples/pch06/query6.pl b/org.glite.jp.index/examples/pch06/query6.pl deleted file mode 100644 index f03a806..0000000 --- a/org.glite.jp.index/examples/pch06/query6.pl +++ /dev/null @@ -1,172 +0,0 @@ -#! /usr/bin/perl -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# 6. query: -# -# Find all output averaged images of softmean (average) procedures, where the -# warped images taken as input were align_warped using a twelfth order -# nonlinear 1365 parameter model, i.e. "where softmean was preceded in the -# workflow, directly or indirectly, by an align_warp procedure with argument -# -m 12. -# -# call: -# ./query6.pl [PROGRAMS [END_PROGRAMS] [PARAM] ]2>/dev/null -# - -use strict; -use pch; -use Data::Dumper; - -my $ps=$pch::ps; -my $is=$pch::is; -my %program_names=(align_warp=>1); -my $program_param='-m 12'; -my %end_program_names=(softmean=>1); - -#my %jobs = (); # just information cache -my @workflow_jobs = (); # sequencially jobid list -my %workflow_jobs = (); # hash jobid list -my @according_jobs = (); # sequencially jobid list -my %according_jobs = (); # hash jobid list -my $workflow_count = 0; - - -# debug calls -$pch::debug = 0; -my $debug = 0; - -if ($#ARGV + 1 >= 1) { - %program_names = (); - foreach (split(/ */, $ARGV[0])) { - $program_names{$_} = 1; - } -} -if ($#ARGV + 1 >= 2) { - %end_program_names = (); - foreach (split(/ */, $ARGV[1])) { - $end_program_names{$_} = 1; - } -} -if ($#ARGV + 1 >= 3) { - $program_param=$ARGV[2]; -} - -# -# find out processes with given name and parameters -# -my @query_programs = (); -foreach (keys %program_names) { - my @qitem = ['EQUAL', "$_"]; - push @query_programs, @qitem; -} -my @jobs = pch::isquery($is, [ - ["$pch::jplbtag:IPAW_PROGRAM", @query_programs], - ["$pch::jplbtag:IPAW_PARAM", ['EQUAL', "$program_param"]], -], ["$pch::jpwf:successor", @pch::view_attributes]); -print Dumper(@jobs) if ($debug); -die "...so exit on error" if ($pch::err); - -# -# initial set of starting jobs from index server -# (root jobs) -# -foreach my $job (@jobs) { - my %job = %$job; - my %attributes = %{$job{attributes}}; - my $jobid = $job{jobid}; - - if (!exists $workflow_jobs{$jobid}) { - push @workflow_jobs, $jobid; - $workflow_jobs{$jobid} = \%job; - } -} -undef @jobs; - - -# -# collect all jobs (tree browsing down) -# -$workflow_count = 0; -foreach my $jobid (@workflow_jobs) { - my @succs; - my $pname; - - print "Handling $jobid (position $workflow_count)\n" if ($debug); - print " progname: ".$workflow_jobs{$jobid}{attributes}{"$pch::jplbtag:IPAW_PROGRAM"}{value}[0]."\n" if ($debug); - - $pname = $workflow_jobs{$jobid}{attributes}{"$pch::jplbtag:IPAW_PROGRAM"}{value}[0]; - if (exists $end_program_names{$pname}) { - print "It's $pname, adding\n" if $debug; - $according_jobs{$jobid} = \%{$workflow_jobs{$jobid}}; - next; - } - - @succs = pch::isquery($is, [["$pch::jpwf:ancestor", ['EQUAL', "$jobid"]]], \@pch::view_attributes); - die "...so exit on error" if ($pch::err); - - for my $succ (@succs) { - my %succ = %$succ; - print "Considered: $succ{jobid}\n" if ($debug); - if (!exists $workflow_jobs{$succ{jobid}}) { - $workflow_jobs{$succ{jobid}} = \%succ; - push @workflow_jobs, $succ{jobid}; - print "Added $succ{jobid} to $#workflow_jobs\n" if ($debug); - } - else { - print "Already existing $succ{jobid}\n" if ($debug); - } - } - $workflow_count++; -} -undef @workflow_jobs; -undef %workflow_jobs; - - -# -# print the result set -# -print "Results\n"; -print "=======\n"; -print "\n"; -foreach my $jobid (sort { $according_jobs{$b}{attributes}{"$pch::jplbtag:IPAW_STAGE"}{value}[0] <=> $according_jobs{$a}{attributes}{"$pch::jplbtag:IPAW_STAGE"}{value}[0] } keys %according_jobs) { - my %job = %{$according_jobs{$jobid}}; - my %attributes = %{$job{attributes}}; - - print "jobid $jobid:\n"; - - # output all desired atributes - foreach my $attr (@pch::view_attributes) { - my $attr_name = $attr; $attr_name =~ s/.*://; - - print " attr $attr_name: "; - if (exists $attributes{$attr}) { - my %attr = %{$attributes{$attr}}; - - if ($attr eq "$pch::jpsys:regtime") { - print gmtime($attr{value}[0])." (".join(", ", @{$attr{value}}).")\n"; - } else { - print join(", ", @{$attr{value}})."\n"; - } - } else { - print "N/A\n"; - } - } - - print "\n"; -} diff --git a/org.glite.jp.index/examples/query-tests/authz.out b/org.glite.jp.index/examples/query-tests/authz.out deleted file mode 100644 index 53ff341..0000000 --- a/org.glite.jp.index/examples/query-tests/authz.out +++ /dev/null @@ -1,14 +0,0 @@ -query: using JPIS http://localhost:10000 - -Conditions: - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - origin IS ANY - value == Ready -Attributes: - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - -OK -Result 0 jobs: diff --git a/org.glite.jp.index/examples/query-tests/complex_query.in b/org.glite.jp.index/examples/query-tests/complex_query.in deleted file mode 100644 index 3dd8f22..0000000 --- a/org.glite.jp.index/examples/query-tests/complex_query.in +++ /dev/null @@ -1,36 +0,0 @@ - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - - EQUAL - - Done - - - - EQUAL - - Ready - - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - - UNEQUAL - - God - - - - - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - - - diff --git a/org.glite.jp.index/examples/query-tests/complex_query.out b/org.glite.jp.index/examples/query-tests/complex_query.out deleted file mode 100644 index 69971c1..0000000 --- a/org.glite.jp.index/examples/query-tests/complex_query.out +++ /dev/null @@ -1,36 +0,0 @@ -query: using JPIS http://localhost:10000 - -Conditions: - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - origin IS ANY - value == Done - value == Ready - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - origin IS ANY - value <> God -Attributes: - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - -OK -Result 2 jobs: - jobid = https://localhost:7846/pokus1, owner = /O=CESNET/O=Masaryk University/CN=Milos Mulac - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - value = Done - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - value = CertSubj - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 - jobid = https://localhost:7846/pokus2, owner = OwnerName - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - value = Ready - origin = SYSTEM (no detail) - time = Thu Jan 1 02:00:01 1970 - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - value = CertSubj - origin = SYSTEM (no detail) - time = Thu Jan 1 02:00:01 1970 diff --git a/org.glite.jp.index/examples/query-tests/dump1.sql b/org.glite.jp.index/examples/query-tests/dump1.sql deleted file mode 100644 index 0fd7cea..0000000 --- a/org.glite.jp.index/examples/query-tests/dump1.sql +++ /dev/null @@ -1,594 +0,0 @@ --- MySQL dump 10.8 --- --- Host: localhost Database: jpis1test --- ------------------------------------------------------ --- Server version 4.1.7-max-log - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE="NO_AUTO_VALUE_ON_ZERO" */; - --- --- Current Database: `jpis1test` --- - -CREATE DATABASE /*!32312 IF NOT EXISTS*/ `jpis1test`; - -USE `jpis1test`; - --- --- Table structure for table `acls` --- - -DROP TABLE IF EXISTS `acls`; -CREATE TABLE `acls` ( - `aclid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` mediumblob NOT NULL, - `refcnt` int(11) NOT NULL default '0', - PRIMARY KEY (`aclid`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `acls` --- - - -/*!40000 ALTER TABLE `acls` DISABLE KEYS */; -LOCK TABLES `acls` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `acls` ENABLE KEYS */; - --- --- Table structure for table `attr_ac7ea0b2cd17deedbc569733597059ae` --- - -DROP TABLE IF EXISTS `attr_ac7ea0b2cd17deedbc569733597059ae`; -CREATE TABLE `attr_ac7ea0b2cd17deedbc569733597059ae` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_ac7ea0b2cd17deedbc569733597059ae` --- - - -/*!40000 ALTER TABLE `attr_ac7ea0b2cd17deedbc569733597059ae` DISABLE KEYS */; -LOCK TABLES `attr_ac7ea0b2cd17deedbc569733597059ae` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_ac7ea0b2cd17deedbc569733597059ae` ENABLE KEYS */; - --- --- Table structure for table `attr_5de12c1776c3130b9d27a7502a13e11c` --- - -DROP TABLE IF EXISTS `attr_5de12c1776c3130b9d27a7502a13e11c`; -CREATE TABLE `attr_5de12c1776c3130b9d27a7502a13e11c` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_5de12c1776c3130b9d27a7502a13e11c` --- - - -/*!40000 ALTER TABLE `attr_5de12c1776c3130b9d27a7502a13e11c` DISABLE KEYS */; -LOCK TABLES `attr_5de12c1776c3130b9d27a7502a13e11c` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_5de12c1776c3130b9d27a7502a13e11c` ENABLE KEYS */; - --- --- Table structure for table `attr_f496f5d872a2d04ee626045477f340db` --- - -DROP TABLE IF EXISTS `attr_f496f5d872a2d04ee626045477f340db`; -CREATE TABLE `attr_f496f5d872a2d04ee626045477f340db` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_f496f5d872a2d04ee626045477f340db` --- - - -/*!40000 ALTER TABLE `attr_f496f5d872a2d04ee626045477f340db` DISABLE KEYS */; -LOCK TABLES `attr_f496f5d872a2d04ee626045477f340db` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_f496f5d872a2d04ee626045477f340db` ENABLE KEYS */; - --- --- Table structure for table `attr_34d7a9e823c6948d525362d2709bdfcd` --- - -DROP TABLE IF EXISTS `attr_34d7a9e823c6948d525362d2709bdfcd`; -CREATE TABLE `attr_34d7a9e823c6948d525362d2709bdfcd` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_34d7a9e823c6948d525362d2709bdfcd` --- - - -/*!40000 ALTER TABLE `attr_34d7a9e823c6948d525362d2709bdfcd` DISABLE KEYS */; -LOCK TABLES `attr_34d7a9e823c6948d525362d2709bdfcd` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_34d7a9e823c6948d525362d2709bdfcd` ENABLE KEYS */; - --- --- Table structure for table `attr_824794b00ee73be550f893b99ceaa643` --- - -DROP TABLE IF EXISTS `attr_824794b00ee73be550f893b99ceaa643`; -CREATE TABLE `attr_824794b00ee73be550f893b99ceaa643` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_824794b00ee73be550f893b99ceaa643` --- - - -/*!40000 ALTER TABLE `attr_824794b00ee73be550f893b99ceaa643` DISABLE KEYS */; -LOCK TABLES `attr_824794b00ee73be550f893b99ceaa643` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_824794b00ee73be550f893b99ceaa643` ENABLE KEYS */; - --- --- Table structure for table `attr_ac1e0e146f3e1bee11d6e40d07e60abb` --- - -DROP TABLE IF EXISTS `attr_ac1e0e146f3e1bee11d6e40d07e60abb`; -CREATE TABLE `attr_ac1e0e146f3e1bee11d6e40d07e60abb` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_ac1e0e146f3e1bee11d6e40d07e60abb` --- - - -/*!40000 ALTER TABLE `attr_ac1e0e146f3e1bee11d6e40d07e60abb` DISABLE KEYS */; -LOCK TABLES `attr_ac1e0e146f3e1bee11d6e40d07e60abb` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_ac1e0e146f3e1bee11d6e40d07e60abb` ENABLE KEYS */; - --- --- Table structure for table `attr_7636d6368c1cf53bc5511241cac9751f` --- - -DROP TABLE IF EXISTS `attr_7636d6368c1cf53bc5511241cac9751f`; -CREATE TABLE `attr_7636d6368c1cf53bc5511241cac9751f` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_7636d6368c1cf53bc5511241cac9751f` --- - - -/*!40000 ALTER TABLE `attr_7636d6368c1cf53bc5511241cac9751f` DISABLE KEYS */; -LOCK TABLES `attr_7636d6368c1cf53bc5511241cac9751f` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_7636d6368c1cf53bc5511241cac9751f` ENABLE KEYS */; - --- --- Table structure for table `attr_64ea5318d74aca823630ba9ca38971e0` --- - -DROP TABLE IF EXISTS `attr_64ea5318d74aca823630ba9ca38971e0`; -CREATE TABLE `attr_64ea5318d74aca823630ba9ca38971e0` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_64ea5318d74aca823630ba9ca38971e0` --- - - -/*!40000 ALTER TABLE `attr_64ea5318d74aca823630ba9ca38971e0` DISABLE KEYS */; -LOCK TABLES `attr_64ea5318d74aca823630ba9ca38971e0` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_64ea5318d74aca823630ba9ca38971e0` ENABLE KEYS */; - --- --- Table structure for table `attr_81a1d6b95da954e977f22f78417b98a8` --- - -DROP TABLE IF EXISTS `attr_81a1d6b95da954e977f22f78417b98a8`; -CREATE TABLE `attr_81a1d6b95da954e977f22f78417b98a8` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_81a1d6b95da954e977f22f78417b98a8` --- - - -/*!40000 ALTER TABLE `attr_81a1d6b95da954e977f22f78417b98a8` DISABLE KEYS */; -LOCK TABLES `attr_81a1d6b95da954e977f22f78417b98a8` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_81a1d6b95da954e977f22f78417b98a8` ENABLE KEYS */; - --- --- Table structure for table `attr_e6c0fb3b99f16296db2623c02f0d5c6f` --- - -DROP TABLE IF EXISTS `attr_e6c0fb3b99f16296db2623c02f0d5c6f`; -CREATE TABLE `attr_e6c0fb3b99f16296db2623c02f0d5c6f` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_e6c0fb3b99f16296db2623c02f0d5c6f` --- - - -/*!40000 ALTER TABLE `attr_e6c0fb3b99f16296db2623c02f0d5c6f` DISABLE KEYS */; -LOCK TABLES `attr_e6c0fb3b99f16296db2623c02f0d5c6f` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_e6c0fb3b99f16296db2623c02f0d5c6f` ENABLE KEYS */; - --- --- Table structure for table `attr_474e4207c49813e09915732c80c0e1cc` --- - -DROP TABLE IF EXISTS `attr_474e4207c49813e09915732c80c0e1cc`; -CREATE TABLE `attr_474e4207c49813e09915732c80c0e1cc` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_474e4207c49813e09915732c80c0e1cc` --- - - -/*!40000 ALTER TABLE `attr_474e4207c49813e09915732c80c0e1cc` DISABLE KEYS */; -LOCK TABLES `attr_474e4207c49813e09915732c80c0e1cc` WRITE; -INSERT INTO `attr_474e4207c49813e09915732c80c0e1cc` VALUES ('593e62a063231f8c623b74406b3e12b0','CertSubj','S:7201:F::CertSubj',3),('9276789a0093ad44457655ef03ade36a','CertSubj','S:7201:S::CertSubj',2); -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_474e4207c49813e09915732c80c0e1cc` ENABLE KEYS */; - --- --- Table structure for table `attr_e2d5742f6e917ea2e949d49b9fa0c1b3` --- - -DROP TABLE IF EXISTS `attr_e2d5742f6e917ea2e949d49b9fa0c1b3`; -CREATE TABLE `attr_e2d5742f6e917ea2e949d49b9fa0c1b3` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_e2d5742f6e917ea2e949d49b9fa0c1b3` --- - - -/*!40000 ALTER TABLE `attr_e2d5742f6e917ea2e949d49b9fa0c1b3` DISABLE KEYS */; -LOCK TABLES `attr_e2d5742f6e917ea2e949d49b9fa0c1b3` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_e2d5742f6e917ea2e949d49b9fa0c1b3` ENABLE KEYS */; - --- --- Table structure for table `attr_941ae4f469950ed63ad19822dbcf5427` --- - -DROP TABLE IF EXISTS `attr_941ae4f469950ed63ad19822dbcf5427`; -CREATE TABLE `attr_941ae4f469950ed63ad19822dbcf5427` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_941ae4f469950ed63ad19822dbcf5427` --- - - -/*!40000 ALTER TABLE `attr_941ae4f469950ed63ad19822dbcf5427` DISABLE KEYS */; -LOCK TABLES `attr_941ae4f469950ed63ad19822dbcf5427` WRITE; -INSERT INTO `attr_941ae4f469950ed63ad19822dbcf5427` VALUES ('593e62a063231f8c623b74406b3e12b0','Done','S:7201:F::Done',3),('9276789a0093ad44457655ef03ade36a','Ready','S:7201:S::Ready',1); -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_941ae4f469950ed63ad19822dbcf5427` ENABLE KEYS */; - --- --- Table structure for table `attr_97b3c128ab54e621c806b9ffe5c45185` --- - -DROP TABLE IF EXISTS `attr_97b3c128ab54e621c806b9ffe5c45185`; -CREATE TABLE `attr_97b3c128ab54e621c806b9ffe5c45185` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_97b3c128ab54e621c806b9ffe5c45185` --- - - -/*!40000 ALTER TABLE `attr_97b3c128ab54e621c806b9ffe5c45185` DISABLE KEYS */; -LOCK TABLES `attr_97b3c128ab54e621c806b9ffe5c45185` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_97b3c128ab54e621c806b9ffe5c45185` ENABLE KEYS */; - --- --- Table structure for table `attr_04ffb63c6978549209734fc02e8d688d` --- - -DROP TABLE IF EXISTS `attr_04ffb63c6978549209734fc02e8d688d`; -CREATE TABLE `attr_04ffb63c6978549209734fc02e8d688d` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_04ffb63c6978549209734fc02e8d688d` --- - - -/*!40000 ALTER TABLE `attr_04ffb63c6978549209734fc02e8d688d` DISABLE KEYS */; -LOCK TABLES `attr_04ffb63c6978549209734fc02e8d688d` WRITE; -INSERT INTO `attr_04ffb63c6978549209734fc02e8d688d` VALUES ('593e62a063231f8c623b74406b3e12b0','VOCE','S:7201:F::VOCE',3); -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_04ffb63c6978549209734fc02e8d688d` ENABLE KEYS */; - --- --- Table structure for table `attr_48f1a123884d6e24fe205c0f1c60c686` --- - -DROP TABLE IF EXISTS `attr_48f1a123884d6e24fe205c0f1c60c686`; -CREATE TABLE `attr_48f1a123884d6e24fe205c0f1c60c686` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_48f1a123884d6e24fe205c0f1c60c686` --- - - -/*!40000 ALTER TABLE `attr_48f1a123884d6e24fe205c0f1c60c686` DISABLE KEYS */; -LOCK TABLES `attr_48f1a123884d6e24fe205c0f1c60c686` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_48f1a123884d6e24fe205c0f1c60c686` ENABLE KEYS */; - --- --- Table structure for table `attr_52df8110aad9f80fd33a96073bfe58e7` --- - -DROP TABLE IF EXISTS `attr_52df8110aad9f80fd33a96073bfe58e7`; -CREATE TABLE `attr_52df8110aad9f80fd33a96073bfe58e7` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_52df8110aad9f80fd33a96073bfe58e7` --- - - -/*!40000 ALTER TABLE `attr_52df8110aad9f80fd33a96073bfe58e7` DISABLE KEYS */; -LOCK TABLES `attr_52df8110aad9f80fd33a96073bfe58e7` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_52df8110aad9f80fd33a96073bfe58e7` ENABLE KEYS */; - --- --- Table structure for table `attr_47a0c544b03cd51e37f3ad7f9e0a0a62` --- - -DROP TABLE IF EXISTS `attr_47a0c544b03cd51e37f3ad7f9e0a0a62`; -CREATE TABLE `attr_47a0c544b03cd51e37f3ad7f9e0a0a62` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `value` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `full_value` mediumblob NOT NULL, - `origin` int(11) NOT NULL default '0', - KEY `jobid` (`jobid`), - KEY `value` (`value`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attr_47a0c544b03cd51e37f3ad7f9e0a0a62` --- - - -/*!40000 ALTER TABLE `attr_47a0c544b03cd51e37f3ad7f9e0a0a62` DISABLE KEYS */; -LOCK TABLES `attr_47a0c544b03cd51e37f3ad7f9e0a0a62` WRITE; -UNLOCK TABLES; -/*!40000 ALTER TABLE `attr_47a0c544b03cd51e37f3ad7f9e0a0a62` ENABLE KEYS */; - --- --- Table structure for table `attrs` --- - -DROP TABLE IF EXISTS `attrs`; -CREATE TABLE `attrs` ( - `attrid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `name` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `indexed` int(11) NOT NULL default '0', - `type` varchar(32) character set latin1 collate latin1_bin default NULL, - PRIMARY KEY (`attrid`), - KEY `attrid` (`attrid`), - KEY `name` (`name`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `attrs` --- - - -/*!40000 ALTER TABLE `attrs` DISABLE KEYS */; -LOCK TABLES `attrs` WRITE; -INSERT INTO `attrs` VALUES ('824794b00ee73be550f893b99ceaa643','http://egee.cesnet.cz/en/Schema/JP/System:owner',1,'mediumblob'),('ac1e0e146f3e1bee11d6e40d07e60abb','http://egee.cesnet.cz/en/Schema/JP/System:jobId',1,'mediumblob'),('81a1d6b95da954e977f22f78417b98a8','http://egee.cesnet.cz/en/Schema/JP/System:regtime',0,'mediumblob'),('474e4207c49813e09915732c80c0e1cc','http://egee.cesnet.cz/en/Schema/LB/Attributes:user',1,'mediumblob'),('52df8110aad9f80fd33a96073bfe58e7','http://egee.cesnet.cz/en/Schema/LB/Attributes:aTag',0,'mediumblob'),('48f1a123884d6e24fe205c0f1c60c686','http://egee.cesnet.cz/en/Schema/LB/Attributes:eNodes',0,'mediumblob'),('34d7a9e823c6948d525362d2709bdfcd','http://egee.cesnet.cz/en/Schema/LB/Attributes:RB',1,'mediumblob'),('04ffb63c6978549209734fc02e8d688d','http://egee.cesnet.cz/en/Schema/LB/Attributes:CE',1,'mediumblob'),('f496f5d872a2d04ee626045477f340db','http://egee.cesnet.cz/en/Schema/LB/Attributes:UIHost',1,'mediumblob'),('97b3c128ab54e621c806b9ffe5c45185','http://egee.cesnet.cz/en/Schema/LB/Attributes:CPUTime',0,'mediumblob'),('5de12c1776c3130b9d27a7502a13e11c','http://egee.cesnet.cz/en/Schema/LB/Attributes:NProc',0,'mediumblob'),('941ae4f469950ed63ad19822dbcf5427','http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus',1,'mediumblob'),('7636d6368c1cf53bc5511241cac9751f','http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatusDate',0,'mediumblob'),('e2d5742f6e917ea2e949d49b9fa0c1b3','http://egee.cesnet.cz/en/Schema/LB/Attributes:retryCount',0,'mediumblob'),('47a0c544b03cd51e37f3ad7f9e0a0a62','http://egee.cesnet.cz/en/Schema/LB/Attributes:jobType',0,'mediumblob'),('ac7ea0b2cd17deedbc569733597059ae','http://egee.cesnet.cz/en/Schema/LB/Attributes:nsubjobs',0,'mediumblob'),('64ea5318d74aca823630ba9ca38971e0','http://egee.cesnet.cz/en/Schema/LB/Attributes:lastStatusHistory',0,'mediumblob'),('e6c0fb3b99f16296db2623c02f0d5c6f','http://egee.cesnet.cz/en/Schema/LB/Attributes:fullStatusHistory',0,'mediumblob'); -UNLOCK TABLES; -/*!40000 ALTER TABLE `attrs` ENABLE KEYS */; - --- --- Table structure for table `feeds` --- - -DROP TABLE IF EXISTS `feeds`; -CREATE TABLE `feeds` ( - `uniqueid` int(11) NOT NULL auto_increment, - `feedid` varchar(32) character set latin1 collate latin1_bin default NULL, - `state` int(11) NOT NULL default '0', - `locked` int(11) NOT NULL default '0', - `source` varchar(255) NOT NULL default '', - `expires` datetime default NULL, - `condition` mediumblob, - PRIMARY KEY (`uniqueid`), - UNIQUE KEY `feedid` (`feedid`), - KEY `uniqueid` (`uniqueid`), - KEY `feedid_2` (`feedid`), - KEY `state` (`state`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `feeds` --- - - -/*!40000 ALTER TABLE `feeds` DISABLE KEYS */; -LOCK TABLES `feeds` WRITE; -INSERT INTO `feeds` VALUES (93,'12345',8,0,'http://localhost:8901','2005-10-14 10:48:27','COND2'); -UNLOCK TABLES; -/*!40000 ALTER TABLE `feeds` ENABLE KEYS */; - --- --- Table structure for table `jobs` --- - -DROP TABLE IF EXISTS `jobs`; -CREATE TABLE `jobs` ( - `jobid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `dg_jobid` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - `ownerid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `aclid` varchar(32) character set latin1 collate latin1_bin default NULL, - `ps` varchar(255) NOT NULL default '', - PRIMARY KEY (`jobid`), - UNIQUE KEY `dg_jobid` (`dg_jobid`), - KEY `jobid` (`jobid`), - KEY `dg_jobid_2` (`dg_jobid`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `jobs` --- - - -/*!40000 ALTER TABLE `jobs` DISABLE KEYS */; -LOCK TABLES `jobs` WRITE; -INSERT INTO `jobs` VALUES ('593e62a063231f8c623b74406b3e12b0','https://localhost:7846/pokus1','5864429d57da18e4ecf9ea366c6b2c9c',NULL,'http://localhost:8901'),('9276789a0093ad44457655ef03ade36a','https://localhost:7846/pokus2','9996d295b9e10ce182983b258b280779',NULL,'http://localhost:8901'); -UNLOCK TABLES; -/*!40000 ALTER TABLE `jobs` ENABLE KEYS */; - --- --- Table structure for table `users` --- - -DROP TABLE IF EXISTS `users`; -CREATE TABLE `users` ( - `userid` varchar(32) character set latin1 collate latin1_bin NOT NULL default '', - `cert_subj` varchar(255) character set latin1 collate latin1_bin NOT NULL default '', - PRIMARY KEY (`userid`), - UNIQUE KEY `cert_subj` (`cert_subj`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - --- --- Dumping data for table `users` --- - - -/*!40000 ALTER TABLE `users` DISABLE KEYS */; -LOCK TABLES `users` WRITE; -INSERT INTO `users` VALUES ('5864429d57da18e4ecf9ea366c6b2c9c','/O=CESNET/O=Masaryk University/CN=Milos Mulac'),('9996d295b9e10ce182983b258b280779','OwnerName'); -UNLOCK TABLES; -/*!40000 ALTER TABLE `users` ENABLE KEYS */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; - diff --git a/org.glite.jp.index/examples/query-tests/exists_query.in b/org.glite.jp.index/examples/query-tests/exists_query.in deleted file mode 100644 index c56c485..0000000 --- a/org.glite.jp.index/examples/query-tests/exists_query.in +++ /dev/null @@ -1,17 +0,0 @@ - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - - EXISTS - - - - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - - diff --git a/org.glite.jp.index/examples/query-tests/exists_query.out b/org.glite.jp.index/examples/query-tests/exists_query.out deleted file mode 100644 index 2fbebf3..0000000 --- a/org.glite.jp.index/examples/query-tests/exists_query.out +++ /dev/null @@ -1,28 +0,0 @@ -query: using JPIS http://localhost:10000 - -Conditions: - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - origin IS ANY - value EXISTS -Attributes: - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - -OK -Result 1 jobs: - jobid = https://localhost:7846/pokus1, owner = /O=CESNET/O=Masaryk University/CN=Milos Mulac - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - value = Done - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - value = CertSubj - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - value = VOCE - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 diff --git a/org.glite.jp.index/examples/query-tests/jobid_query.in b/org.glite.jp.index/examples/query-tests/jobid_query.in deleted file mode 100644 index 1f57246..0000000 --- a/org.glite.jp.index/examples/query-tests/jobid_query.in +++ /dev/null @@ -1,19 +0,0 @@ - - - - - http://egee.cesnet.cz/en/Schema/JP/System:jobId - - EQUAL - - https://localhost:7846/pokus1 - - - - - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - - diff --git a/org.glite.jp.index/examples/query-tests/jobid_query.out b/org.glite.jp.index/examples/query-tests/jobid_query.out deleted file mode 100644 index e00d456..0000000 --- a/org.glite.jp.index/examples/query-tests/jobid_query.out +++ /dev/null @@ -1,23 +0,0 @@ -query: using JPIS http://localhost:10000 - -Conditions: - http://egee.cesnet.cz/en/Schema/JP/System:jobId - origin IS ANY - value == https://localhost:7846/pokus1 -Attributes: - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - -OK -Result 1 jobs: - jobid = https://localhost:7846/pokus1, owner = /O=CESNET/O=Masaryk University/CN=Milos Mulac - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - value = Done - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - value = CertSubj - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 diff --git a/org.glite.jp.index/examples/query-tests/origin_query.in b/org.glite.jp.index/examples/query-tests/origin_query.in deleted file mode 100644 index 3e398ed..0000000 --- a/org.glite.jp.index/examples/query-tests/origin_query.in +++ /dev/null @@ -1,20 +0,0 @@ - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - FILE - - EQUAL - - Done - - - - - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - - diff --git a/org.glite.jp.index/examples/query-tests/origin_query.out b/org.glite.jp.index/examples/query-tests/origin_query.out deleted file mode 100644 index 573f5d7..0000000 --- a/org.glite.jp.index/examples/query-tests/origin_query.out +++ /dev/null @@ -1,23 +0,0 @@ -query: using JPIS http://localhost:10000 - -Conditions: - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - origin == FILE - value == Done -Attributes: - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - -OK -Result 1 jobs: - jobid = https://localhost:7846/pokus1, owner = /O=CESNET/O=Masaryk University/CN=Milos Mulac - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - value = Done - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - value = CertSubj - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 diff --git a/org.glite.jp.index/examples/query-tests/run-test.sh b/org.glite.jp.index/examples/query-tests/run-test.sh deleted file mode 100755 index da1e208..0000000 --- a/org.glite.jp.index/examples/query-tests/run-test.sh +++ /dev/null @@ -1,314 +0,0 @@ -#! /bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# test script for the index server -# -# requires running mysql -# - -LC_ALL=C - -usage() { -cat <&1| \ - grep timeleft| sed 's/^.* //'` - if [ "$timeleft" = "0:00:00" -o -z "$timeleft" ]; then - echo "No valid proxy cert found nor "\ - "GLITE_HOST_KEY/GLITE_HOST_KEY specified!"\ - " Aborting." - exit 1 - fi - else - echo "Can't check proxy cert (grid-proxy-info not found). If you do not have valid proxy certificate, set GLITE_HOST_KEY/GLITE_HOST_KEY - otherwise tests will fail!" - fi - fi - - # handle the configuration - ARGS="-u ${GLITE_JPIS_TEST_ROOT_USER:-root}" - [ -z "$GLITE_JPIS_TEST_ROOT_PASSWORD" ] || ARGS="--password=${GLITE_JPIS_TEST_ROOT_PASSWORD} $ARGS" - GLITE_JPIS_TEST_PORT=${GLITE_JPIS_TEST_PORT:-"10000"} - GLITE_JPIS_TEST_PIDFILE=${GLITE_JPIS_TEST_PIDFILE:-"/tmp/glite-jp-indexd.pid"} - GLITE_JPIS_TEST_LOGFILE=${GLITE_JPIS_TEST_LOGFILE:-"/tmp/glite-jp-indexd.log"} - GLITE_JPIS_TEST_CONFIG=${GLITE_JPIS_TEST_CONFIG:-"$GLITE_LOCATION/etc/glite-jpis-test-config.xml"} - - if [ -z "$GLITE_JPIS_TEST_DB" ]; then - GLITE_JPIS_TEST_DB="jpis/@localhost:jpis1test" - need_new_db=1; - fi - DB_USER=`echo $GLITE_JPIS_TEST_DB| sed 's!/.*$!!'` - DB_HOST=`echo $GLITE_JPIS_TEST_DB| sed 's!^.*@!!' | sed 's!:.*!!'` - DB_NAME=`echo $GLITE_JPIS_TEST_DB| sed 's!^.*:!!'` - - GLITE_JPIS_DEBUG=0 -} - -create_db() { - # create database when needed - if [ "x$need_new_db" = "x1" ]; then - mysqladmin -f $ARGS drop $DB_NAME > /dev/null 2>&1 - mysqladmin -f $ARGS create $DB_NAME && \ - mysql $ARGS -e "GRANT ALL on $DB_NAME.* to jpis@localhost" && \ - mysql -u $DB_USER $DB_NAME < $GLITE_LOCATION/etc/glite-jp-index-dbsetup.sql || exit 1 - db_created="1" - fi -} - -import_db() { - # import database - echo -n "D" - cat $1 | sed "s/jpis1test/$DB_NAME/" | mysql -u $DB_USER -h $DB_HOST - if [ x"$?" != x"0" ]; then - echo "FAILED to import database." - kill_is; - drop_db; - exit 1 - fi - echo -n "B " -} - -drop_db() { - # drop databaze when created - [ -z "$db_created" ] || mysqladmin -f $ARGS drop $DB_NAME >/dev/null - -} - -run_is() { - # check - if [ -f "${GLITE_JPIS_TEST_PIDFILE}" ]; then - echo "Index server already running!" - echo " pid $(cat ${GLITE_JPIS_TEST_PIDFILE})" - echo " pidfile ${GLITE_JPIS_TEST_PIDFILE}" - exit 1 - fi - - echo -n "I" - # run index server - #valgrind --tool=memcheck --trace-children=yes --num-callers=15 --suppressions=$HOME/egee.supp - X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT} \ - $GLITE_LOCATION/bin/glite-jp-indexd -m $GLITE_JPIS_TEST_DB -p $GLITE_JPIS_TEST_PORT \ - -i ${GLITE_JPIS_TEST_PIDFILE} -o ${GLITE_JPIS_TEST_LOGFILE} \ - -x ${GLITE_JPIS_TEST_CONFIG} $1\ - 2>/tmp/result - - if [ x"$?" != x"0" ]; then - echo FAILED - drop_db; - exit 1 - fi - i=0 - while [ ! -s "${GLITE_JPIS_TEST_PIDFILE}" -a $i -lt 20 ]; do - sleep 0.1 - i=$(($i+1)) - done - if [ ! -s "${GLITE_JPIS_TEST_PIDFILE}" ]; then - echo "Can't startup index server." - kill_is; - drop_db; - exit 1 - fi - - # wait for index server - ret=1 - i=0 - while [ x"$ret" != x"0" -a $i -lt 20 ]; do - netstat -tapn 2>/dev/null | grep "\<$GLITE_JPIS_TEST_PORT\>" > /dev/null - ret=$? - i=$(($i+1)) - sleep 0.1 - done - if [ x"$ret" != x"0" ]; then - echo "Index server not started." - kill_is; - drop_db; - exit 1; - fi - echo -n "S " - sleep 1 -} - -kill_is() { - # kill the index server - kill `cat ${GLITE_JPIS_TEST_PIDFILE}`; - sleep 1; - kill -9 `cat ${GLITE_JPIS_TEST_PIDFILE}` 2>/dev/null - rm -f ${GLITE_JPIS_TEST_PIDFILE} -} - -run_test_query() { - echo -n "Q" - X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT} \ - $GLITE_LOCATION/examples/glite-jpis-client -f hr -q $1 \ - -i http://localhost:$GLITE_JPIS_TEST_PORT 2>&1 | grep -v '^GSLITE_GSPLUGIN: ' > /tmp/result - echo -n "R " - DIFF=`diff -b -B --ignore-matching-lines="query: using JPIS" $2 /tmp/result` - if [ -z "$DIFF" -a "$?" -eq "0" ] ; then - echo "OK." - rm /tmp/result - else - echo "FAILED!" - echo - echo "Expected result (using query $1):" - echo ------------------------------------------------------------------------------ - cat $2 - echo - echo --------------------------------------------------------------------------------------------------- - echo - echo "Obtained result (in /tmp/result):" - echo --------------------------------- - cat /tmp/result - echo - echo --------------------------------------------------------------------------------------------------- - drop_db; - kill_is; - exit 1 - fi -} - -run_test_feed() { - # run the example - X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT}\ - $GLITE_LOCATION/examples/glite-jpis-test -p $GLITE_JPIS_TEST_PORT \ - -m $GLITE_JPIS_TEST_DB -x $GLITE_JPIS_TEST_CONFIG &>/tmp/result - numok="$(cat /tmp/result | grep -c OK)" - if [ "$numok" -eq "2" ]; then - echo OK. - else - echo FAILED! - echo --------------------------------------------------------------------------------------------------- - echo - echo "Obtained result (in /tmp/result):" - echo --------------------------------- - cat /tmp/result - echo - echo --------------------------------------------------------------------------------------------------- - drop_db; - kill_is; - exit 1 - fi -} - - -########################################################################## -# - -if [ "$1" ]; then usage; exit 1; fi -init; - -echo - -echo -n "Simple query test.... " -create_db; -run_is "-n"; -import_db $GLITE_LOCATION/examples/query-tests/dump1.sql; -run_test_query $GLITE_LOCATION/examples/query-tests/simple_query.in $GLITE_LOCATION/examples/query-tests/simple_query.out; -drop_db; -kill_is; - -echo -n "Complex query test... " -create_db; -run_is "-n"; -import_db $GLITE_LOCATION/examples/query-tests/dump1.sql; -run_test_query $GLITE_LOCATION/examples/query-tests/complex_query.in $GLITE_LOCATION/examples/query-tests/complex_query.out; -drop_db; -kill_is; - -echo -n "Feed & query test.... " -create_db; -run_is; -run_test_feed; -drop_db; -kill_is; - -echo -n "Authz test........... " -create_db; -run_is; -import_db $GLITE_LOCATION/examples/query-tests/dump1.sql; -run_test_query $GLITE_LOCATION/examples/query-tests/simple_query.in $GLITE_LOCATION/examples/query-tests/authz.out; -drop_db; -kill_is; - -echo -n "Query jobId test..... " -create_db; -run_is "-n"; -import_db $GLITE_LOCATION/examples/query-tests/dump1.sql; -run_test_query $GLITE_LOCATION/examples/query-tests/jobid_query.in $GLITE_LOCATION/examples/query-tests/jobid_query.out; -drop_db; -kill_is; - -echo -n "Origin test.......... " -create_db; -run_is "-n"; -import_db $GLITE_LOCATION/examples/query-tests/dump1.sql; -run_test_query $GLITE_LOCATION/examples/query-tests/origin_query.in $GLITE_LOCATION/examples/query-tests/origin_query.out; -drop_db; -kill_is; - -echo -n "EXISTS test.......... " -create_db; -run_is "-n"; -import_db $GLITE_LOCATION/examples/query-tests/dump1.sql; -run_test_query $GLITE_LOCATION/examples/query-tests/exists_query.in $GLITE_LOCATION/examples/query-tests/exists_query.out; -drop_db; -kill_is; - -echo -n "WITHIN test.......... " -create_db; -run_is "-n"; -import_db $GLITE_LOCATION/examples/query-tests/dump1.sql; -run_test_query $GLITE_LOCATION/examples/query-tests/within_query.in $GLITE_LOCATION/examples/query-tests/within_query.out; -drop_db; -kill_is; diff --git a/org.glite.jp.index/examples/query-tests/simple_query.in b/org.glite.jp.index/examples/query-tests/simple_query.in deleted file mode 100644 index 3a32ae3..0000000 --- a/org.glite.jp.index/examples/query-tests/simple_query.in +++ /dev/null @@ -1,19 +0,0 @@ - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - - EQUAL - - Ready - - - - - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - - diff --git a/org.glite.jp.index/examples/query-tests/simple_query.out b/org.glite.jp.index/examples/query-tests/simple_query.out deleted file mode 100644 index 3426131..0000000 --- a/org.glite.jp.index/examples/query-tests/simple_query.out +++ /dev/null @@ -1,23 +0,0 @@ -query: using JPIS http://localhost:10000 - -Conditions: - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - origin IS ANY - value == Ready -Attributes: - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - -OK -Result 1 jobs: - jobid = https://localhost:7846/pokus2, owner = OwnerName - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - value = Ready - origin = SYSTEM (no detail) - time = Thu Jan 1 02:00:01 1970 - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - value = CertSubj - origin = SYSTEM (no detail) - time = Thu Jan 1 02:00:01 1970 diff --git a/org.glite.jp.index/examples/query-tests/within_query.in b/org.glite.jp.index/examples/query-tests/within_query.in deleted file mode 100644 index e40d902..0000000 --- a/org.glite.jp.index/examples/query-tests/within_query.in +++ /dev/null @@ -1,19 +0,0 @@ - - - - - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - - WITHIN - VOCA - VOCI - - - - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - - diff --git a/org.glite.jp.index/examples/query-tests/within_query.out b/org.glite.jp.index/examples/query-tests/within_query.out deleted file mode 100644 index c1d7251..0000000 --- a/org.glite.jp.index/examples/query-tests/within_query.out +++ /dev/null @@ -1,28 +0,0 @@ -query: using JPIS http://localhost:12002 - -Conditions: - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - origin IS ANY - value WITHIN VOCA AND VOCI -Attributes: - http://egee.cesnet.cz/en/Schema/JP/System:owner - http://egee.cesnet.cz/en/Schema/JP/System:jobId - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - -OK -Result 1 jobs: - jobid = https://localhost:7846/pokus1, owner = /O=CESNET/O=Masaryk University/CN=Milos Mulac - http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - value = Done - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 - http://egee.cesnet.cz/en/Schema/LB/Attributes:user - value = CertSubj - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 - http://egee.cesnet.cz/en/Schema/LB/Attributes:CE - value = VOCE - origin = FILE (no detail) - time = Thu Jan 1 02:00:01 1970 diff --git a/org.glite.jp.index/interface/JobProvenanceISClient.xsd b/org.glite.jp.index/interface/JobProvenanceISClient.xsd deleted file mode 100644 index 2cf0755..0000000 --- a/org.glite.jp.index/interface/JobProvenanceISClient.xsd +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.index/project/ChangeLog b/org.glite.jp.index/project/ChangeLog deleted file mode 100644 index 99ea05f..0000000 --- a/org.glite.jp.index/project/ChangeLog +++ /dev/null @@ -1,6 +0,0 @@ -1.4.0-1 -- Initial version - -1.4.0-2 -- configure updated - diff --git a/org.glite.jp.index/project/build.number b/org.glite.jp.index/project/build.number deleted file mode 100644 index 5a6321a..0000000 --- a/org.glite.jp.index/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Fri Oct 14 15:22:37 CEST 2005 -module.build=12 diff --git a/org.glite.jp.index/project/build.properties b/org.glite.jp.index/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp.index/project/configure.properties.xml b/org.glite.jp.index/project/configure.properties.xml deleted file mode 100644 index 5406d55..0000000 --- a/org.glite.jp.index/project/configure.properties.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - -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} -gsoap_version=${ext.gsoap.version} -mysql_prefix=${with.mysql.prefix} -mysql_version=${ext.mysql.version} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -cppunit=${with.cppunit.prefix} -jpproject=${subsystem.project.dir} -project=${component.project.dir} - - - diff --git a/org.glite.jp.index/project/properties.xml b/org.glite.jp.index/project/properties.xml deleted file mode 100755 index 5f56392..0000000 --- a/org.glite.jp.index/project/properties.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.index/project/tar_exclude b/org.glite.jp.index/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.jp.index/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.jp.index/project/version.properties b/org.glite.jp.index/project/version.properties deleted file mode 100644 index f183374..0000000 --- a/org.glite.jp.index/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# $Header$ -module.version=1.4.0 -module.age=2 diff --git a/org.glite.jp.index/src/bones_server.c b/org.glite.jp.index/src/bones_server.c deleted file mode 100644 index 0643ba6..0000000 --- a/org.glite.jp.index/src/bones_server.c +++ /dev/null @@ -1,560 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#include "conf.h" -#include "db_ops.h" -#include "soap_ps_calls.h" -#include "context.h" -#include "common.h" - -#include "soap_version.h" -#include "jp_H.h" -#include "jp_.nsmap" - -#if GSOAP_VERSION <= 20602 -#define soap_call___jpsrv__FeedIndex soap_call___ns1__FeedIndex -#define soap_call___jpsrv__FeedIndexRefresh soap_call___ns1__FeedIndexRefresh -#endif - -#define CONN_QUEUE 20 -#define MAX_SLAVES_NUM 20 // max. of slaves to be spawned -#define USER_QUERY_SLAVES_NUM 2 // # of slaves reserved for user queries if - // # PS to conntact is << MAX_SLAVES_NUM - -#define RECONNECT_TIME 60*20 // when try reconnect to PS in case of error (in sec) -#define RECONNECT_TIME_QUICK 1 // time between feed requests -#define REACTION_TIME 60*2 // when try reconnect to PS in case of new feeds (in sec) -#define LAUNCH_TIME 2 // wait (for starting slaves) before requesting feeds - - -extern SOAP_NMAC struct Namespace jp__namespaces[],jpps__namespaces[]; - -int newconn(int,struct timeval *,void *); -int request(int,struct timeval *,void *); -static int reject(int); -static int disconn(int,struct timeval *,void *); -int data_init(void **data); -#ifndef ONETIME_FEEDS -int feed_loop_slave(void); -#endif - - -static struct glite_srvbones_service stab = { - "JP Index Server", -1, newconn, request, reject, disconn -}; - -static time_t cert_mtime; -static char *server_cert, *server_key, *cadir; -static edg_wll_GssCred mycred = NULL; - -static char *port = GLITE_JPIS_DEFAULT_PORT_STR; -static int debug = 1; - -static glite_jp_context_t ctx; -static glite_jp_is_conf *conf; // Let's make configuration visible to all slaves - - -int main(int argc, char *argv[]) -{ - int one = 1, nfeeds; - edg_wll_GssStatus gss_code; - struct sockaddr_in a; - glite_jpis_context_t isctx; - int retval = 0; - char *err; - int i; - - glite_jp_init_context(&ctx); - - if (glite_jp_get_conf(argc, argv, &conf)) { - glite_jp_free_context(ctx); - exit(1); - } - glite_jpis_init_context(&isctx, ctx, conf); - - /* connect to DB */ - if (glite_jpis_init_db(isctx) != 0) { - fprintf(stderr, "Connect DB failed: %s (%s)\n", ctx->error->desc, ctx->error->source); - glite_jpis_free_context(isctx); - glite_jp_free_context(ctx); - glite_jp_free_conf(conf); - return 1; - } - - /* daemonize */ - if (!conf->debug) glite_srvbones_daemonize("glite-jp-indexd", conf->pidfile, conf->logfile); - - /* load plugins */ - for (i=0; conf->plugins[i]; i++) - glite_jp_typeplugin_load(ctx,conf->plugins[i]); - - if (conf->delete_db) { - if (glite_jpis_dropDatabase(isctx) != 0) { - fprintf(stderr, "Drop DB failed: "); - retval = 1; - goto quit; - } - } - - if (glite_jpis_initDatabase(isctx) != 0) { - fprintf(stderr, "Init DB failed: "); - retval = 1; - goto quit; - } - - if (conf->delete_db || conf->force_feed) { - if (glite_jpis_initDatabaseFeeds(isctx) != 0) { - fprintf(stderr, "Init feeds failed: "); - retval = 1; - goto quit; - } - } - - server_cert = conf->server_cert; - server_key = conf->server_key; - - if (!server_cert || !server_key) - fprintf(stderr, "%s: WARNING: key or certificate file not specified, " - "can't watch them for changes\n", - argv[0]); - - if ( cadir ) setenv("X509_CERT_DIR", cadir, 1); - edg_wll_gss_watch_creds(server_cert, &cert_mtime); - - if ( !edg_wll_gss_acquire_cred_gsi(server_cert, server_key, &mycred, &gss_code)) - fprintf(stderr,"Server identity: %s\n",mycred ? mycred->name : "NULL"); - else fputs("WARNING: Running unauthenticated\n",stderr); - - if (conf->feeding) { - fprintf(stderr, "%s: Feeding from '%s'\n", argv[0], conf->feeding); - retval = glite_jpis_feeding(isctx, conf->feeding, mycred ? mycred->name : NULL); - goto quit; - } - - stab.conn = socket(PF_INET, SOCK_STREAM, 0); - if (stab.conn < 0) { - perror("socket"); - return 1; - } - - setsockopt(stab.conn,SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); - - if (conf->port) port = conf->port; - a.sin_family = AF_INET; - a.sin_addr.s_addr = INADDR_ANY; - a.sin_port = htons(atoi(port)); - if (bind(stab.conn,(struct sockaddr *) &a, sizeof(a)) ) { - char buf[200]; - - snprintf(buf,sizeof(buf),"bind(%d)",atoi(port)); - perror(buf); - return 1; - } - - if (listen(stab.conn,CONN_QUEUE)) { - perror("listen()"); - return 1; - } - - // XXX: more tests needed - if (conf->feeds) - for (nfeeds=0; conf->feeds[nfeeds]; nfeeds++); - else nfeeds = 0; - if (conf->slaves <= 0) { - // add some slaves for user queries and PS responses - conf->slaves = nfeeds + (USER_QUERY_SLAVES_NUM - 1); - if (conf->slaves > MAX_SLAVES_NUM) conf->slaves = MAX_SLAVES_NUM; - } - // - // SUM(PS, feeds(PS) - slaves(PS)) slaves would be blocked - // when waited for all PS - // - // wild guess for slaves(PS) == 1 on all PS: - // 1 + SUM(PS, feeds(PS) - 1) slaves is required, - // SUM(PS, feeds(PS)) is enough. - // - if (conf->slaves < nfeeds) { - fprintf(stderr, "WARNING: %d slaves can be too low for %d feeds\n", conf->slaves, nfeeds); - } - glite_srvbones_set_param(GLITE_SBPARAM_SLAVES_COUNT, conf->slaves); -#ifndef ONETIME_FEEDS - if (feed_loop_slave() < 0) { - fprintf(stderr, "forking feed_loop_slave failed!\n"); - } else -#endif - glite_srvbones_run(data_init,&stab,1 /* XXX: entries in stab */,debug); - -quit: - if (isctx->jpctx->error) { - err = glite_jp_error_chain(isctx->jpctx); - fprintf(stderr, "%s: %s\n", argv[0], err); - free(err); - } - - glite_jpis_free_db(isctx); - glite_jp_free_conf(conf); - glite_jpis_free_context(isctx); - glite_jp_free_context(ctx); - - return retval; -} - - -static int get_soap(struct soap *soap, glite_jpis_context_t ctx) { - glite_gsplugin_Context plugin_ctx; - - glite_gsplugin_init_context(&plugin_ctx); - - soap_init(soap); - soap_set_namespaces(soap, jp__namespaces); - soap_set_omode(soap, SOAP_IO_BUFFER); // set buffered response - // buffer set to SOAP_BUFLEN (default = 8k) - if (soap_register_plugin_arg(soap,glite_gsplugin,plugin_ctx)) - return glite_jpis_stack_error(ctx->jpctx, EIO, "can't register gsoap plugin"); - - return 0; -} - - -/* looking for some feed in DB */ -static int feed_caller(struct soap *soap, glite_jpis_context_t isctx) { - char *PS_URL, *feedid, *errs; - long int uniqueid; - int i, ok, ret, status, initialized, result = 0; - - // dirty hack - try quicker several times first - glite_jp_clear_error(isctx->jpctx); - - feedid = NULL; - for (initialized = 0; initialized <= 1; initialized++) { - switch (glite_jpis_lockSearchFeed(isctx,initialized,&uniqueid,&PS_URL,&status,&feedid)) { - case 0: - // some locked feeds found - ok = 0; - for (i = 0; i < 10; i++) { - if (!initialized) { - // contact PS server, ask for data, save - // feedId and expiration to DB and unlock the feed - ret = MyFeedIndex(soap, isctx, uniqueid, PS_URL); - } else { - ret = MyFeedRefresh(soap, isctx, uniqueid, PS_URL, status, feedid); - } - if (ret) { - // error when connecting to PS - errs = glite_jp_error_chain(isctx->jpctx); - printf("[%d] %s: %s, reconnecting later\n", getpid(), __FUNCTION__, errs); - free(errs); - } else { - lprintf("%s %s (%ld) ok\n", initialized ? "refresh" : "init", feedid, uniqueid); - ok = 1; - break; - } - } - if (!ok) { - // when unintialized feed: always reconnect - // when not refreshed feed: reconnect only once and two times quicker - if (!initialized || (status & GLITE_JP_IS_STATE_ERROR) == 0) { - lprintf("reconnecting %s (%ld)\n", feedid, uniqueid); - glite_jpis_tryReconnectFeed(isctx, uniqueid, time(NULL) + RECONNECT_TIME / (initialized + 1), status | GLITE_JP_IS_STATE_ERROR); - } else { - lprintf("destroying %s (%ld)\n", feedid, uniqueid); - glite_jpis_destroyTryReconnectFeed(isctx, uniqueid, time(NULL) - 1); - } - } - free(PS_URL); PS_URL = NULL; - free(feedid); feedid = NULL; - - sleep(RECONNECT_TIME_QUICK); - - result = 1; - break; - case ENOENT: - // no more feeds to initialize - break; - default: - // error during locking - printf("[%d] %s: Locking error: ", getpid(), __FUNCTION__); - if (isctx->jpctx->error) { - errs = glite_jp_error_chain(isctx->jpctx); - printf("%s\n", errs); - free(errs); - } else printf("(no detail)\n"); - return -1; - } - } - - return result; -} - - -#ifndef ONETIME_FEEDS -int feed_loop_slave(void) { - pid_t pid; - glite_jpis_context_t isctx; - struct soap soap; - char *errs; - - if ( (pid = fork()) ) return pid; - - glite_jpis_init_context(&isctx, ctx, conf); - if (glite_jpis_init_db(isctx) != 0) { - printf("[%d] %s: DB error: %s (%s)\n", getpid(), __FUNCTION__, ctx->error->desc, ctx->error->source); - exit(1); - } - - if (get_soap(&soap, isctx) != 0) { - printf("[%d] %s: ", getpid(), __FUNCTION__); - if (isctx->jpctx->error) { - errs = glite_jp_error_chain(isctx->jpctx); - printf("%s\n", errs); - free(errs); - } else printf("(no detail)\n"); - exit(1); - } - - printf("[%d] %s: waiting before feed requests...\n", getpid(), __FUNCTION__); - sleep(LAUNCH_TIME); - printf("[%d] %s: feeder slave started\n", getpid(), __FUNCTION__); - do { - switch (feed_caller(&soap, isctx)) { - case 1: break; - case 0: - sleep(REACTION_TIME); - break; - default: - if (isctx->jpctx->error) { - errs = glite_jp_error_chain(isctx->jpctx); - printf("[%d] %s: %s\n", getpid(), __FUNCTION__, errs); - free(errs); - } - printf("[%d] %s: feed locking error, slave terminated\n", getpid(), __FUNCTION__); - exit(1); - } - } while (1); - - printf("[%d] %s: slave terminated\n", getpid(), __FUNCTION__); - exit(0); -} -#endif - - -/* slave's init comes here */ -int data_init(void **data) -{ - slave_data_t *private; - - private = calloc(sizeof(*private), 1); - glite_jpis_init_context(&private->ctx, ctx, conf); - if (glite_jpis_init_db(private->ctx) != 0) { - printf("[%d] slave_init(): DB error: %s (%s)\n",getpid(),ctx->error->desc,ctx->error->source); - return -1; - } - - printf("[%d] slave started\n",getpid()); - private->soap = soap_new(); - -#if ONETIME_FEEDS - if (get_soap(private->soap, ctx) != 0) { - printf("[%d] %s: ", getpid(), __FUNCTION__); - if (isctx->jpctx->error) { - errs = glite_jp_error_chain(ctx->jpctx); - printf("%s\n", errs); - free(errs); - } else printf("(no error)\n"); - exit(1); - } - - /* ask PS server for data */ - do { - switch (feed_caller(private->soap, private->ctx)) { - case 1: - // one feed handled - break; - case 0: - // no more feeds to initialize - *data = (void *) private; - return 0; - default: - // error during locking - glite_jpis_free_db(private->ctx); - glite_jpis_free_context(private->ctx); - return -1; - } - } while (1); -#else - *data = (void *) private; - return 0; -#endif -} - - -int newconn(int conn,struct timeval *to,void *data) -{ - slave_data_t *private = (slave_data_t *)data; - struct soap *soap = private->soap; - glite_jp_context_t ctx = private->ctx->jpctx; - glite_gsplugin_Context plugin_ctx; - - edg_wll_GssCred newcred = NULL; - edg_wll_GssStatus gss_code; - int ret = 0; - edg_wll_GssPrincipal client = NULL; - edg_wll_GssConnection connection; - - - soap_init2(soap,SOAP_IO_KEEPALIVE,SOAP_IO_KEEPALIVE); - soap_set_omode(soap, SOAP_IO_BUFFER); // set buffered response - // buffer set to SOAP_BUFLEN (default = 8k) - soap_set_namespaces(soap,jp__namespaces); - soap->user = (void *) private; - - switch (edg_wll_gss_watch_creds(server_cert,&cert_mtime)) { - case 0: break; - case 1: if (!edg_wll_gss_acquire_cred_gsi(server_cert,server_key, - &newcred,&gss_code)) - { - - printf("[%d] reloading credentials\n",getpid()); /* XXX: log */ - edg_wll_gss_release_cred(&mycred, NULL); - mycred = newcred; - } - break; - case -1: - printf("[%d] edg_wll_gss_watch_creds failed\n", getpid()); /* XXX: log */ - break; - } - - /* TODO: DNS paranoia etc. */ - memset(&connection, 0, sizeof(connection)); - if (edg_wll_gss_accept(mycred,conn,to,&connection,&gss_code)) { - char *et; - - edg_wll_gss_get_error(&gss_code,"",&et); - - fprintf(stderr,"[%d] GSS connection accept failed: %s\nClosing connection.\n",getpid(),et); - free(et); - ret = 1; - soap_end(soap); - return 1; - } - - ret = edg_wll_gss_get_client_conn(&connection, &client, NULL); - - if (ctx->peer) free(ctx->peer); - if (ret || client->flags & EDG_WLL_GSS_FLAG_ANON) { - printf("[%d] annonymous client\n",getpid()); - ctx->peer = NULL; - } - else { - printf("[%d] client DN: %s\n",getpid(),client->name); /* XXX: log */ - - ctx->peer = strdup(client->name); - edg_wll_gss_free_princ(client); - } - - glite_gsplugin_init_context(&plugin_ctx); - glite_gsplugin_set_connection(plugin_ctx, &connection); - soap_register_plugin_arg(soap,glite_gsplugin,plugin_ctx); - - return 0; -} - -int request(int conn UNUSED,struct timeval *to,void *data) -{ - slave_data_t *private = (slave_data_t *)data; - struct soap *soap = private->soap; - glite_jp_context_t ctx = private->ctx->jpctx; - - glite_gsplugin_set_timeout(glite_gsplugin_get_context(soap),to); - - soap->max_keep_alive = 1; /* XXX: prevent gsoap to close connection */ - soap_begin(soap); - if (soap_begin_recv(soap)) { - if (soap->error < SOAP_STOP) { - soap_send_fault(soap); - return EIO; - } - return ENOTCONN; - } - - soap->keep_alive = 1; - if (soap_envelope_begin_in(soap) - || soap_recv_header(soap) - || soap_body_begin_in(soap) - || jp__serve_request(soap) -#if GSOAP_VERSION >= 20700 - || (soap->fserveloop && soap->fserveloop(soap)) -#endif - ) - { - soap_send_fault(soap); // sets soap->keep_alive back to 0 :( - // and closes connection - if (ctx->error) { - /* XXX: shall we die on some errors? */ - int err = ctx->error->code; - glite_jp_clear_error(ctx); - return err == EIO ? -err : err; /* EIO is fatal */ - } - - return ECANCELED; // let srv_bones know something is wrong - } - - glite_jp_run_deferred(ctx); - return ENOTCONN; -} - -static int reject(int conn) -{ - int flags = fcntl(conn, F_GETFL, 0); - - fcntl(conn,F_SETFL,flags | O_NONBLOCK); - edg_wll_gss_reject(conn); - - return 0; -} - -static int disconn(int conn UNUSED,struct timeval *to UNUSED,void *data) -{ - slave_data_t *private = (slave_data_t *)data; - struct soap *soap = private->soap; - -// XXX: belongs to "data_init complement" -// glite_jpis_free_db(private->ctx); -// glite_jpis_free_context(private->ctx); - soap_end(soap); // clean up everything and close socket - - return 0; -} - - diff --git a/org.glite.jp.index/src/common.c b/org.glite.jp.index/src/common.c deleted file mode 100644 index 3bf16a2..0000000 --- a/org.glite.jp.index/src/common.c +++ /dev/null @@ -1,77 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#include -#include -#include -#include - -#include -#include - -#include "common.h" - -#define WHITE_SPACE_SET "\n\r \t" - - -void glite_jpis_trim(char *str) { - size_t pos, len; - - if (!str) return; - - pos = strspn(str, WHITE_SPACE_SET); - len = strcspn(str + pos, WHITE_SPACE_SET); - if (pos) memmove(str, str + pos, len); - str[len] = '\0'; -} - - -int glite_jpis_stack_error_source(glite_jp_context_t ctx, int code, const char *func, int line, const char *descfmt, ...) { - glite_jp_error_t err; - char *source, *desc; - va_list ap; - - va_start(ap, descfmt); - - asprintf(&source, "%s:%d", func, line); - if (descfmt) vasprintf(&desc, descfmt, ap); - else desc = NULL; - memset(&err, 0, sizeof err); - err.code = code; - err.desc = desc; - err.source = source; - glite_jp_stack_error(ctx, &err); - free(source); - free(desc); - - va_end(ap); - return code; -} - - -int glite_jpis_find_attr(char **attrs, const char *attr){ - size_t i; - - i = 0; - while (attrs[i]) { - if (strcasecmp(attr, attrs[i]) == 0) return 1; - i++; - } - return 0; -} diff --git a/org.glite.jp.index/src/common.h b/org.glite.jp.index/src/common.h deleted file mode 100644 index 4d84e59..0000000 --- a/org.glite.jp.index/src/common.h +++ /dev/null @@ -1,36 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#ifndef GLITE_JPIS_COMMON_H -#define GLITE_JPIS_COMMON_H - -#include -#include - -void glite_jpis_trim(char *str); - -int glite_jpis_stack_error_source(glite_jp_context_t ctx, int code, const char *func, int line, const char *desc, ...); - -#define glite_jpis_stack_error(CTX, CODE, DESCFMT...) glite_jpis_stack_error_source((CTX), (CODE), __FUNCTION__, __LINE__, ##DESCFMT); - -int glite_jp_typeplugin_load(glite_jp_context_t ctx,const char *so); - -int glite_jpis_find_attr(char **attrs, const char *attr); - -#endif diff --git a/org.glite.jp.index/src/conf.c b/org.glite.jp.index/src/conf.c deleted file mode 100644 index e72f941..0000000 --- a/org.glite.jp.index/src/conf.c +++ /dev/null @@ -1,345 +0,0 @@ -/* Module for obtaining configuration for Index Server */ - -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "soap_version.h" -#include - -#include "conf.h" -#include "db_ops.h" -#include "ws_is_typeref.h" - -#include - - -extern SOAP_NMAC struct Namespace jp__namespaces[]; - -static const char *get_opt_string = "dq:c:k:C:V:nm:p:i:o:x:s:Df:F"; - -static struct option opts[] = { - {"debug", 0, NULL, 'd'}, - {"query-type", 1, NULL, 'q'}, - {"cert", 1, NULL, 'c'}, - {"key", 1, NULL, 'k'}, -// {"CAdir", 1, NULL, 'C'}, -// {"VOMSdir", 1, NULL, 'V'}, - {"noauth", 0, NULL, 'n'}, - {"mysql", 1, NULL, 'm'}, - {"port", 1, NULL, 'p'}, - {"pidfile", 1, NULL, 'i'}, - {"logfile", 1, NULL, 'o'}, - {"config", 1, NULL, 'x'}, - {"slaves", 1, NULL, 's'}, - {"delete-db", 0, NULL, 'D'}, - {"feeding", 1, NULL, 'f'}, - {"force-feed", 0, NULL, 'F'}, - {NULL, 0, NULL, 0} -}; - -static int read_conf(glite_jp_is_conf *conf, char *conf_file); -#if 0 -static int dump_conf(void); -#endif - -static void usage(char *me) -{ - fprintf(stderr,"usage: %s [option]\n" - "\t-d, --debug\t don't run as daemon, additional diagnostics\n" - "\t-q, --query-type hist/cont/both (default history)\n" - "\t-k, --key\t private key file\n" - "\t-c, --cert\t certificate file\n" -// "\t-C, --CAdir\t trusted certificates directory\n" -// "\t-V, --VOMSdir\t trusted VOMS servers certificates directory\n" - "\t-n, --noauth\t don't check user identity with result owner\n" - "\t-m, --mysql\t database connect string\n" - "\t-p, --port\t port to listen\n" - "\t-i, --pidfile\t file to store master pid\n" - "\t-o, --logfile\t file to store logs\n" - "\t-x, --config\t file with server configuration\n" - "\t-s, --slaves\t number of slaves for responses\n" - "\t-D, --delete-db\t delete and restore data in the database\n" - "\t-f, --feeding\t feed index server from local file\n" - "\t-F, --force-feed\t force reloading feeds from the config file\n" - "\n" - ,me); -} - - -int glite_jp_get_conf(int argc, char **argv, glite_jp_is_conf **configuration) -{ - char *qt = NULL, *conf_file = NULL; - int opt; - glite_jp_is_conf *conf; - - - conf = calloc(1, sizeof(*conf)); - - while ((opt = getopt_long(argc,argv,get_opt_string,opts,NULL)) != EOF) switch (opt) { - case 'd': conf->debug = 1; break; - case 'q': qt = optarg; break; - case 'c': conf->server_cert = optarg; break; - case 'k': conf->server_key = optarg; break; -// case 'C': cadir = optarg; break; -// case 'V': vomsdir = optarg; break; - case 'n': conf->no_auth = 1; break; - case 'm': conf->cs = optarg; break; - case 'p': conf->port = optarg; break; - case 'i': conf->pidfile = optarg; break; - case 'o': conf->logfile = optarg; break; - case 'x': conf_file = optarg; break; - case 's': conf->slaves = atoi(optarg); if (conf->slaves > 0) break; - case 'D': conf->delete_db = 1; break; - case 'f': conf->feeding = optarg; break; - case 'F': conf->force_feed = 1; break; - default : usage(argv[0]); exit(0); break; - } - - if (!conf->cs) { - fprintf(stderr,"DB contact string not specified! "\ - "Using build-in default: %s \n", GLITE_JP_IS_DEFAULTCS); - } - if (!conf->port) { - fprintf(stderr,"JP IS port not specified! "\ - "Using build-in default: %s \n", GLITE_JPIS_DEFAULT_PORT_STR); - } - - if (!conf_file) { - fprintf(stderr,"JP IS configuration file must be specified! "\ - "Exiting.\n"); - free(conf); - return 1; - } - else { - if (read_conf(conf, conf_file) != 0) return 1; - } - - *configuration = conf; - - return 0; -} - - -void glite_jp_free_conf(glite_jp_is_conf *conf) -{ - size_t i, j; - glite_jp_is_feed *feed; - - if (!conf) return; - - if (conf->attrs) for (i = 0; conf->attrs[i]; i++) free(conf->attrs[i]); - if (conf->indexed_attrs) for (i = 0; conf->indexed_attrs[i]; i++) free(conf->indexed_attrs[i]); - if (conf->multival_attrs) for (i = 0; conf->multival_attrs[i]; i++) free(conf->multival_attrs[i]); - if (conf->queriable_attrs) for (i = 0; conf->queriable_attrs[i]; i++) free(conf->queriable_attrs[i]); - if (conf->feeds) for (i = 0; conf->feeds[i]; i++) { - feed = conf->feeds[i]; - free(feed->PS_URL); - for (j = 0; feed->query[j].attr; j++) glite_jp_free_query_rec(&feed->query[j]); - free(feed->query); - free(feed); - } - free(conf->attrs); - free(conf->indexed_attrs); - free(conf->multival_attrs); - free(conf->queriable_attrs); - free(conf->plugins); - free(conf->feeds); - free(conf); -} - - -void glite_jp_lprintf(const char *source, const char *fmt, ...) { - va_list ap; - - printf("[%d] %s: ", getpid(), source); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); -} - -/* - * Reads configuration from XML conf. file - */ -static int read_conf(glite_jp_is_conf *conf, char *conf_file) -{ - struct soap soap; - struct _jpelem__ServerConfigurationResponse out; - int fd, i; - - - if ((fd = open(conf_file, 0)) < 0) { - fprintf(stderr, "error opening %s: %s\n", conf_file, strerror(errno)); - return 1; - } - - memset(&soap, 0, sizeof(soap)); - soap_init(&soap); - soap_set_namespaces(&soap, jp__namespaces); - - soap_begin(&soap); - soap.recvfd = fd; - soap_begin_recv(&soap); - memset(&out, 0, sizeof(out)); - - soap_default__jpelem__ServerConfigurationResponse(&soap, &out); - if (!soap_get__jpelem__ServerConfigurationResponse(&soap, &out, "ServerConfiguration", NULL)) { - soap_end_recv(&soap); - soap_end(&soap); - soap_print_fault(&soap, stderr); - return EINVAL; - } - soap_end_recv(&soap); - - if (out.__sizeattrs) { - conf->attrs = calloc(out.__sizeattrs + 1, sizeof(*conf->attrs)); - conf->multival_attrs = calloc(1, sizeof(*conf->multival_attrs)); - conf->queriable_attrs = calloc(1, sizeof(*conf->queriable_attrs)); - int mva = 0; - int qa = 0; - for (i=0; i < out.__sizeattrs; i++) { - struct jptype__attrType *attr; - attr = GLITE_SECURITY_GSOAP_LIST_GET(out.attrs, i); - if (!attr->name) { - fprintf(stderr, "missing name of %d attribute in %s\n", i + 1, conf_file); - goto err; - } - conf->attrs[i] = strdup(attr->name); - if (attr->multival == jptype__yesNo__YES){ - conf->multival_attrs = realloc(conf->multival_attrs, (mva+2)*sizeof(*conf->multival_attrs)); - conf->multival_attrs[mva] = strdup(attr->name); - conf->multival_attrs[++mva] = NULL; - } - if (attr->queriable == jptype__yesNo__YES){ - conf->queriable_attrs = realloc(conf->queriable_attrs, (qa+2)*sizeof(*conf->queriable_attrs)); - conf->queriable_attrs[qa] = strdup(attr->name); - conf->queriable_attrs[++qa] = NULL; - } - } - } - if (out.__sizeindexedAttrs) { - conf->indexed_attrs = calloc(out.__sizeindexedAttrs + 1, sizeof(*conf->indexed_attrs)); - for (i=0; i < out.__sizeindexedAttrs; i++) { - conf->indexed_attrs[i] = strdup(out.indexedAttrs[i]); - } - } - if (out.__sizeplugins) { - conf->plugins = calloc(out.__sizeplugins + 1, sizeof(*conf->plugins)); - for (i=0; i < out.__sizeplugins; i++) { - conf->plugins[i] = strdup(out.plugins[i]); - } - } - if (out.__sizefeeds) { - conf->feeds = calloc(out.__sizefeeds + 1, sizeof(*conf->feeds)); - for (i=0; i < out.__sizefeeds; i++) { - struct jptype__feedSession *feed; - - feed = GLITE_SECURITY_GSOAP_LIST_GET(out.feeds, i); - conf->feeds[i] = calloc(1, sizeof(*conf->feeds[i])); - conf->feeds[i]->PS_URL=strdup(feed->primaryServer); - - if (glite_jpis_SoapToPrimaryQueryConds(feed->__sizecondition, - feed->condition, &conf->feeds[i]->query)) goto err; - - conf->feeds[i]->history = feed->history; - conf->feeds[i]->continuous = feed->continuous; - conf->feeds[i]->uniqueid = -1; - } - } - - soap_destroy(&soap); - soap_end(&soap); - soap_done(&soap); - - return 0; - -err: - glite_jp_free_conf(conf); - soap_destroy(&soap); - soap_end(&soap); - soap_done(&soap); - return EINVAL; -} - -#if 0 -/* - * Just helper function - used only once for first generation - * of XML example configuration (which was then reedited in hand) - */ -static int dump_conf(void) { - int retval; - struct _jpelem__ServerConfigurationResponse out; - struct soap soap; - struct jptype__feedSession *feed; - struct jptype__primaryQuery *cond; - - soap_init(&soap); - soap_set_namespaces(&soap, jp__namespaces); - - soap.sendfd = STDOUT_FILENO; - soap_begin_send(&soap); - soap_default__jpelem__ServerConfigurationResponse(&soap, &out); - - out.__sizeattrs = 2; - out.attrs = calloc(2, sizeof(*out.attrs)); - out.attrs[0] = strdup("atrr1"); - out.attrs[1] = strdup("atrr2"); - - out.__sizeindexedAttrs = 2; - out.indexedAttrs = calloc(2, sizeof(*out.indexedAttrs)); - out.indexedAttrs[0] = strdup("idxAtrr1"); - out.indexedAttrs[1] = strdup("idxAtrr2"); - - out.__sizeplugins = 2; - out.plugins = calloc(2, sizeof(*out.plugins)); - out.plugins[0] = strdup("plugin1"); - out.plugins[1] = strdup("plugin2"); - - GLITE_SECURITY_GSOAP_LIST_CREATE(&soap, &out, feeds, struct jptype__feedSession, 1); - feed = GLITE_SECURITY_GSOAP_LIST_GET(out.feeds, 0); - feed->primaryServer = strdup("PrimaryServer"); - feed->__sizecondition = 1; - GLITE_SECURITY_GSOAP_LIST_CREATE(&soap, feed, condition, struct jptype__primaryQuery, 1); - cond = GLITE_SECURITY_GSOAP_LIST_GET(feed->condition, 0); - cond->attr = strdup("queryAttr"); - cond->op = jptype__queryOp__EQUAL; - cond->origin = jptype__attrOrig__SYSTEM; - cond->value = calloc(1, sizeof(*(cond->value))); - GSOAP_SETSTRING(cond->value, soap_strdup(&soap, "attrValue")); - feed->history = 1; - feed->continuous = 0; - - soap_serialize__jpelem__ServerConfigurationResponse(&soap, &out); - retval = soap_put__jpelem__ServerConfigurationResponse(&soap, &out, "jpelem:ServerConfiguration", NULL); - soap_end_send(&soap); - soap_free(&soap); - soap_end(&soap); - - return retval; -} -#endif diff --git a/org.glite.jp.index/src/conf.h b/org.glite.jp.index/src/conf.h deleted file mode 100644 index eaa2f77..0000000 --- a/org.glite.jp.index/src/conf.h +++ /dev/null @@ -1,85 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#ifndef _CONF_H -#define _CONF_H - -#include - -#ifndef UNUSED - #ifdef __GNUC__ - #define UNUSED __attribute__((unused)) - #else - #define UNUSED - #endif -#endif - -#define GLITE_JPIS_DEFAULT_PORT_STR "8902" - -//#define lprintf -#define lprintf(args...) glite_jp_lprintf(__FUNCTION__, ##args) -#define llprintf(MODULE, args...) do { \ - if ((MODULE)) glite_jp_lprintf(__FUNCTION__, ##args); \ -} while(0) - - -typedef struct _glite_jp_is_feed { - char *PS_URL; //URLs of Primary Storage servers - glite_jp_query_rec_t *query; // query to Primary Server (aka filter) - int history, // type of query - continuous; - long int uniqueid; // internal ID -} glite_jp_is_feed; - -typedef struct _glite_jp_is_conf { - // all I need to get from comman line options and configuration file - - // arrays are zero-terminated - char **attrs; // atributes to obtain - char **indexed_attrs; // list of indexed atributes - char **multival_attrs; // list of multivalue attributes - char **queriable_attrs; // list of queriable attributes - char **plugins; // list of plugin.so's - - glite_jp_is_feed **feeds; // null terminated list of feeds - - int debug; - int no_auth; // set if you do not want authorization - char *cs, // database contact string - *port, // server port - *pidfile, - *logfile, - *server_cert, - *server_key; - int slaves; - int delete_db; - - char *feeding; // feed DB from local file - int force_feed; -} glite_jp_is_conf; - - - -// read commad line options and configuration file -int glite_jp_get_conf(int argc, char **argv, glite_jp_is_conf **configuration); -void glite_jp_free_conf(glite_jp_is_conf *conf); - -void glite_jp_lprintf(const char *source, const char *fmt, ...); - -#endif diff --git a/org.glite.jp.index/src/context.c b/org.glite.jp.index/src/context.c deleted file mode 100644 index 4f81c55..0000000 --- a/org.glite.jp.index/src/context.c +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include - -#include - -#include "conf.h" -#include "context.h" - - -int glite_jpis_init_context(glite_jpis_context_t *isctx, glite_jp_context_t jpctx, glite_jp_is_conf *conf) { - char hname[512]; - char *op_args; - - if ((*isctx = calloc(sizeof(**isctx), 1)) != NULL) { - (*isctx)->jpctx = jpctx; - (*isctx)->conf = conf; - edg_wll_gss_gethostname(hname, sizeof hname); - asprintf(&(*isctx)->hname, "https://%s:%s", hname, (conf && conf->port) ? conf->port : GLITE_JPIS_DEFAULT_PORT_STR); - - op_args = (*isctx)->op_args; - op_args[GLITE_JP_QUERYOP_WITHIN] = 2; - op_args[GLITE_JP_QUERYOP_UNDEF] = 0; - op_args[GLITE_JP_QUERYOP_EQUAL] = 1; - op_args[GLITE_JP_QUERYOP_LESS] = 1; - op_args[GLITE_JP_QUERYOP_GREATER] = 1; - op_args[GLITE_JP_QUERYOP_EXISTS] = 0; - return 0; - } else return ENOMEM; -} - - -void glite_jpis_free_context(glite_jpis_context_t ctx) { - if (!ctx) return; - free(ctx->hname); - free(ctx); -} diff --git a/org.glite.jp.index/src/context.h b/org.glite.jp.index/src/context.h deleted file mode 100644 index a8f3f4d..0000000 --- a/org.glite.jp.index/src/context.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_IS_CONTEXT_H -#define GLITE_JP_IS_CONTEXT_H - -#include -#include -#include -#include "conf.h" - - -typedef struct _glite_jpis_context { - glite_jp_context_t jpctx; - glite_jp_is_conf *conf; - glite_lbu_Statement select_unlocked_feed_stmt, lock_feed_stmt, init_feed_stmt, unlock_feed_stmt, select_info_feed_stmt, update_state_feed_stmt, select_info_attrs_indexed, select_jobid_stmt, select_user_stmt, insert_job_stmt, insert_user_stmt; - - char *hname; - - char op_args[GLITE_JP_QUERYOP__LAST]; -} *glite_jpis_context_t; - -typedef struct _slave_data_t{ - glite_jpis_context_t ctx; - glite_jp_is_conf *conf; - struct soap *soap; -} slave_data_t; - -int glite_jpis_init_context(glite_jpis_context_t *isctx, glite_jp_context_t jpctx, glite_jp_is_conf *conf); -void glite_jpis_free_context(glite_jpis_context_t ctx); -#endif diff --git a/org.glite.jp.index/src/db_ops.c b/org.glite.jp.index/src/db_ops.c deleted file mode 100644 index c8aff72..0000000 --- a/org.glite.jp.index/src/db_ops.c +++ /dev/null @@ -1,889 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define GLITE_JP_INDEX_COMPILE 1 - -#include -#include -#include -#include -#include -#include -#include -#include "glite/jp/known_attr.h" -#include "glite/jp/indexdb.h" - -#include "conf.h" -#include "context.h" -#include "db_ops.h" -#include "common.h" - - -#ifndef LOG_SQL -#define LOG_SQL 1 -#endif - -#define SQLCMD_DROP_DATA_TABLE "DROP TABLE " GLITE_JP_INDEXDB_TABLE_ATTR_PREFIX "%s" -#define SQLCMD_CREATE_DATA_TABLE "CREATE TABLE " GLITE_JP_INDEXDB_TABLE_ATTR_PREFIX "%s (\n\ - `jobid` CHAR(32) NOT NULL,\n\ - `value` %s NOT NULL,\n\ - `full_value` %s NOT NULL,\n\ - `origin` INT NOT NULL,\n\ -\n\ - INDEX (jobid),\n\ - INDEX (value)\n\ -) CHARACTER SET utf8 COLLATE utf8_bin ENGINE=innodb;" - -#define SQLCMD_CREATE_JOBS_TABLE_BEGIN "CREATE TABLE jobs (\n\ - `jobid` char(32) NOT NULL,\n\ - `dg_jobid` varchar(255) NOT NULL,\n\ - `ownerid` char(32) NOT NULL,\n\ - `aclid` char(32) NOT NULL,\n\ - `ps` varchar(255) NOT NULL,\n" -#define SQLCMD_CREATE_JOBS_TABLE_END "\ - primary key (jobid),\n\ - unique (dg_jobid),\n\ - index (jobid),\n\ - index (dg_jobid)\n\ -) character set utf8 collate utf8_bin engine=innodb;" - -#define SQLCMD_INSERT_ATTRVAL "INSERT INTO " GLITE_JP_INDEXDB_TABLE_ATTR_PREFIX "%|Ss (jobid, value, full_value, origin) VALUES (\n\ - '%|Ss',\n\ - '%|Ss',\n\ - '%|Ss',\n\ - '%ld'\n\ -)" -#define SQL_CMD_INSERT_SINGLEATTRVAL "UPDATE jobs \n\ - SET attr_%s='%s' \n\ - WHERE dg_jobid='%s'" - -#define WORD_SWAP(X) ((((X) >> 8) & 0xFF) | (((X) & 0xFF) << 8)) -#define LONG_SWAP(X) (WORD_SWAP(((X) >> 16) & 0xFFFF) | ((WORD_SWAP(X) & 0xFFFF) << 16)) -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define LONG_LE(X) (X) -#else -#define LONG_LE(X) LONG_SWAP(X) -#endif - -#define COND_MAGIC 0x444E4F43 - - -static int glite_jpis_db_queries_deserialize(glite_jp_query_rec_t **queries, void *blob, size_t blob_size) UNUSED; - - -static int is_indexed(glite_jp_is_conf *conf, const char *attr) { - return glite_jpis_find_attr(conf->indexed_attrs, attr); -} - -static int is_singleval(glite_jp_is_conf *conf, const char *attr) { - return !glite_jpis_find_attr(conf->multival_attrs, attr); -} - -static int is_queriable(glite_jp_is_conf *conf, const char *attr){ - return glite_jpis_find_attr(conf->queriable_attrs, attr); -} - -static size_t db_arg1_length(glite_jpis_context_t isctx, glite_jp_query_rec_t *query) { - size_t len; - - assert(query->op > GLITE_JP_QUERYOP_UNDEF && query->op <= GLITE_JP_QUERYOP__LAST); - if (isctx->op_args[query->op] >= 1) - len = query->binary ? query->size : (query->value ? strlen(query->value) + 1 : 0); - else len = 0; - - return len; -} - -static size_t db_arg2_length(glite_jpis_context_t isctx, glite_jp_query_rec_t *query) { - size_t len; - - assert(query->op > GLITE_JP_QUERYOP_UNDEF && query->op <= GLITE_JP_QUERYOP__LAST); - if (isctx->op_args[query->op] >= 1) - len = query->binary ? query->size2 : (query->value2 ? strlen(query->value2) + 1 : 0); - else len = 0; - - return len; -} - - -static int array_init(void **data, size_t *len, size_t *maxlen, size_t initial_len) { - *len = 0; - if ((*data = malloc(initial_len)) != NULL) { - *maxlen = initial_len; - return 0; - } else { - *maxlen = 0; - return ENOMEM; - } -} - - -static int array_add(void **data, size_t *len, size_t *maxlen, void *new_data, size_t new_data_len) { - void *tmp; - size_t ptr; - - ptr = *len; - (*len) += new_data_len; - if (*len > *maxlen) { - do { - (*maxlen) *= 2; - } while (*len > *maxlen); - if ((tmp = realloc(*data, *maxlen)) == NULL) return ENOMEM; - *data = tmp; - } - memcpy(((char *)(*data)) + ptr, new_data, new_data_len); - - return 0; -} - - -static int array_add_long(void **data, size_t *len, size_t *maxlen, uint32_t l) { - uint32_t lel; - - lel = LONG_LE(l); - return array_add(data, len, maxlen, &lel, sizeof(uint32_t)); -} - - -static uint32_t array_get_long(void **data) { - uint32_t *lel; - - lel = (uint32_t *)*data; - *data = ((char *)*data) + sizeof(uint32_t); - - return LONG_LE(*lel); -} - - -static void *array_get(void **data, size_t data_len) { - void *res; - - res = *data; - *data = ((char *)*data) + data_len; - - return res; -} - - -static int glite_jpis_db_queries_serialize(glite_jpis_context_t isctx, void **blob, size_t *len, glite_jp_query_rec_t *queries) { - size_t maxlen; - glite_jp_query_rec_t *query; - int ret; - size_t datalen; - - if ((ret = array_init(blob, len, &maxlen, 1024)) != 0) return ret; - query = queries; - while(query && query->attr) { - if ((ret = array_add_long(blob, len, &maxlen, COND_MAGIC)) != 0) goto fail; - datalen = strlen(query->attr) + 1; - if ((ret = array_add_long(blob, len, &maxlen, datalen)) != 0) goto fail; - if ((ret = array_add(blob, len, &maxlen, query->attr, datalen)) != 0) goto fail; - if ((ret = array_add_long(blob, len, &maxlen, query->op)) != 0) goto fail; - if ((ret = array_add_long(blob, len, &maxlen, query->binary ? 1 : 0)) != 0) goto fail; - - datalen = db_arg1_length(isctx, query); - if ((ret = array_add_long(blob, len, &maxlen, datalen)) != 0) goto fail; - if (datalen) - if ((ret = array_add(blob, len, &maxlen, query->value, datalen)) != 0) goto fail; - - datalen = db_arg2_length(isctx, query); - if ((ret = array_add_long(blob, len, &maxlen, datalen)) != 0) goto fail; - if (datalen) - if ((ret = array_add(blob, len, &maxlen, query->value2, datalen)) != 0) goto fail; - - query++; - } - - return 0; -fail: - free(*blob); - *len = 0; - return ret; -} - - -static int glite_jpis_db_queries_deserialize(glite_jp_query_rec_t **queries, void *blob, size_t blob_size) { - size_t maxlen, len, datalen; - void *blob_ptr, *blob_end; - int ret; - uint32_t l; - glite_jp_query_rec_t query; - int i; - - if ((ret = array_init((void *)queries, &len, &maxlen, 512)) != 0) return ret; - blob_ptr = blob; - blob_end = (char *)blob + blob_size; - while (blob_end > blob_ptr) { - ret = ENOMEM; - memset(&query, 0, sizeof query); - l = array_get_long(&blob_ptr); - if (l != COND_MAGIC) { - lprintf("blob=%p, blob_ptr=%p, 0x%08" PRIX32 "\n", blob, blob_ptr, l); - ret = EINVAL; - goto fail_query; - } - - datalen = array_get_long(&blob_ptr); - if (datalen) { - if ((query.attr = malloc(datalen)) == NULL) goto fail_query; - memcpy(query.attr, array_get(&blob_ptr, datalen), datalen); - } else query.attr = NULL; - - query.op = array_get_long(&blob_ptr); - query.binary = array_get_long(&blob_ptr); - - datalen = array_get_long(&blob_ptr); - if (datalen) { - if ((query.value = malloc(datalen)) == NULL) goto fail_query; - memcpy(query.value, array_get(&blob_ptr, datalen), datalen); - } else query.value = NULL; - query.size = datalen; - - datalen = array_get_long(&blob_ptr); - if (datalen) { - if ((query.value2 = malloc(datalen)) == NULL) goto fail_query; - memcpy(query.value2, array_get(&blob_ptr, datalen), datalen); - } else query.value2 = NULL; - query.size2 = datalen; - - if ((ret = array_add((void *)queries, &len, &maxlen, &query, sizeof(query))) != 0) goto fail_query; - } - assert(blob_end == blob_ptr); - - memset(&query, 0, sizeof query); - if ((ret = array_add((void *)queries, &len, &maxlen, &query, sizeof(query))) != 0) goto fail; - - return 0; - -fail_query: -fail: - i = 0; - while ((*queries)[i].attr) { - free((*queries)[i].attr); - free((*queries)[i].value); - free((*queries)[i].value2); - i++; - } - free(*queries); - return ret; -} - - -/* Init the database. - * - * \retval 0 OK - * \retval non-zero JP error code - */ - -int glite_jpis_initDatabase(glite_jpis_context_t ctx) { - char **attrs, *attrid, *num; - const char *type_index, *type_full; - size_t i; - int indexed, nattrs; - char sql[2048]; - glite_jp_context_t jpctx = ctx->jpctx; - glite_lbu_Statement stmt = NULL; - - jpctx = ctx->jpctx; - - // check, if database was already created - if (glite_jp_db_ExecSQL(jpctx, "SELECT COUNT(*) FROM attrs", &stmt) < 0) { - glite_jpis_stack_error(ctx->jpctx, EIO, "error during counting attrs"); - goto fail; - } - if (glite_jp_db_FetchRow(jpctx, stmt, 1, NULL, &num) < 0) { - glite_jpis_stack_error(ctx->jpctx, EIO, "error during fetching attrs"); - goto fail; - } - nattrs = atoi(num); - llprintf(LOG_SQL, "found '%s' attributes in attrs table\n", num, nattrs); - free(num); - glite_jp_db_FreeStmt(&stmt); - if (nattrs != 0) { - lprintf("database with %d attributes kept (use -D for delete)\n", nattrs); - return 0; - } - - if (glite_jp_db_PrepareStmt(jpctx, "INSERT INTO attrs (attrid, name, indexed, type) VALUES (?, ?, ?, ?)", &stmt) != 0) { - glite_jpis_stack_error(ctx->jpctx, EIO, "can't create insert attributes statement"); - goto fail; - } - - // attrs table and attrid_* tables - attrs = ctx->conf->attrs; - i = 0; - if (attrs) while (attrs[i]) { - type_full = glite_jp_attrval_db_type_full(jpctx, attrs[i]); - type_index = glite_jp_attrval_db_type_index(jpctx, attrs[i], GLITE_JPIS_INDEX_LENGTH); - - attrid = glite_jp_indexdb_attr2id(attrs[i]); - indexed = is_indexed(ctx->conf, attrs[i]); - if (glite_jp_db_ExecPreparedStmt(jpctx, stmt, 4, - GLITE_LBU_DB_TYPE_VARCHAR, attrid, - GLITE_LBU_DB_TYPE_VARCHAR, attrs[i], - GLITE_LBU_DB_TYPE_INT, indexed, - GLITE_LBU_DB_TYPE_VARCHAR, type_full) == -1) { - glite_jpis_stack_error(ctx->jpctx, EIO, "can't create '%s' attribute", attrs[i]); - goto fail; - } - - // silently drop - sql[sizeof(sql) - 1] = '\0'; - snprintf(sql, sizeof(sql), SQLCMD_DROP_DATA_TABLE, attrid); - llprintf(LOG_SQL, "preventive dropping '%s' ==> '%s'\n", attrid, sql); - glite_jp_db_ExecSQL(jpctx, sql, NULL); - glite_jp_clear_error(ctx->jpctx); - - // create table - sql[sizeof(sql) - 1] = '\0'; - snprintf(sql, sizeof(sql) - 1, SQLCMD_CREATE_DATA_TABLE, attrid, type_index, type_full); - free(attrid); - llprintf(LOG_SQL, "creating table: '%s'\n", sql); - if ((glite_jp_db_ExecSQL(jpctx, sql, NULL)) == -1) { - glite_jpis_stack_error(ctx->jpctx, EAGAIN, "if the atribute table already exists, restart may help"); - goto fail; - } - - i++; - } - glite_jp_db_FreeStmt(&stmt); - - // create jobs table - snprintf(sql, sizeof(sql) - 1, SQLCMD_CREATE_JOBS_TABLE_BEGIN); - if (ctx->conf->attrs) for (i = 0; ctx->conf->attrs[i]; i++) - if (is_singleval(ctx->conf, ctx->conf->attrs[i]) - && is_queriable(ctx->conf, ctx->conf->attrs[i])){ - snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), - " `attr_%s` %s NOT NULL,\n", - glite_jp_indexdb_attr2id(ctx->conf->attrs[i]), - glite_jp_attrval_db_type_index(jpctx, ctx->conf->attrs[i], GLITE_JPIS_INDEX_LENGTH)); - - if (is_indexed(ctx->conf, ctx->conf->attrs[i])) - snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), - " index (attr_%s), \n", - glite_jp_indexdb_attr2id(ctx->conf->attrs[i])); - } - snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), SQLCMD_CREATE_JOBS_TABLE_END); - llprintf(LOG_SQL, "sql=%s\n", sql); - if ((glite_jp_db_ExecSQL(jpctx, sql, NULL)) == -1) { - glite_jpis_stack_error(ctx->jpctx, EAGAIN, "Cannot create table 'jobs'!"); - goto fail; - } - - return 0; - -fail: - glite_jp_db_FreeStmt(&stmt); - if (!jpctx->error) glite_jpis_stack_error(ctx->jpctx, EIO, "error during initial filling of the database"); - return jpctx->error->code; -} - - -int glite_jpis_initDatabaseFeeds(glite_jpis_context_t ctx) { - glite_jp_context_t jpctx = ctx->jpctx; - glite_lbu_Statement stmt = NULL; - glite_jp_is_feed **feeds; - size_t i; - size_t conds_len; - void *conds; - int state, locked; - - if (glite_jp_db_ExecSQL(jpctx, "DELETE FROM feeds", NULL) == -1) { - glite_jpis_stack_error(ctx->jpctx, EIO, "can't delete feeds"); - goto fail; - } - - // feeds table - if (glite_jp_db_PrepareStmt(jpctx, "INSERT INTO feeds (`state`, `locked`, `source`, `condition`) VALUES (?, ?, ?, ?)", &stmt) != 0) { - glite_jpis_stack_error(ctx->jpctx, EIO, "can't create insert feeds statement"); - goto fail; - } - feeds = ctx->conf->feeds; - i = 0; - if (feeds) while (feeds[i]) { - state = (feeds[i]->history ? GLITE_JP_IS_STATE_HIST : 0) | - (feeds[i]->continuous ? GLITE_JP_IS_STATE_CONT : 0); - locked = 0; - assert(glite_jpis_db_queries_serialize(ctx, &conds, &conds_len, feeds[i]->query) == 0); - if (glite_jp_db_ExecPreparedStmt(jpctx, stmt, 4, - GLITE_LBU_DB_TYPE_INT, state, - GLITE_LBU_DB_TYPE_INT, locked, - GLITE_LBU_DB_TYPE_VARCHAR, feeds[i]->PS_URL, - GLITE_LBU_DB_TYPE_MEDIUMBLOB, conds, conds_len) == -1) - goto fail_conds; - free(conds); - conds = NULL; - feeds[i]->uniqueid = glite_lbu_Lastid(stmt); - - i++; - } - glite_jp_db_FreeStmt(&stmt); - return 0; - -fail_conds: - free(conds); -fail: - glite_jp_db_FreeStmt(&stmt); - if (!jpctx->error) glite_jpis_stack_error(ctx->jpctx, EIO, "error during initial filling of the database"); - return jpctx->error->code; -} - - -/* Drop the whole database. - * - * \retval 0 OK - * \retval non-zero JP error code - */ - -int glite_jpis_dropDatabase(glite_jpis_context_t ctx) { - char *attrid, sql[256]; - unsigned long len; - int ret; - glite_jp_context_t jpctx = ctx->jpctx; - glite_lbu_Statement stmt_tabs = NULL; - - // search data tables and drop them - if (glite_jp_db_PrepareStmt(jpctx, "SELECT attrid FROM attrs", &stmt_tabs) != 0) goto fail; - if (glite_jp_db_ExecPreparedStmt(jpctx, stmt_tabs, 0) == -1) goto fail; - while ((ret = glite_jp_db_FetchRow(jpctx, stmt_tabs, 1, &len, &attrid)) > 0) { - snprintf(sql, sizeof(sql), SQLCMD_DROP_DATA_TABLE, attrid); - llprintf(LOG_SQL, "dropping '%s' ==> '%s'\n", attrid, sql); - if (glite_jp_db_ExecSQL(jpctx, sql, NULL) == -1) printf("warning: can't drop table '" GLITE_JP_INDEXDB_TABLE_ATTR_PREFIX "%s': %s (%s)\n", attrid, jpctx->error->desc, jpctx->error->source); - } - if (ret != 0) goto fail; - glite_jp_db_FreeStmt(&stmt_tabs); - snprintf(sql, sizeof(sql)-1, "DROP TABLE jobs"); - llprintf(LOG_SQL, "dropping 'jobs'"); - if (glite_jp_db_ExecSQL(jpctx, sql, NULL) == -1) printf("warning: can't drop table 'jobs'\n"); - - // drop feeds and atributes - if (glite_jp_db_ExecSQL(jpctx, "DELETE FROM attrs", NULL) == -1) goto fail; - if (glite_jp_db_ExecSQL(jpctx, "DELETE FROM feeds", NULL) == -1) goto fail; - if (glite_jp_db_ExecSQL(jpctx, "DELETE FROM users", NULL) == -1) goto fail; - if (glite_jp_db_ExecSQL(jpctx, "DELETE FROM acls", NULL) == -1) goto fail; - - return 0; - -fail: - glite_jp_db_FreeStmt(&stmt_tabs); - return jpctx->error->code; -} - - -int glite_jpis_init_db(glite_jpis_context_t isctx) { - int ret, caps; - const char *cs; - glite_jp_context_t jpctx; - - jpctx = isctx->jpctx; - if (glite_lbu_InitDBContext(((glite_lbu_DBContext *)&jpctx->dbhandle)) != 0) goto fail_db; - if ((cs = isctx->conf->cs) == NULL) cs = GLITE_JP_IS_DEFAULTCS; - if (glite_lbu_DBConnect(jpctx->dbhandle, cs) != 0) goto fail_db; - - // try transaction for feeding - if (isctx->conf->feeding) { - caps = glite_lbu_DBQueryCaps(jpctx->dbhandle); - if (caps != -1) { - glite_lbu_DBSetCaps(jpctx->dbhandle, caps); - llprintf(LOG_SQL, "transactions %s\n", (caps & GLITE_LBU_DB_CAP_TRANSACTIONS) ? "supported" : "not supported"); - } - } - - // sql command: lock the feed (via uniqueid) - if ((ret = glite_jp_db_PrepareStmt(jpctx, "UPDATE feeds SET locked=1 WHERE (locked = 0) AND (uniqueid = ?)", &isctx->lock_feed_stmt)) != 0) goto fail; - - // sql command: assign the feed (via uniqueid) - if ((ret = glite_jp_db_PrepareStmt(jpctx, "UPDATE feeds SET feedid=?, expires=?, state=? WHERE (uniqueid=?)", &isctx->init_feed_stmt)) != 0) goto fail; - - // sql command: unlock the feed (via uniqueid) - if ((ret = glite_jp_db_PrepareStmt(jpctx, "UPDATE feeds SET locked=0 WHERE (uniqueid=?)", &isctx->unlock_feed_stmt)) != 0) goto fail; - - // sql command: get info about the feed (via feedid) - if ((ret = glite_jp_db_PrepareStmt(jpctx, "SELECT uniqueid, state, source FROM feeds WHERE (feedid=?)", &isctx->select_info_feed_stmt)) != 0) goto fail; - - // sql command: update state of the feed (via uniqueid) - if ((ret = glite_jp_db_PrepareStmt(jpctx, "UPDATE feeds SET state=? WHERE (uniqueid=?)", &isctx->update_state_feed_stmt)) != 0) goto fail; - - // sql command: check for job with jobid - if ((ret = glite_jp_db_PrepareStmt(jpctx, "SELECT jobid FROM jobs WHERE jobid=?", &isctx->select_jobid_stmt)) != 0) goto fail; - - // sql command: insert the job - if ((ret = glite_jp_db_PrepareStmt(jpctx, "INSERT INTO jobs (jobid, dg_jobid, ownerid, ps) VALUES (?, ?, ?, ?)", &isctx->insert_job_stmt)) != 0) goto fail; - - // sql command: check the user - if ((ret = glite_jp_db_PrepareStmt(jpctx, "SELECT userid FROM users WHERE userid=?", &isctx->select_user_stmt)) != 0) goto fail; - - // sql command: insert the user - if ((ret = glite_jp_db_PrepareStmt(jpctx, "INSERT INTO users (userid, cert_subj) VALUES (?, ?)", &isctx->insert_user_stmt)) != 0) goto fail; - - return 0; - -fail_db: - ret = glite_jp_db_SetError(jpctx, __FUNCTION__); -fail: - glite_jpis_free_db(isctx); - return ret; -} - - -void glite_jpis_free_db(glite_jpis_context_t ctx) { - glite_jp_db_FreeStmt(&ctx->lock_feed_stmt); - glite_jp_db_FreeStmt(&ctx->init_feed_stmt); - glite_jp_db_FreeStmt(&ctx->unlock_feed_stmt); - glite_jp_db_FreeStmt(&ctx->select_info_feed_stmt); - glite_jp_db_FreeStmt(&ctx->update_state_feed_stmt); - glite_jp_db_FreeStmt(&ctx->select_jobid_stmt); - glite_jp_db_FreeStmt(&ctx->select_user_stmt); - glite_jp_db_FreeStmt(&ctx->insert_job_stmt); - glite_jp_db_FreeStmt(&ctx->insert_user_stmt); - glite_lbu_DBClose(ctx->jpctx->dbhandle); - glite_lbu_FreeDBContext(ctx->jpctx->dbhandle); - ctx->jpctx->dbhandle = NULL; -} - - -/* Find first unitialized feed, lock it and return URL of corresponding PS - * - * Return value: - * 0 - OK - * ENOENT - no more feeds to initialize - * ENOLCK - error during locking */ - -int glite_jpis_lockSearchFeed(glite_jpis_context_t ctx, int initialized, long int *uniqueid, char **PS_URL, int *status, char **feedid) -{ - int ret; - static int uninit_msg = 1; - char *sql, *res[4], *t, *ps; - glite_lbu_Statement stmt; - - if (feedid) *feedid = NULL; - do { - glite_lbu_TimeToDB(time(NULL), &t); - if (initialized) { - trio_asprintf(&sql, "SELECT uniqueid, source, state, feedid FROM feeds WHERE (locked=0) AND (feedid IS NOT NULL) AND (expires <= %s)", t); - } else - trio_asprintf(&sql, "SELECT uniqueid, source, state, feedid FROM feeds WHERE (locked=0) AND (feedid IS NULL) AND ((state < " GLITE_JP_IS_STATE_ERROR_STR ") OR (expires <= %s))", t); - free(t); - //llprintf(LOG_SQL, "sql=%s\n", sql); - ret = glite_jp_db_ExecSQL(ctx->jpctx, sql, &stmt); - free(sql); - switch (ret) { - case -1: - glite_jpis_stack_error(ctx->jpctx, ENOLCK, "error selecting unlocked feed"); - uninit_msg = 1; - glite_jp_db_FreeStmt(&stmt); - return ENOLCK; - case 0: - if (uninit_msg) { - lprintf("no more %s feeds for now\n", initialized ? "not-refreshed" : "uninitialized"); - uninit_msg = 0; - } - glite_jp_db_FreeStmt(&stmt); - return ENOENT; - default: break; - } - uninit_msg = 1; - if (glite_jp_db_FetchRow(ctx->jpctx, stmt, sizeof(res)/sizeof(res[0]), NULL, res) <= 0) { - glite_jpis_stack_error(ctx->jpctx, ENOLCK, "error fetching unlocked feed"); - glite_jp_db_FreeStmt(&stmt); - return ENOLCK; - } - glite_jp_db_FreeStmt(&stmt); - lprintf("selected feed, uniqueid=%s\n", res[0]); - *uniqueid = atol(res[0]); free(res[0]); - ps = res[1]; - if (status) *status = atoi(res[2]); free(res[2]); - if (feedid) { - free(*feedid); - *feedid = res[3]; - } else free(res[3]); - - ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->lock_feed_stmt, 1, GLITE_LBU_DB_TYPE_INT, *uniqueid); - lprintf("locked %d feeds (uniqueid=%ld)\n", ret, *uniqueid); - } while (ret != 1); - - if (PS_URL) *PS_URL = ps; - else free(ps); - - return 0; -} - - -/* Store feed ID and expiration time returned by PS for locked feed. */ - -int glite_jpis_initFeed(glite_jpis_context_t ctx, long int uniqueid, const char *feedId, time_t feedExpires, int status) -{ - int ret; - time_t tnow, expires; - - tnow = time(NULL); - expires = tnow + (feedExpires - tnow) / 2; - - ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->init_feed_stmt, 4, - GLITE_LBU_DB_TYPE_CHAR, feedId, - GLITE_LBU_DB_TYPE_DATETIME, expires, - GLITE_LBU_DB_TYPE_INT, status, - GLITE_LBU_DB_TYPE_INT, uniqueid); - lprintf("initializing feed, uniqueid=%ld, result=%d\n", uniqueid, ret); - - return ret == 1 ? 0 : ENOLCK; -} - - -/* Unlock given feed */ - -int glite_jpis_unlockFeed(glite_jpis_context_t ctx, long int uniqueid) { - int ret; - - ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->unlock_feed_stmt, 1, GLITE_LBU_DB_TYPE_INT, uniqueid); - lprintf("unlocking feed, uniqueid=%ld, result=%d\n", uniqueid, ret); - - return ret == 1 ? 0 : ENOLCK; -} - - -/* Saves TTL (when to reconnect if error occured) for given feed */ - -int glite_jpis_tryReconnectFeed(glite_jpis_context_t ctx, long int uniqueid, time_t reconn_time, int state) { - int ret; - char *sql, *t; - - glite_lbu_TimeToDB(reconn_time, &t); - lprintf("reconnect, un=%ld, %s\n", uniqueid, t); - trio_asprintf(&sql, "UPDATE feeds SET state=%d, expires=%s WHERE (uniqueid=%ld)", state, t, uniqueid); - free(t); - if ((ret = glite_jp_db_ExecSQL(ctx->jpctx, sql, NULL)) != 1) - glite_jpis_stack_error(ctx->jpctx, EIO, "can't update feed no. %ld in DB", uniqueid); - free(sql); - return ret == -1 ? ctx->jpctx->error->code : 0; -} - - -// TODO: could be merged with initFeed -int glite_jpis_destroyTryReconnectFeed(glite_jpis_context_t ctx, long int uniqueid, time_t reconn_time) { - int ret; - char *sql, *t; - - glite_lbu_TimeToDB(reconn_time, &t); - lprintf("destroy not refreshed feed, un=%ld, %s\n", uniqueid, t); - trio_asprintf(&sql, "UPDATE feeds SET feedid=NULL, state=0, expires=%s WHERE (uniqueid=%ld)", t, uniqueid); - free(t); - if ((ret = glite_jp_db_ExecSQL(ctx->jpctx, sql, NULL)) != 1) - glite_jpis_stack_error(ctx->jpctx, EIO, "can't destroy non-refreshable feed no. %ld in DB", uniqueid); - free(sql); - return ret == -1 ? ctx->jpctx->error->code : 0; -} - - -int glite_jpis_insertAttrVal(glite_jpis_context_t ctx, const char *jobid, glite_jp_attrval_t *av) { - char *sql, *table, *value, *full_value, *md5_jobid; - long int origin; - glite_jp_error_t err; - - glite_jp_clear_error(ctx->jpctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - table = glite_jp_indexdb_attr2id(av->name); - value = glite_jp_attrval_to_db_index(ctx->jpctx, av, GLITE_JPIS_INDEX_LENGTH); - full_value = glite_jp_attrval_to_db_full(ctx->jpctx, av); - md5_jobid = str2md5(jobid); - origin = av->origin; - trio_asprintf(&sql, SQLCMD_INSERT_ATTRVAL, table, md5_jobid, value, full_value, origin); - llprintf(LOG_SQL, "(%s) sql=%s\n", av->name, sql); -// if (ctx->conf->feeding) printf("FEED: %s\n", sql); -// else - if (glite_jp_db_ExecSQL(ctx->jpctx, sql, NULL) != 1){ - err.code = EIO; - err.desc = "DB access failed"; - goto cleanup; - } - free(sql); sql=NULL; - - if (is_singleval(ctx->conf, av->name) && is_queriable(ctx->conf, av->name)){ - trio_asprintf(&sql, SQL_CMD_INSERT_SINGLEATTRVAL, - glite_jp_indexdb_attr2id(av->name), value, jobid); - llprintf(LOG_SQL, "(%s) sql=%s\n", av->name, sql); - if (glite_jp_db_ExecSQL(ctx->jpctx, sql, NULL) != 1){ - err.code = EIO; - err.desc = "DB access failed"; - goto cleanup; - } - free(sql);sql=NULL; - } - -cleanup: - free(md5_jobid); - free(table); - free(value); - free(full_value); - - if (err.code) { - return glite_jpis_stack_error(ctx->jpctx, err.code, err.desc); - } else { - return 0; - } -} - - -int glite_jpis_lazyInsertJob(glite_jpis_context_t ctx, const char *ps, const char *jobid, const char *owner) { - int ret; - char *md5_jobid = NULL, *md5_cert = NULL; - - lprintf("\n"); - - if (!jobid || !owner) { - glite_jpis_stack_error(ctx->jpctx, EINVAL, "jobid and owner is mandatory (jobid=%s, owner=%s)!\n", jobid, owner); - goto fail; - } - md5_jobid = str2md5(jobid); - md5_cert = str2md5(owner); - switch (ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->select_jobid_stmt, 1, GLITE_LBU_DB_TYPE_CHAR, md5_jobid)) { - case 1: lprintf("jobid '%s' found\n", jobid); goto ok0; - case 0: - lprintf("inserting jobid %s (%s)\n", jobid, md5_jobid); - if (glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->insert_job_stmt, 4, - GLITE_LBU_DB_TYPE_CHAR, md5_jobid, - GLITE_LBU_DB_TYPE_VARCHAR, jobid, - GLITE_LBU_DB_TYPE_CHAR, md5_cert, - GLITE_LBU_DB_TYPE_CHAR, ps) != 1) goto fail; - break; - default: assert(ret != 1); break; - } -ok0: - - switch (ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->select_user_stmt, 1, GLITE_LBU_DB_TYPE_CHAR, md5_cert)) { - case 1: lprintf("owner '%s' found\n", owner); goto ok; - case 0: - lprintf("inserting user %s (%s)\n", owner, md5_cert); - if (glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->insert_user_stmt, 2, - GLITE_LBU_DB_TYPE_CHAR, md5_cert, - GLITE_LBU_DB_TYPE_VARCHAR, owner) != 1) goto fail; - break; - default: assert(ret != 1); break; - } - -ok: - free(md5_jobid); - free(md5_cert); - return 0; -fail: - free(md5_jobid); - free(md5_cert); - return ctx->jpctx->error->code; -} - - -#define FEEDING_SEPARATORS ";" -#define FEEDING_JOBID_BKSERVER "localhost-test" -#define FEEDING_JOBID_PORT 0 -#define FEEDING_PRIMARY_STORAGE "localhost:8901" -#define FEEDING_DEFAULT_OWNER "God" -int glite_jpis_feeding(glite_jpis_context_t ctx, const char *fname, const char *dn) { - FILE *f; - char line[1024], *token, *lasts, *jobid = NULL; - int nattrs, lno, i, iname, c; - glite_jp_attrval_t *avs; - glite_jobid_t j; - const char *owner = dn ? dn : FEEDING_DEFAULT_OWNER; - - if ((f = fopen(fname, "rt")) == NULL) { - glite_jpis_stack_error(ctx->jpctx, errno, "can't open csv dump file"); - return 1; - } - - for (nattrs = 0; ctx->conf->attrs[nattrs]; nattrs++); - avs = malloc(nattrs * sizeof avs[0]); - - lno = 0; - while(fgets(line, sizeof line, f) != NULL) { - if ((lno % 100) == 0) { - if (lno) glite_jp_db_Commit(ctx->jpctx); - glite_jp_db_Transaction(ctx->jpctx); - } - lno++; - if (line[0]) { - c = strlen(line) - 1; - if (line[c] != '\r' && line[c] != '\n' && !feof(f)) { - glite_jpis_stack_error(ctx->jpctx, E2BIG, "line too large at %d (max. %d)", lno, sizeof line); - goto err; - } - while (c >= 0 && (line[c] == '\r' || line[c] == '\n')) c--; - line[c + 1] = 0; - } -// printf("'%s'\n", line); - - memset(avs, 0, nattrs * sizeof avs[0]); - i = 0; - iname = 0; - token = strtok_r(line, FEEDING_SEPARATORS, &lasts); - while (token && iname < nattrs) { -// printf("\t'%s'\n", token); - do { - avs[i].name = ctx->conf->attrs[iname]; - iname++; - } while (strcasecmp(avs[i].name, GLITE_JP_ATTR_JOBID) == 0 || strcasecmp(avs[i].name, GLITE_JP_ATTR_OWNER) == 0); - glite_jpis_trim(token); - avs[i].value = token; - avs[i].timestamp = time(NULL); - avs[i].origin = GLITE_JP_ATTR_ORIG_FILE; -// printf("\t %d: %s = '%s'\n", i, avs[i].name, avs[i].value); - i++; - - token = strtok_r(NULL, FEEDING_SEPARATORS, &lasts); - } - - if (glite_jobid_create(FEEDING_JOBID_BKSERVER, FEEDING_JOBID_PORT, &j) != 0) { - glite_jpis_stack_error(ctx->jpctx, errno, "can't create jobid"); - goto err; - } - if ((jobid = glite_jobid_unparse(j)) == NULL) { - glite_jobid_free(j); - glite_jpis_stack_error(ctx->jpctx, ENOMEM, "can't unparse jobid"); - goto err; - } - glite_jobid_free(j); - if (glite_jpis_lazyInsertJob(ctx, FEEDING_PRIMARY_STORAGE, jobid, owner)) goto err; - for (i = 0; i < nattrs && avs[i].name; i++) { - if (glite_jpis_insertAttrVal(ctx, jobid, &avs[i])) goto err; - } - free(jobid); jobid = NULL; - } - glite_jp_db_Commit(ctx->jpctx); - - fclose(f); - free(avs); - return 0; -err: - fclose(f); - free(avs); - free(jobid); - glite_jp_db_Rollback(ctx->jpctx); - return 1; -} diff --git a/org.glite.jp.index/src/db_ops.h b/org.glite.jp.index/src/db_ops.h deleted file mode 100644 index 23af5f0..0000000 --- a/org.glite.jp.index/src/db_ops.h +++ /dev/null @@ -1,67 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#ifndef _DB_OPS_H -#define _DB_OPS_H - - -#include -#include -#include "context.h" - - -#define GLITE_JP_IS_DEFAULTCS "jpis/@localhost:jpis" - -#define GLITE_JP_IS_STATE_HIST 1 -#define GLITE_JP_IS_STATE_CONT 2 -#define GLITE_JP_IS_STATE_DONE 4 -#define GLITE_JP_IS_STATE_ERROR 8 -#define GLITE_JP_IS_STATE_ERROR_STR "8" - -#define GLITE_JPIS_INDEX_LENGTH 255 - -#define GLITE_JPIS_PARAM(DEST, DEST_LEN, SRC) do { \ - (DEST)[sizeof((DEST)) - 1] = '\0'; \ - strncpy((DEST), (SRC), sizeof((DEST)) - 1); \ - (DEST_LEN) = strlen((SRC)); \ -} while(0) - - -char *glite_jpis_attr_name2id(const char *name); - -int glite_jpis_initDatabase(glite_jpis_context_t ctx); -int glite_jpis_initDatabaseFeeds(glite_jpis_context_t ctx); -int glite_jpis_dropDatabase(glite_jpis_context_t ctx); - -int glite_jpis_init_db(glite_jpis_context_t isctx); -void glite_jpis_free_db(glite_jpis_context_t ctx); - -int glite_jpis_lockSearchFeed(glite_jpis_context_t ctx, int initialized, long int *uinqueid, char **PS_URL, int *status, char **feedid); -int glite_jpis_initFeed(glite_jpis_context_t ctx, long int uniqueid, const char *feedId, time_t feedExpires, int status); -int glite_jpis_unlockFeed(glite_jpis_context_t ctx, long int uniqueid); -int glite_jpis_tryReconnectFeed(glite_jpis_context_t ctx, long int uniqueid, time_t reconn_time, int state); -int glite_jpis_destroyTryReconnectFeed(glite_jpis_context_t ctx, long int uniqueid, time_t reconn_time); - -int glite_jpis_insertAttrVal(glite_jpis_context_t ctx, const char *jobid, glite_jp_attrval_t *av); - -int glite_jpis_lazyInsertJob(glite_jpis_context_t ctx, const char *ps, const char *jobid, const char *owner); - -int glite_jpis_feeding(glite_jpis_context_t ctx, const char *fname, const char *dn); - -#endif diff --git a/org.glite.jp.index/src/simple_server.c b/org.glite.jp.index/src/simple_server.c deleted file mode 100644 index 593d05d..0000000 --- a/org.glite.jp.index/src/simple_server.c +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "jp_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; -} diff --git a/org.glite.jp.index/src/soap_ops.c b/org.glite.jp.index/src/soap_ops.c deleted file mode 100644 index 60ba31c..0000000 --- a/org.glite.jp.index/src/soap_ops.c +++ /dev/null @@ -1,738 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include - -#include "glite/lbu/trio.h" -#include "glite/jobid/strmd5.h" -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/jp/attr.h" -#include "glite/jp/known_attr.h" -#include "glite/jp/indexdb.h" - -#include "jp_H.h" -#include "soap_version.h" -#include "glite/security/glite_gscompat.h" -#include "db_ops.h" -#include "ws_ps_typeref.h" -#include "ws_is_typeref.h" -#include "context.h" -#include "common.h" - -#define INDEXED_STRIDE 2 // how often realloc indexed attr result - // XXX: 2 is only for debugging, replace with e.g. 100 -#define JOBIDS_STRIDE 2 // how often realloc matched jobids result - -/*------------------*/ -/* Helper functions */ -/*------------------*/ - -#include "glite/jp/ws_fault.c" - - - -/*-----------------------------------------*/ -/* IS WSDL server function implementations */ -/*-----------------------------------------*/ - - -#define CONTEXT_FROM_SOAP(soap,ctx) glite_jpis_context_t ctx = (glite_jpis_context_t) ((slave_data_t *) (soap->user))->ctx - - -static int updateJob(glite_jpis_context_t ctx, const char *ps, struct jptype__jobRecord *jobAttrs) { - glite_jp_attrval_t av; - struct jptype__attrValue *attr; - int ret, iattrs; - - lprintf("jobid='%s', attrs=%d\n", jobAttrs->jobid, jobAttrs->__sizeattributes); - - if (jobAttrs->remove) assert(*(jobAttrs->remove) == GLITE_SECURITY_GSOAP_FALSE); - - if ((ret = glite_jpis_lazyInsertJob(ctx, ps, jobAttrs->jobid, jobAttrs->owner)) != 0) return ret; - for (iattrs = 0; iattrs < jobAttrs->__sizeattributes; iattrs++) { - attr = GLITE_SECURITY_GSOAP_LIST_GET(jobAttrs->attributes, iattrs); - glite_jpis_SoapToAttrVal(&av, attr); - if (!glite_jpis_find_attr(ctx->conf->attrs, av.name)) { - fprintf(stderr, "unkown attribute '%s'\n", av.name); - continue; - } - if ((ret = glite_jpis_insertAttrVal(ctx, jobAttrs->jobid, &av)) != 0) return ret; - } - - return 0; -} - - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__UpdateJobs( - struct soap *soap, - struct _jpelem__UpdateJobs *jpelem__UpdateJobs, - struct _jpelem__UpdateJobsResponse *jpelem__UpdateJobsResponse UNUSED) -{ - int ret, ijobs; - const char *feedid; - int status, done; - CONTEXT_FROM_SOAP(soap, ctx); - glite_jp_context_t jpctx = ctx->jpctx; - char *err, *ps; - char *res[3]; - long int uniqueid; - - // XXX: test client in examples/jpis-test - // sends to this function some data for testing - puts(__FUNCTION__); - glite_jp_clear_error(jpctx); - ps = NULL; - - // get info about the feed - feedid = jpelem__UpdateJobs->feedId; - lprintf("feedid='%s'\n", feedid); - - if ((ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->select_info_feed_stmt, 1, GLITE_LBU_DB_TYPE_CHAR, feedid)) != 1) { - fprintf(stderr, "can't get info about feed '%s', returned %d records", feedid, ret); - if (jpctx->error) fprintf(stderr, ": %s (%s)\n", jpctx->error->desc, jpctx->error->source); - else fprintf(stderr, "\n"); - goto fail; - } - if (glite_jp_db_FetchRow(ctx->jpctx, ctx->select_info_feed_stmt, 3, NULL, res) <= 0) { - fprintf(stderr, "can't fetch feed '%s'", feedid); - if (jpctx->error) fprintf(stderr, ": %s (%s)\n", jpctx->error->desc, jpctx->error->source); - else fprintf(stderr, "\n"); - glite_jpis_stack_error(ctx->jpctx, ENODATA, "can't fetch feed '%s'", feedid); - goto fail; - } - lprintf("uniqueid=%s, state=%s, source='%s'\n", res[0], res[1], res[2]); - uniqueid = atol(res[0]); free(res[0]); - status = atoi(res[1]); free(res[1]); - ps = res[2]; - - // update status, if needed (only orig) - done = jpelem__UpdateJobs->feedDone ? GLITE_JP_IS_STATE_DONE : 0; - if ((done != (status & GLITE_JP_IS_STATE_DONE)) && done) { - status |= done; - if ((ret = glite_jp_db_ExecPreparedStmt(ctx->jpctx, ctx->update_state_feed_stmt, 2, - GLITE_LBU_DB_TYPE_INT, status, - GLITE_LBU_DB_TYPE_INT, uniqueid)) != 1) { - fprintf(stderr, "can't update state of '%s', returned %d records", feedid, ret); - if (jpctx->error) fprintf(stderr, ": %s (%s)\n", jpctx->error->desc, jpctx->error->source); - else fprintf(stderr, "\n"); - goto fail; - } - } - - // insert all attributes - for (ijobs = 0; ijobs < jpelem__UpdateJobs->__sizejobAttributes; ijobs++) { - if (updateJob(ctx, (const char *) ps, GLITE_SECURITY_GSOAP_LIST_GET(jpelem__UpdateJobs->jobAttributes, ijobs)) != 0) goto fail; - } - free(ps); - - return SOAP_OK; - -fail: - free(ps); - if (ctx->jpctx->error) { - err = glite_jp_error_chain(ctx->jpctx); - fprintf(stderr, "%s:%s\n", __FUNCTION__, err); - free(err); - } - glite_jp_server_err2fault(ctx->jpctx, soap); - return SOAP_FAULT; -} - - -static int checkIndexedConditions(glite_jpis_context_t ctx, struct _jpelem__QueryJobs *in) -{ - char **indexed_attrs = NULL, *res; - int i, j, k, ret; - glite_lbu_Statement stmt; - - - if ((ret = glite_jp_db_ExecSQL(ctx->jpctx, - "SELECT name FROM attrs WHERE (indexed=1)", &stmt)) < 0) goto end; - - i = 0; - while ( (ret = glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, &res)) > 0 ) { - if (!(i % INDEXED_STRIDE)) { - indexed_attrs = realloc(indexed_attrs, - ((i / INDEXED_STRIDE + 1) * INDEXED_STRIDE) - * sizeof(*indexed_attrs)); - } - indexed_attrs[i++] = res; - } - if ( ret < 0 ) goto end; - - for (k=0; k < in->__sizeconditions; k++) { - for (j=0; j < i; j++) { - char *attr = GLITE_SECURITY_GSOAP_LIST_GET(in->conditions, k)->attr; - - if (!attr) { - glite_jpis_stack_error(ctx->jpctx, EINVAL, "condition attribute no %d is NULL", j); - ret = 0; - goto end; - } - if (!strcasecmp(attr, GLITE_JP_ATTR_JOBID) || !strcasecmp(attr, indexed_attrs[j])) { - ret = 0; - goto end; - } - } - } - ret = 1; - -end: - for (j=0; j < i; j++) free(indexed_attrs[j]); - free(indexed_attrs); - - return(ret); -} - - -static int checkConditions(glite_jpis_context_t ctx, struct _jpelem__QueryJobs *in) { - int i, j; - char *attr; - - for (i = 0; i < in->__sizeconditions; i++) { - attr = GLITE_SECURITY_GSOAP_LIST_GET(in->conditions, i)->attr; - if (!attr) return 1; - for (j = 0; ctx->conf->attrs[j] && strcasecmp(ctx->conf->attrs[j], attr) != 0; j++); - if (!ctx->conf->attrs[j]) return 1; - } - for (i = 0; i < in->__sizeattributes; i++) { - if ((attr = in->attributes[i]) == NULL) return 1; - for (j = 0; ctx->conf->attrs[j] && strcasecmp(ctx->conf->attrs[j], attr) != 0; j++); - if (!ctx->conf->attrs[j]) return 1; - } - - return 0; -} - - -/* adds attr table name to the list (null terminated) , iff unigue */ -static void add_attr_table(char *new, char ***attr_tables) -{ - int i; - - for (i=0; (*attr_tables && (*attr_tables)[i]); i++) { - if (!strcmp((*attr_tables)[i], new)) return; - } - - *attr_tables = realloc((*attr_tables), (i+2) * sizeof(**attr_tables)); - (*attr_tables)[i] = strdup(new); - (*attr_tables)[i+1] = NULL; -} - -/* transform soap enum queryOp to mysql equivalent */ -static int get_op(const enum jptype__queryOp in, char **out) -{ - char *qop; - glite_jp_queryop_t op; - - glite_jpis_SoapToQueryOp(in, &op); - switch (op) { - case GLITE_JP_QUERYOP_EQUAL: - qop = strdup("="); - break; - case GLITE_JP_QUERYOP_UNEQUAL: - qop = strdup("!="); - break; - case GLITE_JP_QUERYOP_GREATER: - qop = strdup(">"); - break; - case GLITE_JP_QUERYOP_LESS: - qop = strdup("<"); - break; - case GLITE_JP_QUERYOP_WITHIN: - qop = strdup("BETWEEN"); - break; - default: - // unsupported query operator - return(1); - break; - } - - *out = qop; - return(0); -} - - -static char *get_sql_stringvalue(struct jptype__stringOrBlob *value) { - if (!value) return NULL; - if (!GSOAP_ISSTRING(value)) return NULL; - return GSOAP_STRING(value); -} - - -static int get_sql_indexvalue(char **sql, glite_jpis_context_t ctx, struct jptype__indexQuery *condition, struct jptype__stringOrBlob *value) { - glite_jp_attrval_t attr; - - *sql = NULL; - if (!value) return 0; - memset(&attr, 0, sizeof attr); - attr.name = condition->attr; - if (GSOAP_ISSTRING(value)) { - attr.value = GSOAP_STRING(value); - attr.binary = 0; - } else if (GSOAP_ISBLOB(value)) { - attr.value = (char *)GSOAP_BLOB(value)->__ptr; - attr.size = GSOAP_BLOB(value)->__size; - attr.binary = 1; - } else return 0; - glite_jpis_SoapToAttrOrig(condition->origin, &(attr.origin)); - - *sql = glite_jp_attrval_to_db_index(ctx->jpctx, &attr, GLITE_JPIS_INDEX_LENGTH); - return 0; -} - - -static int get_sql_cond(char **sql, const char *attr_md5, enum jptype__queryOp op, char *value, char *value2) { - char *s, *qop, *column; - - *sql = NULL; - if (get_op(op, &qop) != 0) return 0; - if (attr_md5) trio_asprintf(&column, "attr_%|Ss.value", attr_md5); - else asprintf(&column, "jobs.dg_jobid"); - trio_asprintf(sql, "%s %s '%|Ss'", column, qop, value); - free(column); - free(qop); - if (op == jptype__queryOp__WITHIN) { - if (!value) { - free(*sql); - *sql = NULL; - return EINVAL; - } - trio_asprintf(&s, "%s AND '%|Ss'", *sql, value2); - free(*sql); *sql = s; - } - return 0; -} - - -static char *get_sql_or(glite_jpis_context_t ctx, struct jptype__indexQuery *condition, const char *attr_md5) { - struct jptype__indexQueryRecord *record; - char *sql, *cond, *s = NULL, *value, *value2; - int j; - - sql = strdup(""); - for (j=0; j < condition->__sizerecord; j++) { - record = GLITE_SECURITY_GSOAP_LIST_GET(condition->record, j); - if (record->op == jptype__queryOp__EXISTS) { - /* no additional conditions needed when existing is enough */ - } else { - if (strcasecmp(condition->attr, GLITE_JP_ATTR_JOBID) == 0) { - value = get_sql_stringvalue(record->value); - if (!value) goto err; - value2 = get_sql_stringvalue(record->value2); - if (get_sql_cond(&cond, attr_md5, record->op, value, value2) != 0) goto err; - } else { - get_sql_indexvalue(&value, ctx, condition, record->value); - get_sql_indexvalue(&value2, ctx, condition, record->value2); - get_sql_cond(&cond, attr_md5, record->op, value, value2); - free(value); - free(value2); - if (!cond) goto err; - } - trio_asprintf(&s,"%s%s%s", sql, (sql[0] ? " OR " : ""), cond); - free(cond); - free(sql); sql = s; - } - } - - return sql; -err: - free(sql); - free(s); - return NULL; -} - - -/* get all jobids matching the query conditions */ -static int get_jobids(glite_jpis_context_t ctx, struct _jpelem__QueryJobs *in, char ***jobids, char *** ps_list) -{ - char *qa = NULL, *qb = NULL, *qor, *attr_md5, - *qwhere = NULL, *query = NULL, *res[2], - **jids = NULL, **pss = NULL, **attr_tables = NULL; - int i, ret; - glite_lbu_Statement stmt = NULL; - glite_jp_attr_orig_t orig; - - - qwhere = strdup(""); - for (i=0; i < in->__sizeconditions; i++) { - struct jptype__indexQuery *condition; - - condition = GLITE_SECURITY_GSOAP_LIST_GET(in->conditions, i); - - /* attr name */ - if (strcasecmp(condition->attr, GLITE_JP_ATTR_JOBID) == 0) { - /* no subset from attr_ table, used jobs table instead */ - attr_md5 = NULL; - qa = strdup(""); - } else { - attr_md5 = glite_jp_indexdb_attr2id(condition->attr); - add_attr_table(attr_md5, &attr_tables); - - /* origin */ - if (condition->origin) { - glite_jpis_SoapToAttrOrig(condition->origin, &orig); - trio_asprintf(&qb, "attr_%|Ss.origin = %d AND ", attr_md5, orig); - } else - trio_asprintf(&qb, ""); - - /* select given records in attr_ table */ - trio_asprintf(&qa,"%s%sjobs.jobid = attr_%|Ss.jobid", - (i ? "AND " : ""), qb, attr_md5); - - free(qb); - } - - /* inside part of the condition: record list (ORs) */ - if ((qor = get_sql_or(ctx, condition, attr_md5)) == NULL) goto err; - if (qor[0]) { - asprintf(&qb, "%s%s(%s)", qa, qa[0] ? " AND " : "", qor); - free(qa); - qa = qb; - } - free(qor); - - trio_asprintf(&qb,"%s%s%s", qwhere, qa[0] ? " " : "", qa); - free(qa); qwhere = qb; qb = NULL; qa = NULL; - free(attr_md5); - } - - qa = strdup(""); - - for (i=0; (attr_tables && attr_tables[i]); i++) { - trio_asprintf(&qb,"%s, attr_%s", qa, attr_tables[i]); - free(qa); qa = qb; qb = NULL; - } - - if (ctx->conf->no_auth) { - trio_asprintf(&query, "SELECT DISTINCT dg_jobid,ps FROM jobs%s WHERE%s", qa, qwhere); - } - else { - trio_asprintf(&query, "SELECT DISTINCT dg_jobid,ps FROM jobs,users%s WHERE (jobs.ownerid = users.userid AND users.cert_subj='%s') AND%s", qa, ctx->jpctx->peer, qwhere); - } - printf("Incomming QUERY:\n %s\n", query); - free(qwhere); - free(qa); - - if ((ret = glite_jp_db_ExecSQL(ctx->jpctx, query, &stmt)) < 0) goto err; - free(query); - - i = 0; - while ( (ret = glite_jp_db_FetchRow(ctx->jpctx, stmt, sizeof(res)/sizeof(res[0]), NULL, res)) > 0 ) { - if (!(i % JOBIDS_STRIDE)) { - jids = realloc(jids, - ((i / JOBIDS_STRIDE + 1) * JOBIDS_STRIDE + 1) - * sizeof(*jids)); - } - if (!(i % JOBIDS_STRIDE)) { - pss = realloc(pss, - ((i / JOBIDS_STRIDE + 1) * JOBIDS_STRIDE + 1) - * sizeof(*pss)); - } - jids[i] = res[0]; - jids[i+1] = NULL; - pss[i] = res[1]; - pss[i+1] = NULL; - i++; - } - - if ( ret < 0 ) goto err; - - glite_jp_db_FreeStmt(&stmt); - - *jobids = jids; - *ps_list = pss; - - return 0; - -err: - free(query); - for (i=0; (pss && pss[i]); i++) free(pss[i]); - free(pss); - for (i=0; (jids && jids[i]); i++) free(jids[i]); - free(jids); - glite_jp_db_FreeStmt(&stmt); - - return ret; -} - -static void freeAttval_t(glite_jp_attrval_t jav) -{ - free(jav.name); - free(jav.value); - free(jav.origin_detail); -} - - -/* get all values of a given attribute for a job with a given jobid */ -/* all values are soap_malloc-ated, exept of av (due to absence of */ -/* soap_realloc) */ -/* Needs to be copied to list using soap_malloc in calling function! */ - -static int get_attr(struct soap *soap, glite_jpis_context_t ctx, char *jobid, char *attr_name, int *size, struct jptype__attrValue **out) -{ - glite_jp_attrval_t jav; - struct jptype__attrValue *av; - enum jptype__attrOrig *origin; - char *query, *fv, *jobid_md5, *attr_md5; - int i, ret; - glite_lbu_Statement stmt; - - memset(&jav,0,sizeof(jav)); - jobid_md5 = str2md5(jobid); - attr_md5 = glite_jp_indexdb_attr2id(attr_name); - trio_asprintf(&query,"SELECT full_value FROM attr_%|Ss WHERE jobid = \"%s\"", - attr_md5, jobid_md5); - free(attr_md5); - free(jobid_md5); - - if ((ret = glite_jp_db_ExecSQL(ctx->jpctx, query, &stmt)) < 0) { - glite_jpis_stack_error(ctx->jpctx, EIO, "SELECT from attribute '%s' failed", attr_name); - goto err; - } - free(query); - - av = *out; - i = *size; - while ( (ret = glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, &fv)) > 0 ) { - av = realloc(av, (i+1) * sizeof(*av)); - memset(&av[i], 0, sizeof(av[i])); - - memset(&jav,0,sizeof(jav)); - if (glite_jp_attrval_from_db(ctx->jpctx, fv, &jav)) goto err; - av[i].name = soap_strdup(soap, attr_name); - av[i].value = soap_malloc(soap, sizeof(*(av[i].value))); - memset(av[i].value, 0, sizeof(*(av[i].value))); - if (jav.binary) { - GSOAP_SETBLOB(av[i].value, soap_malloc(soap, sizeof(*(GSOAP_BLOB(av[i].value))))); - memset(GSOAP_BLOB(av[i].value), 0, sizeof(*(GSOAP_BLOB(av[i].value)))); - GSOAP_BLOB(av[i].value)->__ptr = soap_malloc(soap, jav.size); - memcpy(GSOAP_BLOB(av[i].value)->__ptr, jav.value, jav.size); - GSOAP_BLOB(av[i].value)->__size = jav.size; - // XXX: id, type, option - how to handle? - } - else { - GSOAP_SETSTRING(av[i].value, jav.value ? soap_strdup(soap, jav.value) : NULL); - } - av[i].timestamp = jav.timestamp; - glite_jpis_AttrOrigToSoap(soap, jav.origin, &origin); - // atribute has always origin - assert(origin != GLITE_JP_ATTR_ORIG_ANY); - av[i].origin = *origin; soap_dealloc(soap, origin); - if (jav.origin_detail) av[i].originDetail = soap_strdup(soap, jav.origin_detail); - - i++; - freeAttval_t(jav); - } - if (ret < 0) goto err; - - glite_jp_db_FreeStmt(&stmt); - *size = i; - *out = av; - - return 0; - -err: - glite_jp_db_FreeStmt(&stmt); - freeAttval_t(jav); - return 1; -} - - -/* return owner of job record */ -static int get_owner(glite_jpis_context_t ctx, char *jobid, char **owner) -{ - char *ownerid = NULL, *jobid_md5, *query, *fv = NULL; - glite_lbu_Statement stmt; - - - /* get ownerid correspondig to jobid */ - jobid_md5 = str2md5(jobid); - trio_asprintf(&query,"SELECT ownerid FROM jobs WHERE jobid = \"%s\"", - jobid_md5); - free(jobid_md5); - - if ((glite_jp_db_ExecSQL(ctx->jpctx, query, &stmt)) < 0) goto err; - free(query); - - if (glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, &ownerid) <= 0 ) goto err; - - /* DB consistency check - only one record per jobid ! */ - assert (glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, &fv) <=0); free(fv); - - - /* get cert_subj corresponding to ownerid */ - trio_asprintf(&query,"SELECT cert_subj FROM users WHERE userid = \"%s\"", - ownerid); - - if ((glite_jp_db_ExecSQL(ctx->jpctx, query, &stmt)) < 0) goto err; - free(query); - - if (glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, owner) <= 0 ) goto err; - - /* DB consistency check - only one record per userid ! */ - assert (glite_jp_db_FetchRow(ctx->jpctx, stmt, 1, NULL, &fv) <=0); free(fv); - - - return 0; -err: - free(ownerid); - free(query); - return 1; -} - -/* fills structure jobRecord for a given jobid*/ -static int get_attrs(struct soap *soap, glite_jpis_context_t ctx, char *jobid, struct _jpelem__QueryJobs *in, struct jptype__jobRecord *out) -{ - struct jptype__attrValue *av = NULL; - int j, size = 0; - - - assert(out); - memset(out, 0, sizeof(*out)); - - /* jobid */ - out->jobid = soap_strdup(soap, jobid); - - /* sizeattributes & attributes */ - size = 0; - for (j=0; j < in->__sizeattributes; j++) - if (get_attr(soap, ctx, jobid, in->attributes[j], &size, &av) ) goto err; - if ( get_owner(ctx, jobid, &(out->owner)) ) goto err; - - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, out, attributes, struct jptype__attrValue, size); - for (j = 0; j < size; j++) - memcpy(GLITE_SECURITY_GSOAP_LIST_GET(out->attributes, j), &av[j], sizeof(av[0])); - free(av); - - return 0; - -err: - return 1; -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__QueryJobs( - struct soap *soap, - struct _jpelem__QueryJobs *in, - struct _jpelem__QueryJobsResponse *out) -{ - CONTEXT_FROM_SOAP(soap, ctx); - struct jptype__jobRecord *jr; - - char **jobids = NULL, **ps_list = NULL; - int i, size, err; - - - puts(__FUNCTION__); - glite_jp_clear_error(ctx->jpctx); - memset(out, 0, sizeof(*out)); - - /* test whether there is any indexed attribudes in the condition */ - if ( checkIndexedConditions(ctx, in) ) { - glite_jpis_stack_error(ctx->jpctx, EINVAL, "No indexed attribute in query"); - goto fail; - } - - /* test whether there is known attribudes in the condition */ - if ( checkConditions(ctx, in) ) { - glite_jpis_stack_error(ctx->jpctx, EINVAL, "Unknown attribute in query"); - goto fail; - } - - /* get all jobids matching the conditions */ - if ( (err = get_jobids(ctx, in, &jobids, &ps_list)) != 0 ) { - glite_jpis_stack_error(ctx->jpctx, err, "Error getting jobs"); - goto fail; - } - - /* get all requested attributes for matching jobids */ - for (i=0; (jobids && jobids[i]); i++); - size = i; - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, out, jobs, struct jptype__jobRecord, size); - for (i=0; (jobids && jobids[i]); i++) { - jr = GLITE_SECURITY_GSOAP_LIST_GET(out->jobs, i); - if ( (err = get_attrs(soap, ctx, jobids[i], in, jr)) != 0 ) { - glite_jpis_stack_error(ctx->jpctx, err, "Error getting attributes of the job '%s'", jobids[i]); - goto fail; - } - - // XXX: in prototype we return only first value of PS URL - // in future database should contain one more table with URLs - jr->__sizeprimaryStorage = 1; - jr->primaryStorage = soap_malloc(soap, sizeof(*(jr->primaryStorage))); - jr->primaryStorage[0] = soap_strdup(soap, ps_list[i]); - free(ps_list[i]); - free(jobids[i]); - } - free(jobids); - free(ps_list); - - return SOAP_OK; -fail: - glite_jp_server_err2fault(ctx->jpctx, soap); - return SOAP_ERR; -} - - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__AddFeed( - struct soap *soap UNUSED, - struct _jpelem__AddFeed *in UNUSED, - struct _jpelem__AddFeedResponse *out UNUSED) -{ - // XXX: test client in examples/jpis-test - // sends to this function some data for testing - puts(__FUNCTION__); - return SOAP_OK; -} - - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__GetFeedIDs( - struct soap *soap UNUSED, - struct _jpelem__GetFeedIDs *in UNUSED, - struct _jpelem__GetFeedIDsResponse *out UNUSED) -{ - // XXX: test client in examples/jpis-test - // sends to this function some data for testing - puts(__FUNCTION__); - return SOAP_OK; -} - - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__DeleteFeed( - struct soap *soap UNUSED, - struct _jpelem__DeleteFeed *in UNUSED, - struct _jpelem__DeleteFeedResponse *out UNUSED) -{ - // XXX: test client in examples/jpis-test - // sends to this function some data for testing - puts(__FUNCTION__); - return SOAP_OK; -} - - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__ServerConfiguration( - struct soap *soap UNUSED, - struct _jpelem__ServerConfiguration *in UNUSED, - struct _jpelem__ServerConfigurationResponse *out UNUSED) -{ - // empty, just for deserializer generation - puts(__FUNCTION__); - return SOAP_OK; -} diff --git a/org.glite.jp.index/src/soap_ps_calls.c b/org.glite.jp.index/src/soap_ps_calls.c deleted file mode 100644 index a9a125e..0000000 --- a/org.glite.jp.index/src/soap_ps_calls.c +++ /dev/null @@ -1,197 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include - -#include "soap_version.h" -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/security/glite_gss.h" -#include "glite/security/glite_gsplugin.h" -#include "glite/security/glite_gscompat.h" - -#include "jp_H.h" - -#include "conf.h" -#include "db_ops.h" -#include "ws_ps_typeref.h" -#include "context.h" -#include "common.h" - -#include "stdsoap2.h" - - -extern struct Namespace jp__namespaces[]; - - -/*------------------*/ -/* Helper functions */ -/*------------------*/ - -#define dprintf(FMT, ARGS...) do {fprintf(stderr, "[%d] %s: ", getpid(), __FUNCTION__); fprintf(stderr, FMT, ##ARGS); } while(0); -#include "glite/jp/ws_fault.c" -#define check_fault(SOAP, ERR) glite_jp_clientCheckFault((SOAP), (ERR), NULL, 0) - - -/*----------------------*/ -/* PS WSDL client calls */ -/*----------------------*/ - -static int find_dest_index(glite_jp_is_conf *conf, long int uniqueid) -{ - int i; - - for (i=0; conf->feeds[i]; i++) - if (conf->feeds[i]->uniqueid == uniqueid) return(i); - - return -1; -} - - -static int refresh_gsoap(glite_jpis_context_t ctx, struct soap *soap) { - edg_wll_GssCred cred; - edg_wll_GssStatus gss_code; - char *et; - // preventive very long timeout - static const struct timeval to = {tv_sec: 7200, tv_usec: 0}; - glite_gsplugin_Context plugin_ctx; - - if (edg_wll_gss_acquire_cred_gsi(ctx->conf->server_cert, ctx->conf->server_key, &cred, &gss_code) != 0) { - edg_wll_gss_get_error(&gss_code,"",&et); - glite_jpis_stack_error(ctx->jpctx, EINVAL, "can't refresh certificates (%s)", et); - free(et); - return EINVAL; - //printf("[%d] %s: %s\n", getpid(), __FUNCTION__, err.desc); - } - - plugin_ctx = glite_gsplugin_get_context(soap); - glite_gsplugin_set_timeout(plugin_ctx, &to); - glite_gsplugin_use_credential(plugin_ctx, cred); - - return 0; -} - - -// call PS FeedIndex for a given destination -int MyFeedIndex(struct soap *soap, glite_jpis_context_t ctx, long int uniqueid, const char *dest) -{ - struct _jpelem__FeedIndex in; - struct _jpelem__FeedIndexResponse out; -// struct jptype__primaryQuery query; -// struct jptype__stringOrBlob value; -// struct xsd__base64Binary blob; - int i, dest_index, status; - glite_jp_is_conf *conf = ctx->conf; - - lprintf("(%ld) for %s called\n", uniqueid, dest); - - if (refresh_gsoap(ctx, soap) != 0) - return glite_jpis_stack_error(ctx->jpctx, EINVAL, "can't refresh credentials"); - - memset(&in, 0, sizeof(in)); - - for (i=0; conf->attrs[i]; i++) ; - in.__sizeattributes = i; - in.attributes = conf->attrs; - - if ((dest_index = find_dest_index(conf, uniqueid)) < 0) - return glite_jpis_stack_error(ctx->jpctx, EINVAL, "internal error (feed index %ld not found)", uniqueid); - - soap_begin(soap); - for (i=0; conf->feeds[dest_index]->query[i].attr; i++); - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, &in, conditions, struct jptype__primaryQuery, i); - - for (i=0; conf->feeds[dest_index]->query[i].attr; i++) { - if (glite_jpis_QueryCondToSoap(soap, &conf->feeds[dest_index]->query[i], - GLITE_SECURITY_GSOAP_LIST_GET(in.conditions, i)) != SOAP_OK) { - soap_end(soap); - return glite_jpis_stack_error(ctx->jpctx, EINVAL, "error during conds conversion"); - } - } - - in.history = conf->feeds[dest_index]->history; - in.continuous = conf->feeds[dest_index]->continuous; - in.destination = ctx->hname; - lprintf("(%ld) destination IS: '%s'\n", uniqueid, ctx->hname); - - if (check_fault(soap,soap_call___jpsrv__FeedIndex(soap,dest,"", &in, &out)) != 0) { - fprintf(stderr, "\n"); - glite_jpis_unlockFeed(ctx, uniqueid); - glite_jpis_stack_error(ctx->jpctx, EIO, "soap_call___jpsrv__FeedIndex() returned error %d", soap->error); - soap_end(soap); - return EIO; - } - else { - status = (conf->feeds[dest_index]->history ? GLITE_JP_IS_STATE_HIST : 0) | (conf->feeds[dest_index]->continuous ? GLITE_JP_IS_STATE_CONT : 0); - lprintf("(%ld) FeedId: %s\n", uniqueid, out.feedId); - lprintf("(%ld) Expires: %s", uniqueid, ctime(&out.feedExpires)); - glite_jpis_initFeed(ctx, uniqueid, out.feedId, time(NULL) + (out.feedExpires - time(NULL)) / 2, status); - glite_jpis_unlockFeed(ctx, uniqueid); - } - - soap_end(soap); - - return 0; -} - - -int MyFeedRefresh(struct soap *soap, glite_jpis_context_t ctx, long int uniqueid, const char *dest, int status, const char *feedid) -{ - struct _jpelem__FeedIndexRefresh in; - struct _jpelem__FeedIndexRefreshResponse out; - - lprintf("(%ld) for %s called, status = %d\n", uniqueid, feedid, status); - - if (refresh_gsoap(ctx, soap) != 0) - return glite_jpis_stack_error(ctx->jpctx, EINVAL, "can't refresh credentials"); - - soap_begin(soap); - memset(&in, 0, sizeof(in)); - in.feedId = soap_strdup(soap, feedid); - if (check_fault(soap,soap_call___jpsrv__FeedIndexRefresh(soap,dest,"", &in, &out)) != 0) { - fprintf(stderr, "\n"); - glite_jpis_unlockFeed(ctx, uniqueid); - glite_jpis_stack_error(ctx->jpctx, EIO, "soap_call___jpsrv__FeedRefresh() returned error %d", soap->error); - soap_end(soap); - return EIO; - } - else { - status &= (~GLITE_JP_IS_STATE_ERROR); - lprintf("(%ld) FeedId: %s\n", uniqueid, feedid); - lprintf("(%ld) Expires: %s", uniqueid, ctime(&out.feedExpires)); - glite_jpis_initFeed(ctx, uniqueid, feedid, time(NULL) + (out.feedExpires - time(NULL)) / 2, status); - glite_jpis_unlockFeed(ctx, uniqueid); - } - - soap_end(soap); - return 0; -} - - -int __jpsrv__RegisterJob(struct soap* soap UNUSED, struct _jpelem__RegisterJob *jpelem__RegisterJob UNUSED, struct _jpelem__RegisterJobResponse *jpelem__RegisterJobResponse UNUSED) { return 0; } -int __jpsrv__StartUpload(struct soap* soap UNUSED, struct _jpelem__StartUpload *jpelem__StartUpload UNUSED, struct _jpelem__StartUploadResponse *jpelem__StartUploadResponse UNUSED) { return 0; } -int __jpsrv__CommitUpload(struct soap* soap UNUSED, struct _jpelem__CommitUpload *jpelem__CommitUpload UNUSED, struct _jpelem__CommitUploadResponse *jpelem__CommitUploadResponse UNUSED) { return 0; } -int __jpsrv__RecordTag(struct soap* soap UNUSED, struct _jpelem__RecordTag *jpelem__RecordTag UNUSED, struct _jpelem__RecordTagResponse *jpelem__RecordTagResponse UNUSED) { return 0; } -int __jpsrv__FeedIndex(struct soap* soap UNUSED, struct _jpelem__FeedIndex *jpelem__FeedIndex UNUSED, struct _jpelem__FeedIndexResponse *jpelem__FeedIndexResponse UNUSED) { return 0; } -int __jpsrv__FeedIndexRefresh(struct soap* soap UNUSED, struct _jpelem__FeedIndexRefresh *jpelem__FeedIndexRefresh UNUSED, struct _jpelem__FeedIndexRefreshResponse *jpelem__FeedIndexRefreshResponse UNUSED) { return 0; } -int __jpsrv__GetJobFiles(struct soap* soap UNUSED, struct _jpelem__GetJobFiles *jpelem__GetJobFiles UNUSED, struct _jpelem__GetJobFilesResponse *jpelem__GetJobFilesResponse UNUSED) { return 0; } -int __jpsrv__GetJobAttributes(struct soap* soap UNUSED, struct _jpelem__GetJobAttributes *jpelem__GetJobAttributes UNUSED, struct _jpelem__GetJobAttributesResponse *jpelem__GetJobAttributesResponse UNUSED) { return 0; } - -int __jpsrv__RecordMultiTags(struct soap* soap UNUSED, struct _jpelem__RecordMultiTags *jpelem__RecordMultiTags UNUSED, struct _jpelem__RecordMultiTagsResponse *jpelem__RecordMultiTagsResponse UNUSED) { return 0; } diff --git a/org.glite.jp.index/src/soap_ps_calls.h b/org.glite.jp.index/src/soap_ps_calls.h deleted file mode 100644 index 8ec2b18..0000000 --- a/org.glite.jp.index/src/soap_ps_calls.h +++ /dev/null @@ -1,29 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#ifndef _SOAP_PS_CALLS_H -#define _SOAP_PS_CALLS_H - -#include "context.h" -#include "conf.h" - -int MyFeedIndex(struct soap *soap, glite_jpis_context_t ctx, long int uniqueid, const char *dest); -int MyFeedRefresh(struct soap *soap, glite_jpis_context_t ctx, long int uniqueid, const char *dest, int status, const char *feedid); - -#endif diff --git a/org.glite.jp.index/src/type_plugin.c b/org.glite.jp.index/src/type_plugin.c deleted file mode 100644 index cbf42d5..0000000 --- a/org.glite.jp.index/src/type_plugin.c +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include "glite/jp/type_plugin.h" - -int glite_jp_typeplugin_load(glite_jp_context_t ctx,const char *so){ -/* XXX: not stored but we never dlclose() yet */ - void *dl_handle = dlopen(so,RTLD_NOW); - - glite_jp_error_t err; - const char *e; - glite_jp_tplug_data_t *data; - int i; - - glite_jp_tplug_init_t init; - memset(&err,0,sizeof err); - - if (!dl_handle) { - err.source = "dlopen()"; - err.code = EINVAL; - err.desc = dlerror(); - return glite_jp_stack_error(ctx,&err); - } - - dlerror(); - init = dlsym(dl_handle,"init"); - e = dlerror(); - if (e) { - char buf[300]; - snprintf(buf,sizeof buf,"dlsym(\"%s\",\"init\")",so); - buf[299] = 0; - err.source = buf; - err.code = ENOENT; - err.desc = e; - return glite_jp_stack_error(ctx,&err); - } - - data = calloc(1,sizeof *data); - - if (init(ctx, NULL, data)) return -1; - - i = 0; - if (ctx->type_plugins) for (i=0; ctx->type_plugins[i]; i++); - ctx->type_plugins = realloc(ctx->type_plugins, - (i+2) * sizeof *ctx->type_plugins); - ctx->type_plugins[i] = data; - ctx->type_plugins[i+1] = NULL; - - /* TODO: check consistency of uri+class pairs wrt. previous plugins */ - - return 0; -} - diff --git a/org.glite.jp.index/src/typemap.dat b/org.glite.jp.index/src/typemap.dat deleted file mode 100644 index e86b875..0000000 --- a/org.glite.jp.index/src/typemap.dat +++ /dev/null @@ -1,4 +0,0 @@ -jpsrv = http://glite.org/wsdl/services/jp -jptype = http://glite.org/wsdl/types/jp -jpelem = http://glite.org/wsdl/elements/jp -jpisclient = http://glite.org/xsd/types/jpisclient diff --git a/org.glite.jp.index/src/ws_is_typeref.c b/org.glite.jp.index/src/ws_is_typeref.c deleted file mode 100644 index 3319934..0000000 --- a/org.glite.jp.index/src/ws_is_typeref.c +++ /dev/null @@ -1,231 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include - -#include -#include "soap_version.h" - -#include "jp_H.h" -#include "ws_typemap.h" -#include -#include "ws_is_typeref.h" - -#include "glite/jp/ws_fault.c" - - -void glite_jpis_SoapToQueryOp(const enum jptype__queryOp in, glite_jp_queryop_t *out) -{ - switch ( in ) - { - case EQUAL: *out = GLITE_JP_QUERYOP_EQUAL; break; - case UNEQUAL: *out = GLITE_JP_QUERYOP_UNEQUAL; break; - case LESS: *out = GLITE_JP_QUERYOP_LESS; break; - case GREATER: *out = GLITE_JP_QUERYOP_GREATER; break; - case WITHIN: *out = GLITE_JP_QUERYOP_WITHIN; break; - case EXISTS: *out = GLITE_JP_QUERYOP_EXISTS; break; - default: assert(0); break; - } -} - -void glite_jpis_SoapToAttrOrig(const enum jptype__attrOrig *in, glite_jp_attr_orig_t *out) -{ - assert(out); - - if (!in) { - *out = GLITE_JP_ATTR_ORIG_ANY; - return; - } - - switch ( *in ) - { - case SYSTEM: *out = GLITE_JP_ATTR_ORIG_SYSTEM; break; - case USER: *out = GLITE_JP_ATTR_ORIG_USER; break; - case FILE_: *out = GLITE_JP_ATTR_ORIG_FILE; break; - default: assert(0); break; - } -} - -static int SoapToQueryRecordVal( - struct jptype__stringOrBlob *in, - int *binary, - size_t *size, - char **value) -{ - - assert(in); - if (GSOAP_ISSTRING(in)) { - *binary = 0; - *size = 0; - *value = strdup(GSOAP_STRING(in)); - - return 0; - } - else if (GSOAP_ISBLOB(in)) { - *binary = 1; - *size = GSOAP_BLOB(in)->__size; - memcpy(*value, GSOAP_BLOB(in)->__ptr, GSOAP_BLOB(in)->__size); - // XXX how to handle id, type, option? - - return 0; - } - else - // malformed value - return 1; -} - - -#if 0 -static int SoapToQueryCond( - struct jptype__indexQuery *in, - glite_jp_query_rec_t **out) -{ - glite_jp_query_rec_t *qr; - int i; - struct jptype__indexQueryRecord *record; - - assert(in); assert(out); - qr = calloc(in->__sizerecord + 1, sizeof(*qr)); - - for (i=0; i < in->__sizerecord; i++) { - record = GLITE_SECURITY_GSOAP_LIST_GET(in->record, i); - qr[i].attr = strdup(in->attr); - glite_jpis_SoapToQueryOp(record->op, &(qr[i].op)); - - switch (qr[i].op) { - case GLITE_JP_QUERYOP_EXISTS: - break; - - case GLITE_JP_QUERYOP_WITHIN: - SoapToQueryRecordVal(record->value2, &(qr[i].binary), - &(qr[i].size2), &(qr[i].value2)); - // fall through - default: - if ( SoapToQueryRecordVal(record->value, &(qr[i].binary), - &(qr[i].size), &(qr[i].value)) ) { - *out = NULL; - return 1; - } - break; - } - - glite_jpis_SoapToAttrOrig(in->origin, &(qr[i].origin) ); - } - - *out = qr; - - return 0; -} - -/** - * Translate JP index query conditions from soap to C query_rec - * - * \param OUT array of glite_jp_query_rec_t query records - */ -int glite_jpis_SoapToQueryConds( - int size, - struct jptype__indexQuery **in, - glite_jp_query_rec_t ***out) -{ - glite_jp_query_rec_t **qr; - int i; - - assert(in); assert(out); - qr = calloc(size+1, sizeof(*qr)); - - for (i=0; iattr); assert(out); - qr = out; - - qr[0].attr = strdup(in->attr); - glite_jpis_SoapToQueryOp(in->op, &(qr[0].op)); - - switch (qr[0].op) { - case GLITE_JP_QUERYOP_EXISTS: - break; - - case GLITE_JP_QUERYOP_WITHIN: - SoapToQueryRecordVal(in->value2, &(qr[0].binary), - &(qr[0].size2), &(qr[0].value2)); - // fall through - default: - if ( SoapToQueryRecordVal(in->value, &(qr[0].binary), - &(qr[0].size), &(qr[0].value)) ) { - return 1; - } - break; - } - - glite_jpis_SoapToAttrOrig(in->origin, &(qr[0].origin) ); - - return 0; -} - - - -/** - * Translate JP primary query conditions from soap to C query_rec - * - * \param IN Soap structure - * \param OUT array of glite_jp_query_rec_t query records - */ -int glite_jpis_SoapToPrimaryQueryConds( - int size, - GLITE_SECURITY_GSOAP_LIST_TYPE(jptype, primaryQuery) in, - glite_jp_query_rec_t **out) -{ - glite_jp_query_rec_t *qr; - int i; - - assert(in || !size); assert(out); - qr = calloc(size+1, sizeof(*qr)); - - for (i=0; i -#include -#include -#include - -#include - -#include "jp_H.h" -#include "ws_typemap.h" -#include "ws_ps_typeref.h" -#include "glite/jp/ws_fault.c" - - -static void QueryOpToSoap(const glite_jp_queryop_t in, enum jptype__queryOp *out) -{ - switch ( in ) - { - case GLITE_JP_QUERYOP_EQUAL: *out = EQUAL; break; - case GLITE_JP_QUERYOP_UNEQUAL: *out = UNEQUAL; break; - case GLITE_JP_QUERYOP_LESS: *out = LESS; break; - case GLITE_JP_QUERYOP_GREATER: *out = GREATER; break; - case GLITE_JP_QUERYOP_WITHIN: *out = WITHIN; break; - case GLITE_JP_QUERYOP_EXISTS: *out = EXISTS; break; - default: assert(0); break; - } -} - -void glite_jpis_AttrOrigToSoap(struct soap *soap, const glite_jp_attr_orig_t in, enum jptype__attrOrig **out) -{ - enum jptype__attrOrig *o = soap_malloc(soap, sizeof(*o)); - - switch ( in ) - { - case GLITE_JP_ATTR_ORIG_ANY: o = NULL; break; - case GLITE_JP_ATTR_ORIG_SYSTEM: *o = SYSTEM; break; - case GLITE_JP_ATTR_ORIG_USER: *o = USER; break; - case GLITE_JP_ATTR_ORIG_FILE: *o = FILE_; break; - default: assert(0); break; - } - - *out = o; -} - -static int QueryRecordValToSoap( - struct soap *soap, - int binary, - size_t size, - char *in, - struct jptype__stringOrBlob **out) -{ - struct jptype__stringOrBlob *val; - - - assert(out); - if ( !(val = soap_malloc(soap, sizeof(*val))) ) return SOAP_FAULT; - memset(val, 0, sizeof(*val) ); - - if (binary) { - GSOAP_SETBLOB(val, soap_malloc(soap, sizeof(*GSOAP_BLOB(val)))); - if ( !GSOAP_BLOB(val) ) return SOAP_FAULT; - GSOAP_BLOB(val)->__size = size; - if ( !(GSOAP_BLOB(val)->__ptr = soap_malloc(soap, GSOAP_BLOB(val)->__size)) ) return SOAP_FAULT; - memcpy(GSOAP_BLOB(val)->__ptr, in, GSOAP_BLOB(val)->__size); - // XXX how to handle id, type, option? - } - else { - GSOAP_SETSTRING(val, soap_strdup(soap, in)); - if ( !(GSOAP_STRING(val) ) ) return SOAP_FAULT; - } - - *out = val; - - return SOAP_OK; -} - -/** - * Translate JP query condition from C query_rec to Soap - * - * \param IN in glite_jp_query_rec_t query record - * \param OUT Soap structure - */ -int glite_jpis_QueryCondToSoap( - struct soap *soap, - glite_jp_query_rec_t *in, - struct jptype__primaryQuery *out) -{ - struct jptype__primaryQuery *qr; - - assert(in); assert(out); - qr = out; - memset(qr, 0, sizeof(*qr)); - - if ( !(qr->attr = soap_strdup(soap, in->attr)) ) return SOAP_FAULT; - QueryOpToSoap(in->op, &(qr->op)); - glite_jpis_AttrOrigToSoap(soap, in->origin, &(qr->origin)); - - switch ( in->op ) { - case GLITE_JP_QUERYOP_WITHIN: - if (QueryRecordValToSoap(soap, in->binary, in->size2, in->value2, &qr->value2)) - return SOAP_FAULT; - case GLITE_JP_QUERYOP_EQUAL: - case GLITE_JP_QUERYOP_UNEQUAL: - case GLITE_JP_QUERYOP_LESS: - case GLITE_JP_QUERYOP_GREATER: - if (QueryRecordValToSoap(soap, in->binary, in->size, in->value, &qr->value)) - return SOAP_FAULT; - case GLITE_JP_QUERYOP_EXISTS: - break; - default: - assert(0); // unknown or undefined operation - break; - } - - *out = *qr; - - return SOAP_OK; -} - -static void SoapToAttrOrig(glite_jp_attr_orig_t *out, const enum jptype__attrOrig in) -{ - switch ( in ) - { - case jptype__attrOrig__SYSTEM: *out = GLITE_JP_ATTR_ORIG_SYSTEM; break; - case jptype__attrOrig__USER: *out = GLITE_JP_ATTR_ORIG_USER; break; - case jptype__attrOrig__FILE_: *out = GLITE_JP_ATTR_ORIG_FILE; break; - default: assert(0); break; - } -} - -void glite_jpis_SoapToAttrVal(glite_jp_attrval_t *av, const struct jptype__attrValue *attr) { - memset(av, 0, sizeof(*av)); - av->name = attr->name; - av->binary = GSOAP_ISBLOB(attr->value); - if (av->binary) { - av->value = GSOAP_BLOB(attr->value)->__ptr; - av->size = GSOAP_BLOB(attr->value)->__size ; - } else { - av->size = -1; - av->value = GSOAP_STRING(attr->value); - } - SoapToAttrOrig(&av->origin, attr->origin); - av->origin_detail = attr->originDetail; - av->timestamp = attr->timestamp; -} diff --git a/org.glite.jp.index/src/ws_ps_typeref.h b/org.glite.jp.index/src/ws_ps_typeref.h deleted file mode 100644 index 04165d0..0000000 --- a/org.glite.jp.index/src/ws_ps_typeref.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JPIS_TYPEREF_H -#define GLITE_JPIS_TYPEREF_H - -int glite_jpis_QueryCondToSoap(struct soap *soap, glite_jp_query_rec_t *in, struct jptype__primaryQuery *out); - -void glite_jpis_AttrOrigToSoap(struct soap *soap, const glite_jp_attr_orig_t in, enum jptype__attrOrig **out); - -void glite_jpis_SoapToAttrVal(glite_jp_attrval_t *av, const struct jptype__attrValue *attr); - -#endif diff --git a/org.glite.jp.index/src/ws_typemap.h b/org.glite.jp.index/src/ws_typemap.h deleted file mode 100644 index 39d9232..0000000 --- a/org.glite.jp.index/src/ws_typemap.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// XXX: may be glued with org.glite.jp.primary/src/jptype_map.h? - -#include "soap_version.h" - -#if GSOAP_VERSION >= 20700 - -#define SYSTEM jptype__attrOrig__SYSTEM -#define USER jptype__attrOrig__USER -#define FILE_ jptype__attrOrig__FILE_ - -#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 -#define EXISTS jptype__queryOp__EXISTS - -#else - -#define __jpsrv__UpdateJobs __ns1__UpdateJobs -#define __jpsrv__QueryJobs __ns1__QueryJobs -#define __jpsrv__AddFeed __ns1__AddFeed -#define __jpsrv__GetFeeds __ns1__getFeedIDs -#define __jpsrv__DeleteFeed __ns1__DeleteFeed -#define __jpsrv__ServerConfiguration __ns1__ServerConfiguration - -#endif - diff --git a/org.glite.jp.primary/.cvsignore b/org.glite.jp.primary/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp.primary/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp.primary/Makefile b/org.glite.jp.primary/Makefile deleted file mode 100644 index 6c53b25..0000000 --- a/org.glite.jp.primary/Makefile +++ /dev/null @@ -1,223 +0,0 @@ -# defaults -top_srcdir=.. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -globalprefix=glite -jpprefix=jp -package=glite-jp-primary -version=0.0.0 -PREFIX=/opt/glite - -glite_location=/opt/glite -nothrflavour=gcc32 -thrflavour=gcc32pthr -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 - -archlib:=lib -host_cpu:=${shell uname -m} -ifeq (${host_cpu},x86_64) - archlib:=lib64 -endif - -archlib:=lib -host_cpu:=${shell uname -m} -ifeq (${host_cpu},x86_64) - archlib:=lib64 -endif - - -ifneq (${classads_prefix},/usr) - classadslib := -L${classads_prefix}/${archlib} -L${classads_prefix}/lib -lclassad -endif - -CLASSADPLUGIN_LIBS:= ${classadslib} -lstdc++ - -CLASSADPLUGIN_LOBJS:= classad_plugin.lo - -GLOBUS_CFLAGS:=-I${globus_prefix}/include/${nothrflavour} - -DEBUG:=-g -O0 -DDEBUG - -CFLAGS:=${DEBUG} -I. -I${top_srcdir}/src -I${gsoap_prefix}/include -I${gsoap_prefix} -I${stagedir}/include -I${classads_prefix}/include -I${classads_prefix}/include/classad -I${libtar_prefix}/include ${GLOBUS_CFLAGS} -# 3.1 CFLAGS:=${DEBUG} -I. -I${top_srcdir}/interface -I${top_srcdir}/src -I${gsoap_prefix}/include -I${gsoap_prefix} -I${stagedir}/include ${GLOBUS_CFLAGS} -I${mysql_prefix}/include -I${mysql_prefix}/include/mysql -I${classads_prefix}/include -I${libtar_prefix}/include - -LDFLAGS:=-L${stagedir}/lib - -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -LTCOMPILE:=libtool --mode=compile ${CC} ${CFLAGS} -SOLINK:=libtool --mode=link ${CC} -module ${LDFLAGS} -rpath ${stagedir}/lib -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install - -daemon:=glite-jp-primarystoraged -example:=jpps-test dag-deps -ps_prefix:=jpps_ -is_prefix:=jpis_ -sample_jobs:=sample_job_aborted sample_job_cleared sample_job_tagged_done sample_job_waiting - -plugins:=glite-jp-ftpdauth.la glite-jp-classad.la glite-jp-sandbox.la glite-jp-callouts_${nothrflavour}.la - -SRCS:= bones_server.c soap_ops.c \ - new_ftp_backend.c file_plugin.c \ - feed.c authz.c attrs.c \ - tags.c\ - is_client.c \ - soap_switch.c - -# ${ps_prefix}ServerLib.c \ -# ${is_prefix}ClientLib.c jpps_C.c - -TEST_SRCS:=jpps-test.c ${ps_prefix}C.c ${ps_prefix}Client.c -DAG_SRCS:=dag-deps.c ${ps_prefix}C.c ${ps_prefix}Client.c - -gsoap_bin_prefix:=${shell if [ -x ${gsoap_prefix}/bin/soapcpp2 ]; then echo ${gsoap_prefix}/bin; else echo ${gsoap_prefix}; fi } - -OBJS:=${SRCS:.c=.o} -TEST_OBJS:=${TEST_SRCS:.c=.o} -DAG_OBJS:=${DAG_SRCS:.c=.o} - -dotless_gsoap_ver:=${shell echo ${gsoap_default_version} | tr -d . } -ifeq ($(shell test -f ${stagedir}/lib/libglite_security_gsoap_plugin_${dotless_gsoap_ver}_${nothrflavour}_c.so && echo ok),ok) - langflavour:=_c -endif -COMMONLIB:=-lglite_jp_common_${nothrflavour} -SRVCOMMONLIB:=-lglite_jp_server_common -BONESLIB:=-lglite_lbu_server_bones -GSOAPLIB:=-L${stagedir}/lib -lglite_security_gsoap_plugin_${dotless_gsoap_ver}_${nothrflavour}${langflavour} -TRIOLIB:=-lglite_lbu_trio -LIBTARLIB:=-L${libtar_prefix}/lib -ltar -GSSLIB:=-lglite_security_gss_${nothrflavour} - -default all: compile - -compile: ${daemon} ${example} ${plugins} - -${daemon}: ${OBJS} - ${LINK} -o $@ -export-dynamic ${OBJS} ${BONESLIB} ${TRIOLIB} ${COMMONLIB} ${GSOAPLIB} ${GSSLIB} ${SRVCOMMONLIB} - -jpps-test: ${TEST_OBJS} - ${LINK} -o $@ ${TEST_OBJS} ${GSOAPLIB} - -dag-deps: ${DAG_OBJS} - ${LINKXX} -o $@ ${DAG_OBJS} ${classadslib} ${GSOAPLIB} - -JobProvenancePS.xh: %.xh: %.wsdl JobProvenanceTypes.wsdl typemap.dat - cp ${stagedir}/interface/JobProvenanceTypes.wsdl . - ${gsoap_bin_prefix}/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $< - rm -f JobProvenanceTypes.wsdl - -JobProvenanceIS.xh: %.xh: %.wsdl JobProvenanceTypes.wsdl typemap.dat - cp ${stagedir}/interface/JobProvenanceTypes.wsdl . - ${gsoap_bin_prefix}/wsdl2h -t ${top_srcdir}/src/typemap.dat -c -o $@ $< - rm -f JobProvenanceTypes.wsdl - -glite-jp-classad.la: ${CLASSADPLUGIN_LOBJS} - ${SOLINK} -o $@ ${CLASSADPLUGIN_LOBJS} ${CLASSADPLUGIN_LIBS} - -${ps_prefix}Client.c ${ps_prefix}ClientLib.c \ -${ps_prefix}Server.c ${ps_prefix}ServerLib.c \ -${ps_prefix}C.c ${ps_prefix}H.h: JobProvenancePS.xh - ${gsoap_bin_prefix}/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_bin_prefix}/soapcpp2 -n -w -c -p ${is_prefix} JobProvenanceIS.xh - -soap_ops.o: ${ps_prefix}ServerLib.c soap_util.c soap_env_ctx.c soap_env_ctx.h - -is_client.o: ${is_prefix}ClientLib.c soap_util.c soap_env_ctx.c soap_env_ctx.h - -env_C.c env_Server.c: - touch env.xh - ${gsoap_bin_prefix}/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 -# - - -bones_server.o simple_server.o: ${is_prefix}H.h ${ps_prefix}H.h - -check: - -echo nothing yet - -doc: - -stage: compile - ${MAKE} PREFIX=${stagedir} DOSTAGE=yes install - -install: - -mkdir -p ${PREFIX}/bin ${PREFIX}/etc ${PREFIX}/examples ${PREFIX}/etc/init.d ${PREFIX}/lib - ${INSTALL} -m 755 ${daemon} ${PREFIX}/bin - ${INSTALL} -m 755 jpps-test ${PREFIX}/examples/glite-jp-primary-test - ${INSTALL} -m 755 ${top_srcdir}/examples/getjobattr.pl ${PREFIX}/examples/glite-jpps-getjobattr.pl - for plugin in ${plugins}; do \ - ${INSTALL} -m 755 $$plugin ${PREFIX}/lib; \ - done - ${INSTALL} -m 755 ${top_srcdir}/config/startup ${PREFIX}/etc/init.d/glite-jp-primary - ${INSTALL} -m 755 ${top_srcdir}/config/glite-jp-primary-dbsetup.sql ${PREFIX}/etc - ${INSTALL} -m 755 ${top_srcdir}/config/glite-jp-primary-dbsetup.sh ${PREFIX}/etc - ${INSTALL} -m 755 ${top_srcdir}/examples/jpps_store_test ${PREFIX}/examples/glite-jp-primary-store-test - ${INSTALL} -m 755 ${top_srcdir}/config/gsi_authz.conf.example ${PREFIX}/etc/gsi_authz.conf - for i in ${sample_jobs}; do \ - ${INSTALL} -m 644 ${top_srcdir}/examples/$$i ${PREFIX}/examples/glite-jp-primary-$$i.lb; \ - done - -mkdir -p ${PREFIX}/yaim/functions/ - -mkdir -p ${PREFIX}/yaim/node-info.d - -mkdir -p ${PREFIX}/yaim/defaults - -mkdir -m 0700 -p ${PREFIX}/yaim/examples/siteinfo/services - ${INSTALL} -m 0644 ${top_srcdir}/config/functions/config* ${PREFIX}/yaim/functions - ${INSTALL} -m 0644 ${top_srcdir}/config/node-info.d/glite* ${PREFIX}/yaim/node-info.d - ${INSTALL} -m 0644 ${top_srcdir}/config/defaults/glite* ${PREFIX}/yaim/defaults - ${INSTALL} -m 0600 ${top_srcdir}/config/site-info.def.example ${PREFIX}/yaim/examples/siteinfo/services/glite_jpps -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 -# - -glite-jp-sandbox.la: sandbox_plugin.lo - ${SOLINK} -o $@ sandbox_plugin.lo ${LIBTARLIB} - -glite-jp-ftpdauth.la: ftpd_auth.lo - ${SOLINK} -o $@ ftpd_auth.lo ${COMMONLIB} ${TRIOLIB} ${SRVCOMMONLIB} - -glite-jp-callouts_${nothrflavour}.la: jp_callouts.lo - ${SOLINK} -o $@ $^ ${COMMONLIB} ${TRIOLIB} ${SRVCOMMONLIB} - -#glite-jp-classad.lo: classad_plugin.c -# ${LTCOMPILE} -DPLUGIN_DEBUG -o $@ -c $< - -#glite-jp-classad.lo: classad_plugin.c -# ${LTCOMPILE} -DPLUGIN_DEBUG -o $@ -c $< - -%.lo: %.c - ${LTCOMPILE} -o $@ -c $< - -soap_ops.o bones_server.o: soap_version.h - -soap_version.h: - ${gsoap_bin_prefix}/soapcpp2 /dev/null - perl -ne '$$. == 2 && /.*([0-9]+)\.([0-9]+)\.([0-9]+)([a-z])?.*/ && printf "#define GSOAP_VERSION %d%02d%02d\n#define GSOAP_VERSION_LETTER '\''".($$4?$$4:"\\0")."'\''\n",$$1,$$2,$$3' soapH.h >$@ - -rm soapC.cpp soapH.h soapStub.h soapClient.cpp soapServer.cpp soapClientLib.cpp soapServerLib.cpp - -soap_env_ctx.c soap_env_ctx.h soap_switch.c: env_C.c mk_soap_switch.pl - ${top_srcdir}/src/mk_soap_switch.pl env_C.c >soap_switch.c diff --git a/org.glite.jp.primary/build.xml b/org.glite.jp.primary/build.xml deleted file mode 100755 index d6081d8..0000000 --- a/org.glite.jp.primary/build.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.primary/config/defaults/glite-jpps.pre b/org.glite.jp.primary/config/defaults/glite-jpps.pre deleted file mode 100644 index fe17ac7..0000000 --- a/org.glite.jp.primary/config/defaults/glite-jpps.pre +++ /dev/null @@ -1,2 +0,0 @@ -### Default values to some glite-JPPS variables -GLITE_USER=glite diff --git a/org.glite.jp.primary/config/functions/config_glite_jpps b/org.glite.jp.primary/config/functions/config_glite_jpps deleted file mode 100644 index 811fef5..0000000 --- a/org.glite.jp.primary/config/functions/config_glite_jpps +++ /dev/null @@ -1,126 +0,0 @@ -function config_glite_jpps_check(){ - requires MYSQL_PASSWORD -} - -function config_glite_jpps_setenv(){ - - yaimgridenv_set GLITE_LOCATION ${INSTALL_ROOT:-opt}/glite - yaimgridenv_set GLITE_LOCATION_VAR ${GLITE_LOCATION_VAR:-/var/glite} - yaimgridenv_set GLOBUS_LOCATION ${GLOBUS_LOCATION:-/opt/globus} - yaimgridenv_set GLITE_USER ${GLITE_USER:-glite} - yaimgridenv_set GLITE_HOST_CERT ${GLITE_USER_HOME:-/home/glite}/.certs/hostcert.pem - yaimgridenv_set GLITE_HOST_KEY ${GLITE_USER_HOME:-/home/glite}/.certs/hostkey.pem - yaimgridenv_set X509_CERT_DIR /etc/grid-security/certificates - yaimgridenv_set GLITE_JP_PRIMARY_PORT ${GLITE_JP_PRIMARY_PORT:-8901} - yaimgridenv_set GLITE_JP_PRIMARY_PEERS ${GLITE_JP_PRIMARY_PEERS:-$GLITE_LOCATION/etc/JPPS-peers} - yaimgridenv_set GLITE_JP_PRIMARY_FTP_PORT ${GLITE_JP_PRIMARY_FTP_PORT:-8911} - yaimgridenv_set GLITE_JP_PRIMARY_INTERNAL ${GLITE_USER_HOME:-/home/glite}/jpps - yaimgridenv_set GLITE_JP_PRIMARY_EXTERNAL gsiftp://`hostname -f`:${GLITE_JP_PRIMARY_FTP_PORT:-8911}${GLITE_USER_HOME:-/home/glite}/jpps - yaimgridenv_set GLITE_JP_PRIMARY_DBCS ${GLITE_JP_PRIMARY_DBCS:-jpps/@localhost:jpps} - yaimgridenv_set GLITE_JP_PRIMARY_SPECIAL ${GLITE_JP_PRIMARY_SPECIAL:-} - yaimgridenv_set GLITE_JP_GSI_AUTHZ ${GLITE_JP_GSI_AUTHZ:-$GLITE_LOCATION/etc/gsi_authz.conf} - - yaimgridpath_append LD_LIBRARY_PATH ${INSTALL_ROOT:-opt}/glite/lib - yaimgridpath_append LD_LIBRARY_PATH ${INSTALL_ROOT:-opt}/globus/lib - yaimgridpath_append LD_LIBRARY_PATH ${INSTALL_ROOT:-opt}/c-ares/lib - yaimgridpath_append LD_LIBRARY_PATH ${INSTALL_ROOT:-opt}/classads/lib - yaimgridpath_append LD_LIBRARY_PATH ${INSTALL_ROOT:-opt}/libtar/lib -} - -function config_glite_jpps() { - - #################################################### - # Job Provenance Primary Storage configuration # - #################################################### - - HOSTNAME=`hostname -f` - - chmod og+rx /var/lib/mysql/ - chown mysql:mysql /var/run/mysqld/ - - # add option --max_allowed_packet=17M - if [ ! -f /etc/my.cnf ]; then - echo "[mysqld]" >> /etc/my.cnf - echo "max_allowed_packet=17M" >> /etc/my.cnf - else - grep "^[mysqld]" /etc/my.cnf > /dev/null - if [ ! $? = 0 ]; then - echo "[mysqld]" >> /etc/my.cnf - echo "max_allowed_packet=17M" >> /etc/my.cnf - fi - fi - - /sbin/chkconfig mysqld on - ps ax | grep -v grep |grep mysqld_safe > /dev/null 2>&1 - if [ ! $? = 0 ] ; then - /etc/init.d/mysqld start - sleep 1 - fi - - ls /tmp/mysql.sock > /dev/null 2>&1 - if [ ! $? = 0 ]; then - ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock - fi - - # set mysql password - set_mysql_passwd || return 1 # the function uses $MYSQL_PASSWORD - - # Check if database exist - mysqlshow --password="$MYSQL_PASSWORD" | grep "jpps" > /dev/null 2>&1 - - if [ ! $? = 0 ]; then - mysql -u root --password="$MYSQL_PASSWORD" -e "CREATE DATABASE jpps" - mysql --password="$MYSQL_PASSWORD" jpps < ${INSTALL_ROOT}/glite/etc/glite-jp-primary-dbsetup.sql - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on jpps.* to jpps IDENTIFIED BY '' WITH GRANT OPTION;" - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on jpps.* to jpps@'$HOSTNAME' IDENTIFIED BY '' WITH GRANT OPTION;" - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on jpps.* to jpps@localhost IDENTIFIED BY '' WITH GRANT OPTION;" - else - yaimlog "Database jpps already exists" - fi - - . /opt/glite/etc/profile.d/grid-env.sh - mkdir -p $GLITE_LOCATION_VAR # Needed to store PID of JPPS - chown $GLITE_USER:$GLITE_USER $GLITE_LOCATION_VAR - chmod 0755 $GLITE_LOCATION_VAR - - mkdir -p $GLITE_JP_PRIMARY_INTERNAL - chown $GLITE_USER:$GLITE_USER $GLITE_JP_PRIMARY_INTERNAL - chmod 0755 $GLITE_JP_PRIMARY_INTERNAL - - mkdir -p $GLITE_USER_HOME/.certs - chown $GLITE_USER:$GLITE_USER $GLITE_USER_HOME/.certs - chmod 0755 $GLITE_USER_HOME/.certs - cp -f /etc/grid-security/hostcert.pem /etc/grid-security/hostkey.pem $GLITE_USER_HOME/.certs/ - if [ ! $? = 0 ] ; then - echo "Please copy host certificate and key into /etc/grid-security and" - echo " $GLITE_USER_HOME/.certs/, change the owner of the ones in" - echo " $GLITE_USER_HOME/.certs/ to $GLITE_USER" - fi - chown $GLITE_USER:$GLITE_USER $GLITE_USER_HOME/.certs/hostcert.pem $GLITE_USER_HOME/.certs/hostkey.pem - chmod 0644 $GLITE_USER_HOME/.certs/hostcert.pem - chmod 0400 $GLITE_USER_HOME/.certs/hostkey.pem - - # Start services - if [ ! -f ${GLITE_LOCATION}/etc/gLiteservices ] ; then - touch ${GLITE_LOCATION}/etc/gLiteservices - fi - - grep glite-jp-primary ${GLITE_LOCATION}/etc/gLiteservices > /dev/null - if [ ! $? = 0 ] ; then - echo "${GLITE_LOCATION}/etc/init.d/glite-jp-primary" >> ${GLITE_LOCATION}/etc/gLiteservices - fi - - touch ${GLITE_JP_PRIMARY_PEERS} - - . /opt/glite/etc/profile.d/grid-env.sh - ${GLITE_LOCATION}/etc/init.d/glite-jp-primary stop - ${GLITE_LOCATION}/etc/init.d/glite-jp-primary start - - if [ ! $? = 0 ] ; then - yaimlog ABORT "Service glite-jp-primary failed to start!" - return 1 - fi - - return 0 - -} diff --git a/org.glite.jp.primary/config/glite-jp-primary-dbsetup.sh b/org.glite.jp.primary/config/glite-jp-primary-dbsetup.sh deleted file mode 100644 index 39a73e7..0000000 --- a/org.glite.jp.primary/config/glite-jp-primary-dbsetup.sh +++ /dev/null @@ -1,30 +0,0 @@ -#! /bin/sh -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# Shell example of preparing the database for JP Index Server -# - -# database -mysqladmin -u root -p create jpps - -# user -mysql -u root -p -e 'GRANT ALL on jpps.* to jpps@localhost' - -# tables -mysql -u jpps jpps < `dirname $0`/glite-jp-primary-dbsetup.sql diff --git a/org.glite.jp.primary/config/glite-jp-primary-dbsetup.sql b/org.glite.jp.primary/config/glite-jp-primary-dbsetup.sql deleted file mode 100644 index 0e2dc70..0000000 --- a/org.glite.jp.primary/config/glite-jp-primary-dbsetup.sql +++ /dev/null @@ -1,63 +0,0 @@ -create table jobs ( - jobid char(32) binary not null, - dg_jobid varchar(255) binary not null, - owner char(32) binary not null, - - reg_time datetime not null, - - primary key (jobid), - unique (dg_jobid), - index (owner), - index (owner,reg_time) -); - -create table files ( - jobid char(32) binary not null, - filename varchar(255) binary not null, - int_path mediumblob null, - ext_url mediumblob null, - - state char(32) binary not null, - deadline datetime null, - ul_userid char(32) binary not null, - - primary key (jobid,filename), - index (ext_url(255)) -); - -create table attrs ( - jobid char(32) binary not null, - name varchar(255) binary not null, - value mediumblob null, - - primary key (jobid,name) -); - -create table users ( - userid char(32) binary not null, - cert_subj varchar(255) binary not null, - - primary key (userid), - unique (cert_subj) -); - -create table backend_info ( - version char(32) binary not null -); - -create table feeds ( - feedid char(32) binary not null, - destination varchar(255) binary not null, - expires datetime not null, - cols mediumblob not null, - query mediumblob not null, - - primary key (feedid) -); - -create table fed_jobs ( - feedid char(32) binary not null, - jobid char(32) binary not null, - - primary key (jobid,feedid) -); diff --git a/org.glite.jp.primary/config/gsi_authz.conf.example b/org.glite.jp.primary/config/gsi_authz.conf.example deleted file mode 100644 index 7f87c98..0000000 --- a/org.glite.jp.primary/config/gsi_authz.conf.example +++ /dev/null @@ -1,6 +0,0 @@ -GLOBUS_GSI_AUTHZ_SYSTEM_INIT glite-jp-callouts authz_jp_system_init_callout -GLOBUS_GSI_AUTHZ_SYSTEM_DESTROY glite-jp-callouts authz_jp_system_destroy_callout -GLOBUS_GSI_AUTHZ_HANDLE_INIT glite-jp-callouts authz_jp_handle_init_callout -GLOBUS_GSI_AUTHZ_HANDLE_DESTROY glite-jp-callouts authz_jp_handle_destroy_callout -GLOBUS_GSI_AUTHORIZE_ASYNC glite-jp-callouts authz_jp_authorize_async_callout -globus_mapping glite-jp-callouts authz_jp_globus_mapping diff --git a/org.glite.jp.primary/config/node-info.d/glite-jpps b/org.glite.jp.primary/config/node-info.d/glite-jpps deleted file mode 100644 index 6b707d4..0000000 --- a/org.glite.jp.primary/config/node-info.d/glite-jpps +++ /dev/null @@ -1,6 +0,0 @@ -JPPS_FUNCTIONS=" -config_host_certs -config_edgusers -config_globus_clients -config_glite_jpps -config_glite_initd" diff --git a/org.glite.jp.primary/config/site-info.def.example b/org.glite.jp.primary/config/site-info.def.example deleted file mode 100755 index ac95cdd..0000000 --- a/org.glite.jp.primary/config/site-info.def.example +++ /dev/null @@ -1,64 +0,0 @@ -# -# site-info.def example, part for org.glite.jp.primary -# -# options configured by YAIM can be overriden by: -# - /etc/glite.conf -# - $GLITE_LOCATION/etc/glite-wms.conf -# - $HOME/.glite.conf # of root user -# - -# -# required minimum set of YAIM options given from -# /opt/glite/yaim/examples/siteinfo/site-info.def -# -YAIM_LOGGING_LEVEL=INFO -MY_DOMAIN=civ.zcu.cz -INSTALL_ROOT=/opt -CRON_DIR=/etc/cron.d -GLOBUS_TCP_PORT_RANGE="20000,25000" -MYSQL_PASSWORD=set_this_to_a_good_password - -# -# default values of basic options -# - -#GLITE_LOCATION=${INSTALL_ROOT:-opt}/glite -#GLITE_LOCATION_VAR=${GLITE_LOCATION_VAR:-/var/glite} -#GLITE_USER=${GLITE_USER:-glite} -#GLITE_HOST_CERT=${GLITE_USER_HOME:-/home/glite}/.certs/hostcert.pem -#GLITE_HOST_KEY=${GLITE_USER_HOME:-/home/glite}/.certs/hostkey.pem -#X509_CERT_DIR=/etc/grid-security/certificates - - -# -# required external options -# - -#GLOBUS_LOCATION=/opt/globus -#CARES_LOCATION=/opt/c-ares - -# -# JPPS configuration default values -# - -# pidfile -#GLITE_JP_PRIMARY_PIDFILE=$GLITE_LOCATION_VAR/glite-jp-primarystoraged.pid - -# port -#GLITE_JP_PRIMARY_PORT=8901 - -# FTP port -#GLITE_JP_PRIMARY_FTP_PORT=8911 - -#FTP authz configuration file -#GLITE_JP_GSI_AUTHZ=$GLITE_LOCATION/etc/gsi_authz.conf - -# List of privileged DN subjects -#GLITE_JP_PRIMARY_PEERS=$GLITE_LOCATION/etc/JPPS-peers - -# connection string to database (USER/PASSWORD@HOST:DBNAME) -# If the default is changed, the database has to be created manually ! -#GLITE_JP_PRIMARY_DBCS=jpps/@localhost:jpps - -# Additional switches for JPPS. -#GLITE_JP_PRIMARY_SPECIAL="" diff --git a/org.glite.jp.primary/config/startup b/org.glite.jp.primary/config/startup deleted file mode 100644 index e901c96..0000000 --- a/org.glite.jp.primary/config/startup +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh - -GLITE_LOCATION=${GLITE_LOCATION:-/opt/glite} -GLITE_LOCATION_VAR=${GLITE_LOCATION_VAR:-${GLITE_LOCATION}/var} - -[ -f /etc/glite.conf ] && . /etc/glite.conf -[ -f $GLITE_LOCATION/etc/glite-wms.conf ] && . $GLITE_LOCATION/etc/glite-wms.conf - -[ -f $GLITE_LOCATION/etc/jp.conf ] && . $GLITE_LOCATION/etc/jp.conf -[ -f $GLITE_LOCATION_VAR/etc/jp.conf ] && . $GLITE_LOCATION_VAR/etc/jp.conf - -[ -f $HOME/.glite.conf ] && . $HOME/.glite.conf - -[ -n "$GLITE_JP_PRIMARY_PIDFILE" ] && pidfile=$GLITE_JP_PRIMARY_PIDFILE || - pidfile="$GLITE_LOCATION_VAR/glite-jp-primarystoraged.pid" - -unset creds - -test -n "$GLITE_JP_PRIMARY_PORT" || GLITE_JP_PRIMARY_PORT=8901 - -start() -{ - if test -z "$GLITE_USER" ;then - echo 'Error: GLITE_USER is not set' - echo FAILED - return 1 - fi - if test -z "$GLOBUS_LOCATION" ;then - echo 'Error: GLOBUS_LOCATION is not set' - echo FAILED - return 1 - fi - if test -z "$GLITE_JP_PRIMARY_PEERS" ;then - echo 'Error: incomplete configuration (GLITE_JP_PRIMARY_PEERS is not set)' - echo FAILED - return 1 - fi - if test -z "$GLITE_JP_PRIMARY_FTP_PORT" -o \ - -z "$GLITE_JP_PRIMARY_INTERNAL" -o -z "$GLITE_JP_PRIMARY_EXTERNAL" ;then - echo 'Error: incomplete configuration (GLITE_JP_PRIMARY_FTP_PORT,' \ - 'GLITE_JP_PRIMARY_INTERNAL, or GLITE_JP_PRIMARY_EXTERNAL is not set)' - echo FAILED - return 1 - fi - - if [ -n "$GLITE_HOST_CERT" -a -n "$GLITE_HOST_KEY" ] ;then - creds="-c '$GLITE_HOST_CERT' -k '$GLITE_HOST_KEY'" - X509_USER_CERT="$GLITE_HOST_CERT" - X509_USER_KEY="$GLITE_HOST_KEY" - fi - - 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="-c /etc/grid-security/hostcert.pem -k /etc/grid-security/hostkey.pem" - X509_USER_CERT=/etc/grid-security/hostcert.pem - X509_USER_KEY=/etc/grid-security/hostkey.pem - fi - fi - - - [ -z "$creds" ] && echo $0: WARNING: No credentials specified. Using default lookup which is dangerous. >&2 - - unset GLITE_JP_PRIMARY_DBCS_OPTION - if test -n "$GLITE_JP_PRIMARY_DBCS"; then - GLITE_JP_PRIMARY_DBCS_OPTION="-BD,'$GLITE_JP_PRIMARY_DBCS'" - fi - - echo -n Starting glite-jp-primarystoraged ... - su - $GLITE_USER -c "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GLOBUS_LOCATION/lib:$GLITE_LOCATION/lib \ - $GLITE_LOCATION/bin/glite-jp-primarystoraged \ - $GLITE_JP_DEBUG \ - -P $GLITE_LOCATION/lib/glite_lb_plugin.so -P $GLITE_LOCATION/lib/glite-jp-sandbox.so \ - $creds -a '$GLITE_JP_PRIMARY_PEERS' \ - -i '$pidfile' -p $GLITE_JP_PRIMARY_PORT $GLITE_JP_PRIMARY_SPECIAL \ - -BI,'$GLITE_JP_PRIMARY_INTERNAL' -BE,'$GLITE_JP_PRIMARY_EXTERNAL' \ - ${GLITE_JP_PRIMARY_DBCS_OPTION} " && echo " done" - if [ $? != 0 ]; then - echo " FAILED" - return 1 - fi - - echo -n Starting JP gridftp server ... - su - $GLITE_USER -c "X509_USER_CERT=\"$X509_USER_CERT\" \ - X509_USER_KEY=\"$X509_USER_KEY\" \ - GLITE_USER=\"$GLITE_USER\" \ - FTPBE_INT_PREFIX=\"$GLITE_JP_PRIMARY_INTERNAL\" \ - LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GLOBUS_LOCATION/lib:$GLITE_LOCATION/lib \ - FTPBE_DB_CS=$GLITE_JP_PRIMARY_DBCS \ - GSI_AUTHZ_CONF=$GLITE_JP_GSI_AUTHZ \ - $GLOBUS_LOCATION/sbin/globus-gridftp-server -debug -s -p $GLITE_JP_PRIMARY_FTP_PORT & \ - pid=\$!; echo \$pid > $pidfile.ftpd; sleep 2; true kill -0 \$pid" && echo " done" || echo " FAILED" -} - -stop() -{ - if [ -f "$pidfile" ]; then - pid=`cat "$pidfile"` - kill $pid - echo -n Stopping glite-jp-primarystoraged \($pid\) ... - try=0 - while ps p $pid >/dev/null 2>&1; do - sleep 1; - try=`expr $try + 1` - if [ $try = 20 ]; then - echo " giving up after $try retries" - return 1 - fi - done - kill -9 $pid >/dev/null 2>&1 - echo " done" - rm -f "$pidfile" - else - echo "$pidfile" does not exist - glite-jp-primarystoraged not running? >&2 - return 1 - fi - if [ -f "$pidfile.ftpd" ]; then - pid=`cat "$pidfile.ftpd"` - kill $pid - echo -n Stopping JP ftp server \($pid\) ... - try=0 - while ps p $pid >/dev/null 2>&1; do - sleep 1; - try=`expr $try + 1` - if [ $try = 20 ]; then - echo " giving up after $try retries" - return 1 - fi - done - kill -9 $pid >/dev/null 2>&1 - echo " done" - rm -f "$pidfile.ftpd" - else - echo "$pidfile.ftpd" does not exist - JP ftp server not running? >&2 - return 1 - fi - - return 0 -} - -status() -{ - retval=0 - # XXX pidfile? - if netstat -an --inet | grep "^tcp .* 0.0.0.0:${GLITE_JP_PRIMARY_PORT} .*LISTEN" >/dev/null 2>&1 ;then - echo glite-jp-primarystoraged running - else - echo glite-jp-primarystoraged not running - retval=1 - fi - - if netstat -an --inet | grep "^tcp .* 0.0.0.0:${GLITE_JP_PRIMARY_FTP_PORT} .*LISTEN" >/dev/null 2>&1 ;then - echo JP gridftp server running - else - echo JP gridftp server not running - retval=1 - fi - - return $retval -} - -case x$1 in - xstart) start;; - xstop) stop;; - xrestart) stop; start;; - xstatus) status;; - x*) echo usage: $0 start,stop,restart,status >&2 - exit 1;; -esac diff --git a/org.glite.jp.primary/configure b/org.glite.jp.primary/configure deleted file mode 100755 index 0bf1a3f..0000000 --- a/org.glite.jp.primary/configure +++ /dev/null @@ -1,701 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; - -my $pwd = `pwd`; chomp $pwd; -my $prefix = $pwd.'/stage'; -my $stagedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my $version; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $sec_tag = ''; -my $jobid_tag = ''; - -my @nodes = qw/client server logger utils client-java doc ws-test db jpprimary jpindex jpclient/; -my %enable_nodes; -my %disable_nodes; - -my %extern_prefix = ( - cares => '/opt/c-ares', - classads => '/opt/classads', - cppunit => '/usr', - expat => '/usr', - globus => '/opt/globus', - gsoap => '/usr', - mysql => '/usr', - voms => '/opt/glite', - gridsite => '/opt/glite', - lcas => '/opt/glite', - ant => '/usr', - jdk => '/usr', - libtar => '/usr', -); - -my %jar = ( - 'commons-codec' => '/usr/share/java/commons-codec-1.3.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %topbuild; - -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test/], - 'security' => [qw/gss gsoap-plugin/], - 'lbjp-common' => [qw/db maildir server-bones trio jp-interface/], - 'jobid' => [qw/api-c api-cpp api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - ); - - -my @opts = ( - 'prefix=s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour=s' => \$thrflavour, - 'nothrflavour=s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$version, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'security-tag=s' => \$sec_tag, - 'jobid-tag=s' => \$jobid_tag, - 'help' => \$help, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$extern_prefix{$_} for keys %extern_prefix; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my @m = map "org.glite.$listmodules.$_",@{$lbmodules{$listmodules}}; - print "@m\n"; - exit 0; -} - -warn "$0: --version and --output make sense only in --mode=etics\n" - if ($version || $output) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},@{$lbmodules{security}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless $disable_nodes{$_}; - } -} - -if (!$en && !$dis) { $enable_nodes{$_} = 1 for (@nodes) } ; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $prefix unless $stagedir; - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: $extern_prefix{$_}\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\nclean:\n"; - - for (@modules) { - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - print MAK "\tcd $full$build && \${MAKE} clean\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $topbuild{$_} ? - "\tcd $full$build && \${MAKE} distclean\n" : - "\trm -rf $full$build\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - - print MAK "$_: @dnames\n\tcd $full$build && \${MAKE} && \${MAKE} install\n\n"; - } - - close MAK; -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag){ - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($sec_tag){ - for (@{$lbmodules{security}}){ - if ("security.".$_ eq $module){ - $tag = '-r '.$sec_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads/ ], - 'lb.client-java' => [ qw/ant:B/ ], - 'lb.common' => [ qw/expat cppunit:B classads/ ], - 'lb.doc' => [], - 'lb.logger' => [ qw/cppunit:B/ ], - 'lb.server' => [ qw/globus expat cares mysql cppunit:B gsoap:B classads voms lcas gridsite/ ], - 'lb.state-machine' => [ qw/classads/ ], - 'lb.utils' => [ qw/cppunit:B/ ], - 'lb.ws-interface' => [], - 'lb.ws-test' => [ qw/gsoap:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/mysql/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw/cppunit:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B/ ], - 'security.gss' => [ qw/globus cares cppunit:B/ ], - 'security.gsoap-plugin' => [ qw/cppunit:B globus cares gsoap:B/ ], - 'jobid.api-c' => [ qw/cppunit:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], -); - -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$need_externs{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $need_externs_type{$ext}->{$1} = $type; - } -} - -%need_jars = ( - 'jobid.api-java' => [ qw/commons-codec/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp jobid.api-c - security.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp jobid.api-c - lb.types:B lbjp-common.trio security.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - jobid.api-c - lb.common - security.gss - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir - jobid.api-c - security.gsoap-plugin security.gss - / ], - 'lb.state-machine' => [ qw/lb.common lbjp-common.jp-interface security.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine - / ], - 'lb.ws-test' => [ qw/security.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/lbjp-common.trio/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw// ], - 'security.gss' => [ qw// ], - 'security.gsoap-plugin' => [ qw/security.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - security.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( gridsite=>'org.gridsite.core'); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', -); - -my @t = qw/lb.client-java jobid.api-java lb.types/; -@topbuild{@t} = (1) x ($#t+1); -} - -sub full -{ - my $short = shift; - return $extrafull{$short} ? $extrafull{$short} : 'org.glite.'.$short; -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java -security.gss security.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -/; - @aux{@m} = (1) x ($#m+1); - - my $short = shift; - my $full = full $short; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $build = ''; - - unless ($topbuild{$_}) { - $build = '/build'; - unless (-d "$full/build") { - mkdir "$full/build" or die "mkdir $full/build: $!\n"; - } - unlink "$full/build/Makefile"; - symlink "../Makefile","$full/build/Makefile" or die "symlink ../Makefile $full/build/Makefile: $!\n"; - } - - open MKINC,">$full$build/Makefile.inc" - or die "$full$build/Makefile.inc: $!\n"; - - print "Creating $full$build/Makefile.inc\n"; - - print MKINC qq{ -PREFIX = $prefix -stagedir = $stagedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -}; - - for (@{$need_externs{$short}}) { - print MKINC "${_}_prefix = $extern_prefix{$_}\n" - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; -} - -my %etics_externs; -my %etics_projects; -BEGIN{ - %etics_externs = ( - globus=>'vdt_globus_essentials', - cares=>'c-ares', - voms=>'org.glite.security.voms-api-cpp', - gridsite=>'org.gridsite.shared', - lcas=>'org.glite.security.lcas', - ); - %etics_projects = ( - vdt=>[qw/globus/], - 'org.glite'=>[qw/voms gridsite lcas/], - ); -}; - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod; - - my ($major,$minor,$rev,$age); - - if ($version) { - $version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - open V,"org.glite.$subsys.$module/project/version.properties" - or die "org.glite.$subsys.$module/project/version.properties: $!\n"; - - while ($_ = ) { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - } - - my @copts = (); - my %ge; - @ge{@{$etics_projects{'org.glite'}}} = (1) x ($#{$etics_projects{'org.glite'}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}/$_*.jar"; - } - - - my $conf = "glite-$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $topbuild{"$subsys.$module"} ? '' : "build.root = build\n"; - - my $confdir = $topbuild{"$subsys.$module"} ? '..' : '../..'; - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = org.glite.$subsys.$module -displayName = $conf -description = org.glite.$subsys.$module -projectName = org.glite -age = $age -deploymentType = None -tag = $conf -version = $major.$minor.$rev -path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz - -[Platform-default:VcsCommand] -displayName = None -description = None -tag = cvs -d \${vcsroot} tag -R \${tag} \${moduleName} -branch = None -commit = None -checkout = cvs -d \${vcsroot} co -r \${tag} \${moduleName} - -[Platform-default:BuildCommand] -postpublish = None -packaging = None -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = make -init = None -install = make install -clean = make clean -test = make check -configure = cd $confdir && \${moduleName}/configure --thrflavour=\${globus.thr.flavor} --nothrflavour=\${globus.nothr.flavor} --prefix=\${prefix} --stage=\${stageDir} --module $subsys.$module @copts -checkstyle = None - -[Platform-default:Property] -$buildroot - -[Platform-default:DynamicDependency] - -}; - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - print C "$proj|$eext = $type\n"; - } - - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - print C "org.glite|org.glite.$_ = $type\n"; - } - - close C; -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$extern_prefix{gsoap}/bin/soapcpp2 -v 2>&1 |" or die "$extern_prefix{gsoap}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - - -sub usage { - my @ext = keys %extern_prefix; - my @myjars, keys %jar; - - print STDERR qq{ -usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - -Mode of operation: - --mode={checkout|build|etics} what to do [build] - -What to build: - --module=module build this module only (mostly in-Etics operation) - --enable-NODE build this "node" (set of modules) only. Available nodes are - @{$lbmodules{lb}},@{$lbmodules{security}} - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --security-tag=tag checkout security modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - -Dependencies: - --with-EXTERNAL=PATH where to look for an external. Required externals - (not all for all modules) are: - @ext - --with-JAR=JAR where to look for jars. Required jars are: - @myjars - Summary of what will be used is always printed - -}; - -} diff --git a/org.glite.jp.primary/doc/README.install b/org.glite.jp.primary/doc/README.install deleted file mode 100644 index 17d0d27..0000000 --- a/org.glite.jp.primary/doc/README.install +++ /dev/null @@ -1,59 +0,0 @@ -0. install glite-jp-primary package - -1. create MySQL database of the service, preferably using - ${GLITE_LOCATION}/etc/glite-jp-primary-dbsetup.sh - (the script prompts two times for MySQL root password) - -2. create a directory where JPPS files will be stored and configure - gridftp server so that this directory is accessible via gridftp - -3. create the configuration file $GLITE_LOCATION/etc/jp.conf, it should - contain /bin/sh syntax assignment to the following variables (or they - have to be set in the environment of the startup script by other means: - - GLITE_USER the unix user running the service - - GLOBUS_LOCATION where is Globus installed - - GLITE_JP_PRIMARY_FTP_PORT - port for the ftp JPPS interface (bulk file transfers) - - GLITE_JP_PRIMARY_INTERNAL - directory where the JPPS files are stored (local path) - - GLITE_JP_PRIMARY_EXTERNAL - URL prefix which is mapped by gridftp to the directory, - eg. gsiftp://this.host.name:$GLITE_JP_PRIMARY_FTP_PORT/some/directory - - - GLITE_JP_PRIMARY_PEERS - file with list (one per line) of X509 certificate subjects of "trusted peers", i.e. L&B servers which may upload data to this JPPS - - -4. start the service with - $GLITE_LOCATION/etc/init.d/glite-jp-primary start - - -5. This step taints the database with testing data. Don't do it if it is an issue. -It is not necessary for the service operation, it's just checking its basic functionality. - -$ JOB=https://scientific.civ.zcu.cz:9200/1Yjk3Wlaspl07y45iX8Tng -$ TEST=$GLITE_LOCATION/examples/glite-jp-primary-test -$ export X5O9_USER_PROXY=/some/proxy.pem # must be among $GLITE_JP_PRIMARY_PEERS - -$ $TEST registerjob $JOB '/the/job/owner/x509/cert' - -$ $TEST startupload "urn:org.glite.jp.primary:lb" 1 text/plain - responds with destination gsiftp url - -$ globus-url-copy file:///$GLITE_LOCATION/examples/glite-jp-primary-sample_job.lb $DESTINATION_URL - -$ $TEST commitupload $DESTINATION_URL - -$ $TEST getjobattr $JOB http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus - -The command should output: - - Waiting FILE Mon Oct 10 23:48:47 2005 - --- diff --git a/org.glite.jp.primary/examples/README.test b/org.glite.jp.primary/examples/README.test deleted file mode 100644 index 9b939b7..0000000 --- a/org.glite.jp.primary/examples/README.test +++ /dev/null @@ -1,94 +0,0 @@ -Create database: ----------------- - -$ mysqladmin -u root -p create jpps -$ mysql -u root -p -mysql> grant all privileges on jpps.* to jpps@localhost identified by ''; - -$ mysql -p -u jpps jpps -#include - -#include -#include -#include - -#include - -#include "glite/jp/known_attr.h" - -#include "jpps_H.h" -#include "jpps_.nsmap" - -#include "jptype_map.h" -#include "glite/security/glite_gsplugin.h" -#include "glite/security/glite_gscompat.h" - -#if GSOAP_VERSION <= 20602 -#define soap_call___jpsrv__RegisterJob soap_call___ns1__RegisterJob -#define soap_call___jpsrv__StartUpload soap_call___ns1__StartUpload -#define soap_call___jpsrv__CommitUpload soap_call___ns1__CommitUpload -#define soap_call___jpsrv__RecordTag soap_call___ns1__RecordTag -#define soap_call___jpsrv__FeedIndex soap_call___ns1__FeedIndex -#define soap_call___jpsrv__FeedIndexRefresh soap_call___ns1__FeedIndexRefresh -#define soap_call___jpsrv__GetJob soap_call___ns1__GetJob -#endif - -#define dprintf(FMT, ARGS...) fprintf(stderr, (FMT), ##ARGS) -#include "glite/jp/ws_fault.c" -#define check_fault(SOAP, ERR) glite_jp_clientCheckFault((SOAP), (ERR), NULL, 0) - - -static void usage(const char *me) -{ - fprintf(stderr,"%s: [-s server-url] jobid\n",me); - - exit (EX_USAGE); -} - -static const char *orig2str(enum jptype__attrOrig orig) -{ - switch (orig) { - case jptype__attrOrig__SYSTEM: return "SYSTEM"; - case jptype__attrOrig__USER: return "USER"; - case jptype__attrOrig__FILE_: return "FILE"; - default: return "unknown"; - } -} - - -int main(int argc,char *argv[]) -{ - char *server = NULL; - int opt,ret = 0,i; - struct soap *soap = soap_new(); - struct _jpelem__GetJobAttributes in; - struct _jpelem__GetJobAttributesResponse out; - char *aname = "http://egee.cesnet.cz/en/Schema/LB/Attributes:JDL"; - struct cclassad *ad; - struct { char *a,*s; } *deps = calloc(1,sizeof *deps); - int ndeps = 0; - char *dep_s,*where,*end,*tmp_a,*tmp_s,*wa,*wa_r,*ws,*ws_r; - - if (argc < 2) usage(argv[0]); - - soap_init(soap); - soap_set_namespaces(soap, jpps__namespaces); - - soap_register_plugin(soap,glite_gsplugin); - - while ((opt = getopt(argc,argv,"s:")) >= 0) switch (opt) { - case 's': server = optarg; - break; - case '?': usage(argv[0]); - } - - if (server) { - argv += 2; - argc -= 2; - } - else server = "http://localhost:8901"; - - - - in.jobid = argv[1]; - in.__sizeattributes = 1; - in.attributes = &aname; - - puts("Retrieving JDL ..."); - if ((ret = check_fault(soap,soap_call___jpsrv__GetJobAttributes(soap,server,"",&in,&out)))) - return 1; - - ad = cclassad_create(GSOAP_STRING(GLITE_SECURITY_GSOAP_LIST_GET(out.attrValues, 0)->value)); - if (!ad) { - fputs("Can't parse JDL\n",stderr); - return 1; - } - - // cclassad_evaluate_to_string(ad,"dependencies",&dep_s); - cclassad_evaluate_to_expr(ad,"dependencies",&dep_s); - - /* XXX: assumes syntacticly correct dependencies = { ... } */ - where = strchr(dep_s,'{'); assert(where); - where++; - - while ((where = strchr(where, '{'))) { /* 2nd level */ - for (where++; isspace(*where); where++); - - if (*where == '{') end = strchr(where, '}')+1; /* more ancestors */ - else for (end = where; !isspace(*end) && *end != ','; end++); - tmp_a = strndup(where,end - where); - where = end++; - - while(isspace(*where)) where++; - where++; /* comma */ - while(isspace(*where)) where++; - - if (*where == '{') end = strchr(where, '}')+1; /* more successors */ - else for (end = where; !isspace(*end) && *end != ','; end++); - tmp_s = strndup(where,end - where); - where = strchr(end+1,'}'); - -#define DELIM "{} ,\t\n" - for (ws = strtok_r(tmp_s,DELIM,&ws_r); ws; ws = strtok_r(NULL,DELIM,&ws_r)) - for (wa = strtok_r(tmp_a,DELIM,&wa_r); wa; wa = strtok_r(NULL,DELIM,&wa_r)) { - deps[ndeps].a = strdup(wa); - deps[ndeps].s = strdup(ws); - deps = realloc(deps, (ndeps+2) * sizeof *deps); - ndeps++; - deps[ndeps].a = deps[ndeps].s = NULL; - } - free(tmp_a); free(tmp_s); - } - - for (i=0; deps[i].a; i++) { - char attr[1000],*ja,*js; - int have_a,have_s; - - printf("node: %s -> %s\n",deps[i].a,deps[i].s); - sprintf(attr,"nodes.%s.description.edg_jobid",deps[i].a); - have_a = cclassad_evaluate_to_string(ad,attr,&ja); - - sprintf(attr,"nodes.%s.description.edg_jobid",deps[i].s); - have_s = cclassad_evaluate_to_string(ad,attr,&js); - - printf("jobid: %s -> %s\n",ja,js); - - if (have_a && have_s) { - struct _jpelem__RecordTag in; - struct _jpelem__RecordTagResponse empty; - struct jptype__tagValue tagval; - struct jptype__stringOrBlob val; - - in.jobid = ja; - in.tag = &tagval; - tagval.name = GLITE_JP_ATTR_WF_SUCCESSOR; - tagval.value = &val; - memset(&val, 0, sizeof(val)); - GSOAP_SETSTRING(&val, js); - - printf("Register successor ...\n"); - ret = check_fault(soap,soap_call___jpsrv__RecordTag(soap, server, "",&in, &empty)); - in.jobid = js; - tagval.name = GLITE_JP_ATTR_WF_ANCESTOR; - GSOAP_SETSTRING(&val, ja); - - printf("Register ancestor ...\n"); - ret = check_fault(soap,soap_call___jpsrv__RecordTag(soap, server, "",&in, &empty)); - putchar(10); - } - } - - return ret; -} diff --git a/org.glite.jp.primary/examples/getjobattr.pl b/org.glite.jp.primary/examples/getjobattr.pl deleted file mode 100644 index 5f7609b..0000000 --- a/org.glite.jp.primary/examples/getjobattr.pl +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use SOAP::Lite; -use Data::Dumper; - -$ENV{HTTPS_CA_DIR}='/etc/grid-security/certificates'; -$ENV{HTTPS_VERSION}='3'; - -$cred = $ENV{X509_USER_PROXY} ? $ENV{X509_USER_PROXY} : "/tmp/x509up_u$<"; -$ENV{HTTPS_CERT_FILE}= $ENV{HTTPS_KEY_FILE} = $ENV{HTTPS_CA_FILE} = $cred; - -$proxy = shift; -$job = shift; - -die "usage: $0 https://jp.primary.storage.org:8901/jpps https://some.nice.job/id attr attr ...\n" - unless $ARGV[0]; - -$c = SOAP::Lite - -> proxy($proxy) - -> uri('http://glite.org/wsdl/services/jp'); - -service $c 'http://egee.cesnet.cz/cms/export/sites/egee/en/WSDL/3.1/JobProvenancePS.wsdl' or die "service: $1\n"; - -ns $c 'http://glite.org/wsdl/elements/jp'; - -print "WSDL OK\n"; - -push @attr,SOAP::Data->name(attributes => $_) for (@ARGV); - -$req = SOAP::Data->value( - SOAP::Data->name(jobid => $job), - @attr -# SOAP::Data->name(attributes => 'http://egee.cesnet.cz/en/Schema/LB/Attributes:CE'), -# SOAP::Data->name(attributes => 'http://egee.cesnet.cz/en/Schema/JP/System:owner') -); - - - -on_fault $c sub { print Dumper($_[1]->fault); $fault = 1; }; - -$resp = GetJobAttributes $c $req; - -print Dumper $resp->body unless $fault; - diff --git a/org.glite.jp.primary/examples/job_template b/org.glite.jp.primary/examples/job_template deleted file mode 100644 index 14b312d..0000000 --- a/org.glite.jp.primary/examples/job_template +++ /dev/null @@ -1,14 +0,0 @@ -DG.ARRIVED=20051010210927.000000 DATE=20051010210926.978300 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="UserInterface" DG.SRC_INSTANCE="" DG.EVNT="RegJob" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000001:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.REGJOB.JDL="blabla" DG.REGJOB.NS="NNNSSSS" DG.REGJOB.PARENT="" DG.REGJOB.JOBTYPE="SIMPLE" DG.REGJOB.NSUBJOBS="0" DG.REGJOB.SEED="uLU0BArrdV98O41PLThJ5Q" -DG.ARRIVED=20051010210928.000000 DATE=20051010210928.871099 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="NetworkServer" DG.SRC_INSTANCE="" DG.EVNT="Accepted" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000001:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.ACCEPTED.FROM="UserInterface" DG.ACCEPTED.FROM_HOST="sending component hostname" DG.ACCEPTED.FROM_INSTANCE="sending component instance" DG.ACCEPTED.LOCAL_JOBID="new jobId (Condor Globus ...)" -DG.ARRIVED=20051010210928.000000 DATE=20051010210928.917822 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="NetworkServer" DG.SRC_INSTANCE="" DG.EVNT="EnQueued" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000003:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.ENQUEUED.QUEUE="destination queue" DG.ENQUEUED.JOB="job description in receiver language" DG.ENQUEUED.RESULT="OK" DG.ENQUEUED.REASON="detailed description of transfer" -DG.ARRIVED=20051010210928.000000 DATE=20051010210928.947076 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="DeQueued" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000004:WM=000001:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.DEQUEUED.QUEUE="queue name" DG.DEQUEUED.LOCAL_JOBID="new jobId assigned by the receiving component" -DG.ARRIVED=20051010210928.000000 DATE=20051010210928.980395 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="HelperCall" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000004:WM=000003:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.HELPERCALL.HELPER_NAME="name of the called component" DG.HELPERCALL.HELPER_PARAMS="parameters of the call" DG.HELPERCALL.SRC_ROLE="CALLING" -DG.ARRIVED=20051010210929.000000 DATE=20051010210929.011781 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="Match" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000004:WM=000005:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.MATCH.DEST_ID="destination CE/queue" -DG.ARRIVED=20051010210929.000000 DATE=20051010210929.283947 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Done" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000007:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.DONE.STATUS_CODE="OK" DG.DONE.REASON="reason for the change" DG.DONE.EXIT_CODE="0" -DG.ARRIVED=20051010210929.000000 DATE=20051010210929.042443 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="HelperReturn" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000004:WM=000007:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.HELPERRETURN.HELPER_NAME="name of the called component" DG.HELPERRETURN.RETVAL="returned data" DG.HELPERRETURN.SRC_ROLE="CALLING" -DG.ARRIVED=20051010210929.000000 DATE=20051010210929.071034 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="EnQueued" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000004:WM=000009:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.ENQUEUED.QUEUE="destination queue" DG.ENQUEUED.JOB="job description in receiver language" DG.ENQUEUED.RESULT="OK" DG.ENQUEUED.REASON="detailed description of transfer" -DG.ARRIVED=20051010210929.000000 DATE=20051010210929.101204 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="JobController" DG.SRC_INSTANCE="" DG.EVNT="DeQueued" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000001:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.DEQUEUED.QUEUE="queue name" DG.DEQUEUED.LOCAL_JOBID="new jobId assigned by the receiving component" -DG.ARRIVED=20051010210929.000000 DATE=20051010210929.132080 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="JobController" DG.SRC_INSTANCE="" DG.EVNT="Transfer" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000003:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.TRANSFER.DESTINATION="LRMS" DG.TRANSFER.DEST_HOST="destination hostname" DG.TRANSFER.DEST_INSTANCE="destination instance" DG.TRANSFER.JOB="(nil)" DG.TRANSFER.RESULT="OK" DG.TRANSFER.REASON="detailed description of transfer" DG.TRANSFER.DEST_JOBID="destination internal jobid" -DG.ARRIVED=20051010210929.000000 DATE=20051010210929.167712 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Accepted" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000001:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.ACCEPTED.FROM="JobController" DG.ACCEPTED.FROM_HOST="sending component hostname" DG.ACCEPTED.FROM_INSTANCE="sending component instance" DG.ACCEPTED.LOCAL_JOBID="new jobId (Condor Globus ...)" -DG.ARRIVED=20051010210929.000000 DATE=20051010210929.203602 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Transfer" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000003:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.TRANSFER.DESTINATION="LRMS" DG.TRANSFER.DEST_HOST="destination hostname" DG.TRANSFER.DEST_INSTANCE="destination instance" DG.TRANSFER.JOB="(nil)" DG.TRANSFER.RESULT="OK" DG.TRANSFER.REASON="detailed description of transfer" DG.TRANSFER.DEST_JOBID="destination internal jobid" -DG.ARRIVED=20051010210929.000000 DATE=20051010210929.249042 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Running" DG.JOBID="_CHANGE_ME_JOBID_" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000005:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.RUNNING.NODE="worker node" diff --git a/org.glite.jp.primary/examples/jpps-test.c b/org.glite.jp.primary/examples/jpps-test.c deleted file mode 100644 index e7fd993..0000000 --- a/org.glite.jp.primary/examples/jpps-test.c +++ /dev/null @@ -1,303 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include - -#include "jpps_H.h" -#include "jpps_.nsmap" - -#include "jptype_map.h" -#include "glite/security/glite_gsplugin.h" -#include "glite/security/glite_gscompat.h" - -#if GSOAP_VERSION <= 20602 -#define soap_call___jpsrv__RegisterJob soap_call___ns1__RegisterJob -#define soap_call___jpsrv__StartUpload soap_call___ns1__StartUpload -#define soap_call___jpsrv__CommitUpload soap_call___ns1__CommitUpload -#define soap_call___jpsrv__RecordTag soap_call___ns1__RecordTag -#define soap_call___jpsrv__FeedIndex soap_call___ns1__FeedIndex -#define soap_call___jpsrv__FeedIndexRefresh soap_call___ns1__FeedIndexRefresh -#define soap_call___jpsrv__GetJob soap_call___ns1__GetJob -#endif - -#define dprintf(FMT, ARGS...) printf(FMT, ##ARGS) -#include "glite/jp/ws_fault.c" -#define check_fault(SOAP, ERR) glite_jp_clientCheckFault((SOAP), (ERR), NULL, 0) - -static void usage(const char *me) -{ - fprintf(stderr,"%s: [-s server-url] operation args \n\n" - " operations are:\n" - " RegisterJob jobid owner\n" - " StartUpload jobid class commit_before mimetype\n" - " CommitUpload destination\n" - " RecordTag jobid tagname stringvalue ...\n" - " GetJobFiles jobid\n" - " GetJobAttr jobid attr\n" - " FeedIndex [yes (history)]\n" - " FeedIndexRefresh feedid\n" - ,me); - - exit (EX_USAGE); -} - -/* FIXME: new wsdl */ -#if 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 } - }, -}; -#endif - -static const char *orig2str(enum jptype__attrOrig orig) -{ - switch (orig) { - case jptype__attrOrig__SYSTEM: return "SYSTEM"; - case jptype__attrOrig__USER: return "USER"; - case jptype__attrOrig__FILE_: return "FILE"; - default: return "unknown"; - } -} - -int main(int argc,char *argv[]) -{ - char *server = NULL; - int opt,ret = 0; - struct soap *soap = soap_new2(SOAP_IO_KEEPALIVE,SOAP_IO_KEEPALIVE); - - if (argc < 2) usage(argv[0]); - -/* soap_init(soap); */ - soap_set_namespaces(soap, jpps__namespaces); - - soap_register_plugin(soap,glite_gsplugin); - - /*while ((opt = getopt(argc,argv,"s:")) >= 0) switch (opt) { - case 's': server = optarg; - break; - //case '?': usage(argv[0]); - }*/ - int i; - for (i = 0; i < argc-1; i++) - if (strcmp(argv[i], "-s") == 0) - server = argv[i+1]; - - if (server) { - argv += 2; - argc -= 2; - } - else server = "http://localhost:8901"; - - - if (!strcasecmp(argv[1],"RegisterJob")) { - struct _jpelem__RegisterJob in; - struct _jpelem__RegisterJobResponse empty; - - if (argc != 4) usage(argv[0]); - in.job = argv[2]; - in.owner = argv[3]; - ret = check_fault(soap, - soap_call___jpsrv__RegisterJob(soap,server,"",&in,&empty)); - } else if (!strcasecmp(argv[1], "StartUpload")) { - struct _jpelem__StartUpload in; - struct _jpelem__StartUploadResponse out; - - in.job = argv[2]; - in.class_ = argv[3]; - in.name = NULL; - in.commitBefore = atoi(argv[4]) + time(NULL); - in.contentType = argv[5]; - - if (argc != 6) usage(argv[0]); - if (!(ret = check_fault(soap, - soap_call___jpsrv__StartUpload(soap, server, "",&in,&out)))) - { - printf("Destination: %s\nCommit before: %s\n", out.destination, ctime(&out.commitBefore)); - } - } else if (!strcasecmp(argv[1], "CommitUpload")) { - struct _jpelem__CommitUpload in; - struct _jpelem__CommitUploadResponse empty; - - in.destination = argv[2]; - - if (argc != 3) usage(argv[0]); - if (!(ret = check_fault(soap, - soap_call___jpsrv__CommitUpload(soap, server, "",&in,&empty)))) { - /* OK */ - } - } else if (!strcasecmp(argv[1], "RecordTag")) { - struct _jpelem__RecordTag in; - struct _jpelem__RecordTagResponse empty; - struct jptype__tagValue tagval; - struct jptype__stringOrBlob val; - int idx; - - if (argc < 5 && argc % 2 == 0) usage(argv[0]); - - in.jobid = argv[2]; - in.tag = &tagval; - tagval.value = &val; - - for (idx = 3; idx < argc; idx += 2) { - tagval.name = argv[idx]; - memset(&val, 0, sizeof(val)); - GSOAP_SETSTRING(&val, argv[idx+1]); - - printf("%s ... ",tagval.name); - if (!(ret = check_fault(soap, - soap_call___jpsrv__RecordTag(soap, server, "",&in, &empty)))) { - /* OK */ - } - } - } - else if (!strcasecmp(argv[1],"FeedIndex")) { - char *ap[2] = { - "http://egee.cesnet.cz/en/Schema/LB/Attributes:RB", - "http://egee.cesnet.cz/en/Schema/JP/System:owner" - }; - int sizepq; - - struct jptype__stringOrBlob vals[2]; - memset(vals, 0, sizeof vals); - GSOAP_SETSTRING(vals, "/O=CESNET/O=Masaryk University/CN=Ales Krenek"); - GSOAP_SETSTRING(vals + 1, "Done"); - - struct jptype__primaryQuery q[] = { - { - "http://egee.cesnet.cz/en/Schema/JP/System:owner", - jptype__queryOp__EQUAL, - NULL, vals, NULL - }, - { - "http://egee.cesnet.cz/en/Schema/LB/Attributes:finalStatus", - jptype__queryOp__UNEQUAL, - NULL, vals+1, NULL - } - }; - GLITE_SECURITY_GSOAP_LIST_TYPE(jptype, primaryQuery) pq; - - GLITE_SECURITY_GSOAP_LIST_CREATE0(soap, pq, sizepq, struct jptype__primaryQuery, 2); - memcpy(GLITE_SECURITY_GSOAP_LIST_GET(pq, 0), &q[0], sizeof(q[0])); - memcpy(GLITE_SECURITY_GSOAP_LIST_GET(pq, 1), &q[1], sizeof(q[1])); - struct _jpelem__FeedIndex in = { - "http://some.index//", - 2,ap, - sizepq,pq, - 0, - 1 - }; - struct _jpelem__FeedIndexResponse out; - - in.history = argc >= 3 && !strcasecmp(argv[2],"yes"); - - if (!(ret = check_fault(soap,soap_call___jpsrv__FeedIndex(soap,server,"",&in,&out)))) - { - printf("FeedId: %s\nExpires: %s\n",out.feedId,ctime(&out.feedExpires)); - } - GLITE_SECURITY_GSOAP_LIST_DESTROY(soap, &in, conditions); - } -/* FIXME: new wsdl */ -#if 0 - } 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)); - } - } -#endif - else if (!strcasecmp(argv[1],"GetJobFiles")) { - struct _jpelem__GetJobFiles in; - struct _jpelem__GetJobFilesResponse out; - struct jptype__jppsFile *outf; - - if (argc != 3) usage(argv[0]); - in.jobid = argv[2]; - - if (!(ret = check_fault(soap,soap_call___jpsrv__GetJobFiles(soap,server,"", - &in,&out)))) - { - int i; - - printf("JobFiles:\n"); - - for (i=0; iclass_, - outf->name, - outf->url); - } - } - - } - else if (!strcasecmp(argv[1],"GetJobAttr")) { - struct _jpelem__GetJobAttributes in; - struct _jpelem__GetJobAttributesResponse out; - struct jptype__attrValue *outav; - - int rep = 1; - - if (argc < 4 || argc > 5) usage(argv[0]); - - if (argc == 5) rep = atoi(argv[4]); - - in.jobid = argv[2]; - in.__sizeattributes = 1; - in.attributes = &argv[3]; - - for (;rep;rep--) if (!(ret = check_fault(soap,soap_call___jpsrv__GetJobAttributes(soap,server,"",&in,&out)))) - { - int i; - - puts("Attribute values:"); - for (i=0; ivalue) ? - GSOAP_STRING(outav->value) : - "binary", - orig2str(outav->origin), - outav->originDetail, - ctime(&outav->timestamp)); - } - - } - - } - else { usage(argv[0]); ret = 1; } - - return ret; -} - - -/* XXX: we don't use it */ -SOAP_NMAC struct Namespace namespaces[] = { {NULL,NULL} }; diff --git a/org.glite.jp.primary/examples/jpps_store_test b/org.glite.jp.primary/examples/jpps_store_test deleted file mode 100755 index c461739..0000000 --- a/org.glite.jp.primary/examples/jpps_store_test +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash - -# usage: -# -# $ export X509_USER_PROXY=/trusted/peer/credentials -# $ /where/it/is/jpps_store_test \ -# -s jppps.host.name:port \ # default localhost:8901 -# -o '/job/owner/DN' \ # mandatory -# -t "name=value" ... \ # may occur multiple times -# -d /dump/file/template # optional -# -# in /dump/file/template occurences of _CHANGE_ME_JOBID_ are substituted with -# fake jobid generated by this script - -echodo() -{ - echo '**' $@ - "$@" || exit 1 -} - -if [ -f jpps-test ]; -then - jpps="./jpps-test" -elif [ -f glite-jp-primary-test ]; -then - jpps="./glite-jp-primary-test" -else - echo "glite-jp-primary-test or jpps-test not found!" - exit 1; -fi - -#getopt -s sh o:d:t:s: "$@" -#set -- `getopt -s sh o:d:t:s: "$@"` -while [ "x$1" != x ]; do case $1 in - -s) shift; jpps="$jpps -s $1";; - -o) shift; owner="$1";; - -d) shift; dump="$1";; - -t) shift; tags="$1|$tags";; -esac; shift; done - -[ x"$owner" = x ] && { echo -o required; exit 1; } - -jobid="https://nonexistent.test.server/jpps_store_test_$$" - -echodo $jpps RegisterJob $jobid "$owner" - -echodo $jpps GetJobAttr $jobid http://egee.cesnet.cz/en/Schema/JP/System:owner - -echodo $jpps GetJobAttr $jobid http://egee.cesnet.cz/en/Schema/JP/System:regtime - - -if [ -f "$dump" ]; then - sed "s|_CHANGE_ME_JOBID_|$jobid|" $dump >job.$$ - echodo $jpps StartUpload $jobid urn:org.glite.jp.primary:lb 1234 text/plain >start.$$ - cat start.$$ - dest=`grep '^Destination:' start.$$ | cut -d' ' -f2` - rm start.$$ - echodo globus-url-copy "file:$PWD/job.$$" $dest -# rm job.$$ - echodo $jpps CommitUpload "$dest" - -# does not pass authz check -- probably OK -# echodo $jpps GetJobFiles $jobid - - lbprefix="http://egee.cesnet.cz/en/Schema/LB/Attributes" - echodo $jpps GetJobAttr $jobid "$lbprefix:user" - echodo $jpps GetJobAttr $jobid "$lbprefix:finalStatus" -fi - -if [ "x$tags" != x ]; then - oIFS=$IFS - IFS='|' - set -- $tags - IFS=$oIFS - - while [ x$1 != x ]; do - value=`echo $1 | sed 's/^.*=//'` - name=`echo $1 | sed 's/=.*$//'` - - echodo $jpps RecordTag $jobid $name $value - - echodo $jpps GetJobAttr $jobid $name - - shift - done -fi diff --git a/org.glite.jp.primary/examples/recordmultitags.pl b/org.glite.jp.primary/examples/recordmultitags.pl deleted file mode 100755 index e7f05f0..0000000 --- a/org.glite.jp.primary/examples/recordmultitags.pl +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use SOAP::Lite; -use Data::Dumper; - -$ENV{HTTPS_CA_DIR}='/etc/grid-security/certificates'; -$ENV{HTTPS_VERSION}='3'; - -$cred = $ENV{X509_USER_PROXY} ? $ENV{X509_USER_PROXY} : "/tmp/x509up_u$<"; -$ENV{HTTPS_CERT_FILE}= $ENV{HTTPS_KEY_FILE} = $ENV{HTTPS_CA_FILE} = $cred; - -$proxy = shift; - -die "usage: $0 https://jp.primary.storage.org:8901/jpps https://some.nice.job/id attr=value ...\n\t\thttps://another.nice.job/id attr=value ...\n" - unless $ARGV[0]; - -$c = SOAP::Lite - -> proxy($proxy) - -> uri('http://glite.org/wsdl/services/jp'); - -service $c 'http://egee.cesnet.cz/cms/export/sites/egee/en/WSDL/HEAD/JobProvenancePS.wsdl' or die "service: $1\n"; - -ns $c 'http://glite.org/wsdl/elements/jp'; - -print "WSDL OK\n"; - -push @ARGV,'__KONEC__'; -$job = shift; -while ($_ = shift) { - if (! /(.*)=(.*)/) { - push @j,SOAP::Data->name(jobs => \SOAP::Data->value( - SOAP::Data->name(jobid=>$job), - @a - )); - - break if $_ eq '__KONEC__'; - - $job = $_; - @a = (); - } - else { - $name = $1; $value = $2; - print "$job: $name = $value\n"; - - push @a, SOAP::Data->name(attributes=>\SOAP::Data->value( - SOAP::Data->name(name=>$name), - SOAP::Data->name(value=> \SOAP::Data->value(SOAP::Data->name(string=>$value))) - )) - } -} - - -$req = SOAP::Data->value(@j); -print Dumper($req); - -on_fault $c sub { print Dumper($_[1]->fault); $fault = 1; }; - -$resp = RecordMultiTags $c $req; - -print Dumper $resp->body unless $fault; - diff --git a/org.glite.jp.primary/examples/sample_job_aborted b/org.glite.jp.primary/examples/sample_job_aborted deleted file mode 100644 index daf2674..0000000 --- a/org.glite.jp.primary/examples/sample_job_aborted +++ /dev/null @@ -1,9 +0,0 @@ -DATE=20060313114012.259501 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="UserInterface" DG.SRC_INSTANCE="" DG.EVNT="RegJob" DG.JOBID="https://scientific.civ.zcu.cz:9000/c63-U-RaOAAHp8YV8QMipw" DG.SEQCODE="UI=000001:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.REGJOB.JDL="blabla" DG.REGJOB.NS="NNNSSSS" DG.REGJOB.PARENT="" DG.REGJOB.JOBTYPE="SIMPLE" DG.REGJOB.NSUBJOBS="0" DG.REGJOB.SEED="uLU0BArrdV98O41PLThJ5Q" -DATE=20060313114012.332573 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="NetworkServer" DG.SRC_INSTANCE="" DG.EVNT="Accepted" DG.JOBID="https://scientific.civ.zcu.cz:9000/c63-U-RaOAAHp8YV8QMipw" DG.SEQCODE="UI=000002:NS=0000000001:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ACCEPTED.FROM="UserInterface" DG.ACCEPTED.FROM_HOST="sending component hostname" DG.ACCEPTED.FROM_INSTANCE="sending component instance" DG.ACCEPTED.LOCAL_JOBID="new jobId (Condor Globus ...)" -DATE=20060313114012.421854 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="NetworkServer" DG.SRC_INSTANCE="" DG.EVNT="EnQueued" DG.JOBID="https://scientific.civ.zcu.cz:9000/c63-U-RaOAAHp8YV8QMipw" DG.SEQCODE="UI=000002:NS=0000000003:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ENQUEUED.QUEUE="destination queue" DG.ENQUEUED.JOB="job description in receiver language" DG.ENQUEUED.RESULT="OK" DG.ENQUEUED.REASON="detailed description of transfer" -DATE=20060313114012.527562 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="DeQueued" DG.JOBID="https://scientific.civ.zcu.cz:9000/c63-U-RaOAAHp8YV8QMipw" DG.SEQCODE="UI=000002:NS=0000000004:WM=000001:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.DEQUEUED.QUEUE="queue name" DG.DEQUEUED.LOCAL_JOBID="new jobId assigned by the receiving component" -DATE=20060313114012.629873 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="HelperCall" DG.JOBID="https://scientific.civ.zcu.cz:9000/c63-U-RaOAAHp8YV8QMipw" DG.SEQCODE="UI=000002:NS=0000000004:WM=000003:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.HELPERCALL.HELPER_NAME="name of the called component" DG.HELPERCALL.HELPER_PARAMS="parameters of the call" DG.HELPERCALL.SRC_ROLE="CALLING" -DATE=20060313114012.730207 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="Match" DG.JOBID="https://scientific.civ.zcu.cz:9000/c63-U-RaOAAHp8YV8QMipw" DG.SEQCODE="UI=000002:NS=0000000004:WM=000005:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.MATCH.DEST_ID="destination CE/queue" -DATE=20060313114012.835673 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="HelperReturn" DG.JOBID="https://scientific.civ.zcu.cz:9000/c63-U-RaOAAHp8YV8QMipw" DG.SEQCODE="UI=000002:NS=0000000004:WM=000007:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.HELPERRETURN.HELPER_NAME="name of the called component" DG.HELPERRETURN.RETVAL="returned data" DG.HELPERRETURN.SRC_ROLE="CALLING" -DATE=20060313114012.940723 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="EnQueued" DG.JOBID="https://scientific.civ.zcu.cz:9000/c63-U-RaOAAHp8YV8QMipw" DG.SEQCODE="UI=000002:NS=0000000004:WM=000009:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ENQUEUED.QUEUE="destination queue" DG.ENQUEUED.JOB="job description in receiver language" DG.ENQUEUED.RESULT="OK" DG.ENQUEUED.REASON="detailed description of transfer" -DATE=20060313114013.040365 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="JobController" DG.SRC_INSTANCE="" DG.EVNT="Abort" DG.JOBID="https://scientific.civ.zcu.cz:9000/c63-U-RaOAAHp8YV8QMipw" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000001:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ABORT.REASON="just to test" diff --git a/org.glite.jp.primary/examples/sample_job_cleared b/org.glite.jp.primary/examples/sample_job_cleared deleted file mode 100644 index 65793b8..0000000 --- a/org.glite.jp.primary/examples/sample_job_cleared +++ /dev/null @@ -1,15 +0,0 @@ -DATE=20060313113718.964280 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="UserInterface" DG.SRC_INSTANCE="" DG.EVNT="RegJob" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000001:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.REGJOB.JDL="blabla" DG.REGJOB.NS="NNNSSSS" DG.REGJOB.PARENT="" DG.REGJOB.JOBTYPE="SIMPLE" DG.REGJOB.NSUBJOBS="0" DG.REGJOB.SEED="uLU0BArrdV98O41PLThJ5Q" -DATE=20060313113719.131973 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="NetworkServer" DG.SRC_INSTANCE="" DG.EVNT="Accepted" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000001:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ACCEPTED.FROM="UserInterface" DG.ACCEPTED.FROM_HOST="sending component hostname" DG.ACCEPTED.FROM_INSTANCE="sending component instance" DG.ACCEPTED.LOCAL_JOBID="new jobId (Condor Globus ...)" -DATE=20060313113719.202155 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="NetworkServer" DG.SRC_INSTANCE="" DG.EVNT="EnQueued" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000003:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ENQUEUED.QUEUE="destination queue" DG.ENQUEUED.JOB="job description in receiver language" DG.ENQUEUED.RESULT="OK" DG.ENQUEUED.REASON="detailed description of transfer" -DATE=20060313113719.316644 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="DeQueued" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000001:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.DEQUEUED.QUEUE="queue name" DG.DEQUEUED.LOCAL_JOBID="new jobId assigned by the receiving component" -DATE=20060313113719.442051 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="HelperCall" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000003:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.HELPERCALL.HELPER_NAME="name of the called component" DG.HELPERCALL.HELPER_PARAMS="parameters of the call" DG.HELPERCALL.SRC_ROLE="CALLING" -DATE=20060313113719.542691 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="Match" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000005:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.MATCH.DEST_ID="destination CE/queue" -DATE=20060313113719.632697 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="HelperReturn" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000007:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.HELPERRETURN.HELPER_NAME="name of the called component" DG.HELPERRETURN.RETVAL="returned data" DG.HELPERRETURN.SRC_ROLE="CALLING" -DATE=20060313113719.739851 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="EnQueued" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000009:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ENQUEUED.QUEUE="destination queue" DG.ENQUEUED.JOB="job description in receiver language" DG.ENQUEUED.RESULT="OK" DG.ENQUEUED.REASON="detailed description of transfer" -DATE=20060313113719.839754 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="JobController" DG.SRC_INSTANCE="" DG.EVNT="DeQueued" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000001:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.DEQUEUED.QUEUE="queue name" DG.DEQUEUED.LOCAL_JOBID="new jobId assigned by the receiving component" -DATE=20060313113719.955172 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="JobController" DG.SRC_INSTANCE="" DG.EVNT="Transfer" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000003:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.TRANSFER.DESTINATION="LRMS" DG.TRANSFER.DEST_HOST="destination hostname" DG.TRANSFER.DEST_INSTANCE="destination instance" DG.TRANSFER.JOB="(nil)" DG.TRANSFER.RESULT="OK" DG.TRANSFER.REASON="detailed description of transfer" DG.TRANSFER.DEST_JOBID="destination internal jobid" -DATE=20060313113720.062341 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Accepted" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000001:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ACCEPTED.FROM="JobController" DG.ACCEPTED.FROM_HOST="sending component hostname" DG.ACCEPTED.FROM_INSTANCE="sending component instance" DG.ACCEPTED.LOCAL_JOBID="new jobId (Condor Globus ...)" -DATE=20060313113720.158744 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Transfer" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000003:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.TRANSFER.DESTINATION="LRMS" DG.TRANSFER.DEST_HOST="destination hostname" DG.TRANSFER.DEST_INSTANCE="destination instance" DG.TRANSFER.JOB="(nil)" DG.TRANSFER.RESULT="OK" DG.TRANSFER.REASON="detailed description of transfer" DG.TRANSFER.DEST_JOBID="destination internal jobid" -DATE=20060313113720.261956 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Running" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000005:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.RUNNING.NODE="worker node" -DATE=20060313113720.371040 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Done" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000007:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.DONE.STATUS_CODE="OK" DG.DONE.REASON="reason for the change" DG.DONE.EXIT_CODE="0" -DATE=20060313113720.473822 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Clear" DG.JOBID="https://scientific.civ.zcu.cz:9000/Zziy0_yoV0-j9dtlNl1h7w" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000009:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.CLEAR.REASON="USER" diff --git a/org.glite.jp.primary/examples/sample_job_tagged_done b/org.glite.jp.primary/examples/sample_job_tagged_done deleted file mode 100644 index 1c0d57d..0000000 --- a/org.glite.jp.primary/examples/sample_job_tagged_done +++ /dev/null @@ -1,15 +0,0 @@ -DATE=20060313114125.327248 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="UserInterface" DG.SRC_INSTANCE="" DG.EVNT="RegJob" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000001:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.REGJOB.JDL="blabla" DG.REGJOB.NS="NNNSSSS" DG.REGJOB.PARENT="" DG.REGJOB.JOBTYPE="SIMPLE" DG.REGJOB.NSUBJOBS="0" DG.REGJOB.SEED="uLU0BArrdV98O41PLThJ5Q" -DATE=20060313114125.449249 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="NetworkServer" DG.SRC_INSTANCE="" DG.EVNT="Accepted" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000001:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ACCEPTED.FROM="UserInterface" DG.ACCEPTED.FROM_HOST="sending component hostname" DG.ACCEPTED.FROM_INSTANCE="sending component instance" DG.ACCEPTED.LOCAL_JOBID="new jobId (Condor Globus ...)" -DATE=20060313114125.577238 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="NetworkServer" DG.SRC_INSTANCE="" DG.EVNT="EnQueued" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000003:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ENQUEUED.QUEUE="destination queue" DG.ENQUEUED.JOB="job description in receiver language" DG.ENQUEUED.RESULT="OK" DG.ENQUEUED.REASON="detailed description of transfer" -DATE=20060313114125.708618 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="DeQueued" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000001:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.DEQUEUED.QUEUE="queue name" DG.DEQUEUED.LOCAL_JOBID="new jobId assigned by the receiving component" -DATE=20060313114125.817613 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="HelperCall" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000003:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.HELPERCALL.HELPER_NAME="name of the called component" DG.HELPERCALL.HELPER_PARAMS="parameters of the call" DG.HELPERCALL.SRC_ROLE="CALLING" -DATE=20060313114125.913634 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="Match" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000005:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.MATCH.DEST_ID="destination CE/queue" -DATE=20060313114126.015139 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="HelperReturn" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000007:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.HELPERRETURN.HELPER_NAME="name of the called component" DG.HELPERRETURN.RETVAL="returned data" DG.HELPERRETURN.SRC_ROLE="CALLING" -DATE=20060313114126.132840 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="EnQueued" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000009:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ENQUEUED.QUEUE="destination queue" DG.ENQUEUED.JOB="job description in receiver language" DG.ENQUEUED.RESULT="OK" DG.ENQUEUED.REASON="detailed description of transfer" -DATE=20060313114126.254850 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="JobController" DG.SRC_INSTANCE="" DG.EVNT="DeQueued" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000001:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.DEQUEUED.QUEUE="queue name" DG.DEQUEUED.LOCAL_JOBID="new jobId assigned by the receiving component" -DATE=20060313114126.359397 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="JobController" DG.SRC_INSTANCE="" DG.EVNT="Transfer" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000003:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.TRANSFER.DESTINATION="LRMS" DG.TRANSFER.DEST_HOST="destination hostname" DG.TRANSFER.DEST_INSTANCE="destination instance" DG.TRANSFER.JOB="(nil)" DG.TRANSFER.RESULT="OK" DG.TRANSFER.REASON="detailed description of transfer" DG.TRANSFER.DEST_JOBID="destination internal jobid" -DATE=20060313114126.462961 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Accepted" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000001:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.ACCEPTED.FROM="JobController" DG.ACCEPTED.FROM_HOST="sending component hostname" DG.ACCEPTED.FROM_INSTANCE="sending component instance" DG.ACCEPTED.LOCAL_JOBID="new jobId (Condor Globus ...)" -DATE=20060313114126.564692 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Transfer" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000003:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.TRANSFER.DESTINATION="LRMS" DG.TRANSFER.DEST_HOST="destination hostname" DG.TRANSFER.DEST_INSTANCE="destination instance" DG.TRANSFER.JOB="(nil)" DG.TRANSFER.RESULT="OK" DG.TRANSFER.REASON="detailed description of transfer" DG.TRANSFER.DEST_JOBID="destination internal jobid" -DATE=20060313114126.665625 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Running" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000005:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.RUNNING.NODE="worker node" -DATE=20060313114126.775084 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="LogMonitor" DG.SRC_INSTANCE="" DG.EVNT="Done" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000007:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.DONE.STATUS_CODE="OK" DG.DONE.REASON="reason for the change" DG.DONE.EXIT_CODE="0" -DATE=20060313114936.079576 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="Application" DG.SRC_INSTANCE="" DG.EVNT="UserTag" DG.JOBID="https://scientific.civ.zcu.cz:9000/rQn3lfqMWxWz3Dpm7kypqQ" DG.SEQCODE="UI=000002:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000007:LRMS=000000:APP=000002" DG.USER="/O=CESNET/O=Masaryk University/CN=Milos Mulac" DG.USERTAG.NAME="color" DG.USERTAG.VALUE="green" diff --git a/org.glite.jp.primary/examples/sample_job_waiting b/org.glite.jp.primary/examples/sample_job_waiting deleted file mode 100644 index f9b515f..0000000 --- a/org.glite.jp.primary/examples/sample_job_waiting +++ /dev/null @@ -1,8 +0,0 @@ -DG.ARRIVED=20051010204845.000000 DATE=20051010204845.409455 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="UserInterface" DG.SRC_INSTANCE="" DG.EVNT="RegJob" DG.JOBID="https://scientific.civ.zcu.cz:9200/1Yjk3Wlaspl07y45iX8Tng" DG.SEQCODE="UI=000001:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.REGJOB.JDL="blabla" DG.REGJOB.NS="NNNSSSS" DG.REGJOB.PARENT="" DG.REGJOB.JOBTYPE="SIMPLE" DG.REGJOB.NSUBJOBS="0" DG.REGJOB.SEED="uLU0BArrdV98O41PLThJ5Q" -DG.ARRIVED=20051010204847.000000 DATE=20051010204847.451986 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="DeQueued" DG.JOBID="https://scientific.civ.zcu.cz:9200/1Yjk3Wlaspl07y45iX8Tng" DG.SEQCODE="UI=000002:NS=0000000004:WM=000001:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.DEQUEUED.QUEUE="queue name" DG.DEQUEUED.LOCAL_JOBID="new jobId assigned by the receiving component" -DG.ARRIVED=20051010204847.000000 DATE=20051010204847.485702 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="HelperCall" DG.JOBID="https://scientific.civ.zcu.cz:9200/1Yjk3Wlaspl07y45iX8Tng" DG.SEQCODE="UI=000002:NS=0000000004:WM=000003:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.HELPERCALL.HELPER_NAME="name of the called component" DG.HELPERCALL.HELPER_PARAMS="parameters of the call" DG.HELPERCALL.SRC_ROLE="CALLING" -DG.ARRIVED=20051010204847.000000 DATE=20051010204847.520663 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="Match" DG.JOBID="https://scientific.civ.zcu.cz:9200/1Yjk3Wlaspl07y45iX8Tng" DG.SEQCODE="UI=000002:NS=0000000004:WM=000005:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.MATCH.DEST_ID="destination CE/queue" -DG.ARRIVED=20051010204847.000000 DATE=20051010204847.552015 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="HelperReturn" DG.JOBID="https://scientific.civ.zcu.cz:9200/1Yjk3Wlaspl07y45iX8Tng" DG.SEQCODE="UI=000002:NS=0000000004:WM=000007:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.HELPERRETURN.HELPER_NAME="name of the called component" DG.HELPERRETURN.RETVAL="returned data" DG.HELPERRETURN.SRC_ROLE="CALLING" -DG.ARRIVED=20051010204847.000000 DATE=20051010204847.584267 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="WorkloadManager" DG.SRC_INSTANCE="" DG.EVNT="EnQueued" DG.JOBID="https://scientific.civ.zcu.cz:9200/1Yjk3Wlaspl07y45iX8Tng" DG.SEQCODE="UI=000002:NS=0000000004:WM=000009:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.ENQUEUED.QUEUE="destination queue" DG.ENQUEUED.JOB="job description in receiver language" DG.ENQUEUED.RESULT="OK" DG.ENQUEUED.REASON="detailed description of transfer" -DG.ARRIVED=20051010204847.000000 DATE=20051010204847.381506 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="NetworkServer" DG.SRC_INSTANCE="" DG.EVNT="Accepted" DG.JOBID="https://scientific.civ.zcu.cz:9200/1Yjk3Wlaspl07y45iX8Tng" DG.SEQCODE="UI=000002:NS=0000000001:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.ACCEPTED.FROM="UserInterface" DG.ACCEPTED.FROM_HOST="sending component hostname" DG.ACCEPTED.FROM_INSTANCE="sending component instance" DG.ACCEPTED.LOCAL_JOBID="new jobId (Condor Globus ...)" -DG.ARRIVED=20051010204847.000000 DATE=20051010204847.409422 HOST="scientific.civ.zcu.cz" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=0 DG.SOURCE="NetworkServer" DG.SRC_INSTANCE="" DG.EVNT="EnQueued" DG.JOBID="https://scientific.civ.zcu.cz:9200/1Yjk3Wlaspl07y45iX8Tng" DG.SEQCODE="UI=000002:NS=0000000003:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000" DG.USER="/O=CESNET/O=Masaryk University/CN=Ales Krenek" DG.ENQUEUED.QUEUE="destination queue" DG.ENQUEUED.JOB="job description in receiver language" DG.ENQUEUED.RESULT="OK" DG.ENQUEUED.REASON="detailed description of transfer" diff --git a/org.glite.jp.primary/project/ChangeLog b/org.glite.jp.primary/project/ChangeLog deleted file mode 100644 index 072a7ec..0000000 --- a/org.glite.jp.primary/project/ChangeLog +++ /dev/null @@ -1,6 +0,0 @@ -1.5.0-1 -- Initial version - -1.5.0-2 -- configure updated - diff --git a/org.glite.jp.primary/project/build.number b/org.glite.jp.primary/project/build.number deleted file mode 100644 index 17d7d4d..0000000 --- a/org.glite.jp.primary/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Oct 15 06:52:14 CEST 2005 -module.build=39 diff --git a/org.glite.jp.primary/project/build.properties b/org.glite.jp.primary/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp.primary/project/configure.properties.xml b/org.glite.jp.primary/project/configure.properties.xml deleted file mode 100644 index cfa060a..0000000 --- a/org.glite.jp.primary/project/configure.properties.xml +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - -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} -gsoap_version=${ext.gsoap.version} -mysql_prefix=${with.mysql.prefix} -mysql_version=${ext.mysql.version} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -cppunit=${with.cppunit.prefix} -jpproject=${subsystem.project.dir} -project=${component.project.dir} -classads_prefix=${with.classads.prefix} -libtar_prefix=${with.libtar.prefix} - - - diff --git a/org.glite.jp.primary/project/properties.xml b/org.glite.jp.primary/project/properties.xml deleted file mode 100755 index 2149dd4..0000000 --- a/org.glite.jp.primary/project/properties.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.primary/project/tar_exclude b/org.glite.jp.primary/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.jp.primary/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.jp.primary/project/version.properties b/org.glite.jp.primary/project/version.properties deleted file mode 100644 index 5cacd92..0000000 --- a/org.glite.jp.primary/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.5.0 -module.age=2 diff --git a/org.glite.jp.primary/src/attrs.c b/org.glite.jp.primary/src/attrs.c deleted file mode 100644 index 6762102..0000000 --- a/org.glite.jp.primary/src/attrs.c +++ /dev/null @@ -1,278 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include - -#include "glite/lbu/trio.h" -#include "glite/jp/types.h" -#include "glite/jp/attr.h" -#include "glite/jp/backend.h" -#include "glite/jp/file_plugin.h" -#include "glite/jp/builtin_plugins.h" - -#include "feed.h" -#include "attrs.h" - -static struct { - char *namespace; - glite_jpps_fplug_data_t **plugins; - int nplugins; - char **opened_classes; // for each plugin contains name of the open class (NULL for no open file) - char **opened_files; // for each plugin contains name of the open file (NULL for no open file) - void **plugin_handles; // contains handle for each opened plugin (NULL for not opened) - void **file_handles; // contains handle for each opened file by plugin (NULL for not opened) -} *known_namespaces; - -static void scan_namespaces(glite_jp_context_t ctx) -{ - int i,j,k; - glite_jpps_fplug_data_t *pd; - - if (!ctx->plugins) return; - - for (i=0; ctx->plugins[i]; i++) { - pd = ctx->plugins[i]; - - if (pd->namespaces){ - for (j=0; pd->namespaces[j]; j++) { - for (k=0; known_namespaces && known_namespaces[k].namespace - && strcmp(pd->namespaces[j],known_namespaces[k].namespace); k++) {}; - - if (known_namespaces && known_namespaces[k].namespace) { - printf("Adding new plugin into namespace %s\n", known_namespaces[k].namespace); - known_namespaces[k].plugins = realloc(known_namespaces[k].plugins, - (known_namespaces[k].nplugins + 2) * sizeof(glite_jpps_fplug_data_t *)); - known_namespaces[k].plugins[known_namespaces[k].nplugins++] = pd; - known_namespaces[k].plugins[known_namespaces[k].nplugins] = NULL; - known_namespaces[k].namespace = pd->namespaces[j]; - known_namespaces[k].opened_classes = realloc(known_namespaces[k].opened_classes, - (known_namespaces[k].nplugins + 1) * sizeof(char*)); - known_namespaces[k].opened_classes[known_namespaces[k].nplugins-1] = NULL; - known_namespaces[k].opened_files = realloc(known_namespaces[k].opened_files, - (known_namespaces[k].nplugins + 1) * sizeof(char*)); - known_namespaces[k].opened_files[known_namespaces[k].nplugins-1] = NULL; - known_namespaces[k].plugin_handles = realloc(known_namespaces[k].plugin_handles, - (known_namespaces[k].nplugins + 1) * sizeof(void*)); - known_namespaces[k].plugin_handles[known_namespaces[k].nplugins-1] = NULL; - known_namespaces[k].file_handles = realloc(known_namespaces[k].file_handles, - (known_namespaces[k].nplugins + 1) * sizeof(void*)); - known_namespaces[k].file_handles[known_namespaces[k].nplugins-1] = NULL; - } - else { - printf("Adding new namespace %s\n", pd->namespaces[j]); - known_namespaces = realloc(known_namespaces,(k+2) * sizeof *known_namespaces); - known_namespaces[k].plugins = malloc(2 * sizeof(glite_jpps_fplug_data_t *)); - known_namespaces[k].plugins[0] = pd; - known_namespaces[k].plugins[1] = NULL; - known_namespaces[k].nplugins = 1; - known_namespaces[k].namespace = pd->namespaces[j]; - memset(known_namespaces+k+1,0,sizeof *known_namespaces); - known_namespaces[k].opened_classes = calloc(1, sizeof(char*)); - known_namespaces[k].opened_files = calloc(1, sizeof(char*)); - known_namespaces[k].plugin_handles = calloc(1, sizeof(void*)); - known_namespaces[k].file_handles = calloc(1, sizeof(void*)); - } - } - } - } -} - -static int merge_attrvals(glite_jp_attrval_t **out,int nout,const glite_jp_attrval_t *in) -{ - int nin; - - if (!in) return nout; - - for (nin=0; in[nin].name; nin++); - *out = realloc(*out,(nout+nin+1) * sizeof **out); - memcpy(*out + nout,in,(nin+1) * sizeof **out); - memset(*out + nout+nin, 0, sizeof **out); - return nout+nin; -} - -static void process_files(glite_jp_context_t ctx, const char *job, glite_jp_attrval_t** out, int* nout, const char* attr, const glite_jpps_fplug_data_t* plugin, const char* class, const char* uri, char **opened_class, char **opened_file, void **op_handle, void **of_handle){ - void *ph, *beh; - char** names = NULL; - int nnames; - int n; - glite_jp_error_t *keep_err = NULL; - - nnames = glite_jppsbe_get_names(ctx, job, class, &names); - - for (n = 0; n < nnames; n++){ - int plugin_ok = 0; - if (*opened_class && !strcmp(*opened_class, class) && ((!*opened_file && !names[n]) || !strcmp(*opened_file, names[n]))){ - ph = *op_handle; - beh = *of_handle; - plugin_ok = 1; - } - else{ - if (*opened_class){ - free(*opened_class); - *opened_class = NULL; - free(*opened_file); - *opened_file = NULL; - plugin->ops.close(plugin->fpctx, *op_handle); - *op_handle = NULL; - glite_jppsbe_close_file(ctx, *of_handle); - *of_handle = NULL; - } - if (! glite_jppsbe_open_file(ctx,job,class, names[n], O_RDONLY, &beh) - && !plugin->ops.open(plugin->fpctx,beh,uri,&ph)){ - plugin_ok = 1; - *opened_class = strdup(class); - if (names[n]) - *opened_file = strdup(names[n]); - else - *opened_file = NULL; - *op_handle = (void*)ph; - *of_handle = (void*)beh; - printf("opening plugin %i at class %s, file %s\n", *op_handle, class, names[n]); - } - } - if (plugin_ok){ - glite_jp_attrval_t* myattr; - // XXX: ignore errors - if (!plugin->ops.attr(plugin->fpctx,ph,attr,&myattr) && myattr) { - int k; - for (k=0; myattr[k].name; k++) { - myattr[k].origin = GLITE_JP_ATTR_ORIG_FILE; - if (!myattr[k].origin_detail) - trio_asprintf(&myattr[k].origin_detail,"%s %s", uri, names[n] ? names[n] : ""); - } - *nout = merge_attrvals(out,*nout,myattr); - free(myattr); - } - keep_err = ctx->error; ctx->error = NULL; - if (keep_err) { ctx->error = keep_err; keep_err = NULL; } - } - keep_err = ctx->error; ctx->error = NULL; - if (keep_err) { ctx->error = keep_err; keep_err = NULL; } - } - - for (n = 0; n < nnames; n++) - free(names[n]); - free(names); -} - -int glite_jpps_get_attrs(glite_jp_context_t ctx,const char *job,char **attr,int nattr,glite_jp_attrval_t **attrs_out) -{ - glite_jp_attrval_t *meta = NULL,*out = NULL,*tag_out = NULL; - char const **other = NULL; - int i,j,nmeta,nother,err = 0,nout = 0; - - nmeta = nother = 0; - glite_jp_clear_error(ctx); - -/* sort the queried attributes to backend metadata and others -- retrived by plugins - * XXX: assumes unique values for metadata. - */ - - for (i=0; iclasses[l]; l++) - process_files(ctx, job, &out, &nout, other[i], known_namespaces[j].plugins[k] - , known_namespaces[j].plugins[k]->classes[l] - , known_namespaces[j].plugins[k]->uris[l] - , &known_namespaces[j].opened_classes[k] - , &known_namespaces[j].opened_files[k] - , &known_namespaces[j].plugin_handles[k] - , &known_namespaces[j].file_handles[k]); - break; - } - } - free(attr_namespace); - } - -/* close plugins */ - for (i = 0; known_namespaces && known_namespaces[i].namespace; i++) - for (j = 0; known_namespaces[i].plugins[j]; j++) - if (known_namespaces[i].opened_classes[j]){ - known_namespaces[i].plugins[j]->ops.close(known_namespaces[i].plugins[j]->fpctx - , known_namespaces[i].plugin_handles[j]); - printf("closing plugin %i at class %s, file %s\n", known_namespaces[i].plugin_handles[j], known_namespaces[i].opened_classes[j], known_namespaces[i].opened_files[j]); - glite_jppsbe_close_file(ctx, known_namespaces[i].file_handles[j]); - if (known_namespaces[i].opened_classes[j]){ - free(known_namespaces[i].opened_classes[j]); - known_namespaces[i].opened_classes[j] = NULL; - } - if (known_namespaces[i].opened_files[j]){ - free(known_namespaces[i].opened_files[j]); - known_namespaces[i].opened_files[j] = NULL; - } - known_namespaces[i].plugin_handles[j] = NULL; - known_namespaces[i].file_handles[j] = NULL; - } - - nout = merge_attrvals(&out,nout,meta); - - free(meta); meta = NULL; - - if (nout) { - *attrs_out = out; - err = 0; - } - else { - glite_jp_error_t e; - e.code = ENOENT; - e.source = __FUNCTION__; - e.desc = "no attributes found"; - err = glite_jp_stack_error(ctx,&e); - } - -cleanup: - if (meta) for (i=0; i -#include -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "jpps_H.h" -#include "jptype_map.h" - -int glite_jpps_authz(glite_jp_context_t ctx,int op,const char *job,const char *owner) -{ - glite_jp_error_t err; - char buf[200]; - int i; - - memset(&err,0,sizeof err); - glite_jp_clear_error(ctx); - err.source = __FUNCTION__; - err.code = EPERM; - - switch (op) { - case SOAP_TYPE___jpsrv__RegisterJob: - case SOAP_TYPE___jpsrv__StartUpload: - case SOAP_TYPE___jpsrv__CommitUpload: - for (i=0; ctx->trusted_peers && ctx->trusted_peers[i]; i++) - if (!strcmp(ctx->trusted_peers[i],ctx->peer)) return 0; - err.desc = "you are not a trusted peer"; - return glite_jp_stack_error(ctx,&err); - - case SOAP_TYPE___jpsrv__GetJobFiles: - case SOAP_TYPE___jpsrv__GetJobAttributes: - case SOAP_TYPE___jpsrv__RecordTag: - assert(owner); - if (!ctx->noauth && strcmp(owner,ctx->peer)) { - err.desc = "you are not a job owner"; - glite_jp_stack_error(ctx,&err); - return 1; - } - return 0; - break; - - default: - snprintf(buf,sizeof buf,"%d: unknown operation",op); - err.desc = buf; - err.code = EINVAL; - return glite_jp_stack_error(ctx,&err); - } -} - -int glite_jpps_readauth(glite_jp_context_t ctx,const char *file) -{ - FILE *f = fopen(file,"r"); - glite_jp_error_t err; - int cnt = 0; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - if (!f) { - err.code = errno; - err.desc = file; - return glite_jp_stack_error(ctx,&err); - } - - ctx->trusted_peers = NULL; - while (!feof(f)) { - char buf[BUFSIZ]; - - if (fscanf(f,"%[^\n]\n",buf) != 1) { - err.code = EINVAL; - err.desc = file; - fclose(f); - return glite_jp_stack_error(ctx,&err); - } - - ctx->trusted_peers = realloc(ctx->trusted_peers, (cnt+2) * sizeof *ctx->trusted_peers); - ctx->trusted_peers[cnt++] = strdup(buf); - ctx->trusted_peers[cnt] = NULL; - } - fclose(f); - return 0; -} - diff --git a/org.glite.jp.primary/src/authz.h b/org.glite.jp.primary/src/authz.h deleted file mode 100644 index dae14b2..0000000 --- a/org.glite.jp.primary/src/authz.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/** - * Check authorisation of JPPS operation on job. - * - * \param[in] ctx JP context including peer name & other credentials (VOMS etc.) - * \param[in] op operation, one of SOAP_TYPE___jpsrv__* - * \param[in] job jobid of the job to decide upon - * \param[in] owner current known owner of the job (may be NULL), shortcut to avoid - * unnecessary database query. - * - * \retval 0 OK, operation permitted - * \retval EPERM denied - * \retval other error - */ - -int glite_jpps_authz(glite_jp_context_t ctx,int op,const char *job,const char *owner); - -int glite_jpps_readauth(glite_jp_context_t ctx,const char *file); - diff --git a/org.glite.jp.primary/src/backend.h b/org.glite.jp.primary/src/backend.h deleted file mode 100644 index 96b3ace..0000000 --- a/org.glite.jp.primary/src/backend.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_BACKEND_H -#define GLITE_JP_BACKEND_H - -#include -#include -#include - -#include "feed.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, - const char *class, /* must be filesystem-friendly */ - const char *name, /* optional name within the 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_get_names( - glite_jp_context_t ctx, - const char *job, - const char *class, - char ***names_out -); - -int glite_jppsbe_destination_info( - glite_jp_context_t ctx, - const char *destination, - char **job_out, - char **class_out, - char **name_out -); - -int glite_jppsbe_get_job_url( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name, /* optional within class */ - char **url_out -); - -int glite_jppsbe_open_file( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name, /* optional within class */ - int mode, - void **handle_out -); - -int glite_jppsbe_close_file( - glite_jp_context_t ctx, - void *handle -); - -int glite_jppsbe_file_attrs( - glite_jp_context_t ctx, - void *handle, - struct stat *buf -); - -int glite_jppsbe_pread( - glite_jp_context_t ctx, - void *handle, - 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_is_metadata( - glite_jp_context_t ctx, - const char *attr -); - -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[], - char *attrs[], - void *arg, - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[], - void *arg - ) -); - -/** mark the job as sent to this feed */ -int glite_jppsbe_set_fed( - glite_jp_context_t ctx, - const char *feed, - const char *job -); - -/** check whether the job has been already sent to this feed */ -int glite_jppsbe_check_fed( - glite_jp_context_t ctx, - const char *feed, - const char *job, - int *result -); - -/** store the feed to database */ -int glite_jppsbe_store_feed( - glite_jp_context_t ctx, - struct jpfeed *feed -); - -/** purge expired feeds */ -int glite_jppsbe_purge_feeds( - glite_jp_context_t ctx -); - -/** read stored feed into context */ -int glite_jppsbe_read_feeds( - glite_jp_context_t ctx -); - -#endif /* GLITE_JP_BACKEND_H */ diff --git a/org.glite.jp.primary/src/backend_private.h b/org.glite.jp.primary/src/backend_private.h deleted file mode 100644 index ceed681..0000000 --- a/org.glite.jp.primary/src/backend_private.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_BACKEND_PRIVATE_H -#define GLITE_JP_BACKEND_PRIVATE_H - -#include -#include -#include - -#include "feed.h" - -#include "glite/jp/backend.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, - const char *class, /* must be filesystem-friendly */ - const char *name, /* optional name within the 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_append_tags(void *fpctx, char *jobid, glite_jp_attrval_t *attr); - -/** mark the job as sent to this feed */ -int glite_jppsbe_set_fed( - glite_jp_context_t ctx, - const char *feed, - const char *job -); - -/** check whether the job has been already sent to this feed */ -int glite_jppsbe_check_fed( - glite_jp_context_t ctx, - const char *feed, - const char *job, - int *result -); - -/** store the feed to database */ -int glite_jppsbe_store_feed( - glite_jp_context_t ctx, - struct jpfeed *feed -); - -/** purge expired feeds */ -int glite_jppsbe_purge_feeds( - glite_jp_context_t ctx -); - -/** read stored feed into context */ -int glite_jppsbe_read_feeds( - glite_jp_context_t ctx -); - -#endif /* GLITE_JP_BACKEND_PRIVATE_H */ diff --git a/org.glite.jp.primary/src/bones_server.c b/org.glite.jp.primary/src/bones_server.c deleted file mode 100644 index 3f27989..0000000 --- a/org.glite.jp.primary/src/bones_server.c +++ /dev/null @@ -1,436 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/jp/file_plugin.h" - -#include "glite/lbu/srvbones.h" -#include "glite/security/glite_gss.h" - -#include -#include "glite/security/glite_gsplugin.h" - -#include "feed.h" -#include "backend_private.h" - -#include "soap_version.h" -#include "jpps_H.h" - -#define CONN_QUEUE 20 - -extern SOAP_NMAC struct Namespace jpis__namespaces[],jpps__namespaces[]; - -static int newconn(int,struct timeval *,void *); -static int request(int,struct timeval *,void *); -static int reject(int); -static int disconn(int,struct timeval *,void *); -static int data_init(void **data); - -static struct glite_srvbones_service stab = { - "JP Primary Storage", -1, newconn, request, reject, disconn -}; - -static time_t cert_mtime; -char *server_cert, *server_key, *cadir; -char file_prefix[PATH_MAX] = "/var/glite/log/dglogd.log"; -char *il_sock = NULL; -edg_wll_GssCred mycred = NULL; -static char *mysubj; - -static char *port = "8901"; -static int debug = 0; - -static glite_jp_context_t ctx; - -static int call_opts(glite_jp_context_t,char *,char *,int (*)(glite_jp_context_t,int,char **)); - -const char *glite_jp_default_namespace; - -pid_t master; - -int main(int argc, char *argv[]) -{ - int one = 1,opt,i; - edg_wll_GssStatus gss_code; - struct sockaddr_in a; - char *b_argv[20] = { "backend" },*p_argv[20] = { "plugins" },*com; - int b_argc,p_argc; - char buf[1000]; - int slaves = 10; - char *logfile = "/dev/null"; - char pidfile[PATH_MAX] = "/var/run/glite-jp-primarystoraged.pid"; - FILE *fpid; - - glite_jp_init_context(&ctx); - edg_wll_gss_gethostname(buf,sizeof buf); - buf[999] = 0; - ctx->myURL = buf; - - if (geteuid()) snprintf(pidfile,sizeof pidfile,"%s/glite-jp-primarystoraged.pid",getenv("HOME")); - - b_argc = p_argc = 1; - - while ((opt = getopt(argc,argv,"B:P:a:p:s:dl:i:c:k:nf:w:")) != EOF) switch (opt) { - case 'B': - assert(b_argc < 20); - if (com = strchr(optarg,',')) *com = 0; - - /* XXX: memleak -- who cares for once */ - asprintf(&b_argv[b_argc++],"-%s",optarg); - if (com) b_argv[b_argc++] = com+1; - - break; - case 'P': - assert(p_argc < 20); - p_argv[p_argc++] = optarg; - - break; - case 'a': - if (glite_jpps_readauth(ctx,optarg)) { - fprintf(stderr,"%s: %s\n",argv[0],glite_jp_error_chain(ctx)); - exit (1); - } - break; - case 'p': - port = optarg; - break; - case 'd': debug = 1; break; - case 's': slaves = atoi(optarg); - if (slaves <= 0) { - fprintf(stderr,"%s: -s %s: invalid number\n",argv[0],optarg); - exit(1); - } - break; - case 'l': logfile = optarg; break; - case 'i': strncpy(pidfile,optarg,PATH_MAX); pidfile[PATH_MAX-1] = 0; break; - case 'c': server_cert = optarg; break; - case 'k': server_key = optarg; break; - case 'n': ctx->noauth = 1; break; - case 'f': strncpy(file_prefix, optarg, PATH_MAX); file_prefix[PATH_MAX-1] = 0; break; - case 'w': il_sock = strdup(optarg); break; - case '?': fprintf(stderr,"usage: %s: -Bb,val ... -Pplugin.so ...\n" - "b is backend option\n",argv[0]); - exit (1); - } - - if (b_argc == 1) { - fputs("-B required\n",stderr); - exit (1); - } - - optind = 0; /* XXX: getopt used internally */ - if (glite_jppsbe_init(ctx,b_argc,b_argv)) { - fputs(glite_jp_error_chain(ctx), stderr); - exit(1); - } - - optind = 0; /* XXX: getopt used internally */ - if (b_argc > 1 && glite_jpps_fplug_load(ctx,p_argc,p_argv)) { - fputs(glite_jp_error_chain(ctx), stderr); - exit(1); - } - - srand48(time(NULL)); /* feed id generation */ - -#if GSOAP_VERSION <= 20602 - for (i=0; jpps__namespaces[i].id && strcmp(jpps__namespaces[i].id,"ns1"); i++); -#else - for (i=0; jpps__namespaces[i].id && strcmp(jpps__namespaces[i].id,"jpsrv"); i++); -#endif - assert(jpps__namespaces[i].id); - glite_jp_default_namespace = jpps__namespaces[i].ns; - - stab.conn = socket(PF_INET, SOCK_STREAM, 0); - if (stab.conn < 0) { - perror("socket"); - return 1; - } - - setsockopt(stab.conn,SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); - - a.sin_family = AF_INET; - a.sin_addr.s_addr = INADDR_ANY; - a.sin_port = htons(atoi(port)); - if (bind(stab.conn,(struct sockaddr *) &a, sizeof(a)) ) { - char buf[200]; - - snprintf(buf,sizeof(buf),"bind(%d)",atoi(port)); - perror(buf); - return 1; - } - - if (listen(stab.conn,CONN_QUEUE)) { - perror("listen()"); - return 1; - } - - if (!server_cert || !server_key) - fprintf(stderr, "%s: WARNING: key or certificate file not specified, " - "can't watch them for changes\n", - argv[0]); - - if ( cadir ) setenv("X509_CERT_DIR", cadir, 1); - edg_wll_gss_watch_creds(server_cert, &cert_mtime); - - if ( !edg_wll_gss_acquire_cred_gsi(server_cert, server_key, &mycred, &gss_code)) { - mysubj = strdup(mycred->name); - fprintf(stderr,"Server idenity: %s\n",mysubj); - } - else fputs("WARNING: Running unauthenticated\n",stderr); - - /* XXX: daemonise */ - - if (!debug) { - int lfd = open(logfile,O_CREAT|O_TRUNC|O_WRONLY,0600); - if (lfd < 0) { - fprintf(stderr,"%s: %s: %s\n",argv[0],logfile,strerror(errno)); - exit(1); - } - daemon(0,1); - dup2(lfd,1); - dup2(lfd,2); - } - - setpgrp(); /* needs for signalling */ - master = getpid(); - fpid = fopen(pidfile,"r"); - if ( fpid ) - { - int opid = -1; - - if ( fscanf(fpid,"%d",&opid) == 1 ) - { - if ( !kill(opid,0) ) - { - fprintf(stderr,"%s: another instance running, pid = %d\n",argv[0],opid); - return 1; - } - else if (errno != ESRCH) { perror("kill()"); return 1; } - } - fclose(fpid); - } else if (errno != ENOENT) { perror(pidfile); return 1; } - - fpid = fopen(pidfile, "w"); - if (!fpid) { perror(pidfile); return 1; } - fprintf(fpid, "%d", getpid()); - fclose(fpid); - - glite_srvbones_set_param(GLITE_SBPARAM_SLAVES_COUNT,slaves); - glite_srvbones_run(data_init,&stab,1 /* XXX: entries in stab */,debug); - - return 0; -} - -static int data_init(void **data) -{ - *data = (void *) soap_new(); - - printf("[%d] slave started\n",getpid()); - glite_jpps_srv_init(ctx); - glite_jppsbe_init_slave(ctx); /* XXX: global but slave's */ - //sleep(10); - if (glite_jppsbe_purge_feeds(ctx) || /* XXX: is there a better place for the call? */ - glite_jppsbe_read_feeds(ctx)) fputs(glite_jp_error_chain(ctx),stderr); - printf("[%d] slave init done\n",getpid()); - - return 0; -} - -static int newconn(int conn,struct timeval *to,void *data) -{ - struct soap *soap = (struct soap *) data; - glite_gsplugin_Context plugin_ctx; - - edg_wll_GssCred newcred = NULL; - edg_wll_GssStatus gss_code; - edg_wll_GssPrincipal client = NULL; - edg_wll_GssConnection connection; - - int ret = 0; - - soap_init2(soap,SOAP_IO_KEEPALIVE,SOAP_IO_KEEPALIVE); - soap_set_omode(soap, SOAP_IO_BUFFER); // set buffered response - // buffer set to SOAP_BUFLEN (default = 8k) - - soap_set_namespaces(soap,jpps__namespaces); - soap->user = (void *) ctx; /* XXX: one instance per slave */ - - switch (edg_wll_gss_watch_creds(server_cert,&cert_mtime)) { - case 0: break; - case 1: if (!edg_wll_gss_acquire_cred_gsi(server_cert,server_key, - &newcred,&gss_code)) - { - - printf("[%d] reloading credentials\n",getpid()); /* XXX: log */ - edg_wll_gss_release_cred(&mycred, NULL); - mycred = newcred; - - /* drop it too, it is recreated and reloads creds when necessary */ - if (ctx->other_soap) { - soap_end(ctx->other_soap); - soap_free(ctx->other_soap); - ctx->other_soap = NULL; - } - } - break; - case -1: - printf("[%d] edg_wll_gss_watch_creds failed\n", getpid()); /* XXX: log */ - break; - } - - /* TODO: DNS paranoia etc. */ - - if (edg_wll_gss_accept(mycred,conn,to,&connection,&gss_code)) { - char *et; - - edg_wll_gss_get_error(&gss_code,"",&et); - - fprintf(stderr,"[%d] GSS connection accept failed: %s\nClosing connection.\n",getpid(),et); - free(et); - ret = 1; - goto cleanup; - } - - ret = edg_wll_gss_get_client_conn(&connection, &client, NULL); - - if (ctx->peer) free(ctx->peer); - if (ret || client->flags & EDG_WLL_GSS_FLAG_ANON) { - printf("[%d] annonymous client\n",getpid()); - ctx->peer = NULL; - } - else { - printf("[%d] client DN: %s\n",getpid(),client->name); /* XXX: log */ - - ctx->peer = strdup(client->name); - edg_wll_gss_free_princ(client); - } - - glite_gsplugin_init_context(&plugin_ctx); - glite_gsplugin_set_connection(plugin_ctx, &connection); - soap_register_plugin_arg(soap,glite_gsplugin,plugin_ctx); - - return 0; - -cleanup: - soap_end(soap); - - return ret; -} - -static int request(int conn,struct timeval *to,void *data) -{ - struct soap *soap = data; - glite_jp_context_t ctx = soap->user; - - glite_gsplugin_set_timeout(glite_gsplugin_get_context(soap),to); - - soap->max_keep_alive = 1; /* XXX: prevent gsoap to close connection */ - soap_begin(soap); - if (soap_begin_recv(soap)) { - if (soap->error < SOAP_STOP) { - soap_send_fault(soap); - return EIO; - } - return ENOTCONN; - } - - soap->keep_alive = 1; - if (soap_envelope_begin_in(soap) - || soap_recv_header(soap) - || soap_body_begin_in(soap) - || jpps__serve_request(soap) -#if GSOAP_VERSION >= 20700 - || (soap->fserveloop && soap->fserveloop(soap)) -#endif - ) - { - soap_send_fault(soap); // sets soap->keep_alive back to 0 :( - // and closes connection - if (ctx->error) { - /* XXX: shall we die on some errors? */ - int err = ctx->error->code; - glite_jp_clear_error(ctx); - return err; - } - return ECANCELED; // let srv_bones know something is wrong - } -//printf("Ja cekam %d\n", getpid()); -//sleep(10); - if (glite_jp_run_deferred(ctx)) { - char *e; - fprintf(stderr,"[%d] %s\n",getpid(),e = glite_jp_error_chain(ctx)); - free(e); - } - return 0; -} - -static int reject(int conn) -{ - int flags = fcntl(conn, F_GETFL, 0); - - fcntl(conn,F_SETFL,flags | O_NONBLOCK); - edg_wll_gss_reject(conn); - - return 0; -} - -static int disconn(int conn,struct timeval *to,void *data) -{ - struct soap *soap = (struct soap *) data; - glite_jp_context_t ctx = soap->user; - - soap_end(soap); // clean up everything and close socket - if (ctx->other_soap) { - soap_end(ctx->other_soap); - soap_free(ctx->other_soap); - ctx->other_soap = NULL; - } - - return 0; -} - -#define WSPACE "\t\n " - -static int call_opts(glite_jp_context_t ctx,char *opt,char *name,int (*f)(glite_jp_context_t,int,char **)) -{ - int ac = 1,ret,my_optind; - char **av = malloc(sizeof *av),*ap; - - *av = name; - for (ap = strtok(opt,WSPACE); ap; ap = strtok(NULL,WSPACE)) { - av = realloc(av,(ac+1) * sizeof *av); - av[ac++] = ap; - } - - my_optind = optind; - optind = 0; - ret = f(ctx,ac,av); - optind = my_optind; - free(av); - return ret; -} - - -/* XXX: we don't use it */ -SOAP_NMAC struct Namespace namespaces[] = { {NULL,NULL} }; diff --git a/org.glite.jp.primary/src/classad_plugin.c b/org.glite.jp.primary/src/classad_plugin.c deleted file mode 100644 index 573f1a7..0000000 --- a/org.glite.jp.primary/src/classad_plugin.c +++ /dev/null @@ -1,232 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* -#include "glite/lb/context.h" -#include "glite/lb/jobstat.h" -#include "glite/lb/events.h" -#include "glite/lb/events_parse.h" -#include "glite/lb/trio.h" -*/ -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/jp/attr.h" -#include "glite/jp/known_attr.h" - -#include "glite/jp/file_plugin.h" -#include "glite/jp/backend.h" -#include "glite/jp/builtin_plugins.h" - -//#define INITIAL_NUMBER_EVENTS 100 -//#define INITIAL_NUMBER_STATES EDG_WLL_NUMBER_OF_STATCODES -//#define LB_PLUGIN_NAMESPACE "urn:org.glite.lb" - -//extern int processEvent(intJobStat *, edg_wll_Event *, int, int, char **); - - -typedef struct _classad_handle{ - char* data; - struct cclassad* ad; - time_t timestamp; -} classad_handle; - -static int classad_query(void *fpctx, void *handle, const char *attr, glite_jp_attrval_t **attrval); -static int classad_open(void *fpctx, void *bhandle, const char *uri, void **handle); -static int classad_open_str(void *fpctx, const char *str, const char *uri, const char *ns, void **handle); -static int classad_close(void *fpctx, void *handle); -static int classad_filecom(void *fpctx, void *handle); - -int init(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data) { - data->fpctx = ctx; - - data->uris = calloc(2,sizeof *data->uris); - data->uris[0] = strdup(GLITE_JP_FILETYPE_CLASSAD); - - data->classes = calloc(2,sizeof *data->classes); - data->classes[0] = strdup("classad"); - - data->namespaces = calloc(2, sizeof *data->namespaces); - data->namespaces[0] = strdup(GLITE_JP_JDL_NS); - - data->ops.open = classad_open; - data->ops.close = classad_close; - data->ops.attr = classad_query; - data->ops.open_str = classad_open_str; - data->ops.filecom = classad_filecom; - -#ifdef PLUGIN_DEBUG - fprintf(stderr,"classad_plugin: init OK\n"); -#endif - - return 0; -} - - -void done(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data) { - free(data->uris[0]); - free(data->classes[0]); - free(data->uris); - free(data->classes); - memset(data, 0, sizeof(*data)); -} - - -static int classad_open(void *fpctx, void *bhandle, const char *uri, void **handle) { - glite_jp_context_t ctx = (glite_jp_context_t) fpctx; - glite_jp_error_t err; - classad_handle* h; - void* fh; - int retval = 0; - - glite_jp_clear_error(ctx); - h = calloc(1, sizeof(classad_handle)); - h->data = NULL; - struct stat fattr; - glite_jppsbe_file_attrs(ctx, bhandle, &fattr); - h->timestamp = fattr.st_mtime; - - // read the classad file - char buf[1024]; - size_t nbytes; - off_t offset = 0; - - do{ - if (! (retval = glite_jppsbe_pread(ctx, bhandle, buf, sizeof buf, offset, &nbytes))){ - h->data = realloc(h->data, offset + nbytes); - memcpy(h->data + offset, buf, nbytes); - offset += nbytes; - } - else - goto fail; - }while(nbytes); - - h->ad = cclassad_create(h->data); - -#ifdef PLUGIN_DEBUG - fprintf(stderr,"classad_plugin: opened\n"); -#endif - - *handle = h; - - return 0; - -fail: - err.code = EIO; - err.desc = NULL; - err.source = __FUNCTION__; - glite_jp_stack_error(ctx,&err); - - return retval; -} - -static int classad_open_str(void *fpctx,const char *str,const char *uri,const char *ns,void **handle){ - classad_handle* h; - - h = calloc(1, sizeof(classad_handle)); - h->data = strdup(str); - h->ad = cclassad_create(h->data); - h->timestamp = 0; - -#ifdef PLUGIN_DEBUG - fprintf(stderr,"classad_plugin: opened\n"); -#endif - - *handle = h; - - return 0; - -} - -static int classad_close(void *fpctx,void *handle) { - classad_handle *h = (classad_handle *) handle; - - cclassad_delete(h->ad); - free(h->data); - free(h); - -#ifdef PLUGIN_DEBUG - fprintf(stderr,"classad plugin: close OK\n"); -#endif - return 0; -} - - -static int classad_query(void *fpctx,void *handle, const char *attr,glite_jp_attrval_t **attrval) { - glite_jp_context_t ctx = (glite_jp_context_t) fpctx; - glite_jp_error_t err; - glite_jp_attrval_t *av = NULL; - classad_handle* h = (classad_handle*)handle; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - char *str = NULL; - - if (! h->ad){ - err.code = ENOENT; - err.desc = strdup("Classad plugin: No classad string, cannot get attr!"); - *attrval = NULL; - printf("Exiting classat_query...\n"); - return glite_jp_stack_error(ctx,&err); - } - - if (!cclassad_evaluate_to_string(h->ad, strrchr(attr, ':')+1, &str) && - cclassad_evaluate_to_expr(h->ad, strrchr(attr, ':')+1, &str) && - !strcasecmp(str,"undefined")) { free(str); str = NULL; } - - if (str) { - //struct stat fattr; - /*XXX ignore error */ - //glite_jppsbe_file_attrs(ctx, h->bhandle, &fattr); - av = calloc(2, sizeof(glite_jp_attrval_t)); - av[0].name = strdup(attr); - av[0].value = str; str = NULL; - av[0].size = -1; - av[0].timestamp = h->timestamp; - av[0].origin = GLITE_JP_ATTR_ORIG_FILE; - } - else{ - printf("Classad plugin: bad attr!\n"); - } - - if (str) free(str); - - *attrval = av; - - if (av) - return 0; - else{ - err.code = ENOENT; - err.desc = attr; - return glite_jp_stack_error(ctx,&err); - } -} - -static int classad_filecom(void *fpctx, void *handle){ - return -1; -} - diff --git a/org.glite.jp.primary/src/feed.c b/org.glite.jp.primary/src/feed.c deleted file mode 100644 index f8b649f..0000000 --- a/org.glite.jp.primary/src/feed.c +++ /dev/null @@ -1,995 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "glite/jobid/strmd5.h" -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/jp/known_attr.h" -#include "glite/jp/file_plugin.h" -#include "glite/jp/builtin_plugins.h" - -#include "feed.h" -#include "is_client.h" -#include "backend_private.h" - -extern pid_t master; - -/* - * seconds before feed expires: should be - * XXX: should be configurable, default for real deployment sort of 1 hour - */ -#define FEED_TTL 360 - -/* XXX: configurable */ -#define BATCH_FEED_SIZE 200 - -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; - glite_jp_attrval_t qattr; - - if (strcmp(qry->attr,attr->name)) return 0; - - if (qry->origin != GLITE_JP_ATTR_ORIG_ANY && qry->origin != attr->origin) return 0; - - memset(&qattr,0,sizeof qattr); - qattr.name = qry->attr; - qattr.value = qry->value; - qattr.binary = qry->binary; - qattr.size = qry->size; - qattr.origin = qry->origin; - - /* XXX: don't assert */ - assert(glite_jp_attrval_cmp(ctx,attr,&qattr,&cmp) == 0); - - 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: - qattr.value = qry->value2; - qattr.size = qry->size2; - /* XXX: assert */ - assert(glite_jp_attrval_cmp(ctx,attr,&qattr,&cmp2) == 0); - return cmp >= 0 && cmp2 <= 0; - } -} - -/* retrieve all attributes for a feed */ -int full_feed( - glite_jp_context_t ctx, - const struct jpfeed *feed, - const char *job, - glite_jp_attrval_t **attrs) -{ - int i,ret,no_owner = 1; - char **ma = NULL; - - for (i=0; feed->attrs[i]; i++) - if (!strcmp(feed->attrs[i],GLITE_JP_ATTR_OWNER)) no_owner = 0; - - if (no_owner) { - ma = malloc((i+2) * sizeof *ma); - ma[0] = GLITE_JP_ATTR_OWNER; - memcpy(ma+1,feed->attrs,(i+1) * sizeof *ma); - } - ret = glite_jpps_get_attrs(ctx,job, - no_owner ? ma : feed->attrs, - i+no_owner,attrs); - free(ma); - return ret; -} - -/* XXX: limit on query size -- I'm lazy to malloc() */ -#define QUERY_MAX 100 - -static int is_feed_matching( - glite_jp_context_t ctx, - const struct jpfeed *feed, - const char *job, - -/* XXX: not checked for correctness, - assuming single occurence only */ - const glite_jp_attrval_t attrs[] -) -{ - int i,fed,ret = 0; - int qi[QUERY_MAX]; - char *owner = NULL; - glite_jp_attrval_t *attr_out = NULL; - glite_jp_attrval_t *newattr = NULL; - - glite_jp_clear_error(ctx); - - if (feed->qry) { - int j,complete = 1; - - memset(qi,0,sizeof qi); - for (i=0; feed->qry[i].attr; i++) { - int sat = 0; - assert(iqry[i].attr)) { - if (check_qry_item(ctx,feed->qry+i,attrs+j)) { - qi[i] = 1; - sat = 1; /* matched, needn't loop further */ - } - else return -1; /* can't be satisfied either */ - } - - if (!sat) complete = 0; - } - - /* not all attributes in query are known from input - * we have to retrieve job metadata from the backend - * - * XXX: It is not optimal to retrieve it here without sharing - * over multiple invocations of match_feed() for the same job. - */ - - if (!complete) { - char **attr = NULL; - - j=0; - for (i=0; feed->qry[i].attr; i++) if (!qi[i]) { - assert(jqry[i].attr; - j++; - } - - int err = glite_jpps_get_attrs(ctx, job, attr, j, &attr_out); - int k; - if (! err) for (k = 0; attr_out[k].name; k++); - if (!err && (k < j)){ - glite_jp_error_t err; - - memset(&err,0,sizeof err); - err.code = EIO; - err.source = __FUNCTION__; - err.desc = "complete query"; - ret = glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - for (i=0; feed->qry[i].attr; i++) { - for (j = 0; j < k; j++) - if (strcmp(feed->qry[i].attr, attr_out[j].name) == 0){ - if (!check_qry_item(ctx, feed->qry+i, attr_out+j)) { - ret = -1; - goto cleanup; - } - if (!strcmp(attr_out[i].name,GLITE_JP_ATTR_OWNER)) owner = attr_out[i].value; - break; - } - } - } - } - -cleanup: - if (attr_out){ - //for (i = 0; attr_out[i].name; i++) - // glite_jp_attrval_free(&(attr_out[i])); - free(attr_out); - } - return ret; -} - -static int match_feed( - glite_jp_context_t ctx, - const struct jpfeed *feed, - const char *job, - -/* XXX: not checked for correctness, - assuming single occurence only */ - const glite_jp_attrval_t attrs[] -) -{ - if (is_feed_matching(ctx, feed, job, attrs)) - return 0; - - glite_jp_attrval_t meta[QUERY_MAX+1]; - char *owner = NULL; - int fed, i; - - glite_jppsbe_check_fed(ctx,feed->id,job,&fed); - if (!fed) { - glite_jp_attrval_t *a; - full_feed(ctx,feed,job,&a); - for (i=0; a[i].name && strcmp(a[i].name,GLITE_JP_ATTR_OWNER); i++); - owner = a[i].value; - - /* XXX: better error handling ? */ - if (!glite_jpps_single_feed(ctx,feed->id,0,feed->destination,job,owner,a)) - glite_jppsbe_set_fed(ctx,feed->id,job); /* XXX: on error? */ - - for (i=0; a[i].name; i++) glite_jp_attrval_free(a+i,0); - free(a); - } - else { - int mf = 0; - if (!owner) { - mf = 1; - memset(meta,0,sizeof meta); - meta[0].name = strdup(GLITE_JP_ATTR_OWNER); - glite_jppsbe_get_job_metadata(ctx,job,meta); - owner = meta[0].value; - } - glite_jpps_single_feed(ctx,feed->id,0,feed->destination,job,owner,attrs); - if (mf) - for (i=0; meta[i].name; i++) glite_jp_attrval_free(meta+i,0); - } - - return 0; -} - -static int match_feed_multi( - glite_jp_context_t ctx, - const struct jpfeed *feed, - const char **jobs, - const glite_jp_attrval_t **attrs -) -{ - glite_jp_attrval_t meta[QUERY_MAX+1]; - char **owners = NULL; - int *fed = NULL; - glite_jp_attrval_t **attrs_to_feed = NULL; - char **jobs_to_feed = NULL; - int i, k; - int j = 0; - - for (i = 0; jobs[i]; i++){ - if (! is_feed_matching(ctx, feed, jobs[i], attrs[i])){ - owners = realloc(owners, (j+1)*sizeof(*owners)); - attrs_to_feed = realloc(attrs_to_feed, (j+1)*sizeof(attrs_to_feed)); - jobs_to_feed = realloc(jobs_to_feed, (j+1)*sizeof(jobs_to_feed)); - fed = realloc(fed, (j+1)*sizeof(*fed)); - attrs_to_feed[j] = attrs[i]; - jobs_to_feed[j] = jobs[i]; - glite_jppsbe_check_fed(ctx,feed->id,jobs[i],&fed[j]); - if (!fed){ - glite_jp_attrval_t *a; - full_feed(ctx,feed,jobs[i],&a); - int k; - for (k=0; a[k].name && strcmp(a[k].name,GLITE_JP_ATTR_OWNER); k++); - owners[j] = strdup(a[k].value); - for (k=0; a[k].name; k++) glite_jp_attrval_free(a+k, 0); - free(a); - } - else{ - memset(meta,0,sizeof meta); - meta[0].name = strdup(GLITE_JP_ATTR_OWNER); - glite_jppsbe_get_job_metadata(ctx,jobs[i],meta); - owners[j] = strdup(meta[0].value); - for (k = 0; meta[k].name; k++) glite_jp_attrval_free(meta+k,0); - } - j++; - } - } - - if (! glite_jpps_multi_feed(ctx, feed->id, 0, j, - feed->destination, jobs_to_feed, owners, attrs_to_feed)) - for (i = 0; i < j; i++) - if (fed[i]) - glite_jppsbe_set_fed(ctx,feed->id,jobs_to_feed[i]); - - for (i = 0; i < j; i++){ - free(owners[i]); - //free(jobs_to_feed[i]); - //glite_jp_attrval_free(attrs_to_feed[i],0); - } - free(jobs_to_feed); - free(owners); - free(attrs_to_feed); - free(fed); - - return 0; -} - -/* TODO: overit, ze do dalsich atributu se leze az kdyz matchuji metadata - * kdyby ne, stejne se to nepovede ; - * totez pro match_file */ - -typedef struct{ - char *job; - glite_jp_attrval_t *attrs; -} match_attr; - - -static int match_attr_deferred( - glite_jp_context_t ctx, - void *ma -) -{ - char *job = ((match_attr*)ma)->job; - glite_jp_attrval_t *attrs = ((match_attr*)ma)->attrs; - - struct jpfeed *f = (struct jpfeed *) ctx->feeds; - int i,j,doit; - - for (;f; f = f->next) { - doit = 0; - - for (i=0; !doit && f->attrs[i]; i++) - for (j=0; !doit && attrs[j].name; j++) - if (!strcmp(f->attrs[i],attrs[j].name)) doit = 1; - - /* XXX: ignore any errors */ - if (doit) match_feed(ctx,f,job,attrs); - } - - free(((match_attr*)ma)->job); - //free(((match_attr*)ma)->attrs); - - return glite_jp_clear_error(ctx); -} - -int glite_jpps_match_attr( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t attrs[] -) -{ - match_attr *ma = malloc(sizeof *ma); - ma->job = strdup(job); - ma->attrs = malloc(sizeof(*ma->attrs)); - ma->attrs[0].name = NULL; - int i; - for (i = 0; attrs[i].name; i++){ - ma->attrs = realloc(ma->attrs, (i+2)*sizeof(*ma->attrs)); - - memcpy(&(ma->attrs[i]), &(attrs[i]), sizeof(*ma->attrs)); - ma->attrs[i].name = strdup(attrs[i].name); - ma->attrs[i].value = strdup(attrs[i].value); - - ma->attrs[i+1].name = NULL; - } - glite_jp_add_deferred(ctx, match_attr_deferred, ma); -} - -typedef struct{ - char **jobs; - glite_jp_attrval_t **attrs; -} match_attr_multi; - -static int match_attr_multi_deferred( - glite_jp_context_t ctx, - void *m -) -{ - match_attr_multi *mam = (match_attr_multi*)m; - struct jpfeed *f = (struct jpfeed *) ctx->feeds; - int i, j, k, doit; - - for (;f; f = f->next) { - doit = 0; - for (i = 0; !doit && f->attrs[i]; i++) - for (j = 0; !doit && mam->attrs[j]; j++) - for (k = 0; !doit && mam->attrs[j][k].name; k++) - if (!strcmp(f->attrs[i],mam->attrs[j][k].name)) doit = 1; - - if (doit) match_feed_multi(ctx, f, mam->jobs, mam->attrs); - } - - for (i=0; mam->jobs[i]; i++){ - free(mam->jobs[i]); - if (mam->attrs[i]) - for (j = 0; mam->attrs[i][j].name; j++) - glite_jp_attrval_free(&(mam->attrs[i][j]), 0); - free(mam->attrs[i]); - } - free(mam->jobs); - free(mam->attrs); - - return 0; -} - -int glite_jpps_match_attr_multi( - glite_jp_context_t ctx, - const char **jobs, - const glite_jp_attrval_t **attrs -) -{ - int i, j; - - match_attr_multi *mam = malloc(sizeof *mam); - mam->jobs = NULL; - mam->attrs = NULL; - for (i = 0; jobs[i]; i++) { - mam->jobs = realloc(mam->jobs, (i+2)*sizeof(*mam->jobs)); - mam->jobs[i] = strdup(jobs[i]); - mam->attrs = realloc(mam->attrs, (i+2)*sizeof(*mam->attrs)); - mam->attrs[i] = calloc(0, sizeof(**mam->attrs)); - for (j = 0; attrs[i][j].name; j++){ - mam->attrs[i] = realloc(mam->attrs[i], (j+2)*sizeof(**mam->attrs)); - memcpy(&(mam->attrs[i][j]), &(attrs[i][j]), sizeof(**mam->attrs)); - mam->attrs[i][j].name = strdup(attrs[i][j].name); - mam->attrs[i][j].value = strdup(attrs[i][j].value); - mam->attrs[i][j].origin_detail = NULL;//strdup(attrs[i][j].origin_detail); - } - mam->attrs[i][j].name = NULL; - } - mam->jobs[i] = NULL; - mam->attrs[i] = NULL; - - glite_jp_add_deferred(ctx, match_attr_multi_deferred, mam); - - return 0; - -/* TODO - int i,j; - - puts(__FUNCTION__); - for (i=0; jobs[i]; i++) { - printf("job %s\n",jobs[i]); - - for (j=0; attrs[i][j].name; j++) { - printf("\t%s = %s\n",attrs[i][j].name,attrs[i][j].value); - } - } - - return 0;*/ -} - -static int attr_void_cmp(const void *a, const void *b) -{ - char const * const *ca = (char const * const *) a; - char const * const *cb = (char const * const *) b; - return strcmp(*ca,*cb); -} - -static void attr_union(char **a, char **b, char ***c) -{ - int ca = 0,cb = 0,cnt,i,j; - char **out; - - if (a) for (ca = 0; a[ca]; ca++); - if (b) for (cb = 0; b[cb]; cb++); - out = malloc((ca+cb+1) * sizeof *out); - if (a) memcpy(out,a,ca * sizeof *out); - if (b) memcpy(out+ca,b,cb * sizeof *out); - out[cnt = ca+cb] = NULL; - qsort(out,cnt,sizeof *out,attr_void_cmp); - - for (i=0; i i+1) memmove(out+i+1,out+j,(cnt-j) * sizeof *out); - cnt -= j-i-1; - } - assert(cnt); - out[cnt] = NULL; - - *c = out; -} - -typedef struct{ - char *job; - char *class; - char *name; -} match_file; - -int match_file_deferred( - glite_jp_context_t ctx, - void *mf -) -{ - char *job = ((match_file*)mf)->job; - char *class = ((match_file*)mf)->class; - char *name = ((match_file*)mf)->name; - - glite_jpps_fplug_data_t **pd = NULL; - int pi; - void *bh = NULL; - int ret; - struct jpfeed *f = ctx->feeds; - glite_jp_attrval_t meta[QUERY_MAX+1]; - - int nvals = 0,j,i; - char **attrs = NULL, **attrs2; - glite_jp_attrval_t *vals = NULL,*oneval; - - fprintf(stderr,"%s: %s %s %s\n",__FUNCTION__,job,class,name); - - memset(meta,0,sizeof meta); - meta[0].name = strdup(GLITE_JP_ATTR_OWNER); - glite_jppsbe_get_job_metadata(ctx,job,meta); - - if (!f) return 0; - - switch (glite_jpps_fplug_lookup_byclass(ctx,class,&pd)) { - case ENOENT: return 0; /* XXX: shall we complain? */ - case 0: break; - default: return -1; - } - - - for (;f;f=f->next) { - attr_union(attrs,f->attrs,&attrs2); - free(attrs); - attrs = attrs2; - } - - vals = malloc(sizeof *vals); - vals[0].name = NULL; - - for (pi=0; pd[pi]; pi++) { - int ci; - for (ci=0; pd[pi]->uris[ci]; ci++) if (!strcmp(pd[pi]->classes[ci],class)) { - void *ph; - - if (!bh && (ret = glite_jppsbe_open_file(ctx,job,pd[pi]->classes[ci],name,O_RDONLY,&bh))) { - free(pd); - return ret; - } - - if (pd[pi]->ops.open(pd[pi]->fpctx,bh,class,&ph)) { - /* XXX: complain more visibly */ - fputs("plugin open failed\n",stderr); - continue; - } - - for (i=0; attrs[i]; i++) - if (!pd[pi]->ops.attr(pd[pi]->fpctx,ph,attrs[i],&oneval)) { - /* XXX: ignore error */ - for (j=0; oneval[j].name; j++); - vals = realloc(vals,(nvals+j+1) * sizeof *vals); - memcpy(vals+nvals,oneval,(j+1) * sizeof *vals); - nvals += j; - free(oneval); - } - - pd[pi]->ops.close(pd[pi]->fpctx,ph); - } - } - - free(attrs); - - if (bh) glite_jppsbe_close_file(ctx,bh); - free(pd); - - for (f = ctx->feeds; f; f=f->next) { - int k,fed; - glite_jp_attrval_t * fattr; - - match_feed(ctx,f,job,vals); - -/* covered by match_feed() - glite_jppsbe_check_fed(ctx,f->id,job,&fed); - if (!fed) full_feed(ctx,f,job,&fattr); - else { - fattr = malloc((nvals+1) * sizeof *fattr); - - j = 0; - for (i=0; iattrs[k]; k++) - if (!strcmp(f->attrs[k],vals[i].name)) - memcpy(fattr+j++,vals+i,sizeof *fattr); - - memset(fattr+j,0,sizeof *fattr); - - } - for (i=0; meta[i].name && strcmp(meta[i].name,GLITE_JP_ATTR_OWNER); i++); - if (!glite_jpps_single_feed(ctx,f->id,0,f->destination,job,meta[i].value,fattr) && !fed) - glite_jppsbe_set_fed(ctx,f->id,job); - - if (!fed) for (i=0; fattr[i].name; i++) glite_jp_attrval_free(fattr+i,0); - free(fattr); -*/ - } - - for (i=0; vals[i].name; i++) glite_jp_attrval_free(vals+i,0); - free(vals); - - for (i=0; meta[i].name; i++) glite_jp_attrval_free(meta+i,0); - - free(((match_file*)mf)->job); - free(((match_file*)mf)->class); - free(((match_file*)mf)->name); - - return 0; -} - -int glite_jpps_match_file( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name -) -{ - match_file* mf = malloc(sizeof(*mf)); - mf->job = strdup(job); - mf->class = strdup(class); - if (name) - mf->name = strdup(name); - else - mf->name = NULL; - - glite_jp_add_deferred(ctx, match_file_deferred, mf); -} - -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); -} - -static struct jpfeed *make_jpfeed( - const char *destination, - char const *const *attrs, - const glite_jp_query_rec_t *qry, - char *id, - time_t expires) -{ - int i; - struct jpfeed *f = calloc(1,sizeof *f); - - f->id = id ? strdup(id) : NULL; - f->destination = strdup(destination); - f->expires = expires; - for (i=0; attrs[i]; i++) { - f->attrs = realloc(f->attrs,(i+2) * sizeof *f->attrs); - f->attrs[i] = strdup(attrs[i]); - f->attrs[i+1] = NULL; - } - for (i=0; qry[i].attr; 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); - } - - return f; -} - -void jpfeed_free(struct jpfeed *f) -{ - int i; - - assert(f->njobs == 0); /* XXX: we shouldn't do this */ - - free(f->id); - free(f->destination); - if (f->attrs) { - for (i=0; f->attrs[i]; i++) free(f->attrs[i]); - free(f->attrs); - } - for (i=0; inmeta_attr; i++) free(f->meta_attr[i]); - free(f->meta_attr); - for (i=0; inother_attr; i++) free(f->other_attr[i]); - free(f->other_attr); - - if (f->qry) { - for (i=0; f->qry[i].attr; i++) glite_jp_free_query_rec(f->qry+i); - free(f->qry); - } - - for (i=0; inmeta_qry; i++) glite_jp_free_query_rec(f->meta_qry+i); - free(f->meta_qry); - for (i=0; inother_qry; i++) glite_jp_free_query_rec(f->other_qry+i); - free(f->other_qry); - - /* XXX: no next */ - - free(f); -} - -static void drop_jobs(struct jpfeed *f) -{ - int i,j; - for (i=0; injobs; i++) { - for (j=0; f->job_attrs[i][j].name; j++) - glite_jp_attrval_free(&f->job_attrs[i][j],0); - free(f->job_attrs[i]); - free(f->jobs[i]); - free(f->owners[i]); - } - free(f->job_attrs); f->job_attrs = NULL; - free(f->jobs); f->jobs = NULL; - free(f->owners); f->owners = NULL; - f->njobs = 0; -} - -static int drain_feed(glite_jp_context_t ctx, struct jpfeed *f,int done) -{ - int ret = 0; - glite_jp_clear_error(ctx); - if (f->njobs) { - int i; - ret = glite_jpps_multi_feed(ctx,f->id,done,f->njobs,f->destination,f->jobs,f->owners,f->job_attrs); - - if (!ret && f->continuous) for (i=0; injobs; i++) glite_jppsbe_set_fed(ctx,f->id,f->jobs[i]); - drop_jobs(f); - } - return ret; -} - -static int feed_query_callback( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t meta[], - void *arg) -{ - int i,j,nout = 0,ec; - glite_jp_error_t err; - struct jpfeed *f = arg; - glite_jp_attrval_t *other = NULL,*out = NULL; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - glite_jp_clear_error(ctx); - -/* retrieve other attributes */ - ec = glite_jpps_get_attrs(ctx,job,f->other_attr,f->nother_attr,&other); - switch (ec) { - case 0: break; - case ENOENT: glite_jp_clear_error(ctx); break; - default: - err.code = EIO; - err.desc = "retrieve job attributes"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - -/* filter on non-meta query items */ - if (f->nother_qry && !other) goto cleanup; /* unknown values can't match */ - - for (i=0; inother_qry; i++) { - for (j=0; other[j].name; j++) - if (check_qry_item(ctx,f->other_qry+i,other+j)) break; - if (!other[j].name) goto cleanup; /* no match is not an error */ - } - -/* extract attributes to be fed, stack the job for a batch feed */ - for (i=0; meta && meta[i].name; i++) - for (j=0; jnmeta_attr; j++) - if (!strcmp(meta[i].name,f->meta_attr[j])) { - out = realloc(out,(nout+2) * sizeof *out); - glite_jp_attrval_copy(out+nout,meta+i); - nout++; - } - - if (other) - for (i=0; other[i].name; i++) - for (j=0; jint_other_attr; j++) - if (!strcmp(other[i].name,f->other_attr[j])) { - out = realloc(out,(nout+2) * sizeof *out); - glite_jp_attrval_copy(out+nout,other+i); - nout++; - } - - if (nout) { - int oi; - - memset(out+nout,0,sizeof *out); - f->jobs = realloc(f->jobs,(f->njobs+1)*sizeof *f->jobs); - f->jobs[f->njobs] = strdup(job); - f->job_attrs = realloc(f->job_attrs,(f->njobs+1)*sizeof *f->job_attrs); - f->job_attrs[f->njobs] = out; - out = NULL; - - for (oi=0; strcmp(meta[oi].name,GLITE_JP_ATTR_OWNER); oi++); - assert(meta[oi].name); - f->owners = realloc(f->owners,(f->njobs+1)*sizeof *f->owners); - f->owners[f->njobs] = strdup(meta[oi].value); - - f->njobs++; - } - -/* run the feed eventually */ - if (f->njobs >= BATCH_FEED_SIZE && drain_feed(ctx,f,0)) { - err.code = EIO; - err.desc = "sending batch feed"; - glite_jp_stack_error(ctx,&err); - } - -cleanup: - for (i=0; other && other[i].name; i++) glite_jp_attrval_free(other+i,0); - free(other); - - return err.code; -} - - -static int run_feed_deferred(glite_jp_context_t ctx,void *feed) -{ - struct jpfeed *f = feed; - int i,m,o,cnt,ret = 0; - char **meta; - - glite_jp_clear_error(ctx); -/* count "meta" attributes */ - cnt = 0; - for (i=0; f->attrs[i]; i++) - if (glite_jppsbe_is_metadata(ctx,f->attrs[i])) cnt++; - - f->meta_attr = cnt ? malloc((cnt+1) * sizeof *f->meta_attr) : NULL; - f->nmeta_attr = cnt; - - f->other_attr = i-cnt ? malloc((i-cnt+1) * sizeof *f->other_attr) : NULL; - f->nother_attr = i-cnt; - -/* sort attributes to "meta" and others */ - m = o = 0; - for (i=0; f->attrs[i]; i++) - if (glite_jppsbe_is_metadata(ctx,f->attrs[i])) - if (!strcmp(f->attrs[i],GLITE_JP_ATTR_OWNER)) { - free(f->attrs[i]); - f->nmeta_attr--; - } - else f->meta_attr[m++] = f->attrs[i]; - else { - /* XXX: jobid and owner are sent anyway */ - if (!strcmp(f->attrs[i],GLITE_JP_ATTR_JOBID)) { - free(f->attrs[i]); - f->nother_attr--; - } - else f->other_attr[o++] = f->attrs[i]; - } - - if (f->nmeta_attr == 0) { free(f->meta_attr); f->meta_attr = NULL; } - if (f->nother_attr == 0) { free(f->other_attr); f->other_attr = NULL; } - - if (f->meta_attr) f->meta_attr[m] = NULL; - if (f->other_attr) f->other_attr[o] = NULL; - - -/* the same for query records */ - cnt = 0; - for (i=0; f->qry[i].attr; i++) - if (glite_jppsbe_is_metadata(ctx,f->qry[i].attr)) cnt++; - - f->meta_qry = cnt ? malloc((cnt+1) * sizeof *f->meta_qry) : NULL; - if (f->meta_qry) memset(f->meta_qry+cnt,0,sizeof *f->meta_qry); - f->nmeta_qry = cnt; - f->other_qry = i-cnt ? malloc((i-cnt+1) * sizeof *f->other_qry) : NULL; - f->nother_qry = i-cnt; - - m = o = 0; - for (i=0; f->qry[i].attr; i++) - if (glite_jppsbe_is_metadata(ctx,f->qry[i].attr)) memcpy(f->meta_qry+m++,f->qry+i,sizeof *f->meta_qry); - else memcpy(f->other_qry+o++,f->qry+i,sizeof *f->other_qry); - - free(f->attrs); free(f->qry); - f->attrs = NULL; - f->qry = NULL; - - if (f->meta_qry) memset(f->meta_qry+m,0,sizeof *f->meta_qry); - else { - glite_jp_error_t err; - err.code = EINVAL; - err.source = __FUNCTION__; - err.desc = "at least one metadata query item required"; - ret = glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - if (f->other_qry) memset(f->other_qry+o,0,sizeof *f->other_qry); - -/* extract other_qry items that are not present in other_attr */ - f->int_other_attr = o = f->nother_attr; - for (i=0; inother_qry; i++) { - int j; - for (j=0; jint_other_attr && strcmp(f->other_attr[j],f->other_qry[i].attr); j++); - if (j == f->int_other_attr) { - f->other_attr = realloc(f->other_attr,(o+2) * sizeof *f->other_attr); - f->other_attr[o++] = strdup(f->other_qry[i].attr); - } - } - if (f->other_attr) f->other_attr[o] = NULL; - f->nother_attr = o; - - meta = calloc(f->nmeta_attr+2,sizeof *meta); - meta[0] = GLITE_JP_ATTR_OWNER; - if (f->meta_attr) memcpy(meta+1,f->meta_attr,(f->nmeta_attr+1) * sizeof *meta); - else meta[1] = NULL; - - ret = glite_jppsbe_query(ctx,f->meta_qry,meta,f,feed_query_callback); - free(meta); - if (ret == 0) ret = drain_feed(ctx,f,1); - else if (ret == ENOENT) ret = 0; - else drop_jobs(f); - -cleanup: - - jpfeed_free(f); - return ret; -} - -int glite_jpps_run_feed( - glite_jp_context_t ctx, - const char *destination, - char const * const *attrs, - const glite_jp_query_rec_t *qry, - int continuous, - char **feed_id) -{ - struct jpfeed *f; - - fprintf(stderr,"%s: \n",__FUNCTION__); - if (!*feed_id) *feed_id = generate_feedid(); - - f = make_jpfeed(destination,attrs,qry,*feed_id,(time_t) 0); - f->continuous = continuous; - glite_jp_add_deferred(ctx,run_feed_deferred,f); - - return 0; -} - -static int register_feed_deferred(glite_jp_context_t ctx,void *feed) -{ - struct jpfeed *f = feed; - - if (glite_jppsbe_store_feed(ctx,f)) fputs(glite_jp_error_chain(ctx),stderr); - else{ - time(&(f->expires)); - f->expires += FEED_TTL; - glite_jppsbe_refresh_feed(ctx, f->id, f->expires); - kill(-master,SIGUSR1); /* gracefully terminate slaves - and let master restart them */ - } - - return 0; -} - - -int glite_jpps_register_feed( - glite_jp_context_t ctx, - const char *destination, - char const *const *attrs, - const glite_jp_query_rec_t *qry, - char **feed_id, - time_t *expires) -{ - struct jpfeed *f = NULL; - - if (!*feed_id) *feed_id = generate_feedid(); - time(expires); *expires += FEED_TTL; - - f = make_jpfeed(destination,attrs,qry,*feed_id,*expires); - glite_jp_add_deferred(ctx,register_feed_deferred,f); - - return 0; -} - -int glite_jpps_refresh_feed(glite_jp_context_t ctx, char *feed_id, time_t *expires){ - time(expires); *expires += FEED_TTL; - - glite_jppsbe_refresh_feed(ctx, feed_id, *expires); - - printf("Feed %s has been refreshed.\n", feed_id); - - return 0; -} - diff --git a/org.glite.jp.primary/src/feed.h b/org.glite.jp.primary/src/feed.h deleted file mode 100644 index a4f63af..0000000 --- a/org.glite.jp.primary/src/feed.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ifndef GLITE_JP_FEED_H -#define GLITE_JP_FEED_H - - -struct jpfeed { -/* feed data */ - char *id,*destination; - time_t expires; - int continuous; - -/* complete and split query and attribute list */ - char **attrs,**meta_attr,**other_attr; - int int_other_attr; /* index from where other_attr is extended - with attributes from other_query */ - - int nother_attr, nmeta_attr, nmeta_qry, nother_qry; - glite_jp_query_rec_t *qry,*meta_qry,*other_qry; - -/* jobs stacked for feed */ - int njobs; - char **jobs; - char **owners; - glite_jp_attrval_t **job_attrs; - -/* next feed */ - 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 *,const char *,const char *); -int glite_jpps_match_attr_multi(glite_jp_context_t,const char **, const glite_jp_attrval_t **); -int glite_jpps_match_tag(glite_jp_context_t,const char *,const char *,const char *); -int glite_jpps_run_feed(glite_jp_context_t,const char *,char const * const *,const glite_jp_query_rec_t *,int,char **); -int glite_jpps_register_feed(glite_jp_context_t,const char *,char const * const *,const glite_jp_query_rec_t *,char **,time_t *); - -#endif /* GLITE_JP_FEED_H */ diff --git a/org.glite.jp.primary/src/file_plugin.c b/org.glite.jp.primary/src/file_plugin.c deleted file mode 100644 index 65226d5..0000000 --- a/org.glite.jp.primary/src/file_plugin.c +++ /dev/null @@ -1,142 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include - -#include -#include "glite/jp/file_plugin.h" - -static struct option opts[] = { - { "plugin", 1, NULL, 'p' }, - { NULL } -}; - -static int loadit(glite_jp_context_t ctx,const char *so) -{ -/* XXX: not stored but we never dlclose() yet */ - void *dl_handle = dlopen(so,RTLD_NOW); - - glite_jp_error_t err; - const char *e; - glite_jpps_fplug_data_t *data,*dp; - int i; - - glite_jpps_fplug_init_t init; - memset(&err,0,sizeof err); - - if (!dl_handle) { - err.source = "dlopen()"; - err.code = EINVAL; - err.desc = dlerror(); - return glite_jp_stack_error(ctx,&err); - } - - dlerror(); - init = dlsym(dl_handle,"init"); - e = dlerror(); - if (e) { - char buf[300]; - snprintf(buf,sizeof buf,"dlsym(\"%s\",\"init\")",so); - buf[299] = 0; - err.source = buf; - err.code = ENOENT; - err.desc = e; - return glite_jp_stack_error(ctx,&err); - } - - data = calloc(1,sizeof *data); - - if (init(ctx,data)) return -1; - - i = 0; - if (ctx->plugins) for (i=0; ctx->plugins[i]; i++); - ctx->plugins = realloc(ctx->plugins, (i+2) * sizeof *ctx->plugins); - ctx->plugins[i] = data; - ctx->plugins[i+1] = NULL; - - /* TODO: check consistency of uri+class pairs wrt. previous plugins */ - - return 0; -} - -int glite_jpps_fplug_load(glite_jp_context_t ctx,int argc,char **argv) -{ - int i; - - for (i=1; iplugins) { - return glite_jp_stack_error(ctx,&err); - } - - for (i = 0; ctx->plugins[i]; i++) { - int j; - glite_jpps_fplug_data_t *p = ctx->plugins[i]; - - for (j=0; p->uris && p->uris[j]; j++) - if ((uri && !strcmp(p->uris[j],uri)) || (class && !strcmp(p->classes[j],class))) { - out = realloc(out, (matches+2) * sizeof *out); - out[matches++] = p; - out[matches] = NULL; - } - } - - if (matches) { - *plugin_data = out; - return 0; - } - else return glite_jp_stack_error(ctx,&err); -} - -int glite_jpps_fplug_lookup(glite_jp_context_t ctx,const char *uri, glite_jpps_fplug_data_t ***plugin_data) -{ - return lookup_common(ctx,uri,NULL,plugin_data); -} - -int glite_jpps_fplug_lookup_byclass(glite_jp_context_t ctx, const char *class,glite_jpps_fplug_data_t ***plugin_data) -{ - return lookup_common(ctx,NULL,class,plugin_data); -} - diff --git a/org.glite.jp.primary/src/ftpd_auth.c b/org.glite.jp.primary/src/ftpd_auth.c deleted file mode 100644 index ac4563e..0000000 --- a/org.glite.jp.primary/src/ftpd_auth.c +++ /dev/null @@ -1,219 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include - -#include "glite/lbu/trio.h" -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "glite/jp/db.h" - -extern void reply(int n, char *fmt,...); - -#define FTPBE_DEFAULT_DB_CS "jpps/@localhost:jpps" - -static char *user_subj = NULL; -static char *int_prefix = NULL; -static glite_jp_context_t ctx; - -static int open_db() -{ - char *db_cs = NULL; - - db_cs = getenv("FTPBE_DB_CS"); - if (!db_cs) db_cs = FTPBE_DEFAULT_DB_CS; - - int_prefix = getenv("FTPBE_INT_PREFIX"); - if (!int_prefix) { - reply(550, "Internal error: prefix not configured"); - return 0; - } - - glite_jp_init_context(&ctx); - if (glite_lbu_InitDBContext(((glite_lbu_DBContext *)&ctx->dbhandle)) != 0) { - reply(550, "Internal error: backend DB initialization failed"); - return 0; - } - if (glite_lbu_DBConnect(ctx->dbhandle, db_cs) != 0) { - reply(550, "Internal error: backend DB access failed"); - return 0; - } - - return 1; -} - -static void close_db() -{ - glite_lbu_DBClose(ctx->dbhandle); - glite_lbu_FreeDBContext(ctx->dbhandle); -} - - -int globus_gss_assist_gridmap(char* globus_id, char** mapped_name) -{ - char *logname; - - logname = getenv("GLITE_USER"); - if (logname) { - *mapped_name = strdup(logname); - user_subj = strdup(globus_id); - if (!(*mapped_name) || !user_subj) return 1; - - return 0; - } else { - return 1; - /* - * Note: return value need not follow globus numbering - * scheme in ftpd - */ - } -} - -int globus_gss_assist_userok(char*globus_id, char *account) -{ - char *logname; - - logname = getenv("GLITE_USER"); - if (logname) - return strcmp(account,strdup(logname)) ? 1 : 0; - else - return 1; -} - -int checknoretrieve(char *name) -{ - int result = 1; /* deny access by default */ - - char *stmt = NULL; - int db_retn; - glite_lbu_Statement db_res; - char *db_row[1] = { NULL }; - - trio_asprintf(&stmt,"select j.owner from jobs j,files f where " - "f.ext_url='%|Ss%|Ss' and j.jobid=f.jobid", - int_prefix, name); - if (!stmt) { - reply(550, "Internal error: out of memory"); - return 1; - } - - if (!open_db()) return 1; - - if ((db_retn = glite_jp_db_ExecSQL(ctx, stmt, &db_res)) <= 0) { - if (db_retn == 0) { - reply(553, "No such file registered"); - } else { - reply(550, "Internal error: backend DB access failed"); - } - goto out; - } - - db_retn = glite_jp_db_FetchRow(ctx, db_res, 1, NULL, db_row); - if (db_retn != 1) { - glite_jp_db_FreeStmt(&db_res); - reply(550, "Internal error: backend DB access failed"); - goto out; - } - glite_jp_db_FreeStmt(&db_res); - - if (!strcmp(db_row[0], user_subj)) { - result = 0; - } else { - reply(553, "Permission denied"); - } - -out: - free(db_row[0]); - close_db(); - free(stmt); - return result; -} - -int upl_check(char *name, uid_t * uid, gid_t * gid, int *f_mode, int *valid) -{ - int result = -1; /* deny access by default */ - - char *stmt = NULL; - int db_retn; - glite_lbu_Statement db_res; - char *db_row[1] = { NULL }; - - *valid = 0; /* don't used uid & gid */ - - trio_asprintf(&stmt,"select state from files " - "where ext_url='%|Ss%|Ss' and ul_userid='%|Ss'", - int_prefix, name, user_subj); - if (!stmt) { - reply(550, "Internal error: out of memory"); - return -1; - } - - if (!open_db()) return -1; - - if ((db_retn = glite_jp_db_ExecSQL(ctx, stmt, &db_res)) <= 0) { - if (db_retn == 0) { - reply(553, "No such upload in progress"); - } else { - reply(550, "Internal error: backend DB access failed"); - } - goto out; - } - - db_retn = glite_jp_db_FetchRow(ctx, db_res, 1, NULL, db_row); - if (db_retn != 1) { - glite_jp_db_FreeStmt(&db_res); - reply(550, "Internal error: backend DB access failed"); - goto out; - } - glite_jp_db_FreeStmt(&db_res); - - if (!strcmp(db_row[0], "uploading")) { - result = 1; - } else { - reply(553, "Permission denied"); - } - -out: - free(db_row[0]); - close_db(); - free(stmt); - return result; -} - -int del_check(char *name) -{ - reply(553, "Deleting files not supported"); - return 0; -} - -int rename(const char *f, const char * t) -{ - errno = EPERM; - return -1; -} - -FILE *ftpd_popen(char *program, char *type, int closestderr) -{ - errno = EPERM; - return NULL; -} diff --git a/org.glite.jp.primary/src/is_client.c b/org.glite.jp.primary/src/is_client.c deleted file mode 100644 index e0ff27c..0000000 --- a/org.glite.jp.primary/src/is_client.c +++ /dev/null @@ -1,499 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef SOAP_FMAC1 -#define SOAP_FMAC1 static - -#include - -#include "glite/jp/types.h" -#include "soap_version.h" -#include "glite/security/glite_gsplugin.h" -#include "glite/security/glite_gscompat.h" - -#include "feed.h" -#include "is_client.h" - -/* same as ClientLib.c, without WITH_NOGLOBAL */ -#define SOAP_FMAC3 static -#include "jpis_C.c" -#include "jpis_Client.c" - -#include "jpis_.nsmap" - -#include "soap_env_ctx.h" -#include "soap_env_ctx.c" - -#include "glite/jp/ws_fault.c" -#include "soap_util.c" - - -#define MAX_RETRY 10 -#define RETRY_SLEEP 2 - -extern char *server_key, *server_cert; /* XXX */ -extern char file_prefix[]; -extern char *il_sock; - -struct client_data { - char *host; - int port; - long offset; -}; - -/* -static int fconnect(struct soap *soap, const char *endpoint, const char *host, int port){ - int s, len; - const char *dest = "/tmp/il_sock"; - struct sockaddr_un remote; - - if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) - return SOAP_ERR; - - remote.sun_family = AF_UNIX; - strcpy(remote.sun_path, dest); - len = strlen(remote.sun_path) + sizeof(remote.sun_family); - if (connect(s, (struct sockaddr *)&remote, len) < 0) - return SOAP_ERR; - - soap->socket = s; - - return SOAP_OK; -} -*/ - -void notify_il_sock(struct soap *soap) { - struct client_data *data = soap->user; - int s, len; - struct sockaddr_un remote; - char *buf; - - if(il_sock == NULL) return; - if(data == NULL) return; - - if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) - return; - - remote.sun_family = AF_UNIX; - strcpy(remote.sun_path, il_sock); - len = strlen(remote.sun_path) + sizeof(remote.sun_family); - if (connect(s, (struct sockaddr *)&remote, len) < 0) { - close(s); - return; - } - - asprintf(&buf, "POST / HTTP/1.1\r\nHost: %s:%d\r\nContent-Length: 1\r\n\r\n", - data->host, data->port); - if(buf) { - /* fire and forget */ - send(s, buf, strlen(buf) + 1, MSG_NOSIGNAL | MSG_DONTWAIT); - free(buf); - } - free(remote.sun_path); - close(s); - return; -} - - -int myopen(struct soap *soap, const char *endpoint, const char *host, int port) -{ - char filename[PATH_MAX]; - FILE *outfile; - int i, filedesc; - struct client_data *data; - - data = malloc(sizeof(*data)); - if(data == NULL) - return ENOMEM; - - /* XXX: should it be strdup'ed? */ - data->host = host; - data->port = port; - - snprintf(filename, PATH_MAX-1, "%s.%s:%d", file_prefix, host, port); - filename[PATH_MAX - 1] = 0; - -try_again: - if((outfile = fopen(filename, "a")) == NULL) { - goto cleanup; - } - if((filedesc = fileno(outfile)) < 0) { - goto cleanup; - } - - for(i = 0; i < 5; i++) { - struct flock filelock; - int filelock_status; - struct stat statbuf; - - filelock.l_type = F_WRLCK; - filelock.l_whence = SEEK_SET; - filelock.l_start = 0; - filelock.l_len = 0; - - if((filelock_status=fcntl(filedesc, F_SETLK, &filelock)) < 0) { - switch(errno) { - case EAGAIN: - case EACCES: - case EINTR: - if((i+1) < 5) sleep(1); - break; - default: - goto cleanup; - } - } else { - if(stat(filename, &statbuf)) { - if(errno == ENOENT) { - fclose(outfile); - goto try_again; - } else { - goto cleanup; - } - } else { - /* success */ - break; - } - } - } - - if(i == 5) { - errno = ETIMEDOUT; - goto cleanup; - } - - data->offset = ftell(outfile); - soap->user = data; - soap->sendfd = filedesc; - return filedesc; - -cleanup: - filedesc = errno; - if(outfile) fclose(outfile); - return filedesc; -} - - -int myclose(struct soap *soap) -{ - if(soap->sendfd > 2) { - write(soap->sendfd, "\n", 1); - close(soap->sendfd); - soap->sendfd = -1; - /* send message to IL on socket */ - notify_il_sock(soap); - if(soap->user) { - free((struct client_data*)soap->user); - soap->user = NULL; - } - } - return SOAP_OK; -} - -int mysend(struct soap *soap, const char *s, size_t n) -{ - int ret; - - ret = write(soap->sendfd, s, n); - if(ret < 0) - return ret; - return SOAP_OK; -} - -size_t myrecv(struct soap *soap, char *s, size_t n) -{ - const char response[] = "" - "" - " " - " " - " " - " " - ""; - - int len; - - if(soap->user == NULL) - soap->user = response; - - len = sizeof(response) - ((char*)soap->user - response); - if(n < len) len = n; - strncpy(s, (char*)soap->user, len); - soap->user += len; - return len; -} - -static int check_other_soap(glite_jp_context_t ctx) -{ - glite_gsplugin_Context plugin_ctx; - int ret = 0; - - if (!ctx->other_soap) { - glite_gsplugin_init_context(&plugin_ctx); - if (server_key || server_cert) { - edg_wll_GssCred cred; - - ret = edg_wll_gss_acquire_cred_gsi(server_cert, server_key, &cred, NULL); - glite_gsplugin_use_credential(plugin_ctx, cred); - } - - ctx->other_soap = soap_new(); - soap_init(ctx->other_soap); - soap_set_namespaces(ctx->other_soap,jpis__namespaces); - soap_set_omode(ctx->other_soap, SOAP_IO_BUFFER); // set buffered response - // buffer set to SOAP_BUFLEN (default = 8k) - if(il_sock == NULL) { - /* send to JPIS directly */ - soap_register_plugin_arg(ctx->other_soap,glite_gsplugin,plugin_ctx); - ctx->other_soap->user = ctx; - } else { - /* this makes the SOAP client send all traffic through local socket to IL */ - // ctx->other_soap->fconnect = fconnect; - ctx->other_soap->fopen = myopen; - ctx->other_soap->fclose = myclose; - ctx->other_soap->fsend = mysend; - } - } - return ret; -} - -static check_fault(glite_jp_context_t ctx,struct soap *soap,int ec) -{ - glite_jp_error_t err; - char buf[1000] = "unknown fault"; - - switch (ec) { - case SOAP_OK: return 0; - default: - err.code = EIO; - err.source = __FUNCTION__; - err.desc = buf; - if (soap->fault) snprintf(buf,sizeof buf,"%s %s\n", - soap->fault->faultcode, - soap->fault->faultstring); - buf[999] = 0; - glite_jp_stack_error(ctx,&err); - return err.code; - } -} - -static struct _glite_jp_soap_env_ctx_t *keep_soap_env_ctx; - -#define SWITCH_SOAP_CTX \ -{ \ - keep_soap_env_ctx = glite_jp_soap_env_ctx; \ - glite_jp_soap_env_ctx = &my_soap_env_ctx; \ -} \ - -#define RESTORE_SOAP_CTX \ -{ \ - glite_jp_soap_env_ctx = keep_soap_env_ctx; \ -} \ - -static int glite_jpps_single_feed_wrapped( - glite_jp_context_t ctx, - const char *feed, - int done, - const char *destination, - const char *job, - const char *owner, - glite_jp_attrval_t const *attrs -) -{ - struct _jpelem__UpdateJobs in; - struct _jpelem__UpdateJobsResponse out; - struct jptype__jobRecord jr, *jrp = &jr; - int i; - enum xsd__boolean false = GLITE_SECURITY_GSOAP_FALSE; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - - /* TODO: call JP Index server via interlogger */ - - printf("feed %s to %s, job %s\n",feed,destination,job); - - check_other_soap(ctx); - - in.feedId = (char *) feed; /* XXX: const */ - in.feedDone = done; - in.__sizejobAttributes = 1; -#warning FIXME for valtri - in.jobAttributes = &jrp; - - for (i=0; attrs[i].name; i++); - jr.jobid = soap_strdup(ctx->other_soap, job); - jr.owner = soap_strdup(ctx->other_soap, owner); - - jr.__sizeattributes = jp2s_attrValues(ctx->other_soap, - (glite_jp_attrval_t *) attrs, /* XXX: const */ - &jr.attributes,0); - - jr.remove = &false; - jr.__sizeprimaryStorage = 1; - jr.primaryStorage = &ctx->myURL; - - - SWITCH_SOAP_CTX - if (soap_call___jpsrv__UpdateJobs(ctx->other_soap,destination,"", - &in,&out - )) { - char buf[1000]; - err.code = EIO; - err.source = __FUNCTION__; - err.desc = buf; - memset(buf, 0, sizeof(buf)); - if (ctx->other_soap->fault) { - snprintf(buf,sizeof buf,"%s %s\n", - ctx->other_soap->fault->faultcode, - ctx->other_soap->fault->faultstring); - } - else { - sprintf(buf,"No detailed error description (JP IS not running?)\n"); - } - buf[999] = 0; - glite_jp_stack_error(ctx,&err); - } - RESTORE_SOAP_CTX - - soap_dealloc(ctx->other_soap, jr.jobid); - soap_dealloc(ctx->other_soap, jr.owner); - attrValues_free(ctx->other_soap,jr.attributes,jr.__sizeattributes); - - return err.code; -} - -int glite_jpps_single_feed( - glite_jp_context_t ctx, - const char *feed, - int done, - const char *destination, - const char *job, - const char *owner, - glite_jp_attrval_t const *attrs -) -{ - int retry,ret; - assert(owner); - for (retry = 0; retry < MAX_RETRY; retry++) { - if ((ret = glite_jpps_single_feed_wrapped(ctx,feed,done,destination,job,owner,attrs)) == 0) break; - sleep(RETRY_SLEEP); - } - return ret; -} - - -static int glite_jpps_multi_feed_wrapped( - glite_jp_context_t ctx, - const char *feed, - int done, - int njobs, - const char *destination, - char **jobs, - char **owners, - glite_jp_attrval_t **attrs) -{ - int i,j; - - struct _jpelem__UpdateJobs in; - struct _jpelem__UpdateJobsResponse out; - struct jptype__jobRecord *jr; - enum xsd__boolean false = GLITE_SECURITY_GSOAP_FALSE; - glite_jp_error_t err; - - printf("multi_feed %s to %s\n",feed,destination); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - - check_other_soap(ctx); - - in.feedId = (char *) feed; /* XXX: const */ - in.feedDone = done; - GLITE_SECURITY_GSOAP_LIST_CREATE(ctx->other_soap, &in, jobAttributes, struct jptype__jobRecord, njobs); - - for (i=0; ijobid = jobs[i]; - jr->owner = owners[i]; - - assert(jr->owner); - - jr->__sizeattributes = jp2s_attrValues(ctx->other_soap, - attrs[i], - &jr->attributes,0); - - jr->remove = &false; - jr->__sizeprimaryStorage = 1; - jr->primaryStorage = &ctx->myURL; - } - - //#ifndef JP_PERF - SWITCH_SOAP_CTX - check_fault(ctx,ctx->other_soap, - soap_call___jpsrv__UpdateJobs(ctx->other_soap,destination,"", &in,&out)); - RESTORE_SOAP_CTX - for (i=0; iother_soap,jr->attributes,jr->__sizeattributes); - } - GLITE_SECURITY_GSOAP_LIST_DESTROY(ctx->other_soap, &in, jobAttributes); - //#endif - - return err.code; -} - - -int glite_jpps_multi_feed( - glite_jp_context_t ctx, - const char *feed, - int done, - int njobs, - const char *destination, - char **jobs, - char **owners, - glite_jp_attrval_t **attrs) -{ - int retry,ret; - for (retry = 0; retry < MAX_RETRY; retry++) { - if ((ret = glite_jpps_multi_feed_wrapped(ctx,feed,done,njobs,destination,jobs,owners,attrs)) == 0) break; - sleep(RETRY_SLEEP); - } - return ret; -} diff --git a/org.glite.jp.primary/src/is_client.h b/org.glite.jp.primary/src/is_client.h deleted file mode 100644 index 1290f0d..0000000 --- a/org.glite.jp.primary/src/is_client.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -int glite_jpps_single_feed(glite_jp_context_t,const char *,int,const char *,const char *,const char *,glite_jp_attrval_t const *); -int glite_jpps_multi_feed(glite_jp_context_t,const char *,int,int,const char *,char **,char **,glite_jp_attrval_t **); - - diff --git a/org.glite.jp.primary/src/jp_callouts.c b/org.glite.jp.primary/src/jp_callouts.c deleted file mode 100644 index 9284ff3..0000000 --- a/org.glite.jp.primary/src/jp_callouts.c +++ /dev/null @@ -1,539 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include - -#include "glite/lbu/trio.h" -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/jp/db.h" - -#include "jp_callouts.h" - -#define FTPBE_DEFAULT_DB_CS "jpps/@localhost:jpps" - -/* - This file provides following authorization callouts used by the globus - gridftp server. The callouts must be specified in the gsi_auth.confs - configuration file. - 1. GLOBUS_GSI_AUTHZ_SYSTEM_INIT - - called upon request arrival, runs under the deamon uid - - opens connection to the DB - 2. globus_mapping - - performs mapping to a local account - - n-to-one mapping implemented, which uses a generic user name - 3. GLOBUS_GSI_AUTHZ_HANDLE_INIT - - runs under the mapped client uid - - used to save current GSS context for later use - 4. GLOBUS_GSI_AUTHORIZE_ASYNC - - called just before the request is served - - performs actual authZ decision based on current state of the file in - in the JP DB - 5. GLOBUS_GSI_AUTHZ_HANDLE_DESTROY - - cleanup of saved data - (6. GLOBUS_GSI_AUTHZ_SYSTEM_DESTROY) - - cleanup - - we should close the connection to the DB, however this callout doesn't - seem to be called by the ftpd -*/ - -static globus_result_t -query_db(glite_jp_context_t ctx, glite_lbu_Statement *res, - const char *format, ...) -{ - char *stmt = NULL; - int ret; - glite_lbu_Statement db_res; - va_list ap; - globus_result_t result = GLOBUS_FAILURE; - - va_start(ap, format); - trio_vasprintf(&stmt, format, ap); - if (stmt == NULL) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERRNO_ERROR(result, errno); - return result; - } - va_end(ap); - - ret = glite_jp_db_ExecSQL(ctx, stmt, &db_res); - if (ret <= 0) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_AUTHZ_DENIED_BY_CALLOUT, - ((ret == 0) ? "No such file registered" : - "Internal error: backend DB access failed")); - goto end; - } - - *res = db_res; - result = GLOBUS_SUCCESS; - -end: - if (stmt) - free(stmt); - - return result; -} - -static globus_result_t -authz_read(authz_jp_system_state_struct *state, char *object, char *client) -{ - globus_result_t result = GLOBUS_FAILURE; - int db_retn; - glite_lbu_Statement db_res; - char *db_row[1] = { NULL }; - char *p; - - /* skip the gsiftp:// or ftp:// prefix */ - p = strstr(object, "ftp://"); - if (p == NULL) { - result = GLOBUS_FAILURE; - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_AUTHZ_DENIED_BY_CALLOUT, - ("Unsupported file type, access denied")); - goto out; - } - p += 6; - - /* find where the filename starts in the URL */ - p = strchr(p, '/'); - - result = query_db(state->jp_ctx, &db_res, - "select j.owner from jobs j,files f where " - "f.int_path='%|Ss' and j.jobid=f.jobid", p); - if (result != GLOBUS_SUCCESS) - return result; - - db_retn = glite_jp_db_FetchRow(state->jp_ctx, db_res, 1, NULL, db_row); - if (db_retn != 1) { - result = GLOBUS_FAILURE; - glite_jp_db_FreeStmt(&db_res); - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_AUTHZ_DENIED_BY_CALLOUT, - ("Internal error: backend DB access failed")); - goto out; - } - glite_jp_db_FreeStmt(&db_res); - - if (!strcmp(db_row[0], client)) { - result = GLOBUS_SUCCESS; - } else { - result = GLOBUS_FAILURE; - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_AUTHZ_DENIED_BY_CALLOUT, - ("Permission denied")); - } - -out: - free(db_row[0]); - return result; -} - -static globus_result_t -authz_write(authz_jp_system_state_struct *state, char *object, char *client) -{ - globus_result_t result = GLOBUS_FAILURE; - int db_retn; - glite_lbu_Statement db_res; - char *db_row[1] = { NULL }; - char *p; - - /* skip the gsiftp:// or ftp:// prefix */ - p = strstr(object, "ftp://"); - if (p == NULL) { - result = GLOBUS_FAILURE; - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_AUTHZ_DENIED_BY_CALLOUT, - ("Unsupported file type, access denied")); - goto out; - } - p += 6; - - /* find where the filename starts in the URL */ - p = strchr(p, '/'); - - result = query_db(state->jp_ctx, &db_res, - "select f.state from files f, users u " - "where f.int_path='%|Ss' and f.ul_userid=u.userid " - "and u.cert_subj='%|Ss'", - p, client); - if (result != GLOBUS_SUCCESS) - return result; - - db_retn = glite_jp_db_FetchRow(state->jp_ctx, db_res, 1, NULL, db_row); - if (db_retn != 1) { - glite_jp_db_FreeStmt(&db_res); - result = GLOBUS_FAILURE; - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_AUTHZ_DENIED_BY_CALLOUT, - ("Internal error: backend DB access failed")); - goto out; - } - glite_jp_db_FreeStmt(&db_res); - - if (!strcmp(db_row[0], "uploading")) { - result = GLOBUS_SUCCESS; - } else { - result = GLOBUS_FAILURE; - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_AUTHZ_DENIED_BY_CALLOUT, - ("Upload not in progress")); - } - -out: - free(db_row[0]); - return result; -} - -static globus_result_t -authz_del(authz_jp_system_state_struct *state, char *object, char *client) -{ - globus_result_t result = GLOBUS_FAILURE; - - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_AUTHZ_DENIED_BY_CALLOUT, - ("Deleting files not supported")); - return result; -} - -static int -get_client(gss_ctx_id_t ctx, char **name) -{ - gss_buffer_desc token = GSS_C_EMPTY_BUFFER; - OM_uint32 maj_stat, min_stat; - gss_name_t client_name = GSS_C_NO_NAME; - int ret; - - maj_stat = gss_inquire_context(&min_stat, ctx, &client_name, NULL, NULL, - NULL, NULL, NULL, NULL); - if (GSS_ERROR(maj_stat)) { - ret = -1; - goto end; - } - - maj_stat = gss_display_name(&min_stat, client_name, &token, NULL); - if (GSS_ERROR(maj_stat)) { - ret = -1; - goto end; - } - - *name = strdup(token.value); - ret = 0; - -end: - if (token.length) - gss_release_buffer(&min_stat, &token); - if (client_name != GSS_C_NO_NAME) - gss_release_name(&min_stat, &client_name); - - return ret; -} - -globus_result_t -authz_jp_system_init_callout(va_list ap) -{ - void * authz_system_state; - authz_jp_system_state_struct *state = NULL; - char *db_cs = NULL; - globus_result_t result = GLOBUS_FAILURE; - glite_jp_context_t jp_ctx; - - authz_system_state = va_arg(ap, void *); - - db_cs = getenv("FTPBE_DB_CS"); - if (!db_cs) db_cs = FTPBE_DEFAULT_DB_CS; - - /* XXX the error messages aren't displayed by ftpd on errors */ - - glite_jp_init_context(&jp_ctx); - - if (glite_lbu_InitDBContext(((glite_lbu_DBContext *)&jp_ctx->dbhandle)) != 0) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_SYSTEM_ERROR, - ("Internal error: backend DB initialization failed")); - return GLOBUS_FAILURE; - } - - if (glite_lbu_DBConnect(jp_ctx->dbhandle, db_cs) != 0) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_SYSTEM_ERROR, - ("Internal error: backend DB access failed")); - return GLOBUS_FAILURE; - } - - state = globus_libc_calloc(1, sizeof(*state)); - if (state == NULL) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERRNO_ERROR(result, errno); - return GLOBUS_FAILURE; - } - - state->jp_ctx = jp_ctx; - - *(authz_jp_system_state_struct **)authz_system_state = state; - return GLOBUS_SUCCESS; -} - -globus_result_t -authz_jp_system_destroy_callout(va_list ap) -{ - void * authz_system_state; - globus_result_t result = GLOBUS_SUCCESS; - - authz_system_state = va_arg(ap, void *); - - /* XXX close the DB here, however this call seems not be called by gridftpd */ - return result; -} - -globus_result_t -authz_jp_handle_init_callout(va_list ap) -{ - globus_gsi_authz_handle_t *handle; - char * service_name; - gss_ctx_id_t context; - globus_gsi_authz_cb_t callback; - void * callback_arg; - void * authz_system_state; - globus_result_t result = GLOBUS_FAILURE; - - handle = va_arg(ap, globus_gsi_authz_handle_t *); - service_name = va_arg(ap, char *); - context = va_arg(ap, gss_ctx_id_t); - callback = va_arg(ap, globus_gsi_authz_cb_t); - callback_arg = va_arg(ap, void *); - authz_system_state = va_arg(ap, void *); - - if (handle == NULL) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR(result, - GLOBUS_GSI_AUTHZ_CALLOUT_BAD_ARGUMENT_ERROR, - ("null handle")); - goto end; - } - - *handle = globus_libc_calloc(1, sizeof(**handle)); - if (*handle == NULL) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERRNO_ERROR(result, errno); - goto end; - } - - (*handle)->gss_ctx = context; - result = GLOBUS_SUCCESS; - -end: - if (callback) - callback(callback_arg, callback_arg, result); - - return result; -} - -globus_result_t -authz_jp_authorize_async_callout(va_list ap) -{ - globus_gsi_authz_handle_t handle; - char * action; - char * object; - globus_gsi_authz_cb_t callback; - void * callback_arg; - void * authz_system_state; - globus_result_t result = GLOBUS_FAILURE; - char *client = NULL; - - handle = va_arg(ap, globus_gsi_authz_handle_t); - action = va_arg(ap, char *); - object = va_arg(ap, char *); - callback = va_arg(ap, globus_gsi_authz_cb_t); - callback_arg = va_arg(ap, void *); - authz_system_state = va_arg(ap, void *); - - if (action == NULL) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_BAD_ARGUMENT_ERROR, - ("null action")); - goto end; - } - - if (object == NULL) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_BAD_ARGUMENT_ERROR, - ("null object")); - goto end; - } - - if (handle == NULL) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_BAD_ARGUMENT_ERROR, - ("null handle")); - goto end; - } - - if (handle->gss_ctx == NULL) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_BAD_ARGUMENT_ERROR, - ("bad handle")); - goto end; - } - - if (authz_system_state == NULL) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_BAD_ARGUMENT_ERROR, - ("system state not initialized, probably the GLOBUS_GSI_AUTHZ_SYSTEM_INIT callout isn't handled")); - goto end; - } - - get_client(handle->gss_ctx, &client); - if (client == NULL) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_BAD_ARGUMENT_ERROR, - ("cannot identify client")); - goto end; - } - -// fprintf(stdout, " client \"%s\" asking to \"%s\" on \"%s\"\n", client, action, object); - - if (strcmp(action, "create") == 0) { - result = authz_write(authz_system_state, object, client); - } else if (strcmp(action, "write") == 0) { - result = authz_write(authz_system_state, object, client); - } else if (strcmp(action, "read") == 0) { - result = authz_read(authz_system_state, object, client); - } else if (strcmp(action, "delete") == 0) { - result = authz_del(authz_system_state, object, client); - } else { - result = GLOBUS_FAILURE; - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_BAD_ARGUMENT_ERROR, - ("unsupported operation")); - } - -end: - if (callback && result == GLOBUS_SUCCESS) - callback(callback_arg, handle, result); - - if (client) - free(client); - - return result; -} - -int -authz_jp_handle_destroy_callout(va_list ap) -{ - globus_gsi_authz_handle_t handle; - void * authz_system_state; - int result = (int) GLOBUS_SUCCESS; - globus_gsi_authz_cb_t callback; - void * callback_arg; - - handle = va_arg(ap, globus_gsi_authz_handle_t); - callback = va_arg(ap, globus_gsi_authz_cb_t); - callback_arg = va_arg(ap, void *); - authz_system_state = va_arg(ap, void *); - - if (handle != NULL) { - globus_libc_free(handle); - } - - /* XXX - glite_jp_db_close((authz_jp_system_state_struct*)authz_system_state->jp_ctx); - */ - -#if 0 - if (callback) - callback(callback_arg, handle, result); -#endif - return result; -} - -globus_result_t -authz_jp_globus_mapping(va_list ap) -{ - gss_ctx_id_t context; - char * service; - char * desired_identity; - char * identity_buffer; - unsigned int buffer_length; - char *logname; - char *client = NULL; - int ret; - globus_result_t result = GLOBUS_FAILURE; - - context = va_arg(ap, gss_ctx_id_t); - service = va_arg(ap, char *); - desired_identity = va_arg(ap, char *); - identity_buffer = va_arg(ap, char *); - buffer_length = va_arg(ap, unsigned int); - - logname = getenv("GLITE_USER"); - if (logname == NULL) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_CONFIGURATION_ERROR, - ("the GLITE_USER variable isn't set, can't map user")); - return GLOBUS_FAILURE; - } - - if (desired_identity) { - result = (strcmp(logname, desired_identity) == 0) ? - GLOBUS_SUCCESS : GLOBUS_FAILURE; - goto end; - } - - ret = get_client(context, &client); - if (ret) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_SYSTEM_ERROR, - ("can't get client's name")); - goto end; - } - - if (strlen(logname) + 1 > buffer_length) { - GLOBUS_GSI_AUTHZ_CALLOUT_ERROR( - result, - GLOBUS_GSI_AUTHZ_CALLOUT_SYSTEM_ERROR, - ("Not enough space to store mapped identity")); - goto end; - } - - strcpy(identity_buffer, logname); - result = GLOBUS_SUCCESS; - -end: - if (client) - free(client); - - return result; -} diff --git a/org.glite.jp.primary/src/jp_callouts.h b/org.glite.jp.primary/src/jp_callouts.h deleted file mode 100644 index 95861a7..0000000 --- a/org.glite.jp.primary/src/jp_callouts.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include "glite/jp/context.h" - -/* must be named this way to provide the name expected by the globus_gsi_authz - * header and its typedef of globus_gsi_authz_handle_t */ -typedef struct globus_i_gsi_authz_handle_s { - gss_ctx_id_t gss_ctx; -} globus_i_gsi_authz_handle_s; - -typedef struct authz_jp_system_state_struct { - glite_jp_context_t jp_ctx; -} authz_jp_system_state_struct; diff --git a/org.glite.jp.primary/src/jptype_map.h b/org.glite.jp.primary/src/jptype_map.h deleted file mode 100644 index 09b59ea..0000000 --- a/org.glite.jp.primary/src/jptype_map.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "soap_version.h" - -#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 - -#else - -#define __jpsrv__RegisterJob __ns1__RegisterJob -#define __jpsrv__StartUpload __ns1__StartUpload -#define __jpsrv__CommitUpload __ns1__CommitUpload -#define __jpsrv__RecordTag __ns1__RecordTag -#define __jpsrv__FeedIndex __ns1__FeedIndex -#define __jpsrv__FeedIndexRefresh __ns1__FeedIndexRefresh -#define __jpsrv__GetJob __ns1__GetJob - -#define SOAP_TYPE___jpsrv__RegisterJob SOAP_TYPE___ns1__RegisterJob -#define SOAP_TYPE___jpsrv__StartUpload SOAP_TYPE___ns1__StartUpload -#define SOAP_TYPE___jpsrv__CommitUpload SOAP_TYPE___ns1__CommitUpload -#define SOAP_TYPE___jpsrv__GetJob SOAP_TYPE___ns1__GetJob - -#endif - diff --git a/org.glite.jp.primary/src/mk_soap_switch.pl b/org.glite.jp.primary/src/mk_soap_switch.pl deleted file mode 100755 index f332e00..0000000 --- a/org.glite.jp.primary/src/mk_soap_switch.pl +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -$formula = "/* Generated from @ARGV with the help of black magic.\n Do not edit.\n*/\n\n"; -print "${formula}#include \"soap_env_ctx.h\"\n\n"; - -# XXX: hardcoded -$prefix = 'ENV'; - -open EH,">soap_env_ctx.h" or die "soap_env_ctx.h: $!\n"; -open EC,">soap_env_ctx.c" or die "soap_env_ctx.c: $!\n"; - -print EH "${formula}struct _glite_jp_soap_env_ctx_t {\n"; - -print EC "${formula}static struct _glite_jp_soap_env_ctx_t my_soap_env_ctx = {\n"; - - -while ($_ = <>) { - if (/^}$/) { - print; - $infunc = 0; - undef @args; - next; - } - - next if $infunc; - - if (/^SOAP_FMAC3\s+(.+)\s+SOAP_FMAC4\s+([^(]+)\(([^)]*)\)/) { - $type = $1; - $func = $2; - @a = split /,/,$3; - for $a (@a) { - $a =~ /.*\W(\w+)/; - push @args,$1; - } - print; - - next if $func =~ "SOAP_$prefix"; - - print EH "\t$type (*$func)();\n"; - print EC "\t$func,\n"; - next; - } - - if (/^{/) { - print; - next if $func =~ "SOAP_$prefix"; - local $"=','; - $infunc = 1; - print "\t"; - print 'return ' unless $type eq 'void'; - print "glite_jp_soap_env_ctx->$func(@args);\n"; - - next; - } - - print; -} - -print EH "};\n\n"; -print EH "extern struct _glite_jp_soap_env_ctx_t *glite_jp_soap_env_ctx;\n"; -print EC "};\n"; - -print "struct _glite_jp_soap_env_ctx_t *glite_jp_soap_env_ctx;\n"; diff --git a/org.glite.jp.primary/src/new_ftp_backend.c b/org.glite.jp.primary/src/new_ftp_backend.c deleted file mode 100644 index a192b55..0000000 --- a/org.glite.jp.primary/src/new_ftp_backend.c +++ /dev/null @@ -1,2145 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "glite/lbu/trio.h" -#include "glite/lbu/escape.h" -#include "glite/jobid/strmd5.h" -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/jp/known_attr.h" -#include "glite/jp/attr.h" -#include "glite/jp/db.h" - -#include "feed.h" -#include "tags.h" -#include "backend_private.h" - -#include "jpps_H.h" /* XXX: SOAP_TYPE___jpsrv__GetJob */ - -#include "jptype_map.h" - -#define FTPBE_DEFAULT_DB_CS "jpps/@localhost:jpps" - -struct ftpbe_config { - char *internal_path; - char *external_path; - char *db_cs; -// char *gridmap; - char *logname; -}; - -static struct ftpbe_config *config = NULL; - -struct fhandle_rec { - gzFile fd_gz; - char* filename; - int filemode; - char* filedata; - int offset; - int eof; - int modified; -}; -typedef struct fhandle_rec *fhandle; - -static struct option ftpbe_opts[] = { - { "ftp-internal-path", 1, NULL, 'I' }, - { "ftp-external-path", 1, NULL, 'E' }, - { "ftp-db-cs", 1, NULL, 'D' }, -// { "ftp-gridmap", 1, NULL, 'G' }, - { NULL, 0, NULL, 0 } -}; - -/******************************************************************************* - Internal helpers -*******************************************************************************/ - - -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->db_cs == 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 int store_user(glite_jp_context_t ctx, const char *userid, const char *subj) -{ - glite_jp_error_t err; - char *stmt; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(userid != NULL); - assert(subj != NULL); - - trio_asprintf(&stmt,"insert into users(userid,cert_subj) " - "values ('%|Ss','%|Ss')",userid,subj); - if (!stmt) { - err.code = ENOMEM; - return glite_jp_stack_error(ctx,&err); - } - - if (glite_jp_db_ExecSQL(ctx, stmt, NULL) < 0) { - if (ctx->error->code == EEXIST) - glite_jp_clear_error(ctx); - else { - free(stmt); - err.code = EIO; - err.desc = "DB access failed"; - return glite_jp_stack_error(ctx,&err); - } - } - free(stmt); - - return 0; -} - -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) ; -} - -/******************************************************************************** - Backend calls -********************************************************************************/ -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:D:" /* G: */, ftpbe_opts, NULL)) != EOF) { - switch (opt) { - case 'I': - config->internal_path = optarg; - int i = strlen(optarg) - 1; - while (optarg[i] == '/'){ - optarg[i] = 0; - i--; - } - break; - case 'E': config->external_path = optarg; break; - case 'D': config->db_cs = optarg; break; -// case 'G': config->gridmap = optarg; break; - default: break; - } - } - - /* Defaults */ - if (!config->db_cs) config->db_cs = strdup(FTPBE_DEFAULT_DB_CS); - - if (config_check(ctx, config)) { - err.code = EINVAL; - err.desc = "Invalid FTP backend configuration"; - return glite_jp_stack_error(ctx,&err); - } - - if (glite_lbu_InitDBContext(((glite_lbu_DBContext *)&ctx->dbhandle)) != 0) { - err.code = glite_jp_db_SetError(ctx, __FUNCTION__); - err.desc = "Cannot init backend's database (during init)"; - return glite_jp_stack_error(ctx,&err); - } - if (glite_lbu_DBConnect(ctx->dbhandle, config->db_cs)) { - err.code = glite_jp_db_SetError(ctx, __FUNCTION__); - err.desc = "Cannot access backend's database (during connect)"; - return glite_jp_stack_error(ctx,&err); - } else { - /* slaves open their own connections */ - glite_lbu_DBClose(ctx->dbhandle); - glite_lbu_FreeDBContext(ctx->dbhandle); - } - - return 0; -} - -int glite_jppsbe_init_slave( - glite_jp_context_t ctx -) -{ - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (glite_lbu_InitDBContext(((glite_lbu_DBContext *)&ctx->dbhandle)) != 0) { - err.code = glite_jp_db_SetError(ctx, __FUNCTION__); - err.desc = "Cannot init backend's database (during init)"; - return glite_jp_stack_error(ctx,&err); - } - if (glite_lbu_DBConnect(ctx->dbhandle, config->db_cs)) { - err.code = glite_jp_db_SetError(ctx, __FUNCTION__); - err.desc = "Cannot access backend's database (during connect)"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - -int glite_jppsbe_register_job( - glite_jp_context_t ctx, - const char *job, - const char *owner -) -{ - glite_jp_error_t err; - char *data_dir = NULL; - char *ju = NULL; - char *ju_path = NULL; - char *ownerhash = NULL; - struct timeval reg_tv; - char *stmt = NULL; - char *dbtime = NULL; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(job != NULL); - assert(owner != NULL); - - gettimeofday(®_tv, 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); - } - - ownerhash = str2md5(owner); /* static buffer */ - if (store_user(ctx, ownerhash, owner)) { - err.code = EIO; - err.desc = "Cannot store user entry"; - goto error_out; - } - - glite_lbu_TimeToDB(reg_tv.tv_sec, &dbtime); - if (!dbtime) { - err.code = ENOMEM; - goto error_out; - } - - trio_asprintf(&stmt,"insert into jobs(jobid,dg_jobid,owner,reg_time) " - "values ('%|Ss','%|Ss','%|Ss', %s)", - ju, job, ownerhash, dbtime); - if (!stmt) { - err.code = ENOMEM; - goto error_out; - } - - if (glite_jp_db_ExecSQL(ctx, stmt, NULL) < 0) { - if (ctx->error->code == EEXIST) { - err.code = EEXIST; - err.desc = "Job already registered"; - } - else { - err.code = EIO; - err.desc = "DB access failed"; - } - 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 (mkdirpath(data_dir, strlen(config->internal_path)) < 0 && - errno != EEXIST) { - err.code = errno; - err.desc = "Cannot mkdir jobs's data directory"; - goto error_out; - } - -error_out: - free(data_dir); - free(stmt); free(dbtime); - free(ju); free(ju_path); - - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - -#if 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; -} -#endif - -int glite_jppsbe_start_upload( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name, - const char *content_type, - char **destination_out, - time_t *commit_before_inout -) -{ - char *data_basename = NULL; - char *data_fname = NULL; - char *ju = NULL; - char *ju_path = NULL; - char *peername = NULL; - char *peerhash = NULL; - char *commit_before_inout_str; - time_t now; - char *now_str = NULL; - - char *stmt = NULL; - glite_lbu_Statement db_res; - int db_retn; - char *db_row[2] = { NULL, NULL }; - - 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); - - assert(class!=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 (peername == NULL) { - err.code = EINVAL; - err.desc = "Cannot obtain client certificate info"; - goto error_out; - } - - trio_asprintf(&stmt, "select owner, reg_time from jobs" - " where jobid='%|Ss'", ju); - - if (!stmt) { - err.code = ENOMEM; - goto error_out; - } - - if ((db_retn = glite_jp_db_ExecSQL(ctx, stmt, &db_res)) <= 0) { - if (db_retn == 0) { - err.code = ENOENT; - err.desc = "No such job registered"; - } else { - err.code = EIO; - err.desc = "DB access failed"; - } - goto error_out; - } - - db_retn = glite_jp_db_FetchRow(ctx, db_res, sizeof(db_row)/sizeof(db_row[0]), NULL, db_row); - if (db_retn != 2) { - glite_jp_db_FreeStmt(&db_res); - err.code = EIO; - err.desc = "DB access failed"; - goto error_out; - } - - glite_jp_db_FreeStmt(&db_res); - - /* XXX authorization done in soap_ops.c */ - - /* XXX name length */ - if (asprintf(&data_basename, "%s%s%s", class, - (name != NULL) ? "." : "", - (name != NULL) ? name : "") == -1) { - err.code = ENOMEM; - goto error_out; - } - - if (asprintf(&data_fname, "%s/data/%s/%d/%s/%s", - config->internal_path, db_row[0], - regtime_trunc(glite_lbu_DBToTime(db_row[1])), - ju, data_basename) == -1) { - err.code = ENOMEM; - goto error_out; - } - if (asprintf(destination_out, "%s/data/%s/%d/%s/%s", - config->external_path, db_row[0], - regtime_trunc(glite_lbu_DBToTime(db_row[1])), - ju, data_basename) == -1) { - err.code = ENOMEM; - goto error_out; - } - - if (commit_before_inout != NULL) - /* XXX no timeout enforced */ - /* XXX: gsoap does not like so much, one year should be enough - *commit_before_inout = (time_t) LONG_MAX; - */ - *commit_before_inout = time(NULL) + 5*60;//365*24*60*60; - - /* - if (add_to_gridmap(ctx, peername)) { - err.code = EIO; - err.desc = "Cannot add peer DN to ftp server authorization file"; - goto error_out; - } - */ - else if (*commit_before_inout > time(NULL) + 5*60) - *commit_before_inout = time(NULL) + 5*60; - - peerhash = str2md5(peername); /* static buffer */ - if (store_user(ctx, peerhash, peername)) { - err.code = EIO; - err.desc = "Cannot store upload user entry"; - goto error_out; - } - - free(stmt); stmt = NULL; - - time(&now); - glite_lbu_TimeToDB(now,&now_str); - - trio_asprintf(&stmt,"delete from files where jobid = '%|Ss' and state = 'uploading' and deadline < %s", ju, now_str); - free(now_str); - - if (!stmt) { - err.code = ENOMEM; - goto error_out; - } - if (glite_jp_db_ExecSQL(ctx, stmt, NULL) < 0) { - err.code = EIO; - err.desc = "DB access failed"; - goto error_out; - } - - free(stmt); stmt = NULL; - - glite_lbu_TimeToDB(*commit_before_inout, &commit_before_inout_str); - trio_asprintf(&stmt,"insert into files" - "(jobid,filename,int_path,ext_url,state,deadline,ul_userid) " - "values ('%|Ss','%|Ss','%|Ss','%|Ss','%|Ss', %s, '%|Ss')", - ju, data_basename, data_fname, *destination_out, "uploading", - commit_before_inout_str, peerhash); - free(commit_before_inout_str); - if (!stmt) { - err.code = ENOMEM; - goto error_out; - } - - if (glite_jp_db_ExecSQL(ctx, stmt, NULL) < 0) { - if (ctx->error->code == EEXIST) { - err.code = EEXIST; - err.desc = "File already stored or upload in progress"; - } else { - err.code = EIO; - err.desc = "DB access failed"; - } - goto error_out; - } - -error_out: - free(db_row[0]); free(db_row[1]); - free(stmt); - free(data_basename); - free(data_fname); - 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 -) -{ - char *peername = NULL; - char *peerhash = NULL; - - char *stmt = NULL; - glite_lbu_Statement db_res; - int db_retn; - char *db_row[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - int i; - - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(destination != NULL); - - trio_asprintf(&stmt, "select * from files where " - "ext_url='%|Ss' and state='uploading'", destination); - if (!stmt) { - err.code = ENOMEM; - goto error_out; - } - - if ((db_retn = glite_jp_db_ExecSQL(ctx, stmt, &db_res)) <= 0) { - if (db_retn == 0) { - err.code = ENOENT; - err.desc = "No such upload in progress"; - } else { - err.code = EIO; - err.desc = "DB access failed"; - } - goto error_out; - } - - db_retn = glite_jp_db_FetchRow(ctx, db_res, sizeof(db_row)/sizeof(db_row[0]), NULL, db_row); - if (db_retn != 7) { - glite_jp_db_FreeStmt(&db_res); - err.code = EIO; - err.desc = "DB access failed"; - goto error_out; - } - glite_jp_db_FreeStmt(&db_res); - - peername = glite_jp_peer_name(ctx); - if (peername == NULL) { - err.code = EINVAL; - err.desc = "Cannot obtain client certificate info"; - goto error_out; - } - - peerhash = str2md5(peername); /* static buffer */ - if (strcmp(peerhash, db_row[6])) { - err.code = EPERM; - err.desc = "Upload started by client with different identity"; - goto error_out; - } - - free(stmt); - trio_asprintf(&stmt,"update files set state='committed', deadline=NULL " - "where jobid='%|Ss' and filename='%|Ss'", db_row[0], db_row[1]); - - if (!stmt) { - err.code = ENOMEM; - goto error_out; - } - - if (glite_jp_db_ExecSQL(ctx, stmt, NULL) < 0) { - err.code = EIO; - err.desc = "DB access failed"; - goto error_out; - } -error_out: - for (i=0; i<7; i++) free(db_row[i]); - free(peername); - free(stmt); - 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, - char **class, - char **name -) -{ - char *stmt = NULL; - glite_lbu_Statement db_res; - int db_retn; - char *db_row[2] = { NULL, NULL}; - int i; - char *cp = NULL; - - glite_jp_error_t err; - - assert(destination != NULL); - assert(job != NULL); - assert(class != NULL); - assert(name != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - - trio_asprintf(&stmt, "select j.dg_jobid,f.filename from jobs j,files f where " - "f.ext_url='%|Ss' and j.jobid=f.jobid", destination); - if (!stmt) { - err.code = ENOMEM; - goto error_out; - } - - if ((db_retn = glite_jp_db_ExecSQL(ctx, stmt, &db_res)) <= 0) { - if (db_retn == 0) { - err.code = ENOENT; - err.desc = "Invalid destination string"; - } else { - err.code = EIO; - err.desc = "DB access failed"; - } - goto error_out; - } - - db_retn = glite_jp_db_FetchRow(ctx, db_res, sizeof(db_row)/sizeof(db_row[0]), NULL, db_row); - if (db_retn != 2) { - glite_jp_db_FreeStmt(&db_res); - err.code = EIO; - err.desc = "DB access failed"; - goto error_out; - } - glite_jp_db_FreeStmt(&db_res); - - *job = strdup(db_row[0]); - - cp = strchr(db_row[1],'.'); - if (!cp) { - *name = NULL; - } else { - *cp++ = '\0'; - *name = strdup(cp); - } - *class = strdup(db_row[1]); - - if (!*job || !*class) { - err.code = ENOMEM; - goto error_out; - } - -error_out: - for (i=0; i<2; i++) free(db_row[i]); - free(stmt); - 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, - const char *class, - const char *name, - char **url_out -) -{ - char *data_basename = NULL; - char *ju = NULL; - char *ju_path = NULL; - - char *stmt = NULL; - glite_lbu_Statement db_res; - int db_retn; - char *db_row[3] = { NULL, NULL, NULL }; - - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(job!=NULL); - assert(url_out != NULL); - - assert(class!=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); - } - - trio_asprintf(&stmt, "select j.owner,reg_time,u.cert_subj from jobs j, users u " - "where j.jobid='%|Ss' and j.owner = u.userid", ju); - - if (!stmt) { - err.code = ENOMEM; - goto error_out; - } - - if ((db_retn = glite_jp_db_ExecSQL(ctx, stmt, &db_res)) <= 0) { - if (db_retn == 0) { - err.code = ENOENT; - err.desc = "No such job registered"; - } else { - err.code = EIO; - err.desc = "DB access failed"; - } - goto error_out; - } - - free(stmt); stmt = NULL; - - db_retn = glite_jp_db_FetchRow(ctx, db_res, sizeof(db_row)/sizeof(db_row[0]), NULL, db_row); - if (db_retn != 3) { - glite_jp_db_FreeStmt(&db_res); - err.code = EIO; - err.desc = "DB access failed"; - goto error_out; - } - - glite_jp_db_FreeStmt(&db_res); - - if (glite_jpps_authz(ctx,SOAP_TYPE___jpsrv__GetJobFiles,job,db_row[2])) { - err.code = EPERM; - goto error_out; - } - - /* XXX name length */ - if (asprintf(&data_basename, "%s%s%s", class, - (name != NULL) ? "." : "", - (name != NULL) ? name : "") == -1) { - err.code = ENOMEM; - goto error_out; - } - - if (asprintf(url_out, "%s/data/%s/%d/%s/%s", - config->external_path, db_row[0], - regtime_trunc(glite_lbu_DBToTime(db_row[1])), - ju, data_basename) == -1) { - err.code = ENOMEM; - goto error_out; - } - -// FIXME: relict? -#if 0 - trio_asprintf(&stmt,"select 'x' from files where jobid='%|Ss' " - "and ext_url = '%|Ss' " - "and state='committed' ",ju,*url_out); - - if ((db_retn = glite_jp_db_ExecSQL(ctx,stmt,&db_res)) <= 0) { - if (db_retn == 0) { - err.code = ENOENT; - err.desc = "not uploaded yet"; - } - else { - err.code = EIO; - err.desc = "DB access failed"; - } - /* goto error_out; */ - } -#endif - -error_out: - free(db_row[0]); free(db_row[1]); - free(stmt); - free(data_basename); - 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, - const char *class, - const char *name, - char **fname_out -) -{ - char *data_basename = NULL; - char *ju = NULL; - char *ju_path = NULL; - - char *stmt = NULL; - glite_lbu_Statement db_res; - int db_retn; - char *db_row[2] = { NULL, NULL }; - - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - assert(job!=NULL); - assert(fname_out != NULL); - - assert(class!=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); - } - - trio_asprintf(&stmt, "select owner, reg_time from jobs " - "where jobid='%|Ss'", ju); - - if (!stmt) { - err.code = ENOMEM; - goto error_out; - } - - if ((db_retn = glite_jp_db_ExecSQL(ctx, stmt, &db_res)) <= 0) { - if (db_retn == 0) { - err.code = ENOENT; - err.desc = "No such job registered"; - } else { - err.code = EIO; - err.desc = "DB access failed"; - } - goto error_out; - } - - db_retn = glite_jp_db_FetchRow(ctx, db_res, sizeof(db_row)/sizeof(db_row[0]), NULL, db_row); - if (db_retn != 2) { - glite_jp_db_FreeStmt(&db_res); - err.code = EIO; - err.desc = "DB access failed"; - goto error_out; - } - - glite_jp_db_FreeStmt(&db_res); - - /* XXX name length */ - if (asprintf(&data_basename, "%s%s%s", class, - (name != NULL) ? "." : "", (name != NULL) ? name : "") == -1) { - err.code = ENOMEM; - goto error_out; - } - - if (asprintf(fname_out, "%s/data/%s/%d/%s/%s", - config->internal_path, db_row[0], - regtime_trunc(glite_lbu_DBToTime(db_row[1])), - ju, data_basename) == -1) { - err.code = ENOMEM; - goto error_out; - } - -error_out: - free(db_row[0]); free(db_row[1]); - free(stmt); - free(data_basename); - 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, - const char *class, - const char *name, - 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, name, &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; - } - - int error = 0; - int created = 0; - if (mode % 4 == O_RDONLY) - handle->fd_gz = gzopen(fname, "r"); - else if (mode % 4 == O_WRONLY) - handle->fd_gz = gzopen(fname, "r+"); - else if (mode % 4 == O_RDWR){ - handle->fd_gz = gzopen(fname, "r+"); - if ((handle->fd_gz == NULL) && (mode & O_CREAT)){ - handle->fd_gz = gzopen(fname, "w+"); - created = 1; // when the file is created, gzread returns -2 - } - } - if (handle->fd_gz == NULL){ - gzerror(((fhandle)handle)->fd_gz, &(err.code)); - err.desc = "Cannot open requested file"; - free(handle); handle = NULL; - error = 1; - goto error_out; - } - - handle->offset = 0; - handle->eof = 0; - - if (! created){ - const int READ_STEP = 8192; - //handle->filedata = malloc(sizeof(*handle->filedata)*READ_STEP); - int diff = 0; - char buf[READ_STEP]; - do{ - diff = gzread(handle->fd_gz, buf/*handle->filedata + handle->eof*/, READ_STEP); - if (diff < 0){ - gzerror(((fhandle)handle)->fd_gz, &(err.code)); - err.desc = "Error reading file"; - free(handle->filedata); - error = 1; - goto error_out; - } - handle->eof += diff; - handle->filedata = realloc(handle->filedata, sizeof(*handle->filedata)*handle->eof); - memcpy(handle->filedata + handle->eof - diff, buf, sizeof(*buf)*diff); - } while(diff == READ_STEP); - } - - /*if (gzclose(fd_gz)){ - gzerror(((fhandle)handle)->fd_gz, &(err.code)); - err.desc = "Error closing file descriptor"; - free(handle->filedata); - goto error_out; - }*/ - - handle->filename = strdup(fname); - handle->filemode = mode; - handle->modified = 0; - - *handle_out = (void*) handle; - -error_out: - free(fname); - if (error) { - 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 (gzclose(((fhandle)handle)->fd_gz)){ - gzerror(((fhandle)handle)->fd_gz, &(err.code)); - err.desc = "Error closing file descriptor"; - goto error_out; - } - - if (((fhandle)handle)->modified){ - if ((((fhandle)handle)->fd_gz = gzopen(((fhandle)handle)->filename, "w")) == NULL){ - gzerror(((fhandle)handle)->fd_gz, &(err.code)); - err.desc = "Error opening file for write changes"; - goto error_out; - } - if (gzwrite(((fhandle)handle)->fd_gz, ((fhandle)handle)->filedata, ((fhandle)handle)->eof) < 0){ - gzerror(((fhandle)handle)->fd_gz, &(err.code)); - err.desc = "Error writing changes"; - goto error_out; - } - if (gzclose(((fhandle)handle)->fd_gz)){ - gzerror(((fhandle)handle)->fd_gz, &(err.code)); - err.desc = "Error closing file descriptor"; - goto error_out; - } - } - -error_out: - free(((fhandle)handle)->filedata); - free(((fhandle)handle)->filename); - free(handle); handle=NULL; - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - return 0; - } -} - - -int glite_jppsbe_file_attrs(glite_jp_context_t ctx, void *handle, struct stat *buf){ - glite_jp_error_t err; - - assert(handle != NULL); - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (! stat(((fhandle)handle)->filename, buf)) { - err.code = errno; - err.desc = "Error calling fstat"; - return glite_jp_stack_error(ctx,&err); - } - - 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 -) -{ - 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 (((fhandle)handle)->filename == NULL){ - err.code = 0; - err.desc = "Cannot read, file not open"; - return glite_jp_stack_error(ctx,&err); - } - - int to_read; - if (offset + nbytes > ((fhandle)handle)->eof) - to_read = ((fhandle)handle)->eof - offset; - else - to_read = nbytes; - memcpy(buf, ((fhandle)handle)->filedata + offset, to_read); - ((fhandle)handle)->offset = offset + to_read; - - *nbytes_ret = to_read; - - 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 (((fhandle)handle)->filename == NULL){ - err.code = 0; - err.desc = "Cannot write, file not open"; - return glite_jp_stack_error(ctx,&err); - } - - if (((fhandle)handle)->filemode % 4 == 0){ - err.desc = "Cannot write to readonly file"; - return glite_jp_stack_error(ctx,&err); - } - - if (offset + nbytes > ((fhandle)handle)->eof){ - ((fhandle)handle)->filedata = realloc(((fhandle)handle)->filedata, offset + nbytes); - ((fhandle)handle)->eof = offset + nbytes; - } - - memcpy(((fhandle)handle)->filedata + offset, buf, nbytes); - - ((fhandle)handle)->modified = 1; - - return 0; -} - -int glite_jppsbe_compress_and_remove_file( - glite_jp_context_t ctx, - const char *job, - const char *class, - const char *name -){ - glite_jp_error_t err; - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - char *src, *dest; - get_job_fname(ctx, job, class, name, &src); - - dest = malloc(sizeof(*dest)*(strlen(src)+strlen(".gz")+1)); - sprintf(dest, "%s.gz", src); - - char buf[8192]; - FILE* s = fopen(src, "r"); - gzFile d = gzopen(dest, "w"); - size_t l; - while ((l = fread(buf, sizeof(*buf), 8192, s)) > 0) - gzwrite(d, buf, sizeof(*buf)*l); - gzclose(d); - fclose(s); - - char *ju, *ju_path; - if (jobid_unique_pathname(ctx, job, &ju, &ju_path, 1) != 0) { - err.code = ctx->error->code; - err.desc = "Cannot obtain jobid unique path/name"; - goto error_out; - } - - rename(dest, src); - -error_out: - if (err.code) { - return glite_jp_stack_error(ctx,&err); - } else { - 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__; - - ((fhandle)handle)->filedata = realloc(((fhandle)handle)->filedata, ((fhandle)handle)->eof + nbytes); - memcpy(((fhandle)handle)->filedata + ((fhandle)handle)->eof, buf, nbytes); - - ((fhandle)handle)->eof += nbytes; - ((fhandle)handle)->modified = 1; - - return 0; -} - -static int get_job_info( - glite_jp_context_t ctx, - const char *job, - char **owner, - struct timeval *tv_reg -) -{ - char *qry,*col[2]; - int rows; - glite_jp_error_t err; - glite_lbu_Statement s = NULL; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - glite_jp_clear_error(ctx); - - trio_asprintf(&qry,"select u.cert_subj,j.reg_time " - "from jobs j, users u " - "where j.owner = u.userid " - "and j.dg_jobid = '%|Ss'",job); - - if ((rows = glite_jp_db_ExecSQL(ctx,qry,&s)) <= 0) { - if (rows == 0) { - err.code = ENOENT; - err.desc = "No records for this job"; - } - else { - err.code = EIO; - err.desc = "DB call fail retrieving job files"; - } - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - if (glite_jp_db_FetchRow(ctx,s,sizeof(col)/sizeof(col[0]), NULL, col) < 0) { - err.code = EIO; - err.desc = "DB call fail retrieving job files"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - *owner = col[0]; - tv_reg->tv_sec = glite_lbu_DBToTime(col[1]); - tv_reg->tv_usec = 0; - free(col[1]); - -cleanup: - free(qry); - if (s) glite_jp_db_FreeStmt(&s); - return err.code; -} - -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 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].name; i++) { -/* must be implemented via filetype plugin - case GLITE_JP_ATTR_TIME: - case GLITE_JP_ATTR_TAG: -*/ - if (!strcmp(attrs_inout[i].name,GLITE_JP_ATTR_OWNER) - || !strcmp(attrs_inout[i].name,GLITE_JP_ATTR_REGTIME)) { - 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; - } - } - else { - err.code = EINVAL; - err.desc = "Invalid attribute type"; - goto error_out; - break; - } - - if (!strcmp(attrs_inout[i].name,GLITE_JP_ATTR_OWNER)) { - attrs_inout[i].value = strdup(owner); - if (!attrs_inout[i].value) { - err.code = ENOMEM; - err.desc = "Cannot copy owner string"; - goto error_out; - } - attrs_inout[i].origin = GLITE_JP_ATTR_ORIG_SYSTEM; - attrs_inout[i].origin_detail = NULL; - - /* XXX */ - attrs_inout[i].timestamp = tv_reg.tv_sec; - } - - if (!strcmp(attrs_inout[i].name,GLITE_JP_ATTR_REGTIME)) { - trio_asprintf(&attrs_inout[i].value,"%ld.%06ld",tv_reg.tv_sec,tv_reg.tv_usec); - attrs_inout[i].origin = GLITE_JP_ATTR_ORIG_SYSTEM; - attrs_inout[i].origin_detail = NULL; - attrs_inout[i].timestamp = tv_reg.tv_sec; - } - -/* must be implemented via filetype plugin - case GLITE_JP_ATTR_TIME: - case GLITE_JP_ATTR_TAG: -*/ - } - -error_out: - free(owner); - if (err.code) { - while (i > 0) { - i--; - glite_jp_attrval_free(attrs_inout+i,0); - } - 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; -} - - -int glite_jppsbe_query( - glite_jp_context_t ctx, - const glite_jp_query_rec_t query[], - char * attrs[], - void *arg, - int (*callback)( - glite_jp_context_t ctx, - const char *job, - const glite_jp_attrval_t metadata[], - void *arg - ) -) -{ - glite_jp_error_t err; - int i,ret; - int quser = 0; - char *where = NULL,*stmt = NULL,*aux = NULL, *cols = NULL; - char *qres[3] = { NULL, NULL, NULL }; - int cmask = 0, owner_idx = -1, reg_idx = -1; - glite_lbu_Statement q = NULL; - glite_jp_attrval_t metadata[3]; - - memset(&err,0,sizeof err); - glite_jp_clear_error(ctx); - err.source = __FUNCTION__; - - /* XXX: assuming not more than 2 */ - memset(metadata,0, sizeof metadata); - - /* XXX: const discarding is OK */ - for (i=0;attrs[i]; i++) { - assert(i<2); - metadata[i].name = (char *) attrs[i]; - } - - for (i=0; query[i].attr; i++) { - char *qitem; - - /* XXX: don't assert() */ - assert(!query[i].binary); - - if (!strcmp(query[i].attr,GLITE_JP_ATTR_OWNER)) { - switch (query[i].op) { - case GLITE_JP_QUERYOP_EQUAL: - quser = 1; - trio_asprintf(&qitem,"u.cert_subj = '%|Ss'",query[i].value); - break; - default: - err.code = EINVAL; - err.desc = "only = allowed for owner queries"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - } - else if (!strcmp(query[i].attr,GLITE_JP_ATTR_REGTIME)) { - time_t t = glite_jp_attr2time(query[i].value); - char *t1,*t2 = NULL; - - glite_lbu_TimeToDB(t, &t1); - switch (query[i].op) { - case GLITE_JP_QUERYOP_EQUAL: - trio_asprintf(&qitem,"j.reg_time = %s",t1); - break; - case GLITE_JP_QUERYOP_UNEQUAL: - trio_asprintf(&qitem,"j.reg_time != %s",t1); - break; - case GLITE_JP_QUERYOP_LESS: - trio_asprintf(&qitem,"j.reg_time < %s",t1); - break; - case GLITE_JP_QUERYOP_GREATER: - trio_asprintf(&qitem,"j.reg_time > %s",t1); - break; - case GLITE_JP_QUERYOP_WITHIN: - free(t2); - glite_lbu_TimeToDB(glite_jp_attr2time(query[i].value2)+1, &t2); - trio_asprintf(&qitem,"j.reg_time >= %s and j.reg_time <= %s",t1,t2); - break; - default: - err.code = EINVAL; - err.desc = "invalid query op"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - free(t1); - free(t2); - } - trio_asprintf(&aux,"%s%s%s",where ? where : "",where ? " and " : "", qitem); - free(where); - free(qitem); - where = aux; - aux = NULL; - } - - for (i=0; metadata[i].name; i++) { - assert (i<2); /* XXX: should never happen */ - - if (!strcmp(metadata[i].name,GLITE_JP_ATTR_OWNER)) { - quser = 1; - cmask |= 1; - owner_idx = i; - } - else if (!strcmp(metadata[i].name,GLITE_JP_ATTR_REGTIME)) { - cmask |= 2; - reg_idx = i; - } - else { - err.code = EINVAL; - err.desc = "invalid query column"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - } - switch (cmask) { - case 1: cols = "j.dg_jobid,u.cert_subj"; break; - case 2: cols = "j.dg_jobid,j.reg_time"; break; - case 3: cols = "j.dg_jobid,u.cert_subj,j.reg_time"; break; - } - - trio_asprintf(&stmt,"select %s from jobs j%s where %s %s", - cols, - quser ? ",users u" : "", - where, - cmask & 1 ? "and u.userid = j.owner" : ""); - - if ((ret = glite_jp_db_ExecSQL(ctx,stmt,&q)) < 0) { - err.code = EIO; - err.desc = "DB call fail"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - else if (ret == 0) { - err.code = ENOENT; - err.desc = "no matching jobs"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - while ((ret = glite_jp_db_FetchRow(ctx,q,sizeof(qres)/sizeof(qres[0]), NULL, qres)) > 0) { - if (cmask & 1) { - /* XXX: owner always first */ - metadata[owner_idx].value = qres[1]; - metadata[owner_idx].origin = GLITE_JP_ATTR_ORIG_SYSTEM; - qres[1] = NULL; - } - if (cmask & 2) { - int qi = cmask == 2 ? 1 : 2; - time_t t = glite_lbu_DBToTime(qres[qi]); - metadata[reg_idx].value = glite_jp_time2attr(t); - metadata[reg_idx].origin = GLITE_JP_ATTR_ORIG_SYSTEM; - free(qres[qi]); - qres[qi] = NULL; - } - if (callback(ctx,qres[0],metadata,arg)) { - err.code = EIO; - err.desc = qres[0]; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - free(qres[0]); - free(metadata[0].value); - free(metadata[1].value); - qres[0] = metadata[0].value = metadata[1].value = NULL; - } - - - if (ret < 0) { - err.code = EIO; - err.desc = "DB call fail"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - -cleanup: - free(where); - free(aux); - free(stmt); - free(qres[0]); free(qres[1]); free(qres[2]); - free(metadata[0].value); free(metadata[1].value); - if (q) glite_jp_db_FreeStmt(&q); - - return err.code; -} - - -int glite_jppsbe_is_metadata(glite_jp_context_t ctx,const char *attr) -{ - /* XXX: should be more */ - if (!strcmp(attr,GLITE_JP_ATTR_OWNER)) return 1; - if (!strcmp(attr,GLITE_JP_ATTR_REGTIME)) return 1; - - return 0; -} - - -int glite_jppsbe_get_names( - glite_jp_context_t ctx, - const char *job, - const char *class, - char ***names_out -) -{ - char *qry = NULL,*file = NULL,*dot; - char **out = NULL; - glite_lbu_Statement s = NULL; - int rows,nout = 0; - glite_jp_error_t err; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - trio_asprintf(&qry,"select filename from files f,jobs j " - "where j.dg_jobid = '%|Ss' and j.jobid = f.jobid and f.state = 'committed'",job); - - if ((rows = glite_jp_db_ExecSQL(ctx,qry,&s)) <= 0) { - if (rows == 0) { - err.code = ENOENT; - err.desc = "No files for this job"; - } - else { - err.code = EIO; - err.desc = "DB call fail retrieving job files"; - } - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - while ((rows = glite_jp_db_FetchRow(ctx,s,1,NULL,&file))) { - if (rows < 0) { - err.code = EIO; - err.desc = "DB call fail retrieving job files"; - goto cleanup; - } - - dot = strchr(file,'.'); /* XXX: can class contain dot? */ - - if (dot) *dot = 0; - out = realloc(out,(nout+1) * sizeof *out); - if (!strcmp(file,class)) out[nout++] = dot ? dot+1 : NULL; - - free(file); - file = NULL; - } - -cleanup: - if (s) glite_jp_db_FreeStmt(&s); - free(qry); - free(file); - - if (ctx->error) { - int i; - for (i=0; out && out[i]; i++) free(out[i]); - free(out); - return -ctx->error->code; - } - - if (nout) *names_out = out; - return nout; -} - - -/** mark the job as sent to this feed */ -int glite_jppsbe_set_fed( - glite_jp_context_t ctx, - const char *feed, - const char *job -) -{ - char *stmt = NULL,*u = NULL; - int rows,ret; - glite_jp_error_t err; - memset(&err,0,sizeof err); - - if ((ret = jobid_unique_pathname(ctx,job,&u,NULL,0))) return ret; - - trio_asprintf(&stmt,"insert into fed_jobs(feedid,jobid) " - "values ('%|Ss','%|Ss')", feed,u); - free(u); - - if ((rows = glite_jp_db_ExecSQL(ctx,stmt,NULL)) < 0) { - err.source = __FUNCTION__; - err.code = EIO; - err.desc = "insert into fed_jobs"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - if (rows != 1) { - err.source = __FUNCTION__; - err.code = EIO; - err.desc = "inserted rows != 1"; - glite_jp_stack_error(ctx,&err); - } - -cleanup: - free(stmt); - return err.code; -} - - -/** check whether the job has been already sent to this feed */ -int glite_jppsbe_check_fed( - glite_jp_context_t ctx, - const char *feed, - const char *job, - int *result -) -{ - char *stmt = NULL,*u = NULL; - int rows,ret; - glite_jp_error_t err; - memset(&err,0,sizeof err); - - if ((ret = jobid_unique_pathname(ctx,job,&u,NULL,0))) return ret; - - trio_asprintf(&stmt,"select 'x' from fed_jobs " - "where jobid = '%|Ss' and feedid = '%|Ss'", - u,feed); - - free(u); - - if ((rows = glite_jp_db_ExecSQL(ctx,stmt,NULL)) < 0) { - err.source = __FUNCTION__; - err.code = EIO; - err.desc = "select from fed_jobs"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - *result = rows; - -cleanup: - free(stmt); - return err.code; -} - - -/** store the feed to database */ -int glite_jppsbe_store_feed( - glite_jp_context_t ctx, - struct jpfeed *feed -) -{ - char *stmt,*aux,*alist,*qlist,*e; - int i,rows; - glite_jp_error_t err; - - memset(&err,0,sizeof err); - - qlist = alist = stmt = aux = e = NULL; - - for (i=0; feed->attrs[i]; i++) { - char *e; - trio_asprintf(&aux,"%s%s%s", - alist ? alist : "", - alist ? "\n" : "", - e = glite_lbu_EscapeULM(feed->attrs[i])); - free(e); - free(alist); - alist = aux; - aux = NULL; - } - - for (i=0; feed->qry[i].attr; i++) { - char op,*e1,*e2 = NULL; - - /* XXX */ - assert(!feed->qry[i].binary); - - switch (feed->qry[i].op) { - case GLITE_JP_QUERYOP_EQUAL: op = '='; break; - case GLITE_JP_QUERYOP_UNEQUAL: op = '!'; break; - case GLITE_JP_QUERYOP_LESS: op = '<'; break; - case GLITE_JP_QUERYOP_GREATER: op = '>'; break; - case GLITE_JP_QUERYOP_EXISTS: op = 'E'; break; - default: abort(); /* XXX */ - } - - trio_asprintf(&aux,"%s%s%s\n%c\n%s", - qlist ? qlist : "", - qlist ? "\n" : "", - e1 = glite_lbu_EscapeULM(feed->qry[i].attr), - op, - op != 'E' ? e2 = glite_lbu_EscapeULM(feed->qry[i].value) : "E"); - free(e1); free(e2); - - free(qlist); - qlist = aux; - aux = NULL; - } - - glite_lbu_TimeToDB(feed->expires, &e); - trio_asprintf(&stmt,"insert into feeds(feedid,destination,expires,cols,query) " - "values ('%|Ss','%|Ss',%s,'%|Ss','%|Ss')", - feed->id,feed->destination, - e, - alist,qlist); - - free(alist); free(qlist); free(e); - - if ((rows = glite_jp_db_ExecSQL(ctx,stmt,NULL)) < 0) { - err.source = __FUNCTION__; - err.code = EIO; - err.desc = "insert into fed_jobs"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - if (rows != 1) { - err.source = __FUNCTION__; - err.code = EIO; - err.desc = "inserted rows != 1"; - glite_jp_stack_error(ctx,&err); - } - -cleanup: - free(stmt); - return err.code; - -} - -int glite_jppsbe_refresh_feed( - glite_jp_context_t ctx, - char *feed_id, - time_t expires -) -{ - glite_jp_error_t err; - memset(&err,0,sizeof err); - - char *stmt = NULL; - char *e = NULL; - glite_lbu_TimeToDB(expires, &e); - trio_asprintf(&stmt, "update feeds set expires=%s where feedid='%s'", - e, feed_id); - if (!stmt) { - err.code = ENOMEM; - goto error_out; - } - - if (glite_jp_db_ExecSQL(ctx, stmt, NULL) < 0) { - err.code = EIO; - err.desc = "DB access failed"; - goto error_out; - } - -error_out: - free(stmt); - free(e); - if (err.code) - return glite_jp_stack_error(ctx,&err); - else - return 0; -} - -/** purge expired feeds */ -int glite_jppsbe_purge_feeds( - glite_jp_context_t ctx -) -{ - char *stmt = NULL,*feed = NULL; - char *expires; - glite_jp_error_t err; - glite_lbu_Statement q = NULL; - int rows; - - glite_lbu_TimeToDB(time(NULL), &expires); - memset(&err,0,sizeof err); - - trio_asprintf(&stmt,"select feedid from feeds where expires < %s",expires); - - if ((rows = glite_jp_db_ExecSQL(ctx, stmt, &q)) < 0) { - err.code = EIO; - err.desc = "select from feeds"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - while ((rows = glite_jp_db_FetchRow(ctx,q,1,NULL,&feed)) > 0) { - printf("feed %s has expired.\n", feed); - free(stmt); - trio_asprintf(&stmt,"delete from fed_jobs where feedid = '%|Ss'",feed); - if ((rows = glite_jp_db_ExecSQL(ctx, stmt, NULL)) < 0) { - err.code = EIO; - err.desc = "delete from fed_jobs"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - } - - free(stmt); - trio_asprintf(&stmt,"delete from feeds where expires < %s",expires); - if ((rows = glite_jp_db_ExecSQL(ctx, stmt, NULL)) < 0) { - err.code = EIO; - err.desc = "select from feeds"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - -cleanup: - glite_jp_db_FreeStmt(&q); - free(feed); - free(stmt); - free(expires); - return err.code; -} - - -/** read stored feed into context */ -int glite_jppsbe_read_feeds( - glite_jp_context_t ctx -) -{ - char *stmt,*res[5],*expires; - glite_jp_error_t err; - glite_lbu_Statement q = NULL; - int rows; - - stmt = expires = NULL; - memset(&err,0,sizeof err); - memset(&res,0,sizeof res); - err.source = __FUNCTION__; - - glite_lbu_TimeToDB(time(NULL), &expires); - trio_asprintf(&stmt,"select feedid,destination,expires,cols,query " - "from feeds " - "where expires > %s",expires); - free(expires); expires = NULL; - - if ((rows = glite_jp_db_ExecSQL(ctx, stmt, &q)) < 0) { - err.code = EIO; - err.desc = "select from feeds"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - free(stmt); - - while ((rows = glite_jp_db_FetchRow(ctx,q,sizeof(res)/sizeof(res[0]),NULL, res)) > 0) { - struct jpfeed *f = calloc(1,sizeof *f); - int n; - char *p; - - f->id = res[0]; res[0] = NULL; - f->destination = res[1]; res[1] = NULL; - f->expires = glite_lbu_DBToTime(res[2]); free(res[2]); res[2] = NULL; - - n = 0; - for (p = strtok(res[3],"\n"); p; p = strtok(NULL,"\n")) { - f->attrs = realloc(f->attrs,(n+2) * sizeof *f->attrs); - f->attrs[n] = glite_lbu_UnescapeULM(p); - f->attrs[++n] = NULL; - } - - n = 0; - for (p = strtok(res[4],"\n"); p; p = strtok(NULL,"\n")) { - f->qry = realloc(f->qry,(n+2) * sizeof *f->qry); - memset(&f->qry[n],0,sizeof *f->qry); - f->qry[n].attr = glite_lbu_EscapeULM(p); - p = strtok(NULL,"\n"); - switch (*p) { - case '=': f->qry[n].op = GLITE_JP_QUERYOP_EQUAL; break; - case '<': f->qry[n].op = GLITE_JP_QUERYOP_LESS; break; - case '>': f->qry[n].op = GLITE_JP_QUERYOP_GREATER; break; - case '!': f->qry[n].op = GLITE_JP_QUERYOP_UNEQUAL; break; - case 'E': f->qry[n].op = GLITE_JP_QUERYOP_EXISTS; break; - default: abort(); /* XXX: internal inconsistency */ - } - p = strtok(NULL,"\n"); - if (f->qry[n].op != GLITE_JP_QUERYOP_EXISTS) - f->qry[n].value = glite_lbu_EscapeULM(p); - - memset(&f->qry[++n],0,sizeof *f->qry); - } - f->next = ctx->feeds; - ctx->feeds = f; - } - - if (rows < 0) { - err.code = EIO; - err.desc = "fetch from feeds"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - -cleanup: - glite_jp_db_FreeStmt(&q); - free(res[0]); free(res[1]); free(res[2]); free(res[3]); free(res[4]); - return err.code; -} - -int glite_jppsbe_append_tags( - void *fpctx, - char *jobid, - glite_jp_attrval_t *attr -) -{ - void *file_be; - glite_jp_error_t err; - glite_jp_context_t ctx = fpctx; - int i; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (glite_jppsbe_open_file(ctx,jobid,"tags",NULL, - O_RDWR|O_CREAT,&file_be) - // XXX: tags need reading to check magic number - ) { - err.code = EIO; - err.desc = "cannot open tags file"; - return glite_jp_stack_error(ctx,&err); - } - - for (i=0; attr[i].name; i++) { - if (tag_append(ctx,file_be,attr+i)) - { - glite_jp_error_t *e = ctx->error; - err.code = EIO; - err.desc = "cannot append tag"; - - glite_jppsbe_close_file(ctx,file_be); - glite_jp_clear_error(ctx); - ctx->error = e; - - return glite_jp_stack_error(ctx,&err); - } - } - - if (glite_jppsbe_close_file(ctx,file_be)) - { - err.code = EIO; - err.desc = "cannot close tags file"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - - -int glite_jppsbe_read_tag( - void *fpctx, - const char *jobid, - const char *attr, - glite_jp_attrval_t **attrval -) -{ - glite_jp_error_t err; - glite_jp_context_t ctx = fpctx; - struct tags_handle *h; - int i; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - h = malloc(sizeof (*h)); - h->tags = NULL; - h->n = 0; - - if (glite_jppsbe_open_file(ctx,jobid,"tags",NULL, - O_RDONLY,&(h->bhandle)) - // XXX: tags need reading to check magic number - ) { - err.code = EIO; - err.desc = "cannot open tags file"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - - if (tag_attr(ctx,h,attr,attrval)){ - glite_jp_error_t *e; - err.code = EIO; - err.desc = "cannot read tag"; - glite_jp_stack_error(ctx,&err); - e = ctx->error; - ctx->error = NULL; - glite_jppsbe_close_file(ctx,h->bhandle); - ctx->error = e; - goto cleanup; - } - - if (glite_jppsbe_close_file(ctx,h->bhandle)) - { - err.code = EIO; - err.desc = "cannot close tags file"; - glite_jp_stack_error(ctx,&err); - goto cleanup; - } - -cleanup: - for (i=0; i < h->n; i++){ - free(h->tags[i].name); - free(h->tags[i].value); - } - free(h->tags); - free(h); - - return err.code; -} - - - -/* 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 -*/ diff --git a/org.glite.jp.primary/src/sandbox_plugin.c b/org.glite.jp.primary/src/sandbox_plugin.c deleted file mode 100644 index 89ba7a6..0000000 --- a/org.glite.jp.primary/src/sandbox_plugin.c +++ /dev/null @@ -1,280 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include "glite/jp/backend.h" - -#include "glite/jp/file_plugin.h" -#include "glite/jp/builtin_plugins.h" - -#define ALLOC_CHUNK 3 - - -typedef struct _sb_handle { - void *bhandle; - TAR *t; - tartype_t *tt; - char **file_names; -} sb_handle; - -// Global data needed for read/write wrappers -static struct { - void *bhandle; - glite_jp_context_t ctx; - off_t offset; -} global_data; - - -//static int sandbox_append(void *,void *,int,...); -static int sandbox_open(void *,void *,const char *uri,void **); -static int sandbox_close(void *,void *); -static int sandbox_attr(void *,void *,const char *,glite_jp_attrval_t **); -static int sandbox_filecom(void *,void *); - -int init(glite_jp_context_t ctx, glite_jpps_fplug_data_t *data) -{ - data->fpctx = ctx; - global_data.ctx = ctx; - - data->uris = calloc(2,sizeof *data->uris); - data->uris[0] = strdup(GLITE_JP_FILETYPE_ISB); - - data->classes = calloc(2,sizeof *data->classes); - data->classes[0] = strdup("sandbox"); - - data->namespaces = calloc(5, sizeof *data->namespaces); - data->namespaces[0] = strdup(GLITE_JP_ISB_NS); - data->namespaces[1] = strdup(GLITE_JP_OSB_NS); - data->namespaces[2] = strdup(GLITE_JP_ISB_CONTENT_NS); - data->namespaces[3] = strdup(GLITE_JP_OSB_CONTENT_NS); - - data->ops.open = sandbox_open; - data->ops.close = sandbox_close; - data->ops.attr = sandbox_attr; - data->ops.filecom = sandbox_filecom; - - printf("sandbox_plugin: URI: \"%s\"\n",GLITE_JP_FILETYPE_ISB); - - return 0; -} - - -/** -* Wrappers for tar_open -*/ -static int my_open(const char *pathname, int flags, ...) { - // Do not open file, it is opened in ftp_backend - // returned fd does not matter, read/write/close does ftp_backend - return 12345; -} - -static int my_close(int fd) { - // Closed in ftp_backend - return 0; -} - -static ssize_t my_read(int fd, void *buf, size_t count) { - // wrapper around glite_jppsbe_pread - size_t r; - - if (glite_jppsbe_pread(global_data.ctx,global_data.bhandle,buf,count,global_data.offset,&r)) { - errno = global_data.ctx->error->code; - return -1; - } - - global_data.offset += r; - - return r; -} - -static ssize_t my_write(int fd, const void *buf, size_t count) { - // wrapper around glite_jppsbe_pwrite - // just stub, not needed here&now -} - - - -static int sandbox_open(void *fpctx,void *bhandle,const char *uri,void **handle) -{ - sb_handle *h = calloc(1,sizeof *h); - - - printf("sandbox_open() called\n"); - - h->bhandle = bhandle; - global_data.bhandle = bhandle; - global_data.offset = 0; - - h->tt = malloc(sizeof(*h->tt)); - h->tt->openfunc = my_open; - h->tt->closefunc = my_close; - h->tt->readfunc = my_read; - h->tt->writefunc = my_write; - - if (tar_open(&h->t, NULL /* not needed, opened in ftp_backend */, h->tt, O_RDONLY, 0, TAR_GNU) == -1) - printf("tar_open()\n"); //XXX: use glite_jp_stack_error - - *handle = h; - - return 0; -} - - -static int sandbox_close(void *fpctx,void *handle) -{ - int i; - sb_handle *h = handle; - - tar_close(h->t); - free(h->tt); - - for (i=0; h->file_names; i++) free(h->file_names[i]); - free(h->file_names); - - free(h); - - printf("sandbox_close() called\n"); - - return 0; -} - - -static int sandbox_attr(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval) -{ - glite_jp_error_t err; - glite_jp_context_t ctx = fpctx; - glite_jp_attrval_t *out = NULL; - int i,nout = 0, count = 0; - sb_handle *h = handle; - - - printf("sandbox_attr() called\n"); - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - glite_jp_clear_error(ctx); - - *attrval = NULL; - - if (!strcmp(attr, GLITE_JP_ATTR_ISB_FILENAME)) { - while ((i = th_read(h->t)) == 0) - { - printf("-- %s\n", th_get_pathname(h->t)); - - if ( !(count % ALLOC_CHUNK) ) { - *attrval = realloc(*attrval, (count + ALLOC_CHUNK + 1) * sizeof(**attrval) ); - memset( (*attrval) + count, 0, (ALLOC_CHUNK + 1) * sizeof(**attrval)); - } - (*attrval)[count].name = strdup(GLITE_JP_ATTR_ISB_FILENAME); - (*attrval)[count].value = strdup(th_get_pathname(h->t)); - (*attrval)[count].origin = GLITE_JP_ATTR_ORIG_FILE; - (*attrval)[count].timestamp = th_get_mtime(h->t); - - count++; - - if (TH_ISREG(h->t) && tar_skip_regfile(h->t) != 0) - { - err.code = EIO; - err.desc = "tar_skip_regfile"; - return glite_jp_stack_error(ctx,&err); - } - } - } - else if (!strcmp(attr, GLITE_JP_ATTR_OSB_FILENAME)) { - printf("Namespace %s not implemented yet\n", GLITE_JP_ATTR_OSB_FILENAME); - } - else if (strstr(attr,GLITE_JP_OSB_CONTENT_NS)) { - printf("Namespace %s not implemented yet\n", GLITE_JP_OSB_CONTENT_NS); - } - else if (strstr(attr,GLITE_JP_ISB_CONTENT_NS)) { - char *fileName = (char *) attr + sizeof(GLITE_JP_ISB_CONTENT_NS); - - printf("untaring file: %s\n", fileName); - - while (th_read(h->t) == 0) - { - if ( !strcmp(fileName, th_get_pathname(h->t)) ) { - /* extract the file */ - int k; - size_t size; - char buf[T_BLOCKSIZE]; - char *value; - - - if (!TH_ISREG(h->t)) assert(0); // not a regular file - - size = th_get_size(h->t); - value = (char *) malloc(size * sizeof(char) + 1); - memset( value, 0, size * sizeof(char) + 1); - - for (i = 0; i < size; i += T_BLOCKSIZE) - { - k = tar_block_read(h->t, buf); - if (k == -1) - { - err.code = errno; - err.desc = "tar_block_read"; - return glite_jp_stack_error(ctx,&err); - } - - // tar_block_read calls glite_jppsbe_pread, which usually - // returns whole block (read from the middle of uploaded - // tar file - // so cut k in order to the last chunk had correct size - if (i + T_BLOCKSIZE > size) { - k = size - i; - } - - strncpy(value + i, buf, k); - } - *attrval = malloc(2 * sizeof(**attrval) ); - memset( (*attrval), 0, 2 * sizeof(**attrval)); - - (*attrval)[0].name = strdup(attr); - (*attrval)[0].value = value; - (*attrval)[0].origin = GLITE_JP_ATTR_ORIG_FILE; - (*attrval)[0].timestamp = th_get_mtime(h->t); - } - else if (TH_ISREG(h->t) && tar_skip_regfile(h->t) != 0) - { - err.code = EIO; - err.desc = "tar_skip_regfile"; - return glite_jp_stack_error(ctx,&err); - } - } - } - - return glite_jp_stack_error(ctx,&err); -} - -static int sandbox_filecom(void *fpctx,void *handle){ - return -1; -} - diff --git a/org.glite.jp.primary/src/simple_server.c b/org.glite.jp.primary/src/simple_server.c deleted file mode 100644 index 3ce025d..0000000 --- a/org.glite.jp.primary/src/simple_server.c +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include - -#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} }; diff --git a/org.glite.jp.primary/src/soap_ops.c b/org.glite.jp.primary/src/soap_ops.c deleted file mode 100644 index 87ab088..0000000 --- a/org.glite.jp.primary/src/soap_ops.c +++ /dev/null @@ -1,620 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include - -#undef SOAP_FMAC1 -#define SOAP_FMAC1 static - -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" -#include "glite/jp/attr.h" -#include "glite/jp/known_attr.h" - -#include "feed.h" -#include "attrs.h" - -#include "jptype_map.h" -#include "glite/security/glite_gscompat.h" - -#include "glite/jp/file_plugin.h" -#include "glite/jp/builtin_plugins.h" - -/* the same as ServerLib.c but without WITH_NOGLOBAL which breaks the soap_env_ctx trick */ -#define SOAP_FMAC3 static -#include "jpps_C.c" -#include "jpps_Server.c" - -#include "jpps_.nsmap" - -#include "soap_env_ctx.h" -#include "soap_env_ctx.c" - -#include "glite/jp/ws_fault.c" -#include "soap_util.c" - -#define err2fault(CTX, SOAP) glite_jp_server_err2fault((CTX), (SOAP)); - -#define CONTEXT_FROM_SOAP(soap,ctx) glite_jp_context_t ctx = (glite_jp_context_t) ((soap)->user) - -#define SIZE_TO_COMPRESS 1024 - -int glite_jpps_srv_init(glite_jp_context_t ctx) -{ - glite_jp_soap_env_ctx = &my_soap_env_ctx; - return 0; -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__RegisterJob( - struct soap *soap, - struct _jpelem__RegisterJob *in, - struct _jpelem__RegisterJobResponse *empty) -{ - CONTEXT_FROM_SOAP(soap,ctx); - glite_jp_attrval_t owner_val[2]; - - printf("%s %s %s\n",__FUNCTION__,in->job,in->owner); - if (glite_jpps_authz(ctx,SOAP_TYPE___jpsrv__RegisterJob,in->job,in->owner) || - glite_jppsbe_register_job(ctx,in->job,in->owner)) - { - err2fault(ctx,soap); - return SOAP_FAULT; - } - - memset(owner_val, 0, 2 * sizeof(glite_jp_attrval_t)); - owner_val[0].name = GLITE_JP_ATTR_OWNER; - owner_val[0].value = in->owner; - owner_val[0].origin = GLITE_JP_ATTR_ORIG_SYSTEM; - owner_val[0].timestamp = time(NULL); - owner_val[0].origin_detail = NULL; - owner_val[1].name = NULL; - -/* XXX: errrors should be ingored but not silently */ - glite_jpps_match_attr(ctx,in->job,owner_val); - - return SOAP_OK; -} - - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__StartUpload( - struct soap *soap, - struct _jpelem__StartUpload *in, - struct _jpelem__StartUploadResponse *out) -{ - CONTEXT_FROM_SOAP(soap,ctx); - char *destination; - time_t commit_before = in->commitBefore; - glite_jp_error_t err; - glite_jpps_fplug_data_t **pd = NULL; - int i; - - glite_jp_clear_error(ctx); - memset(&err,0,sizeof err); - - if (glite_jpps_authz(ctx,SOAP_TYPE___jpsrv__StartUpload,NULL,NULL)) { - err2fault(ctx,soap); - return SOAP_FAULT; - } - - switch (glite_jpps_fplug_lookup(ctx,in->class_,&pd)) { - case ENOENT: - err.code = ENOENT; - err.source = __FUNCTION__; - err.desc = "unknown file class"; - glite_jp_stack_error(ctx,&err); - err2fault(ctx,soap); - return SOAP_FAULT; - case 0: break; - default: - err2fault(ctx,soap); - return SOAP_FAULT; - } - - for (i=0; pd[0]->uris[i] && strcmp(pd[0]->uris[i],in->class_); i++); - assert(pd[0]->uris[i]); - - if (glite_jppsbe_start_upload(ctx,in->job,pd[0]->classes[i],in->name,in->contentType, - &destination,&commit_before)) - { - err2fault(ctx,soap); - free(pd); - return SOAP_FAULT; - } - - out->destination = soap_strdup(soap,destination); - free(destination); - out->commitBefore = commit_before; - - free(pd); - return SOAP_OK; -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__CommitUpload( - struct soap *soap, - struct _jpelem__CommitUpload *in, - struct _jpelem__CommitUploadResponse *out) -{ - CONTEXT_FROM_SOAP(soap,ctx); - char *job,*class,*name; - - job = class = name = NULL; - - if (glite_jpps_authz(ctx,SOAP_TYPE___jpsrv__CommitUpload,NULL,NULL) || - glite_jppsbe_commit_upload(ctx,in->destination)) - { - err2fault(ctx,soap); - return SOAP_FAULT; - } - - /* XXX: should not fail when commit_upload was OK */ - assert(glite_jppsbe_destination_info(ctx,in->destination,&job,&class,&name) == 0); - - /* XXX: ignore errors but don't fail silenty */ - glite_jpps_match_file(ctx,job,class,name); - - // apply plugins to commited file - glite_jpps_fplug_data_t *pd; - int i, j; - void *beh, *ph; - if (ctx->plugins) - for (i = 0; ctx->plugins[i]; i++) { - pd = ctx->plugins[i]; - if (pd->classes) - for (j = 0; pd->classes[j]; j++) - if (strcmp(class, pd->classes[j]) == 0){ - if (! glite_jppsbe_open_file(ctx,job,class, name, O_RDONLY, &beh)) { - if (!pd->ops.open(pd->fpctx,beh,pd->uris[j],&ph)) { - pd->ops.filecom(pd->fpctx, ph); - pd->ops.close(pd->fpctx, ph); - } - glite_jppsbe_close_file(ctx,beh); - } - - } - } - - char *fname; - //XXX ignore error - if (!glite_jppsbe_open_file(ctx,job,class, name, O_RDONLY, &beh)){ - struct stat fattr; - glite_jppsbe_file_attrs(ctx, beh, &fattr); - glite_jppsbe_close_file(ctx, beh); - if (fattr.st_size > SIZE_TO_COMPRESS) - glite_jppsbe_compress_and_remove_file(ctx,job,class, name); - } - - free(job); free(class); free(name); - - return SOAP_OK; -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__RecordTag( - struct soap *soap, - struct _jpelem__RecordTag *in, - struct _jpelem__RecordTagResponse *out) -{ - CONTEXT_FROM_SOAP(soap,ctx); - void *file_be,*file_p; - glite_jp_attrval_t attr[2], meta[2]; - - file_be = file_p = NULL; - - memset(attr, 0, 2 * sizeof(glite_jp_attrval_t)); - memset(meta,0,sizeof meta); - meta[0].name = strdup(GLITE_JP_ATTR_OWNER); - - if (glite_jppsbe_get_job_metadata(ctx,in->jobid,meta)) { - goto err; - } - - if (glite_jpps_authz(ctx,SOAP_TYPE___jpsrv__RecordTag,in->jobid,meta[0].value)) { - goto err; - } - - attr[0].name = in->tag->name; - if (GSOAP_ISSTRING(in->tag->value)) { - attr[0].value = GSOAP_STRING(in->tag->value); - attr[0].binary = 0; - } - else { - attr[0].value = GSOAP_BLOB(in->tag->value)->__ptr; - attr[0].size = GSOAP_BLOB(in->tag->value)->__size; - attr[0].binary = 1; - } - attr[0].origin = GLITE_JP_ATTR_ORIG_USER; - attr[0].timestamp = time(NULL); - attr[0].origin_detail = NULL; /* XXX */ - attr[1].name = NULL; - - if (glite_jppsbe_append_tags(ctx,in->jobid,attr)) goto err; - - /* XXX: ignore errors but don't fail silenty */ - glite_jpps_match_attr(ctx,in->jobid,attr); - - return SOAP_OK; -err: - glite_jp_attrval_free(meta,0); - err2fault(ctx,soap); - return SOAP_FAULT; -} - - - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__RecordMultiTags( - struct soap *soap, - struct _jpelem__RecordMultiTags *in, - struct _jpelem__RecordMultiTagsResponse *out -) -{ - CONTEXT_FROM_SOAP(soap,ctx); - int i,j,ret = SOAP_OK; - char **jobs = NULL; - glite_jp_attrval_t **attrs = NULL,meta[2]; - - memset(meta,0,sizeof meta); - meta[0].name = strdup(GLITE_JP_ATTR_OWNER); - - for (i=0; i__sizejobs; i++) { - struct jptype__jobRecord *jr = GLITE_SECURITY_GSOAP_LIST_GET(in->jobs,i); - - if (glite_jppsbe_get_job_metadata(ctx,jr->jobid,meta)) { - ret = SOAP_FAULT; - goto cleanup; - } - -/* XXX: the same as single tag */ - if (glite_jpps_authz(ctx,SOAP_TYPE___jpsrv__RecordTag,jr->jobid,meta[0].value)) { - ret = SOAP_FAULT; - goto cleanup; - } - - jobs = realloc(jobs,sizeof(*jobs) * (i+2)); - jobs[i] = jr->jobid; - jobs[i+1] = NULL; - - attrs = realloc(attrs,sizeof(*attrs) * (i+2)); - attrs[i] = calloc(jr->__sizeattributes+1,sizeof attrs[i][0]); - attrs[i+1] = NULL; - - for (j=0; j < jr->__sizeattributes; j++) { - struct jptype__attrValue *a = GLITE_SECURITY_GSOAP_LIST_GET(jr->attributes,j); - - attrs[i][j].name = a->name; - if (GSOAP_ISSTRING(a->value)) { - attrs[i][j].value = GSOAP_STRING(a->value); - attrs[i][j].binary = 0; - } - else { - attrs[i][j].value = GSOAP_BLOB(a->value)->__ptr; - attrs[i][j].size = GSOAP_BLOB(a->value)->__size; - attrs[i][j].binary = 1; - } - /* XXX input not favoured */ - attrs[i][j].origin = GLITE_JP_ATTR_ORIG_USER; - attrs[i][j].timestamp = time(NULL); - attrs[i][j].origin_detail = NULL; - } - if (glite_jppsbe_append_tags(ctx,jobs[i],attrs[i])) { - err2fault(ctx,soap); - ret = SOAP_FAULT; - goto cleanup; - } - } - -/* XXX: ignore error */ - glite_jpps_match_attr_multi(ctx,(const char **) jobs,(const glite_jp_attrval_t **) attrs); - -cleanup: - if (attrs) { - for (i=0; attrs[i]; i++) { - for (j=0; attrs[i][j].name; j++) glite_jp_attrval_free(&attrs[i][j],0); - free(attrs[i]); - } - free(attrs); - } - free(jobs); - - glite_jp_attrval_free(meta,0); - if (ret == SOAP_FAULT) err2fault(ctx,soap); - return ret; -} - -static void s2jp_qval(const struct jptype__stringOrBlob *in, char **value, int *binary, size_t *size) -{ - if (GSOAP_ISSTRING(in)) { - *value = GSOAP_STRING(in); - *binary = 0; - *size = 0; - } - else { - assert(GSOAP_BLOB(in)); /* XXX: should report error instead */ - *value = GSOAP_BLOB(in)->__ptr; - *binary = 1; - *size = GSOAP_BLOB(in)->__size; - } -} - -static void s2jp_query(const struct jptype__primaryQuery *in, glite_jp_query_rec_t *out) -{ - int b; - - out->attr = in->attr; - - s2jp_qval(in->value,&out->value,&out->binary,&out->size); - 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_qval(in->value2,&out->value2,&b,&out->size2); - assert(out->binary == b); /* XXX: report error instead */ - - break; - } - - if (in->origin) switch (*in->origin) { - case jptype__attrOrig__SYSTEM: out->origin = GLITE_JP_ATTR_ORIG_SYSTEM; break; - case jptype__attrOrig__USER: out->origin = GLITE_JP_ATTR_ORIG_USER; break; - case jptype__attrOrig__FILE_: out->origin = GLITE_JP_ATTR_ORIG_FILE; break; - } - else out->origin = GLITE_JP_ATTR_ORIG_ANY; -} - - -static int check_sane_feed(glite_jp_context_t ctx,struct _jpelem__FeedIndex *in) -{ - glite_jp_error_t err; - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - err.code = EINVAL; - - if (!in->destination) { - err.desc = "destination required"; - return glite_jp_stack_error(ctx,&err); - } - - return 0; -} - - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__FeedIndex( - struct soap *soap, - struct _jpelem__FeedIndex *in, - struct _jpelem__FeedIndexResponse *out) -{ - -/* 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; - - char const **attrs = calloc(in->__sizeattributes+1,sizeof *attrs); - glite_jp_query_rec_t *qry = calloc(in->__sizeconditions+1,sizeof *qry); - int i; - - glite_jp_clear_error(ctx); - - if (check_sane_feed(ctx,in)) { - err2fault(ctx,soap); - ret = SOAP_FAULT; - goto cleanup; - } - - memcpy(attrs,in->attributes,sizeof *attrs * in->__sizeattributes); - for (i = 0; i__sizeconditions; i++) s2jp_query(GLITE_SECURITY_GSOAP_LIST_GET(in->conditions, i),qry+i); - - if (in->history) { - if (glite_jpps_run_feed(ctx,in->destination,attrs,qry,in->continuous,&feed_id)) { - err2fault(ctx,soap); - ret = SOAP_FAULT; - goto cleanup; - } - } - - if (in->continuous) { - if (glite_jpps_register_feed(ctx,in->destination,attrs,qry,&feed_id,&expires)) { - err2fault(ctx,soap); - ret = SOAP_FAULT; - goto cleanup; - } - } - - if (!in->history && !in->continuous) { - glite_jp_error_t err; - memset(&err,0,sizeof err); - err.code = EINVAL; - err.source = __FUNCTION__; - err.desc = "at least one of and must be true"; - glite_jp_stack_error(ctx,&err); - err2fault(ctx,soap); - ret = SOAP_FAULT; - goto cleanup; - } - - out->feedExpires = expires; - out->feedId = soap_strdup(soap,feed_id); - -cleanup: - free(feed_id); - free(attrs); - free(qry); - - return ret; -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__FeedIndexRefresh( - struct soap *soap, - struct _jpelem__FeedIndexRefresh *in, - struct _jpelem__FeedIndexRefreshResponse *out) -{ - CONTEXT_FROM_SOAP(soap,ctx); - - time_t expires = 0; - int ret = SOAP_OK; - - glite_jp_clear_error(ctx); - - if (glite_jpps_refresh_feed(ctx, in->feedId, &expires)){ - err2fault(ctx,soap); - ret = SOAP_FAULT; - return ret; - } - out->feedExpires = expires; - - return ret; -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__GetJobFiles( - struct soap *soap, - struct _jpelem__GetJobFiles *in, - struct _jpelem__GetJobFilesResponse *out) -{ - CONTEXT_FROM_SOAP(soap,ctx); - char *url; - - int i,n; - glite_jp_error_t err; - void **pd; - struct jptype__jppsFile *f = NULL; - glite_jp_attrval_t meta[2]; - - memset(&err,0,sizeof err); - n = 0; - - memset(meta,0,sizeof meta); - meta[0].name = strdup(GLITE_JP_ATTR_OWNER); - - if (glite_jppsbe_get_job_metadata(ctx,in->jobid,meta)) { - goto err; - } - - if (glite_jpps_authz(ctx,SOAP_TYPE___jpsrv__GetJobFiles,in->jobid,meta[0].value)) { - goto err; - } - - memset(meta,0,sizeof meta); - meta[0].name = strdup(GLITE_JP_ATTR_OWNER); - - if (glite_jppsbe_get_job_metadata(ctx,in->jobid,meta)) { - goto err; - } - - if (glite_jpps_authz(ctx,SOAP_TYPE___jpsrv__GetJobFiles,in->jobid,meta[0].value)) { - goto err; - } - - for (pd = ctx->plugins; *pd; pd++) { - glite_jpps_fplug_data_t *plugin = *pd; - - for (i=0; plugin->uris[i]; i++) { - glite_jp_clear_error(ctx); - switch (glite_jppsbe_get_job_url(ctx,in->jobid,plugin->classes[i],NULL,&url)) { - case 0: - f = realloc(f,(n + 1) * sizeof *f); - f[n].class_ = soap_strdup(soap,plugin->uris[i]); -#warning FIXME: file name required in WSDL - f[n].name = NULL; - f[n].url = soap_strdup(soap,url); - n++; - free(url); - break; - case ENOENT: - break; - default: - err.code = ctx->error->code; - err.source = "jpsrv__GetJob()"; - err.desc = plugin->uris[i]; - glite_jp_stack_error(ctx,&err); - err2fault(ctx,soap); - glite_jp_clear_error(ctx); - return SOAP_FAULT; - } - } - } - - if (!n) { - 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; - } - - GLITE_SECURITY_GSOAP_LIST_CREATE(soap, out, files, struct jptype__jppsFile, n); - for (i = 0; i < n; i++) memcpy(GLITE_SECURITY_GSOAP_LIST_GET(out->files, i), &f[i], sizeof(f[i])); - - return SOAP_OK; -err: - glite_jp_attrval_free(meta,0); - err2fault(ctx,soap); - return SOAP_FAULT; -} - -SOAP_FMAC5 int SOAP_FMAC6 __jpsrv__GetJobAttributes( - struct soap *soap, - struct _jpelem__GetJobAttributes *in, - struct _jpelem__GetJobAttributesResponse *out) -{ - glite_jp_attrval_t *attr, meta[2]; - int i,n; - - CONTEXT_FROM_SOAP(soap,ctx); - - memset(meta,0,sizeof meta); - meta[0].name = strdup(GLITE_JP_ATTR_OWNER); - - if (glite_jppsbe_get_job_metadata(ctx,in->jobid,meta)) { - goto err; - } - - if (glite_jpps_authz(ctx,SOAP_TYPE___jpsrv__GetJobAttributes,in->jobid,meta[0].value)) { - goto err; - } - - if (glite_jpps_get_attrs(ctx,in->jobid, - in->attributes, - in->__sizeattributes,&attr)) { - err2fault(ctx,soap); - return SOAP_FAULT; - } - - for (i=0; attr[i].name; i++); - out->__sizeattrValues = jp2s_attrValues(soap,attr,&out->attrValues,1); - - return SOAP_OK; -err: - glite_jp_attrval_free(meta,0); - err2fault(ctx,soap); - return SOAP_FAULT; -} diff --git a/org.glite.jp.primary/src/soap_util.c b/org.glite.jp.primary/src/soap_util.c deleted file mode 100644 index 9235a45..0000000 --- a/org.glite.jp.primary/src/soap_util.c +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -static enum jptype__attrOrig jp2s_origin(glite_jp_attr_orig_t o) -{ - switch (o) { - case GLITE_JP_ATTR_ORIG_SYSTEM: return jptype__attrOrig__SYSTEM; - case GLITE_JP_ATTR_ORIG_USER: return jptype__attrOrig__USER; - case GLITE_JP_ATTR_ORIG_FILE: return jptype__attrOrig__FILE_; - default: abort(); /* XXX */ - } -} - -static int jp2s_attrValues( - struct soap *soap, - glite_jp_attrval_t *in, - GLITE_SECURITY_GSOAP_LIST_TYPE(jptype, attrValue) *outp, - int freeit) -{ - GLITE_SECURITY_GSOAP_LIST_TYPE(jptype, attrValue) out; - struct jptype__attrValue a; - int i,cnt; - - for (cnt=0; in[cnt].name; cnt++); - - GLITE_SECURITY_GSOAP_LIST_CREATE0(soap, out, cnt, struct jptype__attrValue, cnt); - for (i=0; in[i].name; i++) { - memset(&a, 0, sizeof a); - a.name = soap_strdup(soap,in[i].name); - if (freeit) free(in[i].name); - a.value = soap_malloc(soap,sizeof *a.value); - memset(a.value, 0, sizeof *a.value); - if (in[i].binary) { - GSOAP_SETBLOB(a.value, soap_malloc(soap,sizeof *GSOAP_BLOB(a.value))); - memset(GSOAP_BLOB(a.value),0,sizeof *GSOAP_BLOB(a.value)); - GSOAP_BLOB(a.value)->__ptr = soap_malloc(soap,in[i].size); - GSOAP_BLOB(a.value)->__size = in[i].size; - memcpy(GSOAP_BLOB(a.value)->__ptr,in[i].value,in[i].size); - } - else { - GSOAP_SETSTRING(a.value, soap_strdup(soap,in[i].value)); - } - - if (freeit) free(in[i].value); - a.origin = jp2s_origin(in[i].origin); - a.originDetail = in[i].origin_detail ? soap_strdup(soap,in[i].origin_detail) : NULL; - if (freeit) free(in[i].origin_detail); - a.timestamp = in[i].timestamp; - - memcpy(GLITE_SECURITY_GSOAP_LIST_GET(out, i), &a, sizeof a); - } - if (freeit) free(in); - - *outp = out; - return cnt; -} - -static void attrValues_free( - struct soap *soap, - GLITE_SECURITY_GSOAP_LIST_TYPE(jptype, attrValue) a, - int na) -{ - int i; - struct jptype__attrValue *ai; - - for (i=0; ivalue) && GSOAP_STRING(ai->value)) soap_dealloc(soap,GSOAP_STRING(ai->value)); - if (GSOAP_ISBLOB(ai->value) && GSOAP_BLOB(ai->value)) { - soap_dealloc(soap,GSOAP_BLOB(ai->value)->__ptr); - soap_dealloc(soap,GSOAP_BLOB(ai->value)); - } - soap_dealloc(soap,ai->value); - if (ai->originDetail) soap_dealloc(soap,ai->originDetail); - } - GLITE_SECURITY_GSOAP_LIST_DESTROY0(soap, a, na); -} diff --git a/org.glite.jp.primary/src/tags.c b/org.glite.jp.primary/src/tags.c deleted file mode 100644 index 892b635..0000000 --- a/org.glite.jp.primary/src/tags.c +++ /dev/null @@ -1,476 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "glite/jp/backend.h" -#include "tags.h" - -/* magic name_len value_len binary sequence timestamp */ -#define HEADER "JP#TAG# %05u %012lu %c %05u %012lu#" -#define HEADER_SIZE 48 -#define TAGS_MAGIC 0x74c016f2 /* two middle digits encode version, i.e. 01 */ - -static int tagsread(void *fpctx,struct tags_handle *h); - -/*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); -}*/ - -int tag_append(void *fpctx,void *bhandle,glite_jp_attrval_t * tag) -{ - //va_list ap; - char *hdr,*rec; - glite_jp_context_t ctx = fpctx; - uint32_t magic,hlen,rlen,rlen_n; - ssize_t r; - glite_jp_error_t err; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - glite_jp_clear_error(ctx); - - printf("tagappend: %s,%s\n",tag->name,tag->value); - - //assert(oper == GLITE_JP_FPLUG_TAGS_APPEND); - - if (glite_jppsbe_pread(ctx,bhandle,&magic,sizeof magic,0,&r)) { - err.code = EIO; - err.desc = "reading magic number"; - return glite_jp_stack_error(ctx,&err); - } - - if (r == 0) { - magic = htonl(TAGS_MAGIC); - if (glite_jppsbe_pwrite(ctx,bhandle,&magic,sizeof magic,0)) { - err.code = EIO; - err.desc = "writing magic number"; - return glite_jp_stack_error(ctx,&err); - } - } - else if (r != sizeof magic) { - err.code = EIO; - err.desc = "can't read magic number"; - return glite_jp_stack_error(ctx,&err); - } - else if (magic != htonl(TAGS_MAGIC)) { - err.code = EINVAL; - err.desc = "invalid magic number"; - return glite_jp_stack_error(ctx,&err); - } - -/* XXX: origin is always USER, not recorded */ - trio_asprintf(&hdr,"%ld %c", - tag->timestamp,tag->binary ? 'B' : 'S'); - - rlen = strlen(tag->name) + strlen(hdr) + 2 /* \0 after name and after hdr */ + - (r = tag->binary ? tag->size : (tag->value ? strlen(tag->value) : 0)); - - rlen_n = htonl(rlen); - - rec = malloc(rlen + sizeof rlen_n); - *((uint32_t *) rec) = rlen_n; - strcpy(rec + sizeof rlen_n,tag->name); - strcpy(rec + (hlen = sizeof rlen_n + strlen(tag->name) + 1),hdr); - - if (r) memcpy(rec + hlen + strlen(hdr) + 1,tag->value,r); - free(hdr); - -/* record format: - * - 4B length, net byte order - * - attr name, \0 - * - %ld %c \0 (timestamp, B/S) - * - value - */ - if (glite_jppsbe_append(ctx,bhandle,rec,rlen + sizeof rlen_n)) { - err.code = EIO; - err.desc = "writing tag record"; - free(rec); - return glite_jp_stack_error(ctx,&err); - } - - /* XXX: should add tag also to handle->tags, but it is never used - * currently */ - - return 0; -} - -int tag_attr(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval) -{ - struct tags_handle *h = handle; - glite_jp_error_t err; - glite_jp_context_t ctx = fpctx; - glite_jp_attrval_t *out = NULL; - int i,nout = 0; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - if (!h->tags) tagsread(fpctx,handle); - - if (!h->tags) { - err.code = ENOENT; - err.desc = "no tags for this job"; - return glite_jp_stack_error(ctx,&err); - } - - for (i=0; in; i++) if (!strcmp(h->tags[i].name,attr)) { - out = realloc(out,(nout+2) * sizeof *out); - glite_jp_attrval_copy(out+nout,h->tags+i); - nout++; - memset(out+nout,0,sizeof *out); - } - - if (nout) { - *attrval = out; - return 0; - } - else { - err.code = ENOENT; - err.desc = "no value for this tag"; - return glite_jp_stack_error(ctx,&err); - } -} - -static int tagsread(void *fpctx,struct tags_handle *h) -{ - glite_jp_context_t ctx = fpctx; - uint32_t magic,rlen; - glite_jp_error_t err; - ssize_t r; - size_t off = sizeof rlen; - glite_jp_attrval_t *tp; - char *rp; - - memset(&err,0,sizeof err); - err.source = __FUNCTION__; - - glite_jp_clear_error(ctx); - -// read magic number - if (glite_jppsbe_pread(ctx,h->bhandle,&magic,sizeof magic,0,&r)) { - err.code = EIO; - err.desc = "reading magic number"; - return glite_jp_stack_error(ctx,&err); - } - - if (r != sizeof magic) { - err.code = EIO; - err.desc = "can't read magic number"; - return glite_jp_stack_error(ctx,&err); - } - else if (magic != htonl(TAGS_MAGIC)) { - err.code = EINVAL; - err.desc = "invalid magic number"; - return glite_jp_stack_error(ctx,&err); - } - - - while (1) { - char *rec,type; - int rd; - - // read record header - if (glite_jppsbe_pread(ctx,h->bhandle,&rlen,sizeof rlen,off,&r)) { - err.code = EIO; - err.desc = "reading record header"; - return glite_jp_stack_error(ctx,&err); - } - if (r == 0) break; - - if (r != sizeof rlen) { - err.code = EIO; - err.desc = "can't read record header"; - return glite_jp_stack_error(ctx,&err); - } - - off += r; - rec = malloc(rlen = ntohl(rlen)); - - // read whole record body thoroughly - for (rd=0; rdbhandle,rec+rd,rlen-rd,off+rd,&r)) { - err.code = EIO; - err.desc = "reading record body"; - free(rec); - return glite_jp_stack_error(ctx,&err); - } - - off += rlen; - - // parse the record - h->tags = realloc(h->tags,(h->n+2) * sizeof *h->tags); - tp = h->tags+h->n++; - memset(tp,0,sizeof *tp); - - tp->name = strdup(rec); - rp = rec + strlen(rec) + 1; - - sscanf(rp,"%ld %c",&tp->timestamp,&type); - rp += strlen(rp) + 1; - switch (type) { - int i; - - case 'B': tp->binary = 1; break; - case 'S': tp->binary = 0; break; - default: free(rec); - for (i=0; in; i++) - glite_jp_attrval_free(h->tags+i,0); - free(h->tags); - h->tags = NULL; - h->n = 0; - - err.code = EINVAL; - err.desc = "invalid attr type (B/S)"; - return glite_jp_stack_error(ctx,&err); - } - tp->value = malloc((r=rlen - (rp - rec)) + 1); - memcpy(tp->value,rp,r); - if (!tp->binary) tp->value[r] = 0; - tp->origin = GLITE_JP_ATTR_ORIG_USER; - - free(rec); - } - return 0; -} - diff --git a/org.glite.jp.primary/src/tags.h b/org.glite.jp.primary/src/tags.h deleted file mode 100644 index 0f24791..0000000 --- a/org.glite.jp.primary/src/tags.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -struct tags_handle { - void *bhandle; - int n; - glite_jp_attrval_t *tags; -}; - -int tag_append(void *fpctx,void *bhandle,glite_jp_attrval_t * tag); -//int glite_jpps_tag_append(glite_jp_context_t,void *,const char *, const char *); -//int glite_jpps_tag_append(glite_jp_context_t,void *,const glite_jp_tagval_t *); -int tag_attr(void *fpctx,void *handle,const char *attr,glite_jp_attrval_t **attrval); diff --git a/org.glite.jp.primary/src/typemap.dat b/org.glite.jp.primary/src/typemap.dat deleted file mode 100644 index 72f515f..0000000 --- a/org.glite.jp.primary/src/typemap.dat +++ /dev/null @@ -1,3 +0,0 @@ -jpsrv = http://glite.org/wsdl/services/jp -jptype = http://glite.org/wsdl/types/jp -jpelem = http://glite.org/wsdl/elements/jp diff --git a/org.glite.jp.server-common/Makefile b/org.glite.jp.server-common/Makefile deleted file mode 100644 index a65ac71..0000000 --- a/org.glite.jp.server-common/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -# defaults -top_srcdir=.. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -jpprefix=jp -package=glite-jp-server-common -version=0.0.0 -PREFIX=/opt/glite - -glite_location=/opt/glite -nothrflavour=gcc32 -thrflavour=gcc32pthr - -CC=gcc - --include Makefile.inc - - -VPATH=${top_srcdir}/src:${top_srcdir}/examples:${top_srcdir}/test:${top_srcdir}/project:${jpproject}:${stagedir}/interface - -DEBUG:=-g -O0 -W -Wall -DDEBUG -CPPFLAGS:=-I. -I${top_srcdir}/interface -I${top_srcdir}/src -I${stagedir}/include -I${mysql_prefix}/include -I${mysql_prefix}/include/mysql -CFLAGS:=${DEBUG} -D_GNU_SOURCE -LDFLAGS:=-L${stagedir}/lib - -offset=0 -version_info:=-version-info ${shell \ - perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } - - -COMPILE:=libtool --mode=compile ${CC} ${CPPFLAGS} ${CFLAGS} -LINK:=libtool --mode=link ${CC} -rpath ${stagedir}/lib ${LDFLAGS} -LIBLINK:=${LINK} ${version_info} -INSTALL:=libtool --mode=install install - -STATICLIB:=libglite_jp_server_common.a -LTLIB:=libglite_jp_server_common.la - - -SRCS:=db.c -HDRS:=db.h -OBJS:=${SRCS:.c=.o} -LOBJS:=${OBJS:.o=.lo} - -default all: compile examples - -compile: ${LTLIB} ${STATICLIB} - -${LTLIB} ${STATICLIB}: ${OBJS} - ${LIBLINK} -o $@ ${LOBJS} -lglite_lbu_db - -examples: - -check: - -echo nothing yet - -doc: - -stage: compile - $(MAKE) install PREFIX=${stagedir} - -install: - -mkdir -p ${PREFIX}/lib ${PREFIX}/include/${globalprefix}/${jpprefix} - ${INSTALL} -m 755 ${LTLIB} ${PREFIX}/lib - for f in ${HDRS}; do \ - ${INSTALL} -m 644 ${top_srcdir}/interface/"$$f" ${PREFIX}/include/${globalprefix}/${jpprefix}; \ - done - -clean: - -%.o: %.c - ${COMPILE} -c $< -o $@ - -.PHONY: default all compile examples check doc stage dist distsrc distbin install clean diff --git a/org.glite.jp.server-common/build.xml b/org.glite.jp.server-common/build.xml deleted file mode 100755 index 33d20cf..0000000 --- a/org.glite.jp.server-common/build.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.server-common/configure b/org.glite.jp.server-common/configure deleted file mode 100755 index 0bf1a3f..0000000 --- a/org.glite.jp.server-common/configure +++ /dev/null @@ -1,701 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; - -my $pwd = `pwd`; chomp $pwd; -my $prefix = $pwd.'/stage'; -my $stagedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my $version; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $sec_tag = ''; -my $jobid_tag = ''; - -my @nodes = qw/client server logger utils client-java doc ws-test db jpprimary jpindex jpclient/; -my %enable_nodes; -my %disable_nodes; - -my %extern_prefix = ( - cares => '/opt/c-ares', - classads => '/opt/classads', - cppunit => '/usr', - expat => '/usr', - globus => '/opt/globus', - gsoap => '/usr', - mysql => '/usr', - voms => '/opt/glite', - gridsite => '/opt/glite', - lcas => '/opt/glite', - ant => '/usr', - jdk => '/usr', - libtar => '/usr', -); - -my %jar = ( - 'commons-codec' => '/usr/share/java/commons-codec-1.3.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %topbuild; - -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test/], - 'security' => [qw/gss gsoap-plugin/], - 'lbjp-common' => [qw/db maildir server-bones trio jp-interface/], - 'jobid' => [qw/api-c api-cpp api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - ); - - -my @opts = ( - 'prefix=s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour=s' => \$thrflavour, - 'nothrflavour=s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$version, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'security-tag=s' => \$sec_tag, - 'jobid-tag=s' => \$jobid_tag, - 'help' => \$help, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$extern_prefix{$_} for keys %extern_prefix; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my @m = map "org.glite.$listmodules.$_",@{$lbmodules{$listmodules}}; - print "@m\n"; - exit 0; -} - -warn "$0: --version and --output make sense only in --mode=etics\n" - if ($version || $output) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},@{$lbmodules{security}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless $disable_nodes{$_}; - } -} - -if (!$en && !$dis) { $enable_nodes{$_} = 1 for (@nodes) } ; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $prefix unless $stagedir; - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: $extern_prefix{$_}\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\nclean:\n"; - - for (@modules) { - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - print MAK "\tcd $full$build && \${MAKE} clean\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $topbuild{$_} ? - "\tcd $full$build && \${MAKE} distclean\n" : - "\trm -rf $full$build\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - - print MAK "$_: @dnames\n\tcd $full$build && \${MAKE} && \${MAKE} install\n\n"; - } - - close MAK; -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag){ - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($sec_tag){ - for (@{$lbmodules{security}}){ - if ("security.".$_ eq $module){ - $tag = '-r '.$sec_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads/ ], - 'lb.client-java' => [ qw/ant:B/ ], - 'lb.common' => [ qw/expat cppunit:B classads/ ], - 'lb.doc' => [], - 'lb.logger' => [ qw/cppunit:B/ ], - 'lb.server' => [ qw/globus expat cares mysql cppunit:B gsoap:B classads voms lcas gridsite/ ], - 'lb.state-machine' => [ qw/classads/ ], - 'lb.utils' => [ qw/cppunit:B/ ], - 'lb.ws-interface' => [], - 'lb.ws-test' => [ qw/gsoap:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/mysql/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw/cppunit:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B/ ], - 'security.gss' => [ qw/globus cares cppunit:B/ ], - 'security.gsoap-plugin' => [ qw/cppunit:B globus cares gsoap:B/ ], - 'jobid.api-c' => [ qw/cppunit:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], -); - -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$need_externs{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $need_externs_type{$ext}->{$1} = $type; - } -} - -%need_jars = ( - 'jobid.api-java' => [ qw/commons-codec/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp jobid.api-c - security.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp jobid.api-c - lb.types:B lbjp-common.trio security.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - jobid.api-c - lb.common - security.gss - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir - jobid.api-c - security.gsoap-plugin security.gss - / ], - 'lb.state-machine' => [ qw/lb.common lbjp-common.jp-interface security.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine - / ], - 'lb.ws-test' => [ qw/security.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/lbjp-common.trio/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw// ], - 'security.gss' => [ qw// ], - 'security.gsoap-plugin' => [ qw/security.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - security.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( gridsite=>'org.gridsite.core'); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', -); - -my @t = qw/lb.client-java jobid.api-java lb.types/; -@topbuild{@t} = (1) x ($#t+1); -} - -sub full -{ - my $short = shift; - return $extrafull{$short} ? $extrafull{$short} : 'org.glite.'.$short; -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java -security.gss security.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -/; - @aux{@m} = (1) x ($#m+1); - - my $short = shift; - my $full = full $short; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $build = ''; - - unless ($topbuild{$_}) { - $build = '/build'; - unless (-d "$full/build") { - mkdir "$full/build" or die "mkdir $full/build: $!\n"; - } - unlink "$full/build/Makefile"; - symlink "../Makefile","$full/build/Makefile" or die "symlink ../Makefile $full/build/Makefile: $!\n"; - } - - open MKINC,">$full$build/Makefile.inc" - or die "$full$build/Makefile.inc: $!\n"; - - print "Creating $full$build/Makefile.inc\n"; - - print MKINC qq{ -PREFIX = $prefix -stagedir = $stagedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -}; - - for (@{$need_externs{$short}}) { - print MKINC "${_}_prefix = $extern_prefix{$_}\n" - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; -} - -my %etics_externs; -my %etics_projects; -BEGIN{ - %etics_externs = ( - globus=>'vdt_globus_essentials', - cares=>'c-ares', - voms=>'org.glite.security.voms-api-cpp', - gridsite=>'org.gridsite.shared', - lcas=>'org.glite.security.lcas', - ); - %etics_projects = ( - vdt=>[qw/globus/], - 'org.glite'=>[qw/voms gridsite lcas/], - ); -}; - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod; - - my ($major,$minor,$rev,$age); - - if ($version) { - $version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - open V,"org.glite.$subsys.$module/project/version.properties" - or die "org.glite.$subsys.$module/project/version.properties: $!\n"; - - while ($_ = ) { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - } - - my @copts = (); - my %ge; - @ge{@{$etics_projects{'org.glite'}}} = (1) x ($#{$etics_projects{'org.glite'}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}/$_*.jar"; - } - - - my $conf = "glite-$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $topbuild{"$subsys.$module"} ? '' : "build.root = build\n"; - - my $confdir = $topbuild{"$subsys.$module"} ? '..' : '../..'; - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = org.glite.$subsys.$module -displayName = $conf -description = org.glite.$subsys.$module -projectName = org.glite -age = $age -deploymentType = None -tag = $conf -version = $major.$minor.$rev -path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz - -[Platform-default:VcsCommand] -displayName = None -description = None -tag = cvs -d \${vcsroot} tag -R \${tag} \${moduleName} -branch = None -commit = None -checkout = cvs -d \${vcsroot} co -r \${tag} \${moduleName} - -[Platform-default:BuildCommand] -postpublish = None -packaging = None -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = make -init = None -install = make install -clean = make clean -test = make check -configure = cd $confdir && \${moduleName}/configure --thrflavour=\${globus.thr.flavor} --nothrflavour=\${globus.nothr.flavor} --prefix=\${prefix} --stage=\${stageDir} --module $subsys.$module @copts -checkstyle = None - -[Platform-default:Property] -$buildroot - -[Platform-default:DynamicDependency] - -}; - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - print C "$proj|$eext = $type\n"; - } - - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - print C "org.glite|org.glite.$_ = $type\n"; - } - - close C; -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$extern_prefix{gsoap}/bin/soapcpp2 -v 2>&1 |" or die "$extern_prefix{gsoap}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - - -sub usage { - my @ext = keys %extern_prefix; - my @myjars, keys %jar; - - print STDERR qq{ -usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - -Mode of operation: - --mode={checkout|build|etics} what to do [build] - -What to build: - --module=module build this module only (mostly in-Etics operation) - --enable-NODE build this "node" (set of modules) only. Available nodes are - @{$lbmodules{lb}},@{$lbmodules{security}} - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --security-tag=tag checkout security modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - -Dependencies: - --with-EXTERNAL=PATH where to look for an external. Required externals - (not all for all modules) are: - @ext - --with-JAR=JAR where to look for jars. Required jars are: - @myjars - Summary of what will be used is always printed - -}; - -} diff --git a/org.glite.jp.server-common/examples/db-test-int.c b/org.glite.jp.server-common/examples/db-test-int.c deleted file mode 100644 index cf5c085..0000000 --- a/org.glite.jp.server-common/examples/db-test-int.c +++ /dev/null @@ -1,129 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include - -#include "db.h" - - -static void print_err(glite_jp_context_t ctx) { - glite_jp_error_t *e; - - e = ctx->error; - while (e) { - printf("%s(%s)\n", e->desc, e->source); - e = e->reason; - } - printf("\n"); -} - - -int main() { - glite_jp_context_t ctx; - glite_jp_db_stmt_t jpstmt; - - glite_jp_init_context(&ctx); - - printf("connecting...\n"); - if (glite_jp_db_connect(ctx, "jpis/@localhost:jpis1") != 0) goto fail; - - // "trio" queries -{ - int nr, i; - char **res; - - printf("selecting...\n"); - if ((glite_jp_db_execstmt(ctx, "SELECT uniqueid, feedid, state, source, condition FROM feeds", &jpstmt)) == -1) goto fail; - - printf("fetching...\n"); - res = calloc(4, sizeof(char *)); - while ((nr = glite_jp_db_fetchrow(jpstmt, res)) > 0) { - printf("Result: n=%d, res=%p\n", nr, res); - i = 0; - if (res) while(i < nr) {printf("p=%p(%s)\n", res[i], res[i]);free(res[i]);i++;} - } - free(res); - printf("closing stmt...\n"); - glite_jp_db_freestmt(&jpstmt); -} - - // param queries -{ - char res_feedid[33]; - long int res_state; - char res_source[256]; - char res_condition[1024]; - unsigned long res_condition_length; - long int param_state; - - void *my_res, *my_param; - - glite_jp_db_create_params(&my_param, 1, GLITE_JP_DB_TYPE_INT, ¶m_state); - glite_jp_db_create_results(&my_res, 4, - GLITE_JP_DB_TYPE_VARCHAR, NULL, res_feedid, sizeof(res_feedid), NULL, - GLITE_JP_DB_TYPE_INT, NULL, &res_state, - GLITE_JP_DB_TYPE_VARCHAR, NULL, res_source, sizeof(res_source), NULL, - GLITE_JP_DB_TYPE_MEDIUMBLOB, NULL, res_condition, sizeof(res_condition), &res_condition_length - ); - printf("preparing...\n"); - if ((glite_jp_db_prepare(ctx, "SELECT feedid, state, source, condition FROM feeds WHERE state = ?", &jpstmt, my_param, my_res)) != 0) goto fail_close; - - param_state = 1; - printf("executing state %ld...\n", param_state); - if (glite_jp_db_execute(jpstmt) == -1) { - glite_jp_db_freestmt(&jpstmt); - goto fail_stmtclose; - } - printf("fetching...\n"); - while (glite_jp_db_fetch(jpstmt) == 0) { - printf("feedid:%s, state:%ld, source:%s, condition:%s\n", res_feedid, res_state, res_source, res_condition); - } - - param_state = 2; - printf("executing state %ld...\n", param_state); - if (glite_jp_db_execute(jpstmt) == -1) { - glite_jp_db_freestmt(&jpstmt); - goto fail_stmtclose; - } - printf("fetching...\n"); - while (glite_jp_db_fetch(jpstmt) == 0) { - printf("feedid:%s, state:%ld, source:%s, condition:%s\n", res_feedid, res_state, res_source, res_condition); - } -} - - printf("closing stmt...\n"); - glite_jp_db_freestmt(&jpstmt); - printf("closing...\n"); - glite_jp_db_close(ctx); - - glite_jp_free_context(ctx); - return 0; - -fail_stmtclose: - printf("closing stmt...\n"); - glite_jp_db_freestmt(&jpstmt); -fail_close: - printf("closing...\n"); - glite_jp_db_close(ctx); -fail: - printf("failed\n"); - print_err(ctx); - glite_jp_free_context(ctx); - - return 1; -} diff --git a/org.glite.jp.server-common/interface/db.h b/org.glite.jp.server-common/interface/db.h deleted file mode 100644 index d1a0f42..0000000 --- a/org.glite.jp.server-common/interface/db.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _DB_H -#define _DB_H - -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#include "glite/jp/types.h" -#include "glite/lbu/db.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int glite_jp_db_SetError(glite_jp_context_t ctx, const char *source); -int glite_jp_db_ExecSQL(glite_jp_context_t ctx, const char *cmd, glite_lbu_Statement *stmt); -int glite_jp_db_FetchRow(glite_jp_context_t ctx, glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results); -int glite_jp_db_PrepareStmt(glite_jp_context_t ctx, const char *sql, glite_lbu_Statement *stmt); -int glite_jp_db_ExecPreparedStmt(glite_jp_context_t ctx, glite_lbu_Statement stmt, int n,...); -void glite_jp_db_FreeStmt(glite_lbu_Statement *stmt); -int glite_jp_db_Transaction(glite_jp_context_t ctx); -int glite_jp_db_Commit(glite_jp_context_t ctx); -int glite_jp_db_Rollback(glite_jp_context_t ctx); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/org.glite.jp.server-common/project/ChangeLog b/org.glite.jp.server-common/project/ChangeLog deleted file mode 100644 index c9fb222..0000000 --- a/org.glite.jp.server-common/project/ChangeLog +++ /dev/null @@ -1,6 +0,0 @@ -1.3.0-1 -- Initial Version - -1.3.0-2 -- configure updated - diff --git a/org.glite.jp.server-common/project/build.number b/org.glite.jp.server-common/project/build.number deleted file mode 100644 index baeaebc..0000000 --- a/org.glite.jp.server-common/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Oct 15 06:50:18 CEST 2005 -module.build=3 diff --git a/org.glite.jp.server-common/project/configure.properties.xml b/org.glite.jp.server-common/project/configure.properties.xml deleted file mode 100644 index 2fb0a4d..0000000 --- a/org.glite.jp.server-common/project/configure.properties.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - -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} -mysql_prefix=${with.mysql.prefix} -mysql_version=${ext.mysql.version} -thrflavour=${with.globus.thr.flavor} -nothrflavour=${with.globus.nothr.flavor} -cppunit=${with.cppunit.prefix} -jpproject=${subsystem.project.dir} -project=${component.project.dir} - - - diff --git a/org.glite.jp.server-common/project/properties.xml b/org.glite.jp.server-common/project/properties.xml deleted file mode 100755 index bd0829c..0000000 --- a/org.glite.jp.server-common/project/properties.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.server-common/project/tar_exclude b/org.glite.jp.server-common/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.jp.server-common/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.jp.server-common/project/version.properties b/org.glite.jp.server-common/project/version.properties deleted file mode 100644 index 450e0b2..0000000 --- a/org.glite.jp.server-common/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.3.0 -module.age=2 diff --git a/org.glite.jp.server-common/src/db.c b/org.glite.jp.server-common/src/db.c deleted file mode 100644 index b694a0c..0000000 --- a/org.glite.jp.server-common/src/db.c +++ /dev/null @@ -1,128 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#include -#include -#include -#include -#include - -#include "glite/jp/types.h" -#include "glite/jp/context.h" - -#include "db.h" - - -int glite_jp_db_SetError(glite_jp_context_t ctx, const char *source) { - glite_jp_error_t jperr; - char *desc; - - memset(&jperr, 0, sizeof jperr); - if (ctx->dbhandle) { - jperr.code = glite_lbu_DBError(ctx->dbhandle, NULL, &desc); - if (jperr.code && source) jperr.source = source; - jperr.desc = desc; - } else { - asprintf(&desc, "DB context isn't created"); - jperr.code = EINVAL; - jperr.desc = desc; - jperr.source = __FUNCTION__; - } - if (jperr.code) { - glite_jp_stack_error(ctx, &jperr); - free(desc); - } - - return jperr.code; -} - - -int glite_jp_db_ExecSQL(glite_jp_context_t ctx, const char *cmd, glite_lbu_Statement *stmt) { - int num; - - num = glite_lbu_ExecSQL(ctx->dbhandle, cmd, stmt); - if (num < 0) glite_jp_db_SetError(ctx, __FUNCTION__); - - return num; -} - - -int glite_jp_db_FetchRow(glite_jp_context_t ctx, glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results) { - int num; - - num = glite_lbu_FetchRow(stmt, n, lengths, results); - if (num < 0) glite_jp_db_SetError(ctx, __FUNCTION__); - return num; -} - - -int glite_jp_db_PrepareStmt(glite_jp_context_t ctx, const char *sql, glite_lbu_Statement *stmt) { - int ret; - - ret = glite_lbu_PrepareStmt(ctx->dbhandle, sql, stmt); - if (ret != 0) glite_jp_db_SetError(ctx, __FUNCTION__); - return ret; -} - - -int glite_jp_db_ExecPreparedStmt(glite_jp_context_t ctx, glite_lbu_Statement stmt, int n,...) { - va_list ap; - int ret; - - va_start(ap, n); - ret = glite_lbu_ExecPreparedStmt_v(stmt, n, ap); - va_end(ap); - if (ret < 0) glite_jp_db_SetError(ctx, __FUNCTION__); - return ret; -} - - -void glite_jp_db_FreeStmt(glite_lbu_Statement *stmt) { - glite_lbu_FreeStmt(stmt); -} - - -int glite_jp_db_Transaction(glite_jp_context_t ctx) { - int ret; - - ret = glite_lbu_Transaction(ctx->dbhandle); - if (ret != 0) glite_jp_db_SetError(ctx, __FUNCTION__); - - return ret; -} - - -int glite_jp_db_Commit(glite_jp_context_t ctx) { - int ret; - - ret = glite_lbu_Commit(ctx->dbhandle); - if (ret != 0) glite_jp_db_SetError(ctx, __FUNCTION__); - - return ret; -} - - -int glite_jp_db_Rollback(glite_jp_context_t ctx) { - int ret; - - ret = glite_lbu_Rollback(ctx->dbhandle); - if (ret != 0) glite_jp_db_SetError(ctx, __FUNCTION__); - - return ret; -} diff --git a/org.glite.jp.ws-interface/.cvsignore b/org.glite.jp.ws-interface/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.jp.ws-interface/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.jp.ws-interface/LICENSE b/org.glite.jp.ws-interface/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.jp.ws-interface/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.jp.ws-interface/Makefile b/org.glite.jp.ws-interface/Makefile deleted file mode 100644 index 22c2898..0000000 --- a/org.glite.jp.ws-interface/Makefile +++ /dev/null @@ -1,63 +0,0 @@ -# Default values -top_srcdir=.. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -globalprefix=glite -jpprefix=jp -package=glite-jp-ws-interface -version=0.0.0 -PREFIX=/opt/glite - --include Makefile.inc - -VPATH=${top_srcdir}/interface:${top_srcdir}/src -STAGETO=interface - -XSLTPROC=xsltproc --nonet -XMLLINT:=xmllint --nonet -TIDY:=tidy -i -q --show-warnings no --tidy-mark no --wrap 0 -docbookxls:=http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl - -WSDL=JobProvenancePS.wsdl JobProvenanceIS.wsdl JobProvenanceTypes.wsdl -WSDL_S=jpdev.wsdl -XSD=JobProvenanceTypes.xsd - -all compile: ${WSDL} ${XSD} JobProvenance.html ${WSDL_S} - -check: - @echo No unit test required for interface-only module. - -stage: ${WSDL} - $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes - -install: - -mkdir -p ${PREFIX}/${STAGETO} - -mkdir -p ${PREFIX}/share/doc/${package}-${version} - -mkdir -p ${PREFIX}/include/${globalprefix}/${jpprefix} - install -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - -install -m 644 JobProvenance.html ${PREFIX}/share/doc/${package}-${version} -# cd ${top_srcdir}/interface && install -m 644 ${WSDL} ${PREFIX}/${STAGETO} - install -m 644 ${WSDL} ${WSDL_S} ${XSD} ${PREFIX}/${STAGETO} - install -m 644 ${top_srcdir}/src/ws_fault.c ${PREFIX}/include/${globalprefix}/${jpprefix} - -clean: - rm -f *.h - -%.wsdl: %.xml puke-wsdl.xsl - ${XSLTPROC} ../src/puke-wsdl.xsl $< >$@ - -${TIDY} -xml -m $@ - -%.xsd: %.xml puke-schema.xsl - ${XSLTPROC} ../src/puke-schema.xsl $< >$@ - -${TIDY} -xml -m $@ - -JobProvenance.html: doc.xml JobProvenancePS.xml JobProvenanceIS.xml JobProvenanceTypes.xml puke-ug.xsl - -${XSLTPROC} --novalid ../src/puke-ug.xsl $< >doc-html.xml && \ - ${XSLTPROC} --stringparam chapter.autolabel 0 ${docbookxls} doc-html.xml >$@ - -${TIDY} -xml -m doc-html.xml - -${XMLLINT} --valid --noout doc-html.xml - -${TIDY} -asxhtml -m $@ - -jpdev.xml: jpdev.xml.sh JobProvenancePS.xml JobProvenanceIS.xml JobProvenanceTypes.xml - ${top_srcdir}/src/jpdev.sh $< > $@ diff --git a/org.glite.jp.ws-interface/build.xml b/org.glite.jp.ws-interface/build.xml deleted file mode 100644 index ae5d49b..0000000 --- a/org.glite.jp.ws-interface/build.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.ws-interface/configure b/org.glite.jp.ws-interface/configure deleted file mode 100755 index 0bf1a3f..0000000 --- a/org.glite.jp.ws-interface/configure +++ /dev/null @@ -1,701 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; - -my $pwd = `pwd`; chomp $pwd; -my $prefix = $pwd.'/stage'; -my $stagedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my $version; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $sec_tag = ''; -my $jobid_tag = ''; - -my @nodes = qw/client server logger utils client-java doc ws-test db jpprimary jpindex jpclient/; -my %enable_nodes; -my %disable_nodes; - -my %extern_prefix = ( - cares => '/opt/c-ares', - classads => '/opt/classads', - cppunit => '/usr', - expat => '/usr', - globus => '/opt/globus', - gsoap => '/usr', - mysql => '/usr', - voms => '/opt/glite', - gridsite => '/opt/glite', - lcas => '/opt/glite', - ant => '/usr', - jdk => '/usr', - libtar => '/usr', -); - -my %jar = ( - 'commons-codec' => '/usr/share/java/commons-codec-1.3.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %topbuild; - -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test/], - 'security' => [qw/gss gsoap-plugin/], - 'lbjp-common' => [qw/db maildir server-bones trio jp-interface/], - 'jobid' => [qw/api-c api-cpp api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - ); - - -my @opts = ( - 'prefix=s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour=s' => \$thrflavour, - 'nothrflavour=s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$version, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'security-tag=s' => \$sec_tag, - 'jobid-tag=s' => \$jobid_tag, - 'help' => \$help, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$extern_prefix{$_} for keys %extern_prefix; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my @m = map "org.glite.$listmodules.$_",@{$lbmodules{$listmodules}}; - print "@m\n"; - exit 0; -} - -warn "$0: --version and --output make sense only in --mode=etics\n" - if ($version || $output) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},@{$lbmodules{security}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless $disable_nodes{$_}; - } -} - -if (!$en && !$dis) { $enable_nodes{$_} = 1 for (@nodes) } ; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $prefix unless $stagedir; - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: $extern_prefix{$_}\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\nclean:\n"; - - for (@modules) { - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - print MAK "\tcd $full$build && \${MAKE} clean\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $topbuild{$_} ? - "\tcd $full$build && \${MAKE} distclean\n" : - "\trm -rf $full$build\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - - print MAK "$_: @dnames\n\tcd $full$build && \${MAKE} && \${MAKE} install\n\n"; - } - - close MAK; -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag){ - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($sec_tag){ - for (@{$lbmodules{security}}){ - if ("security.".$_ eq $module){ - $tag = '-r '.$sec_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads/ ], - 'lb.client-java' => [ qw/ant:B/ ], - 'lb.common' => [ qw/expat cppunit:B classads/ ], - 'lb.doc' => [], - 'lb.logger' => [ qw/cppunit:B/ ], - 'lb.server' => [ qw/globus expat cares mysql cppunit:B gsoap:B classads voms lcas gridsite/ ], - 'lb.state-machine' => [ qw/classads/ ], - 'lb.utils' => [ qw/cppunit:B/ ], - 'lb.ws-interface' => [], - 'lb.ws-test' => [ qw/gsoap:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/mysql/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw/cppunit:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B/ ], - 'security.gss' => [ qw/globus cares cppunit:B/ ], - 'security.gsoap-plugin' => [ qw/cppunit:B globus cares gsoap:B/ ], - 'jobid.api-c' => [ qw/cppunit:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], -); - -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$need_externs{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $need_externs_type{$ext}->{$1} = $type; - } -} - -%need_jars = ( - 'jobid.api-java' => [ qw/commons-codec/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp jobid.api-c - security.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp jobid.api-c - lb.types:B lbjp-common.trio security.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - jobid.api-c - lb.common - security.gss - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir - jobid.api-c - security.gsoap-plugin security.gss - / ], - 'lb.state-machine' => [ qw/lb.common lbjp-common.jp-interface security.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine - / ], - 'lb.ws-test' => [ qw/security.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/lbjp-common.trio/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw// ], - 'security.gss' => [ qw// ], - 'security.gsoap-plugin' => [ qw/security.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - security.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( gridsite=>'org.gridsite.core'); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', -); - -my @t = qw/lb.client-java jobid.api-java lb.types/; -@topbuild{@t} = (1) x ($#t+1); -} - -sub full -{ - my $short = shift; - return $extrafull{$short} ? $extrafull{$short} : 'org.glite.'.$short; -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java -security.gss security.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -/; - @aux{@m} = (1) x ($#m+1); - - my $short = shift; - my $full = full $short; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $build = ''; - - unless ($topbuild{$_}) { - $build = '/build'; - unless (-d "$full/build") { - mkdir "$full/build" or die "mkdir $full/build: $!\n"; - } - unlink "$full/build/Makefile"; - symlink "../Makefile","$full/build/Makefile" or die "symlink ../Makefile $full/build/Makefile: $!\n"; - } - - open MKINC,">$full$build/Makefile.inc" - or die "$full$build/Makefile.inc: $!\n"; - - print "Creating $full$build/Makefile.inc\n"; - - print MKINC qq{ -PREFIX = $prefix -stagedir = $stagedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -}; - - for (@{$need_externs{$short}}) { - print MKINC "${_}_prefix = $extern_prefix{$_}\n" - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; -} - -my %etics_externs; -my %etics_projects; -BEGIN{ - %etics_externs = ( - globus=>'vdt_globus_essentials', - cares=>'c-ares', - voms=>'org.glite.security.voms-api-cpp', - gridsite=>'org.gridsite.shared', - lcas=>'org.glite.security.lcas', - ); - %etics_projects = ( - vdt=>[qw/globus/], - 'org.glite'=>[qw/voms gridsite lcas/], - ); -}; - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod; - - my ($major,$minor,$rev,$age); - - if ($version) { - $version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - open V,"org.glite.$subsys.$module/project/version.properties" - or die "org.glite.$subsys.$module/project/version.properties: $!\n"; - - while ($_ = ) { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - } - - my @copts = (); - my %ge; - @ge{@{$etics_projects{'org.glite'}}} = (1) x ($#{$etics_projects{'org.glite'}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}/$_*.jar"; - } - - - my $conf = "glite-$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $topbuild{"$subsys.$module"} ? '' : "build.root = build\n"; - - my $confdir = $topbuild{"$subsys.$module"} ? '..' : '../..'; - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = org.glite.$subsys.$module -displayName = $conf -description = org.glite.$subsys.$module -projectName = org.glite -age = $age -deploymentType = None -tag = $conf -version = $major.$minor.$rev -path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz - -[Platform-default:VcsCommand] -displayName = None -description = None -tag = cvs -d \${vcsroot} tag -R \${tag} \${moduleName} -branch = None -commit = None -checkout = cvs -d \${vcsroot} co -r \${tag} \${moduleName} - -[Platform-default:BuildCommand] -postpublish = None -packaging = None -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = make -init = None -install = make install -clean = make clean -test = make check -configure = cd $confdir && \${moduleName}/configure --thrflavour=\${globus.thr.flavor} --nothrflavour=\${globus.nothr.flavor} --prefix=\${prefix} --stage=\${stageDir} --module $subsys.$module @copts -checkstyle = None - -[Platform-default:Property] -$buildroot - -[Platform-default:DynamicDependency] - -}; - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - print C "$proj|$eext = $type\n"; - } - - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - print C "org.glite|org.glite.$_ = $type\n"; - } - - close C; -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$extern_prefix{gsoap}/bin/soapcpp2 -v 2>&1 |" or die "$extern_prefix{gsoap}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - - -sub usage { - my @ext = keys %extern_prefix; - my @myjars, keys %jar; - - print STDERR qq{ -usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - -Mode of operation: - --mode={checkout|build|etics} what to do [build] - -What to build: - --module=module build this module only (mostly in-Etics operation) - --enable-NODE build this "node" (set of modules) only. Available nodes are - @{$lbmodules{lb}},@{$lbmodules{security}} - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --security-tag=tag checkout security modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - -Dependencies: - --with-EXTERNAL=PATH where to look for an external. Required externals - (not all for all modules) are: - @ext - --with-JAR=JAR where to look for jars. Required jars are: - @myjars - Summary of what will be used is always printed - -}; - -} diff --git a/org.glite.jp.ws-interface/project/ChangeLog b/org.glite.jp.ws-interface/project/ChangeLog deleted file mode 100644 index 99ea05f..0000000 --- a/org.glite.jp.ws-interface/project/ChangeLog +++ /dev/null @@ -1,6 +0,0 @@ -1.4.0-1 -- Initial version - -1.4.0-2 -- configure updated - diff --git a/org.glite.jp.ws-interface/project/build.number b/org.glite.jp.ws-interface/project/build.number deleted file mode 100644 index af547f8..0000000 --- a/org.glite.jp.ws-interface/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Oct 15 06:46:41 CEST 2005 -module.build=36 diff --git a/org.glite.jp.ws-interface/project/build.properties b/org.glite.jp.ws-interface/project/build.properties deleted file mode 100755 index e69de29..0000000 diff --git a/org.glite.jp.ws-interface/project/configure.properties.xml b/org.glite.jp.ws-interface/project/configure.properties.xml deleted file mode 100644 index 4b08208..0000000 --- a/org.glite.jp.ws-interface/project/configure.properties.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - -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} - - - diff --git a/org.glite.jp.ws-interface/project/properties.xml b/org.glite.jp.ws-interface/project/properties.xml deleted file mode 100644 index 4ec8018..0000000 --- a/org.glite.jp.ws-interface/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.ws-interface/project/tar_exclude b/org.glite.jp.ws-interface/project/tar_exclude deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.jp.ws-interface/project/version.properties b/org.glite.jp.ws-interface/project/version.properties deleted file mode 100755 index b23d1e3..0000000 --- a/org.glite.jp.ws-interface/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=1.4.0 -module.age=2 diff --git a/org.glite.jp.ws-interface/src/JobProvenanceIS.xml b/org.glite.jp.ws-interface/src/JobProvenanceIS.xml deleted file mode 100644 index 90f61ab..0000000 --- a/org.glite.jp.ws-interface/src/JobProvenanceIS.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - CVS revision: - - - - - - The Job Provenance (JP) Index Server is a volatile counterpart to the - permanent JP Primary Storage. Index servers are populated with subsets - of data from Primary storage(s) and indexed according to particular user needs. - - - - The interface to Index server contains three logical parts: administraive - (control), system and user. The administrative part is used by run-time index - server configuration tool, the system one allows Primary storage(s) to feed - data into the Index server, and the user one is available to users for queries. - - - - - - - - - - Called by JP primary storage as a response to FeedIndex request. - Updates information on jobs in index server, according to what JPPS - currently knows. - Id of the feed, as returned by JPPS FeedIndex operation. - Flag of completed batch feed. - Attributes per job. - - Any error. - - - - - User query to index server. - - Query conditions, similar to LB. - - - Set of attributes to be retrieved directly from index server (if any). - - - List of jobs matching the query. - - Any error. - - - - - Called by JP index serve admin tool to ask new primary storage server to feed it. - Updates information on PS in index server, according to what JPPS - currently knows. - - New feed IS URL, filter and query type. - - Any error. - - - Called by JP index serve admin tool to find out IS open feeds - - List of active feeds on IS. - - Any error. - - - Called by JP index serve admin tool to remove one feed session. - - ID of feed to be removed. - - Any error. - - - - - Internal operation used for parsing XML config file. - Not called at all, only forcing gSoap to generate XML parsers. - - List of attributes which will JPPS send to JPIS. - - - List of indexed attributes which will JPPS send to JPIS. - - - List of type plugins. - - - List of requested feeds. - - Any error. - - - - diff --git a/org.glite.jp.ws-interface/src/JobProvenancePS.xml b/org.glite.jp.ws-interface/src/JobProvenancePS.xml deleted file mode 100644 index 8ce2524..0000000 --- a/org.glite.jp.ws-interface/src/JobProvenancePS.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - CVS revision: - - - - - - The Job Provenance (JP) Primary Storage Service is responsible to keep the JP data - (definition of submitted jobs, execution conditions and environment, and important - points of the job life cycle) in a compact and economic form. - - - - The JP Primary storage, as described in section 8.4 of the - Architecture deliverable DJRA1.1 - provides public interfaces for data storing, retrieval based on basic metadata, - and registration of Index servers for incremental feed. - - - - Command interface to JP is completely covered by the WS interface covered here. - Bulk file transfers are done via specialised protocols, currently gsiftp only. - - - - - - - - Register job with the JP primary storage. - Jobid of the registered job. - Owner of the job (DN of X509 certificate). - Any error. - - - - Start uploading a file. - Jobid to which this file is related. - - Type of the file (URI). The server must have a plugin handing this type. - - Name of the file (used to distinguish among more files of the same type). - The client promisses to finish the upload before this time. - MIME type of the file. - URL where the client should upload the file. - Server's view on when the upload must be finished. - Any error. - - - - Confirm a successfully finished file apload. - Destination URL returned by StartUpload before. - Any error. - - - - Record an additional user tag. - Job to which the tag is added. - Name and value of the tag. - Any error. - - - - Attributes per job - Any error. - - - - Request for feeding a JP Index server (issued by this server). - Endpoint of the listening index server. - Which attributes of jobs is the index server interested in. - Which jobs is the server interested in. - Data on jobs stored at PS in the past are required. - Data on jobs that will arrive in future are required. - Unique ID of the created feed session. - When the session expires. - Any error. - - - - Refresh an existing feed session. - Existing feed session ID to be refreshed. - New session expiration time. - Any error. - - - - Return URL's of files for a given single job. - The job. - List of the stored files. - Any error. - - - - Query concrete attributes of a given job. - The job. - Which attributes should be retrieved. - Values of the queried attributes. - Any error. - - - - diff --git a/org.glite.jp.ws-interface/src/JobProvenanceTypes.xml b/org.glite.jp.ws-interface/src/JobProvenanceTypes.xml deleted file mode 100644 index f6e7016..0000000 --- a/org.glite.jp.ws-interface/src/JobProvenanceTypes.xml +++ /dev/null @@ -1,137 +0,0 @@ - - - - - CVS revision: - - - - - Operators used in queries. Most are self-explanatory. - - - - - The attribute is between two specified values. - The attribute exists (even having a NULL value). - - - - A single user-recorded value for a job attribute. - Name of the attribute, including namespace. - Value. - - - - - - - - - - - - A single condition on job. - Attribute name to query. - Operation. - Where the attribute value came from. - Value to compare the job attribute with. - Another value (for op = WITHIN). - - - - One session between IS and PS (aka feed) charactetristics. - URL of primary server. - Filter conditions. - Query type. - Query type - Unique ID of the feed session. - - - - JP primary storage file identification. - Type of the file (as set on StartUpload). - Name of the file (if there are more of the same type per job). - Where the file is stored on JP primary storage. - - - - Single value of an attribute. - Name of the attribute, including namespace. - String value. - When this value was recorded. - Where this value came from. - - - - - String value. - Binary value. - - - - Specification of attribute origin. - JP system value, e.g. job owner. - Explicitely stored by the user via RecordTag operation. - Coming from uploaded file. - - - - Information on a single job. - Used for recording tags into JPPS, feeding JPIS from JPPS, - and to answer user queries on JPIS. - ID of the job. - Job owner. - - Attribute values, required by query/feed and available right now. - - - User query only: which primary storage(s) have data on this job. - - - UpdateJobs only: this job no longer belongs to the feed. - Attribute values are those which caused the change. - - - - - Single query condition on a job. - Similarly to LB, these outer conditions are logically ANDed. - - Which attribute the condition refers to. - - - Specific attribute origin (if we do care). - - - List of conditions on attribute attr. - These conditions are logically ORed. - - - - - Single condition on an attribute. - Query operation. - Value to compare attribute with. - Value to compare attribute with. - - - - - - - - - Single type of an attribute - Name of the attribute - Cardinality of the attribute - Quariable attribute (indexed) - - - - - - - diff --git a/org.glite.jp.ws-interface/src/doc.xml b/org.glite.jp.ws-interface/src/doc.xml deleted file mode 100644 index 78cb6a5..0000000 --- a/org.glite.jp.ws-interface/src/doc.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/org.glite.jp.ws-interface/src/jpdev.sh b/org.glite.jp.ws-interface/src/jpdev.sh deleted file mode 100755 index e3e2a72..0000000 --- a/org.glite.jp.ws-interface/src/jpdev.sh +++ /dev/null @@ -1,36 +0,0 @@ -#! /bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -xmlcut() { - echo -e "\t" - echo - grep "<$2>" $(dirname $0)/JobProvenance$1.xml -A 1000 | grep "" -B 1000 | grep -v "<$2>\|" -} - -xmlmerge() { - xmlcut PS $1 - echo - xmlcut IS $1 -} - -DOC="$(xmlmerge doc)" -OPERATIONS="$(xmlmerge operations)" - -XML_TMPL=$(sed $(dirname $0)/$1 -e 's/"/\\"/g') -eval "XML_RESULT=\"${XML_TMPL}\"" -echo "$XML_RESULT" diff --git a/org.glite.jp.ws-interface/src/jpdev.xml.sh b/org.glite.jp.ws-interface/src/jpdev.xml.sh deleted file mode 100644 index f5ae764..0000000 --- a/org.glite.jp.ws-interface/src/jpdev.xml.sh +++ /dev/null @@ -1,38 +0,0 @@ - - - CVS revision: -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - - - - -${DOC} - - - - - -${OPERATIONS} - - diff --git a/org.glite.jp.ws-interface/src/puke-schema.xsl b/org.glite.jp.ws-interface/src/puke-schema.xsl deleted file mode 100644 index fdbe9fb..0000000 --- a/org.glite.jp.ws-interface/src/puke-schema.xsl +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - false - - - - - - - - - - : - - - - - - 0 - 1 - - - - - unbounded - 1 - - - - - - - - - - - - - - - : - - - - - unbounded - 1 - - - - - - - - - - - - - - - : - - - - - unbounded - 1 - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.ws-interface/src/puke-ug.xsl b/org.glite.jp.ws-interface/src/puke-ug.xsl deleted file mode 100644 index d3dbdd4..0000000 --- a/org.glite.jp.ws-interface/src/puke-ug.xsl +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - Job Provenance - - - Primary Storage -- Overview - - - - - Primary Storage -- Operations - - - - - - - - - Index Server -- Overview - - - - - Index Server -- Operations - - - - - - - - - JP Common Types - - - - - - - - - - - - - list of - - - - - - - - - - - - - - - - - - - <xsl:value-of select="@name"/> - - - Inputs: - - - - - - - N/A - - - - Outputs: - - - - - - - N/A - - - - - - - - - - <xsl:value-of select="@name"/> - - - - Structure (sequence complex type in WSDL) - Fields: ( type name description ) - - - Union (choice complex type in WSDL) - Fields: ( type name description ) - - - Enumeration (restriction of xsd:string in WSDL), - exactly one of the values must be specified. - - Values: - - - Flags (sequence of restricted xsd:string in WSDL), - any number of values can be specified together. - - Values: - - - - - - - - - list of - - - - - - - - - - - - - - - - - - - - (optional) - - - - - - - - - - - - - diff --git a/org.glite.jp.ws-interface/src/puke-wsdl.xsl b/org.glite.jp.ws-interface/src/puke-wsdl.xsl deleted file mode 100644 index ea7598e..0000000 --- a/org.glite.jp.ws-interface/src/puke-wsdl.xsl +++ /dev/null @@ -1,292 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - false - - - - - - - - - - : - - - - - - 0 - 1 - - - - - unbounded - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - : - - - - - unbounded - 1 - - - - - - - - - - - - - - - : - - - - - unbounded - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp.ws-interface/src/ws_fault.c b/org.glite.jp.ws-interface/src/ws_fault.c deleted file mode 100644 index 0ddcf54..0000000 --- a/org.glite.jp.ws-interface/src/ws_fault.c +++ /dev/null @@ -1,209 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#ident "$Header: " - -#include -#include -#include -#include - -#ifndef UNUSED - #ifdef __GNUC__ - #define UNUSED __attribute__((unused)) - #else - #define UNUSED - #endif -#endif - -#define GSOAP_STRING(CHOICE) GLITE_SECURITY_GSOAP_CHOICE_GET(CHOICE, string, stringOrBlob, 1) -#define GSOAP_BLOB(CHOICE) GLITE_SECURITY_GSOAP_CHOICE_GET(CHOICE, blob, stringOrBlob, 1) -#define GSOAP_SETSTRING(CHOICE, VALUE) GLITE_SECURITY_GSOAP_CHOICE_SET(CHOICE, string, jptype, stringOrBlob, 1, VALUE) -#define GSOAP_SETBLOB(CHOICE, VALUE) GLITE_SECURITY_GSOAP_CHOICE_SET(CHOICE, blob, jptype, stringOrBlob, 1, VALUE) -#define GSOAP_ISSTRING(CHOICE) GLITE_SECURITY_GSOAP_CHOICE_ISTYPE(CHOICE, string, jptype, stringOrBlob, 1) -#define GSOAP_ISBLOB(CHOICE) GLITE_SECURITY_GSOAP_CHOICE_ISTYPE(CHOICE, blob, jptype, stringOrBlob, 1) - -#if GSOAP_VERSION >= 20709 - #define GFNUM SOAP_TYPE_jptype__genericFault -#else - #define GFNUM SOAP_TYPE__genericFault -#endif - -#ifndef dprintf -#define dprintf(FMT, ARGS...) printf(FMT, ##ARGS) -#endif - - -static int glite_jp_clientCheckFault(struct soap *soap, int err, const char *name, int toSyslog) UNUSED; -static int glite_jp_clientGetErrno(struct soap *soap, int err) UNUSED; -static void glite_jp_server_err2fault(const glite_jp_context_t ctx,struct soap *soap) UNUSED; - -static struct jptype__genericFault* jp2s_error(struct soap *soap, const glite_jp_error_t *err); -static int clientGetFault(struct soap *soap, int err, const char **reason, struct jptype__genericFault **f, const char **fallback); - - -/* - * get client fault structs - * err - code got from soap call - * reason - error text - * f - extended fault structs or NULL - * fallback - xml fault description or NULL - * return values: - * 0 - OK - * 1 - got a extended fault info - * 2 - internal gsoap fault - */ -static int clientGetFault(struct soap *soap, int err, const char **reason, struct jptype__genericFault **f, const char **fallback) { - struct SOAP_ENV__Detail *detail; - - *f = NULL; - if (fallback) *fallback = NULL; - - switch(err) { - case SOAP_OK: - return 0; - - case SOAP_FAULT: - case SOAP_SVR_FAULT: - detail = GLITE_SECURITY_GSOAP_DETAIL(soap); - if (reason) *reason = GLITE_SECURITY_GSOAP_REASON(soap); - - if (!detail) return 1; - if (detail->__type != GFNUM && detail->__any) { - // compatibility with clients gSoaps < 2.7.9b - if (fallback) *fallback = detail->__any; - return 1; - } - // client is based on gSoap 2.7.9b - assert(detail->__type == GFNUM); -#if GSOAP_VERSION >= 20709 - *f = (struct jptype__genericFault *)detail->fault; -#elif GSOAP_VERSION >= 20700 - *f = ((struct _genericFault *)detail->fault)->jpelem__genericFault; -#else - *f = ((struct _genericFault *)detail->value)->jpelem__genericFault; -#endif - return 1; - - default: - return 2; - } -} - - -static int glite_jp_clientGetErrno(struct soap *soap, int err) { - struct jptype__genericFault *f; - - switch(clientGetFault(soap, err, NULL, &f, NULL)) { - case 0: return 0; - case 1: return f ? f->code : -2; - default: return -1; - } -} - - -static int glite_jp_clientCheckFault(struct soap *soap, int err, const char *name, int toSyslog) -{ - struct jptype__genericFault *f; - const char *reason, *xml; - char indent[200] = " "; - char *prefix; - int retval; - - if (name) asprintf(&prefix, "[%s] ", name); - else prefix = strdup(""); - - switch(clientGetFault(soap, err, &reason, &f, &xml)) { - case 0: - retval = 0; - dprintf("%sOK\n", prefix); - break; - - case 1: - retval = -1; - dprintf("%s%s\n", prefix, reason); - if (toSyslog) syslog(LOG_ERR, "%s", reason); - if (!f && xml) { - dprintf("%s%s%s\n", prefix, indent, xml); - if (toSyslog) syslog(LOG_ERR, "%s", xml); - } - while (f) { - dprintf("%s%s%s: %s (%s)\n", - prefix, indent, - f->source, f->text, f->description); - if (toSyslog) syslog(LOG_ERR, "%s%s: %s (%s)", - prefix, f->source, f->text, f->description); - f = f->reason; - strcat(indent," "); - } - break; - - case 2: - fprintf(stderr, "%ssoap err=%d, ", prefix, err); - soap_print_fault(soap, stderr); - retval = -1; - break; - } - - free(prefix); - return retval; -} - - -static struct jptype__genericFault* jp2s_error(struct soap *soap, const glite_jp_error_t *err) -{ - struct jptype__genericFault *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 = err->desc ? soap_strdup(soap,err->desc) : NULL; - ret->reason = jp2s_error(soap,err->reason); - } - return ret; -} - - -static void glite_jp_server_err2fault(const glite_jp_context_t ctx,struct soap *soap) -{ - struct SOAP_ENV__Detail *detail; - struct jptype__genericFault *item; -#if GSOAP_VERSION >= 20709 - struct jptype__genericFault *f; - item = f = jp2s_error(soap,ctx->error); -#else - struct _genericFault *f = soap_malloc(soap, sizeof *f); - item = f->jpelem__genericFault = jp2s_error(soap,ctx->error); -#endif - soap_receiver_fault(soap,"Oh, shit!",NULL); - // no error in JP context? - if (!item) return; - - detail = (struct SOAP_ENV__Detail *)soap_faultdetail(soap); -#if GSOAP_VERSION >= 20700 - detail->fault = (void *)f; -#else - detail->value = (void *)f; -#endif - detail->__type = GFNUM; - detail->__any = NULL; - - if (soap->version == 2) soap->fault->SOAP_ENV__Detail = detail; - else soap->fault->detail = detail; -} diff --git a/org.glite.jp/.cvsignore b/org.glite.jp/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.jp/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.jp/build.xml b/org.glite.jp/build.xml deleted file mode 100644 index 7ffb4c0..0000000 --- a/org.glite.jp/build.xml +++ /dev/null @@ -1,410 +0,0 @@ - - - - - - - Ant build file to build the GLite Job Provenance Subsystem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Preparing directories ... - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <project name="${subsystem.name}" type="post-subsystem" packageName="${global.prefix}-${subsystem.prefix}"/> - - - - diff --git a/org.glite.jp/configure b/org.glite.jp/configure deleted file mode 100755 index 6b61ac6..0000000 --- a/org.glite.jp/configure +++ /dev/null @@ -1,691 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; - -my $pwd = `pwd`; chomp $pwd; -my $prefix = $pwd.'/stage'; -my $stagedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my $version; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $sec_tag = ''; -my $jobid_tag = ''; - -my @nodes = qw/client server logger utils client-java doc ws-test db jpprimary jpindex jpclient/; -my %enable_nodes; -my %disable_nodes; - -my %extern_prefix = ( - cares => '/opt/c-ares', - classads => '/opt/classads', - cppunit => '/usr', - expat => '/usr', - globus => '/opt/globus', - gsoap => '/usr', - mysql => '/usr', - voms => '/opt/glite', - gridsite => '/opt/glite', - lcas => '/opt/glite', - ant => '/usr', - jdk => '/usr', - libtar => '/usr', -); - -my %jar = ( - 'commons-codec' => '/usr/share/java/commons-codec-1.3.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %topbuild; - -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test/], - 'security' => [qw/gss gsoap-plugin/], - 'lbjp-common' => [qw/db maildir server-bones trio jp-interface/], - 'jobid' => [qw/api-c api-cpp api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - ); - - -my @opts = ( - 'prefix=s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour=s' => \$thrflavour, - 'nothrflavour=s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$version, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'security-tag=s' => \$sec_tag, - 'jobid-tag=s' => \$jobid_tag, - 'help' => \$help, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$extern_prefix{$_} for keys %extern_prefix; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my @m = map "org.glite.$listmodules.$_",@{$lbmodules{$listmodules}}; - print "@m\n"; - exit 0; -} - -warn "$0: --version and --output make sense only in --mode=etics\n" - if ($version || $output) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},@{$lbmodules{security}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless $disable_nodes{$_}; - } -} - -if (!$en && !$dis) { $enable_nodes{$_} = 1 for (@nodes) } ; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $prefix unless $stagedir; - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: $extern_prefix{$_}\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\nclean:\n"; - - for (@modules) { - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - print MAK "\tcd $full$build && \${MAKE} clean\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $topbuild{$_} ? - "\tcd $full$build && \${MAKE} distclean\n" : - "\trm -rf $full$build\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - - my $full = full($_); - my $build = $topbuild{$_} ? '': '/build'; - - print MAK "$_: @dnames\n\tcd $full$build && \${MAKE} && \${MAKE} install\n\n"; - } - - close MAK; -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag){ - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($sec_tag){ - for (@{$lbmodules{security}}){ - if ("security.".$_ eq $module){ - $tag = '-r '.$sec_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads/ ], - 'lb.client-java' => [ qw/ant:B/ ], - 'lb.common' => [ qw/expat cppunit:B classads/ ], - 'lb.doc' => [], - 'lb.logger' => [ qw/cppunit:B/ ], - 'lb.server' => [ qw/globus expat cares mysql cppunit:B gsoap:B classads voms lcas gridsite/ ], - 'lb.state-machine' => [ qw/classads/ ], - 'lb.utils' => [ qw/cppunit:B/ ], - 'lb.ws-interface' => [], - 'lb.ws-test' => [ qw/gsoap:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/mysql/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw/cppunit:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B/ ], - 'security.gss' => [ qw/globus cares cppunit:B/ ], - 'security.gsoap-plugin' => [ qw/cppunit:B globus cares gsoap:B/ ], - 'jobid.api-c' => [ qw/cppunit:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], -); - -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$need_externs{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $need_externs_type{$ext}->{$1} = $type; - } -} - -%need_jars = ( - 'jobid.api-java' => [ qw/commons-codec/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp jobid.api-c - security.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp jobid.api-c - lb.types:B lbjp-common.trio security.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - jobid.api-c - lb.common - security.gss - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir - jobid.api-c - security.gsoap-plugin security.gss - / ], - 'lb.state-machine' => [ qw/lb.common lbjp-common.jp-interface security.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine - / ], - 'lb.ws-test' => [ qw/security.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lbjp-common.db' => [ qw/lbjp-common.trio/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.server-bones' => [ qw// ], - 'lbjp-common.trio' => [ qw// ], - 'security.gss' => [ qw// ], - 'security.gsoap-plugin' => [ qw/security.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - security.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - security.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( gridsite=>'org.gridsite.core'); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', -); - -my @t = qw/lb.client-java jobid.api-java lb.types/; -@topbuild{@t} = (1) x ($#t+1); -} - -sub full -{ - my $short = shift; - return $extrafull{$short} ? $extrafull{$short} : 'org.glite.'.$short; -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java -security.gss security.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -/; - @aux{@m} = (1) x ($#m+1); - - my $short = shift; - my $full = full $short; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $build = ''; - - unless ($topbuild{$_}) { - $build = '/build'; - unless (-d "$full/build") { - mkdir "$full/build" or die "mkdir $full/build: $!\n"; - } - unlink "$full/build/Makefile"; - symlink "../Makefile","$full/build/Makefile" or die "symlink ../Makefile $full/build/Makefile: $!\n"; - } - - open MKINC,">$full$build/Makefile.inc" - or die "$full$build/Makefile.inc: $!\n"; - - print "Creating $full$build/Makefile.inc\n"; - - print MKINC qq{ -PREFIX = $prefix -stagedir = $stagedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -}; - - for (@{$need_externs{$short}}) { - print MKINC "${_}_prefix = $extern_prefix{$_}\n" - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; -} - -my %etics_externs; -my %etics_projects; -BEGIN{ - %etics_externs = ( - globus=>'vdt_globus_essentials', - cares=>'c-ares', - voms=>'org.glite.security.voms-api-cpp', - gridsite=>'org.gridsite.shared', - lcas=>'org.glite.security.lcas', - ); - %etics_projects = ( - vdt=>[qw/globus/], - 'org.glite'=>[qw/voms gridsite lcas/], - ); -}; - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod; - - my ($major,$minor,$rev,$age); - - if ($version) { - $version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - open V,"org.glite.$subsys.$module/project/version.properties" - or die "org.glite.$subsys.$module/project/version.properties: $!\n"; - - while ($_ = ) { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - } - - my @copts = (); - my %ge; - @ge{@{$etics_projects{'org.glite'}}} = (1) x ($#{$etics_projects{'org.glite'}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}/$_*.jar"; - } - - - my $conf = "glite-$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $topbuild{"$subsys.$module"} ? '' : "build.root = build\n"; - - my $confdir = $topbuild{"$subsys.$module"} ? '..' : '../..'; - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = org.glite.$subsys.$module -displayName = $conf -description = org.glite.$subsys.$module -projectName = org.glite -age = $age -deploymentType = None -tag = $conf -version = $major.$minor.$rev -path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz - -[Platform-default:VcsCommand] -displayName = None -description = None -tag = cvs -d \${vcsroot} tag -R \${tag} \${moduleName} -branch = None -commit = None -checkout = cvs -d \${vcsroot} co -r \${tag} \${moduleName} - -[Platform-default:BuildCommand] -postpublish = None -packaging = None -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = make -init = None -install = make install -clean = make clean -test = make check -configure = cd $confdir && \${moduleName}/configure --thrflavour=\${globus.thr.flavor} --nothrflavour=\${globus.nothr.flavor} --prefix=\${prefix} --stage=\${stageDir} --module $subsys.$module @copts -checkstyle = None - -[Platform-default:Property] -$buildroot - -[Platform-default:DynamicDependency] - -}; - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_; - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - print C "$proj|$eext = $type\n"; - } - - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - print C "org.glite|org.glite.$_ = $type\n"; - } - - close C; -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$extern_prefix{gsoap}/bin/soapcpp2 -v 2>&1 |" or die "$extern_prefix{gsoap}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - - -sub usage { - my @ext = keys %extern_prefix; - my @myjars, keys %jar; - - print STDERR qq{ -usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - -Mode of operation: - --mode={checkout|build|etics} what to do [build] - -What to build: - --module=module build this module only (mostly in-Etics operation) - --enable-NODE build this "node" (set of modules) only. Available nodes are - @{$lbmodules{lb}},@{$lbmodules{security}} - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --security-tag=tag checkout security modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - -Dependencies: - --with-EXTERNAL=PATH where to look for an external. Required externals - (not all for all modules) are: - @ext - --with-JAR=JAR where to look for jars. Required jars are: - @myjars - Summary of what will be used is always printed - -}; - -} diff --git a/org.glite.jp/doc/README b/org.glite.jp/doc/README deleted file mode 100644 index 4a2d054..0000000 --- a/org.glite.jp/doc/README +++ /dev/null @@ -1 +0,0 @@ -All JP documentation is now in org.glite.jp.doc module. diff --git a/org.glite.jp/project/build.number b/org.glite.jp/project/build.number deleted file mode 100644 index add42f8..0000000 --- a/org.glite.jp/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Fri Oct 14 15:24:20 CEST 2005 -module.build=38 diff --git a/org.glite.jp/project/build.properties b/org.glite.jp/project/build.properties deleted file mode 100644 index 2a85dda..0000000 --- a/org.glite.jp/project/build.properties +++ /dev/null @@ -1,2 +0,0 @@ -ext.gsoap.version=2.7.9d -ext.gsoap.rep.file=gSOAP-2.7.9d.tar.gz diff --git a/org.glite.jp/project/dependencies.properties b/org.glite.jp/project/dependencies.properties deleted file mode 100644 index 28948b6..0000000 --- a/org.glite.jp/project/dependencies.properties +++ /dev/null @@ -1,16 +0,0 @@ -################################################################### -# System dependencies -################################################################### - -org.glite.version = glite_branch_3_1_0 -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.server-common.version = HEAD -org.glite.jp.index.version = HEAD -org.glite.jp.primary.version = HEAD -org.glite.jp.client.version = HEAD - -ext.gsoap.version = 2.7.9d diff --git a/org.glite.jp/project/glite.jp.csf.xml b/org.glite.jp/project/glite.jp.csf.xml deleted file mode 100644 index ba274b4..0000000 --- a/org.glite.jp/project/glite.jp.csf.xml +++ /dev/null @@ -1,322 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The org.glite and org.glite.jp modules have been updated, please rerun the configuration file - - - - - The org.glite and org.glite.jp modules have been updated, please rerun the configuration file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp/project/properties.xml b/org.glite.jp/project/properties.xml deleted file mode 100755 index 276cf76..0000000 --- a/org.glite.jp/project/properties.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.jp/project/run-workspace b/org.glite.jp/project/run-workspace deleted file mode 100644 index a5d1f54..0000000 --- a/org.glite.jp/project/run-workspace +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -cd ../.. - -cvs co org.glite -cvs co org.glite.jp - -cd org.glite.jp/project -ant -f glite.jp.csf.xml - diff --git a/org.glite.jp/project/taskdefs.xml b/org.glite.jp/project/taskdefs.xml deleted file mode 100755 index c4cc889..0000000 --- a/org.glite.jp/project/taskdefs.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/org.glite.jp/project/version.properties b/org.glite.jp/project/version.properties deleted file mode 100644 index 6a4c8b1..0000000 --- a/org.glite.jp/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# : /cvs/jra1mw/org.glite.jp/project/version.properties,v 1.43 2009/03/13 10:21:06 zsustr Exp $ -module.version=1.6.0 -module.age=2 diff --git a/org.glite.lb-utils.context/.cvsignore b/org.glite.lb-utils.context/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.lb-utils.context/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.lb-utils.context/LICENSE b/org.glite.lb-utils.context/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.lb-utils.context/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils.context/build.xml b/org.glite.lb-utils.context/build.xml deleted file mode 100644 index 81cd270..0000000 --- a/org.glite.lb-utils.context/build.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.context/project/build.number b/org.glite.lb-utils.context/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils.context/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils.context/project/build.properties b/org.glite.lb-utils.context/project/build.properties deleted file mode 100755 index e69de29..0000000 diff --git a/org.glite.lb-utils.context/project/configure.properties.xml b/org.glite.lb-utils.context/project/configure.properties.xml deleted file mode 100644 index 0b17304..0000000 --- a/org.glite.lb-utils.context/project/configure.properties.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - diff --git a/org.glite.lb-utils.context/project/properties.xml b/org.glite.lb-utils.context/project/properties.xml deleted file mode 100644 index 86c1f8a..0000000 --- a/org.glite.lb-utils.context/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.context/project/version.properties b/org.glite.lb-utils.context/project/version.properties deleted file mode 100755 index 6f1f8ab..0000000 --- a/org.glite.lb-utils.context/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 0.0.0 -module.age = 0 \ No newline at end of file diff --git a/org.glite.lb-utils.db/.cvsignore b/org.glite.lb-utils.db/.cvsignore deleted file mode 100755 index ff82493..0000000 --- a/org.glite.lb-utils.db/.cvsignore +++ /dev/null @@ -1,5 +0,0 @@ -.project -.cdtproject -build -doc -reports diff --git a/org.glite.lb-utils.db/LICENSE b/org.glite.lb-utils.db/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.lb-utils.db/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils.db/Makefile b/org.glite.lb-utils.db/Makefile deleted file mode 100644 index 447dd4c..0000000 --- a/org.glite.lb-utils.db/Makefile +++ /dev/null @@ -1,137 +0,0 @@ -# defaults -top_srcdir=. -builddir=build -stagedir=. -distdir=. -globalprefix=glite -lbutilsprefix=lb-utils -package=glite-lb-utils-db -version=0.2.0 -PREFIX=/opt/glite -flavour=gcc32thr - -glite_location=/opt/glite -mysql_prefix=/opt/mysql -mysql_version=4.1.11 -cppunit_prefix=/opt/cppunit -thrflavour=gcc32pthr -nothrflavour=gcc32 - --include Makefile.inc --include ../project/version.properties - -version=${module.version} - -CC=gcc - -VPATH=${top_srcdir}/interface:${top_srcdir}/src:${top_srcdir}/examples - -DEBUG:=-g -O0 -Wall - -CFLAGS:= \ - ${DEBUG} \ - -DVERSION=\"${version}\" \ - -I${stagedir}/include -I${top_srcdir}/src -I. \ - -I${top_srcdir}/interface \ - ${COVERAGE_FLAGS} \ - -I${mysql_prefix}/include -I${mysql_prefix}/include/mysql \ - -D_GNU_SOURCE - -ifdef LBS_DB_PROFILE - CFLAGS:=${CFLAGS} -DLBS_DB_PROFILE -endif - -TEST_LIBS:=-L${cppunit_prefix}/lib -lcppunit -TEST_INC:=-I${cppunit_prefix}/include - -LDFLAGS:=-L${stagedir}/lib ${COVERAGE_FLAGS} - -COMPILE:=libtool --mode=compile ${CC} ${CFLAGS} -LINK:=libtool --mode=link ${CC} -rpath ${stagedir}/lib ${LDFLAGS} -INSTALL:=libtool --mode=install install - -archlib:=lib -host_cpu:=${shell uname -m} -ifeq (${host_cpu},x86_64) - archlib:=lib64 -endif - -ifneq (${mysql_prefix},/usr) - ifeq ($(shell echo ${mysql_version} | cut -d. -f1,2),4.1) - mysqlib := -L${mysql_prefix}/${archlib}/mysql - else - mysqlib := -L${mysql_prefix}/${archlib} - endif -endif - -EXT_LIBS:=${mysqlib} -lmysqlclient -lz -lglite_lbu_trio -OBJS:=db.o -TESTOBJS:=dbtest.o -HDRS:=db.h -LOBJS:=${OBJS:.o=.lo} -LTESTOBJS:=${TESTOBJS:.o=.lo} - -libglite_lbu_db.la: ${LOBJS} - ${LINK} -o $@ $< ${EXT_LIBS} - -libglite_lbu_dbtest.la: ${LTESTOBJS} - ${LINK} -o $@ $< ${EXT_LIBS} - -dbtest.lo dbtest.o: db.c db.h - ${COMPILE} -DGLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH=10 -c $< -o $@ - -db_test: db_test.lo libglite_lbu_dbtest.la - ${LINK} -o $@ $+ ${EXT_LIBS} - -db_expire: db_expire.lo libglite_lbu_dbtest.la - ${LINK} -o $@ $+ ${EXT_LIBS} - -default all: compile - -compile: libglite_lbu_db.la - -check: - -echo No checks here yet. - -test_coverage: - -mkdir coverage - cd coverage && $(MAKE) -f ../Makefile top_srcdir=../../ COVERAGE_FLAGS="-fprofile-arcs -ftest-coverage" check - cd coverage && for i in `echo ${OBJS} | tr ' ' '\012' | sort -u`; do gcov $$i ; done - -examples: db_test db_expire - -doc: - doxygen C.dox - -stage: compile - $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -install: - -mkdir -p ${PREFIX}/lib - -mkdir -p ${PREFIX}/include/${globalprefix}/${lbutilsprefix} -# ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - ${INSTALL} -m 755 "libglite_lbu_db.la" "${PREFIX}/lib/libglite_lbu_db.la"; \ - ${INSTALL} -m 644 ${top_srcdir}/interface/${HDRS} ${PREFIX}/include/${globalprefix}/${lbutilsprefix} - -clean: - -%.o %.lo: %.c - ${COMPILE} -c $< - -db.lo: db.c db.h -db_test.lo: libglite_lbu_dbtest.la db.h db_test.c - -.PHONY: default all compile check examples doc stage dist distsrc distbin install clean test_coverage diff --git a/org.glite.lb-utils.db/build.xml b/org.glite.lb-utils.db/build.xml deleted file mode 100644 index 14d4d7e..0000000 --- a/org.glite.lb-utils.db/build.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.db/examples/db_expire.c b/org.glite.lb-utils.db/examples/db_expire.c deleted file mode 100644 index 012a91b..0000000 --- a/org.glite.lb-utils.db/examples/db_expire.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Example (and quick test) of prepared statements expirations. - * Use 'SET GLOBAL wait_timeout=...' for experimenting. - * - * Requires existing database with appropriate access and example table: - * - * mysqladmin -u root -p create test - * mysql -u root -p -e 'GRANT ALL on test.* to testuser@localhost' - * ./db_test - * - * Use CS environment variable when using different user/pwd@machine:dbname. - */ - -#include -#include -#include - -#include "db.h" - -#define CS "testuser/@localhost:test" -#define SELECT_CMD "SELECT id, user, info FROM data WHERE user = ?" - -#define dprintf(ARGS) { printf("%s: ", name); printf ARGS; } - - -static void print_blob(unsigned long len, char *blob) { - int i; - for (i = 0; i < len; i++) printf("%02X ", blob[i]); - printf("(='"); - for (i = 0; i < len; i++) printf("%c", blob[i]); - printf("')"); -} - - -static void print_free_result(const char *name, unsigned long *lens, char **res) { - dprintf((" id='%s'=%d\n", res[0], atoi(res[0]))); - - dprintf((" user='%s'\n", res[1])); - - dprintf((" blob=")); - if (res[2] && lens) print_blob(lens[2], res[2]); - else printf("null"); - printf("\n"); - - free(res[0]); - free(res[1]); - free(res[2]); -} - - -int main(int argn, char *argv[]) { - char *name, *user; - const char *cs; - glite_lbu_DBContext ctx; - glite_lbu_Statement stmt; - int caps, i, nr, c; - unsigned long lens[3]; - char *res[3]; - - if ((name = strrchr(argv[0], '/')) != NULL) name++; - else name = argv[0]; - if ((cs = getenv("CS")) == NULL) cs = CS; - - // init - dprintf(("connecting to %s...\n", cs)); - if (glite_lbu_InitDBContext(&ctx) != 0) goto fail; - if (glite_lbu_DBConnect(ctx, cs) != 0) goto failctx; - if ((caps = glite_lbu_DBQueryCaps(ctx)) == -1) goto failcon; - if ((caps & GLITE_LBU_DB_CAP_PREPARED) == 0) { - dprintf(("can't do prepared commands, exiting.")); - goto failcon; - } - // caps - glite_lbu_DBSetCaps(ctx, caps); - dprintf(("capabilities: %d\n", caps)); - - user = NULL; - dprintf(("preparing '%s'...\n", user)); - if ((glite_lbu_PrepareStmt(ctx, SELECT_CMD, &stmt)) != 0) goto failcon; - - do { - user = "cicomexocitl.civ"; - dprintf(("executing '%s'...\n", user)); - if (glite_lbu_ExecStmt(stmt, 1, GLITE_LBU_DB_TYPE_VARCHAR, user) == -1) goto failstmt; - dprintf(("fetching '%s'...\n", user)); - while ((nr = glite_lbu_FetchRow(stmt, 3, lens, res)) > 0) { - dprintf(("Result: n=%d, res=%p\n", nr, res)); - print_free_result(name, lens, res); - } - if (nr < 0) { - dprintf(("fetch '%s' failed\n", user)); - break; - } - dprintf(("\n")); - - c = fgetc(stdin); - } while (c != -1 && (c == '\r' || c == '\n')); - - dprintf(("closing...\n")); - glite_lbu_DBClose(ctx); - glite_lbu_FreeDBContext(ctx); - return 0; - -failstmt: - printf("closing stmt...\n"); - glite_lbu_FreeStmt(&stmt); -failcon: - dprintf(("closing...\n")); - glite_lbu_DBClose(ctx); -failctx: - glite_lbu_FreeDBContext(ctx); -fail: - dprintf(("failed\n")); - return 1; -} diff --git a/org.glite.lb-utils.db/examples/db_test.c b/org.glite.lb-utils.db/examples/db_test.c deleted file mode 100644 index 02be92a..0000000 --- a/org.glite.lb-utils.db/examples/db_test.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Example (and quick test) of this DB module. - * - * Requires existing database with appropriate access: - * - * mysqladmin -u root -p create test - * mysql -u root -p -e 'GRANT ALL on test.* to testuser@localhost' - * - * Use CS environment variable when using different user/pwd@machine:dbname. - */ - -#include -#include -#include - -#include "db.h" - -#define CS "testuser/@localhost:test" -#define CREATE_CMD "CREATE TABLE data (\n\ - id INT NOT NULL,\n\ - user VARCHAR(32) NOT NULL,\n\ - info BLOB,\n\ - PRIMARY KEY (id),\n\ - INDEX(user)\n\ -) engine=innodb" -#define DROP_CMD "DROP TABLE data" -#define INSERT_TRIO_CMD "INSERT INTO data (id, user, info) VALUES (%d, %s, %s)" -#define SELECT_TRIO_CMD "SELECT id, user, info FROM data WHERE user = '%s'" -#define INSERT_CMD "INSERT INTO data (id, user, info) VALUES (?, ?, ?)" -#define SELECT_CMD "SELECT id, user, info FROM data WHERE user = ?" - -#define dprintf(ARGS) { printf("%s: ", name); printf ARGS; } - - -static void print_blob(unsigned long len, char *blob) { - int i; - for (i = 0; i < len; i++) printf("%02X ", blob[i]); - printf("(='"); - for (i = 0; i < len; i++) printf("%c", blob[i]); - printf("')"); -} - - -static void print_free_result(const char *name, unsigned long *lens, char **res) { - dprintf((" id='%s'=%d\n", res[0], atoi(res[0]))); - - dprintf((" user='%s'\n", res[1])); - - dprintf((" blob=")); - if (res[2] && lens) print_blob(lens[2], res[2]); - else printf("null"); - printf("\n"); - - free(res[0]); - free(res[1]); - free(res[2]); -} - - -int main(int argn, char *argv[]) { - char *name, *cmd; - const char *cs; - glite_lbu_DBContext ctx; - glite_lbu_Statement stmt; - int caps; - - char blob1[] = "Guess: blob or \000string?"; - char blob2[] = {0, 1, 2, 3, 4, 5}; - - int nr; - char *res[3]; - unsigned long lens[3]; - - if ((name = strrchr(argv[0], '/')) != NULL) name++; - else name = argv[0]; - if ((cs = getenv("CS")) == NULL) cs = CS; - cmd = NULL; - - // init - dprintf(("connecting to %s...\n", cs)); - if (glite_lbu_InitDBContext(&ctx) != 0) goto fail; - if (glite_lbu_DBConnect(ctx, cs) != 0) goto failctx; - if ((caps = glite_lbu_DBQueryCaps(ctx)) == -1) goto failcon; - if ((caps & GLITE_LBU_DB_CAP_PREPARED) == 0) { - dprintf(("can't do prepared commands, exiting.")); - goto failcon; - } - // caps - glite_lbu_DBSetCaps(ctx, caps || GLITE_LBU_DB_CAP_ERRORS); - dprintf(("capabilities: %d\n", caps)); - // create all needed tables and data - dprintf(("creating tables...\n")); - glite_lbu_ExecSQL(ctx, DROP_CMD, NULL); - if (glite_lbu_ExecSQL(ctx, CREATE_CMD, NULL) == -1) goto failcon; - // trio-insert - dprintf(("trio-insert...\n")); - asprintf(&cmd, INSERT_TRIO_CMD, 1, "'hyperochus'", "NULL"); - if (glite_lbu_ExecSQL(ctx, cmd, NULL) != 1) goto failcon; - free(cmd); cmd = NULL; - // prepared-insert - dprintf(("prepare-insert...\n")); - if (glite_lbu_PrepareStmt(ctx, INSERT_CMD, &stmt) != 0) goto failcon; - dprintf(("execute 1. insert...\n")); - if (glite_lbu_ExecStmt(stmt, 3, - GLITE_LBU_DB_TYPE_INT, 2, - GLITE_LBU_DB_TYPE_VARCHAR, "cicomexocitl.civ", - GLITE_LBU_DB_TYPE_BLOB, blob1, sizeof(blob1) - 1) != 1) goto failstmt; - dprintf(("execute 2. insert...\n")); - if (glite_lbu_ExecStmt(stmt, 3, - GLITE_LBU_DB_TYPE_INT, 3, - GLITE_LBU_DB_TYPE_VARCHAR, "tartarus", - GLITE_LBU_DB_TYPE_NULL) != 1) goto failstmt; - dprintf(("execute 3. insert...\n")); - if (glite_lbu_ExecStmt(stmt, 3, - GLITE_LBU_DB_TYPE_INT, 4, - GLITE_LBU_DB_TYPE_VARCHAR, "harpia", - GLITE_LBU_DB_TYPE_BLOB, blob2, sizeof(blob2)) != 1) goto failstmt; - glite_lbu_FreeStmt(&stmt); - dprintf(("\n")); - - // trio-query -{ - const char *user; - - user = "harpia"; - dprintf(("selecting '%s'...\n", user)); - asprintf(&cmd, SELECT_TRIO_CMD, user); - if (glite_lbu_ExecSQL(ctx, cmd, &stmt) == -1) goto failcon; - free(cmd); cmd = NULL; - dprintf(("fetching '%s'...\n", user)); - while ((nr = glite_lbu_FetchRow(stmt, 3, lens, res)) > 0) { - dprintf(("Result: n=%d, res=%p\n", nr, res)); - print_free_result(name, lens, res); - } - if (nr < 0) dprintf(("fetch '%s' failed\n", user)); - dprintf(("closing stmt...\n")); - glite_lbu_FreeStmt(&stmt); - dprintf(("\n")); - - user = "nobody"; - dprintf(("selecting '%s'...\n", user)); - asprintf(&cmd, SELECT_TRIO_CMD, user); - if (glite_lbu_ExecSQL(ctx, cmd, &stmt) == -1) goto failcon; - free(cmd); cmd = NULL; - dprintf(("fetching '%s'...\n", user)); - while ((nr = glite_lbu_FetchRow(stmt, 3, lens, res)) > 0) { - dprintf(("Result: n=%d, res=%p\n", nr, res)); - print_free_result(name, lens, res); - } - if (nr < 0) dprintf(("fetch '%s' failed\n", user)); - dprintf(("closing stmt...\n")); - glite_lbu_FreeStmt(&stmt); - dprintf(("\n")); -} - - // "param" queries -{ - const char *user = NULL; - - dprintf(("preparing '%s'...\n", user)); - if ((glite_lbu_PrepareStmt(ctx, SELECT_CMD, &stmt)) != 0) goto failcon; - - user = "cicomexocitl.civ"; - dprintf(("executing '%s'...\n", user)); - if (glite_lbu_ExecStmt(stmt, 1, GLITE_LBU_DB_TYPE_VARCHAR, user) == -1) goto failstmt; - dprintf(("fetching '%s'...\n", user)); - while ((nr = glite_lbu_FetchRow(stmt, 3, lens, res)) > 0) { - dprintf(("Result: n=%d, res=%p\n", nr, res)); - print_free_result(name, lens, res); - } - if (nr < 0) dprintf(("fetch '%s' failed\n", user)); - dprintf(("\n")); - - dprintf(("closing stmt...\n")); - glite_lbu_FreeStmt(&stmt); - dprintf(("\n")); -} - - dprintf(("closing...\n")); - glite_lbu_DBClose(ctx); - glite_lbu_FreeDBContext(ctx); - return 0; - -failstmt: - printf("closing stmt...\n"); - glite_lbu_FreeStmt(&stmt); -failcon: - dprintf(("closing...\n")); - glite_lbu_DBClose(ctx); -failctx: - glite_lbu_FreeDBContext(ctx); -fail: - free(cmd); - dprintf(("failed\n")); - return 1; -} diff --git a/org.glite.lb-utils.db/interface/db.h b/org.glite.lb-utils.db/interface/db.h deleted file mode 100644 index 2818a4e..0000000 --- a/org.glite.lb-utils.db/interface/db.h +++ /dev/null @@ -1,344 +0,0 @@ -#ifndef GLITE_LBU_DB_H -#define GLITE_LBU_DB_H - -#ident "$Header$" - - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * \file db.h - * \defgroup database Database module - * - * Database modul module API (LB & JP Utils). - * - * There are two ways to access DB here: - * - simple: - * - * SQL commands as single string. All values are incorporated in the SQL command strings. Proper escaping is required. - * - enhanced: - * - * Prepared SQL commands with separated parameters, functions PrepareStmt() and ExecStmt(). All values are delivered in separated buffers. Its faster for multiple using and more secure. - * @{ - */ - - -/** - * Enable transaction support if available. - * - * With disabled transaction can be used transaction functions, they are just ignored. - */ -#define GLITE_LBU_DB_CAP_TRANSACTIONS 1 - -/** - * Check prepared parameters support. - */ -#define GLITE_LBU_DB_CAP_PREPARED 2 - -/** - * Check for getting indexes support. - * - * Needed for QueryIndices call. - */ -#define GLITE_LBU_DB_CAP_INDEX 4 - - -/** - * Print all errors. - * - * Not returned from detection of capabilities. - */ -#define GLITE_LBU_DB_CAP_ERRORS 8 - - -/** - * Database connection context. - */ -typedef struct glite_lbu_DBContext_s *glite_lbu_DBContext; - - -/** - * Prepared statement, used for SQL statement with parameters. - */ -typedef struct glite_lbu_Statement_s *glite_lbu_Statement; - - -/** - * Structure holds date for multi-rows insert. - */ -typedef struct glite_lbu_bufInsert_s *glite_lbu_bufInsert; - - - -/** - * All types of parameteres, they match to the SQL types. - */ -typedef enum { - GLITE_LBU_DB_TYPE_NULL = 0, - GLITE_LBU_DB_TYPE_TINYINT = 1, - GLITE_LBU_DB_TYPE_INT = 2, - GLITE_LBU_DB_TYPE_TINYBLOB = 3, - GLITE_LBU_DB_TYPE_TINYTEXT = 4, - GLITE_LBU_DB_TYPE_BLOB = 5, - GLITE_LBU_DB_TYPE_TEXT = 6, - GLITE_LBU_DB_TYPE_MEDIUMBLOB = 7, - GLITE_LBU_DB_TYPE_MEDIUMTEXT = 8, - GLITE_LBU_DB_TYPE_LONGBLOB = 9, - GLITE_LBU_DB_TYPE_LONGTEXT = 10, - GLITE_LBU_DB_TYPE_VARCHAR = 11, - GLITE_LBU_DB_TYPE_CHAR = 12, - GLITE_LBU_DB_TYPE_DATE = 13, - GLITE_LBU_DB_TYPE_TIME = 14, - GLITE_LBU_DB_TYPE_DATETIME = 15, - GLITE_LBU_DB_TYPE_TIMESTAMP = 16, - GLITE_LBU_DB_TYPE_LAST = 17 -} glite_lbu_DBType; - - - -/** - * Get error state from DB context. - * - * \param[in] ctx context to work with - * \param[out] text error name - * \param[out] desc error description - */ -int glite_lbu_DBError(glite_lbu_DBContext ctx, char **text, char **desc); - - -/** - * Initialize the database context. - * - * \param[out] ctx result context - */ -int glite_lbu_InitDBContext(glite_lbu_DBContext *ctx); - - -/** - * Free database context. - */ -void glite_lbu_FreeDBContext(glite_lbu_DBContext ctx); - - -/** - * Connect to the given database. - * - * \param[out] ctx context to work with - * \param[in] cs connect string user/password\@host:database - * - * \return error code, 0 = OK - */ -int glite_lbu_DBConnect(glite_lbu_DBContext ctx, const char *cs); - - -/** - * Close the connection. - * - * \param[in,out] ctx context to work with - */ -void glite_lbu_DBClose(glite_lbu_DBContext ctx); - - -/** - * Check database version and capabilities. - * - * \param[in,out] ctx context to work with - * - * \return capabilities - * \retval -1 error occured - */ -int glite_lbu_DBQueryCaps(glite_lbu_DBContext ctx); - - -/** - * Set the database capabilities on already initialized context. - * - * It should be find out by DBQueryCaps() first. - * - * \param[in,out] ctx context to work with - * \param[in] caps capabilities to use, should be found out by QueryCaps() - */ -void glite_lbu_DBSetCaps(glite_lbu_DBContext ctx, int caps); - - -/** - * Start transaction. - */ -int glite_lbu_Transaction(glite_lbu_DBContext ctx); - - -/** - * Commit (end) transaction. - */ -int glite_lbu_Commit(glite_lbu_DBContext ctx); - - -/** - * Cancel transaction. - */ -int glite_lbu_Rollback(glite_lbu_DBContext ctx); - - -/** - * \param[in,out] stmt executed SQL statement - * \param[in] n number of items for sure there is enough space in lengths and results - * \param[out] lengths array with lengths (good for data blobs), may be NULL - * \param[out] results array with results, all items are allocated - * - * \retval >0 number of fields of the retrieved row - * \retval 0 no more rows - * \retval -1 error - */ -int glite_lbu_FetchRow(glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results); - - -/** - * Free the statement structure and destroy its parameters. - * - * Statement will be set to NULL and multiple calls are allowed. - * - * \param[in,out] stmt statement - */ -void glite_lbu_FreeStmt(glite_lbu_Statement *stmt); - - -/** - * Parse and execute one simple SQL statement. - * All values are incorporated int the SQL command string. - * - * \param[in,out] ctx context to work with - * \param[in] cmd SQL command - * \param[out] stmt statement handle with results (makes sense for selects only) - * - * \return number of rows selected, created or affected by update, -1 on error - */ -int glite_lbu_ExecSQL(glite_lbu_DBContext ctx, const char *cmd, glite_lbu_Statement *stmt); - - -/** - * Query for column names of the statement. - * - * It work only for simple API, so only after ExecSQL(). - * - * \param[in,out] stmt the statement handle - * \param[out] cols result array of names - * - * \return error code - */ -int glite_lbu_QueryColumns(glite_lbu_Statement stmt, char **cols); - - -/** - * Retrieve column names of a query simple SQL statement. - * - * \param[in,out] ctx context to work with - * \param[in] table table name - * \param[out] key_names one-dimensional index names array - * \param[out] column_names two-dimensional column names array - * - * \return 0 if OK, nonzero on error - */ -int glite_lbu_QueryIndices(glite_lbu_DBContext ctx, const char *table, char ***key_names, char ****column_names); - - -/** - * Convert time_t into database-specific time string. - * - * The result string can be used directly in SQL commands. - * - * \param[in] t the converted time - * \param[out] str result allocated string - */ -void glite_lbu_TimeToDB(time_t t, char **str); - - -/** - * Convert database-specific time string to time_t. - * - * String is expected in database for (ISO format). - * - * \param[in] str the converted string - * \return result time - */ -time_t glite_lbu_DBToTime(const char *str); - - -/** - * Init data structure for buffered insert - * - * takes table_name and columns string for future multirow insert - * when insert string oversize size_limit or number of rows to be inserted - * overcome record_limit, the real insert is triggered - */ -int glite_lbu_bufferedInsertInit(glite_lbu_DBContext ctx, glite_lbu_bufInsert *bi, void *mysql, const char *table_name, long size_limit, long record_limit, const char * columns); - - -/** - * adds row of n values into n columns into an insert buffer - * if num. of rows or size of data oversteps the limits, real - * multi-row insert is done - */ -int glite_lbu_bufferedInsert(glite_lbu_bufInsert bi, const char *row); - - -/** - * Flush buffered data and free bi structure. - */ -int glite_lbu_bufferedInsertClose(glite_lbu_bufInsert bi); - - -/** - * Prepare the SQL statement. Use glite_lbu_FreeStmt() to free it. - * - * \param[in,out] ctx context to work with - * \param[in] sql SQL command - * \param[out] stmt returned SQL statement - * - * \return error code - */ -int glite_lbu_PrepareStmt(glite_lbu_DBContext ctx, const char *sql, glite_lbu_Statement *stmt); - - -/** - * Execute prepared SQL statement. - * - * \param[in,out] stmt SQL statement - * \param[in] n number of items - * - * Variable parameters (n-times): - * - * always: - * - * \param type DB item type - * - * then one of them: - * - * \param GLITE_LBU_DB_TYPE_TINYINT int c - * \param GLITE_LBU_DB_TYPE_INT long int i - * \param GLITE_LBU_DB_TYPE_...BLOB/TEXT void *b, unsigned long len - * \param GLITE_LBU_DB_TYPE_[VAR]CHAR char *str - * \param GLITE_LBU_DB_TYPE_DATE/TIME/DATETIME time_t t - * \param GLITE_LBU_DB_TYPE_TIMESTAMP time_t t - * \param GLITE_LBU_DB_TYPE_NULL - - * - * \return number of affected rows, -1 on error - */ -int glite_lbu_ExecStmt(glite_lbu_Statement stmt, int n, ...); - - -/** - * @} database group - */ - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/org.glite.lb-utils.db/project/build.number b/org.glite.lb-utils.db/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils.db/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils.db/project/build.properties b/org.glite.lb-utils.db/project/build.properties deleted file mode 100755 index 1df02e3..0000000 --- a/org.glite.lb-utils.db/project/build.properties +++ /dev/null @@ -1,3 +0,0 @@ -lb-utils.subsystem.name = org.glite.lb-utils -lb-utils.subsystem.prefix = lb-utils - diff --git a/org.glite.lb-utils.db/project/configure.properties.xml b/org.glite.lb-utils.db/project/configure.properties.xml deleted file mode 100644 index 276b497..0000000 --- a/org.glite.lb-utils.db/project/configure.properties.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -lbutilsprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} -flavour=${with.globus.thr.flavor} - -glite_location=${with.glite.location} -mysql_prefix=${with.mysql.prefix} -mysql_version=${ext.mysql.version} -cppunit_prefix=${with.cppunit.prefix} - - -PROJECT_NAME = "Glite LB/JP Utils: Database Module" -PROJECT_NUMBER = ${module.version} -OUTPUT_DIRECTORY = ${component.dir}/doc/C -OPTIMIZE_OUTPUT_FOR_C = YES -INPUT = ../interface/db.h -SHOW_DIRECTORIES = NO -FULL_PATH_NAMES = NO -EXTRACT_ALL = YES -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = YES -#PREDEFINED = _EDG_WLL_EVENT_COMMON -HAVE_DOT = NO - - - - diff --git a/org.glite.lb-utils.db/project/properties.xml b/org.glite.lb-utils.db/project/properties.xml deleted file mode 100644 index d01c359..0000000 --- a/org.glite.lb-utils.db/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.db/project/tar_exclude b/org.glite.lb-utils.db/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.lb-utils.db/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.lb-utils.db/project/version.properties b/org.glite.lb-utils.db/project/version.properties deleted file mode 100755 index 6f1f8ab..0000000 --- a/org.glite.lb-utils.db/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 0.0.0 -module.age = 0 \ No newline at end of file diff --git a/org.glite.lb-utils.db/src/db.c b/org.glite.lb-utils.db/src/db.c deleted file mode 100644 index bce48b8..0000000 --- a/org.glite.lb-utils.db/src/db.c +++ /dev/null @@ -1,1039 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "glite/lbu/trio.h" -#include "db.h" - - -#define GLITE_LBU_MYSQL_INDEX_VERSION 40001 -#define GLITE_LBU_MYSQL_PREPARED_VERSION 40102 -#define BUF_INSERT_ROW_ALLOC_BLOCK 1000 -#ifndef GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH -#define GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH 256 -#endif - - -#define CLR_ERR(CTX) lbu_clrerr((CTX)) -#define ERR(CTX, CODE, DESC) lbu_err((CTX), (CODE), (DESC), __FUNCTION__, __LINE__) -#define STATUS(CTX) ((CTX)->err.code) -#define MY_ERR(CTX) myerr((CTX), __FUNCTION__, __LINE__) -#define MY_ERRSTMT(STMT) myerrstmt((STMT), __FUNCTION__, __LINE__) -#define MY_ISOKSTMT(STMT, RETRY) myisokstmt((STMT), __FUNCTION__, __LINE__, (RETRY)) - -#define USE_TRANS(CTX) ((CTX->caps & GLITE_LBU_DB_CAP_TRANSACTIONS) != 0) - -#define dprintf(CTX, FMT...) if (CTX->caps & GLITE_LBU_DB_CAP_ERRORS) fprintf(stderr, ##FMT) - - -struct glite_lbu_DBContext_s { - MYSQL *mysql; - const char *cs; - int have_caps; - int caps; - struct { - int code; - char *desc; - } err; -}; - - -struct glite_lbu_Statement_s { - glite_lbu_DBContext ctx; - - /* for simple commands */ - MYSQL_RES *result; - - /* for prepared commands */ - MYSQL_STMT *stmt; - unsigned long nrfields; -}; - - -struct glite_lbu_bufInsert_s { - glite_lbu_DBContext ctx; - char *table_name; - char *columns; /* names of columns to be inserted into - * (values separated with commas) */ - char **rows; /* each row hold string of one row to be inserted - * (values separated with commas) */ - long rec_num, /* actual number of rows in structure */ - rec_size; /* approx. size of a real insert string */ - long size_limit, /* size and # of records limit which trigger */ - record_limit; /* real insert; zero means unlimitted */ -}; - - -/* - * mapping glite DB types to mysql types - */ -int glite_type_to_mysql[] = { - MYSQL_TYPE_NULL, - MYSQL_TYPE_TINY, - MYSQL_TYPE_LONG, - MYSQL_TYPE_TINY_BLOB, - MYSQL_TYPE_TINY_BLOB, - MYSQL_TYPE_BLOB, - MYSQL_TYPE_BLOB, - MYSQL_TYPE_MEDIUM_BLOB, - MYSQL_TYPE_MEDIUM_BLOB, - MYSQL_TYPE_LONG_BLOB, - MYSQL_TYPE_LONG_BLOB, - MYSQL_TYPE_VAR_STRING, - MYSQL_TYPE_STRING, - MYSQL_TYPE_DATE, - MYSQL_TYPE_TIME, - MYSQL_TYPE_DATETIME, - MYSQL_TYPE_TIMESTAMP, -}; - - - -static int lbu_clrerr(glite_lbu_DBContext ctx); -static int lbu_err(glite_lbu_DBContext ctx, int code, const char *desc, const char *func, int line); -static int myerr(glite_lbu_DBContext ctx, const char *source, int line); -static int myerrstmt(glite_lbu_Statement stmt, const char *source, int line); -static int myisokstmt(glite_lbu_Statement stmt, const char *source, int line, int *retry); -static int db_connect(glite_lbu_DBContext ctx, const char *cs, MYSQL **mysql); -static void db_close(MYSQL *mysql); -static int transaction_test(glite_lbu_DBContext ctx, MYSQL *m2, int *have_transactions); -static int FetchRowSimple(glite_lbu_DBContext ctx, MYSQL_RES *result, unsigned long *lengths, char **results); -static int FetchRowPrepared(glite_lbu_DBContext ctx, glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results); -void set_time(MYSQL_TIME *mtime, const time_t time); -time_t get_time(const MYSQL_TIME *mtime); - - -/* ---- common ---- */ - - -int glite_lbu_DBError(glite_lbu_DBContext ctx, char **text, char **desc) { - if (text) *text = strdup(strerror(ctx->err.code)); - if (desc) { - if (ctx->err.desc) *desc = strdup(ctx->err.desc); - else *desc = NULL; - } - - return ctx->err.code; -} - - -int glite_lbu_InitDBContext(glite_lbu_DBContext *ctx) { - *ctx = calloc(1, sizeof **ctx); - return *ctx == NULL ? ENOMEM : 0; -} - - -void glite_lbu_FreeDBContext(glite_lbu_DBContext ctx) { - if (ctx) { - assert(ctx->mysql == NULL); - free(ctx->err.desc); - free(ctx); - } -} - - -int glite_lbu_DBConnect(glite_lbu_DBContext ctx, const char *cs) { - if (db_connect(ctx, cs, &ctx->mysql) != 0) return STATUS(ctx); - return 0; -} - - -void glite_lbu_DBClose(glite_lbu_DBContext ctx) { - db_close(ctx->mysql); - ctx->mysql = NULL; -} - - -int glite_lbu_DBQueryCaps(glite_lbu_DBContext ctx) { - MYSQL *m = ctx->mysql; - MYSQL *m2; - int major,minor,sub,version,caps,have_transactions=0; - const char *ver_s; - - if (ctx->have_caps) return ctx->caps; - - caps = 0; - - ver_s = mysql_get_server_info(m); - if (!ver_s || 3 != sscanf(ver_s,"%d.%d.%d",&major,&minor,&sub)) - return ERR(ctx, EINVAL, "problem retreiving MySQL version"); - version = 10000*major + 100*minor + sub; - - if (version >= GLITE_LBU_MYSQL_INDEX_VERSION) caps |= GLITE_LBU_DB_CAP_INDEX; - if (version >= GLITE_LBU_MYSQL_PREPARED_VERSION) caps |= GLITE_LBU_DB_CAP_PREPARED; - - CLR_ERR(ctx); - - if (db_connect(ctx, ctx->cs, &m2) == 0) { - transaction_test(ctx, m2, &have_transactions); - db_close(m2); - } - if (have_transactions) caps |= GLITE_LBU_DB_CAP_TRANSACTIONS; - - if (STATUS(ctx) == 0) { - ctx->have_caps = 1; - return caps; - } else return -1; -} - - -void glite_lbu_DBSetCaps(glite_lbu_DBContext ctx, int caps) { - ctx->caps = caps; -} - - -int glite_lbu_Transaction(glite_lbu_DBContext ctx) { - if (USE_TRANS(ctx)) { - if (glite_lbu_ExecSQL(ctx, "SET AUTOCOMMIT=0", NULL) < 0) goto err; - if (glite_lbu_ExecSQL(ctx, "BEGIN", NULL) < 0) goto err; - } -err: - return STATUS(ctx); -} - - -int glite_lbu_Commit(glite_lbu_DBContext ctx) { - if (USE_TRANS(ctx)) { - if (glite_lbu_ExecSQL(ctx, "COMMIT", NULL) < 0) goto err; - if (glite_lbu_ExecSQL(ctx, "SET AUTOCOMMIT=1", NULL) < 0) goto err; - } -err: - return STATUS(ctx); -} - - -int glite_lbu_Rollback(glite_lbu_DBContext ctx) { - if (USE_TRANS(ctx)) { - if (glite_lbu_ExecSQL(ctx, "ROLLBACK", NULL) < 0) goto err; - if (glite_lbu_ExecSQL(ctx, "SET AUTOCOMMIT=1", NULL) < 0) goto err; - } -err: - return STATUS(ctx); -} - - -int glite_lbu_FetchRow(glite_lbu_Statement stmt, unsigned int n, unsigned long *lengths, char **results) { - memset(results, 0, n * sizeof(*results)); - if (stmt->result) return FetchRowSimple(stmt->ctx, stmt->result, lengths, results); - else return FetchRowPrepared(stmt->ctx, stmt, n, lengths, results); -} - - -void glite_lbu_FreeStmt(glite_lbu_Statement *stmt) { - if (*stmt) { - if ((*stmt)->result) mysql_free_result((*stmt)->result); - if ((*stmt)->stmt) mysql_stmt_close((*stmt)->stmt); - free(*stmt); - *stmt = NULL; - } -} - - -int glite_lbu_QueryIndices(glite_lbu_DBContext ctx, const char *table, char ***key_names, char ****column_names) { - glite_lbu_Statement stmt = NULL; - - int i,j,ret; - -/* XXX: "show index from" columns. Matches at least MySQL 4.0.11 */ - char *showcol[12]; - int Key_name,Seq_in_index,Column_name,Sub_part; - - char **keys = NULL; - int *cols = NULL; - char **col_names = NULL; - - int nkeys = 0; - - char ***idx = NULL; - - Key_name = Seq_in_index = Column_name = Sub_part = -1; - - if (glite_lbu_ExecSQL(ctx,"show index from states",&stmt)<0) - return STATUS(ctx); - - while ((ret = glite_lbu_FetchRow(stmt,sizeof(showcol)/sizeof(showcol[0]),NULL,showcol)) > 0) { - assert(ret <= sizeof showcol/sizeof showcol[0]); - - if (!col_names) { - col_names = malloc(ret * sizeof col_names[0]); - glite_lbu_QueryColumns(stmt,col_names); - for (i=0; i= 0 && Seq_in_index >= 0 && - Column_name >= 0 && Sub_part >= 0); - - } - - for (i=0; imysql, cmd)) { - /* error occured */ - switch (merr = mysql_errno(ctx->mysql)) { - case 0: - break; - case ER_DUP_ENTRY: - ERR(ctx, EEXIST, mysql_error(ctx->mysql)); - return -1; - break; - case CR_SERVER_LOST: - if (retry_nr <= 0) - do_reconnect = 1; - break; - default: - MY_ERR(ctx); - return -1; - break; - } - } - retry_nr++; - } - - if (stmt) { - *stmt = calloc(1, sizeof(**stmt)); - if (!*stmt) { - ERR(ctx, ENOMEM, NULL); - return -1; - } - (**stmt).ctx = ctx; - (**stmt).result = mysql_store_result(ctx->mysql); - if (!(**stmt).result) { - if (mysql_errno(ctx->mysql)) { - MY_ERR(ctx); - *stmt = NULL; - return -1; - } - } - } else { - MYSQL_RES *r = mysql_store_result(ctx->mysql); - mysql_free_result(r); - } -#ifdef LBS_DB_PROFILE - pid = getpid(); - gettimeofday(&end,NULL); - end.tv_usec -= start.tv_usec; - end.tv_sec -= start.tv_sec; - if (end.tv_usec < 0) { end.tv_sec--; end.tv_usec += 1000000; } - - sum.tv_usec += end.tv_usec; - sum.tv_sec += end.tv_sec + sum.tv_usec / 1000000; - sum.tv_usec -= 1000000 * (sum.tv_usec / 1000000); - fprintf(stderr,"[%d] %s\n[%d] %3ld.%06ld (sum: %3ld.%06ld)\n",pid,txt,pid,end.tv_sec,end.tv_usec,sum.tv_sec,sum.tv_usec); -#endif - - return mysql_affected_rows(ctx->mysql); -} - - -int glite_lbu_QueryColumns(glite_lbu_Statement stmt, char **cols) -{ - int i = 0; - MYSQL_FIELD *f; - - if (!stmt->result) return ERR(stmt->ctx, EINVAL, "QueryColumns implemented only for simple API"); - while ((f = mysql_fetch_field(stmt->result))) cols[i++] = f->name; - return i == 0; -} - - -void glite_lbu_TimeToDB(time_t t, char **str) { - struct tm *tm = gmtime(&t); - - asprintf(str,"'%4d-%02d-%02d %02d:%02d:%02d'",tm->tm_year+1900,tm->tm_mon+1, - tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec); -} - - -time_t glite_lbu_DBToTime(const char *str) { - struct tm tm; - - memset(&tm,0,sizeof(tm)); - setenv("TZ","UTC",1); tzset(); - sscanf(str,"%4d-%02d-%02d %02d:%02d:%02d", - &tm.tm_year,&tm.tm_mon,&tm.tm_mday, - &tm.tm_hour,&tm.tm_min,&tm.tm_sec); - tm.tm_year -= 1900; - tm.tm_mon--; - - return mktime(&tm); -} - -/* ---- prepared --- */ - -int glite_lbu_PrepareStmt(glite_lbu_DBContext ctx, const char *sql, glite_lbu_Statement *stmt) { - int ret, retry; - MYSQL_RES *meta; - - // init - *stmt = calloc(1, sizeof(**stmt)); - (*stmt)->ctx = ctx; - - // create the SQL command - if (((*stmt)->stmt = mysql_stmt_init(ctx->mysql)) == NULL) - return MY_ERRSTMT(*stmt); - - // prepare the SQL command - retry = 1; - do { - mysql_stmt_prepare((*stmt)->stmt, sql, strlen(sql)); - ret = MY_ISOKSTMT(*stmt, &retry); - } while (ret == 0); - if (ret == -1) goto failed; - - // number of fields (0 for no results) - if ((meta = mysql_stmt_result_metadata((*stmt)->stmt)) != NULL) { - (*stmt)->nrfields = mysql_num_fields(meta); - mysql_free_result(meta); - } else - (*stmt)->nrfields = 0; - - return CLR_ERR(ctx); - -failed: - glite_lbu_FreeStmt(stmt); - return STATUS(ctx); -} - - -int glite_lbu_ExecStmt(glite_lbu_Statement stmt, int n, ...) { - int i; - va_list ap; - glite_lbu_DBType type; - char *pchar; - long int *plint; - MYSQL_TIME *ptime; - glite_lbu_DBContext ctx; - int ret, retry; - MYSQL_BIND *binds = NULL; - void **data = NULL; - unsigned long *lens; - - // gather parameters - if (n) { - binds = calloc(n, sizeof(MYSQL_BIND)); - data = calloc(n, sizeof(void *)); - lens = calloc(n, sizeof(unsigned long *)); - } - va_start(ap, n); - for (i = 0; i < n; i++) { - type = va_arg(ap, glite_lbu_DBType); - switch (type) { - case GLITE_LBU_DB_TYPE_TINYINT: - pchar = binds[i].buffer = data[i] = malloc(sizeof(char)); - *pchar = va_arg(ap, int); - break; - - case GLITE_LBU_DB_TYPE_INT: - plint = binds[i].buffer = data[i] = malloc(sizeof(long int)); - *plint = va_arg(ap, long int); - break; - - case GLITE_LBU_DB_TYPE_TINYBLOB: - case GLITE_LBU_DB_TYPE_TINYTEXT: - case GLITE_LBU_DB_TYPE_BLOB: - case GLITE_LBU_DB_TYPE_TEXT: - case GLITE_LBU_DB_TYPE_MEDIUMBLOB: - case GLITE_LBU_DB_TYPE_MEDIUMTEXT: - case GLITE_LBU_DB_TYPE_LONGBLOB: - case GLITE_LBU_DB_TYPE_LONGTEXT: - binds[i].buffer = va_arg(ap, void *); - binds[i].length = &lens[i]; - lens[i] = va_arg(ap, unsigned long); - break; - - case GLITE_LBU_DB_TYPE_VARCHAR: - case GLITE_LBU_DB_TYPE_CHAR: - binds[i].buffer = va_arg(ap, char *); - binds[i].length = &lens[i]; - lens[i] = binds[i].buffer ? strlen((char *)binds[i].buffer) : 0; - break; - - case GLITE_LBU_DB_TYPE_DATE: - case GLITE_LBU_DB_TYPE_TIME: - case GLITE_LBU_DB_TYPE_DATETIME: - case GLITE_LBU_DB_TYPE_TIMESTAMP: - ptime = binds[i].buffer = data[i] = malloc(sizeof(MYSQL_TIME)); - set_time(ptime, va_arg(ap, time_t)); - break; - - case GLITE_LBU_DB_TYPE_NULL: - break; - - default: - assert("unimplemented parameter assign" == NULL); - break; - } - binds[i].buffer_type = glite_type_to_mysql[type]; - } - va_end(ap); - - // bind parameters - if (mysql_stmt_bind_param(stmt->stmt, binds) != 0) { - MY_ERRSTMT(stmt); - goto failed; - } - - // run - ctx = stmt->ctx; - retry = 1; - do { - mysql_stmt_execute(stmt->stmt); - ret = MY_ISOKSTMT(stmt, &retry); - } while (ret == 0); - if (ret == -1) goto failed; - - // result - retry = 1; - do { - mysql_stmt_store_result(stmt->stmt); - ret = MY_ISOKSTMT(stmt, &retry); - } while (ret == 0); - if (ret == -1) goto failed; - - // free params - for (i = 0; i < n; i++) free(data[i]); - free(data); - free(binds); - free(lens); - CLR_ERR(ctx); - return mysql_stmt_affected_rows(stmt->stmt); - -failed: - for (i = 0; i < n; i++) free(data[i]); - free(data); - free(binds); - free(lens); - return -1; -} - - -int glite_lbu_bufferedInsertInit(glite_lbu_DBContext ctx, glite_lbu_bufInsert *bi, void *mysql, const char *table_name, long size_limit, long record_limit, const char *columns) -{ - *bi = calloc(1, sizeof(*bi)); - (*bi)->ctx = ctx; - (*bi)->table_name = strdup(table_name); - (*bi)->columns = strdup(columns); - (*bi)->rec_num = 0; - (*bi)->rec_size = 0; - (*bi)->rows = calloc(record_limit, sizeof(*((*bi)->rows)) ); - (*bi)->size_limit = size_limit; - (*bi)->record_limit = record_limit; - - return CLR_ERR(ctx); -} - - -static int flush_bufferd_insert(glite_lbu_bufInsert bi) -{ - char *stmt, *vals, *temp; - long i; - - - if (!bi->rec_num) - return STATUS(bi->ctx); - - asprintf(&vals,"(%s)", bi->rows[0]); - for (i=1; i < bi->rec_num; i++) { - // XXX: use string add (preallocated memory) - asprintf(&temp,"%s,(%s)", vals, bi->rows[i]); - free(vals); vals = temp; temp = NULL; - free(bi->rows[i]); - bi->rows[i] = NULL; - } - - trio_asprintf(&stmt, "insert into %|Ss(%|Ss) values %s;", - bi->table_name, bi->columns, vals); - - if (glite_lbu_ExecSQL(bi->ctx,stmt,NULL) < 0) { - if (STATUS(bi->ctx) == EEXIST) - CLR_ERR(bi->ctx); - } - - /* reset bi counters */ - bi->rec_size = 0; - bi->rec_num = 0; - - free(vals); - free(stmt); - - return STATUS(bi->ctx); -} - - -int glite_lbu_bufferedInsert(glite_lbu_bufInsert bi, const char *row) -{ - bi->rows[bi->rec_num++] = strdup(row); - bi->rec_size += strlen(row); - - if ((bi->size_limit && bi->rec_size >= bi->size_limit) || - (bi->record_limit && bi->rec_num >= bi->record_limit)) - { - if (flush_bufferd_insert(bi)) - return STATUS(bi->ctx); - } - - return CLR_ERR(bi->ctx); -} - - -static void free_buffered_insert(glite_lbu_bufInsert bi) { - long i; - - free(bi->table_name); - free(bi->columns); - for (i=0; i < bi->rec_num; i++) { - free(bi->rows[i]); - } - free(bi->rows); -} - - -int glite_lbu_bufferedInsertClose(glite_lbu_bufInsert bi) -{ - if (flush_bufferd_insert(bi)) - return STATUS(bi->ctx); - free_buffered_insert(bi); - - return CLR_ERR(bi->ctx); -} - - -/* - * helping compatibility function: clear error from the context - */ -static int lbu_clrerr(glite_lbu_DBContext ctx) { - ctx->err.code = 0; - if (ctx->err.desc) { - free(ctx->err.desc); - ctx->err.desc = NULL; - } - return 0; -} - - -/* - * helping compatibility function: sets error on the context - */ -static int lbu_err(glite_lbu_DBContext ctx, int code, const char *desc, const char *func, int line) { - if (code) { - ctx->err.code = code; - free(ctx->err.desc); - ctx->err.desc = desc ? strdup(desc) : NULL; - dprintf(ctx, "[db %d] %s:%d %s\n", getpid(), func, line, desc); - return code; - } else - return ctx->err.code; -} - - -/* - * helping function: find oud mysql error and sets on the context - */ -static int myerr(glite_lbu_DBContext ctx, const char *source, int line) { - return lbu_err(ctx, EIO, mysql_error(ctx->mysql), source, line); -} - - -/* - * helping function: find oud mysql stmt error and sets on the context - */ -static int myerrstmt(glite_lbu_Statement stmt, const char *source, int line) { - return lbu_err(stmt->ctx, EIO, mysql_stmt_error(stmt->stmt), source, line); -} - - -/* - * Ehelping function: error handle - * - * \return -1 failed - * \return 0 retry - * \return 1 OK - */ -static int myisokstmt(glite_lbu_Statement stmt, const char *source, int line, int *retry) { - switch (mysql_stmt_errno(stmt->stmt)) { - case 0: - return 1; - break; - case ER_DUP_ENTRY: - lbu_err(stmt->ctx, EEXIST, mysql_stmt_error(stmt->stmt), source, line); - return -1; - break; - case CR_SERVER_LOST: - if (*retry > 0) { - (*retry)--; - return 0; - } else - return -1; - break; - default: - myerrstmt(stmt, source, line); - return -1; - break; - } -} - - -/* - * mysql connect - */ -static int db_connect(glite_lbu_DBContext ctx, const char *cs, MYSQL **mysql) { - char *buf = NULL; - char *host,*user,*pw,*db; - char *slash,*at,*colon; - int ret; - - // needed for SQL result parameters - assert(sizeof(int) >= sizeof(my_bool)); - - if (!cs) return ERR(ctx, EINVAL, "connect string not specified"); - - if (!(*mysql = mysql_init(NULL))) return ERR(ctx, ENOMEM, NULL); - - mysql_options(*mysql, MYSQL_READ_DEFAULT_FILE, "my"); - - host = user = pw = db = NULL; - - buf = strdup(cs); - slash = strchr(buf,'/'); - at = strrchr(buf,'@'); - colon = strrchr(buf,':'); - - if (!slash || !at || !colon) { - free(buf); - db_close(*mysql); - *mysql = NULL; - return ERR(ctx, EINVAL, "Invalid DB connect string"); - } - - *slash = *at = *colon = 0; - host = at+1; - user = buf; - pw = slash+1; - db = colon+1; - - /* ljocha: CLIENT_FOUND_ROWS added to make authorization check - * working in update_notif(). - * Hope it does not break anything else */ - if (!mysql_real_connect(*mysql,host,user,pw,db,0,NULL,CLIENT_FOUND_ROWS)) { - free(buf); - ret = MY_ERR(ctx); - glite_lbu_DBClose(ctx); - return ret; - } - free(buf); - - ctx->cs = cs; - return 0; -} - - -/* - * mysql close - */ -static void db_close(MYSQL *mysql) { - if (mysql) mysql_close(mysql); -} - - -/* - * test transactions capability: - * - * 1) with connection 1 create testing table test - * 2) with connection 1 insert a value - * 3) with connection 2 look for a value, transactions are for no error and - * no items found - * 4) with connection 1 commit and drop the table - */ -static int transaction_test(glite_lbu_DBContext ctx, MYSQL *m2, int *have_transactions) { - MYSQL *m1; - char *desc, *cmd_create, *cmd_insert, *cmd_select, *cmd_drop; - int retval; - int err; - pid_t pid; - - ctx->caps |= GLITE_LBU_DB_CAP_TRANSACTIONS; - pid = getpid(); - *have_transactions = 0; - - asprintf(&cmd_create, "CREATE TABLE test%d (item INT) ENGINE='innodb'", pid); - asprintf(&cmd_insert, "INSERT INTO test%d (item) VALUES (1)", pid); - asprintf(&cmd_select, "SELECT item FROM test%d", pid); - asprintf(&cmd_drop, "DROP TABLE test%d", pid); - - m1 = ctx->mysql; - //glite_lbu_ExecSQL(ctx, cmd_drop, NULL); - if (glite_lbu_ExecSQL(ctx, cmd_create, NULL) != 0) goto err1; - if (glite_lbu_Transaction(ctx) != 0) goto err2; - if (glite_lbu_ExecSQL(ctx, cmd_insert, NULL) != 1) goto err2; - - ctx->mysql = m2; - if ((retval = glite_lbu_ExecSQL(ctx, cmd_select, NULL)) == -1) goto err2; - - ctx->mysql = m1; - if (glite_lbu_Commit(ctx) != 0) goto err2; - if (glite_lbu_ExecSQL(ctx, cmd_drop, NULL) != 0) goto err1; - -#ifdef LBS_DB_PROFILE - fprintf(stderr, "[%d] use_transactions = %d\n", getpid(), USE_TRANS(ctx)); -#endif - - *have_transactions = retval == 0; - goto ok; -err2: - err = ctx->err.code; - desc = ctx->err.desc; - glite_lbu_ExecSQL(ctx, cmd_drop, NULL); - ctx->err.code = err; - ctx->err.desc = desc; -err1: -ok: - free(cmd_create); - free(cmd_insert); - free(cmd_select); - free(cmd_drop); - return STATUS(ctx); -} - - -/* - * simple version of the fetch - */ -static int FetchRowSimple(glite_lbu_DBContext ctx, MYSQL_RES *result, unsigned long *lengths, char **results) { - MYSQL_ROW row; - int nr, i; - unsigned long *len; - - CLR_ERR(ctx); - - if (!(row = mysql_fetch_row(result))) { - if (mysql_errno((MYSQL *) ctx->mysql)) { - MY_ERR(ctx); - return -1; - } else return 0; - } - - nr = mysql_num_fields(result); - len = mysql_fetch_lengths(result); - for (i=0; inrfields) { - ERR(ctx, EINVAL, "bad number of result fields"); - return -1; - } - - // space for results - if (n) binds = calloc(n, sizeof(MYSQL_BIND)); - if (!lengths) { - lens = calloc(n, sizeof(unsigned long)); - lengths = lens; - } - for (i = 0; i < n; i++) { - binds[i].buffer_type = MYSQL_TYPE_VAR_STRING; - binds[i].buffer_length = GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH - 1; - binds[i].length = &lengths[i]; - binds[i].buffer = results[i] = calloc(1, GLITE_LBU_DEFAULT_RESULT_BUFFER_LENGTH); - } - if (mysql_stmt_bind_result(stmt->stmt, binds) != 0) goto failedstmt; - - // fetch data, all can be truncated - retry = 1; - do { - switch(mysql_stmt_fetch(stmt->stmt)) { -#ifdef MYSQL_DATA_TRUNCATED - case MYSQL_DATA_TRUNCATED: -#endif - case 0: - ret = 1; break; - case 1: ret = MY_ISOKSTMT(stmt, &retry); break; - case MYSQL_NO_DATA: ret = 0; goto quit; /* it's OK */ - default: ERR(ctx, EIO, "other fetch error"); goto failed; - } - } while (ret == 0); - if (ret == -1) goto failed; - - // check if all fileds had enough buffer space - for (i = 0; i < n; i++) { - // fetch the rest if needed - if (lengths[i] > binds[i].buffer_length) { - unsigned int fetched; - - fetched = binds[i].buffer_length; - if ((results[i] = realloc(results[i], lengths[i] + 1)) == NULL) { - ERR(ctx, ENOMEM, "insufficient memory for field data"); - goto failed; - } - results[i][lengths[i]] = '\000'; - binds[i].buffer = results[i] + fetched; - binds[i].buffer_length = lengths[i] - fetched; - - retry = 1; - do { - switch (mysql_stmt_fetch_column(stmt->stmt, binds + i, i, fetched)) { - case 0: ret = 1; break; - case 1: ret = MY_ISOKSTMT(stmt, &retry); break; - case MYSQL_NO_DATA: ret = 0; goto quit; /* it's OK */ - default: ERR(ctx, EIO, "other fetch error"); goto failed; - } - } while (ret == 0); - if (ret == -1) goto failed; - } - } - - CLR_ERR(ctx); - free(binds); - free(lens); - return n; - -failedstmt: - MY_ERRSTMT(stmt); -failed: - ret = -1; -quit: - free(binds); - free(lens); - for (i = 0; i < n; i++) { - free(results[i]); - results[i] = NULL; - } - return ret; -} - - -void set_time(MYSQL_TIME *mtime, const time_t time) { - struct tm tm; - - gmtime_r(&time, &tm); - memset(mtime, 0, sizeof *mtime); - mtime->year = tm.tm_year + 1900; - mtime->month = tm.tm_mon + 1; - mtime->day = tm.tm_mday; - mtime->hour = tm.tm_hour; - mtime->minute = tm.tm_min; - mtime->second = tm.tm_sec; -} - - -time_t get_time(const MYSQL_TIME *mtime) { - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - setenv("TZ","UTC",1); tzset(); - tm.tm_year = mtime->year - 1900; - tm.tm_mon = mtime->month - 1; - tm.tm_mday = mtime->day; - tm.tm_hour = mtime->hour; - tm.tm_min = mtime->minute; - tm.tm_sec = mtime->second; - - return mktime(&tm); -} diff --git a/org.glite.lb-utils.jobid/.cvsignore b/org.glite.lb-utils.jobid/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.lb-utils.jobid/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.lb-utils.jobid/LICENSE b/org.glite.lb-utils.jobid/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.lb-utils.jobid/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils.jobid/Makefile b/org.glite.lb-utils.jobid/Makefile deleted file mode 100644 index 986b5e0..0000000 --- a/org.glite.lb-utils.jobid/Makefile +++ /dev/null @@ -1,98 +0,0 @@ -# Default values -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -package=glite-lb-utils-jobid -version=0.0.0 -PREFIX=/opt/glite -lbuprefix=lbu - --include Makefile.inc --include ../project/version.properties - -version=${module.version} - -VPATH=${top_srcdir}/src:${top_srcdir}/test::${top_srcdir}/doc - -CC=gcc - -DEBUG:=-g -O0 -Wall - -CFLAGS:=${DEBUG} -I${top_srcdir}/src -I${top_srcdir}/interface -I. -D_GNU_SOURCE - -COMPILE:=libtool --mode=compile ${CC} -LINK:=libtool --mode=link ${CC} -rpath ${stagedir}/lib ${LDFLAGS} -INSTALL:=libtool --mode=install install - -OBJS:=cjobid.o strmd5.o -LOBJS:=${OBJS:.o=.lo} - -HDRS:=cjobid.h strmd5.h Exception.h JobId.h JobIdExceptions.h - -STATICLIB:=libglite_lbu_jobid.a -LTLIB:=libglite_lbu_jobid.la - -default: all - -all compile: ${STATICLIB} ${LTLIB} - -# to use libtool versioning correcty, we should have: -# -# current = major + minor + offset -# revision = patch -# age = minor -# -# where offset is a sum of maximal released minor's of all previous major's -# -# version_info=-version-info `echo ${version} | cut -d. -f1,2 | tr . :` - -# counted minors: n/a -offset=0 - -version_info:=-version-info ${shell \ - perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } - -${STATICLIB}: ${OBJS} - ar crv $@ ${OBJS} - ranlib $@ - -${LTLIB}: ${OBJS} - ${LINK} ${version_info} -o $@ ${LOBJS} - -stage: compile - $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes - -check: - @true - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -install: - mkdir -p ${PREFIX}/lib - mkdir -p ${PREFIX}/share/doc/${package}-${version} - ${INSTALL} -m 644 ${LTLIB} ${PREFIX}/lib - ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - if [ x${DOSTAGE} = xyes ]; then \ - mkdir -p ${PREFIX}/include/${globalprefix}/${lbuprefix} ; \ - (cd ${top_srcdir}/interface && install -m 644 ${HDRS} ${PREFIX}/include/${globalprefix}/${lbuprefix}) ; \ - install -m 644 ${STATICLIB} ${PREFIX}/lib; \ - fi - -clean: - -%.o: %.c - ${COMPILE} ${CFLAGS} -c $< diff --git a/org.glite.lb-utils.jobid/build.xml b/org.glite.lb-utils.jobid/build.xml deleted file mode 100644 index e6cc422..0000000 --- a/org.glite.lb-utils.jobid/build.xml +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.jobid/interface/Exception.h b/org.glite.lb-utils.jobid/interface/Exception.h deleted file mode 100644 index 21a9064..0000000 --- a/org.glite.lb-utils.jobid/interface/Exception.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef GLITE_WMS_UTILS_EXCEPTION_EXCEPTION_H -#define GLITE_WMS_UTILS_EXCEPTION_EXCEPTION_H - -/* - * Exception.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - * Contributors are mentioned in the code where appropriate. - */ - -#include -#include -//#include -#include // For logging exceptions to log file -#include // list the exception codes -#include -#include -#include // base ancestor stl::exception - - -namespace glite { - namespace lb_utils { - namespace exception { - -extern pthread_mutex_t METHOD_MUTEX; // used in order to store info into a file (rather then syslog) -#define GLITE_STACK_TRY(method_name) std::string METHOD = method_name ; int LINE = __LINE__ ; try { -#define GLITE_STACK_CATCH() } catch (glite::lb_utils::exception::Exception &exc){ exc.push_back ( __FILE__ , LINE, METHOD ); throw exc ; } catch (std::exception &ex){ glite::lb_utils::exception::Exception exc( __FILE__ , LINE, METHOD, 0, "Standard exception: " + std::string(ex.what()) ); throw exc; } - -/** - * The Exception base classe contains attributes into which are placed exception information and provides - * constructor that beyond the error code take parameters specifying the source file and line number - * (e.g. through __FILE__ and __LINE__) where the error has been generated and string messages, - * allowing an easy way of storing the origin of the exception. - * Moreover it provides methods for getting all the exception information and for logging them either - * in a log file or to the syslog daemon. - * Each of the derived types may contain its private attributes describing the actual error instance in detail. - * Moreover each exception has an attribute representing the exception identifier that is set by the - * class constructor and allows the identification of the original exception. - * - * @version 0.1 - * @date 22 July 2004 - * @author Alessandro Maraschini -*/ - -class Exception : public std::exception{ - public: - /** - * Constructor Update all mandatory fields - * @param method the name of the method that raised the exception - * @param source The source that raised the exception (could be the file path, the class Name, etc etc) - * @param exc the previous exception as in the stack trace */ - Exception ( const std::string& source, const std::string& method, Exception *exc); - /** - * Constructor Update all mandatory fields - * @param code the code representing the thrown exception - * @param exception the name of the thrown exception - * @param method the name of the method that raised the exception - * @param source The source that raised the exception (could be the file path, the class Name, etc etc) */ - Exception ( const std::string& source, const std::string& method, int code, const std::string& exception); - - /** - * Constructor Update all mandatory fields - * @param source the path of the file that raised the exception - * @param line_number the number of the line in the file that raised the exception - * @param method the name of the method that raised the exception - * @param code the code representing the thrown exception - * @param exception the name of the thrown exception */ - Exception (const std::string& source, int line_number, const std::string& method, int code, const std::string& exception); - /** - * Default Destructor - */ - virtual ~Exception() throw (); - /** - * Return a string debug message containing information about Exception thrown - * Debug message contains all the attributes stored in an exception instance such as the method, the file and the line - * that threw the exception. - *@return the debug message string representation - */ - virtual std::string dbgMessage(); - /** - * Return the error code - * @return The integer representing the code of the error that generated the exception - */ - virtual int getCode(); - - /** - * return the Error Message associated to the Exception - * @return The Exception string message representation - */ - virtual const char* what() const throw (); - - /** - * Print Exception error information into a log file - * @param logfile the file where to log exception information - */ - virtual void log(const std::string& logfile = ""); - /** - * Retrieve the Exception name - * @return the name of the Exception thrown - */ - virtual std::string getExceptionName(); - - /** - * Retrieve the Stack of the exception as a list of previous generated exceptions - *@return the string representation of the stack trace: each line correspond to an exception message - */ - virtual std::string printStackTrace() ; - /** - * Return the list of methods that caused the Exception - */ - virtual std::vector getStackTrace() ; - /** - * Update stack information - */ - virtual void push_back ( const std::string& source, int line_number, const std::string& method ) ; - protected: - /** Empty constructor*/ - Exception(); - /** integer error code representing the cause of the error */ - int error_code; - /** string exception message representation*/ - std::string error_message ; - /** line number where the exception was raised */ - int line; - /** The name of the file where the exception was raised */ - std::string source_file; - /** the name of the exception */ - std::string exception_name; - /** the name of the method where the expceiton was raised */ - std::string method_name ; - /** a string representation of the stacktrace */ - std::string stack; - /** the actual internal stacktrace representation */ - std::vector< std::string> stack_strings ; - /** the name of the ancestor exception */ - std::string ancestor ; -}; //End Exception Class -}}} // Closing namespace -#endif diff --git a/org.glite.lb-utils.jobid/interface/JobId.h b/org.glite.lb-utils.jobid/interface/JobId.h deleted file mode 100644 index b99992d..0000000 --- a/org.glite.lb-utils.jobid/interface/JobId.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_JOBID_H -#define GLITE_WMSUTILS_JOBID_JOBID_H - -/* - * JobId.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - * - */ - -#include -#include - -#include "glite/lb-utils/cjobid.h" - -typedef struct _glite_lbu_jobid_s* glite_lbu_jobid_t; - -namespace glite { -namespace lb_utils { -namespace jobid { - -/** - * Managing Identification, checking, retreiving info from a job - * File name: JobId.h - * The JobId class provides a representation of the Datagrid job identifier - * (dg_jobId) and the methods for manipulating it. - * We remind that the format of the dg_jobId is as follows: - * :/ - * - * @ingroup common - * @version 0.1 - * @date 15 April 2002 - * @author Alessandro Maraschini */ - -class JobId { -public: - /**@name Constructors/Destructor */ - //@{ - /** Instantiates an empty JobId object */ - JobId() ; - /** - * Instantiates a JobId object from the passed dg_jobId in string format. - * @param job_id_string a string representig a classAd expression - * @throws WrongIdException When a string is passed in a wrong format - */ - JobId(const std::string& job_id_string); - JobId(const JobId&); - JobId(const glite_lbu_JobId&); - /** - * Destructor - * Destroy the Job Id instance - */ - ~JobId() ; - //@} - - /**@name Miscellaneous */ - //@{ - /** Unsets the JobId instance. Clear all it's memebers */ - void clear() ; - /** - * Check wheater the jobId has been already created (true) or not (false) - *@return true (jobId created) or false (jobId not yet created) - */ - bool isSet() { return ( m_JobId != 0 ) ; } - /** - * Set the JobId instance according to the LB and RB server addresses and the unique string passed as input parameters. - * @param lb_server Loggin and Bookkeeping server address - * @param port Loggin and Bookkeeping port ( dafault value is 9000 ) - * @param unique A Unique identification ( automatically generatad by md5 protocol ) - * @throws WrongIdException When one parameter has been passed in a wrong format */ - void setJobId(const std::string& lb_server, int port = 0, const std::string& unique = ""); - //@} - /**@name Get Methods */ - //@{ - /** @return the LB address into its string format - * @throws EmptyIdException If the jobId has not been initialised yet */ - std::string getServer() const; - /** @return the Unique string into its string format - * @throws EmptyIdException If the jobId has not been initialised yet */ - std::string getUnique() const; - //@} - /** This method sets the JobId instance from the JobId in string format given - * as input. - * @param dg_JobId the string representing the job - * @throws WrongIdException When a string is passed in a wrong format */ - void fromString ( const std::string& dg_JobId ); - /** Converts the jobId into a string - @return the string representation of a JobId*/ - std::string toString() const; - /** casting operator */ - operator const glite_lbu_JobId() const { return m_JobId; } - /** Operator "=" create a deep copy of the JobId instance*/ - JobId & operator=(JobId const &); - /** Operator "=" create a deep copy of the JobId instance*/ - JobId & operator=(const glite_lbu_JobId &); - /** Retrieve the internal id reference - *@return the JobId internal reference used by some LB methods */ - glite_lbu_JobId getId() const ; -private: - // This Variable stores the Job unique identification String - glite_lbu_JobId m_JobId; - mutable char* m_pStr; - mutable char* m_pBkserver; - mutable char* m_pUnique; - /** Operator "<"*/ - friend bool operator<(JobId const& lhs, JobId const& rhs); - /** Operator "=="*/ - friend bool operator==(JobId const& lhs, JobId const& rhs); -}; - -inline bool operator<(JobId const& lhs, JobId const& rhs) -{ - return strcmp ( lhs.m_pStr , rhs.m_pStr ) <0 ; -} - -inline bool operator==(JobId const& lhs, JobId const& rhs) -{ -return strcmp ( lhs.m_pStr , rhs.m_pStr ) ==0 ; -} - -std::ostream& operator<<(std::ostream& os, JobId const& id); - -} // namespace jobid -} // namespace lb_utils -} // namespace glite - -#endif // GLITE_WMSUTILS_JOBID_JOBID_H diff --git a/org.glite.lb-utils.jobid/interface/JobIdExceptions.h b/org.glite.lb-utils.jobid/interface/JobIdExceptions.h deleted file mode 100644 index d154adf..0000000 --- a/org.glite.lb-utils.jobid/interface/JobIdExceptions.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_EXCEPTIONS_H -#define GLITE_WMSUTILS_JOBID_EXCEPTIONS_H - -/* - * JobIdExceptions.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - */ - -#include "glite/lb-utils/Exception.h" - -namespace glite { -namespace lb_utils { -namespace jobid { - -/** - * JobIdException - Exception thrown by JobId Class - * @ingroup Common - * @version 0.1 - * @date 15 April 2002 - * @author Alessandro Maraschini -*/ - -class JobIdException : public glite::lb_utils::exception::Exception { -public: - /** - * Update all mandatory Exception Information - */ - JobIdException (const std::string& file, - int line, - const std::string& method, - int code, - const std::string& exception_name) ; -};//End CLass JobIdException - -/** -* WrongIdFieldException -* This Exception is thrown when a Job Id syntax error is found -* A valid Job Identification string should be made as follows: -* :/ */ -class WrongIdException : public JobIdException { -public: - /** - * Constructor - * @param file - The source file which has generated the Exception - * @param line - The line number in the source file where the Exception has been thrown - * @param method - The Name of the method which has thrown the Exception - * @param code - The Code of the Error raised - * @param field - The wrong expression catched */ - WrongIdException(const std::string& file, - int line, - const std::string& method, - int code ); -}; //End CLass WrongIdException -/** -* EmptyIdException -* This Exception is thrown when the user tries to get information from a JobId -* which has not been initialized yet, i.e tries to use the get Methods -*/ -class EmptyIdException : public JobIdException { -public: - /** - * Constructor - * @param file - The source file which has generated the Exception - * @param line - The line number in the source file where the Exception has been thrown - * @param method - The Name of the method which has thrown the Exception - * @param code - The Code of the Error raised - * @param field - The Empty filed requested for */ - EmptyIdException::EmptyIdException(const std::string& file, - int line, - const std::string& method, - int code , - const std::string& field ); -}; //End CLass EmptyIdException - -} // namespace jobid -} // namespace lb_utils -} // namespace glite - -#endif // GLITE_WMSUTILS_JOBID_EXCEPTIONS_H - diff --git a/org.glite.lb-utils.jobid/interface/cjobid.h b/org.glite.lb-utils.jobid/interface/cjobid.h deleted file mode 100755 index f802ce7..0000000 --- a/org.glite.lb-utils.jobid/interface/cjobid.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef _GLITE_JOBID_H -#define _GLITE_JOBID_H - -/*! - * \file cjobid.h - * \brief L&B consumer API - */ - -#ident "$Header$" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _glite_lbu_JobId *glite_lbu_JobId; - -#define GLITE_WMSC_JOBID_DEFAULT_PORT 9000 /**< Default port where bookkeeping server listens */ -#define GLITE_WMSC_JOBID_PROTO_PREFIX "https://" /**< JobId protocol prefix */ - - -/* All the pointer functions return malloc'ed objects (or NULL on error) */ - -/** - * Create a Job ID. - * See the lb_draft document for details on its construction and components - * \param bkserver book keeping server hostname - * \param port port for the bk service - * \param jobid new created job id - * \ret al 0 success - * \retval EINVAL invalid bkserver - * \retval ENOMEM if memory allocation fails - */ -int glite_lbu_JobIdCreate(const char * bkserver, int port, glite_lbu_JobId * jobid); - -/** - * Recreate a Job ID - * \param bkserver bookkeeping server hostname - * \param port port for the bk service - * \param unique string which represent created jobid (if NULL then new - * one is created) - * \param jobid new created job id - * \retval 0 success - * \retval EINVAL invalid bkserver - * \retval ENOMEM if memory allocation fails - */ -int glite_lbu_JobIdRecreate(const char *bkserver, int port, const char * unique, glite_lbu_JobId * jobid); - -/** - * Create copy of Job ID - * \param in jobid for duplication - * \param jobid duplicated jobid - * \retval 0 for success - * \retval EINVAL invalid jobid - * \retval ENOMEM if memory allocation fails - */ -int glite_lbu_JobIdDup(const glite_lbu_JobId in, glite_lbu_JobId * jobid); - -/* - * Free jobid structure - * \param jobid for dealocation - */ -void glite_lbu_JobIdFree(glite_lbu_JobId jobid); - -/** - * Parse Job ID string and creates jobid structure - * \param jobidstr string representation of jobid - * \param jobid parsed job id - * \retval 0 for success - * \retval EINVAL jobidstr can't be parsed - * \retval ENOMEM if memory allocation fails - */ -int glite_lbu_JobIdParse(const char* jobidstr, glite_lbu_JobId * jobid); - -/** - * Unparse Job ID (produce the string form of JobId). - * \param jobid to be converted to string - * \return allocated string which represents jobid - */ -char* glite_lbu_JobIdUnparse(const glite_lbu_JobId jobid); - -/** - * Extract bookkeeping server address (address:port) - * \param jobid from which the bkserver address should be extracted - * \retval pointer to allocated string with bkserver address - * \retval NULL if jobid is 0 or memory allocation fails - */ -char* glite_lbu_JobIdGetServer(const glite_lbu_JobId jobid); - -/** - * Extract bookkeeping server address and port - * \param jobid from which the bkserver address should be extracted - * \param srvName pointer where to return server name - * \param srvPort pointer where to return server port - * */ -void glite_lbu_JobIdGetServerParts(const glite_lbu_JobId jobid, char **srvName, unsigned int *srvPort); - -/** - * Extract unique string - * \param jobid - * \retval pointer to allocated unique string representing jobid - * \retval NULL if jobid is 0 or memory allocation fails - */ -char* glite_lbu_JobIdGetUnique(const glite_lbu_JobId jobid); - -#ifdef __cplusplus -} -#endif - -#endif /* _GLITE_JOBID_H */ diff --git a/org.glite.lb-utils.jobid/interface/strmd5.h b/org.glite.lb-utils.jobid/interface/strmd5.h deleted file mode 100755 index 27d8544..0000000 --- a/org.glite.lb-utils.jobid/interface/strmd5.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _GLITE_STRMD5_H -#define _GLITE_STRMD5_H - -#ident "$Header$" - -/* Compute MD5 sum of the first argument. - * The sum is returned in the 16-byte array pointed to by 2nd argument - * (if not NULL) - * - * Return value: ASCII string of the sum, i.e. 32 characters [0-9a-f] - * (pointer to static area, changed by subsequent calls) - */ - -#ifdef USE_MBUF -char *strmd5(const char *src, unsigned char *dst); -#endif - -/** - * Returns: allocated 32bytes long ASCII string with md5 sum - * of the first argument - */ -char *str2md5(const char *src); - -/** - * Returns: allocated 22bytes long ASCII string with md5 sum in base64 - * format of the source argument - */ -char *str2md5base64(const char *src); - -#endif /* _GLITE_STRMD5_H */ diff --git a/org.glite.lb-utils.jobid/project/build.number b/org.glite.lb-utils.jobid/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils.jobid/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils.jobid/project/build.properties b/org.glite.lb-utils.jobid/project/build.properties deleted file mode 100755 index 89232f3..0000000 --- a/org.glite.lb-utils.jobid/project/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -# temporary hack before lb-utils are integrated - -lb-utils.subsystem.name = org.glite.lb-utils -lb-utils.subsystem.prefix = lb-utils diff --git a/org.glite.lb-utils.jobid/project/configure.properties.xml b/org.glite.lb-utils.jobid/project/configure.properties.xml deleted file mode 100644 index 23ba931..0000000 --- a/org.glite.lb-utils.jobid/project/configure.properties.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -lbuprefix=${subsystem.prefix} -package=${module.package.name} -PREFIX=${install.dir} - - - - diff --git a/org.glite.lb-utils.jobid/project/properties.xml b/org.glite.lb-utils.jobid/project/properties.xml deleted file mode 100644 index 1adf343..0000000 --- a/org.glite.lb-utils.jobid/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.jobid/project/tar_exclude b/org.glite.lb-utils.jobid/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.lb-utils.jobid/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.lb-utils.jobid/project/version.properties b/org.glite.lb-utils.jobid/project/version.properties deleted file mode 100755 index 52a0f68..0000000 --- a/org.glite.lb-utils.jobid/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 1.0.0 -module.age = 0 diff --git a/org.glite.lb-utils.jobid/src/cjobid.c b/org.glite.lb-utils.jobid/src/cjobid.c deleted file mode 100755 index 6d6a73f..0000000 --- a/org.glite.lb-utils.jobid/src/cjobid.c +++ /dev/null @@ -1,260 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "cjobid.h" -#include "strmd5.h" - -struct _glite_lbu_JobId { - char *id; /* unique job identification */ - /* additional information */ - char *BShost;/* bookkeeping server hostname */ - unsigned int BSport; /* bookkeeping server port */ - char *info; /* additional information (after ? in URI) */ -}; - -int glite_lbu_JobIdCreate(const char *bkserver, int port, glite_lbu_JobId *jobId) -{ - return glite_lbu_JobIdRecreate(bkserver, port, NULL, jobId); -} - - -int glite_lbu_JobIdRecreate(const char* bkserver, int port, const char *unique, glite_lbu_JobId *jobId) -{ - glite_lbu_JobId out; - char hostname[200]; /* used to hold string for encrypt */ - struct timeval tv; - int skip; - char* portbeg; - - struct hostent* he; - - if (!bkserver) - return EINVAL; - - if (unique == NULL) { - gethostname(hostname, 100); - he = gethostbyname(hostname); - assert(he->h_length > 0); - gettimeofday(&tv, NULL); - srandom(tv.tv_usec); - - skip = strlen(hostname); - skip += sprintf(hostname + skip, "-IP:0x%x-pid:%d-rnd:%d-time:%d:%d", - *((int*)he->h_addr_list[0]), getpid(), (int)random(), - (int)tv.tv_sec, (int)tv.tv_usec); - } - - *jobId = NULL; - out = (glite_lbu_JobId) malloc (sizeof(*out)); - if (!out) - return ENOMEM; - - memset(out, 0, sizeof(*out)); - - /* check if it begins with prefix */ - /* unsupported */ - if (strncmp(bkserver, GLITE_WMSC_JOBID_PROTO_PREFIX, sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX)-1) == 0) - return EINVAL; - - out->BShost = strdup(bkserver); - portbeg = strchr(out->BShost, ':'); - if (portbeg) { - *portbeg = 0; - /* try to get port number */ - if (port == 0) - port = atoi(portbeg + 1); - } - - if (port == 0) - port = GLITE_WMSC_JOBID_DEFAULT_PORT; - - out->BSport = port; - - out->id = (unique) ? strdup(unique) : str2md5base64(hostname); - //printf("Encrypt: %s\nBASE64 %s\n", hostname, out->id); - - if (!out->id || !out->BShost) { - glite_lbu_JobIdFree(out); - return ENOMEM; - } - - *jobId = out; - return 0; -} - - -int glite_lbu_JobIdDup(const glite_lbu_JobId in, glite_lbu_JobId *out) -{ - glite_lbu_JobId jid; - *out = NULL; - if (in == NULL) - return 0; - - jid = malloc(sizeof(*jid)); - if (!jid) - return ENOMEM; - - memset(jid, 0,sizeof(*jid)); - jid->BShost = strdup(in->BShost); - jid->id = strdup(in->id); - if (in->info) - jid->info = strdup(in->info); - - if (jid->BShost == NULL || jid->id == NULL) { - glite_lbu_JobIdFree(jid); - return ENOMEM; - } - - jid->BSport = in->BSport; - *out = jid; - return 0; -} - - -// XXX -// use recreate -// parse name, port, unique -int glite_lbu_JobIdParse(const char *idString, glite_lbu_JobId *jobId) -{ - char *pom, *pom1, *pom2; - glite_lbu_JobId out; - - *jobId = NULL; - - out = (glite_lbu_JobId) malloc (sizeof(*out)); - if (out == NULL ) - return ENOMEM; - - memset(out,0,sizeof(*out)); - - if (strncmp(idString, GLITE_WMSC_JOBID_PROTO_PREFIX, sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX) - 1)) { - out->BShost = (char *) NULL; - out->BSport = 0; - - free(out); - return EINVAL; - } - - pom = strdup(idString + sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX) - 1); - pom1 = strchr(pom, '/'); - pom2 = strchr(pom, ':'); - - if (!pom1) { free(pom); free(out); return EINVAL; } - - if ( pom2 && (pom1 > pom2)) { - pom[pom2-pom] = '\0'; - out->BShost = strdup(pom); - pom[pom1-pom] = '\0'; - out->BSport = (unsigned int) strtoul(pom2 + 1,NULL,10); - } else { - pom[pom1-pom] = '\0'; - out->BShost = strdup(pom); - out->BSport = GLITE_WMSC_JOBID_DEFAULT_PORT; - } - - /* XXX: localhost not supported in jobid - if (!strncmp(out->BShost,"localhost",9) { - free(pom); - free(out->BShost); - free(out); - return EINVAL; - } - */ - - /* additional info from URI */ - pom2 = strchr(pom1+1,'?'); - if (pom2) { - *pom2 = 0; - out->info = strdup(pom2+1); - } - - /* extract the unique part */ - out->id = strdup(pom1+1); - - for (pom1 = out->BShost; *pom1; pom1++) - if (isspace(*pom1)) break; - - for (pom2 = out->id; *pom2; pom2++) - if (isspace(*pom2)) break; - - if (*pom1 || *pom2) { - free(pom); - glite_lbu_JobIdFree(out); - return EINVAL; - } - - free(pom); - *jobId = out; - return 0; -} - - -void glite_lbu_JobIdFree(glite_lbu_JobId job) -{ - if (job) { - free(job->id); - free(job->BShost); - free(job->info); - free(job); - } -} - - -char* glite_lbu_JobIdUnparse(const glite_lbu_JobId jobid) -{ - char *out, port[40]; - - if (!jobid) - return NULL; - - if (jobid->BSport) - sprintf(port,":%d",jobid->BSport); - else - *port = 0; - - asprintf(&out, GLITE_WMSC_JOBID_PROTO_PREFIX"%s%s/%s%s%s", - jobid->BShost,port, - jobid->id, - (jobid->info ? "?" : ""), - (jobid->info ? jobid->info : "")); - - return out; -} - - -char* glite_lbu_JobIdGetServer(const glite_lbu_JobId jobid) -{ - char *bs = NULL; - - if (jobid) - asprintf(&bs, "%s:%u", jobid->BShost, - jobid->BSport ? jobid->BSport : GLITE_WMSC_JOBID_DEFAULT_PORT); - - return bs; -} - - -void glite_lbu_JobIdGetServerParts(const glite_lbu_JobId jobid, char **srvName, unsigned int *srvPort) -{ - if (jobid) { - *srvName = strdup(jobid->BShost); - *srvPort = jobid->BSport ? jobid->BSport : GLITE_WMSC_JOBID_DEFAULT_PORT; - } -} - - -char* glite_lbu_JobIdGetUnique(const glite_lbu_JobId jobid) -{ - return jobid ? strdup(jobid->id) : NULL; -} diff --git a/org.glite.lb-utils.jobid/src/strmd5.c b/org.glite.lb-utils.jobid/src/strmd5.c deleted file mode 100755 index 775aee8..0000000 --- a/org.glite.lb-utils.jobid/src/strmd5.c +++ /dev/null @@ -1,122 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include - -#include "strmd5.h" - -#if USE_MBUF /* let's try without it */ -#warning Thread unsafe! -static char mbuf[33]; -#endif - -static int base64_encode(const void *enc, int enc_size, char *out, int out_max_size) -{ - static const char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - - unsigned char* enc_buf = (unsigned char*)enc; - int out_size = 0; - unsigned int bits = 0; - unsigned int shift = 0; - - while ( out_size < out_max_size ) { - if ( enc_size>0 ) { - // Shift in byte - bits <<= 8; - bits |= *enc_buf; - shift += 8; - // Next byte - enc_buf++; - enc_size--; - } else if ( shift>0 ) { - // Pad last bits to 6 bits - will end next loop - bits <<= 6 - shift; - shift = 6; - } else { - // Terminate with Mime style '=' - *out = '='; - out_size++; - - return out_size; - } - - // Encode 6 bit segments - while ( shift>=6 ) { - shift -= 6; - *out = b64[ (bits >> shift) & 0x3F ]; - out++; - out_size++; - } - } - - // Output overflow - return -1; -} - -#ifdef USE_MBUF -char *strmd5(const char *s, unsigned char *digest) -{ - MD5_CTX md5; - unsigned char d[16]; - int i; - - MD5_Init(&md5); - MD5_Update(&md5,s,strlen(s)); - MD5_Final(d,&md5); - - if (digest) memcpy(digest,d,sizeof(d)); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - mbuf[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - mbuf[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - mbuf[32] = 0; - return (char *) mbuf; -} -#endif - -char *str2md5(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char* ret = malloc(33); - int i; - - if (!ret) - return NULL; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - ret[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - ret[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - ret[32] = 0; - return ret; -} - -char *str2md5base64(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char buf[50]; - int l; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - l = base64_encode(d, 16, buf, sizeof(buf) - 1); - if (l < 1) - return NULL; - buf[l - 1] = 0; - return strdup(buf); -} diff --git a/org.glite.lb-utils.server-bones/.cvsignore b/org.glite.lb-utils.server-bones/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.lb-utils.server-bones/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.lb-utils.server-bones/LICENSE b/org.glite.lb-utils.server-bones/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.lb-utils.server-bones/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils.server-bones/build.xml b/org.glite.lb-utils.server-bones/build.xml deleted file mode 100644 index efe49ad..0000000 --- a/org.glite.lb-utils.server-bones/build.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.server-bones/project/build.number b/org.glite.lb-utils.server-bones/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils.server-bones/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils.server-bones/project/build.properties b/org.glite.lb-utils.server-bones/project/build.properties deleted file mode 100755 index e69de29..0000000 diff --git a/org.glite.lb-utils.server-bones/project/configure.properties.xml b/org.glite.lb-utils.server-bones/project/configure.properties.xml deleted file mode 100644 index 6ad627b..0000000 --- a/org.glite.lb-utils.server-bones/project/configure.properties.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - diff --git a/org.glite.lb-utils.server-bones/project/properties.xml b/org.glite.lb-utils.server-bones/project/properties.xml deleted file mode 100644 index a76d544..0000000 --- a/org.glite.lb-utils.server-bones/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.server-bones/project/version.properties b/org.glite.lb-utils.server-bones/project/version.properties deleted file mode 100755 index 6f1f8ab..0000000 --- a/org.glite.lb-utils.server-bones/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 0.0.0 -module.age = 0 \ No newline at end of file diff --git a/org.glite.lb-utils.trio/.cvsignore b/org.glite.lb-utils.trio/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.lb-utils.trio/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.lb-utils.trio/LICENSE b/org.glite.lb-utils.trio/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.lb-utils.trio/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils.trio/Makefile b/org.glite.lb-utils.trio/Makefile deleted file mode 100644 index 96a8386..0000000 --- a/org.glite.lb-utils.trio/Makefile +++ /dev/null @@ -1,114 +0,0 @@ -# Default values -top_srcdir=. -builddir=build -top_builddir=${top_srcdir}/${builddir} -stagedir=. -distdir=. -globalprefix=glite -package=glite-lb-utils-trio -version=0.0.0 -PREFIX=/opt/glite -lbuprefix=lbu - --include Makefile.inc --include ../project/version.properties - -version=${module.version} - -VPATH=${top_srcdir}/src:${top_srcdir}/test::${top_srcdir}/doc - -CC=gcc - -DEBUG:=-g -O0 -Wall - -CFLAGS:=${DEBUG} -I${top_srcdir}/src -I${top_srcdir}/interface -I. -DDATAGRID_EXTENSION - -COMPILE:=libtool --mode=compile ${CC} -LINK:=libtool --mode=link ${CC} -rpath ${stagedir}/lib ${LDFLAGS} -LINKXX:=libtool --mode=link ${CXX} -rpath ${stagedir}/lib ${LDFLAGS} -INSTALL:=libtool --mode=install install - -REPORTS:=${top_srcdir}/reports -TEST_LIBS:=-L${cppunit_prefix}/lib -lcppunit -ldl -TEST_INC:=-I${cppunit_prefix}/include - - -OBJS:=trio.o strio.o escape.o -LOBJS:=${OBJS:.o=.lo} - -HDRS:=trio.h escape.h - -STATICLIB:=libglite_lbu_trio.a -LTLIB:=libglite_lbu_trio.la - -default: all - -all compile: ${STATICLIB} ${LTLIB} - -# to use libtool versioning correcty, we should have: -# -# current = major + minor + offset -# revision = patch -# age = minor -# -# where offset is a sum of maximal released minor's of all previous major's -# -# version_info=-version-info `echo ${version} | cut -d. -f1,2 | tr . :` - -# counted minors: n/a -offset=0 - -version_info:=-version-info ${shell \ - perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } - -${STATICLIB}: ${OBJS} - ar crv $@ ${OBJS} - ranlib $@ - -${LTLIB}: ${OBJS} - ${LINK} ${version_info} -o $@ ${LOBJS} - -stage: compile - $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes - -check: compile mkreports runtest - -mkreports: - -mkdir ${REPORTS} - -runtest: trio_test - ./trio_test ${REPORTS}/trio.xml - -trio_test: trio_test.cpp - ${CXX} -c ${CFLAGS} ${TEST_INC} $< - ${LINKXX} -o $@ trio_test.o ${LTLIB} ${TEST_LIBS} - - -dist: distsrc distbin - -distsrc: - mkdir -p ${top_srcdir}/${package}-${version} - cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version} - cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version} - rm -rf ${top_srcdir}/${package}-${version} - -distbin: - $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir} - save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir - rm -rf tmpbuilddir - -install: - mkdir -p ${PREFIX}/lib - mkdir -p ${PREFIX}/share/doc/${package}-${version} - ${INSTALL} -m 644 ${LTLIB} ${PREFIX}/lib - ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version} - if [ x${DOSTAGE} = xyes ]; then \ - mkdir -p ${PREFIX}/include/${globalprefix}/${lbuprefix} ; \ - (cd ${top_srcdir}/interface && install -m 644 ${HDRS} ${PREFIX}/include/${globalprefix}/${lbuprefix}) ; \ - install -m 644 ${STATICLIB} ${PREFIX}/lib; \ - fi - -clean: - -%.o: %.c - ${COMPILE} ${CFLAGS} -c $< diff --git a/org.glite.lb-utils.trio/build.xml b/org.glite.lb-utils.trio/build.xml deleted file mode 100644 index 7e38dda..0000000 --- a/org.glite.lb-utils.trio/build.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.trio/interface/escape.h b/org.glite.lb-utils.trio/interface/escape.h deleted file mode 100644 index 4795f68..0000000 --- a/org.glite.lb-utils.trio/interface/escape.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef __EDG_WORKLOAD_LOGGING_COMMON_ESCAPE_H__ -#define __EDG_WORKLOAD_LOGGING_COMMON_ESCAPE_H__ -/*! - * \file escape.h - */ - -#ident "$Header$" - - -/*! - * \fn char *glite_lbu_EscapeULM(const char *str) - * \param str a string to escape - * \return new (allocated) escaped string - * \brief in given string (ULM) escape all ULM_QM, ULM_BS and ULM_LF by ULM_BS - */ - -char *glite_lbu_EscapeULM(const char *); - - -/*! - * \fn char *glite_lbu_UnescapeULM(const char *str) - * \param str a string to unescape - * \return new (allocated) unescaped string - * \brief in given string (ULM) unescape all escaped ULM_QM, ULM_BS and ULM_LF - */ - -char *glite_lbu_UnescapeULM(const char *); - - -/*! - * \fn char *glite_lbu_EscapeXML(const char *str); - * \param str a string to escape - * \return new (allocated) escaped string - * \brief in given string (XML) escape all unwanted characters - */ - -char *glite_lbu_EscapeXML(const char *); - - -/*! - * \fn char *glite_lbu_UnescapeXML(const char *str) - * \param str a string to unescape - * \return new (allocated) unescaped string - * \brief in given string (XML) unescape all escaped characters - */ - -char *glite_lbu_UnescapeXML(const char *); - - -/*! - * \fn char *glite_lbu_EscapeSQL(const char *str) - * \param str a string to escape - * \return new (allocated) escaped string - * \briefin given string (SQL) escape all unwanted characters - */ - -char *glite_lbu_EscapeSQL(const char *); - -#endif /* __EDG_WORKLOAD_LOGGING_COMMON_ESCAPE_H__ */ diff --git a/org.glite.lb-utils.trio/interface/trio.h b/org.glite.lb-utils.trio/interface/trio.h deleted file mode 100644 index 04f133c..0000000 --- a/org.glite.lb-utils.trio/interface/trio.h +++ /dev/null @@ -1,187 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -#ifndef TRIO_TRIO_H -#define TRIO_TRIO_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* make utility and C++ compiler in Windows NT fails to find this symbol */ -#if defined(WIN32) && !defined(isascii) -# define isascii ((unsigned)(x) < 0x80) -#endif - -/* - * Error codes. - * - * Remember to add a textual description to trio_strerror. - */ -enum { - TRIO_EOF = 1, - TRIO_EINVAL = 2, - TRIO_ETOOMANY = 3, - TRIO_EDBLREF = 4, - TRIO_EGAP = 5, - TRIO_ENOMEM = 6, - TRIO_ERANGE = 7 -}; - -/* Error macros */ -#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF) -#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8) -#define TRIO_ERROR_NAME(x) trio_strerror(x) - -const char *trio_strerror(int); - -/************************************************************************* - * Print Functions - */ - -int trio_printf(const char *format, ...); -int trio_vprintf(const char *format, va_list args); -int trio_printfv(const char *format, void **args); - -int trio_fprintf(FILE *file, const char *format, ...); -int trio_vfprintf(FILE *file, const char *format, va_list args); -int trio_fprintfv(FILE *file, const char *format, void **args); - -int trio_dprintf(int fd, const char *format, ...); -int trio_vdprintf(int fd, const char *format, va_list args); -int trio_dprintfv(int fd, const char *format, void **args); - -/* trio_sprintf(target, format, ...) - * trio_snprintf(target, maxsize, format, ...) - * - * Build 'target' according to 'format' and succesive - * arguments. This is equal to the sprintf() and - * snprintf() functions. - */ -int trio_sprintf(char *buffer, const char *format, ...); -int trio_vsprintf(char *buffer, const char *format, va_list args); -int trio_sprintfv(char *buffer, const char *format, void **args); - -int trio_snprintf(char *buffer, size_t max, const char *format, ...); -int trio_vsnprintf(char *buffer, size_t bufferSize, const char *format, - va_list args); -int trio_snprintfv(char *buffer, size_t bufferSize, const char *format, - void **args); - -int trio_snprintfcat(char *buffer, size_t max, const char *format, ...); -int trio_vsnprintfcat(char *buffer, size_t bufferSize, const char *format, - va_list args); - -char *trio_aprintf(const char *format, ...); -char *trio_vaprintf(const char *format, va_list args); - -int trio_asprintf(char **ret, const char *format, ...); -int trio_vasprintf(char **ret, const char *format, va_list args); - -/************************************************************************* - * Scan Functions - */ -int trio_scanf(const char *format, ...); -int trio_vscanf(const char *format, va_list args); -int trio_scanfv(const char *format, void **args); - -int trio_fscanf(FILE *file, const char *format, ...); -int trio_vfscanf(FILE *file, const char *format, va_list args); -int trio_fscanfv(FILE *file, const char *format, void **args); - -int trio_dscanf(int fd, const char *format, ...); -int trio_vdscanf(int fd, const char *format, va_list args); -int trio_dscanfv(int fd, const char *format, void **args); - -int trio_sscanf(const char *buffer, const char *format, ...); -int trio_vsscanf(const char *buffer, const char *format, va_list args); -int trio_sscanfv(const char *buffer, const char *format, void **args); - -/************************************************************************* - * Renaming - */ -#ifdef TRIO_REPLACE_STDIO -/* Replace the functions */ -#ifndef HAVE_PRINTF -# define printf trio_printf -#endif -#ifndef HAVE_VPRINTF -# define vprintf trio_vprintf -#endif -#ifndef HAVE_FPRINTF -# define fprintf trio_fprintf -#endif -#ifndef HAVE_VFPRINTF -# define vfprintf trio_vfprintf -#endif -#ifndef HAVE_SPRINTF -# define sprintf trio_sprintf -#endif -#ifndef HAVE_VSPRINTF -# define vsprintf trio_vsprintf -#endif -#ifndef HAVE_SNPRINTF -# define snprintf trio_snprintf -#endif -#ifndef HAVE_VSNPRINTF -# define vsnprintf trio_vsnprintf -#endif -#ifndef HAVE_SCANF -# define scanf trio_scanf -#endif -#ifndef HAVE_VSCANF -# define vscanf trio_vscanf -#endif -#ifndef HAVE_FSCANF -# define fscanf trio_fscanf -#endif -#ifndef HAVE_VFSCANF -# define vfscanf trio_vfscanf -#endif -#ifndef HAVE_SSCANF -# define sscanf trio_sscanf -#endif -#ifndef HAVE_VSSCANF -# define vsscanf trio_vsscanf -#endif -/* These aren't stdio functions, but we make them look similar */ -#define dprintf trio_dprintf -#define vdprintf trio_vdprintf -#define aprintf trio_aprintf -#define vaprintf trio_vaprintf -#define asprintf trio_asprintf -#define vasprintf trio_vasprintf -#define dscanf trio_dscanf -#define vdscanf trio_vdscanf -#endif - -/* strio compatible names */ -#define StrScan trio_sscanf -#define StrFormat trio_sprintf -#define StrFormatMax trio_snprintf -#define StrFormatAlloc trio_aprintf -#define StrFormatAppendMax trio_snprintfcat - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* TRIO_TRIO_H */ diff --git a/org.glite.lb-utils.trio/project/build.number b/org.glite.lb-utils.trio/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils.trio/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils.trio/project/build.properties b/org.glite.lb-utils.trio/project/build.properties deleted file mode 100755 index 89232f3..0000000 --- a/org.glite.lb-utils.trio/project/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -# temporary hack before lb-utils are integrated - -lb-utils.subsystem.name = org.glite.lb-utils -lb-utils.subsystem.prefix = lb-utils diff --git a/org.glite.lb-utils.trio/project/configure.properties.xml b/org.glite.lb-utils.trio/project/configure.properties.xml deleted file mode 100644 index d743f4b..0000000 --- a/org.glite.lb-utils.trio/project/configure.properties.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -globalprefix=${global.prefix} -lbuprefix=${subsystem.prefix} -package=${module.package.name} -cppunit_prefix=${with.cppunit.prefix} -PREFIX=${install.dir} - - - - - diff --git a/org.glite.lb-utils.trio/project/properties.xml b/org.glite.lb-utils.trio/project/properties.xml deleted file mode 100644 index e472152..0000000 --- a/org.glite.lb-utils.trio/project/properties.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils.trio/project/version.properties b/org.glite.lb-utils.trio/project/version.properties deleted file mode 100755 index 6f1f8ab..0000000 --- a/org.glite.lb-utils.trio/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 0.0.0 -module.age = 0 \ No newline at end of file diff --git a/org.glite.lb-utils.trio/src/escape.c b/org.glite.lb-utils.trio/src/escape.c deleted file mode 100644 index 9a1d545..0000000 --- a/org.glite.lb-utils.trio/src/escape.c +++ /dev/null @@ -1,224 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include - -#include "escape.h" - -#define ULM_QM '"' -#define ULM_BS '\\' -#define ULM_LF '\n' - -/* - *---------------------------------------------------------------------- - * - * \fn char *glite_lbu_EscapeULM(const char *str) - * \param str a string to escape - * \return new (allocated) escaped string - * \brief in given string escape all ULM_QM, ULM_BS and ULM_LF by ULM_BS - * - * Calls: malloc, strlen - * - * Algorithm: array lookup - * - the new string will be allocated - * - *---------------------------------------------------------------------- - */ - -char *glite_lbu_EscapeULM(const char *str) -{ -unsigned int i,j; -size_t size; -char *ret; - -if (str == NULL) return NULL; -if ((size = strlen(str)) == 0) return strdup(""); - -ret = (char*) malloc(1+2*size*sizeof(char)); - -j = 0; -for (i=0; i',"gt" }, - { '&',"amp" }, - { '"',"quot" }, - { '\'',"apos" }, - { 0, NULL } -}; - -#define XML_ESCAPE_SET "<>&\"'" - -char *glite_lbu_EscapeXML(const char *in) -{ - const char* tmp_in; - char *out; - int cnt,i,j,k; - - if (!in) return NULL; - - for (cnt = 0, tmp_in = in; *tmp_in != '\0'; ++tmp_in) { - if (strchr(XML_ESCAPE_SET, *tmp_in) || - (*tmp_in & 0x7f) < 0x20 /* control character */ || - (*tmp_in == '%')) cnt++; - } - - out = malloc(strlen(in)+1+cnt*5); - - for (i=j=0; in[i]; i++) { - for (k=0; xml_etab[k].c && xml_etab[k].c != in[i]; k++); - if (xml_etab[k].c) { - int l; - - out[j++] = '&'; - memcpy(out+j,xml_etab[k].e,l=strlen(xml_etab[k].e)); - j += l; - out[j++] = ';'; - } else if ((in[i] & 0x7f) < 0x20 || in[i] == '%') { - sprintf(out+j, "%%%02x", (unsigned char)in[i]); - j+=3; - } else { - out[j++] = in[i]; - } - } - out[j] = 0; - return out; -} - -char *glite_lbu_UnescapeXML(const char *in) -{ - char *out; - int i,j,k; - char xtmp[3]; - unsigned char origchar; - - if (!in) return NULL; - out = malloc(strlen(in)+1); - - for (i=j=0; in[i]; j++) if (in[i] == '&') { - char *s = strchr(in+i,';'); - if (s) { - int l = s-in-i+1; - for (k=0; xml_etab[k].c && strncasecmp(in+i+1,xml_etab[k].e,l-2); k++); - if (xml_etab[k].c) { - out[j] = xml_etab[k].c; - i += l; - } else out[j] = in[i++]; - } else out[j] = in[i++]; - } else if (in[i] == '%') { - if (isxdigit(xtmp[0]=in[i+1]) && isxdigit(xtmp[1]=in[i+2])) { - xtmp[2] = '\0'; - origchar = (unsigned char) strtol(xtmp, NULL, 16); - if ((origchar & 0x7f) < 0x20 || origchar == '%') { - out[j] = origchar; - i += 3; - } else out[j] = in[i++]; - } else out[j] = in[i++]; - } else { - out[j] = in[i++]; - } - out[j] = 0; - return out; -} - -char *glite_lbu_EscapeSQL(const char *in) -{ - const char* tmp_in; - char *out = NULL; - int i,j,cnt; - - if (!in) return NULL; - - for (cnt = 0, tmp_in = in; (tmp_in = strchr(tmp_in,'\'')) != NULL; ++tmp_in) { - ++cnt; - } - for (tmp_in = in; (tmp_in = strchr(tmp_in,'\\')) != NULL; ++tmp_in) { - ++cnt; - } - - out = malloc(strlen(in)+1+cnt); - - for (i=j=0; in[i]; i++) { - if (in[i] == '\\') out[j++] = '\\'; - if (in[i] == '\'') out[j++] = '\''; - out[j++] = in[i]; - } - out[j] = 0; - - return out; -} diff --git a/org.glite.lb-utils.trio/src/strio.c b/org.glite.lb-utils.trio/src/strio.c deleted file mode 100644 index f1ab5b8..0000000 --- a/org.glite.lb-utils.trio/src/strio.c +++ /dev/null @@ -1,581 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -/* - * TODO - * - StrToLongDouble - */ - -static const char rcsid[] = "@(#)$Id$"; - -#if defined(unix) || defined(__xlC__) || defined(__QNX__) -# define PLATFORM_UNIX -#elif defined(WIN32) || defined(_WIN32) -# define PLATFORM_WIN32 -#elif defined(AMIGA) && defined(__GNUC__) -# define PLATFORM_UNIX -#endif - -#if defined(__STDC__) && (__STDC_VERSION__ >= 199901L) -# define TRIO_C99 -#endif - -#include "strio.h" -#include -#include -#include -#include -#include -#include -#ifndef DEBUG -# define NDEBUG -#endif -#include - -#ifndef NULL -# define NULL 0 -#endif -#define NIL ((char)0) -#ifndef FALSE -# define FALSE (1 == 0) -# define TRUE (! FALSE) -#endif - -#define VALID(x) (NULL != (x)) -#define INVALID(x) (NULL == (x)) - -#if defined(PLATFORM_UNIX) -# define USE_STRCASECMP -# define USE_STRNCASECMP -# define USE_STRERROR -# if defined(__QNX__) -# define strcasecmp(x,y) stricmp(x,y) -# define strncasecmp(x,y,n) strnicmp(x,y,n) -# endif -#elif defined(PLATFORM_WIN32) -# define USE_STRCASECMP -# define strcasecmp(x,y) strcmpi(x,y) -#endif - -/************************************************************************* - * StrAppendMax - */ -char *StrAppendMax(char *target, size_t max, const char *source) -{ - assert(VALID(target)); - assert(VALID(source)); - assert(max > 0); - - max -= StrLength(target) + 1; - return (max > 0) ? strncat(target, source, max) : target; -} - -/************************************************************************* - * StrCopyMax - */ -char *StrCopyMax(char *target, size_t max, const char *source) -{ - assert(VALID(target)); - assert(VALID(source)); - assert(max > 0); /* Includes != 0 */ - - target = strncpy(target, source, max - 1); - target[max - 1] = (char)0; - return target; -} - -/************************************************************************* - * StrDuplicate - */ -char *StrDuplicate(const char *source) -{ - char *target; - - assert(VALID(source)); - - target = StrAlloc(StrLength(source) + 1); - if (target) - { - StrCopy(target, source); - } - return target; -} - -/************************************************************************* - * StrDuplicateMax - */ -char *StrDuplicateMax(const char *source, size_t max) -{ - char *target; - size_t len; - - assert(VALID(source)); - assert(max > 0); - - /* Make room for string plus a terminating zero */ - len = StrLength(source) + 1; - if (len > max) - { - len = max; - } - target = StrAlloc(len); - if (target) - { - StrCopyMax(target, len, source); - } - return target; -} - -/************************************************************************* - * StrEqual - */ -int StrEqual(const char *first, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { -#if defined(USE_STRCASECMP) - return (0 == strcasecmp(first, second)); -#else - while ((*first != NIL) && (*second != NIL)) - { - if (toupper(*first) != toupper(*second)) - { - break; - } - first++; - second++; - } - return ((*first == NIL) && (*second == NIL)); -#endif - } - return FALSE; -} - -/************************************************************************* - * StrEqualCase - */ -int StrEqualCase(const char *first, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { - return (0 == strcmp(first, second)); - } - return FALSE; -} - -/************************************************************************* - * StrEqualCaseMax - */ -int StrEqualCaseMax(const char *first, size_t max, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { - return (0 == strncmp(first, second, max)); - } - return FALSE; -} - -/************************************************************************* - * StrEqualLocale - */ -int StrEqualLocale(const char *first, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - -#if defined(LC_COLLATE) - return (strcoll(first, second) == 0); -#else - return StrEqual(first, second); -#endif -} - -/************************************************************************* - * StrEqualMax - */ -int StrEqualMax(const char *first, size_t max, const char *second) -{ - assert(VALID(first)); - assert(VALID(second)); - - if (VALID(first) && VALID(second)) - { -#if defined(USE_STRNCASECMP) - return (0 == strncasecmp(first, second, max)); -#else - /* Not adequately tested yet */ - size_t cnt = 0; - while ((*first != NIL) && (*second != NIL) && (cnt <= max)) - { - if (toupper(*first) != toupper(*second)) - { - break; - } - first++; - second++; - cnt++; - } - return ((cnt == max) || ((*first == NIL) && (*second == NIL))); -#endif - } - return FALSE; -} - -/************************************************************************* - * StrError - */ -const char *StrError(int errorNumber) -{ -#if defined(USE_STRERROR) - return strerror(errorNumber); -#else - return "unknown"; -#endif -} - -/************************************************************************* - * StrFormatDate - */ -size_t StrFormatDateMax(char *target, - size_t max, - const char *format, - const struct tm *datetime) -{ - assert(VALID(target)); - assert(VALID(format)); - assert(VALID(datetime)); - assert(max > 0); - - return strftime(target, max, format, datetime); -} - -/************************************************************************* - * StrHash - */ -unsigned long StrHash(const char *string, int type) -{ - unsigned long value = 0L; - char ch; - - assert(VALID(string)); - - switch (type) - { - case STRIO_HASH_PLAIN: - while ( (ch = *string++) != NIL ) - { - value *= 31; - value += (unsigned long)ch; - } - break; - default: - assert(FALSE); - break; - } - return value; -} - -/************************************************************************* - * StrMatch - */ -int StrMatch(char *string, char *pattern) -{ - assert(VALID(string)); - assert(VALID(pattern)); - - for (; ('*' != *pattern); ++pattern, ++string) - { - if (NIL == *string) - { - return (NIL == *pattern); - } - if ((toupper((int)*string) != toupper((int)*pattern)) - && ('?' != *pattern)) - { - return FALSE; - } - } - /* two-line patch to prevent *too* much recursiveness: */ - while ('*' == pattern[1]) - pattern++; - - do - { - if ( StrMatch(string, &pattern[1]) ) - { - return TRUE; - } - } - while (*string++); - - return FALSE; -} - -/************************************************************************* - * StrMatchCase - */ -int StrMatchCase(char *string, char *pattern) -{ - assert(VALID(string)); - assert(VALID(pattern)); - - for (; ('*' != *pattern); ++pattern, ++string) - { - if (NIL == *string) - { - return (NIL == *pattern); - } - if ((*string != *pattern) - && ('?' != *pattern)) - { - return FALSE; - } - } - /* two-line patch to prevent *too* much recursiveness: */ - while ('*' == pattern[1]) - pattern++; - - do - { - if ( StrMatchCase(string, &pattern[1]) ) - { - return TRUE; - } - } - while (*string++); - - return FALSE; -} - -/************************************************************************* - * StrSpanFunction - * - * Untested - */ -size_t StrSpanFunction(char *source, int (*Function)(int)) -{ - size_t count = 0; - - assert(VALID(source)); - assert(VALID(Function)); - - while (*source != NIL) - { - if (Function(*source)) - break; /* while */ - source++; - count++; - } - return count; -} - -/************************************************************************* - * StrSubstringMax - */ -char *StrSubstringMax(const char *string, size_t max, const char *find) -{ - size_t count; - size_t size; - char *result = NULL; - - assert(VALID(string)); - assert(VALID(find)); - - size = StrLength(find); - if (size <= max) - { - for (count = 0; count <= max - size; count++) - { - if (StrEqualMax(find, size, &string[count])) - { - result = (char *)&string[count]; - break; - } - } - } - return result; -} - -/************************************************************************* - * StrToDouble - * - * double ::= [ ] - * ( | - * | - * ) - * [ [ ] ] - * number ::= 1*( ) - * digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' ) - * exponential ::= ( 'e' | 'E' ) - * sign ::= ( '-' | '+' ) - * decimal_point ::= '.' - */ -double StrToDouble(const char *source, const char **endp) -{ -#if defined(TRIO_C99) - return strtod(source, endp); -#else - /* Preliminary code */ - int isNegative = FALSE; - int isExponentNegative = FALSE; - unsigned long integer = 0; - unsigned long fraction = 0; - unsigned long fracdiv = 1; - unsigned long exponent = 0; - double value = 0.0; - - /* First try hex-floats */ - if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X'))) - { - source += 2; - while (isxdigit((int)*source)) - { - integer *= 16; - integer += (isdigit((int)*source) - ? (*source - '0') - : 10 + (toupper((int)*source) - 'A')); - source++; - } - if (*source == '.') - { - source++; - while (isxdigit((int)*source)) - { - fraction *= 16; - fraction += (isdigit((int)*source) - ? (*source - '0') - : 10 + (toupper((int)*source) - 'A')); - fracdiv *= 16; - source++; - } - if ((*source == 'p') || (*source == 'P')) - { - source++; - if ((*source == '+') || (*source == '-')) - { - isExponentNegative = (*source == '-'); - source++; - } - while (isdigit((int)*source)) - { - exponent *= 10; - exponent += (*source - '0'); - source++; - } - } - } - } - else /* Then try normal decimal floats */ - { - isNegative = (*source == '-'); - /* Skip sign */ - if ((*source == '+') || (*source == '-')) - source++; - - /* Integer part */ - while (isdigit((int)*source)) - { - integer *= 10; - integer += (*source - '0'); - source++; - } - - if (*source == '.') - { - source++; /* skip decimal point */ - while (isdigit((int)*source)) - { - fraction *= 10; - fraction += (*source - '0'); - fracdiv *= 10; - source++; - } - } - if ((*source == 'e') || (*source == 'E')) - { - source++; /* Skip exponential indicator */ - isExponentNegative = (*source == '-'); - if ((*source == '+') || (*source == '-')) - source++; - while (isdigit((int)*source)) - { - exponent *= 10; - exponent += (*source - '0'); - source++; - } - } - } - - value = (double)integer; - if (fraction != 0) - { - value += (double)fraction / (double)fracdiv; - } - if (exponent != 0) - { - if (isExponentNegative) - value /= pow((double)10, (double)exponent); - else - value *= pow((double)10, (double)exponent); - } - if (isNegative) - value = -value; - - if (endp) - *endp = source; - return value; -#endif -} - -/************************************************************************* - * StrToFloat - */ -float StrToFloat(const char *source, const char **endp) -{ -#if defined(TRIO_C99) - return strtof(source, endp); -#else - return (float)StrToDouble(source, endp); -#endif -} - -/************************************************************************* - * StrToUpper - */ -int StrToUpper(char *target) -{ - int i = 0; - - assert(VALID(target)); - - while (NIL != *target) - { - *target = toupper((int)*target); - target++; - i++; - } - return i; -} diff --git a/org.glite.lb-utils.trio/src/strio.h b/org.glite.lb-utils.trio/src/strio.h deleted file mode 100644 index 68845a3..0000000 --- a/org.glite.lb-utils.trio/src/strio.h +++ /dev/null @@ -1,227 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************/ - -#ifndef TRIO_STRIO_H -#define TRIO_STRIO_H - -#if !(defined(DEBUG) || defined(NDEBUG)) -# define NDEBUG -#endif -#include -#include -#include -#include - -#ifndef STRIO_MALLOC -# define STRIO_MALLOC(n) malloc(n) -#endif -#ifndef STRIO_FREE -# define STRIO_FREE(x) free(x) -#endif - -/* - * StrAppend(target, source) - * StrAppendMax(target, maxsize, source) - * - * Append 'source' to 'target' - * - * target = StrAlloc(size) - * - * Allocate a new string - * - * StrContains(target, substring) - * - * Find out if the string 'substring' is - * contained in the string 'target' - * - * StrCopy(target, source) - * StrCopyMax(target, maxsize, source) - * - * Copy 'source' to 'target' - * - * target = StrDuplicate(source) - * target = StrDuplicateMax(source, maxsize) - * - * Allocate and copy 'source' to 'target' - * - * StrEqual(first, second) - * StrEqualMax(first, maxsize, second) - * - * Compare if 'first' is equal to 'second'. - * Case-independent. - * - * StrEqualCase(first, second) - * StrEqualCaseMax(first, maxsize, second) - * - * Compare if 'first' is equal to 'second' - * Case-dependent. Please note that the use of the - * word 'case' has the opposite meaning as that of - * strcasecmp(). - * - * StrFormat(target, format, ...) - * StrFormatMax(target, maxsize, format, ...) - * - * Build 'target' according to 'format' and succesive - * arguments. This is equal to the sprintf() and - * snprintf() functions. - * - * StrFormatDate(target, format, ...) - * - * StrFree(target) - * - * De-allocates a string - * - * StrHash(string, type) - * - * Calculates the hash value of 'string' based on the - * 'type'. - * - * StrIndex(target, character) - * StrIndexLast(target, character) - * - * Find the first/last occurrence of 'character' in - * 'target' - * - * StrLength(target) - * - * Return the length of 'target' - * - * StrMatch(string, pattern) - * StrMatchCase(string, pattern) - * - * Find 'pattern' within 'string'. 'pattern' may contain - * wildcards such as * (asterics) and ? (question mark) - * which matches zero or more characters and exactly - * on character respectively - * - * StrScan(source, format, ...) - * - * Equal to sscanf() - * - * StrSubstring(target, substring) - * - * Find the first occurrence of the string 'substring' - * within the string 'target' - * - * StrTokenize(target, list) - * - * Split 'target' into the first token delimited by - * one of the characters in 'list'. If 'target' is - * NULL then next token will be returned. - * - * StrToUpper(target) - * - * Convert all lower case characters in 'target' into - * upper case characters. - */ - -enum { - STRIO_HASH_NONE = 0, - STRIO_HASH_PLAIN, - STRIO_HASH_TWOSIGNED -}; - -#if !defined(DEBUG) || defined(__DECC) -#define StrAlloc(n) (char *)STRIO_MALLOC(n) -#define StrAppend(x,y) strcat((x), (y)) -#define StrContains(x,y) (0 != strstr((x), (y))) -#define StrCopy(x,y) strcpy((x), (y)) -#define StrIndex(x,y) strchr((x), (y)) -#define StrIndexLast(x,y) strrchr((x), (y)) -#define StrFree(x) STRIO_FREE(x) -#define StrLength(x) strlen((x)) -#define StrSubstring(x,y) strstr((x), (y)) -#define StrTokenize(x,y) strtok((x), (y)) -#define StrToLong(x,y,n) strtol((x), (y), (n)) -#define StrToUnsignedLong(x,y,n) strtoul((x), (y), (n)) -#else /* DEBUG */ - /* - * To be able to use these macros everywhere, including in - * if() sentences, the assertions are put first in a comma - * seperated list. - * - * Unfortunately the DECC compiler does not seem to like this - * so it will use the un-asserted functions above for the - * debugging case too. - */ -#define StrAlloc(n) \ - (assert((n) > 0),\ - (char *)STRIO_MALLOC(n)) -#define StrAppend(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - strcat((x), (y))) -#define StrContains(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - (0 != strstr((x), (y)))) -#define StrCopy(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - strcpy((x), (y))) -#define StrIndex(x,c) \ - (assert((x) != NULL),\ - strchr((x), (c))) -#define StrIndexLast(x,c) \ - (assert((x) != NULL),\ - strrchr((x), (c))) -#define StrFree(x) \ - (assert((x) != NULL),\ - STRIO_FREE(x)) -#define StrLength(x) \ - (assert((x) != NULL),\ - strlen((x))) -#define StrSubstring(x,y) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - strstr((x), (y))) -#define StrTokenize(x,y) \ - (assert((y) != NULL),\ - strtok((x), (y))) -#define StrToLong(x,y,n) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - assert((n) >= 2 && (n) <= 36),\ - strtol((x), (y), (n))) -#define StrToUnsignedLong(x,y,n) \ - (assert((x) != NULL),\ - assert((y) != NULL),\ - assert((n) >= 2 && (n) <= 36),\ - strtoul((x), (y), (n))) -#endif /* DEBUG */ - -char *StrAppendMax(char *target, size_t max, const char *source); -char *StrCopyMax(char *target, size_t max, const char *source); -char *StrDuplicate(const char *source); -char *StrDuplicateMax(const char *source, size_t max); -int StrEqual(const char *first, const char *second); -int StrEqualCase(const char *first, const char *second); -int StrEqualCaseMax(const char *first, size_t max, const char *second); -int StrEqualLocale(const char *first, const char *second); -int StrEqualMax(const char *first, size_t max, const char *second); -const char *StrError(int); -size_t StrFormatDateMax(char *target, size_t max, const char *format, const struct tm *datetime); -unsigned long StrHash(const char *string, int type); -int StrMatch(char *string, char *pattern); -int StrMatchCase(char *string, char *pattern); -size_t StrSpanFunction(char *source, int (*Function)(int)); -char *StrSubstringMax(const char *string, size_t max, const char *find); -float StrToFloat(const char *source, const char **target); -double StrToDouble(const char *source, const char **target); -int StrToUpper(char *target); - -#endif /* TRIO_STRIO_H */ diff --git a/org.glite.lb-utils.trio/src/trio.c b/org.glite.lb-utils.trio/src/trio.c deleted file mode 100644 index 6e4211e..0000000 --- a/org.glite.lb-utils.trio/src/trio.c +++ /dev/null @@ -1,5706 +0,0 @@ - -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************* - * - * A note to trio contributors: - * - * Avoid heap allocation at all costs to ensure that the trio functions - * are async-safe. The exceptions are the printf/fprintf functions, which - * uses fputc, and the asprintf functions and the modifier, which - * by design are required to allocate form the heap. - * - ************************************************************************/ - -/* - * TODO: - * - Scan is probably too permissive about its modifiers. - * - C escapes in %#[] ? - * - C99 support has not been properly tested. - * - Multibyte characters (done for format parsing, except scan groups) - * - Complex numbers? (C99 _Complex) - * - Boolean values? (C99 _Bool) - * - C99 NaN(n-char-sequence) missing - * - Should we support the GNU %a alloc modifier? GNU has an ugly hack - * for %a, because C99 used %a for other purposes. If specified as - * %as or %a[ it is interpreted as the alloc modifier, otherwise as - * the C99 hex-float. This means that you cannot scan %as as a hex-float - * immediately followed by an 's'. - * - Scanning of collating symbols. - */ - -static const char rcsid[] = "@(#)$Id$"; - -/************************************************************************* - * Trio include files - */ -#include "trio.h" -#include "triop.h" -#include "strio.h" - -#ifdef DATAGRID_EXTENSION -#include "escape.h" -#endif - -/* - * Encode the error code and the position. This is decoded - * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION. - */ -#if TRIO_ERRORS -# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8))) -#else -# define TRIO_ERROR_RETURN(x,y) (-1) -#endif - - -/************************************************************************* - * Platform and compiler support detection - */ -#if defined(unix) || defined(__xlC__) || defined(_AIX) || defined(__QNX__) -# define PLATFORM_UNIX -#elif defined(AMIGA) && defined(__GNUC__) -# define PLATFORM_UNIX -#elif defined(WIN32) || defined(_WIN32) || defined(_MSC_VER) -# define PLATFORM_WIN32 -# define TRIO_MSVC_5 1100 -#endif - -#if defined(__STDC__) && defined(__STDC_VERSION__) -# if (__STDC_VERSION__ >= 199409L) -# define TRIO_COMPILER_SUPPORTS_ISO94 -# endif -# if (__STDC_VERSION__ >= 199901L) -# define TRIO_COMPILER_SUPPORTS_C99 -# endif -#endif - -#if defined(_XOPEN_SOURCE) && defined(_XOPEN_SOURCE_EXTENDED) -# define TRIO_COMPILER_SUPPORTS_UNIX98 -#endif - -#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_WIDECHAR -# define TRIO_COMPILER_SUPPORTS_MULTIBYTE -# if !defined(MB_LEN_MAX) -# define MB_LEN_MAX 6 -# endif -#endif - - -/************************************************************************* - * Generic definitions - */ - -#if !(defined(DEBUG) || defined(NDEBUG)) -# define NDEBUG -#endif -#include -#include -#if !defined(TRIO_COMPILER_SUPPORTS_C99) && !defined(isblank) -# define isblank(x) (((x)==32) || ((x)==9)) -#endif -#include -#include -#include -#include -#include -#include - -#ifndef NULL -# define NULL 0 -#endif -#define NIL ((char)0) -#ifndef FALSE -# define FALSE (1 == 0) -# define TRUE (! FALSE) -#endif -#define BOOLEAN_T int - -/* mincore() can be used for debugging purposes */ -#define VALID(x) (NULL != (x)) - -/* xlC crashes on log10(0) */ -#define guarded_log10(x) (((x) == 0.0) ? -HUGE_VAL : log10(x)) -#define guarded_log16(x) (guarded_log10(x) / log10(16.0)) - - -/************************************************************************* - * Platform specific definitions - */ -#if defined(PLATFORM_UNIX) -# include -# include -# include -# define USE_LOCALE -#endif /* PLATFORM_UNIX */ -#if defined(PLATFORM_WIN32) -# include -# define read _read -# define write _write -#endif /* PLATFORM_WIN32 */ - -#if TRIO_WIDECHAR -# if defined(TRIO_COMPILER_SUPPORTS_ISO94) -# include -# include -# else -typedef char wchar_t; -typedef int wint_t; -# define WEOF EOF -# define iswalnum(x) isalnum(x) -# define iswalpha(x) isalpha(x) -# define iswblank(x) isblank(x) -# define iswcntrl(x) iscntrl(x) -# define iswdigit(x) isdigit(x) -# define iswgraph(x) isgraph(x) -# define iswlower(x) islower(x) -# define iswprint(x) isprint(x) -# define iswpunct(x) ispunct(x) -# define iswspace(x) isspace(x) -# define iswupper(x) isupper(x) -# define iswxdigit(x) isxdigit(x) -# endif -#endif - - -/************************************************************************* - * Compiler dependent definitions - */ - -/* Support for long long */ -#ifndef __cplusplus -# if !defined(USE_LONGLONG) -# if defined(__GNUC__) && !defined(__STRICT_ANSI__) -# define USE_LONGLONG -# elif defined(__SUNPRO_C) -# define USE_LONGLONG -# elif defined(_LONG_LONG) || defined(_LONGLONG) -# define USE_LONGLONG -# endif -# endif -#endif - -/* The extra long numbers */ -#if defined(USE_LONGLONG) -typedef signed long long int trio_longlong_t; -typedef unsigned long long int trio_ulonglong_t; -#elif defined(_MSC_VER) -# if (_MSC_VER >= TRIO_MSVC_5) -typedef signed __int64 trio_longlong_t; -typedef unsigned __int64 trio_ulonglong_t; -# else -typedef signed long int trio_longlong_t; -typedef unsigned long int trio_ulonglong_t; -# endif -#else -typedef signed long int trio_longlong_t; -typedef unsigned long int trio_ulonglong_t; -#endif - -/* Maximal and fixed integer types */ -#if defined(TRIO_COMPILER_SUPPORTS_C99) -# include -typedef intmax_t trio_intmax_t; -typedef uintmax_t trio_uintmax_t; -typedef int8_t trio_int8_t; -typedef int16_t trio_int16_t; -typedef int32_t trio_int32_t; -typedef int64_t trio_int64_t; -#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98) -# include -typedef intmax_t trio_intmax_t; -typedef uintmax_t trio_uintmax_t; -typedef int8_t trio_int8_t; -typedef int16_t trio_int16_t; -typedef int32_t trio_int32_t; -typedef int64_t trio_int64_t; -#elif defined(_MSC_VER) && (_MSC_VER >= TRIO_MSVC_5) -typedef trio_longlong_t trio_intmax_t; -typedef trio_ulonglong_t trio_uintmax_t; -typedef __int8 trio_int8_t; -typedef __int16 trio_int16_t; -typedef __int32 trio_int32_t; -typedef __int64 trio_int64_t; -#else -typedef trio_longlong_t trio_intmax_t; -typedef trio_ulonglong_t trio_uintmax_t; -# if defined(TRIO_INT8_T) -typedef TRIO_INT8_T trio_int8_t; -# else -typedef signed char trio_int8_t; -# endif -# if defined(TRIO_INT16_T) -typedef TRIO_INT16_T trio_int16_t; -# else -typedef signed short trio_int16_t; -# endif -# if defined(TRIO_INT32_T) -typedef TRIO_INT32_T trio_int32_t; -# else -typedef signed int trio_int32_t; -# endif -# if defined(TRIO_INT64_T) -typedef TRIO_INT64_T trio_int64_t; -# else -typedef trio_longlong_t trio_int64_t; -# endif -#endif - - -/************************************************************************* - * Internal definitions - */ - -/* Long double sizes */ -#ifdef LDBL_DIG -# define MAX_MANTISSA_DIGITS LDBL_DIG -# define MAX_EXPONENT_DIGITS 4 -#else -# define MAX_MANTISSA_DIGITS DBL_DIG -# define MAX_EXPONENT_DIGITS 3 -#endif - -/* The maximal number of digits is for base 2 */ -#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT) -/* The width of a pointer. The number of bits in a hex digit is 4 */ -#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(void *) * CHAR_BIT / 4) - -/* Infinite and Not-A-Number for floating-point */ -#define INFINITE_LOWER "inf" -#define INFINITE_UPPER "INF" -#define LONG_INFINITE_LOWER "infinite" -#define LONG_INFINITE_UPPER "INFINITE" -#define NAN_LOWER "nan" -#define NAN_UPPER "NAN" - -/* Various constants */ -enum { - TYPE_PRINT = 1, - TYPE_SCAN = 2, - - /* Flags. Use maximum 32 */ - FLAGS_NEW = 0, - FLAGS_STICKY = 1, - FLAGS_SPACE = 2 * FLAGS_STICKY, - FLAGS_SHOWSIGN = 2 * FLAGS_SPACE, - FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN, - FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST, - FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE, - FLAGS_SHORTSHORT = 2 * FLAGS_SHORT, - FLAGS_LONG = 2 * FLAGS_SHORTSHORT, - FLAGS_QUAD = 2 * FLAGS_LONG, - FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD, - FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE, - FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T, - FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T, - FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T, - FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING, - FLAGS_UPPER = 2 * FLAGS_UNSIGNED, - FLAGS_WIDTH = 2 * FLAGS_UPPER, - FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH, - FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER, - FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION, - FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER, - FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE, - FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER, - FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E, - FLAGS_QUOTE = 2 * FLAGS_FLOAT_G, - FLAGS_WIDECHAR = 2 * FLAGS_QUOTE, - FLAGS_ALLOC = 2 * FLAGS_WIDECHAR, - FLAGS_IGNORE = 2 * FLAGS_ALLOC, - FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE, - FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER, - FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER, - /* Reused flags */ - FLAGS_EXCLUDE = FLAGS_SHORT, - FLAGS_USER_DEFINED = FLAGS_IGNORE, - /* Compounded flags */ - FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T, - FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT, - - NO_POSITION = -1, - NO_WIDTH = 0, - NO_PRECISION = -1, - NO_SIZE = -1, - - NO_BASE = -1, - MIN_BASE = 2, - MAX_BASE = 36, - BASE_BINARY = 2, - BASE_OCTAL = 8, - BASE_DECIMAL = 10, - BASE_HEX = 16, - - /* Maximal number of allowed parameters */ - MAX_PARAMETERS = 64, - /* Maximal number of characters in class */ - MAX_CHARACTER_CLASS = UCHAR_MAX, - - /* Maximal string lengths for user-defined specifiers */ - MAX_USER_NAME = 64, - MAX_USER_DATA = 256, - - /* Maximal length of locale separator strings */ - MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX, - /* Maximal number of integers in grouping */ - MAX_LOCALE_GROUPS = 64 -}; - -#define NO_GROUPING ((int)CHAR_MAX) - -/* Fundamental formatting parameter types */ -#define FORMAT_UNKNOWN 0 -#define FORMAT_INT 1 -#define FORMAT_DOUBLE 2 -#define FORMAT_CHAR 3 -#define FORMAT_STRING 4 -#define FORMAT_POINTER 5 -#define FORMAT_COUNT 6 -#define FORMAT_PARAMETER 7 -#define FORMAT_GROUP 8 -#if TRIO_GNU -# define FORMAT_ERRNO 9 -#endif -#if TRIO_EXTENSION -# define FORMAT_USER_DEFINED 10 -#endif - -/* Character constants */ -#define CHAR_IDENTIFIER '%' -#define CHAR_BACKSLASH '\\' -#define CHAR_QUOTE '\"' -#define CHAR_ADJUST ' ' - -/* Character class expressions */ -#define CLASS_ALNUM ":alnum:" -#define CLASS_ALPHA ":alpha:" -#define CLASS_CNTRL ":cntrl:" -#define CLASS_DIGIT ":digit:" -#define CLASS_GRAPH ":graph:" -#define CLASS_LOWER ":lower:" -#define CLASS_PRINT ":print:" -#define CLASS_PUNCT ":punct:" -#define CLASS_SPACE ":space:" -#define CLASS_UPPER ":upper:" -#define CLASS_XDIGIT ":xdigit:" - -/* - * SPECIFIERS: - * - * - * a Hex-float - * A Hex-float - * c Character - * C Widechar character (wint_t) - * d Decimal - * e Float - * E Float - * F Float - * F Float - * g Float - * G Float - * i Integer - * m Error message - * n Count - * o Octal - * p Pointer - * s String - * S Widechar string (wchar_t *) - * u Unsigned - * x Hex - * X Hex - * [] Group - * <> User-defined - * - * Reserved: - * - * D Binary Coded Decimal %D(length,precision) (OS/390) - */ -#define SPECIFIER_CHAR 'c' -#define SPECIFIER_STRING 's' -#define SPECIFIER_DECIMAL 'd' -#define SPECIFIER_INTEGER 'i' -#define SPECIFIER_UNSIGNED 'u' -#define SPECIFIER_OCTAL 'o' -#define SPECIFIER_HEX 'x' -#define SPECIFIER_HEX_UPPER 'X' -#define SPECIFIER_FLOAT_E 'e' -#define SPECIFIER_FLOAT_E_UPPER 'E' -#define SPECIFIER_FLOAT_F 'f' -#define SPECIFIER_FLOAT_F_UPPER 'F' -#define SPECIFIER_FLOAT_G 'g' -#define SPECIFIER_FLOAT_G_UPPER 'G' -#define SPECIFIER_POINTER 'p' -#define SPECIFIER_GROUP '[' -#define SPECIFIER_UNGROUP ']' -#define SPECIFIER_COUNT 'n' -#if TRIO_UNIX98 -# define SPECIFIER_CHAR_UPPER 'C' -# define SPECIFIER_STRING_UPPER 'S' -#endif -#if TRIO_C99 -# define SPECIFIER_HEXFLOAT 'a' -# define SPECIFIER_HEXFLOAT_UPPER 'A' -#endif -#if TRIO_GNU -# define SPECIFIER_ERRNO 'm' -#endif -#if TRIO_EXTENSION -# define SPECIFIER_BINARY 'b' -# define SPECIFIER_BINARY_UPPER 'B' -# define SPECIFIER_USER_DEFINED_BEGIN '<' -# define SPECIFIER_USER_DEFINED_END '>' -# define SPECIFIER_USER_DEFINED_SEPARATOR ':' -#endif - -/* - * QUALIFIERS: - * - * - * Numbers = d,i,o,u,x,X - * Float = a,A,e,E,f,F,g,G - * String = s - * Char = c - * - * - * 9$ Position - * Use the 9th parameter. 9 can be any number between 1 and - * the maximal argument - * - * 9 Width - * Set width to 9. 9 can be any number, but must not be postfixed - * by '$' - * - * h Short - * Numbers: - * (unsigned) short int - * - * hh Short short - * Numbers: - * (unsigned) char - * - * l Long - * Numbers: - * (unsigned) long int - * String: - * as the S specifier - * Char: - * as the C specifier - * - * ll Long Long - * Numbers: - * (unsigned) long long int - * - * L Long Double - * Float - * long double - * - * # Alternative - * Float: - * Decimal-point is always present - * String: - * non-printable characters are handled as \number - * - * Spacing - * - * + Sign - * - * - Alignment - * - * . Precision - * - * * Parameter - * print: use parameter - * scan: no parameter (ignore) - * - * q Quad - * - * Z size_t - * - * w Widechar - * - * ' Thousands/quote - * Numbers: - * Integer part grouped in thousands - * Binary numbers: - * Number grouped in nibbles (4 bits) - * String: - * Quoted string - * - * j intmax_t - * t prtdiff_t - * z size_t - * - * ! Sticky - * @ Parameter (for both print and scan) - * - * I n-bit Integer - * Numbers: - * The following options exists - * I8 = 8-bit integer - * I16 = 16-bit integer - * I32 = 32-bit integer - * I64 = 64-bit integer - */ -#define QUALIFIER_POSITION '$' -#define QUALIFIER_SHORT 'h' -#define QUALIFIER_LONG 'l' -#define QUALIFIER_LONG_UPPER 'L' -#define QUALIFIER_ALTERNATIVE '#' -#define QUALIFIER_SPACE ' ' -#define QUALIFIER_PLUS '+' -#define QUALIFIER_MINUS '-' -#define QUALIFIER_DOT '.' -#define QUALIFIER_STAR '*' -#define QUALIFIER_CIRCUMFLEX '^' -#if TRIO_C99 -# define QUALIFIER_SIZE_T 'z' -# define QUALIFIER_PTRDIFF_T 't' -# define QUALIFIER_INTMAX_T 'j' -#endif -#if TRIO_BSD || TRIO_GNU -# define QUALIFIER_QUAD 'q' -#endif -#if TRIO_GNU -# define QUALIFIER_SIZE_T_UPPER 'Z' -#endif -#if TRIO_MISC -# define QUALIFIER_WIDECHAR 'w' -#endif -#if TRIO_MICROSOFT -# define QUALIFIER_FIXED_SIZE 'I' -#endif -#if TRIO_EXTENSION -# define QUALIFIER_QUOTE '\'' -# define QUALIFIER_STICKY '!' -# define QUALIFIER_VARSIZE '&' /* This should remain undocumented */ -# define QUALIFIER_PARAM '@' /* Experimental */ -# define QUALIFIER_COLON ':' /* For scanlists */ -# define QUALIFIER_EQUAL '=' /* For scanlists */ -#endif -#if DATAGRID_EXTENSION -# define QUALIFIER_ESCAPE '|' -#endif - - -/************************************************************************* - * Internal structures - */ - -/* Parameters */ -typedef struct { - int type; - unsigned long flags; - int width; - int precision; - int base; - int varsize; -#ifdef QUALIFIER_ESCAPE - enum dg_escape { ESCAPE_NONE, ESCAPE_ULM, ESCAPE_XML, ESCAPE_SQL } escape; -#endif - int indexAfterSpecifier; - union { - char *string; -#if TRIO_WIDECHAR - wchar_t *wstring; -#endif - void *pointer; - union { - trio_uintmax_t as_signed; - trio_intmax_t as_unsigned; - } number; - double doubleNumber; - double *doublePointer; - long double longdoubleNumber; - long double *longdoublePointer; - int errorNumber; - } data; - /* For the user-defined specifier */ - char user_name[MAX_USER_NAME]; - char user_data[MAX_USER_DATA]; -} parameter_T; - -/* General trio "class" */ -typedef struct _trio_T { - void *location; - void (*OutStream)(struct _trio_T *, int); - void (*InStream)(struct _trio_T *, int *); - /* - * The number of characters that would have been written/read if - * there had been sufficient space. - */ - int processed; - /* - * The number of characters that are actually written/read. - * Processed and committed with only differ for the *nprintf - * and *nscanf functions. - */ - int committed; - int max; - int current; -} trio_T; - -/* References (for user-defined callbacks) */ -typedef struct _reference_T { - trio_T *data; - parameter_T *parameter; -} reference_T; - -/* Registered entries (for user-defined callbacks) */ -typedef struct _userdef_T { - struct _userdef_T *next; - trio_callback_t callback; - char *name; -} userdef_T; - - -/************************************************************************* - * Internal variables - */ - -static const char null[] = "(nil)"; - -#if defined(USE_LOCALE) -static struct lconv *internalLocaleValues = NULL; -#endif - -/* - * UNIX98 says "in a locale where the radix character is not defined, - * the radix character defaults to a period (.)" - */ -static char internalDecimalPoint[MAX_LOCALE_SEPARATOR_LENGTH + 1] = "."; -static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ","; -static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING }; - -static const char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz"; -static const char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -static BOOLEAN_T internalDigitsUnconverted = TRUE; -static int internalDigitArray[128]; -#if TRIO_EXTENSION -static BOOLEAN_T internalCollationUnconverted = TRUE; -static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS]; -#endif - -static volatile trio_callback_t internalEnterCriticalRegion = NULL; -static volatile trio_callback_t internalLeaveCriticalRegion = NULL; -static userdef_T *internalUserDef = NULL; - - -/************************************************************************* - * trio_strerror [public] - */ -const char *trio_strerror(int errorcode) -{ - /* Textual versions of the error codes */ - switch (TRIO_ERROR_CODE(errorcode)) - { - case TRIO_EOF: - return "End of file"; - case TRIO_EINVAL: - return "Invalid argument"; - case TRIO_ETOOMANY: - return "Too many arguments"; - case TRIO_EDBLREF: - return "Double reference"; - case TRIO_EGAP: - return "Reference gap"; - case TRIO_ENOMEM: - return "Out of memory"; - case TRIO_ERANGE: - return "Invalid range"; - default: - return "Unknown"; - } -} - -/************************************************************************* - * TrioIsQualifier [private] - * - * Description: - * Remember to add all new qualifiers to this function. - * QUALIFIER_POSITION must not be added. - */ -static BOOLEAN_T -TrioIsQualifier(const char ch) -{ - /* QUALIFIER_POSITION is not included */ - switch (ch) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case QUALIFIER_PLUS: - case QUALIFIER_MINUS: - case QUALIFIER_SPACE: - case QUALIFIER_DOT: - case QUALIFIER_STAR: - case QUALIFIER_ALTERNATIVE: - case QUALIFIER_SHORT: - case QUALIFIER_LONG: - case QUALIFIER_LONG_UPPER: - case QUALIFIER_CIRCUMFLEX: -#if defined(QUALIFIER_SIZE_T) - case QUALIFIER_SIZE_T: -#endif -#if defined(QUALIFIER_PTRDIFF_T) - case QUALIFIER_PTRDIFF_T: -#endif -#if defined(QUALIFIER_INTMAX_T) - case QUALIFIER_INTMAX_T: -#endif -#if defined(QUALIFIER_QUAD) - case QUALIFIER_QUAD: -#endif -#if defined(QUALIFIER_SIZE_T_UPPER) - case QUALIFIER_SIZE_T_UPPER: -#endif -#if defined(QUALIFIER_WIDECHAR) - case QUALIFIER_WIDECHAR: -#endif -#if defined(QUALIFIER_QUOTE) - case QUALIFIER_QUOTE: -#endif -#if defined(QUALIFIER_STICKY) - case QUALIFIER_STICKY: -#endif -#if defined(QUALIFIER_VARSIZE) - case QUALIFIER_VARSIZE: -#endif -#if defined(QUALIFIER_PARAM) - case QUALIFIER_PARAM: -#endif -#if defined(QUALIFIER_FIXED_SIZE) - case QUALIFIER_FIXED_SIZE: -#endif -#ifdef QUALIFIER_ESCAPE - case QUALIFIER_ESCAPE: -#endif - return TRUE; - default: - return FALSE; - } -} - -/************************************************************************* - * TrioGenerateNan [private] - * - * Calculating NaN portably is difficult. Some compilers will emit - * warnings about divide by zero, and others will simply fail to - * generate a NaN. - */ -static double -TrioGenerateNaN(void) -{ -#if defined(TRIO_COMPILER_SUPPORTS_C99) - return nan(NULL); -#elif defined(DBL_QNAN) - return DBL_QNAN; -#elif defined(PLATFORM_UNIX) - double value; - void (*signal_handler)(int); - - signal_handler = signal(SIGFPE, SIG_IGN); - value = 0.0 / 0.0; - signal(SIGFPE, signal_handler); - return value; -#else - return 0.0 / 0.0; -#endif -} - -/************************************************************************* - * TrioIsNan [private] - */ -static int -TrioIsNan(double number) -{ -#ifdef isnan - /* C99 defines isnan() as a macro */ - return isnan(number); -#else - double integral, fraction; - - return (/* NaN is the only number which does not compare to itself */ - (number != number) || - /* Fallback solution if NaN compares to NaN */ - ((number != 0.0) && - (fraction = modf(number, &integral), - integral == fraction))); -#endif -} - -/************************************************************************* - * TrioIsInfinite [private] - */ -static int -TrioIsInfinite(double number) -{ -#ifdef isinf - /* C99 defines isinf() as a macro */ - return isinf(number); -#else - return ((number == HUGE_VAL) ? 1 : ((number == -HUGE_VAL) ? -1 : 0)); -#endif -} - -/************************************************************************* - * TrioSetLocale [private] - */ -#if defined(USE_LOCALE) -static void -TrioSetLocale(void) -{ - internalLocaleValues = (struct lconv *)localeconv(); - if (internalLocaleValues) - { - if ((internalLocaleValues->decimal_point) && - (internalLocaleValues->decimal_point[0] != NIL)) - { - StrCopyMax(internalDecimalPoint, - sizeof(internalDecimalPoint), - internalLocaleValues->decimal_point); - } - if ((internalLocaleValues->thousands_sep) && - (internalLocaleValues->thousands_sep[0] != NIL)) - { - StrCopyMax(internalThousandSeparator, - sizeof(internalThousandSeparator), - internalLocaleValues->thousands_sep); - } - if ((internalLocaleValues->grouping) && - (internalLocaleValues->grouping[0] != NIL)) - { - StrCopyMax(internalGrouping, - sizeof(internalGrouping), - internalLocaleValues->grouping); - } - } -} -#endif /* defined(USE_LOCALE) */ - -/************************************************************************* - * TrioGetPosition [private] - * - * Get the %n$ position. - */ -static int -TrioGetPosition(const char *format, - int *indexPointer) -{ - char *tmpformat; - int number = 0; - int index = *indexPointer; - - number = (int)StrToLong(&format[index], &tmpformat, BASE_DECIMAL); - index = (int)(tmpformat - format); - if ((number != 0) && (QUALIFIER_POSITION == format[index++])) - { - *indexPointer = index; - /* - * number is decreased by 1, because n$ starts from 1, whereas - * the array it is indexing starts from 0. - */ - return number - 1; - } - return NO_POSITION; -} - -/************************************************************************* - * TrioFindNamespace [private] - * - * Find registered user-defined specifier. - * The prev argument is used for optimisation only. - */ -static userdef_T * -TrioFindNamespace(const char *name, userdef_T **prev) -{ - userdef_T *def; - - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - for (def = internalUserDef; def; def = def->next) - { - /* Case-sensitive string comparison */ - if (StrEqualCase(def->name, name)) - break; - - if (prev) - *prev = def; - } - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - - return def; -} - -/************************************************************************* - * TrioPreprocess [private] - * - * Description: - * Parse the format string - */ -static int -TrioPreprocess(int type, - const char *format, - parameter_T *parameters, - va_list arglist, - void **argarray) -{ -#if TRIO_ERRORS - /* Count the number of times a parameter is referenced */ - unsigned short usedEntries[MAX_PARAMETERS]; -#endif - /* Parameter counters */ - int parameterPosition; - int currentParam; - int maxParam = -1; - /* Utility variables */ - unsigned long flags; - int width; - int precision; - int varsize; -#ifdef QUALIFIER_ESCAPE - enum dg_escape escape; -#endif - int base; - int index; /* Index into formatting string */ - int dots; /* Count number of dots in modifier part */ - BOOLEAN_T positional; /* Does the specifier have a positional? */ - BOOLEAN_T got_sticky = FALSE; /* Are there any sticky modifiers at all? */ - /* - * indices specifies the order in which the parameters must be - * read from the va_args (this is necessary to handle positionals) - */ - int indices[MAX_PARAMETERS]; - int pos = 0; - /* Various variables */ - char ch; -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - int charlen; -#endif - int i = -1; - int num; - char *tmpformat; - - -#if TRIO_ERRORS - /* - * The 'parameters' array is not initialized, but we need to - * know which entries we have used. - */ - memset(usedEntries, 0, sizeof(usedEntries)); -#endif - - index = 0; - parameterPosition = 0; -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - mblen(NULL, 0); -#endif - - while (format[index]) - { -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - if (! isascii(format[index])) - { - /* - * Multibyte characters cannot be legal specifiers or - * modifiers, so we skip over them. - */ - charlen = mblen(&format[index], MB_LEN_MAX); - index += (charlen > 0) ? charlen : 1; - continue; /* while */ - } -#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */ - if (CHAR_IDENTIFIER == format[index++]) - { - if (CHAR_IDENTIFIER == format[index]) - { - index++; - continue; /* while */ - } - - flags = FLAGS_NEW; - dots = 0; - currentParam = TrioGetPosition(format, &index); - positional = (NO_POSITION != currentParam); - if (!positional) - { - /* We have no positional, get the next counter */ - currentParam = parameterPosition; - } - if(currentParam >= MAX_PARAMETERS) - { - /* Bail out completely to make the error more obvious */ - return TRIO_ERROR_RETURN(TRIO_ETOOMANY, index); - } - - if (currentParam > maxParam) - maxParam = currentParam; - - /* Default values */ - width = NO_WIDTH; - precision = NO_PRECISION; - base = NO_BASE; - varsize = NO_SIZE; -#ifdef QUALIFIER_ESCAPE - escape = ESCAPE_NONE; -#endif - - while (TrioIsQualifier(format[index])) - { - ch = format[index++]; - - switch (ch) - { - case QUALIFIER_SPACE: - flags |= FLAGS_SPACE; - break; - - case QUALIFIER_PLUS: - flags |= FLAGS_SHOWSIGN; - break; - - case QUALIFIER_MINUS: - flags |= FLAGS_LEFTADJUST; - flags &= ~FLAGS_NILPADDING; - break; - - case QUALIFIER_ALTERNATIVE: - flags |= FLAGS_ALTERNATIVE; - break; - - case QUALIFIER_DOT: - if (dots == 0) /* Precision */ - { - dots++; - - /* Skip if no precision */ - if (QUALIFIER_DOT == format[index]) - break; - - /* After the first dot we have the precision */ - flags |= FLAGS_PRECISION; - if ((QUALIFIER_STAR == format[index]) || - (QUALIFIER_PARAM == format[index])) - { - index++; - flags |= FLAGS_PRECISION_PARAMETER; - - precision = TrioGetPosition(format, &index); - if (precision == NO_POSITION) - { - parameterPosition++; - if (positional) - precision = parameterPosition; - else - { - precision = currentParam; - currentParam = precision + 1; - } - } - else - { - if (! positional) - currentParam = precision + 1; - if (width > maxParam) - maxParam = precision; - } - if (currentParam > maxParam) - maxParam = currentParam; - } - else - { - precision = StrToLong(&format[index], &tmpformat, BASE_DECIMAL); - index = (int)(tmpformat - format); - } - } - else if (dots == 1) /* Base */ - { - dots++; - - /* After the second dot we have the base */ - flags |= FLAGS_BASE; - if ((QUALIFIER_STAR == format[index]) || - (QUALIFIER_PARAM == format[index])) - { - index++; - flags |= FLAGS_BASE_PARAMETER; - base = TrioGetPosition(format, &index); - if (base == NO_POSITION) - { - parameterPosition++; - if (positional) - base = parameterPosition; - else - { - base = currentParam; - currentParam = base + 1; - } - } - else - { - if (! positional) - currentParam = base + 1; - if (base > maxParam) - maxParam = base; - } - if (currentParam > maxParam) - maxParam = currentParam; - } - else - { - base = StrToLong(&format[index], &tmpformat, BASE_DECIMAL); - if (base > MAX_BASE) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - index = (int)(tmpformat - format); - } - } - else - { - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - break; /* QUALIFIER_DOT */ - - case QUALIFIER_PARAM: - type = TYPE_PRINT; - /* FALLTHROUGH */ - case QUALIFIER_STAR: - /* This has different meanings for print and scan */ - if (TYPE_PRINT == type) - { - /* Read with from parameter */ - flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER); - width = TrioGetPosition(format, &index); - if (width == NO_POSITION) - { - parameterPosition++; - if (positional) - width = parameterPosition; - else - { - width = currentParam; - currentParam = width + 1; - } - } - else - { - if (! positional) - currentParam = width + 1; - if (width > maxParam) - maxParam = width; - } - if (currentParam > maxParam) - maxParam = currentParam; - } - else - { - /* Scan, but do not store result */ - flags |= FLAGS_IGNORE; - } - - break; /* QUALIFIER_STAR */ - - case '0': - if (! (flags & FLAGS_LEFTADJUST)) - flags |= FLAGS_NILPADDING; - /* FALLTHROUGH */ - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - flags |= FLAGS_WIDTH; - /* &format[index - 1] is used to "rewind" the read - * character from format - */ - width = StrToLong(&format[index - 1], &tmpformat, BASE_DECIMAL); - index = (int)(tmpformat - format); - break; - - case QUALIFIER_SHORT: - if (flags & FLAGS_SHORTSHORT) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - else if (flags & FLAGS_SHORT) - flags |= FLAGS_SHORTSHORT; - else - flags |= FLAGS_SHORT; - break; - - case QUALIFIER_LONG: - if (flags & FLAGS_QUAD) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - else if (flags & FLAGS_LONG) - flags |= FLAGS_QUAD; - else - flags |= FLAGS_LONG; - break; - - case QUALIFIER_LONG_UPPER: - flags |= FLAGS_LONGDOUBLE; - break; - -#if defined(QUALIFIER_SIZE_T) - case QUALIFIER_SIZE_T: - flags |= FLAGS_SIZE_T; - /* Modify flags for later truncation of number */ - if (sizeof(size_t) == sizeof(trio_ulonglong_t)) - flags |= FLAGS_QUAD; - else if (sizeof(size_t) == sizeof(long)) - flags |= FLAGS_LONG; - break; -#endif - -#if defined(QUALIFIER_PTRDIFF_T) - case QUALIFIER_PTRDIFF_T: - flags |= FLAGS_PTRDIFF_T; - if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t)) - flags |= FLAGS_QUAD; - else if (sizeof(ptrdiff_t) == sizeof(long)) - flags |= FLAGS_LONG; - break; -#endif - -#if defined(QUALIFIER_INTMAX_T) - case QUALIFIER_INTMAX_T: - flags |= FLAGS_INTMAX_T; - if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t)) - flags |= FLAGS_QUAD; - else if (sizeof(trio_intmax_t) == sizeof(long)) - flags |= FLAGS_LONG; - break; -#endif - -#if defined(QUALIFIER_QUAD) - case QUALIFIER_QUAD: - flags |= FLAGS_QUAD; - break; -#endif - -#if defined(QUALIFIER_FIXED_SIZE) - case QUALIFIER_FIXED_SIZE: - if (flags & FLAGS_FIXED_SIZE) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - - if (flags & (FLAGS_ALL_SIZES | FLAGS_LONGDOUBLE | - FLAGS_WIDECHAR | FLAGS_VARSIZE_PARAMETER)) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - - if ((format[index] == '6') && - (format[index + 1] == '4')) - { - varsize = sizeof(trio_int64_t); - index += 2; - } - else if ((format[index] == '3') && - (format[index + 1] == '2')) - { - varsize = sizeof(trio_int32_t); - index += 2; - } - else if ((format[index] == '1') && - (format[index + 1] == '6')) - { - varsize = sizeof(trio_int16_t); - index += 2; - } - else if (format[index] == '8') - { - varsize = sizeof(trio_int8_t); - index++; - } - else - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - - flags |= FLAGS_FIXED_SIZE; - break; -#endif - -#ifdef QUALIFIER_ESCAPE - case QUALIFIER_ESCAPE: - switch (format[index++]) { - case 'U': escape = ESCAPE_ULM; break; - case 'X': escape = ESCAPE_XML; break; - case 'S': escape = ESCAPE_SQL; break; - default: return TRIO_ERROR_RETURN(TRIO_EINVAL,index); - } - break; -#endif - - -#if defined(QUALIFIER_WIDECHAR) - case QUALIFIER_WIDECHAR: - flags |= FLAGS_WIDECHAR; - break; -#endif - -#if defined(QUALIFIER_SIZE_T_UPPER) - case QUALIFIER_SIZE_T_UPPER: - break; -#endif - -#if defined(QUALIFIER_QUOTE) - case QUALIFIER_QUOTE: - flags |= FLAGS_QUOTE; - break; -#endif - -#if defined(QUALIFIER_STICKY) - case QUALIFIER_STICKY: - flags |= FLAGS_STICKY; - got_sticky = TRUE; - break; -#endif - -#if defined(QUALIFIER_VARSIZE) - case QUALIFIER_VARSIZE: - flags |= FLAGS_VARSIZE_PARAMETER; - parameterPosition++; - if (positional) - varsize = parameterPosition; - else - { - varsize = currentParam; - currentParam = varsize + 1; - } - if (currentParam > maxParam) - maxParam = currentParam; - break; -#endif - - default: - /* Bail out completely to make the error more obvious */ - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - } /* while qualifier */ - - /* - * Parameters only need the type and value. The value is - * read later. - */ - if (flags & FLAGS_WIDTH_PARAMETER) - { -#if TRIO_ERRORS - usedEntries[width] += 1; -#endif - parameters[pos].type = FORMAT_PARAMETER; - indices[width] = pos; - width = pos++; - } - if (flags & FLAGS_PRECISION_PARAMETER) - { -#if TRIO_ERRORS - usedEntries[precision] += 1; -#endif - parameters[pos].type = FORMAT_PARAMETER; - indices[precision] = pos; - precision = pos++; - } - if (flags & FLAGS_BASE_PARAMETER) - { -#if TRIO_ERRORS - usedEntries[base] += 1; -#endif - parameters[pos].type = FORMAT_PARAMETER; - indices[base] = pos; - base = pos++; - } - if (flags & FLAGS_VARSIZE_PARAMETER) - { -#if TRIO_ERRORS - usedEntries[varsize] += 1; -#endif - parameters[pos].type = FORMAT_PARAMETER; - indices[varsize] = pos; - varsize = pos++; - } - - indices[currentParam] = pos; - - switch (format[index++]) - { -#if defined(SPECIFIER_CHAR_UPPER) - case SPECIFIER_CHAR_UPPER: - flags |= FLAGS_WIDECHAR; - /* FALLTHROUGH */ -#endif - case SPECIFIER_CHAR: - if (flags & FLAGS_LONG) - flags |= FLAGS_WIDECHAR; - else if (flags & FLAGS_SHORT) - flags &= ~FLAGS_WIDECHAR; - parameters[pos].type = FORMAT_CHAR; - break; - -#if defined(SPECIFIER_STRING_UPPER) - case SPECIFIER_STRING_UPPER: - flags |= FLAGS_WIDECHAR; - /* FALLTHROUGH */ -#endif - case SPECIFIER_STRING: - if (flags & FLAGS_LONG) - flags |= FLAGS_WIDECHAR; - else if (flags & FLAGS_SHORT) - flags &= ~FLAGS_WIDECHAR; - parameters[pos].type = FORMAT_STRING; - break; - - - case SPECIFIER_GROUP: - if (TYPE_SCAN == type) - { - int depth = 1; - parameters[pos].type = FORMAT_GROUP; - if (format[index] == QUALIFIER_CIRCUMFLEX) - index++; - if (format[index] == SPECIFIER_UNGROUP) - index++; - if (format[index] == QUALIFIER_MINUS) - index++; - /* Skip nested brackets */ - while (format[index] != NIL) - { - if (format[index] == SPECIFIER_GROUP) - { - depth++; - } - else if (format[index] == SPECIFIER_UNGROUP) - { - if (--depth <= 0) - { - index++; - break; - } - } - index++; - } - } - break; - - case SPECIFIER_INTEGER: - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_UNSIGNED: - flags |= FLAGS_UNSIGNED; - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_DECIMAL: - /* Disable base modifier */ - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_DECIMAL; - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_OCTAL: - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_OCTAL; - parameters[pos].type = FORMAT_INT; - break; - -#if defined(SPECIFIER_BINARY) - case SPECIFIER_BINARY_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_BINARY: - flags |= FLAGS_NILPADDING; - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_BINARY; - parameters[pos].type = FORMAT_INT; - break; -#endif - - case SPECIFIER_HEX_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_HEX: - flags |= FLAGS_UNSIGNED; - flags &= ~FLAGS_BASE_PARAMETER; - base = BASE_HEX; - parameters[pos].type = FORMAT_INT; - break; - - case SPECIFIER_FLOAT_E_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_FLOAT_E: - flags |= FLAGS_FLOAT_E; - parameters[pos].type = FORMAT_DOUBLE; - break; - - case SPECIFIER_FLOAT_G_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_FLOAT_G: - flags |= FLAGS_FLOAT_G; - parameters[pos].type = FORMAT_DOUBLE; - break; - - case SPECIFIER_FLOAT_F_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ - case SPECIFIER_FLOAT_F: - parameters[pos].type = FORMAT_DOUBLE; - break; - - case SPECIFIER_POINTER: - parameters[pos].type = FORMAT_POINTER; - break; - - case SPECIFIER_COUNT: - parameters[pos].type = FORMAT_COUNT; - break; - -#if defined(SPECIFIER_HEXFLOAT) -# if defined(SPECIFIER_HEXFLOAT_UPPER) - case SPECIFIER_HEXFLOAT_UPPER: - flags |= FLAGS_UPPER; - /* FALLTHROUGH */ -# endif - case SPECIFIER_HEXFLOAT: - base = BASE_HEX; - parameters[pos].type = FORMAT_DOUBLE; - break; -#endif - -#if defined(FORMAT_ERRNO) - case SPECIFIER_ERRNO: - parameters[pos].type = FORMAT_ERRNO; - break; -#endif - -#if defined(SPECIFIER_USER_DEFINED_BEGIN) - case SPECIFIER_USER_DEFINED_BEGIN: - { - unsigned int max; - int without_namespace = TRUE; - - parameters[pos].type = FORMAT_USER_DEFINED; - parameters[pos].user_name[0] = NIL; - tmpformat = (char *)&format[index]; - - while ((ch = format[index])) - { - index++; - if (ch == SPECIFIER_USER_DEFINED_END) - { - if (without_namespace) - { - /* We must get the handle first */ - parameters[pos].type = FORMAT_PARAMETER; - parameters[pos].indexAfterSpecifier = index; - parameters[pos].flags = FLAGS_USER_DEFINED; - /* Adjust parameters for insertion of new one */ - pos++; -# if TRIO_ERRORS - usedEntries[currentParam] += 1; -# endif - parameters[pos].type = FORMAT_USER_DEFINED; - currentParam++; - indices[currentParam] = pos; - if (currentParam > maxParam) - maxParam = currentParam; - } - /* Copy the user data */ - max = (unsigned int)(&format[index] - tmpformat); - if (max > MAX_USER_DATA) - max = MAX_USER_DATA; - StrCopyMax(parameters[pos].user_data, - max, - tmpformat); - break; /* while */ - } - if (ch == SPECIFIER_USER_DEFINED_SEPARATOR) - { - without_namespace = FALSE; - /* Copy the namespace for later looking-up */ - max = (int)(&format[index] - tmpformat); - if (max > MAX_USER_NAME) - max = MAX_USER_NAME; - StrCopyMax(parameters[pos].user_name, - max, - tmpformat); - tmpformat = (char *)&format[index]; - } - } - if (ch != SPECIFIER_USER_DEFINED_END) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - break; -#endif /* defined(SPECIFIER_USER_DEFINED_BEGIN) */ - - default: - /* Bail out completely to make the error more obvious */ - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - -#if TRIO_ERRORS - /* Count the number of times this entry has been used */ - usedEntries[currentParam] += 1; -#endif - - /* Find last sticky parameters */ - if (got_sticky && !(flags & FLAGS_STICKY)) - { - for (i = pos - 1; i >= 0; i--) - { - if (parameters[i].type == FORMAT_PARAMETER) - continue; - if ((parameters[i].flags & FLAGS_STICKY) && - (parameters[i].type == parameters[pos].type)) - { - /* Do not overwrite current qualifiers */ - flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY); - if (width == NO_WIDTH) - width = parameters[i].width; - if (precision == NO_PRECISION) - precision = parameters[i].precision; - if (base == NO_BASE) - base = parameters[i].base; - break; - } - } - } - - parameters[pos].indexAfterSpecifier = index; - parameters[pos].flags = flags; - parameters[pos].width = width; - parameters[pos].precision = precision; - parameters[pos].base = (base == NO_BASE) ? BASE_DECIMAL : base; - parameters[pos].varsize = varsize; -#ifdef QUALIFIER_ESCAPE - parameters[pos].escape = escape; -#endif - pos++; - - if (! positional) - parameterPosition++; - - } /* if identifier */ - - } /* while format characters left */ - - for (num = 0; num <= maxParam; num++) - { -#if TRIO_ERRORS - if (usedEntries[num] != 1) - { - if (usedEntries[num] == 0) /* gap detected */ - return TRIO_ERROR_RETURN(TRIO_EGAP, num); - else /* double references detected */ - return TRIO_ERROR_RETURN(TRIO_EDBLREF, num); - } -#endif - - i = indices[num]; - - /* - * FORMAT_PARAMETERS are only present if they must be read, - * so it makes no sense to check the ignore flag (besides, - * the flags variable is not set for that particular type) - */ - if ((parameters[i].type != FORMAT_PARAMETER) && - (parameters[i].flags & FLAGS_IGNORE)) - continue; /* for all arguments */ - - /* - * The stack arguments are read according to ANSI C89 - * default argument promotions: - * - * char = int - * short = int - * unsigned char = unsigned int - * unsigned short = unsigned int - * float = double - * - * In addition to the ANSI C89 these types are read (the - * default argument promotions of C99 has not been - * considered yet) - * - * long long - * long double - * size_t - * ptrdiff_t - * intmax_t - */ - switch (parameters[i].type) - { - case FORMAT_GROUP: - case FORMAT_STRING: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - parameters[i].data.wstring = (argarray == NULL) - ? va_arg(arglist, wchar_t *) - : (wchar_t *)(argarray[num]); - } - else -#endif - { - parameters[i].data.string = (argarray == NULL) - ? va_arg(arglist, char *) - : (char *)(argarray[num]); - } - break; - - case FORMAT_POINTER: - case FORMAT_COUNT: - case FORMAT_USER_DEFINED: - case FORMAT_UNKNOWN: - parameters[i].data.pointer = (argarray == NULL) - ? va_arg(arglist, void *) - : argarray[num]; - break; - - case FORMAT_CHAR: - case FORMAT_INT: - if (TYPE_SCAN == type) - { - if (argarray == NULL) - parameters[i].data.pointer = - (trio_uintmax_t *)va_arg(arglist, void *); - else - { - if (parameters[i].type == FORMAT_CHAR) - parameters[i].data.pointer = - (trio_uintmax_t *)((char *)argarray[num]); - else if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.pointer = - (trio_uintmax_t *)((short *)argarray[num]); - else - parameters[i].data.pointer = - (trio_uintmax_t *)((int *)argarray[num]); - } - } - else - { -#if defined(QUALIFIER_VARSIZE) || defined(QUALIFIER_FIXED_SIZE) - if ((parameters[i].flags & FLAGS_VARSIZE_PARAMETER) || - (parameters[i].flags & FLAGS_FIXED_SIZE)) - { - if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER) - { - /* - * Variable sizes are mapped onto the fixed sizes, in - * accordance with integer promotion. - * - * Please note that this may not be portable, as we - * only guess the size, not the layout of the numbers. - * For example, if int is little-endian, and long is - * big-endian, then this will fail. - */ - varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned; - } - else - { - /* Used for the I modifiers */ - varsize = parameters[i].varsize; - } - parameters[i].flags &= ~FLAGS_ALL_VARSIZES; - - if (varsize <= (int)sizeof(int)) - ; - else if (varsize <= (int)sizeof(long)) - parameters[i].flags |= FLAGS_LONG; -#if defined(QUALIFIER_INTMAX_T) - else if (varsize <= (int)sizeof(trio_longlong_t)) - parameters[i].flags |= FLAGS_QUAD; - else - parameters[i].flags |= FLAGS_INTMAX_T; -#else - else - parameters[i].flags |= FLAGS_QUAD; -#endif - } -#endif /* defined(QUALIFIER_VARSIZE) */ -#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER) - if (parameters[i].flags & FLAGS_SIZE_T) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, size_t) - : (trio_uintmax_t)(*((size_t *)argarray[num])); - else -#endif -#if defined(QUALIFIER_PTRDIFF_T) - if (parameters[i].flags & FLAGS_PTRDIFF_T) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, ptrdiff_t) - : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num])); - else -#endif -#if defined(QUALIFIER_INTMAX_T) - if (parameters[i].flags & FLAGS_INTMAX_T) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, trio_intmax_t) - : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num])); - else -#endif - if (parameters[i].flags & FLAGS_QUAD) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, trio_ulonglong_t) - : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num])); - else if (parameters[i].flags & FLAGS_LONG) - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, long) - : (trio_uintmax_t)(*((long *)argarray[num])); - else - { - if (argarray == NULL) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(arglist, int); - else - { - if (parameters[i].type == FORMAT_CHAR) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num])); - else if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num])); - else - parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num])); - } - } - } - break; - - case FORMAT_PARAMETER: - /* - * The parameter for the user-defined specifier is a pointer, - * whereas the rest (width, precision, base) uses an integer. - */ - if (parameters[i].flags & FLAGS_USER_DEFINED) - parameters[i].data.pointer = (argarray == NULL) - ? va_arg(arglist, void *) - : argarray[num]; - else - parameters[i].data.number.as_unsigned = (argarray == NULL) - ? (trio_uintmax_t)va_arg(arglist, int) - : (trio_uintmax_t)(*((int *)argarray[num])); - break; - - case FORMAT_DOUBLE: - if (TYPE_SCAN == type) - { - if (parameters[i].flags & FLAGS_LONG) - parameters[i].data.longdoublePointer = (argarray == NULL) - ? va_arg(arglist, long double *) - : (long double *)((long double *)argarray[num]); - else - { - if (argarray == NULL) - parameters[i].data.doublePointer = - va_arg(arglist, double *); - else - { - if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.doublePointer = - (double *)((float *)argarray[num]); - else - parameters[i].data.doublePointer = - (double *)((double *)argarray[num]); - } - } - } - else - { - if (parameters[i].flags & FLAGS_LONG) - parameters[i].data.longdoubleNumber = (argarray == NULL) - ? va_arg(arglist, long double) - : (long double)(*((long double *)argarray[num])); - else - { - if (argarray == NULL) - parameters[i].data.longdoubleNumber = (long double)va_arg(arglist, double); - else - { - if (parameters[i].flags & FLAGS_SHORT) - parameters[i].data.longdoubleNumber = (long double)(*((float *)argarray[num])); - else - parameters[i].data.longdoubleNumber = (long double)(long double)(*((double *)argarray[num])); - } - } - } - break; - -#if defined(FORMAT_ERRNO) - case FORMAT_ERRNO: - parameters[i].data.errorNumber = errno; - break; -#endif - - default: - break; - } - } /* for all specifiers */ - return num; -} - - -/************************************************************************* - * - * @FORMATTING - * - ************************************************************************/ - - -/************************************************************************* - * TrioWriteNumber [private] - * - * Description: - * Output a number. - * The complexity of this function is a result of the complexity - * of the dependencies of the flags. - */ -static void -TrioWriteNumber(trio_T *self, - trio_uintmax_t number, - unsigned long flags, - int width, - int precision, - int base) -{ - BOOLEAN_T isNegative; - char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1]; - char *bufferend; - char *pointer; - const char *digits; - int i; - int length; - char *p; - int charsPerThousand; - int groupingIndex; - int count; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE)); - - digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; - - isNegative = (flags & FLAGS_UNSIGNED) - ? FALSE - : ((trio_intmax_t)number < 0); - if (isNegative) - number = -number; - - if (flags & FLAGS_QUAD) - number &= (trio_ulonglong_t)-1; - else if (flags & FLAGS_LONG) - number &= (unsigned long)-1; - else - number &= (unsigned int)-1; - - /* Build number */ - pointer = bufferend = &buffer[sizeof(buffer) - 1]; - *pointer-- = NIL; - charsPerThousand = (int)internalGrouping[0]; - groupingIndex = 1; - for (i = 1; i < (int)sizeof(buffer); i++) - { - *pointer-- = digits[number % base]; - number /= base; - if (number == 0) - break; - - if ((flags & FLAGS_QUOTE) - && (charsPerThousand != NO_GROUPING) - && (i % charsPerThousand == 0)) - { - /* - * We are building the number from the least significant - * to the most significant digit, so we have to copy the - * thousand separator backwards - */ - length = StrLength(internalThousandSeparator); - if (((int)(pointer - buffer) - length) > 0) - { - p = &internalThousandSeparator[length - 1]; - while (length-- > 0) - *pointer-- = *p--; - } - - /* Advance to next grouping number */ - switch (internalGrouping[groupingIndex]) - { - case CHAR_MAX: /* Disable grouping */ - charsPerThousand = NO_GROUPING; - break; - case 0: /* Repeat last group */ - break; - default: - charsPerThousand = (int)internalGrouping[groupingIndex++]; - break; - } - } - } - - /* Adjust width */ - width -= (bufferend - pointer) - 1; - - /* Adjust precision */ - if (NO_PRECISION != precision) - { - precision -= (bufferend - pointer) - 1; - if (precision < 0) - precision = 0; - flags |= FLAGS_NILPADDING; - } - - /* Adjust width further */ - if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE)) - width--; - if (flags & FLAGS_ALTERNATIVE) - { - switch (base) - { - case BASE_BINARY: - case BASE_HEX: - width -= 2; - break; - case BASE_OCTAL: - width--; - break; - default: - break; - } - } - - /* Output prefixes spaces if needed */ - if (! ((flags & FLAGS_LEFTADJUST) || - ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION)))) - { - count = (precision == NO_PRECISION) ? 0 : precision; - while (width-- > count) - self->OutStream(self, CHAR_ADJUST); - } - - /* width has been adjusted for signs and alternatives */ - if (isNegative) - self->OutStream(self, '-'); - else if (flags & FLAGS_SHOWSIGN) - self->OutStream(self, '+'); - else if (flags & FLAGS_SPACE) - self->OutStream(self, ' '); - - if (flags & FLAGS_ALTERNATIVE) - { - switch (base) - { - case BASE_BINARY: - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b'); - break; - - case BASE_OCTAL: - self->OutStream(self, '0'); - break; - - case BASE_HEX: - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); - break; - - default: - break; - } /* switch base */ - } - - /* Output prefixed zero padding if needed */ - if (flags & FLAGS_NILPADDING) - { - if (precision == NO_PRECISION) - precision = width; - while (precision-- > 0) - { - self->OutStream(self, '0'); - width--; - } - } - - /* Output the number itself */ - while (*(++pointer)) - { - self->OutStream(self, *pointer); - } - - /* Output trailing spaces if needed */ - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } -} - -/************************************************************************* - * TrioWriteStringCharacter [private] - * - * Description: - * Output a single character of a string - */ -static void -TrioWriteStringCharacter(trio_T *self, - int ch, - unsigned long flags) -{ - if (flags & FLAGS_ALTERNATIVE) - { - if (! (isprint(ch) || isspace(ch))) - { - /* - * Non-printable characters are converted to C escapes or - * \number, if no C escape exists. - */ - self->OutStream(self, CHAR_BACKSLASH); - switch (ch) - { - case '\007': self->OutStream(self, 'a'); break; - case '\b': self->OutStream(self, 'b'); break; - case '\f': self->OutStream(self, 'f'); break; - case '\n': self->OutStream(self, 'n'); break; - case '\r': self->OutStream(self, 'r'); break; - case '\t': self->OutStream(self, 't'); break; - case '\v': self->OutStream(self, 'v'); break; - case '\\': self->OutStream(self, '\\'); break; - default: - self->OutStream(self, 'x'); - TrioWriteNumber(self, (trio_intmax_t)ch, - FLAGS_UNSIGNED | FLAGS_NILPADDING, - 2, 2, BASE_HEX); - break; - } - } - else if (ch == CHAR_BACKSLASH) - { - self->OutStream(self, CHAR_BACKSLASH); - self->OutStream(self, CHAR_BACKSLASH); - } - else - { - self->OutStream(self, ch); - } - } - else - { - self->OutStream(self, ch); - } -} - -/************************************************************************* - * TrioWriteString [private] - * - * Description: - * Output a string - */ -static void -TrioWriteString(trio_T *self, - const char *string, - unsigned long flags, - int width, - int precision) -{ - int length; - int ch; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - - if (string == NULL) - { - string = null; - length = sizeof(null) - 1; - /* Disable quoting for the null pointer */ - flags &= (~FLAGS_QUOTE); - width = 0; - } - else - { - length = StrLength(string); - } - if ((NO_PRECISION != precision) && - (precision < length)) - { - length = precision; - } - width -= length; - - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); - - if (! (flags & FLAGS_LEFTADJUST)) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - - while (length-- > 0) - { - /* The ctype parameters must be an unsigned char (or EOF) */ - ch = (int)((unsigned char)(*string++)); - TrioWriteStringCharacter(self, ch, flags); - } - - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); -} - -/************************************************************************* - * TrioWriteWideStringCharacter [private] - * - * Description: - * Output a wide string as a multi-byte sequence - */ -#if TRIO_WIDECHAR -static int -TrioWriteWideStringCharacter(trio_T *self, - wchar_t wch, - unsigned long flags, - int width) -{ - int size; - int i; - int ch; - char *string; - char buffer[MB_LEN_MAX + 1]; - - if (width == NO_WIDTH) - width = sizeof(buffer); - - size = wctomb(buffer, wch); - if ((size <= 0) || (size > width) || (buffer[0] == NIL)) - return 0; - - string = buffer; - i = size; - while ((width >= i) && (width-- > 0) && (i-- > 0)) - { - /* The ctype parameters must be an unsigned char (or EOF) */ - ch = (int)((unsigned char)(*string++)); - TrioWriteStringCharacter(self, ch, flags); - } - return size; -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * TrioWriteString [private] - * - * Description: - * Output a wide character string as a multi-byte string - */ -#if TRIO_WIDECHAR -static void -TrioWriteWideString(trio_T *self, - const wchar_t *wstring, - unsigned long flags, - int width, - int precision) -{ - int length; - int size; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - mblen(NULL, 0); -#endif - - if (wstring == NULL) - { - TrioWriteString(self, NULL, flags, width, precision); - return; - } - - if (NO_PRECISION == precision) - { - length = INT_MAX; - } - else - { - length = precision; - width -= length; - } - - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); - - if (! (flags & FLAGS_LEFTADJUST)) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - - while (length > 0) - { - size = TrioWriteWideStringCharacter(self, *wstring++, flags, length); - if (size == 0) - break; /* while */ - length -= size; - } - - if (flags & FLAGS_LEFTADJUST) - { - while (width-- > 0) - self->OutStream(self, CHAR_ADJUST); - } - if (flags & FLAGS_QUOTE) - self->OutStream(self, CHAR_QUOTE); -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * TrioWriteDouble [private] - */ -static void -TrioWriteDouble(trio_T *self, - long double longdoubleNumber, - unsigned long flags, - int width, - int precision, - int base) -{ - int charsPerThousand; - int length; - double number; - double workNumber; - int integerDigits; - int fractionDigits; - int exponentDigits; - int expectedWidth; - int exponent; - unsigned int uExponent = 0; - double dblBase; - BOOLEAN_T isNegative; - BOOLEAN_T isExponentNegative = FALSE; - BOOLEAN_T isHex; - const char *digits; - char numberBuffer[MAX_MANTISSA_DIGITS - * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1]; - char *numberPointer; - char exponentBuffer[MAX_EXPONENT_DIGITS + 1]; - char *exponentPointer = NULL; - int groupingIndex; - char *work; - int i; - BOOLEAN_T onlyzero; - int zeroes = 0; - - assert(VALID(self)); - assert(VALID(self->OutStream)); - assert(base == BASE_DECIMAL || base == BASE_HEX); - - number = (double)longdoubleNumber; - - /* Look for infinite numbers and non-a-number first */ - switch (TrioIsInfinite(number)) - { - case 1: - /* Positive infinity */ - TrioWriteString(self, - (flags & FLAGS_UPPER) - ? INFINITE_UPPER - : INFINITE_LOWER, - flags, width, precision); - return; - - case -1: - /* Negative infinity */ - TrioWriteString(self, - (flags & FLAGS_UPPER) - ? "-" INFINITE_UPPER - : "-" INFINITE_LOWER, - flags, width, precision); - return; - - default: - /* Finitude */ - break; - } - if (TrioIsNan(number)) - { - TrioWriteString(self, - (flags & FLAGS_UPPER) - ? NAN_UPPER - : NAN_LOWER, - flags, width, precision); - return; - } - - /* Normal numbers */ - digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower; - isHex = (base == BASE_HEX); - dblBase = (double)base; - - if (precision == NO_PRECISION) - precision = FLT_DIG; - - isNegative = (number < 0.0); - if (isNegative) - number = -number; - - if ((flags & FLAGS_FLOAT_G) || isHex) - { - if (precision == 0) - precision = 1; - - if ((number < 1.0e-4) || (number > pow(10.0, (double)precision))) - { - /* Use scientific notation */ - flags |= FLAGS_FLOAT_E; - } - else if (number < 1.0) - { - /* - * Use normal notation. If the integer part of the number is - * zero, then adjust the precision to include leading fractional - * zeros. - */ - workNumber = fabs(guarded_log10(number)); - if (workNumber - floor(workNumber) < 0.001) - workNumber--; - zeroes = (int)floor(workNumber); - } - } - - if (flags & FLAGS_FLOAT_E) - { - /* Scale the number */ - workNumber = guarded_log10(number); - if (workNumber == -HUGE_VAL) - { - exponent = 0; - /* Undo setting */ - if (flags & FLAGS_FLOAT_G) - flags &= ~FLAGS_FLOAT_E; - } - else - { - exponent = (int)floor(workNumber); - number /= pow(10.0, (double)exponent); - isExponentNegative = (exponent < 0); - uExponent = (isExponentNegative) ? -exponent : exponent; - /* No thousand separators */ - flags &= ~FLAGS_QUOTE; - } - } - - /* - * Truncated number. - * - * precision is number of significant digits for FLOAT_G - * and number of fractional digits for others - */ - integerDigits = (floor(number) > DBL_EPSILON) - ? 1 + (int)guarded_log10(floor(number)) - : 1; - fractionDigits = ((flags & FLAGS_FLOAT_G) && (zeroes == 0)) - ? precision - integerDigits - : zeroes + precision; - - number = floor(0.5 + number * pow(dblBase, (double)fractionDigits)); - workNumber = (isHex - ? guarded_log16(0.5 + number) - : guarded_log10(0.5 + number)); - if ((int)workNumber + 1 > integerDigits + fractionDigits) - { - if (flags & FLAGS_FLOAT_E) - { - /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */ - exponent--; - uExponent -= (isExponentNegative) ? 1 : -1; - number /= dblBase; - } - else - { - /* Adjust if number was rounded up one digit (ie. 99 to 100) */ - integerDigits++; - } - } - - /* Build the fraction part */ - numberPointer = &numberBuffer[sizeof(numberBuffer) - 1]; - *numberPointer = NIL; - onlyzero = TRUE; - for (i = 0; i < fractionDigits; i++) - { - *(--numberPointer) = digits[(int)fmod(number, dblBase)]; - number = floor(number / dblBase); - - if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_ALTERNATIVE)) - { - /* Prune trailing zeroes */ - if (numberPointer[0] != digits[0]) - onlyzero = FALSE; - else if (onlyzero && (numberPointer[0] == digits[0])) - numberPointer++; - } - else - onlyzero = FALSE; - } - - /* Insert decimal point */ - if ((flags & FLAGS_ALTERNATIVE) || ((fractionDigits > 0) && !onlyzero)) - { - i = StrLength(internalDecimalPoint); - while (i> 0) - { - *(--numberPointer) = internalDecimalPoint[--i]; - } - } - /* Insert the integer part and thousand separators */ - charsPerThousand = (int)internalGrouping[0]; - groupingIndex = 1; - for (i = 1; i < integerDigits + 1; i++) - { - *(--numberPointer) = digits[(int)fmod(number, dblBase)]; - number = floor(number / dblBase); - if (number < DBL_EPSILON) - break; - - if ((i > 0) - && ((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE) - && (charsPerThousand != NO_GROUPING) - && (i % charsPerThousand == 0)) - { - /* - * We are building the number from the least significant - * to the most significant digit, so we have to copy the - * thousand separator backwards - */ - length = StrLength(internalThousandSeparator); - integerDigits += length; - if (((int)(numberPointer - numberBuffer) - length) > 0) - { - work = &internalThousandSeparator[length - 1]; - while (length-- > 0) - *(--numberPointer) = *work--; - } - - /* Advance to next grouping number */ - if (charsPerThousand != NO_GROUPING) - { - switch (internalGrouping[groupingIndex]) - { - case CHAR_MAX: /* Disable grouping */ - charsPerThousand = NO_GROUPING; - break; - case 0: /* Repeat last group */ - break; - default: - charsPerThousand = (int)internalGrouping[groupingIndex++]; - break; - } - } - } - } - - /* Build the exponent */ - exponentDigits = 0; - if (flags & FLAGS_FLOAT_E) - { - exponentPointer = &exponentBuffer[sizeof(exponentBuffer) - 1]; - *exponentPointer-- = NIL; - do { - *exponentPointer-- = digits[uExponent % base]; - uExponent /= base; - exponentDigits++; - } while (uExponent); - } - - /* - * Calculate expected width. - * sign + integer part + thousands separators + decimal point - * + fraction + exponent - */ - expectedWidth = StrLength(numberPointer); - if (isNegative || (flags & FLAGS_SHOWSIGN)) - expectedWidth += sizeof("-") - 1; - if (exponentDigits > 0) - expectedWidth += exponentDigits + - ((exponentDigits > 1) ? sizeof("E+") : sizeof("E+0")) - 1; - if (isHex) - expectedWidth += sizeof("0X") - 1; - - /* Output prefixing */ - if (flags & FLAGS_NILPADDING) - { - /* Leading zeros must be after sign */ - if (isNegative) - self->OutStream(self, '-'); - else if (flags & FLAGS_SHOWSIGN) - self->OutStream(self, '+'); - if (isHex) - { - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); - } - if (!(flags & FLAGS_LEFTADJUST)) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, '0'); - } - } - } - else - { - /* Leading spaces must be before sign */ - if (!(flags & FLAGS_LEFTADJUST)) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, CHAR_ADJUST); - } - } - if (isNegative) - self->OutStream(self, '-'); - else if (flags & FLAGS_SHOWSIGN) - self->OutStream(self, '+'); - if (isHex) - { - self->OutStream(self, '0'); - self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x'); - } - } - /* Output number */ - for (i = 0; numberPointer[i]; i++) - { - self->OutStream(self, numberPointer[i]); - } - /* Output exponent */ - if (exponentDigits > 0) - { - self->OutStream(self, - isHex - ? ((flags & FLAGS_UPPER) ? 'P' : 'p') - : ((flags & FLAGS_UPPER) ? 'E' : 'e')); - self->OutStream(self, (isExponentNegative) ? '-' : '+'); - - /* The exponent must contain at least two digits */ - if (exponentDigits == 1) - self->OutStream(self, '0'); - - for (i = 0; i < exponentDigits; i++) - { - self->OutStream(self, exponentPointer[i + 1]); - } - } - /* Output trailing spaces */ - if (flags & FLAGS_LEFTADJUST) - { - for (i = expectedWidth; i < width; i++) - { - self->OutStream(self, CHAR_ADJUST); - } - } -} - -/************************************************************************* - * TrioFormatProcess [private] - */ -static int -TrioFormatProcess(trio_T *data, - const char *format, - parameter_T *parameters) - -{ -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - int charlen; -#endif - int i; - const char *string; - void *pointer; - unsigned long flags; - int width; - int precision; - int base; - int index; - - index = 0; - i = 0; -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - mblen(NULL, 0); -#endif - - while (format[index]) - { -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - if (! isascii(format[index])) - { - charlen = mblen(&format[index], MB_LEN_MAX); - while (charlen-- > 0) - { - data->OutStream(data, format[index++]); - } - continue; /* while */ - } -#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */ - if (CHAR_IDENTIFIER == format[index]) - { - if (CHAR_IDENTIFIER == format[index + 1]) - { - data->OutStream(data, CHAR_IDENTIFIER); - index += 2; - } - else - { - /* Skip the parameter entries */ - while (parameters[i].type == FORMAT_PARAMETER) - i++; - - flags = parameters[i].flags; - - /* Find width */ - width = parameters[i].width; - if (flags & FLAGS_WIDTH_PARAMETER) - { - /* Get width from parameter list */ - width = (int)parameters[width].data.number.as_signed; - } - - /* Find precision */ - if (flags & FLAGS_PRECISION) - { - precision = parameters[i].precision; - if (flags & FLAGS_PRECISION_PARAMETER) - { - /* Get precision from parameter list */ - precision = (int)parameters[precision].data.number.as_signed; - } - } - else - { - precision = NO_PRECISION; - } - - /* Find base */ - base = parameters[i].base; - if (flags & FLAGS_BASE_PARAMETER) - { - /* Get base from parameter list */ - base = (int)parameters[base].data.number.as_signed; - } - - switch (parameters[i].type) - { - case FORMAT_CHAR: - if (flags & FLAGS_QUOTE) - data->OutStream(data, CHAR_QUOTE); - if (! (flags & FLAGS_LEFTADJUST)) - { - while (--width > 0) - data->OutStream(data, CHAR_ADJUST); - } -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - TrioWriteWideStringCharacter(data, - (wchar_t)parameters[i].data.number.as_signed, - flags, - NO_WIDTH); - } - else -#endif - TrioWriteStringCharacter(data, - (int)parameters[i].data.number.as_signed, - flags); - - if (flags & FLAGS_LEFTADJUST) - { - while(--width > 0) - data->OutStream(data, CHAR_ADJUST); - } - if (flags & FLAGS_QUOTE) - data->OutStream(data, CHAR_QUOTE); - - break; /* FORMAT_CHAR */ - - case FORMAT_INT: - if (base == NO_BASE) - base = BASE_DECIMAL; - - TrioWriteNumber(data, - parameters[i].data.number.as_signed, - flags, - width, - precision, - base); - - break; /* FORMAT_INT */ - - case FORMAT_DOUBLE: - TrioWriteDouble(data, - parameters[i].data.longdoubleNumber, - flags, - width, - precision, - base); - break; /* FORMAT_DOUBLE */ - - case FORMAT_STRING: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - TrioWriteWideString(data, - parameters[i].data.wstring, - flags, - width, - precision); - } - else -#endif -#ifdef QUALIFIER_ESCAPE - { - char *s = NULL; - static const char* empty = "(null)"; - switch (parameters[i].escape) - { - case ESCAPE_ULM: - s = glite_lbu_EscapeULM(parameters[i].data.string); - break; - case ESCAPE_XML: - s = glite_lbu_EscapeXML(parameters[i].data.string); - break; - case ESCAPE_SQL: - s = glite_lbu_EscapeSQL(parameters[i].data.string); - break; - case ESCAPE_NONE: - s = strdup(parameters[i].data.string ? parameters[i].data.string : empty); - break; - } - TrioWriteString(data,s,flags,width,precision); - free(s); - } -#else - { - TrioWriteString(data, - parameters[i].data.string, - flags, - width, - precision); - } -#endif - break; /* FORMAT_STRING */ - - case FORMAT_POINTER: - { - reference_T reference; - - reference.data = data; - reference.parameter = ¶meters[i]; - trio_print_pointer(&reference, parameters[i].data.pointer); - } - break; /* FORMAT_POINTER */ - - case FORMAT_COUNT: - pointer = parameters[i].data.pointer; - if (NULL != pointer) - { - /* - * C99 paragraph 7.19.6.1.8 says "the number of - * characters written to the output stream so far by - * this call", which is data->committed - */ -#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER) - if (flags & FLAGS_SIZE_T) - *(size_t *)pointer = (size_t)data->committed; - else -#endif -#if defined(QUALIFIER_PTRDIFF_T) - if (flags & FLAGS_PTRDIFF_T) - *(ptrdiff_t *)pointer = (ptrdiff_t)data->committed; - else -#endif -#if defined(QUALIFIER_INTMAX_T) - if (flags & FLAGS_INTMAX_T) - *(trio_intmax_t *)pointer = (trio_intmax_t)data->committed; - else -#endif - if (flags & FLAGS_QUAD) - { - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->committed; - } - else if (flags & FLAGS_LONG) - { - *(long int *)pointer = (long int)data->committed; - } - else if (flags & FLAGS_SHORT) - { - *(short int *)pointer = (short int)data->committed; - } - else - { - *(int *)pointer = (int)data->committed; - } - } - break; /* FORMAT_COUNT */ - - case FORMAT_PARAMETER: - break; /* FORMAT_PARAMETER */ - -#if defined(FORMAT_ERRNO) - case FORMAT_ERRNO: - string = StrError(parameters[i].data.errorNumber); - if (string) - { - TrioWriteString(data, - string, - flags, - width, - precision); - } - else - { - data->OutStream(data, '#'); - TrioWriteNumber(data, - (trio_intmax_t)parameters[i].data.errorNumber, - flags, - width, - precision, - BASE_DECIMAL); - } - break; /* FORMAT_ERRNO */ -#endif /* defined(FORMAT_ERRNO) */ - -#if defined(FORMAT_USER_DEFINED) - case FORMAT_USER_DEFINED: - { - reference_T reference; - userdef_T *def = NULL; - - if (parameters[i].user_name[0] == NIL) - { - /* Use handle */ - if ((i > 0) || - (parameters[i - 1].type == FORMAT_PARAMETER)) - def = (userdef_T *)parameters[i - 1].data.pointer; - } - else - { - /* Look up namespace */ - def = TrioFindNamespace(parameters[i].user_name, NULL); - } - if (def) { - reference.data = data; - reference.parameter = ¶meters[i]; - def->callback(&reference); - } - } - break; -#endif /* defined(FORMAT_USER_DEFINED) */ - - default: - break; - } /* switch parameter type */ - - /* Prepare for next */ - index = parameters[i].indexAfterSpecifier; - i++; - } - } - else /* not identifier */ - { - data->OutStream(data, format[index++]); - } - } - return data->processed; -} - -/************************************************************************* - * TrioFormatRef [private] - */ -static int -TrioFormatRef(reference_T *reference, - const char *format, - va_list arglist, - void **argarray) -{ - int status; - parameter_T parameters[MAX_PARAMETERS]; - - status = TrioPreprocess(TYPE_PRINT, format, parameters, arglist, argarray); - if (status < 0) - return status; - - return TrioFormatProcess(reference->data, format, parameters); -} - -/************************************************************************* - * TrioFormat [private] - * - * Description: - * This is the main engine for formatting output - */ -static int -TrioFormat(void *destination, - size_t destinationSize, - void (*OutStream)(trio_T *, int), - const char *format, - va_list arglist, - void **argarray) -{ - int status; - trio_T data; - parameter_T parameters[MAX_PARAMETERS]; - - assert(VALID(OutStream)); - assert(VALID(format)); - - memset(&data, 0, sizeof(data)); - data.OutStream = OutStream; - data.location = destination; - data.max = destinationSize; - -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - - status = TrioPreprocess(TYPE_PRINT, format, parameters, arglist, argarray); - if (status < 0) - return status; - - return TrioFormatProcess(&data, format, parameters); -} - -/************************************************************************* - * TrioOutStreamFile [private] - */ -static void -TrioOutStreamFile(trio_T *self, - int output) -{ - FILE *file = (FILE *)self->location; - - assert(VALID(self)); - assert(VALID(file)); - - self->processed++; - self->committed++; - (void)fputc(output, file); -} - -/************************************************************************* - * TrioOutStreamFileDescriptor [private] - */ -static void -TrioOutStreamFileDescriptor(trio_T *self, - int output) -{ - int fd = *((int *)self->location); - char ch; - - assert(VALID(self)); - - ch = (char)output; - (void)write(fd, &ch, sizeof(char)); - self->processed++; - self->committed++; -} - -/************************************************************************* - * TrioOutStreamString [private] - */ -static void -TrioOutStreamString(trio_T *self, - int output) -{ - char **buffer = (char **)self->location; - - assert(VALID(self)); - assert(VALID(buffer)); - - **buffer = (char)output; - (*buffer)++; - self->processed++; - self->committed++; -} - -/************************************************************************* - * TrioOutStreamStringMax [private] - */ -static void -TrioOutStreamStringMax(trio_T *self, - int output) -{ - char **buffer; - - assert(VALID(self)); - buffer = (char **)self->location; - assert(VALID(buffer)); - - if (self->processed < self->max) - { - **buffer = (char)output; - (*buffer)++; - self->committed++; - } - self->processed++; -} - -/************************************************************************* - * TrioOutStreamStringDynamic [private] - */ -#define DYNAMIC_START_SIZE 32 -struct dynamicBuffer { - char *buffer; - size_t length; - size_t allocated; -}; - -static void -TrioOutStreamStringDynamic(trio_T *self, - int output) -{ - struct dynamicBuffer *infop; - - assert(VALID(self)); - assert(VALID(self->location)); - - infop = (struct dynamicBuffer *)self->location; - - if (infop->buffer == NULL) - { - /* Start with a reasonable size */ - infop->buffer = (char *)TRIO_MALLOC(DYNAMIC_START_SIZE); - if (infop->buffer == NULL) - return; /* fail */ - - infop->allocated = DYNAMIC_START_SIZE; - self->processed = 0; - self->committed = 0; - } - else if (self->committed + sizeof(NIL) >= infop->allocated) - { - char *newptr; - - /* Allocate increasing chunks */ - newptr = (char *)TRIO_REALLOC(infop->buffer, infop->allocated * 2); - - if (newptr == NULL) - return; - - infop->buffer = newptr; - infop->allocated *= 2; - } - - infop->buffer[self->committed] = (char)output; - self->committed++; - self->processed++; - - infop->length = self->committed; -} - -/************************************************************************* - * printf - */ -int -trio_printf(const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(format)); - - va_start(args, format); - status = TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vprintf(const char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL); -} - -#ifdef __GNUC__ -#define UNUSED_VAR __attribute__((unused)) -#else -#define UNUSED_VAR -#endif - -static void shutup_unitialized(va_list *dummy UNUSED_VAR) { -} - -int -trio_printfv(const char *format, - void ** args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(format)); - - return TrioFormat(stdout, 0, TrioOutStreamFile, format, dummy, args); -} - -/************************************************************************* - * fprintf - */ -int -trio_fprintf(FILE *file, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(file)); - assert(VALID(format)); - - va_start(args, format); - status = TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vfprintf(FILE *file, - const char *format, - va_list args) -{ - assert(VALID(file)); - assert(VALID(format)); - - return TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL); -} - -int -trio_fprintfv(FILE *file, - const char *format, - void ** args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(file)); - assert(VALID(format)); - - return TrioFormat(file, 0, TrioOutStreamFile, format, dummy, args); -} - -/************************************************************************* - * dprintf - */ -int -trio_dprintf(int fd, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(format)); - - va_start(args, format); - status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vdprintf(int fd, - const char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL); -} - -int -trio_dprintfv(int fd, - const char *format, - void **args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(format)); - - return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, dummy, args); -} - -/************************************************************************* - * sprintf - */ -int -trio_sprintf(char *buffer, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(buffer)); - assert(VALID(format)); - - va_start(args, format); - status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL); - *buffer = NIL; /* Terminate with NIL character */ - va_end(args); - return status; -} - -int -trio_vsprintf(char *buffer, - const char *format, - va_list args) -{ - int status; - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL); - *buffer = NIL; - return status; -} - -int -trio_sprintfv(char *buffer, - const char *format, - void **args) -{ - int status; - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, 0, TrioOutStreamString, format, dummy, args); - *buffer = NIL; - return status; -} - -/************************************************************************* - * snprintf - */ -int -trio_snprintf(char *buffer, - size_t bufferSize, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(buffer)); - assert(VALID(format)); - - va_start(args, format); - status = TrioFormat(&buffer, bufferSize > 0 ? bufferSize - 1 : 0, - TrioOutStreamStringMax, format, args, NULL); - if (bufferSize > 0) - *buffer = NIL; - va_end(args); - return status; -} - -int -trio_vsnprintf(char *buffer, - size_t bufferSize, - const char *format, - va_list args) -{ - int status; - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, bufferSize > 0 ? bufferSize - 1 : 0, - TrioOutStreamStringMax, format, args, NULL); - if (bufferSize > 0) - *buffer = NIL; - return status; -} - -int -trio_snprintfv(char *buffer, - size_t bufferSize, - const char *format, - void **args) -{ - int status; - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(buffer)); - assert(VALID(format)); - - status = TrioFormat(&buffer, bufferSize > 0 ? bufferSize - 1 : 0, - TrioOutStreamStringMax, format, dummy, args); - if (bufferSize > 0) - *buffer = NIL; - return status; -} - -/************************************************************************* - * snprintfcat - * Appends the new string to the buffer string overwriting the '\0' - * character at the end of buffer. - */ -int -trio_snprintfcat(char *buffer, - size_t bufferSize, - const char *format, - ...) -{ - int status; - va_list args; - size_t buf_len; - - va_start(args, format); - - assert(VALID(buffer)); - assert(VALID(format)); - - buf_len = strlen(buffer); - buffer = &buffer[buf_len]; - - status = TrioFormat(&buffer, bufferSize - 1 - buf_len, - TrioOutStreamStringMax, format, args, NULL); - va_end(args); - *buffer = NIL; - return status; -} - -int -trio_vsnprintfcat(char *buffer, - size_t bufferSize, - const char *format, - va_list args) -{ - int status; - size_t buf_len; - assert(VALID(buffer)); - assert(VALID(format)); - - buf_len = strlen(buffer); - buffer = &buffer[buf_len]; - status = TrioFormat(&buffer, bufferSize - 1 - buf_len, - TrioOutStreamStringMax, format, args, NULL); - *buffer = NIL; - return status; -} - -/************************************************************************* - * trio_aprintf - */ - -/* Deprecated */ -char * -trio_aprintf(const char *format, - ...) -{ - va_list args; - struct dynamicBuffer info; - - assert(VALID(format)); - - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - va_start(args, format); - (void)TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - va_end(args); - if (info.length) { - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return NULL; -} - -/* Deprecated */ -char * -trio_vaprintf(const char *format, - va_list args) -{ - struct dynamicBuffer info; - - assert(VALID(format)); - - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - (void)TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - if (info.length) { - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return NULL; -} - -int -trio_asprintf(char **result, - const char *format, - ...) -{ - va_list args; - int status; - struct dynamicBuffer info; - - assert(VALID(format)); - - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - va_start(args, format); - status = TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - va_end(args); - if (status < 0) { - *result = NULL; - return status; - } - if (info.length == 0) { - /* - * If the length is zero, no characters have been written and therefore - * no memory has been allocated, but we must to allocate and return an - * empty string. - */ - info.buffer = (char *)TRIO_MALLOC(sizeof(char)); - if (info.buffer == NULL) { - *result = NULL; - return TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); - } - } - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - *result = info.buffer; - - return status; -} - -int -trio_vasprintf(char **result, - const char *format, - va_list args) -{ - int status; - struct dynamicBuffer info; - - assert(VALID(format)); - - info.buffer = NULL; - info.length = 0; - info.allocated = 0; - - status = TrioFormat(&info, 0, TrioOutStreamStringDynamic, format, args, NULL); - if (status < 0) { - *result = NULL; - return status; - } - if (info.length == 0) { - info.buffer = (char *)TRIO_MALLOC(sizeof(char)); - if (info.buffer == NULL) { - *result = NULL; - return TRIO_ERROR_RETURN(TRIO_ENOMEM, 0); - } - } - info.buffer[info.length] = NIL; /* we terminate this with a zero byte */ - *result = info.buffer; - - return status; -} - - -/************************************************************************* - * - * @CALLBACK - * - ************************************************************************/ - - -/************************************************************************* - * trio_register [public] - */ -void * -trio_register(trio_callback_t callback, - const char *name) -{ - userdef_T *def; - userdef_T *prev = NULL; - - if (callback == NULL) - return NULL; - - if (name) - { - /* Handle built-in namespaces */ - if (name[0] == ':') - { - if (StrEqual(name, ":enter")) - { - internalEnterCriticalRegion = callback; - } - else if (StrEqual(name, ":leave")) - { - internalLeaveCriticalRegion = callback; - } - return NULL; - } - - /* Bail out if namespace is too long */ - if (StrLength(name) >= MAX_USER_NAME) - return NULL; - - /* Bail out if namespace already is registered */ - def = TrioFindNamespace(name, &prev); - if (def) - return NULL; - } - - def = (userdef_T *)TRIO_MALLOC(sizeof(userdef_T)); - if (def) - { - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - if (name) - { - /* Link into internal list */ - if (prev == NULL) - internalUserDef = def; - else - prev->next = def; - } - /* Initialize */ - def->callback = callback; - def->name = (name == NULL) - ? NULL - : StrDuplicate(name); - def->next = NULL; - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - } - return def; -} - -/************************************************************************* - * trio_unregister [public] - */ -void -trio_unregister(void *handle) -{ - userdef_T *self = (userdef_T *)handle; - userdef_T *def; - userdef_T *prev = NULL; - - assert(VALID(self)); - - if (self->name) - { - def = TrioFindNamespace(self->name, &prev); - if (def) - { - if (internalEnterCriticalRegion) - (void)internalEnterCriticalRegion(NULL); - - if (prev == NULL) - internalUserDef = NULL; - else - prev->next = def->next; - - if (internalLeaveCriticalRegion) - (void)internalLeaveCriticalRegion(NULL); - } - StrFree(self->name); - } - TRIO_FREE(self); -} - -/************************************************************************* - * trio_get_format [public] - */ -const char * -trio_get_format(void *ref) -{ - assert(((reference_T *)ref)->parameter->type == FORMAT_USER_DEFINED); - - return (((reference_T *)ref)->parameter->user_data); -} - -/************************************************************************* - * trio_get_argument [public] - */ -void * -trio_get_argument(void *ref) -{ - assert(((reference_T *)ref)->parameter->type == FORMAT_USER_DEFINED); - - return ((reference_T *)ref)->parameter->data.pointer; -} - -/************************************************************************* - * trio_get_width / trio_set_width [public] - */ -int -trio_get_width(void *ref) -{ - return ((reference_T *)ref)->parameter->width; -} - -void -trio_set_width(void *ref, - int width) -{ - ((reference_T *)ref)->parameter->width = width; -} - -/************************************************************************* - * trio_get_precision / trio_set_precision [public] - */ -int -trio_get_precision(void *ref) -{ - return (((reference_T *)ref)->parameter->precision); -} - -void -trio_set_precision(void *ref, - int precision) -{ - ((reference_T *)ref)->parameter->precision = precision; -} - -/************************************************************************* - * trio_get_base / trio_set_base [public] - */ -int -trio_get_base(void *ref) -{ - return (((reference_T *)ref)->parameter->base); -} - -void -trio_set_base(void *ref, - int base) -{ - ((reference_T *)ref)->parameter->base = base; -} - -/************************************************************************* - * trio_get_long / trio_set_long [public] - */ -int -trio_get_long(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_LONG); -} - -void -trio_set_long(void *ref, - int is_long) -{ - if (is_long) - ((reference_T *)ref)->parameter->flags |= FLAGS_LONG; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_LONG; -} - -/************************************************************************* - * trio_get_longlong / trio_set_longlong [public] - */ -int -trio_get_longlong(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_QUAD); -} - -void -trio_set_longlong(void *ref, - int is_longlong) -{ - if (is_longlong) - ((reference_T *)ref)->parameter->flags |= FLAGS_QUAD; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_QUAD; -} - -/************************************************************************* - * trio_get_longdouble / trio_set_longdouble [public] - */ -int -trio_get_longdouble(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_LONGDOUBLE); -} - -void -trio_set_longdouble(void *ref, - int is_longdouble) -{ - if (is_longdouble) - ((reference_T *)ref)->parameter->flags |= FLAGS_LONGDOUBLE; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE; -} - -/************************************************************************* - * trio_get_short / trio_set_short [public] - */ -int -trio_get_short(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_SHORT); -} - -void -trio_set_short(void *ref, - int is_short) -{ - if (is_short) - ((reference_T *)ref)->parameter->flags |= FLAGS_SHORT; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SHORT; -} - -/************************************************************************* - * trio_get_shortshort / trio_set_shortshort [public] - */ -int -trio_get_shortshort(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_SHORTSHORT); -} - -void -trio_set_shortshort(void *ref, - int is_shortshort) -{ - if (is_shortshort) - ((reference_T *)ref)->parameter->flags |= FLAGS_SHORTSHORT; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT; -} - -/************************************************************************* - * trio_get_alternative / trio_set_alternative [public] - */ -int -trio_get_alternative(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_ALTERNATIVE); -} - -void -trio_set_alternative(void *ref, - int is_alternative) -{ - if (is_alternative) - ((reference_T *)ref)->parameter->flags |= FLAGS_ALTERNATIVE; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE; -} - -/************************************************************************* - * trio_get_alignment / trio_set_alignment [public] - */ -int -trio_get_alignment(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_LEFTADJUST); -} - -void -trio_set_alignment(void *ref, - int is_leftaligned) -{ - if (is_leftaligned) - ((reference_T *)ref)->parameter->flags |= FLAGS_LEFTADJUST; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST; -} - -/************************************************************************* - * trio_get_spacing /trio_set_spacing [public] - */ -int -trio_get_spacing(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_SPACE); -} - -void -trio_set_spacing(void *ref, - int is_space) -{ - if (is_space) - ((reference_T *)ref)->parameter->flags |= FLAGS_SPACE; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SPACE; -} - -/************************************************************************* - * trio_get_sign / trio_set_sign [public] - */ -int -trio_get_sign(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_SHOWSIGN); -} - -void -trio_set_sign(void *ref, - int is_sign) -{ - if (is_sign) - ((reference_T *)ref)->parameter->flags |= FLAGS_SHOWSIGN; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN; -} - -/************************************************************************* - * trio_get_padding / trio_set_padding [public] - */ -int -trio_get_padding(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_NILPADDING); -} - -void -trio_set_padding(void *ref, - int is_padding) -{ - if (is_padding) - ((reference_T *)ref)->parameter->flags |= FLAGS_NILPADDING; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_NILPADDING; -} - -/************************************************************************* - * trio_get_quote / trio_set_quote [public] - */ -int -trio_get_quote(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_QUOTE); -} - -void -trio_set_quote(void *ref, - int is_quote) -{ - if (is_quote) - ((reference_T *)ref)->parameter->flags |= FLAGS_QUOTE; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_QUOTE; -} - -/************************************************************************* - * trio_get_upper / trio_set_upper [public] - */ -int -trio_get_upper(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_UPPER); -} - -void -trio_set_upper(void *ref, - int is_upper) -{ - if (is_upper) - ((reference_T *)ref)->parameter->flags |= FLAGS_UPPER; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_UPPER; -} - -/************************************************************************* - * trio_get_largest / trio_set_largest [public] - */ -#if TRIO_C99 -int -trio_get_largest(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_INTMAX_T); -} - -void -trio_set_largest(void *ref, - int is_largest) -{ - if (is_largest) - ((reference_T *)ref)->parameter->flags |= FLAGS_INTMAX_T; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_INTMAX_T; -} -#endif - -/************************************************************************* - * trio_get_ptrdiff / trio_set_ptrdiff [public] - */ -int -trio_get_ptrdiff(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_PTRDIFF_T); -} - -void -trio_set_ptrdiff(void *ref, - int is_ptrdiff) -{ - if (is_ptrdiff) - ((reference_T *)ref)->parameter->flags |= FLAGS_PTRDIFF_T; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T; -} - -/************************************************************************* - * trio_get_size / trio_set_size [public] - */ -#if TRIO_C99 -int -trio_get_size(void *ref) -{ - return (((reference_T *)ref)->parameter->flags & FLAGS_SIZE_T); -} - -void -trio_set_size(void *ref, - int is_size) -{ - if (is_size) - ((reference_T *)ref)->parameter->flags |= FLAGS_SIZE_T; - else - ((reference_T *)ref)->parameter->flags &= ~FLAGS_SIZE_T; -} -#endif - -/************************************************************************* - * trio_print_int [public] - */ -void -trio_print_int(void *ref, - int number) -{ - reference_T *self = (reference_T *)ref; - - TrioWriteNumber(self->data, - (trio_intmax_t)number, - self->parameter->flags, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} - -/************************************************************************* - * trio_print_uint [public] - */ -void -trio_print_uint(void *ref, - unsigned int number) -{ - reference_T *self = (reference_T *)ref; - - TrioWriteNumber(self->data, - (trio_intmax_t)number, - self->parameter->flags | FLAGS_UNSIGNED, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} - -/************************************************************************* - * trio_print_double [public] - */ -void -trio_print_double(void *ref, - double number) -{ - reference_T *self = (reference_T *)ref; - - TrioWriteDouble(self->data, - number, - self->parameter->flags, - self->parameter->width, - self->parameter->precision, - self->parameter->base); -} - -/************************************************************************* - * trio_print_string [public] - */ -void -trio_print_string(void *ref, - char *string) -{ - reference_T *self = (reference_T *)ref; - - TrioWriteString(self->data, - string, - self->parameter->flags, - self->parameter->width, - self->parameter->precision); -} - -/************************************************************************* - * trio_print_pointer [public] - */ -void -trio_print_pointer(void *ref, - void *pointer) -{ - reference_T *self = (reference_T *)ref; - unsigned long flags; - trio_uintmax_t number; - - if (NULL == pointer) - { - const char *string = null; - while (*string) - self->data->OutStream(self->data, *string++); - } - else - { - /* - * The subtraction of the null pointer is a workaround - * to avoid a compiler warning. The performance overhead - * is negligible (and likely to be removed by an - * optimising compiler). The (char *) casting is done - * to please ANSI C++. - */ - number = (trio_uintmax_t)((char *)pointer - (char *)0); - /* Shrink to size of pointer */ - number &= (trio_uintmax_t)-1; - flags = self->parameter->flags; - flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | - FLAGS_NILPADDING); - TrioWriteNumber(self->data, - (trio_intmax_t)number, - flags, - POINTER_WIDTH, - NO_PRECISION, - BASE_HEX); - } -} - -/************************************************************************* - * trio_print_ref [public] - */ -int -trio_print_ref(void *ref, - const char *format, - ...) -{ - int status; - va_list arglist; - - assert(VALID(format)); - - va_start(arglist, format); - status = TrioFormatRef((reference_T *)ref, format, arglist, NULL); - va_end(arglist); - return status; -} - -/************************************************************************* - * trio_vprint_ref [public] - */ -int -trio_vprint_ref(void *ref, - const char *format, - va_list arglist) -{ - assert(VALID(format)); - - return TrioFormatRef((reference_T *)ref, format, arglist, NULL); -} - -/************************************************************************* - * trio_printv_ref [public] - */ -int -trio_printv_ref(void *ref, - const char *format, - void **argarray) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(format)); - - return TrioFormatRef((reference_T *)ref, format, dummy, argarray); -} - - -/************************************************************************* - * - * @SCANNING - * - ************************************************************************/ - - -/************************************************************************* - * TrioSkipWhitespaces [private] - */ -static int -TrioSkipWhitespaces(trio_T *self) -{ - int ch; - - ch = self->current; - while (isspace(ch)) - { - self->InStream(self, &ch); - } - return ch; -} - -/************************************************************************* - * TrioGetCollation [private] - */ -#if TRIO_EXTENSION -static void -TrioGetCollation() -{ - int i; - int j; - int k; - char first[2]; - char second[2]; - - /* This is computational expensive */ - first[1] = NIL; - second[1] = NIL; - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - { - k = 0; - first[0] = (char)i; - for (j = 0; j < MAX_CHARACTER_CLASS; j++) - { - second[0] = (char)j; - if (StrEqualLocale(first, second)) - internalCollationArray[i][k++] = (char)j; - } - internalCollationArray[i][k] = NIL; - } -} -#endif - -/************************************************************************* - * TrioGetCharacterClass [private] - * - * FIXME: - * multibyte - */ -static int -TrioGetCharacterClass(const char *format, - int *indexPointer, - unsigned long *flagsPointer, - int *characterclass) -{ - int index = *indexPointer; - int i; - char ch; - char range_begin; - char range_end; - - *flagsPointer &= ~FLAGS_EXCLUDE; - - if (format[index] == QUALIFIER_CIRCUMFLEX) - { - *flagsPointer |= FLAGS_EXCLUDE; - index++; - } - /* - * If the ungroup character is at the beginning of the scanlist, - * it will be part of the class, and a second ungroup character - * must follow to end the group. - */ - if (format[index] == SPECIFIER_UNGROUP) - { - characterclass[(int)SPECIFIER_UNGROUP]++; - index++; - } - /* - * Minus is used to specify ranges. To include minus in the class, - * it must be at the beginning of the list - */ - if (format[index] == QUALIFIER_MINUS) - { - characterclass[(int)QUALIFIER_MINUS]++; - index++; - } - /* Collect characters */ - for (ch = format[index]; - (ch != SPECIFIER_UNGROUP) && (ch != NIL); - ch = format[++index]) - { - switch (ch) - { - case QUALIFIER_MINUS: /* Scanlist ranges */ - - /* - * Both C99 and UNIX98 describes ranges as implementation- - * defined. - * - * We support the following behaviour (although this may - * change as we become wiser) - * - only increasing ranges, ie. [a-b] but not [b-a] - * - transitive ranges, ie. [a-b-c] == [a-c] - * - trailing minus, ie. [a-] is interpreted as an 'a' - * and a '-' - * - duplicates (although we can easily convert these - * into errors) - */ - range_begin = format[index - 1]; - range_end = format[++index]; - if (range_end == SPECIFIER_UNGROUP) - { - /* Trailing minus is included */ - characterclass[(int)ch]++; - ch = range_end; - break; /* for */ - } - if (range_end == NIL) - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - if (range_begin > range_end) - return TRIO_ERROR_RETURN(TRIO_ERANGE, index); - - for (i = (int)range_begin; i <= (int)range_end; i++) - characterclass[i]++; - - ch = range_end; - break; - -#if TRIO_EXTENSION - - case SPECIFIER_GROUP: - - switch (format[index + 1]) - { - case QUALIFIER_DOT: /* Collating symbol */ - /* - * FIXME: This will be easier to implement when multibyte - * characters have been implemented. Until now, we ignore - * this feature. - */ - for (i = index + 2; ; i++) - { - if (format[i] == NIL) - /* Error in syntax */ - return -1; - else if (format[i] == QUALIFIER_DOT) - break; /* for */ - } - if (format[++i] != SPECIFIER_UNGROUP) - return -1; - - index = i; - break; - - case QUALIFIER_EQUAL: /* Equivalence class expressions */ - { - unsigned int j; - unsigned int k; - - if (internalCollationUnconverted) - { - /* Lazy evalutation of collation array */ - TrioGetCollation(); - internalCollationUnconverted = FALSE; - } - for (i = index + 2; ; i++) - { - if (format[i] == NIL) - /* Error in syntax */ - return -1; - else if (format[i] == QUALIFIER_EQUAL) - break; /* for */ - else - { - /* Mark any equivalent character */ - k = (unsigned int)format[i]; - for (j = 0; internalCollationArray[k][j] != NIL; j++) - characterclass[(int)internalCollationArray[k][j]]++; - } - } - if (format[++i] != SPECIFIER_UNGROUP) - return -1; - - index = i; - } - break; - - case QUALIFIER_COLON: /* Character class expressions */ - - if (StrEqualMax(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isalnum(i)) - characterclass[i]++; - index += sizeof(CLASS_ALNUM) - 1; - } - else if (StrEqualMax(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isalpha(i)) - characterclass[i]++; - index += sizeof(CLASS_ALPHA) - 1; - } - else if (StrEqualMax(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (iscntrl(i)) - characterclass[i]++; - index += sizeof(CLASS_CNTRL) - 1; - } - else if (StrEqualMax(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isdigit(i)) - characterclass[i]++; - index += sizeof(CLASS_DIGIT) - 1; - } - else if (StrEqualMax(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isgraph(i)) - characterclass[i]++; - index += sizeof(CLASS_GRAPH) - 1; - } - else if (StrEqualMax(CLASS_LOWER, sizeof(CLASS_LOWER) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (islower(i)) - characterclass[i]++; - index += sizeof(CLASS_LOWER) - 1; - } - else if (StrEqualMax(CLASS_PRINT, sizeof(CLASS_PRINT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isprint(i)) - characterclass[i]++; - index += sizeof(CLASS_PRINT) - 1; - } - else if (StrEqualMax(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (ispunct(i)) - characterclass[i]++; - index += sizeof(CLASS_PUNCT) - 1; - } - else if (StrEqualMax(CLASS_SPACE, sizeof(CLASS_SPACE) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isspace(i)) - characterclass[i]++; - index += sizeof(CLASS_SPACE) - 1; - } - else if (StrEqualMax(CLASS_UPPER, sizeof(CLASS_UPPER) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isupper(i)) - characterclass[i]++; - index += sizeof(CLASS_UPPER) - 1; - } - else if (StrEqualMax(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1, - &format[index])) - { - for (i = 0; i < MAX_CHARACTER_CLASS; i++) - if (isxdigit(i)) - characterclass[i]++; - index += sizeof(CLASS_XDIGIT) - 1; - } - else - { - characterclass[(int)ch]++; - } - break; - - default: - characterclass[(int)ch]++; - break; - } - break; - -#endif /* TRIO_EXTENSION */ - - default: - characterclass[(int)ch]++; - break; - } - } - return 0; -} - -/************************************************************************* - * TrioReadNumber [private] - * - * We implement our own number conversion in preference of strtol and - * strtoul, because we must handle 'long long' and thousand separators. - */ -static BOOLEAN_T -TrioReadNumber(trio_T *self, - trio_uintmax_t *target, - unsigned long flags, - int width, - int base) -{ - trio_uintmax_t number = 0; - int digit; - int count; - BOOLEAN_T isNegative = FALSE; - int j; - - assert(VALID(self)); - assert(VALID(self->InStream)); - assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE)); - - if (internalDigitsUnconverted) - { - /* Lazy evaluation of digits array */ - memset(internalDigitArray, -1, sizeof(internalDigitArray)); - for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++) - { - internalDigitArray[(int)internalDigitsLower[j]] = j; - internalDigitArray[(int)internalDigitsUpper[j]] = j; - } - internalDigitsUnconverted = FALSE; - } - - TrioSkipWhitespaces(self); - - if (!(flags & FLAGS_UNSIGNED)) - { - /* Leading sign */ - if (self->current == '+') - { - self->InStream(self, NULL); - } - else if (self->current == '-') - { - self->InStream(self, NULL); - isNegative = TRUE; - } - } - - count = self->processed; - - if (flags & FLAGS_ALTERNATIVE) - { - switch (base) - { - case NO_BASE: - case BASE_OCTAL: - case BASE_HEX: - case BASE_BINARY: - if (self->current == '0') - { - self->InStream(self, NULL); - if (self->current) - { - if ((base == BASE_HEX) && - (toupper(self->current) == 'X')) - { - self->InStream(self, NULL); - } - else if ((base == BASE_BINARY) && - (toupper(self->current) == 'B')) - { - self->InStream(self, NULL); - } - } - } - else - return FALSE; - break; - default: - break; - } - } - - while (((width == NO_WIDTH) || (self->processed - count < width)) && - (! ((self->current == EOF) || isspace(self->current)))) - { - if (isascii(self->current)) - { - digit = internalDigitArray[self->current]; - /* Abort if digit is not allowed in the specified base */ - if ((digit == -1) || (digit >= base)) - break; - } - else if (flags & FLAGS_QUOTE) - { - /* Compare with thousands separator */ - for (j = 0; internalThousandSeparator[j] && self->current; j++) - { - if (internalThousandSeparator[j] != self->current) - break; - - self->InStream(self, NULL); - } - if (internalThousandSeparator[j]) - break; /* Mismatch */ - else - continue; /* Match */ - } - else - break; - - number *= base; - number += digit; - - self->InStream(self, NULL); - } - - /* Was anything read at all? */ - if (self->processed == count) - return FALSE; - - if (target) - *target = (isNegative) ? -number : number; - return TRUE; -} - -/************************************************************************* - * TrioReadChar [private] - */ -static int -TrioReadChar(trio_T *self, - char *target, - unsigned long flags, - int width) -{ - int i; - char ch; - trio_uintmax_t number; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - for (i = 0; - (self->current != EOF) && (i < width); - i++) - { - ch = (char)self->current; - self->InStream(self, NULL); - if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH)) - { - switch (self->current) - { - case '\\': ch = '\\'; break; - case 'a': ch = '\007'; break; - case 'b': ch = '\b'; break; - case 'f': ch = '\f'; break; - case 'n': ch = '\n'; break; - case 'r': ch = '\r'; break; - case 't': ch = '\t'; break; - case 'v': ch = '\v'; break; - default: - if (isdigit(self->current)) - { - /* Read octal number */ - if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL)) - return 0; - ch = (char)number; - } - else if (toupper(self->current) == 'X') - { - /* Read hexadecimal number */ - self->InStream(self, NULL); - if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX)) - return 0; - ch = (char)number; - } - else - { - ch = (char)self->current; - } - break; - } - } - - if (target) - target[i] = ch; - } - return i + 1; -} - -/************************************************************************* - * TrioReadString [private] - */ -static BOOLEAN_T -TrioReadString(trio_T *self, - char *target, - unsigned long flags, - int width) -{ - int i; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - TrioSkipWhitespaces(self); - - /* - * Continue until end of string is reached, a whitespace is encountered, - * or width is exceeded - */ - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((self->current == EOF) || isspace(self->current))); - i++) - { - if (TrioReadChar(self, &target[i], flags, 1) == 0) - break; /* for */ - } - if (target) - target[i] = NIL; - return TRUE; -} - -/************************************************************************* - * TrioReadWideChar [private] - */ -#if TRIO_WIDECHAR -static int -TrioReadWideChar(trio_T *self, - wchar_t *target, - unsigned long flags, - int width) -{ - int i; - int j; - int size; - int amount = 0; - wchar_t wch; - char buffer[MB_LEN_MAX + 1]; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - for (i = 0; - (self->current != EOF) && (i < width); - i++) - { - if (isascii(self->current)) - { - if (TrioReadChar(self, buffer, flags, 1) == 0) - return 0; - buffer[1] = NIL; - } - else - { - /* - * Collect a multibyte character, by enlarging buffer until - * it contains a fully legal multibyte character, or the - * buffer is full. - */ - j = 0; - do - { - buffer[j++] = (char)self->current; - buffer[j] = NIL; - self->InStream(self, NULL); - } - while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j)); - } - if (target) - { - size = mbtowc(&wch, buffer, sizeof(buffer)); - if (size > 0) - target[i] = wch; - } - amount += size; - self->InStream(self, NULL); - } - return amount; -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * TrioReadWideString [private] - */ -#if TRIO_WIDECHAR -static BOOLEAN_T -TrioReadWideString(trio_T *self, - wchar_t *target, - unsigned long flags, - int width) -{ - int i; - int size; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - TrioSkipWhitespaces(self); - -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - mblen(NULL, 0); -#endif - - /* - * Continue until end of string is reached, a whitespace is encountered, - * or width is exceeded - */ - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((self->current == EOF) || isspace(self->current))); - ) - { - size = TrioReadWideChar(self, &target[i], flags, 1); - if (size == 0) - break; /* for */ - - i += size; - } - if (target) - target[i] = L'\0'; - return TRUE; -} -#endif /* TRIO_WIDECHAR */ - -/************************************************************************* - * TrioReadGroup [private] - * - * FIXME: characterclass does not work with multibyte characters - */ -static BOOLEAN_T -TrioReadGroup(trio_T *self, - char *target, - int *characterclass, - unsigned long flags, - int width) -{ - int ch; - int i; - - assert(VALID(self)); - assert(VALID(self->InStream)); - - ch = self->current; - for (i = 0; - ((width == NO_WIDTH) || (i < width)) && - (! ((ch == EOF) || - (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0)))); - i++) - { - if (target) - target[i] = (char)ch; - self->InStream(self, &ch); - } - - if (target) - target[i] = NIL; - return TRUE; -} - -/************************************************************************* - * TrioReadDouble [private] - * - * FIXME: - * add long double - */ -static BOOLEAN_T -TrioReadDouble(trio_T *self, - double *target, - unsigned long flags, - int width) -{ - int ch; - char doubleString[512] = ""; - int index = 0; - int start; - int j; - BOOLEAN_T isHex = FALSE; - - if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1)) - width = sizeof(doubleString) - 1; - - TrioSkipWhitespaces(self); - - /* - * Read entire double number from stream. StrToDouble requires a - * string as input, but InStream can be anything, so we have to - * collect all characters. - */ - ch = self->current; - if ((ch == '+') || (ch == '-')) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - width--; - } - - start = index; - switch (ch) - { - case 'n': - case 'N': - /* Not-a-number */ - if (index != 0) - break; - /* FALLTHROUGH */ - case 'i': - case 'I': - /* Infinity */ - while (isalpha(ch) && (index - start < width)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - doubleString[index] = NIL; - - /* Case insensitive string comparison */ - if (StrEqual(&doubleString[start], INFINITE_UPPER) || - StrEqual(&doubleString[start], LONG_INFINITE_UPPER)) - { - *target = ((start == 1 && doubleString[0] == '-')) - ? -HUGE_VAL - : HUGE_VAL; - return TRUE; - } - if (StrEqual(doubleString, NAN_LOWER)) - { - /* NaN must not have a preceeding + nor - */ - *target = TrioGenerateNaN(); - return TRUE; - } - return FALSE; - - default: - break; - } - - if (ch == '0') - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - if (toupper(ch) == 'X') - { - isHex = TRUE; - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - } - while ((ch != EOF) && (index - start < width)) - { - /* Integer part */ - if (isHex ? isxdigit(ch) : isdigit(ch)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - else if (flags & FLAGS_QUOTE) - { - /* Compare with thousands separator */ - for (j = 0; internalThousandSeparator[j] && self->current; j++) - { - if (internalThousandSeparator[j] != self->current) - break; - - self->InStream(self, &ch); - } - if (internalThousandSeparator[j]) - break; /* Mismatch */ - else - continue; /* Match */ - } - else - break; /* while */ - } - if (ch == '.') - { - /* Decimal part */ - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - while ((isHex ? isxdigit(ch) : isdigit(ch)) && - (index - start < width)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - if (isHex ? (toupper(ch) == 'P') : (toupper(ch) == 'E')) - { - /* Exponent */ - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - if ((ch == '+') || (ch == '-')) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - while ((isHex ? isxdigit(ch) : isdigit(ch)) && - (index - start < width)) - { - doubleString[index++] = (char)ch; - self->InStream(self, &ch); - } - } - } - - if ((index == start) || (*doubleString == NIL)) - return FALSE; - - if (flags & FLAGS_LONGDOUBLE) -/* *longdoublePointer = StrToLongDouble()*/ - return FALSE; /* FIXME: Remove when long double is implemented */ - else - { - *target = StrToDouble(doubleString, NULL); - } - return TRUE; -} - -/************************************************************************* - * TrioReadPointer [private] - */ -static BOOLEAN_T -TrioReadPointer(trio_T *self, - void **target, - unsigned long flags) -{ - trio_uintmax_t number; - char buffer[sizeof(null)]; - - flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING); - - if (TrioReadNumber(self, - &number, - flags, - POINTER_WIDTH, - BASE_HEX)) - { - /* - * The strange assignment of number is a workaround for a compiler - * warning - */ - if (target) - *target = (char *)0 + number; - return TRUE; - } - else if (TrioReadString(self, - (flags & FLAGS_IGNORE) - ? NULL - : buffer, - 0, - sizeof(null) - 1)) - { - if (StrEqualCase(buffer, null)) - { - if (target) - *target = NULL; - return TRUE; - } - } - return FALSE; -} - -/************************************************************************* - * TrioScan [private] - */ -static int -TrioScan(const void *source, - size_t sourceSize, - void (*InStream)(trio_T *, int *), - const char *format, - va_list arglist, - void **argarray) -{ -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - int charlen; -#endif - int status; - int assignment; - parameter_T parameters[MAX_PARAMETERS]; - trio_T internalData; - trio_T *data; - int ch; -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - int cnt; -#endif - int index; /* Index of format string */ - int i; /* Index of current parameter */ - unsigned long flags; - int width; - int base; - void *pointer; - - assert(VALID(InStream)); - assert(VALID(format)); - - memset(&internalData, 0, sizeof(internalData)); - data = &internalData; - data->InStream = InStream; - data->location = (void *)source; - data->max = sourceSize; - -#if defined(USE_LOCALE) - if (NULL == internalLocaleValues) - { - TrioSetLocale(); - } -#endif - - status = TrioPreprocess(TYPE_SCAN, format, parameters, arglist, argarray); - if (status < 0) - return status; - - assignment = 0; - i = 0; - index = 0; - data->InStream(data, &ch); - -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - mblen(NULL, 0); -#endif - - while (format[index]) - { -#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE) - if (! isascii(format[index])) - { - charlen = mblen(&format[index], MB_LEN_MAX); - /* Compare multibyte characters in format string */ - for (cnt = 0; cnt < charlen - 1; cnt++) - { - if (ch != format[index + cnt]) - { - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - data->InStream(data, &ch); - } - continue; /* while */ - } -#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */ - if (EOF == ch) - return EOF; - - if (CHAR_IDENTIFIER == format[index]) - { - if (CHAR_IDENTIFIER == format[index + 1]) - { - /* Two % in format matches one % in input stream */ - if (CHAR_IDENTIFIER == ch) - { - data->InStream(data, &ch); - index += 2; - continue; /* while format chars left */ - } - else - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - - /* Skip the parameter entries */ - while (parameters[i].type == FORMAT_PARAMETER) - i++; - - flags = parameters[i].flags; - /* Find width */ - width = parameters[i].width; - if (flags & FLAGS_WIDTH_PARAMETER) - { - /* Get width from parameter list */ - width = (int)parameters[width].data.number.as_signed; - } - /* Find base */ - base = parameters[i].base; - if (flags & FLAGS_BASE_PARAMETER) - { - /* Get base from parameter list */ - base = (int)parameters[base].data.number.as_signed; - } - - switch (parameters[i].type) - { - case FORMAT_INT: - { - trio_uintmax_t number; - - if (0 == base) - base = BASE_DECIMAL; - - if (!TrioReadNumber(data, - &number, - flags, - width, - base)) - return assignment; - assignment++; - - if (!(flags & FLAGS_IGNORE)) - { - pointer = parameters[i].data.pointer; -#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER) - if (flags & FLAGS_SIZE_T) - *(size_t *)pointer = (size_t)number; - else -#endif -#if defined(QUALIFIER_PTRDIFF_T) - if (flags & FLAGS_PTRDIFF_T) - *(ptrdiff_t *)pointer = (ptrdiff_t)number; - else -#endif -#if defined(QUALIFIER_INTMAX_T) - if (flags & FLAGS_INTMAX_T) - *(trio_intmax_t *)pointer = (trio_intmax_t)number; - else -#endif - if (flags & FLAGS_QUAD) - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number; - else if (flags & FLAGS_LONG) - *(long int *)pointer = (long int)number; - else if (flags & FLAGS_SHORT) - *(short int *)pointer = (short int)number; - else - *(int *)pointer = (int)number; - } - } - break; /* FORMAT_INT */ - - case FORMAT_STRING: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - if (!TrioReadWideString(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.wstring, - flags, - width)) - return assignment; - } - else -#endif - { - if (!TrioReadString(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - flags, - width)) - return assignment; - } - assignment++; - break; /* FORMAT_STRING */ - - case FORMAT_DOUBLE: - if (!TrioReadDouble(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.doublePointer, - flags, - width)) - return assignment; - assignment++; - break; /* FORMAT_DOUBLE */ - - case FORMAT_GROUP: - { - int characterclass[MAX_CHARACTER_CLASS + 1]; - int rc; - - /* Skip over modifiers */ - while (format[index] != SPECIFIER_GROUP) - { - index++; - } - /* Skip over group specifier */ - index++; - - memset(characterclass, 0, sizeof(characterclass)); - rc = TrioGetCharacterClass(format, - &index, - &flags, - characterclass); - if (rc < 0) - return rc; - - if (!TrioReadGroup(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - characterclass, - flags, - parameters[i].width)) - return assignment; - assignment++; - } - break; /* FORMAT_GROUP */ - - case FORMAT_COUNT: - pointer = parameters[i].data.pointer; - if (NULL != pointer) - { -#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER) - if (flags & FLAGS_SIZE_T) - *(size_t *)pointer = (size_t)data->committed; - else -#endif -#if defined(QUALIFIER_PTRDIFF_T) - if (flags & FLAGS_PTRDIFF_T) - *(ptrdiff_t *)pointer = (ptrdiff_t)data->committed; - else -#endif -#if defined(QUALIFIER_INTMAX_T) - if (flags & FLAGS_INTMAX_T) - *(trio_intmax_t *)pointer = (trio_intmax_t)data->committed; - else -#endif - if (flags & FLAGS_QUAD) - { - *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->committed; - } - else if (flags & FLAGS_LONG) - { - *(long int *)pointer = (long int)data->committed; - } - else if (flags & FLAGS_SHORT) - { - *(short int *)pointer = (short int)data->committed; - } - else - { - *(int *)pointer = (int)data->committed; - } - } - break; /* FORMAT_COUNT */ - - case FORMAT_CHAR: -#if TRIO_WIDECHAR - if (flags & FLAGS_WIDECHAR) - { - if (TrioReadWideChar(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.wstring, - flags, - (width == NO_WIDTH) ? 1 : width) > 0) - return assignment; - } - else -#endif - { - if (TrioReadChar(data, - (flags & FLAGS_IGNORE) - ? NULL - : parameters[i].data.string, - flags, - (width == NO_WIDTH) ? 1 : width) > 0) - return assignment; - } - assignment++; - break; /* FORMAT_CHAR */ - - case FORMAT_POINTER: - if (!TrioReadPointer(data, - (flags & FLAGS_IGNORE) - ? NULL - : (void **)parameters[i].data.pointer, - flags)) - return assignment; - assignment++; - break; /* FORMAT_POINTER */ - - case FORMAT_PARAMETER: - break; /* FORMAT_PARAMETER */ - - default: - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - } - ch = data->current; - index = parameters[i].indexAfterSpecifier; - i++; - } - else /* Not an % identifier */ - { - if (isspace((int)format[index])) - { - /* Whitespaces may match any amount of whitespaces */ - ch = TrioSkipWhitespaces(data); - } - else if (ch == format[index]) - { - data->InStream(data, &ch); - } - else - return TRIO_ERROR_RETURN(TRIO_EINVAL, index); - - index++; - } - } - return assignment; -} - -/************************************************************************* - * TrioInStreamFile [private] - */ -static void -TrioInStreamFile(trio_T *self, - int *intPointer) -{ - FILE *file = (FILE *)self->location; - - assert(VALID(self)); - assert(VALID(file)); - - self->current = fgetc(file); - self->processed++; - self->committed++; - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} - -/************************************************************************* - * TrioInStreamFileDescriptor [private] - */ -static void -TrioInStreamFileDescriptor(trio_T *self, - int *intPointer) -{ - int fd = *((int *)self->location); - int size; - unsigned char input; - - assert(VALID(self)); - - size = read(fd, &input, sizeof(char)); - self->current = (size == 0) ? EOF : input; - self->processed++; - self->committed++; - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} - -/************************************************************************* - * TrioInStreamString [private] - */ -static void -TrioInStreamString(trio_T *self, - int *intPointer) -{ - unsigned char **buffer; - - assert(VALID(self)); - assert(VALID(self->InStream)); - assert(VALID(self->location)); - - buffer = (unsigned char **)self->location; - self->current = (*buffer)[0]; - if (self->current == NIL) - self->current = EOF; - (*buffer)++; - self->processed++; - self->committed++; - - if (VALID(intPointer)) - { - *intPointer = self->current; - } -} - -/************************************************************************* - * scanf - */ -int -trio_scanf(const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(format)); - - va_start(args, format); - status = TrioScan(stdin, 0, TrioInStreamFile, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vscanf(const char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioScan(stdin, 0, TrioInStreamFile, format, args, NULL); -} - -int -trio_scanfv(const char *format, - void **args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(format)); - - return TrioScan(stdin, 0, TrioInStreamFile, format, dummy, args); -} - -/************************************************************************* - * fscanf - */ -int -trio_fscanf(FILE *file, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(file)); - assert(VALID(format)); - - va_start(args, format); - status = TrioScan(file, 0, TrioInStreamFile, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vfscanf(FILE *file, - const char *format, - va_list args) -{ - assert(VALID(file)); - assert(VALID(format)); - - return TrioScan(file, 0, TrioInStreamFile, format, args, NULL); -} - -int -trio_fscanfv(FILE *file, - const char *format, - void **args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(file)); - assert(VALID(format)); - - return TrioScan(file, 0, TrioInStreamFile, format, dummy, args); -} - -/************************************************************************* - * dscanf - */ -int -trio_dscanf(int fd, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(format)); - - va_start(args, format); - status = TrioScan(&fd, 0, TrioInStreamFileDescriptor, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vdscanf(int fd, - const char *format, - va_list args) -{ - assert(VALID(format)); - - return TrioScan(&fd, 0, TrioInStreamFileDescriptor, format, args, NULL); -} - -int -trio_dscanfv(int fd, - const char *format, - void **args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(format)); - - return TrioScan(&fd, 0, TrioInStreamFileDescriptor, format, dummy, args); -} - -/************************************************************************* - * sscanf - */ -int -trio_sscanf(const char *buffer, - const char *format, - ...) -{ - int status; - va_list args; - - assert(VALID(buffer)); - assert(VALID(format)); - - va_start(args, format); - status = TrioScan(&buffer, 0, TrioInStreamString, format, args, NULL); - va_end(args); - return status; -} - -int -trio_vsscanf(const char *buffer, - const char *format, - va_list args) -{ - assert(VALID(buffer)); - assert(VALID(format)); - - return TrioScan(&buffer, 0, TrioInStreamString, format, args, NULL); -} - -int -trio_sscanfv(const char *buffer, - const char *format, - void **args) -{ - va_list dummy; - shutup_unitialized(&dummy); - - assert(VALID(buffer)); - assert(VALID(format)); - - return TrioScan(&buffer, 0, TrioInStreamString, format, dummy, args); -} - diff --git a/org.glite.lb-utils.trio/src/triop.h b/org.glite.lb-utils.trio/src/triop.h deleted file mode 100644 index ca49fab..0000000 --- a/org.glite.lb-utils.trio/src/triop.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************* - * - * $Id$ - * - * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - ************************************************************************ - * - * Private functions, types, etc. used for callback functions. - * - * The ref pointer is an opaque type and should remain as such. - * Private data must only be accessible through the getter and - * setter functions. - * - ************************************************************************/ - -#ifndef TRIO_TRIOP_H -#define TRIO_TRIOP_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef TRIO_C99 -# define TRIO_C99 1 -#endif -#ifndef TRIO_BSD -# define TRIO_BSD 1 -#endif -#ifndef TRIO_GNU -# define TRIO_GNU 1 -#endif -#ifndef TRIO_MISC -# define TRIO_MISC 1 -#endif -#ifndef TRIO_UNIX98 -# define TRIO_UNIX98 1 -#endif -#ifndef TRIO_MICROSOFT -# define TRIO_MICROSOFT 1 -#endif -#ifndef TRIO_EXTENSION -# define TRIO_EXTENSION 1 -#endif -#ifndef TRIO_WIDECHAR -# define TRIO_WIDECHAR 0 -#endif -#ifndef TRIO_ERRORS -# define TRIO_ERRORS 1 -#endif - -#ifndef TRIO_MALLOC -# define TRIO_MALLOC(n) malloc(n) -#endif -#ifndef TRIO_REALLOC -# define TRIO_REALLOC(x,n) realloc((x),(n)) -#endif -#ifndef TRIO_FREE -# define TRIO_FREE(x) free(x) -#endif - -typedef int (*trio_callback_t)(void *ref); - -void *trio_register(trio_callback_t callback, const char *name); -void trio_unregister(void *handle); - -const char *trio_get_format(void *ref); -void *trio_get_argument(void *ref); - -/* Modifiers */ -int trio_get_width(void *ref); -void trio_set_width(void *ref, int width); -int trio_get_precision(void *ref); -void trio_set_precision(void *ref, int precision); -int trio_get_base(void *ref); -void trio_set_base(void *ref, int base); -int trio_get_padding(void *ref); -void trio_set_padding(void *ref, int is_padding); -int trio_get_short(void *ref); /* h */ -void trio_set_shortshort(void *ref, int is_shortshort); -int trio_get_shortshort(void *ref); /* hh */ -void trio_set_short(void *ref, int is_short); -int trio_get_long(void *ref); /* l */ -void trio_set_long(void *ref, int is_long); -int trio_get_longlong(void *ref); /* ll */ -void trio_set_longlong(void *ref, int is_longlong); -int trio_get_longdouble(void *ref); /* L */ -void trio_set_longdouble(void *ref, int is_longdouble); -int trio_get_alternative(void *ref); /* # */ -void trio_set_alternative(void *ref, int is_alternative); -int trio_get_alignment(void *ref); /* - */ -void trio_set_alignment(void *ref, int is_leftaligned); -int trio_get_spacing(void *ref); /* (space) */ -void trio_set_spacing(void *ref, int is_space); -int trio_get_sign(void *ref); /* + */ -void trio_set_sign(void *ref, int is_showsign); -int trio_get_quote(void *ref); /* ' */ -void trio_set_quote(void *ref, int is_quote); -int trio_get_upper(void *ref); -void trio_set_upper(void *ref, int is_upper); -#if TRIO_C99 -int trio_get_largest(void *ref); /* j */ -void trio_set_largest(void *ref, int is_largest); -int trio_get_ptrdiff(void *ref); /* t */ -void trio_set_ptrdiff(void *ref, int is_ptrdiff); -int trio_get_size(void *ref); /* z / Z */ -void trio_set_size(void *ref, int is_size); -#endif - -/* Printing */ -int trio_print_ref(void *ref, const char *format, ...); -int trio_vprint_ref(void *ref, const char *format, va_list args); -int trio_printv_ref(void *ref, const char *format, void **args); - -void trio_print_int(void *ref, int number); -void trio_print_uint(void *ref, unsigned int number); -/* void trio_print_long(void *ref, long number); */ -/* void trio_print_ulong(void *ref, unsigned long number); */ -void trio_print_double(void *ref, double number); -void trio_print_string(void *ref, char *string); -void trio_print_pointer(void *ref, void *pointer); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* TRIO_TRIOP_H */ diff --git a/org.glite.lb-utils.trio/test/trio_test.cpp b/org.glite.lb-utils.trio/test/trio_test.cpp deleted file mode 100644 index 3ba4b9c..0000000 --- a/org.glite.lb-utils.trio/test/trio_test.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include - -#include -#include - -#include "trio.h" - -class TrioTest: public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE(TrioTest); - CPPUNIT_TEST(escapeULM); - CPPUNIT_TEST(escapeXML); - CPPUNIT_TEST(escapeSQL); - CPPUNIT_TEST_SUITE_END(); - -public: - void escapeULM(); - void escapeXML(); - void escapeSQL(); -}; - -void TrioTest::escapeULM() -{ - char *e, *r = "START we have =, \\\", and \\n in the string END"; - - trio_asprintf(&e,"START %|Us END", "we have =, \", and \n in the string"), - std::cerr << e << std::endl; - - CPPUNIT_ASSERT_MESSAGE("escape ULM failed",!strcmp(e,r)); -} - -void TrioTest::escapeXML() -{ - char *e, *r = "START there is a <tag> containing &something; </tag> END"; - - trio_asprintf(&e,"START %|Xs END", "there is a containing &something; "), - std::cerr << e << std::endl; - - CPPUNIT_ASSERT_MESSAGE("escape XML failed",!strcmp(e,r)); -} - -void TrioTest::escapeSQL() -{ - char *e, *r = "START SQL doesn''t like '' END"; - - trio_asprintf(&e,"START %|Ss END", "SQL doesn't like '"), - std::cerr << e << std::endl; - - CPPUNIT_ASSERT_MESSAGE("escape SQL failed",!strcmp(e,r)); -} - -CPPUNIT_TEST_SUITE_REGISTRATION( TrioTest ); - -#include -#include - -#include -#include -#include -#include -#include -#include - -int main (int argc,const char *argv[]) -{ - CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); - - assert(argc == 2); - std::ofstream xml(argv[1]); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - CppUnit::TestRunner runner; - runner.addTest(suite); - runner.run(controller); - - CppUnit::XmlOutputter xout( &result, xml ); - CppUnit::CompilerOutputter tout( &result, std::cout); - xout.write(); - tout.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} diff --git a/org.glite.lb-utils/.cvsignore b/org.glite.lb-utils/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.lb-utils/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.lb-utils/LICENSE b/org.glite.lb-utils/LICENSE deleted file mode 100755 index 259a91f..0000000 --- a/org.glite.lb-utils/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb-utils/build.xml b/org.glite.lb-utils/build.xml deleted file mode 100644 index 85553ce..0000000 --- a/org.glite.lb-utils/build.xml +++ /dev/null @@ -1,303 +0,0 @@ - - - - - - - Ant build file to build the lb-utils subsystem. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Preparing directories ... - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <project name="${subsystem.name}" type="post-subsystem" packageName="${global.prefix}-${subsystem.prefix}"/> - - - - diff --git a/org.glite.lb-utils/project/build.number b/org.glite.lb-utils/project/build.number deleted file mode 100644 index 5cfec85..0000000 --- a/org.glite.lb-utils/project/build.number +++ /dev/null @@ -1 +0,0 @@ -module.build = 0 diff --git a/org.glite.lb-utils/project/build.properties b/org.glite.lb-utils/project/build.properties deleted file mode 100755 index e69de29..0000000 diff --git a/org.glite.lb-utils/project/dependencies.properties b/org.glite.lb-utils/project/dependencies.properties deleted file mode 100644 index c590a39..0000000 --- a/org.glite.lb-utils/project/dependencies.properties +++ /dev/null @@ -1,13 +0,0 @@ - -################################################################### -# System dependencies -################################################################### - -org.glite.version = HEAD -org.glite.lb-utils.version = HEAD - -# Component dependencies tag = do not remove this line = -org.glite.lb-utils.db.version = HEAD -#org.glite.lb-utils.jobid.version = HEAD -#org.glite.lb-utils.server-bones.version = HEAD -#org.glite.lb-utils.trio.version = HEAD diff --git a/org.glite.lb-utils/project/glite.lb-utils.csf.xml b/org.glite.lb-utils/project/glite.lb-utils.csf.xml deleted file mode 100644 index 98945b8..0000000 --- a/org.glite.lb-utils/project/glite.lb-utils.csf.xml +++ /dev/null @@ -1,218 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The org.glite and org.glite.lb-utils modules have been updated, please rerun the configuration file - - - - - The org.glite and org.glite.lb-utils modules have been updated, please rerun the configuration file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils/project/properties.xml b/org.glite.lb-utils/project/properties.xml deleted file mode 100644 index 5f9597f..0000000 --- a/org.glite.lb-utils/project/properties.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb-utils/project/taskdefs.xml b/org.glite.lb-utils/project/taskdefs.xml deleted file mode 100644 index 7963150..0000000 --- a/org.glite.lb-utils/project/taskdefs.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - diff --git a/org.glite.lb-utils/project/version.properties b/org.glite.lb-utils/project/version.properties deleted file mode 100755 index 6f1f8ab..0000000 --- a/org.glite.lb-utils/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version = 0.0.0 -module.age = 0 \ No newline at end of file diff --git a/org.glite.lb.client-interface/.cvsignore b/org.glite.lb.client-interface/.cvsignore deleted file mode 100644 index 1df717b..0000000 --- a/org.glite.lb.client-interface/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.lb.client-interface/IMPORTANT-README b/org.glite.lb.client-interface/IMPORTANT-README deleted file mode 100644 index 469e260..0000000 --- a/org.glite.lb.client-interface/IMPORTANT-README +++ /dev/null @@ -1,39 +0,0 @@ -This module is now obsolete. - -Files moved from ./interface to org.glite.lb.client/interface: - -consumer_fake.h -consumer.h -dump.h -Job.h -JobStatus.h.T -load.h -notification.h -Notification.h -producer_fake.h -producer.h.T -purge.h -ServerConnection.h -statistics.h - - -Files moved from ./interface to org.glite.lb.common/interface: - -context.h -CountRef.h -Event.h.T -events.h.T -jobstat.h.T -LoggingExceptions.h -notifid.h - - -Files moved form ./doc to org.glite.lb.client/doc: - -C.dox -CPP.dox -api/api.tex -api/Makefile -api/fig/logging-arch.eps -api/fig/logging-arch.pdf - diff --git a/org.glite.lb.client-interface/LICENSE b/org.glite.lb.client-interface/LICENSE deleted file mode 100644 index 259a91f..0000000 --- a/org.glite.lb.client-interface/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb.client-interface/Makefile b/org.glite.lb.client-interface/Makefile deleted file mode 100644 index fa5226d..0000000 --- a/org.glite.lb.client-interface/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# Default values -all compile: diff --git a/org.glite.lb.client-interface/build.xml b/org.glite.lb.client-interface/build.xml deleted file mode 100755 index d389be7..0000000 --- a/org.glite.lb.client-interface/build.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb.client-interface/project/build.number b/org.glite.lb.client-interface/project/build.number deleted file mode 100644 index e24af99..0000000 --- a/org.glite.lb.client-interface/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Fri Aug 18 12:25:13 CEST 2006 -module.build=0245 diff --git a/org.glite.lb.client-interface/project/build.properties b/org.glite.lb.client-interface/project/build.properties deleted file mode 100644 index e69de29..0000000 diff --git a/org.glite.lb.client-interface/project/configure.properties.xml b/org.glite.lb.client-interface/project/configure.properties.xml deleted file mode 100644 index e6996e6..0000000 --- a/org.glite.lb.client-interface/project/configure.properties.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - -top_srcdir=.. -builddir=build -stagedir=${stage.abs.dir} -distdir=${dist.dir} -package=${module.package.name} -globalprefix=${global.prefix} -lbprefix=${subsystem.prefix} -PREFIX=${install.dir} -version=${module.version} - - - diff --git a/org.glite.lb.client-interface/project/properties.xml b/org.glite.lb.client-interface/project/properties.xml deleted file mode 100755 index 31d958b..0000000 --- a/org.glite.lb.client-interface/project/properties.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.lb.client-interface/project/tar_exclude b/org.glite.lb.client-interface/project/tar_exclude deleted file mode 100644 index e1fcd1a..0000000 --- a/org.glite.lb.client-interface/project/tar_exclude +++ /dev/null @@ -1,10 +0,0 @@ -tar_exclude -CVS -build.xml -build -build.properties -properties.xml -configure.properties.xml -.cvsignore -.project -.cdtproject diff --git a/org.glite.lb.client-interface/project/version.properties b/org.glite.lb.client-interface/project/version.properties deleted file mode 100644 index 29918df..0000000 --- a/org.glite.lb.client-interface/project/version.properties +++ /dev/null @@ -1,4 +0,0 @@ -# $Id$ -# $Name$ -module.version=2.3.2 -module.age=1 diff --git a/org.glite.lb.client-java/Makefile b/org.glite.lb.client-java/Makefile deleted file mode 100644 index 59c86cb..0000000 --- a/org.glite.lb.client-java/Makefile +++ /dev/null @@ -1,113 +0,0 @@ -top_srcdir=. -stagedir=../stage - --include Makefile.inc - -# broken -# SimpleLLTest.class ProducerTestLL.class ProducerTestIL.class - -FULL_EXAMPLES := $(addprefix ${top_srcdir}/examples/,SSLClient.java SSLServer.java QueryDemo.java NotificationExample.java CreamTest.java) -SSL_EXAMPLES := $(addprefix ${top_srcdir}/examples/simple-ssl/,MyX509KeyManager.java MyX509TrustManager.java ExampleSSLSocketFactory.java LBClientSSL.java) -TM_EXAMPLES := $(addprefix ${top_srcdir}/examples/simple-trustmanager/,LBClientTM.java) - -VPATH := ${top_srcdir}/src/org/glite/lb ${top_srcdir}/examples ${top_srcdir}/examples/simple-ssl ${top_srcdir}/examples/simple-trustmanager - -JAVAC:=${jdk_prefix}/bin/javac -JAVAH:=${jdk_prefix}/bin/javah -JAVA:=${jdk_prefix}/bin/java - -GEN:=${stagedir}${prefix}/sbin/glite-lb-at3 ${top_srcdir}/project/genEventTypes.pl -AT3DIR:=${stagedir}${prefix}/share/glite-lb/at3 -axis_classpath:=$(shell ${top_srcdir}/project/list-jars.sh ${axis_prefix}/lib ${axis_prefix}/share/java /usr/share/java /usr/lib/java) -trustmanager_classpath:=$(shell ls -1 ${trustmanager_prefix}/share/java/glite-security-trustmanager.jar ${trustmanager_prefix}/share/java/trustmanager.jar ${trustmanager_prefix}/share/java/trustmanager-axis.jar ${stagedir}${prefix}/share/java/trustmanager.jar ${stagedir}${prefix}/share/java/trustmanager-axis.jar 2>/dev/null | tr '\012' :) - -all compile: compile-java-axis compile-java-lb compile-java-gen compile-java-lb2 build-jar examples build-c - -wtf: - echo "axis_classpath: ${axis_classpath}" - -compile-java-axis: genws - ${JAVAC} \ - -classpath ${jakarta-commons-lang_jar}:${stagedir}${prefix}/share/java/jobid-api-java.jar:${trustmanager_classpath}:${utiljava_prefix}/share/java/glite-security-util-java.jar:${axis_classpath} \ - -d build \ - build/axis/org/glite/wsdl/services/lb/*.java \ - build/axis/org/glite/wsdl/services/lb4agu/*.java \ - `find build/axis/org/ogf/schemas/glue -name *.java -print` \ - build/axis/org/glite/wsdl/types/lb/*.java \ - build/axis/org/glite/wsdl/types/lb/holders/*.java \ - build/axis/org/glite/wsdl/elements/lb/*.java \ - build/axis/holders/StringArrayHolder.java - -compile-java-lb: Event.java Timeval.java Sources.java Level.java SeqCode.java Escape.java - -mkdir -p build/classes - ${JAVAC} \ - -classpath ${jakarta-commons-lang_jar}:${stagedir}${prefix}/share/java/jobid-api-java.jar:${trustmanager_classpath}:${utiljava_prefix}/share/java/glite-security-util-java.jar:${axis_classpath}:build/classes \ - -d build $+ - -compile-java-gen: genevents - ${JAVAC} \ - -classpath ${jakarta-commons-lang_jar}:${stagedir}${prefix}/share/java/jobid-api-java.jar:${trustmanager_classpath}:${utiljava_prefix}/share/java/glite-security-util-java.jar:${axis_classpath}:build:build/classes \ - -d build \ - build/gen/*.java - -compile-java-lb2: Context.java ContextDirect.java ContextIL.java ContextLL.java EventConvertor.java ILFileWriter.java ILProto.java Job.java LBCredentials.java LBException.java NotifParser.java Notification.java SSL.java SSLSend.java ServerConnection.java - ${JAVAC} \ - -classpath ${jakarta-commons-lang_jar}:${stagedir}${prefix}/share/java/jobid-api-java.jar:${trustmanager_classpath}:${utiljava_prefix}/share/java/glite-security-util-java.jar:${axis_classpath}:build:build/classes \ - -d build/classes $+ - -build-jar: lb-client-java.jar - -lb-client-java.jar: - cd build && ${jdk_prefix}/bin/jar cf lb-client-java.jar holders org - cd build/classes && ${jdk_prefix}/bin/jar uf ../lb-client-java.jar org - ${jdk_prefix}/bin/jar i build/lb-client-java.jar - -build-c: - ${JAVAH} -classpath build:build/classes -jni -d build org.glite.lb.ContextIL - -mkdir -p build/c - -ln -s ${top_srcdir}/src_c . - -ln -s ../../src_c/Makefile build/c - cd build/c && $(MAKE) PREFIX=${PREFIX} JAVA_HOME=${jdk_prefix} topdir=../.. - -examples: build/classes/examples - -build/classes/examples: ${FULL_EXAMPLES} ${SSL_EXAMPLES} ${TM_EXAMPLES} - -mkdir -p build/classes/examples/src/simple-ssl build/classes/examples/src/simple-trustmanager - ${jdk_prefix}/bin/javac -d build/classes/examples -cp build:build/classes:build/classes/examples:${stagedir}${prefix}/share/java/jobid-api-java.jar:${axis_classpath} ${FULL_EXAMPLES} - ${jdk_prefix}/bin/javac -d build/classes/examples -cp build:build/classes:build/classes/examples:${axis_classpath} ${SSL_EXAMPLES} - ${jdk_prefix}/bin/javac -d build/classes/examples -cp build:build/classes:${trustmanager_classpath}:${axis_classpath} ${TM_EXAMPLES} - cp ${FULL_EXAMPLES} build/classes/examples/src - cp ${SSL_EXAMPLES} build/classes/examples/src/simple-ssl - cp ${TM_EXAMPLES} build/classes/examples/src/simple-trustmanager - cd build/classes/examples && ${jdk_prefix}/bin/jar cfi lb-client-java-examples.jar src org $(addsuffix .class,$(basename $(notdir ${FULL_EXAMPLES}))) && ${jdk_prefix}/bin/jar i lb-client-java-examples.jar - -genevents: build/gen - -build/gen: - -mkdir -p build/gen - ${GEN} build/gen - -genws: build/axis - -build/axis: - ${JAVA} -classpath ${axis_classpath} org.apache.axis.wsdl.WSDL2Java -o build/axis ${stagedir}${prefix}/share/wsdl/glite-lb/LB.wsdl - -check: - @echo "No check" - -stage: - $(MAKE) install PREFIX=${stagedir} - -install: - mkdir -p ${DESTDIR}${PREFIX}${prefix}/share/java - cp build/lb-client-java.jar ${DESTDIR}${PREFIX}${prefix}/share/java - cp build/classes/examples/lb-client-java-examples.jar ${DESTDIR}${PREFIX}${prefix}/share/java - cd build/c && $(MAKE) install PREFIX=${PREFIX} - -clean: - rm -rf build - -distclean: - rm -rvf Makefile.inc *.spec debian/ - -.PHONY: all compile compile-java-axis compile-java-lb compile-java-gen compile-java-lb2 build-jar build-c examples genevents genws check stage install clean distclean wtf diff --git a/org.glite.lb.client-java/configure b/org.glite.lb.client-java/configure deleted file mode 100755 index bcb1531..0000000 --- a/org.glite.lb.client-java/configure +++ /dev/null @@ -1,2058 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; -use POSIX qw(locale_h strftime); - -my $pwd = `pwd`; chomp $pwd; -my $prefix = '/usr'; -my $stagedir = undef; -my $root = $pwd.'/stage'; -my $sysroot = ''; -my $sysconfdir; -my $localstatedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my ($version, $force_version); -my $branch; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $jobid_tag = ''; -my $libdir = getlibdir(); -my $project = 'emi'; -my $project_version; -my (%projects, %project); -my $debug = 0; -my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : ''; - -my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal/; -my @default_nodes = qw/lb px proxyrenewal nagios/; -my %enable_nodes; -my %disable_nodes; -my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1); - -my %package = ( - 'maintainer' => 'CESNET Product Teams ', - 'uploaders' => 'František Dvořák ', - 'url' => 'http://glite.cern.ch', - 'debian_vcs' => 'Vcs-Cvs: :pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw -Vcs-Browser: http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi', -); - -# key: internal package name (arguments, ...) -# 'pkg': pkg-config name -# 'prefix': used when pkg-config fails -my %externs = ( - cares => { - prefix => '/opt/c-ares', - pkg => 'libcares' - }, - classads => { - prefix=> '/usr', - pkg => 'classads' - }, - cppunit => { - prefix=> '/usr', - pkg => 'cppunit' - }, - expat => { - prefix=> '/usr', - pkg => 'expat' - }, - globus => { - prefix=> '/opt/globus', - pkg => 'globus-gssapi-gsi' - }, - 'myproxy-devel' => { - prefix=> '/opt/globus', - pkg => 'myproxy' - }, - 'myproxy-server' => { - prefix=> '', - }, - 'myproxy-admin' => { - prefix=> '', - }, - gsoap => { - prefix=> '/usr', - pkg => 'gsoap' - }, - gsoapxx => { - prefix=> '/usr', - pkg => 'gsoap++' - }, - mysql => { - prefix=> '/usr' - }, - 'mysql-devel' => { - prefix=> '' - }, - 'mysql-server' => { - prefix => '' - }, - voms => { - prefix => '/opt/glite', - pkg => 'voms-2.0' - }, - gridsite => { - prefix => '/opt/glite' - }, - lcas => { - prefix => '/opt/glite', - pkg => 'lcas' - }, - trustmanager => { - prefix => '/opt/glite' - }, - trustmanager_axis => { - prefix => '/opt/glite' - }, - utiljava => { - prefix=> '/opt/glite' - }, - ant => { - prefix=> '/usr' - }, - jdk => { - prefix=> '/usr/java/latest', - locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ], - }, - libtar => { - prefix=> '/usr' - }, - axis => { - prefix=> '/usr' - }, - log4c => { - prefix=> '/usr' - }, - postgresql => { - prefix=> '/usr' - }, - activemq => { - prefix=>'/opt/activemq-cpp-library', - pkg => 'activemq-cpp' - }, -); - -my %jar = ( - 'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar', - 'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %buildroot; -my (%etics_externs, %etics_projects); - -# -# modules of the subsystems -# -# additional modules from $project{modules} are automatically added -# -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], - 'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/], - 'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - 'gridsite' => [ qw/apache libs commands core devel slashgrid services service-clients gsexec/ ], - 'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ], - 'canl' => [ qw/c c-devel/ ], - ); - -# -# sub-packages -# -# modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly -# -my %subpackages = ( - 'jobid.api-c-devel' => 'jobid.api-c', - 'jobid.api-cpp-devel' => 'jobid.api-cpp', - 'lbjp-common.db-devel' => 'lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'lbjp-common.log', - 'lbjp-common.maildir-devel' => 'lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'lbjp-common.trio', - 'lb.client-progs' => 'lb.client', - 'lb.client-devel' => 'lb.client', - 'lb.common-devel' => 'lb.common', - 'lb.logger-devel' => 'lb.logger', - 'lb.state-machine-devel' => 'lb.state-machine', - 'px.proxyrenewal-devel' => 'px.proxyrenewal', - 'px.proxyrenewal-progs' => 'px.proxyrenewal', - 'canl.c-devel' => 'canl.c', -); - -my @opts = ( - 'prefix:s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour:s' => \$thrflavour, - 'nothrflavour:s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$force_version, - 'branch=s' => \$branch, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'root:s' => \$root, - 'sysroot:s' => \$sysroot, - 'sysconfdir=s' => \$sysconfdir, - 'localstatedir=s' => \$localstatedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'jobid-tag=s' => \$jobid_tag, - 'canl-tag=s' => \$canl_tag, - 'help' => \$help, - 'libdir=s' => \$libdir, - 'project=s' => \$project, - 'debug' => \$debug, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; -$prefix=~s/\/$//; -$root=~s/\/$//; -$sysroot=~s/\/$//; -if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; } -if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; } -$sysconfdir=~s/\/$//; -$localstatedir=~s/\/$//; - -$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq ''; -$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq ''; -$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq ''; - -$externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq ''; -$externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq ''; -$externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq ''; - -if ($project =~ /^([^0-9]*)(.*)$/) { - $project = $1; - $project_version = $2; -} -%project = %{$projects{$project}}; -$project_version = $project{current_version} unless $project_version; -for my $platform (keys %{$project{etics_externs}}) { - for $_ (keys %{$project{etics_externs}{$platform}}) { - $etics_externs{$platform}{$_} = $project{etics_externs}{$platform}{$_}; - } -} -reshuffle_platforms(\%etics_externs, $project{supported_platforms}); -reshuffle_platforms(\%{$project{etics_externs_devel}}, $project{supported_platforms}); -for $_ (keys %{$project{etics_projects}}) { - $etics_projects{$_} = $project{etics_projects}{$_}; -} -for $_ (keys %{$project{need_externs_aux}}) { - $need_externs_aux{$_} = $project{need_externs_aux}{$_}; -} -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - my ($pkg, $type) =/([^:]*)(?::(.*))?/; - $type = 'BR' unless ($type); - - push @{$need_externs{$ext}},$pkg; - $need_externs_type{$ext}->{$pkg} = $type; - } -} -if ($project eq 'emi') { - $extranodmod{lb} = 'lb.emi-lb'; - $extranodmod{px} = 'px.emi-px'; -} -for $_ (keys %{$project{modules}}) { - push @{$lbmodules{$_}},@{$project{modules}{$_}}; -} - - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name}; - my @m; - - if (exists $lbmodules{$listmodules}) { - @m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}}; - } else { - if ($project eq 'emi' and $project_version == 1) { - # no sub-packages in EMI-1 - } else { - for my $sub (keys %subpackages) { - push @m, $sub if ($subpackages{$sub} eq $listmodules); - } - } - } - print map $_ eq "" ? "" : "$_ ", @m; - print "\n"; - exit 0; -} - -warn "$0: --branch and --output make sense only in --mode=etics\n" - if ($output || $branch) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_}); - } -} - -if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } }; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $root unless $stagedir; -$stagedir=~s/\/$// if ($stagedir); - -if ($mode eq 'build') { for my $ext (keys %externs) { - if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; } - elsif (defined $externs{$ext}{pkg}) { - my ($flag, $env, $cmd, $ret); - my $pkg = $externs{$ext}{pkg}; - my $flagname = uc $externs{$ext}{pkg}; - $flagname =~ s/-[0-9\.]*$//; - $flagname =~ y/-\+/_X/; - - print "Checking $pkg ... "; - $env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig"; - $cmd = "$env pkg-config $pkg --exists >/dev/null"; - `$cmd`; $ret = $?; - print "('$cmd' => $ret)\n" if ($debug); - if ($ret == 0) { - $externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`; - chomp $externs{$ext}{prefix}; - print "$externs{$ext}{prefix}\n"; - - $flag=`$env pkg-config $pkg --cflags`; - $externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag); - $flag=`$env pkg-config $pkg --libs`; - $externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag); - } else { - print "(using default $externs{$ext}{prefix})\n"; - } - print "\n" if ($debug); - } - elsif ($ext eq 'jdk') { - my $jdk_prefix; - - print "Looking for some caffein ... "; - if (defined $ENV{'JDK_HOME'}) { - $jdk_prefix = $ENV{'JDK_HOME'}; - print "JDK_HOME=$jdk_prefix\n"; - } elsif (defined $ENV{'JAVA_HOME'}) { - $jdk_prefix = $ENV{'JAVA_HOME'}; - print "JAVA_HOME=$jdk_prefix\n"; - } else { - foreach my $i (0..$#{$externs{$ext}{locations}}) { - if (-e $externs{$ext}{locations}[$i]) { - $jdk_prefix=$externs{$ext}{locations}[$i]; - print "(found directory $jdk_prefix)\n"; - last; - } - } - print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix); - } - $externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix); - } -} } - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') { - print CONF "$_=$ENV{$_} " if (defined $ENV{$_}); - } - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } }; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - if ($module) { - print "Not creating summary Makefile\n" if $debug; - } else { - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\n"; - print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n"; - print MAK "clean check install:\n"; - - for (@modules) { - my $full = full($_); - print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $buildroot{$_} eq '' ? - "\tcd $full && \${MAKE} distclean\n" : - "\trm -rf $full/$buildroot{$_}\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage'; - - my $full = full($_); - my $build = $buildroot{$_}; - - print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n"; - print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n"; - } - - close MAK; - } -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag) { - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - if ($canl_tag) { - for (@{$lbmodules{'canl'}}){ - if ("canl.".$_ eq $module){ - $tag = '-r '.$canl_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%etics_externs = ( - default => { - 'myproxy-devel'=>'myproxy-devel', - 'myproxy-server'=>'myproxy-server', - 'myproxy-admin'=>'myproxy-admin', - cares=>'c-ares', - utiljava=>'org.glite.security.util-java', - gpt=>'gpt', - fetchcrl=>'fetch-crl', - activemq=>'activemq-cpp-library', - }, -); - -%etics_projects = ( -); - -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads libtool:B globus:B/ ], - 'lb.common' => [ qw/expat cares:B cppunit:B classads libtool:B globus:B/ ], - 'lb.doc' => [ qw/tetex-latex:B/ ], - 'lb.logger' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B globus:B/ ], - 'lb.nagios' => [ qw/globus_proxy_utils:R/ ], - 'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql-server:R cppunit:B gsoap:B classads voms:B lcas gridsite:B bison:B libtool:B libxml2 flex:B/ ], - 'lb.state-machine' => [ qw/classads libtool:B libxslt:B expat:B globus:B/ ], - 'lb.utils' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ], - 'lb.ws-test' => [ qw/gsoap:B libtool:B globus:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/docbook-utils:B libtool:B globus:B/ ], - 'lbjp-common.db' => [ qw/mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.log' => [ qw/log4c libtool:B/ ], - 'lbjp-common.maildir' => [ qw/libtool:B/ ], - 'lbjp-common.server-bones' => [ qw/libtool:B/ ], - 'lbjp-common.trio' => [ qw/cppunit:B libtool:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.gss' => [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B/ ], - 'lbjp-common.gsoap-plugin' => [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B/ ], - 'jobid.api-c' => [ qw/cppunit:B libtool:B openssl:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B libtool:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus_essentials:R globus:B mysql-server:R/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B mysql-server:R/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], - 'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'gridsite.commands' => [ qw/curl:R openssl:R/ ], - 'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ], - 'gridsite.libs' => [ qw/libxml2:R openssl:R/ ], - 'gridsite.devel' => [ qw// ], - 'gridsite.slashgrid' => [ qw/curl:R fuse:R/], - 'gridsite.services' => [ qw/curl:R gsoap:R/ ], - 'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ], - 'gridsite.gsexec' => [ qw// ], - 'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B/ ], - 'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec - 'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B krb5-devel:B/ ], -); - -%need_jars = ( - 'jobid.api-java' => [ qw/jakarta-commons-codec/ ], - 'lb.client-java' => [ qw/jakarta-commons-lang/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp:B jobid.api-c - lbjp-common.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - lb.ws-interface:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp:B jobid.api-c - lb.types:B lbjp-common.trio lbjp-common.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - lbjp-common.log - jobid.api-c - lb.common - lbjp-common.gss - / ], - 'lb.logger-msg' => [ qw/ - lb.logger:B - / ], - 'lb.nagios' => [ qw/ - lb.client:R - lb.ws-test:R - lb.utils:R - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log - jobid.api-c - lbjp-common.gsoap-plugin lbjp-common.gss - / ], - 'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine lb.types:B - / ], - 'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/ - jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client - lbjp-common.gss lbjp-common.log - / ], - 'lb.yaim' => [ qw// ], - 'lb.glite-LB' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lb.emi-lb' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.log' => [ qw// ], - 'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ], - 'lbjp-common.trio' => [ qw// ], - 'lbjp-common.gss' => [ qw// ], - 'lbjp-common.gsoap-plugin' => [ qw/lbjp-common.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - lbjp-common.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], - - 'gridsite.core' => [ qw// ], - 'gridsite.commands' => [ qw/gridsite.core:B/ ], - 'gridsite.apache' => [ qw/gridsite.core:B/ ], - 'gridsite.libs' => [ qw/gridsite.core:B / ], - 'gridsite.devel' => [ qw/gridsite.core:B/ ], - 'gridsite.slashgrid' => [ qw/gridsite.core:B/], - 'gridsite.services' => [ qw/gridsite.core:B/ ], - 'gridsite.service-clients' => [ qw/gridsite.core:B/ ], - 'gridsite.gsexec' => [ qw/gridsite.core:B/ ], - - 'px.proxyrenewal' => [ qw// ], - 'px.glite-PX' => [qw/px.myproxy-yaim:R/], - 'px.emi-px' => [qw/px.myproxy-yaim:R/], - 'px.myproxy-yaim' => [ qw// ], - 'px.myproxy-config' => [], - - 'canl.c' => [], - - # sub-packages (virtual ETICS components depending on the main) - 'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ], - 'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ], - 'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ], - 'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ], - 'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ], - 'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ], - 'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ], - 'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ], - 'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ], - 'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ], - 'lb.client-progs' => [ qw/lb.client:B/ ], - 'lb.client-devel' => [ qw/lb.client:B/ ], - 'lb.common-devel' => [ qw/lb.common:B/ ], - 'lb.logger-devel' => [ qw/lb.logger:B/ ], - 'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ], - 'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ], - 'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ], - 'canl.c-devel' => [ qw/canl.c:B/ ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( - gridsite=>'org.gridsite.core', - 'canl.c' => 'emi.canl.canl-c', - 'canl.c-devel' => 'emi.canl.canl-c', - 'jobid.api-c-devel' => 'org.glite.jobid.api-c', - 'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp', - 'lbjp-common.db-devel' => 'org.glite.lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'org.glite.lbjp-common.log', - 'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio', - 'lb.client-devel' => 'org.glite.lb.client', - 'lb.client-progs' => 'org.glite.lb.client', - 'lb.common-devel' => 'org.glite.lb.common', - 'lb.logger-devel' => 'org.glite.lb.logger', - 'lb.state-machine-devel' => 'org.glite.lb.state-machine', - 'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal', - 'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal', -); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', - lb => 'lb.glite-LB', - px => 'px.glite-PX', - proxyrenewal => 'px.proxyrenewal', - canl => 'canl.c', -); - -%obsoletes = ( - 'lb.yaim' => [ qq/glite-yaim-lb/ ], - 'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ], - 'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ], - 'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], -); - -%conflicts = ( -); - -%provides = ( - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], - 'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ], -); - -%cvs_prefix = ( - 'lb' => 'org.glite', - 'jp' => 'org.glite', - 'jobid' => 'org.glite', - 'lbjp-common' => 'org.glite', - 'gridsite' => 'org', - 'px' => 'org.glite', - 'canl' => 'emi', -); - -%cvs_tag_prefix = ( - 'lb' => 'glite-', - 'jp' => 'glite-', - 'jobid' => 'glite-', - 'lbjp-common' => 'glite-', - 'gridsite' => '', - 'px' => 'glite-', - 'canl' => 'emi-', -); - -# ==== projects specification ==== -# etics_name ........... ETICS project name -# conf_prefix .......... ETICS configurations name prefix -# tag_prefix ........... VCS tag prefix -# local_prefix ......... prefix (relative to stage) -# etics_externs ........ ETICS modules names of externals -# (${NAME.location}, ETICS conf. dependencies) -# etics_projects ....... ETICS project names of externals -# etics_externs_devel .. ETICS modules names of devel versions of externals -# etics_locations ...... ETICS locations in ${NAME.location} properties -# need_externs_aux ..... project-specific external dependencies -# supported_platforms .. platforms supported by the project -# modules .............. additional modules in subsystems -%projects = ( - glite => { - current_version => 3, - etics_name => 'org.glite', - conf_prefix => { %cvs_tag_prefix }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}', - local_prefix => '', - etics_externs => { - default => { - globus_essentials=>'vdt_globus_essentials', - globus=>'globus', - globus_proxy_utils=>'vdt_globus_essentials', - gridsite=>'org.gridsite.libs', - yaim_core=>'org.glite.yaim.core', - gip_release=>'glite-info-provider-release', - gip_service=>'glite-info-provider-service', - bdii=>'bdii', - glite_version=>'glite-version', - glite_info_templates=>'glite-info-templates', - glue_schema=>'glue-schema', - trustmanager=>'org.glite.security.trustmanager', - axis=>'axis', - lcas=>'org.glite.security.lcas', - gsoapxx=>'-', - jdk=>'jdk', - voms=>'org.glite.security.voms-api-cpp', - }, - }, - etics_externs_devel => { - default => { - gridsite=>'org.gridsite.devel', - voms=>'org.glite.security.voms-api', - }, - }, - etics_projects => { - vdt=>[qw/globus globus_essentials globus_proxy_utils gpt/], - 'org.glite'=>[qw/voms gridsite lcas gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/], - }, - etics_locations => { - '*' => '', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ], - 'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R/ ], - 'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412 => 1, - sl5_ia32_gcc412 => 1, - deb5_x86_64_gcc432 => 1, - deb5_ia32_gcc432 => 1, - slc4_x86_64_gcc346 => 1, - slc4_ia32_gcc346 => 1, - }, - modules => { - 'lb' => [ qw/glite-LB/ ], - 'px' => [ qw/glite-PX/ ], - }, - }, - - emi => { - current_version => 2, - etics_name => 'emi', - conf_prefix => { - 'lb' => 'emi-', - 'jp' => 'emi-', - 'jobid' => 'emi-', - 'lbjp-common' => 'emi-', - 'gridsite' => 'emi-', - 'px' => 'emi-', - 'canl' => 'emi-', - }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour= --nothrflavour=', - local_prefix => '/usr', - etics_externs => { - default => { - globus_essentials=>'globus-gssapi-gsi', - globus=>'globus-gssapi-gsi-devel', - globus_proxy_utils=>'globus-proxy-utils', - gridsite=>'emi.gridsite.libs', - yaim_core=>'emi.yaim.yaim-core', - yaim_bdii=>'emi.bdii.yaim-bdii', - gip_service=>'emi.bdii.glite-info-provider-service', - bdii=>'emi.bdii.core', - glite_version=>'emi.emi-version', - glue_schema=>'emi.bdii.glue-schema', - trustmanager=>'emi.java-security.trustmanager', - trustmanager_axis=>'emi.java-security.trustmanager-axis', - axis=>'axis1.4', - lcas=>'emi.sac.lcas', - gsoapxx=>'-', - jdk=>'java', - voms => 'emi.voms.voms-api', - }, - sl5_x86_64_gcc412EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - sl6_x86_64_gcc446EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - deb6_x86_64_gcc445 => { - axis => 'axis1.4', - # mappings in ETICS project configuration - #globus_essentials => 'libglobus-gssapi-gsi4', - #globus => 'libglobus-gssapi-gsi-dev', - #axis => 'libaxis-java', - #cares => 'libc-ares2', - #cppunit => 'libcppunit', - #expat => 'libexpat1', - #log4c => 'liblog4c3', - #curl => 'libcurl3', - #'mysql' => 'libmysqlclient16', - #'mysql-devel' => 'libmysqlclient-dev', - #libxslt => 'xsltproc', - #'jakarta-commons-codec' => 'libcommons-codec-java', - #'jakarta-commons-lang' => 'libcommons-lang-java', - #'tetex-latex' => 'texlive-latex-extra', - #'perl-LDAP' => 'libnet-ldap-perl', - #'fuse-lib' => 'libfuse2', - #'fuse' => 'fuse-utils', - }, - }, - etics_externs_devel => { - default => { - cares => 'c-ares-devel', - classads => 'classads-devel', - cppunit => 'cppunit-devel', - expat => 'expat-devel', - gsoap => 'gsoap-devel', - voms => 'emi.voms.voms-api-devel', - libtar => 'libtar-devel', - log4c => 'log4c-devel', - postgresql => 'postgresql-devel', - curl => 'curl-devel', - libxml2 => 'libxml2-devel', - openssl => 'openssl-devel', - gridsite=>'emi.gridsite.devel', - jdk=>'java-devel', - }, - deb6_x86_64_gcc445 => { - # mappings in ETICS project configuration - #cares => 'libc-ares-dev', - #cppunit => 'libcppunit-dev', - #expat => 'libexpat1-dev', - #libtar => 'libtar-dev', - #log4c => 'liblog4c-dev', - #postgresql => 'libpq-dev', - #curl => 'libcurl4-openssl-dev', - #libxml2 => 'libxml2-dev', - #openssl => 'libssl-dev', - #'tetex-latex' => 'texlive-latex-extra', - #libxslt=>'xsltproc', - #'httpd-devel' => 'apache2-prefork-dev', - #'fuse-devel' => 'libfuse-dev', - #gsoap => 'gsoap', - #'krb5-devel' => 'libkrb5-dev', - }, - }, - etics_projects => { - 'emi'=>[qw/voms voms-devel gridsite lcas gip_service bdii glite_version glue_schema yaim_core yaim_bdii trustmanager trustmanager_axis/], - }, - etics_locations => { - axis => 'axis', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ], - 'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - 'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412EPEL => 1, - sl5_ia32_gcc412EPEL => 1, - sl6_x86_64_gcc446EPEL => 1, - deb6_x86_64_gcc445 => 1, - }, - modules => { - 'lb' => [ qw/emi-lb/ ], - 'px' => [ qw/emi-px/ ], - }, - }, -); - -%platform_properties = ( - 'jobid.api-java' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.types' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.doc' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.ws-interface' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.nagios' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.myproxy-config' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'gridsite.devel' => { - default => { 'packageName' => 'gridsite-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' }, - }, - 'jobid.api-c-devel' => { - default => { 'packageName' => 'glite-jobid-api-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' }, - }, - 'jobid.api-cpp-devel' => { - default => { 'packageName' => 'glite-jobid-api-cpp-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' }, - }, - 'lbjp-common.db-devel' => { - default => { 'packageName' => 'glite-lbjp-common-db-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' }, - }, - 'lbjp-common.gsoap-plugin-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' }, - }, - 'lbjp-common.gss-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gss-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' }, - }, - 'lbjp-common.jp-interface-devel' => { - default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' }, - }, - 'lbjp-common.log-devel' => { - default => { 'packageName' => 'glite-lbjp-common-log-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' }, - }, - 'lbjp-common.maildir-devel' => { - default => { 'packageName' => 'glite-lbjp-common-maildir-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' }, - }, - 'lbjp-common.server-bones-devel' => { - default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' }, - }, - 'lbjp-common.trio-devel' => { - default => { 'packageName' => 'glite-lbjp-common-trio-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' }, - }, - 'lb.client-devel' => { - default => { 'packageName' => 'glite-lb-client-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' }, - }, - 'lb.common-devel' => { - default => { 'packageName' => 'glite-lb-common-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' }, - }, - 'lb.state-machine-devel' => { - default => { 'packageName' => 'glite-lb-state-machine-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' }, - }, - 'lb.logger-devel' => { - default => { 'packageName' => 'glite-lb-logger-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' }, - }, - 'px.proxyrenewal-devel' => { - default => { 'packageName' => 'glite-px-proxyrenewal-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' }, - }, -); - -my @k = keys %deps_aux; -@buildroot{@k} = ('') x ($#k+1); - -$buildroot{'gridsite.core'} = 'src'; -} - -sub full -{ - my ($short) = @_; - my $subsys = $short; - $subsys =~ s/\..*//; - - my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite'; - return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short"; -} - -sub get_version -{ - my ($fmod, $top_srcdir) = @_; - - my ($subsys,$mod) = split /\./,$fmod,2; - my ($major,$minor,$rev,$age); - my $old_; - - if ($force_version) { - $force_version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - my $path = "$top_srcdir/project"; - if ($subsys eq 'gridsite') { - $path = "$cvs_prefix{$subsys}.$subsys.core/project"; - } - open V,"$path/version.properties" - or die "$path/version.properties: $!\n"; - - $old_ = $_; - while () { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - $_ = $old_; - } - $version = "$major.$minor.$rev-$age"; - - return ($major, $minor, $rev, $age); -} - -sub get_description -{ - my ($top_srcdir) = @_; - - my $cvs_module = $top_srcdir; - my $package_description = ""; - my $package_summary = ""; - - if (-e "$cvs_module/project/package.description") { - open V, "$cvs_module/project/package.description"; - $package_description = join ("", ); - close V; - chomp $package_description; - } - else { - print STDERR "package.description not found for $subsys.$module!\n"; } - - if (-e "$cvs_module/project/package.summary") { - open V, "$cvs_module/project/package.summary"; - $package_summary = join ("", ); - close V; - chomp $package_summary; - $package_summary =~ s/\n/\\n/g; - } - else { - print STDERR "package.summary not found for $subsys.$module!\n"; } - - return ($package_summary, $package_description); -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb -lbjp-common.gss lbjp-common.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px -canl.c -/; - @aux{@m} = (1) x ($#m+1); - - my ($short) = @_; - my $full = full $short; - my ($subsys,$mod) = split /\./,$short,2; - my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}"; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $top_srcdir = '.'; - my $abs_srcdir = ''; - my $build = ''; - - if ($module) { - $top_srcdir = $0; - $top_srcdir =~ s,/?[^/]*$,,; - $abs_srcdir = $top_srcdir; - $top_srcdir =~ s,^$,\.,; - } else { - $build = "$full/"; - $abs_srcdir = "$full/"; - unless ($buildroot{$_} eq '') { - $top_srcdir = '..'; - $build .= "$buildroot{$_}/"; - unless (-d "$build") { - mkdir "$build" or die "mkdir $build: $!\n"; - } - } - } - - my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir; - my ($package_summary, $package_description) = get_description $abs_srcdir; - if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; } - my $package_description_debian = $package_description; - $package_description_debian =~ s/^/ /mg; - - my ($old_locale, $specdate, $debdate); - - # files for ETICS always in root source directory - mkdir $abs_srcdir."project" unless (-d $abs_srcdir."project"); - open PKGCHL,">".$abs_srcdir."project/changelog" - or die $abs_srcdir."project/changelog: $!\n"; - $old_locale = setlocale(LC_TIME); - setlocale(LC_TIME, "C"); - $specdate = strftime("%a %b %d %Y", gmtime()); - $debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime()); - setlocale(LC_TIME, $old_locale); - print PKGCHL qq{* $specdate CESNET team -- automatically generated package -}; - close PKGCHL; - - unless ($top_srcdir eq '.') { - unlink $build."Makefile"; - symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n"; - } - - open MKINC,">".$build."Makefile.inc" - or die $build."Makefile.inc: $!\n"; - - print "Creating ".$build."Makefile.inc\n"; - - print MKINC qq{project = $project -PREFIX = $root -prefix = $prefix -stagedir = $stagedir -sysroot = $sysroot -sysconfdir = $sysconfdir -localstatedir = $localstatedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -libdir = $libdir -top_srcdir = $top_srcdir -}; - - for (@{$need_externs{$short}}) { - next unless defined $externs{$_} and defined $externs{$_}{prefix}; - print MKINC "${_}_prefix = $externs{$_}{prefix}\n"; - print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags}; - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; - - my $dh; - my $debian = 0; - - opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!"; - for my $dir (readdir $dh) { - if ($dir=~/^(.*)\.spec$/) { - if ($1 ne $packageName) { - printf STDERR "Changed RPM name: $packageName --> $1\n" if ($debug);; - $packageName=$1; - } - last; - } - } - closedir $dh; - - for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") { - if (-f "$abs_srcdir/project/$file") { - my $old_ = $_; - printf STDERR "Creating $build$file\n" if ($debug);; - open DST, ">$build$file"; - open SRC, "<$abs_srcdir/project/$file"; - while () { - if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; } - if (/\@URL\@/) { s/\@URL\@/$package{url}/g; } - if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; } - if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; } - if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; } - if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; } - if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; } - if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; } - if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; } - if (/\@AGE\@/) { s/\@AGE\@/$age/g; } - if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; } - if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; } - if (/\@DEBIAN_VCS\@/) { s/\@DEBIAN_VCS\@/$package{debian_vcs}/g; } - if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; } - if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; } - if (/^\s*.+\/configure\s/ and $force_version) { - print "Version forced to $version\n" if ($debug);; - s/--version\s+\S+\s?//; - s/$/ --version $version/; - } - printf DST "%s", "$_"; - } - close SRC; - close DST; - $_ = $old_; - } - } - - print "Creating ${build}debian/\n" if ($debug);; - - `rm -rfv ${build}debian`; - mkdir $build."debian" or die $!; - `cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`; - `mv ${build}debian.* ${build}debian/ 2>/dev/null`; - `rm -f ${build}debian/*.orig`; - opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!"; - for $_ (readdir $dh) { - if (/^debian\.(.*)/) { - `mv ${build}debian/$_ ${build}debian/$1`; - $debian = 1; - } - } - closedir $dh; - - if ($debian) { - my ($dir, $file); - - chmod 0755, "${build}debian/rules"; - $file="${build}debian/docs"; if (not -f $file) { `touch $file`; } - $dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; } - $file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` } - $file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` } - $file="${build}debian/changelog"; if (not -f $file) { - open FH, ">$file" or die $!; - print FH qq{$packageName ($major.$minor.$rev-$age) unstable; urgency=low - - * Automatically generated package - - -- $package{maintainer} $debdate -}; - close FH; - } - - } else { - `rm -rf ${build}debian`; - } -} - -BEGIN{ -}; - -sub mode_etics_packaging { - my ($fmod, $cmd, $rpmprepare, $debprepare) = @_; - my ($workspaceDir, $srcPackageName, $srcAge, $topDir); - - # old-school packaging by ETICS for EMI-1 - if ($project eq 'emi' and $project_version == 1) { return; } - - if ($fmod eq 'gridsite.core') { - $workspaceDir = '..'; - $srcPackageName = 'gridsite'; - $srcAge = ''; - $topDir = '../'; - } else { - $workspaceDir = '${workspaceDir}'; - $srcPackageName = '${packageName}'; - $srcAge = '-${age}'; - $topDir = ''; - } - - $cmd->{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SRPMSLocation}'; - $cmd->{default}{packaging} = $rpmprepare; - $cmd->{default}{packaging} .= "dir=\${workspaceDir}/rpm_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SRPMSLocation} \$dir/{BUILD,RPMS,SOURCES,SRPMS} 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/SOURCES/ - rpmbuild -bs --nodeps --define \"_topdir \$dir\" $srcPackageName.spec - cp -v \$dir/SRPMS/*.src.rpm \${package.SRPMSLocation}/ - rm -rf \$dir"; - - for my $p ('deb5_x86_64_gcc432', 'deb5_ia32_gcc432', 'deb6_x86_64_gcc445', 'deb6_ia32_gcc445') { - for my $c (keys %{$cmd->{default}}) { $cmd->{$p}{$c} = $cmd->{default}{$c}; } - $cmd->{$p}{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SDEBSLocation}'; - $cmd->{$p}{packaging} = $debprepare; - $cmd->{$p}{packaging} .= "dir=\${workspaceDir}/dpkg_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SDEBSLocation} \$dir 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/${srcPackageName}_\${version}.orig.tar.gz - tar xzf \$dir/${srcPackageName}_\${version}.orig.tar.gz -C \$dir - cp -rf ${topDir}debian/ \$dir/$srcPackageName-\${version}/ - cd \$dir/$srcPackageName-\${version} - dpkg-buildpackage -S -d -nc - cd - - cp -v \$dir/*.tar.gz \$dir/*.dsc \${package.SDEBSLocation}/ - rm -rf \$dir"; - } -} - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod,2; - my $full = full "$subsys.$module"; - - my ($major,$minor,$rev,$age) = get_version $fmod, $full; - - # XXX: --with ignored for platform-dependend packages - my @copts = (); - my %ge; - @ge{@{$etics_projects{$project{etics_name}}}} = (1) x ($#{$etics_projects{$project{etics_name}}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/ and (defined $externs{$_} or defined $jar{$_})) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - next if ($eext eq '-'); - if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}) { - $eext = $project{etics_locations}{$_} if ($project{etics_locations}{$_}); - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } else { - if ($ge{$_} and not defined $externs{$_}{pkg}) { - push @copts, "--with-$_=\${stageDir}"; - } - } - } - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}); - } - - my $conf; - my $conftag; - my ($confprefix, $nameprefix, $packageName); - - $dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n"; - - $confprefix = $project{conf_prefix}{$subsys}; - $nameprefix = $confprefix; - $nameprefix =~ s/-$//; - $nameprefix =~ s/-/\./g; - $packageName = "$project{tag_prefix}{$subsys}$subsys-${module}"; - - if ($branch) { - $conf = "$confprefix${subsys}-${module}_$branch"; - $conftag = $branch; - # forced low age number - $age = $branch eq 'HEAD' ? '0head' : '0dev'; - push @copts, '--version ${version}-${age}'; - } - else { - $conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; -# XXX: gridsite hack - $conftag = $subsys eq 'gridsite' ? "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : - "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - - # lowering age for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age - 1; - } - } - - # emi1 suffix for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age.$project.$project_version; - $conf = $conf.$project.$project_version; - } - - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"}; - - my $confdir = $buildroot{"$subsys.$module"} eq '' ? '.' : '..'; - - my $cvs_module = full "$subsys.$module"; - my ($package_summary, $package_description) = get_description $cvs_module; - if ($package_description) { - $package_description =~ s/\n/\\n/g; - $package_description = "package.description = $package_description\n"; - } - if ($package_summary) { - $package_summary = "package.summary = $package_summary\n"; - } - - my %cmd; - $cmd_vcs{checkout} = "cvs -d \${vcsroot} co -d \${moduleName} ".($conftag eq 'HEAD' ? '-A' : '-r ${tag}')." $cvs_module 2>/dev/null"; - #$cmd_vcs{checkout} = "((test -d jra1mw/.git && (cd jra1mw; git pull)) || (git clone -q http://scientific.zcu.cz/git/jra1mw.git"; - #$cmd_vcs{checkout} .= " && (cd jra1mw; git checkout -b \${tag} --track origin/\${tag})" unless ($conftag eq /HEAD/); - #$cmd_vcs{checkout} .= ")) && (test -d \${moduleName} || ln -s jra1mw/$cvs_module \${moduleName})"; - $cmd_vcs{checkout} .= "\n\ttest -f \${packageName}-\${version}-\${age}.src.tar.gz || (ln -s \${moduleName} \${packageName}-\${version}; tar -chf - \${packageName}-\${version} --exclude CVS --exclude .git --exclude .etics | gzip --best > \${packageName}-\${version}-\${age}.src.tar.gz; rm \${packageName}-\${version})"; - $cmd_vcs{tag} = "cvs -d \${vcsroot} tag -R \${tag} ${moduleName}"; - - $cmd{default}{init} = 'None'; - $cmd{default}{configure} = 'None'; - $cmd{default}{compile} = 'None'; - $cmd{default}{test} = 'None'; - $cmd{default}{install} = 'None'; - $cmd{default}{packaging} = 'None'; - $cmd{default}{clean} = 'make clean'; - - if (exists $subpackages{$fmod}) { - $cmd{default}{clean} = 'None'; - $cmd{default}{packaging} = "echo building nothing, $subpackages{$fmod} will build this package"; - $cmd_vcs{checkout} = "mkdir -v \${moduleName} 2>/dev/null || true"; - } elsif ($subsys eq 'gridsite') { - $cmd_vcs{tag} = 'None'; - - if ($module eq 'core') { - my $flags; - - if ($project ne 'glite') { - # don't evaluate pkg-config calls to get them into source package - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=\`pkg-config gsoap --variable=prefix\` - OPENSSL_GLOBUS_FLAGS=\`pkg-config globus-openssl --cflags\` - OPENSSL_GLOBUS_LIBS=\`pkg-config globus-openssl --libs\`'; - } else { - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=${gsoap.location} - OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor} - OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir} - HTTPD_FLAGS=-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-1 -I${httpd-devel.location}/include/apr-1.0 -I${httpd-devel.location}/include/apr-0 -I${httpd-devel.location}/include/pcre'; - } - - $cmd{default}{configure} = "cat > Makefile.inc </dev/null"; - $cmd{default}{init} = 'echo "/sbin/ldconfig" > project/.post - echo "/sbin/ldconfig" > project/.postun'; - $cmd{default}{configure} = "cat > src/Makefile.inc <{default}}) { - $defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n"; - } - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = $project{etics_name}.$subsys.$module -displayName = $conf -description = $cvs_prefix{$subsys}.$subsys.$module -projectName = $project{etics_name} -age = $age -deploymentType = None -vcsroot = :pserver:anonymous\@glite.cvs.cern.ch:/cvs/glite -tag = $conftag -version = $major.$minor.$rev -$dwpath -[Platform-default:VcsCommand] -displayName = None -description = None -tag = $cmd_vcs{tag} -branch = None -commit = None -checkout = $cmd_vcs{checkout} - -}; - - for my $p (keys %cmd) { - next if $p ne 'default' and exists $project{supported_platforms} and not exists $project{supported_platforms}{$p}; - - print C qq{[Platform-$p:BuildCommand] -postpublish = None -packaging = $cmd{$p}{packaging} -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = $cmd{$p}{compile} -init = $cmd{$p}{init} -install = $cmd{$p}{install} -clean = $cmd{$p}{clean} -test = $cmd{$p}{test} -configure = $cmd{$p}{configure} -checkstyle = None - -}; - } - - print C qq{[Platform-default:Property] -$buildroot -package.preserve.libtool = false -$package_description$package_summary$defprops}; - - for (@{$obsoletes{"$subsys.$module"}}) { - print C "package.obsoletes = $_\n"; - print C "package.replaces = $_\n"; - } - for (@{$conflicts{"$subsys.$module"}}) { - print C "package.conflicts = $_\n"; - } - for (@{$provides{"$subsys.$module"}}) { - print C "package.provides = $_\n"; - } - print C "\n"; - - for my $pp (keys %{$platform_properties{"$subsys.$module"}}) { - next if $pp eq 'default'; - next if exists $project{supported_platforms} and not exists $project{supported_platforms}{$pp}; - - print C "[Platform-$pp:Property]\n$buildroot\n"; - - for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) { - print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n"; - } - print C "$package_description$package_summary\n"; - } - - for my $platform ('default', keys %{$project{supported_platforms}}) { - my $used = 0; - my $output = ''; - - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$platform}{$_}; - my $edev = $project{etics_externs_devel}{$platform}{$_}; - - # for the default platform using package of the same - # name for runtime dependency - if (not $eext) { - if ($platform eq 'default') { -#print "default runtime $_ on default\n"; - $eext = $_; } - else { -#print "no runtime $_ on $platform\n"; - $eext = '-'; } - } - if ($eext eq '-' and $edev eq '-') { -#print "skipping $_ on $platform\n"; - next; - } - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - - if ($edev) { - if ($type eq 'B') { - # no runtime - change to devel pkg - $eext = $edev; - } elsif ($type eq 'BR' or $type eq 'RB') { - # additional devel pkg - if ($edev ne '-') { $output .= "$proj|$edev = B\n"; } - } - } - if ($eext ne '-') { $output .= "$proj|$eext = $type\n"; } - } - - if ($platform eq 'default') { - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - if (not $used) { - $used = 1; - } - $output .= "$project{etics_name}|$project{etics_name}.$_ = $type\n"; - } - } - - if ($output) { - print C qq{ -[Platform-$platform:DynamicDependency] -$output}; - } - } - - close C; - - for $file ("$cvs_module/project/debian.rules", "$cvs_module/project/$packageName.spec") { - my $lib; - my $main_module; - @copts = (); - - if ($file =~ /debian\.rules$/) { $lib = 'lib'; } - else { $lib = '%{_lib}'; } - - my $main_module = "$subsys.$module"; - if (exists $subpackages{$main_module}) { $main_module = $subpackages{$main_module}; } - - # locations hacks - if ($file =~ /$packageName\.spec$/) { - if ($fmod eq 'lb.client-java') { - push @copts, ''; - push @copts, '--with-axis=/usr/local/axis1.4'; - } - } - - if (-f $file) { - open DST,">$file.new" or die "$file.new: $!\n"; - open SRC,"<$file" or die "$file: $!\n"; - while () { - if (/^(\s*).+\/configure\s/) { - printf DST "%s", "$1"; - printf DST "/usr/bin/perl $confdir/configure $project{flavours} --root=/ --prefix=$project{local_prefix} --libdir=$lib --project=$project --module $main_module@copts\n"; - } else { - printf DST "%s", "$_"; - } - } - close SRC; - close DST; - - `diff -b "$file" "$file.new"`; - if ($? == 0) { - print STDERR "($file not changed)\n"; - unlink "$file.new"; - } else { - print STDERR "Writing $file\n"; - rename "$file", "$file.orig" unless -f "$file.orig"; - rename "$file.new", "$file"; - } - } - } -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - $gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - -sub getlibdir { - if ( -e "/etc/debian_version") { # We are on Debian - $lib64="lib"; - $lib32="lib32"; } - else { # Another distribution - $lib64="lib64"; - $lib32="lib"; } - $libdir=$lib32; - - open INP, "uname -s | "; # Check kernel name - $kname= ; - chomp($kname); - close INP; - - if ( $kname eq "Linux") { - $arch = ("x86_64\npowerpc\nppc64\n"); - - open INP, "uname -p | "; # Check processor type - $procname= ; - chomp($procname); - close INP; - - if ($arch =~/^$procname\n/) { - return ($lib64); } - - open INP, "uname -m | "; # Check machine hardware - $machname= ; - chomp($machname); - close INP; - - if ($arch =~/^$machname\n/) { - return ($lib64); } - - # special cases (hyperlink lib64, Debian) - if (-l "/usr/lib64") { - $libdir=$lib32; } - - # if /usr/lib64 doesn't exist at all (AIX) - unless ( -e "/usr/lib64" ) { - $libdir=$lib32; } - } - - if ( $kname eq "SunOS") { - if (-e "/usr/lib/64") { - $libdir="lib/64"; } - } - - return $libdir; -} - -sub reshuffle_platforms($$) { - my ($data, $platforms) = @_; - my ($platform, %blacklist, $value); - - return if not $platforms; - - for $platform (keys %$data) { -#print "plat: $platform: $data->{$platform}\n"; - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { -#print " blacklist: $_ = $data->{$platform}{$_}\n"; - $blacklist{$_} = 1; - } - } - - for $_ (keys %blacklist) { - $value = $data->{default}{$_} ? $data->{default}{$_} : $_; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - if (not defined $data->{$platform}{$_}) { - $data->{$platform}{$_} = $value; -#print "added $value to $platform\n" - } - } - $data->{default}{$_} = '-'; -#print "deleted $_ from default\n"; - } - - # merge dependencies across the supported platforms - %blacklist = []; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { - $blacklist{$_} = 1; - } - } - for $_ (keys %blacklist) { - $value = undef; - $same = 1; - for $platform (keys %$platforms) { - if (not $value) { $value = $data->{$platform}{$_}; } - if (not $data->{$platform}{$_} or $value ne $data->{$platform}{$_}) { - $same = 0; - last; - } - } - if ($same and $value) { -#print "merged dependency $_\n"; - $data->{default}{$_} = $value; - for $platform (keys %$platforms) { - delete $data->{$platform}{$_}; - } - } - } -} - -sub usage { - my @ext = keys %externs; - my @myjars = keys %jar; - - print STDERR qq{ -Usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --stage=DIR staging directory [./stage] - --root=DIR installation root (custom relocation root -> sysroot) [./stage] - --sysroot=DIR system root (custom relocation root -> sysroot) [] - --sysconfdir=DIR system configuration directory [PREFIX/etc] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - --listmodules=module list subpackages of a module - --version=maj.min.rev-age version used instead of reading version.properties - --branch=branch CVS branch/etics name suffix (HEAD, branch_2_1, ...) - --libdir=libdir typically [lib,lib64] postfix - --project=PROJECT build or generate etics for a project (glite/emi1/emi) [emi] - --debug print more details - -Mode of operation: - --mode=\{checkout|build|etics\} what to do [build] - -What to build: - --module=module build this module only - --enable-NODE build this "node" (set of modules) only - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - --canl-tag=tag checkout canl modules with specific tag - -Dependencies (summary of what will be used is always printed): - --with-EXTERNAL=PATH where to look for an external [autodetect] - --with-JAR=JAR where to look for jars - -Available nodes: - @nodes - -Default nodes: - @default_nodes - -Externals (not all for all modules) are: - @ext - -External jars are: - @myjars - -}; - -} diff --git a/org.glite.lb.client-java/examples/CreamTest.java b/org.glite.lb.client-java/examples/CreamTest.java deleted file mode 100644 index 3e9fc14..0000000 --- a/org.glite.lb.client-java/examples/CreamTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import org.glite.lb.*; -import org.glite.jobid.Jobid; - -public class CreamTest { - -public static void main(String[] args) -{ - - int i; - String srv = null,socket = null,prefix = null,lib = "glite_lb_sendviasocket"; - - for (i = 0; i < args.length; i++) { - if (args[i].equals("-m")) srv = args[++i]; - else if (args[i].equals("-s")) socket = args[++i]; - else if (args[i].equals("-f")) prefix = args[++i]; - else if (args[i].equals("-l")) lib = args[++i]; /* needs java.library.path */ - } - - try { - String[] srvpart = srv.split(":"); - int srvport = Integer.parseInt(srvpart[1]); - Jobid job = new Jobid(srvpart[0],srvport); - - LBCredentials cred = new LBCredentials(System.getenv("X509_USER_PROXY"),"/etc/grid-security/certificates"); - - - ContextDirect ctxd = new ContextDirect(srvpart[0],srvport); - ctxd.setCredentials(cred); - ctxd.setSource(new Sources(Sources.CREAM_EXECUTOR)); - ctxd.setJobid(job); - ctxd.setSeqCode(new SeqCode(SeqCode.CREAM,"no_seqcodes_with_cream")); - - -/* initial registration goes directly */ - EventRegJob reg = new EventRegJob(); - reg.setNs("https://where.is.cream:1234"); - reg.setJobtype(EventRegJob.Jobtype.CREAM); - ctxd.log(reg); - - System.out.println("JOBID="+job); - - ContextIL ctx = new ContextIL(prefix,socket,lib); - ctx.setSource(new Sources(Sources.CREAM_EXECUTOR)); - ctx.setJobid(job); - ctx.setSeqCode(new SeqCode(SeqCode.CREAM,"no_seqcodes_with_cream_cheat_duplicate")); - ctx.setUser(ctxd.getUser()); - -/* 2nd registration with JDL, via IL */ - reg.setJdl("[\n\ttest = \"hellow, world\";\n]"); - ctx.log(reg); - - Event e = new EventCREAMStart(); - ctx.log(e); - - EventCREAMStore store = new EventCREAMStore(); - store.setResult(EventCREAMStore.Result.START); - store.setCommand(EventCREAMStore.Command.CMDSTART); - ctx.log(store); - - EventCREAMCall call = new EventCREAMCall(); - call.setCallee(new Sources(Sources.LRMS)); - call.setDestid("fake_Torque_ID"); - call.setResult(EventCREAMCall.Result.OK); - call.setCommand(EventCREAMCall.Command.CMDSTART); - - ctx.log(call); - - } catch (Exception e) - { - System.err.println("Oops"); - e.printStackTrace(); - } - -} - - - -} diff --git a/org.glite.lb.client-java/examples/NotificationExample.java b/org.glite.lb.client-java/examples/NotificationExample.java deleted file mode 100644 index 8e9a88e..0000000 --- a/org.glite.lb.client-java/examples/NotificationExample.java +++ /dev/null @@ -1,114 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ - -import org.glite.lb.Notification; -import org.glite.lb.LBCredentials; -import org.glite.lb.LBException; - -import java.util.Date; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.glite.wsdl.types.lb.JobStatus; -import org.glite.wsdl.types.lb.QueryAttr; -import org.glite.wsdl.types.lb.QueryConditions; -import org.glite.wsdl.types.lb.QueryOp; -import org.glite.wsdl.types.lb.QueryRecValue; -import org.glite.wsdl.types.lb.QueryRecord; -import org.glite.wsdl.types.lb.StatName; - -/** - * This is an example on how to use the package org.glite.lb.notif_java - * - * - * @author Kopac - */ -public class NotificationExample { - - /** - * example method on how to use this package - * - * @param args parameters for the methods, order as follows: - *

    - * 1. path to user's certificate - *

    - * 2. path to a list of trusted certificates - *

    - * 3. owner ID - *

    - * 4. port number - *

    - * 5. LB server address - */ - public static void main(String[] args){ - try { - - //creation of an instance of class that prepares SSL connection for - //webservice, first of the two possibilities is used - LBCredentials credentials = new LBCredentials(args[0], args[1]); - - //creation of QueryConditions instance. this one tells the notification to - //be associated with jobs of an owner and that don't have a tag. meh - QueryRecValue value1 = new QueryRecValue(null, args[2], null); - QueryRecord[] record = new QueryRecord[]{new QueryRecord(QueryOp.EQUAL, value1, null)}; - QueryConditions[] conditions = new QueryConditions[]{new - QueryConditions(QueryAttr.OWNER, null, StatName.SUBMITTED, record)}; - - //creating an instance of NotificationImpl, the argument is port number - Notification notif = new Notification(Integer.parseInt(args[3]), credentials); - - Date date = new Date(System.currentTimeMillis()+86400000); - - //registering a new notification, first parameter is LB server address in String, - //second previously created QueryConditions, there are no JobFlags provided - //and the last one tells the server to keep it active for two days - notif.newNotif(args[4], conditions, null, date); - - //id of the newly created notification - String notifId = notif.getNotifid(); - - //refreshing the previously created notification by two days - notif.refresh(notifId, date); - - //tells the client to read incomming notifications with a timeout of 1 minute - JobStatus state = notif.receive(60000); - //from here on, state can be used to pick the desired info using its - //get methods - - //like this - System.out.println(state.getAcl()); - System.out.println(state.getCancelReason()); - System.out.println(state.getJobId()); - - //creates a new instance of NotificationImpl with the port 14342 and - //binds the notification to this new instance, meaning to a new local - //address - Notification notif2 = new Notification(14342, credentials); - notif2.bind(notifId, date); - - //lastly, the notification is dropped - notif2.drop(notifId); - - } catch (LBException ex) { - Logger.getLogger(NotificationExample.class.getName()).log(Level.SEVERE, null, ex); - } - } -} diff --git a/org.glite.lb.client-java/examples/ProducerTestIL.java b/org.glite.lb.client-java/examples/ProducerTestIL.java deleted file mode 100644 index a2cda6b..0000000 --- a/org.glite.lb.client-java/examples/ProducerTestIL.java +++ /dev/null @@ -1,166 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -import java.util.Random; -import org.glite.jobid.Jobid; -import org.glite.lb.*; - -/** - * This class shows how to work with ContextIL. - * - * @author Pavel Piskac - */ -public class ProducerTestIL { - - public static void main(String[] args) { - - if (args.length != 10) { - System.out.println("How to use test class:\n" + - "you have to set 10 arguments in this order, if the choice is optional \"\" or text has to be set:\n" + - "1. jobid in format \"https://somewhere:port/unique_part\" (required)\n" + - "2. path to shared library written in c to be able to send messages via unix socket (optional)\n" + - "3. source, enum constant from class Sources, determines which part of sequence code will be increased (required)\n" + - "4. flag (required)\n" + - "5. host name, if it is \"\" then is set name of the computer where is test class running (optional)\n" + - "6. user name (required)\n" + - "7. srcInstance (optional)\n" + - "8. path to directory where will be saved files with events for each job (required)\n" + - "9. path to unix socket (required if path to shared library is set)\n" + - "10. description for event in this case event running (required)\n"); - } else { - /* Create new instance of jobid, you can use other constructors too (see org.glite.jobid.api_java.Jobid.java) - * Examples: - * Jobid jobid = new Jobid("https://skurut68-2.cesnet.cz:9000/paja6_test2"); - */ - Jobid jobid = new Jobid(args[0]); - System.out.println("jobid: " + args[0]); - - /* Create sequence code - * Example: - * SeqCode seqCode = new SeqCode(); - * Insert sequence number in format - * UI=XXXXXX:NS=XXXXXXXXXX:WM=XXXXXX:BH=XXXXXXXXXX:JSS=XXXXXX:LM=XXXXXX:LRMS=XXXXXX:APP=XXXXXX:LBS=XXXXXX - * where X is 0-9, or you can just create new instance of SeqCode where all parts are set to 0 - * Example: - * SeqCode seqCode = new SeqCode(); - * seqCode.getSeqCodeFromString("UI=000001:NS=0000000002:WM=000003:BH=0000000004:" + - * "JSS=000005:LM=000006:LRMS=000007:APP=000008:LBS=000009"); - * seqCode.incrementSeqCode(Sources.USER_INTERFACE); - * resulting sequence code will be - * UI=000002:NS=0000000002:WM=000003:BH=0000000004:JSS=000005:LM=000006:LRMS=000007:APP=000008:LBS=000009 - */ - SeqCode seqCode = new SeqCode(); - - /* Choose type of sending a log messages (at this time is implemented only ContextIL class) - * You can choose from some constructors (see org.glite.lb.client_java.ContextIL class) - */ - ContextIL ctx = new ContextIL(); - - /* If you chose emtpy ContextIL constructor you have to set some attributes. - * One of them is pathToNativeLib which sais where java can find shared library written in c. - * Example: ctx.setPathToNativeLib("/home/paja6/locallogger/build/classes/org/glite/lb/"); - */ - ctx.setPathToNativeLib(args[1]); - System.out.println("pathToNativeLib: " + args[1]); - - /* Id of the message is some random unique number. - */ - ctx.setId(new Random().nextInt(99999999)); - - /* Source indicates source of the message, it is constant from org.glite.lb.client_java.Sources class - * and determines which part of sequence number will be increased. - * Example: ctx.setSource(Sources.LRMS); - * In this case we have to use method which converts args[2] to Sources. In real environment it will - * not be used. - */ - ctx.setSource(new Integer(args[2])); - System.out.println("source: " + args[2]); - - /* Flag - * Example: ctx.setFlag(0); - */ - ctx.setFlag(new Integer(args[3])); - System.out.println("flag: " + args[3]); - - /* Name of the computer where is locallogger running - * Example: ctx.setHost("pelargir.ics.muni.cz"); - */ - ctx.setHost(args[4]); - System.out.println("host: " + args[4]); - - /* Name of the user who owns the job. - * Example: ctx.setUser("Pavel Piskac"); - */ - ctx.setUser(args[5]); - System.out.println("user: " + args[5]); - - /* TODO co to vlastne znamena? - * Mostly "" is set - * Example: ctx.setSrcInstance(""); - */ - ctx.setSrcInstance(args[6]); - System.out.println("srcInstance: " + args[6]); - - /* Set the jobid for the context. - */ - ctx.setJobid(jobid); - - /* Set the jobid for the context. - */ - ctx.setSeqCode(seqCode); - - /* Number of connection attempts while sending the message via unix socket. - * Default value is 3 but you can change it. - */ - ctx.setConnAttempts(5); - - /* Timeout in seconds for the connection while sending the message via unix socket. - * Default value is 3 but you can change it. - */ - ctx.setTimeout(2); - - /* Path to directory where will be saved files with logs until inter-logger sends - * the content. - * Example: ctx.setPrefix("/home/paja6/tmp/dglog." + jobid.getUnique()); - */ - ctx.setPrefix(args[7]); - System.out.println("prefix: " + args[7]); - - /* Path to unix socket. - * Example: ctx.setPathToSocket("/home/paja6/tmp/il.sock"); - */ - ctx.setPathToSocket(args[8]); - System.out.println("pathToSocket: " + args[8]); - - /* Create new instance of the event which will be logged. - */ - EventRunning running = new EventRunning(); - - /* Set some description for the event. - * Example: running.setNode("worker node"); - */ - running.setNode(args[9]); - System.out.println("node: " + args[9]); - - /* And now is the context and event prepared to work. - * - */ - ctx.log(running); - } - } -} diff --git a/org.glite.lb.client-java/examples/ProducerTestLL.java b/org.glite.lb.client-java/examples/ProducerTestLL.java deleted file mode 100644 index ebb01f7..0000000 --- a/org.glite.lb.client-java/examples/ProducerTestLL.java +++ /dev/null @@ -1,184 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -import java.util.Random; -import org.glite.jobid.Jobid; -import org.glite.lb.*; - -/** - * This class shows how to work with ContextIL. - * - * @author Pavel Piskac - */ -public class ProducerTestLL { - - public static void main(String[] args) { - - if (args.length != 12) { - System.out.println("How to use test class:\n" + - "you have to set 12 arguments in this order, if the choice is optional \"\" or text has to be set:\n" + - "1. jobid in format \"https://somewhere:port/unique_part\" (required)\n" + - "2. source, enum constant from class Sources, determines which part of sequence code will be increased (required)\n" + - "3. flag (required)\n" + - "4. host name, if it is \"\" then is set name of the computer where is test class running (optional)\n" + - "5. user name (required)\n" + - "6. srcInstace (optional)\n" + - "7. connection timeout (optional)\n" + - "8. proxy server address (required)\n" + - "9. proxy server port, default value is 9002 (optional)\n" + - "10. path to user's certificate (required)\n" + - "11. path to directory where will be saved files with logs until inter-logger sends the content.\n" + - "12. worker node name for example event."); - } else { - /* Create new instance of jobid, you can use other constructors too (see org.glite.jobid.api_java.Jobid.java) - * Examples: - * Jobid jobid = new Jobid("https://skurut68-2.cesnet.cz:9000/paja6_test2"); - * Jobid jobid = new Jobid("https://skurut68-2.cesnet.cz", 9000, "paja6_test2"); - * Jobid jobid = new Jobid("https://skurut68-2.cesnet.cz", 9000); //unique part is automatically generated - * Jobid jobid = new Jobid(); - * jobid.setBkserver("https://skurut68-2.cesnet.cz"); - * jobid.setPort(9000); - * jobid.setUnique("paja6_testProxy3"); - */ - Jobid jobid = new Jobid(args[0]); - System.out.println("jobid: " + args[0]); - - /* Create sequence code - * Example: - * SeqCode seqCode = new SeqCode(); - * Insert sequence number in format - * UI=XXXXXX:NS=XXXXXXXXXX:WM=XXXXXX:BH=XXXXXXXXXX:JSS=XXXXXX:LM=XXXXXX:LRMS=XXXXXX:APP=XXXXXX:LBS=XXXXXX - * where X is 0-9, or you can just create new instance of SeqCode where all parts are set to 0 - * Example: - * SeqCode seqCode = new SeqCode(); - * seqCode.getSeqCodeFromString("UI=000001:NS=0000000002:WM=000003:BH=0000000004:" + - * "JSS=000005:LM=000006:LRMS=000007:APP=000008:LBS=000009"); - * seqCode.incrementSeqCode(Sources.USER_INTERFACE); - * resulting sequence code will be - * UI=000002:NS=0000000002:WM=000003:BH=0000000004:JSS=000005:LM=000006:LRMS=000007:APP=000008:LBS=000009 - */ - SeqCode seqCode = new SeqCode(); - - /* Choose type of sending a log messages (at this time is implemented only ContextIL class) - * You can choose from some constructors (see org.glite.lb.client_java.ContextIL class) - */ - ContextLL ctx = new ContextLL(); - - /* Id of the message is some random unique number. - * This value will be ceplaced by value from proxy. - */ - ctx.setId(new Random().nextInt(99999999)); - - /* Source indicates source of the message, it is constant from org.glite.lb.client_java.Sources class - * and determines which part of sequence number will be increased. - * Example: ctx.setSource(Sources.LRMS); - * In this case we have to use method which converts args[2] to Sources. In real environment it will - * not be used. - */ - ctx.setSource(new Integer(args[1])); - System.out.println("source: " + args[1]); - - /* Flag. - * Example: ctx.setFlag(0); - */ - ctx.setFlag(new Integer(args[2])); - System.out.println("flag: " + args[2]); - - /* Name of the computer where is locallogger running - * Example: ctx.setHost("pelargir.ics.muni.cz"); - */ - ctx.setHost(args[3]); - System.out.println("host: " + args[3]); - - /* Name of the user who owns the job, this attribute will be replaced - * by value get from certificate. - * Example: ctx.setUser("Pavel Piskac"); - */ - ctx.setUser(args[4]); - System.out.println("user: " + args[4]); - - /* TODO co to vlastne znamena? - * Mostly "" is set - * Example: ctx.setSrcInstance(""); - */ - ctx.setSrcInstance(args[5]); - System.out.println("srcInstance: " + args[5]); - - /* Set the jobid for the context. - */ - ctx.setJobid(jobid); - - /* Set the jobid for the context. - */ - ctx.setSeqCode(seqCode); - - /* Timeout in seconds for the connection while sending the message via unix socket. - * Default value is 3 but you can change it. - */ - ctx.setTimeout(new Integer(args[6])); - System.out.println("timeout: " + args[6]); - - /* Address to proxy. - * Example: - * ctx.setAddress("147.251.3.62"); - */ - ctx.setAddress(args[7]); - System.out.println("address: " + args[7]); - - /* Proxy server port. - * Example: - * ctx.setPort(9002); - */ - ctx.setPort(new Integer(args[8])); - System.out.println("port: " + args[8]); - - /* Path to user's certificate. Only *.ks and *.p12 certificates are allowed. - * Example: - * ctx.setPathToCertificate("/home/paja6/myCertificate.p12"); - */ - ctx.setCredentials(new LBCredentials(args[9],null)); - System.out.println("pathToCertificate: " + args[9]); - - /* Path to directory where will be saved files with logs until inter-logger sends - * the content. - * Example: ctx.setPrefix("/home/paja6/tmp/dglog." + jobid.getUnique()); - */ - ctx.setPrefix(args[10]); - System.out.println("prefix: " + args[10]); - - /* Create new instance of the event which will be logged. - */ - EventRunning running = new EventRunning(); - - /* Set some description for the event. - * Example: running.setNode("worker node"); - */ - running.setNode(args[11]); - System.out.println("node: " + args[11]); - - /* And now is the context and event prepared to work. - * - */ - try { - ctx.log(running); - } catch (LBException e) { - e.printStackTrace(); - } - } - } -} diff --git a/org.glite.lb.client-java/examples/QueryDemo.java b/org.glite.lb.client-java/examples/QueryDemo.java deleted file mode 100644 index 3f8204a..0000000 --- a/org.glite.lb.client-java/examples/QueryDemo.java +++ /dev/null @@ -1,274 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import java.rmi.RemoteException; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.Iterator; -import java.util.List; -import org.glite.jobid.Jobid; -import org.glite.lb.*; -import org.glite.wsdl.types.lb.GenericFault; -import org.glite.wsdl.types.lb.JobStatus; -import org.glite.wsdl.types.lb.QueryAttr; -import org.glite.wsdl.types.lb.QueryConditions; -import org.glite.wsdl.types.lb.QueryOp; -import org.glite.wsdl.types.lb.QueryRecValue; -import org.glite.wsdl.types.lb.QueryRecord; -import org.glite.wsdl.types.lb.StatName; -import org.glite.wsdl.types.lb.Timeval; -import org.apache.axis.AxisFault; - - -/** - * This is a demonstration class for query API. - * It contains all possible methodes that can be called on ServerConnection - * and Job objects. - * @author Tomas Kramec, 207545@mail.muni.cz - */ -public class QueryDemo { - - - /** - * This method serves for formating output information about given job status. - * It is only an example of how the data can be presented. It can be changed - * by user's needs. - * - * @param status Job status - * @return text representation of the given status - */ - private static String jobStatusToString(JobStatus status) { - StringBuilder sb = new StringBuilder(); - sb.append("State: "+status.getState()+"\n"); - sb.append("Job ID: "+status.getJobId()+"\n"); - sb.append("Owner: "+status.getOwner()+"\n"); - sb.append("Job type: "+status.getJobtype()+"\n"); - sb.append("Destination: "+status.getLocation()+"\n"); - sb.append("Done code: "+status.getDoneCode()+"\n"); - sb.append("User tags: "); - //if there are some user tags write it out. - if (status.getUserTags() != null) { - for (int i=0;i idx = sc.getIndexedAttrs(); - for (int i=0;i jobs = sc.userJobs(); - //get their states - List js = sc.userJobStates(); - Iterator it = jobs.iterator(); - Iterator itJs = js.iterator(); - while (it.hasNext()) { - System.out.println(it.next()); - System.out.println(jobStatusToString(itJs.next())); - } - - //Demonstration of Job class - System.out.println(); - System.out.println("----------------JOB----------------"); - - //create new Job - Job myJob = new Job(args[6], sc); - //print job state info - System.out.println(); - System.out.println("Status: " + jobStatusToString(myJob.getStatus(null))); - - //print info about job's events - System.out.println(); - List events = myJob.getEvents(); - System.out.println("Found "+events.size()+" events:"); - for (int i=0;i recList = new ArrayList(); - for (int i=0;i interval) - QueryConditions condOnTime = new QueryConditions(QueryAttr.TIME, null, StatName.SUBMITTED, timeRec); - - //create QueryConditions list representing this formula: - //(JOBID='jobId1' or JOBID='jobId2 or ...) AND (TIME is in interval) - //where jobId1,... are ids of user's jobs - List condList = new ArrayList(); - condList.add(condOnJobid); - condList.add(condOnTime); - - //get all jobs matching the given conditions - List jobResult = sc.queryJobs(condList); - //get all their states - List jobStatesResult = sc.queryJobStates(condList, null); - - //Print information about results - Calendar calendar = new GregorianCalendar(); - DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); - System.out.println(); - System.out.print("Jobs registered "); - calendar.setTimeInMillis(timeFrom.getT().getTvSec()*1000); - System.out.print("from "+ df.format(calendar.getTime())+" "); - calendar.setTimeInMillis(timeTo.getT().getTvSec()*1000); - System.out.print("to "+ df.format(calendar.getTime())+"\n"); - Iterator jobsit = jobResult.iterator(); - Iterator statusit = jobStatesResult.iterator(); - while (jobsit.hasNext()) { - System.out.println(jobsit.next()); - System.out.println(jobStatusToString(statusit.next())); - } - } - } catch (Exception e) - { - Throwable cause = e.getCause(); - - if (cause != null && cause instanceof AxisFault) { - cause.printStackTrace(); - } - else { - System.err.println("Oops"); - e.printStackTrace(); - } - } - } - } -} diff --git a/org.glite.lb.client-java/examples/SSLClient.java b/org.glite.lb.client-java/examples/SSLClient.java deleted file mode 100644 index 9baf00b..0000000 --- a/org.glite.lb.client-java/examples/SSLClient.java +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import org.glite.lb.SSLSend; -import org.glite.lb.LBCredentials; - -public class SSLClient { - public static void main(String[] args) { - - SSLSend ssl = new SSLSend(); - - try { - ssl.send(new LBCredentials(args[0],null),"localhost",9002,100,"baff"); - } - catch (Exception e) { - System.err.println(e); - } - - } -} diff --git a/org.glite.lb.client-java/examples/SSLServer.java b/org.glite.lb.client-java/examples/SSLServer.java deleted file mode 100644 index 99a8789..0000000 --- a/org.glite.lb.client-java/examples/SSLServer.java +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import org.glite.lb.SSL; -import org.glite.lb.LBCredentials; -import java.io.*; -import java.net.Socket; - -public class SSLServer { - public static void main(String[] args) { - - SSL ssl = new SSL(); - - try { - ssl.setCredentials(new LBCredentials(args[0],null)); - Socket sock = ssl.accept(Integer.parseInt(args[1]),100000); - System.out.println("accept ok"); - InputStream in = sock.getInputStream(); - PrintStream out = new PrintStream(sock.getOutputStream(),false); - - while (true) { - byte[] buf = new byte[1000]; - int len = in.read(buf); - System.out.write(buf,0,len); - out.print("buzz off"); - } - } - catch (Exception e) { - e.printStackTrace(); - } - - } -} diff --git a/org.glite.lb.client-java/examples/SimpleLLTest.java b/org.glite.lb.client-java/examples/SimpleLLTest.java deleted file mode 100644 index fe6decb..0000000 --- a/org.glite.lb.client-java/examples/SimpleLLTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import java.util.Random; -import org.glite.jobid.Jobid; -import org.glite.lb.*; - -/** - * This class shows how to work with ContextLL. - * - * @author Pavel Piskac - */ -public class SimpleLLTest { - - public static void main(String[] args) { - - try { - Jobid jobid = new Jobid("https://skurut68-2.cesnet.cz:9000/paja6_test2"); - SeqCode seqCode = new SeqCode(); - ContextLL ctx = new ContextLL(); - ctx.setId(new Random().nextInt(99999999)); - ctx.setSource(1); - ctx.setFlag(0); - ctx.setHost("pelargir.ics.muni.cz"); - ctx.setUser("Pavel Piskac"); - ctx.setSrcInstance(""); - ctx.setJobid(jobid); - ctx.setSeqCode(seqCode); - ctx.setTimeout(5); - ctx.setAddress("localhost"); - ctx.setPort(9002); - ctx.setCredentials(new LBCredentials(args[0],null)); - ctx.setPrefix("/tmp/dglog.paja6_testProxy6"); - EventRunning running = new EventRunning(); - running.setNode("node"); - ctx.log(running); - } - catch (Exception e) { e.printStackTrace(); } - } -} diff --git a/org.glite.lb.client-java/examples/simple-ssl/ExampleSSLSocketFactory.java b/org.glite.lb.client-java/examples/simple-ssl/ExampleSSLSocketFactory.java deleted file mode 100644 index f29e3c0..0000000 --- a/org.glite.lb.client-java/examples/simple-ssl/ExampleSSLSocketFactory.java +++ /dev/null @@ -1,125 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb.examples.ssl; - -import org.apache.axis.components.net.BooleanHolder; -import org.apache.axis.components.net.DefaultSocketFactory; -import org.apache.axis.components.net.SecureSocketFactory; -import org.apache.log4j.Logger; - -import javax.net.ssl.*; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketException; -import java.security.PrivateKey; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Date; -import java.util.Hashtable; - -/** - * Factory for SSLSockets for Axis, which creates sockets for SSLv3 connection. - * Globus SSL libraries don't support SSLv2 initial packet, so SSLv2Hello protocol - * on SSLSocket must be disabled. - * - * @author Martin Kuba makub@ics.muni.cz - */ -public class ExampleSSLSocketFactory extends DefaultSocketFactory implements SecureSocketFactory { - - static Logger log = Logger.getLogger(ExampleSSLSocketFactory.class); - - static Certificate[] cChain = null; - static PrivateKey pKey = null; - static X509Certificate[] certAuths = null; - - static void registerForAxis(Certificate[] certs, PrivateKey privateKey, X509Certificate[] certificateAuthorities) { - log.debug("registering as Axis SecureSocketFactory"); - cChain = certs; - pKey = privateKey; - certAuths = certificateAuthorities; - System.setProperty("org.apache.axis.components.net.SecureSocketFactory", ExampleSSLSocketFactory.class.getName()); - } - - protected SSLSocketFactory sslFactory = null; - - public ExampleSSLSocketFactory(Hashtable attributes) throws Exception { - super(attributes); - SSLContext sctx = SSLContext.getInstance("SSL"); - KeyManager[] myKeys = new KeyManager[]{new MyX509KeyManager(cChain, pKey)}; - TrustManager[] myTrust = new TrustManager[]{new MyX509TrustManager(certAuths)}; - //init SSLContext with our keymanager and trustmanager, and default random device - sctx.init(myKeys, myTrust, null); - if (log.isDebugEnabled()) { - log.debug("attributes: " + attributes); - log.debug("SSLContext.provider: " + sctx.getProvider().getInfo()); - } - sslFactory = sctx.getSocketFactory(); - } - - - public Socket create(String host, int port, StringBuffer otherHeaders, BooleanHolder useFullURL) throws IOException, SocketException { - int i; - - log.debug("create(" + host + ":" + port + ")"); - //create SSL socket - SSLSocket socket = (SSLSocket) sslFactory.createSocket(); - //enable only SSLv3 - socket.setEnabledProtocols(new String[]{"SSLv3"}); // SSLv2Hello, SSLv3,TLSv1 - //enable only ciphers without RC4 (some bug, probably in older globus) - String[] ciphers = socket.getEnabledCipherSuites(); - ArrayList al = new ArrayList(ciphers.length); - for (i = 0; i < ciphers.length; i++) { - if (ciphers[i].indexOf("RC4") == -1) al.add(ciphers[i]); - } - socket.setEnabledCipherSuites((String [])al.toArray(new String[al.size()])); - //connect as client - socket.setUseClientMode(true); - socket.setSoTimeout(30000); //read timeout - socket.connect(new InetSocketAddress(host, port), 3000); //connect timeout - //create or join a SSL session - SSLSession sess = socket.getSession(); - if (sess == null) { - log.debug("sess is null"); - return socket; - } - - if (log.isDebugEnabled()) { - //print all we know - byte[] id = sess.getId(); - StringBuffer sb = new StringBuffer(id.length * 2); - for (i = 0; i < id.length; i++) { - sb.append(Integer.toHexString(id[i] < 0 ? 256 - id[i] : id[i])); - } - log.debug("SSLSession.id = " + sb.toString()); -// log.debug("peerHost:Port = " + sess.getPeerHost() + ":" + sess.getPeerPort()); - log.debug("cipherSuite = " + sess.getCipherSuite()); - log.debug("protocol = " + sess.getProtocol()); -// log.debug("isValid = " + sess.isValid()); - log.debug("creationTime = " + (new Date(sess.getCreationTime()))); - log.debug("lastAccessedTime= " + (new Date(sess.getLastAccessedTime()))); -// log.debug("applicationBufferSize= " + sess.getApplicationBufferSize()); -// log.debug("packetBufferSize= " + sess.getPacketBufferSize()); -// log.debug("localPrincipal= " + sess.getLocalPrincipal()); -// log.debug("peerPrincipal= " + sess.getPeerPrincipal()); - } - return socket; - } - -} diff --git a/org.glite.lb.client-java/examples/simple-ssl/LBClientSSL.java b/org.glite.lb.client-java/examples/simple-ssl/LBClientSSL.java deleted file mode 100644 index afe8669..0000000 --- a/org.glite.lb.client-java/examples/simple-ssl/LBClientSSL.java +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb.examples.ssl; - -import org.apache.log4j.Logger; -import org.glite.wsdl.services.lb.LoggingAndBookkeepingPortType; -import org.glite.wsdl.services.lb.LoggingAndBookkeepingLocator; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.URL; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Enumeration; - -/** - * Example client of LoggingAndBookkeeping web service. Please note that the client depends - * only on Axis and Log4j libraries, it uses cryptography included in the JDK. - * - * @author Martin Kuba makub@ics.muni.cz - * @version $Id$ - */ -public class LBClientSSL { - static Logger log = Logger.getLogger(LBClientSSL.class); - - public static void main(String[] args) throws Exception { - if(args.length<2) { - System.out.println("usage: java LBClientSSL []"); - System.exit(-1); - } - File keyfile = new File(args[0]); - String password = args[1]; - URL url = new URL("https://localhost:9003/"); - if(args.length==3) { - url = new URL(args[2]); - } - - //read in a keystore file - KeyStore ks = readKeyStoreFile(keyfile, password); - //find key alias (name) - String alias = null; - for (Enumeration en = ks.aliases(); en.hasMoreElements();) { - alias = (String)en.nextElement(); - if (ks.isKeyEntry(alias)) break; - else alias = null; - } - if (alias == null) throw new RuntimeException("the keystore contains no keys"); - //get my private key and certificates - Certificate[] certs = ks.getCertificateChain(alias); - PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray()); - //use my CA as the only trusted certificate authority - X509Certificate[] trustedCertAuths = new X509Certificate[]{(X509Certificate) certs[certs.length - 1]}; - - //register our SSL handling - ExampleSSLSocketFactory.registerForAxis(certs, key, trustedCertAuths); - - //get client stub - LoggingAndBookkeepingPortType lb = new LoggingAndBookkeepingLocator().getLoggingAndBookkeeping(url); - - //call the service - String version = lb.getVersion(null); - System.out.println("LB version: " + version); - } - - public static KeyStore readKeyStoreFile(File ksfile, String password) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException { - String kstype; - if (ksfile.getName().endsWith("ks")) kstype = "JKS"; - else if (ksfile.getName().endsWith(".p12")) kstype = "PKCS12"; - else throw new IOException("Only JKS (*ks) and PKCS12 (*.p12) files are supported "); - KeyStore store = KeyStore.getInstance(kstype); - store.load(new FileInputStream(ksfile), password != null ? password.toCharArray() : null); - return store; - } - -} diff --git a/org.glite.lb.client-java/examples/simple-ssl/MyX509KeyManager.java b/org.glite.lb.client-java/examples/simple-ssl/MyX509KeyManager.java deleted file mode 100644 index 206098a..0000000 --- a/org.glite.lb.client-java/examples/simple-ssl/MyX509KeyManager.java +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb.examples.ssl; - -import org.apache.log4j.Logger; - -import javax.net.ssl.X509KeyManager; -import java.net.Socket; -import java.security.Principal; -import java.security.PrivateKey; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; - -/** - * Implementation of X509KeyManager, which always returns one pair of a private key and certificate chain. - */ -public class MyX509KeyManager implements X509KeyManager { - static Logger log = Logger.getLogger(MyX509KeyManager.class); - private final X509Certificate[] certChain; - private final PrivateKey key; - - public MyX509KeyManager(Certificate[] cchain, PrivateKey key) { - this.certChain = new X509Certificate[cchain.length]; - System.arraycopy(cchain, 0, this.certChain, 0, cchain.length); - this.key = key; - } - - //not used - public String[] getClientAliases(String string, Principal[] principals) { - log.debug("getClientAliases()"); - return null; - } - - - // Intented to be implemented by GUI for user interaction, but we have only one key. - public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { - if (log.isDebugEnabled()) { - log.debug("chooseClientAlias()"); - for (int i = 0; i < keyType.length; i++) log.debug("keyType[" + i + "]=" + keyType[i]); - for (int i = 0; i < issuers.length; i++) log.debug("issuers[" + i + "]=" + issuers[i]); - } - return "thealias"; - } - - //not used on a client - public String[] getServerAliases(String string, Principal[] principals) { - log.debug("getServerAliases()"); - return null; - } - - //not used on a client - public String chooseServerAlias(String string, Principal[] principals, Socket socket) { - log.debug("chooseServerAlias()"); - return null; - } - - public X509Certificate[] getCertificateChain(String alias) { - log.debug("getCertificateChain()"); - return certChain; - } - - public PrivateKey getPrivateKey(String alias) { - log.debug("getPrivateKey()"); - return key; - } -} diff --git a/org.glite.lb.client-java/examples/simple-ssl/MyX509TrustManager.java b/org.glite.lb.client-java/examples/simple-ssl/MyX509TrustManager.java deleted file mode 100644 index cec0ba7..0000000 --- a/org.glite.lb.client-java/examples/simple-ssl/MyX509TrustManager.java +++ /dev/null @@ -1,100 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb.examples.ssl; - -import org.apache.log4j.Logger; - -import javax.net.ssl.X509TrustManager; -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.*; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * Simple trust manager validating server certificates against supplied trusted CAs. - * - * @author Martin Kuba makub@ics.muni.cz - * @version $Id$ - */ -public class MyX509TrustManager implements X509TrustManager { - static Logger log = Logger.getLogger(MyX509TrustManager.class); - private final X509Certificate[] certificateAuthorities; - private final Set trustAnchors; - - /** - * Creates an instance with supplied trusted root CAs. - * @param certificateAuthorities - */ - public MyX509TrustManager(X509Certificate[] certificateAuthorities) { - int i; - - this.certificateAuthorities = certificateAuthorities; - this.trustAnchors = new HashSet(); - for (i = 0; i < certificateAuthorities.length; i++) { - this.trustAnchors.add(new TrustAnchor(certificateAuthorities[i], null)); - } - } - - //not used on a client - public X509Certificate[] getAcceptedIssuers() { - log.debug("getAcceptedIssuers()"); - return this.certificateAuthorities; - } - - //not used on a client - public void checkClientTrusted(X509Certificate[] certs, String authType) { - log.debug("checkClientTrusted()"); - } - - /** - * Validates certificate chain sent by a server against trusted CAs. - * @param certs - * @param authType - * @throws CertificateException - */ - public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException { - if (log.isDebugEnabled()) { - log.debug("checkServerTrusted(certs: "+ certs.length + ", authType=" + authType+")"); - for (int i = 0; i < certs.length; i++) { - log.debug("cert[" + i + "]=" + certs[i].getSubjectX500Principal().toString()); - } - } - //validate server certificate - try { - PKIXParameters pkixParameters = new PKIXParameters(this.trustAnchors); - pkixParameters.setRevocationEnabled(false); - CertificateFactory certFact = CertificateFactory.getInstance("X.509"); - CertPath path = certFact.generateCertPath(Arrays.asList(certs)); - CertPathValidator certPathValidator = CertPathValidator.getInstance("PKIX"); - certPathValidator.validate(path, pkixParameters); - } catch (NoSuchAlgorithmException e) { - log.error(e.getMessage(), e); - } catch (InvalidAlgorithmParameterException e) { - log.error(e.getMessage(), e); - } catch (CertPathValidatorException e) { - CertificateException ce; - log.error(e.getMessage(), e); - ce = new CertificateException(e.getMessage()); - ce.setStackTrace(e.getStackTrace()); - throw ce; - } - log.debug("server is trusted"); - } -} diff --git a/org.glite.lb.client-java/examples/simple-trustmanager/LBClientTM.java b/org.glite.lb.client-java/examples/simple-trustmanager/LBClientTM.java deleted file mode 100644 index eeff9f5..0000000 --- a/org.glite.lb.client-java/examples/simple-trustmanager/LBClientTM.java +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb.examples.trustmanager; - -import java.net.URL; -import org.apache.axis.AxisFault; -import org.apache.axis.AxisProperties; -import org.apache.log4j.Logger; -import org.apache.log4j.ConsoleAppender; - -import org.glite.wsdl.services.lb.LoggingAndBookkeepingLocator; -import org.glite.wsdl.services.lb.LoggingAndBookkeepingPortType; -import org.glite.wsdl.types.lb.JobStatus; - -/** - * Example client of LoggingAndBookkeeping web service. It uses cryptography - * included in the gLite security trustmanager. - */ -public class LBClientTM { - private static String proxyFile = null; - private static String endpoint = "https://localhost:9003"; - private static Logger log = Logger.getLogger(LBClientTM.class); - - public static void main(String[] args) throws Exception { - if (args.length > 0) proxyFile = args[0]; - if (args.length > 1) endpoint = args[1]; - - log.info("endpoint being used "+ endpoint); - if (proxyFile != null) log.info("proxy location being used " + proxyFile); - - URL url = new URL(endpoint); - int port = url.getPort(); - String protocol = url.getProtocol(); - String path = url.getPath(); - log.info(" port number "+ port + ", protocol ("+ protocol + "), path: " + path); - - System.setProperty("sslProtocol", "SSLv3"); - AxisProperties.setProperty("axis.socketSecureFactory","org.glite.security.trustmanager.axis.AXISSocketFactory"); - // certificate based authentication */ -// System.setProperty("sslCertFile","/home/glite/.cert/hostcert.pem"); -// System.setProperty("sslKey","/home/glite/.cert/hostkey.pem"); -// System.setProperty("sslKeyPasswd",""); - - // proxy based authentication - if (proxyFile != null) System.setProperty("gridProxyFile", proxyFile); - - try { - LoggingAndBookkeepingLocator loc = new LoggingAndBookkeepingLocator(); - String sn = loc.getLoggingAndBookkeepingWSDDServiceName(); - log.info(" service name " + sn); - - LoggingAndBookkeepingPortType stub = loc.getLoggingAndBookkeeping(url); - log.info(" got endpoint "); - - String version = stub.getVersion(null); - log.info("LB version "+ version); - JobStatus status = stub.jobStatus("https://scientific.civ.zcu.cz:9000/PnSBRXoIHVzX68H5vAtxmA", null); - log.info("job status "+ status); - } catch (AxisFault af) { - log.error( " AxisFault - " + af.getFaultString()); - af.printStackTrace(); - } - } -} diff --git a/org.glite.lb.client-java/project/ChangeLog b/org.glite.lb.client-java/project/ChangeLog deleted file mode 100644 index 2fd58a5..0000000 --- a/org.glite.lb.client-java/project/ChangeLog +++ /dev/null @@ -1,96 +0,0 @@ -1.0.1-1 -- Initial release of the client-java module. - -1.0.2-1 -- Fixed time zone in UTC times in events - -1.0.3-1 -- Improved portability - -1.0.4-1 -- Fixed target 'clean' in the Makefile to handle debian builds -- Fixed format of the package description file - -1.0.4-2 -- Module rebuilt - -1.0.5-1 -- Makefile fix for use of jakarta-commons-* external modules - -1.0.5-2 -- Module rebuilt - -1.0.5-3 -- Module rebuilt - -1.0.5-4 -- Module rebuilt - -1.0.5-5 -- Module rebuilt - -1.0.5-6 -- Module rebuilt - -1.0.6-1 -- Support gcj java - -1.1.0-1 -- Fixes for parallel release in EMI & gLite -- CREAM_CORE->CREAM_EXECUTOR - -1.1.1-1 -- Detectin project name in Makefile -- Figed m4 file location -- When staged, install rather not-relinked .la file for the dependent C++ library -- Introduction on a sysconfdir option (for /etc vs /usr) -- DESTDIR in makefiles - -1.1.2-1 -- Build JAR file indexes -- Support gcj java - -1.1.2-2 -- Module rebuilt - -1.1.3-1 -- Relocatable build directory - -1.1.3-2 -- Module rebuilt - -1.1.3-3 -- Module rebuilt - -1.1.4-1 -- at3 and check_version utilities path -- jdk -> java-devel - -1.1.5-1 -- at3 location detection reverted -- '--stage=/' behaviour in fixed configure -- wsdl files moved - -1.1.6-1 -- Distinguish between generated and non-generated java files for FindBugs etics plugin -- Classes for non-generated files are built in build/classes directory now - -1.1.7-1 -- Build on Debian 6 and SL 6 - -1.2.0-1 -- Preparation for a new multiplatform release - -1.2.0-2 -- Module rebuilt - -1.2.1-1 -- License string as recognized by rpmlint and packaging guidelines. -- Packaging improvements (rpmlint and lintian checks) - -1.2.1-2 -- Module rebuilt - -1.2.2-1 -- Limit number of jars used for axis (scanning script with the expected list) - diff --git a/org.glite.lb.client-java/project/debian.control b/org.glite.lb.client-java/project/debian.control deleted file mode 100644 index a8e6165..0000000 --- a/org.glite.lb.client-java/project/debian.control +++ /dev/null @@ -1,17 +0,0 @@ -Source: glite-lb-client-java -Priority: extra -Maintainer: @MAINTAINER@ -Uploaders: @UPLOADERS@ -Build-Depends: debhelper (>= 7.0.50~), ant, chrpath, default-jdk, emi-trustmanager, emi-trustmanager-axis, glite-jobid-api-java, glite-lb-types, glite-lb-ws-interface, libaxis-java, libcommons-lang-java, libtool -Standards-Version: 3.9.1 -Section: misc -Homepage: @URL@ -DM-Upload-Allowed: yes -@DEBIAN_VCS@ - -Package: glite-lb-client-java -Section: misc -Architecture: any -Depends: ${misc:Depends}, emi-trustmanager-axis, emi-trustmanager, glite-jobid-api-java, libcommons-lang-java -Description: @SUMMARY@ -@DEBIAN_DESCRIPTION@ diff --git a/org.glite.lb.client-java/project/debian.copyright b/org.glite.lb.client-java/project/debian.copyright deleted file mode 100644 index 3d762ae..0000000 --- a/org.glite.lb.client-java/project/debian.copyright +++ /dev/null @@ -1,38 +0,0 @@ -This work was packaged for Debian by: - - @MAINTAINER@ on Thu, 08 Dec 2011 00:46:07 +0100 - -It was downloaded from: - - @URL@ - -Upstream Author(s): - - @MAINTAINER@ - -Copyright: - - - -License: - - 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. - -On Debian systems, the complete text of the Apache version 2.0 license -can be found in "/usr/share/common-licenses/Apache-2.0". - -The Debian packaging is: - - Copyright (C) 2004-2011 Members of the EGEE Collaboration - -and is licensed under the Apache License, Version 2.0. diff --git a/org.glite.lb.client-java/project/debian.glite-lb-client-java.dirs b/org.glite.lb.client-java/project/debian.glite-lb-client-java.dirs deleted file mode 100644 index 42a1652..0000000 --- a/org.glite.lb.client-java/project/debian.glite-lb-client-java.dirs +++ /dev/null @@ -1,2 +0,0 @@ -usr/lib -usr/share/java diff --git a/org.glite.lb.client-java/project/debian.glite-lb-client-java.install b/org.glite.lb.client-java/project/debian.glite-lb-client-java.install deleted file mode 100644 index ec8a5cc..0000000 --- a/org.glite.lb.client-java/project/debian.glite-lb-client-java.install +++ /dev/null @@ -1,2 +0,0 @@ -usr/lib/* -usr/share/java/*.jar diff --git a/org.glite.lb.client-java/project/debian.rules b/org.glite.lb.client-java/project/debian.rules deleted file mode 100644 index 104d175..0000000 --- a/org.glite.lb.client-java/project/debian.rules +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- - --include /usr/share/dpkg/buildflags.mk - -# Uncomment this to turn on verbose mode. -export DH_VERBOSE=1 - -configure: configure-stamp -configure-stamp: - dh_testdir - /usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=lib --project=emi --module lb.client-java - touch $@ - -build: build-indep - -build-arch build-indep: build-stamp - -build-stamp: configure-stamp - dh_testdir - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) check - touch $@ - -clean: configure-stamp - dh_testdir - dh_testroot - rm -f configure-stamp build-stamp - $(MAKE) clean - rm -f Makefile.inc config.status - dh_clean - -install: build-stamp - dh_testdir - dh_testroot - dh_prep - dh_installdirs - $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp - rm -vf $(CURDIR)/debian/tmp/usr/lib/*.la - rm -vf $(CURDIR)/debian/tmp/usr/lib/*.a - find $(CURDIR)/debian/tmp -name '*' -print | xargs -I {} -i bash -c "chrpath -d {} > /dev/null 2>&1" || echo 'Stripped RPATH' - -binary-indep: - -binary-arch: install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_installexamples - dh_installman - dh_installlogrotate - dh_installcron - dh_install --fail-missing - dh_link - dh_strip - dh_compress - dh_fixperms - dh_makeshlibs - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-arch binary-indep diff --git a/org.glite.lb.client-java/project/genEventTypes.pl b/org.glite.lb.client-java/project/genEventTypes.pl deleted file mode 100644 index 4611a10..0000000 --- a/org.glite.lb.client-java/project/genEventTypes.pl +++ /dev/null @@ -1,148 +0,0 @@ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -@@@LANG: java -@@@{ - $dest = shift; - - for my $e ($event->getTypesOrdered) { - my $uc = ucfirst $e; - my $uuc = uc $e; - print "generating $dest/Event$uc.java\n"; - - open E,">$dest/Event$uc.java" or die "$dest/Event$uc.java: $!\n"; - - print E -qq{ -package org.glite.lb; -import org.glite.jobid.Jobid; - -public class Event$uc extends Event \{ - public Event$uc() \{ - \} - - public String getEventType() \{ - return "$uc"; - \} -}; - - selectType $event $e; - - for ($event->getFieldsOrdered) { - my $f = selectField $event $_; - my $fn = $f->{name}; - my $fnu = ucfirst $fn; - my $fnuu = uc $fn; - my $t; - my $init; - - while ($fnu =~ /_([a-z])/) { - my $u = uc $1; - $fnu =~ s/_$1/$u/; - } - - if ($f->{codes}) { - local $_; - $t = $fnu; - print E -qq{ public enum $fnu \{ - UNDEFINED, -}; - $init = " = ${fnu}.UNDEFINED"; - for (@{$f->{codes}}) { - my $cu = uc $_->{name}; - print E -qq{ ${cu}, -}; - } - - print E -qq{ \}; -}; -# public static String ${fnu}ToString($fnu e) \{ -# String out = "UNDEF"; -# switch (e) \{ -#}; -# for (@{$f->{codes}}) { -# my $cu = uc $_->{name}; -# print E -#qq{ -# case ${fnu}.${cu}: out = "$cu"; break; -#}; -# } -# print E -#qq{ -# \} -# return out; -# \} -#}; - } - else { - $t = $f->getType; - $init = $f->{null} && $main::DefaultNullValue{$f->{type}} ne $f->{null} ? " = $f->{null}" : ""; - } - - -# XXX: handle nulls in setXX() ? - print E -qq{ private $t $fn $init; - - public $t get$fnu() \{ - return $fn; - \} - - public void set$fnu($t val) \{ - this.$fn = val; - \} -}; - } - - print E -qq{ public String ulm() \{ - return (" " + -}; - - - for ($event->getFieldsOrdered) { - my $f = selectField $event $_; - my $fn = $f->{name}; - my $t = getType $f; - my $fnu = ucfirst $fn; - while ($fnu =~ /_([a-z])/) { - my $u = uc $1; - $fnu =~ s/_$1/$u/; - } - my $fnuu = uc $fn; - my $val = $t eq 'String' ? - "($fn == null ? \"\" : Escape.ulm($fn))" : - $f->{codes} ? "Escape.ulm(${fn}.toString())" : - $fn; - - print E -qq{ " DG.$uuc.$fnuu=\\"" + $val + "\\"" + -}; - } - - print E -qq{ ""); - \} -\} -}; - - close E; - } - -@@@} diff --git a/org.glite.lb.client-java/project/glite-lb-client-java.spec b/org.glite.lb.client-java/project/glite-lb-client-java.spec deleted file mode 100644 index 563212f..0000000 --- a/org.glite.lb.client-java/project/glite-lb-client-java.spec +++ /dev/null @@ -1,82 +0,0 @@ -%global distver %(rpm -q --quiet redhat-release && rpm -q --queryformat "%{VERSION}" redhat-release || rpm -q --quiet centos-release && rpm -q --queryformat "%{VERSION}" centos-release || rpm -q --quiet sl-release && rpm -q --queryformat "%{VERSION}" sl-release | sed 's/^\\([0-9]*\\).*/\\1/') - -Summary: @SUMMARY@ -Name: glite-lb-client-java -Version: @MAJOR@.@MINOR@.@REVISION@ -Release: @AGE@%{?dist} -Url: @URL@ -License: ASL 2.0 -Vendor: EMI -Group: System Environment/Libraries -BuildRequires: ant -BuildRequires: axis1.4 -BuildRequires: chrpath -BuildRequires: emi-trustmanager -BuildRequires: emi-trustmanager-axis -BuildRequires: glite-jobid-api-java -BuildRequires: glite-lb-types -BuildRequires: glite-lb-ws-interface -BuildRequires: jakarta-commons-lang -%if 0%{?distver} >= 6 -BuildRequires: java-1.6.0-openjdk-devel -%else -BuildRequires: java-devel -%endif -BuildRequires: libtool -Requires: emi-trustmanager-axis -Requires: emi-trustmanager -Requires: glite-jobid-api-java -Requires: jakarta-commons-lang -BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) -AutoReqProv: yes -Source: http://eticssoft.web.cern.ch/eticssoft/repository/emi/emi.lb.client-java/%{version}/src/%{name}-@VERSION@.src.tar.gz - - -%description -@DESCRIPTION@ - - -%prep -%setup -q - - -%build -/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=%{_lib} --project=emi --module lb.client-java --with-axis=/usr/local/axis1.4 -make - - -%check -make check - - -%install -rm -rf $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT -make install DESTDIR=$RPM_BUILD_ROOT -find $RPM_BUILD_ROOT -name '*.la' -exec rm -rf {} \; -find $RPM_BUILD_ROOT -name '*.a' -exec rm -rf {} \; -find $RPM_BUILD_ROOT -name '*' -print | xargs -I {} -i bash -c "chrpath -d {} > /dev/null 2>&1" || echo 'Stripped RPATH' - - -%clean -rm -rf $RPM_BUILD_ROOT - - -%post -p /sbin/ldconfig - - -%postun -p /sbin/ldconfig - - -%files -%defattr(-,root,root) -/usr/%{_lib}/libglite_lb_sendviasocket.so -/usr/%{_lib}/libglite_lb_sendviasocket.so.0 -/usr/%{_lib}/libglite_lb_sendviasocket.so.0.0.0 -/usr/share/java/lb-client-java.jar -/usr/share/java/lb-client-java-examples.jar - - -%changelog -* @SPEC_DATE@ @MAINTAINER@ - @MAJOR@.@MINOR@.@REVISION@-@AGE@%{?dist} -- automatically generated package diff --git a/org.glite.lb.client-java/project/list-jars.sh b/org.glite.lb.client-java/project/list-jars.sh deleted file mode 100755 index 5f4fff4..0000000 --- a/org.glite.lb.client-java/project/list-jars.sh +++ /dev/null @@ -1,22 +0,0 @@ -#! /bin/sh -# -# generate a classpath with all axis dependencies -# - -PREFIXES="${@:-'/usr/lib /usr/share/java'}" -LIST="activation ant-apache-bcel ant-apache-bsf ant-apache-log4j ant-apache-oro ant-apache-regexp ant-apache-resolver ant-apache-xalan2 ant-commons-logging ant-commons-net ant-javamail ant-jdepend ant-jmf ant-jsch ant-junit ant-nodeps ant-swing ant-trax axis axis-jaxrpc axis-saaj jaxrpc saaj commons-codec commons-discovery commons-lang commons-logging-adapters commons-logging-api commons-logging el-api gettext gnome-java-bridge gnumail gnumail-providers inetlib jobid-api-java jsp-api libintl log4j servlet-api wsdl4j xercesImpl xml-apis" - -CP="" -for prefix in $PREFIXES; do - #echo $prefix >&2 - for pkgid in $LIST; do - #echo $pkgid >&2 - for pkg in `ls -1 ${prefix}/${pkgid}*.jar 2>/dev/null`; do - if ! test -h ${pkg}; then - CP="$CP:${pkg}" - fi - done - done -done - -echo $CP | sed 's/^://' diff --git a/org.glite.lb.client-java/project/package.description b/org.glite.lb.client-java/project/package.description deleted file mode 100644 index 98d3fb4..0000000 --- a/org.glite.lb.client-java/project/package.description +++ /dev/null @@ -1 +0,0 @@ -JAVA implementation of the L&B service client. Supports producing (logging) events into L&B, event and job status queries, and receiving notifications. diff --git a/org.glite.lb.client-java/project/package.summary b/org.glite.lb.client-java/project/package.summary deleted file mode 100644 index 6ab8a98..0000000 --- a/org.glite.lb.client-java/project/package.summary +++ /dev/null @@ -1 +0,0 @@ -JAVA implementation of the L&B service client diff --git a/org.glite.lb.client-java/project/version.properties b/org.glite.lb.client-java/project/version.properties deleted file mode 100644 index 09471c0..0000000 --- a/org.glite.lb.client-java/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# $Header$ -module.version=1.2.2 -module.age=1 diff --git a/org.glite.lb.client-java/src/org/glite/lb/Context.java b/org.glite.lb.client-java/src/org/glite/lb/Context.java deleted file mode 100644 index 76f4491..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/Context.java +++ /dev/null @@ -1,370 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -import java.text.SimpleDateFormat; - -import java.net.UnknownHostException; -import java.util.Date; -import java.util.Random; -import java.util.SimpleTimeZone; -import org.glite.jobid.Jobid; - -/** - * Class representing a context for some job - * - * @author Pavel Piskac (173297@mail.muni.cz) - * @version 15. 3. 2008 - */ -public abstract class Context { - - private Sources source; - private int flag; - private String host; - private String user; - private String prog; - private String srcInstance; - private Jobid jobid; - private SeqCode seqCode; - - /** - * Creates new instance of Context class. - */ - public Context() { - } - - /** - * Creates new instance of Context class. - * - * @param id message id, if null, random number is generated - * @param source one if paramaters of Sources enumeration - * @param flag - * @param host host name, if null or "", the name is get from host name of this computer - * @param user user name - * @param prog if null then is used "egd-wms" - * @param srcInstance if null then it is set as "" - * @param jobid - * @throws java.lang.IllegalArgumentException if user or jobid is null - * or flag < 0 or source <=0 || >= 9 - * - */ - public Context(Sources src, - int flag, - String host, - String user, - String prog, - String srcInstance, - Jobid jobid) { - - if (src == null) { - throw new IllegalArgumentException("Context source"); - } - - if (flag < 0) { - throw new IllegalArgumentException("Context flag"); - } - - if (host == null || host.equals("")) { - try { - host = java.net.InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException ex) { - System.err.println(ex); - } - } - - if (user == null) { - throw new IllegalArgumentException("Context user"); - } - - if (prog == null) { - prog = new String("edg-wms"); - } - - if (srcInstance == null) { - srcInstance = new String(""); - } - - if (jobid == null) { - throw new IllegalArgumentException("Context jobid"); - } - - this.source = src; - this.flag = flag; - this.host = host; - this.user = user; - this.prog = prog; - this.srcInstance = srcInstance; - this.jobid = jobid; - } - - /** - * Abstract method which will serve as method for sending messages with events. - * @param event event for which will be created and send message - */ - public abstract void log(Event event) throws LBException; - - /** - * Creates message prepared to send - * @param event event for which is message generated - * @throws IllegalArgumentException if event, source, user or job is null - * or flag < 0 - * @return output String with message - */ - protected String createMessage(Event event) { - if (event == null) { - throw new IllegalArgumentException("Context event"); - } - - if (jobid == null) { - throw new IllegalArgumentException("Context jobid"); - } - - if (jobid.getBkserver() == null) { - throw new IllegalArgumentException("Context Jobid bkserver"); - } - - if (jobid.getPort() <= 0 || jobid.getPort() >= 65536) { - throw new IllegalArgumentException("Context Jobid port"); - } - - if (jobid.getUnique() == null) { - throw new IllegalArgumentException("Context Jobid unique"); - } - - if (event == null) { - throw new IllegalArgumentException("Context event"); - } - - if (seqCode == null) { - throw new IllegalArgumentException("Context seqCode"); - } - - if (flag < 0) { - throw new IllegalArgumentException("Context flag"); - } - - if (host == null || host.equals("")) { - try { - host = java.net.InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException ex) { - System.err.println(ex); - } - } - - if (prog == null) { - prog = new String("edg-wms"); - } - - if (user == null) { - throw new IllegalArgumentException("Context user"); - } - - if (srcInstance == null) { - srcInstance = new String(""); - } - - SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS"); - df.setTimeZone(new SimpleTimeZone(0, "UTC")); - String date = df.format(new Date()) + "000"; - - if (seqCode != null) seqCode.incrementSeqCode(source); - - String output = (" DG.USER=\"" + Escape.ulm(user) + "\"" + - " DATE=" + date + - " HOST=\"" + Escape.ulm(host) + "\"" + - " PROG=" + Escape.ulm(prog) + - " LVL=SYSTEM" + - " DG.PRIORITY=0" + - " DG.SOURCE=\"" + source + "\"" + - " DG.SRC_INSTANCE=\"" + Escape.ulm(srcInstance) + "\"" + - " DG.EVNT=\"" + event.getEventType() + "\"" + - " DG.JOBID=\"" + jobid + "\"" + - " DG.SEQCODE=\"" + Escape.ulm(seqCode.toString()) + "\"" + - event.ulm()); - - return output; - } - - /** - * Return flag - * - * @return flag - */ - public int getFlag() { - return flag; - } - - /** - * Set flag - * - * @param flag - * @throws java.lang.IllegalArgumentException if flag is lower than 0 - */ - public void setFlag(int flag) { - if (flag < 0) { - throw new IllegalArgumentException("Context flag"); - } - - this.flag = flag; - } - - /** - * Returns host name - * - * @return host name - */ - public String getHost() { - return host; - } - - /** - * Sets host name - * @param host host name - * @throws java.lang.IllegalArgumentException if host is null - */ - public void setHost(String host) { - if (host == null) { - throw new IllegalArgumentException("Context host"); - } - - this.host = host; - } - - /** - * Gets jobid. - * - * @return jobid - */ - public Jobid getJobid() { - return jobid; - } - - /** - * Sets jobid. - * - * @param jobid - * @throws java.lang.IllegalArgumentException if jobid is null - */ - public void setJobid(Jobid jobid) { - if (jobid == null) { - throw new IllegalArgumentException("Context jobid"); - } - - this.jobid = jobid; - } - - /** - * Gets prog. - * @return prog - */ - public String getProg() { - return prog; - } - - /** - * Sets prog, if prog is null then is set default value "edg-wms" - * @param prog - */ - public void setProg(String prog) { - if (prog == null) { - prog = new String("edg-wms"); - } - - this.prog = prog; - } - - /** - * Gets sequence code. - * - * @return sequence code - */ - public SeqCode getSeqCode() { - return seqCode; - } - - /** - * Sets sequence code. - * @param seqCode sequence code - * @throws java.lang.IllegalArgumentException if seqCode is null - */ - public void setSeqCode(SeqCode seqCode) { - if (seqCode == null) { - throw new IllegalArgumentException("Context seqCode"); - } - - this.seqCode = seqCode; - } - - /** - * Gets source which represents which part of sequence code will be changed - * @return source - */ - public Sources getSource() { - return source; - } - - /** - * Sets source which represents which part of sequence code will be changed - * @param source source - * @throws java.lang.IllegalArgumentException if source is null - */ - public void setSource(Sources src) { - this.source = src; - } - - /** - * Gets srcInstance. - * @return srcInstance - */ - public String getSrcInstance() { - return srcInstance; - } - - /** - * Sets srcInstace, if srcInstace null then is set "". - * @param srcInstance srcInstance - */ - public void setSrcInstance(String srcInstance) { - if (srcInstance == null) { - srcInstance = new String(""); - } - - this.srcInstance = srcInstance; - } - - /** - * Gets user name. - * @return user name - */ - public String getUser() { - return user; - } - - /** - * Sets user name. - * @param user user name - * @throws java.lang.IllegalArgumentException if user is null - */ - public void setUser(String user) { - if (user == null) { - throw new IllegalArgumentException("Context user"); - } - - this.user = user; - } -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/ContextDirect.java b/org.glite.lb.client-java/src/org/glite/lb/ContextDirect.java deleted file mode 100644 index e395a27..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/ContextDirect.java +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -package org.glite.lb; -import java.net.Socket; - -public class ContextDirect extends Context -{ - String server; - int port; - LBCredentials cred; - ILProto il = null; - int timeout = 20000; - - public ContextDirect() - { - } - - public ContextDirect(String server,int port) - { - if (server == null) { - throw new IllegalArgumentException("server is null"); - } - if (port < 1 || port > 65535) { - throw new IllegalArgumentException("port is not valid range"); - } - this.server = server; - this.port = port; - } - - public void setCredentials(LBCredentials cred) - { - this.cred = cred; - il = null; - } - - @Override - public void log(Event event) throws LBException { - if (il == null) { - SSL ssl = new SSL(); - ssl.setCredentials(cred); - Socket sock = ssl.connect(server,port+1,timeout); - setUser(ssl.myDN()); - try { il = new ILProto(sock); } - catch (Throwable e) { throw new LBException(e); } - } - - String msg = super.createMessage(event); - int maj; - - try { - il.sendMessage(msg); - maj = il.receiveReply(); - } - catch (Throwable e) { throw new LBException(e); } - - if (maj > 0) { - int min = il.errMin(); - String err = il.errMsg(); - - throw new LBException("IL proto: " + maj + " " + min + " " + err); - } - } -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/ContextIL.java b/org.glite.lb.client-java/src/org/glite/lb/ContextIL.java deleted file mode 100644 index 4dde7d2..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/ContextIL.java +++ /dev/null @@ -1,163 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -import org.glite.jobid.Jobid; - -/** - * Class which is used to send messages to inter-logger using unix socket. - * - * @author Pavel Piskac (173297@mail.muni.cz) - */ -public class ContextIL extends Context { - - private String socket; - private String prefix; - private int repeatWriteToFile = 5; - private int connAttempts = 3; - private int timeout = 3; - - //tutorial http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jni.html - //native method which is written in C and imported to Java - native int sendToSocket(String socket_path, - long filepos, - String msg, - int msg_size, - int conn_attempts, - int timeout); - - /** - * Creates new instance of ContextIL. - */ - public ContextIL() { - this.prefix = "/var/glite/log/dglogd.log"; - } - - public ContextIL(String prefix) { - this.prefix = prefix; - } - - public ContextIL(String prefix,String socket,String lib) - { - if (prefix == null) throw new IllegalArgumentException("ContextIL prefix"); - if ((socket != null && lib == null) || (socket == null && lib != null)) - throw new IllegalArgumentException("ContextIL both socket and lib must be set"); - - this.prefix = prefix; - this.socket = socket; - - if (lib != null) System.loadLibrary(lib); - } - - - - /** - * Writes event message to the file and socket. - * - * @param event event - * @throws java.lang.IllegalArgumentException if event, prefix or path - */ - public void log(Event event) throws LBException { - if (event == null) { - throw new IllegalArgumentException("ContextIL event"); - } - - if (prefix == null) { - throw new IllegalArgumentException("ContextIL prefix"); - } - - String message = "DG.LLLID=\"0\"" + super.createMessage(event) +"\n"; - - String file = prefix + "." + getJobid().getUnique(); - - Long fileLength = ILFileWriter.write(file, message, repeatWriteToFile); - - if (socket != null) sendToSocket(socket,fileLength.longValue(),message,message.length(),connAttempts,timeout); - } - - public String getPrefix() { - return prefix; - } - - /** - * Gets count of repeated write to file if some exception is thrown. - * - * @return count of repeated write to file - */ - public int getRepeatWriteToFile() { - return repeatWriteToFile; - } - - /** - * Sets count of repeated write to file if some exception is thrown. - * - * @param repeatWriteToFile count of repeated write to file - */ - public void setRepeatWriteToFile(int repeatWriteToFile) { - if (repeatWriteToFile < 1) { - throw new IllegalArgumentException("ContextIL repeatWriteToFile"); - } - - this.repeatWriteToFile = repeatWriteToFile; - } - - /** - * Gets count of connection attempts which is used while sending the message via unix socket. - * - * @return count of connection attempts - */ - public int getConnAttempts() { - return connAttempts; - } - - /** - * Sets count of connection attempts while sending the message via unix socket. - * - * @param connAttempts count of connection attempts - */ - public void setConnAttempts(int connAttempts) { - if (connAttempts < 1) { - throw new IllegalArgumentException("ContextIL conn_attempts"); - } - - this.connAttempts = connAttempts; - } - - /** - * Gets timeout which is used while sending the message via unix socket. - * - * @return timeout - */ - public int getTimeout() { - return timeout; - } - - /** - * Sets timeout which is used while sending the message via unix socket. - * - * @param timeout timeout - */ - public void setTimeout(int timeout) { - if (timeout < 1) { - throw new IllegalArgumentException("ContextIL time_out"); - } - - this.timeout = timeout; - } - -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/ContextLL.java b/org.glite.lb.client-java/src/org/glite/lb/ContextLL.java deleted file mode 100644 index 4ae98fc..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/ContextLL.java +++ /dev/null @@ -1,178 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -import org.glite.jobid.Jobid; - -/** - * This class provides sending messages using network sockets. - * - * @author Pavel Piskac (173297@mail.muni.cz) - */ -public class ContextLL extends Context { - - private String address; - private int port = 9002; - private String prefix; - private int repeatWriteToFile = 5; - private int timeout = 30000; //in milliseconds - private LBCredentials cred; - private SSLSend sslSend = null; - - public ContextLL() { - } - - public ContextLL(String address, int port, String prefix) { - this.prefix = prefix; - this.address = address; - this.port = port; - } - -/* XXX - public ContextLL(int id, - int source, - int flag, - String host, - String user, - String prog, - String srcInstance, - Jobid jobid, - String address, - int port, - String prefix) { - - super(id, source, flag, host, user, prog, srcInstance, jobid); - - if (prefix == null) { - throw new IllegalArgumentException("ContextLL prefix"); - } - if (address == null) { - throw new IllegalArgumentException("ContextLL socket"); - } - if (port < 0) { - throw new IllegalArgumentException("ContextLL port"); - } - - this.prefix = prefix; - this.address = address; - } - -*/ - @Override - public void log(Event event) throws LBException { - if (event == null) { - throw new IllegalArgumentException("ContextLL event"); - } - - if (prefix == null) { - throw new IllegalArgumentException("ContextLL prefix"); - } - - if (address == null) { - throw new IllegalArgumentException("ContextLL socket"); - } - - if (port < 0) { - throw new IllegalArgumentException("ContextLL port"); - } - - if (sslSend == null) { - sslSend = new SSLSend(); - } - - String message = super.createMessage(event); - - ILFileWriter.write(prefix, message, repeatWriteToFile); - - - sslSend.send(cred, address, port, timeout, message); - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - if (address == null) { - throw new IllegalArgumentException("ContextLL address"); - } - - this.address = address; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - if (port < 0) { - throw new IllegalArgumentException("ContextLL port"); - } - this.port = port; - } - - - public String getPrefix() { - return prefix; - } - - public void setPrefix(String prefix) { - if (prefix == null) { - throw new IllegalArgumentException("ContextLL prefix"); - } - - this.prefix = prefix; - } - - public int getRepeatWriteToFile() { - return repeatWriteToFile; - } - - public void setRepeatWriteToFile(int repeatWriteToFile) { - if (repeatWriteToFile < 1) { - throw new IllegalArgumentException("ContextLL repeatWriteToFile"); - } - - this.repeatWriteToFile = repeatWriteToFile; - } - - public int getTimeout() { - return timeout; - } - - public void setTimeout(int timeout) { - if (timeout < 0) { - throw new IllegalArgumentException("ContextLL timout"); - } - this.timeout = timeout; - } - - public LBCredentials getCredentials() { - return cred; - } - - public void setCredentials(LBCredentials cred) { - if (cred == null) { - throw new IllegalArgumentException("ContextLL credentials"); - } - - this.cred = cred; - } - - -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/Escape.java b/org.glite.lb.client-java/src/org/glite/lb/Escape.java deleted file mode 100644 index e552fef..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/Escape.java +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -class Escape { - public static String ulm(String in) { - String out = in.replaceAll("\"", "\\\\\""); - out = out.replaceAll("\n", "\\\\\\n"); - return out; - } -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/Event.java b/org.glite.lb.client-java/src/org/glite/lb/Event.java deleted file mode 100644 index 21bbf95..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/Event.java +++ /dev/null @@ -1,179 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.GregorianCalendar; -import org.glite.jobid.Jobid; - -/** - * Abstract class which serves as base for all events. - * - * @author Pavel Piskac (173297@mail.muni.cz) - */ -public abstract class Event { - - private Timeval timestamp; - private Timeval arrived; - private String host; - private Level level; - private Integer priority; - private Jobid jobId; - private SeqCode seqcode; - private String user; - private Sources source; - private String srcInstance; - - public Event() { - } - - public Event(Jobid jobId) { - if (jobId == null) throw new IllegalArgumentException("jobId"); - - this.jobId = jobId; - } - - public Jobid getJobId() { - return jobId; - } - - /** - * When implemented, this method returns string which is specific for each event. - * - * @return specific string - */ - public abstract String ulm(); - - /** - * When implemented, this method returns name of event type. - * - * @return name of event - */ - public abstract String getEventType(); - -/* - public String info() { - String date = ""; - if (arrived != null) { - Calendar calendar = new GregorianCalendar(); - DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); - calendar.setTimeInMillis(arrived.getTvSec()*1000); - date = df.format(calendar.getTime()); - } - return "DATE=" + date + " HOST=\"" + host + "\" " + - "LVL="+level+" DG.PRIORITY=" + priority + " DG.SOURCE=\""+ - source + "\" "+"DG.SRC_INSTANCE=\""+srcInstance+"\" "+ - "DG.EVNT=\""+getEventType()+"\" "+"DG.JOBID=\""+jobId+"\" "+ - "DG.SEQCODE=\""+seqcode+"\" "+"DG.USER=\""+user+"\""+ulm(); - } -*/ - - /** - * Get and set methods for Event attributes. - */ - - public Timeval getArrived() { - return arrived; - } - - public void setArrived(Timeval arrived) { - if (arrived == null) throw new IllegalArgumentException("arrived"); - this.arrived = arrived; - } - - public String getHost() { - return host; - } - - public void setHost(String host) { - if (host == null) throw new IllegalArgumentException("host"); - this.host = host; - } - - - public void setJobId(Jobid jobId) { - if (jobId == null) throw new IllegalArgumentException("jobId"); - this.jobId = jobId; - } - - public Level getLevel() { - return level; - } - - public void setLevel(Level level) { - if (level == null) throw new IllegalArgumentException("level"); - this.level = level; - } - - public Integer getPriority() { - return priority; - } - - public void setPriority(Integer priority) { - this.priority = priority; - } - - public SeqCode getSeqcode() { - return seqcode; - } - - public void setSeqcode(SeqCode seqcode) { - if (seqcode == null) throw new IllegalArgumentException("seqcode"); - this.seqcode = seqcode; - } - - public Sources getSource() { - return source; - } - - public void setSource(Sources source) { - if (source == null) throw new IllegalArgumentException("source"); - this.source = source; - } - - public String getSrcInstance() { - return srcInstance; - } - - public void setSrcInstance(String srcInstance) { - if (srcInstance == null) throw new IllegalArgumentException("srcInstance"); - this.srcInstance = srcInstance; - } - - public Timeval getTimestamp() { - return timestamp; - } - - public void setTimestamp(Timeval timestamp) { - if (timestamp == null) throw new IllegalArgumentException("timestamp"); - this.timestamp = timestamp; - } - - public String getUser() { - return user; - } - - public void setUser(String user) { - if (user == null) throw new IllegalArgumentException("user"); - this.user = user; - } - - -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/EventConvertor.java b/org.glite.lb.client-java/src/org/glite/lb/EventConvertor.java deleted file mode 100644 index 84da13d..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/EventConvertor.java +++ /dev/null @@ -1,1101 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -import org.glite.jobid.Jobid; -import org.glite.lb.Event; - -import org.glite.lb.EventAbort; -import org.glite.lb.EventAccepted; -import org.glite.lb.EventCancel; -import org.glite.lb.EventChangeACL; -import org.glite.lb.EventChkpt; -import org.glite.lb.EventClear; -import org.glite.lb.EventCollectionState; -import org.glite.lb.EventCondorError; -import org.glite.lb.EventCondorMatch; -import org.glite.lb.EventCondorReject; -import org.glite.lb.EventCondorResourceUsage; -import org.glite.lb.EventCondorShadowExited; -import org.glite.lb.EventCondorShadowStarted; -import org.glite.lb.EventCondorStarterExited; -import org.glite.lb.EventCondorStarterStarted; -import org.glite.lb.EventCurDescr; -import org.glite.lb.EventDeQueued; -import org.glite.lb.EventDone; -import org.glite.lb.EventEnQueued; -import org.glite.lb.EventHelperCall; -import org.glite.lb.EventHelperReturn; -import org.glite.lb.EventListener; -import org.glite.lb.EventMatch; -import org.glite.lb.EventNotification; -import org.glite.lb.EventPBSDequeued; -import org.glite.lb.EventPBSDone; -import org.glite.lb.EventPBSError; -import org.glite.lb.EventPBSMatch; -import org.glite.lb.EventPBSPending; -import org.glite.lb.EventPBSQueued; -import org.glite.lb.EventPBSRerun; -import org.glite.lb.EventPBSResourceUsage; -import org.glite.lb.EventPBSRun; -import org.glite.lb.EventPending; -import org.glite.lb.EventPurge; -import org.glite.lb.EventReallyRunning; -import org.glite.lb.EventRefused; -import org.glite.lb.EventRegJob; -import org.glite.lb.EventResourceUsage; -import org.glite.lb.EventResubmission; -import org.glite.lb.EventResume; -import org.glite.lb.EventRunning; -import org.glite.lb.EventSuspend; -import org.glite.lb.EventTransfer; -import org.glite.lb.EventUserTag; -import org.glite.lb.Level; -import org.glite.lb.SeqCode; -import org.glite.lb.Sources; -import org.glite.lb.Timeval; -import org.glite.wsdl.types.lb.EventSource; - - -/** - * This class is only for internal purposes of this package. Users of this query API - * do not need it. - * The class serves for converting events from org.glite.wsdl.types.lb.Event type - * to org.glite.lb.Event type. In other words, it maps given wsdl event to the event - * from logging API. - * - * @author Tomas Kramec, 207545@mail.muni.cz - * - */ -public class EventConvertor { - - /** - * This method sets common attributes for the given event. These attributes - * are included in every event. - * - * @param timestamp - * @param arrived - * @param host - * @param level - * @param priority - * @param jobId - * @param seqcode - * @param user - * @param source - * @param srcInstance - */ - private void setCommonAttributes(org.glite.wsdl.types.lb.Timeval timestamp, - org.glite.wsdl.types.lb.Timeval arrived, String host, - org.glite.wsdl.types.lb.Level level, Integer priority, String jobId, - String seqcode, String user, org.glite.wsdl.types.lb.EventSource source, - String srcInstance, Event event) { - - if (event == null) throw new IllegalArgumentException("event cannot be null"); - - if (arrived != null) event.setArrived(new Timeval(arrived.getTvSec(), arrived.getTvUsec())); - if (host != null) event.setHost(host); - if (jobId != null) event.setJobId(new Jobid(jobId)); - if (level != null) event.setLevel(getLevelFromString(level.getValue())); - if (priority != null) event.setPriority(priority); - if (seqcode != null) event.setSeqcode(new SeqCode(SeqCode.NORMAL,seqcode)); /* XXX */ - if (source != null) event.setSource(getSourceFromString(source.getValue())); - if (srcInstance != null) event.setSrcInstance(srcInstance); - if (timestamp != null) event.setTimestamp(new Timeval(timestamp.getTvSec(), timestamp.getTvUsec())); - if (user != null) event.setUser(user); - - - } - - /** - * This private method returns event source depending on input string - * - * @param from represents symbolic name for the source - * @return source value - */ - private Sources getSourceFromString(String from) { - if (from == null) throw new IllegalArgumentException("from cannot be null"); - - Sources source = new Sources(Sources.NONE); - - if (from.equals(EventSource._UserInterface)) source = new Sources(Sources.USER_INTERFACE); - else if (from.equals(EventSource._NetworkServer)) source = new Sources(Sources.NETWORK_SERVER); - else if (from.equals(EventSource._WorkloadManager)) source = new Sources(Sources.WORKLOAD_MANAGER); - else if (from.equals(EventSource._BigHelper)) source = new Sources(Sources.BIG_HELPER); - else if (from.equals(EventSource._JobSubmission)) source = new Sources(Sources.JOB_SUBMISSION); - else if (from.equals(EventSource._LogMonitor)) source = new Sources(Sources.LOG_MONITOR); - else if (from.equals(EventSource._LRMS)) source = new Sources(Sources.LRMS); - else if (from.equals(EventSource._Application)) source = new Sources(Sources.APPLICATION); - else if (from.equals(EventSource._LBServer)) source = new Sources(Sources.LB_SERVER); - - return source; - } - - /** - * This private method returns level depending on the given symbolic name. - * - * @param name symbolic name of the level - * @return level object - */ - - private Level getLevelFromString(String name) { - if(name.equals("UNDEFINED")) return Level.LEVEL_UNDEFINED; - else if(name.equals("EMERGENCY")) return Level.LEVEL_EMERGENCY; - else if(name.equals("ALERT")) return Level.LEVEL_ALERT; - else if(name.equals("ERROR")) return Level.LEVEL_ERROR; - else if(name.equals("WARNING")) return Level.LEVEL_WARNING; - else if(name.equals("AUTH")) return Level.LEVEL_AUTH; - else if(name.equals("SECURITY")) return Level.LEVEL_SECURITY; - else if(name.equals("USAGE")) return Level.LEVEL_USAGE; - else if(name.equals("SYSTEM")) return Level.LEVEL_SYSTEM; - else if(name.equals("IMPORTANT")) return Level.LEVEL_IMPORTANT; - else if(name.equals("DEBUG")) return Level.LEVEL_DEBUG; - else throw new IllegalArgumentException("wrong level type"); - } - - /** - * These private methods serve for creating particular events from logging API. - * They fill in all relevant attributes of output event - * as consistent with the attributes of the given wsdl event. - * - * @param event Wsdl event - * @return appropriate event from logging API - */ - - private EventAbort createEventAbort(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventAbort wsdlEvent = event.getAbort(); - EventAbort ev = new EventAbort(); - - if (wsdlEvent.getReason()!=null) ev.setReason(wsdlEvent.getReason()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventAccepted createEventAccepted(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventAccepted wsdlEvent = event.getAccepted(); - EventAccepted ev = new EventAccepted(); - - Sources source = new Sources(Sources.NONE); - if (wsdlEvent.getFrom() != null) { - source = getSourceFromString(wsdlEvent.getFrom().getValue()); - } - ev.setFrom(source); - - if (wsdlEvent.getFromHost()!=null) ev.setFromHost(wsdlEvent.getFromHost()); - if (wsdlEvent.getFromInstance()!=null) ev.setFromInstance(wsdlEvent.getFromInstance()); - if (wsdlEvent.getLocalJobid()!=null) ev.setLocalJobid(wsdlEvent.getLocalJobid()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventCancel createEventCancel(org.glite.wsdl.types.lb.Event event) { - EventCancel ev = new EventCancel(); - org.glite.wsdl.types.lb.EventCancel wsdlEvent = event.getCancel(); - - if (wsdlEvent.getReason()!=null) ev.setReason(wsdlEvent.getReason()); - - if(wsdlEvent.getStatusCode() != null) { - ev.setStatusCode(EventCancel.StatusCode.valueOf(wsdlEvent.getStatusCode().getValue())); - } else ev.setStatusCode(EventCancel.StatusCode.UNDEFINED); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventChangeACL createEventChangeACL(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventChangeACL wsdlEvent = event.getChangeACL(); - EventChangeACL ev = new EventChangeACL(); - - if (wsdlEvent.getOperation() != null) { - ev.setOperation(EventChangeACL.Operation.valueOf(wsdlEvent.getOperation().getValue())); - } else ev.setOperation(EventChangeACL.Operation.UNDEFINED); - - if (wsdlEvent.getPermission()!= null) { - ev.setPermission(EventChangeACL.Permission.valueOf(wsdlEvent.getPermission().getValue())); - } else ev.setPermission(EventChangeACL.Permission.UNDEFINED); - - if (wsdlEvent.getPermissionType() != null) { - ev.setPermissionType(EventChangeACL.PermissionType.valueOf(wsdlEvent.getPermissionType().getValue())); - } else ev.setPermissionType(EventChangeACL.PermissionType.UNDEFINED); - - if (wsdlEvent.getUserId() != null) ev.setUserId(wsdlEvent.getUserId()); - - if (wsdlEvent.getUserIdType() != null) { - ev.setUserIdType(EventChangeACL.UserIdType.valueOf(wsdlEvent.getUserIdType().getValue())); - } else ev.setUserIdType(EventChangeACL.UserIdType.UNDEFINED); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventChkpt createEventChkpt(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventChkpt wsdlEvent = event.getChkpt(); - EventChkpt ev = new EventChkpt(); - - if (wsdlEvent.getClassad() != null) ev.setClassad(wsdlEvent.getClassad()); - if (wsdlEvent.getTag() != null) ev.setTag(wsdlEvent.getTag()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventClear createEventClear(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventClear wsdlEvent = event.getClear(); - EventClear ev = new EventClear(); - - if (wsdlEvent.getReason() != null) { - ev.setReason(EventClear.Reason.valueOf(wsdlEvent.getReason().getValue())); - } else ev.setReason(EventClear.Reason.UNDEFINED); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventCollectionState createEventCollectionState(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventCollectionState wsdlEvent = event.getCollectionState(); - EventCollectionState ev = new EventCollectionState(); - - if (wsdlEvent.getChild() != null) { - ev.setChild(new Jobid(wsdlEvent.getChild())); - } - if (wsdlEvent.getChildEvent() != null) { - ev.setChildEvent(wsdlEvent.getChildEvent()); - } - if (wsdlEvent.getDoneCode() != null) { - ev.setDoneCode(wsdlEvent.getDoneCode()); - } - if (wsdlEvent.getHistogram() != null) { - ev.setHistogram(wsdlEvent.getHistogram()); - } - if (wsdlEvent.getState() != null) { - ev.setState(wsdlEvent.getState()); - } - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventCondorError createEventCondorError(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventCondorError wsdlEvent = event.getCondorError(); - EventCondorError ev = new EventCondorError(); - - if (ev.getErrorDesc() != null) ev.setErrorDesc(wsdlEvent.getErrorDesc()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventCondorMatch createEventCondorMatch(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventCondorMatch wsdlEvent = event.getCondorMatch(); - EventCondorMatch ev = new EventCondorMatch(); - - if (ev.getDestHost() != null) ev.setDestHost(wsdlEvent.getDestHost()); - if (ev.getOwner() != null) ev.setOwner(wsdlEvent.getOwner()); - if (ev.getPreempting() != null) ev.setPreempting(wsdlEvent.getPreempting()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventCondorReject createEventCondorReject(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventCondorReject wsdlEvent = event.getCondorReject(); - EventCondorReject ev = new EventCondorReject(); - - if (ev.getOwner() != null) ev.setOwner(wsdlEvent.getOwner()); - if (wsdlEvent.getStatusCode() != null) { - ev.setStatusCode(EventCondorReject.StatusCode.valueOf(wsdlEvent.getStatusCode().getValue())); - } else ev.setStatusCode(EventCondorReject.StatusCode.UNDEFINED); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventCondorResourceUsage createEventCondorResourceUsage(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventCondorResourceUsage wsdlEvent = event.getCondorResourceUsage(); - EventCondorResourceUsage ev = new EventCondorResourceUsage(); - - if (ev.getName() != null) ev.setName(wsdlEvent.getName()); - ev.setQuantity(wsdlEvent.getQuantity()); - if (ev.getUnit() != null) ev.setUnit(wsdlEvent.getUnit()); - if (wsdlEvent.getUsage() != null) { - ev.setUsage(EventCondorResourceUsage.Usage.valueOf(wsdlEvent.getUsage().getValue())); - } else ev.setUsage(EventCondorResourceUsage.Usage.UNDEFINED); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - return ev; - } - - private EventCondorShadowExited createEventCondorShadowExited(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventCondorShadowExited wsdlEvent = event.getCondorShadowExited(); - EventCondorShadowExited ev = new EventCondorShadowExited(); - - ev.setShadowExitStatus(wsdlEvent.getShadowExitStatus()); - ev.setShadowPid(wsdlEvent.getShadowPid()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventCondorShadowStarted createEventCondorShadowStarted(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventCondorShadowStarted wsdlEvent = event.getCondorShadowStarted(); - EventCondorShadowStarted ev = new EventCondorShadowStarted(); - - if (ev.getShadowHost() != null) ev.setShadowHost(wsdlEvent.getShadowHost()); - ev.setShadowPid(wsdlEvent.getShadowPid()); - ev.setShadowPort(wsdlEvent.getShadowPort()); - if (ev.getShadowStatus() != null) ev.setShadowStatus(wsdlEvent.getShadowStatus()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventCondorStarterExited createEventCondorStarterExited(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventCondorStarterExited wsdlEvent = event.getCondorStarterExited(); - EventCondorStarterExited ev = new EventCondorStarterExited(); - - if (wsdlEvent.getJobExitStatus() != null) { - ev.setJobExitStatus(wsdlEvent.getJobExitStatus()); - } - if (wsdlEvent.getJobPid() != null) { - ev.setJobPid(wsdlEvent.getJobPid()); - } - if (wsdlEvent.getStarterExitStatus() != null) { - ev.setStarterExitStatus(wsdlEvent.getStarterExitStatus()); - } - if (wsdlEvent.getStarterPid() != null) { - ev.setStarterPid(wsdlEvent.getStarterPid()); - } - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventCondorStarterStarted createEventCondorStarterStarted(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventCondorStarterStarted wsdlEvent = event.getCondorStarterStarted(); - EventCondorStarterStarted ev = new EventCondorStarterStarted(); - - if (wsdlEvent.getStarterPid() != null) { - ev.setStarterPid(wsdlEvent.getStarterPid()); - } - if (wsdlEvent.getUniverse() != null) ev.setUniverse(wsdlEvent.getUniverse()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventCurDescr createEventCurDescr(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventCurDescr wsdlEvent = event.getCurDescr(); - EventCurDescr ev = new EventCurDescr(); - - if (wsdlEvent.getDescr() != null) ev.setDescr(wsdlEvent.getDescr()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventDeQueued createEventDeQueued(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventDeQueued wsdlEvent = event.getDeQueued(); - EventDeQueued ev = new EventDeQueued(); - - if (wsdlEvent.getLocalJobid() != null) ev.setLocalJobid(wsdlEvent.getLocalJobid()); - if (wsdlEvent.getQueue() != null) ev.setQueue(wsdlEvent.getQueue()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventDone createEventDone(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventDone wsdlEvent = event.getDone(); - EventDone ev = new EventDone(); - - ev.setExitCode(wsdlEvent.getExitCode()); - if (wsdlEvent.getReason() != null) ev.setReason(wsdlEvent.getReason()); - if (wsdlEvent.getStatusCode() != null) { - ev.setStatusCode(EventDone.StatusCode.valueOf(wsdlEvent.getStatusCode().getValue())); - } else ev.setStatusCode(EventDone.StatusCode.UNDEFINED); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventEnQueued createEventEnQueued(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventEnQueued wsdlEvent = event.getEnQueued(); - EventEnQueued ev = new EventEnQueued(); - - if (wsdlEvent.getJob() != null) ev.setJob(wsdlEvent.getJob()); - if (wsdlEvent.getQueue() != null) ev.setQueue(wsdlEvent.getQueue()); - if (wsdlEvent.getReason() != null) ev.setReason(wsdlEvent.getReason()); - if (wsdlEvent.getResult() != null) { - ev.setResult(EventEnQueued.Result.valueOf(wsdlEvent.getResult().getValue())); - } else ev.setResult(EventEnQueued.Result.UNDEFINED); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventHelperCall createEventHelperCall(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventHelperCall wsdlEvent = event.getHelperCall(); - EventHelperCall ev = new EventHelperCall(); - - if (wsdlEvent.getHelperName() != null) ev.setHelperName(wsdlEvent.getHelperName()); - if (wsdlEvent.getHelperParams() != null) ev.setHelperParams(wsdlEvent.getHelperParams()); - if (wsdlEvent.getSrcRole() != null) { - ev.setSrcRole(EventHelperCall.SrcRole.valueOf(wsdlEvent.getSrcRole().getValue())); - } else ev.setSrcRole(EventHelperCall.SrcRole.UNDEFINED); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventHelperReturn createEventHelperReturn(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventHelperReturn wsdlEvent = event.getHelperReturn(); - EventHelperReturn ev = new EventHelperReturn(); - - if (wsdlEvent.getHelperName() != null) ev.setHelperName(wsdlEvent.getHelperName()); - if (wsdlEvent.getRetval() != null) ev.setRetval(wsdlEvent.getRetval()); - if (wsdlEvent.getSrcRole() != null) { - ev.setSrcRole(EventHelperReturn.SrcRole.valueOf(wsdlEvent.getSrcRole().getValue())); - } else ev.setSrcRole(EventHelperReturn.SrcRole.UNDEFINED); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventListener createEventListener(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventListener wsdlEvent = event.getListener(); - EventListener ev = new EventListener(); - - if (wsdlEvent.getSvcHost() != null) ev.setSvcHost(wsdlEvent.getSvcHost()); - if (wsdlEvent.getSvcName() != null) ev.setSvcName(wsdlEvent.getSvcName()); - ev.setSvcPort(wsdlEvent.getSvcPort()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventMatch createEventMatch(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventMatch wsdlEvent = event.getMatch(); - EventMatch ev = new EventMatch(); - - if (wsdlEvent.getDestId() != null) ev.setDestId(wsdlEvent.getDestId()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventNotification createEventNotification(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventNotification wsdlEvent = event.getNotification(); - EventNotification ev = new EventNotification(); - - if (wsdlEvent.getDestHost() != null) ev.setDestHost(wsdlEvent.getDestHost()); - ev.setDestPort(wsdlEvent.getDestPort()); - ev.setExpires(wsdlEvent.getExpires()); - if (wsdlEvent.getJobstat() != null) ev.setJobstat(wsdlEvent.getJobstat()); - if (wsdlEvent.getNotifId() != null) { - ev.setNotifId(new Jobid(wsdlEvent.getNotifId())); - } - if (wsdlEvent.getOwner() != null) ev.setOwner(wsdlEvent.getOwner()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventPBSDequeued createEventPBSDequeued(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventPBSDequeued wsdlEvent = event.getPBSDequeued(); - EventPBSDequeued ev = new EventPBSDequeued(); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventPBSDone createEventPBSDone(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventPBSDone wsdlEvent = event.getPBSDone(); - EventPBSDone ev = new EventPBSDone(); - - if (wsdlEvent.getExitStatus() != null) { - ev.setExitStatus(wsdlEvent.getExitStatus()); - } - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventPBSError createEventPBSError(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventPBSError wsdlEvent = event.getPBSError(); - EventPBSError ev = new EventPBSError(); - - if (wsdlEvent.getErrorDesc() != null) ev.setErrorDesc(wsdlEvent.getErrorDesc()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventPBSMatch createEventPBSMatch(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventPBSMatch wsdlEvent = event.getPBSMatch(); - EventPBSMatch ev = new EventPBSMatch(); - - if (wsdlEvent.getDestHost() != null) ev.setDestHost(wsdlEvent.getDestHost()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventPBSPending createEventPBSPending(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventPBSPending wsdlEvent = event.getPBSPending(); - EventPBSPending ev = new EventPBSPending(); - - if (wsdlEvent.getReason() != null) ev.setReason(wsdlEvent.getReason()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventPBSQueued createEventPBSQueued(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventPBSQueued wsdlEvent = event.getPBSQueued(); - EventPBSQueued ev = new EventPBSQueued(); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventPBSRerun createEventPBSRerun(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventPBSRerun wsdlEvent = event.getPBSRerun(); - EventPBSRerun ev = new EventPBSRerun(); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventPBSResourceUsage createEventPBSResourceUsage(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventPBSResourceUsage wsdlEvent = event.getPBSResourceUsage(); - EventPBSResourceUsage ev = new EventPBSResourceUsage(); - - if (wsdlEvent.getName() != null) ev.setName(wsdlEvent.getName()); - if (wsdlEvent.getQuantity() != null) { - ev.setQuantity(wsdlEvent.getQuantity()); - } - if (wsdlEvent.getUnit() != null) ev.setUnit(wsdlEvent.getUnit()); - if (wsdlEvent.getUsage() != null) { - ev.setUsage(EventPBSResourceUsage.Usage.valueOf(wsdlEvent.getUsage().getValue())); - } else ev.setUsage(EventPBSResourceUsage.Usage.UNDEFINED); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventPBSRun createEventPBSRun(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventPBSRun wsdlEvent = event.getPBSRun(); - EventPBSRun ev = new EventPBSRun(); - - if (wsdlEvent.getDestHost() != null) ev.setDestHost(wsdlEvent.getDestHost()); - if (wsdlEvent.getPid() != null) { - ev.setPid(wsdlEvent.getPid()); - } - if (wsdlEvent.getScheduler() != null) ev.setScheduler(wsdlEvent.getScheduler()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventPending createEventPending(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventPending wsdlEvent = event.getPending(); - EventPending ev = new EventPending(); - - if (wsdlEvent.getReason() != null) ev.setReason(wsdlEvent.getReason()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventPurge createEventPurge(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventPurge wsdlEvent = event.getPurge(); - EventPurge ev = new EventPurge(); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventReallyRunning createEventReallyRunning(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventReallyRunning wsdlEvent = event.getReallyRunning(); - EventReallyRunning ev = new EventReallyRunning(); - - if (wsdlEvent.getWnSeq() != null) ev.setWnSeq(wsdlEvent.getWnSeq()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventRefused createEventRefused(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventRefused wsdlEvent = event.getRefused(); - EventRefused ev = new EventRefused(); - - if (wsdlEvent.getFrom() != null) { - ev.setFrom(getSourceFromString(wsdlEvent.getFrom().getValue())); - } else ev.setFrom(new Sources(Sources.NONE)); - if (wsdlEvent.getFromHost() != null) ev.setFromHost(wsdlEvent.getFromHost()); - if (wsdlEvent.getFromInstance() != null) ev.setFromInstance(wsdlEvent.getFromInstance()); - if (wsdlEvent.getReason() != null) ev.setReason(wsdlEvent.getReason()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventRegJob createEventRegJob(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventRegJob wsdlEvent = event.getRegJob(); - EventRegJob ev = new EventRegJob(); - - if (wsdlEvent.getJdl() != null) ev.setJdl(wsdlEvent.getJdl()); - - if (wsdlEvent.getJobtype() != null) { - ev.setJobtype(EventRegJob.Jobtype.valueOf(wsdlEvent.getJobtype().getValue())); - } else ev.setJobtype(EventRegJob.Jobtype.UNDEFINED); - - if (wsdlEvent.getNs() != null) ev.setNs(wsdlEvent.getNs()); - - if (wsdlEvent.getNsubjobs() != null) ev.setNsubjobs(wsdlEvent.getNsubjobs()); - - if (wsdlEvent.getParent() != null) ev.setParent(new Jobid(wsdlEvent.getParent())); - - if (wsdlEvent.getSeed() != null) ev.setSeed(wsdlEvent.getSeed()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventResourceUsage createEventResourceUsage(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventResourceUsage wsdlEvent = event.getResourceUsage(); - EventResourceUsage ev = new EventResourceUsage(); - - ev.setQuantity(wsdlEvent.getQuantity()); - if (wsdlEvent.getResource() != null) ev.setResource(wsdlEvent.getResource()); - if (wsdlEvent.getUnit() != null) ev.setUnit(wsdlEvent.getUnit()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventResubmission createEventResubmission(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventResubmission wsdlEvent = event.getResubmission(); - EventResubmission ev = new EventResubmission(); - - if (wsdlEvent.getReason() != null) ev.setReason(wsdlEvent.getReason()); - if (wsdlEvent.getResult() != null) { - ev.setResult(EventResubmission.Result.valueOf(wsdlEvent.getResult().getValue())); - } else ev.setResult(EventResubmission.Result.UNDEFINED); - if (wsdlEvent.getTag() != null) ev.setTag(wsdlEvent.getTag()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventResume createEventResume(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventResume wsdlEvent = event.getResume(); - EventResume ev = new EventResume(); - - if (wsdlEvent.getReason() != null) ev.setReason(wsdlEvent.getReason()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventRunning createEventRunning(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventRunning wsdlEvent = event.getRunning(); - EventRunning ev = new EventRunning(); - - if (wsdlEvent.getNode() != null) ev.setNode(wsdlEvent.getNode()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventSuspend createEventSuspend(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventSuspend wsdlEvent = event.getSuspend(); - EventSuspend ev = new EventSuspend(); - - if (wsdlEvent.getReason() != null) ev.setReason(wsdlEvent.getReason()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventTransfer createEventTransfer(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventTransfer wsdlEvent = event.getTransfer(); - EventTransfer ev = new EventTransfer(); - - if (wsdlEvent.getDestHost() != null) ev.setDestHost(wsdlEvent.getDestHost()); - if (wsdlEvent.getDestInstance() != null) ev.setDestInstance(wsdlEvent.getDestInstance()); - if (wsdlEvent.getDestJobid() != null) ev.setDestJobid(wsdlEvent.getDestJobid()); - - if (wsdlEvent.getDestination() != null) { - ev.setDestination(getSourceFromString(wsdlEvent.getDestination().getValue())); - } else ev.setDestination(new Sources(Sources.NONE)); - - if (wsdlEvent.getJob() != null) ev.setJob(wsdlEvent.getJob()); - if (wsdlEvent.getReason() != null) ev.setReason(wsdlEvent.getReason()); - - if (wsdlEvent.getResult() != null) { - ev.setResult(EventTransfer.Result.valueOf(wsdlEvent.getResult().getValue())); - } else ev.setResult(EventTransfer.Result.UNDEFINED); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - private EventUserTag createEventUserTag(org.glite.wsdl.types.lb.Event event) { - org.glite.wsdl.types.lb.EventUserTag wsdlEvent = event.getUserTag(); - EventUserTag ev = new EventUserTag(); - - if (wsdlEvent.getName() != null) ev.setName(wsdlEvent.getName()); - if (wsdlEvent.getValue() != null) ev.setValue(wsdlEvent.getValue()); - - setCommonAttributes(wsdlEvent.getTimestamp(), wsdlEvent.getArrived(), - wsdlEvent.getHost(), wsdlEvent.getLevel(), wsdlEvent.getPriority(), - wsdlEvent.getJobId(), wsdlEvent.getSeqcode(), wsdlEvent.getUser(), - wsdlEvent.getSource(), wsdlEvent.getSrcInstance(), ev); - - return ev; - } - - - - /** - * Converts given event of org.glite.wsdl.types.lb.Event type - * into event of org.glite.lb.Event type - * - * @param event Event to be converted - * @return converted event - */ - protected Event convert(org.glite.wsdl.types.lb.Event event) { - - if (event == null) throw new IllegalArgumentException("event cannot be null"); - - //EventAbort - if(event.getAbort()!=null) return createEventAbort(event); - - //EventAccepted - if(event.getAccepted()!=null) return createEventAccepted(event); - - //EventCancel - if (event.getCancel() != null) return createEventCancel(event); - - //EventChangeACL - if (event.getChangeACL() != null) return createEventChangeACL(event); - - //EventChkpt - if (event.getChkpt() != null) return createEventChkpt(event); - - //EventClear - if (event.getClear() != null) return createEventClear(event); - - //EventCollectionState - if (event.getCollectionState() != null) return createEventCollectionState(event); - - //EventCondorError - if (event.getCondorError() != null) return createEventCondorError(event); - - //EventCondorMatch - if (event.getCondorMatch() != null) return createEventCondorMatch(event); - - //EventCondorReject - if (event.getCondorReject() != null) return createEventCondorReject(event); - - //EventCondorResourceUsage - if (event.getCondorResourceUsage() != null) return createEventCondorResourceUsage(event); - - //EventCondorShadowExited - if (event.getCondorShadowExited() != null) return createEventCondorShadowExited(event); - - //EventCondorShadowStarted - if (event.getCondorShadowStarted() != null) return createEventCondorShadowStarted(event); - - //EventCondorStarterExited - if (event.getCondorStarterExited() != null) return createEventCondorStarterExited(event); - - //EventCondorStarterStarted - if (event.getCondorStarterStarted() != null) return createEventCondorStarterStarted(event); - - //EventCurDescr - if (event.getCurDescr() != null) return createEventCurDescr(event); - - //EventDeQueued - if (event.getDeQueued() != null) return createEventDeQueued(event); - - //EventDone - if (event.getDone() != null) return createEventDone(event); - - //EventEnQueued - if (event.getEnQueued() != null) return createEventEnQueued(event); - - //EventHelperCall - if (event.getHelperCall() != null) return createEventHelperCall(event); - - //EventHelperReturn - if (event.getHelperReturn() != null) return createEventHelperReturn(event); - - //EventListener - if (event.getListener() != null) return createEventListener(event); - - //EventMatch - if (event.getMatch() != null) return createEventMatch(event); - - //EventNotification - if (event.getNotification() != null) return createEventNotification(event); - - //EventPBSDequeued - if (event.getPBSDequeued() != null) return createEventPBSDequeued(event); - - //EventPBSDone - if (event.getPBSDone() != null) return createEventPBSDone(event); - - //EventPBSError - if (event.getPBSError() != null) return createEventPBSError(event); - - //EventPBSMatch - if (event.getPBSMatch() != null) return createEventPBSMatch(event); - - //EventPBSPendig - if (event.getPBSPending() != null) return createEventPBSPending(event); - - //EventPBSQueued - if (event.getPBSQueued() != null) return createEventPBSQueued(event); - - //EventPBSRerun - if (event.getPBSRerun() != null) return createEventPBSRerun(event); - - //EventPBSResourceUsage - if (event.getPBSResourceUsage() != null) return createEventPBSResourceUsage(event); - - //EventPBSRun - if (event.getPBSRun() != null) return createEventPBSRun(event); - - //EventPendig - if (event.getPending() != null) return createEventPending(event); - - //EventPurge - if (event.getPurge() != null) return createEventPurge(event); - - //EventReallyRunning - if (event.getReallyRunning() != null) return createEventReallyRunning(event); - - //EventRefused - if (event.getRefused() != null) return createEventRefused(event); - - //EventRegJob - if (event.getRegJob() != null) return createEventRegJob(event); - - //EventResourceUsage - if (event.getResourceUsage() != null) return createEventResourceUsage(event); - - //EventResubmission - if (event.getResubmission() != null) return createEventResubmission(event); - - //EventResume - if (event.getResume() != null) return createEventResume(event); - - //EventRunning - if (event.getRunning() != null) return createEventRunning(event); - - //EventSuspend - if (event.getSuspend() != null) return createEventSuspend(event); - - //EventTransfer - if (event.getTransfer() != null) return createEventTransfer(event); - - //EventUserTag - if (event.getUserTag() != null) return createEventUserTag(event); - - return null; - } - -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/ILFileWriter.java b/org.glite.lb.client-java/src/org/glite/lb/ILFileWriter.java deleted file mode 100644 index 50900f8..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/ILFileWriter.java +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; - -/** - * This class provides writing messages to some file. - * - * @author Pavel Piskac (173297@mail.muni.cz) - */ -public class ILFileWriter { - - public ILFileWriter() { - } - - /** - * Writes message to a file and returns size of this file before writing the - * data - * @param prefix file path - * @param message message which will be written - * @param repeatWriteToFile count of attempts to write to file in case of failure - */ - public static Long write(String prefix, String message, int repeatWriteToFile) throws LBException { - FileWriter fileWriter = null; - long fileLength = 0; - FileLock fileLock = null; - File file; - - for (int i = 0; i < repeatWriteToFile; i++) { - try { - file = new File(prefix); - FileOutputStream out = new FileOutputStream(file,true); - FileChannel fileChannel = out.getChannel(); - - fileLock = fileChannel.tryLock(); - if (fileLock != null) { - if (!file.exists()) { - continue; - } - fileLength = file.length(); - out.write(message.getBytes()); - fileLock.release(); - out.close(); - - if (file.exists()) { - break; - } - } - } catch (Throwable ex) { - if (fileLock != null) { - try { - fileLock.release(); - } catch (IOException ex2) { } - } - throw new LBException(ex); - } - } - - return new Long(fileLength); - } -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/ILProto.java b/org.glite.lb.client-java/src/org/glite/lb/ILProto.java deleted file mode 100644 index f71fa93..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/ILProto.java +++ /dev/null @@ -1,255 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ - -package org.glite.lb; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; - -/** - * this class handles communication with LB server (reads messages it sends) - * - * @author Kopac - */ -public class ILProto { - - private Socket socket = null; - private InputStream inStream = null; - private OutputStream outStream = null; - private static final String magicWordXXX = "6 michal"; - private static final String magicWord = "michal"; - private int min,maj; - private String err; - private byte[] buf; - private int bufptr,bufsiz; - - /** - * construcor initializes the class' socket, inStream and outStream attributes - * - * @param socket an SSLSocket - * @throws java.io.IOException - */ - public ILProto(Socket socket) throws IOException { - this.socket = socket; - inStream = this.socket.getInputStream(); - outStream = this.socket.getOutputStream(); - } - - /** - * this method reads from the inpuStream of the provided socket, checks for - * the magic word and returns relevant info - * - * @return a String containing third line of the inputStream data, without - * the info about its length - * @throws IOException - */ - /* XXX: weird implementation, should follow C */ - public String receiveMessage() throws IOException{ - byte[] b = new byte[17]; - int i = 0; - //read in and convert size of the message - if(inStream.read(b, 0, 17) == -1) { - return null; - } else { - String test = new String(b); - test.trim(); - int length = Integer.parseInt(test); - byte[] notification = new byte[length]; - //read in the rest of the message - int j = 0; - while(i != length || j == -1) { - j = inStream.read(notification, i, length-i); - i=i+j; - } - String retString = checkWord(notification); - if(retString == null) return null; - else - //return - return retString.split(" ", 2)[1]; - } - } - - public void sendMessage(String msg) throws IOException - { - newbuf(magicWord.length() + msg.length() + 100); - put_string(magicWord); - put_string(msg); - String hdr = String.format("%16d\n",bufptr); - outStream.write(hdr.getBytes()); - - writebuf(); - outStream.flush(); - } - - public int receiveReply() throws IOException,LBException - { - newbuf(17); - - if (readbuf(17) != 17) { - throw new LBException("reading IL proto header"); - } - int len = Integer.parseInt((new String(buf)).trim()); - - newbuf(len); - if (readbuf(len) < len) { - throw new LBException("incomplete IL message"); - } - - rewind(); - this.maj = get_int(); - this.min = get_int(); - this.err = get_string(); - - return this.maj; - } - - public int errMin() { return min; } - public String errMsg() { return err; } - - /** - * private method that checks, if the magic word is present in the notification - * - * @param notification a notification without the line specifying its length - * @return null, if the word is not there, the last line of the notification, - * again without its length specification, otherwise - */ - private String checkWord(byte[] notification) { - int i = 0; - while(notification[i] != '\n') { - i++; - } - String word = new String(notification, 0, i+1); - word.trim(); - if(!word.equals(magicWordXXX)) { - return null; - } else { - return new String(notification, i+1, notification.length - i + 1); - } - } - - /** - * this method encodes and sends a reply to the interlogger via the socket's - * outputStream - * - * @param errCode errCode of the calling - * @param minErrCode minimum available errcode - * @param message message for the interlogger - could be any String - * @throws IOException - */ - public void sendReply(int errCode, int minErrCode, String message) throws IOException { - byte[] errByte = (new String()+errCode).getBytes(); - byte[] minErrByte = (new String()+minErrCode).getBytes(); - byte[] msgByte = message.getBytes(); - int length = errByte.length + minErrByte.length + msgByte.length; - byte[] lengthByte = (new String()+length).getBytes(); - int numberOfSpaces = 17 - lengthByte.length; - byte[] returnByte = new byte[length+17]; - int i = 0; - while(i < numberOfSpaces-1) { - returnByte[i] = ' '; - i++; - } - returnByte = putByte(returnByte, lengthByte, numberOfSpaces); - returnByte[16] = '\n'; - returnByte = putByte(returnByte, errByte, 17); - returnByte = putByte(returnByte, minErrByte, 16 + errByte.length); - returnByte = putByte(returnByte, msgByte, 16 + errByte.length + minErrByte.length); - outStream.write(returnByte); - } - - /** - * appends a byte array to the end of an existing byte array - * - * @param arrayToFill array to be filled - * @param filler array to be appended - * @param start starting offset of the first array, from which the second - * array should be appended - * @return the resulting byte array - */ - private byte[] putByte(byte[] arrayToFill, byte[] filler, int start) { - for(int i = start; i < filler.length + start; i++) { - int j = 0; - arrayToFill[i] = filler[j]; - j++; - } - return arrayToFill; - } - - private void newbuf(int size) { - buf = new byte[size]; - bufptr = 0; - bufsiz = size; - } - - private void rewind() { bufptr = 0; } - - private int readbuf(int size) throws IOException { - int r,total = 0; - - while (size > 0 && (r = inStream.read(buf,bufptr,size)) > 0) { - bufptr += r; - size -= r; - total += r; - } - return total; - } - - private void writebuf() throws IOException { - outStream.write(buf,0,bufptr); - } - - private void _put_int(int ii) - { - String s = new String() + ii; - byte[] b = s.getBytes(); - int i; - - for (i=0; i - *

  1. CLASSADS - Include the job description in the query result.
  2. - *
  3. CHILDREN - Include the list of subjob id's in the query result.
  4. - *
  5. CHILDSTAT - Apply the flags recursively to subjobs.
  6. - *
  7. CHILDHIST_FAST - Include partially complete histogram of child job states.
  8. - *
  9. CHILDHIST_THOROUGH - Include full and up-to date histogram of child job states.
  10. - *

    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

- * - * @return Status of the job. - * @throws LBException If some communication or server problem occurs. - */ - public JobStatus getStatus(JobFlagsValue[] flags) throws LBException { - if (serverConnection == null) - throw new IllegalStateException("serverConnection is null, please set it"); - if (jobId == null) - throw new IllegalStateException("jobId is null, please set it"); - return serverConnection.jobState(jobId.toString(), flags); - } - - /** - * Return all events corresponding to this job. - * Obtains all events corresponding to the job that are stored - * in the bookkeeping server database. - *

- * Default value for logging level is SYSTEM. If needed, it can be changed - * by calling setEventLoggingLevel(Level loggingLevel) method - * on the serverConnection attribute of this class. - *

- * - * @return events List of events (of type Event). - * @throws LBException If some communication or server problem occurs. - */ - public List getEvents() throws LBException { - if (serverConnection == null) - throw new IllegalStateException("serverConnection is null, please set it"); - if (jobId == null) - throw new IllegalStateException("jobId is null, please set it"); - - QueryRecValue jobIdValue = new QueryRecValue(null, jobId.toString(), null); - QueryRecord[] jobIdRec = new QueryRecord[] {new QueryRecord(QueryOp.EQUAL, jobIdValue, null)}; - QueryConditions[] query = new QueryConditions[]{new QueryConditions(QueryAttr.JOBID, null, null, jobIdRec)}; - QueryRecValue levelValue = new QueryRecValue(serverConnection.getEventLoggingLevel().getInt()+1, null, null); - QueryRecord[] levelRec = new QueryRecord[] {new QueryRecord(QueryOp.LESS, levelValue, null)}; - QueryConditions[] queryEvent = new QueryConditions[]{new QueryConditions(QueryAttr.LEVEL, null, null, levelRec)}; - List queryList = new ArrayList(); - queryList.add(query[0]); - List queryEventList = new ArrayList(); - queryEventList.add(queryEvent[0]); - - return serverConnection.queryEvents(queryList, queryEventList); - } -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/LBCredentials.java b/org.glite.lb.client-java/src/org/glite/lb/LBCredentials.java deleted file mode 100644 index b18b7b1..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/LBCredentials.java +++ /dev/null @@ -1,135 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ - -package org.glite.lb; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Properties; -import javax.xml.rpc.ServiceException; -import javax.net.ssl.SSLContext; - -import org.apache.axis.SimpleTargetedChain; -import org.apache.axis.Handler; -import org.apache.axis.transport.http.HTTPTransport; -import org.apache.axis.transport.http.SocketHolder; -import org.apache.axis.SimpleChain; -import org.apache.axis.configuration.SimpleProvider; - -import org.glite.security.trustmanager.ContextWrapper; -import org.glite.security.trustmanager.axis.SSLConfigSender; - -import org.glite.wsdl.services.lb.LoggingAndBookkeepingLocator; -import org.glite.wsdl.services.lb.LoggingAndBookkeepingPortType; - - -/** - * - */ -public class LBCredentials { - - private String proxy; - private String caFiles; - private String key; - private String pass; - private String cert; - - public LBCredentials(String proxy, String caFiles) { - if (proxy == null) throw new IllegalArgumentException("Proxy cannot be null"); - - this.proxy = new String(proxy); - if (caFiles != null) { - this.caFiles = new String(caFiles); - } - } - - public LBCredentials(String userCert, String userKey, String userPass, String caFiles) { - if (userCert==null || userKey==null) - throw new IllegalArgumentException("key and cert must not be null"); - - key = new String(userKey); - cert = new String(userCert); - if (userPass != null) pass = new String(userPass); - if (caFiles != null) this.caFiles = new String(caFiles); - } - - protected LoggingAndBookkeepingPortType getStub(String server) throws LBException { - if (server == null) - throw new IllegalArgumentException("Server cannot be null"); - try { - URL queryServerAddress = new URL(server); - int port = queryServerAddress.getPort(); - if (port < 1 || port > 65535) { - throw new IllegalArgumentException("port"); - } - if (!queryServerAddress.getProtocol().equals("https")) { - throw new IllegalArgumentException("wrong protocol"); - } - - Handler transport = new SimpleTargetedChain(new SimpleChain(), - new SSLConfigSender(makeConfig()), - new SimpleChain()); - SimpleProvider transportProvider = new SimpleProvider(); - transportProvider.deployTransport(HTTPTransport.DEFAULT_TRANSPORT_NAME, transport); - LoggingAndBookkeepingLocator loc = new LoggingAndBookkeepingLocator(transportProvider); - return loc.getLoggingAndBookkeeping(queryServerAddress); - } catch (ServiceException ex) { - throw new LBException(ex); - } catch (MalformedURLException ex) { - throw new LBException(ex); - } catch (org.apache.axis.AxisFault ex) { - throw new LBException(ex); - } - } - - private Properties makeConfig() { - Properties cf = new java.util.Properties(); - - if (proxy != null) cf.put(ContextWrapper.CREDENTIALS_PROXY_FILE,proxy); - else { - cf.put(ContextWrapper.CREDENTIALS_CERT_FILE,cert); - cf.put(ContextWrapper.CREDENTIALS_KEY_FILE,key); - if (pass != null) cf.put(ContextWrapper.CREDENTIALS_KEY_PASSWD, pass); - } - - if (caFiles != null) cf.put(ContextWrapper.CA_FILES,caFiles); - cf.put(ContextWrapper.SSL_PROTOCOL, "SSLv3"); - - return cf; - } - - protected SSLContext getSSLContext() throws LBException { - ContextWrapper cw; - - try { - cw = new ContextWrapper(makeConfig()); - } - catch (java.io.IOException e) { - throw new LBException(e); - } - catch (java.security.GeneralSecurityException e) { - throw new LBException(e); - } - return cw.getContext(); - - } -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/LBException.java b/org.glite.lb.client-java/src/org/glite/lb/LBException.java deleted file mode 100644 index 9846eab..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/LBException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -public class LBException extends Exception { - - public LBException(Throwable e) { - super(e); - } - - public LBException(String s) { - super(s); - } - -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/Level.java b/org.glite.lb.client-java/src/org/glite/lb/Level.java deleted file mode 100644 index 678290b..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/Level.java +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -/** - * This class represents logging level for events. - * - * @author Tomas Kramec, 207545@mail.muni.cz - */ -public class Level { - - private final int level; - - public static final Level LEVEL_UNDEFINED = new Level(0); - public static final Level LEVEL_EMERGENCY = new Level(1); - public static final Level LEVEL_ALERT = new Level(2); - public static final Level LEVEL_ERROR = new Level(3); - public static final Level LEVEL_WARNING = new Level(4); - public static final Level LEVEL_AUTH = new Level(5); - public static final Level LEVEL_SECURITY = new Level(6); - public static final Level LEVEL_USAGE = new Level(7); - public static final Level LEVEL_SYSTEM = new Level(8); - public static final Level LEVEL_IMPORTANT = new Level(9); - public static final Level LEVEL_DEBUG = new Level(10); - - private Level(int level) { - this.level = level; - } - - public int getInt() { - return level; - } - @Override - public String toString() { - switch (level) { - case 0: return "UNDEFINED"; - case 1: return "EMERGENCY"; - case 2: return "ALERT"; - case 3: return "ERROR"; - case 4: return "WARNING"; - case 5: return "AUTH"; - case 6: return "SECURITY"; - case 7: return "USAGE"; - case 8: return "SYSTEM"; - case 9: return "IMPORTANT"; - case 10: return "DEBUG"; - default: throw new IllegalArgumentException("wrong level type"); - } - } - -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/NotifParser.java b/org.glite.lb.client-java/src/org/glite/lb/NotifParser.java deleted file mode 100644 index c3d769c..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/NotifParser.java +++ /dev/null @@ -1,145 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ - -package org.glite.lb; - -import java.io.IOException; -import java.io.StringReader; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; -import org.apache.commons.lang.StringEscapeUtils; -import org.glite.wsdl.types.lb.JobStatus; -import org.w3c.dom.Document; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -/** - * this class parses the received message into a readable format - * - * @author Kopac - */ -public class NotifParser { - - Document doc = null; - String header = null; - - - /** - * constructor takes a notification in String format and parses it into a String - * containing the header and an XML doc - * - * @param notif the string with notification in it - * @throws javax.xml.parsers.ParserConfigurationException - * @throws org.xml.sax.SAXException - * @throws java.io.IOException - */ - public NotifParser(String notif) throws ParserConfigurationException, SAXException, IOException { - String[] splitString = notif.split("DG.NOTIFICATION.JOBSTAT=\"", 2); - header = splitString[0]; - doc = createXML(splitString[1]); - } - - /** - * this method reads through an XML document using XPath expressions and - * fills an instance of JobStatus, which it then returns - * this is done using automatically generated code - * - * @param notification an array of bytes containing the raw notification - * @return a Jobstatus instance - */ - public JobStatus getJobInfo() - throws ParserConfigurationException, SAXException, IOException { - JobStatus status = new JobStatus(); - //TODO: insert automated code creation - status.setJobId(evaluateXPath("//jobId").item(0).getTextContent()); - status.setOwner(evaluateXPath("//owner").item(0).getTextContent()); - return status; - } - - /** - * this method returns id of the notification - * - * @return notif id - */ - public String getNotifId() { - String halfHeader = header.split("DG.NOTIFICATION.NOTIFID=\"")[1]; - return halfHeader.substring(0, halfHeader.indexOf("\"")); - } - - /** - * a method for handling xpath queries - * - * @param xpathString xpath expression - * @return the result nodelist - */ - private NodeList evaluateXPath(String xpathString) { - try { - XPathFactory xfactory = XPathFactory.newInstance(); - XPath xpath = xfactory.newXPath(); - XPathExpression expr = xpath.compile(xpathString); - return (NodeList) expr.evaluate(doc, XPathConstants.NODESET); - } catch (XPathExpressionException ex) { - ex.printStackTrace(); - return null; - } - } - - /** - * this method creates an XML document out of a provided String - * note that the string has to be a valid escaped XML document representation, - * otherwise the process will fail - * - * @param body a String containing an XML document - * @return an XML document in the Document format - * @throws javax.xml.parsers.ParserConfigurationException - * @throws org.xml.sax.SAXException - * @throws java.io.IOException - */ - private Document createXML(String body) throws ParserConfigurationException, SAXException, IOException { - String removed = body.substring(0, body.length()-1); - String parsed = StringEscapeUtils.unescapeXml(removed); - //this code removes hexadecimal references from the string (couldn't find - //a suitable parser for this) - StringBuilder build = new StringBuilder(parsed); - int j = build.indexOf("%"); - while(j > 0) { - if(build.charAt(j-1) == '>') { - build.delete(j, j+3); - if(build.charAt(j) == '<') { - j = build.indexOf("%"); - } - } else { - j = build.indexOf("%", j+1); - } - } - parsed = build.toString(); - //ends here - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - return factory.newDocumentBuilder().parse(new InputSource(new StringReader(parsed))); - } -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/Notification.java b/org.glite.lb.client-java/src/org/glite/lb/Notification.java deleted file mode 100644 index 326ab70..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/Notification.java +++ /dev/null @@ -1,252 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ - -package org.glite.lb; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; -import java.rmi.RemoteException; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.util.Calendar; -import java.util.Date; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.rpc.holders.CalendarHolder; -import org.glite.jobid.Jobid; -import org.glite.lb.SSL; -import org.glite.wsdl.services.lb.LoggingAndBookkeepingPortType; -import org.glite.wsdl.types.lb.JobFlagsValue; -import org.glite.wsdl.types.lb.JobStatus; -import org.glite.wsdl.types.lb.QueryConditions; -import org.xml.sax.SAXException; - -/** - * This class handles all communication comming from the client toward the server. - * it uses methods generated from .wsdl description files. - * note that each instance of this class is dedicated to a single port. Different - * port means a new instance has to be created - * - * @author Kopac - */ -public class Notification { - - private int port = 0; - private Socket socket = null; - private static String keyStore; - private String notifId; - private LoggingAndBookkeepingPortType stub; - private LBCredentials lbCredent; - - /** - * constructor sets the local port number - * - * @param port number of the local port the notification is bound to - * @param lbCredent instance of class that handles SSL authentication - */ - public Notification(int port, LBCredentials lbCredent) { - this.port = port; - this.lbCredent = lbCredent; - } - - /** - * a private method used to create a unique ID for a new notification - * - * @param host hostname - * @return String containing the unique ID - */ - private String makeId(String host) { - StringBuilder returnString = new StringBuilder(); - returnString.append(host); - Jobid jobid = new Jobid(returnString.toString(), port); - returnString.append("/NOTIF:"); - returnString.append(jobid.getUnique()); - return returnString.toString(); - } - - /** - * returns ID of the latest received notification - * - * @return notifID - */ - public String getNotifid() { - return notifId; - } - - /** - * private method used to recover LB server address from a notif ID - * - * @param notifId notif ID - * @return server address - */ - private String getServer(String notifId) { - StringBuilder ret = new StringBuilder(notifId.split("/")[2]); - char[] ch = new char[]{ret.charAt(ret.length()-1)}; - int i = Integer.parseInt(new String(ch)) + 3; - ret.replace(ret.length()-1, ret.length()-1, new String()+i); - ret.insert(0, "https://"); - return ret.toString(); - } - - /** - * this method sends a request to the server, to create a new notification. - * it's not necessary to provide all the options for this calling, thus - * some of the parameters can be null. in that case, the option they correspond to - * is not used. - * - * @param server a String containing the server address (e.g. https://harad.ics.muni.cz:9553). - * can't be null - * @param conditions an array of QueryConditions, may contain all the possible - * conditions for the new notification. can't be null - * @param flags an array of JobFlagsValue, may contain all the possible flags - * and their values for the new notification. - * @param date a Date containing the desired time, the notification will be valid for - * note that this option can only be used to shorten the validity span, as the server - * checks it and sets the final expiration date to a constant max, should - * the provided Date exceed it. may be null - * @return a Date holding info on how long the new notification will - * be valid for - * @throws LBException - */ - public Date newNotif(String server, QueryConditions[] conditions, JobFlagsValue[] flags, Date date) throws LBException { - try { - CalendarHolder calendarHolder = new CalendarHolder(Calendar.getInstance()); - if (date != null) { - calendarHolder.value.setTime(date); - } else { - calendarHolder.value.setTime(new Date(System.currentTimeMillis() + 86400000)); - } - stub = lbCredent.getStub(server); - String addr = "0.0.0.0:" + port; - String id = makeId(server); - stub.notifNew(id, addr, conditions, flags, calendarHolder); - notifId = id; - return calendarHolder.value.getTime(); - } catch (RemoteException ex) { - throw new LBException(ex); - } - } - - /** - * this method drops an existing notification, removing it completely - * - * @param notifId id of the notification to be dropped - * @throws LBException - */ - public void drop(String notifId) throws LBException { - try { - stub = lbCredent.getStub(getServer(notifId)); - stub.notifDrop(notifId); - } catch (RemoteException ex) { - throw new LBException(ex); - } - } - - /** - * this method is used to extend the validity of an existing notification - * - * @param notifId id of the notification to be refreshed - * @param date information about the desired validity duration of the notification - * in Date format. may be null (in this case, the maximum possible duration is used). - * @throws LBException - */ - public void refresh(String notifId, Date date) throws LBException { - try { - stub = lbCredent.getStub(getServer(notifId)); - CalendarHolder holder = new CalendarHolder(Calendar.getInstance()); - if (date != null) { - holder.value.setTime(date); - } else { - holder.value.setTime(new Date(System.currentTimeMillis() + 86400000)); - } - stub.notifRefresh(notifId, holder); - } catch (RemoteException ex) { - throw new LBException(ex); - } - } - - /** - * this method is used to bind an existing notification to a different local port - * than previously declared - * - * @param notifId id of th notification - * @param date optional attribute, can be used to refresh the notification - * @return length of the validity duration of the notification in Date format - * @throws LBException - */ - public Date bind(String notifId, Date date) throws LBException { - try { - stub = lbCredent.getStub(getServer(notifId)); - String host = InetAddress.getLocalHost().getHostName() + ":" + port; - CalendarHolder holder = new CalendarHolder(Calendar.getInstance()); - if (date != null) { - holder.value.setTime(date); - } else { - holder.value.setTime(new Date(System.currentTimeMillis() + 86400000)); - } - stub.notifBind(notifId, host, holder); - return holder.value.getTime(); - } catch (RemoteException ex) { - throw new LBException(ex); - } catch (UnknownHostException ex) { - throw new LBException(ex); - } - } - - /** - * this method is used to tell the client to start listening for incomming - * connections on the local port, with the specified timeout - * - * @param timeout read timeout - * @return comprehensible information, pulled from the received message - * @throws LBException - */ - public JobStatus receive(int timeout) throws LBException { - SSL ssl = new SSL(); - ssl.setCredentials(lbCredent); - ILProto receiver = null; - String received = null; - try { - if(socket == null) { - socket = ssl.accept(port, timeout); - } - receiver = new ILProto(socket); - if((received = receiver.receiveMessage()) == null) { - socket = ssl.accept(port, timeout); - receiver = new ILProto(socket); - received = receiver.receiveMessage(); - } - receiver.sendReply(0, 0, "success"); - NotifParser parser = new NotifParser(received); - notifId = parser.getNotifId(); - return parser.getJobInfo(); - } catch (IOException ex) { - throw new LBException(ex); - } catch (ParserConfigurationException ex) { - throw new LBException(ex); - } catch (SAXException ex) { - throw new LBException(ex); - } - } -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/SSL.java b/org.glite.lb.client-java/src/org/glite/lb/SSL.java deleted file mode 100644 index fcf4c0e..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/SSL.java +++ /dev/null @@ -1,122 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -import javax.net.ssl.*; -import java.net.SocketException; -import java.io.*; -import java.net.InetSocketAddress; -import java.net.Socket; - -public class SSL { - - - - SSLContext sctx; - SSLSocket client; - SSLServerSocket server; - SSLSession sess; - LBCredentials creds; - - void init_ctx() throws LBException { - if (sctx == null) { - if (creds == null) throw new NullPointerException("credentials must be specfied"); - - sctx = creds.getSSLContext(); - } - } - - public void setCredentials(LBCredentials c) { - creds = c; - } - - public Socket connect(String host,int port,int timeout) throws LBException { - init_ctx(); - - try { - client = (SSLSocket) sctx.getSocketFactory().createSocket(); - - client.setEnabledProtocols(new String[]{"SSLv3"}); - client.setUseClientMode(true); - client.setSoTimeout(timeout); //read timeout - - client.connect(new InetSocketAddress(host, port), timeout); //connect timeout - client.startHandshake(); - - sess = client.getSession(); - if (sess == null) { - throw new NullPointerException("null session"); - } - } - catch (IOException e) { throw new LBException(e); } - - return client; - //return new PrintStream(client.getOutputStream(),false); - } - - public Socket accept(int port,int timeout) throws LBException - { - SSLSocket conn; - init_ctx(); - - try { - server = (SSLServerSocket) sctx.getServerSocketFactory().createServerSocket(); - - server.setEnabledProtocols(new String[]{"SSLv3"}); - server.setSoTimeout(timeout); - - server.bind(new InetSocketAddress(port)); - - conn = (SSLSocket) server.accept(); - } - catch (IOException e) { throw new LBException(e); } - - return conn; - } - - public void close() throws LBException - { - try { - client.close(); - } - catch (IOException e) { throw new LBException(e); } - } - - private static String slashDN(String dn) { - String f[] = dn.split(","); - int i; - String out = new String(); - - /* XXX: proxy */ - for (i=f.length-1; i>=0 && f[i].indexOf("=proxy") == -1; i--) - out += "/" + f[i]; - - return out; - } - - public String myDN() - { - java.security.cert.Certificate[] cert = sess.getLocalCertificates(); - java.security.cert.X509Certificate xcert = - (java.security.cert.X509Certificate) cert[0]; - - return slashDN(xcert.getSubjectX500Principal().getName()); - } - - -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/SSLSend.java b/org.glite.lb.client-java/src/org/glite/lb/SSLSend.java deleted file mode 100644 index e3e3c33..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/SSLSend.java +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -import java.io.IOException; -import java.io.PrintStream; -import java.security.*; -import java.net.Socket; - -/** - * This class opens secure connection using SSLv3 and then sends message to set - * address. - * - * @author Pavel Piskac - */ -public class SSLSend { - - private static final String EDG_WLL_LOG_SOCKET_HEADER = "DGLOG"; - - /** - * This method is used to send messages using a secure socket. - * - * @param keyStoreSender path to user's certificate - * @param host host name - * @param port port number - * @param timeout connection timeout - * @param message message which will be send - */ - public void send(LBCredentials cred, String host, - int port, int timeout, String message) - throws LBException - { - - try { - SSL lbsock = new SSL(); - - lbsock.setCredentials(cred); - Socket sock = lbsock.connect(host,port,timeout); - PrintStream s = new PrintStream(sock.getOutputStream(),false); - - s.print(EDG_WLL_LOG_SOCKET_HEADER); - - message = message.replaceFirst("DG.LLLID=[0-9]* ", ""); - message = message.replaceFirst("DG.USER=\\x22[a-zA-Z ]*\\x22 ", ""); - - int messageSize = message.length() + 2; - byte revertedInt[] = new byte[4]; - revertedInt[0] = (byte) (messageSize % 256); - messageSize >>= 8; - revertedInt[1] = (byte) (messageSize % 256); - messageSize >>= 8; - revertedInt[2] = (byte) (messageSize % 256); - messageSize >>= 8; - revertedInt[3] = (byte) (messageSize); - - s.write(revertedInt,0,4); - s.print(message + '\n' + '\0'); - s.flush(); - s.close(); - } - catch (IOException e) { - throw new LBException(e); - } - } -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/SeqCode.java b/org.glite.lb.client-java/src/org/glite/lb/SeqCode.java deleted file mode 100644 index 1cfd673..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/SeqCode.java +++ /dev/null @@ -1,165 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -/** - * This class represents sequence code. - * - * @author Pavel Piskac (173297@mail.muni.cz) - * @version 9. 4. 2008 - */ -public class SeqCode { - - public static final int NORMAL = 1; - public static final int DUPLICATE = 11; - public static final int PBS = 2; - public static final int CONDOR = 4; - public static final int CREAM = 4; - public static final int CREAMWMS = 5; - - private int[] seqCode = {0, 0, 0, 0, 0, 0, 0, 0, 0}; - private int type = 0; - private String cream_code; - - /** - * Empty constructor which creates new instance of SeqCode with all values - * equal 0 - */ - public SeqCode() { - } - - /** - * Constructor which creates new instance of SeqCode with values set by user - * in input attribute - * - * @param seqCodeString - */ - public SeqCode(int type,String seqCodeString) { - getSeqCodeFromString(type,seqCodeString); - } - - /** - * This method increments one specific part of sequence code given by part attribute - * - * @param part part of sequence number which will be increased - */ - public void incrementSeqCode(Sources src) { - int part = src.source; - switch (type) { - case NORMAL: - case DUPLICATE: - if (src == null) - throw new IllegalArgumentException("SeqCode part"); - seqCode[part-1]++; - break; - case CREAMWMS: - if (src == null) - throw new IllegalArgumentException("SeqCode part"); - seqCode[src.LRMS-1] += 1000; //XXX hardcoded to add 1000 to LRMS when WMS jobs goes through CREAM - break; - default: break; - } - } - - /** - * Converts string representation of sequence code to format which is used - * in this class. - * Insert sequence codes in format: - * UI=000000:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000 - * @param seqCodeString - */ - public void getSeqCodeFromString(int type,String seqCodeString) { - switch (type) { - case NORMAL: - case DUPLICATE: - case CREAMWMS: - if (!seqCodeString.matches("UI=\\d{1,}:NS=\\d{1,}:WM=\\d{1,}:BH=\\d{1,}:" + - "JSS=\\d{1,}:LM=\\d{1,}:LRMS=\\d{1,}:APP=\\d{1,}:LBS=\\d{1,}")) { - throw new IllegalArgumentException("this is not correct sequence code: " + seqCodeString); - } - - int currentPosition = 0; - int equalsPosition = 0; - int colonPosition = 0; - for (int i = 0; i <= 8; i++) { - equalsPosition = seqCodeString.indexOf('=', currentPosition); - if (i == 8) { - colonPosition = seqCodeString.length(); - } else { - colonPosition = seqCodeString.indexOf(':', currentPosition); - } - seqCode[i] = (new Integer(seqCodeString.substring(equalsPosition+1, colonPosition))).intValue(); - currentPosition = colonPosition + 1; - } - break; - case CREAM: - cream_code = seqCodeString; - break; - default: throw new IllegalArgumentException("unsupported seqcode type " + type); - } - this.type = type; - } - - public String toString() { - switch (type) { - case NORMAL: - case DUPLICATE: - case CREAMWMS: - String tmp = Integer.toString(seqCode[0]); - String output = "UI="; - output += "000000".substring(0, 6 - tmp.length ()) + tmp; - output += ":"; - output += "NS="; - tmp = Integer.toString(seqCode[1]); - output += "0000000000".substring(0, 10 - tmp.length ()) + tmp; - output += ":"; - output += "WM="; - tmp = Integer.toString(seqCode[2]); - output += "0000000000".substring(0, 6 - tmp.length ()) + tmp; - output += ":"; - output += "BH="; - tmp = Integer.toString(seqCode[3]); - output += "0000000000".substring(0, 10 - tmp.length ()) + tmp; - output += ":"; - output += "JSS="; - tmp = Integer.toString(seqCode[4]); - output += "0000000000".substring(0, 6 - tmp.length ()) + tmp; - output += ":"; - output += "LM="; - tmp = Integer.toString(seqCode[5]); - output += "0000000000".substring(0, 6 - tmp.length ()) + tmp; - output += ":"; - output += "LRMS="; - tmp = Integer.toString(seqCode[6]); - output += "0000000000".substring(0, 6 - tmp.length ()) + tmp; - output += ":"; - output += "APP="; - tmp = Integer.toString(seqCode[7]); - output += "0000000000".substring(0, 6 - tmp.length ()) + tmp; - output += ":"; - output += "LBS="; - tmp = Integer.toString(seqCode[8]); - output += "0000000000".substring(0, 6 - tmp.length ()) + tmp; - return output; - case CREAM: - return cream_code; - default: - throw new IllegalArgumentException("unitialized seqcode"); - } - } -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/ServerConnection.java b/org.glite.lb.client-java/src/org/glite/lb/ServerConnection.java deleted file mode 100644 index f99f1f2..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/ServerConnection.java +++ /dev/null @@ -1,536 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -package org.glite.lb; - -import holders.StringArrayHolder; -import java.rmi.RemoteException; -import java.util.ArrayList; -import java.util.List; -import org.apache.axis.client.Stub; -import org.glite.jobid.Jobid; -import org.glite.lb.Event; -import org.glite.lb.Level; -import org.glite.wsdl.services.lb.LoggingAndBookkeepingPortType; -import org.glite.wsdl.types.lb.JobFlagsValue; -import org.glite.wsdl.types.lb.JobStatus; -import org.glite.wsdl.types.lb.QueryConditions; -import org.glite.wsdl.types.lb.holders.JobStatusArrayHolder; - -/** - * This class serves for obtaining data from the bookkeeping - * server. - * The L&B service queries come in two flavors: - *
  1. conjunctive query, as in (cond1) or (cond2)
  2. - *
  3. conjunction of disjunctive queries, as in ( (cond1) - * or (cond2) ) and ( (cond3) or (cond4) )
- * 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. - * - * @author Tomas Kramec, 207545@mail.muni.cz - */ -public class ServerConnection { - - private String queryServerAddress; - private int queryJobsLimit=0; - private int queryEventsLimit=0; - private QueryResultsFlag queryResultsFlag = QueryResultsFlag.NONE; - private Level eventLogLevel = Level.LEVEL_SYSTEM; - private LoggingAndBookkeepingPortType queryServer; - private LBCredentials lbCredent; - - - /** - * This enum represents flag to indicate handling of too large results. - * In case the result limit is reached: - *
    - *
  1. NONE - means no results are returned at all.
  2. - *
  3. LIMITED - means a result contains at most limit items.
  4. - *
  5. ALL - means all results are returned withouth any limitation.
  6. - *
- */ - public enum QueryResultsFlag { - /** - * No results are returned at all. - */ - NONE, - /** - * Result contains at most limit items. Limits for job and event - * results can be set by calling appropriate method on the ServerConnection - * instance. - */ - LIMITED, - /** - * Results are returned withouth any limitation. - */ - ALL - } - - /** - * Constructor initializes the context and - * directs new instance to query the given bookkeping server. - * - * @param server String containing the server address (e.g. https://harad.ics.muni.cz:9453). - * @param lbCredent instance of class that holds credentials for SSL authentication - */ - public ServerConnection(String server, LBCredentials lbCredent) throws LBException { - if (server == null) throw new IllegalArgumentException("Server cannot be null"); - if (lbCredent == null) throw new IllegalArgumentException("Credentials cannot be null"); - - this.lbCredent = lbCredent; - setQueryServerAddress(server); - setQueryTimeout(120); - } - - /** - * Set bookkeeping server. - * Directs the instance to query the given bookkeping server. - * - * @param server String containing the server address (e.g. https://harad.ics.muni.cz:9553). - */ - public void setQueryServerAddress(String server) throws LBException { - if (server == null) throw new IllegalArgumentException("Server cannot be null"); - - queryServer = lbCredent.getStub(server); - queryServerAddress = server; - - } - - /** - * Get address of the bookkeeping server. - * Returns address of the bookkeeping server this instance is - * bound to. - * - * @return Address (https://hostname:port). - */ - public String getQueryServerAddress() { - return queryServerAddress; - } - - /** - * Set query timeout. - * Sets the time interval to wait for server response. - * Default value is 120 seconds. - * - * @param time Time in seconds before the query expires. 0 means no timeout. - */ - public void setQueryTimeout(int time) { - if (time < 0 || time > 1800) - throw new IllegalArgumentException("timeout must be between 0 and 1800"); - - ((Stub) queryServer).setTimeout(time*1000); - - } - - /** - * Get query timeout. - * Returns the time interval this instance waits for server - * response. - * - * @return Number of seconds to wait. 0 means no timeout. - */ - public int getQueryTimeout() { - return ((Stub) queryServer).getTimeout()/1000; - } - - /** - * Set logging level. - * Sets the level for logging the events. - * Possible values:
    - *
  1. EMERGENCY
  2. - *
  3. ALERT
  4. - *
  5. ERROR
  6. - *
  7. WARNING
  8. - *
  9. AUTH
  10. - *
  11. SECURITY
  12. - *
  13. USAGE
  14. - *
  15. SYSTEM
  16. - *
  17. IMPORTANT
  18. - *
  19. DEBUG
  20. - *
- * Default value is SYSTEM. - * @param loggingLevel level for logging the events - */ - public void setEventLoggingLevel(Level loggingLevel) { - if (loggingLevel == null) throw new IllegalArgumentException("loggingLevel"); - - this.eventLogLevel = loggingLevel; - } - - /** - * Get logging level. - * Returns the level for logging the events. - * - * @return level value - */ - public Level getEventLoggingLevel() { - return eventLogLevel; - } - - /** - * Retrieve the set of single indexed attributes. - * 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 list returned, each element represents a query condition. - * Query attribute of the condition corresponds to the indexed attribute. - * If the query attribute is USERTAG, tagName is its name; - * if it is TIME, statName is state name. - * - * @return list of QueryConditions - * @throws LBException If some communication or server problem occurs. - */ - public List getIndexedAttrs() throws LBException { - try { - QueryConditions[] cond = queryServer.getIndexedAttrs(""); - List indexedAttrs = new ArrayList(); - for (int i = 0; i < cond.length; i++) { - indexedAttrs.add(cond[i]); - } - return indexedAttrs; - } catch (RemoteException ex) { - throw new LBException(ex); - } - } - - /** - * Retrieve hard result set size limit. This - * property is set at the server side. - * - * Returns the hard limit on the number of - * results returned by the bookkeeping server. - * - * @return Server limit. - * @throws LBException If some communication or server problem occurs. - */ - public int getServerLimit() throws LBException { - try { - return queryServer.getServerLimit(""); - } catch (RemoteException ex) { - throw new LBException(ex); - } - } - - /** - * Set the soft result set size limit. - * Sets the maximum number of results this instance is willing - * to obtain when querying for jobs. - * Default value is 0. It means no limits for results. - * - * @param jobsLimit Maximum number of results. 0 for no limit. - */ - public void setQueryJobsLimit(int jobsLimit) { - if (jobsLimit < 0) throw new IllegalArgumentException("jobsLimit"); - this.queryJobsLimit = jobsLimit; - } - - /** - * Get soft result set size limit. - * Gets the maximum number of results this instance is willing - * to obtain when querying for jobs. - * - * @return queryJobsLimit Maximum number of results. - */ - public int getQueryJobsLimit() { - return queryJobsLimit; - } - - /** - * Set the soft result set size limit. - * Sets the maximum number of results this instance is willing - * to obtain when querying for events. - * Default value is 0. It means no limits for results. - * - * @param eventsLimit Maximum number of results. 0 for no limit. - */ - public void setQueryEventsLimit(int eventsLimit) { - if (eventsLimit < 0) throw new IllegalArgumentException("eventsLimit"); - this.queryEventsLimit = eventsLimit; - } - - /** - * Get soft result set size limit. - * Gets the maximum number of results this instance is willing - * to obtain when querying for events. - * - * @return queryEventsLimit Soft limit. - */ - public int getQueryEventsLimit() { - return queryEventsLimit; - } - - /** - * Sets the flag indicating the way of handling of too large query results. - * Default is NONE. - * - * @param flag One of NONE, LIMITED or ALL. - */ - public void setQueryResultsFlag(QueryResultsFlag flag) { - if (flag == null) throw new IllegalArgumentException("flag"); - - queryResultsFlag = flag; - } - - /** - * Gest the flag indicating the way of handling of too large query results. - * - * @return queryResultsFlag - */ - public QueryResultsFlag getQueryResultsFlag() { - return queryResultsFlag; - } - - /** - * Retrieve all events satisfying the conjunctive-disjunctive - * query records. - * Returns all events belonging to the jobs specified by - * jobCond and satisfying queryCond. The - * conditions are given in conjunctive-disjunctive form - * ((cond1 OR cond2 OR ...) AND ...) - * - * @param jobCond List of conditions on jobs. - * @param eventCond List of coditions on events. - * @return eventList List of Event objects representing L&B events. - * @throws LBException If some communication or server problem occurs. - */ - public List queryEvents(List jobCond, - List eventCond) throws LBException { - - if (jobCond == null) throw new IllegalArgumentException("jobCond cannot be null"); - if (eventCond == null) throw new IllegalArgumentException("eventCond cannot be null"); - - org.glite.wsdl.types.lb.Event[] events = null; - try { - events = queryServer.queryEvents(jobCond.toArray(new QueryConditions[jobCond.size()]), eventCond.toArray(new QueryConditions[eventCond.size()])); - } catch (RemoteException ex) { - throw new LBException(ex); - } - - List eventList= new ArrayList(); - - if (events!= null) { - int queryResults; - //if the events limit is reached - if (queryEventsLimit!=0 && events.length > queryEventsLimit) { - queryResults = getResultSetSize(queryEventsLimit, events.length); - } else queryResults = events.length; - - EventConvertor convertor = new EventConvertor(); - for (int i=0;i queryJobs(List query) throws LBException { - if (query == null) throw new IllegalArgumentException("query cannot be null"); - - StringArrayHolder jobHolder = new StringArrayHolder(); - try { - queryServer.queryJobs(query.toArray(new QueryConditions[query.size()]), new JobFlagsValue[]{}, jobHolder, new JobStatusArrayHolder()); - } catch (RemoteException ex) { - throw new LBException(ex); - } - - List jobList = new ArrayList(); - - if (jobHolder.value!= null) { - int queryResults; - int jobsCount = jobHolder.value.length; - //if the jobs limit is reached - if (queryJobsLimit!=0 && jobsCount > queryJobsLimit) { - queryResults = getResultSetSize(queryJobsLimit, jobsCount); - } else queryResults = jobsCount; - - for (int i=0;i queryJobStates(List query, - JobFlagsValue[] flags) throws LBException { - if (query == null) throw new IllegalArgumentException("query cannot be null"); - - JobStatusArrayHolder jobStatusHolder = new JobStatusArrayHolder(); - try { - queryServer.queryJobs(query.toArray(new QueryConditions[query.size()]), flags, new StringArrayHolder(), jobStatusHolder); - } catch (RemoteException ex) { - throw new LBException(ex); - } - - List jobStates= new ArrayList(); - - if (jobStatusHolder.value!= null) { - int queryResults; - int jobsCount = jobStatusHolder.value.length; - //if the jobs limit is reached - if (queryJobsLimit!=0 && jobsCount > queryJobsLimit) { - queryResults = getResultSetSize(queryJobsLimit, jobsCount); - } else queryResults = jobsCount; - - for (int i=0;i userJobStates() throws LBException { - JobStatusArrayHolder jobStatusHolder = new JobStatusArrayHolder(); - try { - queryServer.userJobs(new StringArrayHolder(), jobStatusHolder); - } catch (RemoteException ex) { - throw new LBException(ex); - } - - List jobStates= new ArrayList(); - - if (jobStatusHolder.value!= null) { - int queryResults; - int jobsCount = jobStatusHolder.value.length; - //if the jobs limit is reached - if (queryJobsLimit!=0 && jobsCount > queryJobsLimit) { - queryResults = getResultSetSize(queryJobsLimit, jobsCount); - } else queryResults = jobsCount; - - for (int i=0;i userJobs() throws LBException { - StringArrayHolder jobHolder = new StringArrayHolder(); - try { - queryServer.userJobs(jobHolder, new JobStatusArrayHolder()); - } catch (RemoteException ex) { - throw new LBException(ex); - } - - List jobs= new ArrayList(); - - if (jobHolder.value!= null) { - int queryResults; - int jobsCount = jobHolder.value.length; - //if the jobs limit is reached - if (queryJobsLimit!=0 && jobsCount > queryJobsLimit) { - queryResults = getResultSetSize(queryJobsLimit, jobsCount); - } else queryResults = jobsCount; - - for (int i=0;i 11) - throw new IllegalArgumentException("lb.Source"); - } - - public Sources(int source) { - check(source); - this.source = source; - } - - public String toString() { - return names[source]; - } -} diff --git a/org.glite.lb.client-java/src/org/glite/lb/Timeval.java b/org.glite.lb.client-java/src/org/glite/lb/Timeval.java deleted file mode 100644 index 4d07d3c..0000000 --- a/org.glite.lb.client-java/src/org/glite/lb/Timeval.java +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.glite.lb; - -/** - * This class represents the timestamp in this form: tvSec.tvUsec. - * It consists of two parts: - *
    - *
  1. tvSec - represents time in seconds
  2. - *
  3. tvUsec - represents time in microseconds
  4. - *
- * - * For example: 1240415967.234999 - * @author Tomas Kramec, 207545@mail.muni.cz - */ -public class Timeval { - - private long tvSec; - private long tvUsec; - - public Timeval() { - } - - /** - * Creates an instance of Timeval. - * - * @param tvSec in seconds - * @param tvUsec in microseconds - */ - public Timeval(long tvSec, long tvUsec) { - this.tvSec = tvSec; - this.tvUsec = tvUsec; - } - - - /** - * Gets the tvSec value for this Timeval. - * - * @return tvSec in seconds - */ - public long getTvSec() { - return tvSec; - } - - - /** - * Sets the tvSec value for this Timeval. - * - * @param tvSec in seconds - */ - public void setTvSec(long tvSec) { - this.tvSec = tvSec; - } - - - /** - * Gets the tvUsec value for this Timeval. - * - * @return tvUsec in microseconds - */ - public long getTvUsec() { - return tvUsec; - } - - - /** - * Sets the tvUsec value for this Timeval. - * - * @param tvUsec in microseconds - */ - public void setTvUsec(long tvUsec) { - this.tvUsec = tvUsec; - } -} diff --git a/org.glite.lb.client-java/src_c/Makefile b/org.glite.lb.client-java/src_c/Makefile deleted file mode 100755 index a9cc9e3..0000000 --- a/org.glite.lb.client-java/src_c/Makefile +++ /dev/null @@ -1,34 +0,0 @@ --include ../../Makefile.inc - -CC=gcc -PATH_TO_JAVA=${JAVA_HOME} - -OS=$(shell uname | tr '[:upper:]' '[:lower:]') - -# when there is a system prefix, we are probably working with java from GCC, -# with java headers already in default search paths -ifeq (${PATH_TO_JAVA},/usr) -JDK_CPPFLAGS= -else -JDK_CPPFLAGS=-I${PATH_TO_JAVA}/include/$(OS) -endif - -LIB=libglite_lb_sendviasocket.la -OBJ=send_via_socket.lo - -VPATH=${topdir}/src_c - -compile: ${LIB} - -${LIB}: ${OBJ} - libtool --mode=link ${CC} -rpath ${PREFIX}${prefix}/${libdir} -o $@ ${OBJ} -lm - -%.lo: %.c - libtool --mode=compile ${CC} -I.. -I${PATH_TO_JAVA}/include ${JDK_CPPFLAGS} -c $< - -install: compile - -mkdir -p ${DESTDIR}${PREFIX}${prefix}/${libdir} - libtool --mode=install install -m 755 ${LIB} ${DESTDIR}${PREFIX}${prefix}/${libdir} - -clean: - rm -rf ${OBJ} .libs ${LIB} diff --git a/org.glite.lb.client-java/src_c/send_via_proxy.c b/org.glite.lb.client-java/src_c/send_via_proxy.c deleted file mode 100755 index b8e68ee..0000000 --- a/org.glite.lb.client-java/src_c/send_via_proxy.c +++ /dev/null @@ -1,297 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - *---------------------------------------------------------------------- - * Open a GSS connection to local-logger, send already formatted ULM string - * and get answer back from local-logger - * \brief connect to local-logger, send message and get answer back - * \param[in,out] ctx context to work with, - * \param[in] logline formated ULM string - *---------------------------------------------------------------------- - */ -int edg_wll_DoLogEvent( - edg_wll_Context ctx, - edg_wll_LogLine logline) -{ - int ret = 0, answer = EAGAIN; - int conn; - - edg_wll_ResetError(ctx); - memset(&conn,0,sizeof(conn)); - - /* connect to local-logger */ - if ((ret = edg_wll_log_connect(ctx,&conn))) { - fprintf(stderr, "edg_wll_log_connect error"); - goto edg_wll_DoLogEvent_end; - } - - /* send message */ - if ((ret = edg_wll_log_write(ctx,conn,logline)) == -1) { - fprintf(stderr, "edg_wll_log_write error"); - goto edg_wll_DoLogEvent_end; - } - - /* get answer */ - if ((ret = edg_wll_log_read(ctx,conn)) == -1) { - fprintf(stderr, "edg_wll_log_read error"); - } else { - answer = edg_wll_Error(ctx, NULL, NULL); - } - -edg_wll_DoLogEvent_end: - if (ret) edg_wll_log_close(ctx,conn); - - return 0; -} - -/** - *---------------------------------------------------------------------- - * connect to locallogger - *---------------------------------------------------------------------- - */ -int edg_wll_log_connect(edg_wll_Context ctx, int *conn) -{ - int ret, answer=0, index; - char *my_subject_name = NULL; - edg_wll_GssStatus gss_stat; - - //edg_wll_ResetError(ctx); - //edg_wll_poolLock(); - - /* check if connection already in pool */ - if ( (index = ConnectionIndex(ctx, ctx->p_destination, ctx->p_dest_port)) == -1 ) { - if (ctx->connections->connOpened == ctx->connections->poolSize) - if (ReleaseConnection(ctx, NULL, 0)) - goto edg_wll_log_connect_end; - index = AddConnection(ctx, ctx->p_destination, ctx->p_dest_port); - if (index < 0) { - edg_wll_SetError(ctx,EAGAIN,"connection pool size exceeded"); - goto edg_wll_log_connect_end; - } -#if 0 - /* acquire gss credentials */ - ret = edg_wll_gss_acquire_cred_gsi( - ctx->p_proxy_filename ? ctx->p_proxy_filename : ctx->p_cert_filename, - ctx->p_proxy_filename ? ctx->p_proxy_filename : ctx->p_key_filename, - &ctx->connections->connPool[index].gsiCred, &my_subject_name, &gss_stat); - /* give up if unable to acquire prescribed credentials, otherwise go on anonymously */ - if (ret && ctx->p_proxy_filename) { - edg_wll_SetErrorGss(ctx, "edg_wll_gss_acquire_cred_gsi(): failed to load GSI credentials", &gss_stat); - goto edg_wll_log_connect_err; - } - /* gss_connect */ - if (ctx->connections->connPool[index].gss.context == GSS_C_NO_CONTEXT) { - - /* acquire gss credentials */ - ret = edg_wll_gss_acquire_cred_gsi( - ctx->p_proxy_filename ? ctx->p_proxy_filename : ctx->p_cert_filename, - ctx->p_proxy_filename ? ctx->p_proxy_filename : ctx->p_key_filename, - &ctx->connections->connPool[index].gsiCred, &my_subject_name, &gss_stat); - /* give up if unable to acquire prescribed credentials, otherwise go on anonymously */ - if (ret && ctx->p_proxy_filename) { - edg_wll_SetErrorGss(ctx, "edg_wll_gss_acquire_cred_gsi(): failed to load GSI credentials", &gss_stat); - goto edg_wll_log_connect_err; - } - if ((answer = edg_wll_gss_connect( - ctx->connections->connPool[index].gsiCred, - ctx->connections->connPool[index].peerName, - ctx->connections->connPool[index].peerPort, - &ctx->p_tmp_timeout, - &ctx->connections->connPool[index].gss, - &gss_stat)) < 0) { - answer = handle_gss_failures(ctx,answer,&gss_stat,"edg_wll_gss_connect()"); - goto edg_wll_log_connect_err; - } - goto edg_wll_log_connect_end; - } else goto edg_wll_log_connect_end; - -edg_wll_log_connect_err: - if (index >= 0) CloseConnection(ctx, &index); - index = -1; - -edg_wll_log_connect_end: - if (index >= 0) edg_wll_connectionTryLock(ctx, index); - if (my_subject_name) free(my_subject_name); - - edg_wll_poolUnlock(); - - *conn = index; - return answer; -} - -/** - *---------------------------------------------------------------------- - * close connection to locallogger - *---------------------------------------------------------------------- - */ -int edg_wll_log_close(edg_wll_Context ctx, int conn) -{ - int ret = 0; - - if (conn == -1) return 0; - ret = CloseConnection(ctx,&conn); - edg_wll_connectionUnlock(ctx,conn); - return ret; -} - -/** - *---------------------------------------------------------------------- - * write/send to locallogger - *---------------------------------------------------------------------- - */ -int edg_wll_log_write(edg_wll_Context ctx, int conn, edg_wll_LogLine logline) -{ - char header[EDG_WLL_LOG_SOCKET_HEADER_LENGTH+1]; - int err; - int answer; - size_t count,sent; - int size; - u_int8_t size_end[4]; - edg_wll_GssStatus gss_code; - - errno = err = answer = count = sent = 0; - size = strlen(logline)+1; - size_end[0] = size & 0xff; size >>= 8; - size_end[1] = size & 0xff; size >>= 8; - size_end[2] = size & 0xff; size >>= 8; - size_end[3] = size; - size = strlen(logline)+1; - - edg_wll_ResetError(ctx); - - sprintf(header,"%s",EDG_WLL_LOG_SOCKET_HEADER); - header[EDG_WLL_LOG_SOCKET_HEADER_LENGTH]='\0'; - if ((err = edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, header, EDG_WLL_LOG_SOCKET_HEADER_LENGTH, &ctx->p_tmp_timeout, &count, &gss_code)) < 0) { - switch (answer = handle_gss_failures(ctx,err,&gss_code,"edg_wll_gss_write_full()")) { - case ENOTCONN: - edg_wll_log_close(ctx,conn); - if (edg_wll_log_connect(ctx,&conn) || - edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, header, EDG_WLL_LOG_SOCKET_HEADER_LENGTH, &ctx->p_tmp_timeout, &count, &gss_code) < 0) { - edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending header"); - return -1; - } - break; - case 0: - break; - default: - edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending header"); - return -1; - } - } - sent += count; - - count = 0; - if ((err = edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, size_end, 4, &ctx->p_tmp_timeout, &count, &gss_code)) < 0) { - switch (answer = handle_gss_failures(ctx,err,&gss_code,"edg_wll_gss_write_full()")) { - case ENOTCONN: - edg_wll_log_close(ctx,conn); - if (edg_wll_log_connect(ctx,&conn) || - edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, size_end, 4, &ctx->p_tmp_timeout, &count, &gss_code) < 0) { - edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending message size"); - return -1; - } - break; - case 0: - break; - default: - edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending message size"); - return -1; - - } - } - sent += count; - - count = 0; - if (( err = edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, logline, size, &ctx->p_tmp_timeout, &count, &gss_code)) < 0) { - switch (answer = handle_gss_failures(ctx,err,&gss_code,"edg_wll_gss_write_full()")) { - case ENOTCONN: - edg_wll_log_close(ctx,conn); - if (edg_wll_log_connect(ctx,&conn) || - edg_wll_gss_write_full(&ctx->connections->connPool[conn].gss, logline, size, &ctx->p_tmp_timeout, &count, &gss_code) < 0) { - edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending message"); - return -1; - } - break; - case 0: - break; - default: - edg_wll_UpdateError(ctx,answer,"edg_wll_log_write(): error sending message"); - return -1; - } - } - sent += count; - - return sent; -} - -/** - *---------------------------------------------------------------------- - * read/receive from locallogger - *---------------------------------------------------------------------- - */ -int edg_wll_log_read(edg_wll_Context ctx, int conn) -{ - int err; - int answer; - u_int8_t answer_end[4]; - size_t count; - edg_wll_GssStatus gss_code; - - errno = err = answer = count = 0; - - edg_wll_ResetError(ctx); - - count = 0; - if ((err = edg_wll_gss_read_full(&ctx->connections->connPool[conn].gss, answer_end, 4, &ctx->p_tmp_timeout, &count, &gss_code)) < 0 ) { - switch (answer = handle_gss_failures(ctx,err,&gss_code,"edg_wll_gss_read_full()")) { - case ENOTCONN: - edg_wll_log_close(ctx,conn); - if (edg_wll_log_connect(ctx,&conn) || - edg_wll_gss_read_full(&ctx->connections->connPool[conn].gss, answer_end, 4, &ctx->p_tmp_timeout, &count, &gss_code) < 0 ) { - edg_wll_UpdateError(ctx,answer,"edg_wll_log_read(): error reading answer from local-logger"); - return -1; - } - break; - case 0: - break; - default: - edg_wll_UpdateError(ctx,answer,"edg_wll_log_read(): error reading answer from local-logger"); - return -1; - } - } - answer = answer_end[3]; answer <<=8; - answer |= answer_end[2]; answer <<=8; - answer |= answer_end[1]; answer <<=8; - answer |= answer_end[0]; - edg_wll_SetError(ctx,answer,"edg_wll_log_read(): answer read from locallogger"); - - return count; -} diff --git a/org.glite.lb.client-java/src_c/send_via_socket.c b/org.glite.lb.client-java/src_c/send_via_socket.c deleted file mode 100755 index 48db5af..0000000 --- a/org.glite.lb.client-java/src_c/send_via_socket.c +++ /dev/null @@ -1,219 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "org_glite_lb_ContextIL.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;\ - }\ -} - - -/*! - * Write to socket - * Needn't write entire buffer. Timeout is applicable only for non-blocking - * connections - * \param sock IN: connection to work with - * \param buf IN: buffer - * \param bufsize IN: max size to write - * \param timeout INOUT: max time allowed for operation, remaining time on return - * \retval bytes written (>0) on success - * \retval -1 on write error - */ -static ssize_t -edg_wll_socket_write( - int sock, - const void *buf, - size_t bufsize, - struct timeval *timeout) -{ - ssize_t len = 0; - fd_set fds; - struct timeval to, before, after; - - - if ( timeout ) { - memcpy(&to, timeout, sizeof to); - gettimeofday(&before, NULL); - } - len = write(sock, buf, bufsize); - if ( len <= 0 && errno == EAGAIN ) { - FD_ZERO(&fds); - FD_SET(sock,&fds); - if ( select(sock+1, NULL, &fds, NULL, timeout? &to: NULL) < 0 ) { - len = -1; - } else { - len = write(sock, buf, bufsize); - } - } - if ( timeout ) { - gettimeofday(&after, NULL); - tv_sub(after, before); - tv_sub(*timeout, after); - if ( timeout->tv_sec < 0 ) { - timeout->tv_sec = 0; - timeout->tv_usec = 0; - } - } - - return len; -} - -/*! - * Write specified amount of data to socket - * Attempts to call edg_wll_socket_write() untill the entire request is satisfied - * (or times out). - * \param sock IN: connection to work with - * \param buf IN: buffer - * \param bufsize IN: max size to write - * \param timeout INOUT: max time allowed for operation, remaining time on return - * \param total OUT: bytes actually written - * \retval bytes written (>0) on success - * \retval -1 on write error - */ -static ssize_t -edg_wll_socket_write_full( - int sock, - void *buf, - size_t bufsize, - struct timeval *timeout, - ssize_t *total) -{ - ssize_t len; - *total = 0; - - while ( *total < bufsize ) { - len = edg_wll_socket_write(sock, buf+*total, bufsize-*total, timeout); - if (len < 0) return len; - *total += len; - } - - return 0; -} - -/* - * edg_wll_log_event_send - send event to the socket - * - * Returns: 0 if done properly or errno - * - */ -/*int edg_wll_log_event_send( - const char *socket_path, - long filepos, - const char *msg, - int msg_size, - int conn_attempts, - int timeout_int)*/ -/*JNIEXPORT jint JNICALL Java_org_glite_lb_ContextIL_edg_wll_log_event_send - (JNIEnv *env, - jobject jobj, - jstring socket_path_j, - jlong filepos_j, - jstring msg_j, - jint msg_size_j, - jint conn_attempts_j, - jint timeout_int_j)*/ -JNIEXPORT jint JNICALL -Java_org_glite_lb_ContextIL_sendToSocket - (JNIEnv *env, - jobject jobj, - jstring socket_path_j, - jlong filepos_j, - jstring msg_j, - jint msg_size_j, - jint conn_attempts_j, - jint timeout_int_j) - -{ - const char *socket_path = (*env)->GetStringUTFChars(env, socket_path_j, 0); - const char *msg = (*env)->GetStringUTFChars(env, msg_j, 0); - int timeout_int = (int) timeout_int_j; - //int timeout_int = 3; - long filepos = (long) filepos_j; - int msg_size = (int) msg_size_j; - int conn_attempts = (int) conn_attempts_j; - //int conn_attempts = 3; - struct timeval timeout; - timeout.tv_sec = timeout_int; - timeout.tv_usec = 0; - struct sockaddr_un saddr; - int msg_sock, - flags, - conn_timeout, i; - ssize_t count = 0; - - - if ( (msg_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) { - goto event_send_end; - } - - memset(&saddr, 0, sizeof(saddr)); - saddr.sun_family = AF_UNIX; - strcpy(saddr.sun_path, socket_path); - - if ( (flags = fcntl(msg_sock, F_GETFL, 0)) < 0 - || fcntl(msg_sock, F_SETFL, flags | O_NONBLOCK) < 0 ) { - goto cleanup; - } - - conn_timeout = floor(timeout.tv_sec/(conn_attempts + 1)); - for ( i = 0; i < conn_attempts; i++) { - if ( connect(msg_sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0 ) { - if ( errno == EISCONN ) break; - else if ((errno == EAGAIN) || (errno == ETIMEDOUT)) { - sleep(conn_timeout); - timeout.tv_sec -= conn_timeout; - continue; - } else { - goto cleanup; - } - } else break; - } - - if ( edg_wll_socket_write_full(msg_sock, &filepos, sizeof(filepos), &timeout, &count) < 0 -) { - goto cleanup; - } - - if ( edg_wll_socket_write_full(msg_sock, (void *)msg, msg_size, -&timeout, &count) < 0 ) { - goto cleanup; - } - -cleanup: - close(msg_sock); - -event_send_end: - return 0; -} diff --git a/org.glite.lb.doc/GGUS19469-reply.txt b/org.glite.lb.doc/GGUS19469-reply.txt deleted file mode 100644 index 4f66272..0000000 --- a/org.glite.lb.doc/GGUS19469-reply.txt +++ /dev/null @@ -1,158 +0,0 @@ -We are really sorry that it took us so long to reply to this GGUS -ticket, we thought that there must be a prize for the longest ticket one day. - -Seriously, we took all the comments and suggestions really -seriously and during the gLite restructuring we made all the required -changes and among others we now have a completely new documentation both -for Logging and Bookkeeping (LB) and Job Provenance (JP). - -We attach our comments inline to your initial review/request: - -> The available 'Logging and Bookkeeping User and Reference Guide' has -> several problems: -> -> General remarks : the link from the general glite doc page -> (http://glite.web.cern.ch/glite/documentation/default.asp) links to -> https://edms.cern.ch/file/571273/1/LB-guide.pdf while EDMS proposes -> https://edms.cern.ch/file/571273/2/LB-guide.pdf However both documents -> seem to be the same (even so says diff on the pdf files). Now the most -> surprising thing is that the proposed document is still a DRAFT dating -> almost 1.5 years now. Isn't that more than enough time to publish a -> final document? - -The LB documentation has been changed completely. It is now -part of the org.glite.lb.doc module and it contains four major -documents: - -- LB User's Guide (LBUG) -- LB Adminstrator's Guide (LBAG) -- LB Developer's Guide (LBDG) -- LB Test Plan (LBTP) - -The official web location for these documents is now -http://egee.cesnet.cz/en/JRA1/LB -and links to these documents were updated hopefully on all the following webs: - -http://glite.web.cern.ch/glite/documentation/default.asp -http://glite.web.cern.ch/glite/packages/R3.1/deployment/glite-LB/glite-LB.asp -http://egee-jra1-wm.mi.infn.it/egee-jra1-wm -https://twiki.cern.ch/twiki/bin/view/EGEE/Glite-LB -https://twiki.cern.ch/twiki/bin/view/EGEE/Egee3Jra1 - -The old LB User's Guide was removed from -https://edms.cern.ch/document/571273/2 - -The JP documentation is going to have a similar structure, it is now kept -in the org.glite.jp.doc module and it will be published soon. - - -> At last, the guide mentions example code (quote from p. 14 : "You can -> found this example in client module, file job_status.c."). I found an -> 'examples' dir in the glite-lb-client package, however it does not -> contain C source code but rather useless executable files!! - -The source code of all the examples is now also included in the -glite-lb-client (RPM) together with a simple Makefile so that users -can make the examples on their machines. - -> I skip the "Introduction" section. -> -> 2/ Quickstart Guide -> 2.1/ Command Line Tools -> quite OK but is missing the (C) type of the values that can be given -> to a user tag: only a string or is an integer value possible? This has -> it's importance in the following. - -LB keeps user tags only as strings, it is left on the -application level to give the values some semantics. It is now -mentioned in LBUG Section 2.3.1. - -> I think the documentation misses a description of the equivalent API. -> At least some part of the code of the CLI interface should be -> available, as in a job this duty is probably better done by the code -> itself than by some external command. - -glite-lb-logevent is now in details described in LBUG, Section -2.3, and the use-case of using this tool to log the user-tag is -described in the LBUG 2.3.1. The logging API is in details described in -LBDG together with the programming examples. - - -> 2.2/ L&B querying API -> General remarks: -> when compiling, of course header files and libraries are required. Why -> not indicate them ? what flavor of libglite_lb_client shall be used ? -> And to have some code querying an edg/lcg LB ? although stuff in this -> API is prefixed by edg_, it's not possible to query an edg/lcg LB with -> this API when linking against glite libs : error msg is 'Operation not -> supported (Protocol versions incompatible)'. I'm glad to know now but -> I would have preferred reading it in the docs. - -All this is now mentioned in LBDG Section 4. - -> Section 2.2.2, -> example 1 ("Job status", p. 13) -> It would be quite interesting to give some details about the -> edg_wll_JobStat data type and more generally about every data type -> used for returning results. Also I do not agree with "The code also -> shows a complete handling of returned errors": although it is claimed -> it uses errno values, errno variable is not used and the return codes -> do not always match the defined errno values. Hence the question : how -> to interpret these return codes, can't some details be given in the -> docs ? - -See LBDG Section 4.3.4 and above mentioned examples. - -> example 2 ("All user's jobs" p. 14) does not work: it misses the -> calling of -> edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER, my_lb_srv); -> edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER_PORT, srv_port); -> for the soft to know which LB host to query. This is needed in also -> every following example where no explicit jobid is used. If there is a -> general/convenient way to set it through config files or environment -> vars, it is not mentioned. - -Please try the new examples provided. - - -> One more thing about this example : output can be HUGE! Better mention -> it... - -Mentioned :). - -> example "querying user tags", p. 17 -> I haven't managed to get it working and after quite a few tries I'm -> still unable to query user tags I did set myself (proved by the output -> of the 'glite-lb-logevent' command, which also shows that the tag -> could be capitalized by the m/w) from some successfully -> executing/executed job. -> -> Is this code really working ? Could it be a problem linked with the LB -> or VO I'm using (I tried under 'esr' and 'dteam' VOs)? - -Please try the new examples provided. - - -> I had no more chance with example "All jobs marked as red" p. 19 and -> the event query. Is there some available code somewhere that does -> successfully query some user tag? - -Please try the new examples provided. - - -> 3/ The reference -> Hey, is it really supposed to turn out as a reference? For now, it -> looks more like an index, except that an index helps locating -> occurrences. Has the function 'edg_wll_GetServerLimit' (mentioned on -> p. 97) disappeared from the library? No libglite_lb_whatever seems to -> contain it. - -The automatically generated documentation was really unreadable, so we removed -it almost completely from the LBDG. Only a list of header files and important -API functions can be found there. - -> I can provide the full source code I used if requested. - -We would really appreciate if you could look at the documentation now -and tell us if you find it suitable and if all examples are working for -you without problems. diff --git a/org.glite.lb.doc/LICENSE b/org.glite.lb.doc/LICENSE deleted file mode 100644 index 259a91f..0000000 --- a/org.glite.lb.doc/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.lb.doc/Makefile b/org.glite.lb.doc/Makefile deleted file mode 100644 index 281d3b4..0000000 --- a/org.glite.lb.doc/Makefile +++ /dev/null @@ -1,139 +0,0 @@ -# Default values -top_srcdir=.. -stagedir=. -globalprefix=glite -lbprefix=lb -package=glite-lb-doc -version=0.0.0 -PREFIX=/opt/glite -prefix= - --include Makefile.inc --include ${top_srcdir}/project/version.properties - -version=${module.version} - -VPATH = ${top_srcdir}/src -# example source code is part of the org.glite.lb.client -EXAMPLE_SOURCE_DIR=${top_srcdir}/examples -KPATH = TEXINPUTS=".:$(EXAMPLE_SOURCE_DIR):$(VPATH)//:" -KPATHBIB = BIBINPUTS=".:$(VPATH)//:" - -LATEX = $(KPATH) latex -PDFLATEX = $(KPATH) pdflatex -BIBTEX = $(KPATHBIB) bibtex -DVIPS = $(KPATH) dvips -AT3=${stagedir}${prefix}/sbin/glite-lb-at3 -INSTALL=install - -default all: generate doc - -generate: events.tex status.tex ver.tex - -doc: LBUG.pdf LBAG.pdf LBDG.pdf LBTP.pdf LBTG.pdf - -# %.dvi: %.tex -# $(LATEX) $< -# $(BIBTEX) `basename $< .tex` -# $(LATEX) $< -# $(LATEX) $< -# -# %.ps: %.dvi -# $(DVIPS) -ta4 -o $@ $< - -%.pdf: %.tex - $(PDFLATEX) $< - $(BIBTEX) `basename $< .tex` - $(PDFLATEX) $< - $(PDFLATEX) $< - -%.tex: %.tex.T - rm -f $@ - ${AT3} $< >$@ || ( rm -f $@; false ) - chmod -w $@ >/dev/null - -ver.tex: - printf "\134def\134version{${version}}\n" > ver.tex - -stage: doc - $(MAKE) install PREFIX=${stagedir} - -check: - @echo "No test" - -install: - -mkdir -p ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version}/examples - ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version} - ( cd ${top_srcdir}/project && ${INSTALL} -m 644 ChangeLog package.description package.summary ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version} ) - ${INSTALL} -m 644 ${top_srcdir}/src/README ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version} - ${INSTALL} -m 644 LBUG.pdf ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version} - ${INSTALL} -m 644 LBAG.pdf ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version} - ${INSTALL} -m 644 LBDG.pdf ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version} - ${INSTALL} -m 644 LBTG.pdf ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version} - ${INSTALL} -m 644 LBTP.pdf ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version} -# install DG example sources - for p in ${top_srcdir}/examples/*; do \ - if [ "$$p" = "${top_srcdir}/examples/CVS" ]; then continue; fi; \ - ${INSTALL} -m 644 "$$p" "${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version}/examples"; \ - done - -clean: - rm -rvf LBUG* LBAG* LBDG* LBTP* events.tex status.tex ver.tex comment* - -distclean: - rm -rvf Makefile.inc *.spec debian/ - - -# dependencies: - -COMMON:=copyright.tex \ - definitions.tex \ - emi.cls \ - frontmatter.tex \ - lbjp.bib \ - versions.tex \ - faq.tex \ - ver.tex - -LBUG.pdf: ${COMMON} \ - LBUG.tex \ - LBUG-Abstract.tex \ - LBUG-Introduction.tex components.tex \ - LBUG-Tools.tex logevent.tex https_configuration.tex notify.tex log_usertag.tex change_acl.tex \ - LBUG-Troubleshooting.tex \ - LBUG-Appendix.tex events.tex status.tex faq.tex - -LBAG.pdf: ${COMMON} \ - LBAG.tex \ - LBAG-Abstract.tex \ - LBAG-Introduction.tex components.tex \ - https_configuration.tex \ - LBAG-Installation.tex \ - LBAG-Running.tex \ - LBAG-Troubleshooting.tex faq.tex - -LBDG.pdf: ${COMMON} \ - LBDG.tex \ - LBDG-Abstract.tex \ - LBDG-Introduction.tex \ - producer_api.tex \ - consumer_api.tex \ - notification_api.tex \ - web_services.tex - -LBTP.pdf: ${COMMON} \ - LBTP.tex \ - LBTP-Abstract.tex \ - LBTP-Introduction.tex \ - LBTP-IntegrationTests.tex \ - LBTP-Tests.tex \ - LBTP-PerfTests.tex \ - LBTP-InterTests.tex \ - LBTP-Nagios.tex - -LBTG.pdf: ${COMMON} \ - LBTG.tex \ - LBTG-Abstract.tex \ - LBAG-Troubleshooting.tex - -.PHONY: default all generate doc stage check install clean distclean doc diff --git a/org.glite.lb.doc/configure b/org.glite.lb.doc/configure deleted file mode 100755 index bcb1531..0000000 --- a/org.glite.lb.doc/configure +++ /dev/null @@ -1,2058 +0,0 @@ -#!/usr/bin/perl - -# WARNING: Don't edit this file unless it is the master copy in org.glite.lb -# -# For the purpose of standalone builds of lb/jobid/lbjp-common components -# it is copied on tagging - -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Getopt::Long; -use POSIX qw(locale_h strftime); - -my $pwd = `pwd`; chomp $pwd; -my $prefix = '/usr'; -my $stagedir = undef; -my $root = $pwd.'/stage'; -my $sysroot = ''; -my $sysconfdir; -my $localstatedir; -my $staged; -my $module; -my $thrflavour = 'gcc64dbgpthr'; -my $nothrflavour = 'gcc64dbg'; -my $mode = 'build'; -my $help = 0; -my $listmodules; -my ($version, $force_version); -my $branch; -my $output; -my $lb_tag = ''; -my $lbjp_tag = ''; -my $jp_tag = ''; -my $jobid_tag = ''; -my $libdir = getlibdir(); -my $project = 'emi'; -my $project_version; -my (%projects, %project); -my $debug = 0; -my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : ''; - -my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal/; -my @default_nodes = qw/lb px proxyrenewal nagios/; -my %enable_nodes; -my %disable_nodes; -my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1); - -my %package = ( - 'maintainer' => 'CESNET Product Teams ', - 'uploaders' => 'FrantiÅ¡ek Dvořák ', - 'url' => 'http://glite.cern.ch', - 'debian_vcs' => 'Vcs-Cvs: :pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw -Vcs-Browser: http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi', -); - -# key: internal package name (arguments, ...) -# 'pkg': pkg-config name -# 'prefix': used when pkg-config fails -my %externs = ( - cares => { - prefix => '/opt/c-ares', - pkg => 'libcares' - }, - classads => { - prefix=> '/usr', - pkg => 'classads' - }, - cppunit => { - prefix=> '/usr', - pkg => 'cppunit' - }, - expat => { - prefix=> '/usr', - pkg => 'expat' - }, - globus => { - prefix=> '/opt/globus', - pkg => 'globus-gssapi-gsi' - }, - 'myproxy-devel' => { - prefix=> '/opt/globus', - pkg => 'myproxy' - }, - 'myproxy-server' => { - prefix=> '', - }, - 'myproxy-admin' => { - prefix=> '', - }, - gsoap => { - prefix=> '/usr', - pkg => 'gsoap' - }, - gsoapxx => { - prefix=> '/usr', - pkg => 'gsoap++' - }, - mysql => { - prefix=> '/usr' - }, - 'mysql-devel' => { - prefix=> '' - }, - 'mysql-server' => { - prefix => '' - }, - voms => { - prefix => '/opt/glite', - pkg => 'voms-2.0' - }, - gridsite => { - prefix => '/opt/glite' - }, - lcas => { - prefix => '/opt/glite', - pkg => 'lcas' - }, - trustmanager => { - prefix => '/opt/glite' - }, - trustmanager_axis => { - prefix => '/opt/glite' - }, - utiljava => { - prefix=> '/opt/glite' - }, - ant => { - prefix=> '/usr' - }, - jdk => { - prefix=> '/usr/java/latest', - locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ], - }, - libtar => { - prefix=> '/usr' - }, - axis => { - prefix=> '/usr' - }, - log4c => { - prefix=> '/usr' - }, - postgresql => { - prefix=> '/usr' - }, - activemq => { - prefix=>'/opt/activemq-cpp-library', - pkg => 'activemq-cpp' - }, -); - -my %jar = ( - 'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar', - 'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar', -); - - -my %glite_prefix; -my %need_externs; -my %need_externs_type; -my %need_jars; -my %extrafull; -my %extranodmod; -my %deps; -my %deps_type; -my %buildroot; -my (%etics_externs, %etics_projects); - -# -# modules of the subsystems -# -# additional modules from $project{modules} are automatically added -# -my %lbmodules = ( - 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], - 'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/], - 'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/], - 'jp' => [ qw/client doc index primary server-common ws-interface/ ], - 'gridsite' => [ qw/apache libs commands core devel slashgrid services service-clients gsexec/ ], - 'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ], - 'canl' => [ qw/c c-devel/ ], - ); - -# -# sub-packages -# -# modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly -# -my %subpackages = ( - 'jobid.api-c-devel' => 'jobid.api-c', - 'jobid.api-cpp-devel' => 'jobid.api-cpp', - 'lbjp-common.db-devel' => 'lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'lbjp-common.log', - 'lbjp-common.maildir-devel' => 'lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'lbjp-common.trio', - 'lb.client-progs' => 'lb.client', - 'lb.client-devel' => 'lb.client', - 'lb.common-devel' => 'lb.common', - 'lb.logger-devel' => 'lb.logger', - 'lb.state-machine-devel' => 'lb.state-machine', - 'px.proxyrenewal-devel' => 'px.proxyrenewal', - 'px.proxyrenewal-progs' => 'px.proxyrenewal', - 'canl.c-devel' => 'canl.c', -); - -my @opts = ( - 'prefix:s' => \$prefix, - 'staged=s' => \$staged, - 'module=s' => \$module, - 'thrflavour:s' => \$thrflavour, - 'nothrflavour:s' => \$nothrflavour, - 'mode=s' => \$mode, - 'listmodules=s' => \$listmodules, - 'version=s' => \$force_version, - 'branch=s' => \$branch, - 'output=s' => \$output, - 'stage=s' => \$stagedir, - 'root:s' => \$root, - 'sysroot:s' => \$sysroot, - 'sysconfdir=s' => \$sysconfdir, - 'localstatedir=s' => \$localstatedir, - 'lb-tag=s' => \$lb_tag, - 'lbjp-common-tag=s' => \$lbjp_tag, - 'jp-tag=s' => \$jp_tag, - 'jobid-tag=s' => \$jobid_tag, - 'canl-tag=s' => \$canl_tag, - 'help' => \$help, - 'libdir=s' => \$libdir, - 'project=s' => \$project, - 'debug' => \$debug, -); - -for (@nodes) { - $enable_nodes{$_} = 0; - $disable_nodes{$_} = 0; - - push @opts,"disable-$_",\$disable_nodes{$_}; - push @opts,"enable-$_",\$enable_nodes{$_}; -} - -push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs; -push @opts,"with-$_=s",\$jar{$_} for keys %jar; - -my @keeparg = @ARGV; - -GetOptions @opts or die "Errors parsing command line\n"; -$prefix=~s/\/$//; -$root=~s/\/$//; -$sysroot=~s/\/$//; -if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; } -if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; } -$sysconfdir=~s/\/$//; -$localstatedir=~s/\/$//; - -$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq ''; -$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq ''; -$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq ''; - -$externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq ''; -$externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq ''; -$externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq ''; - -if ($project =~ /^([^0-9]*)(.*)$/) { - $project = $1; - $project_version = $2; -} -%project = %{$projects{$project}}; -$project_version = $project{current_version} unless $project_version; -for my $platform (keys %{$project{etics_externs}}) { - for $_ (keys %{$project{etics_externs}{$platform}}) { - $etics_externs{$platform}{$_} = $project{etics_externs}{$platform}{$_}; - } -} -reshuffle_platforms(\%etics_externs, $project{supported_platforms}); -reshuffle_platforms(\%{$project{etics_externs_devel}}, $project{supported_platforms}); -for $_ (keys %{$project{etics_projects}}) { - $etics_projects{$_} = $project{etics_projects}{$_}; -} -for $_ (keys %{$project{need_externs_aux}}) { - $need_externs_aux{$_} = $project{need_externs_aux}{$_}; -} -for my $ext (keys %need_externs_aux) { - for (@{$need_externs_aux{$ext}}) { - my ($pkg, $type) =/([^:]*)(?::(.*))?/; - $type = 'BR' unless ($type); - - push @{$need_externs{$ext}},$pkg; - $need_externs_type{$ext}->{$pkg} = $type; - } -} -if ($project eq 'emi') { - $extranodmod{lb} = 'lb.emi-lb'; - $extranodmod{px} = 'px.emi-px'; -} -for $_ (keys %{$project{modules}}) { - push @{$lbmodules{$_}},@{$project{modules}{$_}}; -} - - -if ($help) { usage(); exit 0; } - -if ($listmodules) { - my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name}; - my @m; - - if (exists $lbmodules{$listmodules}) { - @m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}}; - } else { - if ($project eq 'emi' and $project_version == 1) { - # no sub-packages in EMI-1 - } else { - for my $sub (keys %subpackages) { - push @m, $sub if ($subpackages{$sub} eq $listmodules); - } - } - } - print map $_ eq "" ? "" : "$_ ", @m; - print "\n"; - exit 0; -} - -warn "$0: --branch and --output make sense only in --mode=etics\n" - if ($output || $branch) && $mode ne 'etics'; - -my $en; -for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } - -my $dis; -for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } - -die "--enable-* and --disable-* are mutually exclusive\n" - if $en && $dis; - -die "--module cannot be used with --enable-* or --disable-*\n" - if $module && ($en || $dis); - -die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}}; - -if ($dis) { - for (@nodes) { - $enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_}); - } -} - -if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } }; - -for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } - -$stagedir = $root unless $stagedir; -$stagedir=~s/\/$// if ($stagedir); - -if ($mode eq 'build') { for my $ext (keys %externs) { - if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; } - elsif (defined $externs{$ext}{pkg}) { - my ($flag, $env, $cmd, $ret); - my $pkg = $externs{$ext}{pkg}; - my $flagname = uc $externs{$ext}{pkg}; - $flagname =~ s/-[0-9\.]*$//; - $flagname =~ y/-\+/_X/; - - print "Checking $pkg ... "; - $env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig"; - $cmd = "$env pkg-config $pkg --exists >/dev/null"; - `$cmd`; $ret = $?; - print "('$cmd' => $ret)\n" if ($debug); - if ($ret == 0) { - $externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`; - chomp $externs{$ext}{prefix}; - print "$externs{$ext}{prefix}\n"; - - $flag=`$env pkg-config $pkg --cflags`; - $externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag); - $flag=`$env pkg-config $pkg --libs`; - $externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag); - } else { - print "(using default $externs{$ext}{prefix})\n"; - } - print "\n" if ($debug); - } - elsif ($ext eq 'jdk') { - my $jdk_prefix; - - print "Looking for some caffein ... "; - if (defined $ENV{'JDK_HOME'}) { - $jdk_prefix = $ENV{'JDK_HOME'}; - print "JDK_HOME=$jdk_prefix\n"; - } elsif (defined $ENV{'JAVA_HOME'}) { - $jdk_prefix = $ENV{'JAVA_HOME'}; - print "JAVA_HOME=$jdk_prefix\n"; - } else { - foreach my $i (0..$#{$externs{$ext}{locations}}) { - if (-e $externs{$ext}{locations}[$i]) { - $jdk_prefix=$externs{$ext}{locations}[$i]; - print "(found directory $jdk_prefix)\n"; - last; - } - } - print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix); - } - $externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix); - } -} } - -if ($mode eq 'build') { - print "Writing config.status\n"; - open CONF,">config.status" or die "config.status: $!\n"; - for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') { - print CONF "$_=$ENV{$_} " if (defined $ENV{$_}); - } - print CONF "$0 @keeparg\n"; - close CONF; -} - - -my @modules; -my %aux; - -if ($module) { -# push @modules,split(/[,.]+/,$module); - push @modules,$module; -} -else { - @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); - - my $n; - - do { - local $"="\n"; - $n = $#modules; - push @modules,(map @{$deps{$_}},@modules); - - undef %aux; @aux{@modules} = (1) x ($#modules+1); - @modules = keys %aux; - } while ($#modules > $n); -} - -@aux{@modules} = (1) x ($#modules+1); -delete $aux{$_} for (split /,/,$staged); -@modules = keys %aux; - -mode_build() if $mode eq 'build'; -mode_checkout() if $mode eq 'checkout'; -mode_etics($module) if $mode eq 'etics'; - -sub mode_build { - print "\nBuilding modules: @modules\n"; - print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n"; - - my @ext = map @{$need_externs{$_}},@modules; - my @myjars = map @{$need_jars{$_}},@modules; - undef %aux; @aux{@ext} = 1; - @ext = keys %aux; - undef %aux; @aux{@myjars} = (1) x ($#myjars+1); - @myjars = keys %aux; - - print "\nRequired externals:\n"; - print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext; - print "\t$_: $jar{$_}\n" for @myjars; - for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } }; - print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; - - mkinc($_) for @modules; - - if ($module) { - print "Not creating summary Makefile\n" if $debug; - } else { - print "Creating Makefile\n"; - - open MAK,">Makefile" or die "Makefile: $!\n"; - - print MAK "all: @modules\n\n"; - print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n"; - print MAK "clean check install:\n"; - - for (@modules) { - my $full = full($_); - print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n" - } - - print MAK "\ndistclean:\n"; - - for (@modules) { - my $full = full($_); - print MAK $buildroot{$_} eq '' ? - "\tcd $full && \${MAKE} distclean\n" : - "\trm -rf $full/$buildroot{$_}\n" - } - - print MAK "\n"; - - for (@modules) { - my %ldeps; undef %ldeps; - @ldeps{@{$deps{$_}}} = 1; - for my $x (split /,/,$staged) { delete $ldeps{$x}; } - my @dnames = $module ? () : keys %ldeps; - my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage'; - - my $full = full($_); - my $build = $buildroot{$_}; - - print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n"; - print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n"; - } - - close MAK; - } -} - -sub mode_checkout() { - for (@modules) { - my $module = $_; - my $tag = ""; - if ($lb_tag){ - for (@{$lbmodules{lb}}){ - if ("lb.".$_ eq $module){ - $tag = '-r '.$lb_tag; - } - } - } - if ($lbjp_tag) { - for (@{$lbmodules{'lbjp-common'}}){ - if ("lbjp-common.".$_ eq $module){ - $tag = '-r '.$lbjp_tag; - } - } - } - if ($jp_tag){ - for (@{$lbmodules{'jp'}}){ - if ("jp.".$_ eq $module){ - $tag = '-r '.$jp_tag; - } - } - } - if ($jobid_tag){ - for (@{$lbmodules{jobid}}){ - if ("jobid.".$_ eq $module){ - $tag = '-r '.$jobid_tag; - } - } - } - if ($canl_tag) { - for (@{$lbmodules{'canl'}}){ - if ("canl.".$_ eq $module){ - $tag = '-r '.$canl_tag; - } - } - } - #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ - # print "found"; - #} - $_ = full($_); - print "\n*** Checking out $_\n"; - system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; - } -} - -BEGIN{ -%etics_externs = ( - default => { - 'myproxy-devel'=>'myproxy-devel', - 'myproxy-server'=>'myproxy-server', - 'myproxy-admin'=>'myproxy-admin', - cares=>'c-ares', - utiljava=>'org.glite.security.util-java', - gpt=>'gpt', - fetchcrl=>'fetch-crl', - activemq=>'activemq-cpp-library', - }, -); - -%etics_projects = ( -); - -%need_externs_aux = ( - 'lb.client' => [ qw/cppunit:B classads libtool:B globus:B/ ], - 'lb.common' => [ qw/expat cares:B cppunit:B classads libtool:B globus:B/ ], - 'lb.doc' => [ qw/tetex-latex:B/ ], - 'lb.logger' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B globus:B/ ], - 'lb.nagios' => [ qw/globus_proxy_utils:R/ ], - 'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql-server:R cppunit:B gsoap:B classads voms:B lcas gridsite:B bison:B libtool:B libxml2 flex:B/ ], - 'lb.state-machine' => [ qw/classads libtool:B libxslt:B expat:B globus:B/ ], - 'lb.utils' => [ qw/cppunit:B libtool:B globus:B/ ], - 'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ], - 'lb.ws-test' => [ qw/gsoap:B libtool:B globus:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/docbook-utils:B libtool:B globus:B/ ], - 'lbjp-common.db' => [ qw/mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.log' => [ qw/log4c libtool:B/ ], - 'lbjp-common.maildir' => [ qw/libtool:B/ ], - 'lbjp-common.server-bones' => [ qw/libtool:B/ ], - 'lbjp-common.trio' => [ qw/cppunit:B libtool:B/ ], - 'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B/ ], - 'lbjp-common.gss' => [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B/ ], - 'lbjp-common.gsoap-plugin' => [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B/ ], - 'jobid.api-c' => [ qw/cppunit:B libtool:B openssl:B/ ], - 'jobid.api-cpp' => [ qw/cppunit:B libtool:B/ ], - 'jobid.api-java' => [ qw/ant:B jdk:B/ ], - 'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ], - 'jp.doc' => [], - 'jp.index' => [ qw/gsoap globus_essentials:R globus:B mysql-server:R/ ], - 'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B mysql-server:R/ ], - 'jp.server-common' => [], - 'jp.ws-interface' => [], - 'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'gridsite.commands' => [ qw/curl:R openssl:R/ ], - 'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ], - 'gridsite.libs' => [ qw/libxml2:R openssl:R/ ], - 'gridsite.devel' => [ qw// ], - 'gridsite.slashgrid' => [ qw/curl:R fuse:R/], - 'gridsite.services' => [ qw/curl:R gsoap:R/ ], - 'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ], - 'gridsite.gsexec' => [ qw// ], - 'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], - 'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B/ ], - 'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec - 'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B krb5-devel:B/ ], -); - -%need_jars = ( - 'jobid.api-java' => [ qw/jakarta-commons-codec/ ], - 'lb.client-java' => [ qw/jakarta-commons-lang/ ], -); - -for my $jar (keys %need_jars) { - for (@{$need_jars{$jar}}) { - $need_externs_type{$jar}->{$_} = 'BR'; # XXX - } -} - -%deps_aux = ( - 'lb.client' => [ qw/ - lb.types:B lb.common - lbjp-common.trio - jobid.api-cpp:B jobid.api-c - lbjp-common.gss - / ], - 'lb.client-java' => [ qw/ - lb.types:B - lb.ws-interface:B - jobid.api-java - / ], - 'lb.common' => [ qw/ - jobid.api-cpp:B jobid.api-c - lb.types:B lbjp-common.trio lbjp-common.gss - / ], - 'lb.doc' => [ qw/lb.types:B/ ], - 'lb.logger' => [ qw/ - lbjp-common.trio - lbjp-common.log - jobid.api-c - lb.common - lbjp-common.gss - / ], - 'lb.logger-msg' => [ qw/ - lb.logger:B - / ], - 'lb.nagios' => [ qw/ - lb.client:R - lb.ws-test:R - lb.utils:R - / ], - 'lb.server' => [ qw/ - lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R - lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log - jobid.api-c - lbjp-common.gsoap-plugin lbjp-common.gss - / ], - 'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ], - 'lb.utils' => [ qw/ - lbjp-common.jp-interface - jobid.api-c - lbjp-common.trio lbjp-common.maildir - lb.client lb.state-machine lb.types:B - / ], - 'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ], - 'lb.ws-interface' => [ qw/lb.types:B/ ], - 'lb.types' => [ qw// ], - 'lb.harvester' => [ qw/ - jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client - lbjp-common.gss lbjp-common.log - / ], - 'lb.yaim' => [ qw// ], - 'lb.glite-LB' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lb.emi-lb' => [ qw/ - lb.logger:R lb.server:R lb.utils:R lb.doc:R - lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R - lb.logger-msg:R - / ], - 'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ], - 'lbjp-common.maildir' => [ qw// ], - 'lbjp-common.log' => [ qw// ], - 'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ], - 'lbjp-common.trio' => [ qw// ], - 'lbjp-common.gss' => [ qw// ], - 'lbjp-common.gsoap-plugin' => [ qw/lbjp-common.gss/ ], - 'jobid.api-c' => [ qw// ], - 'jobid.api-cpp' => [ qw/jobid.api-c/ ], - 'jobid.api-java' => [ qw// ], - - 'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ], - - 'jp.client' => [ qw/ - jp.ws-interface - lbjp-common.jp-interface lbjp-common.maildir - jobid.api-c - lbjp-common.gsoap-plugin - / ], - 'jp.doc' => [ qw// ], - 'jp.index' => [ qw/ - jp.server-common jp.ws-interface - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.primary' => [ qw/ - jobid.api-c - jp.server-common jp.ws-interface - lb.state-machine - lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones - lbjp-common.gsoap-plugin - / ], - 'jp.server-common' => [ qw/ - lbjp-common.jp-interface lbjp-common.db - / ], - 'jp.ws-interface' => [ qw// ], - - 'gridsite.core' => [ qw// ], - 'gridsite.commands' => [ qw/gridsite.core:B/ ], - 'gridsite.apache' => [ qw/gridsite.core:B/ ], - 'gridsite.libs' => [ qw/gridsite.core:B / ], - 'gridsite.devel' => [ qw/gridsite.core:B/ ], - 'gridsite.slashgrid' => [ qw/gridsite.core:B/], - 'gridsite.services' => [ qw/gridsite.core:B/ ], - 'gridsite.service-clients' => [ qw/gridsite.core:B/ ], - 'gridsite.gsexec' => [ qw/gridsite.core:B/ ], - - 'px.proxyrenewal' => [ qw// ], - 'px.glite-PX' => [qw/px.myproxy-yaim:R/], - 'px.emi-px' => [qw/px.myproxy-yaim:R/], - 'px.myproxy-yaim' => [ qw// ], - 'px.myproxy-config' => [], - - 'canl.c' => [], - - # sub-packages (virtual ETICS components depending on the main) - 'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ], - 'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ], - 'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ], - 'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ], - 'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ], - 'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ], - 'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ], - 'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ], - 'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ], - 'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ], - 'lb.client-progs' => [ qw/lb.client:B/ ], - 'lb.client-devel' => [ qw/lb.client:B/ ], - 'lb.common-devel' => [ qw/lb.common:B/ ], - 'lb.logger-devel' => [ qw/lb.logger:B/ ], - 'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ], - 'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ], - 'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ], - 'canl.c-devel' => [ qw/canl.c:B/ ], -); - -for my $ext (keys %deps_aux) { - for (@{$deps_aux{$ext}}) { - /([^:]*)(?::(.*))?/; - push @{$deps{$ext}},$1; - my $type = $2 ? $2 : 'BR'; - $deps_type{$ext}->{$1} = $type; - } -} - - -%extrafull = ( - gridsite=>'org.gridsite.core', - 'canl.c' => 'emi.canl.canl-c', - 'canl.c-devel' => 'emi.canl.canl-c', - 'jobid.api-c-devel' => 'org.glite.jobid.api-c', - 'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp', - 'lbjp-common.db-devel' => 'org.glite.lbjp-common.db', - 'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin', - 'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss', - 'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface', - 'lbjp-common.log-devel' => 'org.glite.lbjp-common.log', - 'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir', - 'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones', - 'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio', - 'lb.client-devel' => 'org.glite.lb.client', - 'lb.client-progs' => 'org.glite.lb.client', - 'lb.common-devel' => 'org.glite.lb.common', - 'lb.logger-devel' => 'org.glite.lb.logger', - 'lb.state-machine-devel' => 'org.glite.lb.state-machine', - 'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal', - 'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal', -); - -#( java => 'client-java' ); -%extranodmod = ( - db => 'lbjp-common.db', - jpprimary => 'jp.primary', - jpindex => 'jp.index', - jpclient => 'jp.client', - lb => 'lb.glite-LB', - px => 'px.glite-PX', - proxyrenewal => 'px.proxyrenewal', - canl => 'canl.c', -); - -%obsoletes = ( - 'lb.yaim' => [ qq/glite-yaim-lb/ ], - 'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ], - 'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ], - 'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], -); - -%conflicts = ( -); - -%provides = ( - 'lbjp-common.gss' => [ qq/glite-security-gss/ ], - 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], - 'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ], -); - -%cvs_prefix = ( - 'lb' => 'org.glite', - 'jp' => 'org.glite', - 'jobid' => 'org.glite', - 'lbjp-common' => 'org.glite', - 'gridsite' => 'org', - 'px' => 'org.glite', - 'canl' => 'emi', -); - -%cvs_tag_prefix = ( - 'lb' => 'glite-', - 'jp' => 'glite-', - 'jobid' => 'glite-', - 'lbjp-common' => 'glite-', - 'gridsite' => '', - 'px' => 'glite-', - 'canl' => 'emi-', -); - -# ==== projects specification ==== -# etics_name ........... ETICS project name -# conf_prefix .......... ETICS configurations name prefix -# tag_prefix ........... VCS tag prefix -# local_prefix ......... prefix (relative to stage) -# etics_externs ........ ETICS modules names of externals -# (${NAME.location}, ETICS conf. dependencies) -# etics_projects ....... ETICS project names of externals -# etics_externs_devel .. ETICS modules names of devel versions of externals -# etics_locations ...... ETICS locations in ${NAME.location} properties -# need_externs_aux ..... project-specific external dependencies -# supported_platforms .. platforms supported by the project -# modules .............. additional modules in subsystems -%projects = ( - glite => { - current_version => 3, - etics_name => 'org.glite', - conf_prefix => { %cvs_tag_prefix }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}', - local_prefix => '', - etics_externs => { - default => { - globus_essentials=>'vdt_globus_essentials', - globus=>'globus', - globus_proxy_utils=>'vdt_globus_essentials', - gridsite=>'org.gridsite.libs', - yaim_core=>'org.glite.yaim.core', - gip_release=>'glite-info-provider-release', - gip_service=>'glite-info-provider-service', - bdii=>'bdii', - glite_version=>'glite-version', - glite_info_templates=>'glite-info-templates', - glue_schema=>'glue-schema', - trustmanager=>'org.glite.security.trustmanager', - axis=>'axis', - lcas=>'org.glite.security.lcas', - gsoapxx=>'-', - jdk=>'jdk', - voms=>'org.glite.security.voms-api-cpp', - }, - }, - etics_externs_devel => { - default => { - gridsite=>'org.gridsite.devel', - voms=>'org.glite.security.voms-api', - }, - }, - etics_projects => { - vdt=>[qw/globus globus_essentials globus_proxy_utils gpt/], - 'org.glite'=>[qw/voms gridsite lcas gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/], - }, - etics_locations => { - '*' => '', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ], - 'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R/ ], - 'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412 => 1, - sl5_ia32_gcc412 => 1, - deb5_x86_64_gcc432 => 1, - deb5_ia32_gcc432 => 1, - slc4_x86_64_gcc346 => 1, - slc4_ia32_gcc346 => 1, - }, - modules => { - 'lb' => [ qw/glite-LB/ ], - 'px' => [ qw/glite-PX/ ], - }, - }, - - emi => { - current_version => 2, - etics_name => 'emi', - conf_prefix => { - 'lb' => 'emi-', - 'jp' => 'emi-', - 'jobid' => 'emi-', - 'lbjp-common' => 'emi-', - 'gridsite' => 'emi-', - 'px' => 'emi-', - 'canl' => 'emi-', - }, - tag_prefix => { %cvs_tag_prefix }, - flavours => '--thrflavour= --nothrflavour=', - local_prefix => '/usr', - etics_externs => { - default => { - globus_essentials=>'globus-gssapi-gsi', - globus=>'globus-gssapi-gsi-devel', - globus_proxy_utils=>'globus-proxy-utils', - gridsite=>'emi.gridsite.libs', - yaim_core=>'emi.yaim.yaim-core', - yaim_bdii=>'emi.bdii.yaim-bdii', - gip_service=>'emi.bdii.glite-info-provider-service', - bdii=>'emi.bdii.core', - glite_version=>'emi.emi-version', - glue_schema=>'emi.bdii.glue-schema', - trustmanager=>'emi.java-security.trustmanager', - trustmanager_axis=>'emi.java-security.trustmanager-axis', - axis=>'axis1.4', - lcas=>'emi.sac.lcas', - gsoapxx=>'-', - jdk=>'java', - voms => 'emi.voms.voms-api', - }, - sl5_x86_64_gcc412EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - sl6_x86_64_gcc446EPEL => { - 'myproxy-devel' => 'myproxy-devel.x86_64', - }, - deb6_x86_64_gcc445 => { - axis => 'axis1.4', - # mappings in ETICS project configuration - #globus_essentials => 'libglobus-gssapi-gsi4', - #globus => 'libglobus-gssapi-gsi-dev', - #axis => 'libaxis-java', - #cares => 'libc-ares2', - #cppunit => 'libcppunit', - #expat => 'libexpat1', - #log4c => 'liblog4c3', - #curl => 'libcurl3', - #'mysql' => 'libmysqlclient16', - #'mysql-devel' => 'libmysqlclient-dev', - #libxslt => 'xsltproc', - #'jakarta-commons-codec' => 'libcommons-codec-java', - #'jakarta-commons-lang' => 'libcommons-lang-java', - #'tetex-latex' => 'texlive-latex-extra', - #'perl-LDAP' => 'libnet-ldap-perl', - #'fuse-lib' => 'libfuse2', - #'fuse' => 'fuse-utils', - }, - }, - etics_externs_devel => { - default => { - cares => 'c-ares-devel', - classads => 'classads-devel', - cppunit => 'cppunit-devel', - expat => 'expat-devel', - gsoap => 'gsoap-devel', - voms => 'emi.voms.voms-api-devel', - libtar => 'libtar-devel', - log4c => 'log4c-devel', - postgresql => 'postgresql-devel', - curl => 'curl-devel', - libxml2 => 'libxml2-devel', - openssl => 'openssl-devel', - gridsite=>'emi.gridsite.devel', - jdk=>'java-devel', - }, - deb6_x86_64_gcc445 => { - # mappings in ETICS project configuration - #cares => 'libc-ares-dev', - #cppunit => 'libcppunit-dev', - #expat => 'libexpat1-dev', - #libtar => 'libtar-dev', - #log4c => 'liblog4c-dev', - #postgresql => 'libpq-dev', - #curl => 'libcurl4-openssl-dev', - #libxml2 => 'libxml2-dev', - #openssl => 'libssl-dev', - #'tetex-latex' => 'texlive-latex-extra', - #libxslt=>'xsltproc', - #'httpd-devel' => 'apache2-prefork-dev', - #'fuse-devel' => 'libfuse-dev', - #gsoap => 'gsoap', - #'krb5-devel' => 'libkrb5-dev', - }, - }, - etics_projects => { - 'emi'=>[qw/voms voms-devel gridsite lcas gip_service bdii glite_version glue_schema yaim_core yaim_bdii trustmanager trustmanager_axis/], - }, - etics_locations => { - axis => 'axis', - }, - need_externs_aux => { - 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ], - 'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ], - 'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - 'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/], - 'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], - }, - supported_platforms => { - sl5_x86_64_gcc412EPEL => 1, - sl5_ia32_gcc412EPEL => 1, - sl6_x86_64_gcc446EPEL => 1, - deb6_x86_64_gcc445 => 1, - }, - modules => { - 'lb' => [ qw/emi-lb/ ], - 'px' => [ qw/emi-px/ ], - }, - }, -); - -%platform_properties = ( - 'jobid.api-java' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.types' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.doc' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.ws-interface' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'lb.nagios' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.yaim' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'px.myproxy-config' => { - default => { 'package.buildarch' => 'noarch' }, - }, - 'gridsite.devel' => { - default => { 'packageName' => 'gridsite-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' }, - }, - 'jobid.api-c-devel' => { - default => { 'packageName' => 'glite-jobid-api-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' }, - }, - 'jobid.api-cpp-devel' => { - default => { 'packageName' => 'glite-jobid-api-cpp-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' }, - }, - 'lbjp-common.db-devel' => { - default => { 'packageName' => 'glite-lbjp-common-db-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' }, - }, - 'lbjp-common.gsoap-plugin-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' }, - }, - 'lbjp-common.gss-devel' => { - default => { 'packageName' => 'glite-lbjp-common-gss-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' }, - }, - 'lbjp-common.jp-interface-devel' => { - default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' }, - }, - 'lbjp-common.log-devel' => { - default => { 'packageName' => 'glite-lbjp-common-log-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' }, - }, - 'lbjp-common.maildir-devel' => { - default => { 'packageName' => 'glite-lbjp-common-maildir-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' }, - }, - 'lbjp-common.server-bones-devel' => { - default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' }, - }, - 'lbjp-common.trio-devel' => { - default => { 'packageName' => 'glite-lbjp-common-trio-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' }, - }, - 'lb.client-devel' => { - default => { 'packageName' => 'glite-lb-client-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' }, - }, - 'lb.common-devel' => { - default => { 'packageName' => 'glite-lb-common-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' }, - }, - 'lb.state-machine-devel' => { - default => { 'packageName' => 'glite-lb-state-machine-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' }, - }, - 'lb.logger-devel' => { - default => { 'packageName' => 'glite-lb-logger-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' }, - }, - 'px.proxyrenewal-devel' => { - default => { 'packageName' => 'glite-px-proxyrenewal-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' }, - }, - 'canl.c-devel' => { - default => { 'packageName' => 'canl-c-devel' }, - deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' }, - }, -); - -my @k = keys %deps_aux; -@buildroot{@k} = ('') x ($#k+1); - -$buildroot{'gridsite.core'} = 'src'; -} - -sub full -{ - my ($short) = @_; - my $subsys = $short; - $subsys =~ s/\..*//; - - my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite'; - return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short"; -} - -sub get_version -{ - my ($fmod, $top_srcdir) = @_; - - my ($subsys,$mod) = split /\./,$fmod,2; - my ($major,$minor,$rev,$age); - my $old_; - - if ($force_version) { - $force_version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; - ($major,$minor,$rev,$age) = ($1,$2,$3,$4); - } - else { - my $path = "$top_srcdir/project"; - if ($subsys eq 'gridsite') { - $path = "$cvs_prefix{$subsys}.$subsys.core/project"; - } - open V,"$path/version.properties" - or die "$path/version.properties: $!\n"; - - $old_ = $_; - while () { - chomp; - ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; - $age = $1 if /module\.age\s*=\s*([[:digit:]]+)/; - } - close V; - $_ = $old_; - } - $version = "$major.$minor.$rev-$age"; - - return ($major, $minor, $rev, $age); -} - -sub get_description -{ - my ($top_srcdir) = @_; - - my $cvs_module = $top_srcdir; - my $package_description = ""; - my $package_summary = ""; - - if (-e "$cvs_module/project/package.description") { - open V, "$cvs_module/project/package.description"; - $package_description = join ("", ); - close V; - chomp $package_description; - } - else { - print STDERR "package.description not found for $subsys.$module!\n"; } - - if (-e "$cvs_module/project/package.summary") { - open V, "$cvs_module/project/package.summary"; - $package_summary = join ("", ); - close V; - chomp $package_summary; - $package_summary =~ s/\n/\\n/g; - } - else { - print STDERR "package.summary not found for $subsys.$module!\n"; } - - return ($package_summary, $package_description); -} - -sub mkinc -{ - my %aux; - undef %aux; - my @m=qw/ -lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb -lbjp-common.gss lbjp-common.gsoap-plugin -jobid.api-c jobid.api-cpp jobid.api-java -lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin -jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface -px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px -canl.c -/; - @aux{@m} = (1) x ($#m+1); - - my ($short) = @_; - my $full = full $short; - my ($subsys,$mod) = split /\./,$short,2; - my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}"; - - unless ($aux{$short}) { - print "Makefile.inc not needed in $full\n"; - return; - } - - my $top_srcdir = '.'; - my $abs_srcdir = ''; - my $build = ''; - - if ($module) { - $top_srcdir = $0; - $top_srcdir =~ s,/?[^/]*$,,; - $abs_srcdir = $top_srcdir; - $top_srcdir =~ s,^$,\.,; - } else { - $build = "$full/"; - $abs_srcdir = "$full/"; - unless ($buildroot{$_} eq '') { - $top_srcdir = '..'; - $build .= "$buildroot{$_}/"; - unless (-d "$build") { - mkdir "$build" or die "mkdir $build: $!\n"; - } - } - } - - my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir; - my ($package_summary, $package_description) = get_description $abs_srcdir; - if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; } - my $package_description_debian = $package_description; - $package_description_debian =~ s/^/ /mg; - - my ($old_locale, $specdate, $debdate); - - # files for ETICS always in root source directory - mkdir $abs_srcdir."project" unless (-d $abs_srcdir."project"); - open PKGCHL,">".$abs_srcdir."project/changelog" - or die $abs_srcdir."project/changelog: $!\n"; - $old_locale = setlocale(LC_TIME); - setlocale(LC_TIME, "C"); - $specdate = strftime("%a %b %d %Y", gmtime()); - $debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime()); - setlocale(LC_TIME, $old_locale); - print PKGCHL qq{* $specdate CESNET team -- automatically generated package -}; - close PKGCHL; - - unless ($top_srcdir eq '.') { - unlink $build."Makefile"; - symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n"; - } - - open MKINC,">".$build."Makefile.inc" - or die $build."Makefile.inc: $!\n"; - - print "Creating ".$build."Makefile.inc\n"; - - print MKINC qq{project = $project -PREFIX = $root -prefix = $prefix -stagedir = $stagedir -sysroot = $sysroot -sysconfdir = $sysconfdir -localstatedir = $localstatedir -thrflavour = $thrflavour -nothrflavour = $nothrflavour -libdir = $libdir -top_srcdir = $top_srcdir -}; - - for (@{$need_externs{$short}}) { - next unless defined $externs{$_} and defined $externs{$_}{prefix}; - print MKINC "${_}_prefix = $externs{$_}{prefix}\n"; - print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags}; - } - - for (@{$need_jars{$short}}) { - print MKINC "${_}_jar = $jar{$_}\n" - } - - my $need_gsoap = 0; - for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } - - print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; - - close MKINC; - - my $dh; - my $debian = 0; - - opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!"; - for my $dir (readdir $dh) { - if ($dir=~/^(.*)\.spec$/) { - if ($1 ne $packageName) { - printf STDERR "Changed RPM name: $packageName --> $1\n" if ($debug);; - $packageName=$1; - } - last; - } - } - closedir $dh; - - for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") { - if (-f "$abs_srcdir/project/$file") { - my $old_ = $_; - printf STDERR "Creating $build$file\n" if ($debug);; - open DST, ">$build$file"; - open SRC, "<$abs_srcdir/project/$file"; - while () { - if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; } - if (/\@URL\@/) { s/\@URL\@/$package{url}/g; } - if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; } - if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; } - if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; } - if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; } - if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; } - if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; } - if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; } - if (/\@AGE\@/) { s/\@AGE\@/$age/g; } - if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; } - if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; } - if (/\@DEBIAN_VCS\@/) { s/\@DEBIAN_VCS\@/$package{debian_vcs}/g; } - if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; } - if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; } - if (/^\s*.+\/configure\s/ and $force_version) { - print "Version forced to $version\n" if ($debug);; - s/--version\s+\S+\s?//; - s/$/ --version $version/; - } - printf DST "%s", "$_"; - } - close SRC; - close DST; - $_ = $old_; - } - } - - print "Creating ${build}debian/\n" if ($debug);; - - `rm -rfv ${build}debian`; - mkdir $build."debian" or die $!; - `cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`; - `mv ${build}debian.* ${build}debian/ 2>/dev/null`; - `rm -f ${build}debian/*.orig`; - opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!"; - for $_ (readdir $dh) { - if (/^debian\.(.*)/) { - `mv ${build}debian/$_ ${build}debian/$1`; - $debian = 1; - } - } - closedir $dh; - - if ($debian) { - my ($dir, $file); - - chmod 0755, "${build}debian/rules"; - $file="${build}debian/docs"; if (not -f $file) { `touch $file`; } - $dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; } - $file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` } - $file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` } - $file="${build}debian/changelog"; if (not -f $file) { - open FH, ">$file" or die $!; - print FH qq{$packageName ($major.$minor.$rev-$age) unstable; urgency=low - - * Automatically generated package - - -- $package{maintainer} $debdate -}; - close FH; - } - - } else { - `rm -rf ${build}debian`; - } -} - -BEGIN{ -}; - -sub mode_etics_packaging { - my ($fmod, $cmd, $rpmprepare, $debprepare) = @_; - my ($workspaceDir, $srcPackageName, $srcAge, $topDir); - - # old-school packaging by ETICS for EMI-1 - if ($project eq 'emi' and $project_version == 1) { return; } - - if ($fmod eq 'gridsite.core') { - $workspaceDir = '..'; - $srcPackageName = 'gridsite'; - $srcAge = ''; - $topDir = '../'; - } else { - $workspaceDir = '${workspaceDir}'; - $srcPackageName = '${packageName}'; - $srcAge = '-${age}'; - $topDir = ''; - } - - $cmd->{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SRPMSLocation}'; - $cmd->{default}{packaging} = $rpmprepare; - $cmd->{default}{packaging} .= "dir=\${workspaceDir}/rpm_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SRPMSLocation} \$dir/{BUILD,RPMS,SOURCES,SRPMS} 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/SOURCES/ - rpmbuild -bs --nodeps --define \"_topdir \$dir\" $srcPackageName.spec - cp -v \$dir/SRPMS/*.src.rpm \${package.SRPMSLocation}/ - rm -rf \$dir"; - - for my $p ('deb5_x86_64_gcc432', 'deb5_ia32_gcc432', 'deb6_x86_64_gcc445', 'deb6_ia32_gcc445') { - for my $c (keys %{$cmd->{default}}) { $cmd->{$p}{$c} = $cmd->{default}{$c}; } - $cmd->{$p}{clean} = 'make clean - rm -rfv ${package.tgzLocation} ${package.SDEBSLocation}'; - $cmd->{$p}{packaging} = $debprepare; - $cmd->{$p}{packaging} .= "dir=\${workspaceDir}/dpkg_build_src_\$\$ - mkdir -p \${package.tgzLocation} \${package.SDEBSLocation} \$dir 2>/dev/null || true - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/ - cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/${srcPackageName}_\${version}.orig.tar.gz - tar xzf \$dir/${srcPackageName}_\${version}.orig.tar.gz -C \$dir - cp -rf ${topDir}debian/ \$dir/$srcPackageName-\${version}/ - cd \$dir/$srcPackageName-\${version} - dpkg-buildpackage -S -d -nc - cd - - cp -v \$dir/*.tar.gz \$dir/*.dsc \${package.SDEBSLocation}/ - rm -rf \$dir"; - } -} - -sub mode_etics { - $fmod = shift; - - die "$0: --module required with --etics\n" unless $fmod; - - my ($subsys,$module) = split /\./,$fmod,2; - my $full = full "$subsys.$module"; - - my ($major,$minor,$rev,$age) = get_version $fmod, $full; - - # XXX: --with ignored for platform-dependend packages - my @copts = (); - my %ge; - @ge{@{$etics_projects{$project{etics_name}}}} = (1) x ($#{$etics_projects{$project{etics_name}}}+1); - - for (@{$need_externs{"$subsys.$module"}}) { - if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/ and (defined $externs{$_} or defined $jar{$_})) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - next if ($eext eq '-'); - if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}) { - $eext = $project{etics_locations}{$_} if ($project{etics_locations}{$_}); - push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}"; - } else { - if ($ge{$_} and not defined $externs{$_}{pkg}) { - push @copts, "--with-$_=\${stageDir}"; - } - } - } - } - - for (@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_; - - push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}); - } - - my $conf; - my $conftag; - my ($confprefix, $nameprefix, $packageName); - - $dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n"; - - $confprefix = $project{conf_prefix}{$subsys}; - $nameprefix = $confprefix; - $nameprefix =~ s/-$//; - $nameprefix =~ s/-/\./g; - $packageName = "$project{tag_prefix}{$subsys}$subsys-${module}"; - - if ($branch) { - $conf = "$confprefix${subsys}-${module}_$branch"; - $conftag = $branch; - # forced low age number - $age = $branch eq 'HEAD' ? '0head' : '0dev'; - push @copts, '--version ${version}-${age}'; - } - else { - $conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; -# XXX: gridsite hack - $conftag = $subsys eq 'gridsite' ? "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : - "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; - - # lowering age for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age - 1; - } - } - - # emi1 suffix for older packaging - if ($project eq 'emi' and $project_version == 1) { - $age = $age.$project.$project_version; - $conf = $conf.$project.$project_version; - } - - my $file = $output ? $output : "$conf.ini"; - open C,">$file" or die "$file: $!\n"; - - my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"}; - - my $confdir = $buildroot{"$subsys.$module"} eq '' ? '.' : '..'; - - my $cvs_module = full "$subsys.$module"; - my ($package_summary, $package_description) = get_description $cvs_module; - if ($package_description) { - $package_description =~ s/\n/\\n/g; - $package_description = "package.description = $package_description\n"; - } - if ($package_summary) { - $package_summary = "package.summary = $package_summary\n"; - } - - my %cmd; - $cmd_vcs{checkout} = "cvs -d \${vcsroot} co -d \${moduleName} ".($conftag eq 'HEAD' ? '-A' : '-r ${tag}')." $cvs_module 2>/dev/null"; - #$cmd_vcs{checkout} = "((test -d jra1mw/.git && (cd jra1mw; git pull)) || (git clone -q http://scientific.zcu.cz/git/jra1mw.git"; - #$cmd_vcs{checkout} .= " && (cd jra1mw; git checkout -b \${tag} --track origin/\${tag})" unless ($conftag eq /HEAD/); - #$cmd_vcs{checkout} .= ")) && (test -d \${moduleName} || ln -s jra1mw/$cvs_module \${moduleName})"; - $cmd_vcs{checkout} .= "\n\ttest -f \${packageName}-\${version}-\${age}.src.tar.gz || (ln -s \${moduleName} \${packageName}-\${version}; tar -chf - \${packageName}-\${version} --exclude CVS --exclude .git --exclude .etics | gzip --best > \${packageName}-\${version}-\${age}.src.tar.gz; rm \${packageName}-\${version})"; - $cmd_vcs{tag} = "cvs -d \${vcsroot} tag -R \${tag} ${moduleName}"; - - $cmd{default}{init} = 'None'; - $cmd{default}{configure} = 'None'; - $cmd{default}{compile} = 'None'; - $cmd{default}{test} = 'None'; - $cmd{default}{install} = 'None'; - $cmd{default}{packaging} = 'None'; - $cmd{default}{clean} = 'make clean'; - - if (exists $subpackages{$fmod}) { - $cmd{default}{clean} = 'None'; - $cmd{default}{packaging} = "echo building nothing, $subpackages{$fmod} will build this package"; - $cmd_vcs{checkout} = "mkdir -v \${moduleName} 2>/dev/null || true"; - } elsif ($subsys eq 'gridsite') { - $cmd_vcs{tag} = 'None'; - - if ($module eq 'core') { - my $flags; - - if ($project ne 'glite') { - # don't evaluate pkg-config calls to get them into source package - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=\`pkg-config gsoap --variable=prefix\` - OPENSSL_GLOBUS_FLAGS=\`pkg-config globus-openssl --cflags\` - OPENSSL_GLOBUS_LIBS=\`pkg-config globus-openssl --libs\`'; - } else { - $flags = 'RELEASE_VERSION=${age} - GSOAPDIR=${gsoap.location} - OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor} - OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir} - HTTPD_FLAGS=-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-1 -I${httpd-devel.location}/include/apr-1.0 -I${httpd-devel.location}/include/apr-0 -I${httpd-devel.location}/include/pcre'; - } - - $cmd{default}{configure} = "cat > Makefile.inc </dev/null"; - $cmd{default}{init} = 'echo "/sbin/ldconfig" > project/.post - echo "/sbin/ldconfig" > project/.postun'; - $cmd{default}{configure} = "cat > src/Makefile.inc <{default}}) { - $defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n"; - } - - print STDERR "Writing $file\n"; - print C qq{ -[Configuration-$conf] -profile = None -moduleName = $project{etics_name}.$subsys.$module -displayName = $conf -description = $cvs_prefix{$subsys}.$subsys.$module -projectName = $project{etics_name} -age = $age -deploymentType = None -vcsroot = :pserver:anonymous\@glite.cvs.cern.ch:/cvs/glite -tag = $conftag -version = $major.$minor.$rev -$dwpath -[Platform-default:VcsCommand] -displayName = None -description = None -tag = $cmd_vcs{tag} -branch = None -commit = None -checkout = $cmd_vcs{checkout} - -}; - - for my $p (keys %cmd) { - next if $p ne 'default' and exists $project{supported_platforms} and not exists $project{supported_platforms}{$p}; - - print C qq{[Platform-$p:BuildCommand] -postpublish = None -packaging = $cmd{$p}{packaging} -displayName = None -description = None -doc = None -prepublish = None -publish = None -compile = $cmd{$p}{compile} -init = $cmd{$p}{init} -install = $cmd{$p}{install} -clean = $cmd{$p}{clean} -test = $cmd{$p}{test} -configure = $cmd{$p}{configure} -checkstyle = None - -}; - } - - print C qq{[Platform-default:Property] -$buildroot -package.preserve.libtool = false -$package_description$package_summary$defprops}; - - for (@{$obsoletes{"$subsys.$module"}}) { - print C "package.obsoletes = $_\n"; - print C "package.replaces = $_\n"; - } - for (@{$conflicts{"$subsys.$module"}}) { - print C "package.conflicts = $_\n"; - } - for (@{$provides{"$subsys.$module"}}) { - print C "package.provides = $_\n"; - } - print C "\n"; - - for my $pp (keys %{$platform_properties{"$subsys.$module"}}) { - next if $pp eq 'default'; - next if exists $project{supported_platforms} and not exists $project{supported_platforms}{$pp}; - - print C "[Platform-$pp:Property]\n$buildroot\n"; - - for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) { - print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n"; - } - print C "$package_description$package_summary\n"; - } - - for my $platform ('default', keys %{$project{supported_platforms}}) { - my $used = 0; - my $output = ''; - - for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) { - my $eext = $etics_externs{$platform}{$_}; - my $edev = $project{etics_externs_devel}{$platform}{$_}; - - # for the default platform using package of the same - # name for runtime dependency - if (not $eext) { - if ($platform eq 'default') { -#print "default runtime $_ on default\n"; - $eext = $_; } - else { -#print "no runtime $_ on $platform\n"; - $eext = '-'; } - } - if ($eext eq '-' and $edev eq '-') { -#print "skipping $_ on $platform\n"; - next; - } - - my $proj = 'externals'; - for my $p (keys %etics_projects) { - for $m (@{$etics_projects{$p}}) { - $proj = $p if $m eq $_; - } - } - - my $type = $need_externs_type{"$subsys.$module"}->{$_}; - - if ($edev) { - if ($type eq 'B') { - # no runtime - change to devel pkg - $eext = $edev; - } elsif ($type eq 'BR' or $type eq 'RB') { - # additional devel pkg - if ($edev ne '-') { $output .= "$proj|$edev = B\n"; } - } - } - if ($eext ne '-') { $output .= "$proj|$eext = $type\n"; } - } - - if ($platform eq 'default') { - for (@{$deps{"$subsys.$module"}}) { - my $type = $deps_type{"$subsys.$module"}->{$_}; - if (not $used) { - $used = 1; - } - $output .= "$project{etics_name}|$project{etics_name}.$_ = $type\n"; - } - } - - if ($output) { - print C qq{ -[Platform-$platform:DynamicDependency] -$output}; - } - } - - close C; - - for $file ("$cvs_module/project/debian.rules", "$cvs_module/project/$packageName.spec") { - my $lib; - my $main_module; - @copts = (); - - if ($file =~ /debian\.rules$/) { $lib = 'lib'; } - else { $lib = '%{_lib}'; } - - my $main_module = "$subsys.$module"; - if (exists $subpackages{$main_module}) { $main_module = $subpackages{$main_module}; } - - # locations hacks - if ($file =~ /$packageName\.spec$/) { - if ($fmod eq 'lb.client-java') { - push @copts, ''; - push @copts, '--with-axis=/usr/local/axis1.4'; - } - } - - if (-f $file) { - open DST,">$file.new" or die "$file.new: $!\n"; - open SRC,"<$file" or die "$file: $!\n"; - while () { - if (/^(\s*).+\/configure\s/) { - printf DST "%s", "$1"; - printf DST "/usr/bin/perl $confdir/configure $project{flavours} --root=/ --prefix=$project{local_prefix} --libdir=$lib --project=$project --module $main_module@copts\n"; - } else { - printf DST "%s", "$_"; - } - } - close SRC; - close DST; - - `diff -b "$file" "$file.new"`; - if ($? == 0) { - print STDERR "($file not changed)\n"; - unlink "$file.new"; - } else { - print STDERR "Writing $file\n"; - rename "$file", "$file.orig" unless -f "$file.orig"; - rename "$file.new", "$file"; - } - } - } -} - -sub gsoap_version { - local $_; - my $gsoap_version; - open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n"; - - while ($_ = ) { - chomp; - - $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; - $gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/; - } - close S; - return $gsoap_version; -} - -sub getlibdir { - if ( -e "/etc/debian_version") { # We are on Debian - $lib64="lib"; - $lib32="lib32"; } - else { # Another distribution - $lib64="lib64"; - $lib32="lib"; } - $libdir=$lib32; - - open INP, "uname -s | "; # Check kernel name - $kname= ; - chomp($kname); - close INP; - - if ( $kname eq "Linux") { - $arch = ("x86_64\npowerpc\nppc64\n"); - - open INP, "uname -p | "; # Check processor type - $procname= ; - chomp($procname); - close INP; - - if ($arch =~/^$procname\n/) { - return ($lib64); } - - open INP, "uname -m | "; # Check machine hardware - $machname= ; - chomp($machname); - close INP; - - if ($arch =~/^$machname\n/) { - return ($lib64); } - - # special cases (hyperlink lib64, Debian) - if (-l "/usr/lib64") { - $libdir=$lib32; } - - # if /usr/lib64 doesn't exist at all (AIX) - unless ( -e "/usr/lib64" ) { - $libdir=$lib32; } - } - - if ( $kname eq "SunOS") { - if (-e "/usr/lib/64") { - $libdir="lib/64"; } - } - - return $libdir; -} - -sub reshuffle_platforms($$) { - my ($data, $platforms) = @_; - my ($platform, %blacklist, $value); - - return if not $platforms; - - for $platform (keys %$data) { -#print "plat: $platform: $data->{$platform}\n"; - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { -#print " blacklist: $_ = $data->{$platform}{$_}\n"; - $blacklist{$_} = 1; - } - } - - for $_ (keys %blacklist) { - $value = $data->{default}{$_} ? $data->{default}{$_} : $_; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - if (not defined $data->{$platform}{$_}) { - $data->{$platform}{$_} = $value; -#print "added $value to $platform\n" - } - } - $data->{default}{$_} = '-'; -#print "deleted $_ from default\n"; - } - - # merge dependencies across the supported platforms - %blacklist = []; - for $platform (keys %$platforms) { - next if $platform eq 'default'; - for $_ (keys %{$data->{$platform}}) { - $blacklist{$_} = 1; - } - } - for $_ (keys %blacklist) { - $value = undef; - $same = 1; - for $platform (keys %$platforms) { - if (not $value) { $value = $data->{$platform}{$_}; } - if (not $data->{$platform}{$_} or $value ne $data->{$platform}{$_}) { - $same = 0; - last; - } - } - if ($same and $value) { -#print "merged dependency $_\n"; - $data->{default}{$_} = $value; - for $platform (keys %$platforms) { - delete $data->{$platform}{$_}; - } - } - } -} - -sub usage { - my @ext = keys %externs; - my @myjars = keys %jar; - - print STDERR qq{ -Usage: $0 options - -General options (defaults in []): - --prefix=PREFIX destination directory [./stage] - --stage=DIR staging directory [./stage] - --root=DIR installation root (custom relocation root -> sysroot) [./stage] - --sysroot=DIR system root (custom relocation root -> sysroot) [] - --sysconfdir=DIR system configuration directory [PREFIX/etc] - --staged=module,module,... what is already in PREFIX (specify without org.glite.) - --thrflavour=flavour - --nothrflavour=flavour threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg] - --listmodules=subsys list modules of a subsystem - --listmodules=module list subpackages of a module - --version=maj.min.rev-age version used instead of reading version.properties - --branch=branch CVS branch/etics name suffix (HEAD, branch_2_1, ...) - --libdir=libdir typically [lib,lib64] postfix - --project=PROJECT build or generate etics for a project (glite/emi1/emi) [emi] - --debug print more details - -Mode of operation: - --mode=\{checkout|build|etics\} what to do [build] - -What to build: - --module=module build this module only - --enable-NODE build this "node" (set of modules) only - --disable-NODE don't build this node - --lb-tag=tag checkout LB modules with specific tag - --jp-tag=tag checkout JP modules with specific tag - --lbjp-common-tag=tag checkout lbjp-common modules with specific tag - --jobid-tag=tag checkout jobid modules with specific tag - --canl-tag=tag checkout canl modules with specific tag - -Dependencies (summary of what will be used is always printed): - --with-EXTERNAL=PATH where to look for an external [autodetect] - --with-JAR=JAR where to look for jars - -Available nodes: - @nodes - -Default nodes: - @default_nodes - -Externals (not all for all modules) are: - @ext - -External jars are: - @myjars - -}; - -} diff --git a/org.glite.lb.doc/examples/Makefile b/org.glite.lb.doc/examples/Makefile deleted file mode 100644 index fc99f0a..0000000 --- a/org.glite.lb.doc/examples/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -glite_location:=${GLITE_LOCATION} -glite_prefix:=${glite_location} - -host_cpu:=${shell uname -m} -ifeq (${host_cpu},x86_64) - LDFLAGS:=-L${glite_prefix}/lib64 -L${glite_prefix}/lib - nothrflavour=gcc64dbg - thrflavour=gcc64dbgpthr -else - LDFLAGS:=-L${glite_prefix}/lib - nothrflavour=gcc32dbg - thrflavour=gcc32dbgpthr -endif - -CC:=gcc -CXX:=g++ - -COMMON_LIB:=-lglite_lb_common_${nothrflavour} -COMMON_LIB_THR:=-lglite_lb_common_${thrflavour} -CLIENT_LIB:=-lglite_lb_client_${nothrflavour} -CLIENT_LIB_THR:=-lglite_lb_client_${thrflavour} -JOBID_LIB:=-lglite_jobid - -LIB:=${COMMON_LIB} ${CLIENT_LIB} ${JOBID_LIB} -LIB_THR:=${COMMON_LIB_THR} ${CLIENT_LIB_THR} ${JOBID_LIB} -PLUSLIB:= -PLUSLIB_THR:= - -CFLAGS:=${DEBUG} \ - -I${glite_prefix}/include \ - -D_GNU_SOURCE - -CXXFLAGS:=${CFLAGS} - -COMPILE:=libtool --mode=compile ${CC} ${CFLAGS} -CXXCOMPILE:=libtool --mode=compile ${CXX} ${CXXFLAGS} -LINK:=libtool --mode=link ${CC} ${LDFLAGS} -LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} -INSTALL:=libtool --mode=install install - -EXAMPLES_SRC:=example1.c prod_example1.c cons_example1.c cons_example2.c cons_example3.c notif_example.c -EXAMPLES:=${EXAMPLES_SRC:.c=} - -EXTRA_SRC:=util.c -EXTRA_OBJ:=${EXTRA_SRC:.c=.o} - -# TODO: migrate them here from branch_RC31_3 -# EXAMPLES_PLUS_SRC:= -# EXAMPLES_PLUS:=${EXAMPLES_PLUS_SRC:.cpp=} -# EXAMPLES_PLUS_THR_SRC:= -# EXAMPLES_PLUS_THR:=${EXAMPLES_PLUS_THR_SRC:.cpp=} - -EXAMPLES_THR_SRC:= -EXAMPLES_THR:=${EXAMPLES_CL_THR_SRC:.c=} - -default all: examples - -examples: ${EXAMPLES} ${EXAMPLES_THR} ${EXAMPLES_PLUS} ${EXAMPLES_PLUS_THR} - -${EXAMPLES}: %: %.o ${EXTRA_OBJ} - ${LINK} -o $@ $< ${EXTRA_OBJ} ${LIB} - -${EXAMPLES_THR}: %: %.o - ${LINK} -o $@ $< ${LIB_THR} - -${EXAMPLES_PLUS}: %: %.o - ${LINKXX} -o $@ $< ${PLUSLIB} - -${EXAMPLES_PLUS_THR}: %: %.o - ${LINKXX} -o $@ $< ${PLUSLIB_THR} - -# catches $TOOLS and logevent compilation -%.o: %.c - ${CC} ${CFLAGS} -c $< - -%.o: %.cpp - ${CXX} ${CXXFLAGS} -c $< - -clean: - rm -rvf ${EXAMPLES} ${EXAMPLES_CL} ${EXAMPLES_CL_THR} - rm -rvf *.o .libs/ - diff --git a/org.glite.lb.doc/examples/README b/org.glite.lb.doc/examples/README deleted file mode 100644 index 94e640a..0000000 --- a/org.glite.lb.doc/examples/README +++ /dev/null @@ -1,19 +0,0 @@ - -This directory contains source code of examples from LB Developer's Guide -To build these examples, set the GLITE_LOCATION variable and run make. - -Consumer examples: - -cons_example1 -------------- -Retrieves a list of jobs based on state and destination. - -cons_example2 -------------- -Retrieves a list of jobs based on state and ORed destination conditions. - - -cons_example3 -------------- -Retrieves a list of jobs based on ORed user tag conditions. - diff --git a/org.glite.lb.doc/examples/README.queries b/org.glite.lb.doc/examples/README.queries deleted file mode 100644 index 214063f..0000000 --- a/org.glite.lb.doc/examples/README.queries +++ /dev/null @@ -1,511 +0,0 @@ -In this file, you can find several examples how to set the query conditions. - -All user's jobs: ----------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_QueryRec jc[2]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].value.c = NULL; - jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); - ... - - -All user's jobs that are curently running: ------------------------------------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_QueryRec jc[3]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].value.c = NULL; - jc[1].attr = EDG_WLL_QUERY_ATTR_STATUS; - jc[1].op = EDG_WLL_QUERY_OP_EQUAL; - jc[1].value.i = EDG_WLL_JOB_RUNNING; - jc[2].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); - ... - - -All user's jobs running at CE XYZ: ----------------------------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_QueryRec jc[4]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].value.c = NULL; - jc[1].attr = EDG_WLL_QUERY_ATTR_STATUS; - jc[1].op = EDG_WLL_QUERY_OP_EQUAL; - jc[1].value.i = EDG_WLL_JOB_RUNNING; - jc[2].attr = EDG_WLL_QUERY_ATTR_DESTINATION; - jc[2].op = EDG_WLL_QUERY_OP_EQUAL; - jc[2].value.c = "XYZ"; - jc[3].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); - ... - - -All user's jobs that have returned an exit code from 2 to 7: ------------------------------------------------------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_QueryRec jc[4]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].value.c = NULL; - jc[1].attr = EDG_WLL_QUERY_ATTR_STATUS; - jc[1].op = EDG_WLL_QUERY_OP_EQUAL; - jc[1].value.i = EDG_WLL_JOB_DONE; - jc[2].attr = EDG_WLL_QUERY_ATTR_EXITCODE; - jc[2].op = EDG_WLL_QUERY_OP_WITHIN; - jc[2].value.i = 2; - jc[2].value2.i = 7; - jc[3].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); - ... - - -All user's jobs running at CE XXX or YYY: ------------------------------------------ - - #include - ... - edg_wll_Context ctx; - edg_wll_QueryRec *jc[4]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - ... - jc[0] = (edg_wll_QueryRec *) malloc(2*sizeof(edg_wll_QueryRec)); - jc[0][0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc[0][0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0][0].value.c = NULL; - jc[0][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - - jc[1] = (edg_wll_QueryRec *) malloc(2*sizeof(edg_wll_QueryRec)); - jc[1][0].attr = EDG_WLL_QUERY_ATTR_STATUS; - jc[1][0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[1][0].value.i = EDG_WLL_JOB_RUNNING; - jc[1][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - - jc[2] = (edg_wll_QueryRec *) malloc(3*sizeof(edg_wll_QueryRec)); - jc[2][0].attr = EDG_WLL_QUERY_ATTR_DESTINATION; - jc[2][0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[2][0].value.c = "XXX"; - jc[2][1].attr = EDG_WLL_QUERY_ATTR_DESTINATION; - jc[2][1].op = EDG_WLL_QUERY_OP_EQUAL; - jc[2][1].value.c = "YYY"; - jc[2][2].attr = EDG_WLL_QUERY_ATTR_UNDEF; - - jc[3] = NULL; - edg_wll_QueryJobsExt(ctx, (const edg_wll_QueryRec **)jc, 0, &jobsOut, &statesOut); - free(jc[0]); free(jc[1]); free(jc[2]); - ... - - -All user's jobs marked with the user tag 'color' and with its value 'red': --------------------------------------------------------------------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_QueryRec jc[2]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].attr_id.tag = "color"; - jc[0].value.c = "red"; - jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); - ... - - -All user's jobs marked with the user tag 'color' and with its value 'red' or 'green': -------------------------------------------------------------------------------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_QueryRec jc[1][3]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - ... - jc[0][0].attr = EDG_WLL_QUERY_ATTR_USERTAG; - jc[0][0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0][0].attr_id.tag = "color"; - jc[0][0].value.c = "red"; - jc[0][1].attr = EDG_WLL_QUERY_ATTR_USERTAG; - jc[0][1].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0][1].attr_id.tag = "color"; - jc[0][1].value.c = "green"; - jc[0][2].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryJobsExt(ctx, (const edg_wll_QueryRec **)jc, 0, &jobsOut, &statesOut); - ... - - -All user's jobs marked with red color and using the 'xyz' algorithm: --------------------------------------------------------------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_QueryRec jc[2]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].attr_id.tag = "color"; - jc[0].value.c = "red"; - jc[1].attr = EDG_WLL_QUERY_ATTR_USERTAG; - jc[1].op = EDG_WLL_QUERY_OP_EQUAL; - jc[1].attr_id.tag = "algorithm"; - jc[1].value.c = "xyz"; - jc[2].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); - ... - - -All jobs that were submitted in the last 24 hours: --------------------------------------------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_QueryRec jc[2]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_TIME; - jc[0].op = EDG_WLL_QUERY_OP_GREATER; - jc[0].attr_id.state = EDG_WLL_JOB_SUBMITTED; - jc[0].value.t.tv_sec = time_now - (24 * 60 * 60); - jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); - ... - - -All jobs with a specified state within a particular time interval: ------------------------------------------------------------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_QueryRec jc[3]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].value.c = NULL; - jc[1].attr = EDG_WLL_QUERY_ATTR_TIME; - jc[1].op = EDG_WLL_QUERY_OP_WITHIN; - jc[1].attr_id.state = EDG_WLL_JOB_SUBMITTED; - jc[1].value.t.tv_sec = time_now - (48 * 60 * 60); - jc[1].value2.t.tv_sec = time_now - (24 * 60 * 60); - jc[2].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); - ... - - -\label{ASQ} -Event queries and job queries are similar. -Obviously, the return type is different\Dash the \LB\ raw events. -There is one more input parameter -representing specific conditions on events (possibly empty) -in addition to conditions on jobs. -Some examples showing event queries -are considered in the following paragraph. - - -All events marking any user's job as 'red': -------------------------------------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_Event *eventsOut; - edg_wll_QueryRec jc[2]; - edg_wll_QueryRec ec[2]; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].value.c = NULL; - jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - ec[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; - ec[0].op = EDG_WLL_QUERY_OP_EQUAL; - ec[0].attr_id.tag = "color"; - ec[0].value.c = "red"; - ec[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryEvents(ctx, jc, ec, &eventsOut); - ... - - -All events marking red jobs as green: -------------------------------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_Event *eventsOut; - edg_wll_QueryRec jc[2]; - edg_wll_QueryRec ec[2]; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].attr_id.tag = "color"; - jc[0].value.c = "red"; - jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - ec[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; - ec[0].op = EDG_WLL_QUERY_OP_EQUAL; - ec[0].attr_id.tag = "color"; - ec[0].value.c = "green"; - ec[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryEvents(ctx, jc, ec, &eventsOut); - ... - - -All user's jobs that were resubmitted: --------------------------------------- - - #include - ... - edg_wll_Context ctx; - edg_wll_Event *eventsOut; - edg_wll_QueryRec jc[2]; - edg_wll_QueryRec ec[2]; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].value.c = NULL; - jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - ec[0].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; - ec[0].op = EDG_WLL_QUERY_OP_EQUAL; - ec[0].value.i = EDG_WLL_EVENT_RESUBMISSION; - ec[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryEvents(ctx, jc, ec, &eventsOut); - ... - - -All user's jobs which were resubmitted in the last 2 hours: ------------------------------------------------------------ - - #include - ... - edg_wll_Context ctx; - edg_wll_Event *eventsOut; - edg_wll_QueryRec jc[2]; - edg_wll_QueryRec ec[3]; - ... - jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].value.c = NULL; - jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - ec[0].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; - ec[0].op = EDG_WLL_QUERY_OP_EQUAL; - ec[0].value.i = EDG_WLL_EVENT_RESUBMISSION; - ec[1].attr = EDG_WLL_QUERY_ATTR_TIME; - ec[1].op = EDG_WLL_QUERY_OP_GREATER; - ec[1].value.t.tv_sec = time_now - (2 * 60 * 60); - ec[2].attr = EDG_WLL_QUERY_ATTR_UNDEF; - edg_wll_QueryEvents(ctx, jc, ec, &eventsOut); - ... - - -Complex query: --------------- -Task: which of my red jobs are heading to a destination -that already encountered problems executing red jobs? - -1. First we retrieve the information of red jobs failures. - - #include - ... - edg_wll_Context ctx; - edg_wll_QueryRec jc1[3],ec1[3]; - edg_wll_Event *failures; - - jc1[0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc1[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc1[0].value.c = NULL; - jc1[1].attr = EDG_WLL_QUERY_ATTR_USERTAG; - jc1[1].attr_id.tag = "color"; - jc1[1].op = EDG_WLL_QUERY_OP_EQUAL; - jc1[1].value.c = "red"; - jc1[2].attr = EDG_WLL_QUERY_ATTR_DONECODE; - jc1[2].op = EDG_WLL_QUERY_OP_EQUAL; - jc1[2].value.i = EDG_WLL_DONE_FAILED; - jc1[3].attr = EDG_WLL_QUERY_ATTR_UNDEF; - - ec1[0].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; - ec1[0].op = EDG_WLL_QUERY_OP_EQUAL; - ec1[0].value.i = EDG_WLL_EVENT_DONE; - ec1[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - - edg_wll_QueryEvents(ctx,jc1,ec1,&failures); - ... -\end{verbatim} - - -2. We loop over the job ID's extracted from the events returned -in the previous step, and retrieve their `Match' and `Done' events. - -Note: it is desirable to avoid repeated queries on the same job. - - ... - edg_wll_QueryRec *jc2[2],*ec2[2]; - char *last_job = strdup(""),*this_job,**failed_sites = NULL; - edg_wll_Event *match_done; - char **failed_sites; - int n, i, j; - ... - jc2[0][0].attr = EDG_WLL_QUERY_ATTR_JOBID; - jc2[0][0].op = EDG_WLL_QUERY_OP_EQUAL; - jc2[0][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - jc2[1] = NULL; - ec2[0][0].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; - ec2[0][0].op = EDG_WLL_QUERY_OP_EQUAL; - ec2[0][0].value.i = EDG_WLL_EVENT_MATCH; - ec2[0][1].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; - ec2[0][1].op = EDG_WLL_QUERY_OP_EQUAL; - ec2[0][1].value.i = EDG_WLL_EVENT_DONE; - ec2[0][2].attr = EDG_WLL_QUERY_ATTR_UNDEF; - ec2[1] = NULL; - - n = 0; - for (i=0; failures[i].type; i++) { - this_job = edg_wlc_JobIdUnparse(failures[i].any.jobId); - if (strcmp(last_job,this_job)) { - free(last_job); - last_job = this_job; - jc2[0][0].value.j = failures[i].any.jobId; - edg_wll_QueryEventsExt(ctx,(const edg_wll_QueryRec **)jc2, - (const edg_wll_QueryRec **)ec2,&match_done); - for (j=0; match_done[j].type; j++) { - if (match_done[j].type == EDG_WLL_EVENT_MATCH && - match_done[j+1].type == EDG_WLL_EVENT_DONE && - match_done[j+1].done.status_code == EDG_WLL_DONE_FAILED) - { - failed_sites = realloc(failed_sites,(n+1)*sizeof *failed_sites); - failed_sites[n++] = strdup(match_done[j].match.dest_id); - } - edg_wll_FreeEvent(&match_done[j]); - } - } - else free(this_job); - edg_wll_FreeEvent(&failures[i]); - } - free(failures); - ... - - -3. Finally we can query the server for the jobs heading to one of the failing -sites. - - ... - edg_wll_QueryRec *jc3[3]; - edg_wlc_JobId *unlucky_jobs; - ... /* remove duplicates from failed_sites */ - - for (i=0; i - ... - edg_wll_Context ctx; - edg_wll_Event *eventsOut; - edg_wll_JobStat *statesOut; - edg_wlc_JobId *jobsOut; - edg_wll_QueryRec **jc; - edg_wll_QueryRec **ec; - ... - jc[0][0].attr = EDG_WLL_QUERY_ATTR_USERTAG; - jc[0][0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0][0].attr_id.tag = "color"; - jc[0][0].value.c = "red"; - jc[0][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - jc[2][0].attr = EDG_WLL_QUERY_ATTR_STATUS; - jc[2][0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[2][0].value.i = EDG_WLL_JOB_SUBMITTED; - jc[2][1].attr = EDG_WLL_QUERY_ATTR_STATUS; - jc[2][1].op = EDG_WLL_QUERY_OP_EQUAL; - jc[2][1].value.i = EDG_WLL_JOB_WAITING; - jc[2][2].attr = EDG_WLL_QUERY_ATTR_STATUS; - jc[2][2].op = EDG_WLL_QUERY_OP_EQUAL; - jc[2][2].value.i = EDG_WLL_JOB_READY; - jc[2][3].attr = EDG_WLL_QUERY_ATTR_STATUS; - jc[2][3].op = EDG_WLL_QUERY_OP_EQUAL; - jc[2][3].value.i = EDG_WLL_JOB_SCHEDULED; - jc[2][4].attr = EDG_WLL_QUERY_ATTR_UNDEF; - jc[3] = NULL; - edg_wll_QueryJobsExt(ctx, (const edg_wll_QueryRec **)jc, 0, &jobsOut, &statesOut); - ... - - ... - ec[0][0].attr = EDG_WLL_QUERY_ATTR_USERTAG; - ec[0][0].op = EDG_WLL_QUERY_OP_EQUAL; - ec[0][0].attr_id.tag = "color"; - ec[0][0].value.c = "red"; - ec[0][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - ec[1][0].attr = EDG_WLL_QUERY_ATTR_USERTAG; - ec[1][0].op = EDG_WLL_QUERY_OP_EQUAL; - ec[1][0].attr_id.tag = "color"; - ec[1][0].value.c = "red"; - ec[1][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - ec[2][0].attr = EDG_WLL_QUERY_ATTR_EVENT_TYPE; - ec[2][0].op = EDG_WLL_QUERY_OP_EQUAL; - ec[2][0].value.i = EDG_WLL_EVENT_DONE; - ec[2][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - ec[3] = NULL; - edg_wll_QueryEventsExt(ctx, (const edg_wll_QueryRec **)jc, (const edg_wll_QueryRec **)ec, &eventsOut); - ... - - diff --git a/org.glite.lb.doc/examples/cons_example1.c b/org.glite.lb.doc/examples/cons_example1.c deleted file mode 100644 index 08c474b..0000000 --- a/org.glite.lb.doc/examples/cons_example1.c +++ /dev/null @@ -1,137 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include - -/*headers*/ -#include "glite/jobid/cjobid.h" -#include "glite/lb/events.h" -#include "glite/lb/consumer.h" -/*end headers*/ - - -static struct option opts[] = { - {"help", 0, NULL, 'h'}, - {"server", 1, NULL, 's'}, - {"port", 1, NULL, 'p'}, - {"jobid", 1, NULL, 'j'}, - {"user", 1, NULL, 'u'}, -}; - -static void usage(char *me) -{ - fprintf(stderr, "usage: %s [option]\n" - "\t-h, --help Shows this screen.\n" - "\t-s, --server Server address.\n" - "\t-p, --port Query server port.\n" - "\t-j, --jobid ID of requested job.\n" - "\t-u, --user User DN.\n" - , me); -} - - -int main(int argc, char *argv[]) -{ - char *server, *jobid_s, *user; - int opt, err = 0; - edg_wlc_JobId jobid = NULL; - long i; - int port = 0; - - server = jobid_s = user = NULL; - while ( (opt = getopt_long(argc, argv, "hs:p:j:u:c:n:v:", opts, NULL)) != EOF) - switch (opt) { - case 'h': usage(argv[0]); return 0; - case 's': server = strdup(optarg); break; - case 'p': port = atoi(optarg); break; - case 'j': jobid_s = strdup(optarg); break; - case 'u': user = strdup(optarg); break; - case '?': usage(argv[0]); return 1; - } - - if ( !jobid_s ) { fprintf(stderr, "JobId not given\n"); return 1; } - //if ( !server ) { fprintf(stderr, "LB proxy socket not given\n"); return 1; } - - /*variables*/ - edg_wll_Context ctx; - edg_wll_QueryRec jc[4]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - /*end variables*/ - - if ( (errno = edg_wlc_JobIdParse(jobid_s, &jobid)) ) { perror(jobid_s); return 1; } - - /*context*/ - edg_wll_InitContext(&ctx); - - edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER, server); - if (port) edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER_PORT, port); - /*end context*/ - - /*queryrec*/ - jc[0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].value.c = NULL; - jc[1].attr = EDG_WLL_QUERY_ATTR_STATUS; - jc[1].op = EDG_WLL_QUERY_OP_EQUAL; - jc[1].value.i = EDG_WLL_JOB_RUNNING; - jc[2].attr = EDG_WLL_QUERY_ATTR_DESTINATION; - jc[2].op = EDG_WLL_QUERY_OP_EQUAL; - jc[2].value.c = "XYZ"; - jc[3].attr = EDG_WLL_QUERY_ATTR_UNDEF; - /*end queryrec*/ - - /*query*/ - err = edg_wll_QueryJobs(ctx, jc, 0, &jobsOut, &statesOut); //* \label{l:queryjobs} - if ( err == E2BIG ) { - fprintf(stderr,"Warning: only limited result returned!\n"); - return 0; - } else if (err) { - char *et,*ed; - - edg_wll_Error(ctx,&et,&ed); - fprintf(stderr,"%s: edg_wll_QueryJobs(): %s (%s)\n",argv[0],et,ed); - - free(et); free(ed); - } - /*end query*/ - - /*printstates*/ - for (i = 0; statesOut[i].state; i++ ) { - printf("jobId : %s\n", edg_wlc_JobIdUnparse(statesOut[i].jobId)); - printf("state : %s\n\n", edg_wll_StatToString(statesOut[i].state)); - } - /*end printstates*/ - - 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); - - return err; -} diff --git a/org.glite.lb.doc/examples/cons_example1.cpp b/org.glite.lb.doc/examples/cons_example1.cpp deleted file mode 100644 index 3b82a0a..0000000 --- a/org.glite.lb.doc/examples/cons_example1.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include - -/*headers*/ -#include "glite/jobid/JobId.h" -#include "glite/lb/ServerConnection.h" -#include "glite/lb/Job.h" -/*end headers*/ - -#include "iostream" - -using namespace glite::lb; -using namespace std; - -static struct option opts[] = { - {"help", 0, NULL, 'h'}, - {"server", 1, NULL, 's'}, - {"port", 1, NULL, 'p'}, - {"jobid", 1, NULL, 'j'}, - {"user", 1, NULL, 'u'}, -}; - -static void usage(char *me) -{ - cerr << "usage: " << me << " [option]\n" - "\t-h, --help Shows this screen.\n" - "\t-s, --server Server address.\n" - "\t-p, --port Query server port.\n" - "\t-j, --jobid ID of requested job.\n" - "\t-u, --user User DN.\n"; -} - - -int main(int argc, char *argv[]) -{ - char *server, *jobid_s, *user; - int opt, err = 0; - long i; - int port = 0; - - server = jobid_s = user = NULL; - while ( (opt = getopt_long(argc, argv, "hs:p:j:u:c:n:v:", opts, NULL)) != EOF) - switch (opt) { - case 'h': usage(argv[0]); return 0; - case 's': server = strdup(optarg); break; - case 'p': port = atoi(optarg); break; - case 'j': jobid_s = strdup(optarg); break; - case 'u': user = strdup(optarg); break; - case '?': usage(argv[0]); return 1; - } - - if ( !jobid_s ) { fprintf(stderr, "JobId not given\n"); return 1; } - //if ( !server ) { fprintf(stderr, "LB proxy socket not given\n"); return 1; } - - /*variables*/ - ServerConnection lb_server; - glite::jobid::JobId jobid; - std::vector job_cond; - std::vector statesOut; - /*end variables*/ - - try { - /*queryserver*/ - jobid = glite::jobid::JobId(jobid_s); - - lb_server.setQueryServer(jobid.host(), jobid.port()); - /*end queryserver*/ - - /*querycond*/ - job_cond.push_back(QueryRecord(QueryRecord::OWNER, QueryRecord::EQUAL, std::string(user))); - job_cond.push_back(QueryRecord(QueryRecord::STATUS, QueryRecord::EQUAL, JobStatus::RUNNING)); - job_cond.push_back(QueryRecord(QueryRecord::DESTINATION, QueryRecord::EQUAL, std::string("xyz"))); - /*end querycond*/ - - /*query*/ - statesOut = lb_server.queryJobStates(job_cond, 0); //* \label{l:cppqueryjobs} - /*end query*/ - - /*printstates*/ - for (i = 0; i< statesOut.size(); i++ ) { - cout << "jobId : " << statesOut[i].getValJobId(JobStatus::JOB_ID).toString() << endl; - cout << "state : " << statesOut[i].name() << endl << endl; - } - /*end printstates*/ - - } catch(std::exception e) { - cerr << e.what() << endl; - } - return 0; -} diff --git a/org.glite.lb.doc/examples/cons_example2.c b/org.glite.lb.doc/examples/cons_example2.c deleted file mode 100644 index 47d2786..0000000 --- a/org.glite.lb.doc/examples/cons_example2.c +++ /dev/null @@ -1,151 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include - -/*headers*/ -#include "glite/jobid/cjobid.h" -#include "glite/lb/events.h" -#include "glite/lb/consumer.h" -/*end headers*/ - - -static struct option opts[] = { - {"help", 0, NULL, 'h'}, - {"server", 1, NULL, 's'}, - {"port", 1, NULL, 'p'}, - {"jobid", 1, NULL, 'j'}, - {"user", 1, NULL, 'u'}, -}; - -static void usage(char *me) -{ - fprintf(stderr, "usage: %s [option]\n" - "\t-h, --help Shows this screen.\n" - "\t-s, --server LB server.\n" - "\t-p, --port LB server port.\n" - "\t-j, --jobid ID of requested job.\n" - "\t-u, --user User DN.\n" - , me); -} - - -int main(int argc, char *argv[]) -{ - char *server, *jobid_s, *user; - edg_wlc_JobId jobid = NULL; - int opt, err = 0; - long i; - int port = 0; - - server = jobid_s = user = NULL; - while ( (opt = getopt_long(argc, argv, "hs:p:j:u:c:n:v:", opts, NULL)) != EOF) - switch (opt) { - case 'h': usage(argv[0]); return 0; - case 's': server = strdup(optarg); break; - case 'p': port = atoi(optarg); break; - case 'j': jobid_s = strdup(optarg); break; - case 'u': user = strdup(optarg); break; - case '?': usage(argv[0]); return 1; - } - - if ( !jobid_s ) { fprintf(stderr, "JobId not given\n"); return 1; } - - /*variables*/ - edg_wll_Context ctx; - edg_wll_QueryRec *jc[4]; - edg_wll_JobStat *statesOut = NULL; - edg_wlc_JobId *jobsOut = NULL; - /*end variables*/ - - if ( (errno = edg_wlc_JobIdParse(jobid_s, &jobid)) ) { perror(jobid_s); return 1; } - - /*context*/ - edg_wll_InitContext(&ctx); - - edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER, server); - if (port) edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER_PORT, port); - /*end context*/ - - /*queryrec*/ - jc[0] = (edg_wll_QueryRec *) malloc(2*sizeof(edg_wll_QueryRec)); - jc[0][0].attr = EDG_WLL_QUERY_ATTR_OWNER; - jc[0][0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0][0].value.c = NULL; - jc[0][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - - jc[1] = (edg_wll_QueryRec *) malloc(2*sizeof(edg_wll_QueryRec)); - jc[1][0].attr = EDG_WLL_QUERY_ATTR_STATUS; - jc[1][0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[1][0].value.i = EDG_WLL_JOB_RUNNING; - jc[1][1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - - jc[2] = (edg_wll_QueryRec *) malloc(3*sizeof(edg_wll_QueryRec)); - jc[2][0].attr = EDG_WLL_QUERY_ATTR_DESTINATION; - jc[2][0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[2][0].value.c = "XXX"; - jc[2][1].attr = EDG_WLL_QUERY_ATTR_DESTINATION; - jc[2][1].op = EDG_WLL_QUERY_OP_EQUAL; - jc[2][1].value.c = "YYY"; - jc[2][2].attr = EDG_WLL_QUERY_ATTR_UNDEF; - - jc[3] = NULL; - /*end queryrec*/ - - /*query*/ - err = edg_wll_QueryJobsExt(ctx, (const edg_wll_QueryRec **)jc, - 0, &jobsOut, &statesOut); - /*end query*/ - - if ( err == E2BIG ) { - fprintf(stderr,"Warning: only limited result returned!\n"); - return 0; - } else if (err) { - char *et,*ed; - - edg_wll_Error(ctx,&et,&ed); - fprintf(stderr,"%s: edg_wll_QueryJobs(): %s (%s)\n",argv[0],et,ed); - - free(et); free(ed); - } - - /*printstates*/ - for (i = 0; statesOut[i].state; i++ ) { - printf("jobId : %s\n", edg_wlc_JobIdUnparse(statesOut[i].jobId)); - printf("state : %s\n\n", edg_wll_StatToString(statesOut[i].state)); - } - /*end printstates*/ - - 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); - } - free(jc[0]); free(jc[1]); free(jc[2]); - - edg_wll_FreeContext(ctx); - - return err; -} diff --git a/org.glite.lb.doc/examples/cons_example2.cpp b/org.glite.lb.doc/examples/cons_example2.cpp deleted file mode 100644 index 09aa9ae..0000000 --- a/org.glite.lb.doc/examples/cons_example2.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include - -/*headers*/ -#include "glite/jobid/JobId.h" -#include "glite/lb/Event.h" -#include "glite/lb/ServerConnection.h" -/*end headers*/ - -#include - -using namespace glite::lb; -using namespace std; - -static struct option opts[] = { - {"help", 0, NULL, 'h'}, - {"server", 1, NULL, 's'}, - {"port", 1, NULL, 'p'}, - {"jobid", 1, NULL, 'j'}, - {"user", 1, NULL, 'u'}, -}; - -static void usage(char *me) -{ - cerr << "usage: " << me << "[option]\n" - "\t-h, --help Shows this screen.\n" - "\t-s, --server LB server.\n" - "\t-p, --port LB server port.\n" - "\t-j, --jobid ID of requested job.\n" - "\t-u, --user User DN.\n"; -} - - -int main(int argc, char *argv[]) -{ - char *server, *jobid_s, *user; - glite::jobid::JobId jobid; - int opt, err = 0; - long i; - int port = 0; - - server = jobid_s = user = NULL; - while ( (opt = getopt_long(argc, argv, "hs:p:j:u:c:n:v:", opts, NULL)) != EOF) - switch (opt) { - case 'h': usage(argv[0]); return 0; - case 's': server = strdup(optarg); break; - case 'p': port = atoi(optarg); break; - case 'j': jobid_s = strdup(optarg); break; - case 'u': user = strdup(optarg); break; - case '?': usage(argv[0]); return 1; - } - - if ( !jobid_s ) { cerr << "JobId not given\n"; return 1; } - - /*variables*/ - ServerConnection lb_server; - std::vector> jc; - std::vector jc_part; - std::vector statesOut; - /*end variables*/ - - try { - jobid = glite::jobid::JobId(jobid_s); - - /*context*/ - lb_server.setQueryServer(jobid.host(), jobid.port()); - /*end context*/ - - /*queryrec*/ - jc_part.push_back(QueryRecord(QueryRecord::OWNER, QueryRecord::EQUAL, "")); - jc.push_back(jc_part); - - jc_part.clear(); - jc_part.push_back(QueryRecord(QueryRecord::STATUS, QueryRecord::EQUAL, JobStatus::RUNNING)); - jc.push_back(jc_part); - - jc_part.clear(); - jc_part.push_back(QueryRecord(QueryRecord::DESTINATION, QueryRecord::EQUAL, "XXX")); - jc_part.push_back(QueryRecord(QueryRecord::DESTINATION, QueryRecord::EQUAL, "YYY")); - jc.push_back(jc_part); - /*end queryrec*/ - - /*query*/ - statesOut = lb_server.queryJobStates(jc, 0); - /*end query*/ - - /*printstates*/ - for (i = 0; i< statesOut.size(); i++ ) { - cout << "jobId : " << statesOut[i].getValJobId(JobStatus::JOB_ID).toString() << endl; - cout << "state : " << statesOut[i].name() << endl << endl; - } - /*end printstates*/ - - } catch(std::exception e) { - cerr << e.what() << endl; - } - return 0; -} diff --git a/org.glite.lb.doc/examples/cons_example3.c b/org.glite.lb.doc/examples/cons_example3.c deleted file mode 100644 index c014049..0000000 --- a/org.glite.lb.doc/examples/cons_example3.c +++ /dev/null @@ -1,136 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include - -/*headers*/ -#include "glite/jobid/cjobid.h" -#include "glite/lb/events.h" -#include "glite/lb/consumer.h" -/*end headers*/ - - -static struct option opts[] = { - {"help", 0, NULL, 'h'}, - {"server", 1, NULL, 's'}, - {"port", 1, NULL, 'p'}, - {"jobid", 1, NULL, 'j'}, - {"user", 1, NULL, 'u'}, -}; - -static void usage(char *me) -{ - fprintf(stderr, "usage: %s [option]\n" - "\t-h, --help Shows this screen.\n" - "\t-s, --server LB server.\n" - "\t-p, --port LB server port.\n" - "\t-j, --jobid ID of requested job.\n" - "\t-u, --user User DN.\n" - , me); -} - - -int main(int argc, char *argv[]) -{ - char *server, *jobid_s, *user; - int opt, err = 0; - edg_wlc_JobId jobid = NULL; - long i; - int port = 0; - - - server = jobid_s = NULL; - while ( (opt = getopt_long(argc, argv, "hs:p:j:u:c:n:v:", opts, NULL)) != EOF) - switch (opt) { - case 'h': usage(argv[0]); return 0; - case 's': server = strdup(optarg); break; - case 'p': port = atoi(optarg); break; - case 'j': jobid_s = strdup(optarg); break; - case 'u': user = strdup(optarg); break; - case '?': usage(argv[0]); return 1; - } - - if ( !jobid_s ) { fprintf(stderr, "JobId not given\n"); return 1; } - - /*variables*/ - edg_wll_Context ctx; - edg_wll_Event *eventsOut; - edg_wll_QueryRec jc[2]; - edg_wll_QueryRec ec[2]; - /*end variables*/ - - if ( (errno = edg_wlc_JobIdParse(jobid_s, &jobid)) ) { perror(jobid_s); return 1; } - - /*context*/ - edg_wll_InitContext(&ctx); - - edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER, server); - if (port) edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER_PORT, port); - /*end context*/ - - /*queryrec*/ - jc[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - jc[0].attr_id.tag = "color"; - jc[0].value.c = "red"; - jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - ec[0].attr = EDG_WLL_QUERY_ATTR_USERTAG; - ec[0].op = EDG_WLL_QUERY_OP_EQUAL; - ec[0].attr_id.tag = "color"; - ec[0].value.c = "green"; - ec[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - /*end queryrec*/ - - /*query*/ - err = edg_wll_QueryEvents(ctx, jc, ec, &eventsOut); - /*end query*/ - - if ( err == E2BIG ) { - fprintf(stderr,"Warning: only limited result returned!\n"); - return 0; - } else if (err) { - char *et,*ed; - - edg_wll_Error(ctx,&et,&ed); - fprintf(stderr,"%s: edg_wll_QueryEvents(): %s (%s)\n",argv[0],et,ed); - - free(et); free(ed); - } - - if ( err == ENOENT ) return err; - - /*printevents*/ - for (i = 0; eventsOut && (eventsOut[i].type); i++ ) { - //printf("jobId : %s\n", edg_wlc_JobIdUnparse(eventsOut[i].jobId)); - printf("event : %s\n\n", edg_wll_EventToString(eventsOut[i].type)); - } - /*end printevents*/ - - if ( eventsOut ) { - for (i=0; &(eventsOut[i]); i++) edg_wll_FreeEvent(&(eventsOut[i])); - free(eventsOut); - } - - edg_wll_FreeContext(ctx); - - return err; -} diff --git a/org.glite.lb.doc/examples/cons_example3.cpp b/org.glite.lb.doc/examples/cons_example3.cpp deleted file mode 100644 index ee1b784..0000000 --- a/org.glite.lb.doc/examples/cons_example3.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -extern "C" { -#include -#include -} - -#include -#include - -/*headers*/ -#include "glite/jobid/JobId.h" -#include "glite/lb/Event.h" -#include "glite/lb/ServerConnection.h" -/*end headers*/ - -using namespace std; - -static struct option opts[] = { - {"help", 0, NULL, 'h'}, - {"server", 1, NULL, 's'}, - {"port", 1, NULL, 'p'}, - {"jobid", 1, NULL, 'j'}, - {"user", 1, NULL, 'u'}, -}; - -static void usage(char *me) -{ - cerr << "usage: %s [option]\n" - << "\t-h, --help Shows this screen.\n" - << "\t-s, --server LB server.\n" - << "\t-p, --port LB server port.\n" - << "\t-j, --jobid ID of requested job.\n" - << "\t-u, --user User DN.\n" - << me << endl; -} - - -int main(int argc, char *argv[]) -{ - char *server_s, *jobid_s, *user; - int opt, err = 0; - glite::jobid::JobId jobid; - long i; - int port = 0; - - - server = jobid_s = NULL; - while ( (opt = getopt_long(argc, argv, "hs:p:j:u:c:n:v:", opts, NULL)) != EOF) - switch (opt) { - case 'h': usage(argv[0]); return 0; - case 's': server_s = optarg; break; - case 'p': port = atoi(optarg); break; - case 'j': jobid_s = optarg; break; - case 'u': user = optarg; break; - case '?': usage(argv[0]); return 1; - } - - if ( !jobid_s ) { - cerr << "JobId not given\n"; return 1; - } - - /*variables*/ - ServerConnection lb_server; - vector eventsOut; - vector jc; - vector ec; - /*end variables*/ - - try { - - /*context*/ - lb_server.setQueryServer(server_s, port); - /*end context*/ - - /*queryrec*/ - jc.push_back(QueryRecord("color", QueryRecord::EQUAL, "red")); - ec.push_back(QueryRecord("color", QueryRecord::EQUAL, "green")); - /*end queryrec*/ - - /*query*/ - events_out = lb_server.queryEvents(jc,ec); - /*end query*/ - - - /*printevents*/ - for(i = 0; i < eventsOut.size(); i++) { - dumpEvent(&(eventsOut[i])); - } - /*end printevents*/ - - } catch(std::exception e) { - cerr << e.what() << endl; - } - - return 0; -} diff --git a/org.glite.lb.doc/examples/example1.c b/org.glite.lb.doc/examples/example1.c deleted file mode 100644 index 6d60cc9..0000000 --- a/org.glite.lb.doc/examples/example1.c +++ /dev/null @@ -1,66 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#include -#include -#include -#include - -#include "glite/lb/context.h" -#include "glite/lb/xml_conversions.h" -#include "glite/lb/consumer.h" - -extern void print_jobs(edg_wll_JobStat *); - -int main(int argc,char **argv) -{ - - edg_wll_Context ctx; - edg_wll_JobStat *statesOut = NULL; - edg_wll_QueryRec jc[2]; - - edg_wll_InitContext(&ctx); - - jc[0].attr = EDG_WLL_QUERY_ATTR_JOBID; - jc[0].op = EDG_WLL_QUERY_OP_EQUAL; - if ( edg_wlc_JobIdParse( - argv[1], - &jc[0].value.j) ) - { - edg_wll_FreeContext(ctx); - exit(1); - } - jc[1].attr = EDG_WLL_QUERY_ATTR_UNDEF; - if (edg_wll_QueryJobs(ctx, jc, 0, NULL, &statesOut)) { - char *err_text,*err_desc; - - edg_wll_Error(ctx,&err_text,&err_desc); - fprintf(stderr,"QueryJobs: %s (%s)\n",err_text,err_desc); - free(err_text); - free(err_desc); - } - else { - print_jobs(statesOut); /* process the returned data */ - edg_wll_FreeStatus(statesOut); - free(statesOut); - } - edg_wlc_JobIdFree(jc[0].value.j); - edg_wll_FreeContext(ctx); - return 0; -} diff --git a/org.glite.lb.doc/examples/notif_example.c b/org.glite.lb.doc/examples/notif_example.c deleted file mode 100644 index ab986bb..0000000 --- a/org.glite.lb.doc/examples/notif_example.c +++ /dev/null @@ -1,144 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include - -/*headers*/ -#include "glite/security/glite_gss.h" -#include "glite/lb/context.h" -#include "glite/lb/notification.h" -/*end headers*/ - -static struct option opts[] = { - {"help", 0, NULL, 'h'}, - {"user", 1, NULL, 'u'}, - {"timeout", 1, NULL, 't'}, -}; - -static void usage(char *me) -{ - fprintf(stderr, "usage: %s [option]\n" - "\t-h, --help Shows this screen.\n" - "\t-u, --user User DN.\n" - "\t-t, --timeout Timeout for receiving.\n" - "GLITE_WMS_NOTIF_SERVER must be set.\n" - , me); -} - - -int main(int argc, char *argv[]) -{ - char *user; - int i, opt, err = 0; - time_t valid; - struct timeval timeout = {220, 0}; - - user = NULL; - while ( (opt = getopt_long(argc, argv, "h:u:t:", opts, NULL)) != EOF) - switch (opt) { - case 'h': usage(argv[0]); return 0; - case 'u': user = strdup(optarg); break; - case 't': timeout.tv_sec = atoi(optarg); break; - case '?': usage(argv[0]); return 1; - } - - /*variables*/ - edg_wll_Context ctx; - edg_wll_QueryRec **conditions; - edg_wll_NotifId notif_id = NULL, recv_notif_id = NULL; - edg_wll_JobStat stat; - /*end variables*/ - - /*context*/ - edg_wll_InitContext(&ctx); - /*end context*/ - - /* set server:port if don't want to depend on GLITE_WMS_NOTIF_SERVER */ - /* edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER, server); */ - /* if (port) edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER_PORT, port); */ - - conditions = (edg_wll_QueryRec **)calloc(2,sizeof(edg_wll_QueryRec *)); - conditions[0] = (edg_wll_QueryRec *)calloc(2,sizeof(edg_wll_QueryRec)); - - - /* set notification conditions to Owner=xxx */ - /*queryrec*/ - conditions[0][0].attr = EDG_WLL_QUERY_ATTR_OWNER; - conditions[0][0].op = EDG_WLL_QUERY_OP_EQUAL; - conditions[0][0].value.c = user; - /*end queryrec*/ - - /*register*/ - if (edg_wll_NotifNew(ctx, (edg_wll_QueryRec const* const*)conditions, - 0, -1, NULL, ¬if_id, &valid)) { - char *et,*ed; - - edg_wll_Error(ctx,&et,&ed); - fprintf(stderr,"%s: edg_wll_NotifNew(): %s (%s)\n",argv[0],et,ed); - - free(et); free(ed); - goto register_err; - } - fprintf(stdout,"Registration OK, notification ID: %s\nvalid: (%ld)\n", - edg_wll_NotifIdUnparse(notif_id), - valid); - /*end register*/ - - fprintf(stdout,"Waiting for a notification for %d seconds\n", timeout.tv_sec); - - /*receive*/ - if ( (err = edg_wll_NotifReceive(ctx, -1, &timeout, &stat, &recv_notif_id)) ) { - if (err != ETIMEDOUT) { - char *et,*ed; - - edg_wll_Error(ctx,&et,&ed); - fprintf(stderr,"%s: edg_wll_NotifReceive(): %s (%s)\n",argv[0],et,ed); - - free(et); free(ed); - goto receive_err; - } - fprintf(stdout,"No job state change recived in given timeout\n"); - } - else - { - /* Check recv_notif_id if you have registered more notifications */ - /* Print received state change */ - printf("jobId : %s\n", edg_wlc_JobIdUnparse(stat.jobId)); - printf("state : %s\n\n", edg_wll_StatToString(stat.state)); - edg_wll_FreeStatus(&stat); - } - /*end receive*/ - -receive_err: - - /* Drop registration if not used anymore edg_wll_NotifDrop() */ - - edg_wll_NotifIdFree(recv_notif_id); - edg_wll_NotifCloseFd(ctx); - /* edg_wll_NotifClosePool(ctx); */ - -register_err: - - edg_wll_FreeContext(ctx); - - return err; -} diff --git a/org.glite.lb.doc/examples/prod_example1.c b/org.glite.lb.doc/examples/prod_example1.c deleted file mode 100644 index 2281af6..0000000 --- a/org.glite.lb.doc/examples/prod_example1.c +++ /dev/null @@ -1,125 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include - -/*headers*/ -#include "glite/jobid/cjobid.h" -#include "glite/lb/events.h" -#include "glite/lb/producer.h" -/*end headers*/ - - -static struct option opts[] = { - {"help", 0, NULL, 'h'}, - {"sock", 1, NULL, 's'}, - {"jobid", 1, NULL, 'j'}, - {"user", 1, NULL, 'u'}, - {"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-u, --user User DN.\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[]) -{ - char *server, *seq_code, *jobid_s, *user, *name, *value; - int opt, err = 0; - - - server = seq_code = jobid_s = name = value = NULL; - while ( (opt = getopt_long(argc, argv, "hs:j:u:c:n:v:", opts, NULL)) != EOF) - switch (opt) { - case 'h': usage(argv[0]); return 0; - case 's': server = strdup(optarg); break; - case 'j': jobid_s = strdup(optarg); break; - case 'u': user = strdup(optarg); break; - case 'c': seq_code = strdup(optarg); break; - case 'n': name = strdup(optarg); break; - case 'v': value = strdup(optarg); break; - case '?': usage(argv[0]); return 1; - } - - if ( !jobid_s ) { fprintf(stderr, "JobId 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; } - - - edg_wll_Context ctx; - edg_wlc_JobId jobid = NULL; - - if ( (errno = edg_wlc_JobIdParse(jobid_s, &jobid)) ) { perror(jobid_s); return 1; } - - /*context*/ - edg_wll_InitContext(&ctx); - - edg_wll_SetParam(ctx, EDG_WLL_PARAM_SOURCE, EDG_WLL_SOURCE_USER_INTERFACE); - edg_wll_SetParam(ctx, EDG_WLL_PARAM_HOST, server); - //edg_wll_SetParam(ctx, EDG_WLL_PARAM_PORT, port); - /*end context*/ - - /*sequence*/ - if (edg_wll_SetLoggingJob(ctx, jobid, seq_code, EDG_WLL_SEQ_NORMAL)) { - char *et,*ed; - edg_wll_Error(ctx,&et,&ed); - fprintf(stderr,"SetLoggingJob(%s,%s): %s (%s)\n",jobid_s,seq_code,et,ed); - exit(1); - } - /*end sequence*/ - - /*log*/ - err = edg_wll_LogEvent(ctx, //* \label{l:logevent} - 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); - } - /*end log*/ - - seq_code = edg_wll_GetSequenceCode(ctx); - puts(seq_code); - free(seq_code); - - edg_wll_FreeContext(ctx); - - return err; -} diff --git a/org.glite.lb.doc/examples/util.C b/org.glite.lb.doc/examples/util.C deleted file mode 100644 index eabb98f..0000000 --- a/org.glite.lb.doc/examples/util.C +++ /dev/null @@ -1,160 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners/ for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#include "glite/lb/Event.h" -#include "glite/lb/JobStatus.h" - -#include - -using namespace glite::lb; -using namespace std; - -/*event*/ -void -dumpEvent(Event *event) -{ -// list of attribute names and types - typedef vector> AttrListType; - - cout << "Event name: " << event->name() << endl; - AttrListType attr_list = event->getAttrs(); //* \label{l:getattrs} - for(AttrListType::iterator i = attr_list.begin(); - i != attr_list.end(); - i++) { - Event::Attr attr = attr_list[i].first; - - cout << Event::getAttrName(attr) << " = "; - switch(attr_list[i].second) { - case Event::INT_T: - case Event::PORT_T: - case Event::LOGSRC_T: - cout << event->getValInt(attr) << endl; - break; - - case Event::STRING_T: - cout << event->getValString(attr) << endl; - break; - - case Event::TIMEVAL_T: - cout << event->getValTime(attr).tv_sec << endl; - break; - - case Event::FLOAT_T: - cout << event->getValFloat(attr) << endl; - break; - - case Event::DOUBLE_T: - cout << event->getValDouble(attr) << endl; - break; - - case Event::JOBID_T: - cout << event->getValJobId(attr).toString() << endl; - break; - - default: - cout << "attribute type not supported" << endl; - break; - } - } -} -/*end event*/ - - -/*status*/ -void dumpState(JobStatus *status) -{ - typedef vector> AttrListType; - - cout << "Job status: " << status->name << endl; - - AttrListType attr_list = status->getAttrs(); //* \label{l:jgetattrs} - for(AttrListType::iterator i = attr_list.begin(); - i != attr_list.end(); - i++) { - JobStatus::Attr attr = attr_list[i].first; - cout << JobStatus::getAttrName(attr) << " = "; - switch(attr_list[i].second) { - - case INT_T: - cout << status->getValInt(attr) << endl; - break; - - case STRING_T: - cout << status->getValInt(attr) << endl; - break; - - case TIMEVAL_T: - cout << status->getValTime(attr).tv_sec << endl; - break; - - case BOOL_T: - cout << status->getValBool(attr).tv_sec << endl; - break; - - case JOBID_T: - cout << status->getValJobid(attr).toString() << endl; - break; - - case INTLIST_T: - vector list = status->getValIntList(attr); - for(vector::iterator i = list.begin(); - i != list.end(); - i++) { - cout << list[i] << " "; - } - cout << endl; - break; - - case STRLIST_T: - vector list = status->getValStringList(attr); - for(vector::iterator i = list.begin(); - i != list.end(); - i++) { - cout << list[i] << " "; - } - cout << endl; - break; - - case TAGLIST_T: /**< List of user tags. */ - vector> list = status->getValTagList(attr); - for(vector>::iterator i = list.begin(); - i != list.end(); - i++) { - cout << list[i].first << "=" << list[i].second << " "; - } - cout << endl; - break; - - case STSLIST_T: /**< List of states. */ - vector list = status->getValJobStatusList(attr); - for(vector::iterator i = list.begin(); - i != list.end(); - i++) { - // recursion - dumpState(&list[i]); - } - cout << endl; - break; - - default: - cout << "attribute type not supported" << endl; - break; - - } - } -} -/*end status*/ diff --git a/org.glite.lb.doc/examples/util.c b/org.glite.lb.doc/examples/util.c deleted file mode 100644 index 22d99b9..0000000 --- a/org.glite.lb.doc/examples/util.c +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#include -#include -#include -#include - -#include -#include - -int use_proxy = 0; - -void -print_jobs(edg_wll_JobStat *states) -{ - int i,j; - - for (i=0; states[i].state != EDG_WLL_JOB_UNDEF; i++) { - char *id = edg_wlc_JobIdUnparse(states[i].jobId); - char *st = edg_wll_StatToString(states[i].state); - - if (!states[i].parent_job) { - if (states[i].jobtype == EDG_WLL_STAT_SIMPLE) { - printf(" %s .... %s %s\n", id, st, (states[i].state==EDG_WLL_JOB_DONE) ? edg_wll_done_codeToString(states[i].done_code) : "" ); - } - else if ((states[i].jobtype == EDG_WLL_STAT_DAG) || - (states[i].jobtype == EDG_WLL_STAT_COLLECTION)) { - printf("%s %s .... %s %s\n", (states[i].jobtype==EDG_WLL_STAT_DAG)?"DAG ":"COLL",id, st, (states[i].state==EDG_WLL_JOB_DONE) ? edg_wll_done_codeToString(states[i].done_code) : ""); - for (j=0; states[j].state != EDG_WLL_JOB_UNDEF; j++) { - if (states[j].parent_job) { - char *par_id = edg_wlc_JobIdUnparse(states[j].parent_job); - - if (!strcmp(id,par_id)) { - char *sub_id = edg_wlc_JobIdUnparse(states[j].jobId), - *sub_st = edg_wll_StatToString(states[j].state); - - printf(" `- %s .... %s %s\n", sub_id, sub_st, (states[j].state==EDG_WLL_JOB_DONE) ? edg_wll_done_codeToString(states[j].done_code) : ""); - free(sub_id); - free(sub_st); - } - free(par_id); - } - } - } - } - - free(id); - free(st); - } - - printf("\nFound %d jobs\n",i); -} - - - diff --git a/org.glite.lb.doc/project/ChangeLog b/org.glite.lb.doc/project/ChangeLog deleted file mode 100644 index 311057c..0000000 --- a/org.glite.lb.doc/project/ChangeLog +++ /dev/null @@ -1,178 +0,0 @@ -1.0.0-1 -- LB 2.0 release - -1.0.0-2 -- fixed configure to work in etics - -1.0.0-3 -- Added the dummy 'check' rule to the Makefile - -1.0.1-1 -- Notification section - new example, comments incorporated - -1.0.2-1 -- Notificaton API -- TestPlan updates -- Updates in other sections - -1.0.3-1 -- Updates to the User Guide, Admin Guide and Test Plan Test Suite Documentation - -1.0.4-1 -- Admin Guide updates - installation and migration -- Test Plan updates - -1.1.0-1 -- Documentation updated to follow development - -1.1.1-1 -- Testplan documentation extended. - -1.1.2-1 -- Short reference to CRAM job logging functionality added - -1.1.3-1 -- Extended documentation for C++ API - -1.1.4-1 -- C++ examples -- Extended C++ consumer API documentation - -1.1.5-1 -- L&B version overview updated - -1.1.6-1 -- Documented new authorization functions - -1.1.7-1 -- More docs for authorization functions - -1.1.8-1 -- Minor updates in the Admin Guide and Test Plan - -1.1.9-1 -- Fixed target 'clean' in the Makefile to handle debian builds -- Updated references to L&B versions -- General grammar and typo fixes -- A new shared FAQ section prepared -- Documentation for new TestPlan tests - -1.1.9-2 -- Module rebuilt - -1.1.10-1 -- TestPlan tests documentation updated. - -1.1.10-2 -- Module rebuilt - -1.1.10-3 -- Module rebuilt - -1.1.11-1 -- New threaded test documented in LBTP - -1.1.11-2 -- Module rebuilt - -1.1.11-3 -- Module rebuilt - -1.1.12-1 -- Extended information on logging -- More on logging to syslog -- A few typos fixed - -1.2.0-1 -- Documentation updated to cover new features to be released with EMI-1 - -1.2.1-1 -- Documentation for new authz features - - Change job ownership - - Permissions to log user tags -- Introduction on a sysconfdir option (for /etc vs /usr) -- DESTDIR in makefiles - -1.2.2-1 -- Changes covering the new release with EMI - -1.2.2-2 -- Module rebuilt - -1.2.3-1 -- Separate Troubleshooting Guide -- Relocatable build directory - -1.2.4-1 -- Use emi document class - -1.2.5-1 -- Documentation for the basic deployment of notifications delivered over the MSG system -- Switching to a new, officially sanctioned EMI class -- Updates of command names - -1.2.6-1 -- at3 and check_version utilities path -- Documented searching for message brokers dynamically in BDII. - -1.2.7-1 -- at3 location detection reverted -- '--stage=/' behaviour fixed in configure -- Basic documentation for notifications over messaging -- Better reflect version differences -- Update on changes in L&B 3.0 -- Grammar fixes - -1.2.8-1 -- Portable syntax of test condition in install commands. -- Extended information on logging -- More on logging to syslog -- A few typos fixed -- Support for GLITE_LB_WMS_DN and GLITE_LB_AUTHZ_* yaim parameters -- More thorough distinction between EMI and gLite installation -- Polishing of the installation documentation -- Switch to yet another EMI template - -1.2.9-1 -- New FAQ on WMS and LB_SUPER_USERS - -1.2.10-1 -- Syntax fixed to work in both SL & Deb -- New description of the Nagios probe -- Typo fixes -- Version info updated -- New test for the Nagios probe -- TestPlan sections reshuffled to match intended structure -- More on messaging and related topics -- New FAQ entry (Duplicate entry ... for key 1) -- Architecture images updated - MSG added into the notification part - -1.3.0-1 -- Preparation for a new multiplatform release -- Portable syntax of test condition in install commands. - -1.3.1-1 -- New section on checking server configuration remotely -- The TestPlan document is installed along with other docs -- Front matter facelift -- Extended explanation of configuration files -- Notif keeping explained -- LB versions printed in italic rather than bold -- Smoke Test clarifications (GGUS #78132) -- Explanation of the Job History feature - -1.3.2-1 -- License string as recognized by rpmlint and packaging guidelines -- implementation status column removed from the test suite overview; there are no unimplemented tests anymore -- Description of a new test in the test plan -- New section on https testing -- Functionality test implementation hints commented out, all proposed tests have already been implemented -- Explaining more config details - -1.3.3-1 -- New test description -- NOTIF query strings explained - -1.3.4-1 -- CREAM and SB Transfers documentation - diff --git a/org.glite.lb.doc/project/debian.control b/org.glite.lb.doc/project/debian.control deleted file mode 100644 index bbc9d05..0000000 --- a/org.glite.lb.doc/project/debian.control +++ /dev/null @@ -1,17 +0,0 @@ -Source: glite-lb-doc -Priority: extra -Maintainer: @MAINTAINER@ -Uploaders: @UPLOADERS@ -Build-Depends: debhelper (>= 7.0.50~) -Standards-Version: 3.9.1 -Section: doc -Homepage: @URL@ -DM-Upload-Allowed: yes -@DEBIAN_VCS@ - -Package: glite-lb-doc -Section: doc -Architecture: all -Depends: ${misc:Depends} -Description: @SUMMARY@ -@DEBIAN_DESCRIPTION@ diff --git a/org.glite.lb.doc/project/debian.copyright b/org.glite.lb.doc/project/debian.copyright deleted file mode 100644 index 3d762ae..0000000 --- a/org.glite.lb.doc/project/debian.copyright +++ /dev/null @@ -1,38 +0,0 @@ -This work was packaged for Debian by: - - @MAINTAINER@ on Thu, 08 Dec 2011 00:46:07 +0100 - -It was downloaded from: - - @URL@ - -Upstream Author(s): - - @MAINTAINER@ - -Copyright: - - - -License: - - 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. - -On Debian systems, the complete text of the Apache version 2.0 license -can be found in "/usr/share/common-licenses/Apache-2.0". - -The Debian packaging is: - - Copyright (C) 2004-2011 Members of the EGEE Collaboration - -and is licensed under the Apache License, Version 2.0. diff --git a/org.glite.lb.doc/project/debian.glite-lb-doc.dirs b/org.glite.lb.doc/project/debian.glite-lb-doc.dirs deleted file mode 100644 index 6c9585c..0000000 --- a/org.glite.lb.doc/project/debian.glite-lb-doc.dirs +++ /dev/null @@ -1,2 +0,0 @@ -usr/share/doc/glite-lb-doc -usr/share/doc/glite-lb-doc/examples diff --git a/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.ag b/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.ag deleted file mode 100644 index 8819972..0000000 --- a/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.ag +++ /dev/null @@ -1,7 +0,0 @@ -Document: glite-lb-doc-ag -Title: Logging and Bookkeeping - Administrator's Guide -Abstract: L&B Administrator’s Guide explains how to administer the Logging and Bookkeeping (L&B) service. Several deployment scenarios are described together with the installation, configuration, running and troubleshooting steps. -Section: Network/Monitoring - -Format: PDF -Files: /usr/share/doc/glite-lb-doc/LBAG.pdf.gz diff --git a/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.dg b/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.dg deleted file mode 100644 index 92163e3..0000000 --- a/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.dg +++ /dev/null @@ -1,7 +0,0 @@ -Document: glite-lb-doc-dg -Title: Logging and Bookkeeping - Developer's Guide -Abstract: L&B Developer’s Guide explains how to use the Logging and Bookkeeping (L&B) service API. Logging (producer), querying (consumer) and notification API as well as the Web Services Interface is described in details together with programing examples. -Section: Network/Monitoring - -Format: PDF -Files: /usr/share/doc/glite-lb-doc/LBDG.pdf.gz diff --git a/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.tg b/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.tg deleted file mode 100644 index 1832cbd..0000000 --- a/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.tg +++ /dev/null @@ -1,7 +0,0 @@ -Document: glite-lb-doc-tg -Title: Logging and Bookkeeping - Troubleshooting Guide -Abstract: Troubleshooting Guide for Logging and Bookkeeping (L&B) service. -Section: Network/Monitoring - -Format: PDF -Files: /usr/share/doc/glite-lb-doc/LBTG.pdf.gz diff --git a/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.tp b/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.tp deleted file mode 100644 index 7427999..0000000 --- a/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.tp +++ /dev/null @@ -1,7 +0,0 @@ -Document: glite-lb-doc-tp -Title: Logging and Bookkeeping - Test Plan & Test Suite Documentation -Abstract: L&B Test Plan document explains how to test the Logging and Bookkeeping (L&B) service. Two major categories of tests are described: integration tests (include installation, configuration and basic service ping tests) and system tests (basic functionality tests, performance and stress tests, interoperability tests and security tests). -Section: Network/Monitoring - -Format: PDF -Files: /usr/share/doc/glite-lb-doc/LBTP.pdf.gz diff --git a/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.ug b/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.ug deleted file mode 100644 index 772d1a8..0000000 --- a/org.glite.lb.doc/project/debian.glite-lb-doc.doc-base.ug +++ /dev/null @@ -1,7 +0,0 @@ -Document: glite-lb-doc-ug -Title: Logging and Bookkeeping - User's Guide -Abstract: L&B User’s Guide explains how to use the Logging and Bookkeeping (L&B) service from the user’s point of view. The service architecture is described thoroughly. Examples on using L&B event logging command to log a user tag and change job ACL are given, as well as L&B query and notification use cases. -Section: Network/Monitoring - -Format: PDF -Files: /usr/share/doc/glite-lb-doc/LBUG.pdf.gz diff --git a/org.glite.lb.doc/project/debian.glite-lb-doc.install b/org.glite.lb.doc/project/debian.glite-lb-doc.install deleted file mode 100644 index fc2b692..0000000 --- a/org.glite.lb.doc/project/debian.glite-lb-doc.install +++ /dev/null @@ -1,2 +0,0 @@ -usr/share/doc/glite-lb-doc/* -usr/share/doc/glite-lb-doc/examples/* diff --git a/org.glite.lb.doc/project/debian.rules b/org.glite.lb.doc/project/debian.rules deleted file mode 100644 index f516a3c..0000000 --- a/org.glite.lb.doc/project/debian.rules +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- - --include /usr/share/dpkg/buildflags.mk - -# Uncomment this to turn on verbose mode. -export DH_VERBOSE=1 - -configure: configure-stamp -configure-stamp: - dh_testdir - /usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=lib --project=emi --module lb.doc - touch $@ - -build: build-indep - -build-indep: build-stamp - -build-stamp: configure-stamp - dh_testdir - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) - CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) check - touch $@ - -clean: configure-stamp - dh_testdir - dh_testroot - rm -f configure-stamp build-stamp - $(MAKE) clean - rm -f Makefile.inc config.status - dh_clean - -install: build-stamp - dh_testdir - dh_testroot - dh_prep - dh_installdirs - $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp - mv $(CURDIR)/debian/tmp/usr/share/doc/glite-lb-doc-@MAJOR@.@MINOR@.@REVISION@ $(CURDIR)/debian/tmp/usr/share/doc/glite-lb-doc - (cd $(CURDIR)/debian/tmp/usr/share/doc/glite-lb-doc; \ - rm -fv ChangeLog LICENSE; \ - cat $(CURDIR)/project/ChangeLog | gzip -9 > changelog.gz) - -binary-indep: install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_installexamples - dh_installman - dh_installlogrotate - dh_installcron - dh_install --fail-missing - dh_link - dh_compress - dh_fixperms - dh_makeshlibs - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep diff --git a/org.glite.lb.doc/project/glite-lb-doc.spec b/org.glite.lb.doc/project/glite-lb-doc.spec deleted file mode 100644 index 8e6e2cb..0000000 --- a/org.glite.lb.doc/project/glite-lb-doc.spec +++ /dev/null @@ -1,63 +0,0 @@ -Summary: @SUMMARY@ -Name: glite-lb-doc -Version: @MAJOR@.@MINOR@.@REVISION@ -Release: @AGE@%{?dist} -Url: @URL@ -License: ASL 2.0 -Vendor: EMI -Group: Development/Tools -BuildArch: noarch -BuildRequires: tetex-latex -BuildRequires: glite-lb-types -BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) -AutoReqProv: yes -Source: http://eticssoft.web.cern.ch/eticssoft/repository/emi/emi.lb.doc/%{version}/src/%{name}-@VERSION@.src.tar.gz - - -%description -@DESCRIPTION@ - - -%prep -%setup -q - - -%build -/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=%{_lib} --project=emi --module lb.doc -make - - -%check -make check - - -%install -rm -rf $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT -make install DESTDIR=$RPM_BUILD_ROOT - - -%clean -rm -rf $RPM_BUILD_ROOT - - -%files -%defattr(-,root,root) -%dir /usr/share/doc/%{name}-%{version}/ -%dir /usr/share/doc/%{name}-%{version}/examples/ -/usr/share/doc/%{name}-%{version}/examples/* -/usr/share/doc/%{name}-%{version}/LICENSE -/usr/share/doc/%{name}-%{version}/README -/usr/share/doc/%{name}-%{version}/ChangeLog -/usr/share/doc/%{name}-%{version}/LBAG.pdf -/usr/share/doc/%{name}-%{version}/LBUG.pdf -/usr/share/doc/%{name}-%{version}/LBDG.pdf -/usr/share/doc/%{name}-%{version}/LBTG.pdf -/usr/share/doc/%{name}-%{version}/LBTP.pdf -/usr/share/doc/%{name}-%{version}/package.summary -/usr/share/doc/%{name}-%{version}/package.description - - -%changelog -* @SPEC_DATE@ @MAINTAINER@ - @MAJOR@.@MINOR@.@REVISION@-@AGE@%{?dist} -- automatically generated package diff --git a/org.glite.lb.doc/project/package.description b/org.glite.lb.doc/project/package.description deleted file mode 100644 index 5b72d81..0000000 --- a/org.glite.lb.doc/project/package.description +++ /dev/null @@ -1 +0,0 @@ -glite-lb-doc is a package containing the complete LB documentation. This package contains the LB User's Guide (LBUG.pdf), LB Administrator's Guide (LBAG.pdf), LB Developer's Guide (LBDG.pdf) and LB Test Plan (LBTP.pdf). diff --git a/org.glite.lb.doc/project/package.summary b/org.glite.lb.doc/project/package.summary deleted file mode 100644 index 9668489..0000000 --- a/org.glite.lb.doc/project/package.summary +++ /dev/null @@ -1 +0,0 @@ -gLite Logging and Bookkeeping documentation diff --git a/org.glite.lb.doc/project/version.properties b/org.glite.lb.doc/project/version.properties deleted file mode 100644 index e2aeb57..0000000 --- a/org.glite.lb.doc/project/version.properties +++ /dev/null @@ -1,3 +0,0 @@ -# $Header$ -module.version=1.3.4 -module.age=1 diff --git a/org.glite.lb.doc/src/LBAG-Abstract.tex b/org.glite.lb.doc/src/LBAG-Abstract.tex deleted file mode 100644 index 71ea87f..0000000 --- a/org.glite.lb.doc/src/LBAG-Abstract.tex +++ /dev/null @@ -1,21 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% when changed, update also http://egee.cesnet.cz/en/JRA1/LB/lb.html -% (in CVSROOT=:gserver:lindir.ics.muni.cz:/cvs/edg, cvsweb/lb.html) -The Administrator's Guide explains how to administer the Logging and -Bookkeeping (\LB) service. Several deployment scenarios are described together -with the installation, configuration, running and troubleshooting steps. diff --git a/org.glite.lb.doc/src/LBAG-Installation.tex b/org.glite.lb.doc/src/LBAG-Installation.tex deleted file mode 100644 index a8f9413..0000000 --- a/org.glite.lb.doc/src/LBAG-Installation.tex +++ /dev/null @@ -1,857 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\section{Installation and Configuration} - -\subsection{Complete list of packages} - -\LB is currently distributed mainly in RPMs packages and, since \LBver{3.2} also in \emph{deb} packages. It is available also in -binary form packed as \texttt{.tar.gz}. - -In \LBver{1.x}, the list of all LB packages was the following: - -\begin{tabularx}{\textwidth}{>{\tt}lX} -glite-lb-common & common files \\ -glite-lb-client & client library and CLI tools\\ -glite-lb-client-interface & client library interface (header files) \\ -glite-lb-harvester & enhanced \LB notification client (since \LBver{1.10}) \\ -glite-lb-logger & local-logger and inter-logger \\ -glite-lb-proxy & proxy (restricted server used by WMS)\\ -glite-lb-server & server \\ -glite-lb-server-bones & multi-process server building library \\ -glite-lb-utils & auxiliary utilities \\ -glite-lb-ws-interface & web service interface \\ -glite-security-gsoap-plugin & GSS wrapper and GSS plugin for gSoap -\end{tabularx} - -Starting with \LBver{2.0}, the code has been restructured quite a lot, especially the dependencies were lightened, -and the new list of packages -- applicable also to \LBver{3.x} is now the following: - -\begin{tabularx}{\textwidth}{>{\tt}lX} -glite-lb-doc & documentation \\ -glite-lb-common & common files \\ -glite-lb-client & client library and CLI tools\\ -glite-lb-client-java & Java implementation of the client (since \LBver{2.1})\\ -glite-lb-harvester & enhanced \LB notification client (since \LBver{2.1})\\ -glite-lb-logger & local-logger and inter-logger \\ -glite-lb-logger-msg & plugin for message delivery over ActiveMQ (since \LBver{3.0}) \\ -glite-lb-server & server, including merged proxy functionality \\ -glite-lb-state-machine & state machine and LB plugin for Job Provenance \\ -glite-lb-utils & auxiliary utilities \\ -glite-lb-ws-interface & web service interface \\ -glite-lb-yaim & YAIM initialization scripts for \LB (since \LBver{2.1}) \\ -glite-lb-nagios-plugins & Nagios plugin that checks the \LB server (since \LBver{3.1}) \\ -\end{tabularx} - - -More detailed description together with the dependencies can be read directly from each package, -for example by issuing the command -\begin{verbatim} - rpm -qiR -\end{verbatim} - -Some of the LB packages depend also on other gLite packages, different -due to the restructuring since \LBver{2.0}. -For \LBver{1.x} they are: - - -\begin{tabularx}{\textwidth}{>{\tt}lX} -glite-wms-utils-jobid & gLite jobId management library \\ -glite-jp-common & Job Provenance auxiliary library \\ -\end{tabularx} - -\noindent -And for \LBver{2.0 and newer}: - -\nopagebreak -\begin{tabularx}{\textwidth}{>{\tt}lX} -glite-jobid-api-c & gLite jobId C API library \\ -% pro beh LB neni triba -% glite-jp-common & JP common files \\ -glite-lbjp-common-db & database access layer \\ -glite-lbjp-common-jp-interface & interface to the Job Provenance service\\ -glite-lbjp-common-log & glite common logging format implementation \\ -glite-lbjp-common-maildir & persistent request spool management \\ -glite-lbjp-common-server-bones & multi-process server building library \\ -glite-lbjp-common-trio & extended printf implementation \\ -glite-lbjp-common-gss & GSS wrapper (formerly \emph{glite-security-gss})\\ -glite-lbjp-common-gsoap-plugin & GSS plugin for gSoap (formerly \emph{glite-security-gsoap-plugin})\\ -\end{tabularx} - -where all \verb'glite-lbjp-common-*' packages are common both to \LB and -Job Provenance (\JP). - -\subsubsection{Development packages} - -Since \LBver{3.2} development files have been separated from runtime packages, and they are distributed in standalone \texttt{-devel} packages. They are not required for \LB's operation. The following list of development RPMs is given form the sake of completeness: - -\begin{tabularx}{\textwidth}{>{\tt}p{6cm}>{\tt}X} -glite-jobid-api-c-devel -glite-jobid-api-cpp-devel -glite-lb-client-devel -glite-lb-common-devel -glite-lb-logger-devel -glite-lb-state-machine-devel & -glite-lbjp-common-db-devel -glite-lbjp-common-gsoap-plugin-devel -glite-lbjp-common-gss-devel -glite-lbjp-common-jp-interface-devel -glite-lbjp-common-log-devel -glite-lbjp-common-maildir-devel -glite-lbjp-common-server-bones-devel -glite-lbjp-common-trio-devel -\end{tabularx} - -\subsection{Common logging format} -\label{inst:comlog} -Since \LBver{2.1} \LB service follows the \textbf{gLite common logging recommendations v1.1}: -\begin{center} -\url{https://twiki.cern.ch/twiki/pub/EGEE/EGEEgLite/logging.html}. -\end{center} - -The implementation is done in the \texttt{glite-lbjp-common-log} package and it -uses \texttt{log4c} (\url{http://log4c.sourceforge.net}) -and its configuration file \texttt{log4crc}. - -There is one configuration file \texttt{$[$/opt/glite$]$/etc/glite-lb/log4crc} -that startup scripts use by setting the \texttt{LOG4C\_RCPATH} environment -variable. - -A file \texttt{log4crc.example-debugging} may be useful to copy to -\texttt{\$HOME/.log4crc} (or by setting the \texttt{LOG4C\_RCPATH} environment variable -to a directory containing the \texttt{log4crc} file) to obtain detailed debugging output. -One can debug only specific parts of the LB system, for example -by uncommenting \texttt{LB.SERVER.DB} category in the \texttt{log4crc} file, -one gets only the debugging info related to the underlying database subsystem calls. - - -Currently supported log categories are: - -\nopagebreak -\begin{tabularx}{\textwidth}{>{\tt}lX} -SECURITY & Security matters \\ -ACCESS & Communication issues \\ -CONTROL & \LB server control \\ -LB & \emph{unused} \\ -LB.LOGD & Messages from the \LB local logger \\ -LB.INTERLOGD & Messages from the \LB interlogger \\ -LB.NOTIFINTERLOGD & Messages from the notification interlogger \\ -LB.SERVER & Processing within the \LB server \\ -LB.SERVER.DB & DB calls made by the server \\ -LB.SERVER.REQUEST & Processing \LB server requests \\ -LB.HARVESTER & Messages from the \LB harvester \\ -LB.HARVESTER.DB & DB calls made by the harvester \\ -LB.AUTHZ & Authentication matters \\ -\end{tabularx} - -The following log priorities are recognized, in a descending order of severity: \texttt{fatal}, \texttt{error}, \texttt{warn}, \texttt{info}, \texttt{debug}. Note that running with any of the logging categories set do \texttt{debug} for a prolonged period of time will result in the logfile growing uncontroledly. - -In a typical setup, logging messages generated by the \LB service will be found in \texttt{/var/log/messages}. - -\note\ \emph{syslog} is typically configured to drop log messages with priority \texttt{debug}. You may want to enable it, for example by using something like this in \texttt{/etc/syslog.conf} and then restarting {syslog}: -\begin{verbatim} -*.debug;mail.none;authpriv.none;cron.none -/var/log/messages -\end{verbatim} - -\subsection{\LB server} - -\subsubsection{Hardware requirements} -\label{inst:hw_req} - -Hardware requirements depend on performance and storage time requirements. -Disk space used by LB server consists of database space and working space -for backup dumps and temporary files used by exports to Job Provenance and -R-GMA tables. Necessary database space can be calculated by multiplying -job retention length (job purge timeout), job submission rate, and -per-job space requirements (120\,KB per job is recommended for current common -EGEE usage pattern; jobs can consume more than that with use of very long -JDL descriptions, user tags, or very high number of resubmissions). -For temporary files, approximately 10\,GB is sufficient for LB server setups -working normally, more can be needed when backlog forms in data export -to any external service. For example, typical setup processing 40\,000 jobs per -day where all jobs are purged after 10 days needs about 58 gigabytes -($10 \cdot 40000 \cdot 120 \mbox{KB (per job)} + 10$) not accounting for operating -system and system logs. - -For smooth handling of 40\,000 jobs/day, this or better machine configuration -is necessary: -\begin{itemize} -\item 1GB RAM -\item CPU equivalent of single Xeon/Opteron 1.5GHz -\item single 7200 rpm SATA disk. -\end{itemize} -In order to achieve higher performace, following changes are recommended: -\begin{itemize} -\item Faster disks. Disk access speed is crucial for LB server, couple of 15k rpm -SCSI or SAS disks (one for MySQL database data file, the second for DB logs, LB server's -working directories, and operating system files) or RAID with battery backed -write-back cache is preferable. -\item More memory. Large RAM improves performance through memory caching, -relative speed gain is likely to be rougly proportional to memory/database size ratio. -To use 3\,GB or more efficiently, 64bit OS and MySQL server versions are recommended. -\item Faster or more processors. CPU requirements scale approximately linearly with -offered load. -\end{itemize} - -\subsubsection{Standard Installation} - -\begin{itemize} -\item Installing from \textbf{EMI or UMD repository} (applies to \LBver{3.0} and higher): - -Install and configure a clean system, the \textbf{EPEL} repository, and the \textbf{EMI} repository as per instructions given in \htmladdnormallink{https://twiki.cern.ch/twiki/bin/view/EMI/GenericInstallationConfigurationEMI1}{https://twiki.cern.ch/twiki/bin/view/EMI/GenericInstallationConfigurationEMI1}. Then install metapackage \texttt{emi-lb}. - -\item Installing from \textbf{gLite's node-type repository} (applies to \LBver{up to 2.1}): -% XXX Don't forget to increase version if ever LB 3 releases with gLite - -Install and configure OS and basic services (certificates, CAs, time synchronization, software repositories) according to the \htmladdnormallink{https://twiki.cern.ch/twiki/bin/view/LCG/GenericInstallGuide320}{https://twiki.cern.ch/twiki/bin/view/LCG/GenericInstallGuide320}. Then install metapackage \texttt{glite-LB} from an appropriate gLite software repository. - -\end{itemize} - -YAIM configuration can be done then: - -\begin{quote} -\texttt{/opt/glite/yaim/bin/yaim -c -s site-info.def -n glite-LB} -\end{quote} - -Available parameters specific to LB server are (mandatory parameters are \textbf{highlighted}): - -%variable&meaning&default value &further details\\ -\begin{itemize} -\item \textbf{MYSQL\_PASSWORD} -- root password of MySQL server (mandatory) -\item \texttt{GLITE\_LB\_EXPORT\_PURGE\_ARGS} -- purge timeouts (default: \texttt{--cleared 2d --aborted 15d --cancelled 15d --other 60d}) - -According to local retention policy you may want to use different purge timeouts (for example WLCG would need \texttt{--cleared 90d --aborted 90d --cancelled 90d --other 90d}). -\item \texttt{GLITE\_LB\_EXPORT\_ENABLED} -- set to \texttt{true} for export to JP, installed glite-lb-client and glite-jp-client are needed (default: \texttt{false}) -\item \texttt{GLITE\_LB\_EXPORT\_JPPS} -- Job Provenance Primary Storage where to export purged jobs, required if export to JP is enabled -\item \texttt{GLITE\_LB\_RTM\_ENABLED} -- enable settings for Real Time Monitor - indexes and additional access (default: false) -\item \texttt{GLITE\_LB\_TYPE} -- type of the \LB service: server, proxy, both (default: autodetect, \LB node only: 'server', WMS node only: proxy, \LB and WMS: 'both') -\item \texttt{GLITE\_LB\_INDEX\_OWNER} -- when specified, add (\texttt{true}) or drop (\texttt{false}) 'owner' index (default: 'owner' index not touched) -\item \texttt{GLITE\_LB\_MSG\_BROKER} -- URL of the MSG broker, 'auto' for looking in BDII, 'false' for disabling MSG notifications (default: auto) -\item \texttt{GLITE\_LB\_MSG\_NETWORK} -- required network type when searching in BDII (default: PROD) -\item \texttt{LCG\_GFAL\_INFOSYS} -- BDII servers (default: lcg-bdii.cern.ch:2170) -\end{itemize} - -Authorization: -\begin{itemize} -\item \texttt{GLITE\_LB\_SUPER\_USERS} -- additional super-users (default: empty)\footnote{The use of this parameter is a FAQ. See section \ref{FAQ:WMS_superusers}.} -\item \texttt{GLITE\_LB\_WMS\_DN} -- DNs of WMS servers (default: empty)\footnotemark[\thefootnote] -\item \texttt{GLITE\_LB\_RTM\_DN} -- DNs using to get notifications from \LB server\\ -(default: \texttt{heppc24.hep.ph.ic.ac.uk} machine certificate) -\item \texttt{GLITE\_LB\_AUTHZ\_} -- more detailed tuning of access grants, see Section~\ref{inst:authz} (default: empty, '\texttt{.*}' for logging and job registrations) -\end{itemize} - -Additional helper or legacy parameters: -\begin{itemize} -\item \texttt{GLITE\_LB\_LOCATION} -- \LB prefix (default: \texttt{/opt/glite} or \texttt{/usr}) -\item \texttt{GLITE\_LB\_LOCATION\_ETC} -- system config directory (default: \texttt{/opt/glite/etc} or \texttt{/etc}) -\item \texttt{GLITE\_LB\_LOCATION\_VAR} -- gLite local state directory (default: \texttt{/opt/glite/var} or \texttt{/var/glite}) -\item \texttt{GLITE\_JP\_LOCATION} -- can be used when JP subsystem location differs from LB (default: empty) -\item \texttt{GLITE\_LB\_HARVESTER\_ENABLED} -- set to \texttt{true} for sending notifications, used mainly for legacy export to MSG publish system (default: \texttt{false}) -\item \texttt{GLITE\_LB\_HARVESTER\_MSG\_OPTIONS} -- additional options for MSG publish (default: \texttt{--wlcg}) -\item \texttt{GLITE\_WMS\_LCGMON\_FILE} -- pathname of file where job state -export data are written for use by lgcmon/R-GMA -(default: \texttt{/var/glite/logging/status.log}). \emph{Note: This feature is now obsolete and only available in \LBver{1.x}.} -\end{itemize} - - -In addition to those, YAIM LB module uses following parameters: -\begin{itemize} -\item \texttt{INSTALL\_ROOT} -- installation root, shouldn't be changed (default: '/opt' or '/') -\item \texttt{GLITE\_LOCATION\_VAR} -- directory for local state files (default: '/opt/glite/var' or '/var/glite') -\item \texttt{GLITE\_USER} -- unprivileged user name (default: 'glite') -\item \textbf{SITE\_NAME} -- site name (mandatory) -\item \textbf{SITE\_EMAIL} -- site email, for cron scripts (mandatory) -\end{itemize} - -Lists are separated by comma. - -\subsubsection{Configuration Files} - -Using \emph{yaim}, you do not need to edit \LB's configuration files for your installation to work. On the other hand, if you cannot use \emph{yaim}, you may configure your \LB server through config files detailed bellow. Since \LBver{3.0} configuration files are located in \texttt{/etc/glite-lb/}. - -\begin{tabularx}{\textwidth}{>{\tt}lX} -glite-lb-authz.conf & Authorization policy, in use since \LBver{2.1}. Extensively explained in Section \ref{inst:authz} (page \pageref{inst:authz}).\\ -log4crc & Logging output configuration, in use since \LBver{2.0}. Explained in Section \ref{inst:comlog} (page \pageref{inst:comlog}).\\ -msg.conf & Messaging plugin and features configuration, in use since \LBver{3.0}. Explained in Section \ref{inst:messaging} (page \pageref{inst:messaging}).\\ -site-notif.conf & Permanent notification registrations to be maintained on the server. Available since \LBver{3.2}. Explained in section \ref{inst:sitenotif} (page \pageref{inst:sitenotif}). -%\\glite-lb-my.cnf & Pre-prepared \emph{MySQL} configuration file, designed to be included in \texttt{my.cnf} by the \texttt{!include} directive. Available since \LBver{3.2}. -\end{tabularx} - -Besides configuration files observed directly by \LB's services, there is a score of other files installed by \LB and used by other system services. They are: - -\newcounter{initdfootnote} -\begin{tabularx}{\textwidth}{>{\tt}lX} -/etc/cron.d/glite-lb-purge.cron & Nightly execution of the \LB purger (see Section \ref{inst:purge}).\\ -/etc/cron.d/locallogger.cron & Prevent stale handle on \texttt{hostcert.pem} by running a \texttt{touch} on it quarter-daily.\\ -/etc/cron.d/glite-lb-notif-keeper.cron & Refresh registration of \LB notifications set up by site admins py regular calls to \texttt{glite-lb-notif-keeper}. Present since \LBver{3.2}\\ -/etc/init.d/glite-lb-bkserverd & Start up the \LB server. Many command line options are hard-coded in the script.\footnotemark\setcounter{initdfootnote}{\thefootnote}\\ -/etc/init.d/glite-lb-harvester & Start up the \LB harvester. Some command line options are hard-coded in the script.\footnotemark[\theinitdfootnote]\\ -/etc/init.d/glite-lb-locallogger & Start up the \LB local logger. Some command line options are hard-coded in the script.\footnotemark[\theinitdfootnote] -\end{tabularx} -\footnotetext{When using \emph{yaim}, these scripts are generated and command line options inserted by \emph{yaim}.} - -\input{https_configuration} - -\subsubsection{Migration to a Different OS Version} -\label{inst:OSmigration} -Migration of a LB server to different machine is possible using -following simple procedure (just file copy of the MySQL database). We -tested the migration from SL4 32bit (mysql 4.1.22-2) to SL5 64bit -(mysql 5.0.45-7). - -Steps: -\begin{itemize} -\item \emph{Prepare a new machine.} The new machine must get the same hostname - as the old machine had. It is a part of job ids stored in the database. -\item \emph{Move data.} Just stop the MySQL server and move - \verb'/var/lib/mysql' data directory directly to the target machine. -\item \emph{(optional) Restore file contexts.} You may need to restore file - contexts in case of enabled SELinux. -\end{itemize} -For example, commands on the target machine: - \begin{verbatim} - service mysqld stop - cd /var/lib - tar xf /tmp/lb.tar - restorecond -R mysql - service mysqld start - \end{verbatim} - -\subsubsection{Migration of database to support transactions} -Started from version 1.4.3 of the \texttt{glite-lb-server} -package, the \LB server introduced optional use of database -transactions for \LB database updates in order to improve their -performace. This feature is switched on by default when underlying -MySQL database uses transactional InnoDB tables. For new -installations, YAIM configuration process will create transactional -database automatically. For existing LB server database the migration -process is not automatically handled. - -Note: If you want to add transactions when migrating to \LBver{2.0 or higher} skip -this section and use \LBver{2.x} migration procedure. The migration of -database to support transactions is included ini that procedure. - -Steps: -\begin{itemize} - \item \emph{Stop the server.} Stop both a \LB server and a MySQL - server. Making a fresh backup copy of database is a good idea. - \item \emph{Database conversion.} Use provided SQL script: - \begin{quote} - \begin{verbatim} -mysql -u lbserver lbserver20 \ - <[/opt/glite]/etc/glite-lb-dbsetup-migrate2transactions.sql - \end{verbatim} - \end{quote} - \item \emph{Start the servers.} MySQL and \LB. Check logs. -\end{itemize} - - -\subsubsection{Migration to \LB 2.x} -\label{inst:migrate20} -The migration process of existing \LB 1.x database to the \LB 2.x is -not handled automatically. The database schema change is required due -to support of merged \LB server and proxy services using single -database, pointers to purged jobs (``zombies'') and other -improvements. - -Warning: There are two types of \LB database based on the fact that -you can have a \LB server or \LB proxy. For more information about \LB -proxy please see \ref{inst:LBproxy} - -Steps: -\begin{itemize} - \item \emph{Stop the server and upgrade to \LB 2.x.} Stop both a \LB - server and a MySQL server. Making a fresh backup copy of database is - a good idea. Do the upgrade to \LB 2.x, optionally you can move the - database to new OS in this step (see \ref{inst:OSmigration}). - \item \emph{Before migration some database tuning is - required.} Especially parameter \texttt{innodb\_buffer\_pool\_size} - needs to be increased, to support bigger transactions. For details - see Section~\ref{inst:db_tuning} - \item \emph{Database type.} Check if you have a \LB server or a \LB - proxy. In the following step you must properly set the switch - \verb'-s' (server) or \verb'-p' (proxy). - \item \emph{Database conversion.} Use provided shell script (with the proper - switch from previous step): - \begin{quote} - \verb'[/opt/glite]/etc/glite-lb-migrate_db2version20 {-s|-p}' - \end{quote} - \item \emph{(Optional) Drop unnecesary index.} This operation is - likely to take a lot of time when applied to large database. - \begin{quote} - \verb'mysql -u lbserver lbserver20 -e "alter table events drop index host"' - \end{quote} - \item \emph{(Optional) Check the \LB indexes.} You may need to add - LastUpdateTime for monitoring services. See \ref{maintain:index} - \item \emph{Start the servers.} MySQL and \LB. Check logs. -\end{itemize} - -This migration procedure is tested in following environment: LB 1.9.x -from RPMs SL4 32bit (mysql 4.1.22-2), LB server node, migration to SL5 -64bit (mysql 5.0.45-7) LB2.0 RPM. - -\subsubsection{Migration to \LB 3.x} -\label{inst:migrate30} -There are no specific configuration changes required when migrating from \LBver{2.x} to \LBver{3.x}. In case you wish to migrate from \LBver{1.x}, follow instructions given in section \ref{inst:migrate20} but upgrade directly to \LBver{3.0} in the first step. - -\emph{Note:} Upgrading from \LBver{2.x} provided by gLite \LB node repository to \LBver{3.0 or higher} provided by the EMI repository has never been tested. - -%\TODO{automated conversion through YAIM ?} - -\subsubsection{Connecting to the Messaging Infrastructure} -\label{inst:messaging} - -As of \LBver{3.0}, the \LB server node becomes a producer of messages, which it delivers into the messaging infrastructure. - -Correct broker settings are infered from BDII by YAIM on configuration. By default, messaging-related settings are stored in file: - - \begin{quote} - \begin{verbatim} -[/opt/glite]/etc/glite-lb/msg.conf - \end{verbatim} - \end{quote} - -Overall, \texttt{msg.conf} specifies the following information: - -\begin{itemize} -\item The messaging plugin to be used by the notification interlogger. Plugin settings should be correct \emph{ab initio} and do not require modification by administrators. -\item Broker settings (attribute \texttt{broker}). They may require an adaptive change in case the currently configured broker disappears and automatic checks fail to switch the settings to another one on time. -\item Permissible topic title prefixes (attribute \texttt{prefix}). Registrations for delivery to topics not matching the prefix will be rejected. In case no prefix is specified, \LB applies the default EGI prefix: \texttt{grid.emi.} -\end{itemize} -Note: Current broker and prefix settings can be retrieved from the \LB server by any authenticated user reading the server's configuration page -- see Section \ref{s:findbroker}. - - -\subsubsection{Messaging: Persistent Registration for Notifications} -\label{inst:sitenotif} - -Starting with \LBver{3.2} there is a mechanism for site admins to set up and maintain ``permanent'' registrations for notifications, which should be always kept active on the server. A maintainer script regularly checks existing registrations, extends their validity, and sets up new registrations. - -The process is governed by a separate configuration file \texttt{/etc/glite-lb/site-notif.conf}. The format of the file is simple, one line per registration, with each line giving a single-word handle and a list of arguments to use for registration.\footnote{Command \texttt{glite-lb-notify} is used to make the registrations. See \cite{lbug} for applicable arguments.} - -For instance the following line in \texttt{/etc/glite-lb/site-notif.conf}: - -\begin{verbatim} -testnotif --state running -c -N -a x-msg://grid.emi.lbexample -\end{verbatim} - -\indent{}will set up and maintain registration for messages to be generated whenever a job changes state (\texttt{-c}) to \emph{running} (\texttt{-{}-state running}). Messages will be delivered to topic \texttt{grid.emi.lbexample} and user identification (DN) will be replaced with a hash (\texttt{-N}). The word \texttt{testnotif} is just a plain-text handle. - -In another practical example, the following line in \texttt{/etc/glite-lb/site-notif.conf}: - -\begin{verbatim} -voDboard -T -v testvo -a x-msg://grid.emi.testvo.dashboard -\end{verbatim} - -\indent{}will set up and maintain registration for messages to be generated whenever a job belonging to VO \emph{testvo} (\texttt{-v testvo}) reaches a terminal state (\texttt{-T}),\footnote{Terminal states are recognized by the server. As of \LBver{3.2} they are: \emph{cleared}, \emph{aborted}, \emph{canceled} and \emph{purged}.} and delivered to topic \texttt{grid.emi.testvo.dashboard}. Again, the word \texttt{voDboard} is simply a plain-text handle. - -The maintainer script \texttt {glite-lb-notif-keeper} runs regularly and makes sure that registrations do not expire and that the messaging infrastructure keeps receiving them. In case of a listener (messaging broker) being unavailable for a prolonged period of time, the registration is terminated to prevent build-up of undelivered messages. A new registration will be created next time round, and if the listener comes up before then, normal operation will resume. - -\paragraph{Applying changes} After changing the \texttt{site-notif.conf} file, the simplest option is to do nothing and wait for \emph{cron} to invoke the maintainer script \texttt{glite-lb-notif-keeper}. You may also run the script manually from the command line. The script handles newly added registrations as well as registrations whose conditions have changed. It does not deal with registrations (lines) removed from the configuration file, though. Those are simply left to expire, typically 12 hours after the latest renewal. In case immediate removal is required, you need to drop the existing registration using \texttt{glite-lb-notify drop}.\footnote{Note that the server's identity is used to create the registrations, i.e. that the server is the owner. You may need to supply the server's identity to be able to remove a problematic registration.} - -\subsubsection{Index configuration} - -Initial YAIM configuration creates \LB indexes typically, -the actual configuration depends on required features (\eg\ RTM job monitoring). -See Section~\ref{maintain:index} for instructions -on changing \LB server index configuration afterwards in order -to meet specific needs. - -\subsubsection{Authorization policy} -\label{inst:authz} -The \LB server applies a quite strict access control policy on the -operations provided to the clients to ensure a sufficient level of data -protection. By default, the information about a job is only available to the -owner of the job. The job owner can specify an ACL assigned to their jobs -specifying permissions granted to other users so that they could access the -job records, too. More information about the ACL management can be found in -the \LB Users' guide. - -Apart from using the ACLs, the \LB server administrator can also set a -server-level policy granting rights to perform particular operation on \LB -server that are considered privileged. -For example, a privileged -user can access data about jobs owned by other users, bypassing the default -\LB access control mechanism. \LBver{2.1} specifies several categories of -rights that can be granted to the users: - -\begin{itemize} -\item \verb'ADMIN_ACCESS' -\item \verb'READ_ALL' -\item \verb'PURGE' -\item \verb'STATUS_FOR_MONITORING' -\item \verb'GET_STATISTICS' -\item \verb'REGISTER_JOBS' -\item \verb'LOG_WMS_EVENTS' -\item \verb'LOG_CE_EVENTS' -\item \verb'LOG_GENERAL_EVENTS' -\item \verb'GRANT_OWNERSHIP' (since \LBver{3.0}) -\item \verb'READ_ANONYMIZED' (since \LBver{3.2}) -\end{itemize} - -The first action disables all authorization checks. The next four categories concern with acquring data from the \LB -server, while the other ones make it possible to define a web of trusted sources -passing events to the \LB server. - -\verb'ADMIN_ACCESS' is the most powefull privilege allowing to bypass any -authorization checks on the server. It replaces the superuser role, which -existed in \LBver{2.0} and older. Note, that the \verb'--super-users' -command-line option still exists and translates internally into granting -\verb'ADMIN_ACCESS'. - -\verb'READ_ALL' enables to access all job information stored on the server. -\verb'PURGE' grants the privilege to ask for purging the \LB database. The \LB -server's identity is automatically assigned the \verb'READ_ALL' and -\verb'PURGE' so that these operations are available \eg to a cron script -running on \LB node. - -When granted to a user, the \verb'STATUS_FOR_MONITORING' right allows the user to -query statuses of all jobs maintaned by the server, however only a small -subset of the status fields is returned to back. For example, the caller -does not obtain the identity of the job owner. The purpose of this right is -to provide a way to collect information necessary for overall monitoring -while preserving a basic level of privacy. - -\verb'GET_STATISTICS' allows its bearers to query for on-line statitistics -generated by the \LB server. See~\ref{maintain:statistics} for more -information about the purpose of the function. - -\verb'READ_ANONYMIZED' allows reading access to job information on the server, -but only in an anonymized form (user identification hashed). - -\LBver{1.x} allowed anyone possessing a trusted digital certificate to send an -arbitrary event to the \LB server. While enabling an easy setup, such an -arrangement does not comply with some contemporary requirements, \eg job -traceability, since the data could be distorted by a malicious user. In order -to strengthen the trustworthiness of the data provided, the \LBver{2.1} -server has introduced an authorization mechanism to control the originators -of events. The authorization model presumes a set of trusted components -that are only allowed to send ``important'' events, while other types can be -logged from any source. The \verb'REGISTER_JOBS' authorization category -specifies clients allowed to register jobs with the \LB server. The -\verb'LOG_CE_EVENTS' category makes it possible to define a set of trusted -CEs that are allowed to log events originating from within sites (in -particular \verb'RUNNING', \verb'REALLYRUNNING', and \verb'DONE'). -Similarly, the \verb'LOG_WMS_EVENTS' category defines a web of trusted WMS -nodes. The \verb'LOG_GENERAL_EVENTS' category comprises events that can be -sent from any place on the grid, namely \verb'CURDESC', \verb'USERTAG', and -\verb'CHANGEACL'. It is important to understand that these access control -rules provides additional level to the existing authorization routines. -In particular, being granted the \verb'LOG_GENERAL_EVENTS' right is not sufficient to -e.g. change ACLs on jobs of other people and obtain an access to the job information. - -As of \LBver{3.0} it is possible for the job owner to hand over the ownership -of the payload to another user, which eases handling \eg of pilot jobs. In -order to set the payload owner, the job owner must log a -\verb'GrantPayloadOwnership' event, where the identity of the new -payload owner is introduced. The event can only originate from loggers -described by the \verb'GRANT_OWNERSHIP' category of the policy file. More -information and an example of ownership setting is given in the \LB Users' -guide. - -The \LB policy is specified in a policy configuration file that must be given -in the server configuration. Specifying the policy file also triggers the -enforcement of access policy rights, especially the ones describing the event -sources. If the policy is not enabled, the \LB server accepts events from any -logger with a trusted certificate. The format of the policy is a subset of the -Simplified policy langauge introduced by the Argus gLite authorization -service\footnote{\url{https://twiki.cern.ch/twiki/bin/view/EGEE/SimplifiedPolicyLanguage}}. -Unlike the Argus language, the \LB policy supports only certificate subject -names and VOMS fully qualified attribute names (FQANs) to describe the users -and do not support 'deny'ing of rights. Also, general regular expressions -cannot be used in the argument, only the \verb'".*"' wild card is supported. An -example of the policy file follows: - -\begin{lstlisting} -resource "LB" { - action "ADMIN_ACCESS" { - rule permit { - subject = "/DC=cz/DC=cesnet-ca/O=CESNET/CN=Daniel Kouril" - } - rule permit { - fqan = "/vo/Role=Manager" - } - } - action "STATUS_FOR_MONITORING" { - rule permit { - fqan = "/vo/monitoring" - } - rule permit { - fqan = "/TEST/rtm" - } - } - action "LOG_WMS_EVENTS" { - rule permit { - subject = "/DC=cz/DC=cesnet-ca/O=CESNET/CN=wms01.cesnet.cz" - } - } - action "LOG_GENERAL_EVENTS" { - rule permit { - subject = ".*" - } - } - action "REGISTER_JOBS" { - rule permit { - subject = ".*" - } - } - action "GRANT_OWNERSHIP" { - rule permit { - fqan = "/VO/Pilot_job_factory" - } - } -} -\end{lstlisting} - -After changing the file, the server has to be restarted. - -In order to provide yet additional level of authorization, the LCAS -schema\cite{lcas} is still used in the server. If enabled in configuration, -it can be used to specify more general settings using the standard LCAS -modules and e.g. blacklist particular users. The standard LCAS documentation -should be followed to set up the LCAS layer properly. - -% \subsubsection{Notification delivery}\TODO{co tu ma byt?} - -\subsubsection{Export to R-GMA} - -\emph{Note: This feature is now obsolete and only available in \LBver{1.x}.} - -{\sloppy -\LB server can export information on job state changes to R-GMA infrastructure through \verb'lcgmon' -in real time. This export is enabled by YAIM by default and uses \verb'GLITE_WMS_LCGMON_FILE' -environmental variable to retrieve name of log file which is to be consumed by \verb'lcgmon' (usually -\verb'/var/glite/logging/status.log'). The log file has to be rotated regularly. - -} - -\subsubsection{Data backup} -\label{inst:backup} - -Data stored \LB server can be backed up using backups of underlaying database or using \verb'glite-lb-dump' utility. -The latter has some advantages, see Section~\ref{run:dump} for details. - -\subsubsection{Purging old data} -\label{inst:purge} - -Initial YAIM configuration creates a cron job which runs once a day and purges old -data (jobs in Cleared state after two days, Aborted and Cancelled after 15 days, and other jobs -after 60 days of inactivity). It is recommended to run the cron jobs more often (in order to purge less jobs -during single run) if event queue backlogs form in client WMS machines when the purging cron jobs is running. -For details on setting job purge timeouts, see Sect.~\ref{run:purge} - - -\subsubsection{Exploiting parallelism} - -\LB server uses 10 worker processes (threads) to handle active client accesses (inactive connections are killed -when necessary). Each worker process uses separate connection to database server. Number of worker processes -can be changed by adding \verb'--slaves' parameter with desired number to servers command line -using \verb'GLITE_LB_SERVER_OTHER_OPTIONS' variable. - -\subsubsection{Tuning database engine} -\label{inst:db_tuning} - -In order to achieve high performance with LB server underlaying MySQL -database server has to be configured reasonably well too. -Default values of some MySQL settings are likely to be suboptimal -and need tuning, especially for larger machines. -These are MySQL configuration variables (to be configured in \texttt{[mysqld]} -section of \texttt{/etc/my.cnf}) that need tuning most often: -\begin{itemize} -\item \texttt{innodb\_buffer\_pool\_size} -- size of database memory pool/cache. -It is generally recommended to set it to aroung 75\% of RAM size -(32bit OS/MySQL versions limit this to approx. 2GB due to address space -constraints). - -\item \texttt{innodb\_flush\_log\_at\_trx\_commit} -- frequency of flushing to disk. -Recommended values include: -\begin{itemize} -\item 1 (default) -- flush at each write transaction commit; relatively -slow without battery-backed disk cache but offers highest level of data safety -\item 0 -- flush once per second; fast, use if loss of latest updates on MySQL -or OS crash (e.g. unhandled power outage) is acceptable (database remains consistent) -\end{itemize} - -\item \texttt{innodb\_log\_file\_size} -- size of database log file. Larger values -save some I/O activity, but also make database shutdown and crash recovery slower. -Recommended value: 50MB. Clean mysqld shutdown and deletion of log files -(\texttt{/var/lib/mysql/ib\_logfile*} by default) is necessary before change. - -\item \texttt{innodb\_data\_file\_path} -- path to main database file. File on -disk separate from OS and MySQL log files (\texttt{innodb\_log\_group\_home\_dir} variable, -\texttt{/var/lib/mysql/} by default) is recommended. - -\end{itemize} - -\subsection{\LB proxy} -\label{inst:LBproxy} -% TODO: Describe LB Proxy migration here. - - -All necessary configuration of \LB proxy is done by YAIM, -and described with gLite WMS installation elsewhere. -Previous \LB server section applies to merged server+proxy setups (since \LBver{2.0}). - -A~special care must be taken when an existing \LB proxy database -is migrated to \LBver{2.x}. -In general, this is not a~typical scenario -- \LBver{2.x} server in proxy mode -on WMS node is introduced with a~major WMS upgrade, and it is expeced -to be installed from scratch rather than migrated, preserving \LB proxy data. - -If the migration is really needed, \verb'glite-lb-migrate_db2version20' -script should be run with~\verb'-p' (Sect~\ref{inst:migrate20}). -However, the \LB database name remains \verb'lbproxy' while -the \LBver{2.x} binaries expect unified \verb'lbserver20' by default. -Because renaming a~MySQL database is a~non-trivial, error prone task, -the recommended workaround is to add the following variable setting - -\verb'GLITE_LB_SERVER_OTHER_OPTIONS="--mysql lbserver/@localhost:lbproxy"' - -into the gLite startup environment (\verb'[/opt/glite]/etc/profile.d') instead. -This setting makes \LB server use the \verb'lbproxy' database instead of the default. - -\subsection{\LB logger} - -All necessary configuration of normal \LB logger is done by YAIM. - -\subsection{\LB harvester} - -\LB Harvester gathers information about jobs from \LB servers using efficient -\LB notification mechanism. It manages notifications and keeps them in -a persistent storage (file or database table) to reuse later on next launch. -It takes care of refreshing notifications and queries \LB servers back when -some notification expires. - -It is not intended for normal usage. You will need Harvester for sending notifications to MSG publish infrastructure, but only for older \LB server releases (gLite 3.1.x, support since gLite 3.1.19). Example of YAIM configuration: - -\begin{verbatim} -GLITE_LB_HARVESTER_ENABLED=true -GLITE_LB_HARVESTER_MSG_OPTIONS="--wlcg-topic=org.wlcg.usage.jobStatus - --wlcg-config=/etc/msg-publish/msg-publish.conf - --wlcg-binary=/usr/bin/msg-publish" -\end{verbatim} - -Since gLite 3.2.1, \LB Harvester is not needed for MSG publish. Notifications are reliably delivered by interlogger instead. Delivery can be switched on in this case by \texttt{GLITE\_LB\_MSG\_ENABLED} and \texttt{GLITE\_LB\_MSG\_BROKER} YAIM options. - -\subsection{Smoke tests} - -Thorough tests of \LB, including performance measurement, are -covered in the \LB Test Plan document \cite{lbtp}. -This section describes only elementary tests that verify basic -functionality of the services. - -The following test description assumes the \LB services installed -and started as described above. - -\def\req{\noindent\textbf{Prerequisities:}\xspace} -\def\how{\noindent\textbf{How to run:}\xspace} -\def\result{\noindent\textbf{Expected result:}\xspace} - -\subsubsection{Job registration} - -Register a~new job with the \LB server and check that its status is -reported correctly. - -\req Installed glite-lb-client package, valid user's X509 credentials, -known destination (address:port) of running \LB server. -Can be invoked from any machine.\newcounter{examplesfootnote} -\footnote{Example scripts or binaries used here can be found either -in \texttt{/opt/glite/examples} (if installed from a LB node repository) or -\texttt{/usr/lib64/glite-lb/examples} (if installed from the EMI repository). Please note that these examples are primarily intended for developers, and their use (e.g. command line options) is not covered by documentation execpt for these few specific use cases.}\setcounter{examplesfootnote}{\thefootnote} - -\how -\begin{quote} -\texttt{glite-lb-job\_reg -m} \emph{server\_name:port} \texttt{-s Application} -\end{quote} -A~new jobid is generated and printed. Run -\begin{quote} -\verb'glite-lb-job_status' \emph{jobid} -\end{quote} - -\result -The command should report ``Submitted'' job status. - -\subsubsection{Logging events via lb-logger} - -\label{smoke-log} - -Send several \LB events, simulating normal job life cycle. -Checks delivery of the events via \LB logger. - -\req Installed package \texttt{glite-lb-client}, valid X509 credentials, -known destination (address:port) of running \LB server. -Must be run on a~machine where \texttt{glite-lb-logger} package is set up and running.\footnotemark[\theexamplesfootnote] - -\how -\begin{quote} -\texttt{glite-lb-running.sh -m} \emph{server\_name:port} -\end{quote} - -The command prints a~new jobid, followed by diagnostic messages as the events are logged. -Check the status of the new job with -\begin{quote} -\verb'glite-lb-job_status' \emph{jobid} -\end{quote} - -\result -Due to asynchronous event -delivery various job states can be reported for limited time (several seconds). -Finally the -``Running'' status should be reached. - -\subsubsection{Logging events via lb-proxy} - -Send events via \LB proxy. Checks the proxy functionality. - -\req Running \LB proxy, in standalone package for \LBver{1.x}, or -\LB server running with \verb'-P' (proxy only) or \verb'-B' (both server and proxy) -options.\footnotemark[\theexamplesfootnote] - -\how Similar to Sect.~\ref{smoke-log}: -\begin{quote} -\verb'glite-lb-running.sh -x -m ' \emph{server\_name:port} -\end{quote} - -And check with: -\begin{quote} -\verb'glite-lb-job_status -x /tmp/lb_proxy_server.sock' \emph{jobid} -\end{quote} - - -\subsubsection{Notification delivery} - -Register for receiving notifications, and log events which trigger -notification delivery. This checks the whole notification mechanism. - -\req Package \texttt{glite-lb-client} installed, valid user credentials, environment variables (namely \texttt{GLITE\_WMS\_NOTIF\_SERVER}) set to point to the \LB server. - -\how -First register for notifications. Option \texttt{-O}\footnote{Supported since \LBver{2.0}. For older versions, you need to use option \texttt{-j} and give at least one JobID of a job that already exists!} allows you to register for notifications on all your jobs: -\begin{quote} -\texttt{glite-lb-notify new -O} -\end{quote} -This prints out a notification ID (\emph{NotifID}) and validity information. Continue by listening for notifications, using that ID: -\begin{quote} -\texttt{glite-lb-notify receive} \emph{NotifID} -\end{quote} -Then, using a different console, register at least one job and generate events. Make sure you use the same Identity used to register for notifications in the first place. -\begin{quote} -\texttt{glite-lb-running.sh -m} \emph{server\_name:port} -\end{quote} - -\result -The listener (\texttt{glite-lb-notify}) should print out notifications (JobID, state and owner), showing progressive changes of job state as events arrive to the server. There will be multiple notifications showing the same state. That is normal since not all events result in a job state change. If you want to see notifications only for job state changes, use option \texttt{-c} on registration. - -For more test scenarios, see notification-related sections in~\cite{lbug,lbtp}. Especially \cite{lbug} has a comprehensive set of examples using the \texttt{glite-lb-notify} command. diff --git a/org.glite.lb.doc/src/LBAG-Introduction.tex b/org.glite.lb.doc/src/LBAG-Introduction.tex deleted file mode 100644 index 86a1e96..0000000 --- a/org.glite.lb.doc/src/LBAG-Introduction.tex +++ /dev/null @@ -1,123 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\section{Introduction} - -\subsection{Service overview} - -A~fairly complete overview of the \LB service is given in \LB User's Guide~\cite{lbug}. -This section is a~brief excerpt only, providing minimal information necessary for -understanding the rest of this document. - -The task of \LB is gathering \emph{\LB events} from various grid middleware components -(see Figure~\ref{f:comp-gather}) -and delivering the events to \LB servers where users can query for them -(Figure~\ref{f:comp-query}). -%Figure~\ref{f:comp-gather} shows all principal components involved in the event gathering. - -\begin{figure}[ht] -\centering -\includegraphics[width=.67\hsize]{LB-components-gather} -\caption{Components involved in gathering and transfering \LB events} -\label{f:comp-gather} -\end{figure} - -\begin{figure}[ht] -\centering -\includegraphics[width=.67\hsize]{LB-components-query} -\caption{\LB queries and notifications} -\label{f:comp-query} -\end{figure} - -%\TODO{uplne to same (ty components) mame i v UG; chceme to tady duplikovat? -%vlast kdyz v odstavci nad tim se pise, ze uz je to popsane v UG} -\input components - - -\subsection{Deployment scenarios} - -%\TODO{salvet} - -%\TODO{jakou zatez ktery snese} - -\subsubsection{Standalone \LB server} -\label{deploy-stand} - -This is a recommended standard production deployment. - -\LB server is installed on a~dedicated machine, -where no other grid services (gLite WMS in particular) run. -Hence user queries and notification processing are offloaded -from the WMS, not affecting its performance directly. - -In this setup the full reported performance is achieved, -currently up to several hundreds thousands jobs per day, with the goal -of one million, see~\cite{lbtp}. - -Further performance can be gained with clustering $M$ WMSs and $N$ \LB{}s -while configuring all WMSs to distribute jobs to the \LB{}s uniformly. -In this setup bottlenecks emerging from \LB proxy to \LB server serialized -communication are likely to be eliminated. -The optimal $M:N$ ratio strongly depends on the rate of user queries -and number of evaluated notifications, -and it must be determined empirically for each specific installation. - -\begin{figure}[ht] -\centering -\includegraphics[width=.9\hsize]{LB-components} -\caption{\LB deployment -- overall picture} -\label{f:comp} -\end{figure} - - -\subsubsection{Hybrid \LB server-proxy} -\label{deploy-hybrid} - -\LB server runs on the WMS node, in combined server-proxy mode, -serving both user queries and supporting WMS. -Total processing requirements for a~single jobs are lower -(unlike with separated proxy and server, job state is computed and stored only once). - -On the other hand, processing user queries is done on the WMS node, -limiting its performance then. -This setup is suitable for smaller installations with a~single (unclustered) -WMS, expected load of upto 30--50 kjobs/day, and not very heavy user-generated -load. - -The functionality is available since \LBver{2.0}. - -\begin{figure}[ht] -\centering -\includegraphics[width=.9\hsize]{LB-components-LB-WMS} -\caption{\LB deployment with combined server-proxy} -\label{f:comp-hybrid} -\end{figure} - - -\subsubsection{\LB server on WMS node} - -\textbf{This setup is obsolete and very inefficient, hence discouraged.} - -Ancient \LB versions ($<$\,1.2), where \LB proxy was not available yet, -used to be frequently installed with \LB server on the WMS machine. -With the introduction of \LB proxy it makes little sense anymore -but, unfortunately, this setup still persists at some sites. -Its consequence is doubling both CPU and disk load, yielding observable -performance degradation. - -Large production sites should consider standalone \LB server (Sect.~\ref{deploy-stand}) -instead, while for smaller sites the hybrid setup (Sect.~\ref{deploy-hybrid}) may -be more appropriate. diff --git a/org.glite.lb.doc/src/LBAG-Running.tex b/org.glite.lb.doc/src/LBAG-Running.tex deleted file mode 100644 index 56d19a3..0000000 --- a/org.glite.lb.doc/src/LBAG-Running.tex +++ /dev/null @@ -1,683 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\section{Maintenance} - -\subsection{Changing default settings} -All configurable settings of the \LB daemons (network and local sockets, -file paths, modified behaviour etc.) can be set with specific command line -options. -In the following only relevant options are discussed whenever appropriate. -See specific manual pages for complete reference. - -\subsection{\LB server and proxy} - -This section deals with several typical but more peculiar tasks -that need more verbose description. -It is complemented with the full commands reference that is provided -as standard manual pages installed with the \LB packages. - -\subsubsection{Standard and debug logs} - -In normal operation \LB server sends error messages to syslog. -Informational messages are generally avoided in order to prevent syslog congestion. - -Since \LBver{2.1}, the service implements a common logging format\footnote{\url{http://en.wikipedia.org/wiki/Common_Log_Format}} (see section\,\ref{inst:comlog}, page\,\pageref{inst:comlog}). - -For \LBver{2.0 and lower}, the following instructions apply: - -\begin{sloppypar} -When tracing problems, GLITE\_LB\_SERVER\_DEBUG environment variable can be set to -non-empty value when starting the service. -Then verbose log \$GLITE\_LOCATION\_VAR/lb.log -(as well as \$GLITE\_LOCATION\_VAR/notif-il.log eventually when notifications are enabled). -Beware that these can grow huge easily. -\end{sloppypar} - -\textbf{\LBver{1.x} only:} not available for \LB proxy, \verb'-d' and output redirection -have to be added manually if necessary. - -\subsubsection{Changing index configuration} -\label{maintain:index} - -\LB server only (\LB proxy database is neither so huge nor accessed directly by users). - -% full-scan skodi, LB se tomu brani -Inefficient queries, yielding full scan of \LB database tables (up to millions of tuples) would degrade server performance. -Therefore \LB does not allow arbitrary queries in general -(server option \verb'--no-index' can change this behaviour). -On the contrary, a~query has to hit a~\emph{job index}, build on one or -more job attributes. -It is left up to the specific \LB server administrator to decide -which job attributes are selective enough to be indexed and allow queries -(\eg for many-users communities job owner can be a~sufficient criterion; -for others, where only a~few users submit thousands of jobs, it is not). - -% indexy -- implementace jako extra sloupce => zmeny offline, konfigurace -% olizovana z DB -Technically, job indices are implemented via dedicated columns -in a~database table. -These columns and their indices are scanned by the \LB server on startup, -therefore there is no specific configuration file. -Changing the index configuration is rather heavyweight operation -(depending on the number of jobs in the database), it performs -updates of all tuples in general, and it should be done when the server is not -running. - -% utilitka bkindex -- pouziti -Indices are manipulated with a~standalone utility \verb'glite-lb-bkindex' -(see its man page for complete usage reference). -A~general sequence of changing the indices is: -\begin{enumerate} -\item stop the running server -\item retrieve current index configuration -\begin{quote} -\verb'glite-lb-bkindex -d >index_file' -\end{quote} -\item edit \verb'index_file' appropriately -\item re-index the database (it may take long time) -\begin{quote} -\verb'glite-lb-bkindex -r -v index_file' -\end{quote} -\verb'-r' stands for ``really do it'', \verb'-v' is ``be verbose'' -\item start the server again -\end{enumerate} - -% format vstupniho souboru -The index description file follows the classad format, having the following grammar: -\begin{quote} -\emph{IndexFile} ::= [ JobIndices = \{ \emph{IndexList} \} ] \\ -\emph{IndexList} ::= \emph{IndexDef} $|$ \emph{IndexDef}, \emph{IndexList} \\ -\emph{IndexDef} ::= \emph{IndexColumn} $|$ \emph{ComplexIndex} \\ -\emph{IndexColumn} ::= [ type = "\emph{IndexType}"; name = "\emph{IndexName}" ]\\ -\emph{ComplexIndex} ::= \{ \emph{ColumnList} \} \\ -\emph{ColumnList} ::= \emph{IndexColumn} $|$ \emph{IndexColumn}, \emph{ColumnList} -\end{quote} - -where eligible \emph{IndexType}, \emph{IndexName} combinations are given -in Tab.~\ref{t:indexcols}. -A~template index configuration, containing indices on the most frequently -used attributes, can be found in\\ \texttt{[/opt/glite]/etc/glite-lb-index.conf.template}.\footnote{The \texttt{/opt/glite} prefix applies for \LB installed from gLite's \LB node repository.} - - -\begin{table} -\begin{center} -\begin{tabularx}{.9\hsize}{|l|l|X|} -\hline -\emph{IndexType} & \emph{IndexName} & description \\ -\hline -system & owner & job owner \\ - & destination & where the job is heading to (computing element name) \\ - & location & where is the job being processed \\ - & network\_server & endpoint of WMS \\ - & stateEnterTime & time when current status was entered \\ - & lastUpdateTime & last time when the job status was updated \\ -\hline -time & \emph{state name} & when the job entered given state (Waiting, Ready, \dots) \\ -\hline -user & \emph{arbitrary} & arbitrary user tag \\ -\hline -\end{tabularx} -\end{center} -\caption{Available index column types and names} -\label{t:indexcols} -\end{table} - -% super user muze vsechno - -\subsubsection{Multiple instances} - -% lze to, i nad jednou databazi, zadna automaticka podpora - -Specific conditions (\eg debugging, different authorization setup, \dots) -may require running multiple \LB server instances -on the same machine. -Such setup is available, however, there is no specific support in automated -configuration, the additional non-default server instances must be run manually. - -The other server instance must use different ports (changed with \verb'-p' -and \verb'-w' options), as well as use different pid file (\verb'-i' option). - -The servers may or may not share the database (non-default is specified -with \verb'-m')% -\footnote{Even when sharing the database, the servers are still -partially isolated from -one another, \eg a~job \url{https://my.machine:9000/xyz} cannot be queried -as \url{https://my.machine:8000/xyz}. -However, due to implementation internals, the second job cannot be registered.}. - -Though it may have little sense to run multiple \LB proxy instances, it is possible too. -Non-default listening socket have to be specified via \verb'-p' option then. - - - -\subsubsection{Backup dumps} -\label{run:dump} - -\LB server only, not supported by proxy. - -(This functionality should not be confused with per-job dumps, Sect.~\ref{inst:purge} and \ref{run:purge}) - -Besides setting up \LB server database on a~reliable storage or -backing it up directly (Sect.~\ref{inst:backup}) -\LB server supports backing up only incremental changes in the data. -Advantages of this approach are lower volume of data to be backed up, -and possibility to load them to another instance (\eg for heavyweight -queries which should not disturb normal operation), disadvantage is -a~more complex and more fragile setup. - -Using an external utility \verb'glite-lb-dump' (typical invocation is with -a~single option \verb'-m' \emph{server\_name:port}, see man page for -details) the server is triggered to dump events, which arrived in -a~specified time interval, into a~text file. (Default interval is from last -dump till the current time.) - -\verb'glite-lb-dump' is a~standalone client program, however, -the events are stored at server side (\ie not transferred to the client, -due to performance reasons), -in a~uniquely named text -file prefixed with the value of \verb'-D' server option. This kind of dump -contains events according to their arrival time, regardless of jobs they belong -to. - -It is sufficient to run the dump regularly (from a~cron job), with a~frequency -matching an acceptable risk of loosing data (several hours typically), and back -up the resulting dump files. - -In the event of server crash, its database should be recreated empty, -and the server started up. -Then the dump files can be loaded back with complementary -\verb'glite-lb-load' utility. - -Server privileges granting \verb'ADMIN_ACCESS' (see section~\ref{inst:authz}) are required to run \verb'glite-lb-dump' and \verb'glite-lb-load'. -Dumping the events does not interfere with normal server operation. - -This backup strategy can interfere with too aggressive setting of old -data purging (Sect.~\ref{run:purge}), -If the purging grace period is shorter than the dump interval, -events may get purged before they are captured by the backup dump. -However, this interference is unlikely (reasonable purge grace period -is several times longer than dump period), -and it is not fatal in general (data were purged on purpose either). - -\subsubsection{Purging and processing old data} -\label{run:purge} - -Primary purpose of the LB purge operation is removal of aged data from LB database. This is necessary in -production in order to prevent ever-increasing database and sustain reasonable -performance of the server. Therefore the purge should be invoked periodically. - -The purge operation has additional important ``side effect'' -- dumping the -purged data into a plain text file. These dumps can be archived ``as is'' or -uploaded to Job Provenance. - -\paragraph{Purge setup} - -The purge operation itself is performed by a~running \LB server -(there is no need to shut it down, then). -However, it is triggered with \verb'glite-lb-purge' client command -(complete usage reference is given in its man page). -A~typical invocation specifies \LB server to purge (\verb'-m' option), -and purge timeouts (grace periods) for several job states -- options -\verb'-a' (aborted), \verb'-n' (canceled), \verb'-c' (cleared), and -\verb'-o' (other). \LB versions 2.0 supports also \verb'-e' (done) option. -A~job falling in one of the four categories is purged when it has not been -touched (\ie an event arrived) for time longer than the specified category -timeout. -Suggested values are several days for aborted and canceled jobs, -and one day for cleared jobs, however, the values may strongly vary -with \LB server policy. - -Optionally, \verb'-s' purge command option instructs the server to -dump the purged data into a~file at the server side. -It's location (prefix) is given by \verb'-S' server option, -the purge command reports a~specific file name on its output. - -It is recommended (and the default YAIM setup does so, via -the \verb'glite-lb-export.sh' wrapper) to run the purge -command periodically from cron. - -Server privileges granting \verb'ADMIN_ACCESS' (see section~\ref{inst:authz}) are required to run \verb'glite-lb-purge'. - -If the server database has already grown huge, the purge operation can take -rather long and hit the \LB server operation timeout. At client side, \ie the -glite-lb-purge command, it can be increased by setting GLITE\_WMS\_QUERY\_TIMEOUT -environment variable. -Sometimes hardcoded server-side timeout can be still reached. In either case the -server fails to return a correct response to the client but the purge is done anyway. - -\LB proxy purges jobs automatically when they reach a~state ensuring that WMS will -neither query nor log events to them anymore. -Therefore routine purging is not required theoretically. -However, frozen jobs which never reach such a~state may occur in an unstable environment, -and they may cumulate in \LB proxy database for ever. -Therefore occasional purging is recommended too. -\LBver{2.x} supports \verb'-x' option of \verb'glite-lb-purge', allowing -to purge \LB proxy database too. -With \LBver{1.x} the emergency purge procedure described bellow is the only option. - -\paragraph{Emergency purge} - -When regular purge was not invoked for some time, it may happen that -the database grows huge and the regular (on-line) purge fails. -In order to work around such situation we provide an off-line emergency -purge script \verb'glite-lb-bkpurge-offline.sh' - -The script accepts the same \verb'-acno' options, and adds \verb'-d' for ``done'' jobs. -Via \verb'-p' also \LB proxy database can be purged (all \LB versions). - -On startup, a~warning message is printed and interactive confirmation -requested. -Re-check that \LB server (proxy) is not running, and carry on only when you -know what you are doing. - -\paragraph{Post-mortem statistics} - -Once a job is purged from the database, all important data about the job can be -processed offline from the corresponding dump file. The idea of post-mortem -statistics is the following: - -\begin{itemize} -\item LB server produces dump files (during each purge on regular basis), -see LB server startup script; option \verb'-D / --dump-prefix' of \verb'glite-lb-bkserverd', -\item these dumps are exported for the purposes of JP also on regular basis, -see LB/JP deplyment module; option \verb'-s/ --store' of \verb'glite-lb-lb_dump_exporter', -\item it depends on the LB server policy if dumps in this directory are used for -the statistics purposes or all files are hardlinked for example to a different -directory -\item general idea is such that data are available for statistics server that downloads -and removes dumps after download! Dump files are then processed on the statistics -server. -\end{itemize} - -What needs to be done on the LB server: -\begin{itemize} -\item \verb'glite-lb-bkserverd' and \verb'glite-lb-lb_dump_exporter' running -\item \verb'gridftp' running (allowing statistics server to download and remove files from -a given directory -\end{itemize} - - -What needs to be done on the statistics server: -\begin{itemize} -\item \verb'glite-lb-utils' package installed -\item download and remove files from the LB server -see \verb'glite-lb-statistics-gsi.sh' (shell script in the examples directory) -\item process dump files using the \verb'glite-lb-statistics' tool -see \verb'glite-lb-statistics.sh' (shell script in the examples directory) -\end{itemize} -all scripts are supposed to be run from a crontab. - - -\paragraph{Export to Job Provenance} - -An important, though currently optional, processing of \LB dumps -is their upload to the Job Provenance service for permanent preservation -of the data. - - -When enabled (via configuration environment variables, see bellow), -the export is done in two steps: -\begin{itemize} -\item \verb'glite-lb-export.sh' wrapper script, after calling \verb'glite-lb-purge', breaks up the resulting dump file on a~per-job basis. -The individual job dump files are stored in a~dedicated spool directory. -\item \verb'glite-jp-importer' daemon (installed optionally in glite-jp-client.rpm) checks the spool directory periodically, -and tries to upload the files into JP. -\end{itemize} - -Details, including the configuration variables, are covered at the following -wiki page: - -\url{http://egee.cesnet.cz/mediawiki/index.php/LB_purge_and_export_to_JP}. - -\paragraph{Persistent Information on Purged Jobs (``Zombies'')} - -Since \LB version 2.0, the JobID of a purged job is not fully discarded but stored in a separate table. A query for the status of such job returns \emph{Identifier removed}.\footnote{As of \LB\,3.0. In 2.0 and 2.1 releases an empty job status structure was returned with job state set to \emph{purged}.} There are two purposes to this arrangement: - -\begin{enumerate} -\item Confirming that the job existed and that its details have been exported to Job Provenance (if deployed and configured), -\item Preventing reuse of the JobID in case of flag \code{EDG\_WLL\_LOGLFLAG\_EXCL} set on registration. -\end{enumerate} - -\subsubsection{On-line monitoring and statistics} -\label{maintain:statistics} - -\paragraph{CE reputability rank} - -Rather frequent problem in the grid production are ``black hole'' sites (Computing Elements). -Such a~site declares itself to have an empty queue, therefore schedulers usually prefer sending -jobs there. The site accepts the job but it fails there immediately. -In this way large number of jobs can be swallowed, affecting the overall success rate -(namely for non-resubmittable jobs). - -\LB data as a~whole contain enough information to detect such sites. -However, due to the primary per-job structure certain reorganization is required. - -A~job is always assigned to a~\emph{group} according to -the CE where it is executed (cf.\ ``destination'' job state attribute). -Similarly to RRDtool\footnote{\url{http://oss.oetiker.ch/rrdtool/}} -for each recently active group (CE), -and for each job state (Ready, Scheduled, Running, Done/OK, Done/Failed), -a~fixed sized series of counters is maintained. -At time $t$, the counters cover intervals $[t-T,t]$, $[t-2T,t-T]$, \dots -where $T$ a~fixed interval size. -Whenever a~job state changes, the series matching the group and new state -is shifted eventually (dropping its expired tail), and the current counter -is incremented. -In addition, multiple series for different $T$ values (\ie covering different -total times) are available. - -% API -The data are available via statistics calls of the client API, -see \verb'statistics.h' for details (coming with glite-lb-client in \LBver{2.x}, -glite-lb-client-interface in \LBver{1.x}). -The call specifies the group and job state of interest, as well as queried -time interval. -The interval is fitted to the running counter series as accurately as possible, -and the average number of jobs per second which entered the specific state for -the given group is computed. The resolution ($T$) of the used counters is also -returned. - -\begin{sloppypar} -% successFraction(CEId) classad gLite 3.1 WMS, nedokumentovana, netestovana -In gLite 3.1 WMS the calls can be accessed from inside of the matchmaking process -via \verb'successFraction(CEId)' -JDL function. -The function computes the ratio of successful vs.\ all jobs for a~given CE, -and it can be directly used to penalize detected black hole CEs in the ranking -JDL expression. -\end{sloppypar} - - -% zapnuti na serveru, volatilita, privilegia -The functionality is enabled with \verb'--count-statistics' \LB server option -(disabled by default). - -The gathered information is currently not persistent, it is lost when the server is stopped. -Despite the statistics call API is defined in a~general way, the implementation is -restricted to a~hardcoded configuration of a~single grouping criterion (the destination), -and a~fixed set of counter series (60 counters of $T=10s$, 30 of 1 minute, and 12 of 15 minutes). -The functionality has not been very thoroughly tested yet. - -% omezeni implementace: hardcoded konfigurace, jen Rate, neprilis dukladne testovane - - - -\paragraph{glite-lb-mon} is a program for monitoring the number of jobs on the -LB server and their several statistics. It is part of the -\verb'glite-lb-utils' package, so the monitoring can be done from remote machine -where this package is installed and the enironment variable -\verb'GLITE_WMS_QUERY_SERVER' properly set. Values like minimum, average and -maximum time spent in the system are calulated for jobs that entered the -final state (Aborted, Cleared, Cancelled) in specific time (default last -hour). Also number of jobs that entered the system during this time is -calculated. - -A special bkindex configuration is needed. -The following time indices must be defined: -\begin{verbatim} - [ type = "time"; name = "submitted" ], - [ type = "time"; name = "cleared" ], - [ type = "time"; name = "aborted" ], - [ type = "time"; name = "cancelled" ], -\end{verbatim} -For more details se man page glite-lb-mon(1). - - -\paragraph{glite-lb-mon-db} is a low-level program for monitoring the the -number of jobs in the LB system. Using the LB internals, it connects directly -to the underlying MySQL database and reads the number of jobs in each state. -The tool is distributed itogether with the server in the \verb'glite-lb-server' package. -It can be used to read data also from the database of LB Proxy. -For more details se man page glite-lb-mon-db(1). - - -\paragraph{Subjob states in a collection} can be calculated on demand on the server and -returned as a histogram using standard job status query. There are two ways how to obtain the -histogram: -\begin{itemize} -\item fast histograms, the last known states are returned, see e.g. -\begin{verbatim} - glite-lb-job_status -fasthist -\end{verbatim} -\item full histograms. the states of all collection subjobs are recalculated, see o.g. -\begin{verbatim} - glite-lb-job_status -fullhist -\end{verbatim} -\end{itemize} -The command \verb'glite-lb-job_status' is a low level query program that can be -found in the package \verb'glite-lb-client' among examples. - - -%\subsection{\LB proxy} - -%\TODO{ljocha} -%Purge zamrzlych jobu (overit v kodu, na ktere verzi to mame ) - - -\subsection{\LB logger} - -\iffalse -\TODO{ljocha} - -Karantena (od ktere verze to mame?) -- kdyz se nepodari rozparsovat soubor -- client/examples -- parse-logevent-file??, lze pouzit - -Cistky pri zaseknuti, nesmyslna jobid apod. - -Debugovaci rezim - -Notifikacni IL -\fi - -The logger component (implemented by \verb'glite-lb-interlogd' daemon fed by -either \verb'glite-lb-logd' or \LB proxy) -is responsible for the store-and-forward event delivery in \LB -(Sect~\ref{comp:logger}). -Therefore eventual operational problems are related mostly to -cumulating undelivered events. - -\subsubsection{Event files} - -\LB logger stores events in one file per job, named -\verb'$GLITE_LOCATION_VAR/log/dglogd.log.JOBID' by default -(JOBID is only the part after the \LB server address prefix). -The format is text (ULM~\cite{ulm}), one event per line. -In addition, control information on delivery status is stored in additional -file with \verb'.ctl' suffix. - -\begin{sloppypar} -In case of emergency (\eg corrupted file) the files can be examined -with \verb'glite-lb-parse_eventsfile'.\footnote{Not fully supported tool, installed -by \texttt{glite-lb-client} package among examples.} -It is possible to hand-edit the event files in emergency (remove corrupted lines). -However, glite-lb-interlogd must not be running, and the corresponding .ctl file -must be removed. -\end{sloppypar} - -\subsubsection{Backlog reasons} - -\paragraph{Undeliverable jobid.} -In normal gLite job processing, jobids are verified on job submission -(via synchronous job registration, see~\cite{lbug}), hence occurrence of -undeliverable jobid (\ie its prefix does not point to -a~working \LB server) is unlikely. -On the other hand, if it happens, -and an event with such a~jobid is logged, -\eg due to a~third-party job processing software bug, -glite-lb-interlogd keeps trying to deliver it indefinitely.\footnote{Unless -event expiration is set, though it is not done for normal events.} -The unsuccessful attempts are reported via syslog. -The only solution is manual -removal of the corresponding files -and restart of the service. - -\paragraph{Corrupted event file.} -For various reasons the files may get corrupted. -In general, corrupted file is detected by glite-lb-interlogd, and it is moved -to \emph{quarantine} (by renaming the file to contain ``quarantine'' in its name). -The action is reported in syslog. -The renamed files can be removed or repaired by hand and renamed back -for glite-lb-interlogd to pick them up again -(in this case, the service needn't be stopped). - -\paragraph{Slow delivery.} -Either glite-lb-interlogd or the target \LB server(s) may not keep pace -with the incoming stream of events. -Amount of such backlog can be quickly assessed by looking at timestamps of the oldest -event files (with \verb'ls -lt $GLITE_LOCATION_VAR/log/', for example). -Fully processed event files are deleted in approx. one minute intervals, -so files last modified one minute ago or newer do not constitute backlog at all. -Unless the backlog situation is permanent, no specific action is required---the -event backlog decreases once the source is drained. -Otherwise hardware bottlenecks (CPU, disk, network) have to be identified -(with standard OS monitoring) and removed, see sections~\ref{inst:hw_req} and -\ref{inst:db_tuning} for \LB server tuning tips. In order to maximize -performance of \verb'glite-lb-interlogd', it is recommended to distribute -jobs to multiple \LB servers that can be shared by multiple WMS setups in turn. - -\subsubsection{Notification delivery} -\begin{sloppypar} -When \verb'glite-lb-logger' package is optionally installed with \LB server, -a~modified \verb'glite-lb-notif-interlogd' is run by the server startup -script. -This version of the daemon is specialized for \LB notifications delivery; -it uses the same mechanism, however, the events (notifications) are routed -by \emph{notification id} rather than jobid, and targeted to user's listeners, -not \LB servers. -See~\cite{lbug, lbdg} for details. -\end{sloppypar} - -On the contrary to normal events, it is more likely that the event destination -disappears permanently. -Therefore the notification events have their expiration time set, -and glite-lb-interlogd purges expired undelivered notifications by default. -Therefore the need for manual purge is even less likely. - -The event files have different prefix (\verb'/var/tmp/glite-lb-notif' by default). - -\subsubsection{Debug mode} - -All the logger daemons, \ie glite-lb-logd, glite-lb-interlogd, and -glite-lb-notif-interlogd, can be started with \verb'-d' -to avoid detaching control terminal, and \verb'-v' to increase -debug message verbosity. -See manual pages for details. - -\subsection{Used resources} -\label{run:resources} - -\subsubsection{Server and proxy} - -\begin{description} -\item[Processes and threads.] -By default \LB server runs as one master process, -and 10 slave processes. -Threads are not used. - -Master pid is stored in the file \verb'$HOME/edg-bkserverd.pid' (\LBver{1.x}) -or in the file \verb'$HOME/glite-lb-bkserverd.pid' (\LBver{2.x}) respectively. -Number of slaves can be set with \verb'-s, --slaves' option, -pid file location with~\verb'-i, --pidfile'. - -Slave server processes are restarted regularly in order to prevent -memory leakage. - -\item[Network and UNIX ports.] -\LB server listens on port 9000 for incoming queries, -9001 for incoming events, and 9003 for WS interface queries. -The former two can be changed with \verb'-p, --port' option -(incoming events are always one port higher than queries), -the latter with~\verb'-w, --wsport'. - -When \LB notifications are enabled (automatically in server startup script when -glite-lb-logger is also installed with the server), -\verb'/tmp/glite-lb-notif.sock' is used for communication with notification interlogger. -It can be changed with \verb'--notif-il-sock'. - -\LB proxy communicates on two UNIX sockets: -\verb'/tmp/lb_proxy_server.sock' (queries) and -\verb'/tmp/lb_proxy_store.sock' (incoming events). - -\LBver{2.x}: as proxy and server are merged, the mode of operation determines -the actual server ports (network or UNIX). -Notifications are not delivered from proxy-only mode. - -\item[IPC.] \LBver{1.x} only: mutual exclusion of server slaves is done -via SYSV semaphores. The semset key is obtained by calling ftok(3) on -the pid file. - -\LBver{2.x} does not use semaphores anymore. - -\item[Database.] -Server data are stored in MySQL database. Normal setup assumes ``server scenario'', -\ie the database IS NOT protected with password and it is not accessible over network. -Option \verb'-m user/password@machine:database' can be used to change -the default connect string \verb'lbserver/@localhost:lbserver20'. - -\item[Dump files.] -Backup dump (Sect.~\ref{run:dump}) files are stored in -\verb'/tmp/dump' by default, however, gLite startup script uses -\verb'--dump-prefix' option to relocate them into \verb'$GLITE_LOCATION_VAR/dump'. -Similarly dumps resulting from purge operation (Sect.~\ref{run:purge}) -go to \verb'/tmp/purge' by default, and startup script uses \verb'--purge-prefix' -to set \verb'$GLITE_LOCATION_VAR/purge'. - -When export to Job Provenance is enabled (Sect.~\ref{run:purge}) -job registrations are exported to directory \verb'/tmp/jpreg' -overridden in startup script with \verb'--jpreg-dir' to \verb'$GLITE_LOCATION_VAR/jpreg'. -In addition, dump files are further processed in \verb'GLITE_LOCATION_VAR/jpdump'. - -Normal operation of JP export should not leave any files behind, -however, abnormal situations (JP unavailable for longer time etc.) -may start filling the disk space. Therefore periodic checks are -recommended. - -Also when purge and dump operations are invoked resulting files are left in their -directories and it is the responsibility of the operation caller to clean them up. - -\item[Notifications] -(see above with Network ports) are stored in files with \verb'/var/tmp/glite-lb-notif' -prefix. It can be changed with \verb'--notif-il-fprefix'. - -Normal operation of notification interlogger purges these files when -they are either delivered or expire. - -\end{description} - -\subsubsection{Logger} - -\begin{description} -\item[Processes and threads.] -glite-lb-logd uses one permanent process and forks a~child to serve -each incoming connection. - -glite-lb-interlogd (and derived glite-lb-notif-interlogd) is multithreaded: -one thread for handling input, another for recovery, and a~dynamic pool of others -to deliver events to their destinations. - -\item[Network and UNIX ports.] -glite-lb-logd listens on 9002 (can be changed with \verb'-p' option). -The daemons communicate over UNIX socket \verb'/tmp/interlogger.sock', -can be changed with \verb'-s' (for both daemons simultaneously). - -\item[Event files] are stored -with prefix \verb'/var/glite/log/dglogd.log' (changed with \verb'-f'). - - -\end{description} - diff --git a/org.glite.lb.doc/src/LBAG-Troubleshooting.tex b/org.glite.lb.doc/src/LBAG-Troubleshooting.tex deleted file mode 100644 index 7c7dec1..0000000 --- a/org.glite.lb.doc/src/LBAG-Troubleshooting.tex +++ /dev/null @@ -1,32 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -%\section{Troubleshooting} - -%\TODO{gather information and finish the section} - -\iffalse -\TODO{ljocha, salvet} - -\begin{verbatim} -- is it documented what information is useful to debug the problem? - -- co muze administrator udelat sam (vystup z jakych prikazu, logu, gdb bt, ...), -co s nasi pomoci (dat Zdenkovi pristup a pod. :-) - -- kam poslat email, kde submitnout bug a pod. -\end{verbatim} -\fi diff --git a/org.glite.lb.doc/src/LBAG.tex b/org.glite.lb.doc/src/LBAG.tex deleted file mode 100644 index 12132d3..0000000 --- a/org.glite.lb.doc/src/LBAG.tex +++ /dev/null @@ -1,70 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\documentclass{emi} -\def\insideAG{} - -\input{definitions} - -\title{Logging and Bookkeeping -- Administrator's Guide} -%\Subtitle{Administrator's Guide} -\author{CESNET EGEE III JRA1 and SA3 team} -%\DocIdentifier{glite-lb-doc-ag-\version} -%\DeliverableId{} -\Date{\today} -%\Activity{JRA1: Middleware Engineering} -%\DocStatus{FINAL} -\DocVersion{\version} -%\Dissemination{PUBLIC} -%\DocumentLink{\url{http://egee.cesnet.cz/cvsweb/LB/LBAG.pdf}} -\Abstract{\input{LBAG-Abstract}} -\EMICompVersion{3.x} - -\begin{document} - -%\input{frontmatter} -\input{funding} -\input{copyright} -\newpage -\tableofcontents - -\newpage -\input{versions} - -\newpage -\input{LBAG-Introduction} - -\newpage -\input{LBAG-Installation} - -%\newpage -%\input{LBAG-Configuration} - -\newpage -\input{LBAG-Running} - -\newpage -\input{LBAG-Troubleshooting} - -\newpage -\input{faq} - -\newpage -\nocite{jgc} -\bibliographystyle{unsrt} -\bibliography{lbjp} - -\end{document} diff --git a/org.glite.lb.doc/src/LBDG-Abstract.tex b/org.glite.lb.doc/src/LBDG-Abstract.tex deleted file mode 100644 index d6bacc9..0000000 --- a/org.glite.lb.doc/src/LBDG-Abstract.tex +++ /dev/null @@ -1,22 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% when changed, update also http://egee.cesnet.cz/en/JRA1/LB/lb.html -% (in CVSROOT=:gserver:lindir.ics.muni.cz:/cvs/edg, cvsweb/lb.html) -The Developer's Guide explains how to use the Logging and Bookkeeping (\LB) -service API. Logging (producer), querying (consumer) and notification API as -well as the Web Services Interface is described in details together with -programing examples. diff --git a/org.glite.lb.doc/src/LBDG-Introduction.tex b/org.glite.lb.doc/src/LBDG-Introduction.tex deleted file mode 100644 index ea272b6..0000000 --- a/org.glite.lb.doc/src/LBDG-Introduction.tex +++ /dev/null @@ -1,623 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% -*- mode: latex -*- - -\section{Introduction} - -This document is intented to guide the reader through basic steps -of writing, compiling and running programs communicating with the \LB -service using the \LB library. It is not intended as a complete API -reference; for this, the reader is referred to the C or C++ header -files, which are thoroughly documented using the doxygen--style -comments. - -The \LB API can be divided by functionality into two independent -parts: -\begin{itemize} -\item \textit{\LB Producer API} (section \ref{s:Producer-API}) is used -to create and send events to the \LB server (proxy), -\item \textit{\LB Consumer API} (section \ref{s:Consumer-API}) and \textit{\LB -Notification API} (section \ref{s:Notification-API}) are used to obtain -information from the \LB server (proxy). -\end{itemize} -These two parts (and in fact the whole \LB service implementation) -share a number of common concepts, design principles, data types and -functions which we will describe first. Most of common data types and -functions are separated in its own SW module called -\verb'org.glite.lb.common' and are described in section~\ref{s:common} - -\marginpar{Example code}% -Source code for examples shown in this guide is distributed together -with the document. The examples contain excerpts from the actual files -with reference to the file name and line numbers. All the examples can -be compiled using attached Makefile. - -\marginpar{Recommended reading}% -Before you start reading this guide, it is recommended to accomodate -yourself with the \LB architecture described in the first part of the -\LB user's guide (\cite{lbug}). - - -\subsection{Language Bindings} -The \LB library itself is developed in C language, the C API covers -all the \LB services. There are bindings for other languages (C++, -Java) as well as web-service (WS) based interface, but these cover only -subsets of \LB functionality and internally they use the C API -themselves (in the C++ case the C API is also exported). - -We describe the C API first and then the differences between C and the -other languages, as the C constructs often reflect directly. - -As for the \LB\ WS interface, it reflects only the functionality of -\LB\ Querying API (see Sect.~\ref{s:Consumer-API-WS}). - -There exist also HTML and plain text interfaces to \LB. We do not expect anybody using them -in a programming language (though it is possible), they might be useful rather in -scripts. Their usage is rather straightforward as it is described in the User's Guide \cite{lbug}. - - -\subsection{Getting and Building Client Libraries} - -All C and C++ \LB\ API's are implemented in \LB\ client library -(\verb'glite-lb-client' package of standard gLite distribution), -and \LB common library (\verb'glite-lb-common'). -These bring in other gLite dependencies: -\begin{itemize} -\item \verb'glite-lb-client-interface' (\LBver{1.x} only) -\item \verb'glite-security-gsoap-plugin' (\LBver{1.x} only) -\item \verb'glite-security-gss' (only \LBver{2.0} and higher) -\end{itemize} -and external dependencies: -\begin{itemize} -\item globus -- only GSS library is needed, we use -\verb'vdt_globus_essentials' package from VDT if available. -\item expat -- XML parser, available in most operating systems -\item c-ares -- asynchronous resolver library -\item cppunit -- unit tests library, required for build only -\item classads -- ClassAd parser and matchmaking library from Condor -\end{itemize} - -For platforms supported by gLite officially all the required packages -can be downloaded from \url{http://www.glite.org}. -However, \LB\ is fairly portable and it can be built on other -platforms fairly smoothly. - -Detailed instructions on getting the sources, including the required -dependencies, are available at -\url{https://erebor.ics.muni.cz/wiki/lb_build.html} -\footnote{The location may change -but we will keep it linked from -official \LB\ pages -\url{http://egee.cesnet.cz/en/JRA1/LB/}.}. - - -\subsection{General Guidelines} - -\marginpar{Naming conventions}% -All names exported by the \LB library (function names, symbolic -constants) are prefixed to avoid name clashes. The prefix is -\verb'edg_wll_' for function names and \verb'EDG_WLL_' for -symbolic constants\footnote{The EDG\_WLL\_ stands for European -DataGrid, the original EU project, and Workload Logging, the subsystem -identification.}. In C++ the namespace \verb'glite::lb' is used -instead. - -\marginpar{Symbolic constants}% -Symbolic constants (\ie enumerated types) are used at various places in the \LB -API. There is a user--friendly string representation of each -constant and for each enumerated type there are two functions that -convert strings to enum values and vice versa. Example is given in -section~\ref{s:edg_wll_Event} - -\marginpar{Input and output arguments}% -All input arguments in \LB API are designated \verb'const' (for simple -types) or have \verb'const' in type name (for structures). - -If pointers are passed in output of function call (either as a return -value, output argument or part of structure), the corresponding -objects are \emph{always} allocated dynamically and have to be freed -when not used anymore. Structures defined in \LB API can be -deallocated by calling convenience -\verb'edg_wll_Free'\textit{Type}\verb'()' functions. {\it This -deallocates members of the structure, but not the structure itself. It -has to be \verb'free()''d explicitly.} - -\marginpar{Opaque and transparent types}% -Types used in \LB API are either opaque or transparent. \textit{Opaque -types} are considered internal to the library, their structure is not -exposed to users and is subject to change without notice. The only way -to modify opaque objects is to use API calls. Example of opaque type -is \verb'edg_wll_Context'. - -Structure of \textit{transparent types} is completely visible to -user, is well documented and no incompatible changes will be done -without notice. Example of transparent type is -\verb'edg_wll_Event'. - -\marginpar{Return values}% -The return type of most of the API functions is \verb'int'. -Unless specified otherwise, zero return value means success, non-zero -failure. Standard error codes from \verb'errno.h' are used as -much as possible. In a few cases the error can not be intuitively -mapped into standard code and \LB specific error value greater than -\verb'EDG_WLL_ERROR_BASE' is returned. - -Few API function return \verb'char *'. In such a~case -\verb'NULL' indicates an error, non-null value means success. - -\subsection{Context and Parameter Settings} -\label{s:context} - -The \LB library does not maintain internal state (apart of network -connections, see \ref{s:pool}), all the API -functions refer to a~\emph{context} argument instead. -Context object preserves state information among the various API -calls, the state including \LB library parameters (\eg security -context, server addresses, timeouts), reference to open connections -(connection pool), error state etc. - -The API caller can create many context objects which are guaranteed -to be independent on one another. In this way thread--safety of the -library is achieved as long as the context is not used by more threads -at the same time. One thread may use more than one context, though. -w -Upon context initialization, all the parameters are assigned default -values. If not set explicitly, many of the parameters take their -value from environment variables. If the corresponding environment -variable is set, the parameter is initialized to its value instead of -the default. Note that a~few parameters cannot be assigned default -value; consequently setting them either in environment or with an -explicit API call is mandatory before using the appropriate part of -the API. - -The context also stores details on errors of the recent API call. - -For use with the \emph{producer} calls (see section~\ref{s:Producer-API}) -the context has to be assigned a~single \jobid (with the -\verb'edg_wll_SetLoggingJob()' call), and keeps track of an event -\emph{sequence code} for the job (see also \LB Architecture described in \cite{lbug}). - -The context object and its API functions are described more thoroughly -in section~\ref{s:edg_wll_context} - -\subsection{Connection Pool} -\label{s:pool} -The \LB library maintains pool of client--server connections to -improve performance (creating SSL connection is heavy--weight -operation). The connections are transparently shared and reused by all -contexts/threads to eliminate the overhead of secure channel -establishment. This behaviour is completely hidden by the library. - - - -\section{\LB Common Components} -\label{s:common} - -\subsection{C Language Binding} - -\subsubsection{Header Files} - -Header files for the common structures and functions are summarized in -table~\ref{t:cheaders}. If you use the producer and/or consumer API -described further in this document, you do not have to include them -explicitly. - -\begin{table}[h] -\begin{tabularx}{\textwidth}{>{\tt}lX} -glite/jobid/cjobid.h & Definition of job identifier. \\ -glite/lb/context.h & Definition of context structure and parameters. \\ -glite/lb/events.h & \LB event data structure.\\ -glite/lb/jobstat.h & Job status structure returned by consumer API.\\ -\end{tabularx} -\caption{Header files for common structures} -\label{t:cheaders} -\end{table} - -\subsubsection{Building Client Programs} -The easiest way to build programs using the \LB library in C is to use -GNU's libtool to take care of all the dependencies: -\begin{verbatim} -flavour=gcc32dbg -libtool --mode=compile gcc -c example1.c util.c \ - -I\$GLITE_LOCATION/include -D_GNU_SOURCE -libtool --mode=link gcc -o example1 example1.o util.o \ - -L$GLITE_LOCATION/lib -lglite_lb_client_$flavour -\end{verbatim} -The library comes in different flavours (with/without debugging -symbols, with/without thread support) which are in turn linked with -(and depend on) the correct Globus library flavours. When linking -threaded programs you have to use the library flavour with thread -support. - -The RPM package needed is \texttt{glite-lb-client} and its dependencies -which contain all necessary libraries. - -\subsubsection{Context} -\label{s:edg_wll_context} -\marginpar{Context initialization}% -Opaque data structure representing \LB API context (see -section~\ref{s:context}) is named \verb'edg_wll_Context'. -The context must be initialized before the first \LB API call: -\begin{lstlisting} -#include - -edg_wll_Context ctx; -edg_wll_InitContext(&ctx); -\end{lstlisting} - -\marginpar{Parameter setting}% -The context parameters can be set explicitly by calling -\begin{lstlisting} -int edg_wll_SetParam(edg_wll_Context *, edg_wll_ContextParam, ...); -\end{lstlisting} -function. The second argument is symbolic name of the context -parameter; parameters specific for producer and consumer API are -described in respective API sections, the common parameters are: - -\begin{table}[h] -\begin{tabularx}{\textwidth}{lX} -{\bf C name} & {\bf Description} \\ -\hline -\lstinline'EDG_WLL_PARAM_X509_KEY' & -Key file to use for authentication. -\par {\it Type: } \lstinline'char *' -\par {\it Environment: } \lstinline'X509_USER_KEY' -\\ -\lstinline'EDG_WLL_PARAM_X509_CERT' & -Certificate file to use for authentication. -\par {\it Type: } \lstinline'char *' -\par {\it Environment: } \lstinline'X509_USER_CERT' -\\ -\lstinline'EDG_WLL_PARAM_CONNPOOL_SIZE' & -Maximum number of open connections maintained by the library. -\par {\it Type: } \lstinline'int' -\par {\it Environment: } \\ -\end{tabularx} -\caption{Common context parameters} -\label{t:cparam} -\end{table} - -The third argument is parameter value, which can be of type -\verb'int', \verb'char *' or \verb'struct timeval *'. -If the parameter value is set to \verb'NULL' (or 0), the -parameter is reset to the default value. - -If you want to obtain current value of some context parameter, call -\begin{lstlisting} -int edg_wll_GetParam(edg_wll_Context, edg_wll_ContextParam, ...); -\end{lstlisting} -function: -\begin{lstlisting} -char *cert_file; - -edg_wll_GetParam(ctx, EDG_WLL_PARAM_X509_CERT, &cert_file); -printf("Certificate used: %s\n", cert_file); -free(cert_file); -\end{lstlisting} -The third argument points at variable with type corresponding to the -requested parameter. Do not forget to free the result. - -\TODO{sitera: Mame odkaz kde jsou popsany defaulty a vazby na promenne environmentu (ty jsou v LBUG Appendix C)} - -\marginpar{Obtaining error details}% -When \LB API call returns error, additional details can be obtained -from the context: -\begin{lstlisting} -char *err_text,*err_desc; - -edg_wll_Error(ctx, &err_text, &err_desc); -fprintf(stderr, "LB library error: %s (%s)\n", err_text, err_desc); -free(err_text); -free(err_desc); -\end{lstlisting} - -\marginpar{Context deallocation}% -If the context is needed no more, deallocate it: -\begin{lstlisting} -edg_wll_FreeContext(ctx); -\end{lstlisting} - -For more information see file \verb'glite/lb/context.h' - -\subsubsection{JobId} -The primary entity of \LB is a job, identified by JobId -- a unique -identifier of the job (see also \cite{lbug}). The type representing -the JobId is opaque \verb'glite_jobid_t'. The JobId is in fact -just URL with \verb'https' protocol, path component being unique string -with no further structure and host and port designating the \LB server -holding the job information. The JobId can be: -\begin{itemize} -\item created new for given \LB server (the unique part will be -generated by the \LB library): -\begin{lstlisting} -glite_jobid_t jobid; -int ret; -if(ret = glite_jobid_create("some.host", 0, &jobid)) { - fprintf(stderr, "error creating jobid: %s\n", strerror(ret)); -} -\end{lstlisting} -\item parsed from string (\eg when given as an program argument or -read from file): -\begin{lstlisting}[firstnumber=3] -if(ret = glite_jobid_parse("https://some.host:9000/OirOgeWh_F9sfMZjnIPYhQ", &jobid)) { - fprintf(stderr, "error parsing jobid: %s\n", strerror(ret)); -} -\end{lstlisting} -\item or obtained as part of \LB server query result. -\end{itemize} -In either case the jobid must be freed when no longer in use: -\begin{lstlisting} -glite_jobid_free(jobid); -\end{lstlisting} - -For more information see file \verb'glite/jobid/cjobid.h' - -\marginpar{\textbf{\LB 1.x}}% -{\it In the older \LB versions (1.x) the -structure was named \verb'edg_wlc_JobId' and the functions had prefix -\verb'edg_wlc_JobId', \eg\verb'edg_wlc_JobIdFree()'. Exact description -can be found in the header file \verb'glite/wmsutils/cjobid.h'} - - -\subsubsection{Event} - -\label{s:edg_wll_Event} -The transparent data structure \verb'edg_wll_Event' represents \LB -event, atomic data unit received and processed by \LB. It is a union of -common structure and structures for all event types: -\begin{lstlisting} -union _edg_wll_Event { - edg_wll_EventCode type; - edg_wll_AnyEvent any; - edg_wll_TransferEvent transfer; - edg_wll_AcceptedEvent accepted; - //* \dots {\it more follows} \dots -} -typedef union _edg_wll_Event edg_wll_Event; -\end{lstlisting} - -The most important common event attributes are listed in -table~\ref{t:cevent}, the following example shows access: -\begin{lstlisting} -edg_wll_Event event; - -event.type = 0; -event.any.user = "me"; -\end{lstlisting} - -\begin{table}[h] -\begin{tabularx}{\textwidth}{llX} -\bf Attribute name & \bf Attribute type & \bf Description \\ -\hline -\verb'type' & \verb'edg_wll_EventCode' & Event type. Values are -symbolic constants \eg \verb'EDG_WLL_EVENT_DONE' \\ -\verb'jobId' & \verb'glite_jobid_t' & Jobid of the job the event -belongs to. \\ -\verb'user' & \verb'char*' & Identity (certificate subject) of the -event sender. \\ -\verb'host' & \verb'char*' & Hostname of the machine the event was -sent from. \\ -\verb'source' & \verb'edg_wll_Source' & Designation of the WMS component -the event was sent from, \eg \verb'EDG_WLL_SOURCE_USER_INTERFACE' \\ -\verb'timestamp' & \verb'struct timeval' & Time when the event was -generated. \\ -\verb'seqcode' & \verb'char*' & Sequence code assigned to the event. \\ -\end{tabularx} -\caption{Common event attributes} -\label{t:cevent} -\end{table} - -The \verb'edg_wll_Event' is returned by consumer \LB -API job event related calls. The only important operation defined on -\verb'edg_wll_Event' itself is -\begin{lstlisting} -edg_wll_FreeEvent(edg_wll_Event *event) -\end{lstlisting} -to free the event structure. - -\marginpar{List of event types}% -The event structure makes use of enumerated types extensively, -starting with the \verb'type' atribute. The following example -demonstrates how to convert enumerated values into more -user--friendly strings; it will print out the event names known to the -\LB library: -\begin{lstlisting} -edg_wll_EventCode ev_type; - -for(ev_type = 1; ev_type < EDG_WLL_EVENT__LAST; ev_type++) { - char *ev_string = edg_wll_EventToString(ev_type); - if(ev_string) { - /* there may be holes */ - printf("%s\n", ev_string); - free(ev_string); - } -} -\end{lstlisting} - -For more information see file \verb'include/glite/lb/events.h' - -\subsubsection{JobStatus} -The transparent data type \verb'edg_wll_JobStat' represents status of -a job as computed by the \LB from received events. Much like the -\verb'edg_wll_Event' structure it can be viewed as a set of -attributes, where some attributes are common and some specific -for a given job state (but unlike the \verb'edg_wll_Event' it is not -implemented as union of structs but rather as one big struct). -Generally speaking, when the attribute value is set, it is a valid -part of job state description. Most important common attributes are -summarized in table~\ref{t:cstatus}. - - - -\begin{table}[h] -\begin{tabularx}{\linewidth}{llX} -\bf Attribute name & \bf Attribute type & \bf Description \\ -\hline -\verb'jobId' & \verb'glite_jobid_t' & Job identifier of this job. \\ -\verb'state' & \verb'edg_wll_JobStatCode' & Numeric code of the status, \eg -\verb'EDG_WLL_JOB_SUBMITTED'. \\ -\verb'type' & \verb'enum edg_wll_StatJobtype' & Type of the job, \eg -\verb'EDG_WLL_JOB_SIMPLE'. \\ -\verb'children' & \verb'char**' & List of subjob \jobid's \\ -\verb'owner' & \verb'char*' & Owner (certificate subject) of the -job. \\ -\end{tabularx} -\caption{Common job status attributes}\label{t:cstatus} - -\end{table} - -Job status structure is returned by the \LB consumer API job status -queries. When no longer used, it has to be freed by calling -\begin{lstlisting} -void edg_wll_FreeStatus(edg_wll_JobStat *); -\end{lstlisting} - -The following example prints out the states of jobs given in the input -list; the job states are printed together with their subjobs on the -same input list: -\lstinputlisting[title={\bf File: }\lstname,firstline=12,numbers=left]{util.c} - -For more information see file \verb'include/glite/lb/jobstat.h' - -\subsection{C++ Language Binding} -The C++ languague binding now only supports the consumer (querying) -API. It is not the (re)implementation of the library in C++; instead -it is just a thin adaptation layer on top of the C API, which means -all the structures and functions of the C API can be used in C++. The -C++ classes wrap up the concepts and structures of C API and provide -convenient access to the functionality. The namespace used for -\LB C++ API is \verb'glite::lb'. - -\marginpar{Exceptions}% -While the C++ API closely follows the C API functionality, there are -also two important differences: error handling and memory management. - -When the \LB method call fails, the exception of class -\verb'glite::lb::Exception' (derived from \verb'std::runtime_error') -is raised that holds the error description and information about the -source file, line and method the exception was thrown from (possibly -accumulating information from other exception). - -\marginpar{Reference counting}% -When the C \LB library calls return allocated structures, they are -encapsulated within C++ accessor objects. Copying the C++ object does -not copy the underlying structure, it increases the reference count -instead, making use of the same allocated data. The reference count is -decremented with destruction of the wrapper object, when it drops to -zero, the allocated memory is freed. - -Using this scheme all the data allocated by the \LB library are held -in memory only once. - -\marginpar{Context}% -The context in C API is part of common components, the C++ API on the -other hand differentiates between query context -(see Section~\ref{s:ServerConnection}) and logging context; the description is -therefore part of the respective chapters. - -\subsubsection{Header Files} -Header files for the C++ version of common definitions are summarized -in table~\ref{t:cppheaders}. - -\begin{table}[h] -\begin{tabularx}{\textwidth}{>{\tt}lX} -glite/jobid/JobId.h & Definition of job identifier. \\ -glite/lb/LoggingExceptions.h & Exception class for \LB--specific errors.\\ -\end{tabularx} -\caption{Header file for common C++ classes} -\label{t:cppheaders} - -\end{table} - -\subsubsection{Building Programs} -The recommended way to build programs using the C++ \LB library is, -like in the C case, to use the \verb'libtool' utility: -\begin{verbatim} -flavour=gcc32dbg -libtool --mode=compile gcc -c example1.c util.c \ - -I\$GLITE_LOCATION/include -D_GNU_SOURCE -libtool --mode=link gcc -o example1 example1.o util.o \ - -L$GLITE_LOCATION/lib -lglite_lb_clientpp_$flavour -\end{verbatim} -The only difference is the library name, the RPM package required is -again \verb'glite-lb-client'. - -\subsubsection{JobId} -The \verb'glite::jobid::JobId' class represents job identification and -provides convenient methods for manipulating the data. The -\verb'JobId' object can be created: -\begin{itemize} -\item from the C structure (this is used mainly internally within the -library): -\begin{lstlisting} -using namespace glite::jobid; -glite_jobid_t cjobid; - -JobId jobid(cjobid); -\end{lstlisting} -\emph{Note:} This creates copy of the structure, the original structure has to be -deallocated as usual. -\item parsed from the string: -\begin{lstlisting} -JobId jobid("https://some.host:9000/OirOgeWh_F9sfMZjnIPYhQ"); -\end{lstlisting} -\item from the components: -\begin{lstlisting} -JobId jobid(Hostname("some.host"), 9000, "OirOgeWh_F9sfMZjnIPYhQ"); -\end{lstlisting} -The last two arguments are optional, so you have to specify only -name of the \LB server machine (the \verb'Hostname' class is used to -disambiguate the constructors): -\begin{lstlisting} -JobId jobid(Hostname("some.host")); -\end{lstlisting} -In that case new unique part is generated automatically. -\end{itemize} -Apart from that there are the usual copy constructor and assignment -operator that make deep copy of the object, and the destructor that -deallocates the memory. - -\marginpar{Data access}% -The \verb'JobId' class provides methods for obtaining the host, port -and unique part of the \jobid\ as well as conversion into C -\verb'glite_jobid_t' type and into string representation. There is -also a defined ordering (\verb'operator<') on the \jobid's, which is just the -lexicographical ordering of corresponding string -representations. The following example illustrates these features: - -\begin{lstlisting} -JobId a(Hostname("me")); -JobId b(Hostname("me")); - -cout << "jobid host and port: " << a.host() << ", " << -a.port() << endl; -cout << (a < b) ? a.unique() : b.unique() << " comes first" << endl; -cout << "Complete jobid: " << a.toString() << endl; -\end{lstlisting} - -\subsubsection{Exception} -The \verb'glite::lb::Exception' is a base class for all exceptions -thrown by the \LB library. It inherits from \verb'std::runtime_error' -and adds no additional members or methods except constructors. The -typical usage is this: -\begin{lstlisting} -try { - // some code with LB calls -} catch (glite::lb::Exception &e) { - cerr << "LB library exception: " << e.what() << endl; -} -\end{lstlisting} diff --git a/org.glite.lb.doc/src/LBDG.tex b/org.glite.lb.doc/src/LBDG.tex deleted file mode 100644 index dcd19e8..0000000 --- a/org.glite.lb.doc/src/LBDG.tex +++ /dev/null @@ -1,115 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% -*- mode: latex -*- -\documentclass{emi} -\def\insideDG{} - -\input{definitions} -%\def\LB{LB\xspace} - -\title{Logging and Bookkeeping -- Developer's Guide} -%\Subtitle{Developer's Guide} -\author{CESNET EGEE III JRA1 and SA3 team} -%\DocIdentifier{glite-lb-doc-dg-\version} -%\DeliverableId{} -\Date{\today} -%\Activity{JRA1: Middleware Engineering} -%\DocStatus{DRAFT} -\DocVersion{\version} -%\Dissemination{PUBLIC} -%\DocumentLink{\url{http://egee.cesnet.cz/cvsweb/LB/LBDG.pdf}} -\Abstract{\input{LBDG-Abstract}} -\EMICompVersion{3.x} - - -\usepackage{listings} -\usepackage{amsmath} - -%\setlength{\marginparwidth}{1.2in} -\let\oldmarginpar\marginpar -\renewcommand\marginpar[1]{\-\oldmarginpar[\raggedleft\footnotesize #1]% -{\raggedright\footnotesize #1}} - -\begin{document} -\reversemarginpar -\lstset{language=C,basicstyle=\footnotesize,numbers=none,breaklines=true} -%\lstset{title={\bf File: }\lstname} -\lstset{rangeprefix=/*,rangesuffix=*/,includerangemarker=false} -\lstset{escapeinside={//*}{\^^M}} - -% ----- BEGIN COPY ----- -% copied from org.glite.lb.client/doc/api/api.tex in hope it could be useful - -%\parindent=0pt -%\parskip=\smallskipamount - -\makeatletter -\def\jobid{\textit{JobId}\xspace} -\def\@tti[#1]{\item[{\normalfont\texttt{#1}}]\catcode`\_=8} -\def\tti{\catcode`\_=11\noexpand\@tti} -\newlength{\tw} - -\def\synopsis{\catcode`\_=11\noexpand\@synopsis} -\def\@synopsis#1#2{ -\tw=\linewidth -\advance\tw-2em -\texttt{#1(}\\ -\strut\hskip2em\begin{tabularx}\tw{>{\begingroup\tt}l<{\endgroup}lX} -#2 -\end{tabularx}\\ -\texttt) -\catcode`\_=8 -} - -\def\Synopsis{\subsubsection*{Synopsis}} -\def\Description{\subsubsection*{Description}} -\def\Return{\subsubsection*{Return values}} - -% ----- END COPY ----- - -%\input{frontmatter} -\input{funding} -\input{copyright} -\tableofcontents - -\newpage -\input{versions} - -\newpage -\input{LBDG-Introduction} - -\newpage -\input{producer_api} - -\newpage -\input{consumer_api} - -\newpage -\input{notification_api} - -% \newpage -% \input{web_services} - -\TODO{zminit http interface - podporujeme ho jeste? tusim ze fila -to nejak resuscitoval} - -\newpage -\bibliographystyle{unsrt} -\bibliography{lbjp} - -\end{document} - diff --git a/org.glite.lb.doc/src/LBTG-Abstract.tex b/org.glite.lb.doc/src/LBTG-Abstract.tex deleted file mode 100644 index a0fd003..0000000 --- a/org.glite.lb.doc/src/LBTG-Abstract.tex +++ /dev/null @@ -1,21 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% when changed, update also http://egee.cesnet.cz/en/JRA1/LB/lb.html -% (in CVSROOT=:gserver:lindir.ics.muni.cz:/cvs/edg, cvsweb/lb.html) -The Troubleshooting Guide covers user-side troubleshooting of the Logging and Bookkeeping -(\LB) service. It is based on previous experience with problems frequently - encountered by users. diff --git a/org.glite.lb.doc/src/LBTG.tex b/org.glite.lb.doc/src/LBTG.tex deleted file mode 100644 index 38e754d..0000000 --- a/org.glite.lb.doc/src/LBTG.tex +++ /dev/null @@ -1,58 +0,0 @@ -%% -%%%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\documentclass{emi} -\def\insideUG{} - -\input{definitions} - -\title{Logging and Bookkeeping -- Troubleshooting Guide} -%\Subtitle{Troubleshooting Guide} -\author{CESNET EMI LB Product Team} -%\DocIdentifier{glite-lb-doc-tg-\version} -%\DeliverableId{} -\Date{\today} -%\Activity{JRA1: Middleware Engineering} -%\DocStatus{FINAL} -\DocVersion{\version} -%\Dissemination{PUBLIC} -%\DocumentLink{\url{http://egee.cesnet.cz/cvsweb/LB/LBTG.pdf}} -\Abstract{\input{LBTG-Abstract}} -\EMICompVersion{3.x} - - -\begin{document} - -%\input{frontmatter} -\input{funding} -\input{copyright} -\tableofcontents - -\newpage -\input{versions} - -\newpage -\input{LBUG-Troubleshooting} - -\newpage -\input{faq} - -\newpage -\bibliographystyle{unsrt} -\bibliography{lbjp} - -\end{document} - diff --git a/org.glite.lb.doc/src/LBTP-Abstract.tex b/org.glite.lb.doc/src/LBTP-Abstract.tex deleted file mode 100644 index 0387fd5..0000000 --- a/org.glite.lb.doc/src/LBTP-Abstract.tex +++ /dev/null @@ -1,23 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% when changed, update also http://egee.cesnet.cz/en/JRA1/LB/lb.html -% (in CVSROOT=:gserver:lindir.ics.muni.cz:/cvs/edg, cvsweb/lb.html) -The Test Plan document explains how to test the Logging and Bookkeeping (\LB) -service. Two major categories of tests are described: integration tests -(include installation, configuration and basic service ping tests) and -system tests (basic functionality tests, performance and stress tests, -interoperability tests and security tests). diff --git a/org.glite.lb.doc/src/LBTP-IntegrationTests.tex b/org.glite.lb.doc/src/LBTP-IntegrationTests.tex deleted file mode 100644 index a18c0e2..0000000 --- a/org.glite.lb.doc/src/LBTP-IntegrationTests.tex +++ /dev/null @@ -1,116 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% Integration tests - -% Installation and configuration tests are done manually by the certification team, -% there is no need to specify them here at the moment, they can be added later - -% \section{Installation tests} -% \label{s:installation} -% \TODO{salvet: list installed packages, check all dependencies, ...} -% \begin{center} -% \url{https://twiki.cern.ch/twiki/bin/view/EGEE/Glite-LB} -% \end{center} - - -% \newpage -% \section{Configuration tests} -% \label{s:configuration} -% \TODO{salvet: check all config files, ...} -% \begin{center} -% \url{https://twiki.cern.ch/twiki/bin/view/EGEE/Glite-LB} -% \end{center} - - -% \newpage -\section{Service ping tests} -\label{s:ping} - -In this section we describe basic tests of \LB if the services are up and running. -% Local tests are meant to be run on the install node (where the appropriate daemon is running) -% whereas remote tests are meant to be run via another node. - -\subsection{Test Suite Overview} - -This subsection gives a comprehensive overview of all service ping tests. - -\begin{tabularx}{\textwidth}{|l|l|X|} -\hline - {\bf Executable} & {\bf Status} & {\bf Use} \\ -\hline -{\tt lb-test-logger-local.sh} & Implemented & Test job logging facilities on a local machine (processes running, ports listening, etc.). \\ -\hline -{\tt lb-test-logger-remote.sh} & Implemented & Test the local logger availability remotely (open ports). \\ -\hline -{\tt lb-test-server-local.sh} & Implemented & Test for LB server running on a local machine (processes running, ports listening, etc.). \\ -\hline -{\tt lb-test-server-remote.sh} & Implemented & Test the LB server availability remotely (open ports). \\ -\hline -\end{tabularx} - -\subsection{Logger (local \& inter)} - -\subsubsection{Local tests} -\what\ check if both \texttt{glite-lb-logd} and \texttt{glite-lb-interlogd} are running, -check if \texttt{glite-lb-logd} is listening on which port (9002 by default), -socket-connect to \texttt{glite-lb-logd}, -check if enough disk capacity is free for \code{dglog*} files, -socket-connect to \texttt{glite-lb-interlogd}. - -\how\ \ctblb{lb-test-logger-local.sh} - - -\subsubsection{Remote tests} -\req\ environment variable \texttt{GLITE\_WMS\_LOG\_DESTINATION} set, GSI credentials set - -\what\ network ping, -check GSI credentials, -socket-connect, -gsi-connect - -\how\ \ctblb{lb-test-logger-remote.sh} - - -\subsection{Server} - -\subsubsection{Local tests} -\req\ environment variables \texttt{GLITE\_WMS\_LBPROXY\_STORE\_SOCK}, -and \texttt{GLITE\_WMS\_LBPROXY\_SERVE\_SOCK} set - -\what\ check MySQL (running, accessible, enough disk capacity, ...), -check if both daemons \texttt{glite-lb-bkserverd} and \texttt{glite-lb-notif-interlogd} are running, -check if \texttt{glite-lb-bkserverd} is listening on which ports (9000, 9001 and 9003 by default), -socket-connect to all \texttt{glite-lb-bkserverd} ports and sockets, -check if enough disk capacity is free for dumps, -socket-connect to \texttt{glite-lb-notif-interlogd}. - -\how\ \ctblb{lb-test-server-local.sh} - - -\subsubsection{Remote tests} -\req\ environment variable \texttt{GLITE\_WMS\_QUERY\_SERVER} set, GSI credentials set - -\what\ network ping, -check GSI credentials, -socket-connect to all server ports, -gsi-connect to all server ports, -WS getVersion. - -\how\ \ctblb{lb-test-server-remote.sh} - - - diff --git a/org.glite.lb.doc/src/LBTP-InterTests.tex b/org.glite.lb.doc/src/LBTP-InterTests.tex deleted file mode 100644 index c25eb6c..0000000 --- a/org.glite.lb.doc/src/LBTP-InterTests.tex +++ /dev/null @@ -1,26 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% \section{Interoperability tests} -% \label{s:interoperability} -% \TODO{salvet, ljocha: Test of interoperability with other grids} - - -% \newpage -% \section{Security tests} -% \label{s:security} -% \TODO{kouril: complete security audit} - diff --git a/org.glite.lb.doc/src/LBTP-Introduction.tex b/org.glite.lb.doc/src/LBTP-Introduction.tex deleted file mode 100644 index d1631ba..0000000 --- a/org.glite.lb.doc/src/LBTP-Introduction.tex +++ /dev/null @@ -1,148 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\section{Introduction} - -This document explains how to test the Logging and Bookkeeping (\LB) service. - -As part of the EGEE-III project, Specific Service Activity SA3: Integration, -testing and certification\footnote{\url{https://twiki.cern.ch/twiki/bin/view/EGEE/SA3}}, -testing is an essential activity and all important information about gLite software -testing should be available from the web page - -\begin{center} -\url{https://twiki.cern.ch/twiki/bin/view/EGEE/EGEECertification#Test_writing}. -\end{center} - -This document describes test plan for the \LB service. - - -\subsection{Test categories} - -% Obsolete, not used anymore: -% -% Several layers of tests are considered: -% \begin{description} -% \item[Layer 1 - service ping tests:] Basic test if a service is up and running. -% \item[Layer 2 - service functionality tests:] Test the fully supported functionality of a service. This includes also service interface tests. -% \item[Layer 3 - system tests:] Test a complete system that traverses multiple services. -% \item[Layer 4 - stress tests:] Stress test services and systems (including long running jobs to check for resource leaks). -% \item[Layer 5 - performance tests:] Test performance of the service (including the MegaJob results). -% \item[Layer 6 - interoperability tests:] Test for interoperability with other grids (might be interactive). -% \end{description} - -According to the gLite Test Writing Guidelines -\footnote{\url{https://twiki.cern.ch/twiki/bin/view/LCG/LCGgliteTestWritingGuidelines}}, -we consider two test categories with the following test types: - -\begin{description} -\item[Integration tests] verify if the software is installable and configurable. -They also check for basic, not depending on other grid services, functionality -of the component (e.g. daemon is up and running). -\begin{itemize} -\item Installation tests %, see Section~\ref{s:installation} -\item Configuration tests %, see Section~\ref{s:configuration} -\item Service ping tests: basic tests if service is up and running, see Section~\ref{s:ping} -\end{itemize} -% -\item[System tests] verify if the component works within the grid in -interaction with other grid services. -\begin{itemize} -\item Functionality tests of fully supported functionality (including APIs and CLI), see Section~\ref{s:functionality} -\item Performance and stress tests, see Section~\ref{s:perftests} -\item Interoperability tests %, see Section~\ref{s:interoperability} -\item Security tests %, see Section~\ref{s:security} -\end{itemize} -\end{description} - -The tests could be run either locally (on the install node = where the service -is installed, configured and running) or remotely (via another node, where some -parts of the software also must be installed). - -Apart from these tests, there exist also tests of the individual components run -for example during the build process (especially unit tests). They are not -described in this document. - - -\subsection{Certification tests} - -EGEE Certification team collects tests for \LB in a gLite module -\verb'org.glite.testsuites.ctb' in the \verb'LB' directory. All \LB tests are -described at -\url{https://twiki.cern.ch/twiki/bin/view/LCG/AvailableTests#Logging_and_Bookkeeping_LB} -as well as next to each test case in the following sections. - -The tests can be used as sensors in different monitoring frameworks -(see also below). - - - - -\subsection{Integration into other frameworks} - -\subsubsection{Service Availability Monitoring} - -Service Availability Monitoring -(SAM)\footnote{\url{http://sam-docs.web.cern.ch/sam-docs}} is a framework for -the monitoring of production and pre-production grid sites. It provides a set -of probes which are submitted at regular intervals, and a database that stores -test results. In effect, SAM provides monitoring of grid services from a user -perspective. - -%\TODO{ljocha: More about SAM. How LB is integrated - LB sensors for SAM} - - -\subsubsection{Nagios} - -Nagios\footnote{\url{http://www.nagios.org}} is a host and service monitor -designed to inform you of network problems before your clients, end-users or -managers do. - -There is a Nagios plugin that tests the status of the \LB server. It is discussed in detail in section~\ref{s:nagios}, page~\pageref{s:nagios}. - - -\subsubsection{ETICS} - -ETICS\footnote{\url{http://etics.web.cern.ch/etics/}} stands for -"eInfrastructure for Testing, Integration and Configuration of Software". It -provides a service to help software developers, managers and users to better -manage complexity and improve the quality of their software. Using cutting -edge Grid software and best practices, ETICS allows to fully automate -the way your software is built and tested. - -Please see the ETICS User Manual \cite{etics_manual} for the description -of the ETICS service and basic ETICS commands. The command to be issued to -test the whole \LB subsystem is: - -\begin{verbatim} - etics-test org.glite.lb -\end{verbatim} - -It can be issued locally or using the remote build and test system. -%\TODO{More about ETICS testing?} - -General ideas of \LB tests using ETICS are the following - -\begin{itemize} -\item tests are in CVS together with the code - -\item tests run the service themselves on some non-default ports and perform a set of -elementary actions similar to those from \ctblb{}\ -to test the basic functionality of the service which is stopped again at the -end of the test - -\end{itemize} -%\TODO{More about LB tests for individual modules} diff --git a/org.glite.lb.doc/src/LBTP-Nagios.tex b/org.glite.lb.doc/src/LBTP-Nagios.tex deleted file mode 100644 index 48bb9b2..0000000 --- a/org.glite.lb.doc/src/LBTP-Nagios.tex +++ /dev/null @@ -1,124 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% System tests - -\section{Nagios Probe} -\label{s:nagios} - -There is a Nagios probe to check the service status of an \LB server node. It is distributed from the EMI repository and the name of the package is \texttt{emi-lb-nagios-plugins}. - -\subsection{Tests Performed} -Before starting the actual test the probe checks for existence and validity of a proxy certificate, and for availability of commands (essential system commands, various \LB Client commands and grid proxy manipulation commands). - -The following tests are performed by the probe. Various tests check the working status of various processes running on the \LB server node: - -\begin{enumerate} -\item Register job - \begin{itemize} - \item \LB server (\texttt{glite-lb-bkserverd}) - \end{itemize} -\item Register to receive notifications - \begin{itemize} - \item \LB server (\texttt{glite-lb-bkserverd}) - \end{itemize} -\item Log events resulting in state \emph{cleared} - \begin{itemize} - \item \LB logger (\texttt{glite-lb-logd}) - \end{itemize} -\item Check job state - \begin{itemize} - \item \LB server (\texttt{glite-lb-bkserverd}) - \item Interlogger (\texttt{glite-lb-interlogd}) - \end{itemize} -\item Receive notifications - \begin{itemize} - \item Notification interlogger (\texttt{glite-lb-notif-interlogd}) - \end{itemize} -\end{enumerate} - -The test also tries to drop the test notification and purge the test job to clean up after itself. However, purging the job won't probably be allowed by the \LB server's policy and the test job will remain registered on the \LB server until removed by a regular purge. - -\subsection{Return Values} -Return values follow the Nagios pattern: - -\begin{description} -\item[0] The service is running normally -\item[1] The service is running but there were warnings -\item[2] The service status is critical -\item[3] The service status is unknown, probe could not run -\end{description} - -\subsection{Console Output} -Text output indicates the results of the probe and gives a more detailed description of failure causes. - -The probe can return one of the following: - -\begin{tabularx}{\textwidth}{|c|p{5cm}|X|} -\hline -\multirow{3}{*}{WARNING} & \emph{Unexpected version output} & The server responded to a query for server version over the WS interface, but the format of the response did not match the expected pattern. \\ -& \emph{Unexpected state of test job} & The state of the test job did not remain unchanged (\texttt{Submitted}) but neither did it reach status \texttt{Cleared} in the alotted time. All deamons seem to work but the processing is slow.\\ -& \emph{Could not drop notification} & The owner should be able to drop their own notification. Failure to do so is unexpected but does not mean that the service is not functioning. \\ -\hline -\multirow{6}{*}{DOWN} & \emph{Unable to Get Server Version} & The server did not respond to a query for server version over the WS interface. It is probably not running, is unaccessible or SSL handshake failed due to faulty/outdated certificates/CRLs. \\ -& \emph{Job Registration Failed Locally} & The probe was unable to perform the local side of job registration. This should be rare. \\ -& \emph{\LB Server Not Running} & The probe was unable to register a test job or a test notification with the \LB server. It is probably not running or is unaccessible. \\ -& \emph{Event Delivery Chain (Logger/Interlogger) Not Running} & The server process is running but events are not being delivered by \LB's local logger/interlogger. Check the Logger and the Interlogger. \\ -& \emph{Notification Interlogger Not Running} & Events are being delivered correctly and server responds properly to status queries, but it its not delivering notification messages. The notification interlogger is probably not running.\\ -\hline -\multirow{5}{*}{UNKNOWN} & \emph{Probe timed out} & The probe was unable to finish before the alotted time. Consider increasing the timeout with \texttt{-t}. The minimum reasonable value is 10\,s. \\ -& \emph{No server specified} & Server address was not specified when running the probe. Give one with \texttt{-H}. \\ -& \emph{Probe could not write temporary files} & The temporary directory was not writable. Check the default location or specify a new one with \texttt{-T}.\\ -& \emph{Some commands are not available} & Probe could not run. Some of the required commands are not present on the system. Run probe from command line with \texttt{-v[vv]} and check output. \\ -& \emph{No Credentials} & No proxy certificate was found. Probe could not run. \\ -& \emph{Credentials Expired} & A proxy certificate was found, but expired. Probe could not run. \\ -\hline -\end{tabularx} - -\subsection{Running the Probe} - -\subsubsection{Command Line Arguments} -The probe recognizes the following command line arguments: - -\begin{tabularx}{\textwidth}{l l X} - \texttt{-h} & \texttt{-{}-help} & Print out simple console help \\ - \texttt{-v[vv]} & \texttt{-{}-verbose} & Set verbosity level (\texttt{-{}-verbose} denotes a single \texttt{v}). \\ - \texttt{-H} & \texttt{-{}-hostname} & \LB node address. Environmental variable \texttt{GLITE\_WMS\_QUERY\_SERVER} used if unspecified. \\ - \texttt{-p} & \texttt{-{}-port} & \LB server port. Other port numbers (logger, WS interface) are derrived from it. Environmental variable \texttt{GLITE\_WMS\_QUERY\_SERVER} or default port \texttt{9000} used if unspecified. \\ - \texttt{-t} & \texttt{-{}-timeout} & Timeout in seconds. The minimum reasonable timeout is approx.~10\,s. There is no default, except the internal waiting cycle for notifications, which will time out after approx.~20\,s.\footnote{The probe adjusts the internal waiting cycle to spend a maximum of $\frac{3}{4}$ of the specified timeout interval while waiting for notifications to deliver. It will finish correctly before timing out if undelivered notifications are the only problem.} \\ - \texttt{-T} & \texttt{-{}-tmpdir} & Directory to store temporary files. By default the probe uses \texttt{/var/lib/grid-monitoring/emi.lb} and falls back to \texttt{/tmp} if the former does not exist or is not writable. \\ -\end{tabularx} - -\subsubsection{Environmental Variables} -In essence the probe recognizes the same environmental variables as the \LB client. No environmental variables need to be set if hostname is specified as a command line argument to the probe. - -\begin{tabularx}{\textwidth}{p{4.5cm} X} -\texttt{GLITE\_WMS\_QUERY\_SERVER} & \textbf{The} \LB server. This is the server that will be contacted and tested if no hostname is supplied to the probe. \\ -\texttt{GLITE\_LB\_SERVER\_PORT GLITE\_LB\_LOGGER\_PORT} & Specifies the \LB server port or the \LB local logger port, respectively. It is used only in case a hostname is given as a command line argument to the probe wit no port number. \\ -% This is not a very nice way to set two parapgraps aside. I hate the fixed width setting but I could not find any other solution. -\end{tabularx} - -\subsubsection{Sample Nagios Service Definition} -Simple definition to be included in \texttt{/etc/nagios/commands.cfg}: - -\begin{verbatim} -define command{ - command_name check-lb-server - command_line /usr/libexec/grid-monitoring/probes/emi.lb/LB-probe \$HOSTADDRESS$ - } -\end{verbatim} - - diff --git a/org.glite.lb.doc/src/LBTP-PerfTests.tex b/org.glite.lb.doc/src/LBTP-PerfTests.tex deleted file mode 100644 index a403e35..0000000 --- a/org.glite.lb.doc/src/LBTP-PerfTests.tex +++ /dev/null @@ -1,552 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\section{Performance and stress tests} -\label{s:perftests} - -%\TODO{Michal: nejak sesynchronizovat s webem} -In this section we describe only the general idea of performance and stress tests of \LB components. -This work is in progress and all necessary information is updated at the wiki page: - -\begin{center} -\url{http://egee.cesnet.cz/mediawiki/index.php/LB_and_JP_Performance_Testing} -\end{center} - -The general idea is thus the following: - -\begin{itemize} - -\item All source modifications for tests are in CVS, conditionally compiled only -with appropriate symbol. - -\item To compile LB with performance testing enabled, set environment variable -\verb'LB_PERF' to 1 prior to LB build: -\begin{verbatim} - export LB_PERF=1 - etics-build org.glite.lb -\end{verbatim} - -\item Component tests are run by shell scripts located under component -directories, these tests may require binaries from other components, though. - -\item All tests use sequence of events for typical jobs (small job, big job, -small DAG, big DAG) prepared beforehand. These events are stored in files in -ULM format in CVS (see \texttt{org.glite.lb.common/examples}). -%\TODO{new strategy? use real jobs...} - -\item Events are generated by \verb'glite-lb-stresslog' program, which reads -ULM text of events for particular test job and logs the event sequence directly -by calling \verb'*_DoLogEvent'. The number of test jobs is -configurable. Stresslog inserts into every event timestamp when the event was -generated and sent. - -\item Events are consumed by breaking normal event processing either in the -component being tested or the next component in chain, that is instrumented to -read and discard events immediately. The consumption itself is done by calling -special function which takes current time, extracts timestamp from event and -prints the difference (ie.. the event processing time)\footnote{the only -exception is test of the logging library itself}. These "break points" are -chosen to measure throughput of the various component parts and to identify -possible bottlenecks within the components. - -\item Test jobs are preregistered within the LB if the test includes -bookkeeping server and/or proxy by the test script program and their id's are -stored in separate file to enable re-use by other load-generating tools (status -queries, for example). - -\item Test results: - \begin{itemize} - \item Some numbers must be reported by component themselves, not by - the event generator (due to the asynchronous LB nature). The - test script collects those numbers and presents them as the test - result at the end of testing. - - \item After completion test scripts print the table described for the - respective tests filled in with measured values (ie.. the table - is not filled in manually by human tester). - - \item Measure event throughput by - \[ \mbox{event\_throughput} = \frac{1}{\mbox{time\_delivered} - \mbox{time\_arrived}} \] -%\TODO{measure job throughput for event patterns of typical jobs or deduce -%job throughput from throughput of selected types of events?} - - \item Publish the results on the web. - -% \item \TODO{ETICS test framework is used to run performance and stress tests automatically.} - \end{itemize} - -% vztahuje se k cemu? -% * only if next event is sent after previous was delivered -% -\end{itemize} - - - -\endinput - - -In the following subsections we describe performance and stress tests for -individual LB components. They include both tests of the isolated components -on one node (may require binaries from other components to produce/consume -events) as well as tests of LB components among more nodes. - - -%-------------------- -\subsection{Logging library test} -%-------------------- - -\begin{verbatim} -* component: - org.glite.lb.client - -* binaries required: - logevent_libtest - -* test shell script: - perftest_loglib - -* input required: - - events - -* test description: - - measures time required to format given events into ULM. Events - are read from file, parsed into components, timestamped and - produced. - - - events produced: - - by calling logging function edg_wll_LogEvent*() - - - events consumed: - - discarded by logging function instead of sending via - appropriate protocol (LogEventMaster) - -* results: - - job type (size) throughput (100k jobs) - ----------------------------------------- - small job - big job - small DAG - big DAG - -\end{verbatim} - - -% ---------------- -\subsection{Local logger test} -% ---------------- - -\begin{verbatim} -* component: - org.glite.lb.logger - -* binaries required: - stresslog - glite_lb_logd_perf - glite_lb_logd_perf_nofile - - does not store events in file - glite_lb_interlogd_perf_empty - - consumes immediately after reading event - -* test shell script: - perftest_logd - -* input required: - - client and host certificates - - events - -* test description: - - measures time required for event to be sent from client to - local logger and processed by local logger. Local logger is - either instructed (by option) or instrumented to skip some - parts of event processing: - a) no parse, no file, no ipc - glite_lb_logd_perf_nofile --noParse --noIPC - b) no file, no ipc - glite_lb_logd_perf_nofile --noIPC - c) no ipc - glite_lb_logd_perf --noIPC - d) normal operation - glite_lb_logd_perf - - no parse - LL does not parse events - no file - LL does not store events into files - no ipc - LL does not send events through socket to IL - - - events produced: - - stresslog sends events to logd using client->logd - protocol (*_DoLogEvent()) - - - events consumed: - i) after storing into files - ii) by "empty" IL - -* results: - - - -i) events stored in files - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - a) - b) - c) - d) - -ii) events sent to IL - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - a) - b) - c) - d) - - -\end{verbatim} - -% ---------------- -\subsection{Interlogger test} -% ---------------- - -\begin{verbatim} -* component: - org.glite.lb.logger - -* binaries required: - stresslog - glite_lb_interlogd_perf - glite_lb_interlogd_perf_noparse - - does not parse events, server address is hard-coded - glite_lb_interlogd_perf_nosync - - does not call event_store_sync() - glite_lb_interlogd_perf_norecover - - recovery thread disabled - glite_lb_interlogd_perf_nosend - - events are consumed instead of sending - glite_lb_interlogd_perf_lazy - - lazy closing connection to bkserver - glite_lb_bkserverd_perf_empty - - consumes event immediately after receiving - -* test shell script: - perftest_interlogd - -* input required: - - host certificate - - events - -* test description: - - measures time the event travels through interlogger. - Interlogger is instrumented to skip some parts of event - processing for particular test, specifically tests include - these variants: - a) disabled event parsing. The server address - (eg. jobid) is hard-coded. - b) disabled event synchronization from files - c) disabled recovery thread - d) lazy bkserver connection close - e) normal operation - - - events produced: - 1) stresslog sends events to interlogger using the UNIX - domain socket and logd->interlogger protocol, events are - stored in files (stresslog behaves like logd) -% TODO: pro toto neni funkce v producerske knihovne - 2) interlogger reads events from event files created by - stresslog (by recovery thread) - 3) stresslog stores events to files and every n-th - (optional argument) is sent also through the UNIX socket - - - events consumed: - i) discarded instead of being sent - ii) by "empty" bkserver - -* results: - - -i) events discarded -1) events received on socket -(options 2 and 3 are not tested) - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - a) - b) - c) - e) - - -ii) events sent to empty bkserver -1) events received on socket - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - a) - b) - c) - d) - e) - - -2) events recovered from files - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - d) - e) - - -3) events synced from files, every 10th event sent on socket - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - a) - b) - c) - d) - e) - -\end{verbatim} - -% ------------ -\subsection{LBProxy test} -% ------------ - -\begin{verbatim} -* component: - org.glite.lb.proxy - -* binaries required: - stresslog - glite_lb_proxy_perf_noparse - - consumes events before parsing - glite_lb_proxy_perf_nostore - - consumes events before storing into database - glite_lb_proxy_perf_nostate - - consumes events before computing job status - glite_lb_proxy_perf_nosend - - consumes events before sending to interlogger - glite_lb_interlogd_perf_empty - - consumes immediately after reading event - -* test shell script: - perftest_proxy - -* input required: - - events - -* test description: - - measures time required for processing event by LB proxy. Test - is performed with (a)) and without (b)) checking for duplicate - events. - - - events produced: - - stresslog sends events using the IL protocol on local - socket (using DoLogEventProxy()) - - - events consumed: - i) before parsing - ii) before storing into database - iii) after storing into database - iv) after job status computation - v) normal operation - - - - -* results: - -a) with duplicity check: - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - i) - ii) - iii) - iv) - v) - - -b) without duplicity check: - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - i) - ii) - iii) - iv) - v) -\end{verbatim} - -%-------------- -\subsection{LB server test} -% -------------- - - -\begin{verbatim} -* component: - org.glite.lb.server - -* binaries required: - stresslog - glite_lb_server_perf_noparse - - consumes events before parsing - glite_lb_server_perf_nostore - - consumes events before storing into database - glite_lb_server_perf_nostate - - consumes events before computing job status - -* test shell script: - perftest_server - -* input required: - - host certificates - - events - -* test description: - - measures time required for processing event by LB server. Test - is performed with (a)) and without (b)) checking for duplicate - events. - - - events produced: - - stresslog sends events using the IL protocol (using DoLogEventDirect()) - - - events consumed: - i) before parsing - ii) before storing into database - iii) after storing into database - iv) normal operation - -* results: - -a) with duplicity check: - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - i) - ii) - iii) - iv) - - -b) without duplicity check: - - throughput: small big small big - job job DAG DAG - ------------------------------------------------- - i) - ii) - iii) - iv) - -\end{verbatim} - -% --------------------- -\subsection{Job registration test} -% --------------------- - -\begin{verbatim} -* component: - org.glite.lb.server - org.glite.lb.proxy - -* binaries required: - stressreg - - generates registration events - glite_lb_bkserverd - glite_lb_proxy - glite_lb_bkserverd_perf_empty - glite_lb_proxy_perf_empty - -* test shell script: - perftest_jobreg - -* input required: - - host & user certificates - -* test description: - - measures time required to register given number of jobs (time - to process registration event). The registration event is - synchronous in principle, so it is possible to get results just - from the client (stressreg). Test variants include: - a) current implementation - b) implementation of connection pool at the client - c) parallel communication with server and proxy - - - - events produced: - - stressreg sends registration events by calling - edg_wll_RegisterJob*() - - - events consumed: - i) normally processed by server & proxy - ii) server replies immediate success - iii) proxy replies immediate success - -* results: - -a) current implementation - - throughput: one DAG DAG DAG - job (1000 nodes) (5000 nodes) (10000 nodes) - ----------------------------------------------------------------- - i) - ii) - iii) - - -b) connection pool - - throughput: one DAG DAG DAG - job (1000 nodes) (5000 nodes) (10000 nodes) - ----------------------------------------------------------------- - i) - ii) - iii) - - -c) parallel communication - - throughput: one DAG DAG DAG - job (1000 nodes) (5000 nodes) (10000 nodes) - ----------------------------------------------------------------- - i) - - -\end{verbatim} - -% --------------------- -\subsection{"Real world" tests} -% --------------------- - -Aim of these tests is to simulate real environment of the LB operation as -closely as possible. We simulate the environment on WMS node as this is the -most performance critical point. Events are sent through proxy and interlogger -on one machine (WMS node) to the server on another machine (LB node), we also -create some background noise by simultaneously polling the server and/or proxy -for job status by several clients in parallel. - diff --git a/org.glite.lb.doc/src/LBTP-Tests.tex b/org.glite.lb.doc/src/LBTP-Tests.tex deleted file mode 100644 index 3bc588b..0000000 --- a/org.glite.lb.doc/src/LBTP-Tests.tex +++ /dev/null @@ -1,659 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% System tests - -\section{System functionality tests} -\label{s:functionality} - -\subsection{Test Suite Overview} - -This subsection gives a comprehensive overview of all system functionality tests. - -\subsubsection{Test Scripts} - -Besides pure System Functionality Tests, this list also includes In-the-Wild tests and Regression Tests discussed in a few following chapters. They are used in the same manner and, typically, on the same occasions, which is why they are all listed in the same place. - -\begin{tabularx}{\textwidth}{|l|X|} -\hline - {\bf Executable} & {\bf Use} \\ -\hline -{\tt lb-test-job-registration.sh} & Tries to register a job and checks if the registration worked. \\ -\hline -{\tt lb-test-event-delivery.sh} & Tries to register a job and log events. Checks if the registration worked and events resulted in state change accordingly. \\ -\hline -{\tt lb-test-https.sh} & Test the HTTPs interface. \\ -\hline -{\tt lb-test-logevent.sh} & Test if local logger accepts events correctly (i.e. returns 0). \\ -\hline -{\tt lb-test-il-recovery.sh} & Tests if interlogger recovers correctly and processes events logged in between when restarted. \\ -\hline -{\tt lb-test-job-states.sh} & Test that job state queries return correctly and that testing jobs are in expected states. \\ -\hline -{\tt lb-test-collections.sh} & Perform various collection-specific tests. \\ -\hline -{\tt lb-test-proxy-delivery.sh} & Test correct event delivery through \LB proxy. \\ -\hline -{\tt lb-test-ws.sh} & Query events and job states through the Web-Service interface. \\ -\hline -{\tt lb-test-notif.sh} & Test if notifications are delivered correctly for testing jobs. \\ -\hline -%{\tt lb-test-notif-additional.sh} & Proposed & Test notification delivery with additional options. \\ -%\hline -{\tt lb-test-notif-switch.sh} & Test the correct behavior of a notification once its target jobid changes. \\ -\hline -{\tt lb-test-notif-recovery.sh} & Test if notification client receives notifications correctly upon restart. \\ -\hline -{\tt lb-test-purge.pl} & Test that \LB server purge works correctly. \\ -\hline -{\tt lb-test-wild.pl} & Test \LB ``in the wild'' (test with real-life WMS). \\ -\hline -{\tt lb-test-bdii.sh} & Test \LB server is published correctly over BDII. \\ -\hline -{\tt lb-test-sandbox-transfer.sh} & Test \LB's support for logging sandbox transfers. \\ -\hline -{\tt lb-test-changeacl.sh} & Test proper parsing of \code{ChangeACL} events. \\ -\hline -{\tt lb-test-statistics.sh} & Test statistic functions provided by \LB \\ -\hline -{\tt lb-test-threaded.sh} & Rudimentary test for threaded clients \LB \\ -\hline -{\tt lb-test-notif-msg.sh} & Test delivery of \LB notifications over ActiveMQ \\ -\hline -{\tt lb-test-permissions.sh} & Check ownership and permission settings for config and runtime files \\ -\hline -{\tt lb-test-nagios-probe.sh} & Run the nagios probe and check results \\ -\hline -{\tt lb-test-notif-keeper.sh} & Test the \texttt{notif-keeper} script \\ -\hline -\end{tabularx} - -\subsubsection{Event logging examples} - -There is an {\tt examples} subdirectory in {\tt GLITE\_LOCATION}. It holds various example files---both binaries and scripts. There is---among others---a suite of scripts aimed at testing event delivery and the proper operation of the \LB state machine. Scripts named {\tt glite-lb-.sh}---where {\tt } corresponds with a job state---can be used to generate sequences of events that will always get an existing job into that state. (For example the {\tt glite-lb-running.sh} script logs a series of 12 events resulting in the job state turning to running.) Some of these scripts are used by system functionality tests detailed bellow but all of them can also be used for manual testing. - -\subsection{Event delivery} - -\subsubsection{Normal event delivery} -\label{normal} -% event delivery -% poslat .sh, job log vrati to, co bylo ve fajlech - -\req\ all \LB\ daemons running (\path{glite-lb-logd}, \path{glite-lb-interlogd}, -\path{glite-lb-bkserverd}) - -\what\ -\begin{enumerate} -\item Register jobs with \code{edg\_wll\_RegisterJob} -\item Log reasonable sequences of events with \code{edg\_wll\_Log*}, both through logger and/or proxy -\item Check with \code{edg\_wll\_JobLog} that the events got delivered afterwards (approx. 10s). -\item Also check delivery and processing of events related to collections. -\end{enumerate} - -\how\ \ctblb{lb-test-event-delivery.sh} -% org.glite.testsuites.ctb/LB/lb-l2.sh now does the following: -% - array_job_reg: registeres $JOBS_ARRAY_SIZE jobs -% - logEvents: logs events by glite-lb-$state.sh example scripts -% - logTags: logs user tags -% - testLB: calls glite-lb-job_log for all jobs -% - testLB2: calls glite-lb-job_status for all jobs -% -% What needs to be done: -% - rename the script, tidy it -% - create some meaningful sequence of events for logEvents - -\note\ The test includes artificial delays. Takes approx. 60\,s to finish. - -\result\ All sub tests (API calls) should return 0. The same events that were logged must be returned. - - -\subsubsection{Job registration only} -\label{reg} -\req\ running \path{glite-lb-bkserverd} - -\what\ call \code{edg\_wll\_RegisterJob}. Jobids should preferably point -to a~remote \LB\ server. Try re-registration using flag \code{EDG\_WLL\_LOGLFLAG\_EXCL} in various scenarios. - -\how\ \ctblb{lb-test-job-registration.sh} - -\result\ All sub tests (API calls) return 0. - -%\begin{hints} -%\path{glite-lb-regjob} example can be used. It generates a~unique jobid, -%prints it and calls \LB\ API appropriately. -%\end{hints} - - - -\subsubsection{Standalone local logger -- log event} -\label{log} -% async -- prida do fajlu, OK -% logevent - -\req\ running \path{glite-lb-logd} only, jobs registered in test~\ref{reg}. - -\what\ call \code{edg\_wll\_Log*} for various event types in a~sequence -resembling real \LB\ usage, using the same jobids as in test~\ref{reg} - -\how\ \ctblb{lb-test-logevent.sh [event-file-prefix]} - -\result\ All sub tests (API calls) return 0, events are added one per line to the local logger files. - - - -\subsubsection{Interlogger recovery} -\label{recover} -% recover interloggeru -% il & server (remote) -% spustit, protlaci soubory na server, soubory zmizi, lze se dotazat na stav - -\req\ running \path{glite-lb-bkserverd} on the machine and port where -jobids from \ref{reg} point to; files generated in~\ref{log}; -\path{glite-lb-interlogd} is stopped. - -\what\ Make a~copy of the files created in~\ref{log}, then start -\path{glite-lb-interlogd}. After approx. 10\,s check the jobs -with \code{edg\_wll\_JobLog} call. - -\how\ \ctblb{lb-test-il-recovery.sh} - -\note\ The test includes artificial delays. Takes approx. 15 to 75\,s to finish. - -\result \code{edg\_wll\_JobLog} should return the same events that were -contained in the local logger files. The files should be removed by -interlogger after approx. 1 min. - -%\begin{hints} -%\path{glite-lb-joblog} example outputs the events in (almost) the same -%format as the local logger files. -%\end{hints} - - - - -\subsection{Job state computation} - -\subsubsection{Normal job states} -\label{state} -% normal event delivery & job state machine -% .sh, dotaz na stav - -\req\ \path{glite-lb-bkserverd} running, events from \ref{normal} logged. - -\what\ Check state of the jobs with \code{edg\_wll\_JobStatus}. Check all possible job states -(if necessary, log relevant events). Query both server and/or proxy. - -\how\ \ctblb{lb-test-job-states.sh} - -\note\ The test includes artificial delays. Takes approx. 150\,s to finish. - -\result\ The API call should return 0, the jobs should be in the expected -states. Thorough tests may also cross check the values supplied in the -events (e.g. destination computing element) wrt. the values reported in the job states. - - -\subsubsection{Sandbox Transfers} - -\req\ All \LB\ services running - -\what\ -\begin{enumerate} -\item Register a compute job. -\item Register input sandbox transfer. -\item Register output sandbox transfer. -\item Generate events to trigger job state changes in one of the sandbox transfer jobs. - \begin{enumerate} - \item Start the transfer and check that state has changed appropriately. - \item Finish the transfer and check that state has changed appropriately. - \end{enumerate} -\item Use another sandbox transfer job registered above to start, then fail the transfer and check that this is reflected by the resulting transfer job status. -\item Check that the compute job and its sandbox transfer jobs link up correctly. - -\end{enumerate} - -\how\ \ctblb{lb-test-sandbox-transfer.sh} - -\note\ The test includes artificial delays. Takes approx. 50\,s to finish. - -\result\ Job states should change on event delivery as expect, related jobs should ``know'' their IDs. - - -\subsubsection{Collection-specific Tests} - -\req\ All \LB\ services running - -\what\ -There is no specific workflow for this test. It is a placeholder for various minor feature and regression tests related to job collections. - -\how\ \ctblb{lb-test-collections.sh} - -\result\ All included checks should finish OK. - - -%\subsubsection{Non-simple job states} -%\TODO{dags, collections, their states and states (and histogram) of their children/subjobs, ...} - - - -%\subsection{Query tests} -%\TODO{query all my jobs, query one job, query with some structured conditions, some other queries that caused problems in the past, ...} - - -\subsection{\LB server and proxy combined test} - -\req\ running \path{glite-lb-proxy}, \path{glite-lb-interlogd} and -\path{glite-lb-bkserverd} - -\what\ Register jobs with \code{edg\_wll\_RegisterJobProxy}, log events -using \code{edg\_wll\_LogEventProxy} and check the job states against -both lbproxy (using \code{edg\_wll\_JobStatusProxy}) and bkserver -(using \code{edg\_wll\_JobStatus}). Also test job collections and registration, including registration of subjobs. Pay special attention to job reaching final -job status and to the automatic purge from proxy. - -% - check the timeouts. - ??tam byly nejaky timeouty??? - -\how\ \ctblb{lb-test-proxy-delivery.sh} - -%\TODO{mozna to ma prijit do nejakeho testsuitu, netusim} -{\tt glite-lb-running.sh -x -m LB\_HOST:PORT} \\ -- logs sequence of events and returns JOBID \\ - -{\tt Q1: glite-lb-job\_status -x JOBID } \\ -{\tt Q2: glite-lb-job\_status JOBID } \\ -- Q1 queries LB proxy, Q2 queries LB server - both should return status of the job \\ - -{\tt glite-lb-cleared.sh -x -m JOBID} \\ -- logs sequence of events to JOBID pushing it to terminal state \\ - -{\tt Q1: glite-lb-job\_status -x JOBID } \\ -{\tt Q2: glite-lb-job\_status JOBID } \\ -- Q1 returns {\em error: edg\_wll\_JobStatusProxy: No such file or directory (no matching jobs found)} while Q2 returns state of the job until it is purged \\ - -\result\ A new job state should be available immediately at the -lbproxy and probably with a small delay also at the bkserver. Jobs that reach the final job state -are really purged from the proxy. - -\note\ The test includes artificial delays. Takes approx. 50\,s to finish. - - -\subsection{WS interface} -%\TODO{fila, valtri: tests using Java example} -\req\ \path{glite-lb-bkserverd} running, events from \ref{normal} logged - -\what\ retrieve both events and job states with the \LB\ WS interface -(operations \code{JobStatus}, \code{QueryEvents}). - -\how\ \ctblb{lb-test-ws.sh} - -\note\ The test includes artificial delays. Takes approx. 10\,s to finish. - -\result\ the returned data should match those returned by the legacy API calls. - - - - -%\subsection{HTML interface} -%\TODO{fila: query tests using wget/curl} - - - -%\subsection{Change ACL} -%\TODO{kouril: to be added later with new authz schema} - - - - -\subsection{Notifications} -% notifikace -% regjob, reg notifikace na vsechno, poslat udalosti, hlidat notif - -All notification tests require the \LB server to be run with notifications enabled, -i.e. to be run for example with options -\texttt{--notif-il-sock /tmp/sock.test\_notif --notif-il-fprefix /tmp/test\_notif}, -where \texttt{/tmp/sock.test\_notif} is a socket of notification interlogger. - -Please see also \cite{lbug}, Section 2.4, for other possible scenarios how to test the notification delivery. - - -\subsubsection{Single job, any state change} -\label{notif1} -\req\ All \LB\ services running - -\what -\begin{enumerate} -\item Register a job. -\item Start a~notification client, -register with \code{edg\_wll\_NotifNew} for any state changes of the job, -and invoke \code{edg\_wll\_NotifReceive}. -\item Send events triggering job state changes. -\end{enumerate} - -\how\ \ctblb{lb-test-notif.sh} - -\note\ The test includes artificial delays. Takes approx. 12\,s to finish. - -\result\ All the events should trigger notifications reported by the running -notification client. - -%\begin{hints} -%\path{glite-lb-notify} example can be used with its commands \path{new} and \path{receive}. -%\end{hints} - - -\subsubsection{Include another job} -\label{notif2} -\req\ All \LB\ services running, notification from \ref{notif1} still active - -\how\ -\begin{enumerate} -\item Register another job. -\item Augment the notification registration with the new jobid using -\code{edg\_wll\_NotifChange}. -\item Start notification client, bind to the registration with -\code{edg\_wll\_NotifBind}. -\item Send events for the new job. -\end{enumerate} - -\how\ \ctblb{lb-test-notif-switch.sh} - -\note\ The test includes artificial delays. Takes approx. 25\,s to finish. Also note that this test will not work with \LB versions older than 2.0. - -\result\ Notifications should be received by the client. - -%\begin{hints} -%Commands \path{change} and \path{receive} of \path{glite-lb-notify} -%can be used. -%\end{hints} - -% notifikace -- zmena adresy/portu -% pak poslat udalost, musi dojit -% uz je v predchozim implicitne - - - -\subsubsection{Delayed delivery} -% notifikace -- zpozdene doruceni -% registrovat, odpojit, poslat udalosti, pripojit se - -\req\ All \LB\ services running - -\what\ -\begin{enumerate} -\item Register another job. -\item Register a~notification as in~\ref{notif1} but terminate the client -immediately. -\item Log events for the job. -\item Restart the client, binding to the notification and call -\code{edg\_wll\_NotifReceive} repeatedly. -\end{enumerate} - -\how\ \ctblb{lb-test-notif-recovery.sh} - -\note\ The test includes artificial delays. Takes approx. 25\,s to finish. - -\result\ Delayed notifications should be received by the client almost -immediately. - - -\subsubsection{Delivery to ActiveMQ} -\label{notifamq} -\req\ All \LB\ services running, ActiveMQ broker configured and running - -\what -\begin{enumerate} -\item Register a job. -\item Start a~notification client, -\item Retrieve broker address from the server (since \LBver{3.2}) -register with \code{edg\_wll\_NotifNew} for any state changes of the job, -and listen for messages. -\end{enumerate} - -\how\ \ctblb{lb-test-notif-msg.sh} - -\note\ The test includes artificial delays. Takes approx. 25\,s to finish. - -\result\ All the events should trigger notifications that will be reported -through ActiveMQ messages. - -%\begin{hints} -%The \path{glite-lb-notify} example can be used to register a notification and \path{glite-lb-cmsclient} can be used to receive messages. -%\end{hints} - - -\subsection{Site Notification Maintenance} -\label{notifkeeper} - -\req\ All \LB\ services running. - -\what -\begin{enumerate} -\item Create or modify a \texttt{site-notif.conf} file -\item Run the ``keeper'' script and check if the effect was as desired -\begin{itemize} -\item Setting up a new notification -\item Changing its conditions -\item Registering for anonymized notifications -\item \dots -\end{itemize} -\item Repeat from step~1 with different settings until all scenarios have been checked -\end{enumerate} - -\how\ \ctblb{lb-test-notif-keeper.sh} - -\note\ The test includes artificial delays. Takes approx. 30\,s to finish. - -\result\ Notifications must be registered and messages must arrive matching the currently applicable contents of the config file. - - -\subsection{Server purge} - -\textbf{WARNING: This test is destructive, it destroys ALL data in an -existing \LB\ database.} - -The test is fairly complex but it does not make too much sense to split it -artificially. - -\req\ All \LB services running, preferably a~dedicated server for this test. - -\what -\begin{enumerate} -\item Purge all data on the server with \path{glite-lb-purge} -\item Log two sets of jobs, separated with delay of at least 60s so -that the sets can be distinguished from each other. -\item \label{purge1} -Using \code{edg\_wll\_JobLog} retrieve events of all the jobs -\item \label{purge2} -Purge the first set of jobs (by specifying appropriate timestamp), -letting the server dump the purged events. -\item \label{purge3} Purge the other set of jobs, also dumping the events. -\item \label{purge4} Run purge once more. -\item Check if purged jobs turned into zombies. -\item In addition, check if a \emph{cron} task exists to run the \emph{purge} operation regularly and that it logs its output correctly. -\end{enumerate} - -\how\ \ctblb{lb-test-purge.pl} - -\note\ The test includes artificial delays. Takes approx. 3.5\,minutes to finish. - -\note\ This test is destructive to your data. You need to run it with the \texttt{-{}-i-want-to-purge} option to confirm your intention. Also, you need to provide the \LB server \texttt{address:port} explicitly as an argument to rule out any confusion. - -\result\ Data dumped in steps \ref{purge1} and \ref{purge2} should be the -same as retrieved in~\ref{purge1}. The final purge invocation should -do nothing (i.e. nothing was left in the database). - -% test_purge -%\begin{hints} -%The example \path{org.glite.lb.client/examples/purge\_test} does exactly this sequence of steps, -%including the checks. -%\end{hints} - -\subsection{Other Service Tests} - -\subsubsection{ACL Parsing} - -\req\ All \LB\ services running - -\what\ -\begin{enumerate} -\item Register a job. -\item Send a \code{ChangeACL} event to add authorized user. -\item Check job status to see if the event was processed correctly. -\end{enumerate} - -\how\ \ctblb{lb-test-changeacl.sh} - -\note\ The test includes artificial delays. Takes approx. 15\,s to finish. - -\note\ This test does not check if the setting actually takes effect. Implementing that functionality -- relying on the use of at least two different identities -- in an automated test is rather challenging. - -\result\ The \emph{test~DN} should be listed in the job's ACL. - -\subsubsection{Statistics} - -\req\ All \LB\ services running - -\what\ -\begin{enumerate} -\item Register a series of jobs. -\item Generate events to push jobs to a given state. -\item Run statistics to calculate rate of jobs reaching that state. -\item Query for average time needed by test jobs to go from one state to another. -\item Check if the statistics returned reasonable results. -\end{enumerate} - -\how\ \ctblb{lb-test-statistics.sh} - -\note\ The test includes artificial delays. Takes approx. 30\,s to finish. - -\result\ Meaningful values should be returned by both tests. - -\subsubsection{Multi-Threaded Operation} - -\req\ \LB\ server running - -\what\ -\begin{enumerate} -\item Register a series of jobs. -\item Run a client using multiple threads to query the server simultaneously. -\item Check if all threads finished OK. -\end{enumerate} - -\how\ \ctblb{lb-test-threaded.sh} - -\note\ This is not a thorough test. It is not capable of discovering rare or improbable problems but it will check the essentials of multi-threaded opration. - -\result\ The test must not hang. Meaningful results (albeit errors) must be returned by all threads. - -\subsubsection{Config and Runtime File Permissions} -\label{permissions} -\req\ All \LB\ services configured and running. - -\what -\begin{enumerate} -\item Decide on permission/ownership masks for various files identified for checking. -\item Check ownership and permission settings for selected files. -\item Compare that with a pre-determined mask. -\end{enumerate} - -\how\ \ctblb{lb-test-permissions.sh} - -\result\ The status of all files should match the pre-determined mask. - - -\subsubsection{Nagios Probe} -\label{permissions} -\req\ All \LB\ services configured and running, nagios probe\footnote{see also page \pageref{s:nagios}} installed. - -\what -\begin{enumerate} -\item Check probe for presence -\item Run the probe -\item Check if text and exit code are OK or at least consistent -\end{enumerate} - -\how\ \ctblb{lb-test-nagios-probe.sh} - -\result\ The probe has returned OK and exit code was 0. - -\note\ The probe includes artificial delays. The test takes approx. 10\,s to finish. - -\subsubsection{HTTPs Interface} -\label{permissions} -\req\ All \LB\ services configured and running. - -\what -\begin{enumerate} -\item Register a test job -\item Register a test notification -\item Query user jobs over the HTTPs interface -\item Query test job status over the HTTPs interface -\item Query notification status over the HTTPs interface -\item Download server configuration page and check if essential values are present -\item Download statistics page and check if essential values are present and $> 0$ -\end{enumerate} - -\how\ \ctblb{lb-test-https.sh} - -\result\ All information was succesfully downloaded and matched expectations. - - -\section{LB ``In the Wild''---Real-World WMS Test} -\req\ All \LB services running, working grid infrastructure accessible (including permissions). - -\what -\begin{enumerate} -\item Submit a simple \emph{hello-world}-type job. -\item Submit a simple job and cancel it. -\item Submit a collection of simple jobs. -\item Submit a collection and cancel it. -\item Submit a simple job that is sure to fail. -\item Submit a collection of jobs, one of which is sure to fail. -\end{enumerate} - -In all above cases: Watch the life cycle. Check the resulting state (\emph{Cleared}, \emph{Cancelled} or \emph{Aborted}). Check events received in the course of job execution; events from all relevant components must be present (NS, WM, JC, LM, and LRMS). - -\how\ \ctblb{lb-test-wild.sh} - -\result\ Jobs were submitted. Cancel operation worked where applicable. Resulting state was as expected (\emph{Cleared}, \emph{Cancelled} or \emph{Aborted}). Events were received from all components as expected. - -\note\ The test runs automatically. Bear in mind that in a real-life grid, even valid jobs may not always finish successfully. Analyze failures and re-run if necessary. - -\note\ The number of jobs to generate may be specified using the \texttt{-n} argument - -\note\ Job submissions are limited to VOCE CEs in normal circumstances. Use the \texttt{-w} argument to override. - -\note\ Due to the nature of grid computing, this test may take hours to complete! - - - -\section{Regression testing} - -\subsection{Publishing Correct Service Version over BDII} -\req\ All \LB and BDII services running. - -\what -\begin{enumerate} -\item Regression test for bug 55482 (\texttt{http://savannah.cern.ch/bugs/?55482}) -\item Query for information on the server. -\item Check version returned by the query. -\end{enumerate} - -\how\ \ctblb{lb-test-bdii.sh} - -\result\ Query returns proper service status. Proper LB Server version is returned. - -\note\ The test will also ask the \LB server for a version number through its WS interface, and compare the two values. This, however, will not be done if the machine you use to run the tests does not have the proper binaries installed (\texttt{glite-lb-ws\_getversion}), or if you do not make a proxy certificate available. Should that be the case, the test only checks if a version is returned and prints it out, without comparing. - diff --git a/org.glite.lb.doc/src/LBTP.tex b/org.glite.lb.doc/src/LBTP.tex deleted file mode 100644 index 3809cca..0000000 --- a/org.glite.lb.doc/src/LBTP.tex +++ /dev/null @@ -1,74 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\documentclass{emi} -\def\insideTP{} - -\input{definitions} - -\title{Logging and Bookkeeping -- Test Plan \& Test Suite Documentation} -%\Subtitle{Test Plan Test Suite Documentation} -\author{CESNET EGEE III JRA1 and SA3 team} -%\DocIdentifier{glite-lb-doc-tp-\version} -%\DeliverableId{} -\Date{\today} -%\Activity{SA3: Integration, Testing and Certification} -%\DocStatus{FINAL} -\DocVersion{\version} -%\Dissemination{PUBLIC} -%\DocumentLink{\url{http://egee.cesnet.cz/cvsweb/LB/LBTP.pdf}} -\Abstract{\input{LBTP-Abstract}} -\EMICompVersion{3.x} - - -\begin{document} - -%\input{frontmatter} -\input{funding} -\input{copyright} -\tableofcontents - -\newpage -\input{versions} - -\newpage -\input{LBTP-Introduction} - -\newpage -\input{LBTP-IntegrationTests} - -\newpage -\input{LBTP-Tests} - -\newpage -\input{LBTP-PerfTests} - -\newpage -\input{LBTP-InterTests} - -\newpage -\input{LBTP-Nagios} - -%\appendix -%\newpage -%\input{LBTP-Appendix} - -\newpage -\bibliographystyle{unsrt} -\bibliography{lbjp} - -\end{document} - diff --git a/org.glite.lb.doc/src/LBUG-Abstract.tex b/org.glite.lb.doc/src/LBUG-Abstract.tex deleted file mode 100644 index 45c3367..0000000 --- a/org.glite.lb.doc/src/LBUG-Abstract.tex +++ /dev/null @@ -1,22 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% when changed, update also http://egee.cesnet.cz/en/JRA1/LB/lb.html -% (in CVSROOT=:gserver:lindir.ics.muni.cz:/cvs/edg, cvsweb/lb.html) -The User's Guide explains how to use the Logging and Bookkeeping (\LB) service -from the user's point of view. The service architecture is described -thoroughly. Examples on using \LB's event logging commands to log user tags and -change job ACLs are given, as well as \LB query and notification use cases. diff --git a/org.glite.lb.doc/src/LBUG-Appendix.tex b/org.glite.lb.doc/src/LBUG-Appendix.tex deleted file mode 100644 index 0abc1b8..0000000 --- a/org.glite.lb.doc/src/LBUG-Appendix.tex +++ /dev/null @@ -1,142 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\section*{Appendix} - -\section{\LB Event Types} -\label{a:events} -Complete list of all events' names together with their description follows. -% see events.tex.T -\input{events} - -\newpage -\section{\LB Job States} -\label{a:jobstat} -Complete list of all job' states together with their description follows. -% see status.tex.T -\input{status} - -\begin{figure}[h] -\centering -\includegraphics[width=.6\hsize]{images/wms2-jobstat} -\caption{\LB\ job state diagram} -\end{figure} - -\newpage -\subsection{CREAM Job States Mapping} -Support of CREAM jobs is available since \LBver{2.1}. This is the implemented -mapping of job states between CREAM and \LB: -\label{a:creammapping} - -\begin{tabularx}{\textwidth}{>{\bfseries}lX} -CREAM state & \LB state \\ -Registered & Submited \\ -Pending & Waiting \\ -Idle & Scheduled \\ -Running & Running \\ -Really Running & Running \\ -% Held -Done OK & Done \\ -Done Failed & Done \\ -Aborted & Aborted \\ -Cancelled & Cancelled \\ -\end{tabularx} - -\newpage -\section{Environment variables} -\label{a:environment} - -Complete list of all environment variables affecting LB behaviour follows with -their description and default values (if applicable). - -% default values can be read especially from org.glite.lb.common/src/param.c -% and apropriate header files - -\begin{tabularx}{\textwidth}{l>{\raggedright\arraybackslash}X} -GLITE\_WMS\_LOG\_DESTINATION & - % see also glite/lb/log_proto.h (org.glite.lb.common/interface/log_proto.h) - address of the \texttt{glite-lb-logd} daemon (for logging events), - in form \texttt{hostname:port}, - default value is \texttt{localhost:9002}\\ -GLITE\_WMS\_LOG\_TIMEOUT & - % see also glite/lb/timeouts.h (org.glite.lb.common/interface/timeouts.h) - timeout (in seconds) for asynchronous logging, - default value is \texttt{120} seconds, - maximum value is \texttt{300} seconds \\ -GLITE\_WMS\_LOG\_SYNC\_TIMEOUT & - % see also glite/lb/timeouts.h (org.glite.lb.common/interface/timeouts.h) - timeout (in seconds) for synchronous logging, - default value is \texttt{120} seconds, - maximum value is \texttt{600} seconds \\ -GLITE\_WMS\_NOTIF\_SERVER & - address of the \texttt{glite-lb-bkserver} daemon (for receiving notifications) - in form \texttt{hostname:port}, for receiving notifications, - there is no default value, - mandatory for \texttt{glite-lb-notify} \\ -GLITE\_WMS\_NOTIF\_TIMEOUT & - % see also glite/lb/timeouts.h (org.glite.lb.common/interface/timeouts.h) - timeout (in seconds) for notification registration, - default value is \texttt{120} seconds, - maximum value is \texttt{1800} seconds \\ -GLITE\_WMS\_QUERY\_SERVER & - address of the \texttt{glite-lb-bkserver} daemon (for queries), - in form \texttt{hostname:port}, - there is no default value \\ -GLITE\_WMS\_QUERY\_TIMEOUT & - % see also glite/lb/timeouts.h (org.glite.lb.common/interface/timeouts.h) - timeout (in seconds) for queries, - default value is \texttt{120} seconds, - maximum value is \texttt{1800} seconds \\ -GLITE\_WMS\_LBPROXY\_STORE\_SOCK & - UNIX socket location for logging to LB Proxy, - default value is \texttt{/tmp/lb\_proxy\_store.sock} \\ -GLITE\_WMS\_LBPROXY\_SERVE\_SOCK & - UNIX socket location for queries to LB Proxy, - default value is \texttt{/tmp/lb\_proxy\_serve.sock} \\ -GLITE\_WMS\_LBPROXY\_USER & - user credentials (DN) when communicating with LB Proxy, - there is no default value \\ -X509\_USER\_CERT, X509\_USER\_KEY & - location of user credentials (certificate and private key), - default values are \texttt{~/.globus/user{cert,key}.pem} \\ -GLOBUS\_HOSTNAME & - hostname to appear as event origin, useful only for debugging, - default value is hostname \\ -QUERY\_SERVER\_OVERRIDE & - values defined in QUERY\_SERVER will override also values in jobid in queries, - useful for debugging only, - default value \texttt{no} \\ -QUERY\_JOBS\_LIMIT & - maximal size of results for query on jobs, - default value is \texttt{0} (unlimited) \\ -QUERY\_EVENTS\_LIMIT & - maximal size of results for query on events, - default value is \texttt{0} (unlimited) \\ -QUERY\_RESULTS & - specifies behavior of query functions when size limit is reached, - value can be \texttt{None} (no results are returned), - \texttt{All} (all results are returned, even if over specified limit), - \texttt{Limited} (size of results is limited to size specified by QUERY\_JOBS\_LIMIT - or QUERY\_EVENTS\_LIMIT) \\ -CONNPOOL\_SIZE & - maximal number of open connections in logging library, - for developers only, - default value is \texttt{50} \\ -\end{tabularx} - -For backward compatibility, all \verb'GLITE_WMS_*' variables can be prefixed by -\verb'EDG_WL_' instead, for example \verb'EDG_WL_LOG_DESTINATION'. - diff --git a/org.glite.lb.doc/src/LBUG-Introduction.tex b/org.glite.lb.doc/src/LBUG-Introduction.tex deleted file mode 100644 index 3988522..0000000 --- a/org.glite.lb.doc/src/LBUG-Introduction.tex +++ /dev/null @@ -1,978 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\section{\LB Architecture} - -%historie: vyrobeno pro WMS v EDG, 1. a 2. verze (seq. èísla, -%cache a dotazy na stavy), v EGEE gLite---ustabilnìní, proxy - -\LB's primary purpose is tracking WMS jobs as they are processed by -individual Grid components, not counting on the WMS to provide this data. -The information gathered from individual sources is collected, stored in -a database and made available at a single contact point. The user gets a -complete view on her job without the need to inspect several service logs -(which she may not be authorized to see in the entirety or she may not be -even aware of their existence). - -While \LB keeps track of submitted and running jobs, the information is -kept by the \LB service also after the job has been finished (successfully -completed its execution, failed, or has been canceled for any reason). The -information is usually available several days after the last event -related to the job arrived, to give user an opportunity to check the job's -final state and eventually evaluate failure reasons. - -As \LB collects also information provided by the WMS, the WMS services are -no longer required to provide a job-state querying interface. Most of the -WMS services can be even designed as stateless---they process a~job and -pass it over to another service, not keeping state information about the job -anymore. During development and deployment of the first WMS version this -approach turned to be essential in order to scale the services to the -required extent~\cite{jgc}. - -\LB must collect information about all important events in the Grid job -life. These include transitions between components or services, results -of matching and brokerage, waiting in queue systems or start and end of -actual execution. -We decided to achieve this -goal through provision of an API (and the associated library) and -instrumenting individual WMS services and other Grid components with direct -calls to this API. But as \LB is a centralized service (there exists -a single point where all information about a particular job must -eventually arrive), direct synchronous transfer of data could have -prohibiting impact on the WMS operation. -The temporary unavailability or overload of the remote \LB service -must not prevent (nor block) the instrumented service to perform as usual. -An asynchronous model with a clear \emph{asynchronous delivery -semantics}, see Sect.~\ref{gathering}, is used to address this issue. - -As individual Grid components have only local and transient view of a -job, they are able to send only information about individual events. This -raw, fairly complex information is not -a~suitable form to be presented to the user for frequent queries. It must -be processed at the central service and users must be presented primarily with this -processed form. This form is derived from the \emph{job state} and its -transition, not from the job events themselves. The raw information is -still available, in case more detailed insight is necessary. - -While the removal of state information from (some of) the WMS services -helped to achieve the high scalability of the whole WMS, the state -information is still essential for the decisions made within the resource -broker or during the matchmaking process. -\Eg decision on job resubmission is usually affected by the number of -previous resubmission attempts. This kind of information is currently -available in the \LB only, so the next ``natural'' requirement has been -to provide an interface for WMS (and other) services to the \LB to query -for the state information. However, this requirement contains two -contradictions: (i)~due to the asynchronous event delivery model, the \LB -information may not be up to date and remote queries may lead to unexpected -results -(or even inconsistent ones---some older information may not be available for -one query but may arrive before a subsequent query is issued), -and (ii)~the dependence on a~remote service to provide vital state information -may block the local service if the remote one is not responding. -These problems are addressed by providing \emph{local view} of the \LB data, -see Sect.~\ref{local} - - - - -\subsection{Concepts} - - -\subsubsection{Jobs and events} -To keep track of user jobs on the Grid, we first need some reliable -way to identify them. This is accomplished by assigning a unique -identifier, which we call \emph{jobid} (``Grid jobid''), to every job -before it enters the Grid. A~unique jobid is assigned, making it the -primary index to unambiguously identify any Grid job. This jobid is then -passed between Grid -components together with the job description as the job flows through -the Grid; the components themselves may have (and usually do) their -own job identifiers, which are unique only within these components. - -Every Grid component dealing with the job during its lifetime -may be a source of information about the job. The \LB gathers information -from all the -relevant components. This information is obtained in the form of -\LB events, pieces of data generated by Grid components, which mark -important points in the job lifetime (\eg passing of job control -between the Grid components are important milestones in job lifetime -independently on the actual Grid architecture); see Appendix~\ref{a:events} -for a~complete list. We collect those -events, store them into a database and simultaneously process them to -provide higher level view on the job's state. The \LB collects redundant -information---the event scheme has been designed to be as redundant as -possible---and this redundancy is used to improve resiliency in a -presence of component or network failures, which are omnipresent on any -Grid. - -The \LB events themselves are structured into \emph{attribute}~= -\emph{value} pairs, the set of required and optional attributes is defined by the -event \emph{type} (or scheme). For the purpose of tracking job status on -the Grid and with the knowledge of WMS Grid middleware structure we -defined an \LB schema with specific \LB event -types (see Appendix\ref{a:events}). -The schema contains a common base, the attributes that must be assigned -to every single event. The primary key is the jobid, which is also one of -the required attributes. Among other common attributes belong currently the -timestamps of the event origin and of the event arrival to LB, -generating component name, the event type, its priority and sequence code -(see Sect.~\ref{evprocess}) and so on. For a complete list of attributes -see \cite{lbdg}. - -While the necessary and sufficient condition for a global jobid is -to be Grid-wide unique, additional desired property relates to the -transport of events through the network: All events belonging to the same -job must be sent to the same \LB database. This must be done on a~per -message basis, as each message may be generated by a different component. -The same problem is encountered -by users when they look for information about their job---they need -to know where to find the appropriate \LB database too. -While it is possible to devise a global service where each job registers -its jobid together with the address of the appropriate database, such a -service could easily become a bottleneck. We opted for another solution, -to keep the address of the \LB database within the jobid (actually, -fully qualified hostname is strongly recommended instead of numeric address -and numeric IPv6 address is not supported for backward compatibility reasons). -This way, finding appropriate \LB database address becomes a local operation -(at most parsing the jobid) and users can use the same mechanism when -connecting to the \LB database to retrieve information about a particular -job (users know its jobid). To simplify the situation even further, -the jobid has the form of an URL, where the protocol part is -``https'', server and port identify the machine running the appropriate -\LB server -(database) and the path contains base64 encoded MD5 hash of random -number, timestamp, PID of the generating process and IP address of the -machine, where the jobid was generated. Jobid in this form can be -used even in the web browser to obtain information about the job, -provided the \LB database runs a web server interface. This jobid is -reasonably unique---while in theory two different job identifications can -have the same MD5 hash, the probability is low enough for this jobid to -represent a globally unique job identification. - -%zajímá nás job, globální id, v¹echna data vzta¾ena k~nìmu, syrové události -% -%více zdrojù dat pro jeden job, redundance, shromá¾dìní na jednom místì - -\subsubsection{Event gathering} -\label{gathering} -%zdroje událostí, lokální semantika logování, store-and-forward - -As described in the previous section, information about jobs are -gathered from all the Grid components processing the job in the form -of \LB events. The gathering is based on the \emph{push} model where -the components are actively producing and sending events. The push model -offers higher performance and scalability than the pull model, where the -components are to be queried by the server. In the push model, the \LB -server does not even have to know the event sources, it is sufficient -to listen for and accept events on defined interface. - -The event delivery to the destination \LB server is asynchronous and -based on the store--and--forward model to minimize the performance -impact on component processing. Only the local processing is synchronous, -the \LB event is sent synchronously only to the nearest \LB component -responsible for event delivery. This component -is at the worst located in the same local area network (LAN) and usually -it runs on the same host as -the producing component. The event is stored there (using persistent -storage -- disk file) and confirmation is sent back to the -producing component. From the component's point of view, the -send event operation is fast and reliable, but its success only means -the event was accepted for later delivery. The \LB delivery components -then handle the event asynchronously and ensure its delivery to the -\LB server even in the presence of network failures and host reloads. - -It is important to note that this transport system does not guarantee -ordered delivery of events to the \LB server; it \emph{does} guarantee -reliable and secure delivery, however. The guarantees are statistical -only, as the protocol is not resilient to permanent disk or node crashes -nor to the complete purge of the data from local disk. Being part of the -trusted infrastructure, even the local \LB components should run on -a trusted and maintained machine, where additional reliability may be -obtained \eg by a RAID disk subsystem. - -\subsubsection{Event processing}% -\label{evprocess} - -%diagram stavù, mapování událostí na hrany - -%uspoøádání událostí -- seq. èísla, vèetnì shallow vìtví - -% ! abstraktne, nemame jeste komponenty - -% prichazeji udalosti, vice zdroju, zmenene poradi (az ztraty) -% redundantni informace -% motivace: usetrit uzivatele, hlasit agregovany stav jobu -As described in the previous section, \LB gathers raw events from various -Grid middleware components and aggregates them on a~single server -on a per-job basis. -The events contain a very low level detailed information about the job -processing at individual Grid components. This level of detail is -valuable for tracking various problems with the job and/or the -components, and as complementary events are gathered (\eg each job control -transfer is logged independently by two components), the information is -highly redundant. Moreover, the events could arrive in wrong order, -making the interpretation of raw information difficult and not -straightforward. -Users, on the other hand, are interested in a much higher view, the -overall state of their job. - -For these reasons the raw events undergo complex processing, yielding -a~high level view, the \emph{job state}, that is the primary type of data -presented to the user. -Various job states form nodes of the job state diagram (Fig.~\ref{f:jobstat}). -See Appendix~\ref{a:jobstat} for a list of the individual states. - -% stavovy automat -% obrazek: stavovy diagram - -\begin{figure}[ht] -\centering -\includegraphics[width=.6\hsize]{images/wms2-jobstat} -\caption{\LB\ job state diagram} -\label{f:jobstat} -\end{figure} - -% typ udalosti -> zmeny typu stavu -\LB\ defines a~\emph{job state machine} that is responsible for updating -the job state on receiving a~new event. -The logic of this algorithm is non-trivial; the rest of this section deals -with its main features. - -Transitions between the job states happen on receiving events of particular -type coming from particular sources. -There may be more distinct events assigned to a~single edge of the state diagram. -For instance, the job becomes \emph{Scheduled} when it enters batch system -queue of a~Grid computing element. -The fact is witnessed by either \emph{Transfer/OK} event reported by -the job submission service or by \emph{Accept} event reported by the computing -element. Receiving any one of these events (in any order) triggers the -state change. - -% fault tolerance -This way, the state machine is highly fault-tolerant---it can cope with -delayed, reordered or even lost events. -For example, when a~job is in the \emph{Waiting} state and the \emph{Done} -event arrives, it is not treated as inconsistency but it is assumed that -the intermediate events are delayed or lost and the job state is switched -to the \emph{Done} state directly. - -% udalosti nesou atributy, promitaji se do stavu -The \LB events carry various common and event-type specific attributes, -\eg \emph{timestamp} (common) or \emph{destination} (\emph{Transfer} type). -The job state record contains, besides the major state identification, -similar attributes, \eg -an array of timestamps indicating when the job entered each state, -or \emph{location}---identification of the Grid component which is currently -handling the job. -Updating the job state attributes is also the task of the state machine, -employing the above mentioned fault tolerance---despite a~delayed event -cannot switch -the major job state back -it still may carry valuable information to update the job state attributes. - -% typy jobu -Jobs monitored by \LB service may have different type. For gLite jobs, \LB supports -simple jobs and jobs representing \emph{set of jobs} -- \emph{DAGs} (with dependencies between -subjobs described by direct acyclic graph) and \emph{collections} (without dependencies -between subjobs). -In these cases, subjobs are monitored in standard way, with one extensions - when job -status is changed, information is propagated also to the job representing corresponding -collection or DAG. -Job representing collection or DAG can be used to monitor status of the set, including -information like how many subjobs is already finished etc. -Support for non-gLite jobs, namely for PBS or Condor systems, is described in section -\ref{sec:nonglite} - - -\subsubsection{Event ordering}% -\label{evorder} - -As described above, the ability to correctly order arriving events is -essential for the job state computation. -As long as the job state diagram was acyclic (which was true for the -initial WMS release), each event had its unique place in the expected sequence -hence event ordering could always be done implicitly from the -context. -However, this approach is not applicable once job resubmission -yielding cycles in the job state diagram was introduced. - -Event ordering that would rely on timestamps assigned to events upon -their generation, assuming strict clock synchronization over the Grid, -turned to be a~naive approach. -Clocks on real machines are not precisely synchronized and there are no reliable -ways to enforce synchronization across administrative domains. - -To demonstrate a problem with desynchronized clocks, that may lead to -wrong event interpretation, let us consider a~simplified example -in Tab.~\ref{t:cefail}. -% -\iffalse %stare -% usporadani udalosti -- seq. cisla -% priklad problemu -So far we assumed that the state machine is able to detect a~delayed event. -As the state diagram contains cycles, delay cannot be detected from the type -of the event only. -The simplest approach is relying on the event timestamps. -However, in the Grid environment one cannot assume strictly synchronized clocks. -Table~\ref{t:cefail} shows a~simplified example of the problem caused by delayed -clocks. -\fi -% -\begin{table}[ht] -\begin{center} -\begin{tabular}{rlrl} -1.&WM: Accept& -6.&WM: Accept\\ -2.&WM: Match $A$& -7.&WM: Match $B$\\ -3.&WM: Transfer to $A$& -8.&WM: Transfer to $B$\\ -4.&CE~$A$: Accept & -9.&CE~$B$: Accept \\ -5.&CE~$A$: Run & -10.&CE~$B$: Run \\ -\dots & $A$ dies\\ -\end{tabular} -\end{center} -\caption{Simplified \LB events in the CE failure scenario} -\label{t:cefail} -\end{table} -% -We assume that the workload manager (WM) sends the job to a~computing element -(CE)~A, where it starts running but the job dies in the middle. -The failure is detected and the job is resubmitted back to the WM which sends it to CE~B then. -However, if A's clock is ahead in time and B's clock is correct (which -means behind the A's clock), the events in the right column are treated -as delayed. The state machine will interpret events incorrectly, assuming -the job has been run on B before sending it to A. -The job would always (assuming the A's events arrive before B's events to -the \LB) be reported as ``\emph{Running} at A'' despite -the real state should follow the \emph{Waiting} \dots \emph{Running} sequence. -Even the \emph{Done} event can be sent by B with a timestamp that says -this happened before the job has been submitted to A and the job state -will end with a discrepancy---it has been reported to finish on B while -still reported to run on A. - -Therefore we are looking for a~more robust and general solution. We can -discover severe clock bias if the timestamp on an event is in a future -with respect to the time on an \LB server, but this is generally a dangerous -approach (the \LB server clock could be severely behind the real time). -We decided not to rely on absolute time as reported by timestamps, but to -introduce a kind of \emph{logical time} that is associated with the logic -of event generation. -The principal idea is arranging the pass through the job state -diagram (corresponding to a~particular job life), that may include -loops, into an execution tree that represents the job history. -Closing a~loop in the pass through the state diagram corresponds -to forking a~branch in the execution tree. -The scenario in Tab.~\ref{t:cefail} is mapped to the tree in -Fig.~\ref{f:seqtree}. -The approach is quite general---any finite pass through any state -diagram (finite directed graph) can be encoded in this way. - -\begin{figure}[ht] -\centering -\includegraphics[scale=.833]{images/seqtree} -\caption{Job state sequence in the CE failure scenario, arranged into a~tree. -Solid lines form the tree, arrows show state transitions.} -\label{f:seqtree} -\end{figure} - -Our goal is augmenting \LB events with sufficient information that -\begin{itemize} - \item identifies uniquely a~branch on the execution tree, - \item determines the sequence of events on the branch, - \item orders the branches themselves, which means that it determines - which one is more recent. -\end{itemize} -If such information is available, the execution tree can be -reconstructed on the fly as the events arrive, and even delayed events -are sorted into the tree correctly. An incoming event is considered -for job state computation only if it belongs to the most recent -branch. - -The situation becomes even more complicated when -the \emph{shallow resubmission} WM advanced feature is enabled. -In this mode WM may resubmit the job before being sure the previous attempt -is really unsuccessful, potentially creating multiple parallel instances -of the job. -The situation maps to several branches of the execution tree that -evolve really in parallel. -However, only one of the job instances becomes active (really running) finally; -the others are aborted. -Because the choice of active instance is done later, -it may not correspond to the most recent execution branch. -Therefore, when an event indicating the choice of active instance arrives, -the job state must be recomputed, using the corresponding active branch -instead the most recent one. - -Section~\ref{seqcode} describes the current implementation of event -ordering mechanism based on ideas presented here. - -\subsubsection{Queries and notifications}\label{retrieve} - -According to the GMA classification the user retrieves data from -the infrastructure in two modes, called -\emph{queries} and \emph{notifications} in~\LB. - -Querying \LB is fairly straightforward---the user specifies query -conditions, connects to the querying infrastructure endpoint, and -receives the results. -For ``single job'' queries, where jobid is known, the endpoint (the -appropriate \LB server) is inhered from the jobid. -More general queries must specify the \LB server explicitely, -and their semantics is intentionally restricted -to ``all such jobs known here''. -We trade off generality for performance and reliability, -leaving the problem of finding the right query endpoint(s), the right -\LB servers, to higher level information and service-discovery services. - -If the user is interested in one or more jobs, frequent polling of the -\LB server may be cumbersome for the user and creates unnecessary overload -on the sever. A notification subscription is therefore available, -allowing users to subscribe to receive notification whenever a~job -starts matching user specified conditions. -Every subscription contains also the location of the user's -listener; -successful subscription returns time-limited \emph{notification handle}. -During the validity period of the subscription, the \LB infrastructure -is responsible for queuing and reliable delivery of the notifications. -The user may even re-subscribe (providing the original handle) with different -listener location (\eg moving from office to home), and \LB re-routes -the notifications generated in the meantime to the new destination. -The \LB event delivery infrastructure is reused for the notification -transport. Alongside it, there is a possibility to deliver notification -messages thourgh the messaging infratstructure. - -\subsubsection{Local views}\label{local} -% motivace proxy - -%As outlined in Sect.~\ref{reqs} -WMS components are, besides logging -information into \LB, interested in querying this information back in order -to avoid the need of keeping per-job state information. -However, despite the required information is present in \LB, -the standard mode of \LB operation is not suitable for this purpose due -to the following reasons: -\begin{itemize} -\item Query interface is provided on the \LB component which gathers -events belonging to the same job but coming from different sources. -Typically, this is a~remote service with respect to the event sources (WMS components). -Therefore the query operation is sensitive to any network failure that may -occur, blocking the operation of the querying service for indefinite time. -\item Due to the asynchronous logging semantics, there is a~non-zero time -window between successful completion of the logging call and the point in -time when the logged event starts affecting the query result. -This semantics may yield unexpected, seemingly inconsistent outcome. -\end{itemize} - -The problem can be overcome by introducing \emph{local view} on job data. -Besides forwarding events to -the server where events belonging to a~job are gathered from multiple sources, -\LB infrastructure can store the logged events temporarily -on the event source, and perform the processing described -in Sect.~\ref{evprocess} -In this setup, the logging vs.\ query semantics can be synchronous---it is -guaranteed that a~successfully logged event is reflected in the result of -an immediately following query, -because no network operations are involved. -Only events coming from this particular physical node (but potentially -from all services running there) are considered, thus the locality of the view. -On the other hand, certain \LB events are designed to contain redundant -information, therefore the local view on processed data (job state) -becomes virtually complete on a~reasonably rich \LB data source like -the Resource Broker node. - - -\subsection{Current \LB implementation} -The principal components of the \LB service and their interactions -are shown in Figures~\ref{f:comp-gather} (gathering and transferring -\LB events) and~\ref{f:comp-query} (\LB query and notification services). - -\begin{figure}[ht] -\centering -\includegraphics[scale=.5]{images/LB-components-gather} -\caption{\LB components involved in gathering and transferring the events} -\label{f:comp-gather} -\end{figure} - -\input components - -\subsubsection{Sequence codes for event ordering}% -\label{seqcode} - -As discussed in Sect.~\ref{evorder}, sequence codes are used as logical -timestamps to ensure proper event ordering on the \LB server. The sequence code -counter is incremented whenever an event is logged and the sequence code must -be passed between individual Grid components together with the job control. -However, a single valued counter is not sufficient to support detection of -branch forks within the execution tree. When considering again the Computing -Element failure scenario described in Sect.~\ref{evorder}, there is no way to -know that the counter value of the last event logged by the failed CE A is 5 -(see Table~\ref{t:cefail} on page~\pageref{t:cefail}). - -Therefore we define a~hierarchical \emph{sequence code}---an array of -counters, each corresponding to a~single Grid component class handling the job% -\footnote{Currently the following gLite components: Network Server, Workload -Manager, Job Controller, Log Monitor, Job Wrapper, and the application itself.}. -Table~\ref{t:cefail2} below shows the same scenario with a~simplified two-counter -sequence code. The counters correspond to the WM and CE component classes -and they are incremented when each of the components logs an event. -When WM receives the job back for resubmission, -the CE counter becomes irrelevant (as the job control is on WM now), -and the WM counter is incremented again. - -\begin{table}[ht] -\begin{center} -\begin{tabular}{rlrl} -1:x&WM: Accept& -4:x&WM: Accept\\ -2:x&WM: Match $A$& -5:x&WM: Match $B$\\ -3:x&WM: Transfer to $A$& -6:x&WM: Transfer to $B$\\ -3:1&CE~$A$: Accept & -6:1&CE~$B$: Accept \\ -3:2&CE~$A$: Run & -6:2&CE~$B$: Run \\ -\dots & $A$ dies\\ -\end{tabular} -\end{center} -\caption{The same CE failure scenario: hierarchical sequence codes. -``x'' denotes an undefined and unused value.} -\label{t:cefail2} -\end{table} - -%Events on a~branch are ordered following the lexicographical order -%of the sequence codes. -%Branches are identified according to the WM counter as WM is -%currently the only component where branching can occur. - -The state machine keeps the current (highest seen) code for the job, -being able to detect a~delayed event by simple lexicographic comparison -of the sequence codes. -Delayed events are not used for major state computation, then. -Using another two assumptions (that are true for the current -implementation): -\begin{itemize} - \item events coming from a~single component arrive in order, - \item the only branching point is WM, -\end{itemize} -it is safe to qualify events with lower WM counter (than the already -received one) to belong to inactive -branches, hence ignore them even for update of job state attributes. - -\subsubsection{\LB data protection} -Events passed between the \LB components as well as the results of their -processing provide detailed information about the corresponding job and its -life and users obviously expect the job data provided by the \LB server to -be credible, reflecting the real jobs' operation on the Grid. Therefore, the -data must be based solely on authentic information generated by legitimate -grid components. The job data also provides information about user's -activities, which many users want to keep private. In order to provide a -sufficient level of security, the \LB infrastructure implements a security -mechanism that provides data protection and access control to the data. - -All the \LB components communicate solely over secure channels whenever they -send data over a network. The TLS protocol~\cite{tls} is used for both mutual -authentication of the client and server and also encryption of the -communication. All the \LB components as well as the clients must possess a -digital certificate that they use to prove their identity. The \LB -infrastructure supports both standard X.509 certificates or proxy -certificates~\cite{proxycert} that are standard authentication mechanism in -the gLite environment. Depending on the server configuration and action -requested, the users may be required to present VOMS attributes in their -proxy certificates. - -By default, access to information about a job is only allowed to the user -who submitted the job (\ie the job owner). The job owner can also assign an -access control list to his or job in the \LB specifying other users who are -allowed to read the data from \LB. The ACLs are represented in -the GridSite GACL format~\cite{gacl2} and are stored in the \LB database -along with the job information. The stored ACL are checked on each query -requesting the data. The ACLs are under control of the job owner, who can -add and remove entries in the ACL arbitrarily using the \LB API or -command-line tools (see~\ref{e:change-acl}). Each entry of an ACL can -specify either a user subject name, a name of a VOMS group, or an attribute -specified in the Full qualified attribute name format (the FQAN support is -available since \LBver{2.0}). An ACL assigned to a job is returned as part of -job status information. - -Besides of using the ACLs, the \LB administrator can also specify a~set of -privileged users with access to all job records on a particular \LB server -(\emph{super-users}). These privileged users can \eg collect information on -usage and produce monitoring data based on the \LB information. - -%Data trustworthiness - the events aren't signed, no real non-reputability or -%traceability of the event sources. - - -\subsection{User interaction} -\begin{figure}[ht] -\centering -\includegraphics[scale=.5]{images/LB-components-query} -\caption{\LB queries and notifications} -\label{f:comp-query} -\end{figure} - -So far we focused on the \LB internals and the interaction between its -components. -In this section we describe the interaction of users with the service. - -\subsubsection{Event submission} -%implicitní -- registrace jobu, systémové události na middlewarových komponentách -The event submission is mostly implicit, -\ie it is done transparently by the Grid middleware components -on behalf of the user. -Typically, whenever an important point in the job life is reached, -the involved middleware component logs an appropriate \LB event. -This process is not directly visible to the user. - -A specific case is the initial registration of the job. -This must be done synchronously, as otherwise subsequent events logged for -the same job may be refused with a ``no such job'' error report. -Therefore submission of a job to the WMS is the only synchronous event -logging that does not return until the job is successfully registered with -the \LB server. -Moreover, the initial registration is sent by the \LB client library in -parallel to \LB proxy (Sect.~\ref{s:proxy}) and \LB server. - -On the other hand, even the registration event may carry large data -(e.g. JDL of huge job collection). Therefore -also an additional asychronous variant is used, causing two job registration -events appear typically. - -% explicitní -- user tagy, ACL -However, the user may also store information into the \LB explicitly -by logging user events---\emph{tags} (or annotations) of the -form ``name = value''. -Authorization information is also manipulated in this way. - -Description of tools for event submission and ACL manipulation -can be found in Section \ref{s:lb-tools} - - -\subsubsection{Querying information} -%\TODO{prejmenovat, aby v nazvy byly Queries} - -From the user point of view, the information retrieval (\emph{query}) is the -most important interaction with the \LB service. - -%dotazy na stav -The typical \LB usage are queries on the high-level job state information. -\LB supports not only single job queries, it is also possible to -retrieve information about jobs matching a specific condition. -The conditions may refer to both the \LB system attributes -and the user annotations. Rather complex query semantics can be -supported, \eg -\emph{Which of my jobs annotated as ``apple'' or ``pear'' are already -scheduled for execution and are heading to the ``garden'' computing element?} -The \LB Developer's -Guide\cite{lbdg} provides a~series of similar examples of -complex queries. - -%dotazy na události -As another option, the user may retrieve raw \LB events. -Such queries are mostly used for debugging, identification of repeating -problems, and similar purposes. -The query construction refers to event attributes rather -than job state. - -The query language supports common comparison operators, and it allows -two-level nesting of conditions (logically \emph{and}-ed and \emph{or}-ed). -Our experience shows that it is sufficiently strong to cover most user -requirements while being simple enough to keep the query cost reasonable. -Complete reference of the query language can be found in~\LB Developer's Guide -\cite{lbdg}. - -\subsubsection{Notifications} -\LB notifications are the other mode of user interaction. - -The \LB infrastructure can notify its users when something interesting happens on an \LB server -(typically a job status change). This allows users to wait comfortably until they are informed by the server, rather than having to poll the \LB server periodically to detect changes. - -Users register for notifications via the notification client \verb'glite-lb-notify', described in Section -\ref{s:lb-notify} -Conditions under which the notifications are sent can be specified. For example -- job XY reaches state -DONE. In \LBver{1.x}, one or more JOBID's are required in the condition and only a single occurence -of a specific attribute is allowed among ANDed conditions. More complex conditions are allowed since \LBver{2.0}, including specification of job owner, or requesting to receive notifications only on actual job state change. \LBver{3.0} introduces an option to deliver notification messages over OpenWire or STOMP-based messaging infrastructure.\footnote{Such as Apache's ActiveMQ.} - -Each registration is delivered to the \LB server where it is stored. -At the same time, the server generates a unique notification ID for the registration and returns it to the -user. - -The registration exists only for a limited amount of time. Validity information is returned by \LB server together with -the notification ID when registering. During this period the user can attach to the server and receive notification messages, -change conditions which triger the notification, prolong validity of the registration, or remove the registration -from the \LB server. - -While the registration is valid, the user is able to repeatably connect to the \LB server from different places in the -network and continue receiving notifications associated with the given notification ID.\footnote{Should the user have opted to receive notification messages over the messaging infrastructure, then---obviously---they need to connect to the correct topic on a messaging broker, rather than contacting the \LB sever. If unsure what messaging brokers are available in your grid environment, read that information from BDII or use the \LB Server's configuration page (Section \ref{s:findbroker}). -} Notifications generated -while the user was not connected are stored and waiting until the user reconnects. - -Since \LBver{3.2}, notification messages may also contain a history of all events received for a given job so far. - -\subsubsection{Caveats} -\LB is designed to perform well in the unreliable distributed Grid -environment. -An unwelcome but inevitable consequence of this design -are certain contra-intuitive features in the system behavior, -namely: -\begin{itemize} -\item -Asynchronous, possibly delayed event delivery may yield seemingly -inconsistent view on the job state \wrt\ information that is available -to the user via different channels. -\Eg the user may know that her job terminated because of monitoring the -application progress directly, but the \LB \emph{Done} events indicating -job termination are delayed so that \LB reports the job to be still -in the \emph{Running} state. - -\item -% sekvenèní èísla -- ¹patnì øazené události jsou ignorovány pro výpoèet stavu -Due to the reasons described in Sect.~\ref{evorder} \LB is rather sensitive -to event ordering based on sequence codes. -The situation becomes particularly complicated when there are multiple -branches of job execution. -Consequently the user may see an \LB event that is easily interpreted that -it should switch the job state, however, it has no effect in fact -because of being (correctly) sorted to an already inactive branch. - -\item -% purge -- data z~\LB\ zmizí -\LB is not a~permanent job data storage. The data get purged from the -server on timeout, unrelated to any user's action. -Therefore, the \LB query may return ``Identifier removed'' error message (or not -include the job in a list of retrieved jobs) even if the same previous -\LB query behaved differently. - -\end{itemize} - -\ludek{\subsection{Performance and scalability} -The \LB service was designed with performance and -scalability issues in mind. We have developed a series of tests of the -individual \LB components to measure the actual behavior under -stress conditions. These tests give us a good performance estimate of -the \LB service and help us identify and remove possible bottlenecks. - -The testing itself is done by feeding the \LB components with events -prepared beforehand, using whatever protocol appropriate for the given -component. The feeding program uses a set of predefined events of a -typical job which we have chosen from the production \LB server -database. Timestamp is taken before the first event is sent, then the -feeding program begins sending events of individual jobs (the jobs are -all the same, the only difference is the jobid; the number of jobs used is -configurable). The tested component is instrumented in the source code -to break normal event processing at selected points (\eg discard -events immediately after being read to measure the input channel -performance, or discard events instead of sending them to the next -component, etc.). This segmentation of event processing enables to -identify places in the code which may slow down the event transfer. -Optionally the events may be discarded by the next component in the -logical path. The last event of the last job is special termination -event, which is recognized when being discarded; then the second -timestamp is taken and the difference between the two gives us total -time necessary to pass given number of jobs through. - -Note that due to the asynchronous nature of the \LB service measuring for -example the time it takes to send given number of jobs does not give -us the required result, thus event (or job) throughput---when the -producer receives acknowledgment about successful send operation, it -is not guaranteed that the event passed through the component. - -The results shown in table~\ref{perf:results} give the overall -throughput components (events are discarded by the next component -on the path), with the exception of proxy, where the throughput to the -database is measured. It can be seen that the majority of code is fast -enough to handle even high event rates and that most components are up -to our goal to handle one million of jobs per day. The first line -indicates how fast we are able to ``generate'' events in the feeding -program. - -\begin{table}[ht] -\begin{tabular}{l|r} -{\bf Component} & {\bf Job throughput (jobs/day)} \\ -\hline -Test producer & 153,600,000 \\ -Locallogger & 101,700 \\ -Interlogger & 5,335,100 \\ -Proxy & 1,267,110 \\ -\end{tabular} -\caption{Performance testing results} -\label{perf:results} -\end{table} - -During the performance testing we have identified two possible -bottlenecks: -\begin{itemize} -\item Opening connections and establishing SSL sessions is very -expensive operation. It hinders mainly the performance of locallogger, -because the current implementation uses one SSL session for -event. -\item Database operations. Storing events into database is expensive, -but inevitable; however we were able to optimize for example the -code checking for duplicated events. -\end{itemize} - -In the current work we are addressing the issue of SSL operations by -introducing concept of SSL connection pools, which enables components -to reuse existing connections transparently without need to tear-down -and setup new SSL contexts. } - -\subsection{Advanced use} - -The usability of the \LB service is not limited to the simple tasks -described earlier. It can be easily extended to support real-time job -monitoring (not only the notifications) and the aggregate information -collected in the \LB servers is a valuable source of data used for post-mortem -statistical analysis of jobs and also the Grid infrastructure behavior. -Moreover, \LB data can be used to improve scheduling decisions. - -\subsubsection{\LB and real time monitoring} -The \LB server is extended to provide quickly and without any substantial -load on the database engine the following data: -\begin{enumerate} -\item number of jobs in the system grouped by internal status -(\emph{Submitted}, \emph{Running}, \emph{Done},~\ldots), -\item number of jobs that reached final state in the last -hour, -\item associated statistics like average, maximum, and minimum time spent -by jobs in the system, -\item number of jobs that entered the WMS system in the last hour. -\end{enumerate} -\LB server can be regularly queried to provide this data to give an -overview about both jobs running on the Grid and also the behavior of the -Grid infrastructure as seen from the job (or end user) perspective. -Thus \LB\ becomes a~data source for various real-tim Grid monitoring tools. - -\subsubsection{R-GMA feed} -\emph{Note: This feature is now obsolete and only available in \LBver{1.x}.} - -The \LB server also supports streaming the most important data---the job -state changes---to another monitoring system. It works as the -notification service, sending information about job state changes to -a~specific listener that is the interface to a monitoring interface. -As a~particular example of such a generic service, the R-GMA feed component -has been developed. It supports sending job state changes to -the R-GMA infrastructure that is part of the Grid monitoring -infrastructure used in the EGEE Grid. - -Only basic information about job state changes is provided -this way, taking into account the security limitation of the R-GMA. - -\subsubsection{\LB Job Statistics} -Data collected within the \LB servers are regularly purged, complicating -thus any long term post-mortem statistical analysis. Without a Job -Provenance, the data from the \LB must be copied in a controlled way and -made available in an environment where even non-indexed queries can be -asked. - -Using the \LB Job Statistics tools, one dump file per job is created -when the job reaches a~terminal state. These dump files can be -further processed to provide and XML encoded Job History Record% -\footnote{\url{http://egee.cesnet.cz/en/Schema/LB/JobRecord}} that -contains all the relevant information from the job life. The Job History -Records are fed into a statistical tools to reveal interesting information -about the job behavior within the Grid. - -This functionality is being replaced by the direct download of all the -relevant data from the Job Provenance. - -\subsubsection{Computing Element reputability rank} -\label{s:ce-rank} -Production operation of the EGEE middleware showed -that misbehaving computing elements may have significant impact on -the overall Grid performance. -The most serious problem is the ``black hole'' effect---a~CE that -accepts jobs at a~high rate but they all fail there. -Such CE usually appears to be free in Grid information services -so the resource brokers keep to assign further jobs to it. - -\LB data contain sufficient information to identify similar problems. -By processing the incoming data the information -was made available as on-line auxiliary statistics like -rate of incoming jobs per CE, rate of job failure, average duration of job etc. -The implementation is lightweight, allowing very high query rate. -On the RB the statistics are available as ClassAd -functions, allowing the user to specify that similarly misbehaving -CE's should be penalized or completely avoided -when RB decides where jobs get submitted. - - -\subsubsection{CREAM jobs} -\LBver{3.2} implements support for CREAM jobs.\footnote{Essential support was already available in \LBver{2.1}.} \LB gathers events from CREAM, performing both the mapping of CREAM attributes to WMS attributes (if possible) and storing CREAM-specific attributes. Thus, jobs submitted directly to computing elements can be tracked by \LB. Moreover, jobs submitted to WMS and from there to CREAM log WMS- and CREAM-specific data, which are integrated by \LB to provide more detailed and up-to-date job status information. CREAM job states are mapped to \LB's state diagram according to Appendix \ref{a:creammapping}. - -CREAM events are generated by the CREAM executor and LRMS; the generic \emph{CREAMStatus} event is generated when CREAM notifies that the job status has been changed. - -\subsubsection{Sandbox transfers} -A sandbox transfer is special entity in \LB, which tracks the transfer of input or output sandboxes of the (compute) job. Thus, it allows to check state of sandboxes giving more detailed overview of the status of compute job. - -The sandbox transfer has its unique JobID and is cross-linked with the related compute job. There are two types of sandboxes -- the input sandbox and the output sandbox. Each job has at most one input and one output sandbox associated, however, the sandbox can be created as a collection of sandboxes. The sandbox collection includes the owner, the overall status and the list of children sandboxes, whereas the regular sandbox tracks particular sandbox including data such as status, owner, source, destination. - -Having its unique JobID, sandbox transfers are tracked by standard tools (API, command line utilities, HTTPs, notifications) in the same manner as traditional compute jobs. - -\subsubsection{Non-gLite event sources} -\label{sec:nonglite} - -\LB has been enhanced to support also non-gLite events, namely events from PBS -or Condor batch systems \cite{hpdc07}. These events are handeled differently from gLite events, -for a complete list of the PBS and Condor events see Appendix \ref{a:events}. -Since job states in the batch system slightly differ from the states of a job -defined in \LB (see also Appendix \ref{a:jobstat}), events are processed separately -from gLite events. Both PBS and Condor events has its own state machine that processes the -events and determines the now state of the job. - -Recently, there were also attempts to use \LB system to transport different types of events: -Certificate Revocation Lists or syslog messages. For a detailed description see -\cite{LB4CRL}. - -\subsubsection{Controlling access to job information} -\label{sec:job-authz} -Access to information about a job subjects to strong access control -mechanism. By default, only the job owner is allowed to access the -information about their jobs. There are, however, means how additional -rights can be granted to other persons. The \LB server administrator can -specify a server-level policy, which grants specific rights to all jobs -stored in the server, please refer to the \LB Administrators' guide for -more information. - -Besides the server-wide configuration, a job owner can also grant access to -their jobs to other users. Each job can be assigned an Access control list -(ACL), which specifyies which users are allowed to work with the job -information. If a job owner wants other users to be allowed to obtain -information about their job, they provide an ACL rule granting \verb'READ' -access for the users. The users can be identified either by their X.509 -subject name or their VOMS attributes. As of \LBver{3.0}, it is also -possible to grant a \verb'TAG' right, which allows multiple users to add -user tags to the same job. The current ACL of a job is returned as a part -of the job status. Management of the ACL entries is done using logging a -special \LB event in a standard way (see \ref{e:change-acl} for particular -examples). - -Starting from \LBver{3.0}, it is also possible to specify the owner of the -actual payload of a job. The feature has been introduced for better support -of multi-user pilot jobs, where the pilot submitter differs from the owner -of actual payload. In order to set the payload owner, the job owner has to -log a \verb'GrantPayloadOwnership' event which specifies the subject owner of the -payload owner. This event is supposed to come from a pilot job factory -which monitors the pilot jobs and keeps an overview about when a particular -payload is started. The new payload owner has to confirm the transition -with a \verb'TakePayloadOwnership' logged to the job using his or her -credentials. The payload and job owners have the same rights to the jobs, -they both can query the job, etc. The identity of the current payload owner -is returned as part of the job status information. diff --git a/org.glite.lb.doc/src/LBUG-Tools.tex b/org.glite.lb.doc/src/LBUG-Tools.tex deleted file mode 100644 index ccd79da..0000000 --- a/org.glite.lb.doc/src/LBUG-Tools.tex +++ /dev/null @@ -1,142 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\section{User tools} -\label{s:lb-tools} - -In this section we give a description of the CLI tools that a regular grid user -might want to use. If not stated otherwise, the tools are distributed in the -\verb'glite-lb-client' package. - -\subsection{Environment variables} - -Behaviour of the commands can be changed by setting enviroment variables, specifing mostly -location of servers or setting timeouts for various operations. -For a complete list of environment variables, their form and default value -description, see Appendix~\ref{a:environment}. Setting the environment variable -is for some commands mandatory, so reading the documentaion below and -appropriate manpages is highly recommended. - - -\subsection{glite-wms-job-status and glite-wms-job-logging-info} - -We start with tools that are distributed in \verb'glite-wms-ui-cli-python' package -and that can be found probably on all UI machines. Description of all user -commands that are used during the job submission process (generating proxy, -creating a JDL describing the job, submitting a job, retrieving output, -cancelling a job, etc.) is beoynd this document and it can be found for example -in \cite{wmsug}. We mention here only the commands that are related to -job monitoring. - -Once job has been submitted to WMS (by \verb'glite-wms-job-submit'), -a user can retrieve the job status by -\begin{verbatim} - glite-wms-job-status -\end{verbatim} -or if job ID is saved in the file -\begin{verbatim} - glite-wms-job-status -i -\end{verbatim} -or if user wants to see status of all his/her jobs -\begin{verbatim} - glite-wms-job-status --all -\end{verbatim} -List of all possible job states is summarised in Appendix \ref{a:jobstat}. - -Logging details on submitted job can be accessed via -\begin{verbatim} - glite-wms-job-logging-info -v -\end{verbatim} -or if job ID is saved in the file -\begin{verbatim} - glite-wms-job-logging-info -v -i -\end{verbatim} -where verbosity level can be from 0 to 3. - - -\input{logevent} - -\input{notify} - - -\subsection{HTML and plain text interface} - -It is possible to use a standard Web browser or a command-line tool such as \texttt{wget} or \texttt{curl} to extract information from the \LB server. Although the querying power is higly limited, the HTTP or Plain Text interface can still serve as a simple tool to access information. - -\subsubsection{Job ID or Notification ID as URL} -\label{simple} -Since the gLite jobId has the form of a unique URL, it is possible to cut and paste it directly -to the web browser to view the information about the job (esp. its status), e.g. -\begin{verbatim} - firefox https://pelargir.ics.muni.cz:9000/1234567890 -\end{verbatim} -To list all user's jobs, it is possible to query only the \LB server address, e.g. -\begin{verbatim} - firefox https://pelargir.ics.muni.cz:9000 -\end{verbatim} -To list all user's notification registrations curently valid on a given \LB server, use an URL constructed as in folowing example: -\begin{verbatim} - firefox https://pelargir.ics.muni.cz:9000/NOTIF -\end{verbatim} - -On top of that, \LB super users may use query strings \texttt{?all} or \texttt{?foreign} to display registrations belonging to anyone or anyone but themselves, respectively. - -A notification ID also takes the form of an URL. If you direct your browser to a particular notification ID, the \LB server will provide related registration details. -\begin{verbatim} - firefox https://pelargir.ics.muni.cz:9000/NOTIF:1234567890 -\end{verbatim} -In all cases it is necessary to have the user certificate installed in the browser. - -\subsubsection{Plain Text Modifier} - -Since \LBver{2.0}, it is also possible to obtain the above results in a machine readable -\verb'key=value' form by adding a suffix \verb'text' to the above URLs. For example -\begin{verbatim} - curl -3 --key $X509_USER_KEY --cert $X509_USER_CERT \ - --capath /etc/grid-security/certificates \ - https://pelargir.ics.muni.cz:9000?text -\end{verbatim} -or -\begin{verbatim} - curl -3 --key $X509_USER_KEY --cert $X509_USER_CERT \ - --capath /etc/grid-security/certificates \ - https://pelargir.ics.muni.cz:9000/1234567890?text -\end{verbatim} - -\input{https_configuration} - -\subsection{Job state changes as an RSS feed} -The \LB includes an RSS interface allowing users to keep trace of their jobs in a very simple way using an RSS reader. The parameters of the RSS feeds are predefined, so no configuration is required. - -The address of a feed is given by the URL of the \LB server and a \textit{/RSS:rss\_feed\_name} postfix, e.g. -\begin{verbatim} - https://pelargir.ics.muni.cz:9000/RSS:finished -\end{verbatim} - -There are currently 3 feeds implemented in LB: -\begin{itemize} - \item \textit{finished} for jobs in terminal states (Done/OK, Aborted and Canceled) - \item \textit{running} for running jobs - \item \textit{aborted} for aborted jobs -\end{itemize} - -\subsection{Other useful tools} - -For debugging purposes, low-level commands for getting \LB job status and job related events are provided in -\verb'examples' directory (\verb'glite-lb-job_status' and \verb'glite-lb-job_log'). The same directory -contains also debugging commands for getting of all user jobs (\verb'glite-lb-user_jobs') and -CE-reputability rank (see Section \ref{s:ce-rank}, \verb'glite-lb-stats'). - diff --git a/org.glite.lb.doc/src/LBUG-Troubleshooting.tex b/org.glite.lb.doc/src/LBUG-Troubleshooting.tex deleted file mode 100644 index 50994c2..0000000 --- a/org.glite.lb.doc/src/LBUG-Troubleshooting.tex +++ /dev/null @@ -1,59 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\section{Troubleshooting} - -Please, report usage problems via the GGUS support system at -\begin{center} -\url{https://gus.fzk.de/index.html} -\end{center} -Apparent software bugs are tracked in Savannah at -\begin{center} -\url{https://savannah.cern.ch/bugs/?func=additem&group=jra1mdw} -\end{center} - -When submitting a \LB spcecific problem/bug, the following information might be useful: -\begin{itemize} -\item version of software used (all \verb'glite-lb-*' packages installed at your site) -\item description of the problem, the \verb'jobId', addresses of all relevant - machines (\LB server, ...), environment variables set, etc. -\item output from the following commands: -\begin{verbatim} - glite-wms-job-status - glite-wms-job-logging-info -v 3 -\end{verbatim} -\item information on your proxy: -\begin{verbatim} - voms-proxy-info -debug -all -\end{verbatim} -or, if VOMS client is not installed, -\begin{verbatim} - grid-proxy-info -debug -\end{verbatim} -\item sometimes additional information can be found in the output from the commands -\begin{verbatim} - glite-lb-job_status - glite-lb-job_log -\end{verbatim} -that should be available in the \verb'$GLITE_LOCATION/examples' directory, -\item appropriate excerpts from the logs on the server side are also highly appreciated, -please tell your administrator to look at the Troubleshooting section in LB Administrator's -Guide \cite{lbag} to follow the steps there and provide you the necessary information. -\end{itemize} - -Users are encouradged to send developers all non-bugs comments and questions by email to -address \email{egee-jra1@lindir.ics.muni.cz}. - diff --git a/org.glite.lb.doc/src/LBUG.tex b/org.glite.lb.doc/src/LBUG.tex deleted file mode 100644 index e36b610..0000000 --- a/org.glite.lb.doc/src/LBUG.tex +++ /dev/null @@ -1,67 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\documentclass{emi} -\def\insideUG{} - -\input{definitions} - -\title{Logging and Bookkeeping -- User's Guide} -%\Subtitle{User's Guide} -\author{CESNET EGEE III JRA1 and SA3 team} -%\DocIdentifier{glite-lb-doc-ug-\version} -%\DeliverableId{} -\Date{\today} -%\Activity{JRA1: Middleware Engineering} -%\DocStatus{FINAL} -\DocVersion{\version} -%\Dissemination{PUBLIC} -%\DocumentLink{\url{http://egee.cesnet.cz/cvsweb/LB/LBUG.pdf}} -\Abstract{\input{LBUG-Abstract}} -\EMICompVersion{3.x} - -\begin{document} - -%\input{frontmatter} -\input{funding} -\input{copyright} -\tableofcontents - -\newpage -\input{versions} - -\newpage -\input{LBUG-Introduction} - -\newpage -\input{LBUG-Tools} - -\newpage -\input{LBUG-Troubleshooting} - -\newpage -\input{faq} - -\appendix -\newpage -\input{LBUG-Appendix} - -\newpage -\bibliographystyle{unsrt} -\bibliography{lbjp} - -\end{document} - diff --git a/org.glite.lb.doc/src/README b/org.glite.lb.doc/src/README deleted file mode 100644 index 20b9e45..0000000 --- a/org.glite.lb.doc/src/README +++ /dev/null @@ -1,13 +0,0 @@ -This is the official documentation for Logging and Bookkeeping Service. -It consists of the following documents: - -LBUG.pdf - Logging and Bookkeeping User's Guide -LBAG.pdf - Logging and Bookkeeping Admin's Guide -LBDG.pdf - Logging and Bookkeeping Developer's Guide -LBTP.pdf - Logging and Bookkeeping Test Plan - -Please, report all bugs to EU EGEE Bug Tracking System located at -https://savannah.cern.ch/bugs/?func=additem&group=jra1mdw - -Feel free to send us your non-bugs comments to email -egee-jra1@lindir.ics.muni.cz diff --git a/org.glite.lb.doc/src/README-standards.txt b/org.glite.lb.doc/src/README-standards.txt deleted file mode 100644 index d7c7911..0000000 --- a/org.glite.lb.doc/src/README-standards.txt +++ /dev/null @@ -1,293 +0,0 @@ -Logging and Bookkeeping (LB) service and standards -================================================== - -The aim of this document is to list all possible IT standards related to the -Logging and Bookkeeping (LB) service togehter with the recommendations what should -be changed in the LB code to support the standards as well as with the proposals -to change also the standard specifications. There is no particular order in the list. - -Good starting points for reading are: - -[OGSA-Standards] Defining the Grid: A Roadmap for OGSA® Standards -OGF Informational Document GFD-I.123 http://www.ogf.org/documents/GFD.123.pdf -- overview of the many interrelated recommendations and -informational documents being produced by the OGSA - -[OGSA-Architecture] The Open Grid Services Architecture, Version 1.5 -OGF Informational Document GFD-I.080 http://www.ogf.org/documents/GFD.80.pdf -- Job Tracking not explicitly mentioned here, maybe we could propose OGSA-LB? :) - -Standards and Web services -- see http://www.ibm.com/developerworks/webservices/standards/ - - -Command Line + User Interface Standards ---------------------------------------- - -- support for Internationalization (i18n) and localization (l10n), -in particular UTF-8 support in user tags --- switch all output to LC_MESSAGES compliant format - -- standard error codes from all CLI tools --- define on gLite level - - -Coding and Language Standards ------------------------------ - -[WSDL] Web Services Description Language (WSDL) 1.1 -W3C Note http://www.w3.org/TR/wsdl -- check if LB.wsdl and LBTypes.wsdl satisfy this specification - -[XML] Extensible Markup Language (XML) 1.1 (Second Edition) -W3C Recommendation http://www.w3.org/TR/xml11 -- check if all XMLs in LB satisfy this specification - -[XML-Namespaces] Namespaces in XML 1.1 (Second Edition) -W3C Recommendation http://www.w3.org/TR/xml-names11 -- check if all XML namespaces in LB satisfy this specification - -[SOAP] SOAP Version 1.2 -W3C Recommendation http://www.w3.org/TR/soap12 -- check SOAP in security.gsoap-plugin -- see also W3C Working Group XML Protocol: http://www.w3.org/2000/xp/Group/ - -[GNU] GNU Coding Standards: http://www.gnu.org/prep/standards/ -- DISCUSSION: adopt these coding standards to the code of LB? - - -Network Protocols Standards ---------------------------- - -[IPv6] Internet Protocol version 6 (IPv6) -IETF Standard, for IPv6 related specifications see http://www.ipv6.org/specs.html -- all communication in LB must be modified to fully support IPv6 -- affected modules: [org.glite.]jobid, security.gss, security.gsoap-plugin, lb.common, -lb.client, lb.logger, lb.server -- done as of release 2.1 (IPv6 is fully supported except use of numeric - IPv6 address in jobid) - -[SNMP] Simple Network Management Protocol (SNMP), Version 3 -IETF Standard, for list of related RFCs see http://en.wikipedia.org/wiki/SNMP#RFCs -- SNMPv3: http://www.ibr.cs.tu-bs.de/projects/snmpv3/ -- create private enterprise numbers for gLite under the prefix: -iso.org.dod.internet.private.enterprise (1.3.6.1.4.1) -- create MIB for LB and implement basic monitoring functions (lb.server) - - -Job related standards ---------------------- - -[JSDL] Job Submission Description Language (JSDL) Specification, Version 1.0 -OGF Recommendation GFD-R.136 http://www.ogf.org/documents/GFD.136.pdf -- specifies the semantics and structure of JSDL and includes the normative XML Schema for JSDL -- LB should be aware of the JSDL format since some of the attributes are (will be) read from it - -[JSDL-exp] Implementation and Interoperability Experiences with the Job Submission Description Language(JSDL) 1.0 -OGF Experimental Document GFD-E.140 http://www.ogf.org/documents/GFD.140.pdf -- good summary of different JSDL implementations and interoperability experiences -- LB should be aware of different JSDL implementations - -[OGSA-BES] OGSA Basic Execution Service, Version 1.0 -OGF Proposed Recommendation GFD-R-P.108 http://www.ogf.org/documents/GFD.108.pdf -- defines a basic state model with states: -pending, running, finished, terminated, failed (last three terminal states) -- plus specializations: -running -> running stage-in, running executing, running stage-out -running -> running proceeded, running suspended (with events resume, suspend) -running -> running on-resource, running migrating (with event migrate) -running -> running can-proceed, running held (with events hold, release) -- LB could provide information for BES-Factory and BES-Activity port-type -BES-Factory port-type defines operations for initiating, monitoring, and managing -sets of activities, and for accessing information about the BES. -BES-Activity port-type indicates an extension point for operations relating to the -monitoring and management of individual activities. BES-Activity is unspecified -and maybe it could be extended by LB specification in the future. -- reflect the above states specializations in the LB state machine - - -WS Standards ------------- - -[WS-I-BP] The Web Services-Interoperability Organization (WS-I) Basic Profile -Version 1.1 (Specification) http://www.ws-i.org/Profiles/BasicProfile-1.1.html -Version 1.2 (Board Approval Draft) http://www.ws-i.org/Profiles/BasicProfile-1.2.html -Version 2.0 (Working Group Draft) http://www.ws-i.org/Profiles/BasicProfile-2_0(WGD).html -- defines a set of non-proprietary WS specifications, along with clarifications, -refinements, interpretations and amplifications of those specifications which promote -interoperability -- rather general specification of WS interoperability, defines messages and service description -(esp. SOAP Bindings) -- check if LB WS needs to change - -[WS-Addresing] Web Services Addressing 1.0 - Core -W3C Recommendation http://www.w3.org/TR/ws-addr-core -+ -[WS-Naming] WS-Naming Specification -OGF Proposed Recommendation GFD-R-P.109 http://www.ogf.org/documents/GFD.109.pdf -- in LB define properly EndPoint Identifier (EPI) - - -WS Data Acces and Integration ------------------------------ - -[WS-DAI] Web Services Data Access and Integration - The Core (WS-DAI) Specification, Version 1.0 -OGF Proposed Recommendation GFD-R-P.074 http://www.ogf.org/documents/GFD.74.pdf -- specification for a collection of generic data interfaces that are made available as WS -- describe basic concepts (data service model, interface, data access, lifetime) -and data service properties and messages (static and configurable data description, data access and -factory messages) -- this is general specification, see particular proposals to access relational [WS-DAIR] and -XML [WS-DAIX] representations of data below -- there are probably no particular needs to change this specification (at the moment) -- LB probably COULD be WS-DAI compliant and implement at least one of the WS-DAIR or WS-DAIX -realisations - do we really want it? - - -[WS-DAIX] Web Services Data Access and Integration - The XML Realization (WS-DAIX) Specification, Version 1.0 -OGF Proposed Recommendation GFD-R-P.075 http://www.ogf.org/documents/GFD.75.pdf -- specification for a collection of data access interfaces for XML data resources -- it is NOT a new query/update language for XML, it works as a "channel" to XPath/XQuery/XUpdate -- defines new interfaces XMLCollectionDescription and XMLCollectionAccess --- direct access to data: XPathAccess/XQueryAccess/XUpdateAccess across a XMLCollection --- indirect access: XPathFactory/XQueryFactory/XUpdateFactory across a XMLCollection -- XMLCollection collects together XML documents (MAY be nested) --- several different approaches in LB possible: "single document" could be a -job state description -> collection of jobs -one event -> collection of events -one query -> complex queries --- XMLCollectionAccess then defines operations -Add/Get/Remove Documents, Create/Remove Subcollection, Add/Get/Remove Schema -- XMLSequence represents the result sequence of an XQuery or XPath request. A sequence is -an ordered collection of zero or more items (node, atomic value) -- implementation in LB MAY be either easy (update already used XML to WS-DAIX "format") -or very difficult (keep data on LB server in one or more different XML formats) - - -[WS-DAIR] Web Services Data Access and Integration - The Relational Realisation (WS-DAIR) Specification, Version 1.0 -OGF Proposed Recommendation GFD-R-P.076 http://www.ogf.org/documents/GFD.76.pdf -- specification for a collection of data access interfaces for relational data resources -- defines a new direct access interfaces SQLAccessDescription and SQLAccess -and indirect SQLAccessFactory and SQLResponseFactory -- SQLAccess then defines operations -GetSQLPropertyDocument (returns SQLAccessDescription, i.e. static schema + dataset description) and -SQLExecute (IN: SQLExecuteRequest, OUT: SQLExecuteResponse) -- response is defined by SQLResponseDescription/Access, --- it can contain SQLRowSets - results of an SQL query over the database, it is defined by SQLRowSetDescription/Access -- implementation in LB could be easier than for WS-DAIX -- could be an independent service on top of the LB database (or directly in the lb.server?) -- should not be difficult to define the AccessDescription and implement Access - - -[DAIS-InterTest] Interoperability Testing for DAIS Working Group Specifications -OGF Informational Document GFD-I.077 http://www.ogf.org/documents/GFD.77.pdf -- describes how to test WS-DAI* implementations (mandatory and optional features) -- once LB implements WS-DAI*, these tests will have to be performed - - -WS Notifications ----------------- - -WS-Notification is a family of related specifications that define a standard Web services -approach to notification using a topic-based publish/subscribe pattern. -- see http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsn - -[WS-BaseNotification] Web Services Base Notification 1.3 -OASIS Standard http://docs.oasis-open.org/wsn/wsn-ws_base_notification-1.3-spec-os.pdf -- standard message exchanges to be implemented by service providers that wish to participate in Notifications -- defines notification consumer and producer interface, pull-style notifications, -subscription manager interface, and some security considerations -- Notifications via WS is a new functionality to LB that should not be too difficult to implement - -[WS-BrokeredNotification] Web Services Brokered Notification 1.3 -OASIS Standard http://docs.oasis-open.org/wsn/wsn-ws_brokered_notification-1.3-spec-os.pdf -- standard message exchanges for a notification broker service provider (allowing publication -of messages from entities that are not themselves service providers) -- a notification broker is an intermediary between message publishers and message subscribers -- possible implementation in LB might consider a notification broker rather than implementing -the functionality directly within the LB server - -[WS-Topics] Web Services Topics 1.3 -OASIS Standard http://docs.oasis-open.org/wsn/wsn-ws_topics-1.3-spec-os.pdf -- defines a mechanism to organize and categorize items of interest for subscription known as “topics” -- defines four topic expression dialects that can be used as subscription expressions in subscribe -request messages and other parts of the WS-Notification system -- specifies an XML model for describing metadata associated with topics -- this document should be considered during implementation of WS-Notifications - - -WS Reliable Messaging ---------------------- - -[WS-RM] Web Services ReliableMessaging 1.1 -OASIS Standard http://docs.oasis-open.org/ws-rx/wsrm/200702/wsrm-1.1-spec-os-01-e1.html -- describes a protocol that allows messages to be delivered reliably between -distributed applications in the presence of software component, system, or network failures -- see also https://www.ibm.com/developerworks/webservices/library/specification/ws-rm/ -- it probably SHOULD be considered when implementing LB WS-Notifications as well as -in the standard WS messaging provided by LB - - -WS Security ------------ - -[WS-I-BSP] The Web Services-Interoperability Organization (WS-I) Basic Security Profile -Version 1.0 (Specification) http://www.ws-i.org/Profiles/BasicSecurityProfile-1.0.html -Version 1.1 (Working Group Approval Draft) http://www.ws-i.org/Profiles/BasicSecurityProfile-1.1.html -- defines transport layer mechanisms, SOAP nodes and messages, security headers, timestamps, -security tokens (X.509, Kerberos, SAML, EncryptedKey), XML Signature and XML Encryption, -attachment security -- LB should probably adopt all these mechanisms - -[WS-I-RSP] The Web Services-Interoperability Organization (WS-I) Reliable Security Profile -Version 1.0 (Working Group Draft) http://www.ws-i.org/Profiles/ReliableSecureProfile-1.0.html -- defines secure reliable messaging and secure conversation -- LB should probably adopt all these mechanisms -- see also Reliable Secure Profile Usage Scenarios http://www.ws-i.org/profiles/rsp-scenarios-1.0.pdf - -[Sec-addr] Secure Addressing Profile 1.0 -OGF Proposed Recommendation GFD-R-P.131 http://www.ogf.org/documents/GFD.131.pdf -- defines WS-SecurityPolicy assertions within WS-Addressing -- in LB define properly EndPoint Reference (EPR) -- affects all LB WS (ljocha: especially LB notifications?) - -[Sec-comm] Secure Communication Profile 1.0 -OGF Proposed Recommendation GFD-R-P.132 http://www.ogf.org/documents/GFD.132.pdf -- defines authentication, authorization (and auditing), integrity and confidentiality properties of WS interactions -- affects all LB WS, LB SHOULD adopt: --- Message-level authentication (see section 7) --- Integrity (e.g. CRITICAL_SIGNING of SOAP messages) --- more transport-level mechanisms and policies (see section 6) -- proper LB security audit required - - -WS Transactions ---------------- - -WS Transactions specifications define mechanisms for transactional interoperability between -WS domains and provide a means to compose transactional qualities of service into WS applications. -- see http://www.ibm.com/developerworks/webservices/library/specification/ws-tx -- describes an extensible coordination framework (WS-Coordination) and specific coordination types for -short duration, ACID transactions (WS-AtomicTransaction) and longer running business transactions (WS-BusinessActivity) -- LB should consider WS-AtomicTransaction when logging via WS is going to be supported -(org.glite.lb.java-client?) and WS-BusinessActivity probably for WS queries - - -Other references ----------------- - -[OASIS] OASIS Standards and Other Approved Work -- see http://www.oasis-open.org/specs/ - -[OGF] OGF Documents -- http://www.ogf.org/gf/docs/?final - -[W3C] W3C Technical Reports and Publications -- see http://www.w3.org/TR/ - -[STD] IETF Official Internet Protocol Standards -- see http://www.rfc-editor.org/rfcxx00.html - -[IETF] IETF Internet-Drafts -- see http://www.ietf.org/ID.html - diff --git a/org.glite.lb.doc/src/change_acl.tex b/org.glite.lb.doc/src/change_acl.tex deleted file mode 100644 index 91d09db..0000000 --- a/org.glite.lb.doc/src/change_acl.tex +++ /dev/null @@ -1,95 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\subsubsection{Example: Changing Job Access Control List} -\label{e:change-acl} - -In order to change the Access Control List (ACL) for a job (see also \ref{sec:job-authz}), a special event -\verb'ChangeACL' is used. This event can be logged by the job owner using the -\verb'glite-lb-logevent' command (see also Sect.~\ref{glite-lb-logevent}). -The general template for changing the ACL is as follows: - -\begin{verbatim} -glite-lb-logevent -e ChangeACL -s UserInterface -p -j - --user_id - --user_id_type - --permission READ - --permission_type --operation -\end{verbatim} - -where - -\begin{tabularx}{\textwidth}{>{\texttt}lX} -\verb'' & specifies the job to change access to\\ -\verb'' & specifies the user to grant or revoke permission. The - parameter can be either an X.500 name - (subject name), a VOMS group (of the form VO:Group), or a Full - qualified attribute name (FQAN). \\ -\verb'' & indicates the type of the user\_id given above. - \verb'DN', \verb'GROUP', and \verb'FQAN' can be given to - specify X.500 name, VOMS group, or FQAN, respectively \\ -\verb'' & ACL permission to change, currently only \verb'READ' is - supported. Starting from \LBver{3.0}, the permission \verb'TAG' can - also be used.\\ -\verb'' & Type of permission requested. \verb'ALLOW' or - \verb'DENY' can be specified. \\ -\verb'' & Operation requested to be performed with ACL. \verb'ADD' - or \verb'REMOVE' can be specified. \\ -\end{tabularx} - -Adding a user specified by his or her subject name to the ACL (\ie granting -access rights to another user): - -\begin{verbatim} -glite-lb-logevent -e ChangeACL -s UserInterface -p -j \ - --user_id '/O=CESNET/O=Masaryk University/CN=Daniel Kouril' \ - --user_id_type DN --permission READ --permission_type ALLOW \ - --operation ADD -\end{verbatim} - - -Removing a user specified by his or her subject name from the ACL (\ie -revoking access right to another user): - -\begin{verbatim} -glite-lb-logevent -e ChangeACL -s UserInterface -p -j \ - --user_id '/O=CESNET/O=Masaryk University/CN=Daniel Kouril' \ - --user_id_type DN --permission READ --permission_type ALLOW \ - --operation REMOVE -\end{verbatim} - - -Adding a VOMS attribute to the ACL: - -\begin{verbatim} -glite-lb-logevent -e ChangeACL -s UserInterface -p -j \ - --user_id '/VOCE/Role=Administrator' --user_id_type FQAN \ - --permission TAG --permission_type ALLOW \ - --operation ADD -\end{verbatim} - - -Note that \LBver{1.x} supported only using VOMS group names, not full FQANs, -whose support has been introduced in \LBver{2.0}. \LBver{1.x} also did not -allow the users to use symbolic names for the values specifying ACL -setting and integers must be used instead. For example, to grant access -right on a \LBver{1.x} server one has to use following syntax: - -\begin{verbatim} -glite-lb-logevent -e ChangeACL -s UserInterface -p -j \ - --user_id '/O=CESNET/O=Masaryk University/CN=Daniel Kouril' \ - --user_id_type 0 --permission 1 --permission_type 0 --operation 0 -\end{verbatim} diff --git a/org.glite.lb.doc/src/components.tex b/org.glite.lb.doc/src/components.tex deleted file mode 100644 index 94520bc..0000000 --- a/org.glite.lb.doc/src/components.tex +++ /dev/null @@ -1,164 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\subsubsection{\LB API and library} -Both logging events and querying the service are implemented via -calls to a~public \LB API. -The complete API (both logging and queries) -is available in ANSI~C binding, most of the querying capabilities also in C++. -These APIs are provided as sets of C/C++ header files and shared libraries. -The library implements communication protocol with other \LB components -(logger and server), including encryption, authentication etc. -Since \LBver{2.0} an experimental Java binding of the logging API is available. - -We do not describe the API here in detail; it is documented in~\LB Developer's -Guide\cite{lbdg}, -including complete reference and both simple and complex usage examples. - -Events can be also logged with a~standalone program (using the C~API in turn), -intended for usage in scripts. - -The query interface is also available as a~web-service provided by the -\LB server (Sect.~\ref{server}). - -Finally, certain frequent queries (all user's jobs, single job status, \dots) -are available as HTML pages (by pointing ordinary web browser to the \LB server -endpoint), or as simple text queries (since \LBver{2.0}) intended for scripts. -See~% -\ifx\insideUG\undefined -\cite{lbug} -\else -\ref{simple} -\fi -for details. - -\subsubsection{Logger} -\label{comp:logger} -The task of the \emph{logger} component is taking over the events from -the logging library, storing them reliably, and forwarding to the destination -server. -The component should be deployed very close to each source of events---on the -same machine ideally, or, in the case of computing elements with many -worker nodes, on the head node of the cluster% -\footnote{In this setup logger also serves as an application proxy, -overcoming networking issues like private address space of the worker nodes, -blocked outbound connectivity etc.}. - -Technically the functionality is realized with two daemons: -\begin{itemize} -\item \emph{Local-logger} accepts incoming events, -appends them in a~plain disk file (one file per Grid job), -and forwards to inter-logger. -It is kept as simple as possible in order to achieve -maximal reliability. -\item \emph{Inter-logger} accepts the events from the local-logger, -implements the event routing (currently trivial as the destination -address is a~part of the jobid), and manages -delivery queues (one per destination server). -It is also responsible for crash recovery---on startup, the queues are -populated with undelivered events read from the local-logger files. -Finally, the inter-logger purges the files when the events are delivered to -their final destination. -\end{itemize} - -\subsubsection{Server} -\label{server} -\emph{\LB server} is the destination component where the events are delivered, -stored and processed to be made available for user queries. -The server storage backend is implemented using MySQL database. - -Incoming events are parsed, checked for correctness, authorized (only the job -owner can store events belonging to a~particular job), and stored into the -database. -In addition, the current state of the job is retrieved from the database, -the event is fed -into the state machine -\ifx\insideUG\undefined\relax\else -(Sect.~\ref{evprocess}), -\fi -and the job state updated -accordingly. - -On the other hand, the server exposes querying interface -(Fig.~\ref{f:comp-query}\ifx\insideUG\undefined\relax\else, Sect.~\ref{retrieve}\fi). -The incoming user queries are transformed into SQL queries on the underlying -database engine. -The query result is filtered, authorization rules applied, and the result -sent back to the user. - -While using the SQL database, its full query power is not made available -to end users. -In order to avoid either intentional or unintentional denial-of-service -attacks, the queries are restricted in such a~way that the transformed SQL -query must hit a~highly selective index on the database. -Otherwise the query is refused, as full database scan would yield unacceptable -load. -The set of indices is configurable, and it may involve both \LB system -attributes (\eg job owner, computing element, -timestamps of entering particular state,~\dots) and user defined ones. - -The server also maintains the active notification handles% -\ifx\insideUG\undefined\relax\else -(Sect.~\ref{retrieve}) -\fi -, providing the subscription interface to the user. -Whenever an event arrives and the updated job state is computed, -it is matched against the active handles% -\footnote{The current implementation enforces specifying an~actual jobid -in the subscription hence the matching has minimal performance impact.}. -Each match generates a~notification message, an extended \LB event -containing the job state data, notification handle, -and the current user's listener location. -The event is passed to the \emph{notification inter-logger} -via persistent disk file and directly (see Fig.~\ref{f:comp-query}). -The daemon delivers events either in a standard way, using the specified -listener as destination, or forwards them to a messaging broker for delivery through the messaging infrastructure. -When using the standard delivery mechanism, -the server generates control messages when the user re-subscribes, -changing the listener location. -Inter-logger recognizes these messages, and changes the routing of all -pending events belonging to this handle accordingly. - - -% asi nepotrebujeme \subsubsection{Clients} - -\subsubsection{Proxy} -\label{s:proxy} - -\emph{\LB proxy} is the implementation of the concept of local view on job state (see -\ifx\insideUG\undefined{\cite{lbug}}\else{Sect.~\ref{local}}\fi). Since -\LBver{2.0}, \LB proxy is intergrated into \LB server executable. When deployed (on -the WMS node in the current gLite middleware) it takes over the role of the -local-logger daemon---it accepts the incoming events, stores them in files, and -forwards them to the inter-logger. - -In addition, the proxy provides the basic principal functionality of \LB server, -\ie processing events into job state and providing a~query interface, -with the following differences: -\begin{itemize} -\item only events coming from sources on this node are considered; hence -the job state may be incomplete, -\item proxy is accessed through local UNIX-domain socket instead of network -interface, -\item no authorization checks are performed---proxy is intended for -privileged access only (enforced by the file permissions on the socket), -\item aggressive purge strategy is applied---whenever a~job reaches -a~known terminal state (which means that no further events are expected), it is purged -from the local database immediately, -\item no index checks are applied---we both trust the privileged parties -and do not expect the database to grow due to the purge strategy. -\end{itemize} - diff --git a/org.glite.lb.doc/src/consumer_api.tex b/org.glite.lb.doc/src/consumer_api.tex deleted file mode 100644 index cac90db..0000000 --- a/org.glite.lb.doc/src/consumer_api.tex +++ /dev/null @@ -1,590 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% -*- mode: latex -*- - -\section{\LB\ Querying (Consumer) API} -\label{s:Consumer-API} -The \LB Consumer API is used to obtain information from \LB server -or Proxy using simple query language (see -Sect.~\ref{s:querylang}). There are two types of queries based -on the results returned: -\begin{itemize} -\item query for events -- the result contains events satisfying given -criteria, -\item query for jobs -- the result contains JobId's and job states of jobs -satisfying given criteria. -\end{itemize} -The potential result sets can be very large; the \LB server imposes -limits on the result set size, which can be further restricted by the -client. - - -\subsection{Query Language} -\label{s:querylang} -The \LB query language is based on simple value assertions on job and -event attributes. There are two types of queries based on the -complexity of selection criteria, \textit{simple} and -\textit{complex}. -Simple queries are can be described by the following formula: -\begin{displaymath} -\textit{attr}_1 \mathop{\textrm{ OP }} \textit{value}_1 \wedge \dots \wedge -\textit{attr}_n \mathop{\textrm{ OP }} \textit{value}_n -\end{displaymath} -where $\textit{attr}_i$ is attribute name, $\mathop{\textrm{ OP }}$ is -one of the $=$, $<$, $>$, $\neq$ and $\in$ relational operators and -$\textit{value}$ is single value (or, in the case of $\in$ operator, -interval) from attribute type. - -Complex queries can be described using the following formula: -\begin{multline*} -(\textit{attr}_1 \mathop{\textrm{ OP }} \textit{value}_{1,1} \vee \dots \vee -\textit{attr}_1 \mathop{\textrm{ OP }} \textit{value}_{1,i_1}) \wedge \\ -(\textit{attr}_2 \mathop{\textrm{ OP }} \textit{value}_{2,1} \vee \dots \vee -\textit{attr}_2 \mathop{\textrm{ OP }} \textit{value}_{2,i_2}) \wedge \\ -\vdots \\ -\wedge (\textit{attr}_n \mathop{\textrm{ OP }} \textit{value}_{n,1} \vee \dots \vee -\textit{attr}_n \mathop{\textrm{ OP }} \textit{value}_{n,i_n}) -\end{multline*} -The complex query can, in contrast to simple query, contain more -assertions on value of single attribute, which are ORed together. - -\marginpar{Indexed attributes}% -The query must always contain at least one attribute indexed -on the \LB server; this restriction is necessary to avoid matching the -selection criteria against all jobs in the \LB database. The list of -indexed attributes for given \LB server can be obtained by \LB API -call. - -\subsection{C Language Binding} - -\subsubsection{Call Semantics} -The \LB server queries are, in contrast to logging event calls, -synchronous (for asynchronous variant see Sect.~\ref{s:Notification-API}, -notifications). The server response contains \jobid's, job states -and/or events known to the server at the moment of processing the -query. Due to the asynchronous nature of event delivery it may not -contain all data that was actually sent; the job state computation is -designed to be resilient to event loss to some extent. - -\marginpar{Result size limits}% -When the item count returned by \LB\ server exceeds the defined -limits, the \verb'E2BIG' error occur. There are two limits\,---\,the server -and the user limit. The user defined limit may be set in the context -at the client side, while the server imposed limit is configured at -the server and can be only queried by the client. The way the \LB -library and server handles the over--limit result size can be -specified by setting context parameter -\verb'EDG_WLL_PARAM_QUERY_RESULTS' to one of the following values: -\begin{itemize} -\item \verb'EDG_WLL_QUERYRES_NONE'\,---\,In case the limit is reached, -no results are returned at all. -\item \verb'EDG_WLL_QUERYRES_LIMITED'\,---\,A result contains at most -``limit'' item count. -\item \verb'EDG_WLL_QUERYRES_ALL'\,---\,All results are returned and -limits have no effect. This option is available only in special cases -such as ``user jobs query'' and the ``job status query''. Otherwise -the EINVAL error is returned. -\end{itemize} -Default value is \verb'EDG_WLL_QUERYRES_NONE'. - - -\subsubsection{Header Files} -\begin{table}[h!] -\begin{tabularx}{\textwidth}{>{\tt}lX} -glite/lb/consumer.h & Prototypes for all query functions. \\ -\end{tabularx} -\end{table} - -\subsubsection{Context Parameters} -The table~\ref{t:ccontext} shows parameters relevant to the query API. - -\begin{table}[h!] -\begin{tabularx}{\textwidth}{lX} -{\bf Name} & {\bf Description} \\ -\hline -\lstinline'EDG_WLL_PARAM_QUERY_SERVER' & -Default server name to query. -\\ -\lstinline'EDG_WLL_PARAM_QUERY_SERVER_PORT' & -Default server port to query. -\\ -\lstinline'EDG_WLL_PARAM_QUERY_SERVER_OVERRIDE' & -host:port parameter setting override even values in \jobid (useful for -debugging \& hacking only) -\\ -\lstinline'EDG_WLL_PARAM_QUERY_TIMEOUT' & -Query timeout. -\\ -\lstinline'EDG_WLL_PARAM_QUERY_JOBS_LIMIT' & -Maximal query jobs result size. -\\ -\lstinline'EDG_WLL_PARAM_QUERY_EVENTS_LIMIT' & -Maximal query events result size. -\\ -\lstinline'EDG_WLL_PARAM_QUERY_RESULTS' & -Flag to indicate handling of too large results. -\\ -\end{tabularx} -\caption{Consumer specific context parameters} -\label{t:ccontext} -\end{table} - - -\subsubsection{Return Values} -\LB\ server returns errors which are classified as hard and soft errors. -The main difference between these categories is that in the case of soft -errors results may still be returned. The authorization errors belong to -``soft error'' sort. Hard errors like \verb'ENOMEM' are typically all -unrecoverable, to obtain results the query must be repeated, possibly -after correcting the failure condition the error indicated. - -Depending on the setting of context parameter -\verb'EDG_WLL_PARAM_QUERY_RESULTS', the \verb'E2BIG' error may fall into both -categories. - - -\subsubsection{Query Condition Encoding} -\label{s:queryrec} -The \LB query language is mapped into (one- or two-dimensional) array -of attribute value assertions represented by -\verb'edg_wll_QueryRec' structure: -\begin{lstlisting} -typedef struct _edg_wll_QueryRec { - edg_wll_QueryAttr attr; //* \textit{attribute to query} - edg_wll_QueryOp op; //* \textit{query operation} - union { - char * tag; //* \textit{user tag name / JDL attribute "path"} - edg_wll_JobStatCode state; //* \textit{job status code} - } attr_id; - union edg_wll_QueryVal { - int i; //* \textit{integer query attribute value} - char *c; //* \textit{character query attribute value} - struct timeval t; //* \textit{time query attribute value} - glite_jobid_t j; //* \textit{JobId query attribute value} - } value, value2; -} edg_wll_QueryRec; -\end{lstlisting} - -% \TODO{pro prehlednost bych mozna pridal seznam vsech atributu na ktere se lze ptat} - -The table~\ref{t:cqueryattr} shows the most common query attributes. -For a complete list see \texttt{query\_rec.h}. - -\begin{table}[ht] -\begin{tabularx}{\textwidth}{lX} -{\bf Name} & {\bf Description} \\ -\hline -\lstinline'EDG_WLL_QUERY_ATTR_JOBID' & Job ID to query. \\ -\lstinline'EDG_WLL_QUERY_ATTR_OWNER' & Job owner. \\ -\lstinline'EDG_WLL_QUERY_ATTR_STATUS' & Current job status. \\ -\lstinline'EDG_WLL_QUERY_ATTR_LOCATION' & Where is the job processed. \\ -\lstinline'EDG_WLL_QUERY_ATTR_DESTINATION' & Destination CE. \\ -\lstinline'EDG_WLL_QUERY_ATTR_DONECODE' & Minor done status (OK,failed,cancelled). \\ -\lstinline'EDG_WLL_QUERY_ATTR_USERTAG' & User tag. \\ -\lstinline'EDG_WLL_QUERY_ATTR_JDL_ATTR' & Arbitrary JDL attribute. \\ -\lstinline'EDG_WLL_QUERY_ATTR_STATEENTERTIME' & When entered current status. \\ -\lstinline'EDG_WLL_QUERY_ATTR_LASTUPDATETIME' & Time of the last known event of the job. \\ -\end{tabularx} -\caption{Query record specific attributes.} -\label{t:cqueryattr} -\end{table} - -The table~\ref{t:cqueryop} shows all supported query operations. - -\begin{table}[ht] -\begin{tabularx}{\textwidth}{lX} -{\bf Name} & {\bf Description} \\ -\hline -\lstinline'EDG_WLL_QUERY_OP_EQUAL' & Attribute is equal to the operand value. \\ -\lstinline'EDG_WLL_QUERY_OP_LESS' & Attribute is grater than the operand value. \\ -\lstinline'EDG_WLL_QUERY_OP_GREATER' & Attribute is less than the operand value. \\ -\lstinline'EDG_WLL_QUERY_OP_WITHIN' & Attribute is in given interval. \\ -\lstinline'EDG_WLL_QUERY_OP_UNEQUAL' & Attribute is not equal to the operand value. \\ -\lstinline'EDG_WLL_QUERY_OP_CHANGED' & Attribute has changed from last check (supported since \LBver{2.0} in notification matching). \\ -\end{tabularx} -\caption{Query record specific operations.} -\label{t:cqueryop} -\end{table} - - - -\subsubsection{Query Jobs Examples} -\label{s:qjobs} - -The simplest use case corresponds to the situation when an exact job ID -is known and the only information requested is the job status. The job ID -format is described in~\cite{djra1.4}. Since \LBver{2.0}, it is also possible to -query all jobs belonging to a specified user, VO or RB. - -The following example shows how to retrieve the status information -about all user's jobs running at a specified CE. - -First we have to include neccessary headers: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=headers-end\ headers]{cons_example1.c} - -Define and initialize variables: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=variables-end\ variables]{cons_example1.c} - -Initialize context and set parameters: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=context-end\ context]{cons_example1.c} - -Set the query record to \emph{all (user's) jobs running at CE 'XYZ'}: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=queryrec-end\ queryrec]{cons_example1.c} - -Query jobs: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=query-end\ query]{cons_example1.c} - -Now we can for example print the job states: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=printstates-end\ printstates]{cons_example1.c} - - -In many cases the basic logic using only conjunctions is not sufficient. -For example, if you need all your jobs running at the destination XXX or at -the destination YYY, the only way to do this with the \texttt{edg\_wll\_QueryJobs()} -call is to call it twice. The \texttt{edg\_wll\_QueryJobsExt()} call allows to make -such a~query in a single step. -The function accepts an array of condition lists. Conditions within a~single list are -OR-ed and the lists themselves are AND-ed. - -The next query example describes how to get all user's jobs running at -CE 'XXX' or 'YYY'. - -We will need an array of three conditions (plus one last empty): - -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=variables-end\ variables]{cons_example2.c} - -The query condition is the following: - -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=queryrec-end\ queryrec]{cons_example2.c} - -As can be clearly seen, there are three lists supplied to -\texttt{edg\_wll\_QueryJobsExt()}. The first list specifies the owner of the -job, the second list provides the required status (\texttt{Running}) and -the last list specifies the two destinations. -The list of lists is terminated with \texttt{NULL}. -This query equals to the formula -\begin{quote} -\texttt{(user=NULL) and (state=Running) and (dest='XXX' or dest='YYY')}. -\end{quote} - -To query the jobs, we simply call -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=query-end\ query]{cons_example2.c} - - - -\subsubsection{Query Events Examples} - -Event queries and job queries are similar. Obviously, the return type is -different \Dash the \LB\ raw events. There is one more input parameter -representing specific conditions on events (possibly empty) in addition to -conditions on jobs. - -The following example shows how to select all events (and therefore jobs) -marking red jobs (jobs that were marked red at some time in the past) as green. - -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=variables-end\ variables]{cons_example3.c} - -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=queryrec-end\ queryrec]{cons_example3.c} - -This example uses \texttt{edg\_wll\_QueryEvents()} call. Two condition lists are -given to \texttt{edg\_wll\_QueryEvents()} call. One represents job conditions and -the second represents event conditions. These two lists are joined together with -logical and (both condition lists have to be satisfied). This is necessary as -events represent a state of a job in a particular moment and this changes in time. - -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=query-end\ query]{cons_example3.c} - -The \texttt{edg\_wll\_QueryEvents()} returns matched events and save them in the -\texttt{eventsOut} variable. Required job IDs are stored in the edg\_wll\_Event -structure. - -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=printevents-end\ printevents]{cons_example3.c} - -In a similar manor to \texttt{edg\_wll\_QueryJobsExt()}, there exists also \texttt{edg\_wll\_QueryEventsExt()} -that can be used to more complex queries related to events. See also \texttt{README.queries} for more examples. - - -Last \LB Querying API call is \texttt{edg\_wll\_JobLog()} that returns all events related to a single job. -In fact, it is a convenience wrapper around \texttt{edg\_wll\_QueryEvents()} and its usage is clearly -demonstrated in the client example \texttt{job\_log.c} (in the client module). - - - -\subsection{C++ Language Binding} -The querying C++ \LB API is modelled after the C \LB API using these basic principles: -\begin{itemize} -\item queries are expressed as vectors of -\verb'glite::lb::QueryRecord' instances, -\item \LB context and general query methods are represented by class -\verb'glite::lb::ServerConnection', -\item \LB job specific queries are encapsulated within class -\verb'glite::lb::Job', -\item query results are returned as (vector or list of) -\verb'glite::lb::Event' or \verb'glite::lb::JobStatus' read-only instances. -\end{itemize} - - -\subsubsection{Header Files} -Header files for the \LB consumer API are summarized in table~\ref{t:ccppheaders}. -\begin{table}[h] -\begin{tabularx}{\textwidth}{>{\tt}lX} -glite/lb/Event.h & Event class for event query results. \\ -glite/lb/JobStatus.h & JobStatus class for job query results. \\ -glite/lb/ServerConnection.h & Core of the C++ \LB API, defines -\verb'QueryRecord' class for specifying queries and -\verb'ServerConnection' class for performing the queries. \\ -glite/lb/Job.h & Defines \verb'Job' class with methods for job -specific queries. \\ -\end{tabularx} -\caption{Consumer C++ API header files} -\label{t:ccppheaders} -\end{table} - -\subsubsection{QueryRecord} -The \verb'glite::lb::QueryRecord' class serves as the base for mapping -the \LB query language into C++, similarly to the C counterpart -\verb'edg_wll_QueryRecord'. The \verb'QueryRecord' object represents -condition on value of single attribute: -\begin{lstlisting} -using namespace glite::lb; - -QueryRecord a(QueryRecord::OWNER, QueryRecord::EQUAL, "me"); -\end{lstlisting} -The \verb'QueryRecord' class defines symbolic names for attributes (in -fact just aliases to \verb'EDG_WLL_QUERY_ATTR_' symbols described in table\ -\ref{t:cqueryattr}) and for logical operations (aliases to -\verb'EDG_WLL_QUERY_OP_' symbols, table\ \ref{t:cqueryop}). The last -parameter to the \verb'QueryRecord' constructor is the attribute -value. - -There are constructors with additional arguments for specific -attribute conditions or logical operators that require it, \ie\ -the \verb'QueryRecord::WITHIN' operator and queries about state enter -times. The query condition ``job that started running between \verb'start' -and \verb'end' times' can be represented in the following way: -\begin{lstlisting} -struct timeval start, end; - -QueryRecord a(QueryRecord::TIME, QueryRecord::WITHIN, JobStatus::RUNNING, - start, end); -\end{lstlisting} - - -\subsubsection{Event} -The objects of class \verb'glite::lb::Event' are returned by the \LB event -queries. The \verb'Event' class intgstr roduces symbolic names for event -type (enum \verb'Event::Type'), event attributes (enum -\verb'Event::Attr') and their types (enum -\verb'Event::AttrType'), feature not available through the C API, as -well as (read only) access to the attribute values. Using -these methods you can: -\begin{itemize} -\item get the event type (both symbolic and string): -\begin{lstlisting} - Event event; - - // we suppose event gets somehow filled in - cout << "Event type: " << event.type << endl; - - cout << "Event name:" << endl; - // these two lines should print the same string - cout << Event::getEventName(event.type) << endl; - cout << event.name() << endl; -\end{lstlisting} -\item get the list of attribute types and values (see -line~\ref{l:getattrs} of the example), -\item get string representation of attribute names, -\item get value of given attribute. -\end{itemize} -The following example demonstrates this by printing event name and attributes: -\lstinputlisting[title={\bf File:}\lstname,numbers=left,linerange=event-end\ event]{util.C} - -\subsubsection{JobStatus} -The \verb'glite::lb::JobStatus' is a result type of job status -queries in the same way the \verb'glite::lb::Event' is used in event -queries. The \verb'JobStatus' class provides symbolic names for job -states (enum \verb'JobStatus::Code'), state attributes -(enum \verb'JobStatus::Attr') and their types (enum -\verb'JobStatus::AttrType'), and read only access to the -attribute values. Using the \verb'JobStatus' interface you can: -\begin{itemize} -\item get the string name for the symbolic job state: -\begin{lstlisting} - JobStatus status; - - // we suppose status gets somehow filled in - cout << "Job state: " << status.type << endl; - - cout << "State name: " << endl; - // these two lines should print the same string - cout << JobStatus::getStateName(status.type) << endl; - cout << status.name() << endl; -\end{lstlisting} -\item get the job state name (both symbolic and string), -\item get the list of job state attributes and types, -\item convert the attribute names from symbolic to string form and -vice versa, -\item get value of given attribute. -\end{itemize} -The following example demostrates this by printing job status (name -and attributes): -\lstinputlisting[title={\bf File:}\lstname,numbers=left,linerange=status-end\ status]{util.C} - -\subsubsection{ServerConnection}\label{s:ServerConnection} -The \verb'glite::lb::ServerConnection' class represents particular \LB -server and allows for queries not specific to particular job (these -are separated into \verb'glite::lb:Job' class). The -\verb'ServerConnection' instance thus encapsulates client part of -\verb'edg_wll_Context' and general query methods. - -There are accessor methods for every consumer context parameter listed -in table \ref{t:ccontext}, \eg for \verb'EDG_WLL_PARAM_QUERY_SERVER' -we have the following methods: -\begin{lstlisting} -void setQueryServer(const std::string& host, int port); -std::pair getQueryServer() const; -\end{lstlisting} -We can also use the generic accessors defined for the parameter types -\verb'Int', \verb'String' and \verb'Time', \eg: -\begin{lstlisting} -void setParam(edg_wll_ContextParam name, int value); -int getParamInt(edg_wll_ContextParam name) const; -\end{lstlisting} - -The \verb'ServerConnection' class provides methods for both event and job queries: -\begin{lstlisting} -void queryJobs(const std::vector& query, - std::vector& jobList) const; - -void queryJobs(const std::vector >& query, - std::vector& jobList) const; - -void queryJobStates(const std::vector& query, - int flags, - std::vector & states) const; - -void queryJobStates(const std::vector >& query, - int flags, - std::vector & states) const; - -void queryEvents(const std::vector& job_cond, - const std::vector& event_cond, - std::vector& events) const; - -void queryEvents(const std::vector >& job_cond, - const std::vector >& event_cond, - std::vector& eventList) const; -\end{lstlisting} -You can see that we use \verb'std::vector' instead of \verb'NULL' terminated -arrays for both query condition lists and results. The API does -not differentiate simple and extended queries by method name -(\verb'queryJobs' and \verb'queryJobsExt' in C), but by parameter -type (\verb'vector' -vs. \verb'vector>'). On the other hand there are -different methods for obtaining \jobid's and full job states as well -as convenience methods for getting user jobs. - -Now we can show the first example of job query from section -\ref{s:qjobs} rewritten in C++. First we have to include the headers: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=headers-end\ headers]{cons_example1.cpp} - -Define variables: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=variables-end\ variables]{cons_example1.cpp} - -Initialize server object: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=queryserver-end\ queryserver]{cons_example1.cpp} - -Create the query condition vector: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=querycond-end\ querycond]{cons_example1.cpp} - -Perform the query: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=query-end\ query]{cons_example1.cpp} - -Print the results: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=printstates-end\ printstates]{cons_example1.cpp} - -The operations can throw an exception, so the code should be enclosed -within try--catch clause. - -The second example rewritten to C++ is shown here; first the query -condition vector: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=queryrec-end\ queryrec]{cons_example2.cpp} - -The query itself: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=query-end\ query]{cons_example2.cpp} - -The third example shows event query (as opposed to job state query in -the first two examples). We are looking for events of jobs, that were -in past painted (tagged by user) green, but now they are red. The -necessary query condition vectors are here: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=queryrec-end\ queryrec]{cons_example3.cpp} - -The query itself: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=query-end\ query]{cons_example3.cpp} - -The resulting event vector is dumped using the utility function -\verb'dumpEvent()' listed above: -\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=printevents-end\ printevents]{cons_example3.cpp} - - -\subsubsection{Job} -The \verb'glite::lb::Job' class encapsulates \LB server queries -specific for particular job as well as client part of context. The -\verb'Job' object provides method for getting the job status and the -event log (\ie all events belonging to the job): -\begin{lstlisting} -JobStatus status(int flags) const; - -void log(std::vector &events) const; -\end{lstlisting} - -\marginpar{\bf Important!}% -It is important to notice that \verb'Job' contain -\verb'ServerConnection' as private member and thus encapsulate client -part of context. That makes them relatively heavy--weight objects and -therefore it is not recommended to create too many instances, but -reuse one instance by assigning different \jobid's to it. - - -\subsection{Web-Services Binding}\label{s:Consumer-API-WS} - -\TODO{ljocha: Complete review, list of all relevant (WSDL) files, their location, etc.} - -In this section we describe the operations defined in the \LB\ WSDL -file (\texttt{LB.wsdl}) as well as its custom types (\texttt{LBTypes.wsdl}). - -For the sake of readability this documentation does not follow the structure -of WSDL strictly, avoiding to duplicate information which is already present -here. Consequently, the SOAP messages are not documented, for example, as they -are derived from operation inputs and outputs mechanically. -The same holds for types: \eg\ we do not document defined elements -which correspond 1:1 to types but are required due to the literal SOAP -encoding. - -For exact definition of the operations and types see the WSDL file. - -\TODO{ljocha: Add fully functional WS examples - in Java, Python, C?} - - -Aby se na to neapomnelo: - -perl-SOAP-Lite-0.69 funguje -perl-SOAP-Lite-0.65 ne (stejne rve document/literal support is EXPERIMENTAL in SOAP::Lite ), tak ma asi pravdu - - -musi mit metodu ns() - diff --git a/org.glite.lb.doc/src/copyright.tex b/org.glite.lb.doc/src/copyright.tex deleted file mode 100644 index 1ad5864..0000000 --- a/org.glite.lb.doc/src/copyright.tex +++ /dev/null @@ -1,42 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% Taken from: -% https://twiki.cern.ch/twiki/bin/view/EGEE/EGEEgLiteSoftwareLicense -% -~ - -\vfill{} - -{\bf -Copyright} \copyright\ {\bf Members of the EGEE Collaboration. 2004. See -\href{http://www.eu-egee.org/partners/}{http://www.eu-egee.org/partners/} for -details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use -this file except in compliance with the License. You may obtain a copy of the -License at - -\begin{center} -\href{http://www.apache.org/licenses/LICENSE-2.0}{http://www.apache.org/licenses/LICENSE-2.0} -\end{center} - -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. -} -\clearpage diff --git a/org.glite.lb.doc/src/definitions.tex b/org.glite.lb.doc/src/definitions.tex deleted file mode 100644 index d1f6ff7..0000000 --- a/org.glite.lb.doc/src/definitions.tex +++ /dev/null @@ -1,54 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% external packages -\usepackage{xspace} -\usepackage{ifthen} -\usepackage{comment} -\usepackage{listings} - -% useful definitions -\def\LB{L\&B\xspace} -\newcommand\LBver[1]{\textit{\LB version {#1}}} -\def\JP{JP\xspace} -%\def\eg{e.\,g.} -\def\eg{for example\xspace} -\def\Eg{For example\xspace} -%\def\ie{i.\,e.} -\def\ie{that is\xspace} -\def\wrt{with respect to\xspace} -\def\Dash{---\penalty-1000} - -\def\req{\noindent\textbf{Prerequisities:}} -\def\how{\noindent\textbf{How to run:}} -\def\what{\noindent\textbf{What to test:}} -\def\result{\noindent\textbf{Expected result:}} -\def\note{\noindent\textbf{Note:}} -\def\path#1{{\normalfont\textsf{#1}}} -\def\code#1{\texttt{#1}} -\def\ctblb#1{\code{org.glite.testsuites.ctb/LB/tests/#1}} - -\specialcomment{hints}{\par\noindent\textbf{Hints: }\begingroup\slshape}{\endgroup} -%\includecomment{hints} - -\long\def\TODO#1{\par\noindent\textbf{TODO:} {\sl#1}\par} -\long\def\ludek#1{} - -\hyphenation{plug-in} - -\newcommand{\email}[1]{\href{mailto:#1}{#1}} - -\input{ver.tex} diff --git a/org.glite.lb.doc/src/doxygen.sty b/org.glite.lb.doc/src/doxygen.sty deleted file mode 100644 index 90f368b..0000000 --- a/org.glite.lb.doc/src/doxygen.sty +++ /dev/null @@ -1,64 +0,0 @@ -\NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{doxygen} -\RequirePackage{calc} -\RequirePackage{array} -%\pagestyle{fancyplain} -\newcommand{\clearemptydoublepage}{\newpage{\pagestyle{empty}\cleardoublepage}} -%\renewcommand{\chaptermark}[1]{\markboth{#1}{}} -%\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} -%\lhead[\fancyplain{}{\bfseries\thepage}] -% {\fancyplain{}{\bfseries\rightmark}} -%\rhead[\fancyplain{}{\bfseries\leftmark}] -% {\fancyplain{}{\bfseries\thepage}} -%\rfoot[\fancyplain{}{\bfseries\scriptsize Generated on Tue Feb 22 11:20:54 2005 for Glite LB Client: C - Interface by Doxygen }]{} -%\lfoot[]{\fancyplain{}{\bfseries\scriptsize Generated on Tue Feb 22 11:20:54 2005 for Glite LB Client: C - Interface by Doxygen }} -%\cfoot{} -\newenvironment{CompactList} -{\begin{list}{}{ - \setlength{\leftmargin}{0.5cm} - \setlength{\itemsep}{0pt} - \setlength{\parsep}{0pt} - \setlength{\topsep}{0pt} - \renewcommand{\makelabel}{}}} -{\end{list}} -\newenvironment{CompactItemize} -{ - \begin{itemize} - \setlength{\itemsep}{-3pt} - \setlength{\parsep}{0pt} - \setlength{\topsep}{0pt} - \setlength{\partopsep}{0pt} -} -{\end{itemize}} -\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp} -\newlength{\tmplength} -\newenvironment{TabularC}[1] -{ -\setlength{\tmplength} - {\linewidth/(#1)-\tabcolsep*2-\arrayrulewidth*(#1+1)/(#1)} - \par\begin{tabular*}{\linewidth} - {*{#1}{|>{\PBS\raggedright\hspace{0pt}}p{\the\tmplength}}|} -} -{\end{tabular*}\par} -\newcommand{\entrylabel}[1]{ - {\parbox[b]{\labelwidth-4pt}{\makebox[0pt][l]{\textbf{#1}}\\}}} -\newenvironment{Desc} -{\begin{list}{} - { - \settowidth{\labelwidth}{40pt} - \setlength{\leftmargin}{\labelwidth} - \setlength{\parsep}{0pt} - \setlength{\itemsep}{-4pt} - \renewcommand{\makelabel}{\entrylabel} - } -} -{\end{list}} -\newenvironment{Indent} - {\begin{list}{}{\setlength{\leftmargin}{0.5cm}} - \item[]\ignorespaces} - {\unskip\end{list}} -\setlength{\parindent}{0cm} -\setlength{\parskip}{0.2cm} -\addtocounter{secnumdepth}{1} -\sloppy -\usepackage[T1]{fontenc} diff --git a/org.glite.lb.doc/src/doxyhack.tex b/org.glite.lb.doc/src/doxyhack.tex deleted file mode 100644 index c628fcf..0000000 --- a/org.glite.lb.doc/src/doxyhack.tex +++ /dev/null @@ -1,47 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -% save previous definitions for use in new macros -\let\dsection=\section -\let\dsubsection=\subsection -\let\dsubsubsection=\subsubsection - -% change the sections definition to reflect the actual hierarchy -% - section is just one in each included file -\renewcommand{\section}[1]{\dsubsubsection{#1}} -% - subsections are for member section headings (constructors, data, ...) -\renewcommand{\subsection}[2]{\ifx*#1 -\dsubsubsection*{#2}\def\zbytek{} -\else -\dsubsubsection*{#1}\def\zbytek{#2}\fi -\zbytek} -% - subsubsections are for particular class members -\def\eatbraces#1]{} -\def\dosubsubsection#1{\par - \vskip 10pt\framebox{\begin{minipage}{\linewidth}{\hangindent=20pt\noindent\bf #1\par}\end{minipage}}\vskip-2pt} -\renewcommand{\subsubsection}[2]{\ifx*#1 - \dosubsubsection{#2}\def\zbytek{} -\else\ifx[#1 - \def\zbytek{\expandafter\dosubsubsection\eatbraces} -\else - \dosubsubsection{#1}\def\zbytek{#2} -\fi\fi -\zbytek} - -%\let\ddescription=\description -%\let\denddescription=\enddescription -%\renewenvironment{description}{\list{}{\labelwidth 5cm\leftmargin 3cm}}{\endlist} - diff --git a/org.glite.lb.doc/src/egee.cls b/org.glite.lb.doc/src/egee.cls deleted file mode 100644 index 9a7e524..0000000 --- a/org.glite.lb.doc/src/egee.cls +++ /dev/null @@ -1,452 +0,0 @@ -% egee.cls: -% -% $Id$ -% -\NeedsTeXFormat{LaTeX2e} -\ProvidesClass{egee}[2002/06/20 EGEE LaTeX Class] -\typeout{EGEE LaTeX class -- 2002/06/13 Rock Lobster!} -% -%% Notes: This class file tries, as largely as possible, to copy the Microsoft -%% Word template document EDMS 2098656 v2.2. Differences and notes are listed -%% below: -%% o The Word Template uses 11pt for the main body, but 12 point -%% occasionally. Any such occurrence of 12pt is mapped into 11pt in this -%% class-file. -%% o This class inherits 11pt article. In that class Huge=30pt and -%% LARGE=22pt, which matches the required point-size for the title page. -%% o The parskip in the Word doc is exactly 1.4mm (0.7mm above and below). -%% Here we've taken the liberty of adding some glue to make things fit -%% better. -%% o The Word Template shows all the (sub)sections on the contents page in -%% capitals and subsubsections in italics. The LateX class doesn't. - -%% Interface - example of an option, should we want to use these later. -%\newif\ifmonotitle\monotitlefalse - -%\DeclareOption{mono}{\monotitletrue} - -\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} -\ProcessOptions - - -% Inherit! -\LoadClass[11pt]{article} - -% Necessary packages: -\RequirePackage{lastpage} -\RequirePackage{tabularx} -\RequirePackage{pslatex} -\RequirePackage{times} -\RequirePackage{verbatim} -\RequirePackage{geometry} -\RequirePackage{url} - -\usepackage[hang,bf,small]{caption} - -% -% We now define a new \if command to test for PDF being enabled. -% It is important because loading graphicx overrides the definition -% of \pdfoutput and sets it to true even when PDF is not enabled. -% Use \ifpdf instead of \ifx\pdfoutput\undefined hereafter. -% - -\newif\ifpdf -\ifx\pdfoutput\undefined - \pdffalse - % \typeout{PDF _not_ defined} -\else - \pdfoutput=1 - \pdftrue - % \typeout{PDF _is_ defined} -\fi - -\ifpdf - \usepackage[pdftex, - pdfpagemode={UseOutlines},bookmarks=true,bookmarksopen=true, - bookmarksopenlevel=2,bookmarksnumbered=true, - hypertexnames=false,colorlinks,linkcolor={blue}, - citecolor={blue},urlcolor={red}, - pdfstartview={FitV}]{hyperref} -\else - \usepackage[hypertex]{hyperref} -\fi - -\ifpdf - \usepackage[pdftex]{graphicx} - \pdfcompresslevel 9 - \pdfadjustspacing 1 -\else - \usepackage[dvips]{graphicx} -\fi - -\usepackage{color} - -\def\footsize{5mm} - -%% -%% PAGE GEOMETRY DEFINITIONS -%% -% From Template file -\geometry{centering,includeheadfoot} -\geometry{a4paper,top=12.5mm,headheight=12.5mm,headsep=5mm,foot=\footsize,footskip=13.3mm,bottom=12.5mm} -\geometry{right=25mm,left=25mm} - - -% APM -- I don't think these are right, my impression is above is correct -%\geometry{a4paper,margin=0.98in,headheight=0.72in} - - -%% -%% PAGE COLOUR DEFINITIONS -%% -\definecolor{blue}{rgb}{0.1,0.1,0.5} -\definecolor{lightgrey}{gray}{0.65} - - -% paulm's prefered name ... -\def\bibname{References} - -\setlength{\parindent}{0pt} -\setlength{\parskip}{1.4mm plus 0.4mm minus 0.2mm} - -\def\@defaultfooter{ - \def\@oddfoot{\vbox to \footsize {% - {\color{blue}\hrule width \textwidth height 1pt depth 0pt}% - \vfil - \small\hbox to \textwidth{\ISTNumber% - \hfil - \hbox{\colorbox{yellow}{\MakeUppercase{\@Dissemination}}}% - \hfil - \hbox{\thepage/\pageref{LastPage}}}% - }% - }% -} - - -\def\ps@title{% - \@defaultfooter - \def\@oddhead{\hbox to \textwidth{\LargeEGEELogo\hfil\CESNETLogo\hfil\ISTLogo}} -} - -\def\ps@headings{% - \@defaultfooter - \def\@oddhead{\vbox to \headheight{% -%\hrule width \textwidth height 1pt\relax - \vbox to 0.75\headheight{% - \hbox to \textwidth{% - \hbox to 0pt{\EGEELogo\hss}% - \hfil - \hbox to 8cm{% - \vbox to 0.75\headheight{% - \vfil - \parbox{8cm}{% - \centering\color{blue}% - \textbf{\MakeUppercase{\@title}}% -\ifx\@Subtitle\@empty\else - \par\textbf{\scriptsize\@Subtitle}% -\fi - }% - \vfil - }% - \hss}% - \hfil -%\hbox to 0pt{\vrule width 1pt height 10pt depth 0pt \hss}% -%% {\scriptsize\setlength{\parskip}{0pt}\setlength{\topsep}{0pt}% -%% % \vbox to 0.75\headheight{% -%% \parbox{4cm}{x% -%% \begin{flushright}% -%% \textit{Doc. Identifier}:\\ -%% \textbf{\@DocIdentifier}\\ -%% \vfil -%% \textit{Date}: \textbf{\@Date} -%% \end{flushright}% -%% }% -%% % }% -%% }% -\hbox to 0pt{\hss\vbox to 0.75\headheight{%\hrule -\tiny%\scriptsize -\parfillskip0pt -\leftskip 0pt plus 1fil -\parskip0ex -\textit{Doc.\ Identifier}: -\par -\textbf{\@DocIdentifier} -\vfil -\textit{Date}: \textbf{\@Date} -%\hrule -}}% -% \hbox to 4cm{\scriptsize -% \vbox to 0.75\headheight{% -% \parbox{4cm}{ -% \halign{\hfill####\cr -% \textit{Doc. Identifier}:\cr -% \textbf{\@DocIdentifier}\cr -% % \noalign{\vfil} -% \textit{Date}: \textbf{\@Date}\cr -% }}% -% \vfil -% }% -% }% - }% - }% -%\hrule width \textwidth height 1pt\relax - \vfil\vskip 2.5mm\relax - {\color{blue}\hrule width \textwidth height 1pt depth 0pt}% - }% - }% -} - -\pagestyle{headings} - -\setlength{\captionmargin}{1cm} - -% image file extensions respective to the output format -\ifpdf - \DeclareGraphicsExtensions{.jpg,.pdf,.png} - \pdfcompresslevel=9 -% \pdfinfo{ /Title (\@DocumentLink) } - \pdfinfo{ /Title (EGEE) } -\else - \DeclareGraphicsExtensions{.eps} -\fi - -\def\frontboxwidth{12.6cm}% - - - -%% -%% Define our title page -%% -\AtBeginDocument{ -\pagestyle{title}% -\hbox{}% Force top of page -\vfill -{\centering -% \Huge\bf\textsf{\textcolor{blue}{EGEE}}\\[20mm]% - \gLiteLogo\\[20mm]% - \LARGE\sc\textsf{\bf \@title}\\[5mm]% - \ifx\@Subtitle\@empty\else - \normalsize\textsf{\@Subtitle}\\[10mm]% - \fi - \ifx\@DeliverableId\@empty\else - \LARGE\sc\textsf{\bf \@DeliverableId}\\[5mm]% - \fi -}% -\vfill -\hbox to \textwidth{ - \hfil - \vbox{ - {\color{blue}\hrule width \frontboxwidth height 1mm depth 0pt} - \hbox to \frontboxwidth{\sf - \begin{tabularx}{\frontboxwidth}{l>{\raggedright\arraybackslash}X} - Document identifier: & \textbf{\@DocIdentifier}\\[3mm] - Date: & \textbf{\@Date}\\[3mm] - Activity:& \textbf{\@Activity}\\[3mm] - Document status: & \textbf{\@DocStatus}\\[3mm] - Document link:& \textbf{\@DocumentLink}\\[3mm] - \end{tabularx} - } - {\color{blue}\hrule width \frontboxwidth height 1mm depth 0pt} - } -} -\vfill -{\sf\underline{Abstract}: \@Abstract} -\vfill -\newpage % end of the first page -\pagestyle{headings} -\setcounter{tocdepth}{3} -} % End of AtBeginningDocument - - -% -% EGEE style small-capital section titles. -% -% The numbering is aligned with the WinWord style, -% although it is not common in the english typography... -% -\newcommand{\sectionbreak}{\newpage} -\renewcommand{\thesection}{\arabic{section}.} -\renewcommand{\thesubsection}{\thesection\arabic{subsection}.} -\renewcommand{\thesubsubsection}{\thesubsection\arabic{subsubsection}.} - -\renewcommand\section{\@startsection {section}{1}{\z@}% - {-3.5ex \@plus -1ex \@minus -.2ex}% - {2.3ex \@plus.2ex}% - {\normalfont\Large\bfseries\sffamily\scshape}} - -\renewcommand\subsection{\@startsection{subsection}{2}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\normalfont\large\bfseries\sffamily\scshape}} -\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\normalfont\normalsize\bfseries\sffamily\scshape}} - - - -%% APM NEED TO REDEFINE section -%\titleformat{\section}{\Large\bfseries\sffamily\scshape}{\thesection}{1em}{} -%\titlecontents{section} [2em] {\vspace*{4pt}} -% {\large \sc \bfseries \contentslabel{2em}} -% {\large \sc \bfseries \hspace*{-2em}} -% {\large \textbf{\titlerule*[1ex]{.}\contentspage}} [\vspace*{4pt}] - -%\titleformat{\subsection}{\large\bfseries\sffamily\scshape}{\thesubsection}{1em}{} -%\titlecontents{subsection} [5em] {} -% {\sc \contentslabel{3em}} -% {\sc \hspace*{-3em}} -% {\titlerule*[1ex]{.}\contentspage} - - -% -% common constants -% -\def\ISTNumber{INFSO-RI-222667} -\newsavebox{\@EGEELogo} -\savebox{\@EGEELogo}{\includegraphics[height=0.75\headheight]{egee}} -\def\EGEELogo{\usebox{\@EGEELogo}} -\def\LargeEGEELogo{\includegraphics[height=\headheight]{egee}} -\def\ISTLogo{\includegraphics[height=\headheight]{isi}} -\def\gLiteLogo{\includegraphics[width=0.6\textwidth]{glite}} -\def\CESNETLogo{\includegraphics[height=\headheight]{cesnet}} - -% -% parameters to be supplied by the author -% -\def\Subtitle#1{\gdef\@Subtitle{#1}} -\gdef\@Subtitle{\@latex@warning@no@line{No \noexpand\Subtitle given}} - -\def\DeliverableId#1{\gdef\@DeliverableId{#1}} -\gdef\@DeliverableId{\@latex@warning@no@line{No \noexpand\DeliverableId given}} - -\def\DocIdentifier#1{\gdef\@DocIdentifier{#1}} -\gdef\@DocIdentifier{\@latex@warning@no@line{No \noexpand\DocIdentifier given % - (e.g. EGEE-JRA1-TEC-edmsId-v0-1)}} - -\def\Date#1{\gdef\@Date{#1}} -\gdef\@Date{\@latex@warning@no@line{No \noexpand\Date given % - (e.g. 01/01/2004)}} - -\def\Activity#1{\gdef\@Activity{#1}} -\gdef\@Activity{\@latex@warning@no@line{No \noexpand\Activity given % - (e.g. JRA1 Middleware Engineering and Integration )}} - -\def\DocStatus#1{\gdef\@DocStatus{#1}} -\gdef\@DocStatus{\@latex@warning@no@line{No \noexpand\DocStatus given % - (e.g. DRAFT, WORKING, DELIVERED)}} - -\def\Dissemination#1{\gdef\@Dissemination{#1}} -\gdef\@Dissemination{\@latex@warning@no@line{No \noexpand\Dissemination given % - (e.g. PUBLIC, INTERNAL, ...)}} - -\def\DocumentLink#1{\gdef\@DocumentLink{#1}} -\gdef\@DocumentLink{\@latex@warning@no@line{No \noexpand\DocumentLink given % - (e.g. http://cern.ch)}} - -\long\def\Abstract#1{\gdef\@Abstract{#1}} -\gdef\@Abstract{\@latex@warning@no@line{No \noexpand\Abstract given}} - -%% -%% Define the abstract using an environment abstract - -% -% This will produce the mailto link in the PDF file -% -% -% We use the URL package, which does this nicely. The old way (\HTTP) was -% a bit buggy as it had problems with '~'s and '_'s -% -\urlstyle{sf} -\ifpdf - \newcommand{\Email}[1]{\href{mailto:#1}{<{#1}>}} - \newcommand{\HTTP}[1]{\href{#1}{\url{#1}}} -\else - \newcommand{\Email}[1]{\textsf{<{#1}>}} - \newcommand{\HTTP}[1]{\url{#1}} -\fi - - -% -% We now redifine \part and \section so that the table of contents -% has the sections/parts in upper case. -% -% Note: need to use \uppercase because \MakeUppercase is not robust -% -\def\@part[#1]#2{% - \ifnum \c@secnumdepth >\m@ne - \refstepcounter{part}% - \addcontentsline{toc}{part}{\thepart\hspace{1em}\uppercase{#1}}% - \else - \addcontentsline{toc}{part}{\uppercase{#1}}% - \fi - {\parindent \z@ \raggedright - \interlinepenalty \@M - \normalfont - \ifnum \c@secnumdepth >\m@ne - \Large\bfseries \partname\nobreakspace\thepart - \par\nobreak - \fi - \huge \bfseries #2% - \markboth{}{}\par}% - \nobreak - \vskip 3ex - \@afterheading} - -\def\@sect#1#2#3#4#5#6[#7]#8{% - \ifnum #2>\c@secnumdepth - \let\@svsec\@empty - \else - \refstepcounter{#1}% - \protected@edef\@svsec{\@seccntformat{#1}\relax}% - \fi - \@tempskipa #5\relax - \ifdim \@tempskipa>\z@ - \begingroup - #6{% - \@hangfrom{\hskip #3\relax\@svsec}% - \interlinepenalty \@M #8\@@par}% - \endgroup - \csname #1mark\endcsname{\uppercase{#7}}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - \texorpdfstring{\uppercase{#7}}{#7}}% - \else - \def\@svsechd{% - #6{\hskip #3\relax - \@svsec #8}% - \csname #1mark\endcsname{\uppercase{#7}}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - \texorpdfstring{\uppercase{#7}}{#7}}}% - \fi - \@xsect{#5}} - -% \addcontentsline{toc} expands to \contentsline{NAME} -% which in turn expands to \l@NAME. So, to specify -% the table of contents, we must define \l@chapter, \l@section, -% \l@subsection, ... ; to specify the list of figures, we must define -% \l@figure; and so on. Most of these can be defined with the -% \@dottedtocline command, which produces a contents line with dots -% between the title and the page number. It works as follows: -% -% \@dottedtocline{LEVEL}{INDENT}{NUMWIDTH} -% LEVEL : An entry is produced only if LEVEL < or = value of -% 'tocdepth' counter. Note, \chapter is level 0, \section -% is level 1, etc. -% INDENT : The indentation from the outer left margin of the start of -% the contents line. -% NUMWIDTH : The width of a box in which the section number is to go, -% if TITLE includes a \numberline command. -% - -\def\l@part{\@dottedtocline{1}{4em}{2.0em}} -\def\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}} -\def\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}} -\def\l@paragraph{\@dottedtocline{4}{7.0em}{4.1em}} -\def\l@subparagraph{\@dottedtocline{5}{10em}{5em}} - diff --git a/org.glite.lb.doc/src/emi.cls b/org.glite.lb.doc/src/emi.cls deleted file mode 100644 index e51e47b..0000000 --- a/org.glite.lb.doc/src/emi.cls +++ /dev/null @@ -1,491 +0,0 @@ -% emi.cls: -% Branched from egee.cls 1.6 -% revision 2.0 [based on word template] -% Emidio Giorgio -- emidio.giorgio@ct.infn.it -% March 31, 2011 - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% License -% -% This work is licensed under Creative Commons Attribution-ShareAlike 3.0. -% http://creativecommons.org/licenses/by/3.0/ -% You are free: -% * to Share Ñ to copy, distribute and transmit the work -% * to Remix Ñ to adapt the work -% -% Under the following conditions: -% * Attribution. You must attribute the work in the manner specified by the author or licensor -% (but not in any way that suggests that they endorse you or your use of the work). -% * Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting -% work only under the same, similar or a compatible license. -% -% * For any reuse or distribution, you must make clear to others the license terms of this work. -% The best way to do this is with a link to this web page : http://creativecommons.org/licenses/by/3.0/ -% * Any of the above conditions can be waived if you get permission from the copyright holder. -% * Nothing in this license impairs or restricts the author's moral rights. -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\NeedsTeXFormat{LaTeX2e} -\ProvidesClass{emi}[2011/03/24 EMI LaTeX Class] -\typeout{EMI LaTeX class -- 2011/03/24} -% -%% Interface - example of an option, should we want to use these later. -%\newif\ifmonotitle\monotitlefalse - -%\DeclareOption{mono}{\monotitletrue} - -\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} -\ProcessOptions - - -% Inherit! -\LoadClass[11pt]{article} - -% Necessary packages: -\RequirePackage{lastpage} -\RequirePackage{tabularx} -\RequirePackage{pslatex} -\RequirePackage{times} -\RequirePackage{verbatim} -\RequirePackage{geometry} -\RequirePackage{url} - -\usepackage[hang,bf,small]{caption} -\usepackage[T1]{fontenc} -\usepackage[scaled]{helvet} -\usepackage{multirow} -\renewcommand*\familydefault{\sfdefault} -% -% We now define a new \if command to test for PDF being enabled. -% It is important because loading graphicx overrides the definition -% of \pdfoutput and sets it to true even when PDF is not enabled. -% Use \ifpdf instead of \ifx\pdfoutput\undefined hereafter. -% - -\newif\ifpdf -\ifx\pdfoutput\undefined - \pdffalse - % \typeout{PDF _not_ defined} -\else - \pdfoutput=1 - \pdftrue - % \typeout{PDF _is_ defined} -\fi - -\ifpdf - \usepackage[pdftex, - pdfpagemode={UseOutlines},bookmarks=true,bookmarksopen=true, - bookmarksopenlevel=0,bookmarksnumbered=true, - hypertexnames=false,colorlinks,linkcolor={blue}, - citecolor={blue},urlcolor={red}, - pdfstartview={FitV}]{hyperref} -\else - \usepackage[hypertex]{hyperref} -\fi - -\ifpdf - \usepackage[pdftex]{graphicx} - \pdfcompresslevel 9 - \pdfadjustspacing 1 -\else - \usepackage[dvips]{graphicx} -\fi - -\usepackage{color} - -\def\footsize{5mm} - -%% -%% PAGE GEOMETRY DEFINITIONS -%% -% From Template file -\geometry{centering,includeheadfoot} -%\geometry{a4paper,top=12.5mm,headheight=12.5mm,headsep=5mm,foot=\footsize,footskip=13.3mm,bottom=12.5mm} -\geometry{a4paper,top=15.5mm,headheight=20mm,headsep=5mm,foot=\footsize,footskip=13.3mm,bottom=12.5mm} -\geometry{right=25mm,left=25mm} - - - -% APM -- I don't think these are right, my impression is above is correct -%\geometry{a4paper,margin=0.98in,headheight=0.72in} - - -%% -%% PAGE COLOUR DEFINITIONS -%% - - - -% paulm's prefered name ... -\def\bibname{References} - -\setlength{\parindent}{0pt} -\setlength{\parskip}{1.4mm plus 0.4mm minus 0.2mm} - -\def\@defaultfooter{ - \def\@oddfoot{\vbox to \footsize {% - {\color{blue}\hrule width \textwidth height 1pt depth 0pt}% - \vfil - %\small\hbox to \textwidth{\ISTNumber% - \small\hbox to \textwidth{% - %\hfil - %\hbox{\colorbox{yellow}{\MakeUppercase{\@Dissemination}}}% - \hfil - \hbox{\thepage/\pageref{LastPage}}}% - }% - }% -} - - -\def\ps@title{% - \@defaultfooter - \def\@oddhead{\hbox to \textwidth{\EMILogo\hfil\LargeCESNETLogo}} -} - -\def\ps@headings{% - \@defaultfooter - \def\@oddhead{\vbox to \headheight{% -%\hrule width \textwidth height 1pt\relax - \vbox to 0.75\headheight{% - \hbox to \textwidth{% - \hbox to 0pt{\EMILogo\hss}% - \hfil - -%% \hbox to 8cm{% -%% \vbox to 0.75\headheight{% -%% \vfil -%% \parbox{8cm}{% -%% \centering\color{blue}% -%% \textbf{\MakeUppercase{\@title}}% -%% %\ifx\@Subtitle\@empty\else -%% % \par\textbf{\scriptsize\@Subtitle}% -%% %\fi -%% }% -%% \vfil -%% }% -%% \hss}% - - \hfil -%\hbox to 0pt{\vrule width 1pt height 10pt depth 0pt \hss}% -%% {\scriptsize\setlength{\parskip}{0pt}\setlength{\topsep}{0pt}% -%% % \vbox to 0.75\headheight{% -%% \parbox{4cm}{x% -%% \begin{flushright}% -%% \textit{Doc. Identifier}:\\ -%% \textbf{\@DocIdentifier}\\ -%% \vfil -%% \textit{Date}: \textbf{\@Date} -%% \end{flushright}% -%% }% -%% % }% -%% }% - -\hbox to 0pt{\hss\vbox to 0.75\headheight{%\hrule -\small -\parfillskip0pt -\leftskip 0pt plus 1fil -\parskip0ex -\textsc{Title}: -\par -\textbf{\@title} - - -\textit{Date}: \textbf{\@Date} -\vfil -%\hrule -}}% -% \hbox to 4cm{\scriptsize -% \vbox to 0.75\headheight{% -% \parbox{4cm}{ -% \halign{\hfill####\cr -% \textit{Doc. Identifier}:\cr -% \textbf{\@DocIdentifier}\cr -% % \noalign{\vfil} -% \textit{Date}: \textbf{\@Date}\cr -% }}% -% \vfil -% }% -% }% - }% - }% -%\hrule width \textwidth height 1pt\relax - \vfil\vskip 2.5mm\relax - {\color{blue}\hrule width \textwidth height 1pt depth 0pt}% - }% - }% -} - -\pagestyle{headings} - -\setlength{\captionmargin}{1cm} - -% image file extensions respective to the output format -\ifpdf - \DeclareGraphicsExtensions{.jpg,.pdf,.png} - \pdfcompresslevel=9 - \pdfinfo{ /Title (EMI) } -\else - \DeclareGraphicsExtensions{.eps} -\fi - -\def\frontboxwidth{11cm}% - -\definecolor{MyTeal}{rgb}{0,0.46,0.46} -\definecolor{blue}{rgb}{0.05,0.26,0.5} -%\definecolor{blue}{rgb}{0.1,0.1,0.5} %% egee blue -\definecolor{lightgrey}{gray}{0.65} - -%% -%% Define our title page -%% -\AtBeginDocument{ -\pagestyle{title}% -\hbox{}% Force top of page -\vfill -{\centering - \fontsize{30}{50}{\textbf{\textsc{\textcolor{blue}{European Middleware Initiative}}}}\\[40mm]% - %\Huge{\textbf{\textsc{\textcolor{blue}{European Middleware Initiative}}}}\\[20mm]% - - \fontsize{22}{28}{\textbf{\textsc{\@title}}}\\[2mm]% - %\ifx\@Subtitle\@empty\else - % \normalsize\textsf{\@Subtitle}\\[10mm]% - %\fi -} -\vfill - -\begin{center} -\hbox to \textwidth{ - - \vbox{ - - {\color{MyTeal}\hrule width \frontboxwidth height 1mm depth 0pt} - - \hbox to \frontboxwidth{\sf - \begin{tabularx}{\frontboxwidth}{l>{\raggedright\arraybackslash}X} -\\ - Document version: & \textbf{\@DocVersion}\\[3mm] - EMI Component Version: & \textbf{\@EMICompVersion}\\[3mm] - Date: & \textbf{\@Date}\\[3mm] - %Document status: & \textbf{\@DocStatus}\\[3mm] - - \end{tabularx} - - } - - {\color{MyTeal}\hrule width \frontboxwidth height 1mm depth 0pt} - %}%centering - } - -} -\end{center} - -%\vfill -%{\sf\underline{Abstract}: \@Abstract} -\vfill -\newpage % end of the first page -\pagestyle{headings} -\setcounter{tocdepth}{3} -} % End of AtBeginningDocument - - -% -% EMI style small-capital section titles. -% -% The numbering is aligned with the WinWord style, -% although it is not common in the english typography... -% -\newcommand{\sectionbreak}{\newpage} -%\renewcommand{\thesection}{\arabic{section}.} -%\renewcommand{\thesubsection}{\thesection\arabic{subsection}.} -%\renewcommand{\thesubsubsection}{\thesubsection\arabic{subsubsection}.} - -\renewcommand\section{\@startsection {section}{1}{\z@}% - {-3.5ex \@plus -1ex \@minus -.2ex}% - {2.3ex \@plus.2ex}% - {\normalfont\Large\bfseries\sffamily\scshape}} - -\renewcommand\subsection{\@startsection{subsection}{2}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\normalfont\large\bfseries\sffamily\scshape}} -\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\normalfont\normalsize\bfseries\sffamily\scshape}} - - - -%% APM NEED TO REDEFINE section -%\titleformat{\section}{\Large\bfseries\sffamily\scshape}{\thesection}{1em}{} -%\titlecontents{section} [2em] {\vspace*{4pt}} -% {\large \sc \bfseries \contentslabel{2em}} -% {\large \sc \bfseries \hspace*{-2em}} -% {\large \textbf{\titlerule*[1ex]{.}\contentspage}} [\vspace*{4pt}] - -%\titleformat{\subsection}{\large\bfseries\sffamily\scshape}{\thesubsection}{1em}{} -%\titlecontents{subsection} [5em] {} -% {\sc \contentslabel{3em}} -% {\sc \hspace*{-3em}} -% {\titlerule*[1ex]{.}\contentspage} - - -% -% common constants -% -%\def\ISTNumber{INFSO-RI-508833} -\newsavebox{\@EMILogo} -%\savebox{\@EMILogo}{\includegraphics[height=0.75\headheight]{EMI_Logo_std}} -\savebox{\@EMILogo}{\includegraphics[height=0.95\headheight]{EMI_Logo_std}} -\def\EMILogo{\usebox{\@EMILogo}} -%\def\LargeEMILogo{\includegraphics[height=\headheight]{EMI_Logo_std}} -\def\SmallEMILogo{\includegraphics[height=\headheight]{EMI_Logo_std}} -\def\LargeCESNETLogo{\includegraphics[height=\headheight]{cesnet}} -% DEL \def\ISTLogo{\includegraphics[height=\headheight]{isi}} - -% -% parameters to be supplied by the author -% -% EG : subtitle seems no more needed -%\def\Subtitle#1{\gdef\@Subtitle{#1}} -%\gdef\@Subtitle{\@latex@warning@no@line{No \noexpand\Subtitle given}} - -%\def\DeliverableId#1{\gdef\@DeliverableId{#1}} -%\gdef\@DeliverableId{\@latex@warning@no@line{No \noexpand\DeliverableId given}} - - -\def\DocVersion#1{\gdef\@DocVersion{#1}} -\gdef\@DocVersion{\@latex@warning@no@line{No \noexpand\DocVersion given % - (e.g. 0.1.2)}} - -\def\EMICompVersion#1{\gdef\@EMICompVersion{#1}} -\gdef\@EMICompVersion{\@latex@warning@no@line{No \noexpand\EMICompVersion given % - (e.g. 1.2.3)}} - -\def\Date#1{\gdef\@Date{#1}} -\gdef\@Date{\@latex@warning@no@line{No \noexpand\Date given % - (e.g. 01/04/2010)}} - -%\def\Activity#1{\gdef\@Activity{#1}} -%\gdef\@Activity{\@latex@warning@no@line{No \noexpand\Activity given % -% (e.g. NA2 Dissemination and Outreach )}} - -%\def\LeadPartner#1{\gdef\@LeadPartner{#1}} -%\gdef\@LeadPartner{\@latex@warning@no@line{No \noexpand\LeadPartner given % -% (e.g. CERN, RAL )}} - -%\def\DocStatus#1{\gdef\@DocStatus{#1}} -%\gdef\@DocStatus{\@latex@warning@no@line{No \noexpand\DocStatus given % -% (e.g. DRAFT, WORKING, DELIVERED)}} - -%\def\Dissemination#1{\gdef\@Dissemination{#1}} -%\gdef\@Dissemination{\@latex@warning@no@line{No \noexpand\Dissemination given % -% (e.g. PUBLIC, INTERNAL, ...)}} - - -\long\def\Abstract#1{\gdef\@Abstract{#1}} -\gdef\@Abstract{\@latex@warning@no@line{No \noexpand\Abstract given}} - -%% -%% Define the abstract using an environment abstract - -% -% This will produce the mailto link in the PDF file -% -% -% We use the URL package, which does this nicely. The old way (\HTTP) was -% a bit buggy as it had problems with '~'s and '_'s -% -\urlstyle{sf} -\ifpdf - \newcommand{\Email}[1]{\href{mailto:#1}{<{#1}>}} - \newcommand{\HTTP}[1]{\href{#1}{\url{#1}}} -\else - \newcommand{\Email}[1]{\textsf{<{#1}>}} - \newcommand{\HTTP}[1]{\url{#1}} -\fi - - -% -% We now redifine \part and \section so that the table of contents -% has the sections/parts in upper case. -% -% Note: need to use \uppercase because \MakeUppercase is not robust -% -\def\@part[#1]#2{% - \ifnum \c@secnumdepth >\m@ne - \refstepcounter{part}% - \addcontentsline{toc}{part}{\thepart\hspace{1em}\uppercase{#1}}% - \else - \addcontentsline{toc}{part}{\uppercase{#1}}% - \fi - {\parindent \z@ \raggedright - \interlinepenalty \@M - \normalfont - \ifnum \c@secnumdepth >\m@ne - \Large\bfseries \partname\nobreakspace\thepart - \par\nobreak - \fi - \huge \bfseries #2% - \markboth{}{}\par}% - \nobreak - \vskip 3ex - \@afterheading} - -\def\@sect#1#2#3#4#5#6[#7]#8{% - \ifnum #2>\c@secnumdepth - \let\@svsec\@empty - \else - \refstepcounter{#1}% - \protected@edef\@svsec{\@seccntformat{#1}\relax}% - \fi - \@tempskipa #5\relax - \ifdim \@tempskipa>\z@ - \begingroup - #6{% - \@hangfrom{\hskip #3\relax\@svsec}% - \interlinepenalty \@M #8\@@par}% - \endgroup - \csname #1mark\endcsname{\uppercase{#7}}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - \texorpdfstring{\uppercase{#7}}{#7}}% - \else - \def\@svsechd{% - #6{\hskip #3\relax - \@svsec #8}% - \csname #1mark\endcsname{\uppercase{#7}}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - \texorpdfstring{\uppercase{#7}}{#7}}}% - \fi - \@xsect{#5}} - -% \addcontentsline{toc} expands to \contentsline{NAME} -% which in turn expands to \l@NAME. So, to specify -% the table of contents, we must define \l@chapter, \l@section, -% \l@subsection, ... ; to specify the list of figures, we must define -% \l@figure; and so on. Most of these can be defined with the -% \@dottedtocline command, which produces a contents line with dots -% between the title and the page number. It works as follows: -% -% \@dottedtocline{LEVEL}{INDENT}{NUMWIDTH} -% LEVEL : An entry is produced only if LEVEL < or = value of -% 'tocdepth' counter. Note, \chapter is level 0, \section -% is level 1, etc. -% INDENT : The indentation from the outer left margin of the start of -% the contents line. -% NUMWIDTH : The width of a box in which the section number is to go, -% if TITLE includes a \numberline command. -% - -\def\l@part{\@dottedtocline{1}{4em}{2.0em}} -\def\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}} -\def\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}} -\def\l@paragraph{\@dottedtocline{4}{7.0em}{4.1em}} -\def\l@subparagraph{\@dottedtocline{5}{10em}{5em}} - diff --git a/org.glite.lb.doc/src/events.tex.T b/org.glite.lb.doc/src/events.tex.T deleted file mode 100644 index 29748fa..0000000 --- a/org.glite.lb.doc/src/events.tex.T +++ /dev/null @@ -1,35 +0,0 @@ -@@@{ -gen qq{ -% !! Automatically generated file. Do not edit. -% !! Change the corresponding template file $ARGV -}; -@@@} - -\subsection*{Events for gLite world:} - -\begin{tabularx}{\textwidth}{l>{\bfseries}lX} -@@@{ -my $flesh = 'gLite'; #XXX -my $fleshno = 0; -my $eventno = $fleshno; -for my $e (sort { $event->{order}->{$a} <=> $event->{order}->{$b} } - $event->getTypes) { - my $u = uc $e; - my $c = getTypeComment $event $e; - - if ($flesh ne $event->{flesh}->{$e}) { - $flesh = $event->{flesh}->{$e}; - gen "\\end{tabularx}\n\n"; - gen "\\subsection*{Events for $flesh world:}\n\n"; - gen "\\begin{tabularx}{\\textwidth}{l>{\\bfseries}lX}\n"; - $fleshno += 100; - $eventno = $fleshno; - } - $eventno++; - gen "$eventno. \& $e: \& $c \\\\ \n"; -} -@@@} -\end{tabularx} - -\endinput - diff --git a/org.glite.lb.doc/src/faq.tex b/org.glite.lb.doc/src/faq.tex deleted file mode 100644 index a9a7927..0000000 --- a/org.glite.lb.doc/src/faq.tex +++ /dev/null @@ -1,96 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% - -\section{FAQ---Frequently Asked Questions} -\label{s:faq} - -\subsection{Job in State `Running' Despite Having Received the `Done' Event from LRMS} - -Jobs stay in state \emph{Running} until a \emph{Done} event is received from the workload management system. \emph{Done} events from local resource managers are not enough since the job in question may have been resubmitted in the meantime. - -\subsection{WMS Cannot Purge Jobs or Perform Other Privileged Tasks} -\label{FAQ:WMS_superusers} - -In short, WMS has not been given adequate permissions when configuring the \LB server. You need to modify your configuration and restart the server: - -\subsubsection{For \LBver {3.0.11 or higher}, using YAIM} -\label{FAQ:WMS_superusers_3_0_11} -Modify your \texttt{siteinfo.def}, specifying the DN of your WMS server in YAIM parameter \texttt{GLITE\_LB\_WMS\_DN}; for instance: - -\begin{center} -\texttt{GLITE\_LB\_WMS\_DN=/DC=cz/DC=cesnet-ca/O=CESNET/CN=wms01.cesnet.cz} -\end{center} - -Then rerun YAIM: -\texttt{/opt/glite/yaim/bin/yaim -c -s site-info.def -n glite-LB} - - This will give your WMS exactly the right permissions to carry out all required operations. - -\subsubsection{For all versions of \LB, using YAIM} - -Modify your \texttt{siteinfo.def}, specifying the DN of your WMS server in YAIM parameter \texttt{GLITE\_LB\_SUPER\_USERS}; for instance: - -\begin{center} -\texttt{GLITE\_LB\_SUPER\_USERS=/DC=cz/DC=cesnet-ca/O=CESNET/CN=wms01.cesnet.cz} -\end{center} - -Then rerun YAIM: -\texttt{/opt/glite/yaim/bin/yaim -c -s site-info.def -n glite-LB} - -This will give your WMS adequate rights to perform its operations and requests (running purge, querying for statistics, etc.) but it will also grant it additional administrator rights (such as granting job ownership). On newer installations, the method explained in section \ref{FAQ:WMS_superusers_3_0_11} is preferable. - -\subsubsection{For \LBver {2.1 or higher}, without YAIM} - -\LB{}'s authorization settings can be found in file \texttt{[/opt/glite]/etc/glite-lb/glite-lb-authz.conf} - -Permit actions \texttt{PURGE}, \texttt{READ\_ALL} and \texttt{GET\_STATISTICS} for your WMS and restart the \LB server. -This will lead to results equivalent to \ref{FAQ:WMS_superusers_3_0_11}. -For instance, change the adequate sections in \texttt{glite-lb-authz.conf} to: - -\begin{verbatim} -action "READ_ALL" { - rule permit { - subject = "/DC=cz/DC=cesnet-ca/O=CESNET/CN=wms01.cesnet.cz" - } -} - -action "PURGE" { - rule permit { - subject = "/DC=cz/DC=cesnet-ca/O=CESNET/CN=wms01.cesnet.cz" - } -} - -action "GET_STATISTICS" { - rule permit { - subject = "/DC=cz/DC=cesnet-ca/O=CESNET/CN=wms01.cesnet.cz" - } -} -\end{verbatim} - -\subsection{\LB Server Throws ``Duplicate entry~\dots~for key~1'' Errors} - -The \LB server will occasionally report errors through \emph{syslog} saying, - -\begin{verbatim} -ERROR CONTROL - ... : File exists (Duplicate entry '...' for key 1) -\end{verbatim} - -These error messages are caused by certain portions of code that take care of storing database records for keys, which may or may not already exist in the database, and do so by trying to insert the record first (hence the key violation) and modify the record if the insert fails. This has the unfortunate side effect of the unsuccessful insert being reported as an \texttt{ERROR} in the logging output. - -Unless you are experiencing trouble with the specific data entity\footnote{Usually a \emph{Job~ID}} referenced in the error message, it is safe to disregard. - - diff --git a/org.glite.lb.doc/src/frontmatter.tex b/org.glite.lb.doc/src/frontmatter.tex deleted file mode 100644 index f603d03..0000000 --- a/org.glite.lb.doc/src/frontmatter.tex +++ /dev/null @@ -1,59 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\begin{center} -{\bf Delivery Slip} -\end{center} -\begin{tabularx}{\textwidth}{|l|l|l|X|X|} -\hline - & {\bf Name} & {\bf Partner} & {\bf Date} & {\bf Signature} \\ -\hline -{\bf From} & Ale\v{s} K\v{r}enek & CESNET & August 1, 2008 & \\ -\hline -{\bf Reviewed by} & & & & \\ - -\hline -{\bf Approved by} & & & & \\ -\hline -\end{tabularx} - -\begin{center} -{\bf Document Change Log} -\end{center} - -\begin{tabularx}{\textwidth}{|l|l|X|X|} -\hline -{\bf Issue } & {\bf Date } & {\bf Comment } & {\bf Author } \\ \hline -Initial version & August 1, 2008 & & CESNET team \\ \hline -Reviewer's comments &&& \\ \hline -Users' comments &&& \\ - -\hline -\end{tabularx} - -\begin{center} -{\bf Document Change Record} -\end{center} - -\begin{tabularx}{\textwidth}{|l|l|X|} -\hline -{\bf Issue } & {\bf Item } & {\bf Reason for Change } \\ \hline - -\hline -\end{tabularx} - -\input{copyright} -\clearpage diff --git a/org.glite.lb.doc/src/funding.tex b/org.glite.lb.doc/src/funding.tex deleted file mode 100644 index 2db506b..0000000 --- a/org.glite.lb.doc/src/funding.tex +++ /dev/null @@ -1 +0,0 @@ -This work is co-funded by the European Commission as part of the EMI project under Grant Agreement INFSO-RI-261611. diff --git a/org.glite.lb.doc/src/https_configuration.tex b/org.glite.lb.doc/src/https_configuration.tex deleted file mode 100644 index 2959e12..0000000 --- a/org.glite.lb.doc/src/https_configuration.tex +++ /dev/null @@ -1,31 +0,0 @@ -\subsubsection{Reading \LB Server Configuration over HTTPs} - -As of \LBver{3.0}, it is also possible to use the HTTPs interface to retrieve essential information on \LB Server configuration. For example: -\begin{verbatim} - firefox https://pelargir.ics.muni.cz:9000/?configuration -\end{verbatim} - -Among others, the following fields may be discerned from the URL: - -\begin{tabularx}{\textwidth}{lX} -\label{s:findbroker} -\texttt{msg\_brokers} & A list of messaging brokers that \LB server uses to deliver messages.\\ -\texttt{msg\_prefixes} & A list of permissible prefixes that must be used in messaging topics.\\ -\texttt{server\_version} & Version of the \LB server binary.\\ -\texttt{server\_identity} & The subject of the \LB server's certificate.\\ -\texttt{server\_indices} & Indices configured in the the \LB server's database. \ifx\insideAG\undefined{\LB job queries typically require at least one indexed attribute among the query conditions}\else{See more on managing indices in Section~\ref{maintain:index} (page \pageref{maintain:index})}\fi. -\\ -\end{tabularx} - -Configuration details shown only to \LB super users: -\nopagebreak - -\begin{tabularx}{\textwidth}{lX} -\texttt{database\_name} & Name of database storing \LB data.\\ -\texttt{database\_host} & Database server used by \LB.\\ -\texttt{authz\_policy\_file} & Full copy of the current authz configuration file.\ifx\insideAG\undefined{}\else{ See more on defining the authorization policy in Section~\ref{inst:authz} (page \pageref{inst:authz}).}\fi\\ -\texttt{admins} & A list of DNs that are allowed super-user access. The list will include superusers given in the authz file as well as those specified from command line through the \texttt{-{}-super-user} option.\\ -\texttt{dump\_start} & Starting time of the latest server dump.\ifx\insideAG\undefined{}\else{See more on backup dumps in Section~\ref{run:dump} (page \pageref{run:dump}).}\fi\\ -\texttt{dump\_end} & Finishing time of the latest server dump.\\ -\end{tabularx} - diff --git a/org.glite.lb.doc/src/images/EMI_Logo_std.pdf b/org.glite.lb.doc/src/images/EMI_Logo_std.pdf deleted file mode 100644 index 2e79001001bf2dba006668ab874cc789e55c7219..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34764 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 diff --git a/org.glite.lb.doc/src/images/LB-components-LB-WMS.pdf b/org.glite.lb.doc/src/images/LB-components-LB-WMS.pdf deleted file mode 100755 index 52b83a5ae5a22568ba58c6884523b279768d22cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84385 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� 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 diff --git a/org.glite.lb.doc/src/images/LB-components-gather.pdf b/org.glite.lb.doc/src/images/LB-components-gather.pdf deleted file mode 100644 index 479548860df6aa808d48cc23d6c989064044f7c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48193 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 Lmz2~o(PjTXc4aw@ diff --git a/org.glite.lb.doc/src/images/LB-components.pdf b/org.glite.lb.doc/src/images/LB-components.pdf deleted file mode 100755 index d2dd3e54e6b75e1340d43e0e410a4a33c64fc7a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93972 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 A82|tP diff --git a/org.glite.lb.doc/src/images/cesnet.pdf b/org.glite.lb.doc/src/images/cesnet.pdf deleted file mode 100644 index 9b07738d8c962af32dcfad0e592bba658aff31e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4518 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 diff --git a/org.glite.lb.doc/src/images/egee.pdf b/org.glite.lb.doc/src/images/egee.pdf deleted file mode 100644 index 1314c4130d6919d140a58db7bb31dc4b7458c013..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 449747 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

rqYt<)4I3yKrvD#M(mV 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 diff --git a/org.glite.lb.doc/src/images/isi.pdf b/org.glite.lb.doc/src/images/isi.pdf deleted file mode 100644 index 4ff331cbe7bf18fb7ded3fc20ca7e25c9d9ca6ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19672 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 F!e4Asw7LKQ diff --git a/org.glite.lb.doc/src/images/seqtree.pdf b/org.glite.lb.doc/src/images/seqtree.pdf deleted file mode 100644 index 33ea80248b0aeb7757fc150e6c22a6d5ce2d68b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5715 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 Dp0uyF diff --git a/org.glite.lb.doc/src/images/wms2-jobstat.pdf b/org.glite.lb.doc/src/images/wms2-jobstat.pdf deleted file mode 100644 index fb3464807c597633804ac29c6f9a35a1e34a40fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7328 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 diff --git a/org.glite.lb.doc/src/lbjp.bib b/org.glite.lb.doc/src/lbjp.bib deleted file mode 100644 index f92fa1b..0000000 --- a/org.glite.lb.doc/src/lbjp.bib +++ /dev/null @@ -1,780 +0,0 @@ - -@InProceedings{ condor, - author = "Michael Litzkow and Miron Livny and Matthew Mutka", - title = "{C}ondor - A Hunter of Idle Workstations", - booktitle = "Proceedings of the 8th International Conference of - Distributed Computing Systems", - year = "1988", - month = "June" -} - -@InProceedings{ gram, - author = "K. Czajkowski and I. Foster and N. Karonis and C. - Kesselman and Martin S. Smith and S. Tuecke", - title = "A resource management architecture for metacomputing - systems.", - booktitle = "Proceedings of the IPPS/SPDP Workshop on Job Scheduling - Strategies for Parallel Processing", - year = "1988", - pages = "62-82" -} - -@InProceedings{ lsf, - author = "S. Zhou", - title = "LSF: Load sharing in large-scale heterogenous distributed - systems", - booktitle = "Proceedings of the Workshop on Cluster Computing", - year = "1992" -} - -@Misc{ dce, - author = "Open Group CAE Specification", - title = "DCE: Remote Procedure Call", - howpublished = "ISBN 1-85912-041-5", - year = "1994" -} - -@Misc{ pbs, - author = "Henderson, R. and Tweten, D", - title = "Portable Batch System: External reference Specification", - howpublished = "NASA, Ames Research Center", - year = "1996" -} - -@Article{ globus, - author = "I. Foster and C. Kesselman", - title = "Globus: a metacomputing infrastructure toolkit.", - journal = "International Journal of Supercomputer Applications", - year = "1997", - volume = "11", - number = "2", - pages = "115-128" -} - -@Misc{ ulm, - author = "J. Abela and T. Debeaupuis", - title = "Universal Format for Logger Messages", - howpublished = "IETF Internet Draft", - year = "1997" -} - -@InProceedings{ autopilot, - author = "R.L. Ribler and J.S. Vetter and H. Simitci and D.A. Reed", - title = "Autopilot: adaptive control of distributed applications", - booktitle = "Proceedings of the Seventh IEEE Symposium on - High-Performance Distributed Computing", - year = "1998", - pages = "172-179" -} - -@InProceedings{ gsi, - author = "I. Foster and C. Kesselman and G. Tsudik and S. Tuecke", - title = "{A Security Architecture for Computational Grids}", - booktitle = "Proceedings of the 5th ACM Conference on Computer and - Communications Security Conference", - year = 1998, - pages = "83-92" -} - -@InProceedings{ classad, - author = "Rajesh Raman and Miron Livny and Marvin Solomon", - title = "Matchmaking: Distributed Resource Management for High - Throughput Computing", - booktitle = "Proceedings of the Seventh IEEE International Symposium on - High Performance Distributed Computing", - year = "1998" -} - -@Article{ nws, - author = "R.Wolski and N. Spring and J. Hayes", - title = "The network weather service: a distributed resource - performance forecasting service for metacomputing", - journal = "J. Future Generation Comput. Syst.", - year = "1999", - volume = "15", - number = "(5/6)", - pages = "757-768" -} - -@Misc{ tls, - author = "T. Dierks and C. Allen", - title = "The {TLS} {P}rotocol {V}ersion 1.0", - howpublished = "IETF RFC 2246 (Standards Track)", - year = 1999, - month = "January" -} - -@Misc{ gssapi, - author = "{J. Linn}", - title = "{Generic Security Service Application Program Interface - Version 2, Update 1}", - howpublished = "IETF RFC 2743", - year = "2000", - month = "January" -} - -@TechReport{ lbdraft, - author = {M. Ruda and A. Krenek and L. Matyska and J. Pospisil and - M. Vocu and J. Sitera}, - title = {Logging and bookkeeping architecture}, - institution = {EU DataGrid}, - year = {2001}, - note = {Part of Deliverable D1.1 WP1 Report on current - technology} -} - -@InProceedings{ mds2, - author = "K. Czajkowski and S. Fitzgerald and I. Foster and C. - Kesselman.", - title = "Grid Information Services for Distributed Resource - Sharing.", - booktitle = " Proceedings of the Tenth IEEE International Symposium on - High-Performance Distributed Computing (HPDC-10)", - year = "2001", - month = "August", - publisher = "IEEE Press" -} - -@Misc{ gma, - author = "B. Tierney and R. Aydt and D. Gunter and W. Smith and - Valerie Taylor and R. Wolski and M. Swany.", - title = "A Grid Monitoring Service Architecture.", - howpublished = "Global Grid Forum Performance Working Group", - year = "2001" -} - -@Misc{ rgma, - author = "S. Fisher", - title = "Relational Model for Information and Monitoring", - howpublished = "Technical Report GWD-Perf-7-1, GGF", - year = "2001" -} - -@InProceedings{ mercury, - author = "Zoltan Balaton and Peter Kacsuk and Norbert Podhorszki and - Ferenc Vajda.", - title = "From Cluster Monitoring to Grid Monitoring Based on GRM", - booktitle = "In proceedings 7th EuroPar2001 Parallel Processings, - Manchester, UK.", - year = "2001", - pages = "874-881" -} - -@Article{ siena, - author = "Antonio Carzaniga and others", - title = "Design and evaluation of a wide-area event notification - service", - journal = "ACM Transactions on Computer Systems", - year = "2001", - volume = "19", - number = "3", - pages = "332-383" -} - -@InProceedings{ maui, - author = "D. Jackson and Q. Snell and M. Clement", - title = "Core algorithms of the Maui scheduler", - booktitle = "Proceedings of the 7th Workshop on Job Scheduling - Strategies for Parallel Processing", - year = "2001" -} - -@Misc{ ggfxml, - author = "W. Smith and D. Gunther and D. Quesnel", - title = "A simple xml producer-consumer protocol", - howpublished = "Grid Working Document GWD-Perf-8-2, Global Grid Forum, - Performance Working Group", - year = "2001" -} - -@TechReport{ lbdraft2, - author = {M. Ruda and A. Krenek and L. Matyska and J. Pospisil and - M. Vocu and J. Sitera}, - title = {Logging and bookkeeping architecture for {D}ata{G}rid - {R}elease 2}, - institution = {EU DataGrid}, - year = {2002}, - note = {Part of Deliverable D1.2 Definition of architecture, - technical plan and evaluation criteria for scheduling, - resource management, security and job description} -} - -@InProceedings{ code, - author = "W. Smith", - title = "A System for Monitoring and Management of Computational - Grids.", - booktitle = "In Proceedings of the 2002 International Conference on - Parallel Processing", - year = "2002" -} - -@Misc{ hawkeye, - title = "HawkEye: A Monitoring and Management Tool for Distributed - Systems", - howpublished = "\url{http://www.cs.wisc.edu/condor/hawkeye}", - year = "2002" -} - -@InProceedings{ chep03, - author = {G. Avellino et.al.}, - title = {{The first deployment of workload management services on - the EU DataGrid testbed: feedback on design and - implementation}}, - booktitle = {Computing in High Energy and Nuclear Physics (CHEP03)}, - year = {2003}, - note = {La Jolla, Ca, USA, March 2003}, - fauthor = {G. Avellino, S. Beco, B. Cantalupo, F. Pacini, A. - Terracina, A. Maraschini, D. Colling, S. Monforte, M. - Pappalardo, L. Salconi, F. Giacomini, E. Ronchieri, D. - Kouril, A. Krenek, L. Matyska, M. Mulac, J. Pospisil, M. - Ruda, Z. Salvet, J. Sitera, M. Vocu, M. Mezzadri, F. Prelz, - A. Gianelle, R. Peluso, M. Sgaravatto, S. Barale, A. - Guarise, A. Werbrouck} -} - -@Article{ alien, - author = "P. Saiz and others", - title = "{AliEn - ALICE environment on the GRID}", - journal = "{Nuclear Instruments and Methods in Physics Research, - Section A}", - year = "2003", - volume = "502", - number = "2-3", - pages = "437-440", - fauthor = { P. Saiz, L. Aphecetche, P. Buncic, R. Piskac, J.E. - Revsbech, V. Sego} -} - -@InProceedings{ rgma2, - author = "A. Cooke and others", - title = "R-GMA: An information integration system for grid - monitoring", - booktitle = "Proc. of the 11th International Conference on Cooperative - Information Systems", - year = "2003" -} - -@InProceedings{ netlogger, - author = "B. Tierney and D. Gunter", - title = "NetLogger: a toolkit for distributed system performance - tuning and debugging", - booktitle = "Proceedings of the IFIP/IEEE Eighth International - Symposium on Integrated Network Management (IM 2003)", - year = "2003", - pages = "97-100", - publisher = "Kluwer", - bolume = "246 of IFIP Conference Proceedings" -} - -@InProceedings{ monalisa, - author = "H.B. Newman and I.C. Legrand and P. Galvez and R. Voicu - and C. Cirstoiu", - title = "MonALISA: a distributed monitoring service architecture", - booktitle = "Computing in High Energy and Nuclear Physics (CHEP03), La - Jolla, CA", - year = "2003" -} - -@InProceedings{ gridrm, - author = "M.A. Baker and G.C. Smith", - title = "GridRM: an extensible resource monitoring system", - booktitle = "Proceedings of the IEEE International Cluster Computing - Conference", - year = "2003", - pages = "207-214" -} - -@InProceedings{ gridlab, - author = "Zoltan Balaton and Gabor Gombas", - title = "Resource and Job Monitoring in the Grid", - booktitle = "Proc. of the Euro-Par 2003 International Conference, - Klagenfurt", - year = 2003 -} - -@Misc{ rgmacms, - author = "D. Bonacorsi and D. Colling and L. Field and S. Fisher and - C. Grandi and P. R. Hobson and P. Kyberd and B. MacEvoy and - J. J. Nebrensky and H. Tallini and S. Traylen", - title = "Scalability Tests of R-GMA Based Grid Job Monitoring - System for CMS Monte Carlo Data Production", - howpublished = "IEEE NSS Conference, Oregon, USA", - year = "2003", - month = "21-24 October" -} - -@Misc{ xacml, - author = "{OASIS Standard}", - title = "{eXtensible Access Control Markup Language (XACML), - Version 1.0}", - year = 2003, - month = "February" -} - -@InProceedings{ gacl1, - author = "L. Cornwall and J. Jensen and D. Kelsey and A. McNab", - title = "{EU DataGrid and GridPP authorization and access control}", - booktitle = "Proceedings of the UK e-Science All Hands Meeting", - year = "2003", - pages = "382--384" -} - -@Misc{ glue, - author = "S. Andreozzi and M. Sgaravatto and C. Vistoli", - title = "Sharing a conceptual model of Grid resources and services", - howpublished = "Proceedings of the Conference for Computing in High Energy - and Nuclear Physics (CHEP03)", - year = "2003" -} - -@InProceedings{ perf, - author = "Xuehai Zhang and Jeffrey L. Freschl and Jennifer M. - Schopf", - title = "A Performance Study of Monitoring and Information Services - for Distributed Systems", - booktitle = "12th IEEE International Symposium on High Performance - Distributed Computing (HPDC-12 '03)", - year = "2003" -} - -@InProceedings{ glite, - author = "E. Laure and F. Hemmer and F. Prelz and S. Beco and S. - Fisher and M. Livny and L. Guy and M. Barroso and P. Buncic - and P. Kunszt and A. {Di Meglio} and A. Aimar and A. Edlund - and D. Groep and F. Pacini and M. Sgaravatto and O. Mulmo", - title = "Middleware for the next generation Grid infrastructure", - booktitle = "Computing in High Energy Physics and Nuclear Physics (CHEP - 2004)", - year = 2004 -} - -@Article{ jgc, - author = {G. Avellino and others}, - title = {{The DataGrid Workload Management System: Challenges and - Results}}, - journal = {Journal of Grid Computing}, - year = {Dec 2004}, - volume = {2}, - number = {4}, - pages = {353--367}, - fauthor = { G. Avellino, S. Beco, B. Cantalupo, A. Maraschini, F. - Pacini, M. Sottilaro, A. Terracina, D. Colling, F. - Giacomini, E. Ronchieri, A. Gianelle, M. Mazzucato, R. - Peluso, M. Sgaravatto, A. Guarise, R. Piro, A. Werbrouck, - D. Kouøil, A. Køenek, L. Matyska, M. Mulaè, J. Pospí¹il, M. - Ruda, Z. Salvet, J. Sitera, J. ©krabal, M. Vocù, M. - Mezzadri, F. Prelz, S. Monforte, M. Pappalardo} -} - -@Misc{ apart, - author = "M. Gerndt and others", - title = "Performance Tools for the {Grid}: State of the Art and - Future", - howpublished = "Tech. Rep. Lehrstuhl fuer Rechnertechnik und - Rechnerorganisation, Technische Universitaet Muenchen - (LRR-TUM). - \url{http://www.lpds.sztaki.hu/~zsnemeth/apart/}", - year = "2004" -} - -@InProceedings{ ahm04194, - author = {Shrija Rajbhandari and David W. Walker}, - title = "{Support for Provenance in a Service-based Computing - Grid}", - booktitle = "{Proceedings of the third UK e-Science All Hands Meeting, - Nottingham, UK}", - year = {2004} -} - -@TechReport{ gro04, - author = {Paul T. Groth}, - title = "{Recording provenance in service-oriented architectures}", - institution = "{University of Southampton; Faculty of Engineering, - Science and Mathematics; School of Electronics and Computer - Science}", - year = {2004} -} - -@InProceedings{ glm04b, - author = {Paul Groth and Michael Luck and Luc Moreau}, - title = "{A protocol for recording provenance in service-oriented - grids}", - booktitle = "{Proceedings of the 8th International Conference on - Principles of Distributed Systems (OPODIS04)}", - year = {2004} -} - -@Article{ ganglia, - author = "M.L. Massie and B.N. Chun and D.E. Culler", - title = "Ganglia Distributed Monitoring System: Design, - Implementation, and Experience", - journal = "Parallel Computing", - year = "2004", - volume = "30", - pages = "817-840" -} - -@Misc{ gae, - author = "Arshad Ali and Ashiq Anjum and Julian Bunn and Richard - Cavanaugh and Frank van Lingen and Richard McClatchey and - Harvey Newman and Waqas ur Rehman and Conrad Steenberg and - Michael Thomas and Ian Willers", - title = "Job Monitoring in an Interactive Grid Analysis - Environment", - howpublished = "Computing in High Energy Physics 2004", - year = "2004" -} - -@InProceedings{ voms1, - author = "R. Alfieri and R. Cecchini and V. Ciaschini and L. - dell'Agnello and \'{A}. Frohner and A. Gianoli and K. - L\H{o}rentey and F. Spataro", - title = "{VOMS}, an {A}uthorization {S}ystem for {V}irtual - {O}rganizations", - booktitle = "Grid Computing: First European Across Grids Conference", - year = "2004" -} - -@InProceedings{ delegation, - author = "V. Welch and I. Foster and C. Kesselman and O. Mulmo and - L. Pearlman and S. Tuecke and J. Gawor and S. Meder and F. - Siebenlist", - title = "{X.509 Proxy Certificates for Dynamic Delegation}", - booktitle = "Proceedings of the 3rd Annual PKI R\&D Workshop", - year = 2004, - month = "April" -} - -@Misc{ proxycert, - author = "S. Tuecke and V. Welch and D. Engert and L. Pearlman and - M. Thompson", - title = "Internet {X}.509 {P}ublic {K}ey {I}nfrastructure ({PKI}) - proxy certificate profile", - howpublished = "IETF RFC 3820", - year = 2004, - month = "June" -} - -@InProceedings{ chep, - author = "D. Kouøil and others", - title = "Distributed Tracking, Storage, and Re-use of Job State - Information on the Grid", - booktitle = "Computing in High Energy and Nuclear Physics (CHEP04)", - year = "2004" -} - -@Misc{ genericlb, - author = "{CESNET JRA1 team}", - title = "Current and Foreseen {\LB}\ Design", - howpublished = "3rd EGEE Conference, Athens, - \url{http://indico.cern.ch/contributionDisplay.py?contribId=201&sessionId=73&confId=0513}" - , - year = 2005 -} - -@InProceedings{ eup1, - author = "Liming Chen and Victor Tan and Fenglian Xu and Alexis - Biller and Paul Groth and Simon Miles and John Ibbotson and - Michael Luck and Luc Moreau", - title = "{A proof of concept: Provenance in a Service Oriented - Architecture}", - booktitle = "{Proceedings of the fourth UK e-Science All Hands Meeting, - Nottingham, UK}", - year = {2005} -} - -@InProceedings{ tgx05, - author = {Paul Townend and Paul Groth and Jie Xu}, - title = "{A provenance-aware weighted fault tolerance scheme for - service-based applications}", - booktitle = "{Proceedings of the $8^{th}$ IEEE International Symposium - on Object-oriented Real-time distributed Computing (ISORC - 2005)}", - year = {2005} -} - -@InProceedings{ mygrid, - author = "M. Nedim Alpdemir and Arijit Mukherjee and Norman W. Paton - and Alvaro A.A. Fernandes and Paul Watson and Kevin Glover - and Chris Greenhalgh and Tom Oinn and Hannah Tipney", - title = "Contextualised Workflow Execution in myGrid", - booktitle = " Proc European Grid Conference , Springer-Verlag LNCS - 3470", - year = 2005, - pages = "444-453" -} - -@Article{ condor2, - author = "Douglas Thain and Todd Tannenbaum and Miron Livny", - title = "Distributed computing in practice: the Condor experience.", - journal = "Concurrency - Practice and Experience", - year = "2005", - volume = "17", - number = "2-4", - pages = "323-356" -} - -@InProceedings{ globus4, - author = "I. Foster", - title = "Globus Toolkit Version 4: Software for Service-Oriented - Systems.", - booktitle = "IFIP International Conference on Network and Parallel - Computing, Springer-Verlag LNCS 3779,", - year = "2005", - pages = "2-13" -} - -@InProceedings{ cgmapisa, - author = "Andrea Ceccanti and Ond\v{r}ej Kraj\'{\i}\v{c}ek and - Ale\v{s} K\v{r}enek and Lud\v{e}k Matyska and Miroslav - Ruda.", - title = "Towards Scalable and Interoperable Grid Monitoring - Infrastructure.", - booktitle = "Proceedings of the first CoreGRID Integration Workshop", - year = "2005", - pages = "10-18" -} - -@InProceedings{ cgma, - author = "Ondøej Krajíèek and Ale¹ Køenek and Ludìk Matyska and - Miroslav Ruda and Jiøí Sitera", - title = "Capability Languages in C-GMA", - booktitle = "Proceedings of Cracow Grid Workshop (CGW05)", - year = "2005" -} - -@Article{ taxonomy, - author = {Serafeim Zanikolas and Rizos Sakellariou}, - title = {A taxonomy of grid monitoring systems}, - journal = {Future Gener. Comput. Syst.}, - year = {2005}, - volume = {21}, - number = {1}, - pages = {163--188}, - issn = {0167-739X}, - doi = {http://dx.doi.org/10.1016/j.future.2004.07.002}, - publisher = {Elsevier Science Publishers B. V.}, - address = {Amsterdam, The Netherlands, The Netherlands} -} - -@Article{ unicore, - author = "Achim Streit and Dietmar Erwin and Thomas Lippert and - Daniel Mallmann and Roger Menday and Michael Rambadt and - Morris Riedel and Mathilde Romberg and Bernd Schuller and - Philipp Wieder", - title = "UNICORE - From Project Results to Production Grids", - journal = "Grid Computing : New Frontiers of High Performance - Computing", - year = "2005", - pages = "357 - 376" -} - -@Article{ voms2, - author = "R. Alfieri and R. Cecchini and V. Ciaschini and L. - dell'Agnello and \'{A}. Frohner and K. L\H{o}rentey and F. - Spataro", - title = "{From gridmap-file to VOMS: managing authorization in a - Grid environment}", - journal = "Future Generation Computer Systems", - year = "2005", - pages = "549-558", - month = "April" -} - -@InProceedings{ cgw05, - author = "F. Dvoøák and D. Kouøil and A. Køenek and L. Matyska and - M. Mulaè and J.Pospi¹il and M. Ruda and Z. Salvet and J. - Sitera and J. ©krabal and M. Vocù ", - title = "Services for Tracking and Archival of Grid Job - Information", - booktitle = "Proceeding of Cracow Grid Workshop", - year = "2005" -} - -@Misc{ rfc4122, - author = "P. Leach and M. Mealling and R. Salz", - title = "A Universally Unique IDentifier (UUID) URN Namespace", - howpublished = "IETF RFC 4122", - year = "2005" -} - -@Misc{ euprovenance, - title = "{EU FP6 Programme Enabling and Supporting Provenance in - Grids for Complex Problems}", - howpublished = "\url{http://twiki.gridprovenance.org/bin/view/Provenance/ProjectInformation}" - , - year = 2006 -} - -@Misc{ atlas, - author = "TODO - predelat na neco poradneho", - title = "{The ATLAS Experiment}", - howpublished = "\url{http://atlas.ch/}", - year = 2006 -} - -@Misc{ ami, - author = "TODO - predelat na neco poradneho", - title = "{The Atlas Metadata Interface}", - howpublished = "\url{https://atlastagcollector.in2p3.fr:8443/AMI/}", - year = 2006 -} - -@Misc{ alice, - author = "TODO - predelat na neco poradneho", - title = "{A Large Ion Collider Experiment}", - howpublished = "\url{http://aliceinfo.cern.ch/Public}", - year = 2006 -} - -@Misc{ sam, - author = "TODO - predelat na neco poradneho", - title = "{SAM (Sequential data Access via Meta-data)}", - howpublished = "\url{http://d0db.fnal.gov/sam/}", - year = 2006 -} - -@InProceedings{ gacl2, - author = "A. McNab and S. Kaushal", - title = "Web services with gridsite and C/C++/scripts", - booktitle = "Computing in High Energy and Nuclear Physics (CHEP 2006)", - year = "2006" -} - -@Misc{ crossgrid, - author = "CrossGrid", - title = "{CrossGrid Project}", - howpublished = "\url{http://www.crossgrid.org}" -} - -@Misc{ dgas, - author = "DGAS", - title = "{The Distributed Grid Accounting System}", - howpublished = "\url{http://www.to.infn.it/grid/accounting/main.html}" -} - -@Misc{ egee, - author = "EGEE", - title = "{Enabling Grids for E-sciencE (EGEE) Project}", - howpublished = "\url{http://lcg.web.cern.ch/LCG/}" -} - -@Misc{ gridice, - author = "EGEE", - title = "{GridIce, the eyes of the Grid}", - howpublished = "\url{http://gridice2.cnaf.infn.it:50080/gridice/}" -} - -@Misc{ djra1.2, - author = {{EGEE JRA1}}, - title = {{EGEE Middleware Design---Release 1}}, - howpublished = {\url{https://edms.cern.ch/document/487871/}} -} - -@Misc{ djra1.3, - author = {{EGEE JRA1}}, - title = {{EGEE Middleware Release 1}}, - howpublished = {\url{https://edms.cern.ch/document/567624/}} -} - -@Misc{ djra1.4, - author = {{EGEE JRA1}}, - title = {{EGEE Middleware Architecture---Release 2}}, - howpublished = {\url{https://edms.cern.ch/document/594698/}} -} - -@Misc{ jra2jobmetrics, - author = "EGEE JRA2", - title = "{Job Metrics}", - howpublished = "\url{http://egee-jra2.web.cern.ch/EGEE-JRA2/QoS/JobsMetrics/JobMetrics.htm}" - -} - -@Misc{ lbug, - author = "A. K\v{r}enek and others", - title = "{L\&B User's Guide}", - howpublished = "\url{http://egee.cesnet.cz/en/JRA1/LB/}", -} - -@Misc{ lbdg, - author = "A. K\v{r}enek and others", - title = "{L\&B Developer's Guide}", - howpublished = "\url{http://egee.cesnet.cz/en/JRA1/LB/}", -} - -@Misc{ lbag, - author = "A. K\v{r}enek and others", - title = "{L\&B Administrator's Guide}", - howpublished = "\url{http://egee.cesnet.cz/en/JRA1/LB/}", -} - -@Misc{ lbtp, - author = "A. K\v{r}enek and others", - title = "{L\&B Test Plan}", - howpublished = "\url{http://egee.cesnet.cz/en/JRA1/LB/}", -} - -@Misc{ wmsug, - author = "F. Pacini and others", - title = "{WMS User's Guide}", - howpublished = "\url{https://edms.cern.ch/file/572489/1/WMS-guide.pdf}" -} - -@Misc{ lcg, - author = "LCG", - title = "{LHC Computing Project (LCG)}", - howpublished = "\url{http://lcg.web.cern.ch/LCG/}" -} - -@Misc{ pasoa, - title = "{PASOA: Provenance Aware Service Oriented Architecture}", - howpublished = "\url{http://twiki.pasoa.ecs.soton.ac.uk/bin/view/PASOA/AboutPasoa}" - -} - -@InProceedings{ hpdc07, - author = {Miroslav Ruda and Ale\v{s} K\v{r}enek and Milo\v{s} - Mula\v{c} and Jan Posp\'{\i}\v{s}il and Zden\v{e}k \v{S}ustr}, - title = {A uniform job monitoring service in multiple job - universes}, - booktitle = {GMW '07: Proceedings of the 2007 workshop on Grid - monitoring}, - year = {2007}, - pages = {17--22}, - address = {New York, NY, USA}, - publisher = {ACM}, - isbn = {978-1-59593-716-2}, - location = {Monterey, California, USA}, - doi = {http://doi.acm.org/10.1145/1272680.1272684}, - abstract = {We describe an ongoing work of extending the gLite Logging - and Bookkeeping (\LB) service to be able to track - additional types of jobs, with the vision of being able to - uniformly follow jobs on the Grid, even when they pass - between different middleware domains. Details are given on - the simpler case of PBS jobs, which prove the cabability of - \LB to deal with additional job types, as well as started - more complex and challenging work on Condor jobs, where the - impact of eventual success is larger.} -} - -@Misc{ etics_manual, - title = "ETICS User Manual", - howpublished = "\url{https://edms.cern.ch/file/795312//ETICS-User_Manual-latest.pdf}", -} - - -@InProceedings{ LB4CRL, - author="Daniel Kouril and Ludek Matyska and Michal Prochazka", - title="A Robust and Efficient Mechanism to Distribute Certificate Revocation - Information Using the Grid Monitoring Architecture,", - pages="614-619", - booktitle="21st International Conference on Advanced Information Networking and -Applications Workshops (AINAW'07)", - year=2007 -} - -@Misc{ lcas, - title = "{Site Authorisation and Enforcement Services: LCAS, LCMAPS, and gLExec}", - howpublished = "\url{https://www.nikhef.nl/pub/projects/grid/gridwiki/index.php/LCAS}", -} - diff --git a/org.glite.lb.doc/src/listings.sty b/org.glite.lb.doc/src/listings.sty deleted file mode 100644 index 7c3eceb..0000000 --- a/org.glite.lb.doc/src/listings.sty +++ /dev/null @@ -1,2002 +0,0 @@ -%% -%% This is file `listings.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% listings-1.3.dtx (with options: `kernel') -%% -%% Please read the software license in listings-1.3.dtx or listings-1.3.pdf. -%% -%% (w)(c) 1996--2004 Carsten Heinz and/or any other author listed -%% elsewhere in this file. -%% -%% Send comments and ideas on the package, error reports and additional -%% programming languages to . -%% -\def\filedate{2004/09/07} -\def\fileversion{1.3} -\NeedsTeXFormat{LaTeX2e} -\AtEndOfPackage{\ProvidesPackage{listings} - [\filedate\space\fileversion\space(Carsten Heinz)]} -\def\lst@CheckVersion#1{\edef\reserved@a{#1}% - \ifx\lst@version\reserved@a \expandafter\@gobble - \else \expandafter\@firstofone \fi} -\let\lst@version\fileversion -\def\lst@InputCatcodes{% - \makeatletter \catcode`\"12% - \catcode`\^^@\active - \catcode`\^^I9% - \catcode`\^^L9% - \catcode`\^^M9% - \catcode`\%14% - \catcode`\~\active} -\def\lst@RestoreCatcodes#1{% - \ifx\relax#1\else - \noexpand\catcode`\noexpand#1\the\catcode`#1\relax - \expandafter\lst@RestoreCatcodes - \fi} -\edef\lst@RestoreCatcodes{% - \noexpand\lccode`\noexpand\/`\noexpand\/% - \lst@RestoreCatcodes\"\^^I\^^M\~\^^@\relax} -\lst@InputCatcodes -\AtEndOfPackage{\lst@RestoreCatcodes} -\def\@lst{lst} -\def\lst@IfSubstring#1#2{% - \def\lst@temp##1#1##2##3\relax{% - \ifx \@empty##2\expandafter\@secondoftwo - \else \expandafter\@firstoftwo \fi}% - \expandafter\lst@temp#2#1\@empty\relax} -\def\lst@IfOneOf#1\relax#2{% - \def\lst@temp##1,#1,##2##3\relax{% - \ifx \@empty##2\expandafter\@secondoftwo - \else \expandafter\@firstoftwo \fi}% - \expandafter\lst@temp\expandafter,#2,#1,\@empty\relax} -\def\lst@DeleteKeysIn#1#2{% - \expandafter\lst@DeleteKeysIn@\expandafter#1#2,\relax,} -\def\lst@DeleteKeysIn@#1#2,{% - \ifx\relax#2\@empty - \expandafter\@firstoftwo\expandafter\lst@RemoveCommas - \else - \ifx\@empty#2\@empty\else - \def\lst@temp##1,#2,##2{% - ##1% - \ifx\@empty##2\@empty\else - \expandafter\lst@temp\expandafter,% - \fi ##2}% - \edef#1{\expandafter\lst@temp\expandafter,#1,#2,\@empty}% - \fi - \fi - \lst@DeleteKeysIn@#1} -\def\lst@RemoveCommas#1{\edef#1{\expandafter\lst@RC@#1\@empty}} -\def\lst@RC@#1{\ifx,#1\expandafter\lst@RC@ \else #1\fi} -\def\lst@ReplaceIn#1#2{% - \expandafter\lst@ReplaceIn@\expandafter#1#2\@empty\@empty} -\def\lst@ReplaceInArg#1#2{\lst@ReplaceIn@#1#2\@empty\@empty} -\def\lst@ReplaceIn@#1#2#3{% - \ifx\@empty#3\relax\else - \def\lst@temp##1#2##2{% - \ifx\@empty##2% - \lst@lAddTo#1{##1}% - \else - \lst@lAddTo#1{##1#3}\expandafter\lst@temp - \fi ##2}% - \let\@tempa#1\let#1\@empty - \expandafter\lst@temp\@tempa#2\@empty - \expandafter\lst@ReplaceIn@\expandafter#1% - \fi} -\providecommand*\@gobblethree[3]{} -\def\lst@GobbleNil#1\@nil{} -\def\lst@Swap#1#2{#2#1} -\def\lst@true{\let\lst@if\iftrue} -\def\lst@false{\let\lst@if\iffalse} -\lst@false -\def\lst@IfNextCharsArg#1{% - \def\lst@tofind{#1}\lst@IfNextChars\lst@tofind} -\def\lst@IfNextChars#1#2#3{% - \let\lst@tofind#1\def\@tempa{#2}\def\@tempb{#3}% - \let\lst@eaten\@empty \lst@IfNextChars@} -\def\lst@IfNextChars@{\expandafter\lst@IfNextChars@@\lst@tofind\relax} -\def\lst@IfNextChars@@#1#2\relax#3{% - \def\lst@tofind{#2}\lst@lAddTo\lst@eaten{#3}% - \ifx#1#3% - \ifx\lst@tofind\@empty - \let\lst@next\@tempa - \else - \let\lst@next\lst@IfNextChars@ - \fi - \expandafter\lst@next - \else - \expandafter\@tempb - \fi} -\def\lst@IfNextCharActive#1#2#3{% - \begingroup \lccode`\~=`#3\lowercase{\endgroup - \ifx~}#3% - \def\lst@next{#1}% - \else - \def\lst@next{#2}% - \fi \lst@next #3} -\def\lst@for#1\do#2{% - \def\lst@forbody##1{#2}% - \@for\lst@forvar:=#1\do - {\expandafter\lst@forbody\expandafter{\lst@forvar}}} -\def\lst@MakeActive#1{% - \let\lst@temp\@empty \lst@MakeActive@#1% - \relax\relax\relax\relax\relax\relax\relax\relax\relax} -\begingroup -\catcode`\^^@=\active \catcode`\^^A=\active \catcode`\^^B=\active -\catcode`\^^C=\active \catcode`\^^D=\active \catcode`\^^E=\active -\catcode`\^^F=\active \catcode`\^^G=\active \catcode`\^^H=\active -\gdef\lst@MakeActive@#1#2#3#4#5#6#7#8#9{\let\lst@next\relax - \ifx#1\relax - \else \lccode`\^^@=`#1% - \ifx#2\relax - \lowercase{\lst@lAddTo\lst@temp{^^@}}% - \else \lccode`\^^A=`#2% - \ifx#3\relax - \lowercase{\lst@lAddTo\lst@temp{^^@^^A}}% - \else \lccode`\^^B=`#3% - \ifx#4\relax - \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B}}% - \else \lccode`\^^C=`#4% - \ifx#5\relax - \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C}}% - \else \lccode`\^^D=`#5% - \ifx#6\relax - \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D}}% - \else \lccode`\^^E=`#6% - \ifx#7\relax - \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E}}% - \else \lccode`\^^F=`#7% - \ifx#8\relax - \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E^^F}}% - \else \lccode`\^^G=`#8% - \ifx#9\relax - \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E^^F^^G}}% - \else \lccode`\^^H=`#9% - \lowercase{\lst@lAddTo\lst@temp{^^@^^A^^B^^C^^D^^E^^F^^G^^H}}% - \let\lst@next\lst@MakeActive@ - \fi \fi \fi \fi \fi \fi \fi \fi \fi - \lst@next} -\endgroup -\def\lst@DefActive#1#2{\lst@MakeActive{#2}\let#1\lst@temp} -\def\lst@DefOther#1#2{% - \begingroup \def#1{#2}\escapechar\m@ne \expandafter\endgroup - \expandafter\lst@DefOther@\meaning#1\relax#1} -\def\lst@DefOther@#1>#2\relax#3{\edef#3{\zap@space#2 \@empty}} -\def\lst@InsideConvert#1{% - \lst@ifmathescape - \lst@InsideConvert@e#1$\@nil - \lst@if - \lst@InsideConvert@ey#1\@nil - \else - \lst@InsideConvert@#1 \@empty - \expandafter\@gobbletwo - \fi - \expandafter\lst@next - \else - \lst@InsideConvert@#1 \@empty - \fi} -\begingroup \lccode`\~=`\ \relax \lowercase{% -\gdef\lst@InsideConvert@#1 #2{% - \lst@MakeActive{#1}% - \ifx\@empty#2% - \lst@lExtend\lst@arg{\lst@temp}% - \else - \lst@lExtend\lst@arg{\lst@temp~}% - \expandafter\lst@InsideConvert@ - \fi #2} -}\endgroup -\def\lst@InsideConvert@e#1$#2\@nil{% - \ifx\@empty#2\@empty \lst@false \else \lst@true \fi} -\def\lst@InsideConvert@ey#1$#2$#3\@nil{% - \lst@InsideConvert@#1 \@empty - \lst@lAddTo\lst@arg{% - \lst@ifdropinput\else - \lst@TrackNewLines\lst@OutputLostSpace \lst@XPrintToken - \setbox\@tempboxa=\hbox\bgroup$\lst@escapebegin - #2% - \lst@escapeend$\egroup \lst@CalcLostSpaceAndOutput - \lst@whitespacefalse - \fi}% - \def\lst@next{\lst@InsideConvert{#3}}% -} -\def\lst@XConvert{\@ifnextchar\bgroup \lst@XConvertArg\lst@XConvert@} -\def\lst@XConvertArg#1{% - {\lst@false \let\lst@arg\@empty - \lst@XConvert#1\@nil - \global\let\@gtempa\lst@arg}% - \lst@lExtend\lst@arg{\expandafter{\@gtempa}}% - \lst@XConvertNext} -\def\lst@XConvert@#1{% - \ifx\@nil#1\else - \begingroup\lccode`\~=`#1\lowercase{\endgroup - \lst@lAddTo\lst@arg~}% - \expandafter\lst@XConvertNext - \fi} -\def\lst@XConvertNext{% - \lst@if \expandafter\lst@XConvertX - \else \expandafter\lst@XConvert \fi} -\def\lst@XConvertX#1{% - \ifx\@nil#1\else - \lst@XConvertX@#1\relax - \expandafter\lst@XConvert - \fi} -\def\lst@XConvertX@#1#2\relax{% - \begingroup\lccode`\~=`#1\lowercase{\endgroup - \lst@XCConvertX@@~}{#2}} -\def\lst@XCConvertX@@#1#2{\lst@lAddTo\lst@arg{{#1#2}}} -\def\lst@Require#1#2#3#4#5{% - \begingroup - \aftergroup\lst@true - \ifx\@empty#3\@empty\else - \def\lst@prefix{#2}\let\lst@require\@empty - \edef\lst@temp{\expandafter\zap@space#3 \@empty}% - \lst@for\lst@temp\do{% - \ifx\@empty##1\@empty\else \lstKV@OptArg[]{##1}{% - #4[####1]{####2}% - \@ifundefined{\@lst\lst@prefix @\lst@malias $\lst@oalias}% - {\edef\lst@require{\lst@require,\lst@malias $\lst@oalias}}% - {}}% - \fi}% - \global\let\lst@loadaspects\@empty - \lst@InputCatcodes - \ifx\lst@require\@empty\else - \lst@for{#5}\do{% - \ifx\lst@require\@empty\else - \InputIfFileExists{##1}{}{}% - \fi}% - \fi - \ifx\lst@require\@empty\else - \PackageError{Listings}{Couldn't load requested #1}% - {The following #1s weren't loadable:^^J\@spaces - \lst@require^^JThis may cause errors in the sequel.}% - \aftergroup\lst@false - \fi - \ifx\lst@loadaspects\@empty\else - \lst@RequireAspects\lst@loadaspects - \fi - \fi - \endgroup} -\def\lst@IfRequired[#1]#2{% - \lst@NormedDef\lst@temp{[#1]#2}% - \expandafter\lst@IfRequired@\lst@temp\relax} -\def\lst@IfRequired@[#1]#2\relax#3{% - \lst@IfOneOf #2$#1\relax\lst@require - {\lst@DeleteKeysIn@\lst@require#2$#1,\relax,% - \global\expandafter\let - \csname\@lst\lst@prefix @#2$#1\endcsname\@empty - #3}} -\let\lst@require\@empty -\def\lst@NoAlias[#1]#2{% - \lst@NormedDef\lst@oalias{#1}\lst@NormedDef\lst@malias{#2}} -\gdef\lst@LAS#1#2#3#4#5#6#7{% - \lst@Require{#1}{#2}{#3}#4#5% - #4#3% - \@ifundefined{lst#2@\lst@malias$\lst@oalias}% - {\PackageError{Listings}% - {#1 \ifx\@empty\lst@oalias\else \lst@oalias\space of \fi - \lst@malias\space undefined}% - {The #1 is not loadable. \@ehc}}% - {#6\csname\@lst#2@\lst@malias $\lst@oalias\endcsname #7}} -\def\lst@RequireAspects#1{% - \lst@Require{aspect}{asp}{#1}\lst@NoAlias\lstaspectfiles} -\let\lstloadaspects\lst@RequireAspects -\@ifundefined{lstaspectfiles} - {\newcommand\lstaspectfiles{lstmisc0.sty,lstmisc.sty}}{} -\gdef\lst@DefDriver#1#2#3#4{% - \@ifnextchar[{\lst@DefDriver@{#1}{#2}#3#4}% - {\lst@DefDriver@{#1}{#2}#3#4[]}} -\gdef\lst@DefDriver@#1#2#3#4[#5]#6{% - \def\lst@name{#1}\let\lst@if#4% - \lst@NormedDef\lst@driver{\@lst#2@#6$#5}% - \lst@IfRequired[#5]{#6}{\begingroup \lst@true}% - {\begingroup}% - \lst@setcatcodes - \@ifnextchar[{\lst@XDefDriver{#1}#3}{\lst@DefDriver@@#3}} -\gdef\lst@DefDriver@@#1#2{% - \lst@if - \global\@namedef{\lst@driver}{#1{#2}}% - \fi - \endgroup - \@ifnextchar[\lst@XXDefDriver\@empty} -\gdef\lst@XXDefDriver[#1]{% - \ifx\@empty#1\@empty\else - \lst@if - \lstloadaspects{#1}% - \else - \@ifundefined{\lst@driver}{}% - {\xdef\lst@loadaspects{\lst@loadaspects,#1}}% - \fi - \fi} -\gdef\lst@XDefDriver#1#2[#3]#4#5{\lst@DefDriver@@#2{also#1=[#3]#4,#5}} -\let\lst@UserCommand\gdef -\newcommand*\lst@BeginAspect[2][]{% - \def\lst@curraspect{#2}% - \ifx \lst@curraspect\@empty - \expandafter\lst@GobbleAspect - \else - \let\lst@next\@empty - \lst@IfRequired[]{#2}% - {\lst@RequireAspects{#1}% - \lst@if\else \let\lst@next\lst@GobbleAspect \fi}% - {\let\lst@next\lst@GobbleAspect}% - \expandafter\lst@next - \fi} -\def\lst@EndAspect{% - \csname\@lst patch@\lst@curraspect\endcsname - \let\lst@curraspect\@empty} -\long\def\lst@GobbleAspect#1\lst@EndAspect{\let\lst@curraspect\@empty} -\def\lst@Key#1#2{% - \@ifnextchar[{\lstKV@def{#1}{#2}}% - {\def\lst@temp{\lst@Key@{#1}{#2}} - \afterassignment\lst@temp - \global\@namedef{KV@\@lst @#1}####1}} -\def\lstKV@def#1#2[#3]{% - \global\@namedef{KV@\@lst @#1@default\expandafter}\expandafter - {\csname KV@\@lst @#1\endcsname{#3}}% - \def\lst@temp{\lst@Key@{#1}{#2}}\afterassignment\lst@temp - \global\@namedef{KV@\@lst @#1}##1} -\def\lst@Key@#1#2{% - \ifx\relax#2\@empty\else - \begingroup \globaldefs\@ne - \csname KV@\@lst @#1\endcsname{#2}% - \endgroup - \fi} -\def\lst@UseHook#1{\csname\@lst hk@#1\endcsname} -\def\lst@AddToHook{\lst@ATH@\iffalse\lst@AddTo} -\def\lst@AddToHookExe{\lst@ATH@\iftrue\lst@AddTo} -\def\lst@AddToHookAtTop{\lst@ATH@\iffalse\lst@AddToAtTop} -\long\def\lst@ATH@#1#2#3#4{% - \@ifundefined{\@lst hk@#3}{% - \expandafter\gdef\csname\@lst hk@#3\endcsname{}}{}% - \expandafter#2\csname\@lst hk@#3\endcsname{#4}% - \def\lst@temp{#4}% - #1% \iftrue|false - \begingroup \globaldefs\@ne \lst@temp \endgroup - \fi} -\long\def\lst@AddTo#1#2{% - \expandafter\gdef\expandafter#1\expandafter{#1#2}} -\def\lst@AddToAtTop#1#2{\def\lst@temp{#2}% - \expandafter\expandafter\expandafter\gdef - \expandafter\expandafter\expandafter#1% - \expandafter\expandafter\expandafter{\expandafter\lst@temp#1}} -\def\lst@lAddTo#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}} -\def\lst@Extend#1#2{% - \expandafter\lst@AddTo\expandafter#1\expandafter{#2}} -\def\lst@lExtend#1#2{% - \expandafter\lst@lAddTo\expandafter#1\expandafter{#2}} -\RequirePackage{keyval}[1997/11/10] -\def\lstKV@TwoArg#1#2{\gdef\@gtempa##1##2{#2}\@gtempa#1{}{}} -\def\lstKV@ThreeArg#1#2{\gdef\@gtempa##1##2##3{#2}\@gtempa#1{}{}{}} -\def\lstKV@FourArg#1#2{\gdef\@gtempa##1##2##3##4{#2}\@gtempa#1{}{}{}{}} -\def\lstKV@OptArg[#1]#2#3{% - \gdef\@gtempa[##1]##2{#3}\lstKV@OptArg@{#1}#2\@} -\def\lstKV@OptArg@#1{\@ifnextchar[\lstKV@OptArg@@{\lstKV@OptArg@@[#1]}} -\def\lstKV@OptArg@@[#1]#2\@{\@gtempa[#1]{#2}} -\def\lstKV@XOptArg[#1]#2#3{% - \global\let\@gtempa#3\lstKV@OptArg@{#1}#2\@} -\def\lstKV@CSTwoArg#1#2{% - \gdef\@gtempa##1,##2,##3\relax{#2}% - \@gtempa#1,,\relax} -\def\lstKV@SetIf#1{\lstKV@SetIf@#1\relax} -\def\lstKV@SetIf@#1#2\relax#3{\lowercase{% - \expandafter\let\expandafter#3% - \csname if\ifx #1t}true\else false\fi\endcsname} -\def\lstKV@SwitchCases#1#2#3{% - \def\lst@temp##1\\#1&##2\\##3##4\@nil{% - \ifx\@empty##3% - #3% - \else - ##2% - \fi - }% - \lst@temp\\#2\\#1&\\\@empty\@nil} -\lst@UserCommand\lstset{\begingroup \lst@setcatcodes \lstset@} -\def\lstset@#1{\endgroup \ifx\@empty#1\@empty\else\setkeys{lst}{#1}\fi} -\def\lst@setcatcodes{\makeatletter \catcode`\==12\relax} -\def\lst@NewMode#1{% - \ifx\@undefined#1% - \lst@mode\lst@newmode\relax \advance\lst@mode\@ne - \xdef\lst@newmode{\the\lst@mode}% - \global\chardef#1=\lst@mode - \lst@mode\lst@nomode - \fi} -\newcount\lst@mode -\def\lst@newmode{\m@ne}% init -\lst@NewMode\lst@nomode % init (of \lst@mode :-) -\def\lst@UseDynamicMode{% - \@tempcnta\lst@dynamicmode\relax \advance\@tempcnta\@ne - \edef\lst@dynamicmode{\the\@tempcnta}% - \expandafter\lst@Swap\expandafter{\expandafter{\lst@dynamicmode}}} -\lst@AddToHook{InitVars}{\let\lst@dynamicmode\lst@newmode} -\def\lst@EnterMode#1#2{% - \bgroup \lst@mode=#1\relax #2% - \lst@FontAdjust - \lst@lAddTo\lst@entermodes{\lst@EnterMode{#1}{#2}}} -\lst@AddToHook{InitVars}{\let\lst@entermodes\@empty} -\let\lst@entermodes\@empty % init -\def\lst@LeaveMode{% - \ifnum\lst@mode=\lst@nomode\else - \egroup \expandafter\lsthk@EndGroup - \fi} -\lst@AddToHook{EndGroup}{}% init -\def\lst@InterruptModes{% - \lst@Extend\lst@modestack{\expandafter{\lst@entermodes}}% - \lst@LeaveAllModes} -\lst@AddToHook{InitVars}{\global\let\lst@modestack\@empty} -\def\lst@ReenterModes{% - \ifx\lst@modestack\@empty\else - \lst@LeaveAllModes - \global\let\@gtempa\lst@modestack - \global\let\lst@modestack\@empty - \expandafter\lst@ReenterModes@\@gtempa\relax - \fi} -\def\lst@ReenterModes@#1#2{% - \ifx\relax#2\@empty - \gdef\@gtempa##1{#1}% - \expandafter\@gtempa - \else - \lst@AddTo\lst@modestack{{#1}}% - \expandafter\lst@ReenterModes@ - \fi - {#2}} -\def\lst@LeaveAllModes{% - \ifnum\lst@mode=\lst@nomode - \expandafter\lsthk@EndGroup - \else - \expandafter\egroup\expandafter\lst@LeaveAllModes - \fi} -\lst@AddToHook{ExitVars}{\lst@LeaveAllModes} -\lst@NewMode\lst@Pmode -\lst@NewMode\lst@GPmode -\def\lst@modetrue{\let\lst@ifmode\iftrue \lsthk@ModeTrue} -\let\lst@ifmode\iffalse % init -\lst@AddToHook{ModeTrue}{}% init -\def\lst@Lmodetrue{\let\lst@ifLmode\iftrue} -\let\lst@ifLmode\iffalse % init -\lst@AddToHook{EOL}{\@whilesw \lst@ifLmode\fi \lst@LeaveMode} -\def\lst@NormedDef#1#2{\lowercase{\edef#1{\zap@space#2 \@empty}}} -\def\lst@NormedNameDef#1#2{% - \lowercase{\edef\lst@temp{\zap@space#1 \@empty}% - \expandafter\xdef\csname\lst@temp\endcsname{\zap@space#2 \@empty}}} -\def\lst@GetFreeMacro#1{% - \@tempcnta\z@ \def\lst@freemacro{#1\the\@tempcnta}% - \lst@GFM@} -\def\lst@GFM@{% - \expandafter\ifx \csname\lst@freemacro\endcsname \relax - \edef\lst@freemacro{\csname\lst@freemacro\endcsname}% - \else - \advance\@tempcnta\@ne - \expandafter\lst@GFM@ - \fi} -\newbox\lst@gtempboxa -\newtoks\lst@token \newcount\lst@length -\def\lst@ResetToken{\lst@token{}\lst@length\z@} -\lst@AddToHook{InitVarsBOL}{\lst@ResetToken \let\lst@lastother\@empty} -\lst@AddToHook{EndGroup}{\lst@ResetToken \let\lst@lastother\@empty} -\def\lst@lettertrue{\let\lst@ifletter\iftrue} -\def\lst@letterfalse{\let\lst@ifletter\iffalse} -\lst@AddToHook{InitVars}{\lst@letterfalse} -\def\lst@Append#1{\advance\lst@length\@ne - \lst@token=\expandafter{\the\lst@token#1}} -\def\lst@AppendOther{% - \lst@ifletter \lst@Output\lst@letterfalse \fi - \futurelet\lst@lastother\lst@Append} -\def\lst@AppendLetter{% - \lst@ifletter\else \lst@OutputOther\lst@lettertrue \fi - \lst@Append} -\def\lst@SaveToken{% - \global\let\lst@gthestyle\lst@thestyle - \global\let\lst@glastother\lst@lastother - \xdef\lst@RestoreToken{\noexpand\lst@token{\the\lst@token}% - \noexpand\lst@length\the\lst@length\relax - \noexpand\let\noexpand\lst@thestyle - \noexpand\lst@gthestyle - \noexpand\let\noexpand\lst@lastother - \noexpand\lst@glastother}} -\def\lst@IfLastOtherOneOf#1{\lst@IfLastOtherOneOf@ #1\relax} -\def\lst@IfLastOtherOneOf@#1{% - \ifx #1\relax - \expandafter\@secondoftwo - \else - \ifx\lst@lastother#1% - \lst@IfLastOtherOneOf@t - \else - \expandafter\expandafter\expandafter\lst@IfLastOtherOneOf@ - \fi - \fi} -\def\lst@IfLastOtherOneOf@t#1\fi\fi#2\relax{\fi\fi\@firstoftwo} -\newdimen\lst@currlwidth % \global -\newcount\lst@column \newcount\lst@pos % \global -\lst@AddToHook{InitVarsBOL} - {\global\lst@currlwidth\z@ \global\lst@pos\z@ \global\lst@column\z@} -\def\lst@CalcColumn{% - \@tempcnta\lst@column - \advance\@tempcnta\lst@length - \advance\@tempcnta-\lst@pos} -\newdimen\lst@lostspace % \global -\lst@AddToHook{InitVarsBOL}{\global\lst@lostspace\z@} -\def\lst@UseLostSpace{\ifdim\lst@lostspace>\z@ \lst@InsertLostSpace \fi} -\def\lst@InsertLostSpace{% - \lst@Kern\lst@lostspace \global\lst@lostspace\z@} -\def\lst@InsertHalfLostSpace{% - \global\lst@lostspace.5\lst@lostspace \lst@Kern\lst@lostspace} -\newdimen\lst@width -\lst@Key{basewidth}{0.6em,0.45em}{\lstKV@CSTwoArg{#1}% - {\def\lst@widthfixed{##1}\def\lst@widthflexible{##2}% - \ifx\lst@widthflexible\@empty - \let\lst@widthflexible\lst@widthfixed - \fi - \def\lst@temp{\PackageError{Listings}% - {Negative value(s) treated as zero}% - \@ehc}% - \let\lst@error\@empty - \ifdim \lst@widthfixed<\z@ - \let\lst@error\lst@temp \let\lst@widthfixed\z@ - \fi - \ifdim \lst@widthflexible<\z@ - \let\lst@error\lst@temp \let\lst@widthflexible\z@ - \fi - \lst@error}} -\lst@AddToHook{FontAdjust} - {\lst@width=\lst@ifflexible\lst@widthflexible - \else\lst@widthfixed\fi \relax} -\lst@Key{fontadjust}{false}[t]{\lstKV@SetIf{#1}\lst@iffontadjust} -\def\lst@FontAdjust{\lst@iffontadjust \lsthk@FontAdjust \fi} -\lst@AddToHook{InitVars}{\lsthk@FontAdjust} -\def\lst@OutputBox#1{\lst@alloverstyle{\box#1}} -\def\lst@alloverstyle#1{#1}% init -\def\lst@Kern#1{% - \setbox\z@\hbox{{\lst@currstyle{\kern#1}}}% - \global\advance\lst@currlwidth \wd\z@ - \lst@OutputBox\z@} -\def\lst@CalcLostSpaceAndOutput{% - \global\advance\lst@lostspace \lst@length\lst@width - \global\advance\lst@lostspace-\wd\@tempboxa - \global\advance\lst@currlwidth \wd\@tempboxa - \global\advance\lst@pos -\lst@length - \setbox\@tempboxa\hbox{\let\lst@OutputBox\box - \ifdim\lst@lostspace>\z@ \lst@leftinsert \fi - \box\@tempboxa - \ifdim\lst@lostspace>\z@ \lst@rightinsert \fi}% - \lst@OutputBox\@tempboxa \lsthk@PostOutput} -\lst@AddToHook{PostOutput}{}% init -\def\lst@OutputToken{% - \lst@TrackNewLines \lst@OutputLostSpace - \lst@ifgobbledws - \lst@gobbledwhitespacefalse - \lst@@discretionary - \fi - \lst@CheckMerge - {\lst@thestyle{\lst@FontAdjust - \setbox\@tempboxa\lst@hbox - {\lsthk@OutputBox - \lst@lefthss - \expandafter\lst@FillOutputBox\the\lst@token\@empty - \lst@righthss}% - \lst@CalcLostSpaceAndOutput}}% - \lst@ResetToken} -\lst@AddToHook{OutputBox}{}% init -\def\lst@gobbledwhitespacetrue{\global\let\lst@ifgobbledws\iftrue} -\def\lst@gobbledwhitespacefalse{\global\let\lst@ifgobbledws\iffalse} -\lst@AddToHookExe{InitBOL}{\lst@gobbledwhitespacefalse}% init -\def\lst@Delay#1{% - \lst@CheckDelay - #1% - \lst@GetOutputMacro\lst@delayedoutput - \edef\lst@delayed{\the\lst@token}% - \edef\lst@delayedlength{\the\lst@length}% - \lst@ResetToken} -\def\lst@Merge#1{% - \lst@CheckMerge - #1% - \edef\lst@merged{\the\lst@token}% - \edef\lst@mergedlength{\the\lst@length}% - \lst@ResetToken} -\def\lst@MergeToken#1#2{% - \advance\lst@length#2% - \lst@lExtend#1{\the\lst@token}% - \expandafter\lst@token\expandafter{#1}% - \let#1\@empty} -\def\lst@CheckDelay{% - \ifx\lst@delayed\@empty\else - \lst@GetOutputMacro\@gtempa - \ifx\lst@delayedoutput\@gtempa - \lst@MergeToken\lst@delayed\lst@delayedlength - \else - {\lst@ResetToken - \lst@MergeToken\lst@delayed\lst@delayedlength - \lst@delayedoutput}% - \let\lst@delayed\@empty - \fi - \fi} -\def\lst@CheckMerge{% - \ifx\lst@merged\@empty\else - \lst@MergeToken\lst@merged\lst@mergedlength - \fi} -\let\lst@delayed\@empty % init -\let\lst@merged\@empty % init -\def\lst@column@fixed{% - \lst@flexiblefalse - \lst@width\lst@widthfixed\relax - \let\lst@OutputLostSpace\lst@UseLostSpace - \let\lst@FillOutputBox\lst@FillFixed - \let\lst@hss\hss - \def\lst@hbox{\hbox to\lst@length\lst@width}} -\def\lst@FillFixed#1{#1\lst@FillFixed@} -\def\lst@FillFixed@#1{% - \ifx\@empty#1\else \lst@hss#1\expandafter\lst@FillFixed@ \fi} -\def\lst@column@flexible{% - \lst@flexibletrue - \lst@width\lst@widthflexible\relax - \let\lst@OutputLostSpace\lst@UseLostSpace - \let\lst@FillOutputBox\@empty - \let\lst@hss\@empty - \let\lst@hbox\hbox} -\def\lst@column@fullflexible{% - \lst@column@flexible - \def\lst@OutputLostSpace{\lst@ifnewline \lst@UseLostSpace\fi}% - \let\lst@leftinsert\@empty - \let\lst@rightinsert\@empty} -\def\lst@outputpos#1#2\relax{% - \def\lst@lefthss{\lst@hss}\let\lst@righthss\lst@lefthss - \let\lst@rightinsert\lst@InsertLostSpace - \ifx #1c% - \let\lst@leftinsert\lst@InsertHalfLostSpace - \else\ifx #1r% - \let\lst@righthss\@empty - \let\lst@leftinsert\lst@InsertLostSpace - \let\lst@rightinsert\@empty - \else - \let\lst@lefthss\@empty - \let\lst@leftinsert\@empty - \ifx #1l\else \PackageWarning{Listings}% - {Unknown positioning for output boxes}% - \fi - \fi\fi} -\def\lst@flexibletrue{\let\lst@ifflexible\iftrue} -\def\lst@flexiblefalse{\let\lst@ifflexible\iffalse} -\lst@Key{columns}{[c]fixed}{\lstKV@OptArg[]{#1}{% - \ifx\@empty##1\@empty\else \lst@outputpos##1\relax\relax \fi - \expandafter\let\expandafter\lst@arg - \csname\@lst @column@##2\endcsname - \lst@arg - \ifx\lst@arg\relax - \PackageWarning{Listings}{Unknown column format `##2'}% - \else - \lst@ifflexible - \let\lst@columnsflexible\lst@arg - \else - \let\lst@columnsfixed\lst@arg - \fi - \fi}} -\let\lst@columnsfixed\lst@column@fixed % init -\let\lst@columnsflexible\lst@column@flexible % init -\lst@Key{flexiblecolumns}\relax[t]{% - \lstKV@SetIf{#1}\lst@ifflexible - \lst@ifflexible \lst@columnsflexible - \else \lst@columnsfixed \fi} -\newcount\lst@newlines -\lst@AddToHook{InitVars}{\global\lst@newlines\z@} -\lst@AddToHook{InitVarsBOL}{\global\advance\lst@newlines\@ne} -\def\lst@NewLine{% - \ifx\lst@OutputBox\@gobble\else - \par\noindent \hbox{}% - \fi - \global\advance\lst@newlines\m@ne - \lst@newlinetrue} -\def\lst@newlinetrue{\global\let\lst@ifnewline\iftrue} -\lst@AddToHookExe{PostOutput}{\global\let\lst@ifnewline\iffalse}% init -\def\lst@TrackNewLines{% - \ifnum\lst@newlines>\z@ - \lsthk@OnNewLine - \lst@DoNewLines - \fi} -\lst@AddToHook{OnNewLine}{}% init -\lst@Key{emptylines}\maxdimen{% - \@ifstar{\lst@true\@tempcnta\@gobble#1\relax\lst@GobbleNil}% - {\lst@false\@tempcnta#1\relax\lst@GobbleNil}#1\@nil - \advance\@tempcnta\@ne - \edef\lst@maxempty{\the\@tempcnta\relax}% - \let\lst@ifpreservenumber\lst@if} -\def\lst@DoNewLines{ - \@whilenum\lst@newlines>\lst@maxempty \do - {\lst@ifpreservenumber - \lsthk@OnEmptyLine - \global\advance\c@lstnumber\lst@advancelstnum - \fi - \global\advance\lst@newlines\m@ne}% - \@whilenum \lst@newlines>\@ne \do - {\lsthk@OnEmptyLine \lst@NewLine}% - \ifnum\lst@newlines>\z@ \lst@NewLine \fi} -\lst@AddToHook{OnEmptyLine}{}% init -\lst@Key{identifierstyle}{}{\def\lst@identifierstyle{#1}} -\lst@AddToHook{EmptyStyle}{\let\lst@identifierstyle\@empty} -\def\lst@GotoTabStop{% - \ifnum\lst@newlines=\z@ - \setbox\@tempboxa\hbox{\lst@outputspace}% - \setbox\@tempboxa\hbox to\wd\@tempboxa{{\lst@currstyle{\hss}}}% - \lst@CalcLostSpaceAndOutput - \else - \global\advance\lst@lostspace \lst@length\lst@width - \global\advance\lst@column\lst@length \lst@length\z@ - \fi} -\def\lst@OutputOther{% - \lst@CheckDelay - \ifnum\lst@length=\z@\else - \let\lst@thestyle\lst@currstyle - \lsthk@OutputOther - \lst@OutputToken - \fi} -\lst@AddToHook{OutputOther}{}% init -\let\lst@currstyle\relax % init -\def\lst@Output{% - \lst@CheckDelay - \ifnum\lst@length=\z@\else - \ifx\lst@currstyle\relax - \let\lst@thestyle\lst@identifierstyle - \else - \let\lst@thestyle\lst@currstyle - \fi - \lsthk@Output - \lst@OutputToken - \fi - \let\lst@lastother\relax} -\lst@AddToHook{Output}{}% init -\def\lst@GetOutputMacro#1{% - \lst@ifletter \global\let#1\lst@Output - \else \global\let#1\lst@OutputOther\fi} -\def\lst@PrintToken{% - \lst@ifletter \lst@Output \lst@letterfalse - \else \lst@OutputOther \let\lst@lastother\@empty \fi} -\def\lst@XPrintToken{% - \lst@PrintToken \lst@CheckMerge - \ifnum\lst@length=\z@\else \lst@PrintToken \fi} -\def\lst@BeginDropOutput#1{% - \xdef\lst@BDOnewlines{\the\lst@newlines}% - \global\let\lst@BDOifnewline\lst@ifnewline - \lst@EnterMode{#1}% - {\lst@modetrue - \let\lst@OutputBox\@gobble - \aftergroup\lst@BDORestore}} -\def\lst@BDORestore{% - \global\lst@newlines\lst@BDOnewlines - \global\let\lst@ifnewline\lst@BDOifnewline} -\let\lst@EndDropOutput\lst@LeaveMode -\def\lst@ProcessLetter{\lst@whitespacefalse \lst@AppendLetter} -\def\lst@ProcessOther{\lst@whitespacefalse \lst@AppendOther} -\def\lst@ProcessDigit{% - \lst@whitespacefalse - \lst@ifletter \expandafter\lst@AppendLetter - \else \expandafter\lst@AppendOther\fi} -\def\lst@whitespacetrue{\global\let\lst@ifwhitespace\iftrue} -\def\lst@whitespacefalse{\global\let\lst@ifwhitespace\iffalse} -\lst@AddToHook{InitVarsBOL}{\lst@whitespacetrue} -\lst@Key{tabsize}{8} - {\ifnum#1>\z@ \def\lst@tabsize{#1}\else - \PackageError{Listings}{Strict positive integer expected}% - {You can't use `#1' as tabsize. \@ehc}% - \fi} -\lst@Key{showtabs}f[t]{\lstKV@SetIf{#1}\lst@ifshowtabs} -\lst@Key{tab}{\kern.06em\hbox{\vrule\@height.3ex}% - \hrulefill\hbox{\vrule\@height.3ex}} - {\def\lst@tab{#1}} -\def\lst@ProcessTabulator{% - \lst@XPrintToken \lst@whitespacetrue - \global\advance\lst@column -\lst@pos - \@whilenum \lst@pos<\@ne \do - {\global\advance\lst@pos\lst@tabsize}% - \lst@length\lst@pos - \lst@PreGotoTabStop} -\def\lst@PreGotoTabStop{% - \lst@ifshowtabs - \lst@TrackNewLines - \setbox\@tempboxa\hbox to\lst@length\lst@width - {{\lst@currstyle{\hss\lst@tab}}}% - \lst@CalcLostSpaceAndOutput - \else - \lst@ifkeepspaces - \@tempcnta\lst@length \lst@length\z@ - \@whilenum \@tempcnta>\z@ \do - {\lst@AppendOther\lst@outputspace - \advance\@tempcnta\m@ne}% - \lst@OutputOther - \else - \lst@GotoTabStop - \fi - \fi - \lst@length\z@ \global\lst@pos\z@} -\def\lst@outputspace{\ } -\def\lst@visiblespace{\lst@ttfamily{\char32}\textvisiblespace} -\lst@Key{showspaces}{false}[t]{\lstKV@SetIf{#1}\lst@ifshowspaces} -\lst@Key{keepspaces}{false}[t]{\lstKV@SetIf{#1}\lst@ifkeepspaces} -\lst@AddToHook{Init} - {\lst@ifshowspaces - \let\lst@outputspace\lst@visiblespace - \lst@keepspacestrue - \fi} -\def\lst@keepspacestrue{\let\lst@ifkeepspaces\iftrue} -\def\lst@ProcessSpace{% - \lst@ifkeepspaces - \lst@whitespacetrue - \lst@PrintToken - \lst@AppendOther\lst@outputspace - \lst@PrintToken - \else \ifnum\lst@newlines=\z@ - \lst@AppendSpecialSpace - \else \ifnum\lst@length=\z@ - \global\advance\lst@lostspace\lst@width - \global\advance\lst@pos\m@ne - \lst@whitespacetrue - \else - \lst@AppendSpecialSpace - \fi - \fi \fi} -\def\lst@AppendSpecialSpace{% - \lst@ifwhitespace - \lst@PrintToken - \global\advance\lst@lostspace\lst@width - \global\advance\lst@pos\m@ne - \lst@gobbledwhitespacetrue - \else - \lst@whitespacetrue - \lst@PrintToken - \lst@AppendOther\lst@outputspace - \lst@PrintToken - \fi} -\lst@Key{formfeed}{\bigbreak}{\def\lst@formfeed{#1}} -\def\lst@ProcessFormFeed{% - \lst@XPrintToken - \ifnum\lst@newlines=\z@ - \lst@EOLUpdate \lsthk@InitVarsBOL - \fi - \lst@formfeed - \lst@whitespacetrue} -\def\lst@Def#1{\lccode`\~=#1\lowercase{\def~}} -\def\lst@Let#1{\lccode`\~=#1\lowercase{\let~}} -\lst@AddToAtTop{\try@load@fontshape}{\def\space{ }} -\def\lst@SelectStdCharTable{% - \lst@Def{9}{\lst@ProcessTabulator}% - \lst@Def{12}{\lst@ProcessFormFeed}% - \lst@Def{32}{\lst@ProcessSpace}} -\def\lst@CCPut#1#2{% - \ifnum#2=\z@ - \expandafter\@gobbletwo - \else - \lccode`\~=#2\lccode`\/=#2\lowercase{\lst@CCPut@~{#1/}}% - \fi - \lst@CCPut#1} -\def\lst@CCPut@#1#2{\lst@lAddTo\lst@SelectStdCharTable{\def#1{#2}}} -\lst@CCPut \lst@ProcessOther - {"21}{"22}{"28}{"29}{"2B}{"2C}{"2E}{"2F} - {"3A}{"3B}{"3D}{"3F}{"5B}{"5D} - \z@ -\lst@CCPut \lst@ProcessDigit - {"30}{"31}{"32}{"33}{"34}{"35}{"36}{"37}{"38}{"39} - \z@ -\lst@CCPut \lst@ProcessLetter - {"40}{"41}{"42}{"43}{"44}{"45}{"46}{"47} - {"48}{"49}{"4A}{"4B}{"4C}{"4D}{"4E}{"4F} - {"50}{"51}{"52}{"53}{"54}{"55}{"56}{"57} - {"58}{"59}{"5A} - {"61}{"62}{"63}{"64}{"65}{"66}{"67} - {"68}{"69}{"6A}{"6B}{"6C}{"6D}{"6E}{"6F} - {"70}{"71}{"72}{"73}{"74}{"75}{"76}{"77} - {"78}{"79}{"7A} - \z@ -\def\lst@CCPutMacro#1#2#3{% - \ifnum#2=\z@ \else - \begingroup\lccode`\~=#2\relax \lccode`\/=#2\relax - \lowercase{\endgroup\expandafter\lst@CCPutMacro@ - \csname\@lst @um/\expandafter\endcsname - \csname\@lst @um/@\endcsname /~}#1{#3}% - \expandafter\lst@CCPutMacro - \fi} -\def\lst@CCPutMacro@#1#2#3#4#5#6{% - \lst@lAddTo\lst@SelectStdCharTable{\def#4{#5#1}}% - \def#1{\lst@UM#3}% - \def#2{#6}} -\def\lst@UM#1{\csname\@lst @um#1@\endcsname} -\lst@CCPutMacro - \lst@ProcessOther {"23}\# - \lst@ProcessLetter{"24}\textdollar - \lst@ProcessOther {"25}\% - \lst@ProcessOther {"26}\& - \lst@ProcessOther {"27}{\lst@ifupquote \textquotesingle - \else \char39\relax \fi} - \lst@ProcessOther {"2A}{\lst@ttfamily*\textasteriskcentered} - \lst@ProcessOther {"2D}{\lst@ttfamily{-{}}{$-$}} - \lst@ProcessOther {"3C}{\lst@ttfamily<\textless} - \lst@ProcessOther {"3E}{\lst@ttfamily>\textgreater} - \lst@ProcessOther {"5C}{\lst@ttfamily{\char92}\textbackslash} - \lst@ProcessOther {"5E}\textasciicircum - \lst@ProcessLetter{"5F}{\lst@ttfamily{\char95}\textunderscore} - \lst@ProcessOther {"60}{\lst@ifupquote \textasciigrave - \else \char96\relax \fi} - \lst@ProcessOther {"7B}{\lst@ttfamily{\char123}\textbraceleft} - \lst@ProcessOther {"7C}{\lst@ttfamily|\textbar} - \lst@ProcessOther {"7D}{\lst@ttfamily{\char125}\textbraceright} - \lst@ProcessOther {"7E}\textasciitilde - \lst@ProcessOther {"7F}- - \@empty\z@\@empty -\def\lst@ttfamily#1#2{\ifx\f@family\ttdefault#1\relax\else#2\fi} -\lst@AddToHook{Init}{\edef\ttdefault{\ttdefault}} -\lst@Key{upquote}{false}[t]{\lstKV@SetIf{#1}\lst@ifupquote - \lst@ifupquote - \@ifundefined{textasciigrave}% - {\let\KV@lst@upquote\@gobble - \lstKV@SetIf f\lst@ifupquote \@gobble\fi - \PackageError{Listings}{Option `upquote' requires `textcomp' - package.\MessageBreak The option has been disabled}% - {Add \string\usepackage{textcomp} to your preamble.}}% - {}% - \fi} -\AtBeginDocument{% - \@ifpackageloaded{upquote}{\RequirePackage{textcomp}% - \lstset{upquote}}{}% - \@ifpackageloaded{upquote2}{\lstset{upquote}}{}} -\def\lst@activecharstrue{\let\lst@ifactivechars\iftrue} -\def\lst@activecharsfalse{\let\lst@ifactivechars\iffalse} -\lst@activecharstrue -\def\lst@SelectCharTable{% - \lst@SelectStdCharTable - \lst@ifactivechars - \catcode9\active \catcode12\active \catcode13\active - \@tempcnta=32\relax - \@whilenum\@tempcnta<128\do - {\catcode\@tempcnta\active\advance\@tempcnta\@ne}% - \fi - \lst@ifec \lst@DefEC \fi - \let\do\lst@do@noligs \verbatim@nolig@list - \lsthk@SelectCharTable - \lst@DeveloperSCT -\lst@DefRange - \ifx\lst@Backslash\relax\else - \lst@LetSaveDef{"5C}\lsts@backslash\lst@Backslash - \fi} -\lst@Key{SelectCharTable}{}{\def\lst@DeveloperSCT{#1}} -\lst@Key{MoreSelectCharTable}\relax{\lst@lAddTo\lst@DeveloperSCT{#1}} -\lst@AddToHook{SetLanguage}{\let\lst@DeveloperSCT\@empty} -\def\lst@do@noligs#1{% - \begingroup \lccode`\~=`#1\lowercase{\endgroup - \lst@do@noligs@~}} -\def\lst@do@noligs@#1{% - \expandafter\expandafter\expandafter\def - \expandafter\expandafter\expandafter#1% - \expandafter\expandafter\expandafter{\expandafter\lst@NoLig#1}} -\def\lst@NoLig{\advance\lst@length\m@ne \lst@Append\lst@nolig} -\def\lst@nolig{\lst@UM\@empty}% -\@namedef{\@lst @um@}{\leavevmode\kern\z@} -\def\lst@SaveOutputDef#1#2{% - \begingroup \lccode`\~=#1\relax \lowercase{\endgroup - \def\lst@temp##1\def~##2##3\relax}{% - \global\expandafter\let\expandafter#2\@gobble##2\relax}% - \expandafter\lst@temp\lst@SelectStdCharTable\relax} -\lst@SaveOutputDef{"5C}\lstum@backslash -\lst@Key{extendedchars}{true}[t]{\lstKV@SetIf{#1}\lst@ifec} -\def\lst@DefEC{% - \lst@CCECUse \lst@ProcessLetter - ^^80^^81^^82^^83^^84^^85^^86^^87^^88^^89^^8a^^8b^^8c^^8d^^8e^^8f% - ^^90^^91^^92^^93^^94^^95^^96^^97^^98^^99^^9a^^9b^^9c^^9d^^9e^^9f% - ^^a0^^a1^^a2^^a3^^a4^^a5^^a6^^a7^^a8^^a9^^aa^^ab^^ac^^ad^^ae^^af% - ^^b0^^b1^^b2^^b3^^b4^^b5^^b6^^b7^^b8^^b9^^ba^^bb^^bc^^bd^^be^^bf% - ^^c0^^c1^^c2^^c3^^c4^^c5^^c6^^c7^^c8^^c9^^ca^^cb^^cc^^cd^^ce^^cf% - ^^d0^^d1^^d2^^d3^^d4^^d5^^d6^^d7^^d8^^d9^^da^^db^^dc^^dd^^de^^df% - ^^e0^^e1^^e2^^e3^^e4^^e5^^e6^^e7^^e8^^e9^^ea^^eb^^ec^^ed^^ee^^ef% - ^^f0^^f1^^f2^^f3^^f4^^f5^^f6^^f7^^f8^^f9^^fa^^fb^^fc^^fd^^fe^^ff% - ^^00} -\def\lst@CCECUse#1#2{% - \ifnum`#2=\z@ - \expandafter\@gobbletwo - \else - \ifnum\catcode`#2=\active - \lccode`\~=`#2\lccode`\/=`#2\lowercase{\lst@CCECUse@#1~/}% - \else - \lst@ifactivechars \catcode`#2=\active \fi - \lccode`\~=`#2\lccode`\/=`#2\lowercase{\def~{#1/}}% - \fi - \fi - \lst@CCECUse#1} -\def\lst@CCECUse@#1#2#3{% - \expandafter\def\csname\@lst @EC#3\endcsname{\lst@UM#3}% - \expandafter\let\csname\@lst @um#3@\endcsname #2% - \edef#2{\noexpand#1% - \expandafter\noexpand\csname\@lst @EC#3\endcsname}} -\lst@AddToHook{Init} - {\let\lsts@nfss@catcodes\nfss@catcodes - \let\nfss@catcodes\lst@nfss@catcodes} -\def\lst@nfss@catcodes{% - \lst@makeletter - ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\relax - \@makeother (\@makeother )\@makeother ,\@makeother :\@makeother\&% - \@makeother 0\@makeother 1\@makeother 2\@makeother 3\@makeother 4% - \@makeother 5\@makeother 6\@makeother 7\@makeother 8\@makeother 9% - \@makeother =\lsts@nfss@catcodes} -\def\lst@makeletter#1{% - \ifx\relax#1\else\catcode`#111\relax \expandafter\lst@makeletter\fi} -\lst@Key{useoutput}{2}{\edef\lst@useoutput{\ifcase#10 0\or 1\else 2\fi}} -\lst@AddToHook{Init} -{\edef\lst@OrgOutput{\the\output}% -\ifcase\lst@useoutput\relax -\or - \output{\global\setbox\lst@gtempboxa\box\@cclv - \expandafter\egroup - \lst@SaveToken - \lst@InterruptModes - \setbox\@cclv\box\lst@gtempboxa - \bgroup\lst@OrgOutput\egroup - \bgroup - \aftergroup\pagegoal\aftergroup\vsize - \aftergroup\lst@ReenterModes\aftergroup\lst@RestoreToken}% -\else - \output{\lst@RestoreOrigCatcodes - \lst@ifec \lst@RestoreOrigExtendedCatcodes \fi - \lst@OrgOutput}% -\fi} -\def\lst@GetChars#1#2#3{% - \let#1\@empty - \@tempcnta#2\relax \@tempcntb#3\relax - \loop \ifnum\@tempcnta<\@tempcntb\relax - \lst@lExtend#1{\expandafter\catcode\the\@tempcnta=}% - \lst@lExtend#1{\the\catcode\@tempcnta\relax}% - \ifnum\the\catcode\@tempcnta=\active - \begingroup\lccode`\~=\@tempcnta - \lowercase{\endgroup - \lst@lExtend#1{\expandafter\let\expandafter~\csname - lstecs@\the\@tempcnta\endcsname}% - \expandafter\let\csname lstecs@\the\@tempcnta\endcsname~}% - \fi - \advance\@tempcnta\@ne - \repeat} -\def\lst@ScanChars{% - \lst@GetChars\lst@RestoreOrigCatcodes\@ne {128}% - \lst@GetChars\lst@RestoreOrigExtendedCatcodes{128}{256}} -\lst@Key{rescanchars}\relax{\lst@ScanChars} -\AtBeginDocument{\lst@ScanChars} -\lst@Key{alsoletter}\relax{% - \lst@DoAlso{#1}\lst@alsoletter\lst@ProcessLetter} -\lst@Key{alsodigit}\relax{% - \lst@DoAlso{#1}\lst@alsodigit\lst@ProcessDigit} -\lst@Key{alsoother}\relax{% - \lst@DoAlso{#1}\lst@alsoother\lst@ProcessOther} -\lst@AddToHook{SelectCharTable} - {\lst@alsoother \lst@alsodigit \lst@alsoletter} -\lst@AddToHookExe{SetLanguage}% init - {\let\lst@alsoletter\@empty - \let\lst@alsodigit\@empty - \let\lst@alsoother\@empty} -\def\lst@DoAlso#1#2#3{% - \lst@DefOther\lst@arg{#1}\let#2\@empty - \expandafter\lst@DoAlso@\expandafter#2\expandafter#3\lst@arg\relax} -\def\lst@DoAlso@#1#2#3{% - \ifx\relax#3\expandafter\@gobblethree \else - \begingroup \lccode`\~=`#3\relax \lowercase{\endgroup - \def\lst@temp##1\def~##2##3\relax{% - \edef\lst@arg{\def\noexpand~{\noexpand#2\expandafter - \noexpand\@gobble##2}}}}% - \expandafter\lst@temp\lst@SelectStdCharTable\relax - \lst@lExtend#1{\lst@arg}% - \fi - \lst@DoAlso@#1#2} -\def\lst@SaveDef#1#2{% - \begingroup \lccode`\~=#1\relax \lowercase{\endgroup\let#2~}} -\def\lst@DefSaveDef#1#2{% - \begingroup \lccode`\~=#1\relax \lowercase{\endgroup\let#2~\def~}} -\def\lst@LetSaveDef#1#2{% - \begingroup \lccode`\~=#1\relax \lowercase{\endgroup\let#2~\let~}} -\def\lst@CDef#1{\lst@CDef@#1} -\def\lst@CDef@#1#2#3#4{\lst@CDefIt#1{#2}{#3}{#4#2#3}#4} -\def\lst@CDefX#1{\lst@CDefX@#1} -\def\lst@CDefX@#1#2#3{\lst@CDefIt#1{#2}{#3}{}} -\def\lst@CDefIt#1#2#3#4#5#6#7#8{% - \ifx\@empty#2\@empty - \def#1{#6\def\lst@next{#7#4#8}\lst@next}% - \else \ifx\@empty#3\@empty - \def#1##1{% - #6% - \ifx##1#2\def\lst@next{#7#4#8}\else - \def\lst@next{#5##1}\fi - \lst@next}% - \else - \def#1{% - #6% - \lst@IfNextCharsArg{#2#3}{#7#4#8}% - {\expandafter#5\lst@eaten}}% - \fi \fi} -\def\lst@CArgX#1#2\relax{% - \lst@DefActive\lst@arg{#1#2}% - \expandafter\lst@CArg\lst@arg\relax} -\def\lst@CArg#1#2\relax{% - \lccode`\/=`#1\lowercase{\def\lst@temp{/}}% - \lst@GetFreeMacro{lst@c\lst@temp}% - \expandafter\lst@CArg@\lst@freemacro#1#2\@empty\@empty\relax} -\def\lst@CArg@#1#2#3#4\@empty#5\relax#6{% - \let#1#2% - \ifx\@empty#3\@empty - \def\lst@next{#6{#2{}{}}}% - \else - \def\lst@next{#6{#2#3{#4}}}% - \fi - \lst@next #1} -\def\lst@CArgEmpty#1\@empty{#1} -\lst@Key{excludedelims}\relax - {\lsthk@ExcludeDelims \lst@NormedDef\lst@temp{#1}% - \expandafter\lst@for\lst@temp\do - {\expandafter\let\csname\@lst @ifex##1\endcsname\iftrue}} -\def\lst@DelimPrint#1#2{% - #1% - \begingroup - \lst@mode\lst@nomode \lst@modetrue - #2\lst@XPrintToken - \endgroup - \lst@ResetToken - \fi} -\def\lst@DelimOpen#1#2#3#4#5#6\@empty{% - \lst@TrackNewLines \lst@XPrintToken - \lst@DelimPrint#1{#6}% - \lst@EnterMode{#4}{\def\lst@currstyle#5}% - \lst@DelimPrint{#1#2}{#6}% - #3} -\def\lst@DelimClose#1#2#3\@empty{% - \lst@TrackNewLines \lst@XPrintToken - \lst@DelimPrint{#1#2}{#3}% - \lst@LeaveMode - \lst@DelimPrint{#1}{#3}} -\def\lst@BeginDelim{\lst@DelimOpen\iffalse\else{}} -\def\lst@EndDelim{\lst@DelimClose\iffalse\else} -\def\lst@BeginIDelim{\lst@DelimOpen\iffalse{}{}} -\def\lst@EndIDelim{\lst@DelimClose\iffalse{}} -\lst@AddToHook{SelectCharTable}{\lst@DefDelims} -\lst@AddToHookExe{SetLanguage}{\let\lst@DefDelims\@empty} -\def\lst@Delim#1{% - \lst@false \let\lst@cumulative\@empty \let\lst@arg\@empty - \@ifstar{\@ifstar{\lst@Delim@{#1}}% - {\let\lst@cumulative\relax - \lst@Delim@{#1}}}% - {\lst@true\lst@Delim@{#1}}} -\def\lst@Delim@#1[#2]{% - \gdef\lst@delimtype{#2}% - \@ifnextchar[\lst@Delim@sty - {\lst@Delim@sty[#1]}} -\def\lst@Delim@sty[#1]{% - \def\lst@delimstyle{#1}% - \ifx\@empty#1\@empty\else - \lst@Delim@sty@ #1\@nil - \fi - \@ifnextchar[\lst@Delim@option - \lst@Delim@delim} -\def\lst@Delim@option[#1]{\def\lst@arg{[#1]}\lst@Delim@delim} -\def\lst@Delim@sty@#1#2\@nil{% - \if\relax\noexpand#1\else - \edef\lst@delimstyle{\expandafter\noexpand - \csname\@lst @\lst@delimstyle\endcsname}% - \fi} -\def\lst@Delim@delim#1\relax#2#3#4#5#6#7#8{% - \ifx #4\@empty \lst@Delim@delall{#2}\fi - \ifx\@empty#1\@empty - \ifx #4\@nil - \@ifundefined{\@lst @#2DM@\lst@delimtype}% - {\lst@Delim@delall{#2@\lst@delimtype}}% - {\lst@Delim@delall{#2DM@\lst@delimtype}}% - \fi - \else - \expandafter\lst@Delim@args\expandafter - {\lst@delimtype}{#1}{#5}#6{#7}{#8}#4% - \let\lst@delim\@empty - \expandafter\lst@IfOneOf\lst@delimtype\relax#3% - {\@ifundefined{\@lst @#2DM@\lst@delimtype}% - {\lst@lExtend\lst@delim{\csname\@lst @#2@\lst@delimtype - \expandafter\endcsname\lst@arg}}% - {\lst@lExtend\lst@delim{\expandafter\lst@UseDynamicMode - \csname\@lst @#2DM@\lst@delimtype - \expandafter\endcsname\lst@arg}}% - \ifx #4\@nil - \let\lst@temp\lst@DefDelims \let\lst@DefDelims\@empty - \expandafter\lst@Delim@del\lst@temp\@empty\@nil\@nil\@nil - \else - \lst@lExtend\lst@DefDelims\lst@delim - \fi}% - {\PackageError{Listings}{Illegal type `\lst@delimtype'}% - {#2 types are #3.}}% - \fi} -\def\lst@Delim@args#1#2#3#4#5#6#7{% - \begingroup - \lst@false \let\lst@next\lst@XConvert - \@ifnextchar #4{\xdef\lst@delimtype{\expandafter\@gobble - \lst@delimtype}% - #5\lst@next#2\@nil - \lst@lAddTo\lst@arg{\@empty#6}% - \lst@GobbleNil}% - {\lst@next#2\@nil - \lst@lAddTo\lst@arg{\@empty#3}% - \lst@GobbleNil}% - #1\@nil - \global\let\@gtempa\lst@arg - \endgroup - \let\lst@arg\@gtempa - \ifx #7\@nil\else - \expandafter\lst@Delim@args@\expandafter{\lst@delimstyle}% - \fi} -\def\lst@Delim@args@#1{% - \lst@if - \lst@lAddTo\lst@arg{{{#1}\lst@modetrue}}% - \else - \ifx\lst@cumulative\@empty - \lst@lAddTo\lst@arg{{{}#1}}% - \else - \lst@lAddTo\lst@arg{{{#1}}}% - \fi - \fi} -\def\lst@Delim@del#1\@empty#2#3#4{% - \ifx #2\@nil\else - \def\lst@temp{#1\@empty#2#3}% - \ifx\lst@temp\lst@delim\else - \lst@lAddTo\lst@DefDelims{#1\@empty#2#3{#4}}% - \fi - \expandafter\lst@Delim@del - \fi} -\def\lst@Delim@delall#1{% - \begingroup - \edef\lst@delim{\expandafter\string\csname\@lst @#1\endcsname}% - \lst@false \global\let\@gtempa\@empty - \expandafter\lst@Delim@delall@\lst@DefDelims\@empty - \endgroup - \let\lst@DefDelims\@gtempa} -\def\lst@Delim@delall@#1{% - \ifx #1\@empty\else - \ifx #1\lst@UseDynamicMode - \lst@true - \let\lst@next\lst@Delim@delall@do - \else - \def\lst@next{\lst@Delim@delall@do#1}% - \fi - \expandafter\lst@next - \fi} -\def\lst@Delim@delall@do#1#2\@empty#3#4#5{% - \expandafter\lst@IfSubstring\expandafter{\lst@delim}{\string#1}% - {}% - {\lst@if \lst@AddTo\@gtempa\lst@UseDynamicMode \fi - \lst@AddTo\@gtempa{#1#2\@empty#3#4{#5}}}% - \lst@false \lst@Delim@delall@} -\gdef\lst@DefDelimB#1#2#3#4#5#6#7#8{% - \lst@CDef{#1}#2% - {#3}% - {\let\lst@bnext\lst@CArgEmpty - \lst@ifmode #4\else - #5% - \def\lst@bnext{#6{#7}{#8}}% - \fi - \lst@bnext}% - \@empty} -\gdef\lst@DefDelimE#1#2#3#4#5#6#7{% - \lst@CDef{#1}#2% - {#3}% - {\let\lst@enext\lst@CArgEmpty - \ifnum #7=\lst@mode% - #4% - \let\lst@enext#6% - \else - #5% - \fi - \lst@enext}% - \@empty} -\lst@AddToHook{Init}{\let\lst@bnext\relax \let\lst@enext\relax} -\gdef\lst@DefDelimBE#1#2#3#4#5#6#7#8#9{% - \lst@CDef{#1}#2% - {#3}% - {\let\lst@bnext\lst@CArgEmpty - \ifnum #7=\lst@mode - #4% - \let\lst@bnext#9% - \else - \lst@ifmode\else - #5% - \def\lst@bnext{#6{#7}{#8}}% - \fi - \fi - \lst@bnext}% - \@empty} -\gdef\lst@delimtypes{s,l} -\gdef\lst@DelimKey#1#2{% - \lst@Delim{}#2\relax - {Delim}\lst@delimtypes #1% - {\lst@BeginDelim\lst@EndDelim} - i\@empty{\lst@BeginIDelim\lst@EndIDelim}} -\lst@Key{delim}\relax{\lst@DelimKey\@empty{#1}} -\lst@Key{moredelim}\relax{\lst@DelimKey\relax{#1}} -\lst@Key{deletedelim}\relax{\lst@DelimKey\@nil{#1}} -\gdef\lst@DelimDM@l#1#2\@empty#3#4#5{% - \lst@CArg #2\relax\lst@DefDelimB{}{}{}#3{#1}{#5\lst@Lmodetrue}} -\gdef\lst@DelimDM@s#1#2#3\@empty#4#5#6{% - \lst@CArg #2\relax\lst@DefDelimB{}{}{}#4{#1}{#6}% - \lst@CArg #3\relax\lst@DefDelimE{}{}{}#5{#1}} -\def\lst@ReplaceInput#1{\lst@CArgX #1\relax\lst@CDefX{}{}} -\def\lst@Literatekey#1\@nil@{\let\lst@ifxliterate\lst@if - \def\lst@literate{#1}} -\lst@Key{literate}{}{\@ifstar{\lst@true \lst@Literatekey} - {\lst@false\lst@Literatekey}#1\@nil@} -\lst@AddToHook{SelectCharTable} - {\ifx\lst@literate\@empty\else - \expandafter\lst@Literate\lst@literate{}\relax\z@ - \fi} -\def\lst@Literate#1#2#3{% - \ifx\relax#2\@empty\else - \lst@CArgX #1\relax\lst@CDef - {} - {\let\lst@next\@empty - \lst@ifxliterate - \lst@ifmode \let\lst@next\lst@CArgEmpty \fi - \fi - \ifx\lst@next\@empty - \ifx\lst@OutputBox\@gobble\else - \lst@XPrintToken \let\lst@scanmode\lst@scan@m - \lst@token{#2}\lst@length#3\relax - \lst@XPrintToken - \fi - \let\lst@next\lst@CArgEmptyGobble - \fi - \lst@next}% - \@empty - \expandafter\lst@Literate - \fi} -\def\lst@CArgEmptyGobble#1\@empty{} -\def\lst@BeginDropInput#1{% - \lst@EnterMode{#1}% - {\lst@modetrue - \let\lst@OutputBox\@gobble - \let\lst@ifdropinput\iftrue - \let\lst@ProcessLetter\@gobble - \let\lst@ProcessDigit\@gobble - \let\lst@ProcessOther\@gobble - \let\lst@ProcessSpace\@empty - \let\lst@ProcessTabulator\@empty - \let\lst@ProcessFormFeed\@empty}} -\let\lst@ifdropinput\iffalse % init -\lst@Key{basicstyle}\relax{\def\lst@basicstyle{#1}} -\lst@Key{inputencoding}\relax{\def\lst@inputenc{#1}} -\lst@AddToHook{Init} - {\lst@basicstyle - \ifx\lst@inputenc\@empty\else - \@ifundefined{inputencoding}{}% - {\inputencoding\lst@inputenc}% - \fi} -\lst@AddToHookExe{EmptyStyle} - {\let\lst@basicstyle\@empty - \let\lst@inputenc\@empty} -\def\lst@parshape{\parshape\@ne \z@ \linewidth} -\lst@AddToHookAtTop{EveryLine}{\lst@parshape} -\lst@AddToHookAtTop{EndGroup}{\lst@parshape} -\newcount\lst@lineno % \global -\lst@AddToHook{InitVars}{\global\lst@lineno\@ne} -\lst@Key{print}{true}[t]{\lstKV@SetIf{#1}\lst@ifprint} -\lst@Key{firstline}\relax{\def\lst@firstline{#1\relax}} -\lst@Key{lastline}\relax{\def\lst@lastline{#1\relax}} -\lst@AddToHook{PreSet} - {\let\lst@firstline\@ne \def\lst@lastline{9999999\relax}} -\lst@Key{linerange}\relax{\lstKV@OptArg[]{#1}{% - \def\lst@interrange{##1}\def\lst@linerange{##2,}}} -\lst@AddToHook{PreSet}{\def\lst@firstline{1\relax}% - \let\lst@linerange\@empty} -\lst@AddToHook{Init} -{\ifx\lst@linerange\@empty - \edef\lst@linerange{{\lst@firstline}-{\lst@lastline},}% - \fi - \lst@GetLineInterval}% -\def\lst@GetLineInterval{\expandafter\lst@GLI\lst@linerange\@nil} -\def\lst@GLI#1,#2\@nil{\def\lst@linerange{#2}\lst@GLI@#1--\@nil} -\def\lst@GLI@#1-#2-#3\@nil{% - \ifx\@empty#1\@empty - \let\lst@firstline\@ne - \else - \def\lst@firstline{#1\relax}% - \fi - \ifx\@empty#2\@empty - \def\lst@lastline{9999999\relax}% - \else - \ifx -#2% - \let\lst@lastline\lst@firstline - \else - \def\lst@lastline{#2\relax}% - \fi - \fi} -\lst@Key{nolol}{false}[t]{\lstKV@SetIf{#1}\lst@ifnolol} -\def\lst@nololtrue{\let\lst@ifnolol\iftrue} -\let\lst@ifnolol\iffalse % init -\lst@Key{captionpos}{t}{\def\lst@captionpos{#1}} -\lst@Key{abovecaptionskip}\smallskipamount{\def\lst@abovecaption{#1}} -\lst@Key{belowcaptionskip}\smallskipamount{\def\lst@belowcaption{#1}} -\lst@Key{label}\relax{\def\lst@label{#1}} -\lst@Key{title}\relax{\def\lst@title{#1}\let\lst@caption\relax} -\lst@Key{caption}\relax{\lstKV@OptArg[{#1}]{#1}% - {\def\lst@caption{##2}\def\lst@@caption{##1}}% - \let\lst@title\@empty} -\lst@AddToHookExe{TextStyle} - {\let\lst@caption\@empty \let\lst@@caption\@empty - \let\lst@title\@empty \let\lst@label\@empty} -\@ifundefined{thechapter} - {\newcounter{lstlisting} - \renewcommand\thelstlisting{\@arabic\c@lstlisting}} - {\newcounter{lstlisting}[chapter] - \renewcommand\thelstlisting - {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@lstlisting}} -\lst@UserCommand\lstlistingname{Listing} -\@ifundefined{abovecaptionskip} -{\newskip\abovecaptionskip - \newskip\belowcaptionskip}{} -\@ifundefined{@makecaption} -{\long\def\@makecaption#1#2{% - \vskip\abovecaptionskip - \sbox\@tempboxa{#1: #2}% - \ifdim \wd\@tempboxa >\hsize - #1: #2\par - \else - \global \@minipagefalse - \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}% - \fi - \vskip\belowcaptionskip}% -}{} -\def\fnum@lstlisting{% - \lstlistingname - \ifx\lst@@caption\@empty\else~\thelstlisting\fi}% -\def\lst@MakeCaption#1{% - \lst@ifdisplaystyle - \ifx #1t% - \ifx\lst@@caption\@empty\expandafter\lst@HRefStepCounter \else - \expandafter\refstepcounter - \fi {lstlisting}% - \ifx\lst@label\@empty\else \label{\lst@label}\fi - \let\lst@arg\lst@intname \lst@ReplaceIn\lst@arg\lst@filenamerpl - \global\let\lst@name\lst@arg \global\let\lstname\lst@name - \lst@ifnolol\else - \ifx\lst@@caption\@empty - \ifx\lst@caption\@empty - \ifx\lst@intname\@empty \else \def\lst@temp{ }% - \ifx\lst@intname\lst@temp \else - \addcontentsline{lol}{lstlisting}\lst@name - \fi\fi - \fi - \else - \addcontentsline{lol}{lstlisting}% - {\protect\numberline{\thelstlisting}\lst@@caption}% - \fi - \fi - \fi - \ifx\lst@caption\@empty\else - \lst@IfSubstring #1\lst@captionpos - {\begingroup \let\@@vskip\vskip - \def\vskip{\afterassignment\lst@vskip \@tempskipa}% - \def\lst@vskip{\nobreak\@@vskip\@tempskipa\nobreak}% - \par\@parboxrestore\normalsize\normalfont % \noindent (AS) - \ifx #1t\allowbreak \fi - \ifx\lst@title\@empty - \lst@makecaption\fnum@lstlisting\lst@caption % (AS) - \else - \lst@maketitle\lst@title % (AS) - \fi - \ifx #1b\allowbreak \fi - \endgroup}{}% - \fi - \fi} -\def\lst@makecaption{\@makecaption} -\def\lst@maketitle{\@makecaption\lst@title@dropdelim} -\def\lst@title@dropdelim#1{\ignorespaces} -\AtBeginDocument{% -\@ifundefined{captionlabelfalse}{}{% - \def\lst@maketitle{\captionlabelfalse\@makecaption\@empty}}% -\@ifundefined{caption@startrue}{}{% - \def\lst@maketitle{\caption@startrue\@makecaption\@empty}}% -} -\def\lst@HRefStepCounter#1{% - \begingroup - \c@lstlisting\lst@neglisting - \advance\c@lstlisting\m@ne \xdef\lst@neglisting{\the\c@lstlisting}% - \ifx\hyper@refstepcounter\@undefined\else - \hyper@refstepcounter{#1}% - \fi - \endgroup} -\gdef\lst@neglisting{\z@}% init -\lst@Key{boxpos}{c}{\def\lst@boxpos{#1}} -\def\lst@boxtrue{\let\lst@ifbox\iftrue} -\let\lst@ifbox\iffalse -\lst@Key{float}\relax[\lst@floatplacement]{% - \lstKV@SwitchCases{#1}% - {true&\let\lst@floatdefault\lst@floatplacement - \let\lst@float\lst@floatdefault\\% - false&\let\lst@floatdefault\relax - \let\lst@float\lst@floatdefault - }{\def\lst@next{\@ifstar{\let\lst@beginfloat\@dblfloat - \let\lst@endfloat\end@dblfloat - \lst@KFloat}% - {\let\lst@beginfloat\@float - \let\lst@endfloat\end@float - \lst@KFloat}} - \edef\lst@float{#1}% - \expandafter\lst@next\lst@float\relax}} -\def\lst@KFloat#1\relax{% - \ifx\@empty#1\@empty - \let\lst@float\lst@floatplacement - \else - \def\lst@float{#1}% - \fi} -\lst@Key{floatplacement}{tbp}{\def\lst@floatplacement{#1}} -\lst@AddToHook{PreSet}{\let\lst@float\lst@floatdefault} -\lst@AddToHook{TextStyle}{\let\lst@float\relax} -\let\lst@floatdefault\relax % init -\lst@AddToHook{DeInit}{% - \ifx\lst@float\relax - \global\let\lst@doendpe\@doendpe - \else - \global\let\lst@doendpe\@empty - \fi} -\AtBeginDocument{% -\@ifundefined{c@float@type}% - {\edef\ftype@lstlisting{\ifx\c@figure\@undefined 1\else 4\fi}} - {\edef\ftype@lstlisting{\the\c@float@type}% - \addtocounter{float@type}{\value{float@type}}}% -} -\lst@Key{aboveskip}\medskipamount{\def\lst@aboveskip{#1}} -\lst@Key{belowskip}\medskipamount{\def\lst@belowskip{#1}} -\lst@AddToHook{TextStyle} - {\let\lst@aboveskip\z@ \let\lst@belowskip\z@} -\lst@Key{everydisplay}{}{\def\lst@EveryDisplay{#1}} -\lst@AddToHook{TextStyle}{\let\lst@ifdisplaystyle\iffalse} -\lst@AddToHook{DisplayStyle}{\let\lst@ifdisplaystyle\iftrue} -\let\lst@ifdisplaystyle\iffalse -\def\lst@Init#1{% - \begingroup - \ifx\lst@float\relax\else - \edef\@tempa{\noexpand\lst@beginfloat{lstlisting}[\lst@float]}% - \expandafter\@tempa - \fi - \ifhmode\ifinner \lst@boxtrue \fi\fi - \lst@ifbox - \lsthk@BoxUnsafe - \hbox to\z@\bgroup - $\if t\lst@boxpos \vtop - \else \if b\lst@boxpos \vbox - \else \vcenter \fi\fi - \bgroup \par\noindent - \else - \lst@ifdisplaystyle - \lst@EveryDisplay - \par\penalty-50\relax - \vspace\lst@aboveskip - \fi - \fi - \normalbaselines - \abovecaptionskip\lst@abovecaption\relax - \belowcaptionskip\lst@belowcaption\relax - \lst@MakeCaption t% - \lsthk@PreInit \lsthk@Init - \lst@ifdisplaystyle - \global\let\lst@ltxlabel\@empty - \if@inlabel - \lst@ifresetmargins - \leavevmode - \else - \xdef\lst@ltxlabel{\the\everypar}% - \lst@AddTo\lst@ltxlabel{% - \global\let\lst@ltxlabel\@empty - \everypar{\lsthk@EveryLine\lsthk@EveryPar}}% - \fi - \fi - \everypar\expandafter{\lst@ltxlabel - \lsthk@EveryLine\lsthk@EveryPar}% - \else - \everypar{}\let\lst@NewLine\@empty - \fi - \lsthk@InitVars \lsthk@InitVarsBOL - \lst@Let{13}\lst@MProcessListing - \let\lst@Backslash#1% - \lst@EnterMode{\lst@Pmode}{\lst@SelectCharTable}% - \lst@InitFinalize} -\let\lst@InitFinalize\@empty % init -\lst@AddToHook{PreInit} - {\rightskip\z@ \leftskip\z@ \parfillskip=\z@ plus 1fil - \let\par\@@par} -\lst@AddToHook{EveryLine}{}% init -\lst@AddToHook{EveryPar}{}% init -\lst@Key{showlines}f[t]{\lstKV@SetIf{#1}\lst@ifshowlines} -\def\lst@DeInit{% - \lst@XPrintToken \lst@EOLUpdate - \global\advance\lst@newlines\m@ne - \lst@ifshowlines - \lst@DoNewLines - \else - \setbox\@tempboxa\vbox{\lst@DoNewLines}% - \fi - \lst@ifdisplaystyle \par\removelastskip \fi - \lsthk@ExitVars\everypar{}\lsthk@DeInit\normalbaselines\normalcolor - \lst@MakeCaption b% - \lst@ifbox - \egroup $\hss \egroup - \vrule\@width\lst@maxwidth\@height\z@\@depth\z@ - \else - \lst@ifdisplaystyle - \par\penalty-50\vspace\lst@belowskip - \fi - \fi - \ifx\lst@float\relax\else - \expandafter\lst@endfloat - \fi - \endgroup} -\newdimen\lst@maxwidth % \global -\lst@AddToHook{InitVars}{\global\lst@maxwidth\z@} -\lst@AddToHook{InitVarsEOL} - {\ifdim\lst@currlwidth>\lst@maxwidth - \global\lst@maxwidth\lst@currlwidth - \fi} -\def\lst@EOLUpdate{\lsthk@EOL \lsthk@InitVarsEOL} -\def\lst@MProcessListing{% - \lst@XPrintToken \lst@EOLUpdate \lsthk@InitVarsBOL - \global\advance\lst@lineno\@ne - \ifnum \lst@lineno>\lst@lastline - \lst@ifdropinput \lst@LeaveMode \fi - \ifx\lst@linerange\@empty - \expandafter\expandafter\expandafter\lst@EndProcessListing - \else - \lst@interrange - \lst@GetLineInterval - \expandafter\expandafter\expandafter\lst@SkipToFirst - \fi - \else - \expandafter\lst@BOLGobble - \fi} -\let\lst@EndProcessListing\endinput -\lst@Key{gobble}{0}{\def\lst@gobble{#1}} -\def\lst@BOLGobble{% - \ifnum\lst@gobble>\z@ - \@tempcnta\lst@gobble\relax - \expandafter\lst@BOLGobble@ -\fi} -\def\lst@BOLGobble@@{% - \ifnum\@tempcnta>\z@ - \expandafter\lst@BOLGobble@ - \fi} -\def\lstenv@BOLGobble@@{% - \lst@IfNextChars\lstenv@endstring{\lstenv@End}% - {\advance\@tempcnta\m@ne \expandafter\lst@BOLGobble@@\lst@eaten}} -\def\lst@BOLGobble@#1{% - \let\lst@next#1% - \ifx \lst@next\relax\else - \ifx \lst@next\lst@MProcessListing\else - \ifx \lst@next\lst@processformfeed\else - \ifx \lst@next\lstenv@backslash - \let\lst@next\lstenv@BOLGobble@@ - \else - \let\lst@next\lst@BOLGobble@@ - \ifx #1\lst@processtabulator - \advance\@tempcnta-\lst@tabsize\relax - \ifnum\@tempcnta<\z@ - \lst@length-\@tempcnta \lst@PreGotoTabStop - \fi - \else - \advance\@tempcnta\m@ne - \fi - \fi \fi \fi \fi - \lst@next} -\def\lst@processformfeed{\lst@ProcessFormFeed} -\def\lst@processtabulator{\lst@ProcessTabulator} -\lst@Key{name}\relax{\def\lst@intname{#1}} -\lst@AddToHookExe{PreSet}{\global\let\lst@intname\@empty} -\lst@AddToHook{PreInit}{% - \let\lst@arg\lst@intname \lst@ReplaceIn\lst@arg\lst@filenamerpl - \global\let\lst@name\lst@arg \global\let\lstname\lst@name} -\def\lst@filenamerpl{_\textunderscore $\textdollar -\textendash} -\def\l@lstlisting#1#2{\@dottedtocline{1}{1.5em}{2.3em}{#1}{#2}} -\lst@UserCommand\lstlistlistingname{Listings} -\lst@UserCommand\lstlistoflistings{\bgroup - \let\contentsname\lstlistlistingname - \let\lst@temp\@starttoc \def\@starttoc##1{\lst@temp{lol}}% - \tableofcontents \egroup} -\@ifpackageloaded{scrlfile} -{\newcommand*\lol@heading{\float@listhead{\lstlistlistingname}} - \renewcommand*\lstlistoflistings{% - \begingroup% - \if@twocolumn - \@restonecoltrue\onecolumn - \else - \@restonecolfalse - \fi - \lol@heading% - \@parskipfalse\@parskip@indent% - \@starttoc{lol}% - \if@restonecol\twocolumn\fi - \endgroup}% -}{} -\newcommand\lstinline[1][]{% - \leavevmode\bgroup % \hbox\bgroup --> \bgroup - \def\lst@boxpos{b}% - \lsthk@PreSet\lstset{flexiblecolumns,#1}% - \lsthk@TextStyle - \@ifnextchar\bgroup{\afterassignment\lst@InlineG \let\@let@token}% - \lstinline@} -\def\lstinline@#1{% - \lst@Init\relax - \lst@IfNextCharActive{\lst@InlineM#1}{\lst@InlineJ#1}} -\lst@AddToHook{TextStyle}{}% init -\lst@AddToHook{SelectCharTable}{\lst@inlinechars} -\global\let\lst@inlinechars\@empty -\def\lst@InlineM#1{\gdef\lst@inlinechars{% - \lst@Def{`#1}{\lst@DeInit\egroup\global\let\lst@inlinechars\@empty}% - \lst@Def{13}{\lst@DeInit\egroup \global\let\lst@inlinechars\@empty - \PackageError{Listings}{lstinline ended by EOL}\@ehc}}% - \lst@inlinechars} -\def\lst@InlineJ#1{% - \def\lst@temp##1#1{% - \let\lst@arg\@empty \lst@InsideConvert{##1}\lst@arg - \lst@DeInit\egroup}% - \lst@temp} -\def\lst@InlineG{% - \lst@Init\relax - \lst@IfNextCharActive{\lst@InlineM\}}% - {\let\lst@arg\@empty \lst@InlineGJ}} -\def\lst@InlineGJ{\futurelet\@let@token\lst@InlineGJTest} -\def\lst@InlineGJTest{% - \ifx\@let@token\egroup - \afterassignment\lst@InlineGJEnd - \expandafter\let\expandafter\@let@token - \else - \ifx\@let@token\@sptoken - \let\lst@next\lst@InlineGJReadSp - \else - \let\lst@next\lst@InlineGJRead - \fi - \expandafter\lst@next - \fi} -\def\lst@InlineGJEnd{\lst@arg\lst@DeInit\egroup} -\def\lst@InlineGJRead#1{% - \lccode`\~=`#1\lowercase{\lst@lAddTo\lst@arg~}% - \lst@InlineGJ} -\def\lst@InlineGJReadSp#1{% - \lccode`\~=`\ \lowercase{\lst@lAddTo\lst@arg~}% - \lst@InlineGJ#1} -\def\lst@MakePath#1{\ifx\@empty#1\@empty\else\lst@MakePath@#1/\@nil/\fi} -\def\lst@MakePath@#1/{#1/\lst@MakePath@@} -\def\lst@MakePath@@#1/{% - \ifx\@nil#1\expandafter\@gobble - \else \ifx\@empty#1\else #1/\fi \fi - \lst@MakePath@@} -\lst@Key{inputpath}{}{\edef\lst@inputpath{\lst@MakePath{#1}}} -\def\lstinputlisting{% - \begingroup \lst@setcatcodes \lst@inputlisting} -\newcommand\lst@inputlisting[2][]{% - \endgroup - \def\lst@set{#1}% - \IfFileExists{\lst@inputpath#2}% - {\expandafter\lst@InputListing\expandafter{\lst@inputpath#2}}% - {\filename@parse{\lst@inputpath#2}% - \edef\reserved@a{\noexpand\lst@MissingFileError - {\filename@area\filename@base}% - {\ifx\filename@ext\relax tex\else\filename@ext\fi}}% - \reserved@a}% - \lst@doendpe \@newlistfalse \ignorespaces} -\def\lst@MissingFileError#1#2{% - \typeout{^^J! Package Listings Error: File `#1(.#2)' not found.^^J% - ^^JType X to quit or to proceed,^^J% - or enter new name. (Default extension: #2)^^J}% - \message{Enter file name: }% - {\endlinechar\m@ne \global\read\m@ne to\@gtempa}% - \ifx\@gtempa\@empty \else - \def\reserved@a{x}\ifx\reserved@a\@gtempa\batchmode\@@end\fi - \def\reserved@a{X}\ifx\reserved@a\@gtempa\batchmode\@@end\fi - \filename@parse\@gtempa - \edef\filename@ext{% - \ifx\filename@ext\relax#2\else\filename@ext\fi}% - \edef\reserved@a{\noexpand\IfFileExists % - {\filename@area\filename@base.\filename@ext}% - {\noexpand\lst@InputListing % - {\filename@area\filename@base.\filename@ext}}% - {\noexpand\lst@MissingFileError - {\filename@area\filename@base}{\filename@ext}}}% - \expandafter\reserved@a % - \fi} -\let\lst@ifdraft\iffalse -\DeclareOption{draft}{\let\lst@ifdraft\iftrue} -\DeclareOption{final}{\let\lst@ifdraft\iffalse} -\lst@AddToHook{PreSet} - {\lst@ifdraft - \let\lst@ifprint\iffalse - \@gobbletwo\fi\fi - \fi} -\def\lst@InputListing#1{% - \begingroup - \lsthk@PreSet \gdef\lst@intname{#1}% - \expandafter\lstset\expandafter{\lst@set}% - \lsthk@DisplayStyle - \catcode\active=\active - \lst@Init\relax \let\lst@gobble\z@ - \lst@SkipToFirst - \lst@ifprint \def\lst@next{\input{#1}}% - \else \let\lst@next\@empty \fi - \lst@next - \lst@DeInit - \endgroup} -\def\lst@SkipToFirst{% - \ifnum \lst@lineno<\lst@firstline - \lst@BeginDropInput\lst@Pmode - \lst@Let{13}\lst@MSkipToFirst - \lst@Let{10}\lst@MSkipToFirst - \else - \expandafter\lst@BOLGobble - \fi} -\def\lst@MSkipToFirst{% - \global\advance\lst@lineno\@ne - \ifnum \lst@lineno=\lst@firstline - \lst@LeaveMode \global\lst@newlines\z@ - \lsthk@InitVarsBOL - \expandafter\lst@BOLGobble - \fi} -\def\lstenv@DroppedWarning{% - \ifx\lst@dropped\@undefined\else - \PackageWarning{Listings}{Text dropped after begin of listing}% - \fi} -\let\lst@dropped\@undefined % init -\begingroup \lccode`\~=`\^^M\lowercase{% -\gdef\lstenv@Process#1{% - \ifx~#1% - \lstenv@DroppedWarning \let\lst@next\lst@SkipToFirst - \else\ifx^^J#1% - \lstenv@DroppedWarning \let\lst@next\lstenv@ProcessJ - \else - \let\lst@dropped#1\let\lst@next\lstenv@Process - \fi \fi - \lst@next} -}\endgroup -\def\lstenv@ProcessJ{% - \let\lst@arg\@empty - \ifx\@currenvir\lstenv@name - \expandafter\lstenv@ProcessJEnv - \else - \expandafter\def\expandafter\lst@temp\expandafter##1% - \csname end\lstenv@name\endcsname - {\lst@InsideConvert{##1}\lstenv@ProcessJ@}% - \expandafter\lst@temp - \fi} -\begingroup \lccode`\~=`\\\lowercase{% -\gdef\lstenv@ProcessJ@{% - \lst@lExtend\lst@arg - {\expandafter\ \expandafter~\lstenv@endstring}% - \catcode10=\active \lst@Let{10}\lst@MProcessListing - \lst@SkipToFirst \lst@arg} -}\endgroup -\def\lstenv@ProcessJEnv#1\end#2{\def\lst@temp{#2}% - \ifx\lstenv@name\lst@temp - \lst@InsideConvert{#1}% - \expandafter\lstenv@ProcessJ@ - \else - \lst@InsideConvert{#1\\end\{#2\}}% - \expandafter\lstenv@ProcessJEnv - \fi} -\def\lstenv@backslash{% - \lst@IfNextChars\lstenv@endstring - {\lstenv@End}% - {\expandafter\lsts@backslash \lst@eaten}}% -\def\lstenv@End{% - \ifx\@currenvir\lstenv@name - \edef\lst@next{\noexpand\end{\lstenv@name}}% - \else - \def\lst@next{\csname end\lstenv@name\endcsname}% - \fi - \lst@next} -\lst@UserCommand\lstnewenvironment#1#2#{% - \@ifundefined{#1}% - {\let\lst@arg\@empty - \lst@XConvert{#1}\@nil - \expandafter\lstnewenvironment@\lst@arg{#1}{#2}}% - {\PackageError{Listings}{Environment `#1' already defined}\@eha - \@gobbletwo}} -\def\@tempa#1#2#3{% -\gdef\lstnewenvironment@##1##2##3##4##5{% - \begingroup - \global\@namedef{end##2}{\lstenv@Error{##2}}% - \global\@namedef{##2}{\def\lstenv@name{##2}% - \begingroup \lst@setcatcodes \catcode\active=\active - \csname##2@\endcsname}% - \let\l@ngrel@x\global - \let\@xargdef\lstenv@xargdef - \expandafter\new@command\csname##2@\endcsname##3% - {\lsthk@PreSet ##4% - \ifx\@currenvir\lstenv@name - \def\lstenv@endstring{#1#2##1#3}% - \else - \def\lstenv@endstring{#1##1}% - \fi - \@namedef{end##2}{\lst@DeInit ##5\endgroup - \lst@doendpe \@ignoretrue}% - \lsthk@DisplayStyle - \let\lst@EndProcessListing\lstenv@SkipToEnd - \lst@Init\lstenv@backslash - \lst@ifprint - \expandafter\expandafter\expandafter\lstenv@Process - \else - \expandafter\lstenv@SkipToEnd - \fi - \lst@insertargs}% - \endgroup}% -} -\let\lst@arg\@empty \lst@XConvert{end}\{\}\@nil -\expandafter\@tempa\lst@arg -\let\lst@insertargs\@empty -\def\lstenv@xargdef#1{ - \expandafter\lstenv@xargdef@\csname\string#1\endcsname#1} -\def\lstenv@xargdef@#1#2[#3][#4]#5{% - \@ifdefinable#2{% - \gdef#2{% - \ifx\protect\@typeset@protect - \expandafter\lstenv@testopt - \else - \@x@protect#2% - \fi - #1% - {#4}}% - \@yargdef - #1% - \tw@ - {#3}% - {#5}}} -\long\def\lstenv@testopt#1#2{% - \@ifnextchar[{\catcode\active5\relax \lstenv@testopt@#1}% - {#1[{#2}]}} -\def\lstenv@testopt@#1[#2]{% - \catcode\active\active - #1[#2]} -\begingroup \lccode`\~=`\\\lowercase{% -\gdef\lstenv@SkipToEnd{% - \long\expandafter\def\expandafter\lst@temp\expandafter##\expandafter - 1\expandafter~\lstenv@endstring{\lstenv@End}% - \lst@temp} -}\endgroup -\def\lstenv@Error#1{\PackageError{Listings}{Extra \string\end#1}% - {I'm ignoring this, since I wasn't doing a \csname#1\endcsname.}} -\begingroup \lccode`\~=`\^^M\lowercase{% -\gdef\lst@TestEOLChar#1{% - \def\lst@insertargs{#1}% - \ifx ~#1\@empty \else - \ifx^^J#1\@empty \else - \global\let\lst@intname\lst@insertargs - \let\lst@insertargs\@empty - \fi \fi} -}\endgroup -\lstnewenvironment{lstlisting}[2][] - {\lst@TestEOLChar{#2}% - \lstset{#1}% - \csname\@lst @SetFirstNumber\endcsname} - {\csname\@lst @SaveFirstNumber\endcsname} -\lst@Key{fancyvrb}\relax[t]{% - \lstKV@SetIf{#1}\lst@iffancyvrb - \lstFV@fancyvrb} -\ifx\lstFV@fancyvrb\@undefined - \gdef\lstFV@fancyvrb{\lst@RequireAspects{fancyvrb}\lstFV@fancyvrb} -\fi -\@ifundefined{ocp}{} - {\lst@AddToHook{OutputBox}% - {\let\lst@ProcessLetter\@firstofone - \let\lst@ProcessDigit\@firstofone - \let\lst@ProcessOther\@firstofone}} -\DeclareOption*{\expandafter\lst@ProcessOption\CurrentOption\relax} -\def\lst@ProcessOption#1#2\relax{% - \ifx #1!% - \lst@DeleteKeysIn\lst@loadaspects{#2}% - \else - \lst@lAddTo\lst@loadaspects{,#1#2}% - \fi} -\@ifundefined{lst@loadaspects} - {\def\lst@loadaspects{strings,comments,escape,style,language,% - keywords,labels,lineshape,frames,emph,index}% - }{} -\InputIfFileExists{lstpatch.sty}{}{} -\let\lst@ifsavemem\iffalse -\DeclareOption{savemem}{\let\lst@ifsavemem\iftrue} -\DeclareOption{noaspects}{\let\lst@loadaspects\@empty} -\ProcessOptions -\lst@RequireAspects\lst@loadaspects -\let\lst@loadaspects\@empty -\lst@UseHook{SetStyle}\lst@UseHook{EmptyStyle} -\lst@UseHook{SetLanguage}\lst@UseHook{EmptyLanguage} -\InputIfFileExists{listings.cfg}{}{} -\InputIfFileExists{lstlocal.cfg}{}{} -\endinput -%% -%% End of file `listings.sty'. diff --git a/org.glite.lb.doc/src/log_usertag.tex b/org.glite.lb.doc/src/log_usertag.tex deleted file mode 100644 index a7194d9..0000000 --- a/org.glite.lb.doc/src/log_usertag.tex +++ /dev/null @@ -1,82 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\subsubsection{Example: Logging a UserTag event} -\label{e:usertag} - -User tag is an arbitrary ``name=value'' pair with which the user can assign -additional information to a job. Further on, LB can be queried based also on -values of user tags. \LB treats all values as strings only, semantic meaning -is left to user application. For internal reasons, all tag names are stored -in lower-case format. Support for case-sensitivenes is planned in future -versions of \LB. - -In order to add user tag for a job a special event \verb'UserTag' is used. This -event can be logged by the job owner using the glite-lb-logevent command (see -also sec.\ref{glite-lb-logevent}). Here we suppose the command is used from -user's running application because a correct setting of environment variables -needed by the command is assured. - -General template for adding user tag is as follows: - -\begin{verbatim} -glite-lb-logevent -s Application -e UserTag - -j - -c - --name - --value -\end{verbatim} - -where - -\begin{tabularx}{\textwidth}{lX} -\texttt{} & specifies the name of user tag \\ -\texttt{} & specifies the value of user tag \\ -\end{tabularx} - -The user application is always executed from within a JobWrapper script (part -of Workload Management System \cite{jgc}). The wrapper sets the appropriate -\verb'JobId' in the environment variable \verb'GLITE_WMS_JOBID'. The user -should pass this value to the \verb'-j' option of \verb'glite-lb-logevent'. -Similarly, the wrapper sets an initial value of the event sequence code in the -environment variable \verb'GLITE_WMS_SEQUENCE_CODE'. - -If the user application calls \verb'glite-lb-logevent' just once, it is -sufficient to pass this value to the \verb'-c' option. However, if there are -more subsequent calls, the user is responsible for capturing an updated -sequence code from the stdout of \verb'glite-lb-logevent' and using it in -subsequent calls. The \LB\ design requires the sequence codes in order to be -able to sort events correctly while not relying on strictly synchronized -clocks. - -The example bellow is a job consisting of 100 phases. A user tag phase is used -to log the phase currently being executed. Subsequently, the user may monitor -execution of the job phases as a part of the job status returned by \LB. - -\begin{verbatim} - #!/bin/sh - - for p in `seq 1 100`; do - - # log the UserTag event - GLITE_WMS_SEQUENCE_CODE=`glite-lb-logevent -s Application - -e UserTag - -j $GLITE_WMS_JOBID -c $GLITE_WMS_SEQUENCE_CODE - --name=phase --value=$p` - - # do the actual computation here - done -\end{verbatim} diff --git a/org.glite.lb.doc/src/logevent.tex b/org.glite.lb.doc/src/logevent.tex deleted file mode 100644 index 8ea4264..0000000 --- a/org.glite.lb.doc/src/logevent.tex +++ /dev/null @@ -1,93 +0,0 @@ -% -%% Copyright (c) Members of the EGEE Collaboration. 2004-2010. -%% See http://www.eu-egee.org/partners for details on the copyright holders. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -% -\subsection{glite-lb-logevent} -\label{glite-lb-logevent} - -Besides the API's \LB\ offers its users a simple command-line interface for -logging events. The command \verb'glite-lb-logevent' is used for this purpose. -However, it is intended for internal WMS debugging tests in the first place and -should not be used for common event logging because of possibility of confusing -\LB\ server job state automaton. - -The command \verb'glite-lb-logevent' is a complex logging tool and the complete -list of parameters can be obtained using the \verb'-h' option. However, -the only legal user usage is for logging \verb'UserTag' and \verb'ChangeACL' -events. The following description is therefore concentrating only on options -dealing with these two events. - -Command usage is: - -\begin{verbatim} - glite-lb-logevent [-h] [-p] [-c seq_code] - -j -s Application -e [key=value ...] -\end{verbatim} - -where - -\begin{tabularx}{\textwidth}{lX} -\texttt{ -p -{}-priority} & send a priority event\\ -\texttt{ -c -{}-sequence} & event sequence code\\ -\texttt{ -j -{}-jobid} & JobId\\ -\texttt{ -e -{}-event} & select event type (see -e help)\\ -\end{tabularx} - -%\medskip - -Each event specified after \verb'-e' option has different sub-options enabling -to set event specific values. - -Address of local-logger, daemon responsible for further message delivery, must -be specified by environment -variable \verb'GLITE_WMS_LOG_DESTINATION' in a form \verb'address:port'. - -Because user is allowed to change ACL or add user tags only for her jobs, paths -to valid X509 user credentials has to be set to authorise her. This is done -using standard X509 environment variables \verb'X509_USER_KEY' and -\verb'X509_USER_CERT'. - -For additional information see also manual page glite-lb-logevent(1). - -\input log_usertag.tex - -\input change_acl.tex - -\subsubsection{Example: Setting payload owner} -\label{e:payload_owner} - -In order to change the owner of the payload (see also \ref{sec:job-authz}), -a pair of \LB events is used. In order for a job owner to specify a new -owner of the payload, the \verb'GrantPayloadOwnership' event is used, \eg: - -\begin{verbatim} -glite-lb-logevent -e GrantPayloadOwnership -s UserInterface -j \ - --payload_owner -\end{verbatim} - -where - -\begin{tabularx}{\textwidth}{>{\texttt}lX} -\verb'' & specifies the job to change access to\\ -\verb'' & specifies the X.509 subject name of the new payload user. \\ -\end{tabularx} - -The new payload owner confirm they accept the ownership using the -\verb'TakePayloadOwnership' event. Note that this event event must be -logged using the credentials of the new user: - -\begin{verbatim} -glite-lb-logevent -e TakePayloadOwnership -s UserInterface -j -\end{verbatim} diff --git a/org.glite.lb.doc/src/lstdoc.sty b/org.glite.lb.doc/src/lstdoc.sty deleted file mode 100644 index 3b9806f..0000000 --- a/org.glite.lb.doc/src/lstdoc.sty +++ /dev/null @@ -1,451 +0,0 @@ -%% -%% This is file `lstdoc.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% listings-1.3.dtx (with options: `doc') -%% -%% Please read the software license in listings-1.3.dtx or listings-1.3.pdf. -%% -%% (w)(c) 1996--2004 Carsten Heinz and/or any other author listed -%% elsewhere in this file. -%% -%% Send comments and ideas on the package, error reports and additional -%% programming languages to . -%% -\def\filedate{2004/09/07} -\def\fileversion{1.3} -\ProvidesPackage{lstdoc} - [\filedate\space\fileversion\space(Carsten Heinz)] -\let\lstdoc@currversion\fileversion -\RequirePackage[writefile]{listings}[2004/09/07] -\newif\iffancyvrb \IfFileExists{fancyvrb.sty}{\fancyvrbtrue}{} -\newif\ifcolor \IfFileExists{color.sty}{\colortrue}{} -\lst@false -\newif\ifhyper -\@ifundefined{pdfoutput} - {} - {\ifnum\pdfoutput>\z@ \lst@true \fi} -\@ifundefined{VTeXversion} - {} - {\ifnum\OpMode>\z@ \lst@true \fi} -\lst@if \IfFileExists{hyperref.sty}{\hypertrue}{}\fi -\newif\ifalgorithmic \IfFileExists{algorithmic.sty}{\algorithmictrue}{} -\newif\iflgrind \IfFileExists{lgrind.sty}{\lgrindtrue}{} -\iffancyvrb \RequirePackage{fancyvrb}\fi -\ifhyper \RequirePackage[colorlinks]{hyperref}\else - \def\href#1{\texttt}\fi -\ifcolor \RequirePackage{color}\fi -\ifalgorithmic \RequirePackage{algorithmic}\fi -\iflgrind \RequirePackage{lgrind}\fi -\RequirePackage{nameref} -\RequirePackage{url} -\renewcommand\ref{\protect\T@ref} -\renewcommand\pageref{\protect\T@pageref} -\def\lst@BeginRemark#1{% - \begin{quote}\topsep0pt\let\small\footnotesize\small#1:} -\def\lst@EndRemark{\end{quote}} -\newenvironment{TODO} - {\lst@BeginRemark{To do}}{\lst@EndRemark} -\newenvironment{ALTERNATIVE} - {\lst@BeginRemark{Alternative}}{\lst@EndRemark} -\newenvironment{REMOVED} - {\lst@BeginRemark{Removed}}{\lst@EndRemark} -\newenvironment{OLDDEF} - {\lst@BeginRemark{Old definition}}{\lst@EndRemark} -\def\advise{\par\list\labeladvise - {\advance\linewidth\@totalleftmargin - \@totalleftmargin\z@ - \@listi - \let\small\footnotesize \small\sffamily - \parsep \z@ \@plus\z@ \@minus\z@ - \topsep6\p@ \@plus1\p@\@minus2\p@ - \def\makelabel##1{\hss\llap{##1}}}} -\let\endadvise\endlist -\def\advisespace{\hbox{}\qquad} -\def\labeladvise{$\to$} -\newenvironment{syntax} - {\list{}{\itemindent-\leftmargin - \def\makelabel##1{\hss\lst@syntaxlabel##1,,,,\relax}}} - {\endlist} -\def\lst@syntaxlabel#1,#2,#3,#4\relax{% - \llap{\scriptsize\itshape#3}% - \def\lst@temp{#2}% - \expandafter\lst@syntaxlabel@\meaning\lst@temp\relax - \rlap{\hskip-\itemindent\hskip\itemsep\hskip\linewidth - \llap{\ttfamily\lst@temp}\hskip\labelwidth - \def\lst@temp{#1}% - \ifx\lst@temp\lstdoc@currversion#1\fi}} -\def\lst@syntaxlabel@#1>#2\relax - {\edef\lst@temp{\zap@space#2 \@empty}} -\newcommand*\syntaxnewline{\newline\hbox{}\kern\labelwidth} -\newcommand*\syntaxor{\qquad or\qquad} -\newcommand*\syntaxbreak - {\hfill\kern0pt\discretionary{}{\kern\labelwidth}{}} -\let\syntaxfill\hfill -\def\alternative#1{\lst@true \alternative@#1,\relax,} -\def\alternative@#1,{% - \ifx\relax#1\@empty - \expandafter\@gobble - \else - \ifx\@empty#1\@empty\else - \lst@if \lst@false \else $\vert$\fi - \textup{\texttt{#1}}% - \fi - \fi - \alternative@} -\long\def\m@cro@#1#2#3{\endgroup \topsep\MacroTopsep \trivlist - \edef\saved@macroname{\string#3}% - \def\makelabel##1{\llap{##1}}% - \if@inlabel - \let\@tempa\@empty \count@\macro@cnt - \loop \ifnum\count@>\z@ - \edef\@tempa{\@tempa\hbox{\strut}}\advance\count@\m@ne \repeat - \edef\makelabel##1{\llap{\vtop to\baselineskip - {\@tempa\hbox{##1}\vss}}}% - \advance \macro@cnt \@ne - \else \macro@cnt\@ne \fi - \edef\@tempa{\noexpand\item[% - #1% - \noexpand\PrintMacroName - \else - \expandafter\noexpand\csname Print#2Name\endcsname % MODIFIED - \fi - {\string#3}]}% - \@tempa - \global\advance\c@CodelineNo\@ne - #1% - \SpecialMainIndex{#3}\nobreak - \DoNotIndex{#3}% - \else - \csname SpecialMain#2Index\endcsname{#3}\nobreak % MODIFIED - \fi - \global\advance\c@CodelineNo\m@ne - \ignorespaces} -\def\macro{\begingroup - \catcode`\\12 - \MakePrivateLetters \m@cro@ \iftrue {Macro}}% MODIFIED -\def\environment{\begingroup - \catcode`\\12 - \MakePrivateLetters \m@cro@ \iffalse {Env}}% MODIFIED -\def\newdocenvironment#1#2#3#4{% - \@namedef{#1}{#3\begingroup \catcode`\\12\relax - \MakePrivateLetters \m@cro@ \iffalse {#2}}% - \@namedef{end#1}{#4\endmacro}% - \@ifundefined{Print#2Name}{\expandafter - \let\csname Print#2Name\endcsname\PrintMacroName}{}% - \@ifundefined{SpecialMain#2Index}{\expandafter - \let\csname SpecialMain#2Index\endcsname\SpecialMainIndex}{}} -\newdocenvironment{aspect}{Aspect}{}{} -\def\PrintAspectName#1{} -\def\SpecialMainAspectIndex#1{% - \@bsphack - \index{aspects:\levelchar\protect\aspectname{#1}\encapchar main}% - \@esphack} -\newdocenvironment{lstkey}{Key}{}{} -\def\PrintKeyName#1{\strut\keyname{#1}\ } -\def\SpecialMainKeyIndex#1{% - \@bsphack - \index{keys\levelchar\protect\keyname{#1}\encapchar main}% - \@esphack} -\newcounter{argcount} -\def\labelargcount{\texttt{\#\arabic{argcount}}\hskip\labelsep$=$} -\def\macroargs{\list\labelargcount - {\usecounter{argcount}\leftmargin=2\leftmargin - \parsep \z@ \@plus\z@ \@minus\z@ - \topsep4\p@ \@plus\p@ \@minus2\p@ - \itemsep\z@ \@plus\z@ \@minus\z@ - \def\makelabel##1{\hss\llap{##1}}}} -\def\endmacroargs{\endlist\@endparenv} -\lst@RequireAspects{writefile} -\newbox\lst@samplebox -\lstnewenvironment{lstsample}[3][] - {\global\let\lst@intname\@empty - \gdef\lst@sample{#2}% - \setbox\lst@samplebox=\hbox\bgroup - \setkeys{lst}{language={},style={},tabsize=4,gobble=5,% - basicstyle=\small\ttfamily,basewidth=0.51em,point={#1}} - #3% - \lst@BeginAlsoWriteFile{\jobname.tmp}} - {\lst@EndWriteFile\egroup - \ifdim \wd\lst@samplebox>.5\linewidth - \begin{center}% - \hbox to\linewidth{\box\lst@samplebox\hss}% - \end{center}% - \lst@sampleInput - \else - \begin{center}% - \begin{minipage}{0.45\linewidth}\lst@sampleInput\end{minipage}% - \qquad - \begin{minipage}{0.45\linewidth}% - \hbox to\linewidth{\box\lst@samplebox\hss}% - \end{minipage}% - \end{center}% - \fi} -\lst@InstallKeywords{p}{point}{pointstyle}\relax{keywordstyle}{}ld -\lstnewenvironment{lstxsample}[1][] - {\begingroup - \setkeys{lst}{belowskip=-\medskipamount,language={},style={},% - tabsize=4,gobble=5,basicstyle=\small\ttfamily,% - basewidth=0.51em,point={#1}} - \lst@BeginAlsoWriteFile{\jobname.tmp}} - {\endgroup - \endgroup} -\def\lst@sampleInput{% - \MakePercentComment\catcode`\^^M=10\relax - \small\lst@sample - {\setkeys{lst}{SelectCharTable=\lst@ReplaceInput{\^\^I}% - {\lst@ProcessTabulator}}% - \leavevmode \input{\jobname.tmp}}\MakePercentIgnore} -\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}% - {1.25ex \@plus1ex \@minus.2ex}% - {-1em}% - {\normalfont\normalsize\bfseries}} -\def\lstref#1{\emph{\ref{#1} \nameref{#1}}} -\def\@part[#1]#2{\addcontentsline{toc}{part}{#1}% - {\parindent\z@ \raggedright \interlinepenalty\@M - \normalfont \huge \bfseries #2\markboth{}{}\par}% - \nobreak\vskip 3ex\@afterheading} -\renewcommand*\l@section[2]{% - \addpenalty\@secpenalty - \addvspace{.25em \@plus\p@}% - \setlength\@tempdima{1.5em}% - \begingroup - \parindent \z@ \rightskip \@pnumwidth - \parfillskip -\@pnumwidth - \leavevmode - \advance\leftskip\@tempdima - \hskip -\leftskip - #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par - \endgroup} -\renewcommand*\l@subsection{\@dottedtocline{2}{0pt}{2.3em}} -\renewcommand*\l@subsubsection{\@dottedtocline{3}{0pt}{3.2em}} -\newcommand\ikeyname[1]{% - \lstkeyindex{#1}{}% - \lstaspectindex{#1}{}% - \keyname{#1}} -\newcommand\ekeyname[1]{% - \@bsphack - \lstkeyindex{#1}{\encapchar usage}% - \lstaspectindex{#1}{\encapchar usage}% - \@esphack} -\newcommand\rkeyname[1]{% - \@bsphack - \lstkeyindex{#1}{\encapchar main}% - \lstaspectindex{#1}{\encapchar main}% - \@esphack{\rstyle\keyname{#1}}} -\newcommand\icmdname[1]{% - \@bsphack - \lstaspectindex{#1}{}% - \@esphack\texttt{\string#1}} -\newcommand\rcmdname[1]{% - \@bsphack - \lstaspectindex{#1}{\encapchar main}% - \@esphack\texttt{\rstyle\string#1}} -\def\lstaspectindex#1#2{% - \global\@namedef{lstkandc@\string#1}{}% - \@ifundefined{lstisaspect@\string#1} - {\index{unknown\levelchar - \protect\texttt{\protect\string\string#1}#2}}% - {\index{\@nameuse{lstisaspect@\string#1}\levelchar - \protect\texttt{\protect\string\string#1}#2}}% -} -\def\lstkeyindex#1#2{% -} -\def\lstisaspect[#1]#2{% - \global\@namedef{lstaspect@#1}{#2}% - \lst@AddTo\lst@allkeysandcmds{,#2}% - \@for\lst@temp:=#2\do - {\ifx\@empty\lst@temp\else - \global\@namedef{lstisaspect@\lst@temp}{#1}% - \fi}} -\gdef\lst@allkeysandcmds{} -\def\lstprintaspectkeysandcmds#1{% - \lst@true - \expandafter\@for\expandafter\lst@temp - \expandafter:\expandafter=\csname lstaspect@#1\endcsname\do - {\lst@if\lst@false\else, \fi \texttt{\lst@temp}}} -\def\lstcheckreference{% - \@for\lst@temp:=\lst@allkeysandcmds\do - {\ifx\lst@temp\@empty\else - \@ifundefined{lstkandc@\lst@temp} - {\typeout{\lst@temp\space not in reference guide?}}{}% - \fi}} -\newcommand*\lst{\texttt{lst}} -\newcommand*\Cpp{C\texttt{++}} -\let\keyname\texttt -\let\keyvalue\texttt -\let\hookname\texttt -\newcommand*\aspectname[1]{{\normalfont\sffamily#1}} -\DeclareRobustCommand\packagename[1]{% - {\leavevmode\text@command{#1}% - \switchfontfamily\sfdefault\rmdefault - \check@icl #1\check@icr - \expandafter}}% -\renewcommand\packagename[1]{{\normalfont\sffamily#1}} -\def\switchfontfamily#1#2{% - \begingroup\xdef\@gtempa{#1}\endgroup - \ifx\f@family\@gtempa\fontfamily#2% - \else\fontfamily#1\fi - \selectfont} -\ifcolor - \definecolor{darkgreen}{rgb}{0,0.5,0} - \def\rstyle{\color{darkgreen}} -\else - \let\rstyle\empty -\fi -\gdef\lst@emails{} -\newcommand*\lstthanks[2] - {#1\lst@AddTo\lst@emails{,#1,<#2>}% - \ifx\@empty#2\@empty\typeout{Missing email for #1}\fi} -\newcommand*\lsthelper[3] - {{\let~\ #1}% - \lst@IfOneOf#1\relax\lst@emails - {}{\typeout{^^JWarning: Unknown helper #1.^^J}}} -\lstdefinelanguage[doc]{Pascal}{% - morekeywords={alfa,and,array,begin,boolean,byte,case,char,const,div,% - do,downto,else,end,false,file,for,function,get,goto,if,in,% - integer,label,maxint,mod,new,not,of,or,pack,packed,page,program,% - procedure,put,read,readln,real,record,repeat,reset,rewrite,set,% - text,then,to,true,type,unpack,until,var,while,with,write,writeln},% - sensitive=false,% - morecomment=[s]{(*}{*)},% - morecomment=[s]{\{}{\}},% - morestring=[d]{'}} -\lstdefinestyle{} - {basicstyle={},% - keywordstyle=\bfseries,identifierstyle={},% - commentstyle=\itshape,stringstyle={},% - numberstyle={},stepnumber=1,% - pointstyle=\pointstyle} -\def\pointstyle{% - {\let\lst@um\@empty \xdef\@gtempa{\the\lst@token}}% - \expandafter\lstkeyindex\expandafter{\@gtempa}{}% - \expandafter\lstaspectindex\expandafter{\@gtempa}{}% - \rstyle} -\lstset{defaultdialect=[doc]Pascal,language=Pascal,style={}} -\def\lstscanlanguages#1#2#3{% - \begingroup - \def\lst@DefDriver@##1##2##3##4[##5]##6{% - \lst@false - \lst@lAddTo\lst@scan{##6(##5),}% - \begingroup - \@ifnextchar[{\lst@XDefDriver{##1}##3}{\lst@DefDriver@@##3}}% - \def\lst@XXDefDriver[##1]{}% - \lst@InputCatcodes - \def\lst@dontinput{#3}% - \let\lst@scan\@empty - \lst@for{#2}\do{% - \lst@IfOneOf##1\relax\lst@dontinput - {}% - {\InputIfFileExists{##1}{}{}}}% - \global\let\@gtempa\lst@scan - \endgroup - \let#1\@gtempa} -\def\lstprintlanguages#1{% - \def\do##1{\setbox\@tempboxa\hbox{##1\space\space}% - \ifdim\wd\@tempboxa<.5\linewidth \wd\@tempboxa.5\linewidth - \else \wd\@tempboxa\linewidth \fi - \box\@tempboxa\allowbreak}% - \begin{quote} - \par\noindent - \hyphenpenalty=\@M \rightskip=\z@\@plus\linewidth\relax - \lst@BubbleSort#1% - \expandafter\lst@NextLanguage#1\relax(\relax),% - \end{quote}} -\def\lst@NextLanguage#1(#2),{% - \ifx\relax#1\else - \def\lst@language{#1}\def\lst@dialects{(#2),}% - \expandafter\lst@NextLanguage@ - \fi} -\def\lst@NextLanguage@#1(#2),{% - \def\lst@temp{#1}% - \ifx\lst@temp\lst@language - \lst@lAddTo\lst@dialects{(#2),}% - \expandafter\lst@NextLanguage@ - \else - \do{\lst@language - \ifx\lst@dialects\lst@emptydialect\else - \expandafter\lst@NormedDef\expandafter\lst@language - \expandafter{\lst@language}% - \space(% - \lst@BubbleSort\lst@dialects - \expandafter\lst@PrintDialects\lst@dialects(\relax),% - )% - \fi}% - \def\lst@next{\lst@NextLanguage#1(#2),}% - \expandafter\lst@next - \fi} -\def\lst@emptydialect{(),} -\def\lst@PrintDialects(#1),{% - \ifx\@empty#1\@empty empty\else - \lst@PrintDialect{#1}% - \fi - \lst@PrintDialects@} -\def\lst@PrintDialects@(#1),{% - \ifx\relax#1\else - , \lst@PrintDialect{#1}% - \expandafter\lst@PrintDialects@ - \fi} -\def\lst@PrintDialect#1{% - \lst@NormedDef\lst@temp{#1}% - \expandafter\ifx\csname\@lst dd@\lst@language\endcsname\lst@temp - \texttt{\underbar{#1}}% - \else - \texttt{#1}% - \fi} -\def\lst@IfLE#1#2\@empty#3#4\@empty{% - \ifx #1\relax - \let\lst@next\@firstoftwo - \else \ifx #3\relax - \let\lst@next\@secondoftwo - \else - \lowercase{\ifx#1#3}% - \def\lst@next{\lst@IfLE#2\@empty#4\@empty}% - \else - \lowercase{\ifnum`#1<`#3}\relax - \let\lst@next\@firstoftwo - \else - \let\lst@next\@secondoftwo - \fi - \fi - \fi \fi - \lst@next} -\def\lst@BubbleSort#1{% - \ifx\@empty#1\else - \lst@false - \expandafter\lst@BubbleSort@#1\relax,\relax,% - \expandafter\lst@BubbleSort@\expandafter,\lst@sorted - \relax,\relax,% - \let#1\lst@sorted - \lst@if - \def\lst@next{\lst@BubbleSort#1}% - \expandafter\expandafter\expandafter\lst@next - \fi - \fi} -\def\lst@BubbleSort@#1,#2,{% - \ifx\@empty#1\@empty - \def\lst@sorted{#2,}% - \def\lst@next{\lst@BubbleSort@@}% - \else - \let\lst@sorted\@empty - \def\lst@next{\lst@BubbleSort@@#1,#2,}% - \fi - \lst@next} -\def\lst@BubbleSort@@#1,#2,{% - \ifx\relax#1\else - \ifx\relax#2% - \lst@lAddTo\lst@sorted{#1,}% - \expandafter\expandafter\expandafter\lst@BubbleSort@@@ - \else - \lst@IfLE #1\relax\@empty #2\relax\@empty - {\lst@lAddTo\lst@sorted{#1,#2,}}% - {\lst@true \lst@lAddTo\lst@sorted{#2,#1,}}% - \expandafter\expandafter\expandafter\lst@BubbleSort@@ - \fi - \fi} -\def\lst@BubbleSort@@@#1\relax,{} -\endinput -%% -%% End of file `lstdoc.sty'. diff --git a/org.glite.lb.doc/src/lstlang1.sty b/org.glite.lb.doc/src/lstlang1.sty deleted file mode 100644 index c108403..0000000 --- a/org.glite.lb.doc/src/lstlang1.sty +++ /dev/null @@ -1,1226 +0,0 @@ -%% -%% This is file `lstlang1.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% lstdrvrs-1.3.dtx (with options: `lang1') -%% -%% (w)(c) 1996/1997/1998/1999/2000/2001/2002/2003/2004 Carsten Heinz -%% and/or any other author listed elsewhere in this file. -%% -%% This file is distributed under the terms of the LaTeX Project Public -%% License from CTAN archives in directory macros/latex/base/lppl.txt. -%% Either version 1.0 or, at your option, any later version. -%% -%% This file is completely free and comes without any warranty. -%% -%% Send comments and ideas on the package, error reports and additional -%% programming languages to . -%% -\ProvidesFile{lstlang1.sty} - [2004/09/05 1.3 listings language file] -%% -%% ACSL definition (c) 2000 by Andreas Matthias -%% -\lst@definelanguage{ACSL}[90]{Fortran}% - {morekeywords={algorithm,cinterval,constant,derivative,discrete,% - dynamic,errtag,initial,interval,maxterval,minterval,% - merror,xerror,nsteps,procedural,save,schedule,sort,% - table,terminal,termt,variable},% - sensitive=false,% - morecomment=[l]!% - }[keywords, comments]% -%% -%% Ada 95 definition (c) Torsten Neuer -%% -\lst@definelanguage[95]{Ada}[83]{Ada}% - {morekeywords={abstract,aliased,protected,requeue,tagged,until}}% -\lst@definelanguage[83]{Ada}% - {morekeywords={abort,abs,accept,access,all,and,array,at,begin,body,% - case,constant,declare,delay,delta,digits,do,else,elsif,end,entry,% - exception,exit,for,function,generic,goto,if,in,is,limited,loop,% - mod,new,not,null,of,or,others,out,package,pragma,private,% - procedure,raise,range,record,rem,renames,return,reverse,select,% - separate,subtype,task,terminate,then,type,use,when,while,with,% - xor},% - sensitive=f,% - morecomment=[l]--,% - morestring=[m]",% percent not defined as stringizer so far - morestring=[m]'% - }[keywords,comments,strings]% -%% -%% awk definitions (c) Christoph Giess -%% -\lst@definelanguage[gnu]{Awk}[POSIX]{Awk}% - {morekeywords={and,asort,bindtextdomain,compl,dcgettext,gensub,% - lshift,mktime,or,rshift,strftime,strtonum,systime,xor,extension}% - }% -\lst@definelanguage[POSIX]{Awk}% - {keywords={BEGIN,END,close,getline,next,nextfile,print,printf,% - system,fflush,atan2,cos,exp,int,log,rand,sin,sqrt,srand,gsub,% - index,length,match,split,sprintf,strtonum,sub,substr,tolower,% - toupper,if,while,do,for,break,continue,delete,exit,function,% - return},% - sensitive,% - morecomment=[l]\#,% - morecomment=[l]//,% - morecomment=[s]{/*}{*/},% - morestring=[b]"% - }[keywords,comments,strings]% -%% -%% Visual Basic definition (c) 2002 Robert Frank -%% -\lst@definelanguage[Visual]{Basic} - {morekeywords={Abs,Array,Asc,AscB,AscW,Atn,Avg,CBool,CByte,CCur,% - CDate,CDbl,Cdec,Choose,Chr,ChrB,ChrW,CInt,CLng,Command,Cos,% - Count,CreateObject,CSng,CStr,CurDir,CVar,CVDate,CVErr,Date,% - DateAdd,DateDiff,DatePart,DateSerial,DateValue,Day,DDB,Dir,% - DoEvents,Environ,EOF,Error,Exp,FileAttr,FileDateTime,FileLen,% - Fix,Format,FreeFile,FV,GetAllStrings,GetAttr,% - GetAutoServerSettings,GetObject,GetSetting,Hex,Hour,IIf,% - IMEStatus,Input,InputB,InputBox,InStr,InstB,Int,Integer,IPmt,% - IsArray,IsDate,IsEmpty,IsError,IsMissing,IsNull,IsNumeric,% - IsObject,LBound,LCase,Left,LeftB,Len,LenB,LoadPicture,Loc,LOF,% - Log,Ltrim,Max,Mid,MidB,Min,Minute,MIRR,Month,MsgBox,Now,NPer,% - NPV,Oct,Partition,Pmt,PPmt,PV,QBColor,Rate,RGB,Right,RightB,Rnd,% - Rtrim,Second,Seek,Sgn,Shell,Sin,SLN,Space,Spc,Sqr,StDev,StDevP,% - Str,StrComp,StrConv,String,Switch,Sum,SYD,Tab,Tan,Time,Timer,% - TimeSerial,TimeValue,Trim,TypeName,UBound,Ucase,Val,Var,VarP,% - VarType,Weekday,Year},% functions - morekeywords=[2]{Accept,Activate,Add,AddCustom,AddFile,AddFromFile,% - AddFromTemplate,AddItem,AddNew,AddToAddInToolbar,% - AddToolboxProgID,Append,AppendChunk,Arrange,Assert,AsyncRead,% - BatchUpdate,BeginTrans,Bind,Cancel,CancelAsyncRead,CancelBatch,% - CancelUpdate,CanPropertyChange,CaptureImage,CellText,CellValue,% - Circle,Clear,ClearFields,ClearSel,ClearSelCols,Clone,Close,Cls,% - ColContaining,ColumnSize,CommitTrans,CompactDatabase,Compose,% - Connect,Copy,CopyQueryDef,CreateDatabase,CreateDragImage,% - CreateEmbed,CreateField,CreateGroup,CreateIndex,CreateLink,% - CreatePreparedStatement,CreatePropery,CreateQuery,% - CreateQueryDef,CreateRelation,CreateTableDef,CreateUser,% - CreateWorkspace,Customize,Delete,DeleteColumnLabels,% - DeleteColumns,DeleteRowLabels,DeleteRows,DoVerb,Drag,Draw,Edit,% - EditCopy,EditPaste,EndDoc,EnsureVisible,EstablishConnection,% - Execute,ExtractIcon,Fetch,FetchVerbs,Files,FillCache,Find,% - FindFirst,FindItem,FindLast,FindNext,FindPrevious,Forward,% - GetBookmark,GetChunk,GetClipString,GetData,GetFirstVisible,% - GetFormat,GetHeader,GetLineFromChar,GetNumTicks,GetRows,% - GetSelectedPart,GetText,GetVisibleCount,GoBack,GoForward,Hide,% - HitTest,HoldFields,Idle,InitializeLabels,InsertColumnLabels,% - InsertColumns,InsertObjDlg,InsertRowLabels,InsertRows,Item,% - KillDoc,Layout,Line,LinkExecute,LinkPoke,LinkRequest,LinkSend,% - Listen,LoadFile,LoadResData,LoadResPicture,LoadResString,% - LogEvent,MakeCompileFile,MakeReplica,MoreResults,Move,MoveData,% - MoveFirst,MoveLast,MoveNext,MovePrevious,NavigateTo,NewPage,% - NewPassword,NextRecordset,OLEDrag,OnAddinsUpdate,OnConnection,% - OnDisconnection,OnStartupComplete,Open,OpenConnection,% - OpenDatabase,OpenQueryDef,OpenRecordset,OpenResultset,OpenURL,% - Overlay,PaintPicture,Paste,PastSpecialDlg,PeekData,Play,Point,% - PopulatePartial,PopupMenu,Print,PrintForm,PropertyChanged,Pset,% - Quit,Raise,RandomDataFill,RandomFillColumns,RandomFillRows,% - rdoCreateEnvironment,rdoRegisterDataSource,ReadFromFile,% - ReadProperty,Rebind,ReFill,Refresh,RefreshLink,RegisterDatabase,% - Reload,Remove,RemoveAddInFromToolbar,RemoveItem,Render,% - RepairDatabase,Reply,ReplyAll,Requery,ResetCustom,% - ResetCustomLabel,ResolveName,RestoreToolbar,Resync,Rollback,% - RollbackTrans,RowBookmark,RowContaining,RowTop,Save,SaveAs,% - SaveFile,SaveToFile,SaveToolbar,SaveToOle1File,Scale,ScaleX,% - ScaleY,Scroll,Select,SelectAll,SelectPart,SelPrint,Send,% - SendData,Set,SetAutoServerSettings,SetData,SetFocus,SetOption,% - SetSize,SetText,SetViewport,Show,ShowColor,ShowFont,ShowHelp,% - ShowOpen,ShowPrinter,ShowSave,ShowWhatsThis,SignOff,SignOn,Size,% - Span,SplitContaining,StartLabelEdit,StartLogging,Stop,% - Synchronize,TextHeight,TextWidth,ToDefaults,TwipsToChartPart,% - TypeByChartType,Update,UpdateControls,UpdateRecord,UpdateRow,% - Upto,WhatsThisMode,WriteProperty,ZOrder},% methods - morekeywords=[3]{AccessKeyPress,AfterAddFile,AfterChangeFileName,% - AfterCloseFile,AfterColEdit,AfterColUpdate,AfterDelete,% - AfterInsert,AfterLabelEdit,AfterRemoveFile,AfterUpdate,% - AfterWriteFile,AmbienChanged,ApplyChanges,Associate,% - AsyncReadComplete,AxisActivated,AxisLabelActivated,% - AxisLabelSelected,AxisLabelUpdated,AxisSelected,% - AxisTitleActivated,AxisTitleSelected,AxisTitleUpdated,% - AxisUpdated,BeforeClick,BeforeColEdit,BeforeColUpdate,% - BeforeConnect,BeforeDelete,BeforeInsert,BeforeLabelEdit,% - BeforeLoadFile,BeforeUpdate,ButtonClick,ButtonCompleted,% - ButtonGotFocus,ButtonLostFocus,Change,ChartActivated,% - ChartSelected,ChartUpdated,Click,ColEdit,Collapse,ColResize,% - ColumnClick,Compare,ConfigChageCancelled,ConfigChanged,% - ConnectionRequest,DataArrival,DataChanged,DataUpdated,DblClick,% - Deactivate,DeviceArrival,DeviceOtherEvent,DeviceQueryRemove,% - DeviceQueryRemoveFailed,DeviceRemoveComplete,DeviceRemovePending,% - DevModeChange,Disconnect,DisplayChanged,Dissociate,% - DoGetNewFileName,Done,DonePainting,DownClick,DragDrop,DragOver,% - DropDown,EditProperty,EnterCell,EnterFocus,Event,ExitFocus,% - Expand,FootnoteActivated,FootnoteSelected,FootnoteUpdated,% - GotFocus,HeadClick,InfoMessage,Initialize,IniProperties,% - ItemActivated,ItemAdded,ItemCheck,ItemClick,ItemReloaded,% - ItemRemoved,ItemRenamed,ItemSeletected,KeyDown,KeyPress,KeyUp,% - LeaveCell,LegendActivated,LegendSelected,LegendUpdated,% - LinkClose,LinkError,LinkNotify,LinkOpen,Load,LostFocus,% - MouseDown,MouseMove,MouseUp,NodeClick,ObjectMove,% - OLECompleteDrag,OLEDragDrop,OLEDragOver,OLEGiveFeedback,% - OLESetData,OLEStartDrag,OnAddNew,OnComm,Paint,PanelClick,% - PanelDblClick,PathChange,PatternChange,PlotActivated,% - PlotSelected,PlotUpdated,PointActivated,PointLabelActivated,% - PointLabelSelected,PointLabelUpdated,PointSelected,% - PointUpdated,PowerQuerySuspend,PowerResume,PowerStatusChanged,% - PowerSuspend,QueryChangeConfig,QueryComplete,QueryCompleted,% - QueryTimeout,QueryUnload,ReadProperties,Reposition,% - RequestChangeFileName,RequestWriteFile,Resize,ResultsChanged,% - RowColChange,RowCurrencyChange,RowResize,RowStatusChanged,% - SelChange,SelectionChanged,SendComplete,SendProgress,% - SeriesActivated,SeriesSelected,SeriesUpdated,SettingChanged,% - SplitChange,StateChanged,StatusUpdate,SysColorsChanged,% - Terminate,TimeChanged,TitleActivated,TitleSelected,% - TitleActivated,UnboundAddData,UnboundDeleteRow,% - UnboundGetRelativeBookmark,UnboundReadData,UnboundWriteData,% - Unload,UpClick,Updated,Validate,ValidationError,WillAssociate,% - WillChangeData,WillDissociate,WillExecute,WillUpdateRows,% - WithEvents,WriteProperties},% VB-events - morekeywords=[4]{AppActivate,Base,Beep,Call,Case,ChDir,ChDrive,% - Const,Declare,DefBool,DefByte,DefCur,DefDate,DefDbl,DefDec,% - DefInt,DefLng,DefObj,DefSng,DefStr,Deftype,DefVar,DeleteSetting,% - Dim,Do,Else,ElseIf,End,Enum,Erase,Event,Exit,Explicit,FileCopy,% - For,ForEach,Friend,Function,Get,GoSub,GoTo,If,Implements,Kill,% - Let,LineInput,Lock,Lset,MkDir,Name,Next,OnError,On,Option,% - Private,Property,Public,Put,RaiseEvent,Randomize,ReDim,Rem,% - Reset,Resume,Return,RmDir,Rset,SavePicture,SaveSetting,% - SendKeys,SetAttr,Static,Sub,Then,Type,Unlock,Wend,While,Width,% - With,Write},% statements - sensitive=false,% - keywordcomment=rem,% - MoreSelectCharTable=\def\lst@BeginKC@{% chmod - \lst@ResetToken - \lst@BeginComment\lst@GPmode{{\lst@commentstyle}% - \lst@Lmodetrue\lst@modetrue}\@empty},% - morecomment=[l]{'},% - morecomment=[s]{/*}{*/},% - morestring=[b]",% - }[keywords,comments,strings,keywordcomments] -\lst@definelanguage[ANSI]{C++}[ISO]{C++}{}% -\lst@definelanguage[GNU]{C++}[ISO]{C++}% - {morekeywords={__attribute__,__extension__,__restrict,__restrict__,% - typeof,__typeof__},% - }% -\lst@definelanguage[Visual]{C++}[ISO]{C++}% - {morekeywords={__asm,__based,__cdecl,__declspec,dllexport,% - dllimport,__except,__fastcall,__finally,__inline,__int8,__int16,% - __int32,__int64,naked,__stdcall,thread,__try,__leave},% - }% -\lst@definelanguage[ISO]{C++}[ANSI]{C}% - {morekeywords={and,and_eq,asm,bad_cast,bad_typeid,bitand,bitor,bool,% - catch,class,compl,const_cast,delete,dynamic_cast,explicit,export,% - false,friend,inline,mutable,namespace,new,not,not_eq,operator,or,% - or_eq,private,protected,public,reinterpret_cast,static_cast,% - template,this,throw,true,try,typeid,type_info,typename,using,% - virtual,wchar_t,xor,xor_eq},% - }% -%% -%% Objective-C definition (c) 1997 Detlev Droege -%% -\lst@definelanguage[Objective]{C}[ANSI]{C} - {morekeywords={bycopy,id,in,inout,oneway,out,self,super,% - @class,@defs,@encode,@end,@implementation,@interface,@private,% - @protected,@protocol,@public,@selector},% - moredirectives={import}% - }% -%% -%% Handel-C definition, refer http://www.celoxica.com -%% -\lst@definelanguage[Handel]{C}[ANSI]{C} - {morekeywords={assert,chan,chanin,chanout,clock,delay,expr,external,% - external_divide,family,ifselect,in,inline,interface,internal,% - internal_divid,intwidth,let,macro,mpram,par,part,prialt,proc,ram,% - releasesema,reset,rom,select,sema,set,seq,shared,signal,try,% - reset,trysema,typeof,undefined,width,with,wom},% - }% -\lst@definelanguage[ANSI]{C}% - {morekeywords={auto,break,case,char,const,continue,default,do,double,% - else,enum,extern,float,for,goto,if,int,long,register,return,% - short,signed,sizeof,static,struct,switch,typedef,union,unsigned,% - void,volatile,while},% - sensitive,% - morecomment=[s]{/*}{*/},% - morecomment=[l]//,% nonstandard - morestring=[b]",% - morestring=[b]',% - moredelim=*[directive]\#,% - moredirectives={define,elif,else,endif,error,if,ifdef,ifndef,line,% - include,pragma,undef,warning}% - }[keywords,comments,strings,directives]% -%% -%% C-Sharp definition (c) 2002 Martin Brodbeck -%% -\lst@definelanguage[Sharp]{C}% - {morekeywords={abstract,base,bool,break,byte,case,catch,char,checked,% - class,const,continue,decimal,default,delegate,do,double,else,% - enum,event,explicit,extern,false,finally,fixed,float,for,foreach,% - goto,if,implicit,in,int,interface,internal,is,lock,long,% - namespace,new,null,object,operator,out,override,params,private,% - protected,public,readonly,ref,return,sbyte,sealed,short,sizeof,% - static,string,struct,switch,this,throw,true,try,typeof,uint,% - ulong,unchecked,unsafe,ushort,using,virtual,void,while,% - as,volatile,stackalloc},% Kai K\"ohne - sensitive,% - morecomment=[s]{/*}{*/},% - morecomment=[l]//,% - morestring=[b]" - }[keywords,comments,strings]% -%% -%% csh definition (c) 1998 Kai Below -%% -\lst@definelanguage{csh} - {morekeywords={alias,awk,cat,echo,else,end,endif,endsw,exec,exit,% - foreach,glob,goto,history,if,logout,nice,nohup,onintr,repeat,sed,% - set,setenv,shift,source,switch,then,time,while,umask,unalias,% - unset,wait,while,@,env,argv,child,home,ignoreeof,noclobber,% - noglob,nomatch,path,prompt,shell,status,verbose,print,printf,% - sqrt,BEGIN,END},% - morecomment=[l]\#,% - morestring=[d]"% - }[keywords,comments,strings]% -%% -%% bash,sh definition (c) 2003 Riccardo Murri -%% -\lst@definelanguage{bash}[]{sh}% - {morekeywords={alias,bg,bind,builtin,command,compgen,complete,% - declare,disown,enable,fc,fg,history,jobs,et,local,logout,printf,% - pushd,popd,select,set,suspend,shopt,source,times,type,typeset,% - ulimit,unalias,wait},% - }% -\lst@definelanguage{sh}% - {morekeywords={awk,break,case,cat,cd,continue,do,done,echo,else,% - env,eval,exec,expr,exit,export,false,fi,for,function,getopts,% - hash,history,if,kill,nice,nohup,ps,pwd,read,readonly,return,% - sed,shift,test,then,times,trap,true,umask,unset,until,while},% - morecomment=[l]\#,% - morestring=[d]"% - }[keywords,comments,strings]% -\lst@definelanguage[90]{Fortran}[95]{Fortran}{} -\lst@definelanguage[95]{Fortran}[77]{Fortran}% - {deletekeywords=SAVE,% - morekeywords={ACTION,ADVANCE,ALLOCATE,ALLOCATABLE,ASSIGNMENT,CASE,% - CONTAINS,CYCLE,DEALLOCATE,DEFAULT,DELIM,EXIT,INCLUDE,IN,NONE,IN,% - OUT,INTENT,INTERFACE,IOLENGTH,KIND,LEN,MODULE,NAME,NAMELIST,NMT,% - NULLIFY,ONLY,OPERATOR,OPTIONAL,OUT,PAD,POINTER,POSITION,PRIVATE,% - PUBLIC,READWRITE,RECURSIVE,RESULT,SELECT,SEQUENCE,SIZE,STAT,% - TARGET,USE,WHERE,WHILE,BLOCKDATA,DOUBLEPRECISION,ELSEIF,% - ENDBLOCKDATA,ENDDO,ENDFILE,ENDFUNCTION,ENDIF,ENDINTERFACE,% - ENDMODULE,ENDPROGRAM,ENDSELECT,ENDSUBROUTINE,ENDTYPE,ENDWHERE,% - GOTO,INOUT,SELECTCASE},% - deletecomment=[f],% no fixed comment line: 1998 Magne Rudshaug - morecomment=[l]!% - }% -\lst@definelanguage[77]{Fortran}% - {morekeywords={ACCESS,ASSIGN,BACKSPACE,BLANK,BLOCK,CALL,CHARACTER,% - CLOSE,COMMON,COMPLEX,CONTINUE,DATA,DIMENSION,DIRECT,DO,DOUBLE,% - ELSE,END,ENTRY,EOF,EQUIVALENCE,ERR,EXIST,EXTERNAL,FILE,FMT,FORM,% - FORMAT,FORMATTED,FUNCTION,GO,TO,IF,IMPLICIT,INQUIRE,INTEGER,% - INTRINSIC,IOSTAT,LOGICAL,NAMED,NEXTREC,NUMBER,OPEN,OPENED,% - PARAMETER,PAUSE,PRECISION,PRINT,PROGRAM,READ,REAL,REC,RECL,% - RETURN,REWIND,SEQUENTIAL,STATUS,STOP,SUBROUTINE,THEN,TYPE,% - UNFORMATTED,UNIT,WRITE,SAVE},% - sensitive=f,%% not Fortran standard %% - morecomment=[f]*,% - morecomment=[f]C,% - morecomment=[f]c,% - morestring=[d]"% - }[keywords,comments,strings]% -\lst@definelanguage{HTML}% - {morekeywords={A,ABBR,ACRONYM,ADDRESS,APPLET,AREA,B,BASE,BASEFONT,% - BDO,BIG,BLOCKQUOTE,BODY,BR,BUTTON,CAPTION,CENTER,CITE,CODE,COL,% - COLGROUP,DD,DEL,DFN,DIR,DIV,DL,DOCTYPE,DT,EM,FIELDSET,FONT,FORM,% - FRAME,FRAMESET,HEAD,HR,H1,H2,H3,H4,H5,H6,HTML,I,IFRAME,IMG,INPUT,% - INS,ISINDEX,KBD,LABEL,LEGEND,LH,LI,LINK,LISTING,MAP,META,MENU,% - NOFRAMES,NOSCRIPT,OBJECT,OPTGROUP,OPTION,P,PARAM,PLAINTEXT,PRE,% - OL,Q,S,SAMP,SCRIPT,SELECT,SMALL,SPAN,STRIKE,STRING,STRONG,STYLE,% - SUB,SUP,TABLE,TBODY,TD,TEXTAREA,TFOOT,TH,THEAD,TITLE,TR,TT,U,UL,% - VAR,XMP,% - accesskey,action,align,alink,alt,archive,axis,background,bgcolor,% - border,cellpadding,cellspacing,charset,checked,cite,class,classid,% - code,codebase,codetype,color,cols,colspan,content,coords,data,% - datetime,defer,disabled,dir,event,error,for,frameborder,headers,% - height,href,hreflang,hspace,http-equiv,id,ismap,label,lang,link,% - longdesc,marginwidth,marginheight,maxlength,media,method,multiple,% - name,nohref,noresize,noshade,nowrap,onblur,onchange,onclick,% - ondblclick,onfocus,onkeydown,onkeypress,onkeyup,onload,onmousedown,% - profile,readonly,onmousemove,onmouseout,onmouseover,onmouseup,% - onselect,onunload,rel,rev,rows,rowspan,scheme,scope,scrolling,% - selected,shape,size,src,standby,style,tabindex,text,title,type,% - units,usemap,valign,value,valuetype,vlink,vspace,width,xmlns},% - tag=**[s]<>,% - sensitive=f,% - morestring=[d]",% ??? doubled - MoreSelectCharTable=% - \lst@CArgX--\relax\lst@DefDelimB{}{}% - {\ifnum\lst@mode=\lst@tagmode\else - \expandafter\@gobblethree - \fi}% - \lst@BeginComment\lst@commentmode{{\lst@commentstyle}}% - \lst@CArgX--\relax\lst@DefDelimE{}{}{}% - \lst@EndComment\lst@commentmode - }[keywords,comments,strings,html]% -%% -%% AspectJ definition (c) Robert Wenner -%% -\lst@definelanguage[AspectJ]{Java}[]{Java}% - {morekeywords={% - adviceexecution,after,args,around,aspect,aspectOf,before,% - call,cflow,cflowbelow,% - execution,get,handler,if,initialization,issingleton,pointcut,% - percflow,percflowbelow,perthis,pertarget,preinitialization,% - privileged,proceed,returning,set,staticinitialization,strictfp,% - target,this,thisEnclosingJoinPoint,thisJoinPoint,throwing,% - within,withincode},% - MoreSelectCharTable=% - \lst@DefSaveDef{`.}\lst@umdot{\lst@umdot\global\let\lst@derefop\@empty}% - \ifx\lst@derefinstalled\@empty\else - \global\let\lst@derefinstalled\@empty -\lst@AddToHook{Output}% -{\lst@ifkeywords - \ifx\lst@derefop\@empty - \global\let\lst@derefop\relax - \ifx\lst@thestyle\lst@gkeywords@sty - \ifx\lst@currstyle\relax - \let\lst@thestyle\lst@identifierstyle - \else - \let\lst@thestyle\lst@currstyle - \fi - \fi - \fi - \fi} -\lst@AddToHook{BOL}{\global\let\lst@derefop\relax}% -\lst@AddTo\lst@ProcessSpace{\global\let\lst@derefop\relax}% - \fi - }% -\lst@definelanguage{Java}% - {morekeywords={abstract,boolean,break,byte,case,catch,char,class,% - const,continue,default,do,double,else,extends,false,final,% - finally,float,for,goto,if,implements,import,instanceof,int,% - interface,label,long,native,new,null,package,private,protected,% - public,return,short,static,super,switch,synchronized,this,throw,% - throws,transient,true,try,void,volatile,while},% - sensitive,% - morecomment=[l]//,% - morecomment=[s]{/*}{*/},% - morestring=[b]",% - morestring=[b]',% - }[keywords,comments,strings]% -%% -%% ByteCodeJava definition (c) 2004 Martine Gautier -%% -\lst@definelanguage{JVMIS}% - {morekeywords={aaload,astore,aconst_null,aload,aload_0,aload_1,% - aload_2,aload_3,anewarray,areturn,arraylength,astore,astore_0,% - astore_1,astore_2,astore_3,athrow,baload,bastore,bipush,caload,% - castore,checkcast,d2f,d2i,d2l,dadd,daload,dastore,dcmpg,dcmpl,% - dconst_0,dconst_1,ddiv,dload,dload_0,dload_1,dload_2,dload_3,% - dmul,dneg,drem,dreturn,dstore,dstore_0,dstore_1,dstore_2,% - dstore_3,dsub,dup,dup_x1,dup_x2,dup2,dup2_x1,dup2_x2,f2d,% - f2i,f2l,fadd,faload,fastore,fcmpg,fcmpl,fconst_0,fconst_1,% - fconst_2,fdiv,fload,fload_0,fload_1,fload_2,fload_3,fmul,% - fneg,frem,freturn,fstore,fstore_0,fstore_1,fstore_2,fstore_3,% - fsub,getfield,getstatic,goto,goto_w,i2b,i2c,i2d,i2f,i2l,i2s,% - iadd,iaload,iand,iastore,iconst_0,iconst_1,iconst_2,iconst_3,% - iconst_4,iconst_5,idiv,if_acmpeq,if_acmpne,if_icmpeq,if_icmpne,% - if_icmplt,if_cmpge,if_cmpgt,if_cmple,ifeq,ifne,iflt,ifge,ifgt,% - ifle,ifnonnull,ifnull,iinc,iload,iload_0,iload_1,iload_2,% - iload_3,imul,ineg,instanceof,invokeinterface,invokespecial,% - invokestatic,invokevirtual,ior,irem,ireturn,ishl,ishr,istore,% - istore_0,istore_1,istore_2,istore_3,isub,iushr,ixor,jsr,jsr_w,% - l2d,l2f,l2i,ladd,laload,land,lastore,lcmp,lconst_0,lconst_1,% - ldc,ldc_w,ldc2_w,ldiv,lload,lload_0,lload_1,lload_2,lload_3,% - lmul,lneg,lookupswitch,lor,lrem,lreturn,lshl,lshr,lstore,% - lstore_0,lstore_1,lstore_2,lstore_3,lsub,lushr,lxor,% - monitorenter,monitorexit,multianewarray,new,newarray,nop,pop,% - pop2,putfield,putstatic,ret,return,saload,sastore,sipush,swap,% - tableswitch,wide,limit,locals,stack},% - }[keywords]% -\lst@definelanguage{Matlab}% - {morekeywords={gt,lt,gt,lt,amp,abs,acos,acosh,acot,acoth,acsc,acsch,% - all,angle,ans,any,asec,asech,asin,asinh,atan,atan2,atanh,auread,% - auwrite,axes,axis,balance,bar,bessel,besselk,bessely,beta,% - betainc,betaln,blanks,bone,break,brighten,capture,cart2pol,% - cart2sph,caxis,cd,cdf2rdf,cedit,ceil,chol,cla,clabel,clc,clear,% - clf,clock,close,colmmd,Colon,colorbar,colormap,ColorSpec,colperm,% - comet,comet3,compan,compass,computer,cond,condest,conj,contour,% - contour3,contourc,contrast,conv,conv2,cool,copper,corrcoef,cos,% - cosh,cot,coth,cov,cplxpair,cputime,cross,csc,csch,csvread,% - csvwrite,cumprod,cumsum,cylinder,date,dbclear,dbcont,dbdown,% - dbquit,dbstack,dbstatus,dbstep,dbstop,dbtype,dbup,ddeadv,ddeexec,% - ddeinit,ddepoke,ddereq,ddeterm,ddeunadv,deblank,dec2hex,deconv,% - del2,delete,demo,det,diag,diary,diff,diffuse,dir,disp,dlmread,% - dlmwrite,dmperm,dot,drawnow,echo,eig,ellipj,ellipke,else,elseif,% - end,engClose,engEvalString,engGetFull,engGetMatrix,engOpen,% - engOutputBuffer,engPutFull,engPutMatrix,engSetEvalCallback,% - engSetEvalTimeout,engWinInit,eps,erf,erfc,erfcx,erfinv,error,% - errorbar,etime,etree,eval,exist,exp,expint,expm,expo,eye,fclose,% - feather,feof,ferror,feval,fft,fft2,fftshift,fgetl,fgets,figure,% - fill,fill3,filter,filter2,find,findstr,finite,fix,flag,fliplr,% - flipud,floor,flops,fmin,fmins,fopen,for,format,fplot,fprintf,% - fread,frewind,fscanf,fseek,ftell,full,function,funm,fwrite,fzero,% - gallery,gamma,gammainc,gammaln,gca,gcd,gcf,gco,get,getenv,% - getframe,ginput,global,gplot,gradient,gray,graymon,grid,griddata,% - gtext,hadamard,hankel,help,hess,hex2dec,hex2num,hidden,hilb,hist,% - hold,home,hostid,hot,hsv,hsv2rgb,if,ifft,ifft2,imag,image,% - imagesc,Inf,info,input,int2str,interp1,interp2,interpft,inv,% - invhilb,isempty,isglobal,ishold,isieee,isinf,isletter,isnan,% - isreal,isspace,issparse,isstr,jet,keyboard,kron,lasterr,lcm,% - legend,legendre,length,lin2mu,line,linspace,load,log,log10,log2,% - loglog,logm,logspace,lookfor,lower,ls,lscov,lu,magic,matClose,% - matDeleteMatrix,matGetDir,matGetFp,matGetFull,matGetMatrix,% - matGetNextMatrix,matGetString,matlabrc,matlabroot,matOpen,% - matPutFull,matPutMatrix,matPutString,max,mean,median,menu,mesh,% - meshc,meshgrid,meshz,mexAtExit,mexCallMATLAB,mexdebug,% - mexErrMsgTxt,mexEvalString,mexFunction,mexGetFull,mexGetMatrix,% - mexGetMatrixPtr,mexPrintf,mexPutFull,mexPutMatrix,mexSetTrapFlag,% - min,more,movie,moviein,mu2lin,mxCalloc,mxCopyCharacterToPtr,% - mxCopyComplex16ToPtr,mxCopyInteger4ToPtr,mxCopyPtrToCharacter,% - mxCopyPtrToComplex16,mxCopyPtrToInteger4,mxCopyPtrToReal8,% - mxCopyReal8ToPtr,mxCreateFull,mxCreateSparse,mxCreateString,% - mxFree,mxFreeMatrix,mxGetIr,mxGetJc,mxGetM,mxGetN,mxGetName,% - mxGetNzmax,mxGetPi,mxGetPr,mxGetScalar,mxGetString,mxIsComplex,% - mxIsFull,mxIsNumeric,mxIsSparse,mxIsString,mxIsTypeDouble,% - mxSetIr,mxSetJc,mxSetM,mxSetN,mxSetName,mxSetNzmax,mxSetPi,% - mxSetPr,NaN,nargchk,nargin,nargout,newplot,nextpow2,nnls,nnz,% - nonzeros,norm,normest,null,num2str,nzmax,ode23,ode45,orient,orth,% - pack,pascal,patch,path,pause,pcolor,pi,pink,pinv,plot,plot3,% - pol2cart,polar,poly,polyder,polyeig,polyfit,polyval,polyvalm,% - pow2,print,printopt,prism,prod,pwd,qr,qrdelete,qrinsert,quad,% - quad8,quit,quiver,qz,rand,randn,randperm,rank,rat,rats,rbbox,% - rcond,real,realmax,realmin,refresh,rem,reset,reshape,residue,% - return,rgb2hsv,rgbplot,rootobject,roots,rose,rosser,rot90,rotate,% - round,rref,rrefmovie,rsf2csf,save,saxis,schur,sec,sech,semilogx,% - semilogy,set,setstr,shading,sign,sin,sinh,size,slice,sort,sound,% - spalloc,sparse,spaugment,spconvert,spdiags,specular,speye,spfun,% - sph2cart,sphere,spinmap,spline,spones,spparms,sprandn,sprandsym,% - sprank,sprintf,spy,sqrt,sqrtm,sscanf,stairs,startup,std,stem,% - str2mat,str2num,strcmp,strings,strrep,strtok,subplot,subscribe,% - subspace,sum,surf,surface,surfc,surfl,surfnorm,svd,symbfact,% - symmmd,symrcm,tan,tanh,tempdir,tempname,terminal,text,tic,title,% - toc,toeplitz,trace,trapz,tril,triu,type,uicontrol,uigetfile,% - uimenu,uiputfile,unix,unwrap,upper,vander,ver,version,view,% - viewmtx,waitforbuttonpress,waterfall,wavread,wavwrite,what,% - whatsnew,which,while,white,whitebg,who,whos,wilkinson,wk1read,% - wk1write,xlabel,xor,ylabel,zeros,zlabel,zoom},% - sensitive,% - morecomment=[l]\%,% - morestring=[m]'% - }[keywords,comments,strings]% -%% -%% Mathematica definitions (c) 1999 Michael Wiese -%% -\lst@definelanguage[3.0]{Mathematica}[1.0]{Mathematica}% - {morekeywords={Abort,AbortProtect,AbsoluteDashing,AbsolutePointSize,% - AbsoluteThickness,AbsoluteTime,AccountingFormAiry,AiPrime,AiryBi,% - AiryBiPrime,Alternatives,AnchoredSearch,AxesEdge,AxesOrigin,% - AxesStyle,Background,BetaRegularized,BoxStyle,C,CheckAbort,% - Circle,ClebschGordan,CMYKColor,ColorFunction,ColorOutput,Compile,% - Compiled,CompiledFunction,ComplexExpand,ComposeList,Composition,% - ConstrainedMax,ConstrainedMin,Contexts,ContextToFilename,% - ContourLines,Contours,ContourShading,ContourSmoothing,% - ContourStyle,CopyDirectory,CopyFile,CosIntegral,CreateDirectory,% - Cuboid,Date,DeclarePackage,DefaultColor,DefaultFont,Delete,% - DeleteCases,DeleteDirectory,DeleteFile,Dialog,DialogIndent,% - DialogProlog,DialogSymbols,DigitQ,Directory,DirectoryStack,Disk,% - Dispatch,DownValues,DSolve,Encode,Epilog,Erfc,Evaluate,% - ExponentFunction,FaceGrids,FileByteCount,FileDate,FileNames,% - FileType,Find,FindList,FixedPointList,FlattenAt,Fold,FoldList,% - Frame,FrameLabel,FrameStyle,FrameTicks,FromCharacterCode,% - FromDate,FullGraphics,FullOptions,GammaRegularized,% - GaussianIntegers,GraphicsArray,GraphicsSpacing,GridLines,% - GroebnerBasis,Heads,HeldPart,HomeDirectory,Hue,IgnoreCases,% - InputStream,Install,InString,IntegerDigits,InterpolatingFunction,% - InterpolatingPolynomial,Interpolation,Interrupt,InverseFunction,% - InverseFunctions,JacobiZeta,LetterQ,LinearProgramming,ListPlay,% - LogGamma,LowerCaseQ,MachineNumberQ,MantissaExponent,MapIndexed,% - MapThread,MatchLocalNames,MatrixExp,MatrixPower,MeshRange,% - MeshStyle,MessageList,Module,NDSolve,NSolve,NullRecords,% - NullWords,NumberFormat,NumberPadding,NumberSigns,OutputStream,% - PaddedForm,ParentDirectory,Pause,Play,PlayRange,PlotRegion,% - PolygonIntersections,PolynomialGCD,PolynomialLCM,PolynomialMod,% - PostScript,PowerExpand,PrecisionGoal,PrimePi,Prolog,% - QRDecomposition,Raster,RasterArray,RealDigits,Record,RecordLists,% - RecordSeparators,ReleaseHold,RenameDirectory,RenameFile,% - ReplaceHeldPart,ReplacePart,ResetDirectory,Residue,% - RiemannSiegelTheta,RiemannSiegelZ,RotateLabel,SameTest,% - SampleDepth,SampledSoundFunction,SampledSoundList,SampleRate,% - SchurDecomposition,SessionTime,SetAccuracy,SetDirectory,% - SetFileDate,SetPrecision,SetStreamPosition,Shallow,SignPadding,% - SinIntegral,SixJSymbol,Skip,Sound,SpellingCorrection,% - SphericalRegion,Stack,StackBegin,StackComplete,StackInhibit,% - StreamPosition,Streams,StringByteCount,StringConversion,% - StringDrop,StringInsert,StringPosition,StringReplace,% - StringReverse,StringTake,StringToStream,SurfaceColor,% - SyntaxLength,SyntaxQ,TableAlignments,TableDepth,% - TableDirections,TableHeadings,TableSpacing,ThreeJSymbol,TimeUsed,% - TimeZone,ToCharacterCode,ToDate,ToHeldExpression,TokenWords,% - ToLowerCase,ToUpperCase,Trace,TraceAbove,TraceBackward,% - TraceDepth,TraceDialog,TraceForward,TraceOff,TraceOn,% - TraceOriginal,TracePrint,TraceScan,Trig,Unevaluated,Uninstall,% - UnsameQ,UpperCaseQ,UpValues,ViewCenter,ViewVertical,With,Word,% - WordSearch,WordSeparators},% - morendkeywords={Stub,Temporary,$Aborted,$BatchInput,$BatchOutput,% - $CreationDate,$DefaultFont,$DumpDates,$DumpSupported,$Failed,% - $Input,$Inspector,$IterationLimit,$Language,$Letters,$Linked,% - $LinkSupported,$MachineEpsilon,$MachineID,$MachineName,% - $MachinePrecision,$MachineType,$MaxMachineNumber,$MessageList,% - $MessagePrePrint,$MinMachineNumber,$ModuleNumber,$NewMessage,% - $NewSymbol,$Notebooks,$OperatingSystem,$Packages,$PipeSupported,% - $PreRead,$ReleaseNumber,$SessionID,$SoundDisplayFunction,% - $StringConversion,$StringOrder,$SyntaxHandler,$TimeUnit,% - $VersionNumber}% - }% -\lst@definelanguage[1.0]{Mathematica}% - {morekeywords={Abs,Accuracy,AccurayGoal,AddTo,AiryAi,AlgebraicRules,% - AmbientLight,And,Apart,Append,AppendTo,Apply,ArcCos,ArcCosh,% - ArcCot,ArcCoth,ArcCsc,ArcCsch,ArcSec,ArcSech,ArcSin,ArcSinh,% - ArcTan,ArcTanh,Arg,ArithmeticGeometricMean,Array,AspectRatio,% - AtomQ,Attributes,Axes,AxesLabel,BaseForm,Begin,BeginPackage,% - BernoulliB,BesselI,BesselJ,BesselK,BesselY,Beta,Binomial,Blank,% - BlankNullSequence,BlankSequence,Block,Boxed,BoxRatios,Break,Byte,% - ByteCount,Cancel,Cases,Catch,Ceiling,CForm,Character,Characters,% - ChebyshevT,ChebyshevU,Check,Chop,Clear,ClearAll,ClearAttributes,% - ClipFill,Close,Coefficient,CoefficientList,Collect,ColumnForm,% - Complement,Complex,CompoundExpression,Condition,Conjugate,% - Constants,Context,Continuation,Continue,ContourGraphics,% - ContourPlot,Cos,Cosh,Cot,Coth,Count,Csc,Csch,Cubics,Cyclotomic,% - D,Dashing,Decompose,Decrement,Default,Definition,Denominator,% - DensityGraphics,DensityPlot,Depth,Derivative,Det,DiagonalMatrix,% - DigitBlock,Dimensions,DirectedInfinity,Display,DisplayFunction,% - Distribute,Divide,DivideBy,Divisors,DivisorSigma,Do,Dot,Drop,Dt,% - Dump,EdgeForm,Eigensystem,Eigenvalues,Eigenvectors,Eliminate,% - EllipticE,EllipticExp,EllipticF,EllipticK,EllipticLog,EllipticPi,% - EllipticTheta,End,EndPackage,EngineeringForm,Environment,Equal,% - Erf,EulerE,EulerPhi,EvenQ,Exit,Exp,Expand,ExpandAll,% - ExpandDenominator,ExpandNumerator,ExpIntegralE,ExpIntegralEi,% - Exponent,Expression,ExtendedGCD,FaceForm,Factor,FactorComplete,% - Factorial,Factorial2,FactorInteger,FactorList,FactorSquareFree,% - FactorSquareFreeList,FactorTerms,FactorTermsList,FindMinimum,% - FindRoot,First,Fit,FixedPoint,Flatten,Floor,FontForm,For,Format,% - FormatType,FortranForm,Fourier,FreeQ,FullDefinition,FullForm,% - Function,Gamma,GCD,GegenbauerC,General,Get,Goto,Graphics,% - Graphics3D,GrayLevel,Greater,GreaterEqual,Head,HermiteH,% - HiddenSurface,Hold,HoldForm,Hypergeometric0F1, Hypergeometric1F1,% - Hypergeometric2F1,HypergeometricU,Identity,IdentityMatrix,If,Im,% - Implies,In,Increment,Indent,Infix,Information,Inner,Input,% - InputForm,InputString,Insert,Integer,IntegerQ,Integrate,% - Intersection,Inverse,InverseFourier,InverseJacobiSN,% - InverseSeries,JacobiAmplitude,JacobiP,JacobiSN,JacobiSymbol,Join,% - Label,LaguerreL,Last,LatticeReduce,LCM,LeafCount,LegendreP,% - LegendreQ,LegendreType,Length,LerchPhi,Less,LessEqual,Level,% - Lighting,LightSources,Limit,Line,LinearSolve,LineBreak,List,% - ListContourPlot,ListDensityPlot,ListPlot,ListPlot3D,Literal,Log,% - LogicalExpand,LogIntegral,MainSolve,Map,MapAll,MapAt,MatchQ,% - MatrixForm,MatrixQ,Max,MaxBend,MaxMemoryUsed,MemberQ,% - MemoryConstrained,MemoryInUse,Mesh,Message,MessageName,Messages,% - Min,Minors,Minus,Mod,Modulus,MoebiusMu,Multinomial,N,NameQ,Names,% - NBernoulliB,Needs,Negative,Nest,NestList,NIntegrate,% - NonCommutativeMultiply,NonConstants,NonNegative,Normal,Not,% - NProduct,NSum,NullSpace,Number,NumberForm,NumberPoint,NumberQ,% - NumberSeparator,Numerator,O,OddQ,Off,On,OpenAppend,OpenRead,% - OpenTemporary,OpenWrite,Operate,Optional,Options,Or,Order,% - OrderedQ,Out,Outer,OutputForm,PageHeight,PageWidth,% - ParametricPlot,ParametricPlot3D,Part,Partition,PartitionsP,% - PartitionsQ,Pattern,Permutations,Plot,Plot3D,PlotDivision,% - PlotJoined,PlotLabel,PlotPoints,PlotRange,PlotStyle,Pochhammer,% - Plus,Point,PointSize,PolyGamma,Polygon,PolyLog,PolynomialQ,% - PolynomialQuotient,PolynomialRemainder,Position,Positive,Postfix,% - Power,PowerMod,PrecedenceForm,Precision,PreDecrement,Prefix,% - PreIncrement,Prepend,PrependTo,Prime,PrimeQ,Print,PrintForm,% - Product,Protect,PseudoInverse,Put,PutAppend,Quartics,Quit,% - Quotient,Random,Range,Rational,Rationalize,Raw,Re,Read,ReadList,% - Real,Rectangle,Reduce,Remove,RenderAll,Repeated,RepeatedNull,% - Replace,ReplaceAll,ReplaceRepeated,Rest,Resultant,Return,Reverse,% - RGBColor,Roots,RotateLeft,RotateRight,Round,RowReduce,Rule,% - RuleDelayed,Run,RunThrough,SameQ,Save,Scaled,Scan,ScientificForm,% - Sec,Sech,SeedRandom,Select,Sequence,SequenceForm,Series,% - SeriesData,Set,SetAttributes,SetDelayed,SetOptions,Shading,Share,% - Short,Show,Sign,Signature,Simplify,Sin,SingularValues,Sinh,% - Skeleton,Slot,SlotSequence,Solve,SolveAlways,Sort,% - SphericalHarmonicY,Splice,Sqrt,StirlingS1,StirlingS2,String,% - StringBreak,StringForm,StringJoin,StringLength,StringMatchQ,% - StringSkeleton,Subscript,Subscripted,Subtract,SubtractForm,Sum,% - Superscript,SurfaceGraphics,Switch,Symbol,Table,TableForm,TagSet,% - TagSetDelayed,TagUnset,Take,Tan,Tanh,ToString,TensorRank,TeXForm,% - Text,TextForm,Thickness,Thread,Through,Throw,Ticks,% - TimeConstrained,Times,TimesBy,Timing,ToExpression,Together,% - ToRules,ToString,TotalHeight,TotalWidth,Transpose,TreeForm,TrueQ,% - Unequal,Union,Unique,Unprotect,Unset,Update,UpSet,UpSetDelayed,% - ValueQ,Variables,VectorQ,ViewPoint,WeierstrassP,% - WeierstrassPPrime,Which,While,WorkingPrecision,Write,WriteString,% - Xor,ZeroTest,Zeta},% - morendkeywords={All,Automatic,Catalan,ComplexInfinity,Constant,% - Degree,E,EndOfFile,EulerGamma,False,Flat,GoldenRatio,HoldAll,% - HoldFirst,HoldRest,I,Indeterminate,Infinity,Listable,Locked,% - Modular,None,Null,OneIdentity,Orderless,Pi,Protected,% - ReadProtected,True,$CommandLine,$Context,$ContextPath,$Display,% - $DisplayFunction,$Echo,$Epilog,$IgnoreEOF,$Line,$Messages,% - $Output,$Path,$Post,$Pre,$PrePrint,$RecursionLimit,$System,% - $Urgent,$Version},% - sensitive,% - morecomment=[s]{(*}{*)},% - morestring=[d]"% - }[keywords,comments,strings]% -%% -%% Octave definition (c) 2001,2002 Ulrich G. Wortmann -%% -\lst@definelanguage{Octave}% - {morekeywords={gt,lt,gt,lt,amp,abs,acos,acosh,acot,acoth,acsc,acsch,% - all,angle,ans,any,asec,asech,asin,asinh,atan,atan2,atanh,auread,% - auwrite,axes,axis,balance,bar,bessel,besselk,bessely,beta,% - betainc,betaln,blanks,bone,break,brighten,capture,cart2pol,% - cart2sph,caxis,cd,cdf2rdf,cedit,ceil,chol,cla,clabel,clc,clear,% - clf,clock,close,colmmd,Colon,colorbar,colormap,ColorSpec,colperm,% - comet,comet3,compan,compass,computer,cond,condest,conj,contour,% - contour3,contourc,contrast,conv,conv2,cool,copper,corrcoef,cos,% - cosh,cot,coth,cov,cplxpair,cputime,cross,csc,csch,csvread,% - csvwrite,cumprod,cumsum,cylinder,date,dbclear,dbcont,dbdown,% - dbquit,dbstack,dbstatus,dbstep,dbstop,dbtype,dbup,ddeadv,ddeexec,% - ddeinit,ddepoke,ddereq,ddeterm,ddeunadv,deblank,dec2hex,deconv,% - del2,delete,demo,det,diag,diary,diff,diffuse,dir,disp,dlmread,% - dlmwrite,dmperm,dot,drawnow,echo,eig,ellipj,ellipke,else,elseif,% - end,engClose,engEvalString,engGetFull,engGetMatrix,engOpen,% - engOutputBuffer,engPutFull,engPutMatrix,engSetEvalCallback,% - engSetEvalTimeout,engWinInit,eps,erf,erfc,erfcx,erfinv,% - errorbar,etime,etree,eval,exist,exp,expint,expm,expo,eye,fclose,% - feather,feof,ferror,feval,fft,fft2,fftshift,fgetl,fgets,figure,% - fill,fill3,filter,filter2,find,findstr,finite,fix,flag,fliplr,% - flipud,floor,flops,fmin,fmins,fopen,for,format,fplot,fprintf,% - fread,frewind,fscanf,fseek,ftell,full,function,funm,fwrite,fzero,% - gallery,gamma,gammainc,gammaln,gca,gcd,gcf,gco,get,getenv,% - getframe,ginput,global,gplot,gradient,gray,graymon,grid,griddata,% - gtext,hadamard,hankel,help,hess,hex2dec,hex2num,hidden,hilb,hist,% - hold,home,hostid,hot,hsv,hsv2rgb,if,ifft,ifft2,imag,image,% - imagesc,Inf,info,input,int2str,interp1,interp2,interpft,inv,% - invhilb,isempty,isglobal,ishold,isieee,isinf,isletter,isnan,% - isreal,isspace,issparse,isstr,jet,keyboard,kron,lasterr,lcm,% - legend,legendre,length,lin2mu,line,linspace,load,log,log10,log2,% - loglog,logm,logspace,lookfor,lower,ls,lscov,lu,magic,matClose,% - matDeleteMatrix,matGetDir,matGetFp,matGetFull,matGetMatrix,% - matGetNextMatrix,matGetString,matlabrc,matlabroot,matOpen,% - matPutFull,matPutMatrix,matPutString,max,mean,median,menu,mesh,% - meshc,meshgrid,meshz,mexAtExit,mexCallMATLAB,mexdebug,% - mexErrMsgTxt,mexEvalString,mexFunction,mexGetFull,mexGetMatrix,% - mexGetMatrixPtr,mexPrintf,mexPutFull,mexPutMatrix,mexSetTrapFlag,% - min,more,movie,moviein,mu2lin,mxCalloc,mxCopyCharacterToPtr,% - mxCopyComplex16ToPtr,mxCopyInteger4ToPtr,mxCopyPtrToCharacter,% - mxCopyPtrToComplex16,mxCopyPtrToInteger4,mxCopyPtrToReal8,% - mxCopyReal8ToPtr,mxCreateFull,mxCreateSparse,mxCreateString,% - mxFree,mxFreeMatrix,mxGetIr,mxGetJc,mxGetM,mxGetN,mxGetName,% - mxGetNzmax,mxGetPi,mxGetPr,mxGetScalar,mxGetString,mxIsComplex,% - mxIsFull,mxIsNumeric,mxIsSparse,mxIsString,mxIsTypeDouble,% - mxSetIr,mxSetJc,mxSetM,mxSetN,mxSetName,mxSetNzmax,mxSetPi,% - mxSetPr,NaN,nargchk,nargin,nargout,newplot,nextpow2,nnls,nnz,% - nonzeros,norm,normest,null,num2str,nzmax,ode23,ode45,orient,orth,% - pack,pascal,patch,path,pause,pcolor,pi,pink,pinv,plot,plot3,% - pol2cart,polar,poly,polyder,polyeig,polyfit,polyval,polyvalm,% - pow2,print,printopt,prism,prod,pwd,qr,qrdelete,qrinsert,quad,% - quad8,quit,quiver,qz,rand,randn,randperm,rank,rat,rats,rbbox,% - rcond,real,realmax,realmin,refresh,rem,reset,reshape,residue,% - return,rgb2hsv,rgbplot,rootobject,roots,rose,rosser,rot90,rotate,% - round,rref,rrefmovie,rsf2csf,save,saxis,schur,sec,sech,semilogx,% - semilogy,set,setstr,shading,sign,sin,sinh,size,slice,sort,sound,% - spalloc,sparse,spaugment,spconvert,spdiags,specular,speye,spfun,% - sph2cart,sphere,spinmap,spline,spones,spparms,sprandn,sprandsym,% - sprank,sprintf,spy,sqrt,sqrtm,sscanf,stairs,startup,std,stem,% - str2mat,str2num,strcmp,strings,strrep,strtok,subplot,subscribe,% - subspace,sum,surf,surface,surfc,surfl,surfnorm,svd,symbfact,% - symmmd,symrcm,tan,tanh,tempdir,tempname,terminal,text,tic,title,% - toc,toeplitz,trace,trapz,tril,triu,type,uicontrol,uigetfile,% - uimenu,uiputfile,unix,unwrap,upper,vander,ver,version,view,% - viewmtx,waitforbuttonpress,waterfall,wavread,wavwrite,what,% - whatsnew,which,while,white,whitebg,who,whos,wilkinson,wk1read,% - stderr,stdout,plot,set,endif,wk1write,xlabel,xor,ylabel,zeros,% - zlabel,zoom,endwhile,endfunction},% - sensitive=f,% - morecomment=[l]\#,% - morecomment=[l]\#\#,% - morestring=[m]',% - morestring=[m]"% - }[keywords,comments,strings]% -\lst@definelanguage[XSC]{Pascal}[Standard]{Pascal} - {deletekeywords={alfa,byte,pack,unpack},% 1998 Andreas Stephan - morekeywords={dynamic,external,forward,global,module,nil,operator,% - priority,sum,type,use,dispose,mark,page,release,cimatrix,% - cinterval,civector,cmatrix,complex,cvector,dotprecision,imatrix,% - interval,ivector,rmatrix,rvector,string,im,inf,re,sup,chr,comp,% - eof,eoln,expo,image,ival,lb,lbound,length,loc,mant,maxlength,odd,% - ord,pos,pred,round,rval,sign,substring,succ,trunc,ub,ubound}% - }% -\lst@definelanguage[Borland6]{Pascal}[Standard]{Pascal} - {morekeywords={asm,constructor,destructor,implementation,inline,% - interface,nil,object,shl,shr,string,unit,uses,xor},% - morendkeywords={Abs,Addr,ArcTan,Chr,Concat,Copy,Cos,CSeg,DiskFree,% - DiskSize,DosExitCode,DosVersion,DSeg,EnvCount,EnvStr,Eof,Eoln,% - Exp,FExpand,FilePos,FileSize,Frac,FSearch,GetBkColor,GetColor,% - GetDefaultPalette,GetDriverName,GetEnv,GetGraphMode,GetMaxMode,% - GetMaxX,GetMaxY,GetModeName,GetPaletteSize,GetPixel,GetX,GetY,% - GraphErrorMsg,GraphResult,Hi,ImageSize,InstallUserDriver,% - InstallUserFont,Int,IOResult,KeyPressed,Length,Lo,MaxAvail,% - MemAvail,MsDos,Odd,Ofs,Ord,OvrGetBuf,OvrGetRetry,ParamCount,% - ParamStr,Pi,Pos,Pred,Ptr,Random,ReadKey,Round,SeekEof,SeekEoln,% - Seg,SetAspectRatio,Sin,SizeOf,Sound,SPtr,Sqr,Sqrt,SSeg,Succ,% - Swap,TextHeight,TextWidth,Trunc,TypeOf,UpCase,WhereX,WhereY,% - Append,Arc,Assign,AssignCrt,Bar,Bar3D,BlockRead,BlockWrite,ChDir,% - Circle,ClearDevice,ClearViewPort,Close,CloseGraph,ClrEol,ClrScr,% - Dec,Delay,Delete,DelLine,DetectGraph,Dispose,DrawPoly,Ellipse,% - Erase,Exec,Exit,FillChar,FillEllipse,FillPoly,FindFirst,FindNext,% - FloodFill,Flush,FreeMem,FSplit,GetArcCoords,GetAspectRatio,% - GetDate,GetDefaultPalette,GetDir,GetCBreak,GetFAttr,% - GetFillSettings,GetFTime,GetImage,GetIntVec,GetLineSettings,% - GetMem,GetPalette,GetTextSettings,GetTime,GetVerify,% - GetViewSettings,GoToXY,Halt,HighVideo,Inc,InitGraph,Insert,% - InsLine,Intr,Keep,Line,LineRel,LineTo,LowVideo,Mark,MkDir,Move,% - MoveRel,MoveTo,MsDos,New,NormVideo,NoSound,OutText,OutTextXY,% - OvrClearBuf,OvrInit,OvrInitEMS,OvrSetBuf,PackTime,PieSlice,% - PutImage,PutPixel,Randomize,Rectangle,Release,Rename,% - RestoreCrtMode,RmDir,RunError,Sector,Seek,SetActivePage,% - SetAllPalette,SetBkColor,SetCBreak,SetColor,SetDate,SetFAttr,% - SetFillPattern,SetFillStyle,SetFTime,SetGraphBufSize,% - SetGraphMode,SetIntVec,SetLineStyle,SetPalette,SetRGBPalette,% - SetTextBuf,SetTextJustify,SetTextStyle,SetTime,SetUserCharSize,% - SetVerify,SetViewPort,SetVisualPage,SetWriteMode,Sound,Str,% - SwapVectors,TextBackground,TextColor,TextMode,Truncate,% - UnpackTime,Val,Window}% - }% -\lst@definelanguage[Standard]{Pascal}% - {morekeywords={alfa,and,array,begin,boolean,byte,case,char,const,div,% - do,downto,else,end,false,file,for,function,get,goto,if,in,% - integer,label,maxint,mod,new,not,of,or,pack,packed,page,program,% - put,procedure,read,readln,real,record,repeat,reset,rewrite,set,% - text,then,to,true,type,unpack,until,var,while,with,write,% - writeln},% - sensitive=f,% - morecomment=[s]{(*}{*)},% - morecomment=[s]{\{}{\}},% - morestring=[d]'% - }[keywords,comments,strings]% -\lst@definelanguage{Perl}% - {morekeywords={abs,accept,alarm,atan2,bind,binmode,bless,caller,% - chdir,chmod,chomp,chop,chown,chr,chroot,close,closedir,connect,% - continue,cos,crypt,dbmclose,dbmopen,defined,delete,die,do,dump,% - each,else,elsif,endgrent,endhostent,endnetent,endprotoent,% - endpwent,endservent,eof,eval,exec,exists,exit,exp,fcntl,fileno,% - flock,for,foreach,fork,format,formline,getc,getgrent,getgrgid,% - getgrnam,gethostbyaddr,gethostbyname,gethostent,getlogin,% - getnetbyaddr,getnetbyname,getnetent,getpeername,getpgrp,% - getppid,getpriority,getprotobyname,getprotobynumber,getprotoent,% - getpwent,getpwnam,getpwuid,getservbyname,getservbyport,% - getservent,getsockname,getsockopt,glob,gmtime,goto,grep,hex,if,% - import,index,int,ioctl,join,keys,kill,last,lc,lcfirst,length,% - link,listen,local,localtime,log,lstat,m,map,mkdir,msgctl,msgget,% - msgrcv,msgsnd,my,next,no,oct,open,opendir,ord,pack,package,pipe,% - pop,pos,print,printf,prototype,push,q,qq,quotemeta,qw,qx,rand,% - read,readdir,readlink,recv,redo,ref,rename,require,reset,return,% - reverse,rewinddir,rindex,rmdir,s,scalar,seek,seekdir,select,% - semctl,semget,semop,send,setgrent,sethostent,setnetent,setpgrp,% - setpriority,setprotoent,setpwent,setservent,setsockopt,shift,% - shmctl,shmget,shmread,shmwrite,shutdown,sin,sleep,socket,% - socketpair,sort,splice,split,sprintf,sqrt,srand,stat,study,sub,% - substr,symlink,syscall,sysopen,sysread,system,syswrite,tell,% - telldir,tie,tied,time,times,tr,truncate,uc,ucfirst,umask,undef,% - unless,unlink,unpack,unshift,untie,until,use,utime,values,vec,% - wait,waitpid,wantarray,warn,while,write,y},% - sensitive,% - morecomment=[l]\#,% - morestring=[b]",% - morestring=[b]',% - MoreSelectCharTable=% - \lst@ReplaceInput{\$\#}{\lst@ProcessOther\$\lst@ProcessOther\#}% - }[keywords,comments,strings]% -%% -%% POV definition (c) 1999 Berthold H\"ollmann -%% -\lst@definelanguage{POV}% - {morekeywords={abs,absorption,acos,acosh,adaptive,adc_bailout,agate,% - agate_turb,all,alpha,ambient,ambient_light,angle,aperture,append,% - arc_angle,area_light,array,asc,asin,asinh,assumed_gamma,atan,% - atan2,atanh,average,background,bezier_spline,bicubic_patch,% - black_hole,blob,blue,blur_samples,bounded_by,box,boxed,bozo,% - break,brick,brick_size,brightness,brilliance,bumps,bump_map,% - bump_size,camera,case,caustics,ceil,checker,chr,clipped_by,clock,% - clock_delta,color,color_map,colour,colour_map,component,% - composite,concat,cone,confidence,conic_sweep,control0,control1,% - cos,cosh,count,crackle,crand,cube,cubic,cubic_spline,cubic_wave,% - cylinder,cylindrical,debug,declare,default,defined,degrees,% - density,density_file,density_map,dents,difference,diffuse,% - dimensions,dimension_size,direction,disc,distance,% - distance_maximum,div,eccentricity,else,emission,end,error,% - error_bound,exp,extinction,fade_distance,fade_power,falloff,% - falloff_angle,false,fclose,file_exists,filter,finish,fisheye,% - flatness,flip,floor,focal_point,fog,fog_alt,fog_offset,fog_type,% - fopen,frequency,gif,global_settings,gradient,granite,% - gray_threshold,green,height_field,hexagon,hf_gray_16,hierarchy,% - hollow,hypercomplex,if,ifdef,iff,ifndef,image_map,include,int,% - interior,interpolate,intersection,intervals,inverse,ior,irid,% - irid_wavelength,jitter,julia_fractal,lambda,lathe,leopard,% - light_source,linear_spline,linear_sweep,local,location,log,% - looks_like,look_at,low_error_factor,macro,mandel,map_type,marble,% - material,material_map,matrix,max,max_intersections,max_iteration,% - max_trace_level,media,media_attenuation,media_interaction,merge,% - mesh,metallic,min,minimum_reuse,mod,mortar,nearest_count,no,% - normal,normal_map,no_shadow,number_of_waves,object,octaves,off,% - offset,omega,omnimax,on,once,onion,open,orthographic,panoramic,% - perspective,pgm,phase,phong,phong_size,pi,pigment,pigment_map,% - planar,plane,png,point_at,poly,polygon,poly_wave,pot,pow,ppm,% - precision,prism,pwr,quadratic_spline,quadric,quartic,quaternion,% - quick_color,quick_colour,quilted,radial,radians,radiosity,radius,% - rainbow,ramp_wave,rand,range,ratio,read,reciprocal,% - recursion_limit,red,reflection,reflection_exponent,refraction,% - render,repeat,rgb,rgbf,rgbft,rgbt,right,ripples,rotate,roughness,% - samples,scale,scallop_wave,scattering,seed,shadowless,sin,% - sine_wave,sinh,sky,sky_sphere,slice,slope_map,smooth,% - smooth_triangle,sor,specular,sphere,spherical,spiral1,spiral2,% - spotlight,spotted,sqr,sqrt,statistics,str,strcmp,strength,strlen,% - strlwr,strupr,sturm,substr,superellipsoid,switch,sys,t,tan,tanh,% - text,texture,texture_map,tga,thickness,threshold,tightness,tile2,% - tiles,torus,track,transform,translate,transmit,triangle,% - triangle_wave,true,ttf,turbulence,turb_depth,type,u,% - ultra_wide_angle,undef,union,up,use_color,use_colour,use_index,% - u_steps,v,val,variance,vaxis_rotate,vcross,vdot,version,vlength,% - vnormalize,vrotate,v_steps,warning,warp,water_level,waves,while,% - width,wood,wrinkles,write,x,y,yes,z},% - moredirectives={break,case,debug,declare,default,else,end,fclose,% - fopen,local,macro,read,render,statistics,switch,undef,version,% - warning,write},% - moredelim=*[directive]\#,% - sensitive,% - morecomment=[l]//,% - morecomment=[s]{/*}{*/},% - morestring=[d]",% - }[keywords,directives,comments,strings]% -%% -%% Python definition (c) 1998 Michael Weber -%% -\lst@definelanguage{Python}% - {morekeywords={access,and,break,class,continue,def,del,elif,else,% - except,exec,finally,for,from,global,if,import,in,is,lambda,not,% - or,pass,print,raise,return,try,while},% - sensitive=true,% - morecomment=[l]\#,% - morecomment=[s]{'''}{'''},% used for documentation text - morecomment=[s]{"""}{"""},% added by Philipp Matthias Hahn - morestring=[b]',% - morestring=[b]"% - }% -%% -%% Scilab definition (c) 2002,2003 Jean-Philippe Grivet -%% -\lst@definelanguage{Scilab}% - {morekeywords={abcd,abinv,abort,abs,acoshm,acosh,acosm,acos,addcolor,% - addf,addinter,addmenu,add_edge,add_node,adj2sp,adj_lists,aff2ab,% - amell,analpf,analyze,ans,apropos,arc_graph,arc_number,argn,arhnk,% - arl2,arma2p,armac,armax1,armax,arma,arsimul,artest,articul,ascii,% - asinhm,asinh,asinm,asin,atanhm,atanh,atanm,atan,augment,auread,% - auwrite,balanc,balreal,bandwr,basename,bdiag,besseli,besselj,% - besselk,bessely,best_match,bezout,bifish,bilin,binomial,black,% - bloc2exp,bloc2ss,bode,bool2s,boolean,boucle,break,bstap,buttmag,% - bvode,cainv,calerf,calfrq,call,canon,casc,case,ccontrg,cdfbet,% - cdfbin,cdfchi,cdfchn,cdffnc,cdff,cdfgam,cdfnbn,cdfnor,cdfpoi,% - cdft,ceil,center,cepstrum,chaintest,chain_struct,champ1,champ,% - chart,chdir,cheb1mag,cheb2mag,check_graph,check_io,chepol,chfact,% - chol,chsolve,circuit,classmarkov,clean,clearfun,clearglobal,% - clear,close,cls2dls,cmb_lin,cmndred,cmoment,code2str,coeff,coffg,% - coff,colcompr,colcomp,colinout,colormap,colregul,companion,comp,% - cond,conj,connex,contour2di,contour2d,contourf,contour,% - contract_edge,contrss,contr,cont_frm,cont_mat,convex_hull,convol,% - convstr,con_nodes,copfac,copy,correl,corr,coshm,cosh,cosm,cos,% - cotg,cothm,coth,covar,csim,cspect,ctr_gram,cumprod,cumsum,% - curblock,cycle_basis,czt,c_link,dasrt,dassl,datafit,date,dbphi,% - dcf,ddp,debug,dec2hex,deff,definedfields,degree,delbpt,% - delete_arcs,delete_nodes,delete,delip,delmenu,demos,denom,% - derivative,derivat,des2ss,des2tf,determ,detr,det,dft,dhinf,% - dhnorm,diag,diary,diff,diophant,dirname,dispbpt,dispfiles,disp,% - dlgamma,double,dragrect,drawaxis,drawlater,drawnow,draw,driver,% - dscr,dsearch,dsimul,dtsi,dt_ility,duplicate,edge_number,% - edit_curv,edit_graph_menus,edit_graph,edit,eigenmarkov,ell1mag,% - elseif,else,emptystr,endfunction,end,eqfir,eqiir,equil1,equil,% - ereduc,erfcx,erfc,erf,errbar,errcatch,errclear,error,eval3dp,% - eval3d,eval,evans,evstr,excel2sci,execstr,exec,exists,exit,expm,% - exp,external,eye,fac3d,factors,faurre,fchamp,fcontour2d,fcontour,% - fec,feedback,feval,ffilt,fftshift,fft,fgrayplot,figure,fileinfo,% - file,filter,findm,findobj,findx0BD,find_freq,find_path,find,% - findABCD,findAC,findBD,findBDK,findR,fit_dat,fix,floor,flts,foo,% - formatman,format,fort,for,fourplan,fplot2d,fplot3d1,fplot3d,% - fprintf,fprintfMat,frep2tf,freq,freson,frexp,frfit,frmag,fscanf,% - fscanfMat,fsfirlin,fsolve,fspecg,fstabst,fstair,ftest,ftuneq,% - fullrfk,fullrf,full,fun2string,funcprot,functions,function,% - funptr,fusee,gainplot,gamitg,gammaln,gamma,gcare,gcd,gcf,% - genfac3d,genlib,genmarkov,gen_net,geom3d,geomean,getblocklabel,% - getcolor,getcurblock,getcwd,getdate,getd,getenv,getfield,getfont,% - getf,getio,getlinestyle,getmark,getpid,getscicosvars,getsymbol,% - getvalue,getversion,get_function_path,get,gfare,gfrancis,girth,% - givens,glever,glist,global,glue,gpeche,graduate,grand,% - graphics_entities,graph_2_mat,graph_center,graph_complement,% - graph_diameter,graph_power,graph_simp,graph_sum,graph_union,% - graph-list,graycolormap,grayplot,graypolarplot,grep,group,% - gr_menu,gschur,gsort,gspec,gstacksize,gtild,g_margin,h2norm,halt,% - hamilton,hankelsv,hank,harmean,havewindow,help,hermit,hess,% - hex2dec,hilb,hinf,hist3d,histplot,horner,host,hotcolormap,% - householder,hrmt,htrianr,hypermat,h_cl,h_inf_st,h_inf,h_norm,% - iconvert,icon_edit,ieee,if,iirgroup,iirlp,iir,ilib_build,% - ilib_compile,ilib_for_link,ilib_gen_gateway,ilib_gen_loader,% - ilib_gen_Make,imag,impl,imrep2ss,imult,im_inv,inistate,input,% - int16,int2d,int32,int3d,int8,intc,intdec,integrate,interpln,% - interp,intersci,intersect,intg,intl,intppty,intsplin,inttrap,% - inttype,int,invr,invsyslin,inv_coeff,inv,iqr,isdef,isdir,isequal,% - iserror,isglobal,isinf,isnan,isoview,isreal,is_connex,jmat,% - justify,kalm,karmarkar,kernel,keyboard,knapsack,kpure,krac2,% - kroneck,kron,lasterror,lattn,lattp,lcf,lcmdiag,lcm,ldivf,ldiv,% - leastsq,legends,length,leqr,levin,lev,lex_sort,lft,lgfft,library,% - lib,lin2mu,lincos,lindquist,lines,line_graph,linfn,linf,link,% - linmeq,linpro,linsolve,linspace,lin,listfiles,list,lmisolver,% - lmitool,loadmatfile,loadplots,loadwave,load_graph,load,locate,% - log10,log1p,log2,logm,logspace,log,lotest,lqe,lqg2stan,lqg_ltr,% - lqg,lqr,lsq,lsslist,lstcat,lstsize,ltitr,ludel,lufact,luget,% - lusolve,lu,lyap,macglov,macr2lst,macrovar,macro,mad,make_graph,% - make_index,manedit,man,mapsound,markp2ss,matfile2sci,matrix,% - mat_2_graph,maxi,max_cap_path,max_clique,max_flow,max,mclearerr,% - mclose,meanf,mean,median,meof,mese,mesh2d,mfft,mfile2sci,mgeti,% - mgetl,mgetstr,mget,milk_drop,mine,mini,minreal,minss,% - min_lcost_cflow,min_lcost_flow1,min_lcost_flow2,min_qcost_flow,% - min_weight_tree,min,mlist,mode,modulo,moment,mopen,move,% - mps2linpro,mputl,mputstr,mput,mrfit,msd,mseek,mtell,mtlb_load,% - mtlb_mode,mtlb_save,mtlb_sparse,mu2lin,mulf,mvvacov,m_circle,% - names,nand2mean,nanmax,nanmeanf,nanmean,nanmedian,nanmin,% - nanstdev,nansum,narsimul,ndims,nearfloat,nehari,neighbors,% - netclose,netwindows,netwindow,newest,newfun,nextpow2,nf3d,nfreq,% - nlev,nnz,nodes_2_path,nodes_degrees,node_number,noisegen,norm,% - null,numdiff,numer,nyquist,obscont1,obscont,observer,obsvss,% - obsv_mat,obs_gram,odedc,odedi,odeoptions,ode_discrete,ode_root,% - ode,oldload,oldsave,ones,optim,orth,param3d1,param3d,% - paramfplot2d,parrot,part,pathconvert,path_2_nodes,pause,pbig,% - pdiv,pen2ea,pencan,penlaur,perctl,perfect_match,pertrans,pfss,% - phasemag,phc,pinv,pipe_network,playsnd,plot2d1,plot2d2,plot2d3,% - plot2d4,plot2d,plot3d1,plot3d2,plot3d3,plot3d,plotframe,% - plotprofile,plot_graph,plot,plzr,pmodulo,pol2des,pol2str,pol2tex,% - polarplot,polar,polfact,poly,portr3d,portrait,power,ppol,prbs_a,% - predecessors,predef,printf,printing,print,prod,profile,projsl,% - projspec,proj,psmall,pspect,pvm_addhosts,pvm_barrier,pvm_bcast,% - pvm_bufinfo,pvm_config,pvm_delhosts,pvm_error,pvm_exit,% - pvm_f772sci,pvm_getinst,pvm_gettid,pvm_get_timer,pvm_gsize,% - pvm_halt,pvm_joingroup,pvm_kill,pvm_lvgroup,pvm_mytid,pvm_parent,% - pvm_probe,pvm_recv,pvm_reduce,pvm_sci2f77,pvm_send,pvm_set_timer,% - pvm_spawn_independent,pvm_spawn,pvm_start,pvm_tasks,% - pvm_tidtohost,pvm,pwd,p_margin,qassign,qr,quapro,quart,quaskro,% - quit,randpencil,rand,range,rankqr,rank,rat,rcond,rdivf,read4b,% - readb,readc_,readmps,read,real,recur,reglin,regress,remezb,remez,% - repfreq,replot,residu,resume,return,riccati,riccsl,ricc,ric_desc,% - rlist,roots,rotate,round,routh_t,rowcompr,rowcomp,rowinout,% - rowregul,rowshuff,rpem,rref,rtitr,rubberbox,salesman,savewave,% - save_graph,save,scaling,scanf,schur,sci2exp,sci2for,sci2map,% - sciargs,scicosim,scicos,scifunc_block,sd2sci,secto3d,select,% - semidef,sensi,setbpt,seteventhandler,setfield,setmenu,% - setscicosvars,set,sfact,sgrid,shortest_path,showprofile,% - show_arcs,show_graph,show_nodes,sident,signm,sign,simp_mode,simp,% - sincd,sinc,sinc,sinhm,sinh,sinm,sin,size,sm2des,sm2ss,smooth,% - solve,sorder,sort,sound,sp2adj,spaninter,spanplus,spantwo,sparse,% - spchol,spcompack,specfact,spec,speye,spget,splin,split_edge,% - spones,sprand,sprintf,spzeros,sqroot,sqrtm,sqrt,squarewave,% - square,srfaur,srkf,ss2des,ss2ss,ss2tf,sscanf,sskf,ssprint,ssrand,% - stabil,stacksize,standard_define,standard_draw,standard_input,% - standard_origin,standard_output,startup,stdevf,stdev,steadycos,% - str2code,strange,strcat,strindex,strings,string,stripblanks,% - strong_connex,strong_con_nodes,strsubst,st_deviation,st_ility,% - subf,subgraph,subplot,successors,sum,supernode,sva,svd,svplot,% - sylm,sylv,sysconv,sysdiag,sysfact,syslin,syssize,systems,system,% - systmat,tabul,tangent,tanhm,tanh,tanm,tan,tdinit,testmatrix,% - texprint,tf2des,tf2ss,then,thrownan,timer,time_id,titlepage,% - tk_getdir,tk_getfile,tlist,toeplitz,tokenpos,tokens,trace,% - translatepaths,trans_closure,trans,trfmod,trianfml,tril,trimmean,% - trisolve,triu,trzeros,typename,typeof,type,uicontrol,uimenu,% - uint16,uint32,uint8,ui_observer,ulink,unglue,union,unique,unix_g,% - unix_s,unix_w,unix_x,unix,unobs,unsetmenu,user,varargin,% - varargout,variancef,variance,varn,warning,wavread,wavwrite,% - wcenter,wfir,what,whereami,whereis,where,while,whos,who_user,who,% - wiener,wigner,window,winsid,with_gtk,with_pvm,with_texmacs,% - with_tk,writb,write4b,write,xarcs,xarc,xarrows,xaxis,xbasc,% - xbasimp,xbasr,xchange,xclear,xclea,xclick,xclip,xdel,xend,xfarcs,% - xfarc,xfpolys,xfpoly,xfrect,xgetech,xgetfile,xgetmouse,xget,% - xgraduate,xgrid,xinfo,xinit,xlfont,xload,xname,xnumb,xpause,% - xpolys,xpoly,xrects,xrect,xrpoly,xs2fig,xs2gif,xs2ppm,xs2ps,% - xsave,xsegs,select,xsetech,xsetm,xset,xstringb,xstringl,xstring,% - xtape,xtitle,x_choices,x_choose,x_dialog,x_matrix,x_mdialog,% - x_message_modeless,x_message,yulewalk,zeropen,zeros,zgrid,zpbutt,% - zpch1,zpch2,zpell,mfprintf,mfscanf,mprintf,mscanf,msprintf,% - msscanf,mucomp,% - ABSBLK_f,AFFICH_f,ANDLOG_f,ANIMXY_f,BIGSOM_f,CLINDUMMY_f,CLKIN_f,% - CLKINV_f,CLKOUT_f,CLKOUTV_f,CLKSOM_f,CLKSOMV_f,CLKSPLIT_f,% - CLOCK_f,CLR_f,CLSS_f,CONST_f,COSBLK_f,CURV_f,DELAY_f,DELAYV_f,% - DEMUX_f,DLR_f,DLRADAPT_f,DLSS_f,EVENTSCOPE_f,EVTDLY_f,EVTGEN_f,% - EXPBLK_f,G_make,GAIN_f,GAINBLK_f,GENERAL_f,GENERIC_f,GENSIN_f,% - GENSQR_f,HALT_f,IFTHEL_f,IN_f,INTEGRAL_f,INTRP2BLK_f,INTRPLBLK_f,% - INVBLK_f,LOGBLK_f,LOOKUP_f,Matplot1,Matplot,MAX_f,MCLOCK_f,% - MFCLCK_f,MIN_f,MUX_f,NDcost,NEGTOPOS_f,OUT_f,POSTONEG_f,POWBLK_f,% - PROD_f,QUANT_f,RAND_f,READC_f,REGISTER_f,RELAY_f,RFILE_f,% - ScilabEval,Sfgrayplot,Sgrayplot,SAMPLEHOLD_f,SAT_f,SAWTOOTH_f,% - SCOPE_f,SCOPXY_f,SELECT_f,SINBLK_f,SOM_f,SPLIT_f,STOP_f,SUPER_f,% - TANBLK_f,TCLSS_f,TEXT_f,TIME_f,TK_EvalFile,TK_EvalStr,TK_GetVar,% - TK_SetVar,TRASH_f,WFILE_f,WRITEC_f,ZCROSS_f,% - \%asn,\%helps,\%k,\%sn},% - alsoletter=\%,% chmod - sensitive,% - morecomment=[l]//,% - morestring=[b]",% - morestring=[m]'% - }[keywords,comments,strings]% -%% -%% SQL definition (c) 1998 Christian Haul -%% (c) 2002 Neil Conway -%% (c) 2002 Robert Frank -%% (c) 2003 Dirk Jesko -%% -\lst@definelanguage{SQL}% - {morekeywords={ABSOLUTE,ACTION,ADD,ALLOCATE,ALTER,ARE,AS,ASSERTION,% - AT,BETWEEN,BIT_LENGTH,BOTH,BY,CASCADE,CASCADED,CASE,CAST,% - CATALOG,CHAR_LENGTH,CHARACTER_LENGTH,CLUSTER,COALESCE,% - COLLATE,COLLATION,COLUMN,CONNECT,CONNECTION,CONSTRAINT,% - CONSTRAINTS,CONVERT,CORRESPONDING,CREATE,CROSS,CURRENT_DATE,% - CURRENT_TIME,CURRENT_TIMESTAMP,CURRENT_USER,DAY,DEALLOCATE,% - DEC,DEFERRABLE,DEFERED,DESCRIBE,DESCRIPTOR,DIAGNOSTICS,% - DISCONNECT,DOMAIN,DROP,ELSE,END,EXEC,EXCEPT,EXCEPTION,EXECUTE,% - EXTERNAL,EXTRACT,FALSE,FIRST,FOREIGN,FROM,FULL,GET,GLOBAL,% - GRAPHIC,HAVING,HOUR,IDENTITY,IMMEDIATE,INDEX,INITIALLY,INNER,% - INPUT,INSENSITIVE,INSERT,INTO,INTERSECT,INTERVAL,% - ISOLATION,JOIN,KEY,LAST,LEADING,LEFT,LEVEL,LIMIT,LOCAL,LOWER,% - MATCH,MINUTE,MONTH,NAMES,NATIONAL,NATURAL,NCHAR,NEXT,NO,NOT,NULL,% - NULLIF,OCTET_LENGTH,ON,ONLY,ORDER,ORDERED,OUTER,OUTPUT,OVERLAPS,% - PAD,PARTIAL,POSITION,PREPARE,PRESERVE,PRIMARY,PRIOR,READ,% - RELATIVE,RESTRICT,REVOKE,RIGHT,ROWS,SCROLL,SECOND,SELECT,SESSION,% - SESSION_USER,SIZE,SPACE,SQLSTATE,SUBSTRING,SYSTEM_USER,% - TABLE,TEMPORARY,THEN,TIMEZONE_HOUR,% - TIMEZONE_MINUTE,TRAILING,TRANSACTION,TRANSLATE,TRANSLATION,TRIM,% - TRUE,UNIQUE,UNKNOWN,UPPER,USAGE,USING,VALUE,VALUES,% - VARGRAPHIC,VARYING,WHEN,WHERE,WRITE,YEAR,ZONE,% - AND,ASC,avg,CHECK,COMMIT,count,DECODE,DESC,DISTINCT,GROUP,IN,% FF - LIKE,NUMBER,ROLLBACK,SUBSTR,sum,VARCHAR2,% FF - MIN,MAX,UNION,UPDATE,% RF - ALL,ANY,CUBE,CUBE,DEFAULT,DELETE,EXISTS,GRANT,OR,RECURSIVE,% DJ - ROLE,ROLLUP,SET,SOME,TRIGGER,VIEW},% DJ - morendkeywords={BIT,BLOB,CHAR,CHARACTER,CLOB,DATE,DECIMAL,FLOAT,% DJ - INT,INTEGER,NUMERIC,SMALLINT,TIME,TIMESTAMP,VARCHAR},% moved here - sensitive=false,% DJ - morecomment=[l]--,% - morecomment=[s]{/*}{*/},% - morestring=[d]',% - morestring=[d]"% - }[keywords,comments,strings]% -%% -%% VHDL definition (c) 1997 Kai Wollenweber -%% -\lst@definelanguage{VHDL}% - {morekeywords={ALL,ARCHITECTURE,ABS,AND,ASSERT,ARRAY,AFTER,ALIAS,% - ACCESS,ATTRIBUTE,BEGIN,BODY,BUS,BLOCK,BUFFER,CONSTANT,CASE,% - COMPONENT,CONFIGURATION,DOWNTO,ELSE,ELSIF,END,ENTITY,EXIT,% - FUNCTION,FOR,FILE,GENERIC,GENERATE,GUARDED,GROUP,IF,IN,INOUT,IS,% - INERTIAL,IMPURE,LIBRARY,LOOP,LABEL,LITERAL,LINKAGE,MAP,MOD,NOT,% - NOR,NAND,NULL,NEXT,NEW,OUT,OF,OR,OTHERS,ON,OPEN,PROCESS,PORT,% - PACKAGE,PURE,PROCEDURE,POSTPONED,RANGE,REM,ROL,ROR,REPORT,RECORD,% - RETURN,REGISTER,REJECT,SIGNAL,SUBTYPE,SLL,SRL,SLA,SRA,SEVERITY,% - SELECT,THEN,TYPE,TRANSPORT,TO,USE,UNITS,UNTIL,VARIABLE,WHEN,WAIT,% - WHILE,XOR,XNOR,% - DISCONNECT,ELIF,WITH},% Arnaud Tisserand - sensitive=f,% 1998 Gaurav Aggarwal - morecomment=[l]--,% - morestring=[d]{"}% - }[keywords,comments,strings]% -%% -%% VHDL-AMS definition (c) Steffen Klupsch -%% -\lst@definelanguage[AMS]{VHDL}[]{VHDL}% - {morekeywords={ACROSS,ARRAY,BREAK,DISCONNECT,NATURE,NOISE,PORT,% - PROCEDURAL,QUANTITY,SHARED,SPECTRUM,SUBNATURE,TERMINAL,THROUGH,% - TOLERANCE,UNAFFACTED,UNITS}} -\lst@definelanguage{XSLT}[]{XML}% - {morekeywords={% - % main elements - xsl:stylesheet,xsl:transform,% - % childs of the main element - xsl:apply-imports,xsl:attribute-set,xsl:decimal-format,xsl:import,% - xsl:include,xsl:key,xsl:namespace-alias,xsl:output,xsl:param,% - xsl:preserve-space,xsl:strip-space,xsl:template,xsl:variable,% - % 21 directives - xsl:apply-imports,xsl:apply-templates,xsl:attribute,% - xsl:call-template,xsl:choose,xsl:comment,xsl:copy,xsl:copy-of,% - xsl:element,xsl:fallback,xsl:for-each,xsl:if,xsl:message,% - xsl:number,xsl:otherwise,xsl:processing-instruction,xsl:text,% - xsl:value-of,xsl:variable,xsl:when,xsl:with-param},% - alsodigit={-},% - }% -\lst@definelanguage{Ant}[]{XML}% - {morekeywords={% - project,target,patternset,include,exclude,excludesfile,includesfile,filterset,% - filter,filtersfile,libfileset,custom,classpath,fileset,none,depend,mapper,% - filename,not,date,contains,selector,depth,or,and,present,majority,size,dirset,% - filelist,pathelement,path,param,filterreader,extension,filterchain,linecontainsregexp,% - regexp,classconstants,headfilter,tabstospaces,striplinebreaks,tailfilter,stripjavacomments,% - expandproperties,linecontains,replacetokens,token,striplinecomments,comment,prefixlines,% - classfileset,rootfileset,root,description,xmlcatalog,entity,dtd,substitution,% - extensionSet,propertyfile,entry,vsscheckin,sql,transaction,cvspass,csc,% - dirname,wlrun,wlclasspath,p4label,replaceregexp,get,jjtree,sleep,jarlib,% - dependset,targetfileset,srcfileset,srcfilelist,targetfilelist,zip,zipgroupfileset,zipfileset,% - patch,jspc,webapp,style,test,arg,jvmarg,sysproperty,testlet,env,tstamp,% - format,unwar,vsshistory,icontract,cvschangelog,user,p4submit,ccmcheckin,% - p4change,bzip2,vssadd,javadoc,bottom,source,doctitle,header,excludepackage,bootclasspath,% - doclet,taglet,packageset,sourcepath,link,footer,package,group,title,tag,% - translate,signjar,vajload,vajproject,jarlib,extensionset,WsdlToDotnet,buildnumber,% - jpcovmerge,tomcat,ejbjar,weblogictoplink,jboss,borland,weblogic,iplanet,jonas,% - support,websphere,wasclasspath,war,manifest,attribute,section,metainf,lib,% - classes,webinf,rename,sequential,serverdeploy,generic,property,move,% - copydir,cccheckin,wljspc,fixcrlf,sosget,pathconvert,map,record,p4sync,exec,% - p4edit,maudit,rulespath,searchpath,antlr,netrexxc,jpcovreport,reference,filters,% - coveragepath,execon,targetfile,srcfile,ccmcheckout,ant,xmlvalidate,xslt,% - iplanet,ccmcheckintask,gzip,native2ascii,starteam,ear,archives,input,% - rmic,extdirs,compilerarg,checksum,mail,bcc,message,cc,to,from,loadfile,vsscheckout,% - stylebook,soscheckin,mimemail,stlabel,gunzip,concat,cab,touch,parallel,splash,% - antcall,cccheckout,typedef,p4have,xmlproperty,copy,tomcat,antstructure,ccmcreatetask,% - rpm,delete,replace,replacefilter,replacetoken,replacevalue,mmetrics,waitfor,isfalse,% - equals,available,filepath,os,filesmatch,istrue,isset,socket,http,uptodate,srcfiles,% - untar,loadproperties,echoproperties,vajexport,stcheckout,bunzip2,copyfile,vsscreate,% - ejbc,unjar,tomcat,wsdltodotnet,mkdir,condition,cvs,commandline,marker,argument,% - tempfile,junitreport,report,taskdef,echo,ccupdate,java,renameext,vsslabel,basename,% - javadoc2,vsscp,tar,tarfileset,tomcat,vajimport,setproxy,wlstop,p4counter,ilasm,% - soscheckout,apply,ccuncheckout,jarlib,location,url,cvstagdiff,jlink,mergefiles,% - addfiles,javacc,pvcs,pvcsproject,jarlib,options,depends,chmod,jar,sound,fail,% - success,mparse,blgenclient,genkey,dname,javah,class,ccmreconfigure,unzip,javac,% - src,p4add,soslabel,jpcoverage,triggers,method,vssget,deltree,ddcreator}, - deletekeywords={default},% - } -\lst@definelanguage{XML}% - {keywords={,CDATA,DOCTYPE,ATTLIST,termdef,ELEMENT,EMPTY,ANY,ID,% - IDREF,IDREFS,ENTITY,ENTITIES,NMTOKEN,NMTOKENS,NOTATION,% - INCLUDE,IGNORE,SYSTEM,PUBLIC,NDATA,PUBLIC,% - PCDATA,REQUIRED,IMPLIED,FIXED,%%% preceded by # - xml,xml:space,xml:lang,version,standalone,default,preserve},% - alsoother=$,% - alsoletter=:,% - tag=**[s]<>,% - morestring=[d]",% ??? doubled - morestring=[d]',% ??? doubled - MoreSelectCharTable=% - \lst@CArgX--\relax\lst@DefDelimB{}{}% - {\ifnum\lst@mode=\lst@tagmode\else - \expandafter\@gobblethree - \fi}% - \lst@BeginComment\lst@commentmode{{\lst@commentstyle}}% - \lst@CArgX--\relax\lst@DefDelimE{}{}{}% - \lst@EndComment\lst@commentmode - \lst@CArgX[CDATA[\relax\lst@CDef{}% - {\ifnum\lst@mode=\lst@tagmode - \expandafter\lst@BeginCDATA - \else \expandafter\lst@CArgEmpty - \fi}% - \@empty - \lst@CArgX]]\relax\lst@CDef{}% - {\ifnum\lst@mode=\lst@GPmode - \expandafter\lst@EndComment - \else \expandafter\lst@CArgEmpty - \fi}% - \@empty - }[keywords,comments,strings,html]% -\endinput -%% -%% End of file `lstlang1.sty'. diff --git a/org.glite.lb.doc/src/lstlang2.sty b/org.glite.lb.doc/src/lstlang2.sty deleted file mode 100644 index c1c9121..0000000 --- a/org.glite.lb.doc/src/lstlang2.sty +++ /dev/null @@ -1,1532 +0,0 @@ -%% -%% This is file `lstlang2.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% lstdrvrs-1.3.dtx (with options: `lang2') -%% -%% (w)(c) 1996/1997/1998/1999/2000/2001/2002/2003/2004 Carsten Heinz -%% and/or any other author listed elsewhere in this file. -%% -%% This file is distributed under the terms of the LaTeX Project Public -%% License from CTAN archives in directory macros/latex/base/lppl.txt. -%% Either version 1.0 or, at your option, any later version. -%% -%% This file is completely free and comes without any warranty. -%% -%% Send comments and ideas on the package, error reports and additional -%% programming languages to . -%% -\ProvidesFile{lstlang2.sty} - [2004/09/05 1.3 listings language file] -%% -%% Abap definition by Knut Lickert -%% -\lst@definelanguage[R/3 6.10]{ABAP}[R/3 4.6C]{ABAP}% - {morekeywords={try,endtry},% - }[keywords,comments,strings] -\lst@definelanguage[R/3 4.6C]{ABAP}[R/3 3.1]{ABAP}% - {morekeywords={method,ref,class,create,object,% - methods,endmethod,private,protected,public,section,% - catch,system-exceptions,endcatch,% - },% - moreprocnamekeys={class},% - literate={->}{{$\rightarrow$}}1{=>}{{$\Rightarrow$}}1,% - }[keywords,comments,strings,procnames] -\lst@definelanguage[R/3 3.1]{ABAP}[R/2 5.0]{ABAP}{}% -\lst@definelanguage[R/2 5.0]{ABAP}% - {sensitive=f,% - procnamekeys={report,program,form,function,module},% - morekeywords={*,add,after,alias,analyzer,and,append,appending,area,assign,at,% - authority-check,before,binary,blank,break-point,calendar,call,% - case,change,changing,check,clear,cnt,co,collect,commit,common,% - component,compute,condense,corresponding,cos,cp,cs,currency-conversion,% - cursor,data,database,dataset,decimals,define,delete,deleting,dequeue,% - describe,detail,dialog,directory,div,divide,do,documentation,% - during,dynpro,else,end-of-page,end-of-selection,endat,endcase,% - enddo,endfor,endform,endif,endloop,endmodule,endselect,% - endwhile,enqueue,exceptions,exit,exp,export,exporting,extract,% - field,fields,field-groups,field-symbols,find,for,form,format,free,% - from,function,generating,get,giving,hide,id,if,import,% - importing,in,incl,include,initial,initialization,input,insert,% - interrupt,into,is,language,leave,leading,left-justified,like,line,lines,line-count, - line-selection,list-processing,load,local,log,logfile,loop,% - margin,mark,mask,memory,menue,message,mod,modify,module,move,% - move-text,multiply,na,new,new-line,new-page,no-gaps,np,ns,% - number,obligatory,occurs,of,on,or,others,output,parameter,% - parameters,parts,perform,pf-status,places,position,process,% - raise,raising,ranges,read,refresh,refresh-dynpro,reject,remote,% - replace,report,reserve,reset,restart,right-justified,run,screen,scroll,search,% - segments,select,select-options,selection-screen,set,shift,sin,% - single,sqrt,start-of-selection,statement,structure,submit,% - subtract,summary,summing,suppress,system,table,tables,task,% - text,time,to,top-of-page,trace,transaction,transfer,% - transfer-dynpro,translate,type,unpack,update,user-command,% - using,value,when,where,while,window,with,workfile,write,},% - morecomment=[l]",% - morecomment=[f][0]*,% - morestring=[d]'% - }[keywords,comments,strings,procnames] -\lst@definelanguage[R/2 4.3]{ABAP}[R/2 5.0]{ABAP}% - {deletekeywords={function,importing,exporting,changing,exceptions,% - raise,raising}% - }[keywords,comments,strings] -%% -%% Corba IDL definition (c) 1999 Jens T. Berger Thielemann -%% -\lst@definelanguage[CORBA]{IDL}% - {morekeywords={any,attribute,boolean,case,char,const,context,default,% - double,enum,exception,fixed,float,in,inout,interface,long,module,% - native,Object,octet,oneway,out,raises,readonly,sequence,short,% - string,struct,switch,typedef,union,unsigned,void,wchar,wstring,% - FALSE,TRUE},% - sensitive,% - moredirectives={define,elif,else,endif,error,if,ifdef,ifndef,line,% - include,pragma,undef,warning},% - moredelim=*[directive]\#,% - morecomment=[l]//,% - morecomment=[s]{/*}{*/},% - morestring=[b]"% - }[keywords,comments,strings,directives]% -%% -%% (Objective) Caml definition (c) 1999 Patrick Cousot -%% -%% Objective CAML and Caml light are freely available, together with a -%% reference manual, at URL ftp.inria.fr/lang/caml-light for the Unix, -%% Windows and Macintosh OS operating systems. -%% -\lst@definelanguage[Objective]{Caml}[light]{Caml} - {deletekeywords={not,prefix,value,where},% - morekeywords={assert,asr,class,closed,constraint,external,false,% - functor,include,inherit,land,lazy,lor,lsl,lsr,lxor,method,mod,% - module,new,open,parser,private,sig,struct,true,val,virtual,when,% - object,ref},% TH - }% -\lst@definelanguage[light]{Caml} - {morekeywords={and,as,begin,do,done,downto,else,end,exception,for,% - fun,function,if,in,let,match,mutable,not,of,or,prefix,rec,then,% - to,try,type,value,where,while,with},% - sensitive,% - morecomment=[n]{(*}{*)},% - morestring=[b]",% - moredelim=*[directive]\#,% - moredirectives={open,close,include}% - }[keywords,comments,strings,directives]% -\lst@definelanguage[ibm]{Cobol}[1985]{Cobol}% - {morekeywords={ADDRESS,BEGINNING,COMP-3,COMP-4,COMPUTATIONAL,% - COMPUTATIONAL-3,COMPUTATIONAL-4,DISPLAY-1,EGCS,EJECT,ENDING,% - ENTRY,GOBACK,ID,MORE-LABELS,NULL,NULLS,PASSWORD,RECORDING,% - RETURN-CODE,SERVICE,SKIP1,SKIP2,SKIP3,SORT-CONTROL,SORT-RETURN,% - SUPPRESS,TITLE,WHEN-COMPILED},% - }% -\lst@definelanguage[1985]{Cobol}[1974]{Cobol}% - {morekeywords={ALPHABET,ALPHABETIC-LOWER,ALPHABETIC-UPPER,% - ALPHANUMERIC,ALPHANUMERIC-EDITED,ANY,CLASS,COMMON,CONTENT,% - CONTINUE,DAY-OF-WEEK,END-ADD,END-CALL,END-COMPUTE,END-DELETE,% - END-DIVIDE,END-EVALUATE,END-IF,END-MULTIPLY,END-PERFORM,END-READ,% - END-RECEIVE,END-RETURN,END-REWRITE,END-SEARCH,END-START,% - END-STRING,END-SUBTRACT,END-UNSTRING,END-WRITE,EVALUATE,EXTERNAL,% - FALSE,GLOBAL,INITIALIZE,NUMERIC-EDITED,ORDER,OTHER,% - PACKED-DECIMAL,PADDING,PURGE,REFERENCE,RELOAD,REPLACE,STANDARD-1,% - STANDARD-2,TEST,THEN,TRUE},% - }% -\lst@definelanguage[1974]{Cobol}% - {morekeywords={ACCEPT,ACCESS,ADD,ADVANCING,AFTER,ALL,ALPHABETIC,ALSO,% - ALTER,ALTERNATE,AND,ARE,AREA,AREAS,ASCENDING,ASSIGN,AT,AUTHOR,% - BEFORE,BINARY,BLANK,BLOCK,BOTTOM,BY,CALL,CANCEL,CD,CF,CH,% - CHARACTER,CHARACTERS,CLOCK-UNITS,CLOSE,COBOL,CODE,CODE-SET,% - COLLATING,COLUMN,COMMA,COMMUNICATION,COMP,COMPUTE,CONFIGURATION,% - CONTAINS,CONTROL,CONTROLS,CONVERTING,COPY,CORR,CORRESPONDING,% - COUNT,CURRENCY,DATA,DATE,DATE-COMPILED,DATE-WRITTEN,DAY,DE,% - DEBUG-CONTENTS,DEGUB-ITEM,DEBUG-LINE,DEBUG-NAME,DEBUG-SUB1,% - DEBUG-SUB2,DEBUG-SUB3,DEBUGGING,DECIMAL-POINT,DECLARATIVES,% - DELETE,DELIMITED,DELIMITER,DEPENDING,DESCENDING,DESTINATION,% - DETAIL,DISABLE,DISPLAY,DIVIDE,DIVISION,DOWN,DUPLICATES,DYNAMIC,% - EGI,ELSE,EMI,ENABLE,END,END-OF-PAGE,ENTER,ENVIRONMENT,EOP,EQUAL,% - ERROR,ESI,EVERY,EXCEPTION,EXIT,EXTEND,FD,FILE,FILE-CONTROL,% - FILLER,FINAL,FIRST,FOOTING,FOR,FROM,GENERATE,GIVING,GO,GREATER,% - GROUP,HEADING,HIGH-VALUE,HIGH-VALUES,I-O,I-O-CONTROL,% - IDENTIFICATION,IF,IN,INDEX,INDEXED,INDICATE,INITIAL,INITIATE,% - INPUT,INPUT-OUTPUT,INSPECT,INSTALLATION,INTO,INVALID,IS,JUST,% - JUSTIFIED,KEY,LABEL,LAST,LEADING,LEFT,LENGTH,LESS,LIMIT,LIMITS,% - LINAGE,LINAGE-COUNTER,LINE,LINE-COUNTER,LINES,LINKAGE,LOCK,% - LOW-VALUE,LOW-VALUES,MEMORY,MERGE,MESSAGE,MODE,MODULES,MOVE,% - MULTIPLE,MULTIPLY,NATIVE,NEGATIVE,NEXT,NO,NOT,NUMBER,NUMERIC,% - OBJECT-COMPUTER,OCCURS,OF,OFF,OMITTED,ON,OPEN,OPTIONAL,OR,% - ORGANIZATION,OUTPUT,OVERFLOW,PAGE,PAGE-COUNTER,PERFORM,PF,PH,PIC,% - PICTURE,PLUS,POINTER,POSITION,PRINTING,POSITIVE,PRINTING,% - PROCEDURE,PROCEDURES,PROCEED,PROGRAM,PROGRAM-ID,QUEUE,QUOTE,% - QUOTES,RANDOM,RD,READ,RECEIVE,RECORD,RECORDING,RECORDS,REDEFINES,% - REEL,REFERENCES,RELATIVE,RELEASE,REMAINDER,REMOVAL,RENAMES,% - REPLACING,REPORT,REPORTING,REPORTS,RERUN,RESERVE,RESET,RETURN,% - REVERSED,REWIND,REWRITE,RF,RH,RIGHT,ROUNDED,RUN,SAME,SD,SEARCH,% - SECTION,SECURITY,SEGMENT,SEGMENT-LIMIT,SELECT,SEND,SENTENCE,% - SEPARATE,SEQUENCE,SEQUENTIAL,SET,SIGN,SIZE,SORT,SORT-MERGE,% - SOURCE,SOURCE-COMPUTER,SPACE,SPACES,SPECIAL-NAMES,STANDARD,START,% - STATUS,STOP,STRING,SUB-QUEUE-1,SUB-QUEUE-2,SUB-QUEUE-3,SUBTRACT,% - SUM,SYMBOLIC,SYNC,SYNCHRONIZED,TABLE,TALLYING,TAPE,TERMINAL,% - TERMINATE,TEXT,THAN,THROUGH,THRU,TIME,TIMES,TO,TOP,TRAILING,TYPE,% - UNIT,UNSTRING,UNTIL,UP,UPON,USAGE,USE,USING,VALUE,VALUES,VARYING,% - WHEN,WITH,WORDS,WORKING-STORAGE,WRITE,ZERO,ZEROES,ZEROS},% - alsodigit=-,% - sensitive=f,% ??? - morecomment=[f][commentstyle][6]*,% - morestring=[d]"% ??? doubled - }[keywords,comments,strings]% -\lst@definelanguage{Delphi}% - {morekeywords={and,as,asm,array,begin,case,class,const,constructor,% - destructor,div,do,downto,else,end,except,exports,file,finally,% - for,function,goto,if,implementation,in,inherited,inline,% - initialization,interface,is,label,library,mod,nil,not,object,of,% - or,packed,procedure,program,property,raise,record,repeat,set,% - shl,shr,string,then,to,try,type,unit,until,uses,var,while,with,% - xor,% - absolute,abstract,assembler,at,cdecl,default,dynamic,export,% - external,far,forward,index,name,near,nodefault,on,override,% - private,protected,public,published,read,resident,storedDir,% - virtual,write},% - morendkeywords={Abs,AddExitProc,Addr,AllocMem,AnsiCompareStr,% - AnsiCompareText,AnsiLowerCase,AnsiUpperCase,Append,AppendStr,% - ArcTan,AssignCrt,Assigned,AssignFile,BlockRead,BlockWrite,Break,% - ChangeFileExt,ChDir,Chr,CloseFile,ClrEol,ClrScr,Concat,Continue,% - Copy,Cos,CSeg,CursorTo,Date,DateTimeToFileDate,DateTimeToStr,% - DateTimeToString,DateToStr,DayOfWeek,Dec,DecodeDate,DecodeTime,% - Delete,DeleteFile,DiskFree,DiskSize,Dispose,DisposeStr,% - DoneWinCrt,DSeg,EncodeDate,EncodeTime,Eof,Eoln,Erase,Exclude,% - Exit,Exp,ExpandFileName,ExtractFileExt,ExtractFileName,% - ExtractFilePath,FileAge,FileClose,FileDateToDateTime,FileExists,% - FileGetAttr,FileGetDate,FileOpen,FilePos,FileRead,FileSearch,% - FileSeek,FileSetAttr,FileSetDate,FileSize,FillChar,FindClose,% - FindFirst,FindNext,FloatToDecimal,FloatToStrF,FloatToStr,% - FloatToText,FloatToTextFmt,Flush,FmtLoadStr,FmtStr,Format,% - FormatBuf,FormatDateTime,FormatFloat,Frac,Free,FreeMem,GetDir,% - GetMem,GotoXY,Halt,Hi,High,Inc,Include,InitWinCrt,Insert,Int,% - IntToHex,IntToStr,IOResult,IsValidIdent,KeyPressed,Length,Ln,Lo,% - LoadStr,Low,LowerCase,MaxAvail,MemAvail,MkDir,Move,New,NewStr,% - Now,Odd,Ofs,Ord,ParamCount,ParamStr,Pi,Pos,Pred,Ptr,Random,% - Randomize,Read,ReadBuf,ReadKey,Readln,ReAllocMem,Rename,% - RenameFile,Reset,Rewrite,RmDir,Round,RunError,ScrollTo,Seek,% - SeekEof,SeekEoln,Seg,SetTextBuf,Sin,SizeOf,SPtr,Sqr,Sqrt,SSeg,% - Str,StrCat,StrComp,StrCopy,StrDispose,StrECopy,StrEnd,StrFmt,% - StrLCat,StrIComp,StrLComp,StrLCopy,StrLen,StrLFmt,StrLIComp,% - StrLower,StrMove,StrNew,StrPas,StrPCopy,StrPos,StrScan,StrRScan,% - StrToDate,StrToDateTime,StrToFloat,StrToInt,StrToIntDef,% - StrToTime,StrUpper,Succ,Swap,TextToFloat,Time,TimeToStr,% - TrackCursor,Trunc,Truncate,TypeOf,UpCase,UpperCase,Val,WhereX,% - WhereY,Write,WriteBuf,WriteChar,Writeln},% - sensitive=f,% - morecomment=[s]{(*}{*)},% - morecomment=[s]{\{}{\}},% - morecomment=[l]{//},% 2001 Christian Gudrian - morestring=[d]'% - }[keywords,comments,strings]% -\lst@definelanguage{Eiffel}% - {morekeywords={alias,all,and,as,BIT,BOOLEAN,CHARACTER,check,class,% - creation,Current,debug,deferred,do,DOUBLE,else,elseif,end,% - ensure,expanded,export,external,false,feature,from,frozen,if,% - implies,indexing,infix,inherit,inspect,INTEGER,invariant,is,% - like,local,loop,NONE,not,obsolete,old,once,or,POINTER,prefix,% - REAL,redefine,rename,require,rescue,Result,retry,select,% - separate,STRING,strip,then,true,undefine,unique,until,variant,% - when,xor},% - sensitive,% - morecomment=[l]--,% - morestring=[d]",% - }[keywords,comments,strings]% -%% -%% Euphoria definition (c) 1998 Detlef Reimers -%% -\lst@definelanguage{Euphoria}% - {morekeywords={abort,and,and_bits,append,arctan,atom,by,call,% - call_proc,call_func,c_proc,c_func,clear_screen,close,% - command_line,compare,constant,cos,do,date,else,elsif,end,exit,% - find,floor,for,function,getc,getenv,get_key,gets,global,% - get_pixel,if,include,integer,length,log,match,machine_func,% - machine_proc,mem_copy,mem_set,not,not_bits,or,object,open,% - or_bits,procedure,puts,position,prepend,print,printf,power,peek,% - poke,pixel,poke4,peek4s,peek4u,return,rand,repeat,remainder,% - routine_id,sequence,sqrt,sin,system,sprintf,then,type,to,time,% - trace,tan,while,with,without,xor,xor_bits},% - sensitive,% - morecomment=[l]--,% - morestring=[d]',% - morestring=[d]"% - }[keywords,comments,strings]% -%% -%% Guarded Command Language (GCL) definition -%% (c) 2002 Mark van Eijk -%% -\lst@definelanguage{GCL}% - {morekeywords={const,con,var,array,of,skip,if,fi,do,od,div,mod},% - literate={|[}{\ensuremath{|\hskip -0.1em[}}2% - {]|}{\ensuremath{]\hskip -0.1em|}}2% - {[]}{\ensuremath{[\hskip -0.1em]}}2% - {->}{\ensuremath{\rightarrow}~}2% - {==}{\ensuremath{\equiv}~}2% - {>=}{\ensuremath{\geq}~}2% - {<=}{\ensuremath{\leq}~}2% - {/\\}{\ensuremath{\land}~}2% - {\\/}{\ensuremath{\lor}~}2% - {!}{\ensuremath{\lnot}}1% - {!=}{\ensuremath{\neq}~}2% - {max}{\ensuremath{\uparrow}}1% - {min}{\ensuremath{\downarrow}}1,% - sensitive=f,% - morecomment=[s]{\{}{\}},% - morestring=[d]'% - }[keywords,comments,strings]% -%% -%% gnuplot definition (c) Christoph Giess -%% -\lst@definelanguage{Gnuplot}% - {keywords={abs,acos,acosh,arg,asin,asinh,atan,atan2,atanh,besj0,% - besj1,besy0,besy1,ceil,cos,cosh,erf,erfc,exp,floor,gamma,ibeta,% - inverf,igamma,imag,invnorm,int,lgamma,log,log10,norm,rand,real,% - sgn,sin,sinh,sqrt,tan,tanh,column,tm_hour,tm_mday,tm_min,tm_mon,% - tm_sec,tm_wday,tm_yday,tm_year,valid,cd,call,clear,exit,fit,% - help,if,load,pause,plot,print,pwd,quit,replot,reread,reset,save,% - set,show,shell,splot,test,update,angles,arrow,autoscale,border,% - boxwidth,clabel,clip,cntrparam,contour,data,dgrid3d,dummy,% - format,function,functions,grid,hidden3d,isosamples,key,keytitle,% - label,logscale,mapping,offsets,output,parametric,pointsize,% - polar,rrange,samples,size,style,surface,terminal,tics,time,% - timefmt,title,trange,urange,variables,view,vrange,xdata,xlabel,% - xmargin,xrange,xtics,mxtics,mytics,xdtics,xmtics,xzeroaxis,% - ydata,ylabel,yrange,ytics,ydtics,ymtics,yzeroaxis,zdata,zero,% - zeroaxis,zlabel,zrange,ztics,zdtics,zmtics,timefm,using,title,% - with,index,every,thru,smooth},% - sensitive,% - comment=[l]\#,% - morestring=[b]",% - morestring=[b]',% - }[keywords,comments,strings]% -%% -%% Haskell98 as implemented in Hugs98. See http://www.haskell.org -%% All keywords from Prelude and Standard Libraries -%% (c) 1999 Peter Bartke -%% -\lst@definelanguage{Haskell}% - {otherkeywords={=>},% - morekeywords={abstype,if,then,else,case,class,data,default,deriving,% - hiding,if,in,infix,infixl,infixr,import,instance,let,module,% - newtype,of,qualified,type,where,do,AbsoluteSeek,AppendMode,% - Array,BlockBuffering,Bool,BufferMode,Char,Complex,Double,Either,% - FilePath,Float,Int,Integer,IO,IOError,Ix,LineBuffering,Maybe,% - Ordering,NoBuffering,ReadMode,ReadWriteMode,ReadS,RelativeSeek,% - SeekFromEnd,SeekMode,ShowS,StdGen,String,Void,Bounded,Enum,Eq,% - Eval,ExitCode,exitFailure,exitSuccess,Floating,Fractional,% - Functor,Handle,HandlePosn,IOMode,Integral,List,Monad,MonadPlus,% - MonadZero,Num,Numeric,Ord,Random,RandomGen,Ratio,Rational,Read,% - Real,RealFloat,RealFrac,Show,System,Prelude,EQ,False,GT,Just,% - Left,LT,Nothing,Right,WriteMode,True,abs,accum,accumArray,% - accumulate,acos,acosh,all,and,any,ap,appendFile,applyM,% - approxRational,array,asTypeOf,asin,asinh,assocs,atan,atan2,atanh,% - bounds,bracket,bracket_,break,catch,catMaybes,ceiling,chr,cis,% - compare,concat,concatMap,conjugate,const,cos,cosh,curry,cycle,% - decodeFloat,delete,deleteBy,deleteFirstsBy,denominator,% - digitToInt,div,divMod,drop,dropWhile,either,elem,elems,elemIndex,% - elemIndices,encodeFloat,enumFrom,enumFromThen,enumFromThenTo,% - enumFromTo,error,even,exitFailure,exitWith,exp,exponent,fail,% - filter,filterM,find,findIndex,findIndices,flip,floatDigits,% - floatRadix,floatRange,floatToDigits,floor,foldl,foldM,foldl1,% - foldr,foldr1,fromDouble,fromEnum,fromInt,fromInteger,% - fromIntegral,fromJust,fromMaybe,fromRat,fromRational,% - fromRealFrac,fst,gcd,genericLength,genericTake,genericDrop,% - genericSplitAt,genericIndex,genericReplicate,getArgs,getChar,% - getContents,getEnv,getLine,getProgName,getStdGen,getStdRandom,% - group,groupBy,guard,hClose,hFileSize,hFlush,hGetBuffering,% - hGetChar,hGetContents,hGetLine,hGetPosn,hIsClosed,hIsEOF,hIsOpen,% - hIsReadable,hIsSeekable,hIsWritable,hLookAhead,hPutChar,hPutStr,% - hPutStrLn,hPrint,hReady,hSeek,hSetBuffering,hSetPosn,head,% - hugsIsEOF,hugsHIsEOF,hugsIsSearchErr,hugsIsNameErr,% - hugsIsWriteErr,id,ioError,imagPart,index,indices,init,inits,% - inRange,insert,insertBy,interact,intersect,intersectBy,% - intersperse,intToDigit,ioeGetErrorString,ioeGetFileName,% - ioeGetHandle,isAlreadyExistsError,isAlreadyInUseError,isAlpha,% - isAlphaNum,isAscii,isControl,isDenormalized,isDoesNotExistError,% - isDigit,isEOF,isEOFError,isFullError,isHexDigit,isIEEE,% - isIllegalOperation,isInfinite,isJust,isLower,isNaN,% - isNegativeZero,isNothing,isOctDigit,isPermissionError,isPrefixOf,% - isPrint,isSpace,isSuffixOf,isUpper,isUserError,iterate,ixmap,% - join,last,lcm,length,lex,lexDigits,lexLitChar,liftM,liftM2,% - liftM3,liftM4,liftM5,lines,listArray,listToMaybe,log,logBase,% - lookup,magnitude,makePolar,map,mapAccumL,mapAccumR,mapAndUnzipM,% - mapM,mapM_,mapMaybe,max,maxBound,maximum,maximumBy,maybe,% - maybeToList,min,minBound,minimum,minimumBy,mkPolar,mkStdGen,% - mplus,mod,msum,mzero,negate,next,newStdGen,not,notElem,nub,nubBy,% - null,numerator,odd,openFile,or,ord,otherwise,partition,phase,pi,% - polar,pred,print,product,properFraction,putChar,putStr,putStrLn,% - quot,quotRem,random,randomIO,randomR,randomRIO,randomRs,randoms,% - rangeSize,read,readDec,readFile,readFloat,readHex,readInt,readIO,% - readList,readLitChar,readLn,readParen,readOct,readSigned,reads,% - readsPrec,realPart,realToFrac,recip,rem,repeat,replicate,return,% - reverse,round,scaleFloat,scanl,scanl1,scanr,scanr1,seq,sequence,% - sequence_,setStdGen,show,showChar,showEFloat,showFFloat,% - showFloat,showGFloat,showInt,showList,showLitChar,showParen,% - showSigned,showString,shows,showsPrec,significand,signum,sin,% - sinh,snd,sort,sortBy,span,split,splitAt,sqrt,stderr,stdin,stdout,% - strict,subtract,succ,sum,system,tail,tails,take,takeWhile,tan,% - tanh,toEnum,toInt,toInteger,toLower,toRational,toUpper,transpose,% - truncate,try,uncurry,undefined,unfoldr,union,unionBy,unless,% - unlines,until,unwords,unzip,unzip3,unzip4,unzip5,unzip6,unzip7,% - userError,when,words,writeFile,zero,zip,zip3,zip4,zip5,zip6,zip7,% - zipWith,zipWithM,zipWithM_,zipWith3,zipWith4,zipWith5,zipWith6,% - zipWith7},% - sensitive,% - morecomment=[l]--,% - morecomment=[n]{\{-}{-\}},% - morestring=[b]"% - }[keywords,comments,strings]% -%% -%% IDL definition (c) 1998 Juergen Heim -%% -\lst@definelanguage{IDL}% - {morekeywords={and,begin,case,common,do,else,end,endcase,endelse,% - endfor,endif,endrep,endwhile,eq,for,function,ge,goto,gt,if,le,lt,% - mod,ne,not,of,on_ioerror,or,pro,repeat,return,then,until,while,% - xor,on_error,openw,openr,openu,print,printf,printu,plot,read,% - readf,readu,writeu,stop},% - sensitive=f,% - morecomment=[l];,% - morestring=[d]'% - }[keywords,comments,strings]% -%% -%% Inform definition (c) 2003 Jonathan Sauer -%% -\lst@definelanguage{inform}{% - % Language keywords - morekeywords={breakdo,else,false,for,has,hasnt,if,% - in,indirect,jump,notin,nothing,NULL,objectloop,ofclass,% - private,property,provides,return,rfalse,rtrue,self,string,% - switch,to,true,until,while,with,% - creature,held,multiexcept,multiheld,multiinside,noun,number,% - scope,topic},% - % - % Inform functions - morekeywords=[2]{box,child,children,font,give,inversion,metaclass,move,% - new_line,parent,print,print_ret,read,remove,restore,sibling,% - save,spaces,quit,style,bold,underline,reverse,roman remaining,% - create,destroy,recreate,copy},% - % - % Inform definitions - morekeywords=[3]{Attribute,Array,Class,Constant,Default,End,Endif,Extend,% - Global,Ifdef,Iffalse,Ifndef,Ifnot,Iftrue,Include,Object,% - Property,Verb,Release,Serial,Statusline},% - % - % Library attributes - morekeywords=[4]{absent,animate,clothing,concealed,container,door,edible,% - enterable,female,general,light,lockable locked,male,moved,% - neuter,on,open,openable,pluralname,proper,scenery,scored,% - static,supporter,switchable,talkable,transparent,visited,% - workflag,worn},% - % - % Libary properties - morekeywords=[5]{n_to,s_to,e_to,w_to,ne_to,nw_to,se_to,sw_to,in_to,% - out_to,u_to,d_to,add_to_scope,after,article,articles,before,% - cant_go,capacity,daemon,describe,description,door_dir,door_to,% - each_turn,found_in,grammar,initial,inside_description,invent,% - life,list_together,name number,orders,parse_name,plural,% - react_after,react_before,short_name,short_name_indef,time_left,% - time_out,when_closed,when_open,when_on,when_off,% - with_key}, - % - % Library routines - morekeywords=[6]{Achieved,AfterRoutines,AllowPushDir,Banner,ChangePlayer,% - CommonAncestor,DictionaryLookup,GetGNAOfObject,HasLightSource,% - IndirectlyContains,IsSeeThrough,Locale,LoopOverScope,LTI_Insert,% - MoveFloatingObjects,NextWord,NextWordStopped,NounDomain,% - ObjectIsUntouchable OffersLight,ParseToken,PlaceInScope,PlayerTo,% - PronounNotice,PronounValue,ScopeWithin,SetPronoun,SetTime,% - StartDaemon,StartTimer,StopDaemon,StopTimer,TestScope,TryNumber,% - UnsignedCompare,WordAddress,WordInProperty,WordLength,% - WriteListFrom,YesOrNo},% - % - % Library,entry points - morekeywords=[7]{AfterLife,AfterPrompt,Amusing,BeforeParsing,ChooseObjects,% - DarkToDark,DeathMessage,GamePostRoutine GamePreRoutine,% - Initialise,InScope,LookRoutine,NewRoom,ParseNoun,ParseNumber,% - ParserError,PrintRank,PrintTaskName,PrintVerb,TimePasses,% - UnknownVerb},% - % - % Library constants - morekeywords=[8]{NEWLINE_BIT,INDENT_BIT,FULLINV_BIT,ENGLISH_BIT,RECURSE_BIT,% - ALWAYS_BIT,TERSE_BIT,PARTINV_BIT,DEFART_BIT,WORKFLAG_BIT,% - ISARE_BIT,CONCEAL_BIT},% - % - % Library,meta actions - morekeywords=[9]{Pronouns,Quit,Restart,Restore,Save,Verify,ScriptOn,ScriptOff,% - NotifyOn,NotifyOff,Places,Objects,Score,FullScore,Version,LMode1,% - LMode2,Lmode3},% - % - % Library,main actions - morekeywords=[10]{Close,Disrobe,Drop,Eat,Empty,EmptyT,Enter,Examine,Exit,GetOff,% - Give,Go,GoIn,Insert,Inv,InvTall,InvWide,Lock,Look,Open,PutOn,Remove,% - Search,Show,SwitchOff,SwitchOn,Take,Transfer,Unlock VagueGo,% - Wear},% - % - % Library,stub actions - morekeywords=[11]{Answer,Ask,AskFor,Attack,Blow,Burn,Buy,Climb,Consult,Cut,Dig,% - Drink,Fill,Jump,JumpOver,Kiss,Listen,LookUnder,Mild,No,Pray,Pull,% - Push,PushDir,Rub,Set,SetTo,Sing,Sleep,Smell,,Sleep,Smell,Sorry,% - Squeeze,Strong,Swim,Swing,Taste,Tell,Think,ThrowAt,Tie,Touch,Turn,% - Wait,Wake,WakeOther,Wave,WaveHands,Yes},% - % - otherkeywords={->,-->},% - sensitive=false,% - morestring=[d]{"},% - morecomment=[l]{!}% - }[keywords,comments,strings]% -\lst@definelanguage{Lisp}% - {morekeywords={abort,abs,acons,acos,acosh,adjoin,alphanumericp,alter,% - append,apply,apropos,aref,arrayp,ash,asin,asinh,assoc,atan,atanh,% - atom,bit,boole,boundp,break,butlast,byte,catenate,ceiling,cerror,% - char,character,characterp,choose,chunk,cis,close,clrhash,coerce,% - collect,commonp,compile,complement,complex,complexp,concatenate,% - conjugate,cons,consp,constantp,continue,cos,cosh,cotruncate,% - count,delete,denominator,describe,directory,disassemble,% - documentation,dpb,dribble,ed,eighth,elt,enclose,endp,eq,eql,% - equal,equalp,error,eval,evalhook,evenp,every,exp,expand,export,% - expt,fboundp,fceiling,fdefinition,ffloor,fifth,fill,find,first,% - float,floatp,floor,fmakunbound,format,fourth,fround,ftruncate,% - funcall,functionp,gatherer,gcd,generator,gensym,gentemp,get,getf,% - gethash,identity,imagpart,import,inspect,integerp,intern,% - intersection,tively,isqrt,keywordp,last,latch,lcm,ldb,ldiff,% - length,list,listen,listp,load,log,logand,logbitp,logcount,logeqv,% - logior,lognand,lognor,lognot,logtest,logxor,macroexpand,% - makunbound,map,mapc,mapcan,mapcar,mapcon,maphash,mapl,maplist,% - mask,max,member,merge,min,mingle,minusp,mismatch,mod,namestring,% - nbutlast,nconc,nintersection,ninth,not,notany,notevery,nreconc,% - nreverse,nsublis,nsubst,nth,nthcdr,null,numberp,numerator,nunion,% - oddp,open,packagep,pairlis,pathname,pathnamep,phase,plusp,% - position,positions,pprint,previous,princ,print,proclaim,provide,% - random,rassoc,rational,rationalize,rationalp,read,readtablep,% - realp,realpart,reduce,rem,remhash,remove,remprop,replace,require,% - rest,revappend,reverse,room,round,rplaca,rplacd,sbit,scan,schar,% - search,second,series,set,seventh,shadow,signal,signum,sin,sinh,% - sixth,sleep,some,sort,split,sqrt,streamp,string,stringp,sublis,% - subseq,subseries,subsetp,subst,substitute,subtypep,svref,sxhash,% - symbolp,tailp,tan,tanh,tenth,terpri,third,truename,truncate,% - typep,unexport,unintern,union,until,values,vector,vectorp,warn,% - write,zerop,and,assert,case,ccase,cond,ctypecase,decf,declaim,% - defclass,defconstant,defgeneric,defmacro,defmethod,defpackage,% - defparameter,defsetf,defstruct,deftype,defun,defvar,do,dolist,% - dotimes,ecase,encapsulated,etypecase,flet,formatter,gathering,% - incf,iterate,labels,let,locally,loop,macrolet,mapping,or,pop,% - producing,prog,psetf,psetq,push,pushnew,remf,return,rotatef,% - setf,shiftf,step,time,trace,typecase,unless,untrace,when},% - sensitive,% ??? - alsodigit=-,% - morecomment=[l];,% - morecomment=[s]{\#|}{|\#},% 1997 Aslak Raanes - morestring=[b]"% - }[keywords,comments,strings]% -%% -%% AutoLISP/VisualLISP - Stefan Lagotzki, info@lagotzki.de -%% -\lst@definelanguage[Auto]{Lisp}% - {morekeywords={abs,acad_colordlg,acad_helpdlg,acad_strlsort,% - action_tile,add_list,alert,alloc,and,angle,angtof,angtos,append,% - apply,arx,arxload,arxunload,ascii,assoc,atan,atof,atoi,atom,% - atoms-family,autoarxload,autoload,Boole,boundp,caddr,cadr,car,% - cdr,chr,client_data_tile,close,command,cond,cons,cos,cvunit,% - defun,defun-q,defun-q-list-ref,defun-q-list-set,dictadd,dictnext,% - dictremove,dictrename,dictsearch,dimx_tile,dimy_tile,distance,% - distof,done_dialog,end_image,end_list,entdel,entget,entlast,% - entmake,entmakex,entmod,entnext,entsel,entupd,eq,equal,*error*,% - eval,exit,exp,expand,expt,fill_image,findfile,fix,float,foreach,% - function,gc,gcd,get_attr,get_tile,getangle,getcfg,getcname,% - getcorner,getdist,getenv,getfiled,getint,getkword,getorient,% - getpoint,getreal,getstring,getvar,graphscr,grclear,grdraw,grread,% - grtext,grvecs,handent,help,if,initdia,initget,inters,itoa,lambda,% - last,layoutlist,length,list,listp,load,load_dialog,log,logand,% - logior,lsh,mapcar,max,mem,member,menucmd,menugroup,min,minusp,% - mode_tile,namedobjdict,nentsel,nentselp,new_dialog,not,nth,% - null,numberp,open,or,osnap,polar,prin1,princ,print,progn,prompt,% - quit,quote,read,read-char,read-line,redraw,regapp,rem,repeat,% - reverse,rtos,set,set_tile,setcfg,setenv,setfunhelp,setq,% - setvar,setview,sin,slide_image,snvalid,sqrt,ssadd,ssdel,ssget,% - ssgetfirst,sslength,ssmemb,ssname,ssnamex,sssetfirst,startapp,% - start_dialog,start_image,start_list,strcase,strcat,strlen,subst,% - substr,tablet,tblnext,tblobjname,tblsearch,term_dialog,terpri,% - textbox,textpage,textscr,trace,trans,type,unload_dialog,untrace,% - vector_image,ver,vl-acad-defun,vl-acad-undefun,vl-arx-import,% - vl-bb-ref,vl-bb-set,vl-catch-all-apply,% - vl-catch-all-error-message,vl-catch-all-error-p,vl-cmdf,vl-consp,% - vl-directory-files,vl-doc-export,vl-doc-import,vl-doc-ref,% - vl-doc-set,vl-every,vl-exit-with-error,vl-exit-with-value,% - vl-file-copy,vl-file-delete,vl-file-directory-p,vl-file-rename,% - vl-file-size,vl-file-systime,vl-filename-base,% - vl-filename-directory,vl-filename-extension,vl-filename-mktemp,% - vl-get-resource,vl-list*,vl-list->string,% - vl-list-exported-functions,vl-list-length,vl-list-loaded-vlx,% - vl-load-all,vl-load-com,vl-load-reactors,vl-member-if,% - vl-member-if-not,vl-position,vl-prin1-to-string,% - vl-princ-to-string,vl-propagate,vl-registry-delete,% - vl-registry-descendents,vl-registry-read,vl-registry-write,% - vl-remove,vl-remove-if,vl-remove-if-not,vl-some,vl-sort,% - vl-sort-i,vl-string->list,vl-string-elt,vl-string-left-trim,% - vl-string-mismatch,vl-string-position,vl-string-right-trim,% - vl-string-search,vl-string-subst,vl-string-translate,% - vl-string-trim,vl-symbol-name,vl-symbol-value,vl-symbolp,% - vl-unload-vlx,vl-vbaload,vl-vbarun,vl-vlx-loaded-p,vlax-3D-point,% - vlax-add-cmd,vlax-create-object,vlax-curve-getArea,% - vlax-curve-getDistAtParam,vlax-curve-getDistAtPoint,% - vlax-curve-getEndParam,vlax-curve-getEndPoint,% - vlax-curve-getParamAtDist,vlax-curve-getParamAtPoint,% - vlax-curve-getPointAtDist,vlax-curve-getPointAtParam,% - vlax-curve-getStartParam,vlax-curve-getStartPoint,% - vlax-curve-isClosed,vlax-curve-isPeriodic,vlax-curve-isPlanar,% - vlax-curve-getClosestPointTo,% - vlax-curve-getClosestPointToProjection,vlax-curve-getFirstDeriv,% - vlax-curve-getSecondDeriv,vlax-dump-object,% - vlax-ename->vla-object,vlax-erased-p,vlax-for,% - vlax-get-acad-object,vlax-get-object,vlax-get-or-create-object,% - vlax-get-property,vlax-import-type-library,vlax-invoke-method,% - vlax-ldata-delete,vlax-ldata-get,vlax-ldata-list,vlax-ldata-put,% - vlax-ldata-test,vlax-make-safearray,vlax-make-variant,% - vlax-map-collection,vlax-method-applicable-p,% - vlax-object-released-p,vlax-product-key,% - vlax-property-available-p,vlax-put-property,vlax-read-enabled-p,% - vlax-release-object,vlax-remove-cmd,vlax-safearray-fill,% - vlax-safearray-get-dim,vlax-safearray-get-element,% - vlax-safearray-get-l-bound,vlax-safearray-get-u-bound,% - vlax-safearray-put-element,vlax-safearray-type,% - vlax-safearray->list,vlax-tmatrix,vlax-typeinfo-available-p,% - vlax-variant-change-type,vlax-variant-type,vlax-variant-value,% - vlax-vla-object->ename,vlax-write-enabled-p,vlisp-compile,% - vlr-acdb-reactor,vlr-add,vlr-added-p,vlr-beep-reaction,% - vlr-command-reactor,vlr-current-reaction-name,vlr-data,% - vlr-data-set,vlr-deepclone-reactor,vlr-docmanager-reactor,% - vlr-dwg-reactor,vlr-dxf-reactor,vlr-editor-reactor,% - vlr-insert-reactor,vlr-linker-reactor,vlr-lisp-reactor,% - vlr-miscellaneous-reactor,vlr-mouse-reactor,vlr-notification,% - vlr-object-reactor,vlr-owner-add,vlr-owner-remove,vlr-owners,% - vlr-pers,vlr-pers-list,vlr-pers-p,vlr-pers-release,% - vlr-reaction-names,vlr-reaction-set,vlr-reactions,vlr-reactors,% - vlr-remove,vlr-remove-all,vlr-set-notification,% - vlr-sysvar-reactor,vlr-toolbar-reactor,vlr-trace-reaction,% - vlr-type,vlr-types,vlr-undo-reactor,vlr-wblock-reactor,% - vlr-window-reactor,vlr-xref-reactor,vports,wcmatch,while,% - write-char,write-line,xdroom,xdsize,zerop},% - alsodigit=->,% - otherkeywords={1+,1-},% - sensitive=false,% - morecomment=[l];,% - morecomment=[l];;,% - morestring=[b]"% - }[keywords,comments,strings]% -%% -%% Make definitions (c) 2000 Rolf Niepraschk -%% -\lst@definelanguage[gnu]{make}% - {morekeywords={SHELL,MAKE,MAKEFLAGS,$@,$\%,$<,$?,$^,$+,$*,% - @,^,<,\%,+,?,*,% Markus Pahlow - export,unexport,include,override,define,ifdef,ifneq,ifeq,else,% - endif,vpath,subst,patsubst,strip,findstring,filter,filter-out,% - sort,dir,notdir,suffix,basename,addsuffix,addprefix,join,word,% - words,firstword,wildcard,shell,origin,foreach,% - @D,@F,*D,*F,\%D,\%F,,-->,--->,:-,==,=>,<=,<=>},% - morekeywords={module,include_module,import_module,interface,% - end_module,implementation,mode,is,failure,semidet,nondet,det,% - multi,erroneous,inst,in,out,di,uo,ui,type,typeclass,instance,% - where,with_type,pred,func,lambda,impure,semipure,if,then,else,% - some,all,not,true,fail,pragma,memo,no_inline,inline,loop_check,% - minimal_model,fact_table,type_spec,terminates,does_not_terminate,% - check_termination,promise_only_solution,unsafe_promise_unique,% - source_file,obsolete,import,export,c_header_code,c_code,% - foreign_code,foreign_proc,may_call_mercury,will_not_call_mercury,% - thread_safe,not_thread_safe},% - sensitive=t,% - morecomment=[l]\%,% - morecomment=[s]{/*}{*/},% - morestring=[bd]",% - morestring=[bd]'% - }[keywords,comments,strings]% -%% -%% Miranda definition (c) 1998 Peter Bartke -%% -%% Miranda: pure lazy functional language with polymorphic type system, -%% garbage collection and functions as first class citizens -%% -\lst@definelanguage{Miranda}% - {morekeywords={abstype,div,if,mod,otherwise,readvals,show,type,where,% - with,bool,char,num,sys_message,False,True,Appendfile,Closefile,% - Exit,Stderr,Stdout,System,Tofile,\%include,\%export,\%free,% - \%insert,abs,and,arctan,cjustify,code,concat,const,converse,cos,% - decode,digit,drop,dropwhile,entier,error,exp,filemode,filter,% - foldl,foldl1,foldr,foldr1,force,fst,getenv,hd,hugenum,id,index,% - init,integer,iterate,last,lay,layn,letter,limit,lines,ljustify,% - log,log10,map,map2,max,max2,member,merge,min,min2,mkset,neg,% - numval,or,pi,postfix,product,read,rep,repeat,reverse,rjustify,% - scan,seq,showfloat,shownum,showscaled,sin,snd,sort,spaces,sqrt,% - subtract,sum,system,take,takewhile,tinynum,tl,transpose,undef,% - until,zip2,zip3,zip4,zip5,zip6,zip},% - sensitive,% - morecomment=[l]||,% - morestring=[b]"% - }[keywords,comments,strings]% -%% -%% ML definition (c) 1999 Torben Hoffmann -%% -\lst@definelanguage{ML}% - {morekeywords={abstype,and,andalso,as,case,do,datatype,else,end,% - eqtype,exception,fn,fun,functor,handle,if,in,include,infix,% - infixr,let,local,nonfix,of,op,open,orelse,raise,rec,sharing,sig,% - signature,struct,structure,then,type,val,with,withtype,while},% - sensitive,% - morecomment=[n]{(*}{*)},% - morestring=[d]"% - }[keywords,comments,strings]% -%% -%% Oz definition (c) Andres Becerra Sandoval -%% -\lst@definelanguage{Oz}% - {morekeywords={andthen,at,attr,case,catch,choice,class,% - cond,declare,define,dis,div,else,elsecase,% - elseif,end,export,fail,false,feat,finally,% - from,fun,functor,if,import,in,local,% - lock,meth,mod,not,of,or,orelse,% - prepare,proc,prop,raise,require,self,skip,% - then,thread,true,try,unit},% - sensitive=true,% - morecomment=[l]{\%},% - morecomment=[s]{/*}{*/},% - morestring=[b]",% - morestring=[d]'% - }[keywords,comments,strings]% -%% -%% PHP definition by Luca Balzerani -%% -\lst@definelanguage{PHP}% - {morekeywords={% - %--- core language - ,::,break,case,continue,default,do,else,% - elseif,for,foreach,if,include,require,phpinfo,% - switch,while,false,FALSE,true,TRUE,% - %--- apache functions - apache_lookup_uri,apache_note,ascii2ebcdic,ebcdic2ascii,% - virtual,apache_child_terminate,apache_setenv,% - %--- array functions - array,array_change_key_case,array_chunk,array_count_values,% - array_filter,array_flip,array_fill,array_intersect,% - array_keys,array_map,array_merge,array_merge_recursive,% - array_pad,array_pop,array_push,array_rand,array_reverse,% - array_shift,array_slice,array_splice,array_sum,array_unique,% - array_values,array_walk,arsort,asort,compact,count,current,each,% - extract,in_array,array_search,key,krsort,ksort,list,natsort,% - next,pos,prev,range,reset,rsort,shuffle,sizeof,sort,uasort,% - usort,% - %--- aspell functions - aspell_new,aspell_check,aspell_check_raw,aspell_suggest,% - %--- bc functions - bcadd,bccomp,bcdiv,bcmod,bcmul,bcpow,bcscale,bcsqrt,bcsub,% - %--- bzip2 functions - bzclose,bzcompress,bzdecompress,bzerrno,bzerror,bzerrstr,% - bzopen,bzread,bzwrite,% - %--- calendar functions - JDToGregorian,GregorianToJD,JDToJulian,JulianToJD,JDToJewish,% - JDToFrench,FrenchToJD,JDMonthName,JDDayOfWeek,easter_date,% - unixtojd,jdtounix,cal_days_in_month,cal_to_jd,cal_from_jd,% - %--- ccvs functions - ccvs_init,ccvs_done,ccvs_new,ccvs_add,ccvs_delete,ccvs_auth,% - ccvs_reverse,ccvs_sale,ccvs_void,ccvs_status,ccvs_count,% - ccvs_report,ccvs_command,ccvs_textvalue,% - %--- classobj functions - call_user_method,call_user_method_array,class_exists,get_class,% - get_class_vars,get_declared_classes,get_object_vars,% - is_a,is_subclass_of,method_exists,% - %--- com functions - COM,VARIANT,com_load,com_invoke,com_propget,com_get,com_propput,% - com_set,com_addref,com_release,com_isenum,com_load_typelib,% - %--- cpdf functions - cpdf_add_annotation,cpdf_add_outline,cpdf_arc,cpdf_begin_text,% - cpdf_clip,cpdf_close,cpdf_closepath,cpdf_closepath_fill_stroke,% - cpdf_continue_text,cpdf_curveto,cpdf_end_text,cpdf_fill,% - cpdf_finalize,cpdf_finalize_page,% - cpdf_import_jpeg,cpdf_lineto,cpdf_moveto,cpdf_newpath,cpdf_open,% - cpdf_page_init,cpdf_place_inline_image,cpdf_rect,cpdf_restore,% - cpdf_rmoveto,cpdf_rotate,cpdf_rotate_text,cpdf_save,% - cpdf_scale,cpdf_set_char_spacing,cpdf_set_creator,% - cpdf_set_font,cpdf_set_horiz_scaling,cpdf_set_keywords,% - cpdf_set_page_animation,cpdf_set_subject,cpdf_set_text_matrix,% - cpdf_set_text_rendering,cpdf_set_text_rise,cpdf_set_title,% - cpdf_setdash,cpdf_setflat,cpdf_setgray,cpdf_setgray_fill,% - cpdf_setlinecap,cpdf_setlinejoin,cpdf_setlinewidth,% - cpdf_setrgbcolor,cpdf_setrgbcolor_fill,cpdf_setrgbcolor_stroke,% - cpdf_show_xy,cpdf_stringwidth,cpdf_set_font_directories,% - cpdf_set_viewer_preferences,cpdf_stroke,cpdf_text,% - cpdf_set_action_url,% - %--- crack functions - crack_opendict,crack_closedict,crack_check,crack_getlastmessage,% - %--- ctype functions - ctype_alnum,ctype_alpha,ctype_cntrl,ctype_digit,ctype_lower,% - ctype_print,ctype_punct,ctype_space,ctype_upper,ctype_xdigit,% - %--- curl functions - curl_init,curl_setopt,curl_exec,curl_close,curl_version,% - curl_error,curl_getinfo,% - %--- cybercash functions - cybercash_encr,cybercash_decr,cybercash_base64_encode,% - %--- cybermut functions - cybermut_creerformulairecm,cybermut_testmac,% - %--- cyrus functions - cyrus_connect,cyrus_authenticate,cyrus_bind,cyrus_unbind,% - cyrus_close,% - %--- datetime functions - checkdate,date,getdate,gettimeofday,gmdate,gmmktime,gmstrftime,% - microtime,mktime,strftime,time,strtotime,% - %--- dbase functions - dbase_create,dbase_open,dbase_close,dbase_pack,dbase_add_record,% - dbase_delete_record,dbase_get_record,% - dbase_numfields,dbase_numrecords,% - %--- dba functions - dba_close,dba_delete,dba_exists,dba_fetch,dba_firstkey,% - dba_nextkey,dba_popen,dba_open,dba_optimize,dba_replace,% - %--- dbm functions - dbmopen,dbmclose,dbmexists,dbmfetch,dbminsert,dbmreplace,% - dbmfirstkey,dbmnextkey,dblist,% - %--- dbx functions - dbx_close,dbx_connect,dbx_error,dbx_query,dbx_sort,dbx_compare,% - %--- dio functions - dio_open,dio_read,dio_write,dio_truncate,dio_stat,dio_seek,% - dio_close,% - %--- dir functions - chroot,chdir,dir,closedir,getcwd,opendir,readdir,rewinddir,% - %--- dotnet functions - dotnet_load,% - %--- errorfunc functions - error_log,error_reporting,restore_error_handler,% - trigger_error,user_error,% - %--- exec functions - escapeshellarg,escapeshellcmd,exec,passthru,system,shell_exec,% - %--- fbsql functions - fbsql_affected_rows,fbsql_autocommit,fbsql_change_user,% - fbsql_commit,fbsql_connect,fbsql_create_db,fbsql_create_blob,% - fbsql_database_password,fbsql_data_seek,fbsql_db_query,% - fbsql_drop_db,fbsql_errno,fbsql_error,fbsql_fetch_array,% - fbsql_fetch_field,fbsql_fetch_lengths,fbsql_fetch_object,% - fbsql_field_flags,fbsql_field_name,fbsql_field_len,% - fbsql_field_table,fbsql_field_type,fbsql_free_result,% - fbsql_list_dbs,fbsql_list_fields,fbsql_list_tables,% - fbsql_num_fields,fbsql_num_rows,fbsql_pconnect,fbsql_query,% - fbsql_read_clob,fbsql_result,fbsql_rollback,fbsql_set_lob_mode,% - fbsql_start_db,fbsql_stop_db,fbsql_tablename,fbsql_warnings,% - fbsql_get_autostart_info,fbsql_hostname,fbsql_password,% - fbsql_username,% - %--- fdf functions - fdf_open,fdf_close,fdf_create,fdf_save,fdf_get_value,% - fdf_next_field_name,fdf_set_ap,fdf_set_status,fdf_get_status,% - fdf_get_file,fdf_set_flags,fdf_set_opt,% - fdf_set_javascript_action,fdf_set_encoding,fdf_add_template,% - %--- filepro functions - filepro,filepro_fieldname,filepro_fieldtype,filepro_fieldwidth,% - filepro_fieldcount,filepro_rowcount,% - %--- filesystem functions - basename,chgrp,chmod,chown,clearstatcache,copy,delete,dirname,% - diskfreespace,disk_total_space,fclose,feof,fflush,fgetc,fgetcsv,% - fgetss,file_get_contents,file,file_exists,fileatime,filectime,% - fileinode,filemtime,fileowner,fileperms,filesize,filetype,flock,% - fopen,fpassthru,fputs,fread,fscanf,fseek,fstat,ftell,ftruncate,% - set_file_buffer,is_dir,is_executable,is_file,is_link,% - is_writable,is_writeable,is_uploaded_file,link,linkinfo,mkdir,% - parse_ini_file,pathinfo,pclose,popen,readfile,readlink,rename,% - rmdir,stat,lstat,realpath,symlink,tempnam,tmpfile,touch,umask,% - %--- fribidi functions - fribidi_log2vis,% - %--- ftp functions - ftp_connect,ftp_login,ftp_pwd,ftp_cdup,ftp_chdir,ftp_mkdir,% - ftp_nlist,ftp_rawlist,ftp_systype,ftp_pasv,ftp_get,ftp_fget,% - ftp_fput,ftp_size,ftp_mdtm,ftp_rename,ftp_delete,ftp_site,% - ftp_quit,ftp_exec,ftp_set_option,ftp_get_option,% - %--- funchand functions - call_user_func_array,call_user_func,create_function,% - func_get_args,func_num_args,function_exists,% - register_shutdown_function,register_tick_function,% - %--- gettext functions - bindtextdomain,bind_textdomain_codeset,dcgettext,dcngettext,% - dngettext,gettext,ngettext,textdomain,% - %--- gmp functions - gmp_init,gmp_intval,gmp_strval,gmp_add,gmp_sub,gmp_mul,% - gmp_div_r,gmp_div_qr,gmp_div,gmp_mod,gmp_divexact,gmp_cmp,% - gmp_com,gmp_abs,gmp_sign,gmp_fact,gmp_sqrt,gmp_sqrtrm,% - gmp_pow,gmp_powm,gmp_prob_prime,gmp_gcd,gmp_gcdext,gmp_invert,% - gmp_jacobi,gmp_random,gmp_and,gmp_or,gmp_xor,gmp_setbit,% - gmp_scan0,gmp_scan1,gmp_popcount,gmp_hamdist,% - %--- http functions - header,headers_sent,setcookie,% - %--- hw functions - hw_Array2Objrec,hw_Children,hw_ChildrenObj,hw_Close,hw_Connect,% - hw_Deleteobject,hw_DocByAnchor,hw_DocByAnchorObj,% - hw_Document_BodyTag,hw_Document_Content,hw_Document_SetContent,% - hw_ErrorMsg,hw_EditText,hw_Error,hw_Free_Document,hw_GetParents,% - hw_GetChildColl,hw_GetChildCollObj,hw_GetRemote,% - hw_GetSrcByDestObj,hw_GetObject,hw_GetAndLock,hw_GetText,% - hw_GetObjectByQueryObj,hw_GetObjectByQueryColl,% - hw_GetChildDocColl,hw_GetChildDocCollObj,hw_GetAnchors,% - hw_Mv,hw_Identify,hw_InCollections,hw_Info,hw_InsColl,hw_InsDoc,% - hw_InsertObject,hw_mapid,hw_Modifyobject,hw_New_Document,% - hw_Output_Document,hw_pConnect,hw_PipeDocument,hw_Root,% - hw_Who,hw_getusername,hw_stat,hw_setlinkroot,hw_connection_info,% - hw_insertanchors,hw_getrellink,hw_changeobject,% - %--- ibase functions - ibase_connect,ibase_pconnect,ibase_close,ibase_query,% - ibase_fetch_row,ibase_fetch_object,ibase_field_info,% - ibase_free_result,ibase_prepare,ibase_execute,ibase_trans,% - ibase_rollback,ibase_timefmt,ibase_num_fields,ibase_blob_add,% - ibase_blob_close,ibase_blob_create,ibase_blob_echo,% - ibase_blob_import,ibase_blob_info,ibase_blob_open,% - %--- icap functions - icap_open,icap_close,icap_fetch_event,icap_list_events,% - icap_delete_event,icap_snooze,icap_list_alarms,% - icap_rename_calendar,icap_delete_calendar,icap_reopen,% - %--- iconv functions - iconv,iconv_get_encoding,iconv_set_encoding,ob_iconv_handler,% - %--- ifx functions - ifx_connect,ifx_pconnect,ifx_close,ifx_query,ifx_prepare,ifx_do,% - ifx_errormsg,ifx_affected_rows,ifx_getsqlca,ifx_fetch_row,% - ifx_fieldtypes,ifx_fieldproperties,ifx_num_fields,ifx_num_rows,% - ifx_create_char,ifx_free_char,ifx_update_char,ifx_get_char,% - ifx_copy_blob,ifx_free_blob,ifx_get_blob,ifx_update_blob,% - ifx_textasvarchar,ifx_byteasvarchar,ifx_nullformat,% - ifxus_free_slob,ifxus_close_slob,ifxus_open_slob,% - ifxus_seek_slob,ifxus_read_slob,ifxus_write_slob,% - %--- iisfunc functions - iis_get_server_by_path,iis_get_server_by_comment,iis_add_server,% - iis_set_dir_security,iis_get_dir_security,iis_set_server_rights,% - iis_set_script_map,iis_get_script_map,iis_set_app_settings,% - iis_stop_server,iis_stop_service,iis_start_service,% - %--- image functions - exif_imagetype,exif_read_data,exif_thumbnail,getimagesize,% - imagealphablending,imagearc,imagefilledarc,imageellipse,% - imagechar,imagecharup,imagecolorallocate,imagecolordeallocate,% - imagecolorclosest,imagecolorclosestalpha,imagecolorclosestthwb,% - imagecolorexactalpha,imagecolorresolve,imagecolorresolvealpha,% - imagecolorset,imagecolorsforindex,imagecolorstotal,% - imagecopy,imagecopymerge,imagecopymergegray,imagecopyresized,% - imagecreate,imagecreatetruecolor,imagetruecolortopalette,% - imagecreatefromgd2,imagecreatefromgd2part,imagecreatefromgif,% - imagecreatefrompng,imagecreatefromwbmp,imagecreatefromstring,% - imagecreatefromxpm,imagedashedline,imagedestroy,imagefill,% - imagefilledrectangle,imagefilltoborder,imagefontheight,% - imagegd,imagegd2,imagegif,imagepng,imagejpeg,imagewbmp,% - imageline,imageloadfont,imagepalettecopy,imagepolygon,% - imagepsencodefont,imagepsfreefont,imagepsloadfont,% - imagepsslantfont,imagepstext,imagerectangle,imagesetpixel,% - imagesetstyle,imagesettile,imagesetthickness,imagestring,% - imagesx,imagesy,imagettfbbox,imageftbbox,imagettftext,% - imagetypes,jpeg2wbmp,png2wbmp,iptcembed,read_exif_data,% - %--- imap functions - imap_8bit,imap_alerts,imap_append,imap_base64,imap_binary,% - imap_bodystruct,imap_check,imap_clearflag_full,imap_close,% - imap_delete,imap_deletemailbox,imap_errors,imap_expunge,% - imap_fetchbody,imap_fetchheader,imap_fetchstructure,% - imap_getmailboxes,imap_getsubscribed,imap_header,% - imap_headers,imap_last_error,imap_listmailbox,% - imap_mail,imap_mail_compose,imap_mail_copy,imap_mail_move,% - imap_mime_header_decode,imap_msgno,imap_num_msg,imap_num_recent,% - imap_ping,imap_popen,imap_qprint,imap_renamemailbox,imap_reopen,% - imap_rfc822_parse_headers,imap_rfc822_write_address,% - imap_search,imap_setacl,imap_set_quota,imap_setflag_full,% - imap_status,imap_subscribe,imap_uid,imap_undelete,% - imap_utf7_decode,imap_utf7_encode,imap_utf8,imap_thread,% - %--- info functions - assert,assert_options,extension_loaded,dl,getenv,get_cfg_var,% - get_defined_constants,get_extension_funcs,getmygid,% - get_loaded_extensions,get_magic_quotes_gpc,% - getlastmod,getmyinode,getmypid,getmyuid,get_required_files,% - ini_alter,ini_get,ini_get_all,ini_restore,ini_set,phpcredits,% - phpversion,php_logo_guid,php_sapi_name,php_uname,putenv,% - set_time_limit,version_compare,zend_logo_guid,zend_version,% - %--- ircg functions - ircg_pconnect,ircg_fetch_error_msg,ircg_set_current,ircg_join,% - ircg_msg,ircg_notice,ircg_nick,ircg_topic,ircg_channel_mode,% - ircg_whois,ircg_kick,ircg_ignore_add,ircg_ignore_del,% - ircg_is_conn_alive,ircg_lookup_format_messages,% - ircg_set_on_die,ircg_set_file,ircg_get_username,% - ircg_nickname_unescape,% - %--- java functions - java_last_exception_clear,java_last_exception_get,% - %--- ldap functions - ldap_add,ldap_bind,ldap_close,ldap_compare,ldap_connect,% - ldap_delete,ldap_dn2ufn,ldap_err2str,ldap_errno,ldap_error,% - ldap_first_attribute,ldap_first_entry,ldap_free_result,% - ldap_get_dn,ldap_get_entries,ldap_get_option,ldap_get_values,% - ldap_list,ldap_modify,ldap_mod_add,ldap_mod_del,% - ldap_next_attribute,ldap_next_entry,ldap_read,ldap_rename,% - ldap_set_option,ldap_unbind,ldap_8859_to_t61,% - ldap_next_reference,ldap_parse_reference,ldap_parse_result,% - ldap_sort,ldap_start_tls,ldap_t61_to_8859,% - %--- mail functions - mail,ezmlm_hash,% - %--- math functions - abs,acos,acosh,asin,asinh,atan,atanh,atan2,base_convert,bindec,% - cos,cosh,decbin,dechex,decoct,deg2rad,exp,expm1,floor,% - hexdec,hypot,is_finite,is_infinite,is_nan,lcg_value,log,log10,% - max,min,mt_rand,mt_srand,mt_getrandmax,number_format,octdec,pi,% - rad2deg,rand,round,sin,sinh,sqrt,srand,tan,tanh,% - %--- mbstring functions - mb_language,mb_parse_str,mb_internal_encoding,mb_http_input,% - mb_detect_order,mb_substitute_character,mb_output_handler,% - mb_strlen,mb_strpos,mb_strrpos,mb_substr,mb_strcut,mb_strwidth,% - mb_convert_encoding,mb_detect_encoding,mb_convert_kana,% - mb_decode_mimeheader,mb_convert_variables,% - mb_decode_numericentity,mb_send_mail,mb_get_info,% - mb_ereg,mb_eregi,mb_ereg_replace,mb_eregi_replace,mb_split,% - mb_ereg_search,mb_ereg_search_pos,mb_ereg_search_regs,% - mb_ereg_search_getregs,mb_ereg_search_getpos,% - %--- mcal functions - mcal_open,mcal_popen,mcal_reopen,mcal_close,% - mcal_rename_calendar,mcal_delete_calendar,mcal_fetch_event,% - mcal_append_event,mcal_store_event,mcal_delete_event,% - mcal_list_alarms,mcal_event_init,mcal_event_set_category,% - mcal_event_set_description,mcal_event_set_start,% - mcal_event_set_alarm,mcal_event_set_class,mcal_is_leap_year,% - mcal_date_valid,mcal_time_valid,mcal_day_of_week,% - mcal_date_compare,mcal_next_recurrence,% - mcal_event_set_recur_daily,mcal_event_set_recur_weekly,% - mcal_event_set_recur_monthly_wday,mcal_event_set_recur_yearly,% - mcal_event_add_attribute,mcal_expunge,mcal_week_of_year,% - %--- mcrypt functions - mcrypt_get_cipher_name,mcrypt_get_block_size,% - mcrypt_create_iv,mcrypt_cbc,mcrypt_cfb,mcrypt_ecb,mcrypt_ofb,% - mcrypt_list_modes,mcrypt_get_iv_size,mcrypt_encrypt,% - mcrypt_module_open,mcrypt_module_close,mcrypt_generic_deinit,% - mcrypt_generic,mdecrypt_generic,mcrypt_generic_end,% - mcrypt_enc_is_block_algorithm_mode,% - mcrypt_enc_is_block_mode,mcrypt_enc_get_block_size,% - mcrypt_enc_get_supported_key_sizes,mcrypt_enc_get_iv_size,% - mcrypt_enc_get_modes_name,mcrypt_module_self_test,% - mcrypt_module_is_block_algorithm,mcrypt_module_is_block_mode,% - mcrypt_module_get_algo_key_size,% - %--- mhash functions - mhash_get_hash_name,mhash_get_block_size,mhash_count,mhash,% - %--- misc functions - connection_aborted,connection_status,connection_timeout,% - define,defined,die,eval,exit,get_browser,highlight_file,% - ignore_user_abort,iptcparse,leak,pack,show_source,sleep,uniqid,% - usleep,% - %--- mnogosearch functions - udm_add_search_limit,udm_alloc_agent,udm_api_version,% - udm_cat_list,udm_clear_search_limits,udm_errno,udm_error,% - udm_free_agent,udm_free_ispell_data,udm_free_res,% - udm_get_res_field,udm_get_res_param,udm_load_ispell_data,% - udm_check_charset,udm_check_stored,udm_close_stored,udm_crc32,% - %--- msession functions - msession_connect,msession_disconnect,msession_count,% - msession_destroy,msession_lock,msession_unlock,msession_set,% - msession_uniq,msession_randstr,msession_find,msession_list,% - msession_set_array,msession_listvar,msession_timeout,% - msession_getdata,msession_setdata,msession_plugin,% - %--- msql functions - msql,msql_affected_rows,msql_close,msql_connect,msql_create_db,% - msql_data_seek,msql_dbname,msql_drop_db,msql_dropdb,msql_error,% - msql_fetch_field,msql_fetch_object,msql_fetch_row,% - msql_field_seek,msql_fieldtable,msql_fieldtype,msql_fieldflags,% - msql_free_result,msql_freeresult,msql_list_fields,% - msql_list_dbs,msql_listdbs,msql_list_tables,msql_listtables,% - msql_num_rows,msql_numfields,msql_numrows,msql_pconnect,% - msql_regcase,msql_result,msql_select_db,msql_selectdb,% - %--- mssql functions - mssql_close,mssql_connect,mssql_data_seek,mssql_fetch_array,% - mssql_fetch_object,mssql_fetch_row,mssql_field_length,% - mssql_field_seek,mssql_field_type,mssql_free_result,% - mssql_min_error_severity,mssql_min_message_severity,% - mssql_num_fields,mssql_num_rows,mssql_pconnect,mssql_query,% - mssql_select_db,mssql_bind,mssql_execute,mssql_fetch_assoc,% - mssql_guid_string,mssql_init,mssql_rows_affected,% - %--- muscat functions - muscat_setup,muscat_setup_net,muscat_give,muscat_get,% - %--- mysql functions - mysql_affected_rows,mysql_change_user,mysql_character_set_name,% - mysql_connect,mysql_create_db,mysql_data_seek,mysql_db_name,% - mysql_drop_db,mysql_errno,mysql_error,mysql_escape_string,% - mysql_fetch_assoc,mysql_fetch_field,mysql_fetch_lengths,% - mysql_fetch_row,mysql_field_flags,mysql_field_name,% - mysql_field_seek,mysql_field_table,mysql_field_type,% - mysql_info,mysql_insert_id,mysql_list_dbs,mysql_list_fields,% - mysql_list_tables,mysql_num_fields,mysql_num_rows,% - mysql_ping,mysql_query,mysql_unbuffered_query,% - mysql_result,mysql_select_db,mysql_tablename,mysql_thread_id,% - mysql_get_host_info,mysql_get_proto_info,mysql_get_server_info,% - %--- network functions - checkdnsrr,closelog,debugger_off,debugger_on,% - fsockopen,gethostbyaddr,gethostbyname,gethostbynamel,getmxrr,% - getprotobynumber,getservbyname,getservbyport,ip2long,long2ip,% - pfsockopen,socket_get_status,socket_set_blocking,% - syslog,% - %--- nis functions - yp_get_default_domain,yp_order,yp_master,yp_match,yp_first,% - yp_errno,yp_err_string,yp_all,yp_cat,% - %--- oci8 functions - OCIDefineByName,OCIBindByName,OCILogon,OCIPLogon,OCINLogon,% - OCIExecute,OCICommit,OCIRollback,OCINewDescriptor,OCIRowCount,% - OCIResult,OCIFetch,OCIFetchInto,OCIFetchStatement,% - OCIColumnName,OCIColumnSize,OCIColumnType,OCIServerVersion,% - OCINewCursor,OCIFreeStatement,OCIFreeCursor,OCIFreeDesc,% - OCIError,OCIInternalDebug,OCICancel,OCISetPrefetch,% - OCISaveLobFile,OCISaveLob,OCILoadLob,OCIColumnScale,% - OCIColumnTypeRaw,OCINewCollection,OCIFreeCollection,% - OCICollAppend,OCICollAssignElem,OCICollGetElem,OCICollMax,% - OCICollTrim,% - %--- oracle functions - Ora_Bind,Ora_Close,Ora_ColumnName,Ora_ColumnSize,Ora_ColumnType,% - Ora_CommitOff,Ora_CommitOn,Ora_Do,Ora_Error,Ora_ErrorCode,% - Ora_Fetch,Ora_Fetch_Into,Ora_GetColumn,Ora_Logoff,Ora_Logon,% - Ora_Numcols,Ora_Numrows,Ora_Open,Ora_Parse,Ora_Rollback,% - %--- outcontrol functions - flush,ob_start,ob_get_contents,ob_get_length,ob_get_level,% - ob_flush,ob_clean,ob_end_flush,ob_end_clean,ob_implicit_flush,% - %--- ovrimos functions - ovrimos_connect,ovrimos_close,ovrimos_longreadlen,% - ovrimos_execute,ovrimos_cursor,ovrimos_exec,ovrimos_fetch_into,% - ovrimos_result,ovrimos_result_all,ovrimos_num_rows,% - ovrimos_field_name,ovrimos_field_type,ovrimos_field_len,% - ovrimos_free_result,ovrimos_commit,ovrimos_rollback,% - %--- pcntl functions - pcntl_fork,pcntl_signal,pcntl_waitpid,pcntl_wexitstatus,% - pcntl_wifsignaled,pcntl_wifstopped,pcntl_wstopsig,% - pcntl_exec,% - %--- pcre functions - preg_match,preg_match_all,preg_replace,preg_replace_callback,% - preg_quote,preg_grep,Pattern Modifiers,Pattern Syntax,% - %--- pdf functions - pdf_add_annotation,pdf_add_bookmark,pdf_add_launchlink,% - pdf_add_note,pdf_add_outline,pdf_add_pdflink,pdf_add_thumbnail,% - pdf_arc,pdf_arcn,pdf_attach_file,pdf_begin_page,% - pdf_begin_template,pdf_circle,pdf_clip,pdf_close,pdf_closepath,% - pdf_closepath_stroke,pdf_close_image,pdf_close_pdi,% - pdf_concat,pdf_continue_text,pdf_curveto,pdf_delete,% - pdf_endpath,pdf_end_pattern,pdf_end_template,pdf_fill,% - pdf_findfont,pdf_get_buffer,pdf_get_font,pdf_get_fontname,% - pdf_get_image_height,pdf_get_image_width,pdf_get_parameter,% - pdf_get_pdi_value,pdf_get_majorversion,pdf_get_minorversion,% - pdf_initgraphics,pdf_lineto,pdf_makespotcolor,pdf_moveto,% - pdf_open,pdf_open_CCITT,pdf_open_file,pdf_open_gif,% - pdf_open_image_file,pdf_open_jpeg,pdf_open_memory_image,% - pdf_open_pdi_page,pdf_open_png,pdf_open_tiff,pdf_place_image,% - pdf_rect,pdf_restore,pdf_rotate,pdf_save,pdf_scale,pdf_setcolor,% - pdf_setflat,pdf_setfont,pdf_setgray,pdf_setgray_fill,% - pdf_setlinecap,pdf_setlinejoin,pdf_setlinewidth,pdf_setmatrix,% - pdf_setpolydash,pdf_setrgbcolor,pdf_setrgbcolor_fill,% - pdf_set_border_color,pdf_set_border_dash,pdf_set_border_style,% - pdf_set_duration,pdf_set_font,pdf_set_horiz_scaling,% - pdf_set_info_author,pdf_set_info_creator,pdf_set_info_keywords,% - pdf_set_info_title,pdf_set_leading,pdf_set_parameter,% - pdf_set_text_rendering,pdf_set_text_rise,pdf_set_text_matrix,% - pdf_set_word_spacing,pdf_show,pdf_show_boxed,pdf_show_xy,% - pdf_stringwidth,pdf_stroke,pdf_translate,% - %--- pfpro functions - pfpro_init,pfpro_cleanup,pfpro_process,pfpro_process_raw,% - %--- pgsql functions - pg_close,pg_affected_rows,pg_connect,pg_dbname,pg_end_copy,% - pg_query,pg_fetch_array,pg_fetch_object,pg_fetch_row,% - pg_field_name,pg_field_num,pg_field_prtlen,pg_field_size,% - pg_free_result,pg_last_oid,pg_host,pg_last_notice,pg_lo_close,% - pg_lo_export,pg_lo_import,pg_lo_open,pg_lo_read,pg_lo_seek,% - pg_lo_read_all,pg_lo_unlink,pg_lo_write,pg_num_fields,% - pg_options,pg_pconnect,pg_port,pg_put_line,pg_fetch_result,% - pg_client_encoding,pg_trace,pg_tty,pg_untrace,pg_get_result,% - pg_send_query,pg_cancel_query,pg_connection_busy,% - pg_connection_status,pg_copy_from,pg_copy_to,pg_escape_bytea,% - pg_result_error,% - %--- posix functions - posix_kill,posix_getpid,posix_getppid,posix_getuid,% - posix_getgid,posix_getegid,posix_setuid,posix_seteuid,% - posix_setegid,posix_getgroups,posix_getlogin,posix_getpgrp,% - posix_setpgid,posix_getpgid,posix_getsid,posix_uname,% - posix_ctermid,posix_ttyname,posix_isatty,posix_getcwd,% - posix_getgrnam,posix_getgrgid,posix_getpwnam,posix_getpwuid,% - %--- printer functions - printer_open,printer_abort,printer_close,printer_write,% - printer_set_option,printer_get_option,printer_create_dc,% - printer_start_doc,printer_end_doc,printer_start_page,% - printer_create_pen,printer_delete_pen,printer_select_pen,% - printer_delete_brush,printer_select_brush,printer_create_font,% - printer_select_font,printer_logical_fontheight,% - printer_draw_rectangle,printer_draw_elipse,printer_draw_text,% - printer_draw_chord,printer_draw_pie,printer_draw_bmp,% - %--- pspell functions - pspell_add_to_personal,pspell_add_to_session,pspell_check,% - pspell_config_create,pspell_config_ignore,pspell_config_mode,% - pspell_config_repl,pspell_config_runtogether,% - pspell_new,pspell_new_config,pspell_new_personal,% - pspell_store_replacement,pspell_suggest,% - %--- qtdom functions - qdom_tree,qdom_error,% - %--- readline functions - readline,readline_add_history,readline_clear_history,% - readline_info,readline_list_history,readline_read_history,% - %--- recode functions - recode_string,recode,recode_file,% - %--- regex functions - ereg,ereg_replace,eregi,eregi_replace,split,spliti,sql_regcase,% - %--- sem functions - sem_get,sem_acquire,sem_release,sem_remove,shm_attach,% - shm_remove,shm_put_var,shm_get_var,shm_remove_var,ftok,% - %--- sesam functions - sesam_connect,sesam_disconnect,sesam_settransaction,% - sesam_rollback,sesam_execimm,sesam_query,sesam_num_fields,% - sesam_diagnostic,sesam_fetch_result,sesam_affected_rows,% - sesam_field_array,sesam_fetch_row,sesam_fetch_array,% - sesam_free_result,% - %--- session functions - session_start,session_destroy,session_name,session_module_name,% - session_id,session_register,session_unregister,session_unset,% - session_get_cookie_params,session_set_cookie_params,% - session_encode,session_set_save_handler,session_cache_limiter,% - session_write_close,% - %--- shmop functions - shmop_open,shmop_read,shmop_write,shmop_size,shmop_delete,% - %--- snmp functions - snmpget,snmpset,snmpwalk,snmpwalkoid,snmp_get_quick_print,% - snmprealwalk,% - %--- strings functions - addcslashes,addslashes,bin2hex,chop,chr,chunk_split,% - count_chars,crc32,crypt,echo,explode,get_html_translation_table,% - hebrev,hebrevc,htmlentities,htmlspecialchars,implode,join,% - localeconv,ltrim,md5,md5_file,metaphone,nl_langinfo,nl2br,ord,% - print,printf,quoted_printable_decode,quotemeta,str_rot13,rtrim,% - setlocale,similar_text,soundex,sprintf,strncasecmp,strcasecmp,% - strcmp,strcoll,strcspn,strip_tags,stripcslashes,stripslashes,% - strlen,strnatcmp,strnatcasecmp,strncmp,str_pad,strpos,strrchr,% - strrev,strrpos,strspn,strstr,strtok,strtolower,strtoupper,% - strtr,substr,substr_count,substr_replace,trim,ucfirst,ucwords,% - vsprintf,wordwrap,% - %--- swf functions - swf_openfile,swf_closefile,swf_labelframe,swf_showframe,% - swf_getframe,swf_mulcolor,swf_addcolor,swf_placeobject,% - swf_removeobject,swf_nextid,swf_startdoaction,% - swf_actiongeturl,swf_actionnextframe,swf_actionprevframe,% - swf_actionstop,swf_actiontogglequality,swf_actionwaitforframe,% - swf_actiongotolabel,swf_enddoaction,swf_defineline,% - swf_definepoly,swf_startshape,swf_shapelinesolid,% - swf_shapefillsolid,swf_shapefillbitmapclip,% - swf_shapemoveto,swf_shapelineto,swf_shapecurveto,% - swf_shapearc,swf_endshape,swf_definefont,swf_setfont,% - swf_fontslant,swf_fonttracking,swf_getfontinfo,swf_definetext,% - swf_definebitmap,swf_getbitmapinfo,swf_startsymbol,% - swf_startbutton,swf_addbuttonrecord,swf_oncondition,% - swf_viewport,swf_ortho,swf_ortho2,swf_perspective,swf_polarview,% - swf_pushmatrix,swf_popmatrix,swf_scale,swf_translate,swf_rotate,% - %--- sybase functions - sybase_affected_rows,sybase_close,sybase_connect,% - sybase_fetch_array,sybase_fetch_field,sybase_fetch_object,% - sybase_field_seek,sybase_free_result,sybase_get_last_message,% - sybase_min_error_severity,sybase_min_message_severity,% - sybase_num_fields,sybase_num_rows,sybase_pconnect,sybase_query,% - sybase_select_db,% - %--- uodbc functions - odbc_autocommit,odbc_binmode,odbc_close,odbc_close_all,% - odbc_connect,odbc_cursor,odbc_do,odbc_error,odbc_errormsg,% - odbc_execute,odbc_fetch_into,odbc_fetch_row,odbc_fetch_array,% - odbc_fetch_object,odbc_field_name,odbc_field_num,% - odbc_field_len,odbc_field_precision,odbc_field_scale,% - odbc_longreadlen,odbc_num_fields,odbc_pconnect,odbc_prepare,% - odbc_result,odbc_result_all,odbc_rollback,odbc_setoption,% - odbc_tableprivileges,odbc_columns,odbc_columnprivileges,% - odbc_primarykeys,odbc_foreignkeys,odbc_procedures,% - odbc_specialcolumns,odbc_statistics,% - %--- url functions - base64_decode,base64_encode,parse_url,rawurldecode,rawurlencode,% - urlencode,% - %--- var functions - doubleval,empty,floatval,gettype,get_defined_vars,% - import_request_variables,intval,is_array,is_bool,is_double,% - is_int,is_integer,is_long,is_null,is_numeric,is_object,is_real,% - is_scalar,is_string,isset,print_r,serialize,settype,strval,% - unset,var_dump,var_export,is_callable,% - %--- vpopmail functions - vpopmail_add_domain,vpopmail_del_domain,% - vpopmail_add_domain_ex,vpopmail_del_domain_ex,% - vpopmail_add_user,vpopmail_del_user,vpopmail_passwd,% - vpopmail_auth_user,vpopmail_alias_add,vpopmail_alias_del,% - vpopmail_alias_get,vpopmail_alias_get_all,vpopmail_error,% - %--- w32api functions - w32api_set_call_method,w32api_register_function,% - w32api_deftype,w32api_init_dtype,% - %--- wddx functions - wddx_serialize_value,wddx_serialize_vars,wddx_packet_start,% - wddx_add_vars,wddx_deserialize,% - %--- xml functions - xml_parser_create,xml_set_object,xml_set_element_handler,% - xml_set_processing_instruction_handler,xml_set_default_handler,% - xml_set_notation_decl_handler,% - xml_parse,xml_get_error_code,xml_error_string,% - xml_get_current_column_number,xml_get_current_byte_index,% - xml_parser_free,xml_parser_set_option,xml_parser_get_option,% - utf8_encode,xml_parser_create_ns,% - xml_set_start_namespace_decl_handler,% - %--- xslt functions - xslt_set_log,xslt_create,xslt_errno,xslt_error,xslt_free,% - xslt_set_sax_handler,xslt_set_scheme_handler,% - xslt_set_base,xslt_set_encoding,xslt_set_sax_handlers,% - %--- yaz functions - yaz_addinfo,yaz_close,yaz_connect,yaz_errno,yaz_error,yaz_hits,% - yaz_database,yaz_range,yaz_record,yaz_search,yaz_present,% - yaz_scan,yaz_scan_result,yaz_ccl_conf,yaz_ccl_parse,% - yaz_wait,yaz_sort,% - %--- zip functions - zip_close,zip_entry_close,zip_entry_compressedsize,% - zip_entry_filesize,zip_entry_name,zip_entry_open,zip_entry_read,% - zip_read,% - %--- zlib functions - gzclose,gzeof,gzfile,gzgetc,gzgets,gzgetss,gzopen,gzpassthru,% - gzread,gzrewind,gzseek,gztell,gzwrite,readgzfile,gzcompress,% - gzdeflate,gzinflate,gzencode,},% - sensitive,% - morecomment=[l]\#,% - morecomment=[l]//,% - morecomment=[s]{/*}{*/},% - morestring=[b]",% - morestring=[b]'% - }[keywords,comments,strings]% -%% -%% Prolog definition (c) 1997 Dominique de Waleffe -%% -\lst@definelanguage{Prolog}% - {morekeywords={op,mod,abort,ancestors,arg,ascii,ask,assert,asserta,% - assertz,atom,atomic,char,clause,close,concat,consult,ed,ef,em,% - eof,fail,file,findall,write,functor,getc,integer,is,length,% - listing,load,name,nl,nonvar,not,numbervars,op,or,pp,prin,print,% - private,prompt,putc,ratom,read,read_from_this_file,rename,repeat,% - retract,retractall,save,see,seeing,seen,sh,skip,statistics,% - subgoal_of,system,tab,tell,telling,time,told,trace,true,unload,% - untrace,var,write},% - sensitive=f,% - morecomment=[l]\%,% - morecomment=[s]{/*}{*/},% - morestring=[bd]",% - morestring=[bd]'% - }[keywords,comments,strings]% -%% -%% classic rexx listings definition -%% by Patrick TJ McPhee -%% -\lst@definelanguage{Rexx} - {morekeywords={address,arg,call,do,drop,else,end,exit,if,iterate,% - interpret,leave,nop,numeric,options,otherwise,parse,% - procedure,pull,push,queue,return,say,signal,then,to,% - trace,when},% - sensitive=false,% - morecomment=[n]{/*}{*/},% - morestring=[d]{'},% - morestring=[d]{"},% - }[keywords,comments,strings]% -\lst@definelanguage{Ruby}% - {morekeywords={__FILE__,__LINE__,BEGIN,END,alias,and,begin,break,% - case,class,def,defined?,do,else,elsif,end,ensure,false,for,% - if,in,module,next,nil,not,or,redo,rescue,retry,return,self,% - super,then,true,undef,unless,until,when,while,yield},% - sensitive=true,% - morecomment=[l]\#,% - morecomment=[l]\#\#,% - morecomment=[s]{=BEGIN}{=END},% - morestring=[b]',% - morestring=[b]",% - morestring=[b]/% - }[keywords,comments,strings]% -%% -%% SHELXL definition (c) 1999 Aidan Philip Heerdegen -%% -\lst@definelanguage{SHELXL}% - {morekeywords={TITL,CELL,ZERR,LATT,SYMM,SFAC,DISP,UNIT,LAUE,% - REM,MORE,TIME,END,HKLF,OMIT,SHEL,BASF,TWIN,EXTI,SWAT,% - MERG,SPEC,RESI,MOVE,ANIS,AFIX,HFIX,FRAG,FEND,EXYZ,EADP,% - EQIV,OMIT,CONN,PART,BIND,FREE,DFIX,BUMP,SAME,SADI,CHIV,% - FLAT,DELU,SIMU,DEFS,ISOR,SUMP,L.S.,CGLS,SLIM,BLOC,DAMP,% - WGHT,FVAR,BOND,CONF,MPLA,RTAB,LIST,ACTA,SIZE,TEMP,WPDB,% - FMAP,GRID,PLAN,MOLE},% - sensitive=false,% - alsoother=_,% Makes the syntax highlighting ignore the underscores - morecomment=[l]{! },% - }% -%% -%% Tcl/Tk definition (c) Gerd Neugebauer -%% -\lst@definelanguage[tk]{tcl}[]{tcl}% - {morekeywords={activate,add,separator,radiobutton,checkbutton,% - command,cascade,all,bell,bind,bindtags,button,canvas,canvasx,% - canvasy,cascade,cget,checkbutton,config,configu,configur,% - configure,clipboard,create,arc,bitmap,image,line,oval,polygon,% - rectangle,text,textwindow,curselection,delete,destroy,end,entry,% - entrycget,event,focus,font,actual,families,measure,metrics,names,% - frame,get,grab,current,release,status,grid,columnconfigure,% - rowconfigure,image,image,create,bitmap,photo,delete,height,types,% - widt,names,index,insert,invoke,itemconfigure,label,listbox,lower,% - menu,menubutton,message,move,option,add,clear,get,readfile,pack,% - photo,place,radiobutton,raise,scale,scroll,scrollbar,search,see,% - selection,send,stdin,stdout,stderr,tag,bind,text,tk,tkerror,% - tkwait,window,variable,visibility,toplevel,unknown,update,winfo,% - class,exists,ismapped,parent,reqwidth,reqheight,rootx,rooty,% - width,height,wm,aspect,client,command,deiconify,focusmodel,frame,% - geometry,group,iconbitmap,iconify,iconmask,iconname,iconposition,% - iconwindow,maxsize,minsize,overrideredirect,positionfrom,% - protocol,sizefrom,state,title,transient,withdraw,xview,yview,% - yposition,% - -accelerator,-activebackground,-activeborderwidth,% - -activeforeground,-after,-anchor,-arrow,-arrowshape,-aspect,% - -async,-background,-before,-bg,-bigincrement,-bitmap,-bordermode,% - -borderwidth,-button,-capstyle,-channel,-class,-closeenough,% - -colormap,-column,-columnspan,-command,-confine,-container,% - -count,-cursor,-data,-default,-detail,-digits,-direction,% - -displayof,-disableforeground,-elementborderwidth,-expand,% - -exportselection,-extend,-family,-fg,-file,-fill,-focus,-font,% - -fontmap,-foreground,-format,-from,-gamma,-global,-height,% - -highlightbackground,-highlightcolor,-highlightthickness,-icon,% - -image,-in,-insertbackground,-insertborderwidth,-insertofftime,% - -insertontime,-imsertwidth,-ipadx,-ipady,-joinstyle,-jump,% - -justify,-keycode,-keysym,-label,-lastfor,-length,-maskdata,% - -maskfile,-menu,-message,-mode,-offvalue,-onvalue,-orient,% - -outlien,-outlinestipple,-overstrike,-override,-padx,-pady,% - -pageanchor,-pageheight,-pagewidth,-pagey,-pagey,-palette,% - -parent,-place,-postcommand,-relheight,-relief,-relwidth,-relx,% - -rely,-repeatdelay,-repeatinterval,-resolution,-root,-rootx,% - -rooty,-rotate,-row,-rowspan,-screen,-selectcolor,-selectimage,% - -sendevent,-serial,-setgrid,-showvalue,-shrink,-side,-size,% - -slant,-sliderlength,-sliderrelief,-smooth,-splinesteps,-state,% - -sticky,-stipple,-style,-subsample,-subwindow,-tags,-takefocus,% - -tearoff,-tearoffcommand,-text,-textvariable,-tickinterval,-time,% - -title,-to,-troughcolor,-type,-underline,-use,-value,-variable,% - -visual,-width,-wrap,-wraplength,-x,-xscrollcommand,-y,% - -bgstipple,-fgstipple,-lmargin1,-lmargin2,-rmargin,-spacing1,% - -spacing2,-spacing3,-tabs,-yscrollcommand,-zoom,% - activate,add,addtag,bbox,cget,clone,configure,coords,% - curselection,debug,delete,delta,deselect,dlineinfo,dtag,dump,% - entrycget,entryconfigure,find,flash,fraction,get,gettags,handle,% - icursor,identify,index,insert,invoke,itemcget,itemconfigure,mark,% - moveto,own,post,postcascade,postscript,put,redither,ranges,% - scale,select,show,tag,type,unpost,xscrollcommand,xview,% - yscrollcommand,yview,yposition}% - }% -\lst@definelanguage[]{tcl}% - {alsoletter={.:,*=&-},% - morekeywords={after,append,array,names,exists,anymore,donesearch,% - get,nextelement,set,size,startsearch,auto_mkindex,binary,break,% - case,catch,cd,clock,close,concat,console,continue,default,else,% - elseif,eof,error,eval,exec,-keepnewline,exit,expr,fblocked,% - fconfigure,fcopy,file,atime,dirname,executable,exists,extension,% - isdirectory,isfile,join,lstat,mtime,owned,readable,readlink,% - rootname,size,stat,tail,type,writable,-permissions,-group,-owner,% - -archive,-hidden,-readonly,-system,-creator,-type,-force,% - fileevent,flush,for,foreach,format,gets,glob,global,history,if,% - incr,info,argsbody,cmdcount,commands,complete,default,exists,% - globals,level,library,locals,patchlevel,procs,script,tclversion,% - vars,interp,join,lappend,lindex,linsert,list,llength,lrange,% - lreplace,lsearch,-exact,-regexp,-glob,lsort,-ascii,-integer,% - -real,-dictionary,-increasing,-decreasing,-index,-command,load,% - namespace,open,package,forget,ifneeded,provide,require,unknown,% - vcompare,versions,vsatisfies,pid,proc,puts,-nonewline,pwd,read,% - regexp,-indices,regsub,-all,-nocaserename,return,scan,seek,set,% - socket,source,split,string,compare,first,index,last,length,match,% - range,tolower,toupper,trim,trimleft,trimright,subst,switch,tell,% - time,trace,variable,vdelete,vinfo,unknown,unset,uplevel,upvar,% - vwait,while,acos,asin,atan,atan2,ceil,cos,cosh,exp,floor,fmod,% - hypot,log,log10,pow,sin,sinh,sqrt,tan,tanh,abs,double,int,round% - },% - morestring=[d]",% - MoreSelectCharTable=% - \lst@CArgX\#\relax\lst@DefDelimB{}{}% - {\ifx\lst@lastother\lstum@backslash - \expandafter\@gobblethree - \fi}% - \lst@BeginComment\lst@commentmode - {{\lst@commentstyle}\lst@Lmodetrue}% - }[keywords,comments,strings]% -%% -%% VBScript definition (c) 2000 Sonja Weidmann -%% -\lst@definelanguage{VBScript}% - {morekeywords={Call,Case,Const,Dim,Do,Each,Else,End,Erase,Error,Exit,% - Explicit,For,Function,If,Loop,Next,On,Option,Private,Public,% - Randomize,ReDim,Rem,Select,Set,Sub,Then,Wend,While,Abs,Array,Asc,% - Atn,CBool,CByte,CCur,CDate,CDbl,Chr,CInt,CLng,Cos,CreateObject,% - CSng,CStr,Date,DateAdd,DateDiff,DatePart,DateSerial,DateValue,% - Day,Exp,Filter,Fix,FormatCurrency,FormatDateTime,FormatNumber,% - FormatPercent,GetObject,Hex,Hour,InputBox,InStr,InStrRev,Int,% - IsArray,IsDate,IsEmpty,IsNull,IsNumeric,IsObject,Join,LBound,% - LCase,Left,Len,LoadPicture,Log,LTrim,Mid,Minute,Month,MonthName,% - MsgBox,Now,Oct,Replace,RGB,Right,Rnd,Round,RTrim,ScriptEngine,% - ScriptEngineBuildVersion,ScriptEngineMajorVersion,% - ScriptEngineMinorVersion,Second,Sgn,Sin,Space,Split,Sqr,StrComp,% - StrReverse,String,Tan,Time,TimeSerial,TimeValue,Trim,TypeName,% - UBound,UCase,VarType,Weekday,WeekdayName,Year, And,Eqv,Imp,Is,% - Mod,Not,Or,Xor,Add,BuildPath,Clear,Close,Copy,CopyFile,% - CopyFolder,CreateFolder,CreateTextFile,Delete,DeleteFile,% - DeleteFolder,Dictionary,Drive,DriveExists,Drives,Err,Exists,File,% - FileExists,FileSystemObject,Files,Folder,FolderExists,Folders,% - GetAbsolutePathName,GetBaseName,GetDrive,GetDriveName,% - GetExtensionName,GetFile,GetFileName,GetFolder,% - GetParentFolderName,GetSpecialFolder,GetTempName,Items,Keys,Move,% - MoveFile,MoveFolder,OpenAsTextStream,OpenTextFile,Raise,Read,% - ReadAll,ReadLine,Remove,RemoveAll,Skip,SkipLine,TextStream,Write,% - WriteBlankLines,WriteLine,Alias,Archive,CDROM,Compressed,% - Directory,Fixed,ForAppending,ForReading,ForWriting,Hidden,Normal,% - RAMDisk,ReadOnly,Remote,Removable,System,SystemFolder,% - TemporaryFolder,TristateFalse,TristateTrue,TristateUseDefault,% - Unknown,Volume,WindowsFolder,vbAbortRetryIgnore,% - vbApplicationModal,vbArray,vbBinaryCompare,vbBlack,vbBlue,% - vbBoolean,vbByte,vbCr,vbCrLf,vbCritical,vbCurrency,vbCyan,% - vbDataObject,vbDate,vbDecimal,vbDefaultButton1,vbDefaultButton2,% - vbDefaultButton3,vbDefaultButton4,vbDouble,vbEmpty,vbError,% - vbExclamation,vbFirstFourDays,vbFirstFullWeek,vbFirstJan1,% - vbFormFeed,vbFriday,vbGeneralDate,vbGreen,vbInformation,% - vbInteger,vbLf,vbLong,vbLongDate,vbLongTime,vbMagenta,vbMonday,% - vbNewLine,vbNull,vbNullChar,vbNullString,vbOKC,ancel,vbOKOnly,% - vbObject,vbObjectError,vbQuestion,vbRed,vbRetryCancel,vbSaturday,% - vbShortDate,vbShortTime,vbSingle,vbString,vbSunday,vbSystemModal,% - vbTab,vbTextCompare,vbThursday,vbTuesday,vbUseSystem,% - vbUseSystemDayOfWeek,vbVariant,vbVerticalTab,vbWednesday,vbWhite,% - vbYellow,vbYesNo,vbYesNoCancel},% - sensitive=f,% - morecomment=[l]',% - morestring=[d]"% - }[keywords,comments,strings]% -%% -%% VRML definition (c) 2001 Oliver Baum -%% -\lst@definelanguage[97]{VRML} - {morekeywords={DEF,EXTERNPROTO,FALSE,IS,NULL,PROTO,ROUTE,TO,TRUE,USE,% - eventIn,eventOut,exposedField,field,Introduction,Anchor,% - Appearance,AudioClip,Background,Billboard,Box,Collision,Color,% - ColorInterpolator,Cone,Coordinate,CoordinateInterpolator,% - Cylinder,CylinderSensor,DirectionalLight,ElevationGrid,Extrusion,% - Fog,FontStyle,Group,ImageTexture,IndexedFaceSet,IndexedLineSet,% - Inline,LOD,Material,MovieTexture,NavigationInfo,Normal,% - NormalInterpolator,OrientationInterpolator,PixelTexture,% - PlaneSensor,PointLight,PointSet,PositionInterpolator,% - ProximitySensor,ScalarInterpolator,Script,Shape,Sound,Sphere,% - SphereSensor,SpotLight,Switch,Text,TextureCoordinate,% - TextureTransform,TimeSensor,TouchSensor,Transform,Viewpoint,% - VisibilitySensor,WorldInfo},% - morecomment=[l]\#,% bug: starts comment in the first column - morestring=[b]"% - }[keywords,comments,strings] -\endinput -%% -%% End of file `lstlang2.sty'. diff --git a/org.glite.lb.doc/src/lstlang3.sty b/org.glite.lb.doc/src/lstlang3.sty deleted file mode 100644 index b43bc9e..0000000 --- a/org.glite.lb.doc/src/lstlang3.sty +++ /dev/null @@ -1,1006 +0,0 @@ -%% -%% This is file `lstlang3.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% lstdrvrs-1.3.dtx (with options: `lang3') -%% -%% (w)(c) 1996/1997/1998/1999/2000/2001/2002/2003/2004 Carsten Heinz -%% and/or any other author listed elsewhere in this file. -%% -%% This file is distributed under the terms of the LaTeX Project Public -%% License from CTAN archives in directory macros/latex/base/lppl.txt. -%% Either version 1.0 or, at your option, any later version. -%% -%% This file is completely free and comes without any warranty. -%% -%% Send comments and ideas on the package, error reports and additional -%% programming languages to . -%% -\ProvidesFile{lstlang3.sty} - [2004/09/05 1.3 listings language file] -\lst@definelanguage[68]{Algol}% - {morekeywords={abs,and,arg,begin,bin,bits,bool,by,bytes,case,channel,% - char,co,comment,compl,conj,divab,do,down,elem,elif,else,empty,% - end,entier,eq,esac,exit,false,fi,file,flex,for,format,from,ge,% - goto,gt,heap,if,im,in,int,is,isnt,le,leng,level,loc,long,lt,lwb,% - minusab,mod,modab,mode,ne,nil,not,od,odd,of,op,or,ouse,out,over,% - overab,par,plusab,plusto,pr,pragmat,prio,proc,re,real,ref,repr,% - round,sema,shl,short,shorten,shr,sign,skip,string,struct,then,% - timesab,to,true,union,up,upb,void,while},% - sensitive=f,% ??? - morecomment=[s]{\#}{\#},% - keywordcomment={co,comment}% - }[keywords,comments,keywordcomments]% -\lst@definelanguage[60]{Algol}% - {morekeywords={array,begin,Boolean,code,comment,div,do,else,end,% - false,for,goto,if,integer,label,own,power,procedure,real,step,% - string,switch,then,true,until,value,while},% - sensitive=f,% ??? - keywordcommentsemicolon={end}{else,end}{comment}% - }[keywords,keywordcomments]% -%% -%% x86masm definition (c) 2002 Andrew Zabolotny -%% -\lst@definelanguage[x86masm]{Assembler}% - {morekeywords={al,ah,ax,eax,bl,bh,bx,ebx,cl,ch,cx,ecx,dl,dh,dx,edx,% - si,esi,di,edi,bp,ebp,sp,esp,cs,ds,es,ss,fs,gs,cr0,cr1,cr2,cr3,% - db0,db1,db2,db3,db4,db5,db6,db7,tr0,tr1,tr2,tr3,tr4,tr5,tr6,tr7,% - st,aaa,aad,aam,aas,adc,add,and,arpl,bound,bsf,bsr,bswap,bt,btc,% - btr,bts,call,cbw,cdq,clc,cld,cli,clts,cmc,cmp,cmps,cmpsb,cmpsw,% - cmpsd,cmpxchg,cwd,cwde,daa,das,dec,div,enter,hlt,idiv,imul,in,% - inc,ins,int,into,invd,invlpg,iret,ja,jae,jb,jbe,jc,jcxz,jecxz,% - je,jg,jge,jl,jle,jna,jnae,jnb,jnbe,jnc,jne,jng,jnge,jnl,jnle,% - jno,jnp,jns,jnz,jo,jp,jpe,jpo,js,jz,jmp,lahf,lar,lea,leave,lgdt,% - lidt,lldt,lmsw,lock,lods,lodsb,lodsw,lodsd,loop,loopz,loopnz,% - loope,loopne,lds,les,lfs,lgs,lss,lsl,ltr,mov,movs,movsb,movsw,% - movsd,movsx,movzx,mul,neg,nop,not,or,out,outs,pop,popa,popad,% - popf,popfd,push,pusha,pushad,pushf,pushfd,rcl,rcr,rep,repe,% - repne,repz,repnz,ret,retf,rol,ror,sahf,sal,sar,sbb,scas,seta,% - setae,setb,setbe,setc,sete,setg,setge,setl,setle,setna,setnae,% - setnb,setnbe,setnc,setne,setng,setnge,setnl,setnle,setno,setnp,% - setns,setnz,seto,setp,setpe,setpo,sets,setz,sgdt,shl,shld,shr,% - shrd,sidt,sldt,smsw,stc,std,sti,stos,stosb,stosw,stosd,str,sub,% - test,verr,verw,wait,wbinvd,xadd,xchg,xlatb,xor,fabs,fadd,fbld,% - fbstp,fchs,fclex,fcom,fcos,fdecstp,fdiv,fdivr,ffree,fiadd,ficom,% - fidiv,fidivr,fild,fimul,fincstp,finit,fist,fisub,fisubr,fld,fld1,% - fldl2e,fldl2t,fldlg2,fldln2,fldpi,fldz,fldcw,fldenv,fmul,fnop,% - fpatan,fprem,fprem1,fptan,frndint,frstor,fsave,fscale,fsetpm,% - fsin,fsincos,fsqrt,fst,fstcw,fstenv,fstsw,fsub,fsubr,ftst,fucom,% - fwait,fxam,fxch,fxtract,fyl2x,fyl2xp1,f2xm1},% - morekeywords=[2]{.align,.alpha,assume,byte,code,comm,comment,.const,% - .cref,.data,.data?,db,dd,df,dosseg,dq,dt,dw,dword,else,end,endif,% - endm,endp,ends,eq,equ,.err,.err1,.err2,.errb,.errdef,.errdif,% - .erre,.erridn,.errnb,.errndef,.errnz,event,exitm,extrn,far,% - .fardata,.fardata?,fword,ge,group,gt,high,if,if1,if2,ifb,ifdef,% - ifdif,ife,ifidn,ifnb,ifndef,include,includelib,irp,irpc,label,% - .lall,le,length,.lfcond,.list,local,low,lt,macro,mask,mod,.model,% - name,ne,near,offset,org,out,page,proc,ptr,public,purge,qword,.% - radix,record,rept,.sall,seg,segment,.seq,.sfcond,short,size,% - .stack,struc,subttl,tbyte,.tfcond,this,title,type,.type,width,% - word,.xall,.xcref,.xlist},% - alsoletter=.,alsodigit=?,% - sensitive=f,% - morestring=[b]",% - morestring=[b]',% - morecomment=[l];% - }[keywords,comments,strings] -%% -%% Clean definition (c) 1999 Jos\'e Romildo Malaquias -%% -%% Clean 1.3 : some standard functional language: pure, lazy, -%% polymorphic type system, modules, type classes, -%% garbage collection, functions as first class citizens -%% -\lst@definelanguage{Clean}% - {otherkeywords={:,::,=,:==,=:,=>,->,<-,<-:,\{,\},\{|,|\},\#,\#!,|,\&,% - [,],!,.,\\\\,;,_},% - morekeywords={from,definition,implementation,import,module,system,% - case,code,if,in,let,let!,of,where,with,infix,infixl,infixr},% - morendkeywords={True,False,Start,Int,Real,Char,Bool,String,World,% - File,ProcId},% - sensitive,% - morecomment=[l]//,% missing comma: Markus Pahlow - morecomment=[n]{/*}{*/},% - morestring=[b]"% - }[keywords,comments,strings]% -\lst@definelanguage{Comal 80}% - {morekeywords={AND,AUTO,CASE,DATA,DEL,DIM,DIV,DO,ELSE,ENDCASE,ENDIF,% - ENDPROC,ENDWHILE,EOD,EXEC,FALSE,FOR,GOTO,IF,INPUT,INT,LIST,LOAD,% - MOD,NEW,NEXT,NOT,OF,OR,PRINT,PROC,RANDOM,RENUM,REPEAT,RND,RUN,% - SAVE,SELECT,STOP,TAB,THEN,TRUE,UNTIL,WHILE,ZONE},% - sensitive=f,% ??? - morecomment=[l]//,% - morestring=[d]"% - }[keywords,comments,strings]% -\lst@definelanguage{Elan}% - {morekeywords={ABS,AND,BOOL,CAND,CASE,CAT,COLUMNS,CONCR,CONJ,CONST,% - COR,DECR,DEFINES,DET,DIV,DOWNTO,ELIF,ELSE,END,ENDIF,ENDOP,% - ENDPACKET,ENDPROC,ENDREP,ENDSELECT,FALSE,FI,FILE,FOR,FROM,IF,% - INCR,INT,INV,LEAVE,LENGTH,LET,MOD,NOT,OF,OP,OR,OTHERWISE,PACKET,% - PROC,REAL,REP,REPEAT,ROW,ROWS,SELECT,SIGN,STRUCT,SUB,TEXT,THEN,% - TRANSP,TRUE,TYPE,UNTIL,UPTO,VAR,WHILE,WITH,XOR,% - maxint,sign,abs,min,max,random,initializerandom,subtext,code,% - replace,text,laenge,pos,compress,change,maxreal,smallreal,floor,% - pi,e,ln,log2,log10,sqrt,exp,tan,tand,sin,sind,cos,cosd,arctan,% - arctand,int,real,lastconversionok,put,putline,line,page,get,% - getline,input,output,sequentialfile,maxlinelaenge,reset,eof,% - close,complexzero,complexone,complexi,complex,realpart,imagpart,% - dphi,phi,vector,norm,replace,matrix,idn,row,column,sub,% - replacerow,replacecolumn,replaceelement,transp,errorsstop,stop},% - sensitive,% - morestring=[d]"% - }[keywords,strings]% -%% -%% Erlang definition (c) 2003 Daniel Gazard -%% -\lst@definelanguage{erlang}% - {morekeywords={abs,after,and,apply,atom,atom_to_list,band,binary,% - binary_to_list,binary_to_term,bor,bsl,bsr,bxor,case,catch,% - date,div,element,erase,end,exit,export,float,float_to_list,% - get,halt,hash,hd,if,info,import,integer,integer_to_list,% - length,link,list,list_to_atom,list_to_float,list_to_integer,% - list_to_tuple,module,node,nodes,now,of,or,pid,port,ports,% - processes,put,receive,reference,register,registered,rem,% - round,self,setelement,size,spawn,throw,time,tl,trace,trunc,% - tuple,tuple_to_list,unlink,unregister,whereis,error,false,% - infinity,nil,ok,true,undefined,when},% - otherkeywords={->,!,[,],\{,\},},% - morecomment=[l]\%,% - morestring=[b]",% - morestring=[b]'% - }[keywords,comments,strings]% -\lst@definelanguage{ksh} - {morekeywords={alias,awk,cat,echo,else,elif,fi,exec,exit,% - for,in,do,done,select,case,esac,while,until,function,% - time,export,cd,eval,fc,fg,kill,let,pwd,read,return,rm,% - glob,goto,history,if,logout,nice,nohup,onintr,repeat,sed,% - set,setenv,shift,source,switch,then,umask,unalias,% - unset,wait,@,env,argv,child,home,ignoreeof,noclobber,% - noglob,nomatch,path,prompt,shell,status,verbose,print,printf,% - sqrt,BEGIN,END},% - morecomment=[l]\#,% - morestring=[d]",% - morestring=[d]',% - morestring=[d]`% - }[keywords,comments,strings]% -\lst@definelanguage{Logo}% - {morekeywords={and,atan,arctan,both,break,bf,bl,butfirst,butlast,% - cbreak, close,co,continue,cos,count,clearscreen,cs,debquit,% - describe,diff,difference,ed,edit,either,emptyp,equalp,er,erase,% - errpause,errquit,fifp,filefprint,fifty,fileftype,fip,fileprint,% - fird,fileread,fity,filetype,fiwd,fileword,f,first,or,fp,fprint,% - fput,fty,ftype,full,fullscreen,go,bye,goodbye,gprop,greaterp,% - help,if,iff,iffalse,ift,iftrue,nth,item,keyp,llast,lessp,list,% - local,lput,make,max,maximum,memberp,memtrace,min,minimum,namep,% - not,numberp,oflush,openr,openread,openw,openwrite,op,output,% - pause,plist,pots,pow,pprop,pps,pr,print,product,quotient,random,% - rc,readchar,rl,readlist,remprop,repcount,repeat,request,rnd,run,% - se,sentence,sentencep,setc,setcolor,setipause,setqpause,po,show,% - sin,split,splitscreen,sqrt,stop,sum,test,text,textscreen,thing,% - to,tone,top,toplevel,type,untrace,wait,word,wordp,yaccdebug,is,% - mod,remainder,trace,zerop,back,bk,bto,btouch,fd,forward,fto,% - ftouch,getpen,heading,hit,hitoot,ht,hideturtle,loff,lampoff,lon,% - lampon,lt,left,lot,lotoot,lto,ltouch,penc,pencolor,pd,pendown,pe,% - penerase,penmode,pu,penup,px,penreverse,rt,right,rto,rtouch,% - scrunch,seth,setheading,setscrun,setscrunch,setxy,shownp,st,% - showturtle,towardsxy,clean,wipeclean,xcor,ycor,tur,turtle,% - display,dpy},% - sensitive=f% ??? - }[keywords]% -%% -%% MetaPost definition (c) 2004 Brooks Moses -%% This definition is based on the language specifications -%% contained in the _User's Manual for Metapost_, with the core -%% language enhancements that are described in the _Drawing -%% Graphs with MetaPost_ documentation. -%% -\lst@definelanguage{MetaPost}% - {% keywords[1] = MetaPost primitives (not found in following tables) - morekeywords={end,begingroup,endgroup,beginfig,endfig,def,vardef,% - primary,secondary,tertiary,primarydef,secondarydef,tertiarydef,% - expr,suffix,text,enddef,if,fi,else,elseif,for,forsuffixes,% - forever,endfor,upto,downto,stop,until,tension,controls,on,off,% - btex,etex,within,input}, - % keywords[2] = Operators (Tables 6-9 in MetaPost User's manual) - morekeywords=[2]{abs,and,angle,arclength,arctime,ASCII,bbox,bluepart,% - boolean,bot,ceiling,center,char,color,cosd,cutafter,cutbefore,% - cycle,decimal,dir,direction,directionpoint,directiontime,div,% - dotprod,floor,fontsize,greenpart,hex,infont,intersectionpoint,% - intersectiontimes,inverse,known,length,lft,llcorner,lrcorner,% - makepath,makepen,mexp,mlog,mod,normaldeviate,not,numeric,oct,% - odd,or,pair,path,pen,penoffset,picture,point,postcontrol,% - precontrol,redpart,reverse,rotated,round,rt,scaled,shifted,% - sind,slanted,sqrt,str,string,subpath,substring,top,transform,% - transformed,ulcorner,uniformdeviate,unitvector,unknown,% - urcorner,whatever,xpart,xscaled,xxpart,xypart,ypart,yscaled,% - yxpart,yypart,zscaled,of,reflectedabout,rotatedaround,ulft,urt,% - llft,lrt,readfrom,write,stroked,filled,textual,clipped,bounded,% - pathpart,penpart,dashpart,textpart,fontpart},% - % keywords[3] = Commands (Table 10) - morekeywords=[3]{addto,clip,cutdraw,draw,drawarrow,drawdblarrow,% - fill,filldraw,interim,let,loggingall,newinternal,pickup,% - save,setbounds,shipout,show,showdependencies,showtoken,% - showvariable,special,tracingall,tracingnone,undraw,unfill,% - unfilldraw,to,also,contour,doublepath,withcolor,withpen,% - dashed,randomseed},% - % keywords[4] = Function-Like Macros (Table 11) - morekeywords=[4]{boxit,boxjoin,bpath,buildcycle,circleit,dashpattern,% - decr,dotlabel,dotlabels,drawboxed,drawboxes,drawoptions,% - drawunboxed,fixpos,fixsize,incr,interpath,label,labels,max,min,pic,% - thelabel,z,image},% - % keywords[5] = Internal and Predefined Variables (Tables 3, 4) - morekeywords=[5]{ahangle,ahlength,bboxmargin,charcode,circmargin,% - day,defaultdx,defaultdy,defaultpen,defaultscale,labeloffset,% - linecap,linejoin,miterlimit,month,pausing,prologues,showstopping,% - time,tracingcapsules,tracingchoices,tracingcommands,% - tracingequations,tracinglostchars,tracingmacros,tracingonline,% - tracingoutput,tracingrestores,tracingspecs,tracingstats,% - tracingtitles,truecorners,warningcheck,year}, - morekeywords=[5]{background,currentpen,currentpicture,cuttings,% - defaultfont},% - % keywords[6] = Predefined Constants (Table 5) - morekeywords=[6]{beveled,black,blue,bp,butt,cc,cm,dd,ditto,down,% - epsilon,evenly,false,fullcircle,green,halfcircle,identity,% - in,infinity,left,mitered,mm,nullpicture,origin,pc,pencircle,% - pt,quartercircle,red,right,rounded,squared,true,unitsquare,% - up,white,withdots}, - sensitive=false,% - alsoother={0123456789$},% - morecomment=[l]\%,% - morestring=[mf]{input\ },% - morestring=[b]"% - }[keywords,comments,strings,mf]% -%% -%% Mizar definition (c) 2003 Adam Grabowski -%% -%% Mizar is freely available at URL www.mizar.org for the Linux x86, -%% Solaris x86, and Windows operating systems. -%% -\lst@definelanguage{Mizar}% - {otherkeywords={->,(\#,\#),.=),\&},% - morekeywords={vocabulary,constructors,$1,$1,$2,$3,$4,$5,$6,$7,$8,% - @proof,according,aggregate,and,antonym,as,associativity,assume,% - asymmetry,attr,be,begin,being,by,canceled,case,cases,cluster,% - clusters,coherence,commutativity,compatibility,connectedness,% - consider,consistency,constructors,contradiction,correctness,def,% - deffunc,define,definition,definitions,defpred,end,environ,equals,% - ex,exactly,existence,for,from,func,given,hence,hereby,holds,% - idempotence,if,iff,implies,involutiveness,irreflexivity,is,it,% - let,means,mode,non,not,notation,now,of,or,otherwise,over,per,% - pred,prefix,projectivity,proof,provided,qua,reconsider,redefine,% - reflexivity,requirements,reserve,scheme,schemes,section,selector,% - set,st,struct,such,suppose,symmetry,synonym,take,that,the,then,% - theorem,theorems,thesis,thus,to,transitivity,uniqueness,% - vocabulary,where},% - sensitive=t,% - morecomment=[l]::% - }[keywords,comments]% -\lst@definelanguage{Modula-2}% - {morekeywords={AND,ARRAY,BEGIN,BY,CASE,CONST,DIV,DO,ELSE,ELSIF,END,% - EXIT,EXPORT,FOR,FROM,IF,IMPLEMENTATION,IMPORT,IN,MOD,MODULE,NOT,% - OF,OR,POINTER,PROCEDURE,QUALIFIED,RECORD,REPEAT,RETURN,SET,THEN,% - TYPE,UNTIL,VAR,WHILE,WITH,ABS,BITSET,BOOLEAN,CAP,CARDINAL,CHAR,% - CHR,DEC,EXCL,FALSE,FLOAT,HALT,HIGH,INC,INCL,INTEGER,LONGCARD,% - LONGINT,LONGREAL,MAX,MIN,NIL,ODD,ORD,PROC,REAL,SIZE,TRUE,TRUNC,% - VAL,DEFINITION,LOOP},% added keywords due to Peter Bartke 99/07/22 - sensitive,% - morecomment=[n]{(*}{*)},% - morestring=[d]',% - morestring=[d]"% - }[keywords,comments,strings]% -\lst@definelanguage{MuPAD}{% - morekeywords={end,next,break,if,then,elif,else,end_if,case,end_case,% - otherwise,for,from,to,step,downto,in,end_for,while,end_while,% - repeat,until,end_repeat,or,and,not,xor,div,mod,union,minus,% - intersect,subset,proc,begin,end_proc,domain,end_domain,category,% - end_category,axiom,end_axiom,quit,delete,frame},% - morekeywords=[2]{NIL,FAIL,TRUE,FALSE,UNKNOWN,I,RD_INF,RD_NINF,% - RD_NAN,name,local,option,save,inherits,of,do},% - otherkeywords={\%if,?,!,:=,<,>,=,<=,<>,>=,==>,<=>,::,..,...,->,% - @,@@,\$},% - sensitive=true,% - morecomment=[l]{//},% - morecomment=[n]{/*}{*/},% - morestring=[b]",% - morestring=[d]{`}% - }[keywords,comments,strings] -\lst@definelanguage{NASTRAN} - {morekeywords={ENDDATA},% - morecomment=[l]$,% - MoreSelectCharTable=% - \lst@CArgX BEGIN\ BULK\relax\lst@CDef{}% - {\lst@ifmode\else \ifnum\lst@length=\z@ - \lst@EnterMode{\lst@GPmode}{\lst@modetrue - \let\lst@currstyle\lst@gkeywords@sty}% - \fi \fi}% - {\ifnum\lst@mode=\lst@GPmode - \lst@XPrintToken \lst@LeaveMode - \fi}% - }[keywords,comments]% -\lst@definelanguage{Oberon-2}% - {morekeywords={ARRAY,BEGIN,BOOLEAN,BY,CASE,CHAR,CONST,DIV,DO,ELSE,% - ELSIF,END,EXIT,FALSE,FOR,IF,IMPORT,IN,INTEGER,IS,LONGINT,% - LONGREAL,LOOP,MOD,MODULE,NIL,OF,OR,POINTER,PROCEDURE,REAL,RECORD,% - REPEAT,RETURN,SET,SHORTINT,THEN,TO,TRUE,TYPE,UNTIL,VAR,WHILE,% - WITH,ABS,ASH,CAP,CHR,COPY,DEC,ENTIER,EXCL,HALT,INC,INCL,LEN,LONG,% - MAX,MIN,NEW,ODD,ORD,SHORT,SIZE},% - sensitive,% - morecomment=[n]{(*}{*)},% - morestring=[d]',% - morestring=[d]"% - }[keywords,comments,strings]% -%% -%% OCL definition (c) 2000 Achim D. Brucker -%% -%% You are allowed to use, modify and distribute this code either under -%% the terms of the LPPL (version 1.0 or later) or the GPL (version 2.0 -%% or later). -%% -\lst@definelanguage[decorative]{OCL}[OMG]{OCL} - {otherkeywords={@pre},% - morendkeywords={name,attributes,associatoinEnds,operations,% - supertypes,allSupertypes,allInstances,oclIsKindOf,oclIsTypeOf,% - oclAsType,oclInState,oclIsNew,evaluationType,abs,floor,round,max,% - min,div,mod,size,concat,toUpper,toLower,substring,includes,% - excludes,count,includesAll,exludesAll,isEmpty,notEmpty,sum,% - exists,forAll,isUnique,sortedBy,iterate,union,intersection,% - including,excluding,symmetricDifference,select,reject,collect,% - asSequence,asBag,asSequence,asSet,append,prepend,subSequence,at,% - first,last,true,false,isQuery}% - }% -\lst@definelanguage[OMG]{OCL}% - {morekeywords={context,pre,inv,post},% - ndkeywords={or,xor,and,not,implies,if,then,else,endif},% - morekeywords=[3]{Boolean,Integer,Real,String,Set,Sequence,Bag,% - OclType,OclAny,OclExpression,Enumeration,Collection,},% - sensitive=t,% - morecomment=[l]--,% - morestring=[d]'% - }[keywords,comments,strings]% -\lst@definelanguage{Plasm}% - {sensitive=false,% - morekeywords={aa,abs,ac,acolor,acos,actor,al,alias,align,and,% - animation,animation,appearance,apply,ar,arc,as,asin,assoc,atan,% - axialcamera,axialcameras,basehermite,bbox,bbox,bernstein,% - bernsteinbasis,bezier,beziercurve,beziermanifold,bezierstripe,% - beziersurface,bigger,biggest,bilinearsurface,binormal,% - biquadraticsurface,black,blend,blue,bottom,box,brown,bspize,% - bspline,bsplinebasis,c,cabinet,camera,cart,case,cat,catch,ceil,% - centeredcameras,centralcavalier,char,charseq,choose,circle,% - circumference,class,cmap,color,comp,computecoords,cone,% - conicalsurface,cons,control,convexcoords,convexhull,coonspatch,% - copy,cos,cosh,crease,crosspolytope,cube,cubiccardinal,% - cubiccardinalbasis,cubichermite,cubicubspline,cubicubsplinebasis,% - cuboid,curl,curvature,curve2cspath,curve2mapvect,cyan,cylinder,% - cylindricalsurface,d,deboor,def,depol,depth_sort,depth_test,% - derbernstein,derbernsteinbase,derbezier,determinant,difference,% - differencepr,dim,dimetric,dirproject,displaygraph,displaynubspline,% - displaynurbspline,distl,distr,div,divergence,dodecahedron,dot,down,% - dp,drawedges,drawforks,drawtree,ds,dsphere,dump,dumprep,ellipse,% - embed,end,eq,ex,exp,explode,export,extract_bodies,extract_polygons,% - extract_wires,extrude,extrusion,fact,false,feature,ff,fillcolor,% - filter,finitecone,first,flash,flashani,floor,fontcolor,fontheight,% - fontspacing,fontwidth,fractalsimplex,frame,frame,frameflash,fromto,% - gausscurvature,ge,grad,gradient,gradmap,gray,green,gt,help,hermite,% - hermitebasis,hermitesurface,hexahedron,icosahedron,id,idnt,if,in,% - inarcs,innerprod,inset,insl,insr,intersection,intersectionpr,% - intervals,intmax,intmin,intsto,inv,isa,isanimpol,isbool,ischar,% - isclosedshape,iscloseto,isempty,iseven,isfun,isfunvect,isge,isgt,% - isint,isintneg,isinto,isintpos,isle,islt,ismat,ismatof,isnat,% - isnull,isnum,isnumneg,isnumpos,isodd,isometric,isorthoshape,ispair,% - ispoint,ispointseq,ispol,ispoldim,ispolytope,ispurepol,isreal,% - isrealneg,isrealpos,isrealvect,isseq,isseqof,isshape,issimplex,% - issqrmat,isstring,isvect,iszero,jacobian,join,joints,k,last,le,% - left,leftcavalier,len,less,lesseq,lex,lift,light,linecolor,% - linesize,list,ln,load,loadlib,loop,lt,lxmy,magenta,map,mapshapes,% - markersize,mat,matdotprod,material,mathom,max,mean,meanpoint,med,% - merge,mesh,min,minkowski,mirror,mixedprod,mk,mkframe,mkpol,% - mkvector,mkversork,mod,model,move,mul,multextrude,mxby,mxmy,mxty,% - myfont,n,nat2string,neq,ngon,norm2,normalmap,not,nu_grid,nubspline,% - nubsplineknots,nurbspline,nurbsplineknots,octahedron,offset,% - onepoint,open,optimize,or,orange,ord,ortho,orthoproject,orthox,% - orthoy,orthoz,outarcs,outerloop,outerwarp,pairdiff,parallel,% - pascaltriangle,pdiff,pdifference,permutahedron,permutations,% - perspective,perspective,pi,pivotop,plane,planemapping,pmap,% - points2shape,polar,polyline,polymarker,polypoint,power,powerset,% - presort,principalnormal,print,prism,profileprodsurface,% - progressivesum,project,projection,purple,pyramid,q,quadarray,% - quadmesh,quote,r,raise,range,rationalbezier,rationalblend,% - rationalbspline,rationalize,red,rev,reverse,rgbacolor,right,% - rightcavalier,ring,rn,rotatedtext,rotationalsurface,rotn,rtail,% - ruledsurface,rxmy,s,save,scalarmatprod,scalarvectprod,schlegel2d,% - schlegel3d,sdifference,sdifferencepr,segment,sel,setand,setdiff,% - setfontcolor,setor,setxor,sex,shape_0,shape_1,shape2points,% - shape2pol,shapeclosed,shapecomb,shapediff,shapedist,% - shapeinbetweening,shapeinf,shapejoin,shapelen,shapenorm,% - shapenormal,shapeprod,shaperot,shapesum,shapesup,shapezero,shift,% - showprop,sign,signal,simplex,simplexpile,sin,sinh,size,skeleton,% - skew,smaller,smallest,solidifier,solidify,sort,sphere,spline,% - splinesampling,splitcells,splitpols,sqr,sqrt,star,string,% - stringtokens,struct,sub,svg,sweep,t,tail,tan,tangent,tanh,% - tensorprodsurface,tetrahedron,text,texture,textwithattributes,% - thinsolid,threepoints,time,tmax,tmin,top,torus,torusmap,trace,% - trans,tree,trianglefan,trianglestripe,trimetric,true,truncone,tt,% - tube,twopoints,uk,ukpol,ukpolf,union,unionpr,unitvect,unprune,up,% - vect2dtoangle,vect2mat,vectdiff,vectnorm,vectprod,vectsum,view,% - viewmodel,viewmodel,vrml,warp,warp,where,white,with,xcavalier,xor,% - xquadarray,xx,ycavalier,yellow},% - moredirectives={loadlib},% - otherkeywords={-,+,*,**,/,~,|,..,^,\&,\&\&,\#,\#\#},% - morecomment=[s]{\%}{\%},% - morestring=[b]',% - literate={~}{{$\sim$}}{1} {^}{$\wedge$}{1},% - }[keywords,directives,comments,strings]% -\lst@definelanguage{PL/I}% - {morekeywords={ABS,ATAN,AUTOMATIC,AUTO,ATAND,BEGIN,BINARY,BIN,BIT,% - BUILTIN,BY,CALL,CHARACTER,CHAR,CHECK,COLUMN,COL,COMPLEX,CPLX,% - COPY,COS,COSD,COSH,DATA,DATE,DECIMAL,DEC,DECLARE,DCL,DO,EDIT,% - ELSE,END,ENDFILE,ENDPAGE,ENTRY,EXP,EXTERNAL,EXT,FINISH,FIXED,% - FIXEDOVERFLOW,FOFL,FLOAT,FORMAT,GET,GO,GOTO,IF,IMAG,INDEX,% - INITIAL,INIT,INTERNAL,INT,LABEL,LENGTH,LIKE,LINE,LIST,LOG,LOG2,% - LOG10,MAIN,MAX,MIN,MOD,NOCHECK,NOFIXEDOVERFLOW,NOFOFL,NOOVERFLOW,% - NOOFL,NOSIZE,NOUNDERFLOW,NOUFL,NOZERODIVIDE,NOZDIV,ON,OPTIONS,% - OVERFLOW,OFL,PAGE,PICTURE,PROCEDURE,PROC,PUT,READ,REPEAT,RETURN,% - RETURNS,ROUND,SIN,SIND,SINH,SIZE,SKIP,SQRT,STATIC,STOP,STRING,% - SUBSTR,SUM,SYSIN,SYSPRINT,TAN,TAND,TANH,THEN,TO,UNDERFLOW,UFL,% - VARYING,WHILE,WRITE,ZERODIVIDE,ZDIV},% - sensitive=f,% - morecomment=[s]{/*}{*/},% - morestring=[d]'% - }[keywords,comments,strings]% -%% -%% Promela definition (c) 2004 William Thimbleby -%% -\lst@definelanguage{Promela} - {morekeywords={active,assert,atomic,bit,bool,break,byte,chan,d_step,% - Dproctype,do,else,empty,enabled,fi,full,goto,hidden,if,init,int,% - len,mtype,nempty,never,nfull,od,of,pcvalue,printf,priority,% - proctype,provided,run,short,skip,timeout,typedef,unless,unsigned,% - xr,xs,true,false,inline,eval},% - moredirectives={define,ifdef,ifndef,if,if,else,endif,undef,include},% - moredelim=*[directive]\#,% - morecomment=[s]{/*}{*/},% - morestring=[b]"% - }[keywords,comments,strings,directives]% -%% -%% Reduce definition (c) 2002 Geraint Paul Bevan -%% -\lst@definelanguage{Reduce}% - {morekeywords={% -%% reserved identifiers -abs,acos,acosh,acot,acoth,acsc,acsch,% -adjprec,algebraic,algint,allbranch,allfac,and,% -antisymmetric,append,arglength,array,asec,asech,% -asin,asinh,atan,atan2,atanh,begin,bfspace,bye,% -card_no,ceiling,clear,clearrules,coeff,coeffn,% -cofactor,combineexpt,combinelogs,comment,comp,% -complex,conj,cons,cont,cos,cosh,cot,coth,cramer,% -cref,csc,csch,decompose,define,defn,deg,demo,den,% -depend,det,df,difference,dilog,display,div,do,e,% -echo,ed,editdef,ei,end,eps,eq,equal,erf,errcont,% -evallhseqp,eval_mode,even,evenp,exp,expandlogs,% -expr,expt,ezgcd,factor,factorial,factorize,fexpr,% -first,fix,fixp,floor,for,forall,foreach,fort,% -fort_width,freeof,fullroots,g,gcd,geq,go,goto,% -greaterp,high_pow,hypot,i,if,ifactor,impart,in,% -index,infinity,infix,input,int,integer,interpol,% -intstr,k,korder,lambda,lcm,lcof,length,leq,lessp,% -let,lhs,linear,linelength,lisp,list,listargp,% -listargs,ln,load,load_package,log,log10,logb,% -low_pow,lterm,macro,mainvar,mass,mat,match,% -mateigen,matrix,max,mcd,member,memq,min,minus,mkid,% -modular,msg,mshell,multiplicities,nat,neq,nero,% -nextprime,nil,nodepend,noncom,nonzero,nosplit,% -nospur,nullspace,num,numberp,odd,off,on,operator,% -or,order,ordp,out,output,part,pause,period,pf,pi,% -plus,precedence,precise,precision,pret,pri,primep,% -print_precision,procedure,product,quit,quotient,% -random,random_new_seed,rank,rat,ratarg,rational,% -rationalize,ratpri,real,rederr,reduct,remainder,% -remfac,remind,repart,repeat,rest,resultant,retry,% -return,reverse,revpri,rhs,rlisp88,% -root_multiplicity,round,roundall,roundbf,rounded,% -saveas,savestructr,scalar,sec,sech,second,set,% -setmod,setq,share,showrules,showtime,shut,sign,sin,% -sinh,smacro,solve,solvesingular,spur,sqrt,structr,% -sub,sum,symbolic,symmetric,t,tan,tanh,third,time,% -times,tp,tra,trace,trfac,trigform,trint,until,% -varname,vecdim,vector,weight,when,where,while,% -write,ws,wtlevel,% -%% identifiers with spaces -%% for all,for each,go to,such that,% -},% - sensitive=false,% - morecomment=[l]\%,% - morecomment=[s]{COMMENT}{;},% - morecomment=[s]{COMMENT}{$},% - morestring="% - }[keywords,comments,strings]% -%% -%% RSL definition (c) 2004 Brian Christensen -%% -\lst@definelanguage{RSL}% - {morekeywords={Bool,Char,devt_relation,Int,Nat,Real,Text,Unit,abs,any,% - as,axiom,card,case,channel,chaos,class,do,dom,elems,else,elsif,end,% - extend,false,for,hd,hide,if,in,inds,initialise,int,len,let,local,% - object,of,out,post,pre,read,real,rng,scheme,skip,stop,swap,% - test_case,theory,then,tl,true,type,until,use,value,variable,while,% - with,write},% -literate=% -{<}{$<$}{1}% -{>}{$>$}{1}% -{[}{$[$}{1}%% -{]}{$]$}{1}%% -{^}{{\mbox{$\widehat{\;}$}}}{1}%% -{'}{{\raisebox{1ex}[1ex][0ex]{\protect\scriptsize$\prime$}}}{1}%% -{||}{{\mbox{$\parallel$}}}{2}%% -{|-}{$\vdash$}{1}%% -{|=|}{{\mbox{$\lceil\!\rceil\!\!\!\!\!\!\;\lfloor\!\rfloor$}}}{1}%% -{**}{$\uparrow$}{1}% -{/\\}{$\wedge$}{1}%% -{inter}{$\cap$}{1}%% -{-\\}{$\lambda$}{1}%% -{->}{$\rightarrow$}{1}%% -{-m->}{{\mbox{$\rightarrow \hspace{-2.5\lst@width} _{m}\;$}}}{1}% -{-~m->}{{\mbox{$\stackrel{\sim}{\mbox{$\rightarrow\hspace{-2.5\lst@width} _{m}\;$}}$}}}{1}% -{-~->}{{\mbox{$\stackrel{\sim}{\rightarrow}$}}}{1}%% -{-set}{\bf{-set}}{4}%% -{-list}{{$^{\ast}$}}{1}%% -{-inflist}{$^\omega$}{1}% -{-infset}{{\mbox{{\bf -infset}}}}{7}% -{\#}{$\circ$}{1}% -{:-}{{\raisebox{.4ex}{\tiny $\bullet$}}}{1}%% -{=}{$=$}{1}%% -{==}{$==$}{2}%% -{=>}{$\Rightarrow$}{1}%% -{\ is\protect\^^M}{{$\;\equiv$}}{2}% -{\ is\ }{{$\equiv$}}{3}%% -{\ isin\protect\^^M}{$\;\in$}{2}%% -{~}{$\sim$}{1}%% -{~=}{$\neq$}{1}%% -{~isin}{$\notin$}{1}%% -{+>}{$\mapsto$}{1}%% -{++}{}{1}% -{|^|}{{\mbox{$\lceil\!\rceil$}}}{1}%% -{\\/}{$\vee$}{1}%% -{exists}{$\exists$}{1}%% -{union}{$\cup$}{1}%% -{>=}{$\geq$}{1}%% -{><}{$\times$}{1}%% -{>>}{$\supset$}{1}% -{>>=}{$\supseteq$}{1}%% -{<=}{$\leq$}{1}%% -{<<}{$\subset$}{1}% -{<.}{$\langle$}{1}%% -{<<=}{$\subseteq$}{1}%% -{<->}{$\leftrightarrow$}{1}%% -{[=}{$\sqsubseteq$}{1}%% -{\{=}{$\preceq$}{1}%% -{\ all\protect\^^M}{$\forall$}{2}%% -{\ all\ }{$\forall$}{3}%% -{!!}{$\dagger$}{1}%% -{always}{$\Box$}{1}%% -{.>}{$\rangle$}{1}%% -{`alpha}{$\alpha$}{1}% -{`beta}{$\beta$}{1}% -{`gamma}{$\gamma$}{1}% -{`delta}{$\delta$}{1}% -{`epsilon}{$\epsilon$}{1}% -{`zeta}{$\zeta$}{1}% -{`eta}{$\eta$}{1}% -{`theta}{$\theta$}{1}% -{`iota}{$\iota$}{1}% -{`kappa}{$\kappa$}{1}% -{`mu}{$\mu$}{1}% -{`nu}{$\nu$}{1}% -{`xi}{$\xi$}{1}% -{`pi}{$\pi$}{1}% -{`rho}{$\rho$}{1}% -{`sigma}{$\sigma$}{1}% -{`tau}{$\tau$}{1}% -{`upsilon}{$\upsilon$}{1}% -{`phi}{$\phi$}{1}% -{`chi}{$\chi$}{1}% -{`psi}{$\psi$}{1}% -{`omega}{$\omega$}{1}% -{`Gamma}{$\Gamma$}{1}% -{`Delta}{$\Delta$}{1}% -{`Theta}{$\Theta$}{1}% -{`Lambda}{$\Lambda$}{1}% -{`Xi}{$\Xi$}{1}% -{`Pi}{$\Pi$}{1}% -{`Sigma}{$\Sigma$}{1}% -{`Upsilon}{$\Upsilon$}{1}% -{`Phi}{$\Phi$}{1}% -{`Psi}{$\Psi$}{1}% -{`Omega}{$\Omega$}{1},% - sensitive=true,% - morecomment=[l]{--},% - morecomment=[s]{/*}{*/}% - }[keywords,comments]% -\lst@definelanguage[IBM]{Simula}[DEC]{Simula}{}% -\lst@definelanguage[DEC]{Simula}[67]{Simula}% - {morekeywords={and,eq,eqv,ge,gt,hidden,imp,le,long,lt,ne,not,% - options,or,protected,short}% - }% -\lst@definelanguage[CII]{Simula}[67]{Simula}% - {morekeywords={and,equiv,exit,impl,not,or,stop}}% -\lst@definelanguage[67]{Simula}% - {morekeywords={activate,after,array,at,before,begin,boolean,% - character,class,comment,delay,detach,do,else,end,external,false,% - for,go,goto,if,in,inner,inspect,integer,is,label,name,new,none,% - notext,otherwise,prior,procedure,qua,reactivate,real,ref,resume,% - simset,simulation,step,switch,text,then,this,to,true,until,value,% - virtual,when,while},% - sensitive=f,% - keywordcommentsemicolon={end}{else,end,otherwise,when}{comment},% - morestring=[d]",% - morestring=[d]'% - }[keywords,keywordcomments,strings]% -\lst@definelanguage{S}[]{R}{} -\lst@definelanguage[PLUS]{S}[]{R}{} -\lst@definelanguage{R}% - {keywords={abbreviate,abline,abs,acos,acosh,action,add1,add,% - aggregate,alias,Alias,alist,all,anova,any,aov,aperm,append,apply,% - approx,approxfun,apropos,Arg,args,array,arrows,as,asin,asinh,% - atan,atan2,atanh,attach,attr,attributes,autoload,autoloader,ave,% - axis,backsolve,barplot,basename,besselI,besselJ,besselK,besselY,% - beta,binomial,body,box,boxplot,break,browser,bug,builtins,bxp,by,% - c,C,call,Call,case,cat,category,cbind,ceiling,character,char,% - charmatch,check,chol,chol2inv,choose,chull,class,close,cm,codes,% - coef,coefficients,co,col,colnames,colors,colours,commandArgs,% - comment,complete,complex,conflicts,Conj,contents,contour,% - contrasts,contr,control,helmert,contrib,convolve,cooks,coords,% - distance,coplot,cor,cos,cosh,count,fields,cov,covratio,wt,CRAN,% - create,crossprod,cummax,cummin,cumprod,cumsum,curve,cut,cycle,D,% - data,dataentry,date,dbeta,dbinom,dcauchy,dchisq,de,debug,% - debugger,Defunct,default,delay,delete,deltat,demo,de,density,% - deparse,dependencies,Deprecated,deriv,description,detach,% - dev2bitmap,dev,cur,deviance,off,prev,,dexp,df,dfbetas,dffits,% - dgamma,dgeom,dget,dhyper,diag,diff,digamma,dim,dimnames,dir,% - dirname,dlnorm,dlogis,dnbinom,dnchisq,dnorm,do,dotplot,double,% - download,dpois,dput,drop,drop1,dsignrank,dt,dummy,dump,dunif,% - duplicated,dweibull,dwilcox,dyn,edit,eff,effects,eigen,else,% - emacs,end,environment,env,erase,eval,equal,evalq,example,exists,% - exit,exp,expand,expression,External,extract,extractAIC,factor,% - fail,family,fft,file,filled,find,fitted,fivenum,fix,floor,for,% - For,formals,format,formatC,formula,Fortran,forwardsolve,frame,% - frequency,ftable,ftable2table,function,gamma,Gamma,gammaCody,% - gaussian,gc,gcinfo,gctorture,get,getenv,geterrmessage,getOption,% - getwd,gl,glm,globalenv,gnome,GNOME,graphics,gray,grep,grey,grid,% - gsub,hasTsp,hat,heat,help,hist,home,hsv,httpclient,I,identify,if,% - ifelse,Im,image,\%in\%,index,influence,measures,inherits,install,% - installed,integer,interaction,interactive,Internal,intersect,% - inverse,invisible,IQR,is,jitter,kappa,kronecker,labels,lapply,% - layout,lbeta,lchoose,lcm,legend,length,levels,lgamma,library,% - licence,license,lines,list,lm,load,local,locator,log,log10,log1p,% - log2,logical,loglin,lower,lowess,ls,lsfit,lsf,ls,machine,Machine,% - mad,mahalanobis,make,link,margin,match,Math,matlines,mat,matplot,% - matpoints,matrix,max,mean,median,memory,menu,merge,methods,min,% - missing,Mod,mode,model,response,mosaicplot,mtext,mvfft,na,nan,% - names,omit,nargs,nchar,ncol,NCOL,new,next,NextMethod,nextn,% - nlevels,nlm,noquote,NotYetImplemented,NotYetUsed,nrow,NROW,null,% - numeric,\%o\%,objects,offset,old,on,Ops,optim,optimise,optimize,% - options,or,order,ordered,outer,package,packages,page,pairlist,% - pairs,palette,panel,par,parent,parse,paste,path,pbeta,pbinom,% - pcauchy,pchisq,pentagamma,persp,pexp,pf,pgamma,pgeom,phyper,pico,% - pictex,piechart,Platform,plnorm,plogis,plot,pmatch,pmax,pmin,% - pnbinom,pnchisq,pnorm,points,poisson,poly,polygon,polyroot,pos,% - postscript,power,ppoints,ppois,predict,preplot,pretty,Primitive,% - print,prmatrix,proc,prod,profile,proj,prompt,prop,provide,% - psignrank,ps,pt,ptukey,punif,pweibull,pwilcox,q,qbeta,qbinom,% - qcauchy,qchisq,qexp,qf,qgamma,qgeom,qhyper,qlnorm,qlogis,qnbinom,% - qnchisq,qnorm,qpois,qqline,qqnorm,qqplot,qr,Q,qty,qy,qsignrank,% - qt,qtukey,quantile,quasi,quit,qunif,quote,qweibull,qwilcox,% - rainbow,range,rank,rbeta,rbind,rbinom,rcauchy,rchisq,Re,read,csv,% - csv2,fwf,readline,socket,real,Recall,rect,reformulate,regexpr,% - relevel,remove,rep,repeat,replace,replications,report,require,% - resid,residuals,restart,return,rev,rexp,rf,rgamma,rgb,rgeom,R,% - rhyper,rle,rlnorm,rlogis,rm,rnbinom,RNGkind,rnorm,round,row,% - rownames,rowsum,rpois,rsignrank,rstandard,rstudent,rt,rug,runif,% - rweibull,rwilcox,sample,sapply,save,scale,scan,scan,screen,sd,se,% - search,searchpaths,segments,seq,sequence,setdiff,setequal,set,% - setwd,show,sign,signif,sin,single,sinh,sink,solve,sort,source,% - spline,splinefun,split,sqrt,stars,start,stat,stem,step,stop,% - storage,strstrheight,stripplot,strsplit,structure,strwidth,sub,% - subset,substitute,substr,substring,sum,summary,sunflowerplot,svd,% - sweep,switch,symbol,symbols,symnum,sys,status,system,t,table,% - tabulate,tan,tanh,tapply,tempfile,terms,terrain,tetragamma,text,% - time,title,topo,trace,traceback,transform,tri,trigamma,trunc,try,% - ts,tsp,typeof,unclass,undebug,undoc,union,unique,uniroot,unix,% - unlink,unlist,unname,untrace,update,upper,url,UseMethod,var,% - variable,vector,Version,vi,warning,warnings,weighted,weights,% - which,while,window,write,\%x\%,x11,X11,xedit,xemacs,xinch,xor,% - xpdrows,xy,xyinch,yinch,zapsmall,zip},% - otherkeywords={!,!=,~,$,*,\&,\%/\%,\%*\%,\%\%,<-,<<-,_,/},% - alsoother={._$},% - sensitive,% - morecomment=[l]\#,% - morestring=[d]",% - morestring=[d]'% 2001 Robert Denham - }% -\lst@definelanguage{SAS}% - {procnamekeys={proc},% - morekeywords={DATA,AND,OR,NOT,EQ,GT,LT,GE,LE,NE,INFILE,INPUT,DO,BY,% - TO,SIN,COS,OUTPUT,END,PLOT,RUN,LIBNAME,VAR,TITLE,FIRSTOBS,OBS,% - DELIMITER,DLM,EOF,ABS,DIM,HBOUND,LBOUND,MAX,MIN,MOD,SIGN,SQRT,% - CEIL,FLOOR,FUZZ,INT,ROUND,TRUNC,DIGAMMA,ERF,ERFC,EXP,GAMMA,% - LGAMMA,LOG,LOG2,LOG10,ARCOS,ARSIN,ATAN,COSH,SINH,TANH,TAN,% - POISSON,PROBBETA,PROBBNML,PROBCHI,PROBF,PROBGAM,PROBHYPR,% - PROBNEGB,PROBNORM,PROBT,BETAINV,CINV,FINV,GAMINV,PROBIT,TINV,CSS,% - CV,KURTOSIS,MEAN,NMISS,RANGE,SKEWNESS,STD,STDERR,SUM,USS,NORMAL,% - RANBIN,RANCAU,RANEXP,RANGAM,RANNOR,RANPOI,RANTBL,RANTRI,RANUNI,% - UNIFORM,IF,THEN,ELSE,WHILE,UNTIL,DROP,KEEP,LABEL,DEFAULT,ARRAY,% - MERGE,CARDS,CARDS4,PUT,SET,UPDATE,ABORT,DELETE,DISPLAY,LIST,% - LOSTCARD,MISSING,STOP,WHERE,ARRAY,DROP,KEEP,WINDOW,LENGTH,RENAME,% - RETAIN,MEANS,UNIVARIATE,SUMMARY,TABULATE,CORR,FREQ,FOOTNOTE,NOTE,% - SHOW},% - otherkeywords={!,!=,~,$,*,\&,_,/,<,>=,=<,>},% - morestring=[d]'% - }[keywords,comments,strings,procnames]% -\lst@definelanguage[AlLaTeX]{TeX}[LaTeX]{TeX}% - {moretexcs={AtBeginDocument,AtBeginDvi,AtEndDocument,AtEndOfClass,% - AtEndOfPackage,ClassError,ClassInfo,ClassWarning,% - ClassWarningNoLine,CurrentOption,DeclareErrorFont,% - DeclareFixedFont,DeclareFontEncoding,DeclareFontEncodingDefaults,% - DeclareFontFamily,DeclareFontShape,DeclareFontSubstitution,% - DeclareMathAccent,DeclareMathAlphabet,DeclareMathAlphabet,% - DeclareMathDelimiter,DeclareMathRadical,DeclareMathSizes,% - DeclareMathSymbol,DeclareMathVersion,DeclareOldFontCommand,% - DeclareOption,DeclarePreloadSizes,DeclareRobustCommand,% - DeclareSizeFunction,DeclareSymbolFont,DeclareSymbolFontAlphabet,% - DeclareTextAccent,DeclareTextAccentDefault,DeclareTextCommand,% - DeclareTextCommandDefault,DeclareTextComposite,% - DeclareTextCompositeCommand,DeclareTextFontCommand,% - DeclareTextSymbol,DeclareTextSymbolDefault,ExecuteOptions,% - GenericError,GenericInfo,GenericWarning,IfFileExists,% - InputIfFileExists,LoadClass,LoadClassWithOptions,MessageBreak,% - OptionNotUsed,PackageError,PackageInfo,PackageWarning,% - PackageWarningNoLine,PassOptionsToClass,PassOptionsToPackage,% - ProcessOptionsProvidesClass,ProvidesFile,ProvidesFile,% - ProvidesPackage,ProvideTextCommand,RequirePackage,% - RequirePackageWithOptions,SetMathAlphabet,SetSymbolFont,% - TextSymbolUnavailable,UseTextAccent,UseTextSymbol},% - morekeywords={array,center,displaymath,document,enumerate,eqnarray,% - equation,flushleft,flushright,itemize,list,lrbox,math,minipage,% - picture,sloppypar,tabbing,tabular,trivlist,verbatim}% - }% -\lst@definelanguage[LaTeX]{TeX}[common]{TeX}% - {moretexcs={a,AA,aa,addcontentsline,addpenalty,addtocontents,% - addtocounter,addtolength,addtoversion,addvspace,alph,Alph,and,% - arabic,array,arraycolsep,arrayrulewidth,arraystretch,author,% - baselinestretch,begin,bezier,bfseries,bibcite,bibdata,bibitem,% - bibliography,bibliographystyle,bibstyle,bigskip,boldmath,% - botfigrule,bottomfraction,Box,caption,center,CheckCommand,circle,% - citation,cite,cleardoublepage,clearpage,cline,columnsep,% - columnseprule,columnwidth,contentsline,dashbox,date,dblfigrule,% - dblfloatpagefraction,dblfloatsep,dbltextfloatsep,dbltopfraction,% - defaultscriptratio,defaultscriptscriptratio,depth,Diamond,% - displaymath,document,documentclass,documentstyle,doublerulesep,% - em,emph,endarray,endcenter,enddisplaymath,enddocument,% - endenumerate,endeqnarray,endequation,endflushleft,endflushright,% - enditemize,endlist,endlrbox,endmath,endminipage,endpicture,% - endsloppypar,endtabbing,endtabular,endtrivlist,endverbatim,% - enlargethispage,ensuremath,enumerate,eqnarray,equation,% - evensidemargin,extracolsep,fbox,fboxrule,fboxsep,filecontents,% - fill,floatpagefraction,floatsep,flushbottom,flushleft,flushright,% - fnsymbol,fontencoding,fontfamily,fontseries,fontshape,fontsize,% - fontsubfuzz,footnotemark,footnotesep,footnotetext,footskip,frac,% - frame,framebox,fussy,glossary,headheight,headsep,height,hline,% - hspace,I,include,includeonly,index,inputlineno,intextsep,% - itemindent,itemize,itemsep,iterate,itshape,Join,kill,label,% - labelsep,labelwidth,LaTeX,LaTeXe,leadsto,lefteqn,leftmargin,% - leftmargini,leftmarginii,leftmarginiii,leftmarginiv,leftmarginv,% - leftmarginvi,leftmark,lhd,lim,linebreak,linespread,linethickness,% - linewidth,list,listfiles,listfiles,listparindent,lrbox,% - makeatletter,makeatother,makebox,makeglossary,makeindex,% - makelabel,MakeLowercase,MakeUppercase,marginpar,marginparpush,% - marginparsep,marginparwidth,markboth,markright,math,mathbf,% - mathellipsis,mathgroup,mathit,mathrm,mathsf,mathsterling,mathtt,% - mathunderscore,mathversion,mbox,mdseries,mho,minipage,% - multicolumn,multiput,NeedsTeXFormat,newcommand,newcounter,% - newenvironment,newfont,newhelp,newlabel,newlength,newline,% - newmathalphabet,newpage,newsavebox,newtheorem,nobreakspace,% - nobreakspace,nocite,nocorr,nocorrlist,nofiles,nolinebreak,% - nonumber,nopagebreak,normalcolor,normalfont,normalmarginpar,% - numberline,obeycr,oddsidemargin,oldstylenums,onecolumn,oval,% - pagebreak,pagenumbering,pageref,pagestyle,paperheight,paperwidth,% - paragraphmark,parbox,parsep,partopsep,picture,poptabs,pounds,% - protect,pushtabs,put,qbezier,qbeziermax,r,raggedleft,raisebox,% - ref,refstepcounter,renewcommand,renewenvironment,restorecr,% - reversemarginpar,rhd,rightmargin,rightmark,rmfamily,roman,Roman,% - rootbox,rule,samepage,sbox,scshape,secdef,section,sectionmark,% - selectfont,setcounter,settodepth,settoheight,settowidth,sffamily,% - shortstack,showoutput,showoverfull,sloppy,sloppypar,slshape,% - smallskip,sqsubset,sqsupset,SS,stackrel,stepcounter,stop,stretch,% - subparagraphmark,subsectionmark,subsubsectionmark,sum,% - suppressfloats,symbol,tabbing,tabbingsep,tabcolsep,tabular,% - tabularnewline,textasciicircum,textasciitilde,textbackslash,% - textbar,textbf,textbraceleft,textbraceright,textbullet,% - textcircled,textcompwordmark,textdagger,textdaggerdbl,textdollar,% - textellipsis,textemdash,textendash,textexclamdown,textfloatsep,% - textfraction,textgreater,textheight,textit,textless,textmd,% - textnormal,textparagraph,textperiodcentered,textquestiondown,% - textquotedblleft,textquotedblright,textquoteleft,textquoteright,% - textregistered,textrm,textsc,textsection,textsf,textsl,% - textsterling,textsuperscript,texttrademark,texttt,textunderscore,% - textup,textvisiblespace,textwidth,thanks,thefootnote,thempfn,% - thempfn,thempfootnote,thepage,thepage,thicklines,thinlines,% - thispagestyle,title,today,topfigrule,topfraction,topmargin,% - topsep,totalheight,tracingfonts,trivlist,ttfamily,twocolumn,% - typein,typeout,unboldmath,unitlength,unlhd,unrhd,upshape,usebox,% - usecounter,usefont,usepackage,value,vector,verb,verbatim,vline,% - vspace,width,% - normalsize,small,footnotesize,scriptsize,tiny,large,Large,LARGE,% - huge,Huge}% - }% -\lst@definelanguage[plain]{TeX}[common]{TeX}% - {moretexcs={advancepageno,beginsection,bf,bffam,bye,cal,cleartabs,% - columns,dosupereject,endinsert,eqalign,eqalignno,fiverm,fivebf,% - fivei,fivesy,folio,footline,hang,headline,it,itemitem,itfam,% - leqalignno,magnification,makefootline,makeheadline,midinsert,mit,% - mscount,nopagenumbers,normalbottom,of,oldstyle,pagebody,% - pagecontents,pageinsert,pageno,plainoutput,preloaded,proclaim,rm,% - settabs,sevenbf,seveni,sevensy,sevenrm,sl,slfam,supereject,% - tabalign,tabs,tabsdone,tabsyet,tenbf,tenex,teni,tenit,tenrm,% - tensl,tensy,tentt,textindent,topglue,topins,topinsert,tt,ttfam,% - ttraggedright,vfootnote}% - }% -\lst@definelanguage[common]{TeX}[primitive]{TeX} - {moretexcs={active,acute,ae,AE,aleph,allocationnumber,allowbreak,% - alpha,amalg,angle,approx,arccos,arcsin,arctan,arg,arrowvert,% - Arrowvert,ast,asymp,b,backslash,bar,beta,bgroup,big,Big,bigbreak,% - bigcap,bigcirc,bigcup,bigg,Bigg,biggl,Biggl,biggm,Biggm,biggr,% - Biggr,bigl,Bigl,bigm,Bigm,bigodot,bigoplus,bigotimes,bigr,Bigr,% - bigskip,bigskipamount,bigsqcup,bigtriangledown,bigtriangleup,% - biguplus,bigvee,bigwedge,bmod,bordermatrix,bot,bowtie,brace,% - braceld,bracelu,bracerd,braceru,bracevert,brack,break,breve,% - buildrel,bullet,c,cap,cases,cdot,cdotp,cdots,centering,% - centerline,check,chi,choose,circ,clubsuit,colon,cong,coprod,% - copyright,cos,cosh,cot,coth,csc,cup,d,dag,dagger,dashv,ddag,% - ddagger,ddot,ddots,deg,delta,Delta,det,diamond,diamondsuit,dim,% - displaylines,div,do,dospecials,dot,doteq,dotfill,dots,downarrow,% - Downarrow,downbracefill,egroup,eject,ell,empty,emptyset,endgraf,% - endline,enskip,enspace,epsilon,equiv,eta,exists,exp,filbreak,% - flat,fmtname,fmtversion,footins,footnote,footnoterule,forall,% - frenchspacing,frown,gamma,Gamma,gcd,ge,geq,gets,gg,goodbreak,% - grave,H,hat,hbar,heartsuit,hglue,hideskip,hidewidth,hom,% - hookleftarrow,hookrightarrow,hphantom,hrulefill,i,ialign,iff,Im,% - imath,in,inf,infty,int,interdisplaylinepenalty,% - interfootnotelinepenalty,intop,iota,item,j,jmath,joinrel,jot,% - kappa,ker,l,L,lambda,Lambda,land,langle,lbrace,lbrack,lceil,% - ldotp,ldots,le,leavevmode,leftarrow,Leftarrow,leftarrowfill,% - leftharpoondown,leftharpoonup,leftline,leftrightarrow,% - Leftrightarrow,leq,lfloor,lg,lgroup,lhook,lim,liminf,limsup,line,% - ll,llap,lmoustache,ln,lnot,log,longleftarrow,Longleftarrow,% - longleftrightarrow,Longleftrightarrow,longmapsto,longrightarrow,% - Longrightarrow,loop,lor,lq,magstep,magstep,magstephalf,mapsto,% - mapstochar,mathhexbox,mathpalette,mathstrut,matrix,max,maxdimen,% - medbreak,medskip,medskipamount,mid,min,models,mp,mu,multispan,% - nabla,narrower,natural,ne,nearrow,neg,negthinspace,neq,newbox,% - newcount,newdimen,newfam,newif,newinsert,newlanguage,newmuskip,% - newread,newskip,newtoks,newwrite,next,ni,nobreak,nointerlineskip,% - nonfrenchspacing,normalbaselines,normalbaselineskip,% - normallineskip,normallineskiplimit,not,notin,nu,null,nwarrow,o,O,% - oalign,obeylines,obeyspaces,odot,oe,OE,offinterlineskip,oint,% - ointop,omega,Omega,ominus,ooalign,openup,oplus,oslash,otimes,% - overbrace,overleftarrow,overrightarrow,owns,P,parallel,partial,% - perp,phantom,phi,Phi,pi,Pi,pm,pmatrix,pmod,Pr,prec,preceq,prime,% - prod,propto,psi,Psi,qquad,quad,raggedbottom,raggedright,rangle,% - rbrace,rbrack,rceil,Re,relbar,Relbar,removelastskip,repeat,% - rfloor,rgroup,rho,rhook,rightarrow,Rightarrow,rightarrowfill,% - rightharpoondown,rightharpoonup,rightleftharpoons,rightline,rlap,% - rmoustache,root,rq,S,sb,searrow,sec,setminus,sharp,showhyphens,% - sigma,Sigma,sim,simeq,sin,sinh,skew,slash,smallbreak,smallint,% - smallskip,smallskipamount,smash,smile,sp,space,spadesuit,sqcap,% - sqcup,sqrt,sqsubseteq,sqsupseteq,ss,star,strut,strutbox,subset,% - subseteq,succ,succeq,sum,sup,supset,supseteq,surd,swarrow,t,tan,% - tanh,tau,TeX,theta,Theta,thinspace,tilde,times,to,top,tracingall,% - triangle,triangleleft,triangleright,u,underbar,underbrace,% - uparrow,Uparrow,upbracefill,updownarrow,Updownarrow,uplus,% - upsilon,Upsilon,v,varepsilon,varphi,varpi,varrho,varsigma,% - vartheta,vdash,vdots,vec,vee,vert,Vert,vglue,vphantom,wedge,% - widehat,widetilde,wlog,wp,wr,xi,Xi,zeta}% - }% -\lst@definelanguage[primitive]{TeX}% - {moretexcs={above,abovedisplayshortskip,abovedisplayskip,aftergroup,% - abovewithdelims,accent,adjdemerits,advance,afterassignment,atop,% - atopwithdelims,badness,baselineskip,batchmode,begingroup,% - belowdisplayshortskip,belowdisplayskip,binoppenalty,botmark,box,% - boxmaxdepth,brokenpenalty,catcode,char,chardef,cleaders,closein,% - closeout,clubpenalty,copy,count,countdef,cr,crcr,csname,day,% - deadcycles,def,defaulthyphenchar,defaultskewchar,delcode,% - delimiter,delimiterfactor,delimitershortfall,dimen,dimendef,% - discretionary,displayindent,displaylimits,displaystyle,% - displaywidowpenalty,displaywidth,divide,doublehyphendemerits,dp,% - edef,else,emergencystretch,end,endcsname,endgroup,endinput,% - endlinechar,eqno,errhelp,errmessage,errorcontextlines,% - errorstopmode,escapechar,everycr,everydisplay,everyhbox,everyjob,% - everymath,everypar,everyvbox,exhyphenpenalty,expandafter,fam,fi,% - finalhypendemerits,firstmark,floatingpenalty,font,fontdimen,% - fontname,futurelet,gdef,global,globaldefs,halign,hangafter,% - hangindent,hbadness,hbox,hfil,hfill,hfilneg,hfuzz,hoffset,% - holdinginserts,hrule,hsize,hskip,hss,ht,hyphenation,hyphenchar,% - hyphenpenalty,if,ifcase,ifcat,ifdim,ifeof,iffalse,ifhbox,ifhmode,% - ifinner,ifmmode,ifnum,ifodd,iftrue,ifvbox,ifvmode,ifvoid,ifx,% - ignorespaces,immediate,indent,input,insert,insertpenalties,% - interlinepenalty,jobname,kern,language,lastbox,lastkern,% - lastpenalty,lastskip,lccode,leaders,left,lefthyphenmin,leftskip,% - leqno,let,limits,linepenalty,lineskip,lineskiplimits,long,% - looseness,lower,lowercase,mag,mark,mathaccent,mathbin,mathchar,% - mathchardef,mathchoice,mathclose,mathcode,mathinner,mathop,% - mathopen,mathord,mathpunct,mathrel,mathsurround,maxdeadcycles,% - maxdepth,meaning,medmuskip,message,mkern,month,moveleft,% - moveright,mskip,multiply,muskip,muskipdef,newlinechar,noalign,% - noboundary,noexpand,noindent,nolimits,nonscript,nonstopmode,% - nulldelimiterspace,nullfont,number,omit,openin,openout,or,outer,% - output,outputpenalty,over,overfullrule,overline,overwithdelims,% - pagedepth,pagefilllstretch,pagefillstretch,pagefilstretch,% - pagegoal,pageshrink,pagestretch,pagetotal,par,parfillskip,% - parindent,parshape,parskip,patterns,pausing,penalty,% - postdisplaypenalty,predisplaypenalty,predisplaysize,pretolerance,% - prevdepth,prevgraf,radical,raise,read,relax,relpenalty,right,% - righthyphenmin,rightskip,romannumeral,scriptfont,% - scriptscriptfont,scriptscriptstyle,scriptspace,scriptstyle,% - scrollmode,setbox,setlanguage,sfcode,shipout,show,showbox,% - showboxbreadth,showboxdepth,showlists,showthe,skewchar,skip,% - skipdef,spacefactor,spaceskip,span,special,splitbotmark,% - splitfirstmark,splitmaxdepth,splittopskip,string,tabskip,% - textfont,textstyle,the,thickmuskip,thinmuskip,time,toks,toksdef,% - tolerance,topmark,topskip,tracingcommands,tracinglostchars,% - tracingmacros,tracingonline,tracingoutput,tracingpages,% - tracingparagraphs,tracingrestores,tracingstats,uccode,uchyph,% - underline,unhbox,unhcopy,unkern,unpenalty,unskip,unvbox,unvcopy,% - uppercase,vadjust,valign,vbadness,vbox,vcenter,vfil,vfill,% - vfilneg,vfuzz,voffset,vrule,vsize,vskip,vsplit,vss,vtop,wd,% - widowpenalty,write,xdef,xleaders,xspaceskip,year},% - sensitive,% - alsoother={0123456789$_},% - morecomment=[l]\%% - }[keywords,tex,comments]% -%% -%% Verilog definition (c) 2003 Cameron H. G. Wright -%% Based on the IEEE 1364-2001 Verilog HDL standard -%% Ref: S. Palnitkar, "Verilog HDL: A Guide to Digital Design and Synthesis," -%% Prentice Hall, 2003. ISBN: 0-13-044911-3 -%% -\lst@definelanguage{Verilog}% - {morekeywords={% reserved keywords - always,and,assign,automatic,begin,buf,bufif0,bufif1,case,casex,% - casez,cell,cmos,config,deassign,default,defparam,design,disable,% - edge,else,end,endcase,endconfig,endfunction,endgenerate,% - endmodule,endprimitive,endspecify,endtable,endtask,event,for,% - force,forever,fork,function,generate,genvar,highz0,highz1,if,% - ifnone,incdir,include,initial,inout,input,instance,integer,join,% - large,liblist,library,localparam,macromodule,medium,module,nand,% - negedge,nmos,nor,noshowcancelled,not,notif0,notif1,or,output,% - parameter,pmos,posedge,primitive,pull0,pull1,pulldown,pullup,% - pulsestyle_onevent,pulsestyle_ondetect,rcmos,real,realtime,reg,% - release,repeat,rnmos,rpmos,rtran,rtranif0,rtranif1,scalared,% - showcancelled,signed,small,specify,specparam,strong0,strong1,% - supply0,supply1,table,task,time,tran,tranif0,tranif1,tri,tri0,% - tri1,triand,trior,trireg,unsigned,use,vectored,wait,wand,weak0,% - weak1,while,wire,wor,xnor,xor},% - morekeywords=[2]{% system tasks and functions - $bitstoreal,$countdrivers,$display,$fclose,$fdisplay,$fmonitor,% - $fopen,$fstrobe,$fwrite,$finish,$getpattern,$history,$incsave,% - $input,$itor,$key,$list,$log,$monitor,$monitoroff,$monitoron,% - $nokey},% - morekeywords=[3]{% compiler directives - `accelerate,`autoexpand_vectornets,`celldefine,`default_nettype,% - `define,`else,`elsif,`endcelldefine,`endif,`endprotect,% - `endprotected,`expand_vectornets,`ifdef,`ifndef,`include,% - `no_accelerate,`noexpand_vectornets,`noremove_gatenames,% - `nounconnected_drive,`protect,`protected,`remove_gatenames,% - `remove_netnames,`resetall,`timescale,`unconnected_drive},% - alsoletter=\`,% - sensitive,% - morecomment=[s]{/*}{*/},% - morecomment=[l]//,% nonstandard - morestring=[b]"% - }[keywords,comments,strings]% -\endinput -%% -%% End of file `lstlang3.sty'. diff --git a/org.glite.lb.doc/src/lstmisc.sty b/org.glite.lb.doc/src/lstmisc.sty deleted file mode 100644 index 9a4f12d..0000000 --- a/org.glite.lb.doc/src/lstmisc.sty +++ /dev/null @@ -1,2086 +0,0 @@ -%% -%% This is file `lstmisc.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% listings-1.3.dtx (with options: `misc,0.21') -%% -%% Please read the software license in listings-1.3.dtx or listings-1.3.pdf. -%% -%% (w)(c) 1996--2004 Carsten Heinz and/or any other author listed -%% elsewhere in this file. -%% -%% Send comments and ideas on the package, error reports and additional -%% programming languages to . -%% -\def\filedate{2004/09/07} -\def\fileversion{1.3} -\ProvidesFile{lstmisc.sty} - [\filedate\space\fileversion\space(Carsten Heinz)] -\lst@CheckVersion\fileversion - {\typeout{^^J% - ***^^J% - *** This file requires `listings.sty' version \fileversion.^^J% - *** You have a serious problem, so I'm exiting ...^^J% - ***^^J}% - \batchmode \@@end} -\lst@BeginAspect{writefile} -\newtoks\lst@WFtoken % global -\lst@AddToHook{InitVarsBOL}{\global\lst@WFtoken{}} -\newwrite\lst@WF -\global\let\lst@WFifopen\iffalse % init -\gdef\lst@WFWriteToFile{% - \begingroup - \let\lst@UM\@empty - \expandafter\edef\expandafter\lst@temp\expandafter{\the\lst@WFtoken}% - \immediate\write\lst@WF{\lst@temp}% - \endgroup - \global\lst@WFtoken{}} -\gdef\lst@WFAppend#1{% - \global\lst@WFtoken=\expandafter{\the\lst@WFtoken#1}} -\gdef\lst@BeginWriteFile{\lst@WFBegin\@gobble} -\gdef\lst@BeginAlsoWriteFile{\lst@WFBegin\lst@OutputBox} -\begingroup \catcode`\^^I=11 -\gdef\lst@WFBegin#1#2{% - \begingroup - \let\lst@OutputBox#1% - \def\lst@Append##1{% - \advance\lst@length\@ne - \expandafter\lst@token\expandafter{\the\lst@token##1}% - \ifx ##1\lst@outputspace \else - \lst@WFAppend##1% - \fi}% - \lst@lAddTo\lst@PreGotoTabStop{\lst@WFAppend{^^I}}% - \lst@lAddTo\lst@ProcessSpace{\lst@WFAppend{ }}% - \let\lst@DeInit\lst@WFDeInit - \let\lst@MProcessListing\lst@WFMProcessListing - \lst@WFifopen\else - \immediate\openout\lst@WF=#2\relax - \global\let\lst@WFifopen\iftrue - \@gobbletwo\fi\fi - \fi} -\endgroup -\gdef\lst@EndWriteFile{% - \immediate\closeout\lst@WF \endgroup - \global\let\lst@WFifopen\iffalse} -\global\let\lst@WFMProcessListing\lst@MProcessListing -\global\let\lst@WFDeInit\lst@DeInit -\lst@AddToAtTop\lst@WFMProcessListing{\lst@WFWriteToFile} -\lst@AddToAtTop\lst@WFDeInit{% - \ifnum\lst@length=\z@\else \lst@WFWriteToFile \fi} -\lst@EndAspect -\lst@BeginAspect{strings} -\gdef\lst@stringtypes{d,b,m,bd,db} -\gdef\lst@StringKey#1#2{% - \lst@Delim\lst@stringstyle #2\relax - {String}\lst@stringtypes #1% - {\lst@BeginString\lst@EndString}% - \@@end\@empty{}} -\lst@Key{string}\relax{\lst@StringKey\@empty{#1}} -\lst@Key{morestring}\relax{\lst@StringKey\relax{#1}} -\lst@Key{deletestring}\relax{\lst@StringKey\@nil{#1}} -\lst@Key{stringstyle}{}{\def\lst@stringstyle{#1}} -\lst@AddToHook{EmptyStyle}{\let\lst@stringstyle\@empty} -\lst@Key{showstringspaces}t[t]{\lstKV@SetIf{#1}\lst@ifshowstringspaces} -\gdef\lst@BeginString{% - \lst@DelimOpen - \lst@ifexstrings\else - {\lst@ifshowstringspaces - \lst@keepspacestrue - \let\lst@outputspace\lst@visiblespace - \fi}} -\lst@AddToHookExe{ExcludeDelims}{\let\lst@ifexstrings\iffalse} -\gdef\lst@EndString{\lst@DelimClose\lst@ifexstrings\else} -\gdef\lst@StringDM@d#1#2\@empty#3#4#5{% - \lst@CArg #2\relax\lst@DefDelimBE{}{}{}#3{#1}{#5}#4} -\gdef\lst@StringDM@b#1#2\@empty#3#4#5{% - \let\lst@ifbstring\iftrue - \lst@CArg #2\relax\lst@DefDelimBE - {\lst@ifletter \lst@Output \lst@letterfalse \fi}% - {\ifx\lst@lastother\lstum@backslash - \expandafter\@gobblethree - \fi}{}#3{#1}{#5}#4} -\global\let\lst@ifbstring\iffalse % init -\lst@AddToHook{SelectCharTable}{% - \lst@ifbstring - \lst@CArgX \\\\\relax \lst@CDefX{}% - {\lst@ProcessOther\lstum@backslash - \lst@ProcessOther\lstum@backslash - \let\lst@lastother\relax}% - {}% - \fi} -\global\let\lst@StringDM@bd\lst@StringDM@b -\global\let\lst@StringDM@db\lst@StringDM@bd -\gdef\lst@StringDM@a#1#2\@empty#3#4#5{% - \lst@CArg #2\relax\lst@DefDelimBE{}{}% - {\let\lst@next\@gobblethree - \lst@ifletter\else - \ifx\lst@lastother)\else \ifx\lst@lastother]\else - \let\lst@next\@empty - \fi \fi \fi - \lst@next}#3{#1}{#5}#4} -\gdef\lst@StringDM@m#1#2\@empty#3#4#5{% - \lst@CArg #2\relax\lst@DefDelimBE{}{}% - {\let\lst@next\@gobblethree - \lst@ifletter\else - \lst@IfLastOtherOneOf{)].0123456789\lstum@rbrace'}% - {}% - {\let\lst@next\@empty}% - \fi - \lst@next}#3{#1}{#5}#4} -\lst@SaveOutputDef{"7D}\lstum@rbrace -\lst@EndAspect -\lst@BeginAspect{mf} -\lst@AddTo\lst@stringtypes{,mf} -\lst@NewMode\lst@mfinputmode -\gdef\lst@String@mf#1\@empty#2#3#4{% - \lst@CArg #1\relax\lst@DefDelimB - {}{}{\lst@ifletter \expandafter\@gobblethree \fi}% - \lst@BeginStringMFinput\lst@mfinputmode{#4\lst@Lmodetrue}% - \@ifundefined{lsts@semicolon}% - {\lst@DefSaveDef{`\;}\lsts@semicolon{% ; and space end the filename - \ifnum\lst@mode=\lst@mfinputmode - \lst@XPrintToken - \expandafter\lst@LeaveMode - \fi - \lsts@semicolon}% - \lst@DefSaveDef{`\ }\lsts@space{% - \ifnum\lst@mode=\lst@mfinputmode - \lst@XPrintToken - \expandafter\lst@LeaveMode - \fi - \lsts@space}% - }{}} -\gdef\lst@BeginStringMFinput#1#2#3\@empty{% - \lst@TrackNewLines \lst@XPrintToken - \begingroup - \lst@mode\lst@nomode - #3\lst@XPrintToken - \endgroup - \lst@ResetToken - \lst@EnterMode{#1}{\def\lst@currstyle#2}% - \lst@ifshowstringspaces - \lst@keepspacestrue - \let\lst@outputspace\lst@visiblespace - \fi} -\lst@EndAspect -\lst@BeginAspect{comments} -\lst@NewMode\lst@commentmode -\gdef\lst@commenttypes{l,f,s,n} -\gdef\lst@CommentKey#1#2{% - \lst@Delim\lst@commentstyle #2\relax - {Comment}\lst@commenttypes #1% - {\lst@BeginComment\lst@EndComment}% - i\@empty{\lst@BeginInvisible\lst@EndInvisible}} -\lst@Key{comment}\relax{\lst@CommentKey\@empty{#1}} -\lst@Key{morecomment}\relax{\lst@CommentKey\relax{#1}} -\lst@Key{deletecomment}\relax{\lst@CommentKey\@nil{#1}} -\lst@Key{commentstyle}{}{\def\lst@commentstyle{#1}} -\lst@AddToHook{EmptyStyle}{\let\lst@commentstyle\itshape} -\gdef\lst@BeginComment{% - \lst@DelimOpen - \lst@ifexcomments\else - \lsthk@AfterBeginComment} -\gdef\lst@EndComment{\lst@DelimClose\lst@ifexcomments\else} -\lst@AddToHook{AfterBeginComment}{} -\lst@AddToHookExe{ExcludeDelims}{\let\lst@ifexcomments\iffalse} -\gdef\lst@BeginInvisible#1#2#3\@empty{% - \lst@TrackNewLines \lst@XPrintToken - \lst@BeginDropOutput{#1}} -\gdef\lst@EndInvisible#1\@empty{\lst@EndDropOutput} -\gdef\lst@CommentDM@l#1#2\@empty#3#4#5{% - \lst@CArg #2\relax\lst@DefDelimB{}{}{}#3{#1}{#5\lst@Lmodetrue}} -\gdef\lst@CommentDM@f#1{% - \@ifnextchar[{\lst@Comment@@f{#1}}% - {\lst@Comment@@f{#1}[0]}} -\gdef\lst@Comment@@f#1[#2]#3\@empty#4#5#6{% - \lst@CArg #3\relax\lst@DefDelimB{}{}% - {\lst@CalcColumn - \ifnum #2=\@tempcnta\else - \expandafter\@gobblethree - \fi}% - #4{#1}{#6\lst@Lmodetrue}} -\gdef\lst@CommentDM@s#1#2#3\@empty#4#5#6{% - \lst@CArg #2\relax\lst@DefDelimB{}{}{}#4{#1}{#6}% - \lst@CArg #3\relax\lst@DefDelimE{}{}{}#5{#1}} -\gdef\lst@CommentDM@n#1#2#3\@empty#4#5#6{% - \ifx\@empty#3\@empty\else - \def\@tempa{#2}\def\@tempb{#3}% - \ifx\@tempa\@tempb - \PackageError{Listings}{Identical delimiters}% - {These delimiters make no sense with nested comments.}% - \else - \lst@CArg #2\relax\lst@DefDelimB - {}% - {\ifnum\lst@mode=#1\relax \expandafter\@gobble \fi}% - {}#4{#1}{#6}% - \lst@CArg #3\relax\lst@DefDelimE{}{}{}#5{#1}% - \fi - \fi} -\lst@EndAspect -\lst@BeginAspect{pod} -\lst@Key{printpod}{false}[t]{\lstKV@SetIf{#1}\lst@ifprintpod} -\lst@Key{podcomment}{false}[t]{\lstKV@SetIf{#1}\lst@ifpodcomment} -\lst@AddToHookExe{SetLanguage}{\let\lst@ifpodcomment\iffalse} -\lst@NewMode\lst@PODmode -\lst@AddToHook{SelectCharTable} - {\lst@ifpodcomment - \lst@CArgX =\relax\lst@DefDelimB{}{}% - {\ifnum\@tempcnta=\z@ - \lst@ifprintpod\else - \def\lst@bnext{\lst@BeginDropOutput\lst@PODmode}% - \expandafter\expandafter\expandafter\@gobblethree - \fi - \else - \expandafter\@gobblethree - \fi}% - \lst@BeginComment\lst@PODmode{{\lst@commentstyle}}% - \lst@CArgX =cut\^^M\relax\lst@DefDelimE - {\lst@CalcColumn}% - {\ifnum\@tempcnta=\z@\else - \expandafter\@gobblethree - \fi}% - {}% - \lst@EndComment\lst@PODmode - \fi} -\lst@EndAspect -\lst@BeginAspect[keywords]{html} -\gdef\lst@tagtypes{s} -\gdef\lst@TagKey#1#2{% - \lst@Delim\lst@tagstyle #2\relax - {Tag}\lst@tagtypes #1% - {\lst@BeginTag\lst@EndTag}% - \@@end\@empty{}} -\lst@Key{tag}\relax{\lst@TagKey\@empty{#1}} -\lst@Key{tagstyle}{}{\def\lst@tagstyle{#1}} -\lst@AddToHook{EmptyStyle}{\let\lst@tagstyle\@empty} -\gdef\lst@BeginTag{% - \lst@DelimOpen - \lst@ifextags\else - {\let\lst@ifkeywords\iftrue - \lst@ifmarkfirstintag \lst@firstintagtrue \fi}} -\lst@AddToHookExe{ExcludeDelims}{\let\lst@ifextags\iffalse} -\gdef\lst@EndTag{\lst@DelimClose\lst@ifextags\else} -\lst@Key{usekeywordsintag}t[t]{\lstKV@SetIf{#1}\lst@ifusekeysintag} -\lst@Key{markfirstintag}f[t]{\lstKV@SetIf{#1}\lst@ifmarkfirstintag} -\gdef\lst@firstintagtrue{\global\let\lst@iffirstintag\iftrue} -\global\let\lst@iffirstintag\iffalse -\lst@AddToHook{PostOutput}{\lst@tagresetfirst} -\lst@AddToHook{Output} - {\gdef\lst@tagresetfirst{\global\let\lst@iffirstintag\iffalse}} -\lst@AddToHook{OutputOther}{\gdef\lst@tagresetfirst{}} -\lst@AddToHook{Output} - {\ifnum\lst@mode=\lst@tagmode - \lst@iffirstintag \let\lst@thestyle\lst@gkeywords@sty \fi - \lst@ifusekeysintag\else \let\lst@thestyle\lst@gkeywords@sty\fi - \fi} -\lst@NewMode\lst@tagmode -\lst@AddToHook{Init}{\global\let\lst@ifnotag\iftrue} -\lst@AddToHook{SelectCharTable}{\let\lst@ifkeywords\lst@ifnotag} -\gdef\lst@Tag@s#1#2\@empty#3#4#5{% - \global\let\lst@ifnotag\iffalse - \lst@CArg #1\relax\lst@DefDelimB {}{}% - {\ifnum\lst@mode=\lst@tagmode \expandafter\@gobblethree \fi}% - #3\lst@tagmode{#5}% - \lst@CArg #2\relax\lst@DefDelimE {}{}{}#4\lst@tagmode}% -\gdef\lst@BeginCDATA#1\@empty{% - \lst@TrackNewLines \lst@PrintToken - \lst@EnterMode\lst@GPmode{}\let\lst@ifmode\iffalse - \lst@mode\lst@tagmode #1\lst@mode\lst@GPmode\relax\lst@modetrue} -\lst@EndAspect -\lst@BeginAspect{escape} -\lst@Key{texcl}{false}[t]{\lstKV@SetIf{#1}\lst@iftexcl} -\lst@AddToHook{TextStyle}{\let\lst@iftexcl\iffalse} -\lst@AddToHook{EOL} - {\ifnum\lst@mode=\lst@TeXLmode - \expandafter\lst@escapeend - \expandafter\lst@LeaveAllModes - \expandafter\lst@ReenterModes - \fi} -\lst@AddToHook{AfterBeginComment} - {\lst@iftexcl \lst@ifLmode \lst@ifdropinput\else - \lst@PrintToken - \lst@LeaveMode \lst@InterruptModes - \lst@EnterMode{\lst@TeXLmode}{\lst@modetrue\lst@commentstyle}% - \expandafter\expandafter\expandafter\lst@escapebegin - \fi \fi \fi} -\lst@NewMode\lst@TeXLmode -\gdef\lst@ActiveCDefX#1{\lst@ActiveCDefX@#1} -\gdef\lst@ActiveCDefX@#1#2#3{ - \catcode`#1\active\lccode`\~=`#1% - \lowercase{\lst@CDefIt~}{#2}{#3}{}} -\gdef\lst@Escape#1#2#3#4{% - \lst@CArgX #1\relax\lst@CDefX - {}% - {\lst@ifdropinput\else - \lst@TrackNewLines\lst@OutputLostSpace \lst@XPrintToken - \lst@InterruptModes - \lst@EnterMode{\lst@TeXmode}{\lst@modetrue}% - \ifx\^^M#2% - \lst@CArg #2\relax\lst@ActiveCDefX - {}% - {\lst@escapeend #4\lst@LeaveAllModes\lst@ReenterModes}% - {\lst@MProcessListing}% - \else - \lst@CArg #2\relax\lst@ActiveCDefX - {}% - {\lst@escapeend #4\lst@LeaveAllModes\lst@ReenterModes - \lst@whitespacefalse}% - {}% - \fi - #3\lst@escapebegin - \fi}% - {}} -\lst@NewMode\lst@TeXmode -\lst@Key{escapebegin}{}{\def\lst@escapebegin{#1}} -\lst@Key{escapeend}{}{\def\lst@escapeend{#1}} -\lst@Key{escapechar}{} - {\ifx\@empty#1\@empty - \let\lst@DefEsc\relax - \else - \def\lst@DefEsc{\lst@Escape{#1}{#1}{}{}}% - \fi} -\lst@AddToHook{TextStyle}{\let\lst@DefEsc\@empty} -\lst@AddToHook{SelectCharTable}{\lst@DefEsc} -\lst@Key{escapeinside}{}{\lstKV@TwoArg{#1}% - {\let\lst@DefEsc\@empty - \ifx\@empty##1@empty\else \ifx\@empty##2\@empty\else - \def\lst@DefEsc{\lst@Escape{##1}{##2}{}{}}% - \fi\fi}} -\lst@Key{mathescape}{false}[t]{\lstKV@SetIf{#1}\lst@ifmathescape} -\lst@AddToHook{SelectCharTable} - {\lst@ifmathescape \lst@Escape{\$}{\$}% - {\setbox\@tempboxa=\hbox\bgroup$}% - {$\egroup \lst@CalcLostSpaceAndOutput}\fi} -\lst@EndAspect -\lst@BeginAspect{keywords} -\global\let\lst@ifsensitive\iftrue % init -\global\let\lst@ifsensitivedefed\iffalse % init % \global -\lst@ifsavemem\else -\gdef\lst@KeywordTest#1#2#3{% - \begingroup \let\lst@UM\@empty - \global\expandafter\let\expandafter\@gtempa - \csname\@lst#1@\the\lst@token\endcsname - \endgroup - \ifx\@gtempa\relax\else - \let\lst@thestyle\@gtempa - \fi} -\gdef\lst@KEYWORDTEST{% - \uppercase\expandafter{\expandafter - \lst@KEYWORDTEST@\the\lst@token}\relax} -\gdef\lst@KEYWORDTEST@#1\relax#2#3#4{% - \begingroup \let\lst@UM\@empty - \global\expandafter\let\expandafter\@gtempa - \csname\@lst#2@#1\endcsname - \endgroup - \ifx\@gtempa\relax\else - \let\lst@thestyle\@gtempa - \fi} -\gdef\lst@WorkingTest#1#2#3{% - \begingroup \let\lst@UM\@empty - \global\expandafter\let\expandafter\@gtempa - \csname\@lst#1@\the\lst@token\endcsname - \endgroup - \@gtempa} -\gdef\lst@WORKINGTEST{% - \uppercase\expandafter{\expandafter - \lst@WORKINGTEST@\the\lst@token}\relax} -\gdef\lst@WORKINGTEST@#1\relax#2#3#4{% - \begingroup \let\lst@UM\@empty - \global\expandafter\let\expandafter\@gtempa - \csname\@lst#2@#1\endcsname - \endgroup - \@gtempa} -\gdef\lst@DefineKeywords#1#2#3{% - \lst@ifsensitive - \def\lst@next{\lst@for#2}% - \else - \def\lst@next{\uppercase\expandafter{\expandafter\lst@for#2}}% - \fi - \lst@next\do - {\expandafter\ifx\csname\@lst#1@##1\endcsname\relax - \global\expandafter\let\csname\@lst#1@##1\endcsname#3% - \fi}} -\gdef\lst@UndefineKeywords#1#2#3{% - \lst@ifsensitivedefed - \def\lst@next{\lst@for#2}% - \else - \def\lst@next{\uppercase\expandafter{\expandafter\lst@for#2}}% - \fi - \lst@next\do - {\expandafter\ifx\csname\@lst#1@##1\endcsname#3% - \global\expandafter\let\csname\@lst#1@##1\endcsname\relax - \fi}} -\fi -\lst@ifsavemem -\gdef\lst@IfOneOutOf#1\relax#2{% - \def\lst@temp##1,#1,##2##3\relax{% - \ifx\@empty##2\else \expandafter\lst@IOOOfirst \fi}% - \def\lst@next{\lst@IfOneOutOf@#1\relax}% - \expandafter\lst@next#2\relax\relax} -\gdef\lst@IfOneOutOf@#1\relax#2#3{% - \ifx#2\relax - \expandafter\@secondoftwo - \else - \expandafter\lst@temp\expandafter,#2,#1,\@empty\relax - \expandafter\lst@next - \fi} -\ifx\iffalse\else\fi -\gdef\lst@IOOOfirst#1\relax#2#3{\fi#2} -\gdef\lst@IFONEOUTOF#1\relax#2{% - \uppercase{\def\lst@temp##1,#1},##2##3\relax{% - \ifx\@empty##2\else \expandafter\lst@IOOOfirst \fi}% - \def\lst@next{\lst@IFONEOUTOF@#1\relax}% - \expandafter\lst@next#2\relax} -\gdef\lst@IFONEOUTOF@#1\relax#2#3{% - \ifx#2\relax - \expandafter\@secondoftwo - \else - \uppercase - {\expandafter\lst@temp\expandafter,#2,#1,\@empty\relax}% - \expandafter\lst@next - \fi} -\gdef\lst@KWTest{% - \begingroup \let\lst@UM\@empty - \expandafter\xdef\expandafter\@gtempa\expandafter{\the\lst@token}% - \endgroup - \expandafter\lst@IfOneOutOf\@gtempa\relax} -\gdef\lst@KeywordTest#1#2#3{\lst@KWTest #2{\let\lst@thestyle#3}{}} -\global\let\lst@KEYWORDTEST\lst@KeywordTest -\gdef\lst@WorkingTest#1#2#3{\lst@KWTest #2#3{}} -\global\let\lst@WORKINGTEST\lst@WorkingTest -\fi -\lst@Key{sensitive}\relax[t]{\lstKV@SetIf{#1}\lst@ifsensitive} -\lst@AddToHook{SetLanguage}{\let\lst@ifsensitive\iftrue} -\lst@AddToHook{Init} - {\lst@ifsensitive\else - \let\lst@KeywordTest\lst@KEYWORDTEST - \let\lst@WorkingTest\lst@WORKINGTEST - \let\lst@IfOneOutOf\lst@IFONEOUTOF - \fi} -\gdef\lst@MakeMacroUppercase#1{% - \ifx\@undefined#1\else \uppercase\expandafter - {\expandafter\def\expandafter#1\expandafter{#1}}% - \fi} -\gdef\lst@InstallTest#1#2#3#4#5#6#7#8{% - \lst@AddToHook{TrackKeywords}{\lst@TrackKeywords{#1}#2#4#6#7#8}% - \lst@AddToHook{PostTrackKeywords}{\lst@PostTrackKeywords#2#3#4#5}} -\lst@AddToHook{Init}{\lsthk@TrackKeywords\lsthk@PostTrackKeywords} -\lst@AddToHook{TrackKeywords} - {\global\let\lst@DoDefineKeywords\@empty}% init -\lst@AddToHook{PostTrackKeywords} - {\lst@DoDefineKeywords - \global\let\lst@DoDefineKeywords\@empty}% init -\lst@AddToHook{Output}{\lst@ifkeywords \lsthk@DetectKeywords \fi} -\lst@AddToHook{DetectKeywords}{}% init -\lst@AddToHook{ModeTrue}{\let\lst@ifkeywords\iffalse} -\lst@AddToHookExe{Init}{\let\lst@ifkeywords\iftrue} -\gdef\lst@InstallTestNow#1#2#3#4#5{% - \@ifundefined{\string#2#1}% - {\global\@namedef{\string#2#1}{}% - \edef\@tempa{% - \noexpand\lst@AddToHook{\ifx#5dDetectKeywords\else Output\fi}% - {\ifx #4w\noexpand\lst@WorkingTest - \else\noexpand\lst@KeywordTest \fi - {#1}\noexpand#2\noexpand#3}}% - \lst@ifsavemem - \@tempa - \else - \@ifundefined{\@lst#1@if@ins}% - {\@tempa \global\@namedef{\@lst#1@if@ins}{}}% - {}% - \fi} - {}} -\gdef\lst@TrackKeywords#1#2#3#4#5#6{% - \lst@false - \def\lst@arg{{#1}#4}% - \expandafter\expandafter\expandafter\lst@TK@ - \expandafter\lst@arg#2\relax\relax - \lst@ifsavemem\else - \def\lst@arg{{#1}#4#2}% - \expandafter\expandafter\expandafter\lst@TK@@ - \expandafter\lst@arg#3\relax\relax - \fi - \lst@if \lst@InstallTestNow{#1}#2#4#5#6\fi} -\gdef\lst@TK@#1#2#3#4{% - \ifx\lst@ifsensitive\lst@ifsensitivedefed - \ifx#3#4\else - \lst@true - \lst@ifsavemem\else - \lst@UndefineKeywords{#1}#4#2% - \lst@AddTo\lst@DoDefineKeywords{\lst@DefineKeywords{#1}#3#2}% - \fi - \fi - \else - \ifx#3\relax\else - \lst@true - \lst@ifsavemem\else - \lst@UndefineKeywords{#1}#4#2% - \lst@AddTo\lst@DoDefineKeywords{\lst@DefineKeywords{#1}#3#2}% - \fi - \fi - \fi - \lst@ifsavemem \ifx#3\relax\else - \lst@ifsensitive\else \lst@MakeMacroUppercase#3\fi - \fi \fi - \ifx#3\relax - \expandafter\@gobblethree - \fi - \lst@TK@{#1}#2} -\gdef\lst@TK@@#1#2#3#4#5{% - \ifx#4\relax - \expandafter\@gobblefour - \else - \lst@IfSubstring{#4#5}#3{}{\lst@UndefineKeywords{#1}#5#2}% - \fi - \lst@TK@@{#1}#2#3} -\lst@AddToHook{InitVars} - {\global\let\lst@ifsensitivedefed\lst@ifsensitive} -\gdef\lst@PostTrackKeywords#1#2#3#4{% - \lst@ifsavemem\else - \global\let#3#1% - \global\let#4#2% - \fi} -\lst@Key{classoffset}\z@{\def\lst@classoffset{#1}} -\gdef\lst@InstallFamily#1#2#3#4#5{% - \lst@Key{#2}\relax{\lst@UseFamily{#2}##1\relax\lst@MakeKeywords}% - \lst@Key{more#2}\relax - {\lst@UseFamily{#2}##1\relax\lst@MakeMoreKeywords}% - \lst@Key{delete#2}\relax - {\lst@UseFamily{#2}##1\relax\lst@DeleteKeywords}% - \ifx\@empty#3\@empty\else - \lst@Key{#3}{#4}{\lstKV@OptArg[\@ne]{##1}% - {\@tempcnta\lst@classoffset \advance\@tempcnta####1\relax - \@namedef{lst@#3\ifnum\@tempcnta=\@ne\else \the\@tempcnta - \fi}{####2}}}% - \fi - \expandafter\lst@InstallFamily@ - \csname\@lst @#2@data\expandafter\endcsname - \csname\@lst @#5\endcsname {#1}{#2}{#3}} -\gdef\lst@InstallFamily@#1#2#3#4#5#6#7#8{% - \gdef#1{{#3}{#4}{#5}#2#7}% - \long\def\lst@temp##1{#6}% - \ifx\lst@temp\@gobble - \lst@AddTo#1{s#8}% - \else - \lst@AddTo#1{w#8}% - \global\@namedef{lst@g#4@wp}##1{#6}% - \fi} -\gdef\lst@UseFamily#1{% - \def\lst@family{#1}% - \@ifnextchar[\lst@UseFamily@{\lst@UseFamily@[\@ne]}} -\gdef\lst@UseFamily@[#1]{% - \@tempcnta\lst@classoffset \advance\@tempcnta#1\relax - \lst@ProvideFamily\lst@family - \lst@UseFamily@a - {\lst@family\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}} -\gdef\lst@UseFamily@a#1{% - \expandafter\lst@UseFamily@b - \csname\@lst @#1@list\expandafter\endcsname - \csname\@lst @#1\expandafter\endcsname - \csname\@lst @#1@also\expandafter\endcsname - \csname\@lst @g#1\endcsname} -\gdef\lst@UseFamily@b#1#2#3#4#5\relax#6{\lstKV@XOptArg[]{#5}#6#1#2#3#4} -\gdef\lst@ProvideFamily#1{% - \@ifundefined{lstfam@#1\ifnum\@tempcnta=\@ne\else\the\@tempcnta\fi}% - {\global\@namedef{lstfam@#1\ifnum\@tempcnta=\@ne\else - \the\@tempcnta\fi}{}% - \expandafter\expandafter\expandafter\lst@ProvideFamily@ - \csname\@lst @#1@data\endcsname - {\ifnum\@tempcnta=\@ne\else \the\@tempcnta \fi}}% - {}}% -\gdef\lst@ProvideFamily@#1#2#3#4#5#6#7#8{% - \expandafter\xdef\csname\@lst @g#2#8@sty\endcsname - {\if #6w% - \expandafter\noexpand\csname\@lst @g#2@wp\endcsname{#8}% - \else - \expandafter\noexpand\csname\@lst @#3#8\endcsname - \fi}% - \ifx\@empty#3\@empty\else - \edef\lst@temp{\noexpand\lst@AddToHook{Init}{% - \noexpand\lst@ProvideStyle\expandafter\noexpand - \csname\@lst @#3#8\endcsname\noexpand#4}}% - \lst@temp - \fi - \expandafter\lst@ProvideFamily@@ - \csname\@lst @#2#8@list\expandafter\endcsname - \csname\@lst @#2#8\expandafter\endcsname - \csname\@lst @#2#8@also\expandafter\endcsname - \csname\@lst @g#2#8@list\expandafter\endcsname - \csname\@lst @g#2#8\expandafter\endcsname - \csname\@lst @g#2#8@sty\expandafter\endcsname - {#1}#5#6#7} -\gdef\lst@ProvideFamily@@#1#2#3#4#5#6#7#8{% - \gdef#1{#2#5}\global\let#2\@empty \global\let#3\@empty % init - \gdef#4{#2#5}\global\let#5\@empty % init - \if #8l\relax - \lst@AddToHook{SetLanguage}{\def#1{#2#5}\let#2\@empty}% - \fi - \lst@InstallTest{#7}#1#2#4#5#6} -\gdef\lst@InstallKeywords#1#2#3#4#5{% - \lst@Key{#2}\relax - {\lst@UseFamily{#2}[\@ne]##1\relax\lst@MakeKeywords}% - \lst@Key{more#2}\relax - {\lst@UseFamily{#2}[\@ne]##1\relax\lst@MakeMoreKeywords}% - \lst@Key{delete#2}\relax - {\lst@UseFamily{#2}[\@ne]##1\relax\lst@DeleteKeywords}% - \ifx\@empty#3\@empty\else - \lst@Key{#3}{#4}{\@namedef{lst@#3}{##1}}% - \fi - \expandafter\lst@InstallFamily@ - \csname\@lst @#2@data\expandafter\endcsname - \csname\@lst @#5\endcsname {#1}{#2}{#3}} -\gdef\lst@ProvideStyle#1#2{% - \ifx#1\@undefined \let#1#2% - \else\ifx#1\relax \let#1#2\fi\fi} -\gdef\lst@BuildClassList#1#2,{% - \ifx\relax#2\@empty\else - \ifx\@empty#2\@empty\else - \lst@lExtend#1{\csname\@lst @#2\expandafter\endcsname - \csname\@lst @g#2\endcsname}% - \fi - \expandafter\lst@BuildClassList\expandafter#1 - \fi} -\gdef\lst@DeleteClassesIn#1#2{% - \expandafter\lst@DCI@\expandafter#1#2\relax\relax} -\gdef\lst@DCI@#1#2#3{% - \ifx#2\relax - \expandafter\@gobbletwo - \else - \def\lst@temp##1#2#3##2{% - \lst@lAddTo#1{##1}% - \ifx ##2\relax\else - \expandafter\lst@temp - \fi ##2}% - \let\@tempa#1\let#1\@empty - \expandafter\lst@temp\@tempa#2#3\relax - \fi - \lst@DCI@#1} -\gdef\lst@MakeKeywords[#1]#2#3#4#5#6{% - \def#3{#4#6}\let#4\@empty \let#5\@empty - \lst@MakeMoreKeywords[#1]{#2}#3#4#5#6} -\gdef\lst@MakeMoreKeywords[#1]#2#3#4#5#6{% - \lst@BuildClassList#3#1,\relax,% - \lst@DefOther\lst@temp{,#2}\lst@lExtend#4\lst@temp} -\gdef\lst@DeleteKeywords[#1]#2#3#4#5#6{% - \lst@MakeKeywords[#1]{#2}\@tempa\@tempb#5#6% - \lst@DeleteClassesIn#3\@tempa - \lst@DeleteKeysIn#4\@tempb} -\lst@InstallFamily k{keywords}{keywordstyle}\bfseries{keywordstyle}{}ld -\gdef\lst@DefKeywordstyle#1#2\@nil@{% - \@namedef{lst@keywordstyle\ifnum\@tempcnta=\@ne\else\the\@tempcnta - \fi}{#1#2}}% -\lst@Key{keywordstyle}{\bfseries}{\lstKV@OptArg[\@ne]{#1}% - {\@tempcnta\lst@classoffset \advance\@tempcnta##1\relax - \@ifstar{\lst@DefKeywordstyle{\uppercase\expandafter{% - \expandafter\lst@token - \expandafter{\the\lst@token}}}}% - {\lst@DefKeywordstyle{}}##2\@nil@}} -\lst@Key{ndkeywords}\relax - {\lst@UseFamily{keywords}[\tw@]#1\relax\lst@MakeKeywords}% -\lst@Key{morendkeywords}\relax - {\lst@UseFamily{keywords}[\tw@]#1\relax\lst@MakeMoreKeywords}% -\lst@Key{deletendkeywords}\relax - {\lst@UseFamily{keywords}[\tw@]#1\relax\lst@DeleteKeywords}% -\lst@Key{ndkeywordstyle}\relax{\@namedef{lst@keywordstyle2}{#1}}% -\lst@Key{keywordsprefix}\relax{\lst@DefActive\lst@keywordsprefix{#1}} -\global\let\lst@keywordsprefix\@empty -\lst@AddToHook{SelectCharTable} - {\ifx\lst@keywordsprefix\@empty\else - \expandafter\lst@CArg\lst@keywordsprefix\relax - \lst@CDef{}% - {\lst@ifletter\else - \global\let\lst@prefixkeyword\@empty - \fi}% - {}% - \fi} -\lst@AddToHook{Init}{\global\let\lst@prefixkeyword\relax} -\lst@AddToHook{Output} - {\ifx\lst@prefixkeyword\@empty - \let\lst@thestyle\lst@gkeywords@sty - \global\let\lst@prefixkeyword\relax - \fi}% -\lst@Key{otherkeywords}{}{% - \let\lst@otherkeywords\@empty - \lst@for{#1}\do{% - \lst@MakeActive{##1}% - \lst@lExtend\lst@otherkeywords{% - \expandafter\lst@CArg\lst@temp\relax\lst@CDef - {}\lst@PrintOtherKeyword\@empty}}} -\lst@AddToHook{SelectCharTable}{\lst@otherkeywords} -\gdef\lst@PrintOtherKeyword#1\@empty{% - \lst@XPrintToken - \begingroup - \lst@modetrue \lsthk@TextStyle - \let\lst@ProcessDigit\lst@ProcessLetter - \let\lst@ProcessOther\lst@ProcessLetter - \lst@lettertrue - #1% - \lst@SaveToken - \endgroup -\lst@RestoreToken -\global\let\lst@savedcurrstyle\lst@currstyle -\let\lst@currstyle\lst@gkeywords@sty - \lst@Output -\let\lst@currstyle\lst@savedcurrstyle} -\lst@EndAspect -\lst@BeginAspect[keywords]{emph} -\lst@InstallFamily e{emph}{emphstyle}{}{emphstyle}{}od -\lst@EndAspect -\lst@BeginAspect[keywords]{tex} -\lst@InstallFamily {cs}{texcs}{texcsstyle}\relax{keywordstyle} - {\ifx\lst@lastother\lstum@backslash - \expandafter\let\expandafter\lst@thestyle - \csname lst@texcsstyle#1\endcsname - \fi} - ld -\lst@Key{texcsstyle}\relax - {\@ifstar{\lst@true\lst@DefTexcsstyle}% - {\lst@false\lst@DefTexcsstyle}#1\@nil@} -\gdef\lst@DefTexcsstyle#1\@nil@{% - \let\lst@iftexcsincludebs\lst@if - \lstKV@OptArg[\@ne]{#1}% - {\@tempcnta\lst@classoffset \advance\@tempcnta##1\relax - \@namedef{lst@texcsstyle\ifnum\@tempcnta=\@ne\else - \the\@tempcnta \fi}{##2}}}% -\global\let\lst@iftexcsincludebs\iffalse -\let\lst@iftexcsincludebs\iffalse -\lst@AddToHook{SelectCharTable} -{\lst@iftexcsincludebs \ifx\@empty\lst@texcs\else - \lst@DefSaveDef{`\\}\lsts@texcsbs - {\ifx\lst@lastother\lstum@backslash - \lsts@texcsbs\lst@XPrintToken - \else - \lst@Merge\lsts@texcsbs - \fi}% - \fi \fi} -\lst@EndAspect -\lst@BeginAspect[keywords]{directives} -\lst@NewMode\lst@CDmode -\lst@AddToHook{EOL}{\ifnum\lst@mode=\lst@CDmode \lst@LeaveMode \fi} -\lst@InstallKeywords{d}{directives}{directivestyle}\relax{keywordstyle} - {\ifnum\lst@mode=\lst@CDmode - \let\lst@thestyle\lst@directivestyle - \fi} - ld -\global\let\lst@directives\@empty % init -\lst@AddTo\lst@delimtypes{,directive} -\gdef\lst@Delim@directive#1\@empty#2#3#4{% - \lst@CArg #1\relax\lst@DefDelimB - {\lst@CalcColumn}% - {}% - {\ifnum\@tempcnta=\z@ - \def\lst@bnext{#2\lst@CDmode{#4\lst@Lmodetrue}% - \let\lst@currstyle\lst@directivestyle}% - \fi - \@gobblethree}% - #2\lst@CDmode{#4\lst@Lmodetrue}} -\lst@AddTo\lst@stringtypes{,directive} -\gdef\lst@StringDM@directive#1#2#3\@empty{% - \lst@CArg #2\relax\lst@CDef - {}% - {\let\lst@bnext\lst@CArgEmpty - \ifnum\lst@mode=\lst@CDmode - \def\lst@bnext{\lst@BeginString{#1}}% - \fi - \lst@bnext}% - \@empty - \lst@CArg #3\relax\lst@CDef - {}% - {\let\lst@enext\lst@CArgEmpty - \ifnum #1=\lst@mode - \let\lst@bnext\lst@EndString - \fi - \lst@bnext}% - \@empty} -\lst@EndAspect -\lst@BeginAspect[keywords,comments]{keywordcomments} -\lst@NewMode\lst@KCmode \lst@NewMode\lst@KCSmode -\gdef\lst@BeginKC{\aftergroup\aftergroup\aftergroup\lst@BeginKC@}% -\gdef\lst@BeginKC@{% - \lst@ResetToken - \lst@BeginComment\lst@KCmode{{\lst@commentstyle}\lst@modetrue}% - \@empty}% -\gdef\lst@BeginKCS{\aftergroup\aftergroup\aftergroup\lst@BeginKCS@}% -\gdef\lst@BeginKCS@{% - \lst@ResetToken - \lst@BeginComment\lst@KCSmode{{\lst@commentstyle}\lst@modetrue}% - \@empty}% -\lst@AddToHook{PostOutput}{\lst@KCpost \global\let\lst@KCpost\@empty} -\global\let\lst@KCpost\@empty % init -\gdef\lst@EndKC{\lst@SaveToken \lst@LeaveMode \lst@RestoreToken - \let\lst@thestyle\lst@identifierstyle \lsthk@Output} -\lst@InstallKeywords{kc}{keywordcomment}{}\relax{} - {\ifnum\lst@mode=\lst@KCmode - \edef\lst@temp{\the\lst@token}% - \ifx\lst@temp\lst@KCmatch - \lst@EndKC - \fi - \else - \lst@ifmode\else - \xdef\lst@KCmatch{\the\lst@token}% - \global\let\lst@KCpost\lst@BeginKC - \fi - \fi} - lo -\lst@Key{keywordcommentsemicolon}{}{\lstKV@ThreeArg{#1}% - {\def\lst@KCAkeywordsB{##1}% - \def\lst@KCAkeywordsE{##2}% - \def\lst@KCBkeywordsB{##3}% - \def\lst@KCkeywords{##1##2##3}}} -\lst@AddToHook{SetLanguage}{% - \let\lst@KCAkeywordsB\@empty \let\lst@KCAkeywordsE\@empty - \let\lst@KCBkeywordsB\@empty \let\lst@KCkeywords\@empty} -\lst@AddToHook{SelectCharTable} - {\ifx\lst@KCkeywords\@empty\else - \lst@DefSaveDef{`\;}\lsts@EKC - {\lst@XPrintToken - \ifnum\lst@mode=\lst@KCmode \lst@EndComment\@empty \else - \ifnum\lst@mode=\lst@KCSmode \lst@EndComment\@empty - \fi \fi - \lsts@EKC}% - \fi} -\gdef\lst@KCAWorkB{% - \lst@ifmode\else \global\let\lst@KCpost\lst@BeginKC \fi} -\gdef\lst@KCBWorkB{% - \lst@ifmode\else \global\let\lst@KCpost\lst@BeginKCS \fi} -\gdef\lst@KCAWorkE{\ifnum\lst@mode=\lst@KCmode \lst@EndKC \fi} -\lst@ProvideFamily@@ - \lst@KCAkeywordsB@list\lst@KCAkeywordsB \lst@KC@also - \lst@gKCAkeywordsB@list\lst@gKCAkeywordsB \lst@KCAWorkB - {kcb}owo % prefix, other key, working procedure, Output hook -\lst@ProvideFamily@@ - \lst@KCAkeywordsE@list\lst@KCAkeywordsE \lst@KC@also - \lst@gKCAkeywordsE@list\lst@gKCAkeywordsE \lst@KCAWorkE - {kce}owo -\lst@ProvideFamily@@ - \lst@KCBkeywordsB@list\lst@KCBkeywordsB \lst@KC@also - \lst@gKCBkeywordsB@list\lst@gKCBkeywordsB \lst@KCBWorkB - {kcs}owo -\lst@EndAspect -\lst@BeginAspect[keywords]{index} -\lst@InstallFamily w{index}{indexstyle}\lstindexmacro{indexstyle} - {\csname\@lst @indexstyle#1\expandafter\endcsname - \expandafter{\the\lst@token}} - od -\lst@UserCommand\lstindexmacro#1{\index{{\ttfamily#1}}} -\lst@EndAspect -\lst@BeginAspect[keywords]{procnames} -\gdef\lst@procnametrue{\global\let\lst@ifprocname\iftrue} -\gdef\lst@procnamefalse{\global\let\lst@ifprocname\iffalse} -\lst@AddToHook{Init}{\lst@procnamefalse} -\lst@AddToHook{DetectKeywords} - {\lst@ifprocname - \let\lst@thestyle\lst@procnamestyle - \lst@ifindexproc \csname\@lst @gindex@sty\endcsname \fi - \lst@procnamefalse - \fi} -\lst@Key{procnamestyle}{}{\def\lst@procnamestyle{#1}} -\lst@Key{indexprocnames}{false}[t]{\lstKV@SetIf{#1}\lst@ifindexproc} -\lst@AddToHook{Init}{\lst@ifindexproc \lst@indexproc \fi} -\gdef\lst@indexproc{% - \@ifundefined{lst@indexstyle1}% - {\@namedef{lst@indexstyle1}##1{}}% - {}} -\lst@InstallKeywords w{procnamekeys}{}\relax{} - {\global\let\lst@PNpost\lst@procnametrue} - od -\lst@AddToHook{PostOutput}{\lst@PNpost\global\let\lst@PNpost\@empty} -\global\let\lst@PNpost\@empty % init -\lst@EndAspect -\lst@BeginAspect{style} -\@ifundefined{lststylefiles} - {\lst@UserCommand\lststylefiles{lststy0.sty}}{} -\lst@UserCommand\lstdefinestyle{\lst@DefStyle\iftrue} -\lst@UserCommand\lst@definestyle{\lst@DefStyle\iffalse} -\gdef\lst@DefStyle{\lst@DefDriver{style}{sty}\lstset} -\global\@namedef{lststy@$}{\lsthk@EmptyStyle} -\lst@AddToHook{EmptyStyle}{}% init -\lst@Key{style}\relax{% - \lst@LAS{style}{sty}{[]{#1}}\lst@NoAlias\lststylefiles - \lsthk@SetStyle - {}} -\lst@AddToHook{SetStyle}{}% init -\lst@EndAspect -\lst@BeginAspect{language} -\@ifundefined{lstdriverfiles} - {\lst@UserCommand\lstlanguagefiles{lstlang0.sty}}{} -\lst@UserCommand\lstdefinelanguage{\lst@DefLang\iftrue} -\lst@UserCommand\lst@definelanguage{\lst@DefLang\iffalse} -\gdef\lst@DefLang{\lst@DefDriver{language}{lang}\lstset} -\lstdefinelanguage{}{} -\lst@Key{language}\relax{\lstKV@OptArg[]{#1}% - {\lst@LAS{language}{lang}{[##1]{##2}}\lst@FindAlias\lstlanguagefiles - \lsthk@SetLanguage - {\lst@FindAlias[##1]{##2}% - \let\lst@language\lst@malias - \let\lst@dialect\lst@oalias}}} -\lst@Key{alsolanguage}\relax{\lstKV@OptArg[]{#1}% - {\lst@LAS{language}{lang}{[##1]{##2}}\lst@FindAlias\lstlanguagefiles - {}% - {\lst@FindAlias[##1]{##2}% - \let\lst@language\lst@malias - \let\lst@dialect\lst@oalias}}} -\lst@AddToHook{SetLanguage}{}% init -\lst@UserCommand\lstalias{\@ifnextchar[\lstalias@\lstalias@@} -\gdef\lstalias@[#1]#2{\lstalias@b #2$#1} -\gdef\lstalias@b#1[#2]#3{\lst@NormedNameDef{lsta@#1}{#3$#2}} -\gdef\lstalias@@#1#2{\lst@NormedNameDef{lsta@#1}{#2}} -\lst@Key{defaultdialect}\relax - {\lstKV@OptArg[]{#1}{\lst@NormedNameDef{lstdd@##2}{##1}}} -\gdef\lst@FindAlias[#1]#2{% - \lst@NormedDef\lst@oalias{#1}% - \lst@NormedDef\lst@malias{#2}% - \@ifundefined{lsta@\lst@malias}{}% - {\edef\lst@malias{\csname\@lst a@\lst@malias\endcsname}}% - \ifx\@empty\lst@oalias \@ifundefined{lstdd@\lst@malias}{}% - {\edef\lst@oalias{\csname\@lst dd@\lst@malias\endcsname}}% - \fi - \edef\lst@temp{\lst@malias $\lst@oalias}% - \@ifundefined{lsta@\lst@temp}{}% - {\edef\lst@temp{\csname\@lst a@\lst@temp\endcsname}}% - \expandafter\lst@FindAlias@\lst@temp $} -\gdef\lst@FindAlias@#1$#2${% - \def\lst@malias{#1}\def\lst@oalias{#2}% - \ifx\@empty\lst@oalias \@ifundefined{lstdd@\lst@malias}{}% - {\edef\lst@oalias{\csname\@lst dd@\lst@malias\endcsname}}% - \fi} -\gdef\lst@RequireLanguages#1{% - \lst@Require{language}{lang}{#1}\lst@FindAlias\lstlanguagefiles - \ifx\lst@loadaspects\@empty\else - \lst@RequireAspects\lst@loadaspects - \fi} -\global\let\lstloadlanguages\lst@RequireLanguages -\lst@EndAspect -\lst@BeginAspect{formats} -\@ifundefined{lstformatfiles} - {\lst@UserCommand\lstformatfiles{lstfmt0.sty}}{} -\lst@UserCommand\lstdefineformat{\lst@DefFormat\iftrue} -\lst@UserCommand\lst@defineformat{\lst@DefFormat\iffalse} -\gdef\lst@DefFormat{\lst@DefDriver{format}{fmt}\lst@UseFormat} -\lstdefineformat{}{} -\lst@Key{format}\relax{% - \lst@LAS{format}{fmt}{[]{#1}}\lst@NoAlias\lstformatfiles - \lsthk@SetFormat - {}} -\lst@AddToHook{SetFormat}{\let\lst@fmtformat\@empty}% init -\gdef\lst@fmtSplit#1#2{% - \def\lst@temp##1#2##2\relax##3{% - \ifnum##3=\z@ - \ifx\@empty##2\@empty - \lst@false - \let\lst@fmta#1% - \let\lst@fmtb\@empty - \else - \expandafter\lst@temp#1\relax\@ne - \fi - \else - \def\lst@fmta{##1}\def\lst@fmtb{##2}% - \fi}% - \lst@true - \expandafter\lst@temp#1#2\relax\z@} -\gdef\lst@IfNextCharWhitespace#1#2#3{% - \lst@IfSubstring#3\lst@whitespaces{#1}{#2}#3} -\begingroup -\catcode`\^^I=12\catcode`\^^J=12\catcode`\^^M=12\catcode`\^^L=12\relax% -\lst@DefActive\lst@whitespaces{\ ^^I^^J^^M}% add ^^L -\global\let\lst@whitespaces\lst@whitespaces% -\endgroup -\gdef\lst@fmtIfIdentifier#1{% - \ifx\relax#1\@empty - \expandafter\@secondoftwo - \else - \expandafter\lst@fmtIfIdentifier@\expandafter#1% - \fi} -\gdef\lst@fmtIfIdentifier@#1#2\relax{% - \let\lst@next\@secondoftwo - \ifnum`#1=`_\else - \ifnum`#1<64\else - \ifnum`#1<91\let\lst@next\@firstoftwo\else - \ifnum`#1<97\else - \ifnum`#1<123\let\lst@next\@firstoftwo\else - \fi \fi \fi \fi \fi - \lst@next} -\gdef\lst@fmtIfNextCharIn#1{% - \ifx\@empty#1\@empty \expandafter\@secondoftwo \else - \def\lst@next{\lst@fmtIfNextCharIn@{#1}}% - \expandafter\lst@next\fi} -\gdef\lst@fmtIfNextCharIn@#1#2#3#4{% - \def\lst@temp##1#4##2##3\relax{% - \ifx \@empty##2\expandafter\@secondoftwo - \else \expandafter\@firstoftwo \fi}% - \lst@temp#1#4\@empty\relax{#2}{#3}#4} -\gdef\lst@fmtCDef#1{\lst@fmtCDef@#1} -\gdef\lst@fmtCDef@#1#2#3#4#5#6#7{% - \lst@CDefIt#1{#2}{#3}% - {\lst@fmtIfNextCharIn{#5}{#4#2#3}{#6#4#2#3#7}}% - #4% - {}{}{}} -\gdef\lst@fmtCDefX#1{\lst@fmtCDefX@#1} -\gdef\lst@fmtCDefX@#1#2#3#4#5#6#7{% - \let#4#1% - \ifx\@empty#2\@empty - \def#1{\lst@fmtIfNextCharIn{#5}{#4}{#6#7}}% - \else \ifx\@empty#3\@empty - \def#1##1{% - \ifx##1#2% - \def\lst@next{\lst@fmtIfNextCharIn{#5}{#4##1}% - {#6#7}}% - \else - \def\lst@next{#4##1}% - \fi - \lst@next}% - \else - \def#1{% - \lst@IfNextCharsArg{#2#3}% - {\lst@fmtIfNextCharIn{#5}{\expandafter#4\lst@eaten}% - {#6#7}}% - {\expandafter#4\lst@eaten}}% - \fi \fi} -\gdef\lst@UseFormat#1{% - \def\lst@fmtwhole{#1}% - \lst@UseFormat@} -\gdef\lst@UseFormat@{% - \lst@fmtSplit\lst@fmtwhole,% - \let\lst@fmtwhole\lst@fmtb - \ifx\lst@fmta\@empty\else - \lst@fmtSplit\lst@fmta=% - \ifx\@empty\lst@fmta\else - \expandafter\lstKV@XOptArg\expandafter[\expandafter]% - \expandafter{\lst@fmtb}\lst@UseFormat@b - \fi - \fi - \ifx\lst@fmtwhole\@empty\else - \expandafter\lst@UseFormat@ - \fi} -\gdef\lst@UseFormat@b[#1]#2{% - \def\lst@fmtc{{#1}}\lst@lExtend\lst@fmtc{\expandafter{\lst@fmta}}% - \def\lst@fmtb{#2}% - \lst@fmtSplit\lst@fmtb\string - \ifx\@empty\lst@fmta - \lst@lAddTo\lst@fmtc{{}}% - \else - \lst@lExtend\lst@fmtc{\expandafter - {\expandafter\lst@fmtPre\expandafter{\lst@fmta}}}% - \fi - \ifx\@empty\lst@fmtb - \lst@lAddTo\lst@fmtc{{}}% - \else - \lst@lExtend\lst@fmtc{\expandafter - {\expandafter\lst@fmtPost\expandafter{\lst@fmtb}}}% - \fi - \expandafter\lst@UseFormat@c\lst@fmtc} -\gdef\lst@UseFormat@c#1#2#3#4{% - \lst@fmtIfIdentifier#2\relax - {\lst@fmtIdentifier{#2}% - \lst@if\else \PackageWarning{Listings}% - {Cannot drop identifier in format definition}% - \fi}% - {\lst@if - \lst@lAddTo\lst@fmtformat{\lst@CArgX#2\relax\lst@fmtCDef}% - \else - \lst@lAddTo\lst@fmtformat{\lst@CArgX#2\relax\lst@fmtCDefX}% - \fi - \lst@DefActive\lst@fmtc{#1}% - \lst@lExtend\lst@fmtformat{\expandafter{\lst@fmtc}{#3}{#4}}}} -\lst@AddToHook{SelectCharTable}{\lst@fmtformat} -\global\let\lst@fmtformat\@empty -\gdef\lst@fmtPre#1{% - \lst@PrintToken - \begingroup - \let\newline\lst@fmtEnsureNewLine - \let\space\lst@fmtEnsureSpace - \let\indent\lst@fmtIndent - \let\noindent\lst@fmtNoindent - #1% - \endgroup} -\gdef\lst@fmtPost#1{% - \global\let\lst@fmtPostOutput\@empty - \begingroup - \def\newline{\lst@AddTo\lst@fmtPostOutput\lst@fmtEnsureNewLine}% - \def\space{\aftergroup\lst@fmtEnsurePostSpace}% - \def\indent{\lst@AddTo\lst@fmtPostOutput\lst@fmtIndent}% - \def\noindent{\lst@AddTo\lst@fmtPostOutput\lst@fmtNoindent}% - \aftergroup\lst@PrintToken - #1% - \endgroup} -\lst@AddToHook{Init}{\global\let\lst@fmtPostOutput\@empty} -\lst@AddToHook{PostOutput} - {\lst@fmtPostOutput \global\let\lst@fmtPostOutput\@empty} -\gdef\lst@fmtEnsureSpace{% - \lst@ifwhitespace\else \expandafter\lst@ProcessSpace \fi} -\gdef\lst@fmtEnsurePostSpace{% - \lst@IfNextCharWhitespace{}{\lst@ProcessSpace}} -\lst@Key{fmtindent}{20pt}{\def\lst@fmtindent{#1}} -\newdimen\lst@fmtcurrindent -\lst@AddToHook{InitVars}{\global\lst@fmtcurrindent\z@} -\gdef\lst@fmtIndent{\global\advance\lst@fmtcurrindent\lst@fmtindent} -\gdef\lst@fmtNoindent{\global\advance\lst@fmtcurrindent-\lst@fmtindent} -\gdef\lst@fmtEnsureNewLine{% - \global\advance\lst@newlines\@ne - \global\advance\lst@newlinesensured\@ne - \lst@fmtignoretrue} -\lst@AddToAtTop\lst@DoNewLines{% - \ifnum\lst@newlines>\lst@newlinesensured - \global\advance\lst@newlines-\lst@newlinesensured - \fi - \global\lst@newlinesensured\z@} -\newcount\lst@newlinesensured % global -\lst@AddToHook{Init}{\global\lst@newlinesensured\z@} -\gdef\lst@fmtignoretrue{\let\lst@fmtifignore\iftrue} -\gdef\lst@fmtignorefalse{\let\lst@fmtifignore\iffalse} -\lst@AddToHook{InitVars}{\lst@fmtignorefalse} -\lst@AddToHook{Output}{\lst@fmtignorefalse} -\gdef\lst@fmtUseLostSpace{% - \lst@ifnewline \kern\lst@fmtcurrindent \global\lst@lostspace\z@ - \else - \lst@OldOLS - \fi} -\lst@AddToHook{Init} - {\lst@true - \ifx\lst@fmtformat\@empty \ifx\lst@fmt\@empty \lst@false \fi\fi - \lst@if - \let\lst@OldOLS\lst@OutputLostSpace - \let\lst@OutputLostSpace\lst@fmtUseLostSpace - \let\lst@ProcessSpace\lst@fmtProcessSpace - \fi} -\gdef\lst@fmtProcessSpace{% - \lst@ifletter - \lst@Output - \lst@fmtifignore\else - \lst@AppendOther\lst@outputspace - \fi - \else \lst@ifkeepspaces - \lst@AppendOther\lst@outputspace - \else \ifnum\lst@newlines=\z@ - \lst@AppendSpecialSpace - \else \ifnum\lst@length=\z@ - \global\advance\lst@lostspace\lst@width - \global\advance\lst@pos\m@ne - \else - \lst@AppendSpecialSpace - \fi - \fi \fi \fi - \lst@whitespacetrue} -\lst@InstallTest{f} - \lst@fmt@list\lst@fmt \lst@gfmt@list\lst@gfmt - \lst@gfmt@wp - wd -\gdef\lst@fmt@list{\lst@fmt\lst@gfmt}\global\let\lst@fmt\@empty -\gdef\lst@gfmt@list{\lst@fmt\lst@gfmt}\global\let\lst@gfmt\@empty -\gdef\lst@gfmt@wp{% - \begingroup \let\lst@UM\@empty - \let\lst@PrintToken\@empty - \csname\@lst @fmt$\the\lst@token\endcsname - \endgroup} -\gdef\lst@fmtIdentifier#1#2#3#4{% - \lst@DefOther\lst@fmta{#2}\edef\lst@fmt{\lst@fmt,\lst@fmta}% - \@namedef{\@lst @fmt$\lst@fmta}{#3#4}} -\lst@EndAspect -\lst@BeginAspect{labels} -\lst@Key{numbers}{none}{% - \let\lst@PlaceNumber\@empty - \lstKV@SwitchCases{#1}% - {none&\\% - left&\def\lst@PlaceNumber{\llap{\normalfont - \lst@numberstyle{\thelstnumber}\kern\lst@numbersep}}\\% - right&\def\lst@PlaceNumber{\rlap{\normalfont - \kern\linewidth \kern\lst@numbersep - \lst@numberstyle{\thelstnumber}}}% - }{\PackageError{Listings}{Numbers #1 unknown}\@ehc}} -\lst@Key{numberstyle}{}{\def\lst@numberstyle{#1}} -\lst@Key{numbersep}{10pt}{\def\lst@numbersep{#1}} -\lst@Key{stepnumber}{1}{\def\lst@stepnumber{#1\relax}} -\lst@AddToHook{EmptyStyle}{\let\lst@stepnumber\@ne} -\lst@Key{numberblanklines}{true}[t] - {\lstKV@SetIf{#1}\lst@ifnumberblanklines} -\lst@Key{numberfirstline}{f}[t]{\lstKV@SetIf{#1}\lst@ifnumberfirstline} -\gdef\lst@numberfirstlinefalse{\let\lst@ifnumberfirstline\iffalse} -\lst@Key{firstnumber}{auto}{% - \lstKV@SwitchCases{#1}% - {auto&\let\lst@firstnumber\@undefined\\% - last&\let\lst@firstnumber\c@lstnumber - }{\def\lst@firstnumber{#1\relax}}} -\lst@AddToHook{PreSet}{\let\lst@advancenumber\z@} -\lst@AddToHook{PreInit} - {\ifx\lst@firstnumber\@undefined - \let\lst@firstnumber\lst@firstline - \fi} -\gdef\lst@SetFirstNumber{% - \ifx\lst@firstnumber\@undefined - \@tempcnta 0\csname\@lst no@\lst@intname\endcsname\relax - \ifnum\@tempcnta=\z@ \@tempcnta\lst@firstline - \else \lst@nololtrue \fi - \advance\@tempcnta\lst@advancenumber - \edef\lst@firstnumber{\the\@tempcnta\relax}% - \fi} -\gdef\lst@SaveFirstNumber{% - \expandafter\xdef - \csname\@lst no\ifx\lst@intname\@empty @ \else @\lst@intname\fi - \endcsname{\the\c@lstnumber}} -\newcounter{lstnumber}% \global -\global\c@lstnumber\@ne % init -\renewcommand*\thelstnumber{\@arabic\c@lstnumber} -\lst@AddToHook{EveryPar} - {\global\advance\c@lstnumber\lst@advancelstnum - \global\advance\c@lstnumber\m@ne \refstepcounter{lstnumber}% - \lst@SkipOrPrintLabel}% -\global\let\lst@advancelstnum\@ne -\lst@AddToHook{Init}{\def\@currentlabel{\thelstnumber}} -\lst@AddToHook{InitVars} - {\global\c@lstnumber\lst@firstnumber - \global\advance\c@lstnumber\lst@advancenumber - \global\advance\c@lstnumber-\lst@advancelstnum - \ifx \lst@firstnumber\c@lstnumber - \global\advance\c@lstnumber-\lst@advancelstnum - \fi} -\lst@AddToHook{ExitVars} - {\global\advance\c@lstnumber\lst@advancelstnum} -\AtBeginDocument{% - \def\theHlstnumber{\ifx\lst@@caption\@empty \lst@neglisting - \else \thelstlisting \fi - .\thelstnumber}} -\newcount\lst@skipnumbers % \global -\lst@AddToHook{Init} - {\ifnum \z@>\lst@stepnumber - \let\lst@advancelstnum\m@ne - \edef\lst@stepnumber{-\lst@stepnumber}% - \fi - \ifnum \z@<\lst@stepnumber - \global\lst@skipnumbers\lst@firstnumber - \global\divide\lst@skipnumbers\lst@stepnumber - \global\multiply\lst@skipnumbers-\lst@stepnumber - \global\advance\lst@skipnumbers\lst@firstnumber - \ifnum\lst@skipnumbers>\z@ - \global\advance\lst@skipnumbers -\lst@stepnumber - \fi - \else - \let\lst@SkipOrPrintLabel\relax - \fi} -\gdef\lst@SkipOrPrintLabel{% - \ifnum\lst@skipnumbers=\z@ - \global\advance\lst@skipnumbers-\lst@stepnumber\relax - \lst@PlaceNumber - \lst@numberfirstlinefalse - \else - \lst@ifnumberfirstline - \lst@PlaceNumber - \lst@numberfirstlinefalse - \fi - \fi - \global\advance\lst@skipnumbers\@ne}% -\lst@AddToHook{OnEmptyLine}{% - \lst@ifnumberblanklines\else \ifnum\lst@skipnumbers=\z@ - \global\advance\lst@skipnumbers-\lst@stepnumber\relax - \fi\fi} -\lst@EndAspect -\lst@BeginAspect{lineshape} -\lst@Key{xleftmargin}{\z@}{\def\lst@xleftmargin{#1}} -\lst@Key{xrightmargin}{\z@}{\def\lst@xrightmargin{#1}} -\lst@Key{resetmargins}{false}[t]{\lstKV@SetIf{#1}\lst@ifresetmargins} -\lst@AddToHook{BoxUnsafe}{\let\lst@xleftmargin\z@ - \let\lst@xrightmargin\z@} -\lst@AddToHook{TextStyle}{% - \let\lst@xleftmargin\z@ \let\lst@xrightmargin\z@ - \let\lst@ifresetmargins\iftrue} -\lst@Key{linewidth}\linewidth{\def\lst@linewidth{#1}} -\lst@AddToHook{PreInit}{\linewidth\lst@linewidth\relax} -\gdef\lst@parshape{% - \parshape\@ne \@totalleftmargin \linewidth} -\lst@AddToHook{Init} - {\lst@ifresetmargins - \advance\linewidth\@totalleftmargin - \advance\linewidth\rightmargin - \@totalleftmargin\z@ - \fi - \advance\linewidth-\lst@xleftmargin - \advance\linewidth-\lst@xrightmargin - \advance\@totalleftmargin\lst@xleftmargin\relax} -\lst@Key{lineskip}{\z@}{\def\lst@lineskip{#1\relax}} -\lst@AddToHook{Init} - {\parskip\z@ - \ifdim\z@=\lst@lineskip\else - \@tempdima\baselineskip - \advance\@tempdima\lst@lineskip - \multiply\@tempdima\@cclvi - \divide\@tempdima\baselineskip\relax - \multiply\@tempdima\@cclvi - \edef\baselinestretch{\strip@pt\@tempdima}% - \selectfont - \fi} -\lst@Key{breaklines}{false}[t]{\lstKV@SetIf{#1}\lst@ifbreaklines} -\lst@Key{breakindent}{20pt}{\def\lst@breakindent{#1}} -\lst@Key{breakautoindent}{t}[t]{\lstKV@SetIf{#1}\lst@ifbreakautoindent} -\lst@Key{breakatwhitespace}{false}[t]% - {\lstKV@SetIf{#1}\lst@ifbreakatwhitespace} -\lst@Key{prebreak}{}{\def\lst@prebreak{#1}} -\lst@Key{postbreak}{}{\def\lst@postbreak{#1}} -\lst@AddToHook{Init} - {\lst@ifbreaklines - \hbadness\@M \pretolerance\@M - \@rightskip\@flushglue \rightskip\@rightskip % \raggedright - \leftskip\z@skip \parindent\z@ - \def\lst@parshape{\parshape\tw@ \@totalleftmargin\linewidth - \lst@breakshape}% - \else - \let\lst@discretionary\@empty - \fi} -\lst@AddToHook{OnNewLine} - {\lst@ifbreaklines \lst@breakNewLine \fi} -\gdef\lst@discretionary{% - \lst@ifbreakatwhitespace - \lst@ifwhitespace \lst@@discretionary \fi - \else - \lst@@discretionary - \fi}% -\gdef\lst@@discretionary{% - \discretionary{\let\space\lst@spacekern\lst@prebreak}% - {\llap{\lsthk@EveryLine - \kern\lst@breakcurrindent \kern-\@totalleftmargin}% - \let\space\lst@spacekern\lst@postbreak}{}} -\lst@AddToHook{PostOutput}{\lst@discretionary} -\gdef\lst@spacekern{\kern\lst@width} -\gdef\lst@breakNewLine{% - \@tempdima\lst@breakindent\relax - \lst@ifbreakautoindent \advance\@tempdima\lst@lostspace \fi - \@tempdimc-\@tempdima \advance\@tempdimc\linewidth - \advance\@tempdima\@totalleftmargin - \xdef\lst@breakshape{\noexpand\lst@breakcurrindent \the\@tempdimc}% - \xdef\lst@breakcurrindent{\the\@tempdima}} -\global\let\lst@breakcurrindent\z@ % init -\gdef\lst@breakshape{\@totalleftmargin \linewidth} -\gdef\lst@breakProcessOther#1{\lst@ProcessOther#1\lst@OutputOther} -\lst@AddToHook{SelectCharTable} - {\lst@ifbreaklines \lst@Def{`)}{\lst@breakProcessOther)}\fi} -\lst@EndAspect -\lst@BeginAspect[lineshape]{frames} -\lst@Key{framexleftmargin}{\z@}{\def\lst@framexleftmargin{#1}} -\lst@Key{framexrightmargin}{\z@}{\def\lst@framexrightmargin{#1}} -\lst@Key{framextopmargin}{\z@}{\def\lst@framextopmargin{#1}} -\lst@Key{framexbottommargin}{\z@}{\def\lst@framexbottommargin{#1}} -\lst@Key{backgroundcolor}{}{\def\lst@bkgcolor{#1}} -\lst@Key{fillcolor}{}{\def\lst@fillcolor{#1}} -\lst@Key{rulecolor}{}{\def\lst@rulecolor{#1}} -\lst@Key{rulesepcolor}{}{\def\lst@rulesepcolor{#1}} -\lst@AddToHook{Init}{% - \ifx\lst@fillcolor\@empty - \let\lst@fillcolor\lst@bkgcolor - \fi - \ifx\lst@rulesepcolor\@empty - \let\lst@rulesepcolor\lst@fillcolor - \fi} -\lst@Key{rulesep}{2pt}{\def\lst@rulesep{#1}} -\lst@Key{framerule}{.4pt}{\def\lst@framerulewidth{#1}} -\lst@Key{framesep}{3pt}{\def\lst@frametextsep{#1}} -\lst@Key{frameshape}{}{% - \let\lst@xrulecolor\@empty - \lstKV@FourArg{#1}% - {\uppercase{\def\lst@frametshape{##1}}% - \uppercase{\def\lst@framelshape{##2}}% - \uppercase{\def\lst@framershape{##3}}% - \uppercase{\def\lst@framebshape{##4}}% - \let\lst@ifframeround\iffalse - \lst@IfSubstring R\lst@frametshape{\let\lst@ifframeround\iftrue}{}% - \lst@IfSubstring R\lst@framebshape{\let\lst@ifframeround\iftrue}{}% - \def\lst@frame{##1##2##3##4}}} -\lst@Key{frameround}\relax - {\uppercase{\def\lst@frameround{#1}}% - \expandafter\lstframe@\lst@frameround ffff\relax} -\global\let\lst@frameround\@empty -\lst@Key{frame}\relax{% - \let\lst@xrulecolor\@empty - \lstKV@SwitchCases{#1}% - {none&\let\lst@frame\@empty\\% - leftline&\def\lst@frame{l}\\% - topline&\def\lst@frame{t}\\% - bottomline&\def\lst@frame{b}\\% - lines&\def\lst@frame{tb}\\% - single&\def\lst@frame{trbl}\\% - shadowbox&\def\lst@frame{tRBl}% - \def\lst@xrulecolor{\lst@rulesepcolor}% - \def\lst@rulesep{\lst@frametextsep}% - }{\def\lst@frame{#1}}% - \expandafter\lstframe@\lst@frameround ffff\relax} -\gdef\lstframe@#1#2#3#4#5\relax{% - \lst@IfSubstring T\lst@frame{\edef\lst@frame{t\lst@frame}}{}% - \lst@IfSubstring R\lst@frame{\edef\lst@frame{r\lst@frame}}{}% - \lst@IfSubstring B\lst@frame{\edef\lst@frame{b\lst@frame}}{}% - \lst@IfSubstring L\lst@frame{\edef\lst@frame{l\lst@frame}}{}% - \let\lst@frametshape\@empty \let\lst@framebshape\@empty - \lst@frameCheck - ltr\lst@framelshape\lst@frametshape\lst@framershape #4#1% - \lst@frameCheck - LTR\lst@framelshape\lst@frametshape\lst@framershape #4#1% - \lst@frameCheck - lbr\lst@framelshape\lst@framebshape\lst@framershape #3#2% - \lst@frameCheck - LBR\lst@framelshape\lst@framebshape\lst@framershape #3#2% - \let\lst@ifframeround\iffalse - \lst@IfSubstring R\lst@frametshape{\let\lst@ifframeround\iftrue}{}% - \lst@IfSubstring R\lst@framebshape{\let\lst@ifframeround\iftrue}{}% - \let\lst@framelshape\@empty \let\lst@framershape\@empty - \lst@IfSubstring L\lst@frame - {\def\lst@framelshape{YY}}% - {\lst@IfSubstring l\lst@frame{\def\lst@framelshape{Y}}{}}% - \lst@IfSubstring R\lst@frame - {\def\lst@framershape{YY}}% - {\lst@IfSubstring r\lst@frame{\def\lst@framershape{Y}}{}}} -\gdef\lst@frameCheck#1#2#3#4#5#6#7#8{% - \lst@IfSubstring #1\lst@frame - {\if #7T\def#4{R}\else \def#4{Y}\fi}% - {\def#4{N}}% - \lst@IfSubstring #3\lst@frame - {\if #8T\def#6{R}\else \def#6{Y}\fi}% - {\def#6{N}}% - \lst@IfSubstring #2\lst@frame{\edef#5{#5#4Y#6}}{}} -\lst@AddToHook{TextStyle} - {\let\lst@frame\@empty - \let\lst@frametshape\@empty - \let\lst@framershape\@empty - \let\lst@framebshape\@empty - \let\lst@framelshape\@empty} -\gdef\lst@frameMakeBoxV#1#2#3{% - \setbox#1\hbox{% - \color@begingroup \lst@rulecolor - \llap{\setbox\z@\hbox{\vrule\@width\z@\@height#2\@depth#3% - \lst@frameL}% - \rlap{\lst@frameBlock\lst@rulesepcolor{\wd\z@}% - {\ht\z@}{\dp\z@}}% - \box\z@ - \ifx\lst@framelshape\@empty - \kern\lst@frametextsep\relax - \else - \lst@frameBlock\lst@fillcolor\lst@frametextsep{#2}{#3}% - \fi - \kern\lst@framexleftmargin}% - \rlap{\kern-\lst@framexleftmargin - \@tempdima\linewidth - \advance\@tempdima\lst@framexleftmargin - \advance\@tempdima\lst@framexrightmargin - \lst@frameBlock\lst@bkgcolor\@tempdima{#2}{#3}% - \ifx\lst@framershape\@empty - \kern\lst@frametextsep\relax - \else - \lst@frameBlock\lst@fillcolor\lst@frametextsep{#2}{#3}% - \fi - \setbox\z@\hbox{\vrule\@width\z@\@height#2\@depth#3% - \lst@frameR}% - \rlap{\lst@frameBlock\lst@rulesepcolor{\wd\z@}% - {\ht\z@}{\dp\z@}}% - \box\z@}% - \color@endgroup}} -\gdef\lst@frameBlock#1#2#3#4{% - \color@begingroup - #1% - \setbox\z@\hbox{\vrule\@height#3\@depth#4% - \ifx#1\@empty \@width\z@ \kern#2\relax - \else \@width#2\relax \fi}% - \box\z@ - \color@endgroup} -\gdef\lst@frameR{% - \expandafter\lst@frameR@\lst@framershape\relax - \kern-\lst@rulesep} -\gdef\lst@frameR@#1{% - \ifx\relax#1\@empty\else - \if #1Y\lst@framevrule \else \kern\lst@framerulewidth \fi - \kern\lst@rulesep - \expandafter\lst@frameR@b - \fi} -\gdef\lst@frameR@b#1{% - \ifx\relax#1\@empty - \else - \if #1Y\color@begingroup - \lst@xrulecolor - \lst@framevrule - \color@endgroup - \else - \kern\lst@framerulewidth - \fi - \kern\lst@rulesep - \expandafter\lst@frameR@ - \fi} -\gdef\lst@frameL{% - \kern-\lst@rulesep - \expandafter\lst@frameL@\lst@framelshape\relax} -\gdef\lst@frameL@#1{% - \ifx\relax#1\@empty\else - \kern\lst@rulesep - \if#1Y\lst@framevrule \else \kern\lst@framerulewidth \fi - \expandafter\lst@frameL@ - \fi} -\gdef\lst@frameH#1#2{% - \global\let\lst@framediml\z@ \global\let\lst@framedimr\z@ - \setbox\z@\hbox{}\@tempcntb\z@ - \expandafter\lst@frameH@\expandafter#1#2\relax\relax\relax - \@tempdimb\lst@frametextsep\relax - \advance\@tempdimb\lst@framerulewidth\relax - \@tempdimc-\@tempdimb - \advance\@tempdimc\ht\z@ - \advance\@tempdimc\dp\z@ - \setbox\z@=\hbox{% - \lst@frameHBkg\lst@fillcolor\@tempdimb\@firstoftwo - \if#1T\rlap{\raise\dp\@tempboxa\box\@tempboxa}% - \else\rlap{\lower\ht\@tempboxa\box\@tempboxa}\fi - \lst@frameHBkg\lst@rulesepcolor\@tempdimc\@secondoftwo - \advance\@tempdimb\ht\@tempboxa - \if#1T\rlap{\raise\lst@frametextsep\box\@tempboxa}% - \else\rlap{\lower\@tempdimb\box\@tempboxa}\fi - \rlap{\box\z@}% - }} -\gdef\lst@frameH@#1#2#3#4{% - \ifx\relax#4\@empty\else - \lst@frameh \@tempcntb#1#2#3#4% - \advance\@tempcntb\@ne - \expandafter\lst@frameH@\expandafter#1% - \fi} -\gdef\lst@frameHBkg#1#2#3{% - \setbox\@tempboxa\hbox{% - \kern-\lst@framexleftmargin - #3{\kern-\lst@framediml\relax}{\@tempdima\z@}% - \ifdim\lst@framediml>\@tempdimb - #3{\@tempdima\lst@framediml \advance\@tempdima-\@tempdimb - \lst@frameBlock\lst@rulesepcolor\@tempdima\@tempdimb\z@}% - {\kern-\lst@framediml - \advance\@tempdima\lst@framediml\relax}% - \fi - #3{\@tempdima\z@ - \ifx\lst@framelshape\@empty\else - \advance\@tempdima\@tempdimb - \fi - \ifx\lst@framershape\@empty\else - \advance\@tempdima\@tempdimb - \fi}% - {\ifdim\lst@framedimr>\@tempdimb - \advance\@tempdima\lst@framedimr\relax - \fi}% - \advance\@tempdima\linewidth - \advance\@tempdima\lst@framexleftmargin - \advance\@tempdima\lst@framexrightmargin - \lst@frameBlock#1\@tempdima#2\z@ - #3{\ifdim\lst@framedimr>\@tempdimb - \@tempdima-\@tempdimb - \advance\@tempdima\lst@framedimr\relax - \lst@frameBlock\lst@rulesepcolor\@tempdima\@tempdimb\z@ - \fi}{}% - }} -\gdef\lst@frameh#1#2#3#4#5{% - \lst@frameCalcDimA#1% - \lst@ifframeround \@getcirc\@tempdima \fi - \setbox\z@\hbox{% - \begingroup - \setbox\z@\hbox{% - \kern-\lst@framexleftmargin - \color@begingroup - \ifnum#1=\z@ \lst@rulecolor \else \lst@xrulecolor \fi - \lst@frameCornerX\llap{#2L}#3#1% - \ifdim\lst@framediml<\@tempdimb - \xdef\lst@framediml{\the\@tempdimb}% - \fi - \begingroup - \if#4Y\else \let\lst@framerulewidth\z@ \fi - \@tempdima\lst@framexleftmargin - \advance\@tempdima\lst@framexrightmargin - \advance\@tempdima\linewidth - \vrule\@width\@tempdima\@height\lst@framerulewidth \@depth\z@ - \endgroup - \lst@frameCornerX\rlap{#2R}#5#1% - \ifdim\lst@framedimr<\@tempdimb - \xdef\lst@framedimr{\the\@tempdimb}% - \fi - \color@endgroup}% - \if#2T\rlap{\raise\dp\z@\box\z@}% - \else\rlap{\lower\ht\z@\box\z@}\fi - \endgroup - \box\z@}} -\gdef\lst@frameCornerX#1#2#3#4{% - \setbox\@tempboxa\hbox{\csname\@lst @frame\if#3RR\fi #2\endcsname}% - \@tempdimb\wd\@tempboxa - \if #3R% - #1{\box\@tempboxa}% - \else - \if #3Y\expandafter#1\else - \@tempdimb\z@ \expandafter\vphantom \fi - {\box\@tempboxa}% - \fi} -\gdef\lst@frameCalcDimA#1{% - \@tempdima\lst@rulesep - \advance\@tempdima\lst@framerulewidth - \multiply\@tempdima#1\relax - \advance\@tempdima\lst@frametextsep - \advance\@tempdima\lst@framerulewidth - \multiply\@tempdima\tw@} -\lst@AddToHook{Init}{\lst@frameInit} -\newbox\lst@framebox -\gdef\lst@frameInit{% - \ifx\lst@framelshape\@empty \let\lst@frameL\@empty \fi - \ifx\lst@framershape\@empty \let\lst@frameR\@empty \fi - \def\lst@framevrule{\vrule\@width\lst@framerulewidth\relax}% - \lst@ifframeround - \lst@frameCalcDimA\z@ \@getcirc\@tempdima - \@tempdimb\@tempdima \divide\@tempdimb\tw@ - \advance\@tempdimb -\@wholewidth - \edef\lst@frametextsep{\the\@tempdimb}% - \edef\lst@framerulewidth{\the\@wholewidth}% - \lst@frameCalcDimA\@ne \@getcirc\@tempdima - \@tempdimb\@tempdima \divide\@tempdimb\tw@ - \advance\@tempdimb -\tw@\@wholewidth - \advance\@tempdimb -\lst@frametextsep - \edef\lst@rulesep{\the\@tempdimb}% - \fi - \lst@frameMakeBoxV\lst@framebox{\ht\strutbox}{\dp\strutbox}% - \def\lst@framelr{\copy\lst@framebox}% - \ifx\lst@frametshape\@empty\else - \lst@frameH T\lst@frametshape - \ifvoid\z@\else - \par\lst@parshape - \@tempdima-\baselineskip \advance\@tempdima\ht\z@ - \ifdim\prevdepth<\@cclvi\p@\else - \advance\@tempdima\prevdepth - \fi - \ifdim\@tempdima<\z@ - \vskip\@tempdima\vskip\lineskip - \fi - \noindent\box\z@\par - \lineskiplimit\maxdimen \lineskip\z@ - \fi - \lst@frameSpreadV\lst@framextopmargin - \fi} -\lst@AddToHook{EveryLine}{\lst@framelr} -\global\let\lst@framelr\@empty -\lst@AddToHook{DeInit} - {\ifx\lst@framebshape\@empty\else \lst@frameExit \fi} -\gdef\lst@frameExit{% - \lst@frameSpreadV\lst@framexbottommargin - \lst@frameH B\lst@framebshape - \ifvoid\z@\else - \everypar{}\par\lst@parshape\nointerlineskip\noindent\box\z@ - \fi} -\gdef\lst@frameSpreadV#1{% - \ifdim\z@=#1\else - \everypar{}\par\lst@parshape\nointerlineskip\noindent - \lst@frameMakeBoxV\z@{#1}{\z@}% - \box\z@ - \fi} -\gdef\lst@frameTR{% - \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@ - \kern-\lst@framerulewidth - \raise\lst@framerulewidth\hbox{% - \vrule\@width\lst@framerulewidth\@height\z@\@depth.5\@tempdima}} -\gdef\lst@frameBR{% - \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@ - \kern-\lst@framerulewidth - \vrule\@width\lst@framerulewidth\@height.5\@tempdima\@depth\z@} -\gdef\lst@frameBL{% - \vrule\@width\lst@framerulewidth\@height.5\@tempdima\@depth\z@ - \kern-\lst@framerulewidth - \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@} -\gdef\lst@frameTL{% - \raise\lst@framerulewidth\hbox{% - \vrule\@width\lst@framerulewidth\@height\z@\@depth.5\@tempdima}% - \kern-\lst@framerulewidth - \vrule\@width.5\@tempdima\@height\lst@framerulewidth\@depth\z@} -\gdef\lst@frameRoundT{% - \setbox\@tempboxa\hbox{\@circlefnt\char\@tempcnta}% - \ht\@tempboxa\lst@framerulewidth - \box\@tempboxa} -\gdef\lst@frameRoundB{% - \setbox\@tempboxa\hbox{\@circlefnt\char\@tempcnta}% - \dp\@tempboxa\z@ - \box\@tempboxa} -\gdef\lst@frameRTR{% - \hb@xt@.5\@tempdima{\kern-\lst@framerulewidth - \kern.5\@tempdima \lst@frameRoundT \hss}} -\gdef\lst@frameRBR{% - \hb@xt@.5\@tempdima{\kern-\lst@framerulewidth - \advance\@tempcnta\@ne \kern.5\@tempdima \lst@frameRoundB \hss}} -\gdef\lst@frameRBL{% - \advance\@tempcnta\tw@ \lst@frameRoundB - \kern-.5\@tempdima} -\gdef\lst@frameRTL{% - \advance\@tempcnta\thr@@\lst@frameRoundT - \kern-.5\@tempdima} -\lst@EndAspect -\lst@BeginAspect[keywords]{make} -\lst@NewMode\lst@makemode -\lst@AddToHook{Output}{% - \ifnum\lst@mode=\lst@makemode - \ifx\lst@thestyle\lst@gkeywords@sty - \lst@makekeytrue - \fi - \fi} -\gdef\lst@makekeytrue{\let\lst@ifmakekey\iftrue} -\gdef\lst@makekeyfalse{\let\lst@ifmakekey\iffalse} -\global\lst@makekeyfalse % init -\lst@Key{makemacrouse}f[t]{\lstKV@SetIf{#1}\lst@ifmakemacrouse} -\gdef\lst@MakeSCT{% - \lst@ifmakemacrouse - \lst@ReplaceInput{$(}{% - \lst@PrintToken - \lst@EnterMode\lst@makemode{\lst@makekeyfalse}% - \lst@Merge{\lst@ProcessOther\$\lst@ProcessOther(}}% - \lst@ReplaceInput{)}{% - \ifnum\lst@mode=\lst@makemode - \lst@PrintToken - \begingroup - \lst@ProcessOther)% - \lst@ifmakekey - \let\lst@currstyle\lst@gkeywords@sty - \fi - \lst@OutputOther - \endgroup - \lst@LeaveMode - \else - \expandafter\lst@ProcessOther\expandafter)% - \fi}% - \else - \lst@ReplaceInput{$(}{\lst@ProcessOther\$\lst@ProcessOther(}% - \fi} -\lst@EndAspect -\lst@BeginAspect{0.21} -\lst@Key{labelstyle}{}{\def\lst@numberstyle{#1}} -\lst@Key{labelsep}{10pt}{\def\lst@numbersep{#1}} -\lst@Key{labelstep}{0}{% - \ifnum #1=\z@ \KV@lst@numbers{none}% - \else \KV@lst@numbers{left}\fi - \def\lst@stepnumber{#1\relax}} -\lst@Key{firstlabel}\relax{\def\lst@firstnumber{#1\relax}} -\lst@Key{advancelabel}\relax{\def\lst@advancenumber{#1\relax}} -\let\c@lstlabel\c@lstnumber -\lst@AddToHook{Init}{\def\thelstnumber{\thelstlabel}} -\newcommand*\thelstlabel{\@arabic\c@lstlabel} -\lst@Key{first}\relax{\def\lst@firstline{#1\relax}} -\lst@Key{last}\relax{\def\lst@lastline{#1\relax}} -\lst@Key{framerulewidth}{.4pt}{\def\lst@framerulewidth{#1}} -\lst@Key{framerulesep}{2pt}{\def\lst@rulesep{#1}} -\lst@Key{frametextsep}{3pt}{\def\lst@frametextsep{#1}} -\lst@Key{framerulecolor}{}{\lstKV@OptArg[]{#1}% - {\ifx\@empty##2\@empty - \let\lst@rulecolor\@empty - \else - \ifx\@empty##1\@empty - \def\lst@rulecolor{\color{##2}}% - \else - \def\lst@rulecolor{\color[##1]{##2}}% - \fi - \fi}} -\lst@Key{backgroundcolor}{}{\lstKV@OptArg[]{#1}% - {\ifx\@empty##2\@empty - \let\lst@bkgcolor\@empty - \else - \ifx\@empty##1\@empty - \def\lst@bkgcolor{\color{##2}}% - \else - \def\lst@bkgcolor{\color[##1]{##2}}% - \fi - \fi}} -\lst@Key{framespread}{\z@}{\def\lst@framespread{#1}} -\lst@AddToHook{PreInit} - {\@tempdima\lst@framespread\relax \divide\@tempdima\tw@ - \edef\lst@framextopmargin{\the\@tempdima}% - \let\lst@framexrightmargin\lst@framextopmargin - \let\lst@framexbottommargin\lst@framextopmargin - \advance\@tempdima\lst@xleftmargin\relax - \edef\lst@framexleftmargin{\the\@tempdima}} -\newdimen\lst@innerspread \newdimen\lst@outerspread -\lst@Key{spread}{\z@,\z@}{\lstKV@CSTwoArg{#1}% - {\lst@innerspread##1\relax - \ifx\@empty##2\@empty - \divide\lst@innerspread\tw@\relax - \lst@outerspread\lst@innerspread - \else - \lst@outerspread##2\relax - \fi}} -\lst@AddToHook{BoxUnsafe}{\lst@outerspread\z@ \lst@innerspread\z@} -\lst@Key{wholeline}{false}[t]{\lstKV@SetIf{#1}\lst@ifresetmargins} -\lst@Key{indent}{\z@}{\def\lst@xleftmargin{#1}} -\lst@AddToHook{PreInit} - {\lst@innerspread=-\lst@innerspread - \lst@outerspread=-\lst@outerspread - \ifodd\c@page \advance\lst@innerspread\lst@xleftmargin - \else \advance\lst@outerspread\lst@xleftmargin \fi - \ifodd\c@page - \edef\lst@xleftmargin{\the\lst@innerspread}% - \edef\lst@xrightmargin{\the\lst@outerspread}% - \else - \edef\lst@xleftmargin{\the\lst@outerspread}% - \edef\lst@xrightmargin{\the\lst@innerspread}% - \fi} -\lst@Key{defaultclass}\relax{\def\lst@classoffset{#1}} -\lst@Key{stringtest}\relax{}% dummy -\lst@Key{outputpos}\relax{\lst@outputpos#1\relax\relax} -\lst@Key{stringspaces}\relax[t]{\lstKV@SetIf{#1}\lst@ifshowstringspaces} -\lst@Key{visisblespaces}\relax[t]{\lstKV@SetIf{#1}\lst@ifshowspaces} -\lst@Key{visibletabs}\relax[t]{\lstKV@SetIf{#1}\lst@ifshowtabs} -\lst@EndAspect -\lst@BeginAspect{fancyvrb} -\@ifundefined{FancyVerbFormatLine} - {\typeout{^^J% - ***^^J% - *** `listings.sty' needs `fancyvrb.sty' right now.^^J% - *** Please ensure its availability and try again.^^J% - ***^^J}% - \batchmode \@@end}{} -\gdef\lstFV@fancyvrb{% - \lst@iffancyvrb - \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine\else - \let\lstFV@FVFL\FancyVerbFormatLine - \let\FancyVerbFormatLine\lstFV@FancyVerbFormatLine - \fi - \else - \ifx\lstFV@FVFL\@undefined\else - \let\FancyVerbFormatLine\lstFV@FVFL - \let\lstFV@FVFL\@undefined - \fi - \fi} -\gdef\lstFV@VerbatimBegin{% - \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine - \lsthk@TextStyle \lsthk@BoxUnsafe - \lsthk@PreSet - \lst@activecharsfalse - \let\normalbaselines\relax -\xdef\lstFV@RestoreData{\noexpand\linewidth\the\linewidth\relax}% - \lst@Init\relax - \lst@ifresetmargins \advance\linewidth-\@totalleftmargin \fi -\lstFV@RestoreData - \everypar{}\global\lst@newlines\z@ - \lst@mode\lst@nomode \let\lst@entermodes\@empty - \lst@InterruptModes -%% D.G. modification begin - Nov. 25, 1998 - \let\@noligs\relax -%% D.G. modification end - \fi} -\gdef\lstFV@VerbatimEnd{% - \ifx\FancyVerbFormatLine\lstFV@FancyVerbFormatLine - \global\setbox\lstFV@gtempboxa\box\@tempboxa - \global\let\@gtempa\FV@ProcessLine - \lst@mode\lst@Pmode - \lst@DeInit - \let\FV@ProcessLine\@gtempa - \setbox\@tempboxa\box\lstFV@gtempboxa - \par - \fi} -\newbox\lstFV@gtempboxa -\lst@AddTo\FV@VerbatimBegin\lstFV@VerbatimBegin -\lst@AddToAtTop\FV@VerbatimEnd\lstFV@VerbatimEnd -\lst@AddTo\FV@LVerbatimBegin\lstFV@VerbatimBegin -\lst@AddToAtTop\FV@LVerbatimEnd\lstFV@VerbatimEnd -\lst@AddTo\FV@BVerbatimBegin\lstFV@VerbatimBegin -\lst@AddToAtTop\FV@BVerbatimEnd\lstFV@VerbatimEnd -\gdef\lstFV@FancyVerbFormatLine#1{% - \let\lst@arg\@empty \lst@FVConvert#1\@nil - \global\lst@newlines\z@ - \vtop{\noindent\lst@parshape - \lst@ReenterModes - \lst@arg \lst@PrintToken\lst@EOLUpdate\lsthk@InitVarsBOL - \lst@InterruptModes}} -\lst@Key{fvcmdparams}% - {\overlay\@ne}% - {\def\lst@FVcmdparams{,#1}} -\lst@Key{morefvcmdparams}\relax{\lst@lAddTo\lst@FVcmdparams{,#1}} -\gdef\lst@FVConvert{\@tempcnta\z@ \lst@FVConvertO@}% -\gdef\lst@FVConvertO@{% - \ifcase\@tempcnta - \expandafter\futurelet\expandafter\@let@token - \expandafter\lst@FVConvert@@ - \else - \expandafter\lst@FVConvertO@a - \fi} -\gdef\lst@FVConvertO@a#1{% - \lst@lAddTo\lst@arg{{#1}}\advance\@tempcnta\m@ne - \lst@FVConvertO@}% -\gdef\lst@FVConvert@@{% - \ifcat\noexpand\@let@token\bgroup \expandafter\lst@FVConvertArg - \else \expandafter\lst@FVConvert@ \fi} -\gdef\lst@FVConvertArg#1{% - {\let\lst@arg\@empty - \lst@FVConvert#1\@nil - \global\let\@gtempa\lst@arg}% - \lst@lExtend\lst@arg{\expandafter{\@gtempa\lst@PrintToken}}% - \lst@FVConvert} -\gdef\lst@FVConvert@#1{% - \ifx \@nil#1\else - \if\relax\noexpand#1% - \lst@lAddTo\lst@arg{\lst@OutputLostSpace\lst@PrintToken#1}% - \else - \lccode`\~=`#1\lowercase{\lst@lAddTo\lst@arg~}% - \fi - \expandafter\lst@FVConvert - \fi} -\gdef\lst@FVConvert@#1{% - \ifx \@nil#1\else - \if\relax\noexpand#1% - \lst@lAddTo\lst@arg{\lst@OutputLostSpace\lst@PrintToken#1}% - \def\lst@temp##1,#1##2,##3##4\relax{% - \ifx##3\@empty \else \@tempcnta##2\relax \fi}% - \expandafter\lst@temp\lst@FVcmdparams,#1\z@,\@empty\relax - \else - \lccode`\~=`#1\lowercase{\lst@lAddTo\lst@arg~}% - \fi - \expandafter\lst@FVConvertO@ - \fi} -\lst@EndAspect -\lst@BeginAspect[keywords,comments,strings,language]{lgrind} -\gdef\lst@LGGetNames#1:#2\relax{% - \lst@NormedDef\lstlang@{#1}\lst@ReplaceInArg\lstlang@{|,}% - \def\lst@arg{:#2}} -\gdef\lst@LGGetValue#1{% - \lst@false - \def\lst@temp##1:#1##2##3\relax{% - \ifx\@empty##2\else \lst@LGGetValue@{#1}\fi} - \expandafter\lst@temp\lst@arg:#1\@empty\relax} -\gdef\lst@LGGetValue@#1{% - \lst@true - \def\lst@temp##1:#1##2:##3\relax{% - \@ifnextchar=\lst@LGGetValue@@{\lst@LGGetValue@@=}##2\relax - \def\lst@arg{##1:##3}}% - \expandafter\lst@temp\lst@arg\relax} -\gdef\lst@LGGetValue@@=#1\relax{\def\lst@LGvalue{#1}} -\gdef\lst@LGGetComment#1#2{% - \let#2\@empty - \lst@LGGetValue{#1b}% - \lst@if - \let#2\lst@LGvalue - \lst@LGGetValue{#1e}% - \ifx\lst@LGvalue\lst@LGEOL - \edef\lstlang@{\lstlang@,commentline={#2}}% - \let#2\@empty - \else - \edef#2{{#2}{\lst@LGvalue}}% - \fi - \fi} -\gdef\lst@LGGetString#1#2{% - \lst@LGGetValue{#1b}% - \lst@if - \let#2\lst@LGvalue - \lst@LGGetValue{#1e}% - \ifx\lst@LGvalue\lst@LGEOL - \edef\lstlang@{\lstlang@,morestringizer=[l]{#2}}% - \else - \ifx #2\lst@LGvalue - \edef\lstlang@{\lstlang@,morestringizer=[d]{#2}}% - \else - \edef\lst@temp{\lst@LGe#2}% - \ifx \lst@temp\lst@LGvalue - \edef\lstlang@{\lstlang@,morestringizer=[b]{#2}}% - \else - \PackageWarning{Listings}% - {String #2...\lst@LGvalue\space not supported}% - \fi - \fi - \fi - \fi} -\gdef\lst@LGDefLang{% - \lst@LGReplace - \let\lstlang@\empty - \lst@LGGetValue{kw}% - \lst@if - \lst@ReplaceInArg\lst@LGvalue{{ },}% - \edef\lstlang@{\lstlang@,keywords={\lst@LGvalue}}% - \fi - \lst@LGGetValue{oc}% - \lst@if - \edef\lstlang@{\lstlang@,sensitive=f}% - \fi - \lst@LGGetValue{id}% - \lst@if - \edef\lstlang@{\lstlang@,alsoletter=\lst@LGvalue}% - \fi - \lst@LGGetComment a\lst@LGa - \lst@LGGetComment c\lst@LGc - \ifx\lst@LGa\@empty - \ifx\lst@LGc\@empty\else - \edef\lstlang@{\lstlang@,singlecomment=\lst@LGc}% - \fi - \else - \ifx\lst@LGc\@empty - \edef\lstlang@{\lstlang@,singlecomment=\lst@LGa}% - \else - \edef\lstlang@{\lstlang@,doublecomment=\lst@LGc\lst@LGa}% - \fi - \fi - \lst@LGGetString s\lst@LGa - \lst@LGGetString l\lst@LGa - \lst@LGGetValue{tc}% - \lst@if - \edef\lstlang@{\lstlang@,lgrindef=\lst@LGvalue}% - \fi - \expandafter\xdef\csname\@lst LGlang@\lst@language@\endcsname - {\noexpand\lstset{\lstlang@}}% - \lst@ReplaceInArg\lst@arg{{: :}:}\let\lst@LGvalue\@empty - \expandafter\lst@LGDroppedCaps\lst@arg\relax\relax - \ifx\lst@LGvalue\@empty\else - \PackageWarningNoLine{Listings}{Ignored capabilities for - \space `\lst@language@' are\MessageBreak\lst@LGvalue}% - \fi} -\gdef\lst@LGDroppedCaps#1:#2#3{% - \ifx#2\relax - \lst@RemoveCommas\lst@LGvalue - \else - \edef\lst@LGvalue{\lst@LGvalue,#2#3}% - \expandafter\lst@LGDroppedCaps - \fi} -\begingroup -\catcode`\/=0 -\lccode`\z=`\:\lccode`\y=`\^\lccode`\x=`\$\lccode`\v=`\| -\catcode`\\=12\relax -/lowercase{% -/gdef/lst@LGReplace{/lst@ReplaceInArg/lst@arg - {{\:}{z }{\^}{y}{\$}{x}{\|}{v}{ \ }{ }{:\ :}{:}{\ }{ }{\(}({\)})}} -/gdef/lst@LGe{\e} -} -/endgroup -\gdef\lst@LGRead#1\par{% - \lst@LGGetNames#1:\relax - \def\lst@temp{endoflanguagedefinitions}% - \ifx\lstlang@\lst@temp - \let\lst@next\endinput - \else - \expandafter\lst@IfOneOf\lst@language@\relax\lstlang@ - {\lst@LGDefLang \let\lst@next\endinput}% - {\let\lst@next\lst@LGRead}% - \fi - \lst@next} -\lst@Key{lgrindef}\relax{% - \lst@NormedDef\lst@language@{#1}% - \begingroup - \@ifundefined{lstLGlang@\lst@language@}% - {\everypar{\lst@LGRead}% - \catcode`\\=12\catcode`\{=12\catcode`\}=12\catcode`\%=12% - \catcode`\#=14\catcode`\$=12\catcode`\^=12\catcode`\_=12\relax - \input{\lstlgrindeffile}% - }{}% - \endgroup - \@ifundefined{lstLGlang@\lst@language@}% - {\PackageError{Listings}% - {LGrind language \lst@language@\space undefined}% - {The language is not loadable. \@ehc}}% - {\lsthk@SetLanguage - \csname\@lst LGlang@\lst@language@\endcsname}} -\@ifundefined{lstlgrindeffile} - {\lst@UserCommand\lstlgrindeffile{lgrindef.}}{} -\lst@EndAspect -\lst@BeginAspect[keywords]{hyper} -\lst@Key{hyperanchor}\hyper@@anchor{\let\lst@hyperanchor#1} -\lst@Key{hyperlink}\hyperlink{\let\lst@hyperlink#1} -\lst@InstallKeywords{h}{hyperref}{}\relax{} - {\begingroup - \let\lst@UM\@empty \xdef\@gtempa{\the\lst@token}% - \endgroup - \lst@GetFreeMacro{lstHR@\@gtempa}% - \global\expandafter\let\lst@freemacro\@empty - \@tempcntb\@tempcnta \advance\@tempcntb\m@ne - \edef\lst@alloverstyle##1{% - \let\noexpand\lst@alloverstyle\noexpand\@empty - \noexpand\smash{\raise\baselineskip\hbox - {\noexpand\lst@hyperanchor{lst.\@gtempa\the\@tempcnta}% - {\relax}}}% - \ifnum\@tempcnta=\z@ ##1\else - \noexpand\lst@hyperlink{lst.\@gtempa\the\@tempcntb}{##1}% - \fi}% - } - od -\lst@EndAspect -\endinput -%% -%% End of file `lstmisc.sty'. diff --git a/org.glite.lb.doc/src/lstpatch.sty b/org.glite.lb.doc/src/lstpatch.sty deleted file mode 100644 index b07de3e..0000000 --- a/org.glite.lb.doc/src/lstpatch.sty +++ /dev/null @@ -1,393 +0,0 @@ -%% -%% This is file `lstpatch.sty', generated manually. -%% -%% (w)(c) 2004 Carsten Heinz -%% -%% This file may be distributed under the terms of the LaTeX Project Public -%% License from CTAN archives in directory macros/latex/base/lppl.txt. -%% Either version 1.0 or, at your option, any later version. -%% -%% Send comments and ideas on the package, error reports and additional -%% programming languages to . -%% -%% This patch file will remove the following bugs from the listings package. -%% Each item contains the bug finder with date of report and first bug fix -%% version, a short description of the problem, and the reason for the bug -%% in parenthesis. -%% -%% 1) Frank Atanassow, 2004/10/07, 1.3b -%% -%% space after mathescape is not preserved -%% (\lst@newlines>0) -%% -%% 2) Benjamin Lings, 2004/10/15, 1.3b (2004/10/17) -%% -%% \usepackage{xy,listings} yields: -%% "Forbidden control sequence found while scanning use of \lst@lExtend" -%% (xy-pic correctly resets catcode of ^^L (to active), which is \outer) -%% -%% -%% The following features are added to the base package. -%% -%% 1.3a (2004/09/07) -%% -%% a) H I G H L Y E X P E R I M E N T A L -%% -%% Use the options -%% rangeprefix= -%% rangesuffix= -%% -%% rangebeginprefix= -%% rangebeginsuffix= -%% -%% rangeendprefix= -%% rangeendsuffix= -%% -%% includerangemarker=true|false -%% together with -%% firstline= -%% lastline= -%% or -%% linerange={-, -%% -, ...} -%% The according markers in the source code are -%% -%% for begin respectively end of range. Moreover, one can use -%% includerangemarker=true|false -%% to show or hide the range markers in the output. -%% -%% 1.3b (2004/10/17) -%% -%% b) multicols= (requires loaded multicol package) -%% -%% -\lst@CheckVersion{1.3} -{\typeout{^^J% - ***^^J% - *** This is a patch for listings 1.3, but you're using^^J% - *** version \lst@version.^^J% - ***^^J - *** Patch file not loaded.^^J% - ***^^J}% - \endinput -} -\def\fileversion{1.3b} -\def\filedate{2004/10/17} -\ProvidesFile{lstpatch.sty}[\filedate\space\fileversion\space (Carsten Heinz)] -% -% 0) Insert % after #1. -\def\@@xbitor #1{\@tempcntb \count#1% - \ifnum \@tempcnta =\z@ - \else - \divide\@tempcntb\@tempcnta - \ifodd\@tempcntb \@testtrue\fi - \fi} -% -% 1) Reset \lst@newlines at end of escape. -\def\lstpatch@escape{% -\gdef\lst@Escape##1##2##3##4{% - \lst@CArgX ##1\relax\lst@CDefX - {}% - {\lst@ifdropinput\else - \lst@TrackNewLines\lst@OutputLostSpace \lst@XPrintToken - \lst@InterruptModes - \lst@EnterMode{\lst@TeXmode}{\lst@modetrue}% - \ifx\^^M##2% - \lst@CArg ##2\relax\lst@ActiveCDefX - {}% - {\lst@escapeend ##4\lst@LeaveAllModes\lst@ReenterModes}% - {\lst@MProcessListing}% - \else - \lst@CArg ##2\relax\lst@ActiveCDefX - {}% - {\lst@escapeend ##4\lst@LeaveAllModes\lst@ReenterModes - \lst@newlines\z@ \lst@whitespacefalse}% - {}% - \fi - ##3\lst@escapebegin - \fi}% - {}}% -} -% -% 2) Deactivate \outer definition of ^^L temporarily (inside and outside -% of \lst@ScanChars) and restore \catcode at end of package. -\begingroup \catcode12=\active\let^^L\@empty -\gdef\lst@ScanChars{% - \let\lsts@ssL^^L% - \def^^L{\par}% - \lst@GetChars\lst@RestoreOrigCatcodes\@ne {128}% - \let^^L\lsts@ssL - \lst@GetChars\lst@RestoreOrigExtendedCatcodes{128}{256}} -\endgroup -\lst@lAddTo\lst@RestoreCatcodes{\catcode12\active} -% -% a) Let's start with the options: -\lst@Key{rangeprefix}\relax{\def\lst@rangebeginprefix{#1}% - \def\lst@rangeendprefix{#1}} -\lst@Key{rangesuffix}\relax{\def\lst@rangebeginsuffix{#1}% - \def\lst@rangeendsuffix{#1}} -\lst@Key{rangebeginprefix}{}{\def\lst@rangebeginprefix{#1}} -\lst@Key{rangebeginsuffix}{}{\def\lst@rangebeginsuffix{#1}} -\lst@Key{rangeendprefix}{}{\def\lst@rangeendprefix{#1}} -\lst@Key{rangeendsuffix}{}{\def\lst@rangeendsuffix{#1}} -\lst@Key{includerangemarker}{true}[t]{\lstKV@SetIf{#1}\lst@ifincluderangemarker} -% -% The key is a redefinition of \lst@GLI@ checking for numbers. -\def\lst@GLI@#1-#2-#3\@nil{% - \lst@IfNumber{#1}% - {\ifx\@empty#1\@empty - \let\lst@firstline\@ne - \else - \def\lst@firstline{#1\relax}% - \fi - \ifx\@empty#3\@empty - \def\lst@lastline{9999999\relax}% - \else - \ifx\@empty#2\@empty - \let\lst@lastline\lst@firstline - \else - \def\lst@lastline{#2\relax}% - \fi - \fi}% -% -% If we've found a general marker, we set firstline and lastline to 9999999. -% This prevents (almost) anything to be printed for now. - {\def\lst@firstline{9999999\relax}% - \let\lst@lastline\lst@firstline -% -% We add the prefixes and suffixes to the markers. - \let\lst@rangebegin\lst@rangebeginprefix - \lst@AddTo\lst@rangebegin{#1}\lst@Extend\lst@rangebegin\lst@rangebeginsuffix - \ifx\@empty#3\@empty - \let\lst@rangeend\lst@rangeendprefix - \lst@AddTo\lst@rangeend{#1}\lst@Extend\lst@rangeend\lst@rangeendsuffix - \else - \ifx\@empty#2\@empty - \let\lst@rangeend\@empty - \else - \let\lst@rangeend\lst@rangeendprefix - \lst@AddTo\lst@rangeend{#2}\lst@Extend\lst@rangeend\lst@rangeendsuffix - \fi - \fi -% The following definition will be executed in the SelectCharTable hook -% and here right now if we are already processing a listing. - \global\def\lst@DefRange{\expandafter\lst@CArgX\lst@rangebegin\relax\lst@DefRangeB}% - \ifnum\lst@mode=\lst@Pmode \expandafter\lst@DefRange \fi}} -% \lst@DefRange is not inserted via a hook anymore. Instead it is now called -% directly from \lst@SelectCharTable. This was necessary to get rid of an -% interference with the escape-to-LaTeX-feature. The bug was reported by -% \lsthelper{Michael~Bachmann}{2004/07/21}{Keine label-Referenzierung -% m\"oglich...}. Another chance is due to the same bug: \lst@DefRange is -% redefined globally when the begin of code is found, see below. The bug was -% reported by \lsthelper{Tobias~Rapp}{2004/04/06}{undetected end of range if -% listing crosses page break} \lsthelper{Markus~Luisser}{2004/08/13}{Bug mit -% 'linerangemarker' in umgebrochenen listings} -%\lst@AddToHook{SelectCharTable}{\lst@DefRange} -\lst@AddToHookExe{DeInit}{\global\let\lst@DefRange\@empty} -% -% Actually defining the marker (via \lst@GLI@, \lst@DefRange, \lst@CArgX as -% seen above) is similar to \lst@DefDelimB---except that we unfold the first -% parameter and use different ,

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�%;KDw)eq+4ZSccvbI57^3UU4A-` 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%0AGND93L=g%gIDK!!ysLl`!@s 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

\n"; - $pre = 0; - } - - my $name = text2name($rest); - $anchor{$name}=1; - - $rest =~ s/\"//g; # cut off quotes - $rest =~ s//>/g; - $out = "

$rest

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

, and  statements.
-\def\lst@DefRangeB#1#2{\lst@DefRangeB@#1#2}
-\def\lst@DefRangeB@#1#2#3#4{%
-    \lst@CDef{#1{#2}{#3}}#4{}%
-    {\lst@ifincluderangemarker
-         \lst@LeaveMode
-         \let#1#4%
-         \lst@DefRangeEnd
-         \lst@InitLstNumber
-     \else
-         \@tempcnta\lst@lineno \advance\@tempcnta\@ne
-         \edef\lst@firstline{\the\@tempcnta\relax}%
-         \gdef\lst@OnceAtEOL{\let#1#4\lst@DefRangeEnd}%
-         \lst@InitLstNumber
-     \fi
-	 \global\let\lst@DefRange\lst@DefRangeEnd
-     \lst@CArgEmpty}%
-    \@empty}
-%
-% Modify labels and define |\lst@InitLstNumber| used above.
-% \lsthelper{Omair-Inam~Abdul-Matin}{2004/05/10}{experimental linerange
-% feature does not work with firstnumber}
-\def\lstpatch@labels{%
-\gdef\lst@SetFirstNumber{%
-    \ifx\lst@firstnumber\@undefined
-        \@tempcnta 0\csname\@lst no@\lst@intname\endcsname\relax
-        \ifnum\@tempcnta=\z@ \else
-            \lst@nololtrue
-            \advance\@tempcnta\lst@advancenumber
-            \edef\lst@firstnumber{\the\@tempcnta\relax}%
-        \fi
-    \fi}%
-}
-\lst@AddToAtTop\lsthk@PreInit
-    {\ifx\lst@firstnumber\@undefined
-         \def\lst@firstnumber{\lst@lineno}%
-     \fi}
-\def\lst@InitLstNumber{%
-     \global\c@lstnumber\lst@firstnumber
-     \global\advance\c@lstnumber\lst@advancenumber
-     \global\advance\c@lstnumber-\lst@advancelstnum
-     \ifx \lst@firstnumber\c@lstnumber
-         \global\advance\c@lstnumber-\lst@advancelstnum
-     \fi}
-%
-%    The end-marker is defined if and only if it's not empty. The definition is
-%    similar to \lst@DefDelimE---with the above exceptions and except that we
-%    define the re-entry point \lst@DefRangeE@@ as it is defined in the new
-%    version of \lst@MProcessListing above.
-\def\lst@DefRangeEnd{%
-    \ifx\lst@rangeend\@empty\else
-        \expandafter\lst@CArgX\lst@rangeend\relax\lst@DefRangeE
-    \fi}
-\def\lst@DefRangeE#1#2{\lst@DefRangeE@#1#2}
-\def\lst@DefRangeE@#1#2#3#4{%
-    \lst@CDef{#1#2{#3}}#4{}%
-    {\let#1#4%
-     \edef\lst@lastline{\the\lst@lineno\relax}%
-     \lst@DefRangeE@@}%
-    \@empty}
-\def\lst@DefRangeE@@#1\@empty{%
-    \lst@ifincluderangemarker
-        #1\lst@XPrintToken
-    \fi
-    \lst@LeaveModeToPmode
-    \lst@BeginDropInput{\lst@Pmode}}
-%
-\def\lst@LeaveModeToPmode{%
-    \ifnum\lst@mode=\lst@Pmode
-        \expandafter\lsthk@EndGroup
-    \else
-        \expandafter\egroup\expandafter\lst@LeaveModeToPmode
-    \fi}
-%
-%    Eventually we shouldn't forget to install \lst@OnceAtEOL, which must
-%    also be called in \lst@MSkipToFirst.
-\lst@AddToHook{EOL}{\lst@OnceAtEOL\global\let\lst@OnceAtEOL\@empty}
-\gdef\lst@OnceAtEOL{}% Init
-\def\lst@MSkipToFirst{%
-    \global\advance\lst@lineno\@ne
-    \ifnum \lst@lineno=\lst@firstline
-        \def\lst@next{\lst@LeaveMode \global\lst@newlines\z@
-        \lst@OnceAtEOL \global\let\lst@OnceAtEOL\@empty
-        \lst@InitLstNumber % Added to work with modified \lsthk@PreInit.
-        \lsthk@InitVarsBOL
-        \lst@BOLGobble}%
-        \expandafter\lst@next
-    \fi}
-\def\lst@SkipToFirst{%
-    \ifnum \lst@lineno<\lst@firstline
-        \def\lst@next{\lst@BeginDropInput\lst@Pmode
-        \lst@Let{13}\lst@MSkipToFirst
-        \lst@Let{10}\lst@MSkipToFirst}%
-        \expandafter\lst@next
-    \else
-        \expandafter\lst@BOLGobble
-    \fi}
-%
-%    Finally the service macro \lst@IfNumber:
-\def\lst@IfNumber#1{%
-    \ifx\@empty#1\@empty
-        \let\lst@next\@firstoftwo
-    \else
-        \lst@IfNumber@#1\@nil
-    \fi
-    \lst@next}
-\def\lst@IfNumber@#1#2\@nil{%
-    \let\lst@next\@secondoftwo
-    \ifnum`#1>47\relax \ifnum`#1>57\relax\else
-        \let\lst@next\@firstoftwo
-    \fi\fi}
-%
-% b) The following is known to fail with some keys.
-\lst@Key{multicols}{}{\@tempcnta=0#1\relax\def\lst@multicols{#1}}
-\def\lst@Init#1{%
-    \begingroup
-    \ifx\lst@float\relax\else
-        \edef\@tempa{\noexpand\lst@beginfloat{lstlisting}[\lst@float]}%
-        \expandafter\@tempa
-    \fi
-% chmod begin
-    \ifx\lst@multicols\@empty\else
-        \edef\lst@next{\noexpand\multicols{\lst@multicols}}
-        \expandafter\lst@next
-    \fi
-% chmod end
-    \ifhmode\ifinner \lst@boxtrue \fi\fi
-    \lst@ifbox
-        \lsthk@BoxUnsafe
-        \hbox to\z@\bgroup
-             $\if t\lst@boxpos \vtop
-        \else \if b\lst@boxpos \vbox
-        \else \vcenter \fi\fi
-        \bgroup \par\noindent
-    \else
-        \lst@ifdisplaystyle
-            \lst@EveryDisplay
-            \par\penalty-50\relax
-            \vspace\lst@aboveskip
-        \fi
-    \fi
-    \normalbaselines
-    \abovecaptionskip\lst@abovecaption\relax
-    \belowcaptionskip\lst@belowcaption\relax
-    \lst@MakeCaption t%
-    \lsthk@PreInit \lsthk@Init
-    \lst@ifdisplaystyle
-        \global\let\lst@ltxlabel\@empty
-        \if@inlabel
-            \lst@ifresetmargins
-                \leavevmode
-            \else
-                \xdef\lst@ltxlabel{\the\everypar}%
-                \lst@AddTo\lst@ltxlabel{%
-                    \global\let\lst@ltxlabel\@empty
-                    \everypar{\lsthk@EveryLine\lsthk@EveryPar}}%
-            \fi
-        \fi
-        \everypar\expandafter{\lst@ltxlabel
-                              \lsthk@EveryLine\lsthk@EveryPar}%
-    \else
-        \everypar{}\let\lst@NewLine\@empty
-    \fi
-    \lsthk@InitVars \lsthk@InitVarsBOL
-    \lst@Let{13}\lst@MProcessListing
-    \let\lst@Backslash#1%
-    \lst@EnterMode{\lst@Pmode}{\lst@SelectCharTable}%
-    \lst@InitFinalize}
-\def\lst@DeInit{%
-    \lst@XPrintToken \lst@EOLUpdate
-    \global\advance\lst@newlines\m@ne
-    \lst@ifshowlines
-        \lst@DoNewLines
-    \else
-        \setbox\@tempboxa\vbox{\lst@DoNewLines}%
-    \fi
-    \lst@ifdisplaystyle \par\removelastskip \fi
-    \lsthk@ExitVars\everypar{}\lsthk@DeInit\normalbaselines\normalcolor
-    \lst@MakeCaption b%
-    \lst@ifbox
-        \egroup $\hss \egroup
-        \vrule\@width\lst@maxwidth\@height\z@\@depth\z@
-    \else
-        \lst@ifdisplaystyle
-            \par\penalty-50\vspace\lst@belowskip
-        \fi
-    \fi
-% chmod begin
-    \ifx\lst@multicols\@empty\else
-        \def\lst@next{\global\let\@checkend\@gobble
-                      \endmulticols
-                      \global\let\@checkend\lst@@checkend}
-        \expandafter\lst@next
-    \fi
-% chmod end
-    \ifx\lst@float\relax\else
-        \expandafter\lst@endfloat
-    \fi
-    \endgroup}
-\let\lst@@checkend\@checkend
-%%
-\endinput
-%%
-%% End of file `lstpatch.sty'.
diff --git a/org.glite.lb.doc/src/notification_api.tex b/org.glite.lb.doc/src/notification_api.tex
deleted file mode 100644
index 0543e62..0000000
--- a/org.glite.lb.doc/src/notification_api.tex
+++ /dev/null
@@ -1,226 +0,0 @@
-%
-%% Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-%% See http://www.eu-egee.org/partners for details on the copyright holders.
-%% 
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%% 
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%% 
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%
-% -*- mode: latex -*-
-
-\section{\LB\ Notification API}
-\label{s:Notification-API}
-
-The \LB\ notification API is another kind of \LB\ consumer API which
-provides streaming publish/subscribe model instead of query/response
-model. It is designed to provide the same information and use the same
-query conditions encoding as the consumer API described in
-sec.~\ref{s:Consumer-API}
-
-Basic usage of the \LB\ notification API is described in the \LB
-user's guide (\cite{lbug}) in section ``Tools'' as there is described
-a tool called \verb'glite-lb-notify' which is a command line interface
-wrapper around the \LB\ notification API. Its source code can also
-serve as a complete exaple of the \LB\ notification API usage.
-
-The \LB\ notification API have currently fully implemented C language
-binding and partially implemented C++ binding.
-
-\subsection{Header files}
-\begin{table}[h]
-\begin{tabularx}{\textwidth}{>{\tt}lX}
-glite/lb/notification.h & Prototypes for all notification API functions. \\
-\end{tabularx}
-\end{table}
-
-\subsection{Call semantics}
-The API have two main parts: notification subscription management and
-receiving data. Each subscription (registration of notification) have
-its unique identifier called \emph{Notification ID} represented by
-type \verb'edg_wll_NotifId'. This ID is returned to the caller when
-creating a new notification and it is used by receiver to get data
-from the notification.
-
-The API uses \verb'EDG_WLL_NOTIF_SERVER' context parameter to set the
-source server (\LB server name and port). 
-
-The typical notification workflow consist of 3 tasks:
-\begin{itemize}
- \item Create a new notification registration based on given conditions.
- \item Refresh the registration. Each notification registration is
-  soft-state registration and must be regullarly refreshed by the
-  owner.
- \item Receiving the data from notification. The \LB infrastructure
-  provides data queuing and garanteed delivery (while the registration
-  is valid). 
-\end{itemize}
-
-The client notification library contains a code providing a pool of
-receiving sockets/connections to optimize a parallel receiving of
-notifications.
-
-For complete reference of all API funcions please see the header
-file. The next sessions briefly describe main facts about API
-funcions.
-
-\subsection{Notification subscription and management}
-\begin{itemize}
- \item \emph{New notification} is created using
-  \verb'edg_wll_NotifNew' call. The call needs properly initialized
-  context and returns a unique notification ID. To create a new
-  notification the same encoding of conditions as for the \LB
-  query/response API is used (sec.~\ref{s:queryrec}). 
-
-  \marginpar{\LB 2 and higher}%
-  In version 1.x there is a restriction that at least one particular
-  JobId must be defined. Since \LB 2.0 you can make a registration based
-  on other attributes without referencing a particular JobId (you can
-  select owner, VO, network server).  It is also a feature of \LB 2.0
-  and higer versions, that you can use attributes derived from JDL (VO).
-
- \item \emph {Refresh of a notification}. When a new notification is
-  created using \verb'edg_wll_NotifNew' call, the notification
-  validity parameter is intended to set the refresh period, not the
-  lifetime of the notification itself. The owner of notification must
-  periodically call \verb'edg_wll_NotifRefresh' to ensure validity of
-  the notification. See also next sections.
-
- \item It is possible to \emph{change existing notification} (its conditions) by
-  \verb'edg_wll_NotifChange' call.
-
- \item If the user does not want to receive notifications anymore,
-  \verb'edg_wll_NotifDrop' call \emph{removes the registration} for
-  notifications from \LB server.
-\end{itemize}
-
-\subsection{Receive data}
-To receive data from a notificaton the API provides
-\verb'edg_wll_NotifReceive' call. It returns first incoming
-notification if at least one is available or waits for a new one. The
-maximal waiting time is limited to a specified timeout. You can also set the
-timeout to zero if you want to poll.
-
-If the user wants to move the client receiving the notifications to a different
-machine than where the registration was done, it is possible. The
-client must use the \verb'edg_wll_NotifBind' call to inform the
-notification infrastructure (interlogger) about its location change.
-
-The notification API cleanup procedure should be called when
-finalizing the client (\verb'edg_wll_NotifClosePool' and 
-\verb'edg_wll_NotifCloseFd' calls -- where the later is optional 
--- see the next section).
-
-\subsection{Advanced aspects}
-
-\subsubsection{External versus internal management of notification socket}
-A notification socket used by \verb'edg_wll_NotifReceive' call to
-receive the notifications is automatically created during the
-\verb'edg_wll_NotifNew' or \verb'edg_wll_NotifBind' calls.
-
-It the user wants to use its own socket (for example to be used in
-main select() call) it can be created and closed by the user and set
-as a parameter (fd) to all calls mentioned above.
-
-When using automatically created socket it must be closed explicitly
-by calling \verb'edg_wll_CloseFd'.
-
-\subsubsection{Multiple registrations}
-Each user can register for multiple notifications (call
-\verb'edg_wll_NotifNew' function more than once). Every registration
-gets its own notification ID and must be managed separately (refresh,
-change, drop). But the \verb'edg_wll_NotifReceive' call is common for
-all the registrations created in the same context (all previous
-\verb'edg_wll_NotifNew' calls). 
-
-If the user wants to distinguish between multiple registrations it is
-needed to inspect a notification ID value of each received notification.
-
-A \verb'edg_wll_NotifBind' works in similar way like
-\verb'edg_wll_NotifNew'. For each notification ID it must be called
-once and subsequent \verb'edg_wll_NotifReceive' call will work with
-the whole set of registrations. Will receive a first notification from
-any of registations.
-
-\subsubsection{Operator CHANGED}
-\marginpar{\LB 2 and higher}%
-The notification events are generated by LB server based on primary
-events send by grid components. Each of the primary events (called LB
-events) generates one notification event to be possibly sent to the
-client but not each LB event for example changes the job state. You
-can use notification conditions to filter only the notification
-events you want to receive, for example $job status = done$. If you
-want to receive all job status changes you need to setup a condition
-on job status attribute using special unary operator
-\verb'CHANGED'. Otherwise (without any condition) you will receive
-more events that you want -- even events where job state was not
-changed. Operator \verb'CHANGED' is available since \LB 2.0.
-
-\subsubsection{Returned attributes}
-\marginpar{\LB 2 and higher}%
-Each LB notification contains a structure describing job state
-including job's JDL. For optimization purposes the API user can set
-the JDL flag in \verb'edg_wll_NotifNew' flags parameter to prevent
-sending of unnecessary JDL data with each notification.
-
-\subsubsection{Timeouts}
-A user of the notification API should distinguish between various timeouts:
-\begin{itemize}
-\item \emph{Registration validity timeout.} Each registration is
-soft-state entity which must be refreshed in a given timeout. If there
-is no refresh received by the LB server in validity timeout period the
-registration is dropped. On the other hand for that timeout all events
-are queued in the LB infrastructure for the case of client's temporary
-unavailability.
-
-The registration validity timeout can be set by the user when creating
-a new registration but only to a reasonably short time period. The
-validity of a registration is driven by the refresh process not the
-timeout itself. For a exaple of registration management via the
-refresh calls please see the \verb'glite-lb-notify' source code as
-mentioned above.
-
-\item \emph{Receive call timeout.} The timeout used in the
-\verb'edg_wll_NotifReceive' call is inteded just to control the
-receiving loop. It is the maximum time the API can spend in the call
-before returning the control to user code.
-
-\end{itemize}
-
-\subsection{Registering and receiving notification example}
-
-The following example registers on \LB\ server to receive
-notifications triggered by any event belonging to a
-given user and waits for notification (until \verb'timeout').
-
-%The glite-lb-bkserverd and glite-lb-notif-interlogd daemons have to be running. The first one user registers to, the second one delivers notifications to the example program (as described in \ref{notification}).
-
-First we have to include neccessary headers:
-\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=headers-end\ headers]{notif_example.c}
-
-Define and initialize variables and context. During context
-initialization user's credentials are loaded and environment variable
-\verb'GLITE_WMS_NOTIF_SERVER' is used as a LB notification server:
-\lstinputlisting[title={\bf File:}\lstname,numbers=left,linerange=variables-end\ variables]{notif_example.c} 
-
-
-Set the query record to \emph{all user's jobs}:
-\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=queryrec-end\ queryrec]{notif_example.c}
-
-New registration based on prepared query record is created and a
-unique notification ID is returned: 
-\lstinputlisting[title={\bf File:}\lstname,numbers=left,linerange=register-end\ register]{notif_example.c}
-
-The \verb'edg_wll_NotifReceive' call returns one notification. If no notification is 
-ready for delivery, the call waits until some notification arrival or timeout:
-\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=receive-end\ receive]{notif_example.c}
-
-% Finalizing the client
-
diff --git a/org.glite.lb.doc/src/notify.tex b/org.glite.lb.doc/src/notify.tex
deleted file mode 100644
index 35aa82f..0000000
--- a/org.glite.lb.doc/src/notify.tex
+++ /dev/null
@@ -1,331 +0,0 @@
-%
-%% Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-%% See http://www.eu-egee.org/partners for details on the copyright holders.
-%% 
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%% 
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%% 
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%
-\subsection{glite-lb-notify}
-\label{s:lb-notify}
-
-\verb'glite-lb-notify' is a fairly simple wrapper on the \LB notification API
-(see also \cite{lbdg}).
-It allows to create a notification (with a restricted richness of specifying 
-conditions), bind to it for receiving notifications, and drop it finally.
-
-\LB notification is a user-initiated trigger at the server.
-Whenever a job enters a state matching conditions specified with the notification,
-the current state of the job is sent to the notification client.
-On the other hand, the notification client is a network listener
-which receives server-initiated connections to get the notifications.
-Unless \verb'-s' is specified, the notification library creates the listener
-socket.
-
-Within the notification validity, clients can disappear and even migrate.
-However, only a single active client for a notification is allowed.
-
-\LB server and port to contact must be specified with GLITE\_WMS\_NOTIF\_SERVER 
-environment variable.
-
-\verb'glite-lb-notify' is supported by \LBver{2.x} and newer. In \LBver{1.x}, \verb'glite-lb-notify' 
-with very limited functionality can be found in \verb'examples' directory.
-
-\verb'glite-lb-notify' support these actions:
-
-\begin{tabularx}{\textwidth}{lX}
-\texttt{new} & Create new notification registration.\\
-\texttt{bind} &  Binds an notification registration to a client.\\
-\texttt{refresh} &  Enlarge notification registration validity.\\
-\texttt{receive}  & Binds to an existing notification registration and listen to
-server.\\
-\texttt{drop}     & Drop the notification registration.\\
-\end{tabularx}
-
-For action \verb'new', command usage is:
-
-\begin{verbatim}
-  glite-lb-notify new [ { -s socket_fd | -a fake_addr } -t requested_validity
-           -j jobid  { -o owner | -O }  -n network_server 
-           -v virtual_organization --state state1,state2,... -c -J -B -T -H -f flags]
-\end{verbatim}
-
-For action \verb'bind', command usage is:
-\begin{verbatim}
-  glite-lb-notify bind [ { -s socket_fd | -a fake_addr } -t requested_validity ] 
-           notifid
-\end{verbatim}
-
-For action \verb'refresh', command usage is:
-\begin{verbatim}
-  glite-lb-notify refresh [-t requested_validity ] notifid
-\end{verbatim}
-
-For action \verb'receive', command usage is:
-\begin{verbatim}
-  glite-lb-notify receive  [ { -s socket_fd | -a fake_addr } ] [-t requested_validity ] [-i timeout] [-r ] [-f field1,field2,...] [notifid]
-\end{verbatim}
-
-For action \verb'drop', command usage is:
-\begin{verbatim}
-   glite-lb-notify drop notifid
-\end{verbatim}
-
-where
-
-\begin{tabularx}{\textwidth}{lX}
-\texttt{  notifid} & Notification ID \\
-\texttt{  -s socket\_fd} &  allows  to  pass  a opened listening socket  \\
-\texttt{  -a fake\_addr} &  fake the client address \\
-\texttt{  -t requested\_validity} & requested validity of the notification (in seconds)   \\
-\texttt{  -j jobid} & job ID to connect notification registration with   \\
-\texttt{  -o owner} & match this owner DN   \\
-\texttt{  -O} & match owner on current user's DN \\
-\texttt{  -n network\_server} &  match only this network server (WMS entry point)  \\
-\texttt{  -v virtual\_organization} & match only jobs of this Virtual Organization  \\
-\texttt{  -i timeout} & timeout to receive operation in seconds   \\
-\texttt{  -f field1,field2,...} & list of status fields to print (only owner by default)   \\
-\texttt{  -c} & notify only on job state change \\
-\texttt{  -S, -{}-state state1,state2,...} & match on events resulting in listed states   \\
-\texttt{  -r} & refresh automatically the notification registration while receiving data\\
-\texttt{  -J, -{}-jdl} & Attach JDL to job status being returned \\
-\texttt{  -B, -{}-bootstrap} & Also send past events matching conditions \\
-\texttt{  -T, -{}-terminal} & Notify only when a job reaches terminal state \\
-\texttt{  -H, -{}-history} & Same as \texttt{-T} plus attach a history of all job's events \\
-\texttt{  -N, -{}-aNonymize} & Anonymize all owner data in all messages under this registration \\
-\end{tabularx}
-
-For additional information see also manual page \texttt{glite-lb-notify(1)}.
-
-\subsubsection{Example: Registration and waiting for simple notification}
-\label{e:notify}
-
-Following steps describe basic testing procedure of the notification
-system by registering a notification on any state change of this job
-and waiting for notification.
-
-Register notification for a given jobid
-%(\verb'https://skurut68-2.cesnet.cz:9100/D1qbFGwvXLnd927JOcja1Q'), 
-with validity 2 hours (7200 seconds):
-
-\begin{verbatim}
-  GLITE_WMS_NOTIF_SERVER=skurut68-2.cesnet.cz:9100 glite-lb-notify new \
-   -j https://skurut68-2.cesnet.cz:9100/D1qbFGwvXLnd927JOcja1Q -t 7200
-\end{verbatim}
-
-returns:
-
-\begin{verbatim}
-  notification ID: https://skurut68-2.cesnet.cz:9100/NOTIF:tOsgB19Wz-M884anZufyUw 
-\end{verbatim}
-
-
-Wait for notification (with timeout 120 seconds):
-\begin{verbatim}
-  GLITE_WMS_NOTIF_SERVER=skurut68-2.cesnet.cz:9100 glite-lb-notify receive \
-   -i 120 https://skurut68-2.cesnet.cz:9100/NOTIF:tOsgB19Wz-M884anZufyUw 
-\end{verbatim}
-
-returns:
-\begin{verbatim}
-  notification is valid until: '2008-07-29 15:04:41' (1217343881)
-  https://skurut68-2.cesnet.cz:9100/D1qbFGwvXLnd927JOcja1Q        Waiting
-      /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-  https://skurut68-2.cesnet.cz:9100/D1qbFGwvXLnd927JOcja1Q        Ready
-      /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-  https://skurut68-2.cesnet.cz:9100/D1qbFGwvXLnd927JOcja1Q        Scheduled
-      /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-  https://skurut68-2.cesnet.cz:9100/D1qbFGwvXLnd927JOcja1Q        Running
-      /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-\end{verbatim}
-
-Destroy notification:
-\begin{verbatim}
-  GLITE_WMS_NOTIF_SERVER=skurut68-2.cesnet.cz:9100 glite-lb-notify drop \
-    https://skurut68-2.cesnet.cz:9100/NOTIF:tOsgB19Wz-M884anZufyUw
-\end{verbatim}
-
-
-\subsubsection{Example: Waiting for notifications on all user's jobs}
-
-Instead of waiting for one job, user may want to accept notification about 
-state changes of all his jobs.
-
-Register notification for actual user:
-\begin{verbatim}
-  GLITE_WMS_NOTIF_SERVER=skurut68-2.cesnet.cz:9100 glite-lb-notify new -O
-\end{verbatim}
-
-returns:
-
-\begin{verbatim}
-  notification ID: https://skurut68-2.cesnet.cz:9100/NOTIF:tOsgB19Wz-M884anZufyUw 
-\end{verbatim}
-
-And continue with \verb'glite-lb-notify receive' similarly to previous example.
-But in this case, we want to display also other information about job --
-not job owner, but destination (where job is running) and location (which component is 
-serving job):
-
-\begin{verbatim}
-  GLITE_WMS_NOTIF_SERVER=skurut68-2.cesnet.cz:9100 glite-lb-notify receive \
-   -i 240 -f destination,location \
-   https://skurut68-2.cesnet.cz:9100/NOTIF:tOsgB19Wz-M884anZufyUw
-\end{verbatim}
-
-returns:
-
-\begin{verbatim}
-  notification is valid until: '2008-07-29 15:43:41' (1217346221)
-
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Waiting
-   (null) NetworkServer/erebor.ics.muni.cz/
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Waiting
-   (null)  destination queue/erebor.ics.muni.cz/
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Waiting
-   (null) WorkloadManager/erebor.ics.muni.cz/
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Waiting
-   (null)  name of the called component/erebor.ics.muni.cz/
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Waiting
-   destination CE/queue WorkloadManager/erebor.ics.muni.cz/
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Waiting
-   destination CE/queue WorkloadManager/erebor.ics.muni.cz/
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Ready
-   destination CE/queue destination queue/erebor.ics.muni.cz/
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Ready
-   destination CE/queue JobController/erebor.ics.muni.cz/
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Ready
-   destination CE/queue LRMS/destination hostname/destination instance
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Ready
-   destination CE/queue LogMonitor/erebor.ics.muni.cz/
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Scheduled
-   destination CE/queue LRMS/destination hostname/destination instance
- https://skurut68-2.cesnet.cz:9100/qbRFxDFCg2qO4-9WYBiiig        Running
-   destination CE/queue LRMS/worknode/worker node
-
-\end{verbatim}
-
-\subsubsection{Example: Registering for notifications to be delivered over ActiveMQ}
-\label{e:notifymsg}
-
-Delivering notification messages over the messaging infrastructure provided by ActiveMQ is a feature introduced in \LBver{3.0}. It uses the fake address capability (\texttt{-a} option) to specify messaging topic to use when generating messages.
-
-\begin{verbatim}
-  GLITE_WMS_NOTIF_SERVER=skurut68-2.cesnet.cz:9100 glite-lb-notify new \
-   -O -a x-msg://grid.emi.lbexample
-\end{verbatim}
-
-Rather than using the \LB notification API to receive messages, access the messaging infrastructure and tap into the given messaging topic (\texttt{grid.emi.lbexample} in our case).
-
-Note that production environments can impose restrictions on topic names. In the context of EGI, for instance, prefix ``\texttt{grid.emi.}'' is mandatory. A full list of permissible topic may be obtained from the \LB Server's configuration page (Section \ref{s:findbroker}).
-
-Also note that in case you are unsure what messaging brokers are available in your grid environment, you can read that information in the \LB Server's configuration page (Section \ref{s:findbroker}).
-
-\subsubsection{Example: Waiting for more notifications on one socket}
-
-The foloving example demonstrates possibility to reuse existing socket for receiving
-multiple notifications. Perl script \verb'notify.pl' (available in 
-examples directory) creates socket, which is then reused for all
-\verb'glite-lb-notify' commands.
-
-\begin{verbatim}
-GLITE_WMS_NOTIF_SERVER=skurut68-2.cesnet.cz:9100 NOTIFY_CMD=glite-lb-notify \
- ./notify.pl -O
-\end{verbatim}
-
-returns:
-
-\begin{verbatim}
-notification ID: https://skurut68-2.cesnet.cz:9100/NOTIF:EO73rjsmexEZJXuSoSZVDg
-valid: '2008-07-29 15:14:06' (1217344446)
-got connection
-https://skurut68-2.cesnet.cz:9100/ANceuj5fXdtaCCkfnhBIXQ        Submitted
-/DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-glite-lb-notify: Connection timed out (read message)
-got connection
-https://skurut68-2.cesnet.cz:9100/p2jBsy5WkFItY284lW2o8A        Submitted
-/DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-glite-lb-notify: Connection timed out (read message)
-got connection
-https://skurut68-2.cesnet.cz:9100/p2jBsy5WkFItY284lW2o8A        Waiting
-/DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-\end{verbatim}
-
-
-\subsubsection{Example: Waiting for notifications on jobs reaching selected states}
-
-This example shows how to set up notifications for jobs reaching state \emph{done} or \emph {aborted}. Since we prefer to receive just one notification per job, we will also use the \texttt{-c} option, which makes sure that notifications will be generated only on actual job state change.
-
-
-\begin{verbatim}
-  GLITE_WMS_NOTIF_SERVER=skurut68-2.cesnet.cz:9100 glite-lb-notify new \
-   --state done,aborted -c
-\end{verbatim}
-
-returns:
-
-\begin{verbatim}
-  notification ID: https://skurut68-2.cesnet.cz:9100/NOTIF:6krjMRshTouH2n7D9t-xdg 
-  valid: '2009-04-30 06:59:18 UTC' (1241074758)	
-\end{verbatim}
-
-Wait for notification (with timeout 120 seconds):
-\begin{verbatim}
-  GLITE_WMS_NOTIF_SERVER=skurut68-2.cesnet.cz:9100 glite-lb-notify receive \
-   -i 120 https://skurut68-2.cesnet.cz:9100/NOTIF:6krjMRshTouH2n7D9t-xdg 
-\end{verbatim}
-
-returns:
-\begin{verbatim}
-https://skurut68-2.cesnet.cz:9100/eIbQNz3oHpv-OkYVu-cXNg	Done
-    /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-https://skurut68-2.cesnet.cz:9100/GpBy2gfIZOAXR2hKOAYGgg	Aborted
-    /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-https://skurut68-2.cesnet.cz:9100/KWXmsqvsTQKizQ4OMiXItA	Done
-    /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-https://skurut68-2.cesnet.cz:9100/O1zs50Nm1r03vx2GLyaxQw	Done
-    /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-\end{verbatim}
-
-\subsubsection{Example: Notify on job reaching terminal state}
-
-This example shows how to register for notifications on finished jobs, i.e. jobs reaching one of the possible terminal states. The user does not need to specify a list of states -- terminal states are recognized on server side.\footnote{Since \LBver{3.2}, where this feature was released, terminal states are: \emph{cleared}, \emph{aborted}, \emph{cancelled}, and \emph{purged}} This use case applies to users who wish to be notified only when their jobs finish, and possibly also pack a history of events with the notification (using argument \texttt{-H}).
-
-\begin{verbatim}
-  GLITE_WMS_NOTIF_SERVER=skurut68-2.cesnet.cz:9100 glite-lb-notify new -T
-\end{verbatim}
-
-returns:
-
-\begin{verbatim}
-  notification ID: https://skurut68-2.cesnet.cz:9100/NOTIF:NLGsqGqvFpzFirHW4UCA6Q
-  valid: '2012-01-11 13:06:22 UTC' (1326287182)
-\end{verbatim}
-
-Wait for notification (with timeout 120 seconds):
-\begin{verbatim}
-  GLITE_WMS_NOTIF_SERVER=skurut68-2.cesnet.cz:9100 glite-lb-notify receive \
-   -i 120 https://skurut68-2.cesnet.cz:9100/NOTIF:NLGsqGqvFpzFirHW4UCA6Q
-\end{verbatim}
-
-returns:
-\begin{verbatim}
-https://skurut68-2.cesnet.cz:9100/2NziNtvLRcuh88FXLs96GA        Cleared
-    /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-https://skurut68-2.cesnet.cz:9100/ERkZaVtRX1E3y6UaNVtAmg        Aborted
-    /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-https://skurut68-2.cesnet.cz:9100/N_Bb0kztImcLnGWc5keDug        Cleared
-    /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-https://skurut68-2.cesnet.cz:9100/Z88Q_i4cI26bSAZqbfdRVg        Cleared
-    /DC=cz/DC=cesnet-ca/O=Masaryk University/CN=Miroslav Ruda
-\end{verbatim}
-
-
diff --git a/org.glite.lb.doc/src/producer_api.tex b/org.glite.lb.doc/src/producer_api.tex
deleted file mode 100644
index 4042f55..0000000
--- a/org.glite.lb.doc/src/producer_api.tex
+++ /dev/null
@@ -1,201 +0,0 @@
-%
-%% Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-%% See http://www.eu-egee.org/partners for details on the copyright holders.
-%% 
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%% 
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%% 
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%
-% -*- mode: latex -*-
-
-\section{\LB\ Logging (Producer) API}
-\label{s:Producer-API}
-
-\subsection{C Language Binding}
-The \LB\ logging API (or producer API) is used to create and deliver
-events to the \LB\ server and/or proxy, depending on the function
-used:
-
-\TODO{kouril: verify ChangeACL}
-
-\begin{table}[h]
-\begin{tabularx}{\textwidth}{lX}
-\bf Function & \bf Delivers to \\
-\hline
-\small\verb'edg_wll_LogEvent(...)' & asynchronously through
-locallogger/interlogger to the \LB\ server \\
-\small\verb'edg_wll_LogEventSync(...)' & synchronously through
-locallogger/interlogger to the \LB\ server \\
-\small\verb'edg_wll_LogEventProxy(...)' & through \LB\ proxy to the \LB\ server \\
-\small\verb'edg_wll_Register*(...)' & directly to both \LB\ server and proxy \\
-\small\verb'edg_wll_ChangeACL(...)' & synchronously to the \LB\ server \\
-\end{tabularx}
-\end{table}
-
-These general functions take as an argument event format (which
-defines the ULM string used) and variable number of arguments corresponding
-to the given format. For each defined event there is predefined format
-string in the form \verb'EDG_WLL_FORMAT_'\textit{EventType}, \eg\
-\verb'EDG_WLL_FORMAT_UserTag', as well as three convenience functions
-\verb'edg_wll_LogUserTag(...)', \verb'edg_wll_LogUserTagSync(...)',
-\verb'edg_wll_LogUserTagProxy(...)'.
-
-For most developers (\ie\ those not developing the WMS itself) the
-\verb'edg_wll_LogUserTag*(...)' and \verb'edg_wll_ChangeACL(...)' are
-the only functions of interest.
-
-\subsubsection{Call semantics}
-\LB producer calls generally do not have transaction semantics, the
-query following succesful logging call is not guaranteed to see
-updated \LB server state. The typical call -- loging an event -- is
-returned immediatelly and the success of the call means that the first
-\LB infrastructure component takes over the event and queues it for
-delivery. If you require transaction semantics, you have to use
-synchronous \verb'edg_wll_LogEventSync(...)' call.
-
-The \LB proxy on the other hand provides a \emph{local view}
-semantics, events logged into proxy using
-\verb'edg_wll_LogEventProxy(...)' are guaranteed to by accessible by
-subsequent queries \emph{on that proxy}.
-
-Job registrations are all synchronous.
-
-\subsubsection{Header files}
-
-\begin{table}[h]
-\begin{tabularx}{\textwidth}{>{\tt}lX}
-%glite/lb/context.h & Definition of context structure and parameters. \\
-glite/lb/producer.h & Prototypes for all event logging functions. \\
-\end{tabularx}
-\end{table}
-
-\subsubsection{Context parameters}
-The table~\ref{t:pcontext} summarizes context parameters relevant to the
-event logging. If  parameter is not set in the context explicitly, the
-\LB\ library will search for value of corresponding environment
-variable.
-
-\begin{table}[h]
-\begin{tabularx}{\textwidth}{lX}
-{\bf Name} & {\bf Description} \\
-\hline
-\lstinline'EDG_WLL_PARAM_HOST' &
-Hostname that appears as event origin.
-\par {\it Type: } \lstinline'char*'
-\par {\it Environment: } \\
-\lstinline'EDG_WLL_PARAM_SOURCE'  &
-Event source component.
-\par {\it Type: }\lstinline'edg_wll_Source'
-\par {\it Environment: } \\
-\lstinline'EDG_WLL_PARAM_DESTINATION'  &
-Hostname of machine running locallogger/interlogger.
-\par {\it Type: }\lstinline'char*'
-\par {\it Environment: }\lstinline'GLITE_WMS_LOG_DESTINATION' \\
-\lstinline'EDG_WLL_PARAM_DESTINATION_PORT' &
-Port the locallogger is listening on.
-\par {\it Type: } \lstinline'int'
-\par {\it Environment: }\lstinline'GLITE_WMS_LOG_DESTINATION' \\
-\lstinline'EDG_WLL_LOG_TIMEOUT'  &
-Logging timeout for asynchronous logging.
-\par {\it Type: }\lstinline'struct timeval'
-\par {\it Environment: }\lstinline'GLITE_WMS_LOG_TIMEOUT' \\
-\lstinline'EDG_WLL_LOG_SYNC_TIMEOUT'  &
-Logging timeout for synchronous logging.
-\par {\it Type: }\lstinline'struct timeval'
-\par {\it Environment: }\lstinline'GLITE_WMS_LOG_SYNC_TIMEOUT' \\
-\lstinline'EDG_WLL_LBPROXY_STORE_SOCK'  &
-\LB\ Proxy store socket path (if logging through \LB\ Proxy)
-\par {\it Type: }\lstinline'char*'
-\par {\it Environment: }\lstinline'GLITE_WMS_LBPROXY_STORE_SOCK' \\
-\lstinline'EDG_WLL_LBPROXY_USER' &
-Certificate subject of the user (if logging through \LB\ proxy).
-\par {\it Type: }\lstinline'char*'
-\par {\it Environment: }\lstinline'GLITE_WMS_LBPROXY_USER' \\
-\end{tabularx}
-\caption{Producer specific context parameters}
-\label{t:pcontext}
-\end{table}
-The \verb'GLITE_WMS_LOG_DESTINATION' environment variable contains
-both locallogger host and port separated by colon (\ie\ ``host:port'').
-
-\marginpar{Logging job and sequence numbers}%
-In addition to the above list, there are two more parameters that must
-be set before logging call is made: \jobid of the logging job and
-\emph{sequence number}. There is a special call for this task:
-\begin{lstlisting}
-extern int edg_wll_SetLoggingJob(
-        edg_wll_Context context,	//* \emph{context to work with}
-        glite_jobid_const_t     job,	//* \emph{jobid of the job}
-        const char *            code,	//* \emph{sequence code}
-        int                     flags	//* \emph{flags on code handling}
-);
-\end{lstlisting}
-After setting the logging job identity, all the following logging
-calls refer to this \jobid and the sequence code is incremented
-according to the source component. See \cite{lbug} for information
-about sequence codes and event numbering, especially the description,
-how the sequence codes are updated.
-
-\subsubsection{Return values}
-The logging functions return 0 on success and one of \texttt{EINVAL,
-ENOSPC, ENOMEM, ECONNREFUSED, EAGAIN} on error. If \texttt{EAGAIN} is
-returned, the function should be called again to retry the delivery;
-it is not guaranteed, however, that the event was not delivered by the
-first call. Possibly duplicated events are discarded by the \LB\
-server or proxy.
-
-\TODO{ljocha: check these}
-The synchronous variants of logging functions can in addition return
-\verb'EDG_WLL_ERROR_NOJOBID' or \verb'EDG_WLL_ERROR_DB_DUP_KEY'.
-
-\subsubsection{Logging event example}
-In this section we will give commented example how to log an UserTag event to
-the \LB.
-
-First we have to include neccessary headers:
-\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=headers-end\ headers]{prod_example1.c}
-
-Initialize context and set parameters:
-\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=context-end\ context]{prod_example1.c}
-
-\TODO{honik: proper setting of sequence codes}
-\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=sequence-end\ sequence]{prod_example1.c}
-
-Log the event:
-\lstinputlisting[title={\bf File: }\lstname,numbers=left,linerange=log-end\ log]{prod_example1.c}
-
-The \verb'edg_wll_LogEvent()' function is defined as follows:
-\begin{lstlisting}[numbers=none]
-extern int edg_wll_LogEvent(
-        edg_wll_Context context,
-        edg_wll_EventCode event,
-        char *fmt, ...);
-\end{lstlisting}
-If you use this function, you have to provide event code, format
-string and corresponding arguments yourself. The UserTag event has
-only two arguments, tag name and value, but other events require more
-arguments.
-
-Instead of using the generic \verb'edg_wll_LogEvent()' at line~\ref{l:logevent}, we could also
-write:
-\begin{lstlisting}
-err = edg_wll_LogUserTag(ctx, name, value);
-\end{lstlisting}
-
-
-\subsubsection{Change ACL example}
-\TODO{kouril}
-
-
-
-\subsection{Java binding}
-\TODO{mirek}
-
diff --git a/org.glite.lb.doc/src/status.tex.T b/org.glite.lb.doc/src/status.tex.T
deleted file mode 100644
index 5a1d0e5..0000000
--- a/org.glite.lb.doc/src/status.tex.T
+++ /dev/null
@@ -1,19 +0,0 @@
-@@@{
-gen qq{
-%  !! Automatically generated file. Do not edit.
-%  !! Change the corresponding template file $ARGV
-};
-@@@}
-
-\begin{tabularx}{\textwidth}{>{\bfseries}lX}
-@@@{
-for my $stat ($status->getTypesOrdered) {
-	my $c = getTypeComment $status $stat;
-
-        gen "$stat: \& $c \\\\ \n";
-        }
-@@@}
-\end{tabularx}
-
-\endinput
-
diff --git a/org.glite.lb.doc/src/versions.tex b/org.glite.lb.doc/src/versions.tex
deleted file mode 100644
index f7c403a..0000000
--- a/org.glite.lb.doc/src/versions.tex
+++ /dev/null
@@ -1,71 +0,0 @@
-%
-%% Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-%% See http://www.eu-egee.org/partners for details on the copyright holders.
-%% 
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%% 
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%% 
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%
-\def\lbdoc{\LB Documentation and versions overview}
-\section*{\lbdoc}
-\addcontentsline{toc}{section}{\texorpdfstring{\uppercase{\lbdoc}}{\lbdoc}}
-\def\lbdoc{}
-
-The Logging and Bookkeeping service (\LB\ for short) was initially developed in
-the EU DataGrid
-project\footnote{\url{http://eu-datagrid.web.cern.ch/eu-datagrid/}} as a~part
-of the Workload Management System (WMS). The development continued in the EGEE,
-EGEE-II and EGEE-III projects,\footnote{\url{http://www.eu-egee.org/}} where
-\LB became an independent part of the
-gLite\footnote{\url{http://www.glite.org}} middleware~\cite{glite}, and then in the EMI Project.\footnote{\url{http://www.eu-emi.eu/}}
-
-The complete \LB Documentation consists of the following parts:
-\begin{itemize}
-\item \textbf{\LB User's Guide} 
-   \ifx\insideUG\undefined{\cite{lbug}}\else{-- this document}\fi. 
-   \input{LBUG-Abstract}
-\item \textbf{\LB Administrator's Guide} 
-   \ifx\insideAG\undefined{\cite{lbag}}\else{-- this document}\fi. 
-   \input{LBAG-Abstract}
-\item \textbf{\LB Developer's Guide} 
-   \ifx\insideDG\undefined{\cite{lbdg}}\else{-- this document}\fi. 
-   \input{LBDG-Abstract}
-\item \textbf{\LB Test Plan} 
-   \ifx\insideTP\undefined{\cite{lbtp}}\else{-- this document}\fi. 
-   \input{LBTP-Abstract}
-\end{itemize}
-
-\textbf{The following versions of \LB service are covered by these documents:}
-\begin{itemize}
-%\item \LBver{x.x}: included in the EMI-3 \emph{Monte Bianco} release
-\item \LBver{3.2}: included in the EMI-2 \emph{Matterhorn} release
-\item \LBver{3.1}: an update for the EMI-1 \emph{Kebnekaise} release
-\item \LBver{3.0}: included in the EMI-1 \emph{Kebnekaise} release
-\item \LBver{2.1}: replacement for \LBver{2.0} in gLite 3.2,
-\item \LBver{2.0}: current stable version, in production as part of gLite 3.2,
-\item \LBver{1.x}: old stable version, in production as part of gLite 3.1.
-\end{itemize}
-\textbf{The older version of \LB that appeared in gLite 3.0 became obsolete and is not maintained anymore.}
-
-\textbf{\LB packages can be obtained from two distinguished sources:}
-
-\nopagebreak
-\begin{itemize}
-\item \textbf{gLite releases}: gLite node-type repositories, offering a specific repository for each node type such as \emph{glite-LB}. Only binary RPM packages are available from that source.
-\item \textbf{emi releases}: EMI repository\footnote{\url{http://emisoft.web.cern.ch/emisoft/}} or EGI's UMD repository,\footnote{\url{http://repository.egi.eu/}} offering all EMI middleware packages from a single repository. There are RPM packages, both source and binary, the latter relying on EPEL for dependencies. There are also DEB packages (starting with EMI-2) and \texttt{tar.gz} archives.
-\end{itemize}
-
-\emph{Note:} Despite offering the same functionality, binary packages obtained from different repositories differ and switching from one to the other for upgrades may not be altogether straightforward.
-
-Updated information about \LB service (including the \LB service roadmap) is available at the
-\LB homepage:
-\href{http://egee.cesnet.cz/en/JRA1/LB}{http://egee.cesnet.cz/en/JRA1/LB}
-
diff --git a/org.glite.lb.doc/src/web_services.tex b/org.glite.lb.doc/src/web_services.tex
deleted file mode 100644
index 013d86e..0000000
--- a/org.glite.lb.doc/src/web_services.tex
+++ /dev/null
@@ -1,42 +0,0 @@
-%
-%% Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-%% See http://www.eu-egee.org/partners for details on the copyright holders.
-%% 
-%% Licensed under the Apache License, Version 2.0 (the "License");
-%% you may not use this file except in compliance with the License.
-%% You may obtain a copy of the License at
-%% 
-%%     http://www.apache.org/licenses/LICENSE-2.0
-%% 
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%
-% -*- mode: latex -*-
-
-\section{Using \LB\ Web Service}
-\TODO{ljocha}
-
-\TODO{Presunout do consumera}
-
-\TODO{Complete review, list of all relevant (WSDL) files, their location, etc.}
-
-The \LB\ web service interface currently reflects the functionality of legacy
-\LB\ Querying API (Sect.~\ref{Consumer-API}).
-
-The following sections describe the operations defined in the \LB\ WSDL
-file as well as its custom types.
-
-For the sake of readability this documentation does not follow the structure
-of WSDL strictly, avoiding to duplicate information which is already present
-here. Consequently, the SOAP messages are not documented, for example, as they
-are derived from operation inputs and outputs mechanically.
-The same holds for types: \eg\ we do not document defined elements
-which correspond 1:1 to types but are required due to the literal SOAP
-encoding.
-
-For exact definition of the operations and types see the WSDL file.
-
-\TODO{Add fully functional WS examples - in Java, Python, C?}
diff --git a/org.glite.lb.emi-lb/Makefile b/org.glite.lb.emi-lb/Makefile
deleted file mode 100644
index c035bc2..0000000
--- a/org.glite.lb.emi-lb/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-top_srcdir=..
-stagedir=.
-package=glite-lb-emi-lb
-version=0.0.0
-PREFIX=/opt/glite
-prefix=
-
--include Makefile.inc
--include ${top_srcdir}/project/version.properties
-
-default all:
-
-install:
-
-stage:
-	$(MAKE) install PREFIX=${stagedir}
-
-check:
-
-clean:
-
-distclean:
-	rm -rvf Makefile.inc *.spec debian/
-
-.PHONY: default all check install stage clean distclean
diff --git a/org.glite.lb.emi-lb/configure b/org.glite.lb.emi-lb/configure
deleted file mode 100755
index e1c5a72..0000000
--- a/org.glite.lb.emi-lb/configure
+++ /dev/null
@@ -1,2027 +0,0 @@
-#!/usr/bin/perl
-
-# WARNING: Don't edit this file unless it is the master copy in org.glite.lb
-#
-# For the purpose of standalone builds of lb/jobid/lbjp-common components
-# it is copied on tagging 
-
-# $Header$
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners/ for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-use Getopt::Long;
-use POSIX qw(locale_h strftime);
-
-my $pwd = `pwd`; chomp $pwd;
-my $prefix = '/usr';
-my $stagedir = undef;
-my $root = $pwd.'/stage';
-my $sysroot = '';
-my $sysconfdir;
-my $localstatedir;
-my $staged;
-my $module;
-my $thrflavour = 'gcc64dbgpthr';
-my $nothrflavour = 'gcc64dbg';
-my $mode = 'build';
-my $help = 0;
-my $listmodules;
-my $version;
-my $branch;
-my $output;
-my $lb_tag = '';
-my $lbjp_tag = '';
-my $jp_tag = '';
-my $jobid_tag = '';
-my $libdir = getlibdir();
-my $project = 'glite';
-my (%projects, %project);
-my $debug = 0;
-my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : '';
-
-my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal/;
-my @default_nodes = qw/lb px proxyrenewal/;
-my %enable_nodes;
-my %disable_nodes;
-my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1);
-
-my %package = (
-	'maintainer' => 'CESNET Product Teams ',
-	'uploaders' => 'František Dvořák ',
-	'url' => 'http://glite.cern.ch',
-	'debian_vcs' => 'Vcs-Cvs: :pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw
-Vcs-Browser: http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi',
-);
-
-# key:      internal package name (arguments, ...)
-# 'pkg':    pkg-config name
-# 'prefix': used when pkg-config fails
-my %externs = (
-	cares => {
-		prefix => '/opt/c-ares',
-		pkg => 'libcares'
-	},
-	classads => {
-		prefix=> '/usr',
-		pkg => 'classads'
-	},
-	cppunit => {
-		prefix=> '/usr',
-		pkg => 'cppunit'
-	},
-	expat => {
-		prefix=> '/usr',
-		pkg => 'expat'
-	},
-	globus => {
-		prefix=> '/opt/globus',
-		pkg => 'globus-gssapi-gsi'
-	},
-	'myproxy-devel' => {
-		prefix=> '/opt/globus',
-		pkg => 'myproxy'
-	},
-	'myproxy-server' => {
-		prefix=> '',
-	},
-	'myproxy-admin' => {
-		prefix=> '',
-	},
-	gsoap => {
-		prefix=> '/usr',
-		pkg => 'gsoap'
-	},
-	gsoapxx => {
-		prefix=> '/usr',
-		pkg => 'gsoap++'
-	},
-	mysql => {
-		prefix=> '/usr'
-	},
-	'mysql-devel' => {
-		prefix=> ''
-	},
-	'mysql-server' => {
-		prefix => ''
-	},
-	voms => {
-		prefix => '/opt/glite',
-		pkg => 'voms-2.0'
-	},
-	gridsite => {
-		prefix => '/opt/glite'
-	},
-	lcas => {
-		prefix => '/opt/glite',
-		pkg => 'lcas'
-	},
-	trustmanager => {
-		prefix => '/opt/glite'
-	},
-	trustmanager_axis => {
-		prefix => '/opt/glite'
-	},
-	utiljava => {
-		prefix=> '/opt/glite'
-	},
-	ant => {
-		prefix=> '/usr'
-	},
-	jdk => {
-		prefix=> '/usr/java/latest',
-		locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ],
-	},
-	libtar => {
-		prefix=> '/usr'
-	},
-	axis => {
-		prefix=> '/usr'
-	},
-	log4c => {
-		prefix=> '/usr'
-	},
-	postgresql => {
-		prefix=> '/usr'
-	},
-	activemq => {
-		prefix=>'/opt/activemq-cpp-library',
-		pkg => 'activemq-cpp'
-	},
-);
-
-my %jar = (
-	'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar',
-	'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar',
-);
-
-
-my %glite_prefix;
-my %need_externs;
-my %need_externs_type;
-my %need_jars;
-my %extrafull;
-my %extranodmod;
-my %deps;
-my %deps_type;
-my %buildroot;
-my (%etics_externs, %etics_projects);
-
-#
-# modules of the subsystems
-#
-# additional modules from $project{modules} are automatically added
-#
-my %lbmodules = (
-	'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], 
-	'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/],
-	'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/],
-	'jp' => [ qw/client doc index primary server-common ws-interface/ ],
-	'gridsite' => [ qw/apache shared commands core devel slashgrid services service-clients gsexec/ ],
-	'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ],
-	'canl' => [ qw/c c-devel/ ],
-	);
-
-#
-# sub-packages
-#
-# modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly
-#
-my %subpackages = (
-	'jobid.api-c-devel' => 'jobid.api-c',
-	'jobid.api-cpp-devel' => 'jobid.api-cpp',
-	'lbjp-common.db-devel' => 'lbjp-common.db',
-	'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin',
-	'lbjp-common.gss-devel' => 'lbjp-common.gss',
-	'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface',
-	'lbjp-common.log-devel' => 'lbjp-common.log',
-	'lbjp-common.maildir-devel' => 'lbjp-common.maildir',
-	'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones',
-	'lbjp-common.trio-devel' => 'lbjp-common.trio',
-	'lb.client-progs' => 'lb.client',
-	'lb.client-devel' => 'lb.client',
-	'lb.common-devel' => 'lb.common',
-	'lb.logger-devel' => 'lb.logger',
-	'lb.state-machine-devel' => 'lb.state-machine',
-	'px.proxyrenewal-devel' => 'px.proxyrenewal',
-	'px.proxyrenewal-progs' => 'px.proxyrenewal',
-	'canl.c-devel' => 'canl.c',
-);
-
-my @opts = (
-	'prefix:s' => \$prefix,
-	'staged=s' => \$staged,
-	'module=s' => \$module,
-	'thrflavour:s' => \$thrflavour,
-	'nothrflavour:s' => \$nothrflavour,
-	'mode=s' => \$mode,
-	'listmodules=s' => \$listmodules,
-	'version=s' => \$version,
-	'branch=s' => \$branch,
-	'output=s' => \$output,
-	'stage=s' => \$stagedir,
-	'root:s' => \$root,
-	'sysroot:s' => \$sysroot,
-	'sysconfdir=s' => \$sysconfdir,
-	'localstatedir=s' => \$localstatedir,
-	'lb-tag=s' => \$lb_tag,
-	'lbjp-common-tag=s' => \$lbjp_tag,
-	'jp-tag=s' => \$jp_tag,
-	'jobid-tag=s' => \$jobid_tag,
-	'canl-tag=s' => \$canl_tag,
-	'help' => \$help,
-	'libdir=s' => \$libdir,
-	'project=s' => \$project,
-	'debug' => \$debug,
-);
-
-for (@nodes) {
-	$enable_nodes{$_} = 0;
-	$disable_nodes{$_} = 0;
-	
-	push @opts,"disable-$_",\$disable_nodes{$_};
-	push @opts,"enable-$_",\$enable_nodes{$_};
-}
-
-push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs;
-push @opts,"with-$_=s",\$jar{$_} for keys %jar;
-
-my @keeparg = @ARGV;
-
-GetOptions @opts or die "Errors parsing command line\n";
-$prefix=~s/\/$//;
-$root=~s/\/$//;
-$sysroot=~s/\/$//;
-if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; }
-if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; }
-$sysconfdir=~s/\/$//;
-$localstatedir=~s/\/$//;
-
-$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq '';
-$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq '';
-$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq '';
-
-$externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq '';
-$externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq '';
-$externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq '';
-
-%project = %{$projects{$project}};
-for my $platform (keys %{$project{etics_externs}}) {
-	for $_ (keys %{$project{etics_externs}{$platform}}) {
-		$etics_externs{$platform}{$_} = $project{etics_externs}{$platform}{$_};
-	}
-}
-reshuffle_platforms(\%etics_externs, $project{supported_platforms});
-reshuffle_platforms(\%{$project{etics_externs_devel}}, $project{supported_platforms});
-for $_ (keys %{$project{etics_projects}}) {
-	$etics_projects{$_} = $project{etics_projects}{$_};
-}
-for $_ (keys %{$project{need_externs_aux}}) {
-	$need_externs_aux{$_} = $project{need_externs_aux}{$_};
-}
-for my $ext (keys %need_externs_aux) {
-	for (@{$need_externs_aux{$ext}}) {
-		my ($pkg, $type) =/([^:]*)(?::(.*))?/;
-		$type = 'BR' unless ($type);
-
-		push @{$need_externs{$ext}},$pkg;
-		$need_externs_type{$ext}->{$pkg} = $type;
-	}
-}
-if ($project eq 'emi') {
-	$extranodmod{lb} = 'lb.emi-lb';
-	$extranodmod{px} = 'px.emi-px';
-}
-for $_ (keys %{$project{modules}}) {
-	push @{$lbmodules{$_}},@{$project{modules}{$_}};
-}
-
-
-if ($help) { usage(); exit 0; }
-
-if ($listmodules) {
-	my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name};
-	my @m;
-
-	if (exists $lbmodules{$listmodules}) {
-		@m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}};
-	} else {
-		for my $sub (keys %subpackages) {
-			push @m, $sub if ($subpackages{$sub} eq $listmodules);
-		}
-	}
-	print map $_ eq "" ? "" : "$_ ", @m;
-	print "\n";
-	exit 0;
-}
-
-warn "$0: --branch and --output make sense only in --mode=etics\n"
-	if ($output || $branch) && $mode ne 'etics';
-
-my $en;
-for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; }
-
-my $dis;
-for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; }
-
-die "--enable-* and --disable-* are mutually exclusive\n"
-	if $en && $dis;
-
-die "--module cannot be used with --enable-* or --disable-*\n"
-	if $module && ($en || $dis);
-
-die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}};
-
-if ($dis) {
-	for (@nodes) {
-		$enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_});
-	}
-}
-
-if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } };
-
-for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; }
-
-$stagedir = $root unless $stagedir;
-$stagedir=~s/\/$// if ($stagedir);
-
-if ($mode eq 'build') { for my $ext (keys %externs) {
-	if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; }
-	elsif (defined $externs{$ext}{pkg}) {
-		my ($flag, $env, $cmd, $ret);
-		my $pkg = $externs{$ext}{pkg};
-		my $flagname = uc $externs{$ext}{pkg};
-		$flagname =~ s/-[0-9\.]*$//;
-		$flagname =~ y/-\+/_X/;
-
-		print "Checking $pkg ... ";
-		$env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig";
-		$cmd = "$env pkg-config $pkg --exists >/dev/null";
-		`$cmd`; $ret = $?;
-		print "('$cmd' => $ret)\n" if ($debug);
-		if ($ret == 0) {
-			$externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`;
-			chomp $externs{$ext}{prefix};
-			print "$externs{$ext}{prefix}\n";
-
-			$flag=`$env pkg-config $pkg --cflags`;
-			$externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag);
-			$flag=`$env pkg-config $pkg --libs`;
-			$externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag);
-		} else {
-			print "(using default $externs{$ext}{prefix})\n";
-		}
-		print "\n" if ($debug);
-	}
-	elsif ($ext eq 'jdk') {
-		my $jdk_prefix;
-
-		print "Looking for some caffein ... ";
-		if (defined $ENV{'JDK_HOME'}) {
-			$jdk_prefix = $ENV{'JDK_HOME'};
-			print "JDK_HOME=$jdk_prefix\n";
-		} elsif (defined $ENV{'JAVA_HOME'}) {
-			$jdk_prefix = $ENV{'JAVA_HOME'};
-			print "JAVA_HOME=$jdk_prefix\n";
-		} else {
-			foreach my $i (0..$#{$externs{$ext}{locations}}) {
-				if (-e $externs{$ext}{locations}[$i]) {
-					$jdk_prefix=$externs{$ext}{locations}[$i];
-					print "(found directory $jdk_prefix)\n";
-					last;
-				}
-			}
-			print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix);
-		}
-		$externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix);
-	}
-} }
-
-if ($mode eq 'build') {
-	print "Writing config.status\n";
-	open CONF,">config.status" or die "config.status: $!\n";
-	for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') {
-		print CONF "$_=$ENV{$_} " if (defined $ENV{$_});
-	}
-	print CONF "$0 @keeparg\n";
-	close CONF;
-}
-
-
-my @modules;
-my %aux;
-
-if ($module) {
-#	push @modules,split(/[,.]+/,$module);
-	push @modules,$module;
-}
-else {
-	@modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes));
-	
-	my $n;
-
-	do {
-		local $"="\n";
- 		$n = $#modules;
-		push @modules,(map @{$deps{$_}},@modules);
-
-		undef %aux; @aux{@modules} = (1) x ($#modules+1);
-		@modules = keys %aux;
-	} while ($#modules > $n);
-}
-
-@aux{@modules} = (1) x ($#modules+1);
-delete $aux{$_} for (split /,/,$staged);
-@modules = keys %aux;
-
-mode_build() if $mode eq 'build';
-mode_checkout() if $mode eq 'checkout';
-mode_etics($module) if $mode eq 'etics';
-
-sub mode_build {
-	print "\nBuilding modules: @modules\n";
-	print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n";
-	
-	my @ext = map @{$need_externs{$_}},@modules;
-	my @myjars = map @{$need_jars{$_}},@modules;
-	undef %aux; @aux{@ext} = 1;
-	@ext = keys %aux;
-	undef %aux; @aux{@myjars} = (1) x ($#myjars+1);
-	@myjars = keys %aux;
-	
-	print "\nRequired externals:\n";
-	print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext;
-	print "\t$_: $jar{$_}\n" for @myjars;
-	for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } };
-	print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n";
-
-	mkinc($_) for @modules;
-
-	if ($module) {
-		print "Not creating summary Makefile\n" if $debug;
-	} else {
-		print "Creating Makefile\n";
-
-		open MAK,">Makefile" or die "Makefile: $!\n";
-
-		print MAK "all: @modules\n\n";
-		print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n";
-		print MAK "clean check install:\n";
-
-		for (@modules) {
-			my $full = full($_);
-			print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n"
-		}
-
-		print MAK "\ndistclean:\n";
-
-		for (@modules) {
-			my $full = full($_);
-			print MAK $buildroot{$_} eq '' ?
-				"\tcd $full && \${MAKE} distclean\n" :
-				"\trm -rf $full/$buildroot{$_}\n"
-		}
-
-		print MAK "\n";
-
-		for (@modules) {
-			my %ldeps; undef %ldeps;
-			@ldeps{@{$deps{$_}}} = 1;
-			for my $x (split /,/,$staged) { delete $ldeps{$x}; }
-			my @dnames = $module ? () : keys %ldeps;
-			my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage';
-
-			my $full = full($_);
-			my $build = $buildroot{$_};
-
-			print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n";
-			print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n";
-		}
-
-		close MAK;
-	}
-}
-	
-sub mode_checkout() {
-	for (@modules) {
-		my $module = $_;
-		my $tag = "";
-		if ($lb_tag){
-			for (@{$lbmodules{lb}}){
-				if ("lb.".$_ eq $module){
-					$tag = '-r '.$lb_tag;
-				}
-			}	
-		}
-		if ($lbjp_tag) {
-			for (@{$lbmodules{'lbjp-common'}}){
-				if ("lbjp-common.".$_ eq $module){
-                                        $tag = '-r '.$lbjp_tag;
-                                }
-			}
-		}
-		if ($jp_tag){
-			for (@{$lbmodules{'jp'}}){
-	                        if ("jp.".$_ eq $module){
-                                        $tag = '-r '.$jp_tag;
-	                        }
-                        }
-		}
-		if ($jobid_tag){
-			for (@{$lbmodules{jobid}}){
-				if ("jobid.".$_ eq $module){
-                                        $tag = '-r '.$jobid_tag;
-                                }
-			}
-		}
-		if ($canl_tag) {
-			for (@{$lbmodules{'canl'}}){
-				if ("canl.".$_ eq $module){
-                                        $tag = '-r '.$canl_tag;
-                                }
-			}
-		}
-		#if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){
-		#	print "found";
-		#}
-		$_ = full($_);
-		print "\n*** Checking out $_\n";
-		system("cvs checkout  $tag $_") == 0 or die "cvs checkout $tag $_: $?\n";
-	}
-}
-
-BEGIN{
-%etics_externs = (
-	default => {
-		'myproxy-devel'=>'myproxy-devel',
-		'myproxy-server'=>'myproxy-server',
-		'myproxy-admin'=>'myproxy-admin',
-		cares=>'c-ares',
-		utiljava=>'org.glite.security.util-java',
-		gpt=>'gpt',
-		fetchcrl=>'fetch-crl',
-		activemq=>'activemq-cpp-library',
-	},
-);
-
-%etics_projects = (
-);
-
-%need_externs_aux = (
-	'lb.client' => [ qw/cppunit:B classads libtool:B/ ],
-	'lb.common' => [ qw/expat cares:B cppunit:B classads libtool:B/ ],
-	'lb.doc' => [ qw/tetex-latex:B/ ],
-	'lb.logger' => [ qw/cppunit:B libtool:B/ ],
-	'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B/ ],
-	'lb.nagios' => [ qw/globus_proxy_utils:R/ ],
-	'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql:R mysql-server:R mysql-devel:B cppunit:B gsoap:B classads voms:B lcas gridsite bison:B libtool:B libxml2 flex:B/ ],
-	'lb.state-machine' => [ qw/classads libtool:B libxslt:B expat:B/ ],
-	'lb.utils' => [ qw/cppunit:B libtool:B/ ],
-	'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ],
-	'lb.ws-test' => [ qw/gsoap:B libtool:B/ ],
-	'lb.types' => [ qw// ],
-	'lb.harvester' => [ qw/docbook-utils:B libtool:B/ ],
-	'lbjp-common.db' => [ qw/mysql:B mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B/ ],
-	'lbjp-common.log' => [ qw/log4c libtool:B/ ],
-	'lbjp-common.maildir' => [ qw/libtool:B/ ],
-	'lbjp-common.server-bones' => [ qw/libtool:B/ ],
-	'lbjp-common.trio' => [ qw/cppunit:B libtool:B/ ],
-	'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B/ ],
-	'lbjp-common.gss' =>  [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B/ ],
-	'lbjp-common.gsoap-plugin' =>  [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B/ ],
-	'jobid.api-c' =>  [ qw/cppunit:B libtool:B openssl:B/ ],
-	'jobid.api-cpp' =>  [ qw/cppunit:B libtool:B/ ],
-	'jobid.api-java' =>  [ qw/ant:B jdk:B/ ],
-	'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ],
-        'jp.doc' => [],
-        'jp.index' => [ qw/gsoap globus_essentials:R globus:B/ ],
-        'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B/ ],
-        'jp.server-common' => [],
-        'jp.ws-interface' => [],
-	'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ],
-	'gridsite.commands' => [ qw/curl:R openssl:R/ ],
-	'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ],
-	'gridsite.shared' => [ qw/libxml2:R openssl:R/ ],
-	'gridsite.devel' => [ qw// ],
-	'gridsite.slashgrid' => [ qw/curl:R fuse:R/],
-	'gridsite.services' => [ qw/curl:R gsoap:R/ ],
-	'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ],
-	'gridsite.gsexec' => [ qw// ],
-	'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ],
-	'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B/ ],
-	'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec
-	'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B/ ],
-);
-
-%need_jars = (
-	'jobid.api-java' => [ qw/jakarta-commons-codec/ ],
-	'lb.client-java' => [ qw/jakarta-commons-lang/ ],
-);
-
-for my $jar (keys %need_jars) {
-	for (@{$need_jars{$jar}}) {
-		$need_externs_type{$jar}->{$_} = 'BR'; 	# XXX
-	}
-}
-
-%deps_aux = (
-	'lb.client' => [ qw/
-		lb.types:B lb.common
-		lbjp-common.trio
-		jobid.api-cpp:B jobid.api-c
-		lbjp-common.gss
-	/ ],
-	'lb.client-java' => [ qw/
-		lb.types:B
-		lb.ws-interface:B
-		jobid.api-java
-	/ ],
-	'lb.common' => [ qw/
-		jobid.api-cpp:B jobid.api-c
-		lb.types:B lbjp-common.trio lbjp-common.gss
-	/ ],
-	'lb.doc' => [ qw/lb.types:B/ ],
-	'lb.logger' => [ qw/
-		lbjp-common.trio
-		lbjp-common.log
-		jobid.api-c
-		lb.common
-		lbjp-common.gss
-	/ ],
-	'lb.logger-msg' => [ qw/
-		lb.logger-devel:B
-	/ ],
-	'lb.nagios' => [ qw/
-		lb.client:R
-		lb.ws-test:R
-		lb.utils:R
-	/ ],
-	'lb.server' => [ qw/
-		lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R
-		lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log
-		jobid.api-c
-		lbjp-common.gsoap-plugin lbjp-common.gss
-	/ ],
-	'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ],
-	'lb.utils' => [ qw/
-		lbjp-common.jp-interface
-		jobid.api-c
-		lbjp-common.trio lbjp-common.maildir
-		lb.client lb.state-machine lb.types:B
-	/ ],
-	'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ],
-	'lb.ws-interface' => [ qw/lb.types:B/ ],
-	'lb.types' => [ qw// ],
-	'lb.harvester' => [ qw/
-		jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client
-		lbjp-common.gss lbjp-common.log
-	/ ],
-	'lb.yaim' => [ qw// ],
-	'lb.glite-LB' => [ qw/
-		lb.logger:R lb.server:R lb.utils:R lb.doc:R
-		lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R
-		lb.logger-msg:R lb.client-progs:R
-	/ ],
-	'lb.emi-lb' => [ qw/
-		lb.logger:R lb.server:R lb.utils:R lb.doc:R
-		lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R
-		lb.logger-msg:R lb.client-progs:R
-	/ ],
-	'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ],
-	'lbjp-common.maildir' => [ qw// ],
-	'lbjp-common.log' => [ qw// ],
-	'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ],
-	'lbjp-common.trio' => [ qw// ],
-	'lbjp-common.gss' =>  [ qw// ],
-	'lbjp-common.gsoap-plugin' =>  [ qw/lbjp-common.gss/ ],
-	'jobid.api-c' =>  [ qw// ],
-	'jobid.api-cpp' =>  [ qw/jobid.api-c/ ],
-	'jobid.api-java' =>  [ qw// ],
-
-	'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ],
-
-	'jp.client' => [ qw/
-                jp.ws-interface
-                lbjp-common.jp-interface lbjp-common.maildir
-                jobid.api-c
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.doc' => [ qw// ],
-	'jp.index' => [ qw/
-                jp.server-common jp.ws-interface
-                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.primary' => [ qw/
-                jobid.api-c
-                jp.server-common jp.ws-interface
-                lb.state-machine
-                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.server-common' => [ qw/ 
-                lbjp-common.jp-interface lbjp-common.db
-        / ],
-	'jp.ws-interface' => [ qw// ],
-
-	'gridsite.core' => [ qw// ],
-	'gridsite.commands' => [ qw/gridsite.core:B gridsite.shared:R/ ],
-	'gridsite.apache' => [ qw/gridsite.core:B gridsite.shared:R/ ],
-	'gridsite.shared' => [ qw/gridsite.core:B / ],
-	'gridsite.devel' => [ qw/gridsite.core:B gridsite.shared:R/ ],
-	'gridsite.slashgrid' => [ qw/gridsite.core:B gridsite.shared:R/],
-	'gridsite.services' => [ qw/gridsite.core:B gridsite.shared:R/ ],
-	'gridsite.service-clients' => [ qw/gridsite.core:B gridsite.shared:R/ ],
-	'gridsite.gsexec' => [ qw/gridsite.core:B/ ],
-
-	'px.proxyrenewal' => [ qw// ],
-	'px.glite-PX' => [qw/px.myproxy-yaim:R/],
-	'px.emi-px' => [qw/px.myproxy-yaim:R/],
-	'px.myproxy-yaim' => [ qw// ],
-	'px.myproxy-config' => [],
-
-	'canl.c' => [],
-
-	# sub-packages (virtual ETICS components depending on the main)
-	'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ],
-	'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ],
-	'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ],
-	'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ],
-	'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ],
-	'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ],
-	'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ],
-	'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ],
-	'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ],
-	'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ],
-	'lb.client-progs' => [ qw/lb.client:B/ ],
-	'lb.client-devel' => [ qw/lb.client:B/ ],
-	'lb.common-devel' => [ qw/lb.common:B/ ],
-	'lb.logger-devel' => [ qw/lb.logger:B/ ],
-	'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ],
-	'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ],
-	'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ],
-	'canl.c-devel' => [ qw/canl.c:B/ ],
-);
-
-for my $ext (keys %deps_aux) {
-	for (@{$deps_aux{$ext}}) {
-		/([^:]*)(?::(.*))?/;
-		push @{$deps{$ext}},$1;
-		my $type = $2 ? $2 : 'BR';
-		$deps_type{$ext}->{$1} = $type;
-	}
-}
-
-
-%extrafull = (
-	gridsite=>'org.gridsite.core',
-	'canl.c' => 'emi.canl.canl-c',
-	'canl.c-devel' => 'emi.canl.canl-c',
-	'jobid.api-c-devel' => 'org.glite.jobid.api-c',
-	'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp',
-	'lbjp-common.db-devel' => 'org.glite.lbjp-common.db',
-	'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin',
-	'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss',
-	'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface',
-	'lbjp-common.log-devel' => 'org.glite.lbjp-common.log',
-	'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir',
-	'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones',
-	'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio',
-	'lb.client-devel' => 'org.glite.lb.client',
-	'lb.client-progs' => 'org.glite.lb.client',
-	'lb.common-devel' => 'org.glite.lb.common',
-	'lb.logger-devel' => 'org.glite.lb.logger',
-	'lb.state-machine-devel' => 'org.glite.lb.state-machine',
-	'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal',
-	'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal',
-);
-
-#( java => 'client-java' );
-%extranodmod = (
-	db => 'lbjp-common.db',
-	jpprimary => 'jp.primary',
-	jpindex => 'jp.index',
-	jpclient => 'jp.client',
-	lb => 'lb.glite-LB',
-	px => 'px.glite-PX',
-	proxyrenewal => 'px.proxyrenewal',
-	canl => 'canl.c',
-);
-
-%obsoletes = (
-	'lb.yaim' => [ qq/glite-yaim-lb/ ],
-	'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ],
-	'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ],
-	'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec
-	'lbjp-common.gss' => [ qq/glite-security-gss/ ],
-	'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
-);
-
-%conflicts = (
-);
-
-%provides = (
-	'lbjp-common.gss' => [ qq/glite-security-gss/ ],
-	'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
-	'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ],
-);
-
-%cvs_prefix = (
-	'lb' => 'org.glite',
-	'jp' => 'org.glite',
-	'jobid' => 'org.glite',
-	'lbjp-common' => 'org.glite',
-	'gridsite' => 'org',
-	'px' => 'org.glite',
-	'canl' => 'emi',
-);
-
-%cvs_tag_prefix = (
-	'lb' => 'glite-',
-	'jp' => 'glite-',
-	'jobid' => 'glite-',
-	'lbjp-common' => 'glite-',
-	'gridsite' => '',
-	'px' => 'glite-',
-	'canl' => 'emi-',
-);
-
-# ==== projects specification ====
-# etics_name ........... ETICS project name
-# conf_prefix .......... ETICS configurations name prefix
-# tag_prefix ........... VCS tag prefix
-# local_prefix ......... prefix (relative to stage)
-# etics_externs ........ ETICS modules names of externals
-#                        (${NAME.location}, ETICS conf. dependencies)
-# etics_projects ....... ETICS project names of externals
-# etics_externs_devel .. ETICS modules names of devel versions of externals
-# etics_locations ...... ETICS locations in ${NAME.location} properties
-# need_externs_aux ..... project-specific external dependencies
-# supported_platforms .. platforms supported by the project
-# modules .............. additional modules in subsystems
-%projects = (
-	glite => {
-		etics_name => 'org.glite',
-		conf_prefix => { %cvs_tag_prefix },
-		tag_prefix => { %cvs_tag_prefix },
-		flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}',
-		local_prefix => '',
-		etics_externs => {
-			default => {
-				globus_essentials=>'vdt_globus_essentials',
-				globus=>'globus',
-				globus_proxy_utils=>'vdt_globus_essentials',
-				gridsite=>'org.gridsite.shared',
-				yaim_core=>'org.glite.yaim.core',
-				gip_release=>'glite-info-provider-release',
-				gip_service=>'glite-info-provider-service',
-				bdii=>'bdii',
-				glite_version=>'glite-version',
-				glite_info_templates=>'glite-info-templates',
-				glue_schema=>'glue-schema',
-				trustmanager=>'org.glite.security.trustmanager',
-				axis=>'axis',
-				lcas=>'org.glite.security.lcas',
-				gsoapxx=>'-',
-				jdk=>'jdk',
-				voms=>'org.glite.security.voms-api-cpp',
-			},
-		},
-		etics_externs_devel => {
-			default => {
-				gridsite=>'org.gridsite.devel',
-				voms=>'org.glite.security.voms-api',
-			},
-		},
-		etics_projects => {
-			vdt=>[qw/globus globus_essentials globus_proxy_utils gpt/],
-			'org.glite'=>[qw/voms gridsite lcas gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/],
-		},
-		etics_locations => {
-			'*' => '',
-		},
-		need_externs_aux => {
-			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ],
-			'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ],
-			'lb.yaim' => [ qw/yaim_core:R perl-LDAP:R/ ],
-			'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/],
-			'px.myproxy-yaim' => [ qw/yaim_core:R/ ],
-		},
-		supported_platforms => {
-			sl5_x86_64_gcc412 => 1,
-			sl5_ia32_gcc412 => 1,
-			deb5_x86_64_gcc432 => 1,
-			deb5_ia32_gcc432 => 1,
-			slc4_x86_64_gcc346 => 1,
-			slc4_ia32_gcc346 => 1,
-		},
-		modules => {
-			'lb' => [ qw/glite-LB/ ],
-			'px' => [ qw/glite-PX/ ],
-		},
-	},
-
-	emi => {
-		etics_name => 'emi',
-		conf_prefix => {
-			'lb' => 'emi-',
-			'jp' => 'emi-',
-			'jobid' => 'emi-',
-			'lbjp-common' => 'emi-',
-			'gridsite' => 'emi-',
-			'px' => 'emi-',
-			'canl' => 'emi-',
-		},
-		tag_prefix => { %cvs_tag_prefix },
-		flavours => '--thrflavour= --nothrflavour=',
-		local_prefix => '/usr',
-		etics_externs => {
-			default => {
-				globus_essentials=>'globus-gssapi-gsi',
-				globus=>'globus-gssapi-gsi-devel',
-				globus_proxy_utils=>'globus-proxy-utils',
-				gridsite=>'emi.gridsite.shared',
-				yaim_core=>'emi.yaim.yaim-core',
-				yaim_bdii=>'emi.bdii.yaim-bdii',
-				gip_service=>'emi.bdii.glite-info-provider-service',
-				bdii=>'emi.bdii.core',
-				glite_version=>'emi.emi-version',
-				glue_schema=>'emi.bdii.glue-schema',
-				trustmanager=>'emi.java-security.trustmanager',
-				trustmanager_axis=>'emi.java-security.trustmanager-axis',
-				axis=>'axis1.4',
-				lcas=>'emi.sac.lcas',
-				gsoapxx=>'-',
-				jdk=>'java',
-				voms => 'emi.voms.voms-api',
-			},
-			sl5_x86_64_gcc412EPEL => {
-				'myproxy-devel' => 'myproxy-devel.x86_64',
-			},
-			sl6_x86_64_gcc446EPEL => {
-				'myproxy-devel' => 'myproxy-devel.x86_64',
-			},
-			deb6_x86_64_gcc445 => {
-				axis => 'axis1.4',
-				# mappings in ETICS project configuration
-				#globus_essentials => 'libglobus-gssapi-gsi4',
-				#globus => 'libglobus-gssapi-gsi-dev',
-				#axis => 'libaxis-java',
-				#cares => 'libc-ares2',
-				#cppunit => 'libcppunit',
-				#expat => 'libexpat1',
-				#log4c => 'liblog4c3',
-				#curl => 'libcurl3',
-				#'mysql' => 'libmysqlclient16',
-				#'mysql-devel' => 'libmysqlclient-dev',
-				#libxslt => 'xsltproc',
-				#'jakarta-commons-codec' => 'libcommons-codec-java',
-				#'jakarta-commons-lang' => 'libcommons-lang-java',
-				#'tetex-latex' => 'texlive-latex-extra',
-				#'perl-LDAP' => 'libnet-ldap-perl',
-				#'fuse-lib' => 'libfuse2',
-				#'fuse' => 'fuse-utils',
-			},
-		},
-		etics_externs_devel => {
-			default => {
-				cares => 'c-ares-devel',
-				classads => 'classads-devel',
-				cppunit => 'cppunit-devel',
-				expat => 'expat-devel',
-				gsoap => 'gsoap-devel',
-				voms => 'emi.voms.voms-api-devel',
-				libtar => 'libtar-devel',
-				log4c => 'log4c-devel',
-				postgresql => 'postgresql-devel',
-				curl => 'curl-devel',
-				libxml2 => 'libxml2-devel',
-				openssl => 'openssl-devel',
-				gridsite=>'emi.gridsite.devel',
-				jdk=>'java-devel',
-			},
-			deb6_x86_64_gcc445 => {
-				# mappings in ETICS project configuration
-				#cares => 'libc-ares-dev',
-				#cppunit => 'libcppunit-dev',
-				#expat => 'libexpat1-dev',
-				#libtar => 'libtar-dev',
-				#log4c => 'liblog4c-dev',
-				#postgresql => 'libpq-dev',
-				#curl => 'libcurl4-openssl-dev',
-				#libxml2 => 'libxml2-dev',
-				#openssl => 'libssl-dev',
-				#'tetex-latex' => 'texlive-latex-extra',
-				#libxslt=>'xsltproc',
-				#'httpd-devel' => 'apache2-prefork-dev',
-				#'fuse-devel' => 'libfuse-dev',
-				#gsoap => 'gsoap',
-			},
-		},
-		etics_projects => {
-			'emi'=>[qw/voms voms-devel gridsite lcas gip_service bdii glite_version glue_schema yaim_core yaim_bdii trustmanager trustmanager_axis/],
-		},
-		etics_locations => {
-			axis => 'axis',
-		},
-		need_externs_aux => {
-			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ],
-			'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ],
-			'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R perl-LDAP:R/ ],
-			'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/],
-			'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ],
-		},
-		supported_platforms => {
-			sl5_x86_64_gcc412EPEL => 1,
-			sl5_ia32_gcc412EPEL => 1,
-			sl6_x86_64_gcc446EPEL => 1,
-			deb6_x86_64_gcc445 => 1,
-		},
-		modules => {
-			'lb' => [ qw/emi-lb/ ],
-			'px' => [ qw/emi-px/ ],
-		},
-	},
-);
-
-%platform_properties = (
-	'jobid.api-java' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.types' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.doc' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.ws-interface' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.yaim' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.nagios' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'px.yaim' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'px.myproxy-config' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'gridsite.devel' => {
-		default => { 'packageName' => 'gridsite-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' },
-	},
-	'canl.c-devel' => {
-		default => { 'packageName' => 'canl-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' },
-	},
-	'jobid.api-c-devel' => {
-		default => { 'packageName' => 'glite-jobid-api-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' },
-	},
-	'jobid.api-cpp-devel' => {
-		default => { 'packageName' => 'glite-jobid-api-cpp-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' },
-	},
-	'lbjp-common.db-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-db-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' },
-	},
-	'lbjp-common.gsoap-plugin-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' },
-	},
-	'lbjp-common.gss-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-gss-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' },
-	},
-	'lbjp-common.jp-interface-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' },
-	},
-	'lbjp-common.log-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-log-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' },
-	},
-	'lbjp-common.maildir-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-maildir-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' },
-	},
-	'lbjp-common.server-bones-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' },
-	},
-	'lbjp-common.trio-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-trio-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' },
-	},
-	'lb.client-devel' => {
-		default => { 'packageName' => 'glite-lb-client-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' },
-	},
-	'lb.common-devel' => {
-		default => { 'packageName' => 'glite-lb-common-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' },
-	},
-	'lb.state-machine-devel' => {
-		default => { 'packageName' => 'glite-lb-state-machine-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' },
-	},
-	'lb.logger-devel' => {
-		default => { 'packageName' => 'glite-lb-logger-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' },
-	},
-	'px.proxyrenewal-devel' => {
-		default => { 'packageName' => 'glite-px-proxyrenewal-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' },
-	},
-	'canl.c-devel' => {
-		default => { 'packageName' => 'canl-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' },
-	},
-);
-
-my @k = keys %deps_aux;
-@buildroot{@k} = ('') x ($#k+1);
-
-$buildroot{'gridsite.core'} = 'src';
-}
-
-sub full
-{
-	my ($short) = @_;
-	my $subsys = $short;
-	$subsys =~ s/\..*//;
-
-	my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite';
-	return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short";
-}
-
-sub get_version
-{
-	my ($fmod, $top_srcdir) = @_;
-
-	my ($subsys,$mod) = split /\./,$fmod,2;
-	my ($major,$minor,$rev,$age);
-	my $old_;
-
-	if ($version) {
-		$version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/;
-		($major,$minor,$rev,$age) = ($1,$2,$3,$4);
-	}
-	else {
-		my $path = "$top_srcdir/project";
-		if ($subsys eq 'gridsite') {
-			$path = "$cvs_prefix{$subsys}.$subsys.core/project";
-		}
-		open V,"$path/version.properties"
-			or die "$path/version.properties: $!\n";
-
-		$old_ = $_;
-		while () {
-			chomp;
-			($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/;
-			$age = $1 if /module\.age\s*=\s*([[:digit:]]+)/;
-		}
-		close V;
-		$_ = $old_;
-
-		$version = "$major.$minor.$rev-$age";
-	}
-
-	return ($major, $minor, $rev, $age);
-}
-
-sub get_description
-{
-	my ($top_srcdir) = @_;
-
-	my $cvs_module = $top_srcdir;
-	my $package_description = "";
-	my $package_summary = "";
-
-	if (-e "$cvs_module/project/package.description") {
-		open V, "$cvs_module/project/package.description";
-		$package_description = join ("", );
-		close V;
-		chomp $package_description;
-	}
-	else {
-		print STDERR "package.description not found for $subsys.$module!\n"; }
-
-	if (-e "$cvs_module/project/package.summary") {
-		open V, "$cvs_module/project/package.summary";
-		$package_summary = join ("", );
-		close V;
-		chomp $package_summary;
-		$package_summary =~ s/\n/\\n/g;
-	}
-	else {
-		print STDERR "package.summary not found for $subsys.$module!\n"; }
-
-	return ($package_summary, $package_description);
-}
-
-sub mkinc
-{
-	my %aux;
-	undef %aux;
-	my @m=qw/
-lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb
-lbjp-common.gss lbjp-common.gsoap-plugin
-jobid.api-c jobid.api-cpp jobid.api-java
-lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin
-jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface
-px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px
-canl.c
-/;
-	@aux{@m} = (1) x ($#m+1);
-
-	my ($short) = @_;
-	my $full = full $short;
-	my ($subsys,$mod) = split /\./,$short,2;
-	my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}";
-
-	unless ($aux{$short}) {
-		print "Makefile.inc not needed in $full\n";
-		return;
-	}
-
-	my $top_srcdir = '.';
-	my $abs_srcdir = '';
-	my $build = '';
-
-	if ($module) {
-		$top_srcdir = $0;
-		$top_srcdir =~ s,/?[^/]*$,,;
-		$abs_srcdir = $top_srcdir;
-		$top_srcdir =~ s,^$,\.,;
-	} else {
-		$build = "$full/";
-		$abs_srcdir = "$full/";
-		unless ($buildroot{$_} eq '') {
-			$top_srcdir = '..';
-			$build .= "$buildroot{$_}/";
-			unless (-d "$build") {
-				mkdir "$build" or die "mkdir $build: $!\n";
-			}
-		}
-	}
-
-	my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir;
-	my ($package_summary, $package_description) = get_description $abs_srcdir;
-	if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; }
-	my $package_description_debian = $package_description;
-	$package_description_debian =~ s/^/ /mg;
-
-	my ($old_locale, $specdate, $debdate);
-
-	# files for ETICS always in root source directory
-	mkdir $abs_srcdir."project" unless (-d $abs_srcdir."project");
-	open PKGCHL,">".$abs_srcdir."project/changelog"
-		or die $abs_srcdir."project/changelog: $!\n";
-	$old_locale = setlocale(LC_TIME);
-	setlocale(LC_TIME, "C");
-	$specdate = strftime("%a %b %d %Y", gmtime());
-	$debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime());
-	setlocale(LC_TIME, $old_locale);
-	print PKGCHL qq{* $specdate CESNET team 
-- automatically generated package
-};
-	close PKGCHL;
-
-	unless ($top_srcdir eq '.') {
-		unlink $build."Makefile";
-		symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n";
-	}
-
-	open MKINC,">".$build."Makefile.inc"
-		or die $build."Makefile.inc: $!\n";
-
-	print "Creating ".$build."Makefile.inc\n";
-
-	print MKINC qq{project = $project
-PREFIX = $root
-prefix = $prefix
-stagedir = $stagedir
-sysroot = $sysroot
-sysconfdir = $sysconfdir
-localstatedir = $localstatedir
-thrflavour = $thrflavour
-nothrflavour = $nothrflavour
-libdir = $libdir
-top_srcdir = $top_srcdir
-};
-
-	for (@{$need_externs{$short}}) {
-		next unless defined $externs{$_} and defined $externs{$_}{prefix};
-		print MKINC "${_}_prefix = $externs{$_}{prefix}\n";
-		print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags};
-	}
-
-	for (@{$need_jars{$short}}) {
-		print MKINC "${_}_jar = $jar{$_}\n"
-	}
-
-	my $need_gsoap = 0;
-	for (@{$need_externs{$short}})  { $need_gsoap = 1 if $_ eq 'gsoap'; }
-
-	print MKINC "gsoap_default_version=".gsoap_version()."\n"  if $need_gsoap;
-
-	close MKINC;
-
-	my $dh;
-	my $debian = 0;
-
-	opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!";
-	for my $dir (readdir $dh) {
-		if ($dir=~/^(.*)\.spec$/) {
-			if ($1 ne $packageName) {
-				printf STDERR "Changed RPM name: $packageName --> $1\n";
-				$packageName=$1;
-			}
-			last;
-		}
-	}
-	closedir $dh;
-
-	for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") {
-		if (-f "$abs_srcdir/project/$file") {
-			my $old_ = $_;
-			printf STDERR "Creating $build$file\n";
-			open DST, ">$build$file";
-			open SRC, "<$abs_srcdir/project/$file";
-			while () {
-				if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; }
-				if (/\@URL\@/) { s/\@URL\@/$package{url}/g; }
-				if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; }
-				if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; }
-				if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; }
-				if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; }
-				if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; }
-				if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; }
-				if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; }
-				if (/\@AGE\@/) { s/\@AGE\@/$age/g; }
-				if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; }
-				if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; }
-				if (/\@DEBIAN_VCS\@/) { s/\@DEBIAN_VCS\@/$package{debian_vcs}/g; }
-				if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; }
-				if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; }
-				printf DST "%s", "$_";
-			}
-			close SRC;
-			close DST;
-			$_ = $old_;
-		}
-	}
-
-	print "Creating ${build}debian/\n";
-
-	`rm -rfv  ${build}debian`;
-	mkdir $build."debian" or die $!;
-	`cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`;
-	`mv ${build}debian.* ${build}debian/ 2>/dev/null`;
-	`rm -f ${build}debian/*.orig`;
-	opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!";
-	for $_ (readdir $dh) {
-		if (/^debian\.(.*)/) {
-			`mv ${build}debian/$_ ${build}debian/$1`;
-			$debian = 1;
-		}
-	}
-	closedir $dh;
-
-	if ($debian) {
-		my ($dir, $file);
-
-		chmod 0755, "${build}debian/rules";
-		$file="${build}debian/docs"; if (not -f $file) { `touch $file`; }
-		$dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; }
-		$file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` }
-		$file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` }
-		$file="${build}debian/changelog"; if (not -f $file) {
-			open FH, ">$file" or die $!;
-			print FH qq{$packageName ($major.$minor.$rev-$age) unstable; urgency=low
-
-  * Automatically generated package
-
- -- $package{maintainer}  $debdate
-};
-			close FH;
-		}
-
-	} else {
-		`rm -rf ${build}debian`;
-	}
-}
-
-BEGIN{
-};
-
-sub mode_etics_packaging {
-	my ($fmod, $cmd, $rpmprepare, $debprepare) = @_;
-	my ($workspaceDir, $srcPackageName, $srcAge, $topDir);
-
-	if ($fmod eq 'gridsite.core') {
-		$workspaceDir = '..';
-		$srcPackageName = 'gridsite';
-		$srcAge = '';
-		$topDir = '../';
-	} else {
-		$workspaceDir = '${workspaceDir}';
-		$srcPackageName = '${packageName}';
-		$srcAge = '-${age}';
-		$topDir = '';
-	}
-
-	$cmd->{clean} = 'make clean
-	rm -rfv ${package.tgzLocation} ${package.SRPMSLocation}';
-	$cmd->{default}{packaging} = $rpmprepare;
-	$cmd->{default}{packaging} .= "dir=\${workspaceDir}/rpm_build_src_\$\$
-	mkdir -p \${package.tgzLocation} \${package.SRPMSLocation} \$dir/{BUILD,RPMS,SOURCES,SRPMS} 2>/dev/null || true
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/SOURCES/
-	rpmbuild -bs --nodeps --define \"_topdir \$dir\" $srcPackageName.spec
-	cp -v \$dir/SRPMS/*.src.rpm \${package.SRPMSLocation}/
-	rm -rf \$dir";
-
-	for my $p ('deb5_x86_64_gcc432', 'deb5_ia32_gcc432', 'deb6_x86_64_gcc445', 'deb6_ia32_gcc445') {
-		for my $c (keys %{$cmd->{default}}) { $cmd->{$p}{$c} = $cmd->{default}{$c}; }
-		$cmd->{$p}{clean} = 'make clean
-	rm -rfv ${package.tgzLocation} ${package.SDEBSLocation}';
-		$cmd->{$p}{packaging} = $debprepare;
-		$cmd->{$p}{packaging} .= "dir=\${workspaceDir}/dpkg_build_src_\$\$
-	mkdir -p \${package.tgzLocation} \${package.SDEBSLocation} \$dir 2>/dev/null || true
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/${srcPackageName}_\${version}.orig.tar.gz
-	tar xzf \$dir/${srcPackageName}_\${version}.orig.tar.gz -C \$dir
-	cp -rf ${topDir}debian/ \$dir/$srcPackageName-\${version}/
-	cd \$dir/$srcPackageName-\${version}
-	dpkg-buildpackage -S -d -nc
-	cd -
-	cp -v \$dir/*.tar.gz \$dir/*.dsc \${package.SDEBSLocation}/
-	rm -rf \$dir";
-	}
-}
-
-sub mode_etics {
-	$fmod = shift;
-
-	die "$0: --module required with --etics\n" unless $fmod;
-	
-	my ($subsys,$module) = split /\./,$fmod,2;
-	my $full = full "$subsys.$module";
-
-	my ($major,$minor,$rev,$age) = get_version $fmod, $full;
-
-	# XXX: --with ignored for platform-dependend packages
-	my @copts = ();
-	my %ge;
-	@ge{@{$etics_projects{$project{etics_name}}}} = (1) x ($#{$etics_projects{$project{etics_name}}}+1);
-
-	for (@{$need_externs{"$subsys.$module"}}) {
-	    if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/ and (defined $externs{$_} or defined $jar{$_})) {
-		my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_;
-		next if ($eext eq '-');
-		if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}) {
-			$eext = $project{etics_locations}{$_} if ($project{etics_locations}{$_});
-			push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}";
-		} else {
-			if ($ge{$_} and not defined $externs{$_}{pkg}) {
-				push @copts, "--with-$_=\${stageDir}";
-			}
-		}
-	    }
-	}
-
-	for (@{$need_jars{"$subsys.$module"}}) {
-		my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_;
-
-		push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_});
-	}
-
-	my $conf;
-	my $conftag;
-	my ($confprefix, $nameprefix, $packageName);
-
-	$dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n";
-
-	$confprefix = $project{conf_prefix}{$subsys};
-	$nameprefix = $confprefix;
-	$nameprefix =~ s/-$//;
-	$nameprefix =~ s/-/\./g;
-	$packageName = "$project{tag_prefix}{$subsys}$subsys-${module}";
-
-	if ($branch) {
-		$conf = "$confprefix${subsys}-${module}_$branch"; 
-		$conftag = $branch;
-		# forced low age number
-		$age = $branch eq 'HEAD' ? '0head' : '0dev';
-		push @copts, '--version ${version}-${age}';
-	}
-	else {
-		$conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; 
-
-# XXX: gridsite hack
-		$conftag = $subsys eq 'gridsite' ? "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : 
-			"$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; }
-
-	my $file = $output ? $output : "$conf.ini";
-	open C,">$file" or die "$file: $!\n";
-
-	my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"};
-
-	my $confdir = $buildroot{"$subsys.$module"} eq '' ? '.' : '..';
-
-	my $cvs_module = full "$subsys.$module";
-	my ($package_summary, $package_description) = get_description $cvs_module;
-	if ($package_description) {
-		$package_description =~ s/\n/\\n/g;
-		$package_description = "package.description = $package_description\n";
-	}
-	if ($package_summary) {
-		$package_summary = "package.summary = $package_summary\n";
-	}
-
-	my %cmd;
-	$cmd_vcs{checkout} = "cvs -d \${vcsroot} co -d \${moduleName} ".($conftag eq 'HEAD' ? '-A' : '-r ${tag}')." $cvs_module 2>/dev/null";
-	#$cmd_vcs{checkout} = "((test -d jra1mw/.git && (cd jra1mw; git pull)) || (git clone -q http://scientific.zcu.cz/git/jra1mw.git";
-	#$cmd_vcs{checkout} .= " && (cd jra1mw; git checkout -b \${tag} --track origin/\${tag})" unless ($conftag eq /HEAD/);
-	#$cmd_vcs{checkout} .= ")) && (test -d \${moduleName} || ln -s jra1mw/$cvs_module \${moduleName})";
-	$cmd_vcs{checkout} .= "\n\ttest -f \${packageName}-\${version}-\${age}.src.tar.gz || (ln -s \${moduleName} \${packageName}-\${version}; tar -chf - \${packageName}-\${version} --exclude CVS --exclude .git --exclude .etics | gzip --best > \${packageName}-\${version}-\${age}.src.tar.gz; rm \${packageName}-\${version})";
-	$cmd_vcs{tag} = "cvs -d \${vcsroot} tag -R \${tag} ${moduleName}";
-
-	$cmd{default}{init} = 'None';
-	$cmd{default}{configure} = 'None';
-	$cmd{default}{compile} = 'None';
-	$cmd{default}{test} = 'None';
-	$cmd{default}{install} = 'None';
-	$cmd{default}{packaging} = 'None';
-	$cmd{default}{clean} = 'make clean';
-
-	if (exists $subpackages{$fmod}) {
-		$cmd{default}{clean} = 'None';
-		$cmd{default}{packaging} = "echo building nothing, $subpackages{$fmod} will build this package";
-		$cmd_vcs{checkout} = "mkdir -v \${moduleName} 2>/dev/null || true";
-	} elsif ($subsys eq 'gridsite') {
-		$cmd_vcs{tag} = 'None';
-
-		if ($module eq 'core') {
-			my $flags;
-
-			if ($project ne 'glite') {
-				# don't evaluate pkg-config calls to get them into source package
-				$flags = 'RELEASE_VERSION=${age}
-	GSOAPDIR=\`pkg-config gsoap --variable=prefix\`
-	OPENSSL_GLOBUS_FLAGS=\`pkg-config globus-openssl --cflags\`
-	OPENSSL_GLOBUS_LIBS=\`pkg-config globus-openssl --libs\`';
-			} else {
-				$flags = 'RELEASE_VERSION=${age}
-	GSOAPDIR=${gsoap.location}
-	OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor}
-	OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir}
-	HTTPD_FLAGS=-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-1 -I${httpd-devel.location}/include/apr-1.0 -I${httpd-devel.location}/include/apr-0 -I${httpd-devel.location}/include/pcre';
-			}
-
-			$cmd{default}{configure} = "cat > Makefile.inc </dev/null";
-			$cmd{default}{init} = 'echo "/sbin/ldconfig" > project/.post
-	echo "/sbin/ldconfig" > project/.postun';
-			$cmd{default}{configure} = "cat > src/Makefile.inc <{default}}) {
-		$defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n";
-	}
-
-	print STDERR "Writing $file\n";
-	print C qq{
-[Configuration-$conf]
-profile = None
-moduleName = $project{etics_name}.$subsys.$module
-displayName = $conf
-description = $cvs_prefix{$subsys}.$subsys.$module
-projectName = $project{etics_name}
-age = $age
-deploymentType = None
-vcsroot = :pserver:anonymous\@glite.cvs.cern.ch:/cvs/glite
-tag = $conftag
-version = $major.$minor.$rev
-$dwpath
-[Platform-default:VcsCommand]
-displayName = None
-description = None
-tag = $cmd_vcs{tag}
-branch = None
-commit = None
-checkout = $cmd_vcs{checkout}
-
-};
-
-	for my $p (keys %cmd) {
-		next if $p ne 'default' and exists $project{supported_platforms} and not exists $project{supported_platforms}{$p};
-
-		print C qq{[Platform-$p:BuildCommand]
-postpublish = None
-packaging = $cmd{$p}{packaging}
-displayName = None
-description = None
-doc = None
-prepublish = None
-publish = None
-compile = $cmd{$p}{compile}
-init = $cmd{$p}{init}
-install = $cmd{$p}{install}
-clean = $cmd{$p}{clean}
-test = $cmd{$p}{test}
-configure = $cmd{$p}{configure}
-checkstyle = None
-
-};
-	}
-
-	print C qq{[Platform-default:Property]
-$buildroot
-package.preserve.libtool = false
-$package_description$package_summary$defprops};
-
-	for (@{$obsoletes{"$subsys.$module"}}) {
-		print C "package.obsoletes = $_\n";
-		print C "package.replaces = $_\n";
-	}
-	for (@{$conflicts{"$subsys.$module"}}) {
-		print C "package.conflicts = $_\n";
-	}
-	for (@{$provides{"$subsys.$module"}}) {
-		print C "package.provides = $_\n";
-	}
-	print C "\n";
-
-	for my $pp (keys %{$platform_properties{"$subsys.$module"}}) {
-		next if $pp eq 'default';
-		next if exists $project{supported_platforms} and not exists $project{supported_platforms}{$pp};
-
-		print C "[Platform-$pp:Property]\n$buildroot\n";
-
-		for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) {
-			print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n";
-		}
-		print C "$package_description$package_summary\n";
-	}
-
-	for my $platform ('default', keys %{$project{supported_platforms}}) {
-		my $used = 0;
-		my $output = '';
-
-		for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) {
-			my $eext = $etics_externs{$platform}{$_};
-			my $edev = $project{etics_externs_devel}{$platform}{$_};
-
-			# for the default platform using package of the same
-			# name for runtime dependency
-			if (not $eext) {
-				if ($platform eq 'default') {
-#print "default runtime $_ on default\n";
-					$eext = $_; }
-				else {
-#print "no runtime $_ on $platform\n";
-					$eext = '-'; }
-			}
-			if ($eext eq '-' and $edev eq '-') {
-#print "skipping $_ on $platform\n";
-				next;
-			}
-
-			my $proj = 'externals';
-			for my $p (keys %etics_projects) {
-				for $m (@{$etics_projects{$p}}) {
-					$proj = $p if $m eq $_;
-				}
-			}
-
-			my $type = $need_externs_type{"$subsys.$module"}->{$_};
-
-			if ($edev) {
-				if ($type eq 'B') {
-					# no runtime - change to devel pkg
-					$eext = $edev;
-				} elsif ($type eq 'BR' or $type eq 'RB') {
-					# additional devel pkg
-					if ($edev ne '-') { $output .= "$proj|$edev = B\n"; }
-				}
-			}
-			if ($eext ne '-') { $output .= "$proj|$eext = $type\n"; }
-		}
-
-		if ($platform eq 'default') {
-			for (@{$deps{"$subsys.$module"}}) {
-				my $type = $deps_type{"$subsys.$module"}->{$_};
-				if (not $used) {
-					$used = 1;
-				}
-				$output .= "$project{etics_name}|$project{etics_name}.$_ = $type\n";
-			}
-		}
-
-		if ($output) {
-					print C qq{
-[Platform-$platform:DynamicDependency]
-$output};
-		}
-	}
-
-	close C;
-
-	for $file ("$cvs_module/project/debian.rules", "$cvs_module/project/$packageName.spec") {
-		my $lib;
-		my $main_module;
-		@copts = ();
-
-		if ($file =~ /debian\.rules$/) { $lib = 'lib'; }
-		else { $lib = '%{_lib}'; }
-
-		my $main_module = "$subsys.$module";
-		if (exists $subpackages{$main_module}) { $main_module = $subpackages{$main_module}; }
-
-		# locations hacks
-		if ($file =~ /$packageName\.spec$/) {
-			if ($fmod eq 'lb.client-java') {
-				push @copts, '';
-				push @copts, '--with-axis=/usr/local/axis1.4';
-			}
-		}
-
-		if (-f $file) {
-			open DST,">$file.new" or die "$file.new: $!\n";
-			open SRC,"<$file" or die "$file: $!\n";
-			while () {
-				if (/^(\s*).+\/configure\s/) {
-					printf DST "%s", "$1";
-					printf DST "/usr/bin/perl $confdir/configure $project{flavours} --root=/ --prefix=$project{local_prefix} --libdir=$lib --project=$project --module $main_module@copts\n";
-				} else {
-					printf DST "%s", "$_";
-				}
-			}
-			close SRC;
-			close DST;
-
-			`diff -b "$file" "$file.new"`;
-			if ($? == 0) {
-				print STDERR "($file not changed)\n";
-				unlink "$file.new";
-			} else {
-				print STDERR "Writing $file\n";
-				rename "$file", "$file.orig" unless -f "$file.orig";
-				rename "$file.new", "$file";
-			}
-		}
-	}
-}
-
-sub gsoap_version {
-	local $_;
-	my $gsoap_version;
-	open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n";
-
-	while ($_ = ) {
-		chomp;
-
-		$gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/;
-		$gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/;
-	}
-	close S;
-	return $gsoap_version;
-}
-
-sub getlibdir {
-	if ( -e "/etc/debian_version") { # We are on Debian
-		$lib64="lib";
-		$lib32="lib32";	}
-	else { # Another distribution
-		$lib64="lib64";
-		$lib32="lib";	}
-        $libdir=$lib32;
-
-        open INP, "uname -s | "; # Check kernel name
-        $kname= ;
-        chomp($kname);
-        close INP;
-
-        if ( $kname eq "Linux") {
-                $arch = ("x86_64\npowerpc\nppc64\n");
-
-                open INP, "uname -p | "; # Check processor type
-                $procname= ;
-                chomp($procname);
-                close INP;
-
-                if ($arch =~/^$procname\n/) {
-                        return ($lib64); }
-
-                open INP, "uname -m | "; # Check machine hardware
-                $machname= ;
-                chomp($machname);
-                close INP;
-
-                if ($arch =~/^$machname\n/) {
-                        return ($lib64); }
-
-                # special cases (hyperlink lib64, Debian)
-                if (-l "/usr/lib64") {
-                        $libdir=$lib32; }
-
-                # if /usr/lib64 doesn't exist at all (AIX)
-                unless ( -e "/usr/lib64" ) {
-                        $libdir=$lib32; }
-        }
-
-        if ( $kname eq "SunOS") {
-                if (-e "/usr/lib/64") {
-                $libdir="lib/64"; }
-        }
-
-        return $libdir;
-}
-
-sub reshuffle_platforms($$) {
-	my ($data, $platforms) = @_;
-	my ($platform, %blacklist, $value);
-
-	return if not $platforms;
-
-	for $platform (keys %$data) {
-#print "plat: $platform: $data->{$platform}\n";
-		next if $platform eq 'default';
-		for $_ (keys %{$data->{$platform}}) {
-#print "  blacklist: $_ = $data->{$platform}{$_}\n";
-			$blacklist{$_} = 1;
-		}
-	}
-
-	for $_ (keys %blacklist) {
-		$value = $data->{default}{$_} ? $data->{default}{$_} : $_;
-		for $platform (keys %$platforms) {
-			next if $platform eq 'default';
-			if (not defined $data->{$platform}{$_}) {
-				$data->{$platform}{$_} = $value;
-#print "added $value to $platform\n"
-			}
-		}
-		$data->{default}{$_} = '-';
-#print "deleted $_ from default\n";
-	}
-
-	# merge dependencies across the supported platforms
-	%blacklist = [];
-	for $platform (keys %$platforms) {
-		next if $platform eq 'default';
-		for $_ (keys %{$data->{$platform}}) {
-			$blacklist{$_} = 1;
-		}
-	}
-	for $_ (keys %blacklist) {
-		$value = undef;
-		$same = 1;
-		for $platform (keys %$platforms) {
-			if (not $value) { $value = $data->{$platform}{$_}; }
-			if (not $data->{$platform}{$_} or $value ne $data->{$platform}{$_}) {
-				$same = 0;
-				last;
-			}
-		}
-		if ($same and $value) {
-#print "merged dependency $_\n";
-			$data->{default}{$_} = $value;
-			for $platform (keys %$platforms) {
-				delete $data->{$platform}{$_};
-			}
-		}
-	}
-}
-
-sub usage {
-	my @ext = keys %externs;
-	my @myjars = keys %jar;
-
-	print STDERR qq{
-Usage: $0 options
-
-General options (defaults in []):
-  --prefix=PREFIX		destination directory [./stage]
-  --stage=DIR			staging directory [./stage]
-  --root=DIR			installation root (custom relocation root -> sysroot) [./stage]
-  --sysroot=DIR			system root (custom relocation root -> sysroot) []
-  --sysconfdir=DIR              system configuration directory [PREFIX/etc]
-  --staged=module,module,...	what is already in PREFIX (specify without org.glite.)
-  --thrflavour=flavour
-  --nothrflavour=flavour	threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg]
-  --listmodules=subsys          list modules of a subsystem
-  --listmodules=module          list subpackages of a module
-  --version=maj.min.rev-age	specify version here instead of reading version.properties
-  --branch=branch		CVS branch/etics name suffix (HEAD, branch_2_1, ...)
-  --libdir=libdir		typically [lib,lib64] postfix
-  --project=PROJECT		build or generate etics for a project (glite/emi) [emi]
-  --debug			print more details
-  
-Mode of operation:
-  --mode=\{checkout|build|etics\}	what to do [build]
-  
-What to build:
-  --module=module		build this module only
-  --enable-NODE			build this "node" (set of modules) only
-  --disable-NODE		don't build this node
-  --lb-tag=tag			checkout LB modules with specific tag
-  --jp-tag=tag			checkout JP modules with specific tag
-  --lbjp-common-tag=tag         checkout lbjp-common modules with specific tag
-  --jobid-tag=tag		checkout jobid modules with specific tag
-  --canl-tag=tag		checkout canl modules with specific tag
-
-Dependencies (summary of what will be used is always printed):
-  --with-EXTERNAL=PATH		where to look for an external [autodetect]
-  --with-JAR=JAR		where to look for jars
-
-Available nodes:
-    @nodes
-
-Default nodes:
-    @default_nodes
-
-Externals (not all for all modules) are:
-    @ext
-
-External jars are:
-    @myjars
-
-};
-
-}
diff --git a/org.glite.lb.emi-lb/project/ChangeLog b/org.glite.lb.emi-lb/project/ChangeLog
deleted file mode 100644
index 7ef4de1..0000000
--- a/org.glite.lb.emi-lb/project/ChangeLog
+++ /dev/null
@@ -1,6 +0,0 @@
-1.0.0-1
-- First release with EMI
-
-1.0.1-1
-- New dependencies on packages spun off while restructuring
-
diff --git a/org.glite.lb.emi-lb/project/debian.control b/org.glite.lb.emi-lb/project/debian.control
deleted file mode 100644
index 0cc7819..0000000
--- a/org.glite.lb.emi-lb/project/debian.control
+++ /dev/null
@@ -1,18 +0,0 @@
-Source: emi-lb
-Priority: extra
-Maintainer: @MAINTAINER@
-Uploaders: @UPLOADERS@
-Build-Depends: debhelper (>= 7.0.50~)
-Standards-Version: 3.9.1
-Section: net
-Homepage: @URL@
-DM-Upload-Allowed: yes
-@DEBIAN_VCS@
-
-Package: emi-lb
-Section: net
-Architecture: any
-Depends: ${misc:Depends}, bdii, emi-version, fetch-crl, glite-lb-client-java, glite-lb-client-progs, glite-lb-doc, glite-lb-harvester, glite-lb-logger, glite-lb-logger-msg, glite-lb-server, glite-lb-utils, glite-lb-ws-test, glite-lb-yaim, glue-schema
-Recommends: glite-info-provider-service
-Description: @SUMMARY@
-@DEBIAN_DESCRIPTION@
diff --git a/org.glite.lb.emi-lb/project/debian.copyright b/org.glite.lb.emi-lb/project/debian.copyright
deleted file mode 100644
index 3d762ae..0000000
--- a/org.glite.lb.emi-lb/project/debian.copyright
+++ /dev/null
@@ -1,38 +0,0 @@
-This work was packaged for Debian by:
-
-    @MAINTAINER@ on Thu, 08 Dec 2011 00:46:07 +0100
-
-It was downloaded from:
-
-    @URL@
-
-Upstream Author(s):
-
-    @MAINTAINER@
-
-Copyright:
-
-    
-
-License:
-
-   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.
-
-On Debian systems, the complete text of the Apache version 2.0 license
-can be found in "/usr/share/common-licenses/Apache-2.0".
-
-The Debian packaging is:
-
-    Copyright (C) 2004-2011 Members of the EGEE Collaboration
-
-and is licensed under the Apache License, Version 2.0.
diff --git a/org.glite.lb.emi-lb/project/debian.rules b/org.glite.lb.emi-lb/project/debian.rules
deleted file mode 100644
index 376f8c9..0000000
--- a/org.glite.lb.emi-lb/project/debian.rules
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile -*-
-
--include /usr/share/dpkg/buildflags.mk
-
-# Uncomment this to turn on verbose mode.
-export DH_VERBOSE=1
-
-configure: configure-stamp
-configure-stamp:
-	dh_testdir
-	/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=lib --project=emi --module lb.emi-lb
-	touch $@
-
-build: build-indep
-
-build-indep: build-stamp
-
-build-stamp: configure-stamp
-	dh_testdir
-	touch $@
-
-clean: configure-stamp
-	dh_testdir
-	dh_testroot
-	rm -f configure-stamp build-stamp
-	$(MAKE) clean
-	rm -f Makefile.inc config.status
-	dh_clean
-
-install: build-stamp
-	dh_testdir
-	dh_testroot
-	dh_prep
-	dh_installdirs
-
-binary-indep: install
-	dh_testdir
-	dh_testroot
-	dh_installchangelogs
-	dh_installdocs
-	dh_installexamples
-	dh_installman
-	dh_installlogrotate
-	dh_installcron
-	dh_install --fail-missing
-	dh_link
-	dh_compress
-	dh_fixperms
-	dh_makeshlibs
-	dh_installdeb
-	dh_shlibdeps
-	dh_gencontrol
-	dh_md5sums
-	dh_builddeb
-
-binary: binary-indep
diff --git a/org.glite.lb.emi-lb/project/emi-lb.spec b/org.glite.lb.emi-lb/project/emi-lb.spec
deleted file mode 100644
index 066e057..0000000
--- a/org.glite.lb.emi-lb/project/emi-lb.spec
+++ /dev/null
@@ -1,59 +0,0 @@
-Summary: @SUMMARY@
-Name: emi-lb
-Version: @MAJOR@.@MINOR@.@REVISION@
-Release: @AGE@%{?dist}
-Url: @URL@
-License: ASL 2.0
-Vendor: EMI
-Group: System Environment/Base
-Requires: bdii
-Requires: emi-version
-Requires: fetch-crl
-Requires: glite-lb-client-java
-Requires: glite-lb-client-progs
-Requires: glite-lb-doc
-Requires: glite-lb-harvester
-Requires: glite-lb-logger
-Requires: glite-lb-logger-msg
-Requires: glite-lb-server
-Requires: glite-lb-utils
-Requires: glite-lb-ws-test
-Requires: glite-lb-yaim
-#Requires: glue-service-provider
-Requires: glite-info-provider-service
-Requires: glue-schema
-Obsoletes: glite-LB <= 3.3.3-3
-BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
-AutoReqProv: yes
-Source: http://eticssoft.web.cern.ch/eticssoft/repository/emi/emi.lb.emi-lb/%{version}/src/%{name}-@VERSION@.src.tar.gz
-
-
-%description
-@DESCRIPTION@
-
-
-%prep
-%setup -q
-
-
-%build
-
-
-%check
-
-
-%install
-rm -rf $RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-
-%files
-
-
-%changelog
-* @SPEC_DATE@ @MAINTAINER@ - @MAJOR@.@MINOR@.@REVISION@-@AGE@%{?dist}
-- automatically generated package
diff --git a/org.glite.lb.emi-lb/project/package.description b/org.glite.lb.emi-lb/project/package.description
deleted file mode 100644
index ebc46ce..0000000
--- a/org.glite.lb.emi-lb/project/package.description
+++ /dev/null
@@ -1 +0,0 @@
-Metapackage to install the L&B service on an LB node
diff --git a/org.glite.lb.emi-lb/project/package.summary b/org.glite.lb.emi-lb/project/package.summary
deleted file mode 100644
index ebc46ce..0000000
--- a/org.glite.lb.emi-lb/project/package.summary
+++ /dev/null
@@ -1 +0,0 @@
-Metapackage to install the L&B service on an LB node
diff --git a/org.glite.lb.emi-lb/project/version.properties b/org.glite.lb.emi-lb/project/version.properties
deleted file mode 100644
index b527236..0000000
--- a/org.glite.lb.emi-lb/project/version.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# $Header
-module.version=1.0.1
-module.age=1
diff --git a/org.glite.lb.glite-LB/Makefile b/org.glite.lb.glite-LB/Makefile
deleted file mode 100644
index 13a1e41..0000000
--- a/org.glite.lb.glite-LB/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-top_srcdir=..
-stagedir=.
-package=glite-lb-yaim
-version=0.0.0
-PREFIX=/opt/glite
-prefix=
-
--include Makefile.inc
--include ${top_srcdir}/project/version.properties
-
-default all:
-
-install:
-
-stage:
-	$(MAKE) install PREFIX=${stagedir}
-
-check:
-
-clean:
-	rm -rvf log.xml rpmbuild/ RPMS/ tgz/ debian/
-
-.PHONY: default all check install stage clean
diff --git a/org.glite.lb.glite-LB/configure b/org.glite.lb.glite-LB/configure
deleted file mode 100755
index 96cd3e0..0000000
--- a/org.glite.lb.glite-LB/configure
+++ /dev/null
@@ -1,1353 +0,0 @@
-#!/usr/bin/perl
-
-# WARNING: Don't edit this file unless it is the master copy in org.glite.lb
-#
-# For the purpose of standalone builds of lb/jobid/lbjp-common components
-# it is copied on tagging 
-
-# $Header$
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners/ for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-use Getopt::Long;
-
-my $pwd = `pwd`; chomp $pwd;
-my $prefix = '/usr';
-my $stagedir = undef;
-my $root = $pwd.'/stage';
-my $sysroot = '';
-my $sysconfdir;
-my $localstatedir;
-my $staged;
-my $module;
-my $thrflavour = 'gcc64dbgpthr';
-my $nothrflavour = 'gcc64dbg';
-my $mode = 'build';
-my $help = 0;
-my $listmodules;
-my $version;
-my $branch;
-my $output;
-my $lb_tag = '';
-my $lbjp_tag = '';
-my $jp_tag = '';
-my $jobid_tag = '';
-my $libdir = getlibdir();
-my $project = 'glite';
-my (%projects, %project);
-my $debug = 0;
-my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : '';
-
-my @nodes = qw/client server logger logger-msg utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal/;
-my @default_nodes = qw/lb px proxyrenewal/;
-my %enable_nodes;
-my %disable_nodes;
-my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1);
-
-# key:      internal package name (arguments, ...)
-# 'pkg':    pkg-config name
-# 'prefix': used when pkg-config fails
-my %externs = (
-	cares => {
-		prefix => '/opt/c-ares',
-		pkg => 'libcares'
-	},
-	classads => {
-		prefix=> '/usr',
-		pkg => 'classads'
-	},
-	cppunit => {
-		prefix=> '/usr',
-		pkg => 'cppunit'
-	},
-	expat => {
-		prefix=> '/usr',
-		pkg => 'expat'
-	},
-	globus => {
-		prefix=> '/opt/globus',
-		pkg => 'globus-gssapi-gsi'
-	},
-	'myproxy-devel' => {
-		prefix=> '/opt/globus',
-		pkg => 'myproxy'
-	},
-	'myproxy-server' => {
-		prefix=> '',
-	},
-	'myproxy-libs' => {
-		prefix=> '',
-	},
-	'myproxy-admin' => {
-		prefix=> '',
-	},
-	gsoap => {
-		prefix=> '/usr',
-		pkg => 'gsoap'
-	},
-	gsoapxx => {
-		prefix=> '/usr',
-		pkg => 'gsoap++'
-	},
-	mysql => {
-		prefix=> '/usr'
-	},
-	'mysql-devel' => {
-		prefix=> ''
-	},
-	'mysql-server' => {
-		prefix => ''
-	},
-	voms => {
-		prefix => '/opt/glite',
-		pkg => 'voms-2.0'
-	},
-	gridsite => {
-		prefix => '/opt/glite'
-	},
-	lcas => {
-		prefix => '/opt/glite',
-		pkg => 'lcas'
-	},
-	trustmanager => {
-		prefix => '/opt/glite'
-	},
-	trustmanager_axis => {
-		prefix => '/opt/glite'
-	},
-	utiljava => {
-		prefix=> '/opt/glite'
-	},
-	ant => {
-		prefix=> '/usr'
-	},
-	jdk => {
-		prefix=> '/usr/java/latest'
-	},
-	libtar => {
-		prefix=> '/usr'
-	},
-	axis => {
-		prefix=> '/usr'
-	},
-	log4c => {
-		prefix=> '/usr'
-	},
-	postgresql => {
-		prefix=> '/usr'
-	},
-	activemq => {
-		prefix=>'/opt/activemq-cpp-library',
-		pkg => 'activemq-cpp'
-	},
-	apr => {
-		prefix=>'/opt/apr',
-		pkg => 'apr-1'
-	},
-	aprutil => {
-		prefix=>'/opt/apr-util',
-		pkg => 'apr-util-1'
-	},
-);
-
-my %jar = (
-	'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar',
-	'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar',
-);
-
-
-my %glite_prefix;
-my %need_externs;
-my %need_externs_type;
-my %need_jars;
-my %extrafull;
-my %extranodmod;
-my %deps;
-my %deps_type;
-my %buildroot;
-my (%etics_externs, %etics_projects);
-
-my %lbmodules = (
-	'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim glite-LB logger-msg/], 
-	'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin/],
-	'jobid' => [qw/api-c api-cpp api-java/],
-	'jp' => [ qw/client doc index primary server-common ws-interface/ ],
-	'gridsite' => [ qw/apache shared commands core devel slashgrid services service-clients gsexec/ ],
-	'px' => [ qw/proxyrenewal glite-PX myproxy-yaim/ ],
-	);
-
-
-my @opts = (
-	'prefix:s' => \$prefix,
-	'staged=s' => \$staged,
-	'module=s' => \$module,
-	'thrflavour:s' => \$thrflavour,
-	'nothrflavour:s' => \$nothrflavour,
-	'mode=s' => \$mode,
-	'listmodules=s' => \$listmodules,
-	'version=s' => \$version,
-	'branch=s' => \$branch,
-	'output=s' => \$output,
-	'stage=s' => \$stagedir,
-	'root:s' => \$root,
-	'sysroot:s' => \$sysroot,
-	'sysconfdir=s' => \$sysconfdir,
-	'localstatedir=s' => \$localstatedir,
-	'lb-tag=s' => \$lb_tag,
-	'lbjp-common-tag=s' => \$lbjp_tag,
-	'jp-tag=s' => \$jp_tag,
-	'jobid-tag=s' => \$jobid_tag,
-	'help' => \$help,
-	'libdir=s' => \$libdir,
-	'project=s' => \$project,
-	'debug' => \$debug,
-);
-
-for (@nodes) {
-	$enable_nodes{$_} = 0;
-	$disable_nodes{$_} = 0;
-	
-	push @opts,"disable-$_",\$disable_nodes{$_};
-	push @opts,"enable-$_",\$enable_nodes{$_};
-}
-
-push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs;
-push @opts,"with-$_=s",\$jar{$_} for keys %jar;
-
-my @keeparg = @ARGV;
-
-GetOptions @opts or die "Errors parsing command line\n";
-$prefix=~s/\/$//;
-$stagedir=~s/\/$// if ($stagedir);
-$root=~s/\/$//;
-$sysroot=~s/\/$//;
-if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; }
-if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; }
-$sysconfdir=~s/\/$//;
-$localstatedir=~s/\/$//;
-
-$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq '';
-$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq '';
-$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq '';
-
-%project = %{$projects{$project}};
-for $_ (keys %{$project{etics_externs}}) {
-	$etics_externs{$_} = $project{etics_externs}{$_};
-}
-for $_ (keys %{$project{etics_projects}}) {
-	$etics_projects{$_} = $project{etics_projects}{$_};
-}
-for $_ (keys %{$project{need_externs_aux}}) {
-	$need_externs_aux{$_} = $project{need_externs_aux}{$_};
-}
-for my $ext (keys %need_externs_aux) {
-	for (@{$need_externs_aux{$ext}}) {
-		my ($pkg, $type) =/([^:]*)(?::(.*))?/;
-		$type = 'BR' unless ($type);
-
-		push @{$need_externs{$ext}},$pkg;
-		$need_externs_type{$ext}->{$pkg} = $type;
-	}
-}
-
-
-if ($help) { usage(); exit 0; }
-
-if ($listmodules) {
-	my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name};
-	my @m = map "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}};
-	print "@m\n";
-	exit 0;
-}
-
-warn "$0: --version, --branch and --output make sense only in --mode=etics\n"
-	if ($version || $output || $branch) && $mode ne 'etics';
-
-my $en;
-for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; }
-
-my $dis;
-for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; }
-
-die "--enable-* and --disable-* are mutually exclusive\n"
-	if $en && $dis;
-
-die "--module cannot be used with --enable-* or --disable-*\n"
-	if $module && ($en || $dis);
-
-die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}};
-
-if ($dis) {
-	for (@nodes) {
-		$enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_});
-	}
-}
-
-if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } };
-
-for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; }
-
-$stagedir = $root unless $stagedir;
-
-if ($mode eq 'build') { for my $ext (keys %externs) {
-	if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; }
-	elsif (defined $externs{$ext}{pkg}) {
-		my ($flag, $env, $cmd, $ret);
-		my $pkg = $externs{$ext}{pkg};
-		my $flagname = uc $externs{$ext}{pkg};
-		$flagname =~ s/-[0-9\.]*$//;
-		$flagname =~ y/-\+/_X/;
-
-		print "Checking $pkg ... ";
-		$env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig";
-		$cmd = "$env pkg-config $pkg --exists >/dev/null";
-		`$cmd`; $ret = $?;
-		print "('$cmd' => $ret)\n" if ($debug);
-		if ($ret == 0) {
-			$externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`;
-			chomp $externs{$ext}{prefix};
-			print "$externs{$ext}{prefix}\n";
-
-			$flag=`$env pkg-config $pkg --cflags`;
-			$externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag);
-			$flag=`$env pkg-config $pkg --libs`;
-			$externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag);
-		} else {
-			print "(using default $externs{$ext}{prefix})\n";
-		}
-		print "\n" if ($debug);
-	}
-	elsif ($ext eq 'jdk') {
-		my $jdk_prefix;
-
-		print "Looking for some caffein ... ";
-		if (defined $ENV{'JDK_HOME'}) {
-			$jdk_prefix = $ENV{'JDK_HOME'};
-			print "JDK_HOME=$jdk_prefix\n";
-		} elsif (defined $ENV{'JAVA_HOME'}) {
-			$jdk_prefix = $ENV{'JAVA_HOME'};
-			print "JAVA_HOME=$jdk_prefix\n";
-		} else {
-			print "(using default $externs{$ext}{prefix}))\n"
-		}
-		$externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix);
-	}
-} }
-
-if ($mode eq 'build') {
-	print "Writing config.status\n";
-	open CONF,">config.status" or die "config.status: $!\n";
-	for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') {
-		print CONF "$_=$ENV{$_} " if (defined $ENV{$_});
-	}
-	print CONF "$0 @keeparg\n";
-	close CONF;
-}
-
-
-my @modules;
-my %aux;
-
-if ($module) {
-#	push @modules,split(/[,.]+/,$module);
-	push @modules,$module;
-}
-else {
-	@modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes));
-	
-	my $n;
-
-	do {
-		local $"="\n";
- 		$n = $#modules;
-		push @modules,(map @{$deps{$_}},@modules);
-
-		undef %aux; @aux{@modules} = (1) x ($#modules+1);
-		@modules = keys %aux;
-	} while ($#modules > $n);
-}
-
-@aux{@modules} = (1) x ($#modules+1);
-delete $aux{$_} for (split /,/,$staged);
-@modules = keys %aux;
-
-mode_build() if $mode eq 'build';
-mode_checkout() if $mode eq 'checkout';
-mode_etics($module) if $mode eq 'etics';
-
-sub mode_build {
-	print "\nBuilding modules: @modules\n";
-	print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n";
-	
-	my @ext = map @{$need_externs{$_}},@modules;
-	my @myjars = map @{$need_jars{$_}},@modules;
-	undef %aux; @aux{@ext} = 1;
-	@ext = keys %aux;
-	undef %aux; @aux{@myjars} = (1) x ($#myjars+1);
-	@myjars = keys %aux;
-	
-	print "\nRequired externals:\n";
-	print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext;
-	print "\t$_: $jar{$_}\n" for @myjars;
-	for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } };
-	print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n";
-	
-	mkinc($_) for @modules;
-
-	if ($module) {
-		print "Not creating summary Makefile\n" if $debug;
-	} else {
-		print "Creating Makefile\n";
-
-		open MAK,">Makefile" or die "Makefile: $!\n";
-
-		print MAK "all: @modules\n\nclean check:\n";
-
-		for (@modules) {
-			my $full = full($_);
-			print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n"
-		}
-
-		print MAK "\ndistclean:\n";
-
-		for (@modules) {
-			my $full = full($_);
-			print MAK $buildroot{$_} eq '' ?
-				"\tcd $full && \${MAKE} distclean\n" :
-				"\trm -rf $full/$buildroot{$_}\n"
-		}
-
-		print MAK "\n";
-
-		for (@modules) {
-			my %ldeps; undef %ldeps;
-			@ldeps{@{$deps{$_}}} = 1;
-			for my $x (split /,/,$staged) { delete $ldeps{$x}; }
-			my @dnames = $module ? () : keys %ldeps;
-
-			my $full = full($_);
-			my $build = $buildroot{$_};
-
-			print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n";
-		}
-
-		close MAK;
-	}
-}
-	
-sub mode_checkout() {
-	for (@modules) {
-		my $module = $_;
-		my $tag = "";
-		if ($lb_tag){
-			for (@{$lbmodules{lb}}){
-				if ("lb.".$_ eq $module){
-					$tag = '-r '.$lb_tag;
-				}
-			}	
-		}
-		if ($lbjp_tag){
-			for (@{$lbmodules{'lbjp-common'}}){
-				if ("lbjp-common.".$_ eq $module){
-                                        $tag = '-r '.$lbjp_tag;
-                                }
-			}
-		}
-		if ($jp_tag){
-			for (@{$lbmodules{'jp'}}){
-	                        if ("jp.".$_ eq $module){
-                                        $tag = '-r '.$jp_tag;
-	                        }
-                        }
-		}
-		if ($jobid_tag){
-			for (@{$lbmodules{jobid}}){
-				if ("jobid.".$_ eq $module){
-                                        $tag = '-r '.$jobid_tag;
-                                }
-			}
-		}
-		#if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){
-		#	print "found";
-		#}
-		$_ = full($_);
-		print "\n*** Checking out $_\n";
-		system("cvs checkout  $tag $_") == 0 or die "cvs checkout $tag $_: $?\n";
-	}
-}
-
-BEGIN{
-%etics_externs = (
-	'myproxy-devel'=>'myproxy-devel',
-	'myproxy-libs'=>'myproxy-libs',
-	'myproxy-server'=>'myproxy-server',
-	'myproxy-admin'=>'myproxy-admin',
-	cares=>'c-ares',
-	voms=>'org.glite.security.voms-api-cpp',
-	utiljava=>'org.glite.security.util-java',
-	gpt=>'gpt',
-	fetchcrl=>'fetch-crl',
-	activemq=>'activemq-cpp-library',
-	apr=>'apr-dev',
-	aprutil=>'aprutil-dev',
-);
-
-%etics_projects = (
-);
-
-%need_externs_aux = (
-	'lb.client' => [ qw/cppunit:B classads libtool:B/ ],
-	'lb.common' => [ qw/expat cares:B cppunit:B classads libtool:B/ ],
-	'lb.doc' => [ qw/tetex-latex:B/ ],
-	'lb.logger' => [ qw/cppunit:B libtool:B/ ],
-	'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B/ ],
-	'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql:R mysql-server:R mysql-devel:B cppunit:B gsoap:B classads voms lcas gridsite bison:B libtool:B/ ],
-	'lb.state-machine' => [ qw/classads libtool:B/ ],
-	'lb.utils' => [ qw/cppunit:B libtool:B/ ],
-	'lb.ws-interface' => [],
-	'lb.ws-test' => [ qw/gsoap:B libtool:B/ ],
-	'lb.types' => [ qw// ],
-	'lb.harvester' => [ qw/docbook-utils:B libtool:B/ ],
-	'lbjp-common.db' => [ qw/mysql:B mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B/ ],
-	'lbjp-common.log' => [ qw/log4c libtool:B/ ],
-	'lbjp-common.maildir' => [ qw/libtool:B/ ],
-	'lbjp-common.server-bones' => [ qw/libtool:B/ ],
-	'lbjp-common.trio' => [ qw/cppunit:B libtool:B/ ],
-	'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B/ ],
-	'lbjp-common.gss' =>  [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B/ ],
-	'lbjp-common.gsoap-plugin' =>  [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B/ ],
-	'jobid.api-c' =>  [ qw/cppunit:B libtool:B/ ],
-	'jobid.api-cpp' =>  [ qw/cppunit:B/ ],
-	'jobid.api-java' =>  [ qw/ant:B jdk:B/ ],
-	'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ],
-        'jp.doc' => [],
-        'jp.index' => [ qw/gsoap globus_essentials:R globus:B/ ],
-        'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B/ ],
-        'jp.server-common' => [],
-        'jp.ws-interface' => [],
-	'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2 openssl:B build_common_cpp:B doxygen:B/ ],
-	'gridsite.commands' => [ qw/curl:R openssl:R/ ],
-	'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ],
-	'gridsite.shared' => [ qw/libxml2:R openssl:R/ ],
-	'gridsite.devel' => [],
-	'gridsite.slashgrid' => [ qw/curl:R fuse-libs:R fuse:R/],
-	'gridsite.services' => [ qw/curl:R gsoap:R/ ],
-	'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ],
-	'gridsite.gsexec' => [ qw// ],
-	'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B myproxy-libs:R voms libtool:R/ ],
-	'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec
-);
-
-%need_jars = (
-	'jobid.api-java' => [ qw/jakarta-commons-codec/ ],
-	'lb.client-java' => [ qw/jakarta-commons-lang/ ],
-);
-
-for my $jar (keys %need_jars) {
-	for (@{$need_jars{$jar}}) {
-		$need_externs_type{$jar}->{$_} = 'BR'; 	# XXX
-	}
-}
-
-%deps_aux = (
-	'lb.client' => [ qw/
-		lb.types:B lb.common
-		lbjp-common.trio
-		jobid.api-cpp:B jobid.api-c
-		lbjp-common.gss
-	/ ],
-	'lb.client-java' => [ qw/
-		lb.types:B
-		lb.ws-interface:B
-		jobid.api-java
-	/ ],
-	'lb.common' => [ qw/
-		jobid.api-cpp:B jobid.api-c
-		lb.types:B lbjp-common.trio lbjp-common.gss
-	/ ],
-	'lb.doc' => [ qw/lb.types:B/ ],
-	'lb.logger' => [ qw/
-		lbjp-common.trio
-		lbjp-common.log
-		jobid.api-c
-		lb.common
-		lbjp-common.gss
-	/ ],
-	'lb.logger-msg' => [ qw/
-		lb.logger
-	/ ],
-	'lb.server' => [ qw/
-		lb.ws-interface lb.types:B lb.common lb.state-machine
-		lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log
-		jobid.api-c
-		lbjp-common.gsoap-plugin lbjp-common.gss
-	/ ],
-	'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ],
-	'lb.utils' => [ qw/
-		lbjp-common.jp-interface
-		jobid.api-c
-		lbjp-common.trio lbjp-common.maildir
-		lb.client lb.state-machine
-	/ ],
-	'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ],
-	'lb.ws-interface' => [ qw/lb.types:B/ ],
-	'lb.types' => [ qw// ],
-	'lb.harvester' => [ qw/
-		jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client
-		lbjp-common.gss lbjp-common.log
-	/ ],
-	'lb.yaim' => [ qw// ],
-	'lb.glite-LB' => [ qw/
-		lb.logger:R lb.server:R lb.utils:R lb.doc:R
-		lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R
-		lb.logger-msg:R
-	/ ],
-	'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ],
-	'lbjp-common.maildir' => [ qw// ],
-	'lbjp-common.log' => [ qw// ],
-	'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ],
-	'lbjp-common.trio' => [ qw// ],
-	'lbjp-common.gss' =>  [ qw// ],
-	'lbjp-common.gsoap-plugin' =>  [ qw/lbjp-common.gss/ ],
-	'jobid.api-c' =>  [ qw// ],
-	'jobid.api-cpp' =>  [ qw/jobid.api-c/ ],
-	'jobid.api-java' =>  [ qw// ],
-
-	'lbjp-common.jp-interface' => [ qw/lbjp-common.db jobid.api-c/ ],
-
-	'jp.client' => [ qw/
-                jp.ws-interface
-                lbjp-common.jp-interface lbjp-common.maildir
-                jobid.api-c
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.doc' => [ qw// ],
-	'jp.index' => [ qw/
-                jp.server-common jp.ws-interface
-                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.primary' => [ qw/
-                jobid.api-c
-                jp.server-common jp.ws-interface
-                lb.state-machine
-                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.server-common' => [ qw/ 
-                lbjp-common.jp-interface lbjp-common.db
-        / ],
-	'jp.ws-interface' => [ qw// ],
-
-	'gridsite.core' => [ qw// ],
-	'gridsite.commands' => [ qw/gridsite.shared:R/ ],
-	'gridsite.apache' => [ qw/gridsite.shared:R/ ],
-	'gridsite.shared' => [ qw// ],
-	'gridsite.devel' => [ qw/gridsite.shared:R/ ],
-	'gridsite.slashgrid' => [ qw/gridsite.shared:R/],
-	'gridsite.services' => [ qw/gridsite.shared:R/ ],
-	'gridsite.service-clients' => [ qw/gridsite.shared:R/ ],
-	'gridsite.gsexec' => [ qw// ],
-
-	'px.proxyrenewal' => [ qw// ],
-	'px.glite-PX' => [qw/px.myproxy-yaim:R/],
-	'px.myproxy-yaim' => [ qw// ],
-	'px.myproxy-config' => [],
-);
-
-for my $ext (keys %deps_aux) {
-	for (@{$deps_aux{$ext}}) {
-		/([^:]*)(?::(.*))?/;
-		push @{$deps{$ext}},$1;
-		my $type = $2 ? $2 : 'BR';
-		$deps_type{$ext}->{$1} = $type;
-	}
-}
-
-
-%extrafull = ( gridsite=>'org.gridsite.core');
-
-#( java => 'client-java' );
-%extranodmod = (
-	db => 'lbjp-common.db',
-	jpprimary => 'jp.primary',
-	jpindex => 'jp.index',
-	jpclient => 'jp.client',
-	lb => 'lb.glite-LB',
-	px => 'px.glite-PX',
-	proxyrenewal => 'px.proxyrenewal'
-);
-
-%obsoletes = (
-	'lb.yaim' => [ qq/glite-yaim-lb/ ],
-	'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ],
-	'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ],
-	'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec
-	'lbjp-common.gss' => [ qq/glite-security-gss/ ],
-	'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
-	'lb.glite-LB' => [ qq/glite-LB/ ],
-	'px.glite-PX' => [ qq/glite-PX/ ],
-);
-
-%cvs_prefix = (
-	'lb' => 'org.glite',
-	'jp' => 'org.glite',
-	'jobid' => 'org.glite',
-	'lbjp-common' => 'org.glite',
-	'gridsite' => 'org',
-	'px' => 'org.glite',
-);
-
-%cvs_tag_prefix = (
-	'lb' => 'glite-',
-	'jp' => 'glite-',
-	'jobid' => 'glite-',
-	'lbjp-common' => 'glite-',
-	'gridsite' => '',
-	'px' => 'glite-',
-);
-
-# ==== projects specification ====
-# etics_name ........... ETICS project name
-# conf_prefix .......... ETICS configurations name prefix
-# tag_prefix ........... VCS tag prefix
-# local_prefix ......... prefix (relative to stage)
-# etics_externs ........ ETICS modules names of externals
-#                        (${NAME.location}, ETICS conf. dependencies)
-# etics_projects ....... ETICS project names of externals
-# etics_externs_devel .. ETICS modules names of devel versions of externals
-# need_externs_aux ..... project-specific external dependencies
-# supported_platforms .. platforms supported by the project
-%projects = (
-	glite => {
-		etics_name => 'org.glite',
-		conf_prefix => { %cvs_tag_prefix },
-		tag_prefix => { %cvs_tag_prefix },
-		flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}',
-		local_prefix => '',
-		etics_externs => {
-			globus_essentials=>'vdt_globus_essentials',
-			globus=>'globus',
-			gridsite=>'org.gridsite.shared',
-			yaim_core=>'org.glite.yaim.core',
-			gip_release=>'glite-info-provider-release',
-			gip_service=>'glite-info-provider-service',
-			bdii=>'bdii',
-			glite_version=>'glite-version',
-			glite_info_templates=>'glite-info-templates',
-			glue_schema=>'glue-schema',
-			trustmanager=>'org.glite.security.trustmanager',
-			axis=>'axis',
-			lcas=>'org.glite.security.lcas',
-			gsoapxx=>'-',
-			build_common_cpp=>'org.glite.build.common-cpp',
-		},
-		etics_externs_devel => {
-			gridsite=>'org.gridsite.devel',
-		},
-		etics_projects => {
-			vdt=>[qw/globus globus_essentials gpt/],
-			'org.glite'=>[qw/voms gridsite lcas gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/],
-		},
-		need_externs_aux => {
-			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ],
-			'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ],
-			'lb.yaim' => [ qw/yaim_core:R/ ],
-			'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/],
-			'px.myproxy-yaim' => [ qw/yaim_core:R/ ],
-		},
-	},
-
-	emi => {
-		etics_name => 'emi',
-		conf_prefix => {
-			'lb' => 'emi-',
-			'jp' => 'emi-',
-			'jobid' => 'emi-',
-			'lbjp-common' => 'emi-',
-			'gridsite' => '',
-			'px' => 'emi-',
-		},
-		tag_prefix => { %cvs_tag_prefix },
-		flavours => '--thrflavour= --nothrflavour=',
-		local_prefix => '/usr',
-		etics_externs => {
-			globus_essentials=>'globus-gssapi-gsi',
-			globus=>'globus-gssapi-gsi-devel',
-			gridsite=>'emi.gridsite.shared',
-			yaim_core=>'emi.yaim.yaim-core',
-			yaim_bdii=>'emi.bdii.yaim-bdii',
-			gip_release=>'emi.bdii.glite-info-provider-release',
-			gip_service=>'emi.bdii.glite-info-provider-service',
-			bdii=>'emi.bdii.bdii-core',
-			glite_version=>'emi.misc.glite-version',
-			glue_schema=>'emi.bdii.glue-schema',
-			trustmanager=>'emi.java-security.trustmanager',
-			trustmanager_axis=>'emi.java-security.trustmanager-axis',
-			axis=>'axis1.4',
-			lcas=>'emi.sac.lcas',
-			gsoapxx=>'-',
-			build_common_cpp=>'emi.misc.glite.build-common-cpp',
-		},
-		etics_externs_devel => {
-			cares => 'c-ares-devel',
-			classads => 'classads-devel',
-			cppunit => 'cppunit-devel',
-			expat => 'expat-devel',
-			gsoap => 'gsoap-devel',
-			voms => 'org.glite.security.voms-api',
-			libtar => 'libtar-devel',
-			log4c => 'log4c-devel',
-			postgresql => 'postgresql-devel',
-			curl => 'curl-devel',
-			libxml2 => 'libxml2-devel',
-			openssl => 'openssl-devel',
-			gridsite=>'emi.gridsite.devel',
-		},
-		etics_projects => {
-			'emi'=>[qw/voms voms-devel gridsite lcas gip_release gip_service bdii glite_version glue_schema yaim_core yaim_bdii trustmanager trustmanager_axis/],
-		},
-		need_externs_aux => {
-			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ],
-			'lb.glite-LB' => [ qw/fetchcrl:R gip_release:R gip_service:R bdii:R glite_version:R glue_schema:R/ ],
-			'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ],
-			'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/],
-			'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ],
-		},
-		supported_platforms => {
-			sl5_x86_64_gcc412EPEL => 1,
-			sl5_ia32_gcc412EPEL => 1,
-		},
-	},
-);
-
-%platform_properties = (
-	'gridsite.core' => {
-		sl5_x86_64_gcc412 => { aprSuffix => '1' },
-		sl5_ia32_gcc412 => { aprSuffix => '1' },
-		sl5_x86_64_gcc412EPEL => { aprSuffix => '1' },
-		sl5_ia32_gcc412EPEL => { aprSuffix => '1' },
-		deb5_x86_64_gcc432 => { aprSuffix => '1.0' },
-		deb5_ia32_gcc432 => { aprSuffix => '1.0' },
-		slc4_x86_64_gcc346 => { aprSuffix => '0' },
-		slc4_ia32_gcc346 => { aprSuffix => '0' },
-		default => { 
-		}
-	},
-	'jobid.api-java' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.types' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.doc' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.ws-interface' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.yaim' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'px.yaim' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'px.myproxy-config' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-);
-
-my @k = keys %deps_aux;
-@buildroot{@k} = ('') x ($#k+1);
-
-$buildroot{'gridsite.core'} = 'src';
-}
-
-sub full
-{
-	my $short = shift;
-	return $extrafull{$short} ? $extrafull{$short} : 'org.glite.'.$short;
-}
-
-sub mkinc
-{
-	my %aux;
-	undef %aux;
-	my @m=qw/
-lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB
-lbjp-common.gss lbjp-common.gsoap-plugin
-jobid.api-c jobid.api-cpp jobid.api-java
-lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin
-jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface
-px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config
-/;
-	@aux{@m} = (1) x ($#m+1);
-
-	my $short = shift;
-	my $full = full $short;
-
-	unless ($aux{$short}) {
-		print "Makefile.inc not needed in $full\n";
-		return;
-	}
-
-	my $top_srcdir = '.';
-	my $build = '';
-
-	if ($module) {
-		$top_srcdir = $0;
-		$top_srcdir =~ s,/?[^/]*$,,;
-		$top_srcdir =~ s,^$,\.,;
-	} else {
-		$build = "$full/";
-		unless ($buildroot{$_} eq '') {
-			$top_srcdir = '..';
-			$build .= "$buildroot{$_}/";
-			unless (-d "$build") {
-				mkdir "$build" or die "mkdir $build: $!\n";
-			}
-		}
-	}
-	unless ($top_srcdir eq '.') {
-		unlink $build."Makefile";
-		symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n";
-		for my $file ('.pre', '.post', '.preun', '.postun changelog') {
-			my $pfile = "project/$file";
-			if (-f "$full/$pfile") {
-				mkdir "$build/project" unless (-d "$build/project");
-				unlink $build.$pfile;
-				symlink "../$top_srcdir/$pfile", $build.$pfile or die "symlink ../$top_srcdir/$pfile ".$build."$pfile: $!\n";
-			}
-		}
-	}
-
-	open MKINC,">".$build."Makefile.inc"
-		or die $build."Makefile.inc: $!\n";
-
-	print "Creating ".$build."Makefile.inc\n";
-
-	print MKINC qq{project = $project
-PREFIX = $root
-prefix = $prefix
-stagedir = $stagedir
-sysroot = $sysroot
-sysconfdir = $sysconfdir
-localstatedir = $localstatedir
-thrflavour = $thrflavour
-nothrflavour = $nothrflavour
-libdir = $libdir
-top_srcdir = $top_srcdir
-};
-
-	for (@{$need_externs{$short}}) {
-		next unless defined $externs{$_} and defined $externs{$_}{prefix};
-		print MKINC "${_}_prefix = $externs{$_}{prefix}\n";
-		print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags};
-	}
-
-	for (@{$need_jars{$short}}) {
-		print MKINC "${_}_jar = $jar{$_}\n"
-	}
-
-	my $need_gsoap = 0;
-	for (@{$need_externs{$short}})  { $need_gsoap = 1 if $_ eq 'gsoap'; }
-
-	print MKINC "gsoap_default_version=".gsoap_version()."\n"  if $need_gsoap;
-
-	close MKINC;
-}
-
-BEGIN{
-};
-
-sub mode_etics {
-	$fmod = shift;
-
-	die "$0: --module required with --etics\n" unless $fmod;
-	
-	my ($subsys,$module) = split /\./,$fmod;
-
-	my ($major,$minor,$rev,$age);
-
-	if ($version) {
-		$version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/;
-		($major,$minor,$rev,$age) = ($1,$2,$3,$4);
-	}
-	else { 
-		my $path = "$cvs_prefix{$subsys}.$subsys.$module/project";
-		if ($subsys eq 'gridsite') {
-			$path = "$cvs_prefix{$subsys}.$subsys.core/project";
-		}
-		open V,"$path/version.properties"
-			or die "$cvs_prefix{$subsys}.$subsys.$module/project/version.properties: $!\n";
-	
-		while ($_ = ) {
-			chomp;
-			($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/;
-			$age = $1 if /module\.age\s*=\s*([[:digit:]]+)/;
-		}
-		close V;
-	}
-
-	my @copts = ();
-	my %ge;
-	@ge{@{$etics_projects{$project{etics_name}}}} = (1) x ($#{$etics_projects{$project{etics_name}}}+1);
-
-	for (@{$need_externs{"$subsys.$module"}}) {
-	    if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/ and (defined $externs{$_} or defined $jar{$_})) {
-		my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_;
-		next if ($eext eq '-');
-		if ($project ne 'glite') {
-			if ($ge{$_} and not defined $externs{$_}{pkg}) {
-				push @copts, "--with-$_=\${stageDir}";
-			}
-		} else {
-			push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}";
-		}
-	    }
-	}
-
-	for (@{$need_jars{"$subsys.$module"}}) {
-		my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_;
-
-		push @copts,"--with-$_ \${$eext.location}$jar{$_}" if ($project eq 'glite');
-	}
-
-	my $conf;
-	my $conftag;
-	my ($confprefix, $nameprefix);
-
-	$dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n";
-
-	$confprefix = $project{conf_prefix}{$subsys};
-	$nameprefix = $confprefix;
-	$nameprefix =~ s/-$//;
-	$nameprefix =~ s/-/\./g;
-
-	if ($branch) {
-		$conf = "$confprefix${subsys}-${module}_$branch"; 
-		$conftag = $branch;
-		# forced low age number
-		$age = $branch eq 'HEAD' ? '0head' : '0dev'; }
-	else {
-		$conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; 
-
-# XXX: gridsite hack
-		$conftag = $subsys eq 'gridsite' ? "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : 
-			"$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}"; }
-
-	my $file = $output ? $output : "$conf.ini";
-	open C,">$file" or die "$file: $!\n";
-
-	my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"};
-
-	my $confdir = $buildroot{"$subsys.$module"} eq '' ? '.' : '..';
-
-	my $package_description = "";
-	my $package_summary = "";
-
-	if (-e "$cvs_prefix{$subsys}.$subsys.$module/project/package.description") {
-		open V, "$cvs_prefix{$subsys}.$subsys.$module/project/package.description";
-		$package_description = join ("", );
-		close V;
-		chomp $package_description;
-		$package_description =~ s/\n/\\n/g; 
-		$package_description = "package.description = $package_description\n";
-	} 
-	else { 
-		print STDERR "package.description not found for $subsys.$module!\n"; }
-
-	if (-e "$cvs_prefix{$subsys}.$subsys.$module/project/package.summary") {
-		open V, "$cvs_prefix{$subsys}.$subsys.$module/project/package.summary";
-		$package_summary = join ("", );
-		close V;
-		chomp $package_summary;
-		$package_summary =~ s/\n/\\n/g; 
-		$package_summary = "package.summary = $package_summary\n";
-	} 
-	else { 
-		print STDERR "package.summary not found for $subsys.$module!\n"; }
-
-	my %cmd;
-	@cmd{qw/configure compile test install packaging clean/} = ('None') x 6;
-	$cmd{clean} = 'make clean';
-	$cmd{checkout} = "cvs -d \${vcsroot} co -d \${moduleName} ".($conftag eq 'HEAD' ? '-A' : '-r ${tag}')." $cvs_prefix{$subsys}.$subsys.$module 2>/dev/null";
-	#$cmd{checkout} = "(test -d \${moduleName}/.git && (cd \${moduleName}; git pull) || git clone http://scientific.zcu.cz/git/jra1mw.git \${moduleName})";
-	#$cmd{checkout} .= " && (cd \${moduleName}; git checkout ${tag})" unless ($conftag =~ /HEAD/);
-	$cmd{tag} = "cvs -d \${vcsroot} tag -R \${tag} ${moduleName}";
-
-	if ($subsys eq 'gridsite') {
-		$cmd{tag} = 'None';
-
-		if ($module eq 'core') {
-			my ($flags, $prefix);
-
-			if ($project ne 'glite') {
-				$flags = 'RELEASE_VERSION=${age}.${platformFamily} libdir=${libdir} GSOAPDIR=`pkg-config gsoap --variable=prefix` OPENSSL_GLOBUS_FLAGS=`pkg-config globus-openssl --cflags` OPENSSL_GLOBUS_LIBS=`pkg-config globus-openssl --libs` FLAVOR_GLOBUS_EXT= HTTPD_FLAGS="-I/usr/include/httpd -I/usr/include/apache2 -I/usr/include/apr-${aprSuffix} -I/usr/include/pcre"';
-				$prefix = "prefix=${prefix}/usr";
-			} else {
-				$flags = 'RELEASE_VERSION=${age}.${platformFamily} libdir=${libdir} GSOAPDIR=${gsoap.location} OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor} OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir}/ FLAVOR_GLOBUS_EXT=_${globus.dbg.nothr.flavor} HTTPD_FLAGS="-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-${aprSuffix} -I${httpd-devel.location}/include/pcre"';
-				$prefix = "prefix=${prefix}";
-			}
-
-			$cmd{compile} = "echo 'make $flags' > build.sh\n\tmake $flags build";
-			$cmd{clean} = "rm -rvf build.sh; $cmd{clean}";
-			$cmd{install} = "make $prefix $flags install";
-			$cmd{packaging} = "make $prefix $flags rpm";
-		}
-		else {
-			$cmd{clean} = 'None';
-			$cmd{packaging} = "echo building nothing, org.gridsite.core make rpm step will create this";
-			$cmd{checkout} = "mkdir -v \${moduleName} 2>/dev/null || true";
-		}
-	}
-	elsif ($subsys eq 'px' and $module eq 'myproxy-config') {
-		$cmd{configure} = "/usr/bin/perl $confdir/configure --root=\${prefix} --prefix= --stage=\${stageDir} --libdir=\${libdir} --project=\${projectName} --module $subsys.$module @copts";
-		$cmd{packaging} = "make rpm package=".$confprefix."$subsys-myproxy-config";
-	}
-	else {
-		$cmd{configure} = "/usr/bin/perl $confdir/configure $project{flavours} --root=\${prefix} --prefix=$project{local_prefix} --stage=\${stageDir} --sysroot=\${package.prefix} --libdir=\${libdir} --project=\${projectName} --module $subsys.$module @copts";
-		$cmd{compile} = 'make';
-		$cmd{test} = 'make check';
-		$cmd{install} = 'make install';
-	}
-
-	my $defprops = '';
-
-	for my $p (keys %{$platform_properties{"$subsys.$module"}->{default}}) {
-		$defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n";
-	}
-
-	print STDERR "Writing $file\n";
-	print C qq{
-[Configuration-$conf]
-profile = None
-moduleName = $project{etics_name}.$subsys.$module
-displayName = $conf
-description = $cvs_prefix{$subsys}.$subsys.$module
-projectName = $project{etics_name}
-age = $age
-deploymentType = None
-vcsroot = :pserver:anonymous\@glite.cvs.cern.ch:/cvs/glite
-tag = $conftag
-version = $major.$minor.$rev
-$dwpath
-[Platform-default:VcsCommand]
-displayName = None
-description = None
-tag = $cmd{tag}
-branch = None
-commit = None
-checkout = $cmd{checkout}
-
-[Platform-default:BuildCommand]
-postpublish = None
-packaging = $cmd{packaging}
-displayName = None
-description = None
-doc = None
-prepublish = None
-publish = None
-compile = $cmd{compile}
-init = None
-install = $cmd{install}
-clean = $cmd{clean}
-test = $cmd{test}
-configure = $cmd{configure}
-checkstyle = None
-
-[Platform-default:Property]
-$buildroot
-aprSuffix = 0
-package.RPMSLocation = \${moduleDir}/$cvs_prefix{$subsys}.$subsys.$module/RPMTMP/RPMS
-package.SRPMSLocation = \${moduleDir}/$cvs_prefix{$subsys}.$subsys.$module/RPMTMP/SRPMS
-package.preserve.libtool = false
-$package_description$package_summary$defprops};
-
-	for (@{$obsoletes{"$subsys.$module"}}) {
-		print C "package.obsoletes = $_\n";
-		print C "package.replaces = $_\n";
-	}
-
-	for my $pp (keys %{$platform_properties{"$subsys.$module"}}) {
-		next if $pp eq 'default';
-		next if exists $project{supported_platforms} and not exists $project{supported_platforms}{$pp};
-
-		print C "[Platform-$pp:Property]\n$buildroot\n";
-
-		for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) {
-			print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n";
-		}
-		print C "package.RPMSLocation = \${moduleDir}/$cvs_prefix{$subsys}.$subsys.$module/RPMTMP/RPMS
-package.SRPMSLocation = \${moduleDir}/$cvs_prefix{$subsys}.$subsys.$module/RPMTMP/SRPMS\n";
-		print C "$package_description$package_summary\n";
-	}
-
-	print C qq{
-[Platform-default:DynamicDependency]
-};
-	for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) {
-		my $eext = $etics_externs{$_} ? $etics_externs{$_} : $_;
-		my $edev = $project{etics_externs_devel}{$_};
-		next if ($eext eq '-');
-
-		my $proj = 'externals';
-		for my $p (keys %etics_projects) {
-			for $m (@{$etics_projects{$p}}) {
-				$proj = $p if $m eq $_;
-			}
-		}
-
-		my $type = $need_externs_type{"$subsys.$module"}->{$_};
-
-		if ($edev) {
-			if ($type eq 'B') {
-				$eext = $edev; # no runtime - change to devel pkg
-			} elsif ($type eq 'BR' or $type eq 'RB') {
-				print C "$proj|$edev = B\n"; # additional devel pkg
-			}
-		}
-		print C "$proj|$eext = $type\n";
-	}
-
-	for (@{$deps{"$subsys.$module"}}) {
-		my $type = $deps_type{"$subsys.$module"}->{$_};
-		print C "$project{etics_name}|$project{etics_name}.$_ = $type\n";
-	}
-
-	close C;
-}
-
-sub gsoap_version {
-	local $_;
-	my $gsoap_version;
-	open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n";
-
-	while ($_ = ) {
-		chomp;
-
-		$gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/;
-		$gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/;
-	}
-	close S;
-	return $gsoap_version;
-}
-
-sub getlibdir {
-	if ( -e "/etc/debian_version") { # We are on Debian
-		$lib64="lib";
-		$lib32="lib32";	}
-	else { # Another distribution
-		$lib64="lib64";
-		$lib32="lib";	}
-        $libdir=$lib32;
-
-        open INP, "uname -s | "; # Check kernel name
-        $kname= ;
-        chomp($kname);
-        close INP;
-
-        if ( $kname eq "Linux") {
-                $arch = ("x86_64\npowerpc\nppc64\n");
-
-                open INP, "uname -p | "; # Check processor type
-                $procname= ;
-                chomp($procname);
-                close INP;
-
-                if ($arch =~/^$procname\n/) {
-                        return ($lib64); }
-
-                open INP, "uname -m | "; # Check machine hardware
-                $machname= ;
-                chomp($machname);
-                close INP;
-
-                if ($arch =~/^$machname\n/) {
-                        return ($lib64); }
-
-                # special cases (hyperlink lib64, Debian)
-                if (-l "/usr/lib64") {
-                        $libdir=$lib32; }
-
-                # if /usr/lib64 doesn't exist at all (AIX)
-                unless ( -e "/usr/lib64" ) {
-                        $libdir=$lib32; }
-        }
-
-        if ( $kname eq "SunOS") {
-                if (-e "/usr/lib/64") {
-                $libdir="lib/64"; }
-        }
-
-        return $libdir;
-}
-
-sub usage {
-	my @ext = keys %externs;
-	my @myjars = keys %jar;
-
-	print STDERR qq{
-Usage: $0 options
-
-General options (defaults in []):
-  --prefix=PREFIX		destination directory [./stage]
-  --stage=DIR			staging directory [./stage]
-  --root=DIR			installation root (custom relocation root -> sysroot) [./stage]
-  --sysroot=DIR			system root (custom relocation root -> sysroot) []
-  --sysconfdir=DIR              system configuration directory [PREFIX/etc]
-  --staged=module,module,...	what is already in PREFIX (specify without org.glite.)
-  --thrflavour=flavour
-  --nothrflavour=flavour	threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg]
-  --listmodules=subsys          list modules of a subsystem
-  --version=maj.min.rev-age	specify version here instead of reading version.properties
-  --branch=branch		CVS branch/etics name suffix (HEAD, branch_2_1, ...)
-  --libdir=libdir		typically [lib,lib64] postfix
-  --project=PROJECT		build or generate etics for a project (glite/emi) [emi]
-  --debug			print more details
-  
-Mode of operation:
-  --mode=\{checkout|build|etics\}	what to do [build]
-  
-What to build:
-  --module=module		build this module only
-  --enable-NODE			build this "node" (set of modules) only
-  --disable-NODE		don't build this node
-  --lb-tag=tag			checkout LB modules with specific tag
-  --jp-tag=tag			checkout JP modules with specific tag
-  --lbjp-common-tag=tag         checkout lbjp-common modules with specific tag
-  --jobid-tag=tag		checkout jobid modules with specific tag
-
-Dependencies (summary of what will be used is always printed):
-  --with-EXTERNAL=PATH		where to look for an external [autodetect]
-  --with-JAR=JAR		where to look for jars
-
-Available nodes:
-    @nodes
-
-Default nodes:
-    @default_nodes
-
-Externals (not all for all modules) are:
-    @ext
-
-External jars are:
-    @myjars
-
-};
-
-}
diff --git a/org.glite.lb.glite-LB/project/ChangeLog b/org.glite.lb.glite-LB/project/ChangeLog
deleted file mode 100644
index a3aee8e..0000000
--- a/org.glite.lb.glite-LB/project/ChangeLog
+++ /dev/null
@@ -1,43 +0,0 @@
-3.2.10-1
-- glite-LB Metapackage module now CVS-based
-- compile and build by make rather than inline commands
-
-3.2.11-1
-- Fixed handling of target 'clean' in Makefile
- 
-3.2.12-1
-- Fixed target 'clean' in the Makefile to handle debian builds
-
-3.2.12-2
-- Module rebuilt
-
-3.3.0-1
-- Fixes for parallel release in EMI & gLite
-
-3.3.1-1
-- DESTDIR in makefiles
-
-3.3.2-1
-- MP installs no files
-
-3.3.2-2
-- Module rebuilt
-
-3.3.2-3
-- Module rebuilt
-
-3.3.3-1
-- Relocatable build directory
-
-3.3.3-2
-- Module rebuilt
-
-3.3.3-3
-- Module rebuilt
-
-3.2.12-10
-- Module rebuilt
-
-3.2.12-11
-- Module rebuilt
-
diff --git a/org.glite.lb.glite-LB/project/package.description b/org.glite.lb.glite-LB/project/package.description
deleted file mode 100644
index ebc46ce..0000000
--- a/org.glite.lb.glite-LB/project/package.description
+++ /dev/null
@@ -1 +0,0 @@
-Metapackage to install the L&B service on an LB node
diff --git a/org.glite.lb.glite-LB/project/package.summary b/org.glite.lb.glite-LB/project/package.summary
deleted file mode 100644
index ebc46ce..0000000
--- a/org.glite.lb.glite-LB/project/package.summary
+++ /dev/null
@@ -1 +0,0 @@
-Metapackage to install the L&B service on an LB node
diff --git a/org.glite.lb.glite-LB/project/version.properties b/org.glite.lb.glite-LB/project/version.properties
deleted file mode 100644
index 53d4ec6..0000000
--- a/org.glite.lb.glite-LB/project/version.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# $Header
-module.version=3.3.3
-module.age=3
diff --git a/org.glite.lb.harvester/Makefile b/org.glite.lb.harvester/Makefile
deleted file mode 100644
index a97cf79..0000000
--- a/org.glite.lb.harvester/Makefile
+++ /dev/null
@@ -1,106 +0,0 @@
-top_srcdir=..
-stagedir=.
-package=glite-lb-harvester
-module.version=0.0.0
-PREFIX=/opt/glite
-prefix=
-sysconfdir=/opt/glite/etc
-globus_prefix=/opt/globus
-libdir=lib
-
--include Makefile.inc
--include ${top_srcdir}/project/version.properties
-version:=${module.version}
-
-CC=gcc
-VPATH=${top_srcdir}/src:${top_srcdir}/doc
-
-CPPFLAGS:=-I${stagedir}${prefix}/include -D_GNU_SOURCE -D_REENTRANT ${CPPFLAGS}
-CFLAGS:=-W -Wall -g -O2 ${CFLAGS}
-LDFLAGS:=${LDFLAGS} 
-ifeq (${thrflavour},)
-LIBS:=-L${stagedir}${prefix}/${libdir} \
-	-lglite_lb_common \
-	-lglite_lb_client \
-	-lpthread -lglite_security_gss
-else
-LIBS:=-L${stagedir}${prefix}/${libdir} \
-	-lglite_lb_common_${thrflavour} \
-	-lglite_lb_client_${thrflavour} \
-	-lpthread -lglite_security_gss_${thrflavour}
-endif
-
-ifneq ($(GLITE_LB_HARVESTER_WITH_LBU_DB),no)
-CPPFLAGS:=$(CPPFLAGS) -DWITH_LBU_DB=1
-LIBS:=$(LIBS) -lglite_lbu_db
-endif
-ifeq ($(GLITE_LB_HARVESTER_WITH_OLD_LB),yes)
-GLOBUS_GSSAPI_GSI_CFLAGS?=-I${globus_prefix}/include/${thrflavour}
-CPPFLAGS:=${GLOBUS_GSSAPI_GSI_CFLAGS} $(CPPFLAGS) -DWITH_OLD_LB=1
-LIBS:=$(LIBS) -lglite_wmsutils_cjobid
-else
-LIBS:=$(LIBS) -lglite_jobid -lglite_lbu_trio -lglite_lbu_log
-endif
-
-COMPILE:=libtool --mode=compile ${CC} ${CPPFLAGS} ${CFLAGS}
-LINK:=libtool --mode=link ${CC} ${LDFLAGS}
-INSTALL:=libtool --mode=install install
-
-default: all
-
-compile all: startup harvester doc debug
-
-startup: ${top_srcdir}/config/startup
-	glite_var="${localstatedir}/glite"; \
-	if echo "${localstatedir}" | grep 'glite'>/dev/null; then \
-		glite_var="${localstatedir}"; \
-	fi; \
-	sed -e 's:@glite_prefix@:${sysroot}${prefix}:' -e 's:@glite_etc@:${sysconfdir}:' -e "s:@glite_var@:$$glite_var:" $< > $@
-	chmod +x $@
-
-check:
-
-debug: harvester-dbg
-
-doc: glite-lb-harvester.1
-
-stage: compile
-	$(MAKE) install PREFIX=${stagedir}
-
-install: compile
-	-mkdir -p ${DESTDIR}${PREFIX}${prefix}/bin ${DESTDIR}${PREFIX}${prefix}/${libdir}/glite-lb/examples \
-		${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version} \
-		${DESTDIR}${PREFIX}${prefix}/share/man/man1 \
-		${DESTDIR}${PREFIX}${sysconfdir}/init.d \
-		${DESTDIR}${PREFIX}${sysconfdir}/glite-lb
-	${INSTALL} -m 755 harvester ${DESTDIR}${PREFIX}${prefix}/bin/glite-lb-harvester
-	${INSTALL} -m 755 harvester-dbg ${DESTDIR}${PREFIX}${prefix}/${libdir}/glite-lb/examples/glite-lb-harvester-dbg
-	${INSTALL} -m 755 ${top_srcdir}/examples/test.sh ${DESTDIR}${PREFIX}${prefix}/${libdir}/glite-lb/examples/glite-lb-harvester-test.sh
-	${INSTALL} -m 444 ${top_srcdir}/examples/test.sql ${DESTDIR}${PREFIX}${sysconfdir}/glite-lb/harvester-test-dbsetup.sql
-	${INSTALL} -m 444 ${top_srcdir}/doc/README ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version}
-	${INSTALL} -m 444 glite-lb-harvester.1 ${DESTDIR}${PREFIX}${prefix}/share/man/man1
-	${INSTALL} -m 755 startup ${DESTDIR}${PREFIX}${sysconfdir}/init.d/glite-lb-harvester
-
-clean:
-	rm -rfv *.o *.lo *.loT .libs/ manpage.links manpage.refs
-	rm -rvf harvester harvester-dbg glite-lb-harvester.* startup
-
-distclean:
-	rm -rvf Makefile.inc *.spec debian/
-
-harvester: harvester.o
-	${LINK} -o $@ $+ ${LIBS}
-
-harvester-dbg: harvester-dbg.o
-	${LINK} -o $@ $+ ${LIBS}
-
-harvester-dbg.o: harvester.c
-	${COMPILE} -DLOG=1 -DWITH_RTM_SQL_STORAGE=1 -c $< -o $@
-
-%.o: %.c
-	${COMPILE} -c $<
-
-%.1: %.sgml
-	docbook2man $<
-
-.PHONY: default all compile debug check doc stage install clean distclean
diff --git a/org.glite.lb.harvester/config/startup b/org.glite.lb.harvester/config/startup
deleted file mode 100755
index 7081626..0000000
--- a/org.glite.lb.harvester/config/startup
+++ /dev/null
@@ -1,216 +0,0 @@
-#!/bin/sh
-### BEGIN INIT INFO
-# Provides: glite-lb-harvester
-# Description: L&B harvester deamon
-# Required-Start: $remote_fs $network $syslog
-# Required-Stop: $remote_fs $network $syslog
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-### END INIT INFO
-# chkconfig: 345 75 25
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners/ for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-GLITE_LB_LOCATION=${GLITE_LB_LOCATION:-'@glite_prefix@'}
-GLITE_LB_LOCATION_ETC=${GLITE_LB_LOCATION_ETC:-'@glite_etc@'}
-GLITE_LB_LOCATION_VAR=${GLITE_LB_LOCATION_VAR:-'@glite_var@'}
-
-[ -f /etc/profile.d/grid-env.sh ] && . /etc/profile.d/grid-env.sh
-[ -f /etc/glite.conf ] && . /etc/glite.conf
-[ -f $GLITE_LB_LOCATION_ETC/glite-wms.conf ] && . $GLITE_LB_LOCATION_ETC/glite-wms.conf
-
-[ -f $GLITE_LB_LOCATION/lb.conf ] && . $GLITE_LB_LOCATION_ETC/lb.conf
-[ -f $GLITE_LB_LOCATION_VAR/etc/lb.conf ] && . $GLITE_LB_LOCATION_VAR/etc/lb.conf
-
-[ -f $HOME/.glite.conf ] && . $HOME/.glite.conf
-
-pidfile=${GLITE_LB_HARVESTER_PIDFILE:-"$GLITE_LB_LOCATION_VAR/glite-lb-harvester.pid"}
-level=${GLITE_LB_HARVESTER_DEBUG_LEVEL:-"1"}
-lockfile=/var/lock/glite-lb-harvester
-
-# database or configuration file needed
-# (using the file as default)
-etc=$GLITE_LB_LOCATION/glite-lb
-[ -z "$GLITE_LB_HARVESTER_DBCS" -a -z "$GLITE_LB_HARVESTER_CONFIG" ] && GLITE_LB_HARVESTER_CONFIG=$etc/harvester.conf
-if [ -n "$GLITE_LB_HARVESTER_CONFIG" ]; then
-	[ ! -d "$etc" ] && mkdir -p "$etc"
-	conf="$conf -c $GLITE_LB_HARVESTER_CONFIG"
-	if [ ! -f "$GLITE_LB_HARVESTER_CONFIG" ]; then
-		hostname -f > $GLITE_LB_HARVESTER_CONFIG
-	fi
-fi
-[ -n "$GLITE_LB_HARVESTER_DBCS" ] && conf="$conf -m $GLITE_LB_HARVESTER_DBCS"
-
-HARVESTER_NOTIFSFILE=/var/tmp/notifs.txt
-
-unset creds port log4c
-
-[ -n "$GLITE_HOST_CERT" -a -n "$GLITE_HOST_KEY" ] &&
-	creds="-C $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="-C /etc/grid-security/hostcert.pem -K /etc/grid-security/hostkey.pem"
-	fi
-fi
-
-start_daemon()
-{
-	local name="$1"
-	local pidfile="$2"
-	local cmd="$3"
-	local stale="$4"
-
-	if [ -f "$pidfile" ]; then
-		if kill -0 `cat $pidfile`; then
-			return 0
-		fi
-		echo "Warning: stale $pidfile for $name"
-		rm -f "$pidfile"
-		if [ -n "$stale" ]; then
-			for file in $stale; do
-				echo "Warning: stale $file for $name"
-				rm -f "$file"
-			done
-		fi
-	fi
-	echo -n "Starting $name ..."
-	su - $GLITE_USER -c "$log4c $cmd"
-
-	if [ $? -eq 0 ]; then
-		echo " done"
-		touch $lockfile
-	else
-		echo " FAILED"
-	fi
-}
-
-stop_daemon()
-{
-	name="$1"
-	local pidfile="$2"
-
-	if [ -f "$pidfile" ]; then
-		pid=`cat "$pidfile"`
-		echo -n Stopping $name \($pid\) ...
-		kill $pid
-		try=0
-		while kill -0 $pid >/dev/null 2>&1; do 
-			sleep 1;
-			try=`expr $try + 1`
-			if [ $try = 20 ]; then
-				kill -9 $pid
-				echo " force quit after $try retries"
-				rm -f $lockfile
-				return 1
-			fi
-	 	done
-		echo " done"
-		rm -f $pidfile
-		rm -f $lockfile
-	else
-		echo $name not running
-		return 1
-	fi
-}
-
-status_daemon()
-{
-	local name="$1"
-	local pidfile="$2"
-	local enabled="$3"
-
-	if [ -f "$pidfile" ]; then
-		pid=`cat "$pidfile"`
-		if kill -0 $pid >/dev/null 2>&1; then
-			echo "$name running as $pid"
-		else
-			echo "$name not running (stale pidfile)"
-			return 1
-		fi
-	else
-		if test -n "$enabled" -a x"$enabled" = x"0"; then
-			echo "$name not running (disabled)"
-			return 0
-		else
-			echo "$name not running"
-			return 1
-		fi
-	fi
-
-	return 0
-}
-
-start()
-{
-	if test -z "$GLITE_USER" ;then
-		echo 'Error: GLITE_USER is not set'
-		echo FAILED
-		return 1
-	fi
-
-	log4c="LOG4C_RCPATH='$GLITE_LB_LOCATION_ETC/glite-lb'"
-
-	[ -z "$creds" ] && echo $0: WARNING: No credentials specified. Using default lookup which is dangerous. >&2
-
-	[ -n "$GLITE_LB_HARVESTER_PORT" ] && port="-p $GLITE_LB_HARVESTER_PORT"
-
-	start_daemon glite-lb-harvester "$pidfile" "$GLITE_LB_LOCATION/bin/glite-lb-harvester \
-		$creds $conf -i $pidfile -d $level $port --daemon\
-		$GLITE_LB_HARVESTER_OTHER_OPTIONS" "$HARVESTER_NOTIFSFILE"
-}
-
-stop()
-{
-	stop_daemon "glite-lb-harvester" $pidfile
-}
-
-status()
-{
-	retval=0
-	status_daemon "glite-lb-harvester" "$pidfile" || retval=1
-
-	return $retval
-}
-
-cleanup()
-{
-	stop | grep -v 'glite-lb-harvester not running'
-	echo -n "Cleaning up notifications ..."
-	$log4c glite-lb-harvester --cleanup $creds $conf -d $level $GLITE_LB_HARVESTER_OTHER_OPTIONS
-	if [ $? = 0 ]; then
-		echo " done"
-	else
-		echo " FAILED"
-		return 1
-	fi
-}
-
-case x$1 in
-	xstart)	start;;
-	xstop)	stop;;
-	xrestart|xforce-reload) stop; start;;
-	xstatus) status;;
-	xcleanup) cleanup;;
-	xcondrestart|xtry-restart)
-		status >/dev/null 2>&1 || exit 0
-		stop; start
-		;;
-	x*)	echo usage: $0 start,stop,restart,status,cleanup >&2
-		exit 1;;
-esac
diff --git a/org.glite.lb.harvester/configure b/org.glite.lb.harvester/configure
deleted file mode 100755
index bcb1531..0000000
--- a/org.glite.lb.harvester/configure
+++ /dev/null
@@ -1,2058 +0,0 @@
-#!/usr/bin/perl
-
-# WARNING: Don't edit this file unless it is the master copy in org.glite.lb
-#
-# For the purpose of standalone builds of lb/jobid/lbjp-common components
-# it is copied on tagging 
-
-# $Header$
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners/ for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-use Getopt::Long;
-use POSIX qw(locale_h strftime);
-
-my $pwd = `pwd`; chomp $pwd;
-my $prefix = '/usr';
-my $stagedir = undef;
-my $root = $pwd.'/stage';
-my $sysroot = '';
-my $sysconfdir;
-my $localstatedir;
-my $staged;
-my $module;
-my $thrflavour = 'gcc64dbgpthr';
-my $nothrflavour = 'gcc64dbg';
-my $mode = 'build';
-my $help = 0;
-my $listmodules;
-my ($version, $force_version);
-my $branch;
-my $output;
-my $lb_tag = '';
-my $lbjp_tag = '';
-my $jp_tag = '';
-my $jobid_tag = '';
-my $libdir = getlibdir();
-my $project = 'emi';
-my $project_version;
-my (%projects, %project);
-my $debug = 0;
-my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : '';
-
-my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal/;
-my @default_nodes = qw/lb px proxyrenewal nagios/;
-my %enable_nodes;
-my %disable_nodes;
-my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1);
-
-my %package = (
-	'maintainer' => 'CESNET Product Teams ',
-	'uploaders' => 'František Dvořák ',
-	'url' => 'http://glite.cern.ch',
-	'debian_vcs' => 'Vcs-Cvs: :pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw
-Vcs-Browser: http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi',
-);
-
-# key:      internal package name (arguments, ...)
-# 'pkg':    pkg-config name
-# 'prefix': used when pkg-config fails
-my %externs = (
-	cares => {
-		prefix => '/opt/c-ares',
-		pkg => 'libcares'
-	},
-	classads => {
-		prefix=> '/usr',
-		pkg => 'classads'
-	},
-	cppunit => {
-		prefix=> '/usr',
-		pkg => 'cppunit'
-	},
-	expat => {
-		prefix=> '/usr',
-		pkg => 'expat'
-	},
-	globus => {
-		prefix=> '/opt/globus',
-		pkg => 'globus-gssapi-gsi'
-	},
-	'myproxy-devel' => {
-		prefix=> '/opt/globus',
-		pkg => 'myproxy'
-	},
-	'myproxy-server' => {
-		prefix=> '',
-	},
-	'myproxy-admin' => {
-		prefix=> '',
-	},
-	gsoap => {
-		prefix=> '/usr',
-		pkg => 'gsoap'
-	},
-	gsoapxx => {
-		prefix=> '/usr',
-		pkg => 'gsoap++'
-	},
-	mysql => {
-		prefix=> '/usr'
-	},
-	'mysql-devel' => {
-		prefix=> ''
-	},
-	'mysql-server' => {
-		prefix => ''
-	},
-	voms => {
-		prefix => '/opt/glite',
-		pkg => 'voms-2.0'
-	},
-	gridsite => {
-		prefix => '/opt/glite'
-	},
-	lcas => {
-		prefix => '/opt/glite',
-		pkg => 'lcas'
-	},
-	trustmanager => {
-		prefix => '/opt/glite'
-	},
-	trustmanager_axis => {
-		prefix => '/opt/glite'
-	},
-	utiljava => {
-		prefix=> '/opt/glite'
-	},
-	ant => {
-		prefix=> '/usr'
-	},
-	jdk => {
-		prefix=> '/usr/java/latest',
-		locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ],
-	},
-	libtar => {
-		prefix=> '/usr'
-	},
-	axis => {
-		prefix=> '/usr'
-	},
-	log4c => {
-		prefix=> '/usr'
-	},
-	postgresql => {
-		prefix=> '/usr'
-	},
-	activemq => {
-		prefix=>'/opt/activemq-cpp-library',
-		pkg => 'activemq-cpp'
-	},
-);
-
-my %jar = (
-	'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar',
-	'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar',
-);
-
-
-my %glite_prefix;
-my %need_externs;
-my %need_externs_type;
-my %need_jars;
-my %extrafull;
-my %extranodmod;
-my %deps;
-my %deps_type;
-my %buildroot;
-my (%etics_externs, %etics_projects);
-
-#
-# modules of the subsystems
-#
-# additional modules from $project{modules} are automatically added
-#
-my %lbmodules = (
-	'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], 
-	'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/],
-	'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/],
-	'jp' => [ qw/client doc index primary server-common ws-interface/ ],
-	'gridsite' => [ qw/apache libs commands core devel slashgrid services service-clients gsexec/ ],
-	'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ],
-	'canl' => [ qw/c c-devel/ ],
-	);
-
-#
-# sub-packages
-#
-# modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly
-#
-my %subpackages = (
-	'jobid.api-c-devel' => 'jobid.api-c',
-	'jobid.api-cpp-devel' => 'jobid.api-cpp',
-	'lbjp-common.db-devel' => 'lbjp-common.db',
-	'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin',
-	'lbjp-common.gss-devel' => 'lbjp-common.gss',
-	'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface',
-	'lbjp-common.log-devel' => 'lbjp-common.log',
-	'lbjp-common.maildir-devel' => 'lbjp-common.maildir',
-	'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones',
-	'lbjp-common.trio-devel' => 'lbjp-common.trio',
-	'lb.client-progs' => 'lb.client',
-	'lb.client-devel' => 'lb.client',
-	'lb.common-devel' => 'lb.common',
-	'lb.logger-devel' => 'lb.logger',
-	'lb.state-machine-devel' => 'lb.state-machine',
-	'px.proxyrenewal-devel' => 'px.proxyrenewal',
-	'px.proxyrenewal-progs' => 'px.proxyrenewal',
-	'canl.c-devel' => 'canl.c',
-);
-
-my @opts = (
-	'prefix:s' => \$prefix,
-	'staged=s' => \$staged,
-	'module=s' => \$module,
-	'thrflavour:s' => \$thrflavour,
-	'nothrflavour:s' => \$nothrflavour,
-	'mode=s' => \$mode,
-	'listmodules=s' => \$listmodules,
-	'version=s' => \$force_version,
-	'branch=s' => \$branch,
-	'output=s' => \$output,
-	'stage=s' => \$stagedir,
-	'root:s' => \$root,
-	'sysroot:s' => \$sysroot,
-	'sysconfdir=s' => \$sysconfdir,
-	'localstatedir=s' => \$localstatedir,
-	'lb-tag=s' => \$lb_tag,
-	'lbjp-common-tag=s' => \$lbjp_tag,
-	'jp-tag=s' => \$jp_tag,
-	'jobid-tag=s' => \$jobid_tag,
-	'canl-tag=s' => \$canl_tag,
-	'help' => \$help,
-	'libdir=s' => \$libdir,
-	'project=s' => \$project,
-	'debug' => \$debug,
-);
-
-for (@nodes) {
-	$enable_nodes{$_} = 0;
-	$disable_nodes{$_} = 0;
-	
-	push @opts,"disable-$_",\$disable_nodes{$_};
-	push @opts,"enable-$_",\$enable_nodes{$_};
-}
-
-push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs;
-push @opts,"with-$_=s",\$jar{$_} for keys %jar;
-
-my @keeparg = @ARGV;
-
-GetOptions @opts or die "Errors parsing command line\n";
-$prefix=~s/\/$//;
-$root=~s/\/$//;
-$sysroot=~s/\/$//;
-if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; }
-if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; }
-$sysconfdir=~s/\/$//;
-$localstatedir=~s/\/$//;
-
-$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq '';
-$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq '';
-$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq '';
-
-$externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq '';
-$externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq '';
-$externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq '';
-
-if ($project =~ /^([^0-9]*)(.*)$/) {
-	$project = $1;
-	$project_version = $2;
-}
-%project = %{$projects{$project}};
-$project_version = $project{current_version} unless $project_version;
-for my $platform (keys %{$project{etics_externs}}) {
-	for $_ (keys %{$project{etics_externs}{$platform}}) {
-		$etics_externs{$platform}{$_} = $project{etics_externs}{$platform}{$_};
-	}
-}
-reshuffle_platforms(\%etics_externs, $project{supported_platforms});
-reshuffle_platforms(\%{$project{etics_externs_devel}}, $project{supported_platforms});
-for $_ (keys %{$project{etics_projects}}) {
-	$etics_projects{$_} = $project{etics_projects}{$_};
-}
-for $_ (keys %{$project{need_externs_aux}}) {
-	$need_externs_aux{$_} = $project{need_externs_aux}{$_};
-}
-for my $ext (keys %need_externs_aux) {
-	for (@{$need_externs_aux{$ext}}) {
-		my ($pkg, $type) =/([^:]*)(?::(.*))?/;
-		$type = 'BR' unless ($type);
-
-		push @{$need_externs{$ext}},$pkg;
-		$need_externs_type{$ext}->{$pkg} = $type;
-	}
-}
-if ($project eq 'emi') {
-	$extranodmod{lb} = 'lb.emi-lb';
-	$extranodmod{px} = 'px.emi-px';
-}
-for $_ (keys %{$project{modules}}) {
-	push @{$lbmodules{$_}},@{$project{modules}{$_}};
-}
-
-
-if ($help) { usage(); exit 0; }
-
-if ($listmodules) {
-	my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name};
-	my @m;
-
-	if (exists $lbmodules{$listmodules}) {
-		@m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}};
-	} else {
-		if ($project eq 'emi' and $project_version == 1) {
-			# no sub-packages in EMI-1
-		} else {
-			for my $sub (keys %subpackages) {
-				push @m, $sub if ($subpackages{$sub} eq $listmodules);
-			}
-		}
-	}
-	print map $_ eq "" ? "" : "$_ ", @m;
-	print "\n";
-	exit 0;
-}
-
-warn "$0: --branch and --output make sense only in --mode=etics\n"
-	if ($output || $branch) && $mode ne 'etics';
-
-my $en;
-for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; }
-
-my $dis;
-for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; }
-
-die "--enable-* and --disable-* are mutually exclusive\n"
-	if $en && $dis;
-
-die "--module cannot be used with --enable-* or --disable-*\n"
-	if $module && ($en || $dis);
-
-die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}};
-
-if ($dis) {
-	for (@nodes) {
-		$enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_});
-	}
-}
-
-if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } };
-
-for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; }
-
-$stagedir = $root unless $stagedir;
-$stagedir=~s/\/$// if ($stagedir);
-
-if ($mode eq 'build') { for my $ext (keys %externs) {
-	if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; }
-	elsif (defined $externs{$ext}{pkg}) {
-		my ($flag, $env, $cmd, $ret);
-		my $pkg = $externs{$ext}{pkg};
-		my $flagname = uc $externs{$ext}{pkg};
-		$flagname =~ s/-[0-9\.]*$//;
-		$flagname =~ y/-\+/_X/;
-
-		print "Checking $pkg ... ";
-		$env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig";
-		$cmd = "$env pkg-config $pkg --exists >/dev/null";
-		`$cmd`; $ret = $?;
-		print "('$cmd' => $ret)\n" if ($debug);
-		if ($ret == 0) {
-			$externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`;
-			chomp $externs{$ext}{prefix};
-			print "$externs{$ext}{prefix}\n";
-
-			$flag=`$env pkg-config $pkg --cflags`;
-			$externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag);
-			$flag=`$env pkg-config $pkg --libs`;
-			$externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag);
-		} else {
-			print "(using default $externs{$ext}{prefix})\n";
-		}
-		print "\n" if ($debug);
-	}
-	elsif ($ext eq 'jdk') {
-		my $jdk_prefix;
-
-		print "Looking for some caffein ... ";
-		if (defined $ENV{'JDK_HOME'}) {
-			$jdk_prefix = $ENV{'JDK_HOME'};
-			print "JDK_HOME=$jdk_prefix\n";
-		} elsif (defined $ENV{'JAVA_HOME'}) {
-			$jdk_prefix = $ENV{'JAVA_HOME'};
-			print "JAVA_HOME=$jdk_prefix\n";
-		} else {
-			foreach my $i (0..$#{$externs{$ext}{locations}}) {
-				if (-e $externs{$ext}{locations}[$i]) {
-					$jdk_prefix=$externs{$ext}{locations}[$i];
-					print "(found directory $jdk_prefix)\n";
-					last;
-				}
-			}
-			print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix);
-		}
-		$externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix);
-	}
-} }
-
-if ($mode eq 'build') {
-	print "Writing config.status\n";
-	open CONF,">config.status" or die "config.status: $!\n";
-	for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') {
-		print CONF "$_=$ENV{$_} " if (defined $ENV{$_});
-	}
-	print CONF "$0 @keeparg\n";
-	close CONF;
-}
-
-
-my @modules;
-my %aux;
-
-if ($module) {
-#	push @modules,split(/[,.]+/,$module);
-	push @modules,$module;
-}
-else {
-	@modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes));
-	
-	my $n;
-
-	do {
-		local $"="\n";
- 		$n = $#modules;
-		push @modules,(map @{$deps{$_}},@modules);
-
-		undef %aux; @aux{@modules} = (1) x ($#modules+1);
-		@modules = keys %aux;
-	} while ($#modules > $n);
-}
-
-@aux{@modules} = (1) x ($#modules+1);
-delete $aux{$_} for (split /,/,$staged);
-@modules = keys %aux;
-
-mode_build() if $mode eq 'build';
-mode_checkout() if $mode eq 'checkout';
-mode_etics($module) if $mode eq 'etics';
-
-sub mode_build {
-	print "\nBuilding modules: @modules\n";
-	print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n";
-	
-	my @ext = map @{$need_externs{$_}},@modules;
-	my @myjars = map @{$need_jars{$_}},@modules;
-	undef %aux; @aux{@ext} = 1;
-	@ext = keys %aux;
-	undef %aux; @aux{@myjars} = (1) x ($#myjars+1);
-	@myjars = keys %aux;
-	
-	print "\nRequired externals:\n";
-	print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext;
-	print "\t$_: $jar{$_}\n" for @myjars;
-	for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } };
-	print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n";
-
-	mkinc($_) for @modules;
-
-	if ($module) {
-		print "Not creating summary Makefile\n" if $debug;
-	} else {
-		print "Creating Makefile\n";
-
-		open MAK,">Makefile" or die "Makefile: $!\n";
-
-		print MAK "all: @modules\n\n";
-		print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n";
-		print MAK "clean check install:\n";
-
-		for (@modules) {
-			my $full = full($_);
-			print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n"
-		}
-
-		print MAK "\ndistclean:\n";
-
-		for (@modules) {
-			my $full = full($_);
-			print MAK $buildroot{$_} eq '' ?
-				"\tcd $full && \${MAKE} distclean\n" :
-				"\trm -rf $full/$buildroot{$_}\n"
-		}
-
-		print MAK "\n";
-
-		for (@modules) {
-			my %ldeps; undef %ldeps;
-			@ldeps{@{$deps{$_}}} = 1;
-			for my $x (split /,/,$staged) { delete $ldeps{$x}; }
-			my @dnames = $module ? () : keys %ldeps;
-			my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage';
-
-			my $full = full($_);
-			my $build = $buildroot{$_};
-
-			print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n";
-			print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n";
-		}
-
-		close MAK;
-	}
-}
-	
-sub mode_checkout() {
-	for (@modules) {
-		my $module = $_;
-		my $tag = "";
-		if ($lb_tag){
-			for (@{$lbmodules{lb}}){
-				if ("lb.".$_ eq $module){
-					$tag = '-r '.$lb_tag;
-				}
-			}	
-		}
-		if ($lbjp_tag) {
-			for (@{$lbmodules{'lbjp-common'}}){
-				if ("lbjp-common.".$_ eq $module){
-                                        $tag = '-r '.$lbjp_tag;
-                                }
-			}
-		}
-		if ($jp_tag){
-			for (@{$lbmodules{'jp'}}){
-	                        if ("jp.".$_ eq $module){
-                                        $tag = '-r '.$jp_tag;
-	                        }
-                        }
-		}
-		if ($jobid_tag){
-			for (@{$lbmodules{jobid}}){
-				if ("jobid.".$_ eq $module){
-                                        $tag = '-r '.$jobid_tag;
-                                }
-			}
-		}
-		if ($canl_tag) {
-			for (@{$lbmodules{'canl'}}){
-				if ("canl.".$_ eq $module){
-                                        $tag = '-r '.$canl_tag;
-                                }
-			}
-		}
-		#if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){
-		#	print "found";
-		#}
-		$_ = full($_);
-		print "\n*** Checking out $_\n";
-		system("cvs checkout  $tag $_") == 0 or die "cvs checkout $tag $_: $?\n";
-	}
-}
-
-BEGIN{
-%etics_externs = (
-	default => {
-		'myproxy-devel'=>'myproxy-devel',
-		'myproxy-server'=>'myproxy-server',
-		'myproxy-admin'=>'myproxy-admin',
-		cares=>'c-ares',
-		utiljava=>'org.glite.security.util-java',
-		gpt=>'gpt',
-		fetchcrl=>'fetch-crl',
-		activemq=>'activemq-cpp-library',
-	},
-);
-
-%etics_projects = (
-);
-
-%need_externs_aux = (
-	'lb.client' => [ qw/cppunit:B classads libtool:B globus:B/ ],
-	'lb.common' => [ qw/expat cares:B cppunit:B classads libtool:B globus:B/ ],
-	'lb.doc' => [ qw/tetex-latex:B/ ],
-	'lb.logger' => [ qw/cppunit:B libtool:B globus:B/ ],
-	'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B globus:B/ ],
-	'lb.nagios' => [ qw/globus_proxy_utils:R/ ],
-	'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql-server:R cppunit:B gsoap:B classads voms:B lcas gridsite:B bison:B libtool:B libxml2 flex:B/ ],
-	'lb.state-machine' => [ qw/classads libtool:B libxslt:B expat:B globus:B/ ],
-	'lb.utils' => [ qw/cppunit:B libtool:B globus:B/ ],
-	'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ],
-	'lb.ws-test' => [ qw/gsoap:B libtool:B globus:B/ ],
-	'lb.types' => [ qw// ],
-	'lb.harvester' => [ qw/docbook-utils:B libtool:B globus:B/ ],
-	'lbjp-common.db' => [ qw/mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B/ ],
-	'lbjp-common.log' => [ qw/log4c libtool:B/ ],
-	'lbjp-common.maildir' => [ qw/libtool:B/ ],
-	'lbjp-common.server-bones' => [ qw/libtool:B/ ],
-	'lbjp-common.trio' => [ qw/cppunit:B libtool:B/ ],
-	'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B/ ],
-	'lbjp-common.gss' =>  [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B/ ],
-	'lbjp-common.gsoap-plugin' =>  [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B/ ],
-	'jobid.api-c' =>  [ qw/cppunit:B libtool:B openssl:B/ ],
-	'jobid.api-cpp' =>  [ qw/cppunit:B libtool:B/ ],
-	'jobid.api-java' =>  [ qw/ant:B jdk:B/ ],
-	'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ],
-        'jp.doc' => [],
-        'jp.index' => [ qw/gsoap globus_essentials:R globus:B mysql-server:R/ ],
-        'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B  mysql-server:R/ ],
-        'jp.server-common' => [],
-        'jp.ws-interface' => [],
-	'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ],
-	'gridsite.commands' => [ qw/curl:R openssl:R/ ],
-	'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ],
-	'gridsite.libs' => [ qw/libxml2:R openssl:R/ ],
-	'gridsite.devel' => [ qw// ],
-	'gridsite.slashgrid' => [ qw/curl:R fuse:R/],
-	'gridsite.services' => [ qw/curl:R gsoap:R/ ],
-	'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ],
-	'gridsite.gsexec' => [ qw// ],
-	'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ],
-	'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B/ ],
-	'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec
-	'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B krb5-devel:B/ ],
-);
-
-%need_jars = (
-	'jobid.api-java' => [ qw/jakarta-commons-codec/ ],
-	'lb.client-java' => [ qw/jakarta-commons-lang/ ],
-);
-
-for my $jar (keys %need_jars) {
-	for (@{$need_jars{$jar}}) {
-		$need_externs_type{$jar}->{$_} = 'BR'; 	# XXX
-	}
-}
-
-%deps_aux = (
-	'lb.client' => [ qw/
-		lb.types:B lb.common
-		lbjp-common.trio
-		jobid.api-cpp:B jobid.api-c
-		lbjp-common.gss
-	/ ],
-	'lb.client-java' => [ qw/
-		lb.types:B
-		lb.ws-interface:B
-		jobid.api-java
-	/ ],
-	'lb.common' => [ qw/
-		jobid.api-cpp:B jobid.api-c
-		lb.types:B lbjp-common.trio lbjp-common.gss
-	/ ],
-	'lb.doc' => [ qw/lb.types:B/ ],
-	'lb.logger' => [ qw/
-		lbjp-common.trio
-		lbjp-common.log
-		jobid.api-c
-		lb.common
-		lbjp-common.gss
-	/ ],
-	'lb.logger-msg' => [ qw/
-		lb.logger:B
-	/ ],
-	'lb.nagios' => [ qw/
-		lb.client:R
-		lb.ws-test:R
-		lb.utils:R
-	/ ],
-	'lb.server' => [ qw/
-		lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R
-		lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log
-		jobid.api-c
-		lbjp-common.gsoap-plugin lbjp-common.gss
-	/ ],
-	'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ],
-	'lb.utils' => [ qw/
-		lbjp-common.jp-interface
-		jobid.api-c
-		lbjp-common.trio lbjp-common.maildir
-		lb.client lb.state-machine lb.types:B
-	/ ],
-	'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ],
-	'lb.ws-interface' => [ qw/lb.types:B/ ],
-	'lb.types' => [ qw// ],
-	'lb.harvester' => [ qw/
-		jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client
-		lbjp-common.gss lbjp-common.log
-	/ ],
-	'lb.yaim' => [ qw// ],
-	'lb.glite-LB' => [ qw/
-		lb.logger:R lb.server:R lb.utils:R lb.doc:R
-		lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R
-		lb.logger-msg:R
-	/ ],
-	'lb.emi-lb' => [ qw/
-		lb.logger:R lb.server:R lb.utils:R lb.doc:R
-		lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R
-		lb.logger-msg:R
-	/ ],
-	'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ],
-	'lbjp-common.maildir' => [ qw// ],
-	'lbjp-common.log' => [ qw// ],
-	'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ],
-	'lbjp-common.trio' => [ qw// ],
-	'lbjp-common.gss' =>  [ qw// ],
-	'lbjp-common.gsoap-plugin' =>  [ qw/lbjp-common.gss/ ],
-	'jobid.api-c' =>  [ qw// ],
-	'jobid.api-cpp' =>  [ qw/jobid.api-c/ ],
-	'jobid.api-java' =>  [ qw// ],
-
-	'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ],
-
-	'jp.client' => [ qw/
-                jp.ws-interface
-                lbjp-common.jp-interface lbjp-common.maildir
-                jobid.api-c
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.doc' => [ qw// ],
-	'jp.index' => [ qw/
-                jp.server-common jp.ws-interface
-                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.primary' => [ qw/
-                jobid.api-c
-                jp.server-common jp.ws-interface
-                lb.state-machine
-                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.server-common' => [ qw/ 
-                lbjp-common.jp-interface lbjp-common.db
-        / ],
-	'jp.ws-interface' => [ qw// ],
-
-	'gridsite.core' => [ qw// ],
-	'gridsite.commands' => [ qw/gridsite.core:B/ ],
-	'gridsite.apache' => [ qw/gridsite.core:B/ ],
-	'gridsite.libs' => [ qw/gridsite.core:B / ],
-	'gridsite.devel' => [ qw/gridsite.core:B/ ],
-	'gridsite.slashgrid' => [ qw/gridsite.core:B/],
-	'gridsite.services' => [ qw/gridsite.core:B/ ],
-	'gridsite.service-clients' => [ qw/gridsite.core:B/ ],
-	'gridsite.gsexec' => [ qw/gridsite.core:B/ ],
-
-	'px.proxyrenewal' => [ qw// ],
-	'px.glite-PX' => [qw/px.myproxy-yaim:R/],
-	'px.emi-px' => [qw/px.myproxy-yaim:R/],
-	'px.myproxy-yaim' => [ qw// ],
-	'px.myproxy-config' => [],
-
-	'canl.c' => [],
-
-	# sub-packages (virtual ETICS components depending on the main)
-	'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ],
-	'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ],
-	'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ],
-	'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ],
-	'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ],
-	'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ],
-	'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ],
-	'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ],
-	'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ],
-	'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ],
-	'lb.client-progs' => [ qw/lb.client:B/ ],
-	'lb.client-devel' => [ qw/lb.client:B/ ],
-	'lb.common-devel' => [ qw/lb.common:B/ ],
-	'lb.logger-devel' => [ qw/lb.logger:B/ ],
-	'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ],
-	'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ],
-	'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ],
-	'canl.c-devel' => [ qw/canl.c:B/ ],
-);
-
-for my $ext (keys %deps_aux) {
-	for (@{$deps_aux{$ext}}) {
-		/([^:]*)(?::(.*))?/;
-		push @{$deps{$ext}},$1;
-		my $type = $2 ? $2 : 'BR';
-		$deps_type{$ext}->{$1} = $type;
-	}
-}
-
-
-%extrafull = (
-	gridsite=>'org.gridsite.core',
-	'canl.c' => 'emi.canl.canl-c',
-	'canl.c-devel' => 'emi.canl.canl-c',
-	'jobid.api-c-devel' => 'org.glite.jobid.api-c',
-	'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp',
-	'lbjp-common.db-devel' => 'org.glite.lbjp-common.db',
-	'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin',
-	'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss',
-	'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface',
-	'lbjp-common.log-devel' => 'org.glite.lbjp-common.log',
-	'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir',
-	'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones',
-	'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio',
-	'lb.client-devel' => 'org.glite.lb.client',
-	'lb.client-progs' => 'org.glite.lb.client',
-	'lb.common-devel' => 'org.glite.lb.common',
-	'lb.logger-devel' => 'org.glite.lb.logger',
-	'lb.state-machine-devel' => 'org.glite.lb.state-machine',
-	'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal',
-	'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal',
-);
-
-#( java => 'client-java' );
-%extranodmod = (
-	db => 'lbjp-common.db',
-	jpprimary => 'jp.primary',
-	jpindex => 'jp.index',
-	jpclient => 'jp.client',
-	lb => 'lb.glite-LB',
-	px => 'px.glite-PX',
-	proxyrenewal => 'px.proxyrenewal',
-	canl => 'canl.c',
-);
-
-%obsoletes = (
-	'lb.yaim' => [ qq/glite-yaim-lb/ ],
-	'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ],
-	'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ],
-	'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec
-	'lbjp-common.gss' => [ qq/glite-security-gss/ ],
-	'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
-);
-
-%conflicts = (
-);
-
-%provides = (
-	'lbjp-common.gss' => [ qq/glite-security-gss/ ],
-	'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
-	'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ],
-);
-
-%cvs_prefix = (
-	'lb' => 'org.glite',
-	'jp' => 'org.glite',
-	'jobid' => 'org.glite',
-	'lbjp-common' => 'org.glite',
-	'gridsite' => 'org',
-	'px' => 'org.glite',
-	'canl' => 'emi',
-);
-
-%cvs_tag_prefix = (
-	'lb' => 'glite-',
-	'jp' => 'glite-',
-	'jobid' => 'glite-',
-	'lbjp-common' => 'glite-',
-	'gridsite' => '',
-	'px' => 'glite-',
-	'canl' => 'emi-',
-);
-
-# ==== projects specification ====
-# etics_name ........... ETICS project name
-# conf_prefix .......... ETICS configurations name prefix
-# tag_prefix ........... VCS tag prefix
-# local_prefix ......... prefix (relative to stage)
-# etics_externs ........ ETICS modules names of externals
-#                        (${NAME.location}, ETICS conf. dependencies)
-# etics_projects ....... ETICS project names of externals
-# etics_externs_devel .. ETICS modules names of devel versions of externals
-# etics_locations ...... ETICS locations in ${NAME.location} properties
-# need_externs_aux ..... project-specific external dependencies
-# supported_platforms .. platforms supported by the project
-# modules .............. additional modules in subsystems
-%projects = (
-	glite => {
-		current_version => 3,
-		etics_name => 'org.glite',
-		conf_prefix => { %cvs_tag_prefix },
-		tag_prefix => { %cvs_tag_prefix },
-		flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}',
-		local_prefix => '',
-		etics_externs => {
-			default => {
-				globus_essentials=>'vdt_globus_essentials',
-				globus=>'globus',
-				globus_proxy_utils=>'vdt_globus_essentials',
-				gridsite=>'org.gridsite.libs',
-				yaim_core=>'org.glite.yaim.core',
-				gip_release=>'glite-info-provider-release',
-				gip_service=>'glite-info-provider-service',
-				bdii=>'bdii',
-				glite_version=>'glite-version',
-				glite_info_templates=>'glite-info-templates',
-				glue_schema=>'glue-schema',
-				trustmanager=>'org.glite.security.trustmanager',
-				axis=>'axis',
-				lcas=>'org.glite.security.lcas',
-				gsoapxx=>'-',
-				jdk=>'jdk',
-				voms=>'org.glite.security.voms-api-cpp',
-			},
-		},
-		etics_externs_devel => {
-			default => {
-				gridsite=>'org.gridsite.devel',
-				voms=>'org.glite.security.voms-api',
-			},
-		},
-		etics_projects => {
-			vdt=>[qw/globus globus_essentials globus_proxy_utils gpt/],
-			'org.glite'=>[qw/voms gridsite lcas gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/],
-		},
-		etics_locations => {
-			'*' => '',
-		},
-		need_externs_aux => {
-			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ],
-			'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ],
-			'lb.yaim' => [ qw/yaim_core:R/ ],
-			'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/],
-			'px.myproxy-yaim' => [ qw/yaim_core:R/ ],
-		},
-		supported_platforms => {
-			sl5_x86_64_gcc412 => 1,
-			sl5_ia32_gcc412 => 1,
-			deb5_x86_64_gcc432 => 1,
-			deb5_ia32_gcc432 => 1,
-			slc4_x86_64_gcc346 => 1,
-			slc4_ia32_gcc346 => 1,
-		},
-		modules => {
-			'lb' => [ qw/glite-LB/ ],
-			'px' => [ qw/glite-PX/ ],
-		},
-	},
-
-	emi => {
-		current_version => 2,
-		etics_name => 'emi',
-		conf_prefix => {
-			'lb' => 'emi-',
-			'jp' => 'emi-',
-			'jobid' => 'emi-',
-			'lbjp-common' => 'emi-',
-			'gridsite' => 'emi-',
-			'px' => 'emi-',
-			'canl' => 'emi-',
-		},
-		tag_prefix => { %cvs_tag_prefix },
-		flavours => '--thrflavour= --nothrflavour=',
-		local_prefix => '/usr',
-		etics_externs => {
-			default => {
-				globus_essentials=>'globus-gssapi-gsi',
-				globus=>'globus-gssapi-gsi-devel',
-				globus_proxy_utils=>'globus-proxy-utils',
-				gridsite=>'emi.gridsite.libs',
-				yaim_core=>'emi.yaim.yaim-core',
-				yaim_bdii=>'emi.bdii.yaim-bdii',
-				gip_service=>'emi.bdii.glite-info-provider-service',
-				bdii=>'emi.bdii.core',
-				glite_version=>'emi.emi-version',
-				glue_schema=>'emi.bdii.glue-schema',
-				trustmanager=>'emi.java-security.trustmanager',
-				trustmanager_axis=>'emi.java-security.trustmanager-axis',
-				axis=>'axis1.4',
-				lcas=>'emi.sac.lcas',
-				gsoapxx=>'-',
-				jdk=>'java',
-				voms => 'emi.voms.voms-api',
-			},
-			sl5_x86_64_gcc412EPEL => {
-				'myproxy-devel' => 'myproxy-devel.x86_64',
-			},
-			sl6_x86_64_gcc446EPEL => {
-				'myproxy-devel' => 'myproxy-devel.x86_64',
-			},
-			deb6_x86_64_gcc445 => {
-				axis => 'axis1.4',
-				# mappings in ETICS project configuration
-				#globus_essentials => 'libglobus-gssapi-gsi4',
-				#globus => 'libglobus-gssapi-gsi-dev',
-				#axis => 'libaxis-java',
-				#cares => 'libc-ares2',
-				#cppunit => 'libcppunit',
-				#expat => 'libexpat1',
-				#log4c => 'liblog4c3',
-				#curl => 'libcurl3',
-				#'mysql' => 'libmysqlclient16',
-				#'mysql-devel' => 'libmysqlclient-dev',
-				#libxslt => 'xsltproc',
-				#'jakarta-commons-codec' => 'libcommons-codec-java',
-				#'jakarta-commons-lang' => 'libcommons-lang-java',
-				#'tetex-latex' => 'texlive-latex-extra',
-				#'perl-LDAP' => 'libnet-ldap-perl',
-				#'fuse-lib' => 'libfuse2',
-				#'fuse' => 'fuse-utils',
-			},
-		},
-		etics_externs_devel => {
-			default => {
-				cares => 'c-ares-devel',
-				classads => 'classads-devel',
-				cppunit => 'cppunit-devel',
-				expat => 'expat-devel',
-				gsoap => 'gsoap-devel',
-				voms => 'emi.voms.voms-api-devel',
-				libtar => 'libtar-devel',
-				log4c => 'log4c-devel',
-				postgresql => 'postgresql-devel',
-				curl => 'curl-devel',
-				libxml2 => 'libxml2-devel',
-				openssl => 'openssl-devel',
-				gridsite=>'emi.gridsite.devel',
-				jdk=>'java-devel',
-			},
-			deb6_x86_64_gcc445 => {
-				# mappings in ETICS project configuration
-				#cares => 'libc-ares-dev',
-				#cppunit => 'libcppunit-dev',
-				#expat => 'libexpat1-dev',
-				#libtar => 'libtar-dev',
-				#log4c => 'liblog4c-dev',
-				#postgresql => 'libpq-dev',
-				#curl => 'libcurl4-openssl-dev',
-				#libxml2 => 'libxml2-dev',
-				#openssl => 'libssl-dev',
-				#'tetex-latex' => 'texlive-latex-extra',
-				#libxslt=>'xsltproc',
-				#'httpd-devel' => 'apache2-prefork-dev',
-				#'fuse-devel' => 'libfuse-dev',
-				#gsoap => 'gsoap',
-				#'krb5-devel' => 'libkrb5-dev',
-			},
-		},
-		etics_projects => {
-			'emi'=>[qw/voms voms-devel gridsite lcas gip_service bdii glite_version glue_schema yaim_core yaim_bdii trustmanager trustmanager_axis/],
-		},
-		etics_locations => {
-			axis => 'axis',
-		},
-		need_externs_aux => {
-			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ],
-			'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ],
-			'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ],
-			'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/],
-			'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ],
-		},
-		supported_platforms => {
-			sl5_x86_64_gcc412EPEL => 1,
-			sl5_ia32_gcc412EPEL => 1,
-			sl6_x86_64_gcc446EPEL => 1,
-			deb6_x86_64_gcc445 => 1,
-		},
-		modules => {
-			'lb' => [ qw/emi-lb/ ],
-			'px' => [ qw/emi-px/ ],
-		},
-	},
-);
-
-%platform_properties = (
-	'jobid.api-java' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.types' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.doc' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.ws-interface' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.yaim' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.nagios' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'px.yaim' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'px.myproxy-config' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'gridsite.devel' => {
-		default => { 'packageName' => 'gridsite-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' },
-	},
-	'canl.c-devel' => {
-		default => { 'packageName' => 'canl-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' },
-	},
-	'jobid.api-c-devel' => {
-		default => { 'packageName' => 'glite-jobid-api-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' },
-	},
-	'jobid.api-cpp-devel' => {
-		default => { 'packageName' => 'glite-jobid-api-cpp-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' },
-	},
-	'lbjp-common.db-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-db-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' },
-	},
-	'lbjp-common.gsoap-plugin-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' },
-	},
-	'lbjp-common.gss-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-gss-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' },
-	},
-	'lbjp-common.jp-interface-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' },
-	},
-	'lbjp-common.log-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-log-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' },
-	},
-	'lbjp-common.maildir-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-maildir-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' },
-	},
-	'lbjp-common.server-bones-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' },
-	},
-	'lbjp-common.trio-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-trio-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' },
-	},
-	'lb.client-devel' => {
-		default => { 'packageName' => 'glite-lb-client-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' },
-	},
-	'lb.common-devel' => {
-		default => { 'packageName' => 'glite-lb-common-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' },
-	},
-	'lb.state-machine-devel' => {
-		default => { 'packageName' => 'glite-lb-state-machine-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' },
-	},
-	'lb.logger-devel' => {
-		default => { 'packageName' => 'glite-lb-logger-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' },
-	},
-	'px.proxyrenewal-devel' => {
-		default => { 'packageName' => 'glite-px-proxyrenewal-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' },
-	},
-	'canl.c-devel' => {
-		default => { 'packageName' => 'canl-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' },
-	},
-);
-
-my @k = keys %deps_aux;
-@buildroot{@k} = ('') x ($#k+1);
-
-$buildroot{'gridsite.core'} = 'src';
-}
-
-sub full
-{
-	my ($short) = @_;
-	my $subsys = $short;
-	$subsys =~ s/\..*//;
-
-	my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite';
-	return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short";
-}
-
-sub get_version
-{
-	my ($fmod, $top_srcdir) = @_;
-
-	my ($subsys,$mod) = split /\./,$fmod,2;
-	my ($major,$minor,$rev,$age);
-	my $old_;
-
-	if ($force_version) {
-		$force_version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/;
-		($major,$minor,$rev,$age) = ($1,$2,$3,$4);
-	}
-	else {
-		my $path = "$top_srcdir/project";
-		if ($subsys eq 'gridsite') {
-			$path = "$cvs_prefix{$subsys}.$subsys.core/project";
-		}
-		open V,"$path/version.properties"
-			or die "$path/version.properties: $!\n";
-
-		$old_ = $_;
-		while () {
-			chomp;
-			($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/;
-			$age = $1 if /module\.age\s*=\s*([[:digit:]]+)/;
-		}
-		close V;
-		$_ = $old_;
-	}
-	$version = "$major.$minor.$rev-$age";
-
-	return ($major, $minor, $rev, $age);
-}
-
-sub get_description
-{
-	my ($top_srcdir) = @_;
-
-	my $cvs_module = $top_srcdir;
-	my $package_description = "";
-	my $package_summary = "";
-
-	if (-e "$cvs_module/project/package.description") {
-		open V, "$cvs_module/project/package.description";
-		$package_description = join ("", );
-		close V;
-		chomp $package_description;
-	}
-	else {
-		print STDERR "package.description not found for $subsys.$module!\n"; }
-
-	if (-e "$cvs_module/project/package.summary") {
-		open V, "$cvs_module/project/package.summary";
-		$package_summary = join ("", );
-		close V;
-		chomp $package_summary;
-		$package_summary =~ s/\n/\\n/g;
-	}
-	else {
-		print STDERR "package.summary not found for $subsys.$module!\n"; }
-
-	return ($package_summary, $package_description);
-}
-
-sub mkinc
-{
-	my %aux;
-	undef %aux;
-	my @m=qw/
-lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb
-lbjp-common.gss lbjp-common.gsoap-plugin
-jobid.api-c jobid.api-cpp jobid.api-java
-lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin
-jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface
-px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px
-canl.c
-/;
-	@aux{@m} = (1) x ($#m+1);
-
-	my ($short) = @_;
-	my $full = full $short;
-	my ($subsys,$mod) = split /\./,$short,2;
-	my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}";
-
-	unless ($aux{$short}) {
-		print "Makefile.inc not needed in $full\n";
-		return;
-	}
-
-	my $top_srcdir = '.';
-	my $abs_srcdir = '';
-	my $build = '';
-
-	if ($module) {
-		$top_srcdir = $0;
-		$top_srcdir =~ s,/?[^/]*$,,;
-		$abs_srcdir = $top_srcdir;
-		$top_srcdir =~ s,^$,\.,;
-	} else {
-		$build = "$full/";
-		$abs_srcdir = "$full/";
-		unless ($buildroot{$_} eq '') {
-			$top_srcdir = '..';
-			$build .= "$buildroot{$_}/";
-			unless (-d "$build") {
-				mkdir "$build" or die "mkdir $build: $!\n";
-			}
-		}
-	}
-
-	my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir;
-	my ($package_summary, $package_description) = get_description $abs_srcdir;
-	if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; }
-	my $package_description_debian = $package_description;
-	$package_description_debian =~ s/^/ /mg;
-
-	my ($old_locale, $specdate, $debdate);
-
-	# files for ETICS always in root source directory
-	mkdir $abs_srcdir."project" unless (-d $abs_srcdir."project");
-	open PKGCHL,">".$abs_srcdir."project/changelog"
-		or die $abs_srcdir."project/changelog: $!\n";
-	$old_locale = setlocale(LC_TIME);
-	setlocale(LC_TIME, "C");
-	$specdate = strftime("%a %b %d %Y", gmtime());
-	$debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime());
-	setlocale(LC_TIME, $old_locale);
-	print PKGCHL qq{* $specdate CESNET team 
-- automatically generated package
-};
-	close PKGCHL;
-
-	unless ($top_srcdir eq '.') {
-		unlink $build."Makefile";
-		symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n";
-	}
-
-	open MKINC,">".$build."Makefile.inc"
-		or die $build."Makefile.inc: $!\n";
-
-	print "Creating ".$build."Makefile.inc\n";
-
-	print MKINC qq{project = $project
-PREFIX = $root
-prefix = $prefix
-stagedir = $stagedir
-sysroot = $sysroot
-sysconfdir = $sysconfdir
-localstatedir = $localstatedir
-thrflavour = $thrflavour
-nothrflavour = $nothrflavour
-libdir = $libdir
-top_srcdir = $top_srcdir
-};
-
-	for (@{$need_externs{$short}}) {
-		next unless defined $externs{$_} and defined $externs{$_}{prefix};
-		print MKINC "${_}_prefix = $externs{$_}{prefix}\n";
-		print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags};
-	}
-
-	for (@{$need_jars{$short}}) {
-		print MKINC "${_}_jar = $jar{$_}\n"
-	}
-
-	my $need_gsoap = 0;
-	for (@{$need_externs{$short}})  { $need_gsoap = 1 if $_ eq 'gsoap'; }
-
-	print MKINC "gsoap_default_version=".gsoap_version()."\n"  if $need_gsoap;
-
-	close MKINC;
-
-	my $dh;
-	my $debian = 0;
-
-	opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!";
-	for my $dir (readdir $dh) {
-		if ($dir=~/^(.*)\.spec$/) {
-			if ($1 ne $packageName) {
-				printf STDERR "Changed RPM name: $packageName --> $1\n" if ($debug);;
-				$packageName=$1;
-			}
-			last;
-		}
-	}
-	closedir $dh;
-
-	for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") {
-		if (-f "$abs_srcdir/project/$file") {
-			my $old_ = $_;
-			printf STDERR "Creating $build$file\n" if ($debug);;
-			open DST, ">$build$file";
-			open SRC, "<$abs_srcdir/project/$file";
-			while () {
-				if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; }
-				if (/\@URL\@/) { s/\@URL\@/$package{url}/g; }
-				if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; }
-				if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; }
-				if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; }
-				if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; }
-				if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; }
-				if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; }
-				if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; }
-				if (/\@AGE\@/) { s/\@AGE\@/$age/g; }
-				if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; }
-				if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; }
-				if (/\@DEBIAN_VCS\@/) { s/\@DEBIAN_VCS\@/$package{debian_vcs}/g; }
-				if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; }
-				if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; }
-				if (/^\s*.+\/configure\s/ and $force_version) {
-					print "Version forced to $version\n" if ($debug);;
-					s/--version\s+\S+\s?//;
-					s/$/ --version $version/;
-				}
-				printf DST "%s", "$_";
-			}
-			close SRC;
-			close DST;
-			$_ = $old_;
-		}
-	}
-
-	print "Creating ${build}debian/\n" if ($debug);;
-
-	`rm -rfv  ${build}debian`;
-	mkdir $build."debian" or die $!;
-	`cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`;
-	`mv ${build}debian.* ${build}debian/ 2>/dev/null`;
-	`rm -f ${build}debian/*.orig`;
-	opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!";
-	for $_ (readdir $dh) {
-		if (/^debian\.(.*)/) {
-			`mv ${build}debian/$_ ${build}debian/$1`;
-			$debian = 1;
-		}
-	}
-	closedir $dh;
-
-	if ($debian) {
-		my ($dir, $file);
-
-		chmod 0755, "${build}debian/rules";
-		$file="${build}debian/docs"; if (not -f $file) { `touch $file`; }
-		$dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; }
-		$file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` }
-		$file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` }
-		$file="${build}debian/changelog"; if (not -f $file) {
-			open FH, ">$file" or die $!;
-			print FH qq{$packageName ($major.$minor.$rev-$age) unstable; urgency=low
-
-  * Automatically generated package
-
- -- $package{maintainer}  $debdate
-};
-			close FH;
-		}
-
-	} else {
-		`rm -rf ${build}debian`;
-	}
-}
-
-BEGIN{
-};
-
-sub mode_etics_packaging {
-	my ($fmod, $cmd, $rpmprepare, $debprepare) = @_;
-	my ($workspaceDir, $srcPackageName, $srcAge, $topDir);
-
-	# old-school packaging by ETICS for EMI-1
-	if ($project eq 'emi' and $project_version == 1) { return; }
-
-	if ($fmod eq 'gridsite.core') {
-		$workspaceDir = '..';
-		$srcPackageName = 'gridsite';
-		$srcAge = '';
-		$topDir = '../';
-	} else {
-		$workspaceDir = '${workspaceDir}';
-		$srcPackageName = '${packageName}';
-		$srcAge = '-${age}';
-		$topDir = '';
-	}
-
-	$cmd->{clean} = 'make clean
-	rm -rfv ${package.tgzLocation} ${package.SRPMSLocation}';
-	$cmd->{default}{packaging} = $rpmprepare;
-	$cmd->{default}{packaging} .= "dir=\${workspaceDir}/rpm_build_src_\$\$
-	mkdir -p \${package.tgzLocation} \${package.SRPMSLocation} \$dir/{BUILD,RPMS,SOURCES,SRPMS} 2>/dev/null || true
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/SOURCES/
-	rpmbuild -bs --nodeps --define \"_topdir \$dir\" $srcPackageName.spec
-	cp -v \$dir/SRPMS/*.src.rpm \${package.SRPMSLocation}/
-	rm -rf \$dir";
-
-	for my $p ('deb5_x86_64_gcc432', 'deb5_ia32_gcc432', 'deb6_x86_64_gcc445', 'deb6_ia32_gcc445') {
-		for my $c (keys %{$cmd->{default}}) { $cmd->{$p}{$c} = $cmd->{default}{$c}; }
-		$cmd->{$p}{clean} = 'make clean
-	rm -rfv ${package.tgzLocation} ${package.SDEBSLocation}';
-		$cmd->{$p}{packaging} = $debprepare;
-		$cmd->{$p}{packaging} .= "dir=\${workspaceDir}/dpkg_build_src_\$\$
-	mkdir -p \${package.tgzLocation} \${package.SDEBSLocation} \$dir 2>/dev/null || true
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/${srcPackageName}_\${version}.orig.tar.gz
-	tar xzf \$dir/${srcPackageName}_\${version}.orig.tar.gz -C \$dir
-	cp -rf ${topDir}debian/ \$dir/$srcPackageName-\${version}/
-	cd \$dir/$srcPackageName-\${version}
-	dpkg-buildpackage -S -d -nc
-	cd -
-	cp -v \$dir/*.tar.gz \$dir/*.dsc \${package.SDEBSLocation}/
-	rm -rf \$dir";
-	}
-}
-
-sub mode_etics {
-	$fmod = shift;
-
-	die "$0: --module required with --etics\n" unless $fmod;
-	
-	my ($subsys,$module) = split /\./,$fmod,2;
-	my $full = full "$subsys.$module";
-
-	my ($major,$minor,$rev,$age) = get_version $fmod, $full;
-
-	# XXX: --with ignored for platform-dependend packages
-	my @copts = ();
-	my %ge;
-	@ge{@{$etics_projects{$project{etics_name}}}} = (1) x ($#{$etics_projects{$project{etics_name}}}+1);
-
-	for (@{$need_externs{"$subsys.$module"}}) {
-	    if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/ and (defined $externs{$_} or defined $jar{$_})) {
-		my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_;
-		next if ($eext eq '-');
-		if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}) {
-			$eext = $project{etics_locations}{$_} if ($project{etics_locations}{$_});
-			push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}";
-		} else {
-			if ($ge{$_} and not defined $externs{$_}{pkg}) {
-				push @copts, "--with-$_=\${stageDir}";
-			}
-		}
-	    }
-	}
-
-	for (@{$need_jars{"$subsys.$module"}}) {
-		my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_;
-
-		push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_});
-	}
-
-	my $conf;
-	my $conftag;
-	my ($confprefix, $nameprefix, $packageName);
-
-	$dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n";
-
-	$confprefix = $project{conf_prefix}{$subsys};
-	$nameprefix = $confprefix;
-	$nameprefix =~ s/-$//;
-	$nameprefix =~ s/-/\./g;
-	$packageName = "$project{tag_prefix}{$subsys}$subsys-${module}";
-
-	if ($branch) {
-		$conf = "$confprefix${subsys}-${module}_$branch"; 
-		$conftag = $branch;
-		# forced low age number
-		$age = $branch eq 'HEAD' ? '0head' : '0dev';
-		push @copts, '--version ${version}-${age}';
-	}
-	else {
-		$conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}";
-# XXX: gridsite hack
-		$conftag = $subsys eq 'gridsite' ? "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : 
-			"$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}";
-
-		# lowering age for older packaging
-		if ($project eq 'emi' and $project_version == 1) {
-			$age = $age - 1;
-		}
-	}
-
-	# emi1 suffix for older packaging
-	if ($project eq 'emi' and $project_version == 1) {
-		$age = $age.$project.$project_version;
-		$conf = $conf.$project.$project_version;
-	}
-
-	my $file = $output ? $output : "$conf.ini";
-	open C,">$file" or die "$file: $!\n";
-
-	my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"};
-
-	my $confdir = $buildroot{"$subsys.$module"} eq '' ? '.' : '..';
-
-	my $cvs_module = full "$subsys.$module";
-	my ($package_summary, $package_description) = get_description $cvs_module;
-	if ($package_description) {
-		$package_description =~ s/\n/\\n/g;
-		$package_description = "package.description = $package_description\n";
-	}
-	if ($package_summary) {
-		$package_summary = "package.summary = $package_summary\n";
-	}
-
-	my %cmd;
-	$cmd_vcs{checkout} = "cvs -d \${vcsroot} co -d \${moduleName} ".($conftag eq 'HEAD' ? '-A' : '-r ${tag}')." $cvs_module 2>/dev/null";
-	#$cmd_vcs{checkout} = "((test -d jra1mw/.git && (cd jra1mw; git pull)) || (git clone -q http://scientific.zcu.cz/git/jra1mw.git";
-	#$cmd_vcs{checkout} .= " && (cd jra1mw; git checkout -b \${tag} --track origin/\${tag})" unless ($conftag eq /HEAD/);
-	#$cmd_vcs{checkout} .= ")) && (test -d \${moduleName} || ln -s jra1mw/$cvs_module \${moduleName})";
-	$cmd_vcs{checkout} .= "\n\ttest -f \${packageName}-\${version}-\${age}.src.tar.gz || (ln -s \${moduleName} \${packageName}-\${version}; tar -chf - \${packageName}-\${version} --exclude CVS --exclude .git --exclude .etics | gzip --best > \${packageName}-\${version}-\${age}.src.tar.gz; rm \${packageName}-\${version})";
-	$cmd_vcs{tag} = "cvs -d \${vcsroot} tag -R \${tag} ${moduleName}";
-
-	$cmd{default}{init} = 'None';
-	$cmd{default}{configure} = 'None';
-	$cmd{default}{compile} = 'None';
-	$cmd{default}{test} = 'None';
-	$cmd{default}{install} = 'None';
-	$cmd{default}{packaging} = 'None';
-	$cmd{default}{clean} = 'make clean';
-
-	if (exists $subpackages{$fmod}) {
-		$cmd{default}{clean} = 'None';
-		$cmd{default}{packaging} = "echo building nothing, $subpackages{$fmod} will build this package";
-		$cmd_vcs{checkout} = "mkdir -v \${moduleName} 2>/dev/null || true";
-	} elsif ($subsys eq 'gridsite') {
-		$cmd_vcs{tag} = 'None';
-
-		if ($module eq 'core') {
-			my $flags;
-
-			if ($project ne 'glite') {
-				# don't evaluate pkg-config calls to get them into source package
-				$flags = 'RELEASE_VERSION=${age}
-	GSOAPDIR=\`pkg-config gsoap --variable=prefix\`
-	OPENSSL_GLOBUS_FLAGS=\`pkg-config globus-openssl --cflags\`
-	OPENSSL_GLOBUS_LIBS=\`pkg-config globus-openssl --libs\`';
-			} else {
-				$flags = 'RELEASE_VERSION=${age}
-	GSOAPDIR=${gsoap.location}
-	OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor}
-	OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir}
-	HTTPD_FLAGS=-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-1 -I${httpd-devel.location}/include/apr-1.0 -I${httpd-devel.location}/include/apr-0 -I${httpd-devel.location}/include/pcre';
-			}
-
-			$cmd{default}{configure} = "cat > Makefile.inc </dev/null";
-			$cmd{default}{init} = 'echo "/sbin/ldconfig" > project/.post
-	echo "/sbin/ldconfig" > project/.postun';
-			$cmd{default}{configure} = "cat > src/Makefile.inc <{default}}) {
-		$defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n";
-	}
-
-	print STDERR "Writing $file\n";
-	print C qq{
-[Configuration-$conf]
-profile = None
-moduleName = $project{etics_name}.$subsys.$module
-displayName = $conf
-description = $cvs_prefix{$subsys}.$subsys.$module
-projectName = $project{etics_name}
-age = $age
-deploymentType = None
-vcsroot = :pserver:anonymous\@glite.cvs.cern.ch:/cvs/glite
-tag = $conftag
-version = $major.$minor.$rev
-$dwpath
-[Platform-default:VcsCommand]
-displayName = None
-description = None
-tag = $cmd_vcs{tag}
-branch = None
-commit = None
-checkout = $cmd_vcs{checkout}
-
-};
-
-	for my $p (keys %cmd) {
-		next if $p ne 'default' and exists $project{supported_platforms} and not exists $project{supported_platforms}{$p};
-
-		print C qq{[Platform-$p:BuildCommand]
-postpublish = None
-packaging = $cmd{$p}{packaging}
-displayName = None
-description = None
-doc = None
-prepublish = None
-publish = None
-compile = $cmd{$p}{compile}
-init = $cmd{$p}{init}
-install = $cmd{$p}{install}
-clean = $cmd{$p}{clean}
-test = $cmd{$p}{test}
-configure = $cmd{$p}{configure}
-checkstyle = None
-
-};
-	}
-
-	print C qq{[Platform-default:Property]
-$buildroot
-package.preserve.libtool = false
-$package_description$package_summary$defprops};
-
-	for (@{$obsoletes{"$subsys.$module"}}) {
-		print C "package.obsoletes = $_\n";
-		print C "package.replaces = $_\n";
-	}
-	for (@{$conflicts{"$subsys.$module"}}) {
-		print C "package.conflicts = $_\n";
-	}
-	for (@{$provides{"$subsys.$module"}}) {
-		print C "package.provides = $_\n";
-	}
-	print C "\n";
-
-	for my $pp (keys %{$platform_properties{"$subsys.$module"}}) {
-		next if $pp eq 'default';
-		next if exists $project{supported_platforms} and not exists $project{supported_platforms}{$pp};
-
-		print C "[Platform-$pp:Property]\n$buildroot\n";
-
-		for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) {
-			print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n";
-		}
-		print C "$package_description$package_summary\n";
-	}
-
-	for my $platform ('default', keys %{$project{supported_platforms}}) {
-		my $used = 0;
-		my $output = '';
-
-		for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) {
-			my $eext = $etics_externs{$platform}{$_};
-			my $edev = $project{etics_externs_devel}{$platform}{$_};
-
-			# for the default platform using package of the same
-			# name for runtime dependency
-			if (not $eext) {
-				if ($platform eq 'default') {
-#print "default runtime $_ on default\n";
-					$eext = $_; }
-				else {
-#print "no runtime $_ on $platform\n";
-					$eext = '-'; }
-			}
-			if ($eext eq '-' and $edev eq '-') {
-#print "skipping $_ on $platform\n";
-				next;
-			}
-
-			my $proj = 'externals';
-			for my $p (keys %etics_projects) {
-				for $m (@{$etics_projects{$p}}) {
-					$proj = $p if $m eq $_;
-				}
-			}
-
-			my $type = $need_externs_type{"$subsys.$module"}->{$_};
-
-			if ($edev) {
-				if ($type eq 'B') {
-					# no runtime - change to devel pkg
-					$eext = $edev;
-				} elsif ($type eq 'BR' or $type eq 'RB') {
-					# additional devel pkg
-					if ($edev ne '-') { $output .= "$proj|$edev = B\n"; }
-				}
-			}
-			if ($eext ne '-') { $output .= "$proj|$eext = $type\n"; }
-		}
-
-		if ($platform eq 'default') {
-			for (@{$deps{"$subsys.$module"}}) {
-				my $type = $deps_type{"$subsys.$module"}->{$_};
-				if (not $used) {
-					$used = 1;
-				}
-				$output .= "$project{etics_name}|$project{etics_name}.$_ = $type\n";
-			}
-		}
-
-		if ($output) {
-					print C qq{
-[Platform-$platform:DynamicDependency]
-$output};
-		}
-	}
-
-	close C;
-
-	for $file ("$cvs_module/project/debian.rules", "$cvs_module/project/$packageName.spec") {
-		my $lib;
-		my $main_module;
-		@copts = ();
-
-		if ($file =~ /debian\.rules$/) { $lib = 'lib'; }
-		else { $lib = '%{_lib}'; }
-
-		my $main_module = "$subsys.$module";
-		if (exists $subpackages{$main_module}) { $main_module = $subpackages{$main_module}; }
-
-		# locations hacks
-		if ($file =~ /$packageName\.spec$/) {
-			if ($fmod eq 'lb.client-java') {
-				push @copts, '';
-				push @copts, '--with-axis=/usr/local/axis1.4';
-			}
-		}
-
-		if (-f $file) {
-			open DST,">$file.new" or die "$file.new: $!\n";
-			open SRC,"<$file" or die "$file: $!\n";
-			while () {
-				if (/^(\s*).+\/configure\s/) {
-					printf DST "%s", "$1";
-					printf DST "/usr/bin/perl $confdir/configure $project{flavours} --root=/ --prefix=$project{local_prefix} --libdir=$lib --project=$project --module $main_module@copts\n";
-				} else {
-					printf DST "%s", "$_";
-				}
-			}
-			close SRC;
-			close DST;
-
-			`diff -b "$file" "$file.new"`;
-			if ($? == 0) {
-				print STDERR "($file not changed)\n";
-				unlink "$file.new";
-			} else {
-				print STDERR "Writing $file\n";
-				rename "$file", "$file.orig" unless -f "$file.orig";
-				rename "$file.new", "$file";
-			}
-		}
-	}
-}
-
-sub gsoap_version {
-	local $_;
-	my $gsoap_version;
-	open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n";
-
-	while ($_ = ) {
-		chomp;
-
-		$gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/;
-		$gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/;
-	}
-	close S;
-	return $gsoap_version;
-}
-
-sub getlibdir {
-	if ( -e "/etc/debian_version") { # We are on Debian
-		$lib64="lib";
-		$lib32="lib32";	}
-	else { # Another distribution
-		$lib64="lib64";
-		$lib32="lib";	}
-        $libdir=$lib32;
-
-        open INP, "uname -s | "; # Check kernel name
-        $kname= ;
-        chomp($kname);
-        close INP;
-
-        if ( $kname eq "Linux") {
-                $arch = ("x86_64\npowerpc\nppc64\n");
-
-                open INP, "uname -p | "; # Check processor type
-                $procname= ;
-                chomp($procname);
-                close INP;
-
-                if ($arch =~/^$procname\n/) {
-                        return ($lib64); }
-
-                open INP, "uname -m | "; # Check machine hardware
-                $machname= ;
-                chomp($machname);
-                close INP;
-
-                if ($arch =~/^$machname\n/) {
-                        return ($lib64); }
-
-                # special cases (hyperlink lib64, Debian)
-                if (-l "/usr/lib64") {
-                        $libdir=$lib32; }
-
-                # if /usr/lib64 doesn't exist at all (AIX)
-                unless ( -e "/usr/lib64" ) {
-                        $libdir=$lib32; }
-        }
-
-        if ( $kname eq "SunOS") {
-                if (-e "/usr/lib/64") {
-                $libdir="lib/64"; }
-        }
-
-        return $libdir;
-}
-
-sub reshuffle_platforms($$) {
-	my ($data, $platforms) = @_;
-	my ($platform, %blacklist, $value);
-
-	return if not $platforms;
-
-	for $platform (keys %$data) {
-#print "plat: $platform: $data->{$platform}\n";
-		next if $platform eq 'default';
-		for $_ (keys %{$data->{$platform}}) {
-#print "  blacklist: $_ = $data->{$platform}{$_}\n";
-			$blacklist{$_} = 1;
-		}
-	}
-
-	for $_ (keys %blacklist) {
-		$value = $data->{default}{$_} ? $data->{default}{$_} : $_;
-		for $platform (keys %$platforms) {
-			next if $platform eq 'default';
-			if (not defined $data->{$platform}{$_}) {
-				$data->{$platform}{$_} = $value;
-#print "added $value to $platform\n"
-			}
-		}
-		$data->{default}{$_} = '-';
-#print "deleted $_ from default\n";
-	}
-
-	# merge dependencies across the supported platforms
-	%blacklist = [];
-	for $platform (keys %$platforms) {
-		next if $platform eq 'default';
-		for $_ (keys %{$data->{$platform}}) {
-			$blacklist{$_} = 1;
-		}
-	}
-	for $_ (keys %blacklist) {
-		$value = undef;
-		$same = 1;
-		for $platform (keys %$platforms) {
-			if (not $value) { $value = $data->{$platform}{$_}; }
-			if (not $data->{$platform}{$_} or $value ne $data->{$platform}{$_}) {
-				$same = 0;
-				last;
-			}
-		}
-		if ($same and $value) {
-#print "merged dependency $_\n";
-			$data->{default}{$_} = $value;
-			for $platform (keys %$platforms) {
-				delete $data->{$platform}{$_};
-			}
-		}
-	}
-}
-
-sub usage {
-	my @ext = keys %externs;
-	my @myjars = keys %jar;
-
-	print STDERR qq{
-Usage: $0 options
-
-General options (defaults in []):
-  --prefix=PREFIX		destination directory [./stage]
-  --stage=DIR			staging directory [./stage]
-  --root=DIR			installation root (custom relocation root -> sysroot) [./stage]
-  --sysroot=DIR			system root (custom relocation root -> sysroot) []
-  --sysconfdir=DIR              system configuration directory [PREFIX/etc]
-  --staged=module,module,...	what is already in PREFIX (specify without org.glite.)
-  --thrflavour=flavour
-  --nothrflavour=flavour	threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg]
-  --listmodules=subsys          list modules of a subsystem
-  --listmodules=module          list subpackages of a module
-  --version=maj.min.rev-age	version used instead of reading version.properties
-  --branch=branch		CVS branch/etics name suffix (HEAD, branch_2_1, ...)
-  --libdir=libdir		typically [lib,lib64] postfix
-  --project=PROJECT		build or generate etics for a project (glite/emi1/emi) [emi]
-  --debug			print more details
-  
-Mode of operation:
-  --mode=\{checkout|build|etics\}	what to do [build]
-  
-What to build:
-  --module=module		build this module only
-  --enable-NODE			build this "node" (set of modules) only
-  --disable-NODE		don't build this node
-  --lb-tag=tag			checkout LB modules with specific tag
-  --jp-tag=tag			checkout JP modules with specific tag
-  --lbjp-common-tag=tag         checkout lbjp-common modules with specific tag
-  --jobid-tag=tag		checkout jobid modules with specific tag
-  --canl-tag=tag		checkout canl modules with specific tag
-
-Dependencies (summary of what will be used is always printed):
-  --with-EXTERNAL=PATH		where to look for an external [autodetect]
-  --with-JAR=JAR		where to look for jars
-
-Available nodes:
-    @nodes
-
-Default nodes:
-    @default_nodes
-
-Externals (not all for all modules) are:
-    @ext
-
-External jars are:
-    @myjars
-
-};
-
-}
diff --git a/org.glite.lb.harvester/doc/INSTALL b/org.glite.lb.harvester/doc/INSTALL
deleted file mode 100644
index f5ff9c9..0000000
--- a/org.glite.lb.harvester/doc/INSTALL
+++ /dev/null
@@ -1,42 +0,0 @@
-Requirements
-============
-
-1) gLite
-- client L&B libraries:
-  - glite-jobid-api-c
-  - glite-lb-common
-  - glite-lb-client
-  - glite-security-gss
-  - globus essential libraries (threaded flavour),
-    use the vesion with the external SSL, not with bundled SSL (!)
- - glite-lbjp-common-db (build only)
- - mysql-devel (build only)
-2) postgresql-devel
-
-
-Steps
-=====
-
-./configure
-make
-make install
-
-Use './configure --help' for the options.
-
-
-Manual way
-==========
-
-configure is simple script generating Makefile.inc. You can build harvester
-straight away by make defining the variables manually. For example with gLite
-installed in ~/glite/stage:
-
-(rm Makefile.inc)
-make stagedir=$HOME/glite/stage
-
-
-Testing
-=======
-
-Test for basic functionality covered by 'test.sh' script in sources.
-See './test.sh --help'.
diff --git a/org.glite.lb.harvester/doc/README b/org.glite.lb.harvester/doc/README
deleted file mode 100644
index 258f34c..0000000
--- a/org.glite.lb.harvester/doc/README
+++ /dev/null
@@ -1,87 +0,0 @@
-Introduction
-============
-
-L&B Harvester gathers information about jobs from L&B servers using effective
-L&B notification mechanism. It manages notifications and keeps them in
-a persistent storage (file or database table) to reuse later on next launch.
-It takes care about refreshing notifications and queries L&B servers back when
-some notification on expires.
-
-The tool was initially written for Real Time Monitor (project at Imperial
-College in London), later was extended with messaging mechanism for WLCG.
-
-
-Requirements
-============
-
-Configuration on L&B servers:
-- lastUpdateTime index
-- harvester identity in super users file
-
-Or the yaim parameters in site-info.def:
-  GLITE_LB_RTM_ENABLED=true
-  GLITE_LB_RTM_DN="certificate subject"
-
-See also L&B Admin Guide.
-
-Launch (with msg-publish sending messages)
-=========================================
-
-Harvester is sending notifications via msg-publish infrastructure. List of the
-L&B server to harvest is specified via -c option.
-
-1) with newer LB 2.0 servers:
-
-  glite-lb-harvester -c servers.txt -C certfile -K keyfile --wlcg
-
-2) with older LB servers (backward compatible but greedy notifications):
-
-  glite-lb-harvester -c servers.txt -C certfile -K keyfile --wlcg --old
-
-Custom configuration of messaging:
-	--wlcg-binary $HOME/bin/msg-publish
-	--wlcg-topic org.wlcg.usage.JobStatus2
-	--wlcg-config $HOME/etc/msg-publish.conf.wlcg
-
-
-Launch (Real Time Monitor and storing to the database)
-======================================================
-
-Harvester is using postgres database. Table 'lb20' with L&B servers to
-harvest (read-only), table 'jobs' with result job states (read/write). It's
-possible to specify L&B servers list by file instead of 'lb20' table,
-via -c option.
-
-  glite-lb-harvester -C certfile -K keyfile --pg rtm/@:rtm
-
-The connection string after '--pg' is in format:
-  USER/PASSWORD@HOST:DATABASE
-Database schema in 'test.sql'.
-
-
-Other recommended options
-=========================
-
-Use 'glite-lb-harvester --help' for additional options.
-
-For example:
- - deamonizing and using syslog:
-	'--daemonize --pidfile /var/run/glite-lb-harvester.pid'
- - decreasing verbosity:
-	'-d 2' (2 for errors and warnings only)
-
-
-Stop
-====
-
-In non-daemon mode CTRL-C can be used, in daemon mode using specified
-pidfile:
-
- kill `cat /var/run/glite-lb-harvester.pid`
-
-pidfile will vanish after exit.
-
-All notifications are preserved on LB servers, and will expire later. You can
-purge them now, if they won't be needed:
-
- glite-lb-harvester --cleanup
diff --git a/org.glite.lb.harvester/doc/glite-lb-harvester.sgml b/org.glite.lb.harvester/doc/glite-lb-harvester.sgml
deleted file mode 100644
index 5d9f75a..0000000
--- a/org.glite.lb.harvester/doc/glite-lb-harvester.sgml
+++ /dev/null
@@ -1,480 +0,0 @@
-
-
-
-
-	
-		glite-lb-harvester
-		1
-		EU EGEE Project
-	
-
-	
-		glite-lb-harvester
-		daemon for processing L&B notifications
-	
-
-	
-		
-			glite-lb-harvester
-
-			
-				-h
-				--help
-			
-
-			
-				-v
-				--version
-			
-
-			
-				-d
-				--debug
-			 LEVEL
-
-			
-				-D
-				--daemon
-			
-
-			
-				-i
-				--pidfile
-			 PIDFILE
-
-			
-				-s
-				--threads
-			 N
-
-			
-				-t
-				--ttl
-			 TIME
-
-			
-				-H
-				--history
-			 TIME
-
-			
-				-c
-				--config
-			
-
-			
-				-m
-				--pg
-			 USER/PWD@SERVER:DBNAME
-
-			
-				-n
-				--notifs
-			 FILE
-
-			
-				-p
-				--port
-			 PORT
-
-			
-				-C
-				--cert
-			 FILE
-
-			
-				-K
-				--key
-			 FILE
-
-			
-				-o
-				--old
-			
-
-			
-				-l
-				--cleanup
-			
-
-			
-				-u
-				--no-purge
-			
-
-			
-				-w
-				--wlcg
-			
-
-			
-				--wlcg-binary
-			 EXECUTABLE
-
-			
-				--wlcg-topic
-			 TOPIC
-
-			
-				--wlcg-config
-			 FILENAME
-
-			
-				--wlcg-flush
-			
-		
-	
-
-	
-		DESCRIPTION
-		
-L&B Harvester gathers information about jobs from L&B servers using efficient
-L&B notification mechanism. It manages notifications and keeps them in
-a persistent storage (file or database table) to reuse later on next launch.
-It takes care about refreshing notifications and queries L&B servers back when
-some notification expires.
-
-The tool was initially written for Real Time Monitor (project at Imperial
-College in London), later was extended by MSG publish messaging mechanism for WLCG.
-		
-	
-
-	
-		Requirements
-		
-It is required on L&B servers side:
-			
-				
-lastUpdateTime index, see "Changing Index Configuration" section in L&B Admin Guide
-				
-				
-L&B harvester identity (certification subject) in super users file
-				
-			
-		
-	
-
-	
-		OPTIONS
-	
-		
-			
-				|
-				
-Print short usage.
-				
-			
-		
-
-		
-			
-			|
-			
-Print harvester version identifier.
-			
-			
-
-			
-			|
-			
-			Verbosity level:
-				
-					0error only
-					1warnings
-					2info/progress
-					3debug
-					4insane
-					+8 (8,9,10,11,12)don't fork and no preventive restarts
-				
-			
-			
-
-			
-			|
-			
-Daemonize and detach from console. Error messages are directed to syslog.
-			
-			
-
-			
-			|
-			
-The file with process ID. Automatically removed on shutdown.
-			
-			
-
-			
-			|
-			
-Number of threads (slaves). Configured L&B servers are equally distributed between threads.
-			
-			
-
-			
-			|
-			
-Validity (time to live) of the notifications. Daemon regularly refreshes notification in advance as needed.
-			
-			
-
-			
-			|
-			
-Historic dive limit in seconds. <= means unlimited.
-			
-			When staring, the L&B harvester queries the L&B servers for existing jobs. It queries L&B server when notification expires too and can't be refreshed on time. This parameter is used for limit, how deep into history L&B harvester should go.
-			
-			Another usage of this parameter is for derivation of the maximal time of retries. When some L&B server is inaccessible or it is in error condition, harvester linearly increases retry time. The maximal retry time is half of this parameter.
-			
-			
-
-			
-			|
-			
-			Config file name with list of L&B servers. When used together with database option  (), this parameter has precedence before lb20 table.
-				
-			
-
-			
-				|
-				
-Database connection string in the USER/PWD@SERVER:DBNAME form. There are used following tables in database:
-					
-						
-	lb20 - the list of L&B servers is taken from this table. But when is specified option  () too, the file has precedence before this table.
-						
-There is kept a column monitored in too: if there is any inactive notification because of errors on given L&B server (one expired or it was unable to create a new one), the false value is set. After refreshing or creating the notification, the value is set back to true.
-						
-						
-	jobs - table for storing job states. Each record is updated for each incoming notification - when state of the job changes in L&B server.
-						
-					
-Database schema can be found in source code of org.glite.lb.harvester: examples/test.sql
-					
-Developer note: information about notifications are kept in a file. It is possible to compile a binary keeping states in the database. It is used in the test in examples source directory.
-				
-			
-
-			
-				|
-				
-File for internal usage in L&B harvester. There is kept persistent information about active notifications or errors on L&B servers. Default is /var/tmp/notifs.txt.
-				
-			
-
-			
-				|
-				
-Specifies the port for listening and requests L&B nodes to send notification messages only to this port. May be needed for networks behind NAT or behind firewalls.
-				
-			
-
-			
-				|
-				
-X509 certificate file.
-				
-			
-
-			
-				|
-				
-X509 key file.
-				
-			
-
-			
-				|
-				
-"silly" mode for L&B servers < 2.0. In this mode transfer of the notification is not optimized at all. On the other hand it will work with older L&B servers.
-				
-			
-
-			
-				|
-				
-Cleans up all active notifications and quits.
-				
-Each  notification automatically expires. But if you know, than notifications used in previous run of L&B harvester won;t be needed, it is recommended to clean up the notifications and spare the resources on L&B servers (queue with undelivered notification messages and matching rules).
-				
-			
-
-			
-				|
-				
-By default jobs are purged from local database when purged on L&B server. This option forces keeping all jobs in database, only with changed state to 'Purged'.
-				
-For using together with  ().
-				
-			
-
-			
-				|
-				
-Enables delivery to MSG publish. Messages are sent by executing a binary with proper parameters.
-				
-			
-
-			
-				
-				
-Full path to msg-publish binary executable, which is called for sending messages. Default is /usr/bin/msg-publish.
-				
-			
-
-			
-				
-				
-Topic used in MSG publish messages. Default is org.wlcg.usage.jobStatus.
-				
-			
-
-			
-				
-				
-Config file used in MSG publish. Default is /etc/msg-publish/msg-publish.conf.
-				
-			
-
-			
-				
-				
-Messages are sent to MSG publish in batches by default. This option enforce sending the messages one by one on each notification from L&B server - for each job state change.
-				
-			
-
-		
-	
-
-	
-		ENVIRONMENT
-
-		
-			
-				GLITE_LB_HARVESTER_NO_REMOVE
-				
-0 or false instructs L&B harvester to not remove temporary files with sent messages for MSG publish. By default temporary files with successfully sent messages are removed. Files with failed messages are always preserved.
-				
-Intended for debugging purposes.
-				
-			
-		
-	
-
-	
-		EXAMPLES
-
-		
-			MSG publish infrastructure
-			
-Harvester will send notifications using msg-publish infrastructure. List of the L&B servers to harvest is specified in config file specified by  option:
-			
-			
-				
-					glite-lb-harvester -c servers.txt -C certfile -K keyfile --wlcg
-					
-With newer L&B servers >= 2.0.
-					
-				
-				
-					glite-lb-harvester -c servers.txt -C certfile -K keyfile --wlcg --old
-					
-With older L&B servers < 2.0 (backward compatible but greedy notifications).
-					
-				
-			
-
-			
-Custom configuration examples for MSG publish:
-				
-					
- $HOME/bin/msg-publish
-					
- org.wlcg.usage.JobStatus2
-					
- $HOME/etc/msg-publish.conf.wlcg
-					
-				
-			
-		
-
-		
-			Real Time Monitor
-			
-Harvester will use postgres database. Table lb20 with L&B servers to harvest (read-only), table jobs for result job states (read/write):
-			
-			
-				
-					glite-lb-harvester -C certfile -K keyfile --pg rtm/@:rtm -p 9004
-					
-In this case the L&B harvester will connect to database rtm on localhost as user rtm. For incoming notification it will request and listen only on port 9004.
-					
-				
-			
-		
-
-		
-			Other recommended options
-			
-Use glite-lb-harvester --help for the whole summary.
-			
-For example:
-				
-					
-						
-						
-Daemonizing and using syslog.
-						
-					
-
-					
-						
-						
-Decreasing verbosity (2 for errors and warnings only).
-						
-					
-				
-			
-		
-	
-
-	
-		EXIT
-		
-In non-daemon mode CTRL-C can be used.
-		
-Use the pidfile in daemon mode (pidfile will vanish after exit):
-		
-kill `cat /var/run/glite-lb-harvester.pid`
-		
-All notifications are preserved on LB servers, and will expire later. You can
-purge them at once, if they won't be needed:
-		
-glite-lb-harvester --cleanup
-		
-	
-
-	
-		EXIT STATUS
-		
-			
-				0
-				Success.
-			
-			
-				1
-				Reloading, used only internally for preventive restarts.
-			
-			
-				2
-				Error occurred. Messages go on console (foreground run) or into syslog (daemon run), depending on verbosity.
-			
-		
-	
-
-	
-		AUTHOR
-		gLite L&B product team, CESNET.
-	
-
-
diff --git a/org.glite.lb.harvester/examples/test.sh b/org.glite.lb.harvester/examples/test.sh
deleted file mode 100755
index ec46899..0000000
--- a/org.glite.lb.harvester/examples/test.sh
+++ /dev/null
@@ -1,912 +0,0 @@
-#! /bin/sh
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-
-usage() {
-cat <&1| \
-				grep timeleft| sed 's/^.* //'`
-			if [ "$timeleft" = "0:00:00" -o -z "$timeleft" ]; then 
-				echo "Proxy certificate check failed."\
-				" Aborting."
-				exit 1
-			fi
-		else
-			echo "Can't check proxy cert (grid-proxy-info not found). If you do not have valid proxy certificate, set GLITE_HOST_KEY/GLITE_HOST_KEY - otherwise tests will fail!"
-		fi
-#	fi
-	identity=`X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT} grid-proxy-info 2>&1| \
-		grep identity| sed 's/^[^/]*//'`
-
-	if [ -z "$GLITE_LB_TEST_DB" ]; then
-		GLITE_LB_TEST_DB="lbserver/@localhost:lbserver20test"
-       		need_new_lb_db=1;
-	fi
-	DB_USER=`echo $GLITE_LB_TEST_DB| sed 's!/.*$!!'`
-	DB_HOST=`echo $GLITE_LB_TEST_DB| sed 's!^.*@!!' | sed 's!:.*!!'`
-	DB_NAME=`echo $GLITE_LB_TEST_DB| sed 's!^.*:!!'`
-	MYSQL_ARGS="-u ${GLITE_MYSQL_ROOT_USER:-root}"
-	[ -z "$GLITE_MYSQL_ROOT_PASSWORD" ] || MYSQL_ARGS="--password=${GLITE_MYSQL_ROOT_PASSWORD} $MYSQL_ARGS"
-
-	if [ -z "$GLITE_RTM_TEST_DB" ]; then
-		GLITE_RTM_TEST_DB="rtm/@localhost:rtmtest"
-       		need_new_rtm_db=1;
-	fi
-	RTM_USER=`echo $GLITE_RTM_TEST_DB| sed 's!/.*$!!'`
-	RTM_HOST=`echo $GLITE_RTM_TEST_DB| sed 's!^.*@!!' | sed 's!:.*!!'`
-	RTM_NAME=`echo $GLITE_RTM_TEST_DB| sed 's!^.*:!!'`
-	PG_ARGS="-U ${GLITE_PG_ROOT_USER:-postgres}"
-
-	#other stuff
-	GLITE_LB_TEST_SERVER_PORT=${GLITE_LB_TEST_SERVER_PORT:-"10000"}
-	GLITE_LB_TEST_PIDFILE=${GLITE_LB_TEST_PIDFILE:-"/tmp/glite-lb-test.pid"}
-	GLITE_LB_NOTIF_IL_PIDFILE=${GLITE_LB_NOTIF_IL_PIDFILE:-"/tmp/glite-lb-notif-il-test.pid"}
-	GLITE_LB_PROXY_IL_PIDFILE=${GLITE_LB_PROXY_IL_PIDFILE:-"/tmp/glite-lb-proxy-il-test.pid"}
-	GLITE_RTM_TEST_PIDFILE=${GLITE_RTM_TEST_PIDFILE:-"/tmp/glite-rtm-test.pid"}
-	GLITE_RTM_TEST_TTL=${GLITE_RTM_TEST_TTL:-"60"}
-
-	jobreg="$GLITE_LB_LOCATION_EXAMPLES/glite-lb-job_reg -m `hostname -f`:${GLITE_LB_TEST_SERVER_PORT} -s UserInterface"
-	logev="$GLITE_LOCATION/bin/glite-lb-logevent -x -S `pwd`/LB/proxy.sockstore.sock -U localhost"
-	purge="$GLITE_LOCATION/bin/glite-lb-purge"
-	[ -x "$purge" ] || purge="$GLITE_LOCATION/sbin/glite-lb-purge"
-	for dir in "$GLITE_LB_LOCATION_EXAMPLES" "`pwd`/../build" "`pwd`"; do
-		if [ -x "$dir/glite-lb-harvester-dbg" ]; then
-			rtm="$dir/glite-lb-harvester-dbg"
-		fi
-		if [ -x "$dir/harvester-dbg" ]; then
-			rtm="$dir/harvester-dbg"
-		fi
-	done
-	if [ -z "$rtm" ]; then
-		echo "glite-lb-harvester-dbg not found"
-		return 1
-	fi
-
-	if echo "$GLITE_RTM_TEST_ADDITIONAL_ARGS" | grep -- '[^-]\?\(--old\>\|-o\>\)' >/dev/null; then
-		n_notifs=1
-	else
-		n_notifs=2
-	fi
-
-	rm -f log
-}
-
-
-drop_db() {
-return 0
-	[ -z "$lb_db_created" ] || mysqladmin -f $MYSQL_ARGS drop "$DB_NAME"
-	[ -z "$rtm_db_created" ] || dropdb $PG_ARGS "$RTM_NAME"
-}
-
-
-create_db() {
-	echo -n "mysql."
-	# create database when needed
-	if [ "x$need_new_lb_db" = "x1" ]; then
-		mysqladmin -f $MYSQL_ARGS drop $DB_NAME > /dev/null 2>&1
-		echo -n "."
-		mysqladmin -f $MYSQL_ARGS create $DB_NAME && \
-		echo -n "."
-		mysql $MYSQL_ARGS -e "GRANT ALL on $DB_NAME.* to $DB_USER@$DB_HOST" && \
-		echo -n "."
-		mysql -u $DB_USER $DB_NAME -h $DB_HOST < $GLITE_LOCATION_ETC/glite-lb/glite-lb-dbsetup.sql || return $?
-		echo -n "."
-		mkdir -p `pwd`/LB
-		cat > `pwd`/LB/glite-lb-index.conf << EOF
-[
-	JobIndices = {
-		[ type = "system"; name = "lastUpdateTime" ]
-	}
-]
-EOF
-		LBDB="$GLITE_LB_TEST_DB" $GLITE_LOCATION/bin/glite-lb-bkindex -r `pwd`/LB/glite-lb-index.conf || return $?
-		lb_db_created="1"
-		echo -n "."
-	else
-		cleanup_mysql || return $?
-	fi
-	echo -n "OK psql."
-	rm -f 'test.sql'
-	if [ -f "$GLITE_LOCATION_ETC/glite-lb/harvester-test-dbsetup.sql" ]; then
-		ln -s "$GLITE_LOCATION_ETC/glite-lb/harvester-test-dbsetup.sql" test.sql
-	else
-		wget --quiet -O 'test.sql' 'http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.lb.harvester/examples/test.sql?revision=HEAD'
-	fi
-	if [ "x$need_new_rtm_db" = "x1" ]; then
-		dropdb $PG_ARGS "$RTM_NAME" >/dev/null 2>&1
-		echo -n "."
-#		createuser $PG_ARGS -A -D "$RTM_NAME" >/dev/null 2>&1
-#		echo -n "."
-		createdb $PG_ARGS --encoding "UTF-8" --template template0 --owner "$RTM_USER" "$RTM_NAME" >psql-create.log 2>&1 || return $?
-		rm psql-create.log
-		echo -n "."
-		rtm_db_created="1"
-		echo "\i test.sql" | psql -AtF ',' -U "$RTM_USER" "$RTM_NAME" >/dev/null || return $?
-		echo -n "."
-	else
-		cleanup_pg || return $?
-	fi
-	echo "OK"
-}
-
-
-cleanup_mysql() {
-	cat << EOF | mysql -u $DB_USER $DB_NAME -h $DB_HOST || return $?
-DELETE FROM acls;
-DELETE FROM events;
-DELETE FROM events_flesh;
-DELETE FROM jobs;
-DELETE FROM long_fields;
-DELETE FROM notif_jobs;
-DELETE FROM notif_registrations;
-DELETE FROM server_state;
-DELETE FROM short_fields;
-DELETE FROM states;
-DELETE FROM status_tags;
-DELETE FROM users;
-DELETE FROM zombie_jobs;
-DELETE FROM zombie_prefixes;
-DELETE FROM zombie_suffixes;
-EOF
-	echo -n "."
-}
-
-
-cleanup_pg() {
-		cat << EOF | psql -AtF ',' -U "$RTM_USER" "$RTM_NAME" >/dev/null || return $?
-DELETE FROM jobs;
-DELETE FROM notifs;
-EOF
-	echo -n "."
-}
-
-
-run_daemons() {
-	mkdir -p LB/dump LB/purge LB/voms 2>/dev/null
-
-	# checks
-	if [ -f "${GLITE_LB_TEST_PIDFILE}" ]; then
-		echo "L&B server already running (${GLITE_LB_TEST_PIDFILE}, `cat ${GLITE_LB_TEST_PIDFILE}`)"
-		quit=1
-	fi
-	if [ -f "${GLITE_RTM_TEST_PIDFILE}" ]; then
-		echo "L&B harvester already running (${GLITE_RTM_TEST_PIDFILE}, `cat ${GLITE_RTM_TEST_PIDFILE}`)"
-		quit=1
-	fi
-	if [ -e "`pwd`/LB/notif.sock" ]; then
-		if [ "`lsof -t $(pwd)/LB/notif.sock | wc -l`" != "0" ]; then
-			echo "Notification interlogger already running (using LB/notif.sock, `lsof -t $(pwd)/LB/notif.sock`)"
-			quit=1
-		fi
-	fi
-	if [ -e "`pwd`/LB/proxy-il.sock" ]; then
-		if [ "`lsof -t $(pwd)/LB/proxy-il.sock | wc -l`" != "0" ]; then
-			echo "Proxy interlogger already running (using LB/proxy-il.sock, `lsof -t $(pwd)/LB/proxy-il.sock`)"
-			quit=1
-		fi
-	fi
-	[ -z "$quit" ] || exit 1
-
-	# run L&B server
-	echo -n "L"
-	X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT} \
-	$GLITE_LOCATION/bin/glite-lb-bkserverd \
-	  -m $GLITE_LB_TEST_DB \
-	  -p $GLITE_LB_TEST_SERVER_PORT -w $(($GLITE_LB_TEST_SERVER_PORT + 3))\
-	  -i ${GLITE_LB_TEST_PIDFILE} \
-	  --withproxy -o `pwd`/LB/proxy.sock\
-	  --proxy-il-sock `pwd`/LB/proxy-il.sock --proxy-il-fprefix `pwd`/LB/proxy-data \
-	  -D `pwd`/LB/dump -S `pwd`/LB/purge \
-	  -V `pwd`/LB/voms \
-	  --notif-il-sock `pwd`/LB/notif.sock --notif-il-fprefix `pwd`/LB/notif-data \
-	> `pwd`/LB/glite-lb-test-pre.log 2>&1
-	if [ x"$?" != x"0" ]; then
-		cat `pwd`/LB/glite-lb-test-pre.log
-		echo FAILED
-		drop_db;
-		exit 1
-	fi
-	echo -n "B "
-
-	# run L&B interlogger
-	echo -n "L"
-	X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT} \
-	$GLITE_LOCATION/bin/glite-lb-interlogd \
-	  --file-prefix `pwd`/LB/proxy-data --socket `pwd`/LB/proxy-il.sock \
-	  --pidfile $GLITE_LB_PROXY_IL_PIDFILE > `pwd`/LB/glite-interlog-test-pre.log 2>&1
-	if [ x"$?" != x"0" ]; then
-		cat `pwd`/LB/glite-interlog-test-pre.log
-		echo FAILED
-		kill_bkserver
-		drop_db;
-		exit 1
-	fi
-	echo -n "I "
-
-	# run L&B notification interlogger
-	echo -n "N"
-	X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT} \
-	$GLITE_LOCATION/bin/glite-lb-notif-interlogd \
-	  --file-prefix `pwd`/LB/notif-data --socket `pwd`/LB/notif.sock \
-	  --pidfile $GLITE_LB_NOTIF_IL_PIDFILE > `pwd`/LB/glite-notif-test-pre.log 2>&1
-	if [ x"$?" != x"0" ]; then
-		cat `pwd`/LB/glite-notif-test-pre.log
-		echo FAILED
-		kill_daemons
-		drop_db;
-		exit 1
-	fi
-	echo -n "I "
-
-	if ! start_harvester; then
-		kill_daemons;
-		drop_db;
-		exit 1
-	fi
-
-	# wait for pidfiles
-	i=0
-	while [ ! -s "${GLITE_LB_TEST_PIDFILE}" -a $i -lt 20 ]; do
-		sleep 0.1
-		i=$(($i+1))
-	done
-	if [ ! -s "${GLITE_LB_TEST_PIDFILE}" ]; then
-		echo "Can't startup L&B server."
-		kill_daemons;
-		drop_db;
-		exit 1
-	fi
-
-	echo -n "notifs."
-	pg_wait 20 "SELECT refresh FROM notifs WHERE notifid IS NOT NULL" $n_notifs || return $?
-	refresh=`echo "$result" | head -n 1`
-	if [ -z "$refresh" ]; then
-		echo "FAIL"
-		return 1
-	fi
-}
-
-
-start_harvester() {
-	# run L&B harvester server
-	echo -n "R"
-	rm -Rf RTM
-	mkdir RTM 2>/dev/null
-	echo "`hostname -f`:${GLITE_LB_TEST_SERVER_PORT}" > `pwd`/RTM/config.txt
-	X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT} \
-	${rtm} \
-	  -m $GLITE_RTM_TEST_DB \
-	  --pidfile ${GLITE_RTM_TEST_PIDFILE} \
-	  --ttl ${GLITE_RTM_TEST_TTL} \
-	  --history $((GLITE_RTM_TEST_TTL / 2)) \
-	  --debug 12 \
-	  --config `pwd`/RTM/config.txt \
-	  --daemonize ${GLITE_RTM_TEST_ADDITIONAL_ARGS} 2>`pwd`/RTM/glite-rtm-test-pre.log >`pwd`/RTM/notifs.log
-	if [ x"$?" != x"0" ]; then
-		cat `pwd`/RTM/glite-rtm-test-pre.log
-		echo FAILED
-		return 1
-	fi
-
-	i=0
-	while [ ! -s "${GLITE_RTM_TEST_PIDFILE}" -a $i -lt 20 ]; do
-		sleep 0.1
-		i=$(($i+1))
-	done
-	if [ ! -s "${GLITE_RTM_TEST_PIDFILE}" ]; then
-		echo "Can't startup L&B harvester."
-		kill_daemons;
-		drop_db;
-		exit 1
-	fi
-
-	echo -n "M "
-}
-
-
-cleanup_harvester() {
-	echo -n "cleaning up..."
-	X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT} \
-	${rtm} \
-	  -m $GLITE_RTM_TEST_DB \
-	  --cleanup \
-	  --debug 12 ${GLITE_RTM_TEST_ADDITIONAL_ARGS} >`pwd`/RTM/glite-rtm-test-cleanup.log 2>&1
-	if [ x"$?" != x"0" ]; then
-		cat `pwd`/RTM/glite-rtm-test-cleanup.log
-		echo FAILED
-		return 1
-	fi
-	echo -n "OK "
-}
-
-
-kill_daemons() {
-	pid1=`cat ${GLITE_LB_TEST_PIDFILE} 2>/dev/null`
-	[ -f "${GLITE_RTM_TEST_PIDFILE}" ] && pid2=`cat ${GLITE_RTM_TEST_PIDFILE}`
-	pid3=`lsof -t $(pwd)/LB/notif.sock 2>/dev/null`
-	pid4=`lsof -t $(pwd)/LB/proxy-il.sock 2>/dev/null`
-	[ ! -z "$pid1" ] && kill $pid1
-	[ ! -z "$pid2" ] && kill -2 $pid2
-	[ ! -z "$pid3" ] && kill $pid3
-	[ ! -z "$pid4" ] && kill $pid4
-	sleep 1;
-	[ ! -z "$pid1" ] && kill -9 $pid1 2>/dev/null
-	[ ! -z "$pid2" ] && kill -9 $pid2 2>/dev/null
-	[ ! -z "$pid3" ] && kill -9 $pid3 2>/dev/null
-	[ ! -z "$pid4" ] && kill -9 $pid4 2>/dev/null
-	rm -f "${GLITE_LB_TEST_PIDFILE}" "${GLITE_RTM_TEST_PIDFILE}" "${GLITE_LB_NOTIF_IL_PIDFILE}" "${GLITE_LB_PROXY_IL_PIDFILE}"
-	rm -f `pwd`/LB/*.sock
-}
-
-
-kill_bkserver() {
-	pid=`cat ${GLITE_LB_TEST_PIDFILE} 2>/dev/null`
-	if [ ! -z "$pid1" ]; then
-		kill $pid;
-		sleep 1;
-		kill -9 $pid
-	fi
-	rm -f "${GLITE_LB_TEST_PIDFILE}"
-}
-
-
-kill_harvester() {
-	pid=`cat ${GLITE_RTM_TEST_PIDFILE} 2>/dev/null`
-	if [ ! -z "$pid1" ]; then
-		kill $pid
-		sleep 1;
-		kill -9 $pid 2>/dev/null
-	fi
-	rm -f "${GLITE_RTM_TEST_PIDFILE}"
-}
-
-
-reg() {
-	echo -n "R"
-	echo $jobreg $@ >> log
-	$jobreg $@ > jobreg.tmp
-	if [ $? -ne 0 ]; then
-		cat jobreg.tmp
-		rm -f jobreg.tmp
-		echo " FAIL!"
-		return 1;
-	fi
-	script=`cat jobreg.tmp | tail -n 2`
-	rm -f jobreg.tmp
-	EDG_JOBID=
-	EDG_WL_SEQUENCE=
-	eval $script
-	if [ -z "$EDG_JOBID" -o -z "$EDG_WL_SEQUENCE" ]; then
-		echo " FAIL!"
-		return 1;
-	fi
-	echo -n "G "
-}
-
-
-ev() {
-	echo -n "E"
-	echo $logev -j "$EDG_JOBID" -c "$EDG_WL_SEQUENCE" "$@" >> log
-	$logev -j "$EDG_JOBID" -c "$EDG_WL_SEQUENCE" "$@" 2> logev-err.tmp >logev.tmp
-	if [ $? -ne 0 ]; then
-		echo " FAIL!"
-		return 2;
-	fi
-	EDG_WL_SEQUENCE=`cat logev.tmp`
-	rm logev.tmp logev-err.tmp
-	echo -n "V "
-}
-
-
-pg_get() {
-	result=
-	lines=
-	echo "$1" | psql -AtF ',' -U "$RTM_USER" "$RTM_NAME" > psql.tmp
-	if [ $? != 0 ]; then
-		return $?
-	fi
-	result="`cat psql.tmp`"
-	lines=`wc -l psql.tmp | sed 's/^[ ]*//' | cut -f1 -d' '`
-#	rm psql.tmp
-	return 0
-}
-
-
-pg_wait() {
-	timeout=$(($1*2))
-	sql="$2"
-	n="$3"
-
-	i=0
-	found=0
-	result=
-	echo -n "S"
-	echo "`date '+%Y-%m-%d %H:%M:%S'` $sql" >> log
-	while [ "$found" = "0" -a $i -lt $timeout ]; do
-		pg_get "$sql" || return $?
-		echo -n "."
-		if [ -z "$n" ]; then
-			if [ "$lines" != "0" ]; then found=1; fi
-		else
-			if [ "$lines" = "$n" ]; then found=1; fi
-		fi
-		if [ "$found" = "0" ]; then sleep 0.5; fi
-		i=$(($i+1))
-	done
-	echo -n "Q "
-	result="$result"
-	echo "`date '+%Y-%m-%d %H:%M:%S'` $lines lines" >> log
-	if [ ! -z "$result" ]; then
-		echo "$result" | sed -e 's/\(.*\)/\t\1/' >> log
-	fi
-	return 0
-}
-
-
-my_get() {
-	result=
-	lines=
-	echo "`date '+%Y-%m-%d %H:%M:%S'` $1" >> log
-	echo "$1" | mysql -B -u "$DB_USER" "$DB_NAME" > mysql.tmp
-	if [ $? != 0 ]; then
-		return $?
-	fi
-	result=`cat mysql.tmp | tail -n +2`
-	lines=`echo "$result" | grep -v '^$' | wc -l | sed 's/^[ ]*//'`
-	echo "`date '+%Y-%m-%d %H:%M:%S'` $lines lines" >> log
-	if [ ! -z "$result" ]; then
-		echo "$result" | sed -e 's/\(.*\)/\t\1/' >> log
-	fi
-#	rm -f mysql.tmp
-	return 0
-}
-
-
-# notif propagation
-test_basic() {
-	ok=0
-
-	# submited
-	echo -n "submitted..."
-	reg || return $?
-	pg_wait 10 "SELECT jobid, state FROM jobs WHERE state='Submitted'" || return $?
-	if [ -z "$result" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	# waiting
-	echo -n "waiting..."
-	ev -s NetworkServer -e Accepted --from='UserInterface' --from_host=`hostname -f` --from_instance="pid$$" || return $?
-	pg_wait 10 "SELECT jobid, state FROM jobs WHERE state='Waiting'" || return $?
-	if [ -z "$result" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	# running
-	echo -n "running..."
-	ev -s LogMonitor -e Running --node="worker node" || return $?
-	pg_wait 10 "SELECT jobid, state FROM jobs WHERE state='Running'" || return $?
-	if [ -z "$result" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	ok=1
-	echo "OK"
-}
-
-
-# proper notif registration cleanup
-test_rebind() {
-	ok=0
-
-	# ---- active ---
-	echo -n "$n_notifs notifications "
-	my_get "SELECT notifid FROM notif_registrations" || return $?
-	# STATUS and JDL
-	if [ "$lines" != "$n_notifs" ]; then
-		echo "FAIL"
-		return 0
-	fi
-	echo -n "OK "
-
-	# ---- store & stop ---
-	echo -n "store&quit"
-	pid=`cat ${GLITE_RTM_TEST_PIDFILE}`
-	kill $pid
-	i=0
-	while [ -s "${GLITE_RTM_TEST_PIDFILE}" -a $i -lt 200 ]; do
-		echo -n "."
-		sleep 0.5
-		i=$(($i+1))
-	done
-	if [ -s "${GLITE_RTM_TEST_PIDFILE}" ]; then
-		echo "FAIL"
-		return 0
-	fi
-	echo -n "OK notifs "
-	my_get "SELECT notifid FROM notif_registrations" || return $?
-	if [ "$lines" != "$n_notifs" ]; then
-		echo "FAIL"
-		return 0
-	fi
-	echo -n "OK "
-
-	# ---- launch & rebind ---
-	if ! start_harvester; then
-		kill_daemons;
-		drop_db;
-		exit 1
-	fi
-
-	echo -n "bind"
-	pg_wait 20 "SELECT notifid FROM notifs WHERE notifid IS NOT NULL" $n_notifs || return $?
-	if [ x"$lines" != x"$n_notifs" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	echo -n "Done "
-	ev -s LogMonitor -e Done --status_code=OK --reason="Finished, yeah!" --exit_code=0 || return $?
-	pg_wait 20 "SELECT jobid, state FROM jobs WHERE state='Done'"
-	if [ -z "$result" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	ok=1
-	echo "OK"
-}
-
-
-test_cleanup() {
-	ok=0
-
-	# ---- deep stop ---
-	echo -n "deep quit"
-	pid=`cat ${GLITE_RTM_TEST_PIDFILE}`
-	kill -2 $pid
-	i=0
-	while [ -s "${GLITE_RTM_TEST_PIDFILE}" -a $i -lt 200 ]; do
-		echo -n "."
-		sleep 0.5
-		i=$(($i+1))
-	done
-	if [ -s "${GLITE_RTMTESTPIDFILE}" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	echo -n "$n_notifs notifications..."
-	my_get "SELECT notifid FROM notif_registrations" || return 1
-	if [ "$lines" != "$n_notifs" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	cleanup_harvester || return $?
-	echo -n "0 notifications..."
-	my_get "SELECT notifid FROM notif_registrations" || return 1
-	if [ "$lines" != "0" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	echo -n "cleandb."
-	cleanup_pg || return $?
-	start_harvester || return $?
-
-	echo -n "notifs."
-	pg_wait 20 "SELECT refresh FROM notifs WHERE notifid IS NOT NULL" $n_notifs || return $?
-	refresh=`echo "$result" | head -n 1`
-	if [ -z "$refresh" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	ok=1
-	echo "OK"
-}
-
-
-test_refresh() {
-	ok=0
-
-	echo -n "refresh."
-	pg_wait $((GLITE_RTM_TEST_TTL * 3 / 4)) "SELECT notifid FROM notifs WHERE notifid IS NOT NULL AND refresh>'$refresh'" $n_notifs || return $?
-	if [ -z "$result" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	ok=1
-	echo "OK"
-}
-
-
-test_jdl() {
-	ok=0
-
-#	kill_daemons
-#	cleanup_mysql && cleanup_pg || return $?
-#	run_daemons || return $?
-
-	# need to wait for notifications to avoid bootstrap
-	echo -n "notifs."
-	pg_wait 20 "SELECT refresh FROM notifs WHERE notifid IS NOT NULL" $n_notifs || return $?
-	refresh=`echo "$result" | head -n 1`
-	if [ -z "$refresh" ]; then
-		echo "FAIL"
-		return 0
-	fi
-	echo -n "OK "
-
-	echo -n "submitted..."
-	reg || return $?
-	pg_wait 10 "SELECT jobid, state FROM jobs WHERE state='Submitted'" || return $?
-	if [ -z "$result" ]; then
-		echo "FAIL"
-		return 0
-	fi
-	echo -n "OK "
-
-	echo -n "waiting..."
-	cat > jdl.txt << EOF
-[
- VirtualOrganisation = "TestingVO";
-]
-EOF
-	ev -s NetworkServer -e Accepted --from='UserInterface' --from_host=`hostname -f` --from_instance="pid$$" || return $?
-	ev -s NetworkServer -e EnQueued --queue "very long and chaotic queue" --job=`pwd`/jdl.txt --result START || return $?
-	ev -s NetworkServer -e EnQueued --queue "very long and chaotic queue" --job="`cat jdl.txt`" --result OK || return $?
-	pg_wait 10 "SELECT jobid, state FROM jobs WHERE state='Waiting'" || return $?
-	if [ -z "$result" ]; then
-		echo "FAIL"
-		return 0
-	fi
-	echo -n "OK "
-
-	echo -n "waiting and VO..."
-	pg_wait 10 "SELECT jobid, state FROM jobs WHERE state='Waiting' AND vo='TestingVO'" || return $?
-	if [ -z "$result" ]; then
-		echo "FAIL"
-		return 0
-	fi
-	echo -n "OK "
-
-	#
-	# test JDL via VO change
-	#
-	# never do it at home ;-)
-	#
-
-	echo -n "changed JDL..."
-	ev -s NetworkServer -e EnQueued --queue "very long and chaotic queue" --job="[ VirtualOrganisation=\"TestingVO2\";]" --result OK || return $?
-	pg_wait 10 "SELECT jobid, state FROM jobs WHERE state='Waiting' AND vo='TestingVO2'" || return $?
-	if [ -z "$result" ]; then
-		echo "FAIL"
-		return 0
-	fi
-	echo -n "OK "
-
-	echo -n "changed after waiting..."
-	ev -s WorkloadManager -e EnQueued --queue "very long and chaotic queue" --destination LogMonitor --dest_host localhost --dest_instance pid$$ --job "(car 'testing=true)"  --result=OK || return $?
-	pg_wait 10 "SELECT jobid, state FROM jobs WHERE state='Ready' AND vo='TestingVO2'" || return $?
-	if [ -z "$result" ]; then
-		echo "FAIL"
-		return 0
-	fi
-	echo -n "ready..."
-	ev -s NetworkServer -e EnQueued --queue "very long and chaotic queue" --job="[ VirtualOrganisation=\"TestingVO3\";]" --result OK || return $?
-	pg_wait 10 "SELECT jobid, state FROM jobs WHERE state='Waiting' AND vo='TestingVO3'" || return $?
-	if [ -z "$result" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	ok=1
-	echo "OK"
-}
-
-
-test_purge() {
-	ok=0
-
-	echo -n "purge."
-	pg_get "SELECT jobid FROM jobs" || return $?
-	if [ -z "$lines" -o $lines -le 0  ]; then
-		echo "no jobs! FAIL"
-		return 0
-	fi
-	echo -n "P"
-	jobunique=`echo "$result" | head -n 1 | tr -d '\n'`
-	jobid="https://`hostname -f`:${GLITE_LB_TEST_SERVER_PORT}/$jobunique"
-	echo $jobid > jobs
-	echo "${purge} -a1 -c1 -n1 -e1 -o1 -m "`hostname -f`:${GLITE_LB_TEST_SERVER_PORT}" -j jobs" >> log
-	echo "  jobs = `cat jobs` | tr -d '\n'" >> log
-	X509_USER_KEY=${X509_USER_KEY} X509_USER_CERT=${X509_USER_CERT} ${purge} -l -a1 -c1 -n1 -e1 -o1 -m "`hostname -f`:${GLITE_LB_TEST_SERVER_PORT}" -j jobs 2> purge-err.tmp >purge.tmp
-	if [ $? -ne 0 ]; then
-		echo " FAIL!"
-		return 2;
-	fi
-	rm -f jobs
-	echo -n "R "
-
-	pg_wait 10 "SELECT * FROM jobs WHERE jobid='$jobunique'" 0 || return $?
-	if [ x"$lines" != x"0" ]; then
-		echo "FAIL"
-		return 0
-	fi
-
-	ok=1
-	echo "OK"
-}
-
-
-quit() {
-	if [ x"$started" = x"" ]; then
-		kill_daemons
-		drop_db
-	fi
-	exit 1
-}
-
-
-fatal() {
-	echo "Fatal error, end"
-	quit
-}
-
-
-start() {
-	echo -n "Launch: "
-	create_db || fatal
-	run_daemons || fatal
-	echo "OK"
-	started=1
-}
-
-
-stop() {
-	kill_daemons
-	drop_db
-}
-
-
-test() {
-	echo -n "Basic: "
-	test_basic || fatal
-	if [ $ok != 1 ]; then quit; fi
-
-	echo -n "Rebind: "
-	test_rebind || fatal
-	if [ $ok != 1 ]; then quit; fi
-
-	echo -n "Cleanup: "
-	test_cleanup || fatal
-	if [ $ok != 1 ]; then quit; fi
-
-	echo -n "Refresh: "
-	test_refresh || fatal
-	if [ $ok != 1 ]; then quit; fi
-
-	echo -n "JDL: "
-	test_jdl || fatal
-	if [ $ok != 1 ]; then quit; fi
-
-#	echo -n "Purge: "
-#	test_purge || fatal
-#	if [ $ok != 1]; then quit; fi
-}
-
-
-case x"$1" in
-xstart)
-	init
-	start
-	;;
-
-xstop)
-	init
-	stop
-	;;
-
-xtest)
-	init
-	test
-	;;
-
-x)
-	init
-	start
-	test
-	stop
-	;;
-
-*)
-	usage
-	exit 1
-esac
diff --git a/org.glite.lb.harvester/examples/test.sql b/org.glite.lb.harvester/examples/test.sql
deleted file mode 100644
index 15736f6..0000000
--- a/org.glite.lb.harvester/examples/test.sql
+++ /dev/null
@@ -1,55 +0,0 @@
---
--- Inicialization (replace pgsql by actual postgres superuser):
---
--- 1) grant privileges, someting like this in $data/pg_hba.conf:
---     local all all trust
---
--- 2) create user:
---     createuser -U pgsql rtm
---
--- 3) crate database:
---     createuser -U pgsql rtm
---
--- 4) create tables:
---     psql -U rtm rtm < test.sql
---
-
-CREATE TABLE "jobs" (
-	jobid VARCHAR PRIMARY KEY,
-	lb VARCHAR,
-	ce VARCHAR,
-	queue VARCHAR,
-	rb VARCHAR,
-	ui VARCHAR,
-	state VARCHAR,
-	state_entered TIMESTAMP,
-	rtm_timestamp TIMESTAMP,
-	active BOOLEAN,
-	state_changed BOOLEAN,
-	registered TIMESTAMP,
-	vo VARCHAR
-);
-
-CREATE TABLE "lb20" (
-	ip TEXT NOT NULL,
-	branch TEXT NOT NULL,
-	serv_version TEXT NOT NULL,
-	monitored BOOLEAN DEFAULT FALSE,
-	last_seen DATE,
-	first_seen DATE,
-
-	PRIMARY KEY(ip)
-);
-
-CREATE TABLE "notifs" (
-	lb VARCHAR,
-	port INTEGER,
-	notifid VARCHAR,
-	notiftype VARCHAR,
-	valid TIMESTAMP,
-	refresh TIMESTAMP,
-	last_update TIMESTAMP,
-	errors INTEGER,
-
-	PRIMARY KEY(lb, port, notiftype)
-);
diff --git a/org.glite.lb.harvester/project/.post b/org.glite.lb.harvester/project/.post
deleted file mode 100644
index 5a553f4..0000000
--- a/org.glite.lb.harvester/project/.post
+++ /dev/null
@@ -1,4 +0,0 @@
-/sbin/chkconfig --add glite-lb-harvester
-if [ $1 -eq 1 ] ; then
-	/sbin/chkconfig glite-lb-harvester off
-fi
diff --git a/org.glite.lb.harvester/project/.postun b/org.glite.lb.harvester/project/.postun
deleted file mode 100644
index 215d986..0000000
--- a/org.glite.lb.harvester/project/.postun
+++ /dev/null
@@ -1,3 +0,0 @@
-if [ "$1" -ge "1" ] ; then
-    /sbin/service glite-lb-harvester condrestart >/dev/null 2>&1 || :
-fi
diff --git a/org.glite.lb.harvester/project/.pre b/org.glite.lb.harvester/project/.pre
deleted file mode 100644
index 27c196b..0000000
--- a/org.glite.lb.harvester/project/.pre
+++ /dev/null
@@ -1,5 +0,0 @@
-getent group glite >/dev/null || groupadd -r glite
-getent passwd glite >/dev/null || useradd -r -g glite -d /var/glite -c "gLite user" glite
-mkdir -p /var/glite /var/log/glite 2>/dev/null || :
-chown glite:glite /var/glite /var/log/glite
-exit 0
diff --git a/org.glite.lb.harvester/project/.preun b/org.glite.lb.harvester/project/.preun
deleted file mode 100644
index 482a67f..0000000
--- a/org.glite.lb.harvester/project/.preun
+++ /dev/null
@@ -1,4 +0,0 @@
-if [ $1 -eq 0 ] ; then
-    /sbin/service glite-lb-harvester stop >/dev/null 2>&1
-    /sbin/chkconfig --del glite-lb-harvester
-fi
diff --git a/org.glite.lb.harvester/project/ChangeLog b/org.glite.lb.harvester/project/ChangeLog
deleted file mode 100644
index a0e2611..0000000
--- a/org.glite.lb.harvester/project/ChangeLog
+++ /dev/null
@@ -1,122 +0,0 @@
-1.0.0-1
-- Initial version
-
-1.0.1-1
-- Changes for Real Time Monitor
-- Workaround for older Globus
-- Minor memleak fixes
-
-1.0.2-1
-- Less verbosity in reporting single notifications
-- Fixed postgres dependency
-
-1.0.3-1
-- Extended documentation
-- Fixed purging
-- Fixed build issues
-
-1.0.4-1
-- Fixed 'nodb' build issues
-
-1.0.5-1
-- Adopted the Common logging format
-- First release of the harvester module integrated into the L&B subsystem (2.1 and later)
-
-1.0.6-1
-- Resource Broker from JDL for CREAM jobs
-- For CE stripping protocol from destination
-- Test script updates
-
-1.0.6-2
-- Module rebuilt
-
-1.0.7-1
-- Fixed target 'clean' in the Makefile to handle debian builds
-- Removed log4c calls in code rune manually
-
-1.0.8-1
-- IPv6-compliant implementation
-- Array boundary fix
-
-1.0.8-2
-- Module rebuilt
-
-1.0.9-1
-- Separated start-up script for L&B harvester.
-
-1.0.9-2
-- Module rebuilt
-
-1.0.10-1
-- Makefile a configuration updated to work across org.glite & EMI
-- BDII status reporting fixed
-
-1.0.10-2
-- Module rebuilt
-
-1.0.10-3
-- Module rebuilt
-
-1.0.10-4
-- Module rebuilt
-
-1.0.11-1
-- Startup scripts remove stale sockets (fix tu bug #77357)
-
-1.1.0-1
-- Fixes for parallel release in EMI & gLite
-- Separated start-up script for L&B harvester
-- Check result of InitContext calls
-
-1.1.1-1
-- Detecting project name in Makefile
-- Introduction on a sysconfdir option (for /etc vs /usr)
-- DESTDIR in makefiles
-
-1.1.2-1
-- product-specific GLITE_*_LOCATION* variables
-- update startup scripts
-
-1.1.3-1
-- Proper default locations in startup scripts, generated during build
-
-1.1.3-2
-- Module rebuilt
-
-1.1.4-1
-- Relocatable build directory
-- Proper defaults in harvester startup script
-- Fixed setting of umask to create event files not readable by others
-
-1.1.5-1
-- Updated paths in harvester test
-
-1.1.6-1
-- Harvester test fixed
-
-1.1.6-2
-- Module rebuilt
-
-1.1.6-3
-- Module rebuilt
-
-1.1.7-1
-- LSB-compliant init scripts
-
-1.2.0-1
-- Preparation for a new multiplatform release
-
-1.2.1-1
-- Start-up scripts according to Fedora Packaging Guidelines
-
-1.2.2-1
-- rpmlint fixes
-- License string as recognized by rpmlint and packaging guidelines
-
-1.2.3-1
-- Do not set up daemons to start during installation. Starting scripts configured by yaim
-- Crash fixed (no jobs on error)
-
-1.2.3-2
-- Module rebuilt
-
diff --git a/org.glite.lb.harvester/project/debian.control b/org.glite.lb.harvester/project/debian.control
deleted file mode 100644
index faf4e53..0000000
--- a/org.glite.lb.harvester/project/debian.control
+++ /dev/null
@@ -1,25 +0,0 @@
-Source: glite-lb-harvester
-Priority: extra
-Maintainer: @MAINTAINER@
-Uploaders: @UPLOADERS@
-Build-Depends: debhelper (>= 7.0.50~), chrpath, docbook-utils, libglite-jobid-api-c-dev, libglite-lb-client-dev, libglite-lb-common-dev, libglite-lbjp-common-gss-dev, libglite-lbjp-common-db-dev, libglite-lbjp-common-log-dev, libglite-lbjp-common-trio-dev, libtool
-Standards-Version: 3.9.1
-Section: misc
-Homepage: @URL@
-DM-Upload-Allowed: yes
-@DEBIAN_VCS@
-
-Package: glite-lb-harvester
-Section: misc
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: @SUMMARY@
-@DEBIAN_DESCRIPTION@
-
-Package: glite-lb-harvester-dbg
-Section: debug
-Architecture: any
-Priority: extra
-Depends: glite-lb-harvester (= ${binary:Version}), ${misc:Depends}
-Description: gLite L&B harvester debugging symbols
- This package contains debugging symbols for gLite L&B harvester.
diff --git a/org.glite.lb.harvester/project/debian.copyright b/org.glite.lb.harvester/project/debian.copyright
deleted file mode 100644
index 3d762ae..0000000
--- a/org.glite.lb.harvester/project/debian.copyright
+++ /dev/null
@@ -1,38 +0,0 @@
-This work was packaged for Debian by:
-
-    @MAINTAINER@ on Thu, 08 Dec 2011 00:46:07 +0100
-
-It was downloaded from:
-
-    @URL@
-
-Upstream Author(s):
-
-    @MAINTAINER@
-
-Copyright:
-
-    
-
-License:
-
-   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.
-
-On Debian systems, the complete text of the Apache version 2.0 license
-can be found in "/usr/share/common-licenses/Apache-2.0".
-
-The Debian packaging is:
-
-    Copyright (C) 2004-2011 Members of the EGEE Collaboration
-
-and is licensed under the Apache License, Version 2.0.
diff --git a/org.glite.lb.harvester/project/debian.glite-lb-harvester.dirs b/org.glite.lb.harvester/project/debian.glite-lb-harvester.dirs
deleted file mode 100644
index a604a74..0000000
--- a/org.glite.lb.harvester/project/debian.glite-lb-harvester.dirs
+++ /dev/null
@@ -1,8 +0,0 @@
-etc/glite-lb
-etc/init.d
-usr/bin
-usr/lib
-usr/lib/glite-lb
-usr/lib/glite-lb/examples
-usr/share/doc/glite-lb-harvester
-usr/share/man/man1
diff --git a/org.glite.lb.harvester/project/debian.glite-lb-harvester.install b/org.glite.lb.harvester/project/debian.glite-lb-harvester.install
deleted file mode 100644
index be7803c..0000000
--- a/org.glite.lb.harvester/project/debian.glite-lb-harvester.install
+++ /dev/null
@@ -1,6 +0,0 @@
-etc/glite-lb/*
-etc/init.d/glite-lb-harvester
-usr/bin/*
-usr/lib/glite-lb/examples/*
-usr/share/doc/glite-lb-harvester/*
-usr/share/man/man1/*
diff --git a/org.glite.lb.harvester/project/debian.preinst b/org.glite.lb.harvester/project/debian.preinst
deleted file mode 100644
index b794d76..0000000
--- a/org.glite.lb.harvester/project/debian.preinst
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-set -e
-
-getent group glite >/dev/null || groupadd -r glite
-getent passwd glite >/dev/null || useradd -r -g glite -d /var/glite -c "gLite user" glite
-mkdir -p /var/glite /var/log/glite 2>/dev/null || :
-chown glite:glite /var/glite /var/log/glite
-
-#DEBHELPER#
diff --git a/org.glite.lb.harvester/project/debian.rules b/org.glite.lb.harvester/project/debian.rules
deleted file mode 100644
index 4d69100..0000000
--- a/org.glite.lb.harvester/project/debian.rules
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile -*-
-
--include /usr/share/dpkg/buildflags.mk
-
-# Uncomment this to turn on verbose mode.
-export DH_VERBOSE=1
-
-configure: configure-stamp
-configure-stamp:
-	dh_testdir
-	/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=lib --project=emi --module lb.harvester
-	touch $@
-
-build: build-arch build-indep
-
-build-arch build-indep: build-stamp
-
-build-stamp: configure-stamp
-	dh_testdir
-	CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE)
-	CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) check
-	touch $@
-
-clean: configure-stamp
-	dh_testdir
-	dh_testroot
-	rm -f configure-stamp build-stamp
-	$(MAKE) clean
-	rm -f Makefile.inc config.status
-	dh_clean
-
-install: build-stamp
-	dh_testdir
-	dh_testroot
-	dh_prep
-	dh_installdirs
-	$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
-	mv $(CURDIR)/debian/tmp/usr/share/doc/glite-lb-harvester-@MAJOR@.@MINOR@.@REVISION@ $(CURDIR)/debian/tmp/usr/share/doc/glite-lb-harvester
-	(cd $(CURDIR)/debian/tmp/usr/share/doc/glite-lb-harvester; \
-	 rm -fv ChangeLog LICENSE; \
-	 cat $(CURDIR)/project/ChangeLog | gzip -9 > changelog.gz)
-
-binary-indep:
-
-binary-arch: install
-	dh_testdir
-	dh_testroot
-	dh_installchangelogs
-	dh_installdocs
-	dh_installexamples
-	dh_installman
-	dh_installlogrotate
-	dh_installinit --onlyscripts --no-start
-	dh_installcron
-	dh_install --fail-missing
-	dh_link
-	dh_strip --dbg-package=glite-lb-harvester-dbg
-	dh_compress
-	dh_fixperms
-	dh_makeshlibs
-	dh_installdeb
-	dh_shlibdeps
-	dh_gencontrol
-	dh_md5sums
-	dh_builddeb
-
-binary: binary-arch binary-indep
diff --git a/org.glite.lb.harvester/project/glite-lb-harvester.spec b/org.glite.lb.harvester/project/glite-lb-harvester.spec
deleted file mode 100644
index 73bab36..0000000
--- a/org.glite.lb.harvester/project/glite-lb-harvester.spec
+++ /dev/null
@@ -1,101 +0,0 @@
-Summary: @SUMMARY@
-Name: glite-lb-harvester
-Version: @MAJOR@.@MINOR@.@REVISION@
-Release: @AGE@%{?dist}
-Url: @URL@
-License: ASL 2.0
-Vendor: EMI
-Group: System Environment/Daemons
-BuildRequires: chrpath
-BuildRequires: docbook-utils
-BuildRequires: glite-jobid-api-c-devel
-BuildRequires: glite-lb-client-devel
-BuildRequires: glite-lb-common-devel
-BuildRequires: glite-lbjp-common-gss-devel
-BuildRequires: glite-lbjp-common-db-devel
-BuildRequires: glite-lbjp-common-log-devel
-BuildRequires: glite-lbjp-common-trio-devel
-BuildRequires: libtool
-Requires(post): chkconfig
-Requires(preun): chkconfig
-Requires(preun): initscripts
-BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
-AutoReqProv: yes
-Source: http://eticssoft.web.cern.ch/eticssoft/repository/emi/emi.lb.harvester/%{version}/src/%{name}-@VERSION@.src.tar.gz
-
-
-%description
-@DESCRIPTION@
-
-
-%prep
-%setup -q
-
-
-%build
-/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=%{_lib} --project=emi --module lb.harvester
-make
-
-
-%check
-make check
-
-
-%install
-rm -rf $RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT
-make install DESTDIR=$RPM_BUILD_ROOT
-sed -i 's,\(lockfile=/var/lock\),\1/subsys,' $RPM_BUILD_ROOT/etc/init.d/glite-lb-harvester
-find $RPM_BUILD_ROOT -name '*' -print | xargs -I {} -i bash -c "chrpath -d {} > /dev/null 2>&1" || echo 'Stripped RPATH'
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-
-%pre
-getent group glite >/dev/null || groupadd -r glite
-getent passwd glite >/dev/null || useradd -r -g glite -d /var/glite -c "gLite user" glite
-mkdir -p /var/glite /var/log/glite 2>/dev/null || :
-chown glite:glite /var/glite /var/log/glite
-exit 0
-
-
-%post
-/sbin/chkconfig --add glite-lb-harvester
-if [ $1 -eq 1 ] ; then
-	/sbin/chkconfig glite-lb-harvester off
-fi
-
-
-%preun
-if [ $1 -eq 0 ] ; then
-    /sbin/service glite-lb-harvester stop >/dev/null 2>&1
-    /sbin/chkconfig --del glite-lb-harvester
-fi
-
-
-%postun
-if [ "$1" -ge "1" ] ; then
-    /sbin/service glite-lb-harvester condrestart >/dev/null 2>&1 || :
-fi
-
-
-%files
-%defattr(-,root,root)
-%dir /etc/glite-lb/
-%dir /usr/%{_lib}/glite-lb/
-%dir /usr/%{_lib}/glite-lb/examples/
-%dir /usr/share/doc/%{name}-%{version}/
-/etc/glite-lb/harvester-test-dbsetup.sql
-/etc/init.d/glite-lb-harvester
-/usr/bin/glite-lb-harvester
-/usr/%{_lib}/glite-lb/examples/glite-lb-harvester-test.sh
-/usr/%{_lib}/glite-lb/examples/glite-lb-harvester-dbg
-/usr/share/doc/%{name}-%{version}/README
-/usr/share/man/man1/glite-lb-harvester.1.gz
-
-
-%changelog
-* @SPEC_DATE@ @MAINTAINER@ - @MAJOR@.@MINOR@.@REVISION@-@AGE@%{?dist}
-- automatically generated package
diff --git a/org.glite.lb.harvester/project/package.description b/org.glite.lb.harvester/project/package.description
deleted file mode 100644
index c35cd6c..0000000
--- a/org.glite.lb.harvester/project/package.description
+++ /dev/null
@@ -1 +0,0 @@
-L&B Harvester gathers job info from L&B servers using efficient L&B notifications. It manages notifications and keeps track of them for reuse on next launch. It takes care of refreshing notifications and querying L&B back once a notification expires.
diff --git a/org.glite.lb.harvester/project/package.summary b/org.glite.lb.harvester/project/package.summary
deleted file mode 100644
index 573de13..0000000
--- a/org.glite.lb.harvester/project/package.summary
+++ /dev/null
@@ -1 +0,0 @@
-Enhanced L&B notification client
diff --git a/org.glite.lb.harvester/project/version.properties b/org.glite.lb.harvester/project/version.properties
deleted file mode 100644
index b54634d..0000000
--- a/org.glite.lb.harvester/project/version.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-module.version=1.2.3
-module.age=2
diff --git a/org.glite.lb.harvester/src/harvester.c b/org.glite.lb.harvester/src/harvester.c
deleted file mode 100644
index 1ea3ea2..0000000
--- a/org.glite.lb.harvester/src/harvester.c
+++ /dev/null
@@ -1,2819 +0,0 @@
-#ident "$Header$"
-/*
-Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-See http://www.eu-egee.org/partners for details on the copyright holders.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-
-/*
- * Real time monitor.
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#if defined(WITH_OLD_LB) || !defined(USE_LOG4C)
-#include 
-#endif
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#ifdef WITH_LBU_DB
-#include 
-#include 
-#endif
-#include 
-#ifndef WITH_OLD_LB
-#include 
-#include 
-#endif
-#include 
-#include 
-
-
-// default number of the threads/sockets
-#define RTM_THREADS 5
-// requested notification life in seconds
-#define RTM_NOTIF_TTL 86400
-// consider end of the notification life sooner
-#define RTM_NOTIF_TTL_TO_DEAD 2
-// poll timeout in seconds
-#define RTM_NOTIF_READ_TIMEOUT 5
-// recheck LB server after error in seconds
-#define RTM_ERROR_REPEAT_RATE 120
-// initial read loop time (can be infinity)
-#define RTM_NOTIF_LOOP_MAX_TIME 1800
-// idle "quit" poll
-#define RTM_IDLE_POLL_TIME 0.5
-// purge & summary jobs poll time
-#define RTM_SUMMARY_POLL_TIME 600
-// preventive suicide against memleaks and ugly things (12 h)
-#define RTM_SUICIDE_TIME 43200
-
-#define RTM_SUMMARY_JOBS 100
-
-#define CON_QUEUE 10
-
-#define RTM_DB_TABLE_JOBS "jobs"
-#define RTM_DB_TABLE_LBS "lb20"
-#define DBPAR(N) ("$" (N))
-#define DBAMP "\""
-
-// debug message level: insane, debug, progress, warning, error
-#define INS 4
-#define DBG 3
-#define INF 2
-#define WRN 1
-#define ERR 0
-#define DEBUG_LEVEL_MASK 7
-#define DEBUG_GUARD_MASK 8
-
-// internal quit codes
-#define RTM_QUIT_RUN 0
-#define RTM_QUIT_CLEANUP 1
-#define RTM_QUIT_PRESERVE 2
-#define RTM_QUIT_RELOAD 3
-
-// exit codes
-#define RTM_EXIT_OK 0
-#define RTM_EXIT_RELOAD 1
-#define RTM_EXIT_ERROR 2
-
-#define RTM_NOTIF_TYPE_STATUS 1
-#define RTM_NOTIF_TYPE_JDL 2
-#define RTM_NOTIF_TYPE_OLD 3
-#define RTM_NOTIF_TYPE_DONE 4
-
-#ifdef RTM_NO_COLORS
-#define RTM_TTY_RED ""
-#define RTM_TTY_GREEN ""
-#define RTM_TTY_RST ""
-#else
-#define RTM_TTY_RED "\e[1;31m"
-#define RTM_TTY_GREEN "\e[1;32m"
-#define RTM_TTY_RST "\e[0;39m"
-#endif
-
-#ifndef LINE_MAX
-#define LINE_MAX 1023
-#endif
-
-#define RTM_FILE_NOTIFS "/var/tmp/notifs.txt"
-#define RTM_FILE_NOTIF_PRINTF "%s\t%s\t%s\t%s\t%s\t%d\n"
-#define RTM_FILE_NOTIF_SCANF "%511[^\t]\t%511[^\t]\t%511[^\t]\t%511[^\t]\t%511[^\t]\t%511[^\t\r\n]\n"
-#define RTM_FILE_NOTIF_NUM 6
-
-#define WLCG_FILENAME_TEMPLATE "/tmp/wlcg_%02d_XXXXXX"
-#define WLCG_COMMAND_MESSAGE "/opt/lcg/bin/msg-publish -c /opt/lcg/etc/msg-publish.conf org.wlcg.usage.jobStatus %s"
-#define WLCG_BINARY "/usr/bin/msg-publish"
-#define WLCG_CONFIG "/etc/msg-publish/msg-publish.conf"
-#define WLCG_TOPIC "org.wlcg.usage.jobStatus"
-
-
-#ifdef WITH_OLD_LB
-#define glite_jobid_t edg_wlc_JobId
-#define glite_jobid_create edg_wlc_JobIdCreate
-#define glite_jobid_recreate edg_wlc_JobIdRecreate
-#define glite_jobid_dup edg_wlc_JobIdDup
-#define glite_jobid_free edg_wlc_JobIdFree
-#define glite_jobid_parse edg_wlc_JobIdParse
-#define glite_jobid_unparse edg_wlc_JobIdUnparse
-#define glite_jobid_getServer edg_wlc_JobIdGetServer
-#define glite_jobid_getServerParts edg_wlc_JobIdGetServerParts
-#define glite_jobid_getUnique edg_wlc_JobIdGetUnique
-#define edg_wll_NotifNew(CTX, CONDS, FLAGS, SOCK, LADDR, ID, VALID) edg_wll_NotifNew((CTX), (CONDS), (SOCK), (LADDR), (ID), (VALID))
-#define edg_wll_JDLField(STAT, NAME) NULL
-#ifndef GLITE_JOBID_DEFAULT_PORT
-#define GLITE_JOBID_DEFAULT_PORT GLITE_WMSC_JOBID_DEFAULT_PORT
-#endif
-#endif
-
-typedef struct {
-	edg_wll_NotifId id;  // notification context (after bootstrap/rebind)
-	char *id_str;        // notification id string
-	int type;            // for distinguish various notifications on one LB
-	char *server;        // LB server hostname
-	unsigned int port;   // LB server port
-	time_t valid;        // maximal validity of the notification
-	time_t refresh;      // when try to refresh (before expiration),
-	                     // used for retry time after error too
-	double last_update;  // last change from the server
-	int active;          // helper (compare LB servers and notifications,
-	                     // if to save to the persistent storage)
-	int error;           // errors counter
-} notif_t;
-
-typedef struct {
-	int id;
-	pthread_t thread;
-	notif_t *notifs;
-	int nservers;
-	time_t next_refresh;
-	char time_s[100];
-	char *dash_filename;
-	int dash_fd;
-#ifdef WITH_LBU_DB
-	glite_lbu_DBContext dbctx;
-	glite_lbu_Statement insertcmd, updatecmd, updatecmd_vo, updatecmd_rb, updatecmd_mon, deletecmd;
-	int dbcaps;
-#endif
-} thread_t;
-
-typedef struct {
-	char *local_address;
-	int nthreads;
-	char *config_file;
-	char *notif_file;
-	int debug;
-	int guard;
-	int daemonize;
-	char *pidfile;
-	int dive;
-	char *dbcs;  // DB connection string
-	char *cert, *key;
-	int ttl;     // requested time to live (validity) of the notifications
-	int cleanup;        // if to clean up notifications on LB servers
-	int wlcg;           // dashboard messaging
-	int wlcg_no_remove; // don't remove temporary files (for debugging)
-	char *wlcg_binary;  // path msg-publish binary
-	char *wlcg_config;  // msg config file
-	char *wlcg_topic;   // msg topic
-	int wlcg_flush;     // send message for eachnotification
-	int silly;          // old LB 1.9 mode
-	int no_purge;       // disabled reaction on purge state
-
-	int nservers;
-	notif_t *notifs;
-} config_t;
-
-typedef struct {
-	notif_t *notifs;
-	int n, maxn;
-	pthread_mutex_t lock;
-	double last_check;
-	int was_summary; // flag for debugging
-#ifdef WITH_LBU_DB
-	glite_lbu_DBContext dbctx;
-#endif
-} db_t;
-
-
-static const char rcsid[] = "@(#)$Id$";
-
-#if defined(WITH_OLD_LB) || !defined(USE_LOG4C)
-static int rtm2syslog[] = {
-	LOG_ERR,
-	LOG_WARNING,
-	LOG_INFO,
-	LOG_DEBUG,
-	LOG_DEBUG,
-};
-#else
-static int rtm2log4c[] = {
-	LOG_PRIORITY_ERROR, // errors
-	LOG_PRIORITY_WARN,  // warnings
-	LOG_PRIORITY_INFO,  // progress
-	LOG_PRIORITY_DEBUG, // debugging
-	LOG_PRIORITY_NOTSET // insane logging
-};
-#endif
-
-static const struct option opts[] = {
-	{ "wlcg-binary", required_argument, 	NULL,   0},
-	{ "wlcg-config", required_argument, 	NULL,   0},
-	{ "wlcg-topic", required_argument, 	NULL,   0},
-	{ "wlcg-flush", no_argument,	 	NULL,   0},
-	{ "help", 	no_argument, 		NULL,	'h'},
-	{ "version",	no_argument,		NULL,	'v'},
-	{ "threads",	required_argument,	NULL,	's'},
-	{ "debug",	required_argument,	NULL,	'd'},
-	{ "daemonize",	no_argument,		NULL,	'D'},
-	{ "pidfile",	required_argument,	NULL,	'i'},
-	{ "ttl",	required_argument,	NULL,	't'},
-	{ "history",	required_argument,	NULL,	'H'},
-	{ "config",	required_argument,	NULL,	'c'},
-	{ "notifs",	required_argument,	NULL,	'n'},
-	{ "port",	required_argument,	NULL,	'p'},
-	{ "pg",		required_argument,	NULL,	'm'},
- 	{ "cert",	required_argument,	NULL,	'C'},
- 	{ "key",	required_argument,	NULL,	'K'},
-	{ "wlcg",	no_argument,		NULL,	'w'},
-	{ "old",	no_argument,		NULL,	'o'},
-	{ "cleanup",	no_argument,		NULL,	'l'},
-	{ "no-purge",	no_argument,		NULL,	'u'},
-	{ NULL, 	no_argument, 		NULL, 	0}
-};
-
-static const char *opts_line = "hvs:d:Di:t:H:c:n:p:m:C:K:wolu";
-
-config_t config = {
-	local_address: NULL,
-	nthreads: RTM_THREADS,
-	config_file: NULL,
-	notif_file: NULL,
-	debug: DBG,
-	guard: 1,
-	dive: 10800,
-	dbcs: NULL,
-	cert: NULL,
-	key: NULL,
-	ttl: RTM_NOTIF_TTL,
-	cleanup: 0,
-	wlcg: 0,
-	silly: 0,
-	no_purge: 0,
-
-	nservers: 0,
-	notifs: NULL,
-};
-db_t db = {
-	notifs: NULL,
-	n: 0,
-	maxn: 0,
-	lock: PTHREAD_MUTEX_INITIALIZER,
-#ifdef WITH_LBU_DB
-	dbctx: NULL
-#endif
-};
-thread_t *threads = NULL;
-volatile sig_atomic_t quit = RTM_QUIT_RUN;
-
-static int listen_port = 0;
-
-#define lprintf(T, LEVEL, FMT, ARGS...) \
-	if ((LEVEL) <= config.debug) lprintf_func((T), (LEVEL), (FMT), ##ARGS)
-#define lprintf_ctx(T, LEVEL, CTX, FMT, ARGS...) \
-	if ((LEVEL) <= config.debug) lprintf_ctx_func((T), (CTX), (LEVEL), (FMT), ##ARGS)
-#define lprintf_dbctx(T, LEVEL, FMT, ARGS...) \
-	if ((LEVEL) <= config.debug) lprintf_dbctx_func((T), (LEVEL), (FMT), ##ARGS)
-
-#ifdef WITH_OLD_LB
-int edg_wll_gss_initialize() {
-	if (globus_module_activate(GLOBUS_GSI_GSSAPI_MODULE) != GLOBUS_SUCCESS) return EINVAL;
-	return 0;
-}
-#endif
-
-void lvprintf_func(thread_t *t, const char *description, int level, const char *fmt, va_list ap) {
-	char prefix[10];
-	char *msg, *line;
-	
-	if (t) snprintf(prefix, sizeof prefix, "[%02d]", t->id);
-	else memcpy(prefix, "[main]", 8);
-	vasprintf(&msg, fmt, ap);
-	if (description) asprintf(&line, "%s %s, %s\n", prefix, msg, description);
-	else asprintf(&line, "%s %s\n", prefix, msg);
-	free(msg);
-
-	if (level <= WRN && !config.daemonize) fprintf(stderr, RTM_TTY_RED);
-	if (config.daemonize) {
-#if defined(WITH_OLD_LB) || !defined(USE_LOG4C)
-		openlog(NULL, LOG_PID | LOG_CONS, LOG_DAEMON);
-		syslog(rtm2syslog[level], "%s", line);
-		closelog();
-#else
-		glite_common_log(LOG_CATEGORY_LB_HARVESTER, rtm2log4c[level], line);
-#endif
-	} else {
-		fputs(line, stderr);
-	}
-	if (level <= WRN && !config.daemonize) fprintf(stderr, RTM_TTY_RST);
-
-	free(line);
-}
-
-
-void lprintf_func(thread_t *t, int level, const char *fmt, ...) {
-	va_list ap;
-
-	va_start(ap, fmt);
-	lvprintf_func(t, NULL, level, fmt, ap);
-	va_end(ap);
-}
-
-
-void lprintf_ctx_func(thread_t *t, edg_wll_Context ctx, int level, const char *fmt, ...) {
-	va_list ap;
-	char *errText, *errDesc, *s;
-
-	va_start(ap, fmt);
-	edg_wll_Error(ctx, &errText, &errDesc);
-	asprintf(&s, "%s: %s", errText, errDesc);
-	lvprintf_func(t, s, level, fmt, ap);
-	free(errText);
-	free(errDesc);
-	free(s);
-	va_end(ap);
-}
-
-
-#ifdef WITH_LBU_DB
-void lprintf_dbctx_func(thread_t *t, int level, const char *fmt, ...) {
-	va_list ap;
-	char *errText = NULL, *errDesc = NULL, *s = NULL;
-	glite_lbu_DBContext dbctx = t ? t->dbctx : db.dbctx;
-
-	va_start(ap, fmt);
-	if (dbctx) {
-		glite_lbu_DBError(dbctx, &errText, &errDesc);
-		asprintf(&s, "%s: %s", errText, errDesc);
-	}
-	lvprintf_func(t, s, level, fmt, ap);
-	free(errText);
-	free(errDesc);
-	free(s);
-	va_end(ap);
-}
-#endif
-
-#ifndef WITH_LBU_DB
-time_t glite_lbu_StrToTime(const char *str) {
-	struct tm       tm;
-
-	memset(&tm,0,sizeof(tm));
-	putenv("TZ=UTC"); tzset();
-	sscanf(str,"%4d-%02d-%02d %02d:%02d:%02d",
-	        &tm.tm_year,&tm.tm_mon,&tm.tm_mday,
-        	&tm.tm_hour,&tm.tm_min,&tm.tm_sec);
-	tm.tm_year -= 1900;
-	tm.tm_mon--;
-
-	return mktime(&tm);
-}
-
-double glite_lbu_StrToTimestamp(const char *str) {
-	struct tm	tm;
-	double	sec;
-
-	memset(&tm,0,sizeof(tm));
-	putenv("TZ=UTC"); tzset();
-	sscanf(str,"%4d-%02d-%02d %02d:%02d:%lf",
-		&tm.tm_year,&tm.tm_mon,&tm.tm_mday,
-		&tm.tm_hour,&tm.tm_min,&sec);
-	tm.tm_year -= 1900;
-	tm.tm_mon--;
-	tm.tm_sec = sec;
-
-	return (sec - tm.tm_sec) + mktime(&tm);
-}
-#endif
-
-
-// hacky time->string conversion
-char *time2str(thread_t *t, time_t time) {
-	struct tm tm;
-
-	if ((int)time <= 0) memcpy(t->time_s, "-", sizeof("-"));
-	else {
-		localtime_r(&time, &tm);
-		strftime(t->time_s, sizeof(t->time_s), "%F %T", &tm);
-	}
-	return t->time_s;
-}
-
-
-double rtm_gettimeofday() {
-	struct timeval tv;
-
-	gettimeofday(&tv, NULL);
-	return tv.tv_sec + tv.tv_usec / 1000000.0;
-}
-
-
-void rtm_time2str(time_t t, char **str) {
-	struct tm	*tm;
-
-	if (t) {
-		tm = gmtime(&t);
-		asprintf(str,"%4d-%02d-%02d %02d:%02d:%02d",tm->tm_year+1900,tm->tm_mon+1,
-			tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
-	} else
-		*str = strdup("-");
-}
-
-
-void rtm_timestamp2str(double t, char **str) {
-	time_t tsec = t;
-	struct tm *tm = gmtime(&tsec);
-
-	if (t) {
-		t = t - tsec + tm->tm_sec;
-		asprintf(str,"%4d-%02d-%02d %02d:%02d:%02.09f",tm->tm_year+1900,tm->tm_mon+1,
-	        	 tm->tm_mday,tm->tm_hour,tm->tm_min,t);
-	} else
-		*str = strdup("-");
-}
-
-
-int rtm_str2time(const char *s) {
-	time_t t;
-
-	if (s && memcmp(s, "-", 2) != 0) {
-		t = glite_lbu_StrToTime(s);
-		if (t == (time_t)-1) return 0;
-	} else
-		t = 0;
-
-	return t;
-}
-
-
-int rtm_str2timestamp(const char *s) {
-	double t;
-
-	if (s && memcmp(s, "-", 2) != 0) {
-		t = glite_lbu_StrToTimestamp(s);
-		if (t <= 0.5) return 0.0;
-	} else
-		t = 0.0;
-
-	return t;
-}
-
-
-int rtm_str2notiftype(const char *str) {
-	if (strcasecmp(str, "STATUS") == 0) return RTM_NOTIF_TYPE_STATUS;
-	if (strcasecmp(str, "DONE") == 0) return RTM_NOTIF_TYPE_DONE;
-	if (strcasecmp(str, "JDL") == 0) return RTM_NOTIF_TYPE_JDL;
-	if (strcasecmp(str, "OLD") == 0) return RTM_NOTIF_TYPE_OLD;
-	return -1;
-}
-
-
-const char *rtm_notiftype2str(int type) {
-	switch (type) {
-	case RTM_NOTIF_TYPE_STATUS: return "STATUS";
-	case RTM_NOTIF_TYPE_DONE: return "DONE";
-	case RTM_NOTIF_TYPE_JDL: return "JDL";
-	case RTM_NOTIF_TYPE_OLD: return "OLD";
-	default: return NULL;
-	}
-}
-
-
-/**
- * Cut the network server hostname from the full URL (got from RegJob event).
- *
- * Formats (only the first one should be in the wild):
- *	https://wms2.egee.cesnet.cz:7443/glite_wms_wmproxy_server
- *	wms2.egee.cesnet.cz
- *	147.228.1.129
- *	HTTPS://[2001:0f68:0000:0000:0000:0000:1986:69af]:80/
- *	2001:0f68::1986:69af
- */
-char* rtm_url_parse(const char *url, int only_hostname) {
-	char *ns, *pos;
-	size_t len;
-
-	if (strncasecmp(url, "https://", 8) == 0) {
-		ns = strdup(url + 8);
-		if (only_hostname) {
-			// first backslash - path
-			pos = strchr(ns, '/');
-			if (pos) pos[0] = '\0';
-			// last colon - port separator
-			pos = strrchr(ns, ':');
-			if (pos) pos[0] = '\0';
-			// brackets - IPv6 address
-			len = strlen(ns);
-			if (len >= 2 && ns[0] == '[' && ns[len - 1] == ']') {
-				pos = strndup(ns + 1, len - 2);
-				free(ns);
-				ns = pos;
-			}
-		}
-		return ns;
-	} else
-		return strdup(url);
-}
-
-
-char *rtm_url2hostname(const char *url) {
-	return rtm_url_parse(url, 1);
-}
-
-
-char *rtm_url2stripped(const char *url) {
-	return rtm_url_parse(url, 0);
-}
-
-
-void wlcg_timeval2str(struct timeval *t, char **str) {
-	struct tm	*tm;
-
-	tm = gmtime(&t->tv_sec);
-	asprintf(str,"%4d-%02d-%02dT%02d:%02d:%02dZ",tm->tm_year+1900,tm->tm_mon+1,
-		tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
-}
-
-
-int wlcg_store_message(thread_t *t, __attribute((unused))notif_t *notif, edg_wll_JobStat *stat) {
-	unsigned int port;
-	int status = 0;
-	char *jobid_str = NULL, *state_str = NULL, *vo = NULL, *lbhost = NULL, *network_host = NULL;
-	char *wlcg_last_update_time_str = NULL, *wlcg_state_start_time_str = NULL;
-
-	jobid_str = stat->jobId ? glite_jobid_unparse(stat->jobId) : strdup("Unknown");
-	glite_jobid_getServerParts(stat->jobId, &lbhost, &port);
-	state_str = edg_wll_StatToString(stat->state);
-	vo = edg_wll_JDLField(stat,"VirtualOrganisation") ? : strdup("Unknown");
-	network_host = stat->network_server ? rtm_url2hostname(stat->network_server) : NULL;
-
-	if (!t->dash_filename || !t->dash_fd) {
-		free(t->dash_filename);
-		asprintf(&t->dash_filename, WLCG_FILENAME_TEMPLATE, t->id);
-		if ((t->dash_fd = mkstemp(t->dash_filename)) == -1) {
-			status = errno;
-			lprintf(t, ERR, "can't create temporary file '%s': %s", t->dash_filename, strerror(status));
-			free(t->dash_filename);
-			t->dash_filename = NULL;
-			goto quit;
-		}
-	}
-
-	wlcg_timeval2str(&stat->lastUpdateTime, &wlcg_last_update_time_str);
-	wlcg_timeval2str(&stat->stateEnterTime, &wlcg_state_start_time_str);
-
-	dprintf(t->dash_fd, "jobId: %s\n\
-stateName: %s\n\
-ownerDN: %s\n\
-voname: %s\n\
-bkHost: %s:%d\n\
-networkHost: %s\n\
-lastUpdateTime: %s\n\
-stateStartTime: %s\n\
-exitCode: %d\n\
-DoneCode: %d\n\
-destSite: %s\n\
-condorId: %s\n\
-StatusReason: %s\n\
-EOT\n", jobid_str, state_str, stat->owner, vo, lbhost, port, network_host ? : "unknown", wlcg_last_update_time_str, wlcg_state_start_time_str, stat->exit_code, stat->done_code, stat->destination ? : "NULLByPublisher", stat->condorId ? : "0", stat->reason && stat->reason[strspn(stat->reason, " \t\n\r")] != '\0' ? stat->reason : "UNAVAILABLE By Publisher");
-
-	free(wlcg_last_update_time_str);
-	free(wlcg_state_start_time_str);
-quit:
-	free(jobid_str);
-	free(lbhost);
-	free(network_host);
-	free(state_str);
-	free(vo);
-	return status;
-}
-
-
-int wlcg_send_message(thread_t *t) {
-	int status = 0;
-	char *command;
-
-	// WLCG message
-	if (t->dash_fd) { // send only if anything to send
-		close(t->dash_fd);
-		asprintf(&command, "'%s' -c '%s' '%s' '%s'", config.wlcg_binary, config.wlcg_config, config.wlcg_topic, t->dash_filename);
-		lprintf(t, DBG, "calling %s", command);
-		switch (vfork()) {
-		case 0:
-			if (execlp("/bin/sh", "/bin/sh", "-c", command, NULL) == -1) {
-				lprintf(t, ERR, "can't exec '%s':%s", command, strerror(errno));
-			}
-			_exit(1);
-			break;
-		case -1:
-			lprintf(t, ERR, "can't fork: %s", strerror(errno));
-			break;
-		default:
-			break;
-		}
-		wait(&status);
-		free(command);
-		if (WIFEXITED(status)) {
-			status = WEXITSTATUS(status);
-			if (status) {
-				lprintf(t, WRN, "%s exited with %d", config.wlcg_binary, status);
-			} else {
-				lprintf(t, DBG, "%s exited successfully", config.wlcg_binary);
-				if (!config.wlcg_no_remove) remove(t->dash_filename);
-			}
-		} else {
-			lprintf(t, ERR, "%s not exited normally", config.wlcg_binary);
-			status = -1;
-		}
-		free(t->dash_filename);
-		t->dash_filename = NULL;
-		t->dash_fd = 0;
-	}
-
-	return status;
-}
-
-
-void notif_free(notif_t *notif) {
-	edg_wll_NotifIdFree(notif->id);
-	free(notif->id_str);
-	free(notif->server);
-	memset(notif, 0, sizeof(notif_t));
-}
-
-
-void notif_invalidate(notif_t *notif) {
-	edg_wll_NotifIdFree(notif->id);
-	free(notif->id_str);
-	notif->id = NULL;
-	notif->id_str = NULL;
-	notif->error = 0;
-}
-
-
-int notif_copy(notif_t *dest, notif_t *src) {
-	if (!src || !dest) return EINVAL;
-	memset(dest, 0, sizeof(notif_t));
-	if (src->id) dest->id = edg_wll_NotifIdDup(src->id);
-	if (src->id_str) dest->id_str = strdup(src->id_str);
-	dest->type = src->type;
-	if (src->server) dest->server = strdup(src->server);
-	dest->port = src->port;
-	dest->valid = src->valid;
-	dest->refresh = src->refresh;
-	dest->last_update = src->last_update;
-	dest->active = src->active;
-	dest->error = src->error;
-	return 0;
-}
-
-
-#ifdef WITH_LBU_DB
-static int db_init(thread_t *t, glite_lbu_DBContext *dbctx) {
-	int err, dbcaps;
-
-	if (config.dbcs) {
-		if ((err = glite_lbu_InitDBContext(dbctx, GLITE_LBU_DB_BACKEND_PSQL, LOG_CATEGORY_LB_HARVESTER_DB)) != 0) {
-			lprintf_dbctx(t, ERR, "can't initialize DB context");
-			return err;
-		}
-		while ((err = glite_lbu_DBConnect(*dbctx, config.dbcs)) != 0 && !quit) {
-			lprintf_dbctx(t, ERR, "can't connect to '%s'", config.dbcs);
-			lprintf(t, INF, "still trying...");
-			sleep(5);
-		}
-		if (err == 0) {
-			if ((dbcaps = glite_lbu_DBQueryCaps(*dbctx)) == -1) {
-				lprintf_dbctx(t, ERR, "can't get database capabilities");
-				dbcaps = 0;
-			}
-			lprintf(t, INF, "DB connected, cs: %s, capabilities: %d", config.dbcs, dbcaps);
-			if (t == NULL && (dbcaps & GLITE_LBU_DB_CAP_PREPARED) == 0) {
-				lprintf(NULL, WRN, "postgresql server doesn't support SQL prepared commands, recommended version >= 8.2");
-			}
-			if (t) t->dbcaps = dbcaps;
-			return 0;
-		} else {
-			glite_lbu_FreeDBContext(*dbctx);
-			return err;
-		}
-	} else {
-		lprintf(t, DBG, "no DB configured (--pg option)");
-		return -1;
-	}
-}
-
-
-static void db_free(__attribute((unused))thread_t *t, glite_lbu_DBContext dbctx) {
-	if (dbctx) {
-		glite_lbu_DBClose(dbctx);
-		glite_lbu_FreeDBContext(dbctx);
-	}
-}
-#endif
-
-
-static notif_t *db_add_notif(char *notifid, int type, time_t valid, time_t refresh, double last_update, char *server, int port, int active, int errors) {
-	void *tmp;
-	notif_t *notif;
-
-	if (db.n >= db.maxn) {
-		db.maxn = db.n + 20;
-		if ((tmp = realloc(db.notifs, db.maxn * sizeof(notif_t))) == NULL) return NULL;
-		db.notifs = (notif_t *)tmp;
-		memset(db.notifs + db.n, 0, (db.maxn - db.n) * sizeof(notif_t));
-	}
-	notif = db.notifs + db.n;
-	notif->id_str = notifid;
-	notif->type = type;
-	notif->valid = valid;
-	notif->refresh = refresh;
-	notif->last_update = last_update;
-	notif->server = server;
-	notif->port = port;
-	notif->active = active;
-	notif->error = errors;
-	db.n++;
-
-	return notif;
-}
-
-
-static int db_save_notifs_file(thread_t *t) {
-	FILE *f;
-	char *filename = NULL;
-	int retval = 1;
-	notif_t *notif;
-	int i, cnt;
-	char *valid_str = NULL, *refresh_str = NULL, *last_update_str = NULL, *id_str = NULL;
-
-	asprintf(&filename, "%s-new", config.notif_file);
-	if ((f = fopen(filename, "wt")) == NULL) {
-		lprintf(t, ERR, "can't write '%s': %s", filename, strerror(errno));
-		goto quit;
-	}
-
-	cnt = 0;
-	for (i = 0; i < db.n; i++) {
-		notif = db.notifs + i;
-		if (!notif->active) {
-			lprintf(t, DBG, "not saving inactive notif %s (%s), server %s:%d", notif->id_str, rtm_notiftype2str(notif->type), notif->server, notif->port);
-			continue;
-		}
-
-		if (notif->id_str) id_str = strdup(notif->id_str);
-		else if (notif->error) asprintf(&id_str, "%s:%d", notif->server, notif->port);
-		if (id_str) {
-			rtm_time2str(notif->valid, &valid_str);
-			rtm_time2str(notif->refresh, &refresh_str);
-			rtm_timestamp2str(notif->last_update, &last_update_str);
-
-			fprintf(f, RTM_FILE_NOTIF_PRINTF, id_str, rtm_notiftype2str(notif->type), valid_str, refresh_str, last_update_str, notif->error);
-			cnt++;
-
-			free(valid_str); valid_str = NULL;
-			free(refresh_str); refresh_str = NULL;
-			free(last_update_str); last_update_str = NULL;
-		}
-		free(id_str);
-		id_str = NULL;
-	}
-	fclose(f);
-	if (rename(filename, config.notif_file) != 0) {
-		lprintf(t, ERR, "can't move new notification file '%s' to '%s': %s", filename, config.notif_file, strerror(errno));
-		goto quit;
-	}
-	retval = 0;
-
-	if (!cnt) unlink(config.notif_file);
-
-quit:
-	free(filename);
-	free(valid_str);
-	free(refresh_str);
-	free(last_update_str);
-	return retval;
-}
-
-
-#if defined(WITH_RTM_SQL_STORAGE) && defined(WITH_LBU_DB)
-static int db_save_notifs_sql(thread_t *t) {
-	int retval = 1;
-	notif_t *notif;
-	int i;
-	char *sql = NULL, *valid_str = NULL, *refresh_str = NULL, *last_update_str = NULL;
-	const char *type_str, *amp;
-
-	for (i = 0; i < db.n; i++) {
-		notif = db.notifs + i;
-/*
-		if (!notif->active) {
-			lprintf(t, INS, "not saving inactive notif %s (%s:%d)", notif->id_str, notif->server, notif->port);
-			continue;
-		}
-*/
-		type_str = rtm_notiftype2str(notif->type);
-		if (notif->id_str || notif->error) {
-			if (notif->valid) glite_lbu_TimeToDB(db.dbctx, notif->valid, &valid_str);
-			else valid_str = strdup("NULL");
-			if (notif->refresh) glite_lbu_TimeToDB(db.dbctx, notif->refresh, &refresh_str);
-			else refresh_str = strdup("NULL");
-			if (notif->last_update) glite_lbu_TimestampToDB(db.dbctx, notif->last_update, &last_update_str);
-			else last_update_str = strdup("NULL");
-			amp = notif->id_str ? "'" : " ";
-			trio_asprintf(&sql, "UPDATE notifs SET notifid=%s%|Ss%s, valid=%s, refresh=%s, last_update=%s, errors=%d WHERE lb='%|Ss' AND port=%d AND notiftype='%|Ss'", amp, notif->id_str ? : "NULL", amp, valid_str, refresh_str, last_update_str, notif->error, notif->server, notif->port, type_str);
-			switch (glite_lbu_ExecSQL(db.dbctx, sql, NULL)) {
-			case 0:
-				// not found - insert
-				// can be handy when using file as input of LBs
-				free(sql);
-				trio_asprintf(&sql, "INSERT INTO notifs (lb, port, notifid, notiftype, valid, refresh, last_update, errors) VALUES ('%|Ss', %d, %s%|Ss%s, '%|Ss', %s, %s, %s, %d)", notif->server, notif->port, amp, notif->id_str ? : "NULL", amp, type_str, valid_str, refresh_str, last_update_str, notif->error);
-				switch (glite_lbu_ExecSQL(db.dbctx, sql, NULL)) {
-				case -1:
-					lprintf_dbctx(t, ERR, "notif '%s' (%s) insert failed", notif->id_str, type_str);
-					goto quit;
-				case 0:
-					lprintf(t, ERR, "notif '%s' (%s) not inserted for unknown reason", type_str);
-					break;
-				default:
-					lprintf(t, INS, "notif '%s' (%s) inserted", notif->id_str, type_str);
-					break;
-				}
-				break;
-			case -1:
-				lprintf_dbctx(t, ERR, "notif '%s' (%s) update failed", notif->id_str, type_str);
-				goto quit;
-			default:
-				lprintf(t, INS, "notif '%s' updated", notif->id_str);
-				break;
-			}
-		} else {
-			trio_asprintf(&sql, "UPDATE notifs SET notifid=NULL, valid=NULL, refresh=NULL, last_update=NULL WHERE lb='%|Ss' AND port=%d AND notiftype='%|Ss'", notif->server, notif->port, type_str);
-			switch (glite_lbu_ExecSQL(db.dbctx, sql, NULL)) {
-			case 0:
-				lprintf(t, INS, "cleared %s notif for %s:%d not found, ok", type_str, notif->server, notif->port);
-				break;
-			case -1:
-				lprintf_dbctx(t, ERR, "clearing notif %s for %s:%d failed", type_str, notif->server, notif->port);
-				goto quit;
-			default:
-				lprintf(t, INS, "cleared notif %s for %s:%d", type_str, notif->server, notif->port);
-				break;
-			}
-		}
-		free(sql); sql = NULL;
-		free(valid_str); valid_str = NULL;
-		free(refresh_str); refresh_str = NULL;
-		free(last_update_str); last_update_str = NULL;
-	}
-	retval = 0;
-quit:
-	free(sql);
-	free(valid_str);
-	free(refresh_str);
-	free(last_update_str);
-	return 0;
-}
-#endif
-
-
-static int db_save_notifs(thread_t *t) {
-#if 0
-	int i;
-
-	for (i = 0; i < db.n; i++) {
-		notif_t *notif = db.notifs + i;
-		lprintf(NULL, DBG, "save: %s (%s), server: %s:%d, active: %d", notif->id_str, rtm_notiftype2str(notif->type), notif->server, notif->port, notif->active);
-	}
-#endif
-
-#if defined(WITH_LBU_DB)
-	int i, ret;
-	notif_t *notif;
-
-	//
-	// Keep monitored flag when:
-	// 1) used and opened DB
-	// 2) LB servers not from config file
-	//
-	if (t && t->dbctx && !config.config_file) {
-		for (i = 0; i < t->nservers; i++) {
-			notif = t->notifs + i;
-
-			if (notif->type == RTM_NOTIF_TYPE_OLD || notif->type == RTM_NOTIF_TYPE_JDL) {
-				lprintf(t, DBG, "changing monitored flag of %d. notification for %s:%d to %d", i, notif->server, notif->port, notif->error ? 0 : 1);
-				if ((t->dbcaps & GLITE_LBU_DB_CAP_PREPARED) == 0) {
-					char *sql;
-
-					trio_asprintf(&sql, "UPDATE " DBAMP RTM_DB_TABLE_LBS DBAMP " SET monitored=%s WHERE ip='%|Ss'", notif->error ? "false" : "true", notif->server);
-					ret = glite_lbu_ExecSQL(t->dbctx, sql, NULL);
-					free(sql);
-				} else {
-					ret = glite_lbu_ExecPreparedStmt(t->updatecmd_mon, 2,
-						GLITE_LBU_DB_TYPE_BOOLEAN, notif->error ? 0 : 1,
-						GLITE_LBU_DB_TYPE_VARCHAR, notif->server
-					);
-				}
-				if (ret == -1) {
-					lprintf_dbctx(t, ERR, "can't update monitored flag in " RTM_DB_TABLE_LBS " table");
-					return 1;
-				}
-			}
-		}
-	}
-#endif
-
-#if defined(WITH_RTM_SQL_STORAGE) && defined(WITH_LBU_DB)
-	if (!db.dbctx) return db_save_notifs_file(t);
-	else return db_save_notifs_sql(t);
-#else
-	return db_save_notifs_file(t);
-#endif
-}
-
-
-static notif_t *db_search_notif(notif_t *notifs, int n, const char *notifid) {
-	int i;
-
-	for (i = 0; i < n && (!notifs[i].id_str || strcmp(notifs[i].id_str, notifid) != 0); i++);
-	return i == n ? NULL : notifs + i;
-}
-
-
-static notif_t *db_search_notif_by_server(notif_t *notifs, int n, const char *server, unsigned int port, int type) {
-	int i;
-
-	for (i = 0; i < n; i++) {
-		if (strcmp(notifs[i].server, server) == 0 && notifs[i].port == port && notifs[i].type == type) break;
-	}
-
-	return i == n ? NULL : notifs + i;
-}
-
-
-#ifdef WITH_LBU_DB
-typedef struct {
-	char *lb;
-	char *jobid;
-	char *unique_str;
-	char *ce;
-	char *queue;
-	char *rb;
-	char *ui;
-	char *state;
-	double state_entered;
-	double rtm_timestamp;
-	int registered;
-	char * vo;
-} db_job_t;
-
-
-//
-// store state into dababase
-// on purged status deletes the record
-//
-static void db_store_change_perform_sql(thread_t *t, edg_wll_JobStatCode state, db_job_t *rec) {
-	char *state_entered_str = NULL, *rtm_timestamp_str = NULL, *regtime_str = NULL;
-	char *sql = NULL, *sql2 = NULL, *sql_part = NULL, *tmp = NULL;
-	const char *active = "true", *state_changed = "true";
-
-	if (state == EDG_WLL_JOB_PURGED) {
-		if (!config.no_purge) {
-			lprintf(t, DBG, "purge %s", rec->jobid);
-			if ((t->dbcaps & GLITE_LBU_DB_CAP_PREPARED) == 0) {
-				trio_asprintf(&sql, "DELETE FROM " RTM_DB_TABLE_JOBS " WHERE jobid='%|Ss' AND lb='%|Ss'", rec->unique_str, rec->lb);
-				lprintf(t, INS, "delete: %s", sql);
-				if (glite_lbu_ExecSQL(t->dbctx, sql, NULL) == -1) {
-					lprintf_dbctx(t, WRN, "can't delete job %s", rec->jobid);
-					goto quit;
-				}
-			} else {
-				if (glite_lbu_ExecPreparedStmt(t->deletecmd, 2,
-					GLITE_LBU_DB_TYPE_VARCHAR, rec->unique_str,
-					GLITE_LBU_DB_TYPE_VARCHAR, rec->lb
-				) == -1) {
-					lprintf_dbctx(t, WRN, "can't delete job %s", rec->jobid);
-					goto quit;
-				}
-			}
-		}
-	} else {
-		if ((t->dbcaps & GLITE_LBU_DB_CAP_PREPARED) == 0) {
-			glite_lbu_TimestampToDB(t->dbctx, rec->state_entered, &state_entered_str);
-			glite_lbu_TimestampToDB(t->dbctx, rec->rtm_timestamp, &rtm_timestamp_str);
-			glite_lbu_TimeToDB(t->dbctx, rec->registered, ®time_str);
-
-			if (rec->vo) trio_asprintf(&sql_part, ", vo='%|Ss'", rec->vo);
-			if (rec->rb) {
-				trio_asprintf(&tmp, "%s, rb='%|Ss'", sql_part ? : "", rec->rb);
-				free(sql_part);
-				sql_part = tmp;
-				tmp = NULL;
-			}
-			trio_asprintf(&sql, "UPDATE " RTM_DB_TABLE_JOBS " SET ce='%|Ss', queue='%|Ss', ui='%|Ss', state='%|Ss', state_entered=%s, rtm_timestamp=%s, active=%s, state_changed=%s, registered=%s%s WHERE jobid='%|Ss' AND lb='%|Ss'", rec->ce, rec->queue, rec->ui, rec->state, state_entered_str, rtm_timestamp_str, active, state_changed, regtime_str, sql_part ? : "", rec->unique_str, rec->lb);
-			lprintf(t, INS, "update: %s", sql);
-			switch (glite_lbu_ExecSQL(t->dbctx, sql, NULL)) {
-			case -1:
-				lprintf_dbctx(t, ERR, "can't get jobs");
-				goto quit;
-			case 0:
-				trio_asprintf(&sql2, "INSERT INTO " RTM_DB_TABLE_JOBS " "
-					"(ce, queue, rb, ui, state, state_entered, rtm_timestamp, jobid, lb, active, state_changed, registered, vo) VALUES "
-					"('%|Ss', '%|Ss', '%|Ss', '%|Ss', '%|Ss', %s, %s, '%|Ss', '%|Ss', %s, %s, %s, '%|Ss')", rec->ce, rec->queue, rec->rb ? : "unknown", rec->ui, rec->state, state_entered_str, rtm_timestamp_str, rec->unique_str, rec->lb, active, state_changed, regtime_str, rec->vo ? : "unknown");
-				lprintf(t, INS, "insert: %s", sql2);
-				if (glite_lbu_ExecSQL(t->dbctx, sql2, NULL) == -1) {
-					lprintf_dbctx(t, ERR, "can't insert job");
-					goto quit;
-				}
-				break;
-			default:
-				break;
-			}
-		} else { // prepared commands
-			int ret;
-
-			ret = glite_lbu_ExecPreparedStmt(t->updatecmd, 11,
-				GLITE_LBU_DB_TYPE_VARCHAR, rec->ce,
-				GLITE_LBU_DB_TYPE_VARCHAR, rec->queue,
-				GLITE_LBU_DB_TYPE_VARCHAR, rec->ui,
-				GLITE_LBU_DB_TYPE_VARCHAR, rec->state,
-				GLITE_LBU_DB_TYPE_TIMESTAMP, rec->state_entered,
-				GLITE_LBU_DB_TYPE_TIMESTAMP, rec->rtm_timestamp,
-				GLITE_LBU_DB_TYPE_BOOLEAN, 1, // active
-				GLITE_LBU_DB_TYPE_BOOLEAN, 1, // state_changed
-				GLITE_LBU_DB_TYPE_TIMESTAMP, (double)rec->registered,
-
-				GLITE_LBU_DB_TYPE_VARCHAR, rec->unique_str, // jobid
-				GLITE_LBU_DB_TYPE_VARCHAR, rec->lb // L&B server
-			);
-
-			switch (ret) {
-			case -1:
-				lprintf_dbctx(t, ERR, "can't update " RTM_DB_TABLE_JOBS " table");
-				goto quit;
-			case 0:
-				if (glite_lbu_ExecPreparedStmt(t->insertcmd, 13,
-					GLITE_LBU_DB_TYPE_VARCHAR, rec->ce,
-					GLITE_LBU_DB_TYPE_VARCHAR, rec->queue,
-					GLITE_LBU_DB_TYPE_VARCHAR, rec->rb ? : "unknown",
-					GLITE_LBU_DB_TYPE_VARCHAR, rec->ui,
-					GLITE_LBU_DB_TYPE_VARCHAR, rec->state,
-					GLITE_LBU_DB_TYPE_TIMESTAMP, rec->state_entered,
-					GLITE_LBU_DB_TYPE_TIMESTAMP, rec->rtm_timestamp,
-					GLITE_LBU_DB_TYPE_VARCHAR, rec->unique_str, // jobid
-					GLITE_LBU_DB_TYPE_VARCHAR, rec->lb, // L&B server
-					GLITE_LBU_DB_TYPE_BOOLEAN, 1, // active
-					GLITE_LBU_DB_TYPE_BOOLEAN, 1, // state_changed
-					GLITE_LBU_DB_TYPE_TIMESTAMP, (double)rec->registered,
-					GLITE_LBU_DB_TYPE_VARCHAR, rec->vo ? : "unknown" // VO
-				) == -1) {
-					lprintf_dbctx(t, ERR, "can't insert to " RTM_DB_TABLE_JOBS " table");
-					goto quit;
-				}
-				break;
-			default:
-				if (rec->vo) {
-					if (glite_lbu_ExecPreparedStmt(t->updatecmd_vo, 3,
-						GLITE_LBU_DB_TYPE_VARCHAR, rec->vo, // VO
-
-						GLITE_LBU_DB_TYPE_VARCHAR, rec->unique_str, // jobid
-						GLITE_LBU_DB_TYPE_VARCHAR, rec->lb // L&B server
-					) == -1)
-						lprintf(t, ERR, "can't update VO in "  RTM_DB_TABLE_JOBS " table");
-				}
-				if (rec->rb) {
-					if (glite_lbu_ExecPreparedStmt(t->updatecmd_rb, 3,
-						GLITE_LBU_DB_TYPE_VARCHAR, rec->rb, // RB
-
-						GLITE_LBU_DB_TYPE_VARCHAR, rec->unique_str, // jobid
-						GLITE_LBU_DB_TYPE_VARCHAR, rec->lb // L&B server
-					) == -1)
-						lprintf(t, ERR, "can't update RB in "  RTM_DB_TABLE_JOBS " table");
-				}
-				break;
-			}
-		} // prepare commands
-	}
-
-quit:
-	free(sql);
-	free(sql2);
-	free(sql_part);
-	free(state_entered_str);
-	free(rtm_timestamp_str);
-	free(regtime_str);
-}
-#endif
-
-
-static int db_store_change(thread_t *t, notif_t *notif, __attribute((unused))int index, edg_wll_JobStat *stat) {
-	char *jobid_str = NULL, *state_str = NULL, *vo = NULL, *lbhost = NULL;
-	unsigned int port;
-
-	jobid_str = stat->jobId ? glite_jobid_unparse(stat->jobId) : strdup("unknown");
-	glite_jobid_getServerParts(stat->jobId, &lbhost, &port);
-	state_str = edg_wll_StatToString(stat->state);
-	vo = edg_wll_JDLField(stat, "VirtualOrganisation");
-	printf(RTM_TTY_GREEN "notifid: %s (%s), jobid: %s, state: %s, vo: %s, last time: %lf" RTM_TTY_RST "\n", notif->id_str, rtm_notiftype2str(notif->type), jobid_str, state_str, vo, notif->last_update);
-
-#ifdef WITH_LBU_DB
-	if (config.dbcs && t->dbctx) {
-		db_job_t rec;
-		char *colon;
-		char *unique_str = NULL, *resource_broker = NULL, *destination = NULL;
-
-		memset(&rec, 0, sizeof rec);
-		// L&B server
-		rec.lb = lbhost;
-		// jobid + uniqe
-		unique_str = glite_jobid_getUnique(stat->jobId);
-		rec.unique_str = unique_str;
-		rec.jobid = jobid_str;
-		// CE
-		destination = stat->destination ? rtm_url2stripped(stat->destination) : strdup("unknown");
-		rec.ce = destination;
-		// queue
-		rec.queue = strchr(rec.ce, '/');
-		if (rec.queue) *rec.queue++='\0';
-		else rec.queue = "unknown";
-		colon = strchr(rec.ce, ':');
-		if (colon) colon[0] = '\0';
-		// Virtual Organization
-		rec.vo = vo;
-		// Resource Broker (CREAM jobs from JDL, gLite jobs hostname from Network Server URL)
-		if (stat->jobtype == EDG_WLL_STAT_CREAM) {
-			resource_broker = edg_wll_JDLField(stat, "SubmitterService");
-		} else {
-			resource_broker = stat->network_server ? rtm_url2hostname(stat->network_server) : NULL;
-		}
-		rec.rb = resource_broker;
-		// UI
-		rec.ui = stat->ui_host ? : "unknown";
-		// state
-		rec.state = state_str ? : "unknown";
-		// state time
-		rec.state_entered = stat->stateEnterTime.tv_sec + stat->stateEnterTime.tv_usec / 1000000.0;
-		// notification time
-		rec.rtm_timestamp = rtm_gettimeofday();
-		// registration time
-		rec.registered = stat->stateEnterTimes[1 + EDG_WLL_JOB_SUBMITTED];
-
-		// store!
-		db_store_change_perform_sql(t, stat->state, &rec);
-
-		free(unique_str);
-		free(resource_broker);
-		free(destination);
-	}
-#endif
-
-	// store message
-	if (config.wlcg) {
-		if (wlcg_store_message(t, notif, stat) != 0) goto quit;
-		if (config.wlcg_flush) wlcg_send_message(t);
-	}
-
-quit:
-	free(jobid_str);
-	free(state_str);
-	free(lbhost);
-	free(vo);
-
-	return 0;
-}
-
-
-static int db_summary_getjobids(__attribute((unused))db_t *db, __attribute((unused))int maxn, __attribute((unused))char **jobids, int *n) {
-/*
-	switch (db->was_summary) {
-	case 0:
-		*n = 3;
-		jobids[0] = strdup("https://skurut68-2.cesnet.cz:9000/FJldtiAR2EHC12C3Zz8WjQ");
-		jobids[1] = strdup("https://skurut68-2.cesnet.cz:9000/AWTCWrUCr3uUh6cuRFaENQ");
-		jobids[2] = strdup("https://skurut68-1.cesnet.cz:9000/o73CG2wrNdEQ909mG0Ac1g");
-		break;
-	case 1:
-		*n = 1;
-		jobids[0] = strdup("https://skurut68-2.cesnet.cz:9000/-46Qa2ag4gLsA_Ki-3bSLw");
-
-		break;
-	default: *n = 0; break;
-	}
-	db->was_summary = (db->was_summary + 1) % 3;
-	return 0;
-*/
-	*n = 0;
-	return 0;
-}
-
-
-static int db_summary_setinfo(__attribute((unused))db_t *db, edg_wll_JobStat *stat) {
-	char *jobidstr;
-
-	jobidstr = stat->jobId ? glite_jobid_unparse(stat->jobId) : NULL;
-	printf(RTM_TTY_GREEN "summary: jobid='%s'" RTM_TTY_RST "\n", jobidstr);
-	free(jobidstr);
-	return 0;
-}
-
-
-int rtm_summary(edg_wll_Context ctx, db_t *db) {
-	char *jobids[RTM_SUMMARY_JOBS];
-	edg_wll_QueryRec lbquery[RTM_SUMMARY_JOBS + 1], *qr;
-	const edg_wll_QueryRec *lbqueryext[2];
-	edg_wll_JobStat *jobstates = NULL;
-	int err = 0, ijob = 0, njobs = 0, iquery = 0, k, server_changed = 0;
-	glite_jobid_t jid = NULL;
-	char *server = NULL, *new_server = NULL;
-	unsigned int port = 0, new_port = 0;
-
-	lprintf(NULL, INS, "Summary");
-
-	lbqueryext[0] = lbquery;
-	lbqueryext[1] = NULL;
-	memset(lbquery, 0, sizeof(lbquery));
-
-	do {
-		if (server) {
-
-		if ((iquery >= RTM_SUMMARY_JOBS || server_changed || !njobs) && iquery) {
-			if ((err = edg_wll_QueryJobsExt(ctx, lbqueryext, 0, NULL, &jobstates)) != 0) {
-				lprintf_ctx(NULL, ERR, ctx, "query to '%s:%u' failed: %s", server, port, strerror(err));
-				// report error jobids and skip the job (do nothing)
-				// TODO
-			}
-			for (k = 0; k < iquery; k++) glite_jobid_free((glite_jobid_t)lbquery[k].value.j);
-
-			if (err == 0) {
-				for (k = 0; jobstates[k].state != EDG_WLL_JOB_UNDEF; k++) {
-					if ((err = db_summary_setinfo(db, jobstates + k)) != 0) lprintf(NULL, ERR, "Can't store %d. summary info for %s:%u", k, server, port);
-					edg_wll_FreeStatus(jobstates + k);
-				}
-				free(jobstates);
-				lprintf(NULL, DBG, "query to '%s:%u' succeed", server, port);
-			}
-
-			iquery = 0;
-			memset(lbquery, 0, sizeof(lbquery));
-			if (!njobs) break; // not needed, just spare summary select
-
-			server_changed = 0;
-		} else {
-			lprintf(NULL, DBG, "summary pushed %d. %s\n", iquery, jobids[ijob]);
-			qr = lbquery + iquery;
-			iquery++;
-			qr->attr = EDG_WLL_QUERY_ATTR_JOBID;
-			qr->op = EDG_WLL_QUERY_OP_EQUAL;
-			glite_jobid_parse(jobids[ijob], (glite_jobid_t *)&qr->value.j);
-			free(jobids[ijob]); jobids[ijob] = NULL;
-			ijob++;
-		}
-
-		} // server
-
-		if (ijob >= njobs) {
-			ijob = 0;
-			memset(jobids, 0, sizeof(jobids));
-			njobs = 0;
-			if ((err = db_summary_getjobids(db, RTM_SUMMARY_JOBS, jobids, &njobs)) != 0) {
-				lprintf(NULL, ERR, "Can't get jobs for the summary");
-				return err;
-			}
-			lprintf(NULL, DBG, "summary for %d jobs", njobs);
-			if (!njobs) {
-				if (iquery) continue; // do the last query
-				else break;
-			}
-		}
-
-		if ((err = glite_jobid_parse(jobids[ijob], &jid)) != 0) {
-			lprintf(NULL, ERR, "Can't parse jobid '%s': %s", jobids[ijob], strerror(err));
-			// report error jobid and skip the job
-			// TODO
-			glite_jobid_free(jid); jid = NULL;
-			free(jobids[ijob]); jobids[ijob] = NULL;
-			ijob++;
-			continue;
-		}
-		free(new_server);
-		glite_jobid_getServerParts(jid, &new_server, &new_port);
-		glite_jobid_free(jid); jid = NULL;
-
-		// first or different LB server
-		if (new_server && (!server || strcmp(server, new_server) != 0 || port != new_port)) {
-			if (server) server_changed = 1;
-
-			free(server);
-			server = new_server;
-			port = new_port;
-
-			new_server = NULL;
-			new_port = 0;
-
-			edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER, server);
-			edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER_PORT, port);
-			lprintf(NULL, INF, "summary LB server '%s:%u'", server, port);
-		}
-	} while (njobs || iquery);
-
-	free(server);
-	free(new_server);
-
-	return err;
-}
-
-
-/*
- * Updates error counter and retry times on the notification.
- *
- * On errors it lineary increases delay. Minimum delay is
- * RTM_ERROR_REPEAT_RATE, maximum is half of the configured
- * bootstrap time.
- *
- * \param t		thread context
- * \param notif		updated notification
- * \param[IN] index	notification order (for debug printing)
- * \param is_error[IN]	error state (to reset or increment error counter)
- *
- */
-static int rtm_update_error_state(thread_t *t, notif_t *notif, int index, int is_error) {
-	int old_error, max_count;
-
-	old_error = notif->error;
-	if (is_error) {
-		if (!notif->error++ || !notif->refresh) notif->refresh = time(NULL);
-		max_count = config.dive / RTM_ERROR_REPEAT_RATE / 2;
-		if (max_count <= 0) max_count = 1;
-		notif->refresh += (notif->error <= max_count ? notif->error : max_count) * RTM_ERROR_REPEAT_RATE;
-		lprintf(t, DBG, "planned to retry at %s", time2str(t, notif->refresh));
-	} else {
-		notif->error = 0;
-	}
-	if (old_error != notif->error) {
-		lprintf(t, DBG, "error count of %d. server %s:%d changed from %d to %d", index, notif->server, notif->port, old_error, notif->error);
-	}
-
-	return 0;
-}
-
-
-/**
- * Updates notifications in persistent storage. Used to send WLCG messages too.
- *
- * \param t	thread context
- * \param[IN]	new_notif updating notification, NULL = no change in shared memory
- * \param[IN]	store     0=light (just shared memory), 1=save (flush, really store)
- * \retval 0 if OK
- */
-int rtm_update_notif(thread_t *t, notif_t *new_notif, int store) {
-	notif_t *notif;
-	int retval = 1;
-
-	pthread_mutex_lock(&db.lock);
-
-	if (new_notif) {	
-		if ((notif = db_search_notif_by_server(db.notifs, db.n, new_notif->server, new_notif->port, new_notif->type)) == NULL) {
-			if (db_add_notif(strdup(new_notif->id_str), new_notif->type, new_notif->valid, new_notif->refresh, new_notif->last_update, strdup(new_notif->server), new_notif->port, 1, 0) == NULL) {
-				lprintf(t, ERR, "can't realloc");
-				goto quit;
-			}
-		} else {
-			notif_free(notif);
-			notif_copy(notif, new_notif);
-		}
-	}
-
-	wlcg_send_message(t);
-
-	if (store) {
-		if (db_save_notifs(t) != 0) goto quit;
-	}
-	retval = 0;
-	
-quit:
-	pthread_mutex_unlock(&db.lock);
-	return retval;
-}
-
-
-int rtm_drop_notif(thread_t *t, char *notifid, int store) {
-	notif_t *notif;
-	int retval = 1;
-
-	pthread_mutex_lock(&db.lock);
-	if ((notif = db_search_notif(db.notifs, db.n, notifid)) != NULL) {
-		notif_invalidate(notif);
-		if (store)
-			if (db_save_notifs(t) != 0) goto quit;
-	}
-	retval = 0;
-quit:
-	pthread_mutex_unlock(&db.lock);
-	return retval;
-}
-
-
-int load_notifs_file() {
-	FILE *f;
-	char *results[RTM_FILE_NOTIF_NUM];
-	notif_t *new_notif;
-	int err;
-	char *notifidstr;
-	time_t valid, refresh;
-	double last_update;
-	edg_wll_NotifId id;
-	int type, i, errcnt, port;
-	int retval = 1;
-
-	if ((f = fopen(config.notif_file, "rt")) == NULL) {
-		if (errno != ENOENT) lprintf(NULL, WRN, "WARNING: can't open notification file '%s'", config.notif_file);
-		return 0;
-	}
-
-	results[0] = malloc(RTM_FILE_NOTIF_NUM * 512);
-	for (i = 1; i < RTM_FILE_NOTIF_NUM; i++) {
-		results[i] = results[0] + i * 512;
-	}
-	while ((err = fscanf(f, RTM_FILE_NOTIF_SCANF, results[0], results[1], results[2], results[3], results[4], results[5])) == RTM_FILE_NOTIF_NUM) {
-		notifidstr = results[0];
-		if ((type = rtm_str2notiftype(results[1])) == -1) {
-			lprintf(NULL, ERR, "unknown notification type '%s' in '%s'", results[1], notifidstr);
-			continue;
-		}
-
-		valid = rtm_str2time(results[2]);
-		refresh = rtm_str2time(results[3]);
-		last_update = rtm_str2timestamp(results[4]);
-
-		errcnt = 0;
-		if (results[5] && strcasecmp(results[5], "-") != 0) {
-			errcnt = atoi(results[5]);
-		}
-
-		if (errcnt) {
-			if (sscanf(notifidstr, "%511[^:]:%d", results[1], &port) != 2) {
-				lprintf(NULL, WRN, "can't parse server specification '%s'", notifidstr);
-				continue;
-			}
-			if ((new_notif = db_add_notif(NULL, type, valid, refresh, last_update, strdup(results[1]), port, 0, errcnt)) == NULL) {
-				lprintf(NULL, ERR, "can't alloc");
-				goto quit;
-			}
-		} else {
-			if (edg_wll_NotifIdParse(notifidstr, &id) != 0) {
-				lprintf(NULL, WRN, "can't parse notification ID '%s'", notifidstr);
-				continue;
-			}
-			if ((new_notif = db_add_notif(strdup(notifidstr), type, valid, refresh, last_update, NULL, 0, 0, errcnt)) == NULL) {
-				lprintf(NULL, ERR, "can't alloc");
-				goto quit;
-			}
-			edg_wll_NotifIdGetServerParts(id, &new_notif->server, &new_notif->port);
-			edg_wll_NotifIdFree(id);
-		}
-	}
-	if (err == EOF) retval = 0;
-	else lprintf(NULL, ERR, "can't parse notification file '%s'", config.notif_file);
-quit:
-	fclose(f);
-	free(results[0]);
-	return retval;
-}
-
-
-#if defined(WITH_RTM_SQL_STORAGE) && defined(WITH_LBU_DB)
-int load_notifs_sql() {
-	notif_t *new_notif;
-	int err;
-	char *notifidstr;
-	time_t valid, refresh;
-	double last_update;
-	edg_wll_NotifId id;
-	int type, i, errcnt;
-	int retval = 1;
-	glite_lbu_Statement stmt = NULL;
-	char *results[8];
-
-	if (glite_lbu_ExecSQL(db.dbctx, "SELECT notifid, notiftype, valid, refresh, last_update, errors, lb, port FROM notifs", &stmt) == -1) {
-		lprintf_dbctx(NULL, ERR, "fetching notification failed");
-		goto quit;
-	}
-	while ((err = glite_lbu_FetchRow(stmt, 8, NULL, results)) > 0) {
-		if (results[0] && results[0][0]) notifidstr = strdup(results[0]);
-		else notifidstr = NULL;
-		free(results[0]);
-		results[0] = NULL;
-
-		if ((type = rtm_str2notiftype(results[1])) == -1) {
-			lprintf(NULL, ERR, "unknown notification type '%s' in '%s'", results[1], notifidstr);
-			for (i = 0; i < 8; i++) free(results[i]);
-			free(notifidstr);
-			continue;
-		}
-		free(results[1]);
-
-		valid = 0;
-		if (results[2] && results[2][0]) {
-			valid = glite_lbu_DBToTime(db.dbctx, results[2]);
-		}
-		free(results[2]);
-
-		refresh = 0;
-		if (results[3] && results[3][0]) {
-			refresh = glite_lbu_DBToTime(db.dbctx, results[3]);
-		}
-		free(results[3]);
-
-		last_update = 0;
-		if (results[4] && results[4][0]) {
-			last_update = glite_lbu_DBToTimestamp(db.dbctx, results[4]);
-		}
-		free(results[4]);
-
-		errcnt = 0;
-		if (results[5] && results[5][0]) errcnt = atoi(results[5]);
-		free(results[5]);
-
-		if ((new_notif = db_add_notif(notifidstr, type, valid, refresh, last_update, (results[6] && !notifidstr) ? strdup(results[6]) : NULL, atoi(results[7]), 0, errcnt)) == NULL) {
-			free(notifidstr);
-			free(results[6]);
-			free(results[7]);
-			lprintf(NULL, ERR, "can't alloc");
-			goto quit;
-		}
-		free(results[6]);
-		free(results[7]);
-		if (notifidstr) {
-			if (edg_wll_NotifIdParse(notifidstr, &id) != 0) {
-				lprintf(NULL, WRN, "can't parse notification IDs '%s'", notifidstr);
-				notif_free(new_notif);
-				db.n--;
-				continue;
-			}
-			edg_wll_NotifIdGetServerParts(id, &new_notif->server, &new_notif->port);
-			edg_wll_NotifIdFree(id);
-		}
-	}
-	if (err == 0) retval = 0;
-	else lprintf_dbctx(NULL, ERR, "fetching failed");
-quit:
-	if (stmt) glite_lbu_FreeStmt(&stmt);
-	return retval;
-}
-#endif
-
-
-int load_notifs() {
-	int i, ret;
-
-	pthread_mutex_lock(&db.lock);
-
-#if defined(WITH_RTM_SQL_STORAGE) && defined(WITH_LBU_DB)
-	if (!db.dbctx) ret = load_notifs_file();
-	else ret = load_notifs_sql();
-#else
-	ret = load_notifs_file();
-#endif
-	// try to reconnect on bad notifications immediately
-	for (i = 0; i < db.n; i++)
-		if (db.notifs[i].error) db.notifs[i].refresh = 0;
-
-	pthread_mutex_unlock(&db.lock);
-
-	return ret;
-}
-
-
-void db_free_notifs() {
-	int i;
-
-	for (i = 0; i < db.n; i++) notif_free(db.notifs + i);
-	free(db.notifs);
-	db.notifs = NULL;
-	db.n = db.maxn = 0;
-}
-
-
-static int daemon_listen(thread_t *t, const char *name, char *port, int *conn_out) {
-	struct	addrinfo *ai;
-	struct	addrinfo hints;
-	char	pretty_addr[256];
-	int	conn;
-	int 	gaie;
-	const int	zero = 0;
-	const int	one = 1;
-
-	memset (&hints, '\0', sizeof (hints));
-	hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE | AI_ADDRCONFIG;
-	hints.ai_socktype = SOCK_STREAM;
-	hints.ai_family = AF_INET6;
-
-	gaie = getaddrinfo (name, port, &hints, &ai);
-	if (gaie != 0 || ai == NULL) {
-		hints.ai_family = 0;
-		gaie = getaddrinfo (NULL, port, &hints, &ai);
-	}
-
-	gaie = getaddrinfo (name, port, &hints, &ai);
-	if (gaie != 0) {
-		lprintf(t, ERR, "getaddrinfo: %s", gai_strerror (gaie));
-		return 1;
-	}
-	if (ai == NULL) {
-		lprintf(t, ERR, "getaddrinfo: no result");
-		return 1;
-	}
-
-	conn = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-	if ( conn < 0 ) {
-		lprintf(t, ERR, "socket(): %s", strerror(errno));
-		freeaddrinfo(ai);
-		return 1; 
-	}
-	lprintf(t, DBG, "socket created: %d", conn);
-	setsockopt(conn, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-	if (ai->ai_family == AF_INET6)
-		setsockopt(conn, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero));
-
-	if ( bind(conn, ai->ai_addr, ai->ai_addrlen) )
-	{
-		lprintf(t, ERR, "bind(%s): %s", port, strerror(errno));
-		close(conn);
-		freeaddrinfo(ai);
-		return 1;
-	}
-
-	if ( listen(conn, CON_QUEUE) ) {
-		lprintf(t, ERR, "listen(): %s", strerror(errno));
-		close(conn);
-		freeaddrinfo(ai);
-		return 1; 
-	}
-
-	freeaddrinfo(ai);
-
-	*conn_out = conn;
-	return 0;
-}
-
-
-void *notify_thread(void *thread_data) {
-	int i, j, err;
-	time_t now, bootstrap;
-	edg_wll_NotifId notifid;
-	struct timeval to;
-	edg_wll_JobStat jobstat, *jobstates;
-	notif_t *notif, *notif_jdl;
-	edg_wll_QueryRec *conditions[3] = { NULL, NULL, NULL }, condition[3], condition2[2];
-	int sock = -1, updated = 0, error = 0, received = 0;
-	thread_t *t = (thread_t *)thread_data;
-	edg_wll_Context ctx = NULL;
-	int flags = 0;
-	char *portstr;
-
-	lprintf(t, DBG, "thread started");
-
-	if (!t->nservers) goto exit;
-
-	// LB
-	if (edg_wll_InitContext(&ctx) != 0) {
-		lprintf(t, ERR, "can't init LB context: %s", strerror(errno));
-		goto exit;
-	}
-	if (config.cert) edg_wll_SetParam(ctx, EDG_WLL_PARAM_X509_CERT, config.cert);
-	if (config.key) edg_wll_SetParam(ctx, EDG_WLL_PARAM_X509_KEY, config.key);
-
-	// listen
-	asprintf(&portstr, "%d", listen_port ? (listen_port + t->id) : 0);
-	if (!portstr) {
-		lprintf(t, ERR, "can't convert port number: ENOMEM");
-		goto exit;
-	}
-	if (daemon_listen(t, NULL, portstr, &sock) != 0)
-		goto exit;
-
-#ifdef WITH_LBU_DB
-	if (db_init(t, &t->dbctx) == 0)
-		if ((t->dbcaps & GLITE_LBU_DB_CAP_PREPARED) != 0) {
-			if (glite_lbu_PrepareStmt(t->dbctx, "INSERT INTO " DBAMP RTM_DB_TABLE_JOBS DBAMP " "
-			    "(ce, queue, rb, ui, state, state_entered, rtm_timestamp, jobid, lb, active, state_changed, registered, vo)"
-			    " VALUES "
-			    "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)",
-			&t->insertcmd) != 0 || glite_lbu_PrepareStmt(t->dbctx, "UPDATE " DBAMP RTM_DB_TABLE_JOBS DBAMP " "
-			    "SET ce=$1, queue=$2, ui=$3, state=$4, state_entered=$5, rtm_timestamp=$6, active=$7, state_changed=$8, registered=$9 WHERE jobid=$10 AND lb=$11", 
-			&t->updatecmd) != 0 || glite_lbu_PrepareStmt(t->dbctx, "UPDATE " DBAMP RTM_DB_TABLE_JOBS DBAMP " "
-			    "SET vo=$1 WHERE jobid=$2 AND lb=$3", 
-			&t->updatecmd_vo) != 0 || glite_lbu_PrepareStmt(t->dbctx, "UPDATE " DBAMP RTM_DB_TABLE_JOBS DBAMP " "
-			    "SET rb=$1 WHERE jobid=$2 AND lb=$3",
-			&t->updatecmd_rb) != 0 || glite_lbu_PrepareStmt(t->dbctx, "UPDATE " DBAMP RTM_DB_TABLE_LBS DBAMP " "
-			    "SET monitored=$1 WHERE ip=$2",
-			&t->updatecmd_mon) != 0 || glite_lbu_PrepareStmt(t->dbctx, "DELETE FROM " DBAMP RTM_DB_TABLE_JOBS DBAMP " WHERE jobid=$1 AND lb=$2",
-			&t->deletecmd) != 0) {
-				lprintf_dbctx(t, ERR, "can't create prepare commands");
-				lprintf(t, DBG, "insertcmd=%p, updatecmd=%p, updatecmd_vo=%p, updatecmd_rb=%p, updatecmd_mon=%p, deletecmd=%p", t->insertcmd, t->updatecmd, t->updatecmd_vo, t->updatecmd_rb, t->updatecmd_mon, t->deletecmd);
-				quit = RTM_QUIT_PRESERVE;
-			}
-		}
-#endif
-
-	//
-	// notifications loop:
-	//   - refresh/create with bootstrap
-	//   - receive & store changes
-	//
-	while (!quit) {
-		now = time(NULL);
-		t->next_refresh = now + RTM_NOTIF_LOOP_MAX_TIME;
-		for (i = 0; i < t->nservers; i++) {
-			notif = t->notifs + i;
-			if (!notif->active) {
-				lprintf(t, INS, "inactive %d. notification '%s' (%s)", i, notif->id_str, rtm_notiftype2str(notif->type));
-				continue;
-			}
-			// skip invalid LBs if not planned yet
-			if (notif->error) {
-				if (notif->refresh > now) {
-					lprintf(t, INS, "not planned to retry previously failed %d. notification '%s' (%s), plan %s", i, notif->id_str, rtm_notiftype2str(notif->type), time2str(t, notif->refresh));
-					if (t->next_refresh > notif->refresh) t->next_refresh = notif->refresh;
-					continue;
-				}
-				lprintf(t, DBG, "retry previously failed %d. notification '%s' (%s)", i, notif->id_str, rtm_notiftype2str(notif->type));
-			}
-			edg_wll_SetParam(ctx, EDG_WLL_PARAM_NOTIF_SERVER, notif->server);
-			edg_wll_SetParam(ctx, EDG_WLL_PARAM_NOTIF_SERVER_PORT, notif->port);
-			now = time(NULL);
-			if (!notif->valid || notif->valid - RTM_NOTIF_TTL_TO_DEAD <= now || !notif->id_str) {
-			// new notification
-				lprintf(t, DBG, "host %s:%d, valid %s, notifstr '%s', notifid %p", notif->server, notif->port, time2str(t, notif->valid), notif->id_str, notif->id);
-
-				// crazy inter-notif interactions
-				switch (notif->type) {
-				case RTM_NOTIF_TYPE_STATUS:
-					// STATUS must wait for existing JDL notification
-					notif_jdl = db_search_notif_by_server(t->notifs, t->nservers, notif->server, notif->port, RTM_NOTIF_TYPE_JDL);
-					if (!notif_jdl || !notif_jdl->valid || notif_jdl->valid - RTM_NOTIF_TTL_TO_DEAD <= now || !notif_jdl->id_str) {
-						lprintf(t, DBG, "not created %d. notification for %s:%d (%s), waiting for %d. (JDL)", i, notif->server, notif->port, rtm_notiftype2str(notif->type), i + RTM_NOTIF_TYPE_JDL - RTM_NOTIF_TYPE_STATUS);
-						// next retry of STATUS stright before the JDL
-						if (notif_jdl) {
-							notif->refresh = notif_jdl->refresh;
-							if (t->next_refresh > notif->refresh) t->next_refresh = notif->refresh;
-						}
-						continue;
-					}
-					break;
-				default:
-					break;
-				}
-				bootstrap = notif->valid > RTM_NOTIF_TTL_TO_DEAD ? notif->valid - RTM_NOTIF_TTL_TO_DEAD : 0;
-				if (config.dive > 0 && now - bootstrap > config.dive) {
-					bootstrap = now - config.dive;
-					lprintf(t, INS, "dive from %s:%d cut to %s (max. dive %d)", notif->server, notif->port, time2str(t, bootstrap), config.dive);
-				}
-				// explicitly drop old (failed) notification, if any
-				if (notif->id_str) {
-					if (notif->id) {
-						if (edg_wll_NotifDrop(ctx, notif->id)) lprintf_ctx(t, WRN, ctx, "dropping %d. notification '%s' (%s) failed", i, notif->id_str, rtm_notiftype2str(notif->type));
-					}
-					// remove from the persistent storage now,
-					// invalidate && update 
-					rtm_drop_notif(t, notif->id_str, 1);
-					// free the notification in the current thread
-					notif_invalidate(notif);
-					now = time(NULL);
-				}
-				// create the new notification
-				notif->valid = now + config.ttl;
-
-				memset(conditions, 0, sizeof(conditions));
-				memset(condition, 0, sizeof(condition));
-				memset(condition2, 0, sizeof(condition2));
-				flags = 0;
-				switch(notif->type) {
-#ifndef WITH_OLD_LB
-				case RTM_NOTIF_TYPE_STATUS:
-					conditions[0] = condition;
-					condition[0].attr = EDG_WLL_QUERY_ATTR_STATUS;
-					condition[0].op = EDG_WLL_QUERY_OP_CHANGED;
-					break;
-				case RTM_NOTIF_TYPE_JDL:
-					conditions[0] = condition;
-					conditions[1] = condition2;
-					condition[0].attr = EDG_WLL_QUERY_ATTR_STATUS;
-					condition[0].op = EDG_WLL_QUERY_OP_EQUAL;
-					condition[0].value.i = EDG_WLL_JOB_WAITING;
-					condition[1].attr = EDG_WLL_QUERY_ATTR_STATUS;
-					condition[1].op = EDG_WLL_QUERY_OP_EQUAL;
-					condition[1].value.i = EDG_WLL_JOB_SUBMITTED;
-					condition2[0].attr = EDG_WLL_QUERY_ATTR_JDL_ATTR;
-					condition2[0].op = EDG_WLL_QUERY_OP_CHANGED;
-					flags = EDG_WLL_STAT_CLASSADS;
-					break;
-#endif
-				case RTM_NOTIF_TYPE_OLD:
-					flags = EDG_WLL_STAT_CLASSADS;
-					break;
-				case RTM_NOTIF_TYPE_DONE:
-					conditions[0] = condition;
-					condition[0].attr = EDG_WLL_QUERY_ATTR_STATUS;
-					condition[0].op = EDG_WLL_QUERY_OP_EQUAL;
-					condition[0].value.i = EDG_WLL_JOB_DONE;
-					flags = EDG_WLL_STAT_CHILDREN;
-					break;
-				default:
-					assert(notif->type != notif->type); // unknown type
-					break;
-				}
-				if (edg_wll_NotifNew(ctx, (edg_wll_QueryRec const * const *) conditions, flags, sock, config.local_address, ¬if->id, ¬if->valid)) {
-					memset(condition,0,sizeof condition);
-					lprintf_ctx(t, ERR, ctx, "can't create %d. notification for %s:%d (%s)", i, notif->server, notif->port, rtm_notiftype2str(notif->type));
-					notif->valid = 0;
-					notif->id = NULL;
-					rtm_update_error_state(t, notif, i, 1);
-					error = 1;
-					goto cont;
-				} 
-				notif->id_str = edg_wll_NotifIdUnparse(notif->id);
-				lprintf(t, INF, "created %d. notification '%s' (%s), valid: %s", i, notif->id_str, rtm_notiftype2str(notif->type), time2str(t, notif->valid));
-
-				// bootstrap
-				memset(condition, 0, sizeof(condition));
-				flags = 0;
-				switch (notif->type) {
-				case RTM_NOTIF_TYPE_STATUS:
-					condition[0].attr = EDG_WLL_QUERY_ATTR_LASTUPDATETIME;
-					condition[0].op = EDG_WLL_QUERY_OP_WITHIN;
-					condition[0].value.t.tv_sec = bootstrap;
-					condition[0].value2.t.tv_sec = now;
-					flags = EDG_WLL_STAT_CLASSADS;
-					break;
-				case RTM_NOTIF_TYPE_OLD:
-					break;
-				case RTM_NOTIF_TYPE_JDL:
-					break;
-				case RTM_NOTIF_TYPE_DONE:
-					break;
-				default:
-					assert(notif->type != notif->type); // unknown type
-					break;
-				}
-
-				if (condition[0].attr) {
-
-				lprintf(t, INF, "bootstrap %s:%d (%d), time %s..%d(now)", notif->server, notif->port, i, time2str(t, bootstrap), now);
-				edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER, notif->server);
-				edg_wll_SetParam(ctx, EDG_WLL_PARAM_QUERY_SERVER_PORT, notif->port);
-				jobstates = NULL;
-				if ((err = edg_wll_QueryJobs(ctx, condition, flags, NULL, &jobstates)) != 0 && err != ENOENT) {
-					lprintf_ctx(t, ERR, ctx, "can't bootstrap jobs on %s:%d, time %s..%d(now)", notif->server, notif->port, time2str(t, bootstrap), now);
-					//
-					// destroy the notification after failed bootstrap
-					//
-					// This error means there is something nasty on the remote LB server.
-					// It could lost some messages between recreating notification,
-					// so destroy this notification now.
-					//
-					if (edg_wll_NotifDrop(ctx, notif->id)) {
-						lprintf_ctx(t, WRN, ctx, "dropping %d. notification '%s' (%s) after failed bootstrap failed", i, notif->id_str, rtm_notiftype2str(notif->type));
-					} else {
-						lprintf(t, INF, "dropped %d. notification '%s' (%s) after failed bootstrap", i, notif->id_str, rtm_notiftype2str(notif->type));
-					}
-					// free the notification instance in the current thread
-					// (not propagated to the persistent storage yet)
-					edg_wll_NotifIdFree(notif->id);
-					notif->id = NULL;
-					free(notif->id_str);
-					notif->id_str = NULL;
-					notif->valid = 0;
-					rtm_update_error_state(t, notif, i, 1);
-					error = 1;
-					if (t->next_refresh > notif->refresh) t->next_refresh = notif->refresh;
-					goto cont;
-				} else {
-					for (j = 0; jobstates && jobstates[j].state != EDG_WLL_JOB_UNDEF; j++) {
-						notif->last_update = jobstates[j].lastUpdateTime.tv_sec + jobstates[j].lastUpdateTime.tv_usec / 1000000.0;
-						db_store_change(t, notif, i, jobstates + j);
-						edg_wll_FreeStatus(jobstates + j);
-					}
-					free(jobstates);
-					lprintf(t, INF, "bootstrap %s:%d (%d), found %d jobs", notif->server, notif->port, i, j);
-					rtm_update_error_state(t, notif, i, 0);
-					updated = 1;
-				}
-
-				} else {
-					rtm_update_error_state(t, notif, i, 0);
-					updated = 1;
-				}
-			} else if (!notif->id) {
-			// rebind existing still valid notification
-				if (edg_wll_NotifIdParse(notif->id_str, ¬if->id)) {
-					lprintf_ctx(t, WRN, ctx, "can't parse %d. notification '%s' (%s)", i, notif->id_str, rtm_notiftype2str(notif->type));
-					notif->valid = 0;
-					notif->id = NULL;
-					i--;
-					continue;
-				}
-				notif->valid = now + config.ttl;
-				if (edg_wll_NotifBind(ctx, notif->id, sock, config.local_address, ¬if->valid)) {
-					lprintf_ctx(t, WRN, ctx, "can't rebind %d. notification '%s' (%s)", i, notif->id_str, rtm_notiftype2str(notif->type));
-					notif->valid = 0;
-					edg_wll_NotifIdFree(notif->id);
-					notif->id = NULL;
-					i--;
-					continue;
-				}
-				lprintf(t, INF, "bound %d. notification '%s' (%s), valid: %s", i, notif->id_str, rtm_notiftype2str(notif->type), time2str(t, notif->valid));
-				rtm_update_error_state(t, notif, i, 0);
-				// no bootstrap here, reliable delivery will send changes
-				updated = 1;
-			} else if (!notif->refresh || notif->refresh <= now) {
-			// refresh notification
-				time_t valid;
-
-				valid = now + config.ttl;
-				if (edg_wll_NotifRefresh(ctx, notif->id, &valid)) {
-					lprintf_ctx(t, WRN, ctx, "can't refresh %d. notification '%s' (%s), will try up to %s...", i, notif->id_str, rtm_notiftype2str(notif->type), time2str(t, notif->valid - RTM_NOTIF_TTL_TO_DEAD));
-					// refresh failed, just move the refresh time...
-					updated = 1;
-				} else {
-					notif->valid = valid;
-					lprintf(t, INF, "refreshed %d. notification '%s' (%s), valid: %s", i, notif->id_str, rtm_notiftype2str(notif->type), time2str(t, notif->valid));
-					rtm_update_error_state(t, notif, i, 0);
-					updated = 1;
-				}
-			} else {
-				lprintf(t, INS, "no change in %d. notification '%s' (%s)", i, notif->id_str, rtm_notiftype2str(notif->type));
-			}
-
-cont:
-			if (updated || error) {
-				if (!error) {
-					assert(notif->valid);
-					notif->refresh = notif->valid ? (now + ((notif->valid - now) >> 1)) : 0;
-				
-				}
-				// create or refresh OK, bootstrap if needed OK, store the new notification
-				updated = 0;
-				error = 0;
-
-				// quicker refresh (or recreate) if needed
-				now = time(NULL);
-				if (notif->valid && now >= notif->refresh) {
-					lprintf(t, WRN, "operation not in time, refreshing/recreating the notification '%s' (%s) now", notif->id_str, rtm_notiftype2str(notif->type));
-					i--;
-					continue;
-				}
- 				rtm_update_notif(t, notif, 1);
-			}
-
-			// compute time of the next event from the new refresh on notification
-	 		if (t->next_refresh > notif->refresh) t->next_refresh = notif->refresh;
-		}
-
-		// receive
-		//
-		// cycle here locally around NotifReceive, we know about next
-		// refresh time
-		//
-		lprintf(t, DBG, "waiting for the notifications up to %s...", t->next_refresh ? time2str(t, t->next_refresh) : "0 (no wait)");
-		while (t->next_refresh > now && !quit) {
-			to.tv_sec = t->next_refresh - now;
-			if (to.tv_sec > RTM_NOTIF_READ_TIMEOUT) to.tv_sec = RTM_NOTIF_READ_TIMEOUT;
-			to.tv_usec = 0;
-			memset(&jobstat, 0, sizeof(jobstat));
-			notifid = NULL;
-			err = edg_wll_NotifReceive(ctx, sock, &to, &jobstat, ¬ifid);
-			lprintf(t, INS, "received, err=%d%s", err, err == ETIMEDOUT ? " (timeout)":"");
-			if (err != 0) {
-				if (err != ETIMEDOUT) {
-					lprintf_ctx(t, ERR, ctx, "can't receive notifications");
-					// don't cycle too quick...
-					sleep(1);
-				}
-				// lazily refresh persistent storage here, only after timeouts
-				if (received) {
-					lprintf(t, DBG, "storing notification times");
- 	 				rtm_update_notif(t, NULL, 1);
-					received = 0;
-				}
-			} else {
-				char *jobidstr, *notifidstr;
-				double last_update;
-
-				if (notifid) {
-					jobidstr = jobstat.jobId ? glite_jobid_unparse(jobstat.jobId) : NULL;
-					notifidstr = notifid ? edg_wll_NotifIdUnparse(notifid) : NULL;
-					for (i = 0; i < t->nservers && (!t->notifs[i].id_str || strcmp(notifidstr, t->notifs[i].id_str) != 0); i++);
-					if (i == t->nservers) {
-						lprintf(t, ERR, "received notify '%s' not found", notifidstr);
-					} else {
-						received = 1;
-						notif = t->notifs + i;
-						//
-						// last changed time from the arrived notification
-						//
-						last_update = jobstat.lastUpdateTime.tv_sec + jobstat.lastUpdateTime.tv_usec / 1000000.0;
-						if (last_update > notif->last_update) notif->last_update = last_update;
-						db_store_change(t, notif, i, &jobstat);
- 	 					rtm_update_notif(t, notif, 0);
-					}
-					free(jobidstr);
-					free(notifidstr);
-				}
-			}
-			if (jobstat.state != EDG_WLL_JOB_UNDEF) edg_wll_FreeStatus(&jobstat);
-			if (notifid) edg_wll_NotifIdFree(notifid);
-
-			now = time(NULL);
-		} // receive
-	} // main loop
-
-exit:	
-	if (sock != -1) close(sock);
-//	for (i = 0; conditions[i]; i++) free(conditions[i]);
-	if (t->nservers && quit != RTM_QUIT_PRESERVE && quit != RTM_QUIT_RELOAD) {
-		for (i = 0; i < t->nservers; i++) {
-			if (t->notifs[i].id) {
-				char *notifidstr;
-
-				notifidstr = edg_wll_NotifIdUnparse(t->notifs[i].id);
-				edg_wll_SetParam(ctx, EDG_WLL_PARAM_NOTIF_SERVER, t->notifs[i].server);
-				edg_wll_SetParam(ctx, EDG_WLL_PARAM_NOTIF_SERVER_PORT, t->notifs[i].port);
-				if (edg_wll_NotifDrop(ctx, t->notifs[i].id)) {
-					lprintf_ctx(t, WRN, ctx, "can't drop %s (%s)", notifidstr, rtm_notiftype2str(t->notifs[i].type));
-				} else {
-					lprintf(t, INF, "notification %s (%s) dropped", notifidstr, rtm_notiftype2str(t->notifs[i].type));
-				}
-				rtm_drop_notif(t, t->notifs[i].id_str, 0);
-				free(notifidstr);
-			}
-		}
-		rtm_update_notif(t, NULL, 1);
-	}
-#ifdef WITH_LBU_DB
-	if (t->insertcmd) glite_lbu_FreeStmt(&t->insertcmd);
-	if (t->updatecmd) glite_lbu_FreeStmt(&t->updatecmd);
-	if (t->updatecmd_vo) glite_lbu_FreeStmt(&t->updatecmd_vo);
-	if (t->updatecmd_rb) glite_lbu_FreeStmt(&t->updatecmd_rb);
-	if (t->updatecmd_mon) glite_lbu_FreeStmt(&t->updatecmd_mon);
-	if (t->deletecmd) glite_lbu_FreeStmt(&t->deletecmd);
-	db_free(t, t->dbctx);
-#endif
-	if (ctx) edg_wll_FreeContext(ctx);
-	lprintf(t, DBG, "thread ended");
-	pthread_exit(NULL);
-	return NULL;
-}
-
-
-int reconcile_threads() {
-	int iserver, ithread, inotif, gran, mod, nnotifs;
-	int i, j, oldn, type, typestart, typeend;
-	notif_t *a, *b;
-	edg_wll_Context ctx = NULL;
-	edg_wll_NotifId notifid;
-	thread_t *t;
-
-	if (!config.cleanup) {
-		if (config.silly) {
-			typestart = RTM_NOTIF_TYPE_OLD;
-			typeend = RTM_NOTIF_TYPE_OLD;
-			nnotifs = 1;
-		} else {
-			typestart = RTM_NOTIF_TYPE_STATUS;
-			typeend = RTM_NOTIF_TYPE_JDL;
-			nnotifs = 2;
-		}
-
-		oldn = db.n;
-
-		// distribute LB servers between threads
-		// (always use existing loaded notification when found)
-		threads = (thread_t *)calloc(config.nthreads, sizeof(thread_t));
-		gran = config.nservers / config.nthreads, mod = config.nservers % config.nthreads;
-		t = NULL;
-		ithread = 0;
-		inotif = 0;
-		for (iserver = 0; iserver < config.nservers; iserver++) {
-			// new thread
-			if (!t || inotif + nnotifs > t->nservers) {
-				assert(ithread < config.nthreads);   // proper number of threads
-				assert(!t || inotif == t->nservers); // start or exactly distributed
-				t = threads + ithread;
-				t->nservers = nnotifs * ((ithread < mod) ? gran + 1 : gran);
-				t->notifs = (notif_t *)calloc(t->nservers, sizeof(notif_t));
-				lprintf(NULL, DBG, "%d. thread: %d notifications", ithread, t->nservers);
-				ithread++;
-				inotif = 0;
-			}
-
-			// next configured server
-			a = config.notifs + iserver;
-			for (type = typestart; type <= typeend; type++) {
-				// find or create all notification types
-				b = db_search_notif_by_server(db.notifs, oldn, a->server, a->port, type);
-				if (!b) b = db_add_notif(NULL, type, 0, 0, 0, strdup(a->server), a->port, 1, 0);
-				else {
-					if (b->id_str) {
-						lprintf(NULL, INF, "found previous notification '%s' (%s)", b->id_str, rtm_notiftype2str(b->type));
-					} else {
-						lprintf(NULL, INF, "found previous server %s:%d (%s), %d errors", b->server, b->port, rtm_notiftype2str(b->type), b->error);
-					}
-					b->active = 1;
-				}
-				// and add each to the thread
-				notif_copy(t->notifs + inotif, b);
-				lprintf(NULL, INS, "thread[%d][%d] <- %s:%d (%s), id %s", ithread-1, inotif, b->server, b->port, rtm_notiftype2str(b->type), b->id_str);
-				inotif++;
-			}
-		}
-		j = 0;
-		for (i = 0; i < db.n; i++)
-			if (db.notifs[i].active) j++;
-		assert(j % nnotifs == 0); // each server all notifs
-	}
-
-	if (edg_wll_InitContext(&ctx) != 0) {
-		lprintf(NULL, ERR, "can't init LB context: %s", strerror(errno));
-		return 1;
-	}
-	if (config.cert) edg_wll_SetParam(ctx, EDG_WLL_PARAM_X509_CERT, config.cert);
-	if (config.key) edg_wll_SetParam(ctx, EDG_WLL_PARAM_X509_KEY, config.key);
-	for (j = 0; j < db.n; j++) {
-		if (!db.notifs[j].active) {
-			if (db.notifs[j].id_str) {
-				lprintf(NULL, INF, "dropping previous notification '%s' (%s)", db.notifs[j].id_str, rtm_notiftype2str(db.notifs[j].type));
-				if (edg_wll_NotifIdParse(db.notifs[j].id_str, ¬ifid)) {
-					lprintf(NULL, WRN, "can't parse notification ID '%s'", db.notifs[j].id_str);
-					continue;
-				}
-				edg_wll_SetParam(ctx, EDG_WLL_PARAM_NOTIF_SERVER, db.notifs[j].server);
-				edg_wll_SetParam(ctx, EDG_WLL_PARAM_NOTIF_SERVER_PORT, db.notifs[j].port);
-				if (edg_wll_NotifDrop(ctx, notifid) != 0) {
-					lprintf_ctx(NULL, WRN, ctx, "can't drop %s (%s)", db.notifs[j].id_str, rtm_notiftype2str(db.notifs[j].type));
-				}
-				edg_wll_NotifIdFree(notifid);
-				notif_invalidate(db.notifs + j);
-			}
-		}
-	}
-	edg_wll_FreeContext(ctx);
-
-	return db_save_notifs(NULL);
-}
-
-
-void usage(const char *prog) {
-	fprintf(stderr, "Usage: %s [options]\n"
-		"	-h, --help         display this help\n"
-		"	-v, --version      display version\n"
-		"	-d, --debug LEVEL  debug level (0=error,1=warn,2=info,3=debug,4=insane,\n"
-		"	                   +8=not fork)\n"
-		"	-D, --daemonize    daemonize\n"
-		"	-i, --pidfile      the file with process ID\n"
-		"	-s, --threads N    number of slave threads\n"
-		"	-t, --ttl TIME     time to live (validity) of the notifications\n"
-		"	                   in seconds (%d)\n"
-		"	-H, --history      historic dive in seconds (<=0 is unlimited)\n"
-		"	-c, --config       config file name (list of LB servers), precedence before " RTM_DB_TABLE_LBS " table\n"
-#ifdef WITH_LBU_DB
-		"	-m, --pg           db connection string (user/pwd@server:dbname) to " RTM_DB_TABLE_LBS " table\n"
-#endif
-		"	-n, --notifs       file for persistent information about active\n"
-		"	                   notifications\n"
-		"	-p, --port         listen only on this port (default: use any)\n"
-		"	-C, --cert         X509 certificate file\n"
-		"	-K, --key          X509 key file\n"
-		"	-o, --old          \"silly\" mode for old L&B 1.9 servers\n"
-		"	-l, --cleanup      clean up the notifications and exit\n"
-		"	-u, --no-purge     disable purging from RTM database\n"
-		"	-w, --wlcg         enable messaging for dashboard\n"
-		"	--wlcg-binary      full path to msg-publish binary\n"
-		"	--wlcg-topic       topic for msg-publish\n"
-		"	--wlcg-config      config file for msg-publish\n"
-		"	--wlcg-flush       send message on each notification\n"
-		, prog, RTM_NOTIF_TTL);
-	fprintf(stderr, "\n");
-	fprintf(stderr, "List of L&B servers: first it's read the config file if specified (-c option). When config file is not used and connection to database is specified, it's tried DB table " RTM_DB_TABLE_LBS ".\n");
-	fprintf(stderr, "\n");
-}
-
-
-int config_preload(int argn, char *argv[]) {
-	int opt, intval, index;
-	char *err, *s;
-
-	while ((opt = getopt_long(argn, argv, opts_line, opts, &index)) != EOF) {
-		switch (opt) {
-		case 'h':
-		case '?':
-			usage(argv[0]);
-			return 1;
-		case 'v':
-			fprintf(stderr, "%s: %s\n", argv[0], rcsid);
-			return 1;
-		case 'd':
-			intval = strtol(optarg, &err, 10);
-			if (err && err[0]) {
-				lprintf(NULL, ERR, "debug level number required");
-				return 2;
-			}
-			config.debug = (intval & DEBUG_LEVEL_MASK);
-			config.guard = !(intval & DEBUG_GUARD_MASK);
-			break;
-		case 'D':
-			config.daemonize = 1;
-			break;
-		case 'i':
-			config.pidfile = strdup(optarg);
-			break;
-		case 's':
-			intval = strtol(optarg, &err, 10);
-			if (err && err[0]) {
-				lprintf(NULL, ERR, "number of threads required");
-				return 2;
-			}
-			config.nthreads = intval;
-			break;
-		case 't':
-			intval = strtol(optarg, &err, 10);
-			if (err && err[0]) {
-				lprintf(NULL, ERR, "requested validity in seconds required");
-				return 2;
-			}
-			config.ttl = intval;
-			break;
-		case 'H':
-			intval = strtol(optarg, &err, 10);
-			if (err && err[0]) {
-				lprintf(NULL, ERR, "historic dive in seconds required");
-				return 2;
-			}
-			config.dive = intval;
-			break;
-		case 'c':
-			free(config.config_file);
-			config.config_file = strdup(optarg);
-			break;
-		case 'n':
-			free(config.notif_file);
-			config.notif_file = strdup(optarg);
-			break;
-		case 'p':
-			listen_port = atoi(optarg);
-			break;
-		case 'm':
-			free(config.dbcs);
-			config.dbcs = strdup(optarg);
-			break;
-		case 'C':
-			free(config.cert);
-			config.cert = strdup(optarg);
-			break;
-		case 'K':
-			free(config.key);
-			config.key = strdup(optarg);
-			break;
-		case 'l':
-			config.cleanup = 1;
-			break;
-		case 'w':
-			config.wlcg = 1;
-			break;
-		case 'o':
-			config.silly = 1;
-			break;
-		case 'u':
-			config.no_purge = 1;
-			break;
-		case 0:
-			switch(index) {
-			case 0:
-				config.wlcg_binary = strdup(optarg);
-				break;
-			case 1:
-				config.wlcg_config = strdup(optarg);
-				break;
-			case 2:
-				config.wlcg_topic = strdup(optarg);
-				break;
-			case 3:
-				config.wlcg_flush = 1;
-				break;
-			default:
-				lprintf(NULL, ERR, "crazy option, index %d", index);
-				break;
-			}
-			break;
-		}
-	}
-	if (!config.notif_file) config.notif_file = strdup(RTM_FILE_NOTIFS);
-	if (config.wlcg) {
-		if (!config.wlcg_binary) config.wlcg_binary = strdup(WLCG_BINARY);
-		if (!config.wlcg_config) config.wlcg_config = strdup(WLCG_CONFIG);
-		if (!config.wlcg_topic) config.wlcg_topic = strdup(WLCG_TOPIC);
-	}
-#ifdef WITH_OLD_LB
-	if (!config.silly) {
-		lprintf(NULL, WRN, "compiled with older LB library, switching on silly mode");
-		config.silly = 1;
-	}
-#endif
-
-	if ((s = getenv("GLITE_LB_HARVESTER_NO_REMOVE")) != NULL) {
-		if (s[0] != '0' && strcasecmp(s, "false") != 0) config.wlcg_no_remove = 1;
-	}
-
-	if (INF <= config.debug) {
-		lprintf(NULL, INF, "threads: %d", config.nthreads);
-		lprintf(NULL, INF, "notifs ttl: %d", config.ttl);
-		lprintf(NULL, INF, "historic dive: %d", config.dive);
-		if (config.dbcs) {
-			lprintf(NULL, INF, "database storage: '%s'", config.dbcs);
-		} else {
-			lprintf(NULL, INF, "file storage: '%s'", config.notif_file);
-		}
-		lprintf(NULL, INF, "WLCG messaging: %s%s", config.wlcg ? "enabled" : "disabled", config.wlcg_no_remove ? " (not removing tmp files)" : "");
-		lprintf(NULL, INF, "debug level: %d", config.debug);
-		lprintf(NULL, INF, "daemonize: %s", config.daemonize ? "enabled" : "disabled");
-		lprintf(NULL, INF, "fork guard: %s", config.guard ? "enabled" : "disabled");
-		lprintf(NULL, INF, "silly compatibility mode: %s", config.silly ? "enabled" : "disabled");
-		lprintf(NULL, INF, "purge: %s", !config.no_purge ? "enabled" : "disabled");
-	}
-
-	return 0;
-}
-
-
-int config_load() {
-	char line[LINE_MAX], *port, *s;
-	FILE *f;
-	void *tmp;
-	int i, n;
-#ifdef WITH_LBU_DB
-	int major, minor, sub, version;
-	char *results[2];
-	char *result = NULL;
-	glite_lbu_Statement stmt = NULL;
-	int err = 0;
-#endif
-
-	if (config.config_file) {
-		if ((f = fopen(config.config_file, "rt")) == NULL) {
-			lprintf(NULL, ERR, "can't open config file '%s': %s", config.config_file, strerror(errno));
-			return 1;
-		}
-
-		n = 10;
-		while (fgets(line, sizeof(line), f) != NULL) {
-			if ((s = strpbrk(line, "\n\r")) != NULL) s[0] = '\0';
-			if (line[0] == '\0' || line[0] == '#') continue;
-			if (config.nservers >= n || !config.notifs) {
-				n = 2 * n;
-				if ((tmp = (notif_t *)realloc(config.notifs, n * sizeof(notif_t))) == NULL) {
-					lprintf(NULL, ERR, "insufficient memory");
-					return 1;
-				}
-				config.notifs = tmp;
-				memset(config.notifs + config.nservers, 0, (n - config.nservers) * sizeof(notif_t));
-			}
-			if ((port = strrchr(line, ':')) != NULL) { port[0] = '\0'; port++; }
-			config.notifs[config.nservers].server = strdup(line);
-			config.notifs[config.nservers++].port = (port && port[0]) ? atoi(port) : GLITE_JOBID_DEFAULT_PORT;
-		}
-
-		fclose(f);
-	} else
-#ifdef WITH_LBU_DB
-	if (db.dbctx) {
-		if ((err = glite_lbu_ExecSQL(db.dbctx, "SELECT COUNT(*) FROM " RTM_DB_TABLE_LBS, &stmt)) < 0 ||
-		    (err = glite_lbu_FetchRow(stmt, 1, NULL, &result)) < 0) {
-			goto err;
-		}
-		if (err == 0) {
-			lprintf(NULL, ERR, "can't count LB servers");
-			goto err;
-		}
-		n = atoi(result);
-		free(result);
-		glite_lbu_FreeStmt(&stmt);
-
-		config.notifs = calloc(n, sizeof(notif_t));
-		config.nservers = 0;
-		if ((err = glite_lbu_ExecSQL(db.dbctx, "SELECT DISTINCT ip, serv_version FROM " RTM_DB_TABLE_LBS, &stmt)) < 0) {
-			goto err;
-		}
-		while (config.nservers < n && (err = glite_lbu_FetchRow(stmt, 2, NULL, results)) > 0) {
-			if (sscanf(results[1], "%d.%d.%d", &major, &minor, &sub) != 3) {
-				lprintf(NULL, ERR, "can't parse LB server version '%s'", results[1]);
-				free(results[1]);
-				break;
-			}
-			version = 10000 * major + 100 * minor + sub;
-			if (version >= 20000 || config.silly) {
-				config.notifs[config.nservers].server = strdup(results[0]);
-				config.notifs[config.nservers++].port = GLITE_JOBID_DEFAULT_PORT;
-			} else {
-				lprintf(NULL, INF, "skipped older LB server %s (version '%s')", results[0], results[1]);
-			}
-			free(results[0]);
-			free(results[1]);
-		}
-		if (err < 0) goto err;
-		glite_lbu_FreeStmt(&stmt);
-	}
-#endif
-
-	if (INF <= config.debug) {
-		lprintf(NULL, INF, "servers: %d", config.nservers);
-		for (i = 0; i < config.nservers; i++) lprintf(NULL, INF, "  %s:%d", config.notifs[i].server, config.notifs[i].port);
-	}
-
-	return 0;
-#ifdef WITH_LBU_DB
-err:
-	if (err) lprintf_dbctx(NULL, ERR, "can't get LB servers");
-	if (stmt) glite_lbu_FreeStmt(&stmt);
-	if (result) free(result);
-#endif
-	return 1;
-}
-
-
-void config_free() {
-	int i;
-
-	for (i = 0; i < config.nservers; i++) free(config.notifs[i].server);
-	free(config.config_file);
-	free(config.notif_file);
-	free(config.pidfile);
-	free(config.dbcs);
-	free(config.notifs);
-	free(config.cert);
-	free(config.key);
-	free(config.wlcg_binary);
-	free(config.wlcg_config);
-	free(config.wlcg_topic);
-}
-
-
-// on keyboard cleanup notification, on termination signal break with
-// notification preserved
-void handle_signal(int num) {
-	lprintf(NULL, INF, "received signal %d", num);
-	switch (num) {
-	case SIGINT:
-	case SIGTERM:
-	default:
-		quit = RTM_QUIT_PRESERVE;
-		break;
-	}
-}
-
-
-int main(int argn, char *argv[]) {
-	struct sigaction sa;
-	sigset_t sset;
-	int i, j;
-	double t1, t2, last_summary = 0, start_time;
-	thread_t *t;
-	struct stat pstat;
-	pid_t watched;
-	int status;
-	edg_wll_Context ctx = NULL;
-	int retval = RTM_EXIT_ERROR;
-	int cert_mtime = 0;
-
-	// load basic configurations
-	switch (config_preload(argn, argv)) {
-	case 0:
-		break;
-	case 1:
-		retval = RTM_EXIT_OK;
-		goto quit_guard0;
-		break;
-	default:
-		retval = RTM_EXIT_ERROR;
-		goto quit_guard0;
-	}
-
-	// daemonize
-	if (config.pidfile) {
-		FILE *f;
-		char s[256];
-
-		if ((f = fopen(config.pidfile, "rt"))) {
-			if (fscanf(f, "%255[^\n\r]", s) == 1) {
-				if (kill(atoi(s),0)) {
-					lprintf(NULL, WRN, "stale pidfile, pid = %s, pidfile '%s'", s, config.pidfile);
-					fclose(f);
-				}
-				else {
-					lprintf(NULL, ERR, "another instance running, pid = %s, pidfile '%s'", s, config.pidfile);
-					fclose(f);
-					goto quit_guard0;
-				}
-			} else {
-				lprintf(NULL, ERR, "another instance possibly running, can't read pidfile '%s': %s", config.pidfile, strerror(errno));
-				fclose(f);
-				goto quit_guard0;
-			}
-		} else if (errno != ENOENT) {
-			lprintf(NULL, ERR, "error opening pidfile '%s': %s", config.pidfile, strerror(errno));
-			goto quit_guard0;
-		}
-	}
-	if (config.daemonize) {
-#ifndef WITH_OLD_LB
-		if (glite_common_log_init()) {
-			fprintf(stderr,"glite_common_log_init() failed, exiting.");
-			exit(RTM_EXIT_ERROR);
-		}
-#endif
-		if (daemon(0, 0) == -1) {
-			lprintf(NULL, ERR, "can't daemonize: %s", strerror(errno));
-			goto quit_guard0;
-		}
-	}
-
-	// disable signals to the guardian
-	sigemptyset(&sset);
-	sigaddset(&sset, SIGABRT);
-	sigaddset(&sset, SIGTERM);
-	sigaddset(&sset, SIGINT);
-	pthread_sigmask(SIG_BLOCK, &sset, NULL);
-
-	if (!config.guard) {
-	// not guard
-		if (config.pidfile) {
-			FILE *f;
-
-			if ((f = fopen(config.pidfile, "wt")) == NULL) {
-				lprintf(NULL, ERR, "can't create pidfile '%s': %s", config.pidfile, strerror(errno));
-				goto quit_guard0;
-			}
-			fprintf(f, "%d", getpid());
-			fclose(f);
-		}
-	} else
-	// guard
-	while ((watched = fork()) != 0) {
-		if (watched == -1) {
-			lprintf(NULL, ERR, "fork() failed: %s", strerror(errno));
-			goto quit_guard;
-		}
-		if (config.pidfile) {
-			FILE *f;
-
-			if ((f = fopen(config.pidfile, "wt")) == NULL) {
-				lprintf(NULL, ERR, "can't create pidfile '%s': %s", config.pidfile, strerror(errno));
-				goto quit_guard0;
-			}
-			fprintf(f, "%d", watched);
-			fclose(f);
-		}
-		if (waitpid(watched, &status, 0) == -1) {
-			lprintf(NULL, ERR, "waitpid() failed: %s", strerror(errno));
-			// orpaned child will restart later anyway,
-			// better to end the child process just now
-			kill(watched, SIGTERM);
-			goto quit_guard;
-		}
-		if (WIFSIGNALED(status)) {
-			switch (WTERMSIG(status)) {
-			case SIGSEGV:
-			case SIGILL:
-			case SIGABRT:
-#ifdef SIGBUS
-			case SIGBUS:
-#endif
-				lprintf(NULL, ERR, "caught signal %d from process %d, resurrecting...", WTERMSIG(status), watched);
-				// slow down the core generator ;-)
-				// disabled signals and ended child in pidfile, live with it
-				pthread_sigmask(SIG_UNBLOCK, &sset, NULL);
-				if (config.pidfile) {
-					if (remove(config.pidfile) == -1) lprintf(NULL, WRN, "can't remove pidfile '%s': %s", config.pidfile, strerror(errno));
-				}
-				sleep(2);
-				pthread_sigmask(SIG_BLOCK, &sset, NULL);
-				break;
-			default:
-				lprintf(NULL, WRN, "ended with signal %d", WTERMSIG(status));
-				goto quit_guard;
-			}
-		} else if (WIFEXITED(status)) {
-			retval = WEXITSTATUS(status);
-			switch(retval) {
-			case RTM_EXIT_OK:
-				lprintf(NULL, INF, "exit with status %d, OK", retval);
-				goto quit_guard;
-			case RTM_EXIT_RELOAD:
-				lprintf(NULL, INF, "exit with status %d, reloading", retval);
-				break;
-			default:
-				lprintf(NULL, WRN, "exit with status %d, error", retval);
-				goto quit_guard;
-			}
-		} else {
-			lprintf(NULL, ERR, "unknown child status");
-			goto quit_guard;
-		}
-	}
-
-	// child continues...
-	umask(S_IRWXG | S_IRWXO);
-
-	// threads && Globus
-	if (edg_wll_gss_initialize()) {
-		lprintf(NULL, ERR, "can't initialize GSS");
-		goto quit_guard;
-	}
-
-#ifndef WITH_OLD_LB
-	// connection pool manually (just for tuning memory leaks)
-	if (!edg_wll_initConnections()) {
-		lprintf(NULL, ERR, "can't initialize LB connections");
-		goto quit_guard;
-	}
-#endif
-
-#ifdef WITH_LBU_DB
-	// database
-	switch(db_init(NULL, &db.dbctx)) {
-	case 0:
-		break;
-	case -1:
-		// no db
-		break;
-	default:
-		// error
-		goto quit;
-	}
-#endif
-
-	// load configurations
-	if (config_load()) goto quit;
-#ifdef WITH_OLD_LB
-	// other client certificate settings ignored by older globus,
-	// using environment (certificate the same for all threads)
-	{
-		char *s;
-
-		if (config.cert) {
-			asprintf(&s, "X509_USER_CERT=%s", config.cert);
-			putenv(s);
-		}
-		if (config.key) {
-			asprintf(&s, "X509_USER_KEY=%s", config.key);
-			putenv(s);
-		}
-	}
-#endif
-
-	// load previous notifications
-	if (load_notifs()) goto quit;
-	// compare lb servers from configuration and notifications,
-	// or clean up and exit if specified
-	if (reconcile_threads()) goto quit;
-	if (config.cleanup) {
-		retval = RTM_EXIT_OK;
-		goto quit;
-	}
-
-	// signal handler
-	sa.sa_handler = handle_signal;
-	sigemptyset(&sa.sa_mask);
-	sa.sa_flags = SA_RESETHAND;
-	if (sigaction(SIGABRT, &sa, NULL) == -1
-	    || sigaction(SIGTERM, &sa, NULL) == -1
-	    || sigaction(SIGINT, &sa, NULL) == -1) {
-		lprintf(NULL, ERR, "can't handle signal: %s", strerror(errno));
-		goto quit;
-	}
-	// enable signals in main
-	pthread_sigmask(SIG_UNBLOCK, &sset, NULL);
-
-	// launch the threads
-	for (i = 0; i < config.nthreads; i++) {
-		t = threads + i;
-		t->id = i;
-		if (pthread_create(&threads[i].thread, NULL, notify_thread, t) != 0) {
-			lprintf(NULL, ERR, "[main] can't create %d. thread: %s\n", i, strerror(errno));
-			goto quit;
-		}
-	}
-
-	if (edg_wll_InitContext(&ctx) != 0) {
-		lprintf(NULL, ERR, "can't init LB context");
-		goto quit;
-	}
-	if (config.cert) edg_wll_SetParam(ctx, EDG_WLL_PARAM_X509_CERT, config.cert);
-	if (config.key) edg_wll_SetParam(ctx, EDG_WLL_PARAM_X509_KEY, config.key);
-	last_summary = 0;
-	start_time = rtm_gettimeofday();
-	while (!quit) {
-		t1 = rtm_gettimeofday();
-		if (t1 - last_summary > RTM_SUMMARY_POLL_TIME) {
-			last_summary = t1;
-			rtm_summary(ctx, &db);
-		}
-		if (config.guard) {
-			if (t1 - start_time > RTM_SUICIDE_TIME) {
-				quit = RTM_QUIT_RELOAD;
-				lprintf(NULL, INF, "preventive suicide");
-				break;
-			}
-			if (config.cert) {
-				if (stat(config.cert, &pstat) == 0) {
-					if (!cert_mtime) cert_mtime = pstat.st_mtime;
-					if (cert_mtime < pstat.st_mtime) {
-						lprintf(NULL, INF, "certificate '%s' changed, reloading", config.cert);
-						quit = RTM_QUIT_RELOAD;
-						break;
-					}
-				} else {
-					lprintf(NULL, ERR, "can't check certificate file '%s'", config.cert, strerror(errno));
-				}
-			}
-		}
-		t2 = rtm_gettimeofday();
-		if (t2 - t1 < RTM_IDLE_POLL_TIME) usleep((RTM_IDLE_POLL_TIME + t1 - t2) * 1000000);
-	}
-	retval = quit == RTM_QUIT_RELOAD ? RTM_EXIT_RELOAD : RTM_EXIT_OK;
-quit:
-	// cleanup on error
-	if (!quit) quit = RTM_QUIT_CLEANUP;
-	if (threads) {
-		for (i = 0; i < config.nthreads; i++) {
-			t = threads + i;
-			if (t->thread) pthread_join(t->thread, NULL);
-			for (j = 0; j < t->nservers; j++) notif_free(t->notifs + j);
-			free(t->notifs);
-		}
-		free(threads);
-	}
-
-	if (config.pidfile && !config.guard) {
-		if (remove(config.pidfile) == -1) lprintf(NULL, WRN, "can't remove pidfile '%s': %s", config.pidfile, strerror(errno));
-	}
-#ifndef WITH_OLD_LB
-	if (config.daemonize) glite_common_log_fini();
-#endif
-
-#ifdef WITH_LBU_DB
-	db_free(NULL, db.dbctx);
-#endif
-	edg_wll_FreeContext(ctx);
-	db_free_notifs();
-	config_free();
-#ifndef WITH_OLD_LB
-	edg_wll_poolFree();
-#endif
-
-	return retval;
-
-quit_guard:
-	if (config.pidfile) {
-		if (remove(config.pidfile) == -1) lprintf(NULL, WRN, "can't remove pidfile '%s': %s", config.pidfile, strerror(errno));
-	}
-quit_guard0:
-	config_free();
-	return retval;
-}
diff --git a/org.glite.lb.logger-msg/LICENSE b/org.glite.lb.logger-msg/LICENSE
deleted file mode 100644
index 259a91f..0000000
--- a/org.glite.lb.logger-msg/LICENSE
+++ /dev/null
@@ -1,69 +0,0 @@
-LICENSE file for EGEE Middleware
-================================
-
-Copyright (c) 2004 on behalf of the EU EGEE Project: 
-The European Organization for Nuclear Research (CERN), 
-Istituto Nazionale di Fisica Nucleare (INFN), Italy
-Datamat Spa, Italy
-Centre National de la Recherche Scientifique (CNRS), France
-CS Systeme d'Information (CSSI), France
-Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden
-Universiteit van Amsterdam (UvA), Netherlands
-University of Helsinki (UH.HIP), Finlan
-University of Bergen (UiB), Norway
-Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met: 
-
-1. Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-3. The end-user documentation included with the redistribution, if
-any, must include the following acknowledgment: "This product includes
-software developed by The EU EGEE Project (http://cern.ch/eu-egee/)."
-Alternatively, this acknowledgment may appear in the software itself, if
-and wherever such third-party acknowledgments normally appear.
-
-4. The names EGEE and the EU EGEE Project must not be
-used to endorse or promote products derived from this software without
-prior written permission. For written permission, please contact
-.
-
-5. You are under no obligation whatsoever to provide anyone with any
-bug fixes, patches, or upgrades to the features, functionality or
-performance of the Software ("Enhancements") that you may develop over
-time; however, if you choose to provide your Enhancements to The EU
-EGEE Project, or if you choose to otherwise publish or distribute your
-Enhancements, in source code form without contemporaneously requiring
-end users of The EU EGEE Proejct to enter into a separate written license
-agreement for such Enhancements, then you hereby grant The EU EGEE Project
-a non-exclusive, royalty-free perpetual license to install, use, copy,
-modify, prepare derivative works, incorporate into the EGEE Middleware
-or any other computer software, distribute, and sublicense your
-Enhancements or derivative works thereof, in binary and source code
-form (if any), whether developed by The EU EGEE Project or third parties.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-This software consists of voluntary contributions made by many
-individuals on behalf of the EU EGEE Prject. For more information on The
-EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on
-EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/
-
-
diff --git a/org.glite.lb.logger-msg/Makefile b/org.glite.lb.logger-msg/Makefile
deleted file mode 100644
index 6fe72d8..0000000
--- a/org.glite.lb.logger-msg/Makefile
+++ /dev/null
@@ -1,133 +0,0 @@
-# defaults
-top_srcdir=..
-stagedir=.
-globalprefix=glite
-lbprefix=lb
-package=glite-lb-logger-msg
-version=0.0.0
-PREFIX=/opt/glite
-sysconfdir=/opt/glite/etc
-
-nothrflavour=gcc32
-thrflavour=gcc32pthr
-
--include Makefile.inc
--include ${top_srcdir}/project/version.properties
-
-version=${module.version}
-
-CC=gcc
-CXX=gcc
-
-VPATH:=${top_srcdir}/src:${top_srcdir}/interface:${top_srcdir}/test:${top_srcdir}/doc:${top_srcdir}/examples:${top_srcdir}/config
-
-VERSION=-DVERSION=\"GLite-${version}\"
-
-ACTIVEMQ_CFLAGS?=`PKG_CONFIG_PATH=${activemq_prefix}/${libdir}/pkgconfig pkg-config --cflags activemq-cpp`
-ACTIVEMQ_LIBS?=-L${activemq_prefix}/${libdir} -lactivemq-cpp
-
-CPPUNIT_LIBS?=-L${cppunit_prefix}/${libdir} -lcppunit
-CPPUNIT_CFLAGS?=-I${cppunit_prefix}/include
-
-DEBUG:=-g -O0
-CFLAGS:=${CFLAGS} ${DEBUG} \
-	-I${stagedir}${prefix}/include -I${top_srcdir}/src \
-	${ACTIVEMQ_CFLAGS} \
-	-D_GNU_SOURCE \
-	${COVERAGE_FLAGS} \
-	${VERSION} ${LB_STANDALONE_FLAGS} ${LB_PERF_FLAGS} 
-
-LDFLAGS:=${LDFLAGS} -L${stagedir}${prefix}/${libdir} \
-	${COVERAGE_FLAGS} 
-
-COMPILE:=libtool --mode=compile ${CC} ${CFLAGS}
-COMPILEXX:=libtool --mode=compile ${CXX} ${CFLAGS}
-LINK:=libtool --mode=link ${CC} ${LDFLAGS}
-LINKXX:=libtool --mode=link ${CXX} -rpath ${stagedir}${prefix}/${libdir} ${LDFLAGS} 
-INSTALL:=libtool --mode=install install
-SOLINK:=libtool --mode=link ${CXX} -module ${LDFLAGS} -rpath ${stagedir}${prefix}/${libdir}
-
-#ifneq (${expat_prefix},/usr)
-#	EXPAT_LIBS:=-L${expat_prefix}/lib
-#endif
-#EXPAT_LIBS:=${EXPAT_LIBS} -lexpat
-#
-#EXT_LIBS:= ${EXPAT_LIBS}
-
-HDRS:=
-
-COMMON_LIB:=
-
-EXT_LIB:=${ACTIVEMQ_LIBS}
-
-GLITE_GSS_LIB:=
-
-PLUGIN_OBJS:=activemq_cpp_plugin.o
-PLUGIN_LOBJS:=${PLUGIN_OBJS:.o=.lo}
-PLUGIN_LIB:=activemq_cpp_plugin.la
-
-EXAMPLES=glite-lb-cmsclient
-
-SCRIPTS_SRC=msg.cron.in msg-config.in
-SCRIPTS=${SCRIPTS_SRC:.in=.new}
-
-ifeq (${thrflavour},)
-default_flavour=
-else
-default_flavour=_${nothrflavour}
-endif
-
-default: all 
-
-all compile: ${PLUGIN_LIB} ${EXAMPLES} ${SCRIPTS}
-
-${PLUGIN_LIB}: ${PLUGIN_LOBJS}
-	${SOLINK} -o $@ ${PLUGIN_LOBJS} ${EXT_LIB} -lglite_lb_common${default_flavour} -lglite_jobid -lglite_lbu_log
-
-${MAN_GZ}: ${MAN}
-	rm -f ${MAN_GZ} ${MAN}
-	cp $? .
-	gzip -f $(notdir $?)
-
-glite-lb-cmsclient: cmsclient.o
-	$(CC) $< ${EXT_LIB} -o $@
-
-man: ${MAN_GZ}
-
-stage: compile
-	$(MAKE) install PREFIX=${stagedir} 
-
-check: 
-# do nothing until test/ is really added to CVS
-# check.ll check.il
-
-#check.ll: logd_proto_test.o ll_test.o
-#	${LINKXX} -o $@ ${COMMON_LIB}_${nothrflavour} ${EXT_LIBS} ${TEST_LIBS} $+
-#	./check.ll
-
-install:
-	-mkdir -p ${DESTDIR}${PREFIX}${prefix}/${libdir}/glite-lb/examples
-	-mkdir -p ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version}
-	-mkdir -p ${DESTDIR}${PREFIX}${prefix}/sbin
-	-mkdir -p ${DESTDIR}${PREFIX}${sysconfdir}/glite-lb
-	-mkdir -p ${DESTDIR}${PREFIX}${sysconfdir}/cron.d
-	${INSTALL} -m 644 ${top_srcdir}/LICENSE ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version}
-	${INSTALL} -m 755 ${PLUGIN_LIB} ${DESTDIR}${PREFIX}${prefix}/${libdir}
-	${INSTALL} -m 755 ${EXAMPLES} ${DESTDIR}${PREFIX}${prefix}/${libdir}/glite-lb/examples
-	( cd ${top_srcdir}/project && ${INSTALL} -m 644 ChangeLog package.description package.summary ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version} )
-	${INSTALL} -m 644 ${top_srcdir}/config/msg.conf.example ${DESTDIR}${PREFIX}${sysconfdir}/glite-lb
-	${INSTALL} -m 755 ${top_srcdir}/src/msg-brokers ${DESTDIR}${PREFIX}${prefix}/sbin/glite-lb-msg-brokers
-	${INSTALL} -m 755 msg-config.new ${DESTDIR}${PREFIX}${prefix}/sbin/glite-lb-msg-config
-	${INSTALL} -m 644 msg.cron.new ${DESTDIR}${PREFIX}${sysconfdir}/cron.d/glite-lb-logger-msg.cron
-
-%.lo %.o: %.cpp
-	${COMPILEXX} -c $< -o $@
-
-%.new: %.in
-	sed -e 's:@glite_prefix@:${sysroot}${prefix}:' -e 's:@glite_etc@:${sysconfdir}:' $< > $@
-
-clean:
-	rm -rvf .libs/ *.o *.lo ${PLUGIN_LIB} ${MAN_GZ} ${EXAMPLES}
-
-distclean:
-	rm -rvf Makefile.inc *.spec debian/
diff --git a/org.glite.lb.logger-msg/config/msg.conf.example b/org.glite.lb.logger-msg/config/msg.conf.example
deleted file mode 100644
index ca51a50..0000000
--- a/org.glite.lb.logger-msg/config/msg.conf.example
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# example configuration for export notifications to MSG system
-#
-
-[interlogd]
-plugin = activemq_cpp_plugin.so
-
-[msg]
-broker = tcp://dev.msg.cern.ch:6166
-#broker = tcp://egi-1.msg.cern.ch:6166
-#broker = tcp://egi-2.msg.cern.ch:6166
diff --git a/org.glite.lb.logger-msg/config/msg.cron.in b/org.glite.lb.logger-msg/config/msg.cron.in
deleted file mode 100644
index 20b018a..0000000
--- a/org.glite.lb.logger-msg/config/msg.cron.in
+++ /dev/null
@@ -1 +0,0 @@
-50 */4 * * *	root	@glite_prefix@/sbin/glite-lb-msg-config @glite_etc@/glite-lb/msg.conf >/tmp/msg-config.log.$$ 2>&1; if test $? -eq 0; then pri=user.notice; else pri=user.error; fi; logger -t glite-lb-msg-config -f /tmp/msg-config.log.$$ -p $pri; rm -f /tmp/msg-config.log.$$
diff --git a/org.glite.lb.logger-msg/configure b/org.glite.lb.logger-msg/configure
deleted file mode 100755
index bcb1531..0000000
--- a/org.glite.lb.logger-msg/configure
+++ /dev/null
@@ -1,2058 +0,0 @@
-#!/usr/bin/perl
-
-# WARNING: Don't edit this file unless it is the master copy in org.glite.lb
-#
-# For the purpose of standalone builds of lb/jobid/lbjp-common components
-# it is copied on tagging 
-
-# $Header$
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners/ for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-use Getopt::Long;
-use POSIX qw(locale_h strftime);
-
-my $pwd = `pwd`; chomp $pwd;
-my $prefix = '/usr';
-my $stagedir = undef;
-my $root = $pwd.'/stage';
-my $sysroot = '';
-my $sysconfdir;
-my $localstatedir;
-my $staged;
-my $module;
-my $thrflavour = 'gcc64dbgpthr';
-my $nothrflavour = 'gcc64dbg';
-my $mode = 'build';
-my $help = 0;
-my $listmodules;
-my ($version, $force_version);
-my $branch;
-my $output;
-my $lb_tag = '';
-my $lbjp_tag = '';
-my $jp_tag = '';
-my $jobid_tag = '';
-my $libdir = getlibdir();
-my $project = 'emi';
-my $project_version;
-my (%projects, %project);
-my $debug = 0;
-my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : '';
-
-my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal/;
-my @default_nodes = qw/lb px proxyrenewal nagios/;
-my %enable_nodes;
-my %disable_nodes;
-my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1);
-
-my %package = (
-	'maintainer' => 'CESNET Product Teams ',
-	'uploaders' => 'František Dvořák ',
-	'url' => 'http://glite.cern.ch',
-	'debian_vcs' => 'Vcs-Cvs: :pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw
-Vcs-Browser: http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi',
-);
-
-# key:      internal package name (arguments, ...)
-# 'pkg':    pkg-config name
-# 'prefix': used when pkg-config fails
-my %externs = (
-	cares => {
-		prefix => '/opt/c-ares',
-		pkg => 'libcares'
-	},
-	classads => {
-		prefix=> '/usr',
-		pkg => 'classads'
-	},
-	cppunit => {
-		prefix=> '/usr',
-		pkg => 'cppunit'
-	},
-	expat => {
-		prefix=> '/usr',
-		pkg => 'expat'
-	},
-	globus => {
-		prefix=> '/opt/globus',
-		pkg => 'globus-gssapi-gsi'
-	},
-	'myproxy-devel' => {
-		prefix=> '/opt/globus',
-		pkg => 'myproxy'
-	},
-	'myproxy-server' => {
-		prefix=> '',
-	},
-	'myproxy-admin' => {
-		prefix=> '',
-	},
-	gsoap => {
-		prefix=> '/usr',
-		pkg => 'gsoap'
-	},
-	gsoapxx => {
-		prefix=> '/usr',
-		pkg => 'gsoap++'
-	},
-	mysql => {
-		prefix=> '/usr'
-	},
-	'mysql-devel' => {
-		prefix=> ''
-	},
-	'mysql-server' => {
-		prefix => ''
-	},
-	voms => {
-		prefix => '/opt/glite',
-		pkg => 'voms-2.0'
-	},
-	gridsite => {
-		prefix => '/opt/glite'
-	},
-	lcas => {
-		prefix => '/opt/glite',
-		pkg => 'lcas'
-	},
-	trustmanager => {
-		prefix => '/opt/glite'
-	},
-	trustmanager_axis => {
-		prefix => '/opt/glite'
-	},
-	utiljava => {
-		prefix=> '/opt/glite'
-	},
-	ant => {
-		prefix=> '/usr'
-	},
-	jdk => {
-		prefix=> '/usr/java/latest',
-		locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ],
-	},
-	libtar => {
-		prefix=> '/usr'
-	},
-	axis => {
-		prefix=> '/usr'
-	},
-	log4c => {
-		prefix=> '/usr'
-	},
-	postgresql => {
-		prefix=> '/usr'
-	},
-	activemq => {
-		prefix=>'/opt/activemq-cpp-library',
-		pkg => 'activemq-cpp'
-	},
-);
-
-my %jar = (
-	'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar',
-	'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar',
-);
-
-
-my %glite_prefix;
-my %need_externs;
-my %need_externs_type;
-my %need_jars;
-my %extrafull;
-my %extranodmod;
-my %deps;
-my %deps_type;
-my %buildroot;
-my (%etics_externs, %etics_projects);
-
-#
-# modules of the subsystems
-#
-# additional modules from $project{modules} are automatically added
-#
-my %lbmodules = (
-	'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], 
-	'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/],
-	'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/],
-	'jp' => [ qw/client doc index primary server-common ws-interface/ ],
-	'gridsite' => [ qw/apache libs commands core devel slashgrid services service-clients gsexec/ ],
-	'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ],
-	'canl' => [ qw/c c-devel/ ],
-	);
-
-#
-# sub-packages
-#
-# modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly
-#
-my %subpackages = (
-	'jobid.api-c-devel' => 'jobid.api-c',
-	'jobid.api-cpp-devel' => 'jobid.api-cpp',
-	'lbjp-common.db-devel' => 'lbjp-common.db',
-	'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin',
-	'lbjp-common.gss-devel' => 'lbjp-common.gss',
-	'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface',
-	'lbjp-common.log-devel' => 'lbjp-common.log',
-	'lbjp-common.maildir-devel' => 'lbjp-common.maildir',
-	'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones',
-	'lbjp-common.trio-devel' => 'lbjp-common.trio',
-	'lb.client-progs' => 'lb.client',
-	'lb.client-devel' => 'lb.client',
-	'lb.common-devel' => 'lb.common',
-	'lb.logger-devel' => 'lb.logger',
-	'lb.state-machine-devel' => 'lb.state-machine',
-	'px.proxyrenewal-devel' => 'px.proxyrenewal',
-	'px.proxyrenewal-progs' => 'px.proxyrenewal',
-	'canl.c-devel' => 'canl.c',
-);
-
-my @opts = (
-	'prefix:s' => \$prefix,
-	'staged=s' => \$staged,
-	'module=s' => \$module,
-	'thrflavour:s' => \$thrflavour,
-	'nothrflavour:s' => \$nothrflavour,
-	'mode=s' => \$mode,
-	'listmodules=s' => \$listmodules,
-	'version=s' => \$force_version,
-	'branch=s' => \$branch,
-	'output=s' => \$output,
-	'stage=s' => \$stagedir,
-	'root:s' => \$root,
-	'sysroot:s' => \$sysroot,
-	'sysconfdir=s' => \$sysconfdir,
-	'localstatedir=s' => \$localstatedir,
-	'lb-tag=s' => \$lb_tag,
-	'lbjp-common-tag=s' => \$lbjp_tag,
-	'jp-tag=s' => \$jp_tag,
-	'jobid-tag=s' => \$jobid_tag,
-	'canl-tag=s' => \$canl_tag,
-	'help' => \$help,
-	'libdir=s' => \$libdir,
-	'project=s' => \$project,
-	'debug' => \$debug,
-);
-
-for (@nodes) {
-	$enable_nodes{$_} = 0;
-	$disable_nodes{$_} = 0;
-	
-	push @opts,"disable-$_",\$disable_nodes{$_};
-	push @opts,"enable-$_",\$enable_nodes{$_};
-}
-
-push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs;
-push @opts,"with-$_=s",\$jar{$_} for keys %jar;
-
-my @keeparg = @ARGV;
-
-GetOptions @opts or die "Errors parsing command line\n";
-$prefix=~s/\/$//;
-$root=~s/\/$//;
-$sysroot=~s/\/$//;
-if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; }
-if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; }
-$sysconfdir=~s/\/$//;
-$localstatedir=~s/\/$//;
-
-$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq '';
-$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq '';
-$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq '';
-
-$externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq '';
-$externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq '';
-$externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq '';
-
-if ($project =~ /^([^0-9]*)(.*)$/) {
-	$project = $1;
-	$project_version = $2;
-}
-%project = %{$projects{$project}};
-$project_version = $project{current_version} unless $project_version;
-for my $platform (keys %{$project{etics_externs}}) {
-	for $_ (keys %{$project{etics_externs}{$platform}}) {
-		$etics_externs{$platform}{$_} = $project{etics_externs}{$platform}{$_};
-	}
-}
-reshuffle_platforms(\%etics_externs, $project{supported_platforms});
-reshuffle_platforms(\%{$project{etics_externs_devel}}, $project{supported_platforms});
-for $_ (keys %{$project{etics_projects}}) {
-	$etics_projects{$_} = $project{etics_projects}{$_};
-}
-for $_ (keys %{$project{need_externs_aux}}) {
-	$need_externs_aux{$_} = $project{need_externs_aux}{$_};
-}
-for my $ext (keys %need_externs_aux) {
-	for (@{$need_externs_aux{$ext}}) {
-		my ($pkg, $type) =/([^:]*)(?::(.*))?/;
-		$type = 'BR' unless ($type);
-
-		push @{$need_externs{$ext}},$pkg;
-		$need_externs_type{$ext}->{$pkg} = $type;
-	}
-}
-if ($project eq 'emi') {
-	$extranodmod{lb} = 'lb.emi-lb';
-	$extranodmod{px} = 'px.emi-px';
-}
-for $_ (keys %{$project{modules}}) {
-	push @{$lbmodules{$_}},@{$project{modules}{$_}};
-}
-
-
-if ($help) { usage(); exit 0; }
-
-if ($listmodules) {
-	my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name};
-	my @m;
-
-	if (exists $lbmodules{$listmodules}) {
-		@m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}};
-	} else {
-		if ($project eq 'emi' and $project_version == 1) {
-			# no sub-packages in EMI-1
-		} else {
-			for my $sub (keys %subpackages) {
-				push @m, $sub if ($subpackages{$sub} eq $listmodules);
-			}
-		}
-	}
-	print map $_ eq "" ? "" : "$_ ", @m;
-	print "\n";
-	exit 0;
-}
-
-warn "$0: --branch and --output make sense only in --mode=etics\n"
-	if ($output || $branch) && $mode ne 'etics';
-
-my $en;
-for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; }
-
-my $dis;
-for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; }
-
-die "--enable-* and --disable-* are mutually exclusive\n"
-	if $en && $dis;
-
-die "--module cannot be used with --enable-* or --disable-*\n"
-	if $module && ($en || $dis);
-
-die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}};
-
-if ($dis) {
-	for (@nodes) {
-		$enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_});
-	}
-}
-
-if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } };
-
-for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; }
-
-$stagedir = $root unless $stagedir;
-$stagedir=~s/\/$// if ($stagedir);
-
-if ($mode eq 'build') { for my $ext (keys %externs) {
-	if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; }
-	elsif (defined $externs{$ext}{pkg}) {
-		my ($flag, $env, $cmd, $ret);
-		my $pkg = $externs{$ext}{pkg};
-		my $flagname = uc $externs{$ext}{pkg};
-		$flagname =~ s/-[0-9\.]*$//;
-		$flagname =~ y/-\+/_X/;
-
-		print "Checking $pkg ... ";
-		$env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig";
-		$cmd = "$env pkg-config $pkg --exists >/dev/null";
-		`$cmd`; $ret = $?;
-		print "('$cmd' => $ret)\n" if ($debug);
-		if ($ret == 0) {
-			$externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`;
-			chomp $externs{$ext}{prefix};
-			print "$externs{$ext}{prefix}\n";
-
-			$flag=`$env pkg-config $pkg --cflags`;
-			$externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag);
-			$flag=`$env pkg-config $pkg --libs`;
-			$externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag);
-		} else {
-			print "(using default $externs{$ext}{prefix})\n";
-		}
-		print "\n" if ($debug);
-	}
-	elsif ($ext eq 'jdk') {
-		my $jdk_prefix;
-
-		print "Looking for some caffein ... ";
-		if (defined $ENV{'JDK_HOME'}) {
-			$jdk_prefix = $ENV{'JDK_HOME'};
-			print "JDK_HOME=$jdk_prefix\n";
-		} elsif (defined $ENV{'JAVA_HOME'}) {
-			$jdk_prefix = $ENV{'JAVA_HOME'};
-			print "JAVA_HOME=$jdk_prefix\n";
-		} else {
-			foreach my $i (0..$#{$externs{$ext}{locations}}) {
-				if (-e $externs{$ext}{locations}[$i]) {
-					$jdk_prefix=$externs{$ext}{locations}[$i];
-					print "(found directory $jdk_prefix)\n";
-					last;
-				}
-			}
-			print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix);
-		}
-		$externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix);
-	}
-} }
-
-if ($mode eq 'build') {
-	print "Writing config.status\n";
-	open CONF,">config.status" or die "config.status: $!\n";
-	for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') {
-		print CONF "$_=$ENV{$_} " if (defined $ENV{$_});
-	}
-	print CONF "$0 @keeparg\n";
-	close CONF;
-}
-
-
-my @modules;
-my %aux;
-
-if ($module) {
-#	push @modules,split(/[,.]+/,$module);
-	push @modules,$module;
-}
-else {
-	@modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes));
-	
-	my $n;
-
-	do {
-		local $"="\n";
- 		$n = $#modules;
-		push @modules,(map @{$deps{$_}},@modules);
-
-		undef %aux; @aux{@modules} = (1) x ($#modules+1);
-		@modules = keys %aux;
-	} while ($#modules > $n);
-}
-
-@aux{@modules} = (1) x ($#modules+1);
-delete $aux{$_} for (split /,/,$staged);
-@modules = keys %aux;
-
-mode_build() if $mode eq 'build';
-mode_checkout() if $mode eq 'checkout';
-mode_etics($module) if $mode eq 'etics';
-
-sub mode_build {
-	print "\nBuilding modules: @modules\n";
-	print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n";
-	
-	my @ext = map @{$need_externs{$_}},@modules;
-	my @myjars = map @{$need_jars{$_}},@modules;
-	undef %aux; @aux{@ext} = 1;
-	@ext = keys %aux;
-	undef %aux; @aux{@myjars} = (1) x ($#myjars+1);
-	@myjars = keys %aux;
-	
-	print "\nRequired externals:\n";
-	print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext;
-	print "\t$_: $jar{$_}\n" for @myjars;
-	for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } };
-	print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n";
-
-	mkinc($_) for @modules;
-
-	if ($module) {
-		print "Not creating summary Makefile\n" if $debug;
-	} else {
-		print "Creating Makefile\n";
-
-		open MAK,">Makefile" or die "Makefile: $!\n";
-
-		print MAK "all: @modules\n\n";
-		print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n";
-		print MAK "clean check install:\n";
-
-		for (@modules) {
-			my $full = full($_);
-			print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n"
-		}
-
-		print MAK "\ndistclean:\n";
-
-		for (@modules) {
-			my $full = full($_);
-			print MAK $buildroot{$_} eq '' ?
-				"\tcd $full && \${MAKE} distclean\n" :
-				"\trm -rf $full/$buildroot{$_}\n"
-		}
-
-		print MAK "\n";
-
-		for (@modules) {
-			my %ldeps; undef %ldeps;
-			@ldeps{@{$deps{$_}}} = 1;
-			for my $x (split /,/,$staged) { delete $ldeps{$x}; }
-			my @dnames = $module ? () : keys %ldeps;
-			my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage';
-
-			my $full = full($_);
-			my $build = $buildroot{$_};
-
-			print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n";
-			print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n";
-		}
-
-		close MAK;
-	}
-}
-	
-sub mode_checkout() {
-	for (@modules) {
-		my $module = $_;
-		my $tag = "";
-		if ($lb_tag){
-			for (@{$lbmodules{lb}}){
-				if ("lb.".$_ eq $module){
-					$tag = '-r '.$lb_tag;
-				}
-			}	
-		}
-		if ($lbjp_tag) {
-			for (@{$lbmodules{'lbjp-common'}}){
-				if ("lbjp-common.".$_ eq $module){
-                                        $tag = '-r '.$lbjp_tag;
-                                }
-			}
-		}
-		if ($jp_tag){
-			for (@{$lbmodules{'jp'}}){
-	                        if ("jp.".$_ eq $module){
-                                        $tag = '-r '.$jp_tag;
-	                        }
-                        }
-		}
-		if ($jobid_tag){
-			for (@{$lbmodules{jobid}}){
-				if ("jobid.".$_ eq $module){
-                                        $tag = '-r '.$jobid_tag;
-                                }
-			}
-		}
-		if ($canl_tag) {
-			for (@{$lbmodules{'canl'}}){
-				if ("canl.".$_ eq $module){
-                                        $tag = '-r '.$canl_tag;
-                                }
-			}
-		}
-		#if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){
-		#	print "found";
-		#}
-		$_ = full($_);
-		print "\n*** Checking out $_\n";
-		system("cvs checkout  $tag $_") == 0 or die "cvs checkout $tag $_: $?\n";
-	}
-}
-
-BEGIN{
-%etics_externs = (
-	default => {
-		'myproxy-devel'=>'myproxy-devel',
-		'myproxy-server'=>'myproxy-server',
-		'myproxy-admin'=>'myproxy-admin',
-		cares=>'c-ares',
-		utiljava=>'org.glite.security.util-java',
-		gpt=>'gpt',
-		fetchcrl=>'fetch-crl',
-		activemq=>'activemq-cpp-library',
-	},
-);
-
-%etics_projects = (
-);
-
-%need_externs_aux = (
-	'lb.client' => [ qw/cppunit:B classads libtool:B globus:B/ ],
-	'lb.common' => [ qw/expat cares:B cppunit:B classads libtool:B globus:B/ ],
-	'lb.doc' => [ qw/tetex-latex:B/ ],
-	'lb.logger' => [ qw/cppunit:B libtool:B globus:B/ ],
-	'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B globus:B/ ],
-	'lb.nagios' => [ qw/globus_proxy_utils:R/ ],
-	'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql-server:R cppunit:B gsoap:B classads voms:B lcas gridsite:B bison:B libtool:B libxml2 flex:B/ ],
-	'lb.state-machine' => [ qw/classads libtool:B libxslt:B expat:B globus:B/ ],
-	'lb.utils' => [ qw/cppunit:B libtool:B globus:B/ ],
-	'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ],
-	'lb.ws-test' => [ qw/gsoap:B libtool:B globus:B/ ],
-	'lb.types' => [ qw// ],
-	'lb.harvester' => [ qw/docbook-utils:B libtool:B globus:B/ ],
-	'lbjp-common.db' => [ qw/mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B/ ],
-	'lbjp-common.log' => [ qw/log4c libtool:B/ ],
-	'lbjp-common.maildir' => [ qw/libtool:B/ ],
-	'lbjp-common.server-bones' => [ qw/libtool:B/ ],
-	'lbjp-common.trio' => [ qw/cppunit:B libtool:B/ ],
-	'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B/ ],
-	'lbjp-common.gss' =>  [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B/ ],
-	'lbjp-common.gsoap-plugin' =>  [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B/ ],
-	'jobid.api-c' =>  [ qw/cppunit:B libtool:B openssl:B/ ],
-	'jobid.api-cpp' =>  [ qw/cppunit:B libtool:B/ ],
-	'jobid.api-java' =>  [ qw/ant:B jdk:B/ ],
-	'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ],
-        'jp.doc' => [],
-        'jp.index' => [ qw/gsoap globus_essentials:R globus:B mysql-server:R/ ],
-        'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B  mysql-server:R/ ],
-        'jp.server-common' => [],
-        'jp.ws-interface' => [],
-	'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ],
-	'gridsite.commands' => [ qw/curl:R openssl:R/ ],
-	'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ],
-	'gridsite.libs' => [ qw/libxml2:R openssl:R/ ],
-	'gridsite.devel' => [ qw// ],
-	'gridsite.slashgrid' => [ qw/curl:R fuse:R/],
-	'gridsite.services' => [ qw/curl:R gsoap:R/ ],
-	'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ],
-	'gridsite.gsexec' => [ qw// ],
-	'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ],
-	'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B/ ],
-	'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec
-	'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B krb5-devel:B/ ],
-);
-
-%need_jars = (
-	'jobid.api-java' => [ qw/jakarta-commons-codec/ ],
-	'lb.client-java' => [ qw/jakarta-commons-lang/ ],
-);
-
-for my $jar (keys %need_jars) {
-	for (@{$need_jars{$jar}}) {
-		$need_externs_type{$jar}->{$_} = 'BR'; 	# XXX
-	}
-}
-
-%deps_aux = (
-	'lb.client' => [ qw/
-		lb.types:B lb.common
-		lbjp-common.trio
-		jobid.api-cpp:B jobid.api-c
-		lbjp-common.gss
-	/ ],
-	'lb.client-java' => [ qw/
-		lb.types:B
-		lb.ws-interface:B
-		jobid.api-java
-	/ ],
-	'lb.common' => [ qw/
-		jobid.api-cpp:B jobid.api-c
-		lb.types:B lbjp-common.trio lbjp-common.gss
-	/ ],
-	'lb.doc' => [ qw/lb.types:B/ ],
-	'lb.logger' => [ qw/
-		lbjp-common.trio
-		lbjp-common.log
-		jobid.api-c
-		lb.common
-		lbjp-common.gss
-	/ ],
-	'lb.logger-msg' => [ qw/
-		lb.logger:B
-	/ ],
-	'lb.nagios' => [ qw/
-		lb.client:R
-		lb.ws-test:R
-		lb.utils:R
-	/ ],
-	'lb.server' => [ qw/
-		lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R
-		lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log
-		jobid.api-c
-		lbjp-common.gsoap-plugin lbjp-common.gss
-	/ ],
-	'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ],
-	'lb.utils' => [ qw/
-		lbjp-common.jp-interface
-		jobid.api-c
-		lbjp-common.trio lbjp-common.maildir
-		lb.client lb.state-machine lb.types:B
-	/ ],
-	'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ],
-	'lb.ws-interface' => [ qw/lb.types:B/ ],
-	'lb.types' => [ qw// ],
-	'lb.harvester' => [ qw/
-		jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client
-		lbjp-common.gss lbjp-common.log
-	/ ],
-	'lb.yaim' => [ qw// ],
-	'lb.glite-LB' => [ qw/
-		lb.logger:R lb.server:R lb.utils:R lb.doc:R
-		lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R
-		lb.logger-msg:R
-	/ ],
-	'lb.emi-lb' => [ qw/
-		lb.logger:R lb.server:R lb.utils:R lb.doc:R
-		lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R
-		lb.logger-msg:R
-	/ ],
-	'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ],
-	'lbjp-common.maildir' => [ qw// ],
-	'lbjp-common.log' => [ qw// ],
-	'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ],
-	'lbjp-common.trio' => [ qw// ],
-	'lbjp-common.gss' =>  [ qw// ],
-	'lbjp-common.gsoap-plugin' =>  [ qw/lbjp-common.gss/ ],
-	'jobid.api-c' =>  [ qw// ],
-	'jobid.api-cpp' =>  [ qw/jobid.api-c/ ],
-	'jobid.api-java' =>  [ qw// ],
-
-	'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ],
-
-	'jp.client' => [ qw/
-                jp.ws-interface
-                lbjp-common.jp-interface lbjp-common.maildir
-                jobid.api-c
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.doc' => [ qw// ],
-	'jp.index' => [ qw/
-                jp.server-common jp.ws-interface
-                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.primary' => [ qw/
-                jobid.api-c
-                jp.server-common jp.ws-interface
-                lb.state-machine
-                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.server-common' => [ qw/ 
-                lbjp-common.jp-interface lbjp-common.db
-        / ],
-	'jp.ws-interface' => [ qw// ],
-
-	'gridsite.core' => [ qw// ],
-	'gridsite.commands' => [ qw/gridsite.core:B/ ],
-	'gridsite.apache' => [ qw/gridsite.core:B/ ],
-	'gridsite.libs' => [ qw/gridsite.core:B / ],
-	'gridsite.devel' => [ qw/gridsite.core:B/ ],
-	'gridsite.slashgrid' => [ qw/gridsite.core:B/],
-	'gridsite.services' => [ qw/gridsite.core:B/ ],
-	'gridsite.service-clients' => [ qw/gridsite.core:B/ ],
-	'gridsite.gsexec' => [ qw/gridsite.core:B/ ],
-
-	'px.proxyrenewal' => [ qw// ],
-	'px.glite-PX' => [qw/px.myproxy-yaim:R/],
-	'px.emi-px' => [qw/px.myproxy-yaim:R/],
-	'px.myproxy-yaim' => [ qw// ],
-	'px.myproxy-config' => [],
-
-	'canl.c' => [],
-
-	# sub-packages (virtual ETICS components depending on the main)
-	'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ],
-	'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ],
-	'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ],
-	'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ],
-	'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ],
-	'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ],
-	'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ],
-	'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ],
-	'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ],
-	'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ],
-	'lb.client-progs' => [ qw/lb.client:B/ ],
-	'lb.client-devel' => [ qw/lb.client:B/ ],
-	'lb.common-devel' => [ qw/lb.common:B/ ],
-	'lb.logger-devel' => [ qw/lb.logger:B/ ],
-	'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ],
-	'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ],
-	'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ],
-	'canl.c-devel' => [ qw/canl.c:B/ ],
-);
-
-for my $ext (keys %deps_aux) {
-	for (@{$deps_aux{$ext}}) {
-		/([^:]*)(?::(.*))?/;
-		push @{$deps{$ext}},$1;
-		my $type = $2 ? $2 : 'BR';
-		$deps_type{$ext}->{$1} = $type;
-	}
-}
-
-
-%extrafull = (
-	gridsite=>'org.gridsite.core',
-	'canl.c' => 'emi.canl.canl-c',
-	'canl.c-devel' => 'emi.canl.canl-c',
-	'jobid.api-c-devel' => 'org.glite.jobid.api-c',
-	'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp',
-	'lbjp-common.db-devel' => 'org.glite.lbjp-common.db',
-	'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin',
-	'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss',
-	'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface',
-	'lbjp-common.log-devel' => 'org.glite.lbjp-common.log',
-	'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir',
-	'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones',
-	'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio',
-	'lb.client-devel' => 'org.glite.lb.client',
-	'lb.client-progs' => 'org.glite.lb.client',
-	'lb.common-devel' => 'org.glite.lb.common',
-	'lb.logger-devel' => 'org.glite.lb.logger',
-	'lb.state-machine-devel' => 'org.glite.lb.state-machine',
-	'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal',
-	'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal',
-);
-
-#( java => 'client-java' );
-%extranodmod = (
-	db => 'lbjp-common.db',
-	jpprimary => 'jp.primary',
-	jpindex => 'jp.index',
-	jpclient => 'jp.client',
-	lb => 'lb.glite-LB',
-	px => 'px.glite-PX',
-	proxyrenewal => 'px.proxyrenewal',
-	canl => 'canl.c',
-);
-
-%obsoletes = (
-	'lb.yaim' => [ qq/glite-yaim-lb/ ],
-	'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ],
-	'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ],
-	'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec
-	'lbjp-common.gss' => [ qq/glite-security-gss/ ],
-	'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
-);
-
-%conflicts = (
-);
-
-%provides = (
-	'lbjp-common.gss' => [ qq/glite-security-gss/ ],
-	'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
-	'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ],
-);
-
-%cvs_prefix = (
-	'lb' => 'org.glite',
-	'jp' => 'org.glite',
-	'jobid' => 'org.glite',
-	'lbjp-common' => 'org.glite',
-	'gridsite' => 'org',
-	'px' => 'org.glite',
-	'canl' => 'emi',
-);
-
-%cvs_tag_prefix = (
-	'lb' => 'glite-',
-	'jp' => 'glite-',
-	'jobid' => 'glite-',
-	'lbjp-common' => 'glite-',
-	'gridsite' => '',
-	'px' => 'glite-',
-	'canl' => 'emi-',
-);
-
-# ==== projects specification ====
-# etics_name ........... ETICS project name
-# conf_prefix .......... ETICS configurations name prefix
-# tag_prefix ........... VCS tag prefix
-# local_prefix ......... prefix (relative to stage)
-# etics_externs ........ ETICS modules names of externals
-#                        (${NAME.location}, ETICS conf. dependencies)
-# etics_projects ....... ETICS project names of externals
-# etics_externs_devel .. ETICS modules names of devel versions of externals
-# etics_locations ...... ETICS locations in ${NAME.location} properties
-# need_externs_aux ..... project-specific external dependencies
-# supported_platforms .. platforms supported by the project
-# modules .............. additional modules in subsystems
-%projects = (
-	glite => {
-		current_version => 3,
-		etics_name => 'org.glite',
-		conf_prefix => { %cvs_tag_prefix },
-		tag_prefix => { %cvs_tag_prefix },
-		flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}',
-		local_prefix => '',
-		etics_externs => {
-			default => {
-				globus_essentials=>'vdt_globus_essentials',
-				globus=>'globus',
-				globus_proxy_utils=>'vdt_globus_essentials',
-				gridsite=>'org.gridsite.libs',
-				yaim_core=>'org.glite.yaim.core',
-				gip_release=>'glite-info-provider-release',
-				gip_service=>'glite-info-provider-service',
-				bdii=>'bdii',
-				glite_version=>'glite-version',
-				glite_info_templates=>'glite-info-templates',
-				glue_schema=>'glue-schema',
-				trustmanager=>'org.glite.security.trustmanager',
-				axis=>'axis',
-				lcas=>'org.glite.security.lcas',
-				gsoapxx=>'-',
-				jdk=>'jdk',
-				voms=>'org.glite.security.voms-api-cpp',
-			},
-		},
-		etics_externs_devel => {
-			default => {
-				gridsite=>'org.gridsite.devel',
-				voms=>'org.glite.security.voms-api',
-			},
-		},
-		etics_projects => {
-			vdt=>[qw/globus globus_essentials globus_proxy_utils gpt/],
-			'org.glite'=>[qw/voms gridsite lcas gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/],
-		},
-		etics_locations => {
-			'*' => '',
-		},
-		need_externs_aux => {
-			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ],
-			'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ],
-			'lb.yaim' => [ qw/yaim_core:R/ ],
-			'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/],
-			'px.myproxy-yaim' => [ qw/yaim_core:R/ ],
-		},
-		supported_platforms => {
-			sl5_x86_64_gcc412 => 1,
-			sl5_ia32_gcc412 => 1,
-			deb5_x86_64_gcc432 => 1,
-			deb5_ia32_gcc432 => 1,
-			slc4_x86_64_gcc346 => 1,
-			slc4_ia32_gcc346 => 1,
-		},
-		modules => {
-			'lb' => [ qw/glite-LB/ ],
-			'px' => [ qw/glite-PX/ ],
-		},
-	},
-
-	emi => {
-		current_version => 2,
-		etics_name => 'emi',
-		conf_prefix => {
-			'lb' => 'emi-',
-			'jp' => 'emi-',
-			'jobid' => 'emi-',
-			'lbjp-common' => 'emi-',
-			'gridsite' => 'emi-',
-			'px' => 'emi-',
-			'canl' => 'emi-',
-		},
-		tag_prefix => { %cvs_tag_prefix },
-		flavours => '--thrflavour= --nothrflavour=',
-		local_prefix => '/usr',
-		etics_externs => {
-			default => {
-				globus_essentials=>'globus-gssapi-gsi',
-				globus=>'globus-gssapi-gsi-devel',
-				globus_proxy_utils=>'globus-proxy-utils',
-				gridsite=>'emi.gridsite.libs',
-				yaim_core=>'emi.yaim.yaim-core',
-				yaim_bdii=>'emi.bdii.yaim-bdii',
-				gip_service=>'emi.bdii.glite-info-provider-service',
-				bdii=>'emi.bdii.core',
-				glite_version=>'emi.emi-version',
-				glue_schema=>'emi.bdii.glue-schema',
-				trustmanager=>'emi.java-security.trustmanager',
-				trustmanager_axis=>'emi.java-security.trustmanager-axis',
-				axis=>'axis1.4',
-				lcas=>'emi.sac.lcas',
-				gsoapxx=>'-',
-				jdk=>'java',
-				voms => 'emi.voms.voms-api',
-			},
-			sl5_x86_64_gcc412EPEL => {
-				'myproxy-devel' => 'myproxy-devel.x86_64',
-			},
-			sl6_x86_64_gcc446EPEL => {
-				'myproxy-devel' => 'myproxy-devel.x86_64',
-			},
-			deb6_x86_64_gcc445 => {
-				axis => 'axis1.4',
-				# mappings in ETICS project configuration
-				#globus_essentials => 'libglobus-gssapi-gsi4',
-				#globus => 'libglobus-gssapi-gsi-dev',
-				#axis => 'libaxis-java',
-				#cares => 'libc-ares2',
-				#cppunit => 'libcppunit',
-				#expat => 'libexpat1',
-				#log4c => 'liblog4c3',
-				#curl => 'libcurl3',
-				#'mysql' => 'libmysqlclient16',
-				#'mysql-devel' => 'libmysqlclient-dev',
-				#libxslt => 'xsltproc',
-				#'jakarta-commons-codec' => 'libcommons-codec-java',
-				#'jakarta-commons-lang' => 'libcommons-lang-java',
-				#'tetex-latex' => 'texlive-latex-extra',
-				#'perl-LDAP' => 'libnet-ldap-perl',
-				#'fuse-lib' => 'libfuse2',
-				#'fuse' => 'fuse-utils',
-			},
-		},
-		etics_externs_devel => {
-			default => {
-				cares => 'c-ares-devel',
-				classads => 'classads-devel',
-				cppunit => 'cppunit-devel',
-				expat => 'expat-devel',
-				gsoap => 'gsoap-devel',
-				voms => 'emi.voms.voms-api-devel',
-				libtar => 'libtar-devel',
-				log4c => 'log4c-devel',
-				postgresql => 'postgresql-devel',
-				curl => 'curl-devel',
-				libxml2 => 'libxml2-devel',
-				openssl => 'openssl-devel',
-				gridsite=>'emi.gridsite.devel',
-				jdk=>'java-devel',
-			},
-			deb6_x86_64_gcc445 => {
-				# mappings in ETICS project configuration
-				#cares => 'libc-ares-dev',
-				#cppunit => 'libcppunit-dev',
-				#expat => 'libexpat1-dev',
-				#libtar => 'libtar-dev',
-				#log4c => 'liblog4c-dev',
-				#postgresql => 'libpq-dev',
-				#curl => 'libcurl4-openssl-dev',
-				#libxml2 => 'libxml2-dev',
-				#openssl => 'libssl-dev',
-				#'tetex-latex' => 'texlive-latex-extra',
-				#libxslt=>'xsltproc',
-				#'httpd-devel' => 'apache2-prefork-dev',
-				#'fuse-devel' => 'libfuse-dev',
-				#gsoap => 'gsoap',
-				#'krb5-devel' => 'libkrb5-dev',
-			},
-		},
-		etics_projects => {
-			'emi'=>[qw/voms voms-devel gridsite lcas gip_service bdii glite_version glue_schema yaim_core yaim_bdii trustmanager trustmanager_axis/],
-		},
-		etics_locations => {
-			axis => 'axis',
-		},
-		need_externs_aux => {
-			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ],
-			'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ],
-			'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ],
-			'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/],
-			'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ],
-		},
-		supported_platforms => {
-			sl5_x86_64_gcc412EPEL => 1,
-			sl5_ia32_gcc412EPEL => 1,
-			sl6_x86_64_gcc446EPEL => 1,
-			deb6_x86_64_gcc445 => 1,
-		},
-		modules => {
-			'lb' => [ qw/emi-lb/ ],
-			'px' => [ qw/emi-px/ ],
-		},
-	},
-);
-
-%platform_properties = (
-	'jobid.api-java' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.types' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.doc' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.ws-interface' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.yaim' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.nagios' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'px.yaim' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'px.myproxy-config' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'gridsite.devel' => {
-		default => { 'packageName' => 'gridsite-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' },
-	},
-	'canl.c-devel' => {
-		default => { 'packageName' => 'canl-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' },
-	},
-	'jobid.api-c-devel' => {
-		default => { 'packageName' => 'glite-jobid-api-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' },
-	},
-	'jobid.api-cpp-devel' => {
-		default => { 'packageName' => 'glite-jobid-api-cpp-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' },
-	},
-	'lbjp-common.db-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-db-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' },
-	},
-	'lbjp-common.gsoap-plugin-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' },
-	},
-	'lbjp-common.gss-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-gss-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' },
-	},
-	'lbjp-common.jp-interface-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' },
-	},
-	'lbjp-common.log-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-log-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' },
-	},
-	'lbjp-common.maildir-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-maildir-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' },
-	},
-	'lbjp-common.server-bones-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' },
-	},
-	'lbjp-common.trio-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-trio-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' },
-	},
-	'lb.client-devel' => {
-		default => { 'packageName' => 'glite-lb-client-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' },
-	},
-	'lb.common-devel' => {
-		default => { 'packageName' => 'glite-lb-common-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' },
-	},
-	'lb.state-machine-devel' => {
-		default => { 'packageName' => 'glite-lb-state-machine-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' },
-	},
-	'lb.logger-devel' => {
-		default => { 'packageName' => 'glite-lb-logger-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' },
-	},
-	'px.proxyrenewal-devel' => {
-		default => { 'packageName' => 'glite-px-proxyrenewal-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' },
-	},
-	'canl.c-devel' => {
-		default => { 'packageName' => 'canl-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' },
-	},
-);
-
-my @k = keys %deps_aux;
-@buildroot{@k} = ('') x ($#k+1);
-
-$buildroot{'gridsite.core'} = 'src';
-}
-
-sub full
-{
-	my ($short) = @_;
-	my $subsys = $short;
-	$subsys =~ s/\..*//;
-
-	my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite';
-	return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short";
-}
-
-sub get_version
-{
-	my ($fmod, $top_srcdir) = @_;
-
-	my ($subsys,$mod) = split /\./,$fmod,2;
-	my ($major,$minor,$rev,$age);
-	my $old_;
-
-	if ($force_version) {
-		$force_version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/;
-		($major,$minor,$rev,$age) = ($1,$2,$3,$4);
-	}
-	else {
-		my $path = "$top_srcdir/project";
-		if ($subsys eq 'gridsite') {
-			$path = "$cvs_prefix{$subsys}.$subsys.core/project";
-		}
-		open V,"$path/version.properties"
-			or die "$path/version.properties: $!\n";
-
-		$old_ = $_;
-		while () {
-			chomp;
-			($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/;
-			$age = $1 if /module\.age\s*=\s*([[:digit:]]+)/;
-		}
-		close V;
-		$_ = $old_;
-	}
-	$version = "$major.$minor.$rev-$age";
-
-	return ($major, $minor, $rev, $age);
-}
-
-sub get_description
-{
-	my ($top_srcdir) = @_;
-
-	my $cvs_module = $top_srcdir;
-	my $package_description = "";
-	my $package_summary = "";
-
-	if (-e "$cvs_module/project/package.description") {
-		open V, "$cvs_module/project/package.description";
-		$package_description = join ("", );
-		close V;
-		chomp $package_description;
-	}
-	else {
-		print STDERR "package.description not found for $subsys.$module!\n"; }
-
-	if (-e "$cvs_module/project/package.summary") {
-		open V, "$cvs_module/project/package.summary";
-		$package_summary = join ("", );
-		close V;
-		chomp $package_summary;
-		$package_summary =~ s/\n/\\n/g;
-	}
-	else {
-		print STDERR "package.summary not found for $subsys.$module!\n"; }
-
-	return ($package_summary, $package_description);
-}
-
-sub mkinc
-{
-	my %aux;
-	undef %aux;
-	my @m=qw/
-lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb
-lbjp-common.gss lbjp-common.gsoap-plugin
-jobid.api-c jobid.api-cpp jobid.api-java
-lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin
-jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface
-px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px
-canl.c
-/;
-	@aux{@m} = (1) x ($#m+1);
-
-	my ($short) = @_;
-	my $full = full $short;
-	my ($subsys,$mod) = split /\./,$short,2;
-	my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}";
-
-	unless ($aux{$short}) {
-		print "Makefile.inc not needed in $full\n";
-		return;
-	}
-
-	my $top_srcdir = '.';
-	my $abs_srcdir = '';
-	my $build = '';
-
-	if ($module) {
-		$top_srcdir = $0;
-		$top_srcdir =~ s,/?[^/]*$,,;
-		$abs_srcdir = $top_srcdir;
-		$top_srcdir =~ s,^$,\.,;
-	} else {
-		$build = "$full/";
-		$abs_srcdir = "$full/";
-		unless ($buildroot{$_} eq '') {
-			$top_srcdir = '..';
-			$build .= "$buildroot{$_}/";
-			unless (-d "$build") {
-				mkdir "$build" or die "mkdir $build: $!\n";
-			}
-		}
-	}
-
-	my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir;
-	my ($package_summary, $package_description) = get_description $abs_srcdir;
-	if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; }
-	my $package_description_debian = $package_description;
-	$package_description_debian =~ s/^/ /mg;
-
-	my ($old_locale, $specdate, $debdate);
-
-	# files for ETICS always in root source directory
-	mkdir $abs_srcdir."project" unless (-d $abs_srcdir."project");
-	open PKGCHL,">".$abs_srcdir."project/changelog"
-		or die $abs_srcdir."project/changelog: $!\n";
-	$old_locale = setlocale(LC_TIME);
-	setlocale(LC_TIME, "C");
-	$specdate = strftime("%a %b %d %Y", gmtime());
-	$debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime());
-	setlocale(LC_TIME, $old_locale);
-	print PKGCHL qq{* $specdate CESNET team 
-- automatically generated package
-};
-	close PKGCHL;
-
-	unless ($top_srcdir eq '.') {
-		unlink $build."Makefile";
-		symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n";
-	}
-
-	open MKINC,">".$build."Makefile.inc"
-		or die $build."Makefile.inc: $!\n";
-
-	print "Creating ".$build."Makefile.inc\n";
-
-	print MKINC qq{project = $project
-PREFIX = $root
-prefix = $prefix
-stagedir = $stagedir
-sysroot = $sysroot
-sysconfdir = $sysconfdir
-localstatedir = $localstatedir
-thrflavour = $thrflavour
-nothrflavour = $nothrflavour
-libdir = $libdir
-top_srcdir = $top_srcdir
-};
-
-	for (@{$need_externs{$short}}) {
-		next unless defined $externs{$_} and defined $externs{$_}{prefix};
-		print MKINC "${_}_prefix = $externs{$_}{prefix}\n";
-		print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags};
-	}
-
-	for (@{$need_jars{$short}}) {
-		print MKINC "${_}_jar = $jar{$_}\n"
-	}
-
-	my $need_gsoap = 0;
-	for (@{$need_externs{$short}})  { $need_gsoap = 1 if $_ eq 'gsoap'; }
-
-	print MKINC "gsoap_default_version=".gsoap_version()."\n"  if $need_gsoap;
-
-	close MKINC;
-
-	my $dh;
-	my $debian = 0;
-
-	opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!";
-	for my $dir (readdir $dh) {
-		if ($dir=~/^(.*)\.spec$/) {
-			if ($1 ne $packageName) {
-				printf STDERR "Changed RPM name: $packageName --> $1\n" if ($debug);;
-				$packageName=$1;
-			}
-			last;
-		}
-	}
-	closedir $dh;
-
-	for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") {
-		if (-f "$abs_srcdir/project/$file") {
-			my $old_ = $_;
-			printf STDERR "Creating $build$file\n" if ($debug);;
-			open DST, ">$build$file";
-			open SRC, "<$abs_srcdir/project/$file";
-			while () {
-				if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; }
-				if (/\@URL\@/) { s/\@URL\@/$package{url}/g; }
-				if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; }
-				if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; }
-				if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; }
-				if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; }
-				if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; }
-				if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; }
-				if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; }
-				if (/\@AGE\@/) { s/\@AGE\@/$age/g; }
-				if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; }
-				if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; }
-				if (/\@DEBIAN_VCS\@/) { s/\@DEBIAN_VCS\@/$package{debian_vcs}/g; }
-				if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; }
-				if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; }
-				if (/^\s*.+\/configure\s/ and $force_version) {
-					print "Version forced to $version\n" if ($debug);;
-					s/--version\s+\S+\s?//;
-					s/$/ --version $version/;
-				}
-				printf DST "%s", "$_";
-			}
-			close SRC;
-			close DST;
-			$_ = $old_;
-		}
-	}
-
-	print "Creating ${build}debian/\n" if ($debug);;
-
-	`rm -rfv  ${build}debian`;
-	mkdir $build."debian" or die $!;
-	`cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`;
-	`mv ${build}debian.* ${build}debian/ 2>/dev/null`;
-	`rm -f ${build}debian/*.orig`;
-	opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!";
-	for $_ (readdir $dh) {
-		if (/^debian\.(.*)/) {
-			`mv ${build}debian/$_ ${build}debian/$1`;
-			$debian = 1;
-		}
-	}
-	closedir $dh;
-
-	if ($debian) {
-		my ($dir, $file);
-
-		chmod 0755, "${build}debian/rules";
-		$file="${build}debian/docs"; if (not -f $file) { `touch $file`; }
-		$dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; }
-		$file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` }
-		$file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` }
-		$file="${build}debian/changelog"; if (not -f $file) {
-			open FH, ">$file" or die $!;
-			print FH qq{$packageName ($major.$minor.$rev-$age) unstable; urgency=low
-
-  * Automatically generated package
-
- -- $package{maintainer}  $debdate
-};
-			close FH;
-		}
-
-	} else {
-		`rm -rf ${build}debian`;
-	}
-}
-
-BEGIN{
-};
-
-sub mode_etics_packaging {
-	my ($fmod, $cmd, $rpmprepare, $debprepare) = @_;
-	my ($workspaceDir, $srcPackageName, $srcAge, $topDir);
-
-	# old-school packaging by ETICS for EMI-1
-	if ($project eq 'emi' and $project_version == 1) { return; }
-
-	if ($fmod eq 'gridsite.core') {
-		$workspaceDir = '..';
-		$srcPackageName = 'gridsite';
-		$srcAge = '';
-		$topDir = '../';
-	} else {
-		$workspaceDir = '${workspaceDir}';
-		$srcPackageName = '${packageName}';
-		$srcAge = '-${age}';
-		$topDir = '';
-	}
-
-	$cmd->{clean} = 'make clean
-	rm -rfv ${package.tgzLocation} ${package.SRPMSLocation}';
-	$cmd->{default}{packaging} = $rpmprepare;
-	$cmd->{default}{packaging} .= "dir=\${workspaceDir}/rpm_build_src_\$\$
-	mkdir -p \${package.tgzLocation} \${package.SRPMSLocation} \$dir/{BUILD,RPMS,SOURCES,SRPMS} 2>/dev/null || true
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/SOURCES/
-	rpmbuild -bs --nodeps --define \"_topdir \$dir\" $srcPackageName.spec
-	cp -v \$dir/SRPMS/*.src.rpm \${package.SRPMSLocation}/
-	rm -rf \$dir";
-
-	for my $p ('deb5_x86_64_gcc432', 'deb5_ia32_gcc432', 'deb6_x86_64_gcc445', 'deb6_ia32_gcc445') {
-		for my $c (keys %{$cmd->{default}}) { $cmd->{$p}{$c} = $cmd->{default}{$c}; }
-		$cmd->{$p}{clean} = 'make clean
-	rm -rfv ${package.tgzLocation} ${package.SDEBSLocation}';
-		$cmd->{$p}{packaging} = $debprepare;
-		$cmd->{$p}{packaging} .= "dir=\${workspaceDir}/dpkg_build_src_\$\$
-	mkdir -p \${package.tgzLocation} \${package.SDEBSLocation} \$dir 2>/dev/null || true
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/${srcPackageName}_\${version}.orig.tar.gz
-	tar xzf \$dir/${srcPackageName}_\${version}.orig.tar.gz -C \$dir
-	cp -rf ${topDir}debian/ \$dir/$srcPackageName-\${version}/
-	cd \$dir/$srcPackageName-\${version}
-	dpkg-buildpackage -S -d -nc
-	cd -
-	cp -v \$dir/*.tar.gz \$dir/*.dsc \${package.SDEBSLocation}/
-	rm -rf \$dir";
-	}
-}
-
-sub mode_etics {
-	$fmod = shift;
-
-	die "$0: --module required with --etics\n" unless $fmod;
-	
-	my ($subsys,$module) = split /\./,$fmod,2;
-	my $full = full "$subsys.$module";
-
-	my ($major,$minor,$rev,$age) = get_version $fmod, $full;
-
-	# XXX: --with ignored for platform-dependend packages
-	my @copts = ();
-	my %ge;
-	@ge{@{$etics_projects{$project{etics_name}}}} = (1) x ($#{$etics_projects{$project{etics_name}}}+1);
-
-	for (@{$need_externs{"$subsys.$module"}}) {
-	    if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/ and (defined $externs{$_} or defined $jar{$_})) {
-		my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_;
-		next if ($eext eq '-');
-		if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}) {
-			$eext = $project{etics_locations}{$_} if ($project{etics_locations}{$_});
-			push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}";
-		} else {
-			if ($ge{$_} and not defined $externs{$_}{pkg}) {
-				push @copts, "--with-$_=\${stageDir}";
-			}
-		}
-	    }
-	}
-
-	for (@{$need_jars{"$subsys.$module"}}) {
-		my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_;
-
-		push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_});
-	}
-
-	my $conf;
-	my $conftag;
-	my ($confprefix, $nameprefix, $packageName);
-
-	$dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n";
-
-	$confprefix = $project{conf_prefix}{$subsys};
-	$nameprefix = $confprefix;
-	$nameprefix =~ s/-$//;
-	$nameprefix =~ s/-/\./g;
-	$packageName = "$project{tag_prefix}{$subsys}$subsys-${module}";
-
-	if ($branch) {
-		$conf = "$confprefix${subsys}-${module}_$branch"; 
-		$conftag = $branch;
-		# forced low age number
-		$age = $branch eq 'HEAD' ? '0head' : '0dev';
-		push @copts, '--version ${version}-${age}';
-	}
-	else {
-		$conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}";
-# XXX: gridsite hack
-		$conftag = $subsys eq 'gridsite' ? "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : 
-			"$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}";
-
-		# lowering age for older packaging
-		if ($project eq 'emi' and $project_version == 1) {
-			$age = $age - 1;
-		}
-	}
-
-	# emi1 suffix for older packaging
-	if ($project eq 'emi' and $project_version == 1) {
-		$age = $age.$project.$project_version;
-		$conf = $conf.$project.$project_version;
-	}
-
-	my $file = $output ? $output : "$conf.ini";
-	open C,">$file" or die "$file: $!\n";
-
-	my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"};
-
-	my $confdir = $buildroot{"$subsys.$module"} eq '' ? '.' : '..';
-
-	my $cvs_module = full "$subsys.$module";
-	my ($package_summary, $package_description) = get_description $cvs_module;
-	if ($package_description) {
-		$package_description =~ s/\n/\\n/g;
-		$package_description = "package.description = $package_description\n";
-	}
-	if ($package_summary) {
-		$package_summary = "package.summary = $package_summary\n";
-	}
-
-	my %cmd;
-	$cmd_vcs{checkout} = "cvs -d \${vcsroot} co -d \${moduleName} ".($conftag eq 'HEAD' ? '-A' : '-r ${tag}')." $cvs_module 2>/dev/null";
-	#$cmd_vcs{checkout} = "((test -d jra1mw/.git && (cd jra1mw; git pull)) || (git clone -q http://scientific.zcu.cz/git/jra1mw.git";
-	#$cmd_vcs{checkout} .= " && (cd jra1mw; git checkout -b \${tag} --track origin/\${tag})" unless ($conftag eq /HEAD/);
-	#$cmd_vcs{checkout} .= ")) && (test -d \${moduleName} || ln -s jra1mw/$cvs_module \${moduleName})";
-	$cmd_vcs{checkout} .= "\n\ttest -f \${packageName}-\${version}-\${age}.src.tar.gz || (ln -s \${moduleName} \${packageName}-\${version}; tar -chf - \${packageName}-\${version} --exclude CVS --exclude .git --exclude .etics | gzip --best > \${packageName}-\${version}-\${age}.src.tar.gz; rm \${packageName}-\${version})";
-	$cmd_vcs{tag} = "cvs -d \${vcsroot} tag -R \${tag} ${moduleName}";
-
-	$cmd{default}{init} = 'None';
-	$cmd{default}{configure} = 'None';
-	$cmd{default}{compile} = 'None';
-	$cmd{default}{test} = 'None';
-	$cmd{default}{install} = 'None';
-	$cmd{default}{packaging} = 'None';
-	$cmd{default}{clean} = 'make clean';
-
-	if (exists $subpackages{$fmod}) {
-		$cmd{default}{clean} = 'None';
-		$cmd{default}{packaging} = "echo building nothing, $subpackages{$fmod} will build this package";
-		$cmd_vcs{checkout} = "mkdir -v \${moduleName} 2>/dev/null || true";
-	} elsif ($subsys eq 'gridsite') {
-		$cmd_vcs{tag} = 'None';
-
-		if ($module eq 'core') {
-			my $flags;
-
-			if ($project ne 'glite') {
-				# don't evaluate pkg-config calls to get them into source package
-				$flags = 'RELEASE_VERSION=${age}
-	GSOAPDIR=\`pkg-config gsoap --variable=prefix\`
-	OPENSSL_GLOBUS_FLAGS=\`pkg-config globus-openssl --cflags\`
-	OPENSSL_GLOBUS_LIBS=\`pkg-config globus-openssl --libs\`';
-			} else {
-				$flags = 'RELEASE_VERSION=${age}
-	GSOAPDIR=${gsoap.location}
-	OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor}
-	OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir}
-	HTTPD_FLAGS=-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-1 -I${httpd-devel.location}/include/apr-1.0 -I${httpd-devel.location}/include/apr-0 -I${httpd-devel.location}/include/pcre';
-			}
-
-			$cmd{default}{configure} = "cat > Makefile.inc </dev/null";
-			$cmd{default}{init} = 'echo "/sbin/ldconfig" > project/.post
-	echo "/sbin/ldconfig" > project/.postun';
-			$cmd{default}{configure} = "cat > src/Makefile.inc <{default}}) {
-		$defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n";
-	}
-
-	print STDERR "Writing $file\n";
-	print C qq{
-[Configuration-$conf]
-profile = None
-moduleName = $project{etics_name}.$subsys.$module
-displayName = $conf
-description = $cvs_prefix{$subsys}.$subsys.$module
-projectName = $project{etics_name}
-age = $age
-deploymentType = None
-vcsroot = :pserver:anonymous\@glite.cvs.cern.ch:/cvs/glite
-tag = $conftag
-version = $major.$minor.$rev
-$dwpath
-[Platform-default:VcsCommand]
-displayName = None
-description = None
-tag = $cmd_vcs{tag}
-branch = None
-commit = None
-checkout = $cmd_vcs{checkout}
-
-};
-
-	for my $p (keys %cmd) {
-		next if $p ne 'default' and exists $project{supported_platforms} and not exists $project{supported_platforms}{$p};
-
-		print C qq{[Platform-$p:BuildCommand]
-postpublish = None
-packaging = $cmd{$p}{packaging}
-displayName = None
-description = None
-doc = None
-prepublish = None
-publish = None
-compile = $cmd{$p}{compile}
-init = $cmd{$p}{init}
-install = $cmd{$p}{install}
-clean = $cmd{$p}{clean}
-test = $cmd{$p}{test}
-configure = $cmd{$p}{configure}
-checkstyle = None
-
-};
-	}
-
-	print C qq{[Platform-default:Property]
-$buildroot
-package.preserve.libtool = false
-$package_description$package_summary$defprops};
-
-	for (@{$obsoletes{"$subsys.$module"}}) {
-		print C "package.obsoletes = $_\n";
-		print C "package.replaces = $_\n";
-	}
-	for (@{$conflicts{"$subsys.$module"}}) {
-		print C "package.conflicts = $_\n";
-	}
-	for (@{$provides{"$subsys.$module"}}) {
-		print C "package.provides = $_\n";
-	}
-	print C "\n";
-
-	for my $pp (keys %{$platform_properties{"$subsys.$module"}}) {
-		next if $pp eq 'default';
-		next if exists $project{supported_platforms} and not exists $project{supported_platforms}{$pp};
-
-		print C "[Platform-$pp:Property]\n$buildroot\n";
-
-		for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) {
-			print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n";
-		}
-		print C "$package_description$package_summary\n";
-	}
-
-	for my $platform ('default', keys %{$project{supported_platforms}}) {
-		my $used = 0;
-		my $output = '';
-
-		for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) {
-			my $eext = $etics_externs{$platform}{$_};
-			my $edev = $project{etics_externs_devel}{$platform}{$_};
-
-			# for the default platform using package of the same
-			# name for runtime dependency
-			if (not $eext) {
-				if ($platform eq 'default') {
-#print "default runtime $_ on default\n";
-					$eext = $_; }
-				else {
-#print "no runtime $_ on $platform\n";
-					$eext = '-'; }
-			}
-			if ($eext eq '-' and $edev eq '-') {
-#print "skipping $_ on $platform\n";
-				next;
-			}
-
-			my $proj = 'externals';
-			for my $p (keys %etics_projects) {
-				for $m (@{$etics_projects{$p}}) {
-					$proj = $p if $m eq $_;
-				}
-			}
-
-			my $type = $need_externs_type{"$subsys.$module"}->{$_};
-
-			if ($edev) {
-				if ($type eq 'B') {
-					# no runtime - change to devel pkg
-					$eext = $edev;
-				} elsif ($type eq 'BR' or $type eq 'RB') {
-					# additional devel pkg
-					if ($edev ne '-') { $output .= "$proj|$edev = B\n"; }
-				}
-			}
-			if ($eext ne '-') { $output .= "$proj|$eext = $type\n"; }
-		}
-
-		if ($platform eq 'default') {
-			for (@{$deps{"$subsys.$module"}}) {
-				my $type = $deps_type{"$subsys.$module"}->{$_};
-				if (not $used) {
-					$used = 1;
-				}
-				$output .= "$project{etics_name}|$project{etics_name}.$_ = $type\n";
-			}
-		}
-
-		if ($output) {
-					print C qq{
-[Platform-$platform:DynamicDependency]
-$output};
-		}
-	}
-
-	close C;
-
-	for $file ("$cvs_module/project/debian.rules", "$cvs_module/project/$packageName.spec") {
-		my $lib;
-		my $main_module;
-		@copts = ();
-
-		if ($file =~ /debian\.rules$/) { $lib = 'lib'; }
-		else { $lib = '%{_lib}'; }
-
-		my $main_module = "$subsys.$module";
-		if (exists $subpackages{$main_module}) { $main_module = $subpackages{$main_module}; }
-
-		# locations hacks
-		if ($file =~ /$packageName\.spec$/) {
-			if ($fmod eq 'lb.client-java') {
-				push @copts, '';
-				push @copts, '--with-axis=/usr/local/axis1.4';
-			}
-		}
-
-		if (-f $file) {
-			open DST,">$file.new" or die "$file.new: $!\n";
-			open SRC,"<$file" or die "$file: $!\n";
-			while () {
-				if (/^(\s*).+\/configure\s/) {
-					printf DST "%s", "$1";
-					printf DST "/usr/bin/perl $confdir/configure $project{flavours} --root=/ --prefix=$project{local_prefix} --libdir=$lib --project=$project --module $main_module@copts\n";
-				} else {
-					printf DST "%s", "$_";
-				}
-			}
-			close SRC;
-			close DST;
-
-			`diff -b "$file" "$file.new"`;
-			if ($? == 0) {
-				print STDERR "($file not changed)\n";
-				unlink "$file.new";
-			} else {
-				print STDERR "Writing $file\n";
-				rename "$file", "$file.orig" unless -f "$file.orig";
-				rename "$file.new", "$file";
-			}
-		}
-	}
-}
-
-sub gsoap_version {
-	local $_;
-	my $gsoap_version;
-	open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n";
-
-	while ($_ = ) {
-		chomp;
-
-		$gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/;
-		$gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/;
-	}
-	close S;
-	return $gsoap_version;
-}
-
-sub getlibdir {
-	if ( -e "/etc/debian_version") { # We are on Debian
-		$lib64="lib";
-		$lib32="lib32";	}
-	else { # Another distribution
-		$lib64="lib64";
-		$lib32="lib";	}
-        $libdir=$lib32;
-
-        open INP, "uname -s | "; # Check kernel name
-        $kname= ;
-        chomp($kname);
-        close INP;
-
-        if ( $kname eq "Linux") {
-                $arch = ("x86_64\npowerpc\nppc64\n");
-
-                open INP, "uname -p | "; # Check processor type
-                $procname= ;
-                chomp($procname);
-                close INP;
-
-                if ($arch =~/^$procname\n/) {
-                        return ($lib64); }
-
-                open INP, "uname -m | "; # Check machine hardware
-                $machname= ;
-                chomp($machname);
-                close INP;
-
-                if ($arch =~/^$machname\n/) {
-                        return ($lib64); }
-
-                # special cases (hyperlink lib64, Debian)
-                if (-l "/usr/lib64") {
-                        $libdir=$lib32; }
-
-                # if /usr/lib64 doesn't exist at all (AIX)
-                unless ( -e "/usr/lib64" ) {
-                        $libdir=$lib32; }
-        }
-
-        if ( $kname eq "SunOS") {
-                if (-e "/usr/lib/64") {
-                $libdir="lib/64"; }
-        }
-
-        return $libdir;
-}
-
-sub reshuffle_platforms($$) {
-	my ($data, $platforms) = @_;
-	my ($platform, %blacklist, $value);
-
-	return if not $platforms;
-
-	for $platform (keys %$data) {
-#print "plat: $platform: $data->{$platform}\n";
-		next if $platform eq 'default';
-		for $_ (keys %{$data->{$platform}}) {
-#print "  blacklist: $_ = $data->{$platform}{$_}\n";
-			$blacklist{$_} = 1;
-		}
-	}
-
-	for $_ (keys %blacklist) {
-		$value = $data->{default}{$_} ? $data->{default}{$_} : $_;
-		for $platform (keys %$platforms) {
-			next if $platform eq 'default';
-			if (not defined $data->{$platform}{$_}) {
-				$data->{$platform}{$_} = $value;
-#print "added $value to $platform\n"
-			}
-		}
-		$data->{default}{$_} = '-';
-#print "deleted $_ from default\n";
-	}
-
-	# merge dependencies across the supported platforms
-	%blacklist = [];
-	for $platform (keys %$platforms) {
-		next if $platform eq 'default';
-		for $_ (keys %{$data->{$platform}}) {
-			$blacklist{$_} = 1;
-		}
-	}
-	for $_ (keys %blacklist) {
-		$value = undef;
-		$same = 1;
-		for $platform (keys %$platforms) {
-			if (not $value) { $value = $data->{$platform}{$_}; }
-			if (not $data->{$platform}{$_} or $value ne $data->{$platform}{$_}) {
-				$same = 0;
-				last;
-			}
-		}
-		if ($same and $value) {
-#print "merged dependency $_\n";
-			$data->{default}{$_} = $value;
-			for $platform (keys %$platforms) {
-				delete $data->{$platform}{$_};
-			}
-		}
-	}
-}
-
-sub usage {
-	my @ext = keys %externs;
-	my @myjars = keys %jar;
-
-	print STDERR qq{
-Usage: $0 options
-
-General options (defaults in []):
-  --prefix=PREFIX		destination directory [./stage]
-  --stage=DIR			staging directory [./stage]
-  --root=DIR			installation root (custom relocation root -> sysroot) [./stage]
-  --sysroot=DIR			system root (custom relocation root -> sysroot) []
-  --sysconfdir=DIR              system configuration directory [PREFIX/etc]
-  --staged=module,module,...	what is already in PREFIX (specify without org.glite.)
-  --thrflavour=flavour
-  --nothrflavour=flavour	threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg]
-  --listmodules=subsys          list modules of a subsystem
-  --listmodules=module          list subpackages of a module
-  --version=maj.min.rev-age	version used instead of reading version.properties
-  --branch=branch		CVS branch/etics name suffix (HEAD, branch_2_1, ...)
-  --libdir=libdir		typically [lib,lib64] postfix
-  --project=PROJECT		build or generate etics for a project (glite/emi1/emi) [emi]
-  --debug			print more details
-  
-Mode of operation:
-  --mode=\{checkout|build|etics\}	what to do [build]
-  
-What to build:
-  --module=module		build this module only
-  --enable-NODE			build this "node" (set of modules) only
-  --disable-NODE		don't build this node
-  --lb-tag=tag			checkout LB modules with specific tag
-  --jp-tag=tag			checkout JP modules with specific tag
-  --lbjp-common-tag=tag         checkout lbjp-common modules with specific tag
-  --jobid-tag=tag		checkout jobid modules with specific tag
-  --canl-tag=tag		checkout canl modules with specific tag
-
-Dependencies (summary of what will be used is always printed):
-  --with-EXTERNAL=PATH		where to look for an external [autodetect]
-  --with-JAR=JAR		where to look for jars
-
-Available nodes:
-    @nodes
-
-Default nodes:
-    @default_nodes
-
-Externals (not all for all modules) are:
-    @ext
-
-External jars are:
-    @myjars
-
-};
-
-}
diff --git a/org.glite.lb.logger-msg/examples/cmsclient.cpp b/org.glite.lb.logger-msg/examples/cmsclient.cpp
deleted file mode 100644
index d703cf2..0000000
--- a/org.glite.lb.logger-msg/examples/cmsclient.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *	 http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-using namespace activemq;
-using namespace activemq::core;
-using namespace activemq::transport;
-using namespace decaf::lang;
-using namespace decaf::util;
-using namespace decaf::util::concurrent;
-using namespace cms;
-using namespace std;
-
-////////////////////////////////////////////////////////////////////////////////
-class SimpleAsyncConsumer : public ExceptionListener,
-							public MessageListener,
-							public DefaultTransportListener {
-
-private:
-
-	Connection* connection;
-	Session* session;
-	Destination* destination;
-	MessageConsumer* consumer;
-	bool useTopic;
-	bool clientAck;
-	std::string brokerURI;
-	std::string destURI;
-	FILE * outputfile;
-
-public:
-
-	SimpleAsyncConsumer( const std::string& brokerURI,
-						 const std::string& destURI,
-						 bool useTopic = false,
-						 bool clientAck = false ) {
-		connection = NULL;
-		session = NULL;
-		destination = NULL;
-		consumer = NULL;
-		this->useTopic = useTopic;
-		this->brokerURI = brokerURI;
-		this->destURI = destURI;
-		this->clientAck = clientAck;
-	}
-
-	virtual ~SimpleAsyncConsumer(){
-		this->cleanup();
-	}
-
-	void close() {
-		this->cleanup();
-	}
-
-	void runConsumer() {
-
-		try {
-
-			// Create a ConnectionFactory
-			ActiveMQConnectionFactory* connectionFactory =
-				new ActiveMQConnectionFactory( brokerURI );
-
-			// Create a Connection
-			connection = connectionFactory->createConnection();
-			delete connectionFactory;
-
-			ActiveMQConnection* amqConnection = dynamic_cast( connection );
-			if( amqConnection != NULL ) {
-				amqConnection->addTransportListener( this );
-			}
-
-			connection->start();
-
-			connection->setExceptionListener(this);
-
-			// Create a Session
-			if( clientAck ) {
-				session = connection->createSession( Session::CLIENT_ACKNOWLEDGE );
-			} else {
-				session = connection->createSession( Session::AUTO_ACKNOWLEDGE );
-			}
-
-			// Create the destination (Topic or Queue)
-			if( useTopic ) {
-				destination = session->createTopic( destURI );
-			} else {
-				destination = session->createQueue( destURI );
-			}
-
-			// Create a MessageConsumer from the Session to the Topic or Queue
-			consumer = session->createConsumer( destination );
-			consumer->setMessageListener( this );
-
-		} catch (CMSException& e) {
-			e.printStackTrace();
-		}
-	}
-
-	// Called from the consumer since this class is a registered MessageListener.
-	virtual void onMessage( const Message* message ){
-
-		static int count = 0;
-
-		try
-		{
-			count++;
-			const TextMessage* textMessage =
-				dynamic_cast< const TextMessage* >( message );
-			string text = "";
-
-			if( textMessage != NULL ) {
-				text = textMessage->getText();
-			} else {
-				text = "NOT A TEXTMESSAGE!";
-			}
-
-			if( clientAck ) {
-				message->acknowledge();
-			}
-
-			fprintf(outputfile, "Message #%d Received: %s\n", count, text.c_str() );
-			fflush(outputfile);
-		} catch (CMSException& e) {
-			e.printStackTrace();
-		}
-	}
-
-	// If something bad happens you see it here as this class is also been
-	// registered as an ExceptionListener with the connection.
-	virtual void onException( const CMSException& ex AMQCPP_UNUSED ) {
-		fprintf(stderr, "CMS Exception occurred.  Shutting down client.\n");
-		//exit(1);
-	}
-
-	virtual void transportInterrupted() {
-		fprintf(stderr, "The Connection's Transiort has been Interrupted.\n");
-	}
-
-	virtual void transportResumed() {
-		fprintf(stderr, "The Connection's Transport has been Restored.\n");
-	}
-
-	virtual void setOutfile(FILE * setout) {
-		outputfile=setout;
-	}
-
-private:
-
-	void cleanup(){
-
-		//*************************************************
-		// Always close destination, consumers and producers before
-		// you destroy their sessions and connection.
-		//*************************************************
-
-		// Destroy resources.
-		try{
-			if( destination != NULL ) delete destination;
-		}catch (CMSException& e) {}
-		destination = NULL;
-
-		try{
-			if( consumer != NULL ) delete consumer;
-		}catch (CMSException& e) {}
-		consumer = NULL;
-
-		// Close open resources.
-		try{
-			if( session != NULL ) session->close();
-			if( connection != NULL ) connection->close();
-		}catch (CMSException& e) {}
-
-		// Now Destroy them
-		try{
-			if( session != NULL ) delete session;
-		}catch (CMSException& e) {}
-		session = NULL;
-
-		try{
-			if( connection != NULL ) delete connection;
-		}catch (CMSException& e) {}
-		connection = NULL;
-	}
-};
-
-////////////////////////////////////////////////////////////////////////////////
-int main(int argc AMQCPP_UNUSED, char* argv[] AMQCPP_UNUSED) {
-	char *argbrokerURI = NULL;
-	char *argdestURI = NULL;
-	char *outputfile = NULL;
-	FILE * outfile;
-	int i;
-
-
-	for(i=1; i]  \n", argv[0]);
-		return 1;
-	}
-
-	activemq::library::ActiveMQCPP::initializeLibrary();
-
-	fprintf(outfile, "=====================================================\n");
-	fprintf(outfile, "Starting the example:\n");
-	fprintf(outfile, "-----------------------------------------------------\n");
-
-	// Set the URI to point to the IPAddress of your broker.
-	// add any optional params to the url to enable things like
-	// tightMarshalling or tcp logging etc.  See the CMS web site for
-	// a full list of configuration options.
-	//
-	//  http://activemq.apache.org/cms/
-	//
-	// Wire Format Options:
-	// =====================
-	// Use either stomp or openwire, the default ports are different for each
-	//
-	// Examples:
-	//	tcp://127.0.0.1:61616					  default to openwire
-	//	tcp://127.0.0.1:61616?wireFormat=openwire  same as above
-	//	tcp://127.0.0.1:61613?wireFormat=stomp	 use stomp instead
-	//
-	std::string brokerURI = "failover:(tcp://";
-	brokerURI += argbrokerURI;
-	brokerURI += ")";
-
-//	std::string brokerURI =
-//		"failover:(tcp://harad.ics.muni.cz:61616"
-//		"?wireFormat=openwire"
-//		"&connection.useAsyncSend=true"
-//		"&transport.commandTracingEnabled=true"
-//		"&transport.tcpTracingEnabled=true"
-//		"&wireFormat.tightEncodingEnabled=true"
-//		")";
-
-	//============================================================
-	// This is the Destination Name and URI options.  Use this to
-	// customize where the consumer listens, to have the consumer
-	// use a topic or queue set the 'useTopics' flag.
-	//============================================================
-	std::string destURI = argdestURI; //?consumer.prefetchSize=1";
-
-	//============================================================
-	// set to true to use topics instead of queues
-	// Note in the code above that this causes createTopic or
-	// createQueue to be used in the consumer.
-	//============================================================
-	bool useTopics = true;
-
-	//============================================================
-	// set to true if you want the consumer to use client ack mode
-	// instead of the default auto ack mode.
-	//============================================================
-	bool clientAck = false;
-
-	// Create the consumer
-	SimpleAsyncConsumer consumer( brokerURI, destURI, useTopics, clientAck );
-
-	consumer.setOutfile(outfile);
-
-	// Start it up and it will listen forever.
-	consumer.runConsumer();
-
-	// Wait to exit.
-	fprintf(stdout, "Press 'q' to quit\n");
-	while( std::cin.get() != 'q') {}
-
-	// All CMS resources should be closed before the library is shutdown.
-	consumer.close();
-
-	fprintf(outfile, "-----------------------------------------------------\n");
-	fprintf(outfile, "Finished with the example.\n");
-	fprintf(outfile, "=====================================================\n");
-
-	if (outputfile) fclose(outfile);
-
-	activemq::library::ActiveMQCPP::shutdownLibrary();
-}
-
-
diff --git a/org.glite.lb.logger-msg/project/ChangeLog b/org.glite.lb.logger-msg/project/ChangeLog
deleted file mode 100644
index f2d70a1..0000000
--- a/org.glite.lb.logger-msg/project/ChangeLog
+++ /dev/null
@@ -1,57 +0,0 @@
-1.0.0-1
-- Initial version
-
-1.0.1-1
-- Detecting project name in Makefile
-- Introduction on a sysconfdir option (for /etc vs /usr)
-- DESTDIR in makefiles
-
-1.0.2-1
-- No direct dependency on apr/apr-util
-
-1.0.2-2
-- Module rebuilt
-
-1.0.3-1
-- Relocatable build directory
-
-1.0.3-2
-- Module rebuilt
-
-1.0.4-1
-- New MSG client example
-- Using stringstream instead of deprecated strstream
-- Sending jobid as part of status notification
-
-1.0.5-1
-- Support for searching for message brokers dynamically in BDII.
-
-1.0.6-1
-- cmsclient example extended
-
-1.0.7-1
-- Support build with gcc 4.4.4 (SL6)
-
-1.1.0-1
-- Preparation for a new multiplatform release
-
-1.1.1-1
-- Include job history in outgoing messages
-
-1.1.2-1
-- Automatically refresh the MSG brokers in configuration, without automatic daemons reloading
-- Packaging improvements (rpmlint and lintian checks)
-- List all types of MSG brokers, in the returned list prefer stomp+ssl
-- Build on Debian 6.0
-- Example client allows specifying output file through a cmdline argument, flushing that output file after every message
-- License string as recognized by rpmlint and packaging guidelines
-
-1.1.2-2
-- Module rebuilt
-
-1.1.3-1
-- msg_brokers script on SL6, reduce dependencies
-
-1.1.3-2
-- Module rebuilt
-
diff --git a/org.glite.lb.logger-msg/project/debian.control b/org.glite.lb.logger-msg/project/debian.control
deleted file mode 100644
index aff179e..0000000
--- a/org.glite.lb.logger-msg/project/debian.control
+++ /dev/null
@@ -1,25 +0,0 @@
-Source: glite-lb-logger-msg
-Priority: extra
-Maintainer: @MAINTAINER@
-Uploaders: @UPLOADERS@
-Build-Depends: debhelper (>= 7.0.50~), activemq-cpp-dev, chrpath, glite-lb-logger-dev, libcppunit-dev, libglite-lbjp-common-log-dev, libglite-lbjp-common-trio-dev, libtool
-Standards-Version: 3.9.1
-Section: misc
-Homepage: @URL@
-DM-Upload-Allowed: yes
-@DEBIAN_VCS@
-
-Package: glite-lb-logger-msg
-Section: misc
-Architecture: any
-Depends: glite-lb-logger, ${misc:Depends}
-Description: @SUMMARY@
-@DEBIAN_DESCRIPTION@
-
-Package: glite-lb-logger-msg-dbg
-Section: debug
-Architecture: any
-Priority: extra
-Depends: glite-lb-logger-msg (= ${binary:Version}), ${misc:Depends}
-Description: gLite L&B logger MSG plugin debugging symbols
- This package contains debugging symbols for gLite L&B logger MSG plugin.
diff --git a/org.glite.lb.logger-msg/project/debian.copyright b/org.glite.lb.logger-msg/project/debian.copyright
deleted file mode 100644
index 3d762ae..0000000
--- a/org.glite.lb.logger-msg/project/debian.copyright
+++ /dev/null
@@ -1,38 +0,0 @@
-This work was packaged for Debian by:
-
-    @MAINTAINER@ on Thu, 08 Dec 2011 00:46:07 +0100
-
-It was downloaded from:
-
-    @URL@
-
-Upstream Author(s):
-
-    @MAINTAINER@
-
-Copyright:
-
-    
-
-License:
-
-   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.
-
-On Debian systems, the complete text of the Apache version 2.0 license
-can be found in "/usr/share/common-licenses/Apache-2.0".
-
-The Debian packaging is:
-
-    Copyright (C) 2004-2011 Members of the EGEE Collaboration
-
-and is licensed under the Apache License, Version 2.0.
diff --git a/org.glite.lb.logger-msg/project/debian.glite-lb-logger-msg.dirs b/org.glite.lb.logger-msg/project/debian.glite-lb-logger-msg.dirs
deleted file mode 100644
index 8cef7ee..0000000
--- a/org.glite.lb.logger-msg/project/debian.glite-lb-logger-msg.dirs
+++ /dev/null
@@ -1,5 +0,0 @@
-etc/glite-lb
-usr/lib/glite-lb
-usr/lib/glite-lb/examples
-usr/sbin
-usr/share/doc/glite-lb-logger-msg
diff --git a/org.glite.lb.logger-msg/project/debian.glite-lb-logger-msg.install b/org.glite.lb.logger-msg/project/debian.glite-lb-logger-msg.install
deleted file mode 100644
index b7eb97b..0000000
--- a/org.glite.lb.logger-msg/project/debian.glite-lb-logger-msg.install
+++ /dev/null
@@ -1,6 +0,0 @@
-etc/glite-lb/*
-etc/cron.d/*
-usr/lib/activemq_cpp_plugin.so*
-usr/lib/glite-lb/examples/*
-usr/sbin/glite-lb-msg-*
-usr/share/doc/glite-lb-logger-msg/*
diff --git a/org.glite.lb.logger-msg/project/debian.rules b/org.glite.lb.logger-msg/project/debian.rules
deleted file mode 100644
index d94ba19..0000000
--- a/org.glite.lb.logger-msg/project/debian.rules
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile -*-
-
--include /usr/share/dpkg/buildflags.mk
-
-# Uncomment this to turn on verbose mode.
-export DH_VERBOSE=1
-
-configure: configure-stamp
-configure-stamp:
-	dh_testdir
-	/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=lib --project=emi --module lb.logger-msg
-	touch $@
-
-build: build-arch build-indep
-
-build-arch build-indep: build-stamp
-
-build-stamp: configure-stamp
-	dh_testdir
-	CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE)
-	CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) check
-	touch $@
-
-clean: configure-stamp
-	dh_testdir
-	dh_testroot
-	rm -f configure-stamp build-stamp
-	$(MAKE) clean
-	rm -f Makefile.inc config.status
-	dh_clean
-
-install: build-stamp
-	dh_testdir
-	dh_testroot
-	dh_prep
-	dh_installdirs
-	$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
-	rm -vf $(CURDIR)/debian/tmp/usr/lib/*.la
-	rm -vf $(CURDIR)/debian/tmp/usr/lib/*.a
-	find $(CURDIR)/debian/tmp -name '*' -print | xargs -I {} -i bash -c "chrpath -d {} > /dev/null 2>&1" || echo 'Stripped RPATH'
-	mv $(CURDIR)/debian/tmp/usr/share/doc/glite-lb-logger-msg-@MAJOR@.@MINOR@.@REVISION@ $(CURDIR)/debian/tmp/usr/share/doc/glite-lb-logger-msg
-	(cd $(CURDIR)/debian/tmp/usr/share/doc/glite-lb-logger-msg; \
-	 rm -fv ChangeLog LICENSE; \
-	 cat $(CURDIR)/project/ChangeLog | gzip -9 > changelog.gz)
-
-binary-indep:
-
-binary-arch: install
-	dh_testdir
-	dh_testroot
-	dh_installchangelogs
-	dh_installdocs
-	dh_installexamples
-	dh_installman
-	dh_installlogrotate
-	dh_installcron
-	dh_install --fail-missing
-	dh_link
-	dh_strip --dbg-package=glite-lb-logger-msg-dbg
-	dh_compress
-	dh_fixperms
-	dh_makeshlibs
-	dh_installdeb
-	dh_shlibdeps
-	dh_gencontrol
-	dh_md5sums
-	dh_builddeb
-
-binary: binary-arch binary-indep
diff --git a/org.glite.lb.logger-msg/project/glite-lb-logger-msg.spec b/org.glite.lb.logger-msg/project/glite-lb-logger-msg.spec
deleted file mode 100644
index 125f64c..0000000
--- a/org.glite.lb.logger-msg/project/glite-lb-logger-msg.spec
+++ /dev/null
@@ -1,72 +0,0 @@
-Summary: @SUMMARY@
-Name: glite-lb-logger-msg
-Version: @MAJOR@.@MINOR@.@REVISION@
-Release: @AGE@%{?dist}
-Url: @URL@
-License: ASL 2.0
-Vendor: EMI
-Group: System Environment/Daemons
-BuildRequires: activemq-cpp-library
-BuildRequires: cppunit-devel%{?_isa}
-BuildRequires: glite-lb-logger-devel%{?_isa}
-BuildRequires: glite-lbjp-common-log-devel%{?_isa}
-BuildRequires: glite-lbjp-common-trio-devel%{?_isa}
-BuildRequires: libtool
-Requires: glite-lb-logger
-BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
-AutoReqProv: yes
-Source: http://eticssoft.web.cern.ch/eticssoft/repository/emi/emi.lb.logger-msg/%{version}/src/%{name}-@VERSION@.src.tar.gz
-
-
-%description
-@DESCRIPTION@
-
-
-%prep
-%setup -q
-
-
-%build
-/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=%{_lib} --project=emi --module lb.logger-msg
-make
-
-
-%check
-make check
-
-
-%install
-rm -rf $RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT
-make install DESTDIR=$RPM_BUILD_ROOT
-find $RPM_BUILD_ROOT -name '*.la' -exec rm -rf {} \;
-find $RPM_BUILD_ROOT -name '*.a' -exec rm -rf {} \;
-find $RPM_BUILD_ROOT -name '*' -print | xargs -I {} -i bash -c "chrpath -d {} > /dev/null 2>&1" || echo 'Stripped RPATH'
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-
-%files
-%defattr(-,root,root)
-%dir /etc/glite-lb/
-%dir /usr/%{_lib}/glite-lb/
-%dir /usr/%{_lib}/glite-lb/examples/
-%dir /usr/share/doc/%{name}-%{version}/
-%config(missingok) /etc/glite-lb/msg.conf.example
-/etc/cron.d/glite-lb-logger-msg.cron
-/usr/%{_lib}/activemq_cpp_plugin.so
-/usr/%{_lib}/activemq_cpp_plugin.so.0
-/usr/%{_lib}/activemq_cpp_plugin.so.0.0.0
-/usr/%{_lib}/glite-lb/examples/glite-lb-cmsclient
-/usr/share/doc/%{name}-%{version}/ChangeLog
-/usr/share/doc/%{name}-%{version}/LICENSE
-/usr/share/doc/%{name}-%{version}/package.summary
-/usr/share/doc/%{name}-%{version}/package.description
-/usr/sbin/glite-lb-msg-*
-
-
-%changelog
-* @SPEC_DATE@ @MAINTAINER@ - @MAJOR@.@MINOR@.@REVISION@-@AGE@%{?dist}
-- automatically generated package
diff --git a/org.glite.lb.logger-msg/project/il.conf b/org.glite.lb.logger-msg/project/il.conf
deleted file mode 100644
index d732668..0000000
--- a/org.glite.lb.logger-msg/project/il.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-[interlogd]
-plugin = activemq_cpp_plugin.so
-
-[msg]
-broker = tcp://broker_host:broker_port
diff --git a/org.glite.lb.logger-msg/project/package.description b/org.glite.lb.logger-msg/project/package.description
deleted file mode 100644
index f2ca5cf..0000000
--- a/org.glite.lb.logger-msg/project/package.description
+++ /dev/null
@@ -1 +0,0 @@
-Plugin for delivering L&B notification messages into the messaging infrastructure.
diff --git a/org.glite.lb.logger-msg/project/package.summary b/org.glite.lb.logger-msg/project/package.summary
deleted file mode 100644
index 2da85e0..0000000
--- a/org.glite.lb.logger-msg/project/package.summary
+++ /dev/null
@@ -1 +0,0 @@
-notification->msg plugin
diff --git a/org.glite.lb.logger-msg/project/version.properties b/org.glite.lb.logger-msg/project/version.properties
deleted file mode 100644
index 8a11015..0000000
--- a/org.glite.lb.logger-msg/project/version.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# $Header$
-module.version=1.1.3
-module.age=2
diff --git a/org.glite.lb.logger-msg/src/activemq_cpp_plugin.cpp b/org.glite.lb.logger-msg/src/activemq_cpp_plugin.cpp
deleted file mode 100644
index 3fe700b..0000000
--- a/org.glite.lb.logger-msg/src/activemq_cpp_plugin.cpp
+++ /dev/null
@@ -1,533 +0,0 @@
-#ident "$Header$"
-/*
-Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-See http://www.eu-egee.org/partners for details on the copyright holders.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-
-/*
- * activemq_cpp_plugin.cpp
- *
- *  Created on: Jan 20, 2010
- *      Author: michal
- */
-
-extern "C" {
-#include "glite/lb/interlogd.h"
-#include "glite/lb/events_parse.h"
-#include "glite/lb/context.h"
-#include "glite/lbu/escape.h"
-#include "glite/lb/jobstat.h"
-#include "glite/lb/xml_parse.h"
-}
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-
-class OutputPlugin {
-
-public:
-
-	OutputPlugin() : session(NULL), destination(NULL), producer(NULL) {};
-
-
-	cms::Message *createMessage(edg_wll_JobStat &state_out);
-	void         connect(const std::string &topic);
-	void         send(cms::Message *msg);
-	void         close();
-	void         cleanup();
-
-	static void   initialize(const std::string &brokerURI);
-
-	static const char *SCHEME;
-
-private:
-
-	static cms::Connection *getConnection();
-	static void releaseConnection();
-
-	cms::Session *session;
-	cms::Topic   *destination;
-	cms::MessageProducer *producer;
-	cms::Connection *current_connection;
-
-	static cms::Connection *connection;
-	static cms::ConnectionFactory *connectionFactory;
-	static pthread_rwlock_t connection_lock;
-};
-
-
-void
-OutputPlugin::connect(const std::string &topic)
-{
-	try {
-		current_connection = getConnection();
-		if(session == NULL) {
-			session = current_connection->createSession(/* TODO: ackMode */);
-			destination = session->createTopic(topic);
-			producer = session->createProducer(destination);
-		}
-		current_connection->start();
-		releaseConnection();
-	} catch (cms::CMSException &e) {
-		glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, "OutputPlugin::connect exception: %s", e.what());
-		releaseConnection();
-		cleanup();
-		throw e;
-	}
-}
-
-
-static
-void timeval2str(struct timeval *t, char **str) {
-        struct tm       *tm;
-
-        tm = gmtime(&t->tv_sec);
-        asprintf(str,"%4d-%02d-%02dT%02d:%02d:%02dZ",tm->tm_year+1900,tm->tm_mon+1,
-                tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec);
-}
-
-
-cms::Message *
-OutputPlugin::createMessage(edg_wll_JobStat &state_out)
-{
-	cms::TextMessage *cms_msg = session->createTextMessage();
-	char *s;
-	unsigned int i;
-	std::ostringstream body;
-
-	body << "{";
-	/* jobid */
-	s = glite_jobid_unparse(state_out.jobId);
-	if(s) {
-		body << "jobid: \"" << s << "\", ";
-		free(s);
-	}
-	/* ownerDn */
-	if(state_out.owner) {
-		body << "ownerDn: \"" << state_out.owner << "\", ";
-		// cms_msg->setStringProperty("ownerDn", val);
-	}
-	/* voname */
-	s = edg_wll_JDLField(&state_out,"VirtualOrganisation");
-	if(s) {
-		body << "VirtualOrganisation: \"" << s << "\", ";
-		free(s);
-	}
-	/* bkHost */
-	glite_jobid_getServerParts(state_out.jobId, &s, &i);
-	if(s) {
-		body << "bkHost: \"" << s << "\", ";
-		free(s);
-	}
-	/* networkServer */
-	/* TODO: XXX cut out hostname */
-	if(state_out.network_server) {
-		body << "networkHost: \"" << state_out.network_server << "\", ";
-	}
-	timeval2str(&state_out.lastUpdateTime, &s);
-	if(s) {
-		body << "lastUpdateTime: \"" << s << "\", ";
-		free(s);
-	}
-	/* stateName */
-	s = edg_wll_StatToString(state_out.state);
-	if(s) {
-		body << "stateName: \"" << s << "\", ";
-		free(s);
-	}
-	timeval2str(&state_out.stateEnterTime, &s);
-	if(s) {
-		body << "stateStartTime: \"" << s << "\", ";
-		free(s);
-	}
-	/* condorId */
-	if(state_out.condorId) {
-		body << "condorId: \"" << state_out.condorId << "\", ";
-	}
-	/* destSite */
-	if(state_out.destination) {
-		body << "destSite: \"" << state_out.destination << "\", ";
-	}
-	/* exitCode */
-	body << "exitCode: " << state_out.exit_code <<  ", ";
-	/* doneCode */
-	body << "doneCode: " << state_out.done_code << ", ";
-	/* statusReason */
-	if(state_out.reason) {
-		body << "statusReason: \"" << state_out.reason << "\", ";
-	}
-	/* summaries */
-	if(state_out.history) {
-		body << "history: " << state_out.history << ", ";
-	}
-	body << "}";
-
-	cms_msg->setText(body.str().c_str());
-	cms_msg->setStringProperty("Content-type", "text/javascript");
-
-	return cms_msg;
-}
-
-
-void
-OutputPlugin::send(cms::Message *msg)
-{
-	try {
-		if(producer != NULL) {
-			producer->send(msg);
-		}
-	} catch(cms::CMSException &e) {
-		cleanup();
-		throw e;
-	}
-}
-
-
-void
-OutputPlugin::close()
-{
-	if(producer != NULL) {
-		delete producer;
-		producer = NULL;
-	}
-	if(destination != NULL) {
-		delete destination;
-		destination = NULL;
-	}
-	if(session != NULL) {
-		session->close();
-		delete session;
-		session = NULL;
-	}
-}
-
-
-void
-OutputPlugin::cleanup()
-{
-	try {
-		close();
-	} catch(cms::CMSException &e) {
-			glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, "activemq_cpp_plugin: close exception: %s", e.what());
-	}
-	pthread_rwlock_wrlock(&connection_lock);
-	if(connection && current_connection == connection) {
-		try {
-			connection->close();
-		} catch(cms::CMSException &e) {
-			glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, "activemq_cpp_plugin: connection close  exception: %s", e.what());
-		}
-		try {
-			delete connection;
-		} catch(cms::CMSException &e) {
-			glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, "activemq_cpp_plugin: cleanup exception: %s", e.what());
-		}
-		connection = NULL;
-		current_connection = NULL;
-	}
-	pthread_rwlock_unlock(&connection_lock);
-}
-
-
-cms::Connection *
-OutputPlugin::getConnection() 
-{
-	pthread_rwlock_rdlock(&connection_lock);
-	if(connection) {
-		return connection;
-	}
-
-	pthread_rwlock_unlock(&connection_lock);
-
-	pthread_rwlock_wrlock(&connection_lock);
-	if(!connection) {
-		connection = connectionFactory->createConnection();
-	}
-	pthread_rwlock_unlock(&connection_lock);
-
-	pthread_rwlock_rdlock(&connection_lock);
-	return connection;
-}
-
-
-void
-OutputPlugin::releaseConnection() 
-{
-	pthread_rwlock_unlock(&connection_lock);
-}
-
-
-void
-OutputPlugin::initialize(const std::string &brokerURI) 
-{
-	pthread_rwlock_init(&connection_lock, NULL);
-	try {
-		activemq::library::ActiveMQCPP::initializeLibrary();
-
-		connectionFactory = cms::ConnectionFactory::createCMSConnectionFactory(brokerURI);
-	} catch (cms::CMSException &e) {
-		try {
-			if(connectionFactory != NULL) {
-				delete connectionFactory;
-				connectionFactory = NULL;
-			}
-		} catch(cms::CMSException &d) {
-		}
-		throw e;
-	}
-}
-
-
-
-extern "C"
-int
-event_queue_connect(struct event_queue *eq, struct queue_thread *me)
-{
-	OutputPlugin *output;
-	std::string topicName(eq->dest_name);
-
-	if(eq->plugin_data == NULL) {
-		output = new OutputPlugin();
-		eq->plugin_data = (void*)output;
-	} else {
-		output = (OutputPlugin*)eq->plugin_data;
-	}
-
-	assert(output != NULL);
-
-	try {
-		glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, 
-				 "    trying to connect to %s", 
-				 eq->dest_name);
-		output->connect(topicName);
-	} catch(cms::CMSException &e) {
-		set_error(IL_DL, 0, (char*)e.what());
-		me->timeout = TIMEOUT;
-		return 0;
-	}
-	me->first_event_sent = 0;
-	eq->last_connected= time(NULL);
-	return 1;
-}
-
-
-extern "C"
-int
-event_queue_send(struct event_queue *eq, struct queue_thread *me)
-{
-	OutputPlugin *output = (OutputPlugin*)eq->plugin_data;
-	edg_wll_Context context;
-	edg_wll_Event *notif_event;
-	edg_wll_JobStat state_out;
-	il_octet_string_t event;
-	char *jobstat_char;
-	int ret;
-
-	assert(output != NULL);
-
-	edg_wll_InitContext(&context);
-
-	while(!event_queue_empty(eq)) {
-	    struct server_msg *msg;
-	    cms::Message *cms_msg;
-
-	    if(event_queue_get(eq, me, &msg) == 0) {
-		    break;
-	    }
-
-	    if(0 == msg->len) {
-		    glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG,
-				     "    not sending empty message at offset %d for job %s",
-				     msg->offset, msg->job_id_s);
-		    if(event_store_commit(msg->es, msg->ev_len, 0, msg->generation) < 0) {
-			    /* failure committing message, this is bad */
-			    goto err;
-		    }
-		    event_queue_remove(eq, me);
-		    continue;
-	    }
-
-	    glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, 
-			     "    trying to deliver event at offset %d for job %s", 
-			     msg->offset, msg->job_id_s);
-	    
-	    if(decode_il_msg(&event, msg->msg + 17) < 0) {
-		    set_error(IL_LBAPI, EINVAL, "event_queue_send: error parsing notification event data");
-		    goto err;
-	    }
-	    ret=edg_wll_ParseNotifEvent(context, event.data, ¬if_event);
-	    if(ret) {
-		    set_error(IL_LBAPI, ret, "event_queue_send: error parsing notification event");
-		    goto err;
-	    }
-	    jobstat_char = glite_lbu_UnescapeXML((const char *) notif_event->notification.jobstat);
-	    if (jobstat_char == NULL) {
-		    set_error(IL_LBAPI, EINVAL, "event_queue_send: error unescaping job status");
-		    goto err;
-	    }
-	    if ( edg_wll_ParseJobStat(context, jobstat_char, strlen(jobstat_char), &state_out)) {
-		    set_error(IL_LBAPI, EINVAL, "event_queue_send: error parsing job status");
-		    fprintf(stderr, "Status string: %s\n", jobstat_char);
-		    goto err;
-	    }
-	    
-	    try {
-		    cms_msg = output->createMessage(state_out);
-		    
-		    free(event.data); event.data = NULL;
-		    edg_wll_FreeEvent(notif_event);
-		    free(notif_event); notif_event = NULL;
-		    edg_wll_FreeStatus(&state_out);
-		    free(jobstat_char); jobstat_char = NULL;
-		    
-		    output->send(cms_msg); 
-		    delete cms_msg;
-		    if(event_store_commit(msg->es, msg->ev_len, 0, msg->generation) < 0) {
-			    /* failure committing message, this is bad */
-			    goto err;
-		    }
-		    glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, 
-				     "    event sent to %s", eq->dest_name);
-		    
-	    } catch(cms::CMSException &e) {
-		    if(cms_msg) {
-			    delete cms_msg;
-		    }
-		    me->timeout = TIMEOUT;
-		    edg_wll_FreeContext(context);
-		    set_error(IL_DL, 0, (char*)e.what());
-		    return 0;
-	    }
-	    event_queue_remove(eq, me);
-	    me->first_event_sent = 1;
-	    eq->last_sent = time(NULL);
-	}
-	edg_wll_FreeContext(context);
-	return 1;
-
-err:
-	if(event.data) {
-		free(event.data);
-	}
-	if(notif_event) {
-		edg_wll_FreeEvent(notif_event);
-		free(notif_event);
-	}
-	if(jobstat_char) {
-		free(jobstat_char);
-	}
-	edg_wll_FreeStatus(&state_out);
-
-	return -1;
-}
-
-
-extern "C"
-int
-event_queue_close(struct event_queue *eq, struct queue_thread *me)
-{
-	OutputPlugin *output = (OutputPlugin*)eq->plugin_data;
-
-	if(output == NULL) {
-		// nothing to close
-		return 0;
-	}
-
-	try { 
-		output->close();
-	} catch(cms::CMSException &e) {
-		set_error(IL_DL, 0, (char*)e.what());
-		return -1;
-	}
-	me->first_event_sent = 0;
-	return 0;
-}
-
-
-extern "C"
-int
-plugin_init(char *config)
-{
-	char *s, *p;
-	char key[MAXPATHLEN], val[MAXPATHLEN];
-	int ret;
-	std::string brokerURI;
-
-	s = strstr(config, "[msg]");
-	if(s == NULL) {
-		set_error(IL_DL, ENOENT, "plugin_init: missing required configuration section [msg]\n");
-		return -1;
-	}
-	s = strchr(s, '\n');
-	if(s) s++;
-	while(s) {
-		if(*s == 0 || *s == '[')
-			break;
-		p = strchr(s, '\n');
-		if(p) *p = 0;
-		ret = sscanf(s, " %s =%s", key, val);
-		if(p) *p = '\n';
-		if(ret == 2) {
-			if(strcmp(key, "broker") == 0) {
-				brokerURI.assign(val);
-			}
-		}
-		s = p + 1;
-	}
-	if(brokerURI.length() == 0) {
-		set_error(IL_DL, ENOENT, "plugin_init: broker uri not configured\n");
-		return -1;
-	}
-
-	try {
-		OutputPlugin::initialize(brokerURI);
-	} catch(cms::CMSException &e) {
-		set_error(IL_DL, 0, (char*)e.what());
-		return -1;
-	}
-
-	return 0;
-}
-
-
-extern "C"
-int
-plugin_supports_scheme(const char *scheme)
-{
-	return strncmp(scheme, OutputPlugin::SCHEME, strlen(OutputPlugin::SCHEME)) == 0;
-}
-
-
-cms::Connection *OutputPlugin::connection = NULL;
-cms::ConnectionFactory *OutputPlugin::connectionFactory = NULL;
-const char *OutputPlugin::SCHEME = "x-msg://";
-pthread_rwlock_t OutputPlugin::connection_lock;
diff --git a/org.glite.lb.logger-msg/src/msg-brokers b/org.glite.lb.logger-msg/src/msg-brokers
deleted file mode 100755
index eea24a9..0000000
--- a/org.glite.lb.logger-msg/src/msg-brokers
+++ /dev/null
@@ -1,357 +0,0 @@
-#!/usr/bin/perl
-#+##############################################################################
-#                                                                              #
-# File: msg-brokers                                                            #
-#                                                                              #
-# Description: manipulate messaging brokers information                        #
-#                                                                              #
-#-##############################################################################
-
-#
-# modules
-#
-
-use strict;
-use warnings;
-use Getopt::Long;
-use Net::LDAP;
-use Pod::Usage;
-
-#
-# constants
-#
-
-use constant LDAP_TIMEOUT  => 10;
-use constant STOMP_TIMEOUT =>  5;
-
-#
-# global variables
-#
-
-our($Action, %Option);
-
-#
-# report a debugging message
-#
-
-sub debug ($$@) {
-    my($level, $format, @arguments) = @_;
-    my($message);
-
-    return unless $Option{debug} >= $level;
-    $message = sprintf($format, @arguments);
-    $message =~ s/\s+$//;
-    print(STDERR "# $message\n");
-}
-
-#
-# report a warning message
-#
-
-sub warning ($@) {
-    my($format, @arguments) = @_;
-    my($message);
-
-    return if $Option{quiet};
-    $message = sprintf($format, @arguments);
-    $message =~ s/\s+$//;
-    print(STDERR "* $message\n");
-}
-
-#
-# report a fatal error
-#
-
-sub fatal ($@) {
-    my($format, @arguments) = @_;
-    my($message);
-
-    $message = sprintf($format, @arguments);
-    $message =~ s/\s+$//;
-    die("msg-brokers: $message\n");
-}
-
-#
-# initialise everything
-#
-
-sub init () {
-    # defaults
-    $Option{bdii} = $ENV{LCG_GFAL_INFOSYS};
-    $Option{debug} = 0;
-    # options parsing
-    GetOptions(
-        "bdii=s"    => \$Option{bdii},
-        "cache=s"   => \$Option{cache},
-        "debug|d+"  => \$Option{debug},
-        "help|h|?"  => \$Option{help},
-        "manual|m"  => \$Option{manual},
-        "network=s" => \$Option{network},
-        "quiet|q"   => \$Option{quiet},
-        "sort|s"    => \$Option{sort},
-    ) or pod2usage(2);
-    pod2usage(1) if $Option{help};
-    pod2usage(exitstatus => 0, verbose => 2) if $Option{manual};
-    # action parsing
-    pod2usage(2) unless @ARGV;
-    if ($ARGV[0] =~ /^(find|list)$/) {
-	$Action = shift(@ARGV);
-	pod2usage(2) if @ARGV;
-    } else {
-	warn("Unknown action: $ARGV[0]\n");
-	pod2usage(2);
-    }
-}
-
-#
-# connect to the BDII and return the corresponding Net::LDAP object
-#
-
-sub connect_bdii () {
-    my($bdii, @list, $ldap, $mesg);
-
-    $bdii = $Option{bdii};
-    fatal("unspecified BDII (use --bdii or set \$LCG_GFAL_INFOSYS)")
-	unless $bdii;
-    if ($bdii =~ /[\,\;]/) {
-	# list of BDIIs
-	@list = split(/[\,\;]+/, $bdii);
-	debug(1, "using BDII list %s", "@list");
-    } else {
-	# single BDII
-	@list = ($bdii);
-	debug(1, "using single BDII %s", $bdii);
-    }
-    foreach $bdii (@list) {
-	$ldap = Net::LDAP->new($bdii,
-            port    => 2170,
-            timeout => LDAP_TIMEOUT,
-            async   => 1,
-        );
-	last if $ldap;
-	if (@list == 1) {
-	    fatal("could not connect to BDII %s: %s", $bdii, $@);
-	} else {
-	    warning("could not connect to BDII %s: %s", $bdii, $@);
-	}
-    }
-    fatal("could not connect to any BDII") unless $ldap;
-    debug(1, "connected to BDII %s", $ldap->{net_ldap_uri});
-    $mesg = $ldap->bind(anonymous => 1);
-    fatal("could not bind to BDII %s: %s", $ldap->{net_ldap_uri}, $mesg->error())
-	if $mesg->code();
-    return($ldap);
-}
-
-#
-# search the BDII and return the corresponding results
-#
-
-sub search_bdii ($%) {
-    my($ldap, %option) = @_;
-    my($mesg);
-
-    $option{base} = "o=grid";
-    $option{timelimit} = LDAP_TIMEOUT;
-    $mesg = $ldap->search(%option);
-    fatal("could not search BDII %s: %s", $ldap->{net_ldap_uri}, $mesg->error())
-	if $mesg->code();
-    return($mesg->entries());
-}
-
-#
-# query the BDII and return the list of matching messaging broker URIs
-#
-
-sub list_brokers ($) {
-    my($ldap, %search, $endpoint, $match, $network, $value, @uris);
-    my($proto,%uris);
-    my($check) = @_;
-
-    $ldap = connect_bdii();
-    %search = (
-        filter => "(&(objectClass=GlueService)(GlueServiceType=msg.broker.*)",
-        attrs  => [ qw(GlueServiceEndpoint GlueServiceUniqueID) ],
-    );
-    $search{filter} .= "(GlueServiceStatus=OK)" if ($check);
-    $search{filter} .= ")";
-    foreach $endpoint (search_bdii($ldap, %search)) {
-	$value = $endpoint->get_value("GlueServiceUniqueID");
-	debug(2, " found endpoint %s", $value);
-	%search = (
-            filter => "(&(GlueServiceDataKey=cluster)(GlueChunkKey=GlueServiceUniqueID=$value))",
-            attrs  => [ qw(GlueServiceDataValue) ],
-	);
-	$match = 0;
-	foreach $network (search_bdii($ldap, %search)) {
-	    $value = $network->get_value("GlueServiceDataValue");
-	    debug(2, "  found network %s", $value);
-	    next if defined($Option{network}) and $Option{network} ne $value;
-	    $match++;
-	}
-	$value = $endpoint->get_value("GlueServiceEndpoint");
-	if ($match) {
-            $proto = '';
-            if ($value =~ /^([^:]*):\/\/.*/) { $proto = $1; }
-            push(@{$uris{$proto}}, $value);
-	    debug(2, "  keep URI %s", $value);
-	} else {
-	    debug(2, "  skip URI %s", $value);
-	}
-    }
-
-    foreach $proto ('stomp+ssl', 'openwire+ssl', 'stomp', 'openwire') {
-	if (exists $uris{$proto}) {
-            push(@uris,@{$uris{$proto}});
-            delete $uris{$proto};
-        }
-    }
-    foreach $proto (keys %uris) {
-            push(@uris,@{$uris{$proto}});
-    }
-    
-    debug(1, "got %d broker URIs from BDII", scalar(@uris));
-    warning("got an empty brokers list from BDII") unless @uris;
-    return(@uris);
-}
-
-#
-# report the final list of messaging broker URIs
-#
-
-sub report_brokers (@) {
-    my(@list) = @_;
-    my($uri, $fh);
-
-    unless (defined($Option{cache})) {
-	# report only to STDOUT
-	foreach $uri (@list) {
-	    print("$uri\n");
-	}
-	return;
-    }
-    unless (@list) {
-	# no brokers so no cache update
-	warning("no brokers found so cache file not updated");
-	return;
-    }
-    # update the cache file
-    open($fh, ">", $Option{cache})
-	or fatal("cannot open %s: %s", $Option{cache}, $!);
-    foreach $uri (@list) {
-	print($fh "$uri\n");
-    }
-    close($fh)
-	or fatal("cannot close %s: %s", $Option{cache}, $!);
-    debug(1, "cache %s updated with %d brokers", $Option{cache}, scalar(@list));
-}
-
-#
-# main part
-#
-
-sub main () {
-    my(@list);
-
-    if ($Action eq "list") {
-	@list = list_brokers(0);
-    } elsif ($Action eq "find") {
-	@list = list_brokers(1);
-    } else {
-	fatal("unexpected action: %s", $Action);
-    }
-    report_brokers(@list);
-}
-
-#
-# just do it
-#
-
-init();
-main();
-
-__END__
-
-=head1 NAME
-
-msg-brokers - manipulate messaging brokers information
-
-=head1 SYNOPSIS
-
-B [I] B|B
-
-=head1 DESCRIPTION
-
-B has three different modes of operation. In all cases,
-it manipulates information about messaging brokers and reports a
-(possibly empty) list of broker URIs, one per line.
-
-=over
-
-=item B
-
-list all the URIs declared in the BDII, optionally filtered by network
-
-=item B
-
-the B functionality described above plus filter by GlueServiceStatus
-
-=back
-
-A fatal error (e.g. cannot contact the BDII) will halt the program.
-A warning (e.g. a given URI cannot be contacted) will be reported
-unless B<--quiet> is used. Both will be sent to STDERR.
-
-The exit status will be 0 on success (with or without warnings) or
-different from 0 in case of a fatal error.
-
-=head1 OPTIONS
-
-=over
-
-=item B<--bdii> I
-
-specify the I or I:I of the BDII to contact;
-this can also be a list, separated by commas or semicolons;
-if not set, it defaults to $LCG_GFAL_INFOSYS
-
-=item B<--cache> I
-
-specify the path of a file to update with the list of URIs;
-if this is set, nothing will be printed on STDOUT;
-note: if the list is empty, the file will I be updated
-
-=item B<--debug>, B<-d>
-
-report debugging information;
-can be used multiple times for increased verbosity
-
-=item B<--help>, B<-h>, B<-?>
-
-show some help
-
-=item B<--manual>, B<-m>
-
-show the complete man page
-
-=item B<--network> I
-
-consider only the brokers for this network
-
-=item B<--quiet>, B<-q>
-
-supress the printing of warnings
-
-=item B<--sort>, B<-s>
-
-sort the brokers per elapsed time to perform the test
-
-=back
-
-=head1 SEE ALSO
-
-L
-
-=head1 AUTHOR
-
-Lionel Cons L
diff --git a/org.glite.lb.logger-msg/src/msg-config.in b/org.glite.lb.logger-msg/src/msg-config.in
deleted file mode 100755
index d4272d6..0000000
--- a/org.glite.lb.logger-msg/src/msg-config.in
+++ /dev/null
@@ -1,72 +0,0 @@
-#! /bin/bash
-
-test -f /etc/profile.d/grid-env.sh && . /etc/profile.d/grid-env.sh
-
-GLITE_LOCATION=${GLITE_LOCATION:-'@glite_prefix@'}
-LCG_GFAL_INFOSYS=${LCG_GFAL_INFOSYS:-'lcg-bdii.cern.ch:2170'}
-GLITE_LB_MSG_NETWORK=${GLITE_LB_MSG_NETWORK:-'PROD'}
-
-CONF=/tmp/msg.$$
-TEMPLATE=$1
-TARGET=$2
-
-if [ -z "$TEMPLATE" ]; then
-	echo "Usage: $0 TEMPLATE [TARGET]"
-	exit 1
-fi
-if [ -z "$TARGET" ]; then
-	TARGET=$TEMPLATE
-fi
-
-# removing and resurrecting
-if [ "$GLITE_LB_MSG_BROKER" = 'false' ]; then
-	if [ -f "$TARGET" ]; then
-		mv $TARGET $TARGET.disabled
-		echo "disabled, configuration removed"
-	fi
-	exit 0
-fi
-if [ ! -s "$TEMPLATE" ]; then
-	if [ -f "$TEMPLATE.disabled" ]; then
-		mv $TEMPLATE.disabled $TEMPLATE
-	else
-		cat <$TEMPLATE
-# automatically generated by glite-lb-msg-config
-
-[interlogd]
-plugin = activemq_cpp_plugin.so
-
-[msg]
-EOF
-	fi
-fi
-
-HEADER="`cat $TEMPLATE | grep -B 1000 '^\[msg\]'`"
-PREFIX="`cat $TEMPLATE | grep -A 1000 '^\[msg\]' | grep prefix  | head -n -1`"
-
-if [ "$GLITE_LB_MSG_BROKER" = 'true' -o "$GLITE_LB_MSG_BROKER" = 'auto' -o -z "$GLITE_LB_MSG_BROKER" ]; then
-	GLITE_LB_MSG_BROKER="`$GLITE_LOCATION/sbin/glite-lb-msg-brokers --bdii $LCG_GFAL_INFOSYS --network $GLITE_LB_MSG_NETWORK --sort find`" || exit $?
-	# bend for using in L&B configuration:
-	#   1) stomp not supported
-	#   2) translate openwire -> tcp, openwire+ssl -> ssl
-	#   3) temporary disable the ssl
-	GLITE_LB_MSG_BROKER=`echo "$GLITE_LB_MSG_BROKER" | grep -v ^stomp | sed -e 's,openwire://,tcp://,' -e 's,openwire+ssl://,ssl://,g' | grep -v ^ssl`
-	GLITE_LB_MSG_BROKER=`echo $GLITE_LB_MSG_BROKER`
-fi
-
-if [ -z "$GLITE_LB_MSG_BROKER" ]; then
-	exit 2
-fi
-
-[ -z "$HEADER" ] || echo "$HEADER" > $CONF
-[ -z "$PREFIX" ] || echo "$PREFIX" >> $CONF
-[ -z "$GLITE_LB_MSG_BROKER" ] || echo 'broker =' $GLITE_LB_MSG_BROKER >> $CONF
-
-if [ ! -f $TARGET ]; then touch $TARGET; fi
-diff -b $TARGET $CONF >/dev/null
-case $? in
-	0) ;;
-	1) mv $CONF $TARGET; echo "new brokers '$GLITE_LB_MSG_BROKER'" ;;
-	2) rm -f $CONF; exit 2 ;;
-esac
-rm -f $CONF
diff --git a/org.glite.lb.nagios/Makefile b/org.glite.lb.nagios/Makefile
deleted file mode 100644
index 2321127..0000000
--- a/org.glite.lb.nagios/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-top_srcdir=..
-stagedir=.
-package=emi-lb-nagios-plugins
-version=0.0.0
-prefix=
-INSTALL=install
-
--include Makefile.inc
--include ${top_srcdir}/project/version.properties
-
-version=${module.version}
-
-all:
-
-install:
-	mkdir -p ${DESTDIR}${PREFIX}/var/lib/grid-monitoring/emi.lb
-	mkdir -p ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version}
-	chmod 750 ${DESTDIR}${PREFIX}/var/lib/grid-monitoring/emi.lb
-	-chown nagios:nagios ${DESTDIR}${PREFIX}/var/lib/grid-monitoring/emi.lb
-	mkdir -p ${DESTDIR}${PREFIX}${prefix}/libexec/grid-monitoring/probes/emi.lb
-	${INSTALL} -m 0755 src/LB-probe ${DESTDIR}${PREFIX}${prefix}/libexec/grid-monitoring/probes/emi.lb
-	( cd ${top_srcdir}/project && ${INSTALL} -m 644 ChangeLog package.description package.summary ${DESTDIR}${PREFIX}${prefix}/share/doc/${package}-${version} )
-
-stage:
-	$(MAKE) install PREFIX=${stagedir}
-
-check:
-	@echo "No test"
-
-clean:
-
-distclean:
-	rm -rvf Makefile.inc *.spec debian/
-
-.PHONY: all install stage clean check
diff --git a/org.glite.lb.nagios/configure b/org.glite.lb.nagios/configure
deleted file mode 100755
index bcb1531..0000000
--- a/org.glite.lb.nagios/configure
+++ /dev/null
@@ -1,2058 +0,0 @@
-#!/usr/bin/perl
-
-# WARNING: Don't edit this file unless it is the master copy in org.glite.lb
-#
-# For the purpose of standalone builds of lb/jobid/lbjp-common components
-# it is copied on tagging 
-
-# $Header$
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners/ for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-use Getopt::Long;
-use POSIX qw(locale_h strftime);
-
-my $pwd = `pwd`; chomp $pwd;
-my $prefix = '/usr';
-my $stagedir = undef;
-my $root = $pwd.'/stage';
-my $sysroot = '';
-my $sysconfdir;
-my $localstatedir;
-my $staged;
-my $module;
-my $thrflavour = 'gcc64dbgpthr';
-my $nothrflavour = 'gcc64dbg';
-my $mode = 'build';
-my $help = 0;
-my $listmodules;
-my ($version, $force_version);
-my $branch;
-my $output;
-my $lb_tag = '';
-my $lbjp_tag = '';
-my $jp_tag = '';
-my $jobid_tag = '';
-my $libdir = getlibdir();
-my $project = 'emi';
-my $project_version;
-my (%projects, %project);
-my $debug = 0;
-my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : '';
-
-my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal/;
-my @default_nodes = qw/lb px proxyrenewal nagios/;
-my %enable_nodes;
-my %disable_nodes;
-my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1);
-
-my %package = (
-	'maintainer' => 'CESNET Product Teams ',
-	'uploaders' => 'František Dvořák ',
-	'url' => 'http://glite.cern.ch',
-	'debian_vcs' => 'Vcs-Cvs: :pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw
-Vcs-Browser: http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi',
-);
-
-# key:      internal package name (arguments, ...)
-# 'pkg':    pkg-config name
-# 'prefix': used when pkg-config fails
-my %externs = (
-	cares => {
-		prefix => '/opt/c-ares',
-		pkg => 'libcares'
-	},
-	classads => {
-		prefix=> '/usr',
-		pkg => 'classads'
-	},
-	cppunit => {
-		prefix=> '/usr',
-		pkg => 'cppunit'
-	},
-	expat => {
-		prefix=> '/usr',
-		pkg => 'expat'
-	},
-	globus => {
-		prefix=> '/opt/globus',
-		pkg => 'globus-gssapi-gsi'
-	},
-	'myproxy-devel' => {
-		prefix=> '/opt/globus',
-		pkg => 'myproxy'
-	},
-	'myproxy-server' => {
-		prefix=> '',
-	},
-	'myproxy-admin' => {
-		prefix=> '',
-	},
-	gsoap => {
-		prefix=> '/usr',
-		pkg => 'gsoap'
-	},
-	gsoapxx => {
-		prefix=> '/usr',
-		pkg => 'gsoap++'
-	},
-	mysql => {
-		prefix=> '/usr'
-	},
-	'mysql-devel' => {
-		prefix=> ''
-	},
-	'mysql-server' => {
-		prefix => ''
-	},
-	voms => {
-		prefix => '/opt/glite',
-		pkg => 'voms-2.0'
-	},
-	gridsite => {
-		prefix => '/opt/glite'
-	},
-	lcas => {
-		prefix => '/opt/glite',
-		pkg => 'lcas'
-	},
-	trustmanager => {
-		prefix => '/opt/glite'
-	},
-	trustmanager_axis => {
-		prefix => '/opt/glite'
-	},
-	utiljava => {
-		prefix=> '/opt/glite'
-	},
-	ant => {
-		prefix=> '/usr'
-	},
-	jdk => {
-		prefix=> '/usr/java/latest',
-		locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ],
-	},
-	libtar => {
-		prefix=> '/usr'
-	},
-	axis => {
-		prefix=> '/usr'
-	},
-	log4c => {
-		prefix=> '/usr'
-	},
-	postgresql => {
-		prefix=> '/usr'
-	},
-	activemq => {
-		prefix=>'/opt/activemq-cpp-library',
-		pkg => 'activemq-cpp'
-	},
-);
-
-my %jar = (
-	'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar',
-	'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar',
-);
-
-
-my %glite_prefix;
-my %need_externs;
-my %need_externs_type;
-my %need_jars;
-my %extrafull;
-my %extranodmod;
-my %deps;
-my %deps_type;
-my %buildroot;
-my (%etics_externs, %etics_projects);
-
-#
-# modules of the subsystems
-#
-# additional modules from $project{modules} are automatically added
-#
-my %lbmodules = (
-	'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], 
-	'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/],
-	'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/],
-	'jp' => [ qw/client doc index primary server-common ws-interface/ ],
-	'gridsite' => [ qw/apache libs commands core devel slashgrid services service-clients gsexec/ ],
-	'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ],
-	'canl' => [ qw/c c-devel/ ],
-	);
-
-#
-# sub-packages
-#
-# modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly
-#
-my %subpackages = (
-	'jobid.api-c-devel' => 'jobid.api-c',
-	'jobid.api-cpp-devel' => 'jobid.api-cpp',
-	'lbjp-common.db-devel' => 'lbjp-common.db',
-	'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin',
-	'lbjp-common.gss-devel' => 'lbjp-common.gss',
-	'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface',
-	'lbjp-common.log-devel' => 'lbjp-common.log',
-	'lbjp-common.maildir-devel' => 'lbjp-common.maildir',
-	'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones',
-	'lbjp-common.trio-devel' => 'lbjp-common.trio',
-	'lb.client-progs' => 'lb.client',
-	'lb.client-devel' => 'lb.client',
-	'lb.common-devel' => 'lb.common',
-	'lb.logger-devel' => 'lb.logger',
-	'lb.state-machine-devel' => 'lb.state-machine',
-	'px.proxyrenewal-devel' => 'px.proxyrenewal',
-	'px.proxyrenewal-progs' => 'px.proxyrenewal',
-	'canl.c-devel' => 'canl.c',
-);
-
-my @opts = (
-	'prefix:s' => \$prefix,
-	'staged=s' => \$staged,
-	'module=s' => \$module,
-	'thrflavour:s' => \$thrflavour,
-	'nothrflavour:s' => \$nothrflavour,
-	'mode=s' => \$mode,
-	'listmodules=s' => \$listmodules,
-	'version=s' => \$force_version,
-	'branch=s' => \$branch,
-	'output=s' => \$output,
-	'stage=s' => \$stagedir,
-	'root:s' => \$root,
-	'sysroot:s' => \$sysroot,
-	'sysconfdir=s' => \$sysconfdir,
-	'localstatedir=s' => \$localstatedir,
-	'lb-tag=s' => \$lb_tag,
-	'lbjp-common-tag=s' => \$lbjp_tag,
-	'jp-tag=s' => \$jp_tag,
-	'jobid-tag=s' => \$jobid_tag,
-	'canl-tag=s' => \$canl_tag,
-	'help' => \$help,
-	'libdir=s' => \$libdir,
-	'project=s' => \$project,
-	'debug' => \$debug,
-);
-
-for (@nodes) {
-	$enable_nodes{$_} = 0;
-	$disable_nodes{$_} = 0;
-	
-	push @opts,"disable-$_",\$disable_nodes{$_};
-	push @opts,"enable-$_",\$enable_nodes{$_};
-}
-
-push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs;
-push @opts,"with-$_=s",\$jar{$_} for keys %jar;
-
-my @keeparg = @ARGV;
-
-GetOptions @opts or die "Errors parsing command line\n";
-$prefix=~s/\/$//;
-$root=~s/\/$//;
-$sysroot=~s/\/$//;
-if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; }
-if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; }
-$sysconfdir=~s/\/$//;
-$localstatedir=~s/\/$//;
-
-$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq '';
-$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq '';
-$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq '';
-
-$externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq '';
-$externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq '';
-$externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq '';
-
-if ($project =~ /^([^0-9]*)(.*)$/) {
-	$project = $1;
-	$project_version = $2;
-}
-%project = %{$projects{$project}};
-$project_version = $project{current_version} unless $project_version;
-for my $platform (keys %{$project{etics_externs}}) {
-	for $_ (keys %{$project{etics_externs}{$platform}}) {
-		$etics_externs{$platform}{$_} = $project{etics_externs}{$platform}{$_};
-	}
-}
-reshuffle_platforms(\%etics_externs, $project{supported_platforms});
-reshuffle_platforms(\%{$project{etics_externs_devel}}, $project{supported_platforms});
-for $_ (keys %{$project{etics_projects}}) {
-	$etics_projects{$_} = $project{etics_projects}{$_};
-}
-for $_ (keys %{$project{need_externs_aux}}) {
-	$need_externs_aux{$_} = $project{need_externs_aux}{$_};
-}
-for my $ext (keys %need_externs_aux) {
-	for (@{$need_externs_aux{$ext}}) {
-		my ($pkg, $type) =/([^:]*)(?::(.*))?/;
-		$type = 'BR' unless ($type);
-
-		push @{$need_externs{$ext}},$pkg;
-		$need_externs_type{$ext}->{$pkg} = $type;
-	}
-}
-if ($project eq 'emi') {
-	$extranodmod{lb} = 'lb.emi-lb';
-	$extranodmod{px} = 'px.emi-px';
-}
-for $_ (keys %{$project{modules}}) {
-	push @{$lbmodules{$_}},@{$project{modules}{$_}};
-}
-
-
-if ($help) { usage(); exit 0; }
-
-if ($listmodules) {
-	my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name};
-	my @m;
-
-	if (exists $lbmodules{$listmodules}) {
-		@m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}};
-	} else {
-		if ($project eq 'emi' and $project_version == 1) {
-			# no sub-packages in EMI-1
-		} else {
-			for my $sub (keys %subpackages) {
-				push @m, $sub if ($subpackages{$sub} eq $listmodules);
-			}
-		}
-	}
-	print map $_ eq "" ? "" : "$_ ", @m;
-	print "\n";
-	exit 0;
-}
-
-warn "$0: --branch and --output make sense only in --mode=etics\n"
-	if ($output || $branch) && $mode ne 'etics';
-
-my $en;
-for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; }
-
-my $dis;
-for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; }
-
-die "--enable-* and --disable-* are mutually exclusive\n"
-	if $en && $dis;
-
-die "--module cannot be used with --enable-* or --disable-*\n"
-	if $module && ($en || $dis);
-
-die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}};
-
-if ($dis) {
-	for (@nodes) {
-		$enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_});
-	}
-}
-
-if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } };
-
-for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; }
-
-$stagedir = $root unless $stagedir;
-$stagedir=~s/\/$// if ($stagedir);
-
-if ($mode eq 'build') { for my $ext (keys %externs) {
-	if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; }
-	elsif (defined $externs{$ext}{pkg}) {
-		my ($flag, $env, $cmd, $ret);
-		my $pkg = $externs{$ext}{pkg};
-		my $flagname = uc $externs{$ext}{pkg};
-		$flagname =~ s/-[0-9\.]*$//;
-		$flagname =~ y/-\+/_X/;
-
-		print "Checking $pkg ... ";
-		$env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig";
-		$cmd = "$env pkg-config $pkg --exists >/dev/null";
-		`$cmd`; $ret = $?;
-		print "('$cmd' => $ret)\n" if ($debug);
-		if ($ret == 0) {
-			$externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`;
-			chomp $externs{$ext}{prefix};
-			print "$externs{$ext}{prefix}\n";
-
-			$flag=`$env pkg-config $pkg --cflags`;
-			$externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag);
-			$flag=`$env pkg-config $pkg --libs`;
-			$externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag);
-		} else {
-			print "(using default $externs{$ext}{prefix})\n";
-		}
-		print "\n" if ($debug);
-	}
-	elsif ($ext eq 'jdk') {
-		my $jdk_prefix;
-
-		print "Looking for some caffein ... ";
-		if (defined $ENV{'JDK_HOME'}) {
-			$jdk_prefix = $ENV{'JDK_HOME'};
-			print "JDK_HOME=$jdk_prefix\n";
-		} elsif (defined $ENV{'JAVA_HOME'}) {
-			$jdk_prefix = $ENV{'JAVA_HOME'};
-			print "JAVA_HOME=$jdk_prefix\n";
-		} else {
-			foreach my $i (0..$#{$externs{$ext}{locations}}) {
-				if (-e $externs{$ext}{locations}[$i]) {
-					$jdk_prefix=$externs{$ext}{locations}[$i];
-					print "(found directory $jdk_prefix)\n";
-					last;
-				}
-			}
-			print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix);
-		}
-		$externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix);
-	}
-} }
-
-if ($mode eq 'build') {
-	print "Writing config.status\n";
-	open CONF,">config.status" or die "config.status: $!\n";
-	for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') {
-		print CONF "$_=$ENV{$_} " if (defined $ENV{$_});
-	}
-	print CONF "$0 @keeparg\n";
-	close CONF;
-}
-
-
-my @modules;
-my %aux;
-
-if ($module) {
-#	push @modules,split(/[,.]+/,$module);
-	push @modules,$module;
-}
-else {
-	@modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes));
-	
-	my $n;
-
-	do {
-		local $"="\n";
- 		$n = $#modules;
-		push @modules,(map @{$deps{$_}},@modules);
-
-		undef %aux; @aux{@modules} = (1) x ($#modules+1);
-		@modules = keys %aux;
-	} while ($#modules > $n);
-}
-
-@aux{@modules} = (1) x ($#modules+1);
-delete $aux{$_} for (split /,/,$staged);
-@modules = keys %aux;
-
-mode_build() if $mode eq 'build';
-mode_checkout() if $mode eq 'checkout';
-mode_etics($module) if $mode eq 'etics';
-
-sub mode_build {
-	print "\nBuilding modules: @modules\n";
-	print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n";
-	
-	my @ext = map @{$need_externs{$_}},@modules;
-	my @myjars = map @{$need_jars{$_}},@modules;
-	undef %aux; @aux{@ext} = 1;
-	@ext = keys %aux;
-	undef %aux; @aux{@myjars} = (1) x ($#myjars+1);
-	@myjars = keys %aux;
-	
-	print "\nRequired externals:\n";
-	print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext;
-	print "\t$_: $jar{$_}\n" for @myjars;
-	for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } };
-	print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n";
-
-	mkinc($_) for @modules;
-
-	if ($module) {
-		print "Not creating summary Makefile\n" if $debug;
-	} else {
-		print "Creating Makefile\n";
-
-		open MAK,">Makefile" or die "Makefile: $!\n";
-
-		print MAK "all: @modules\n\n";
-		print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n";
-		print MAK "clean check install:\n";
-
-		for (@modules) {
-			my $full = full($_);
-			print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n"
-		}
-
-		print MAK "\ndistclean:\n";
-
-		for (@modules) {
-			my $full = full($_);
-			print MAK $buildroot{$_} eq '' ?
-				"\tcd $full && \${MAKE} distclean\n" :
-				"\trm -rf $full/$buildroot{$_}\n"
-		}
-
-		print MAK "\n";
-
-		for (@modules) {
-			my %ldeps; undef %ldeps;
-			@ldeps{@{$deps{$_}}} = 1;
-			for my $x (split /,/,$staged) { delete $ldeps{$x}; }
-			my @dnames = $module ? () : keys %ldeps;
-			my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage';
-
-			my $full = full($_);
-			my $build = $buildroot{$_};
-
-			print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n";
-			print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n";
-		}
-
-		close MAK;
-	}
-}
-	
-sub mode_checkout() {
-	for (@modules) {
-		my $module = $_;
-		my $tag = "";
-		if ($lb_tag){
-			for (@{$lbmodules{lb}}){
-				if ("lb.".$_ eq $module){
-					$tag = '-r '.$lb_tag;
-				}
-			}	
-		}
-		if ($lbjp_tag) {
-			for (@{$lbmodules{'lbjp-common'}}){
-				if ("lbjp-common.".$_ eq $module){
-                                        $tag = '-r '.$lbjp_tag;
-                                }
-			}
-		}
-		if ($jp_tag){
-			for (@{$lbmodules{'jp'}}){
-	                        if ("jp.".$_ eq $module){
-                                        $tag = '-r '.$jp_tag;
-	                        }
-                        }
-		}
-		if ($jobid_tag){
-			for (@{$lbmodules{jobid}}){
-				if ("jobid.".$_ eq $module){
-                                        $tag = '-r '.$jobid_tag;
-                                }
-			}
-		}
-		if ($canl_tag) {
-			for (@{$lbmodules{'canl'}}){
-				if ("canl.".$_ eq $module){
-                                        $tag = '-r '.$canl_tag;
-                                }
-			}
-		}
-		#if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){
-		#	print "found";
-		#}
-		$_ = full($_);
-		print "\n*** Checking out $_\n";
-		system("cvs checkout  $tag $_") == 0 or die "cvs checkout $tag $_: $?\n";
-	}
-}
-
-BEGIN{
-%etics_externs = (
-	default => {
-		'myproxy-devel'=>'myproxy-devel',
-		'myproxy-server'=>'myproxy-server',
-		'myproxy-admin'=>'myproxy-admin',
-		cares=>'c-ares',
-		utiljava=>'org.glite.security.util-java',
-		gpt=>'gpt',
-		fetchcrl=>'fetch-crl',
-		activemq=>'activemq-cpp-library',
-	},
-);
-
-%etics_projects = (
-);
-
-%need_externs_aux = (
-	'lb.client' => [ qw/cppunit:B classads libtool:B globus:B/ ],
-	'lb.common' => [ qw/expat cares:B cppunit:B classads libtool:B globus:B/ ],
-	'lb.doc' => [ qw/tetex-latex:B/ ],
-	'lb.logger' => [ qw/cppunit:B libtool:B globus:B/ ],
-	'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B globus:B/ ],
-	'lb.nagios' => [ qw/globus_proxy_utils:R/ ],
-	'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql-server:R cppunit:B gsoap:B classads voms:B lcas gridsite:B bison:B libtool:B libxml2 flex:B/ ],
-	'lb.state-machine' => [ qw/classads libtool:B libxslt:B expat:B globus:B/ ],
-	'lb.utils' => [ qw/cppunit:B libtool:B globus:B/ ],
-	'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ],
-	'lb.ws-test' => [ qw/gsoap:B libtool:B globus:B/ ],
-	'lb.types' => [ qw// ],
-	'lb.harvester' => [ qw/docbook-utils:B libtool:B globus:B/ ],
-	'lbjp-common.db' => [ qw/mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B/ ],
-	'lbjp-common.log' => [ qw/log4c libtool:B/ ],
-	'lbjp-common.maildir' => [ qw/libtool:B/ ],
-	'lbjp-common.server-bones' => [ qw/libtool:B/ ],
-	'lbjp-common.trio' => [ qw/cppunit:B libtool:B/ ],
-	'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B/ ],
-	'lbjp-common.gss' =>  [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B/ ],
-	'lbjp-common.gsoap-plugin' =>  [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B/ ],
-	'jobid.api-c' =>  [ qw/cppunit:B libtool:B openssl:B/ ],
-	'jobid.api-cpp' =>  [ qw/cppunit:B libtool:B/ ],
-	'jobid.api-java' =>  [ qw/ant:B jdk:B/ ],
-	'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B/ ],
-        'jp.doc' => [],
-        'jp.index' => [ qw/gsoap globus_essentials:R globus:B mysql-server:R/ ],
-        'jp.primary' => [ qw/classads gsoap libtar globus_essentials:R globus:B  mysql-server:R/ ],
-        'jp.server-common' => [],
-        'jp.ws-interface' => [],
-	'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ],
-	'gridsite.commands' => [ qw/curl:R openssl:R/ ],
-	'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ],
-	'gridsite.libs' => [ qw/libxml2:R openssl:R/ ],
-	'gridsite.devel' => [ qw// ],
-	'gridsite.slashgrid' => [ qw/curl:R fuse:R/],
-	'gridsite.services' => [ qw/curl:R gsoap:R/ ],
-	'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ],
-	'gridsite.gsexec' => [ qw// ],
-	'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ],
-	'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B/ ],
-	'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec
-	'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B krb5-devel:B/ ],
-);
-
-%need_jars = (
-	'jobid.api-java' => [ qw/jakarta-commons-codec/ ],
-	'lb.client-java' => [ qw/jakarta-commons-lang/ ],
-);
-
-for my $jar (keys %need_jars) {
-	for (@{$need_jars{$jar}}) {
-		$need_externs_type{$jar}->{$_} = 'BR'; 	# XXX
-	}
-}
-
-%deps_aux = (
-	'lb.client' => [ qw/
-		lb.types:B lb.common
-		lbjp-common.trio
-		jobid.api-cpp:B jobid.api-c
-		lbjp-common.gss
-	/ ],
-	'lb.client-java' => [ qw/
-		lb.types:B
-		lb.ws-interface:B
-		jobid.api-java
-	/ ],
-	'lb.common' => [ qw/
-		jobid.api-cpp:B jobid.api-c
-		lb.types:B lbjp-common.trio lbjp-common.gss
-	/ ],
-	'lb.doc' => [ qw/lb.types:B/ ],
-	'lb.logger' => [ qw/
-		lbjp-common.trio
-		lbjp-common.log
-		jobid.api-c
-		lb.common
-		lbjp-common.gss
-	/ ],
-	'lb.logger-msg' => [ qw/
-		lb.logger:B
-	/ ],
-	'lb.nagios' => [ qw/
-		lb.client:R
-		lb.ws-test:R
-		lb.utils:R
-	/ ],
-	'lb.server' => [ qw/
-		lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R
-		lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log
-		jobid.api-c
-		lbjp-common.gsoap-plugin lbjp-common.gss
-	/ ],
-	'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ],
-	'lb.utils' => [ qw/
-		lbjp-common.jp-interface
-		jobid.api-c
-		lbjp-common.trio lbjp-common.maildir
-		lb.client lb.state-machine lb.types:B
-	/ ],
-	'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ],
-	'lb.ws-interface' => [ qw/lb.types:B/ ],
-	'lb.types' => [ qw// ],
-	'lb.harvester' => [ qw/
-		jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client
-		lbjp-common.gss lbjp-common.log
-	/ ],
-	'lb.yaim' => [ qw// ],
-	'lb.glite-LB' => [ qw/
-		lb.logger:R lb.server:R lb.utils:R lb.doc:R
-		lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R
-		lb.logger-msg:R
-	/ ],
-	'lb.emi-lb' => [ qw/
-		lb.logger:R lb.server:R lb.utils:R lb.doc:R
-		lb.ws-test:R lb.harvester:R lb.yaim:R lb.client-java:R
-		lb.logger-msg:R
-	/ ],
-	'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ],
-	'lbjp-common.maildir' => [ qw// ],
-	'lbjp-common.log' => [ qw// ],
-	'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ],
-	'lbjp-common.trio' => [ qw// ],
-	'lbjp-common.gss' =>  [ qw// ],
-	'lbjp-common.gsoap-plugin' =>  [ qw/lbjp-common.gss/ ],
-	'jobid.api-c' =>  [ qw// ],
-	'jobid.api-cpp' =>  [ qw/jobid.api-c/ ],
-	'jobid.api-java' =>  [ qw// ],
-
-	'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ],
-
-	'jp.client' => [ qw/
-                jp.ws-interface
-                lbjp-common.jp-interface lbjp-common.maildir
-                jobid.api-c
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.doc' => [ qw// ],
-	'jp.index' => [ qw/
-                jp.server-common jp.ws-interface
-                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.primary' => [ qw/
-                jobid.api-c
-                jp.server-common jp.ws-interface
-                lb.state-machine
-                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
-                lbjp-common.gsoap-plugin
-        / ],
-	'jp.server-common' => [ qw/ 
-                lbjp-common.jp-interface lbjp-common.db
-        / ],
-	'jp.ws-interface' => [ qw// ],
-
-	'gridsite.core' => [ qw// ],
-	'gridsite.commands' => [ qw/gridsite.core:B/ ],
-	'gridsite.apache' => [ qw/gridsite.core:B/ ],
-	'gridsite.libs' => [ qw/gridsite.core:B / ],
-	'gridsite.devel' => [ qw/gridsite.core:B/ ],
-	'gridsite.slashgrid' => [ qw/gridsite.core:B/],
-	'gridsite.services' => [ qw/gridsite.core:B/ ],
-	'gridsite.service-clients' => [ qw/gridsite.core:B/ ],
-	'gridsite.gsexec' => [ qw/gridsite.core:B/ ],
-
-	'px.proxyrenewal' => [ qw// ],
-	'px.glite-PX' => [qw/px.myproxy-yaim:R/],
-	'px.emi-px' => [qw/px.myproxy-yaim:R/],
-	'px.myproxy-yaim' => [ qw// ],
-	'px.myproxy-config' => [],
-
-	'canl.c' => [],
-
-	# sub-packages (virtual ETICS components depending on the main)
-	'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ],
-	'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ],
-	'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ],
-	'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ],
-	'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ],
-	'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ],
-	'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ],
-	'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ],
-	'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ],
-	'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ],
-	'lb.client-progs' => [ qw/lb.client:B/ ],
-	'lb.client-devel' => [ qw/lb.client:B/ ],
-	'lb.common-devel' => [ qw/lb.common:B/ ],
-	'lb.logger-devel' => [ qw/lb.logger:B/ ],
-	'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ],
-	'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ],
-	'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ],
-	'canl.c-devel' => [ qw/canl.c:B/ ],
-);
-
-for my $ext (keys %deps_aux) {
-	for (@{$deps_aux{$ext}}) {
-		/([^:]*)(?::(.*))?/;
-		push @{$deps{$ext}},$1;
-		my $type = $2 ? $2 : 'BR';
-		$deps_type{$ext}->{$1} = $type;
-	}
-}
-
-
-%extrafull = (
-	gridsite=>'org.gridsite.core',
-	'canl.c' => 'emi.canl.canl-c',
-	'canl.c-devel' => 'emi.canl.canl-c',
-	'jobid.api-c-devel' => 'org.glite.jobid.api-c',
-	'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp',
-	'lbjp-common.db-devel' => 'org.glite.lbjp-common.db',
-	'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin',
-	'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss',
-	'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface',
-	'lbjp-common.log-devel' => 'org.glite.lbjp-common.log',
-	'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir',
-	'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones',
-	'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio',
-	'lb.client-devel' => 'org.glite.lb.client',
-	'lb.client-progs' => 'org.glite.lb.client',
-	'lb.common-devel' => 'org.glite.lb.common',
-	'lb.logger-devel' => 'org.glite.lb.logger',
-	'lb.state-machine-devel' => 'org.glite.lb.state-machine',
-	'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal',
-	'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal',
-);
-
-#( java => 'client-java' );
-%extranodmod = (
-	db => 'lbjp-common.db',
-	jpprimary => 'jp.primary',
-	jpindex => 'jp.index',
-	jpclient => 'jp.client',
-	lb => 'lb.glite-LB',
-	px => 'px.glite-PX',
-	proxyrenewal => 'px.proxyrenewal',
-	canl => 'canl.c',
-);
-
-%obsoletes = (
-	'lb.yaim' => [ qq/glite-yaim-lb/ ],
-	'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ],
-	'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ],
-	'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec
-	'lbjp-common.gss' => [ qq/glite-security-gss/ ],
-	'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
-);
-
-%conflicts = (
-);
-
-%provides = (
-	'lbjp-common.gss' => [ qq/glite-security-gss/ ],
-	'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
-	'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ],
-);
-
-%cvs_prefix = (
-	'lb' => 'org.glite',
-	'jp' => 'org.glite',
-	'jobid' => 'org.glite',
-	'lbjp-common' => 'org.glite',
-	'gridsite' => 'org',
-	'px' => 'org.glite',
-	'canl' => 'emi',
-);
-
-%cvs_tag_prefix = (
-	'lb' => 'glite-',
-	'jp' => 'glite-',
-	'jobid' => 'glite-',
-	'lbjp-common' => 'glite-',
-	'gridsite' => '',
-	'px' => 'glite-',
-	'canl' => 'emi-',
-);
-
-# ==== projects specification ====
-# etics_name ........... ETICS project name
-# conf_prefix .......... ETICS configurations name prefix
-# tag_prefix ........... VCS tag prefix
-# local_prefix ......... prefix (relative to stage)
-# etics_externs ........ ETICS modules names of externals
-#                        (${NAME.location}, ETICS conf. dependencies)
-# etics_projects ....... ETICS project names of externals
-# etics_externs_devel .. ETICS modules names of devel versions of externals
-# etics_locations ...... ETICS locations in ${NAME.location} properties
-# need_externs_aux ..... project-specific external dependencies
-# supported_platforms .. platforms supported by the project
-# modules .............. additional modules in subsystems
-%projects = (
-	glite => {
-		current_version => 3,
-		etics_name => 'org.glite',
-		conf_prefix => { %cvs_tag_prefix },
-		tag_prefix => { %cvs_tag_prefix },
-		flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}',
-		local_prefix => '',
-		etics_externs => {
-			default => {
-				globus_essentials=>'vdt_globus_essentials',
-				globus=>'globus',
-				globus_proxy_utils=>'vdt_globus_essentials',
-				gridsite=>'org.gridsite.libs',
-				yaim_core=>'org.glite.yaim.core',
-				gip_release=>'glite-info-provider-release',
-				gip_service=>'glite-info-provider-service',
-				bdii=>'bdii',
-				glite_version=>'glite-version',
-				glite_info_templates=>'glite-info-templates',
-				glue_schema=>'glue-schema',
-				trustmanager=>'org.glite.security.trustmanager',
-				axis=>'axis',
-				lcas=>'org.glite.security.lcas',
-				gsoapxx=>'-',
-				jdk=>'jdk',
-				voms=>'org.glite.security.voms-api-cpp',
-			},
-		},
-		etics_externs_devel => {
-			default => {
-				gridsite=>'org.gridsite.devel',
-				voms=>'org.glite.security.voms-api',
-			},
-		},
-		etics_projects => {
-			vdt=>[qw/globus globus_essentials globus_proxy_utils gpt/],
-			'org.glite'=>[qw/voms gridsite lcas gip_release gip_service bdii glite_version glite_info_templates glue_schema yaim_core/],
-		},
-		etics_locations => {
-			'*' => '',
-		},
-		need_externs_aux => {
-			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ],
-			'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ],
-			'lb.yaim' => [ qw/yaim_core:R/ ],
-			'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/],
-			'px.myproxy-yaim' => [ qw/yaim_core:R/ ],
-		},
-		supported_platforms => {
-			sl5_x86_64_gcc412 => 1,
-			sl5_ia32_gcc412 => 1,
-			deb5_x86_64_gcc432 => 1,
-			deb5_ia32_gcc432 => 1,
-			slc4_x86_64_gcc346 => 1,
-			slc4_ia32_gcc346 => 1,
-		},
-		modules => {
-			'lb' => [ qw/glite-LB/ ],
-			'px' => [ qw/glite-PX/ ],
-		},
-	},
-
-	emi => {
-		current_version => 2,
-		etics_name => 'emi',
-		conf_prefix => {
-			'lb' => 'emi-',
-			'jp' => 'emi-',
-			'jobid' => 'emi-',
-			'lbjp-common' => 'emi-',
-			'gridsite' => 'emi-',
-			'px' => 'emi-',
-			'canl' => 'emi-',
-		},
-		tag_prefix => { %cvs_tag_prefix },
-		flavours => '--thrflavour= --nothrflavour=',
-		local_prefix => '/usr',
-		etics_externs => {
-			default => {
-				globus_essentials=>'globus-gssapi-gsi',
-				globus=>'globus-gssapi-gsi-devel',
-				globus_proxy_utils=>'globus-proxy-utils',
-				gridsite=>'emi.gridsite.libs',
-				yaim_core=>'emi.yaim.yaim-core',
-				yaim_bdii=>'emi.bdii.yaim-bdii',
-				gip_service=>'emi.bdii.glite-info-provider-service',
-				bdii=>'emi.bdii.core',
-				glite_version=>'emi.emi-version',
-				glue_schema=>'emi.bdii.glue-schema',
-				trustmanager=>'emi.java-security.trustmanager',
-				trustmanager_axis=>'emi.java-security.trustmanager-axis',
-				axis=>'axis1.4',
-				lcas=>'emi.sac.lcas',
-				gsoapxx=>'-',
-				jdk=>'java',
-				voms => 'emi.voms.voms-api',
-			},
-			sl5_x86_64_gcc412EPEL => {
-				'myproxy-devel' => 'myproxy-devel.x86_64',
-			},
-			sl6_x86_64_gcc446EPEL => {
-				'myproxy-devel' => 'myproxy-devel.x86_64',
-			},
-			deb6_x86_64_gcc445 => {
-				axis => 'axis1.4',
-				# mappings in ETICS project configuration
-				#globus_essentials => 'libglobus-gssapi-gsi4',
-				#globus => 'libglobus-gssapi-gsi-dev',
-				#axis => 'libaxis-java',
-				#cares => 'libc-ares2',
-				#cppunit => 'libcppunit',
-				#expat => 'libexpat1',
-				#log4c => 'liblog4c3',
-				#curl => 'libcurl3',
-				#'mysql' => 'libmysqlclient16',
-				#'mysql-devel' => 'libmysqlclient-dev',
-				#libxslt => 'xsltproc',
-				#'jakarta-commons-codec' => 'libcommons-codec-java',
-				#'jakarta-commons-lang' => 'libcommons-lang-java',
-				#'tetex-latex' => 'texlive-latex-extra',
-				#'perl-LDAP' => 'libnet-ldap-perl',
-				#'fuse-lib' => 'libfuse2',
-				#'fuse' => 'fuse-utils',
-			},
-		},
-		etics_externs_devel => {
-			default => {
-				cares => 'c-ares-devel',
-				classads => 'classads-devel',
-				cppunit => 'cppunit-devel',
-				expat => 'expat-devel',
-				gsoap => 'gsoap-devel',
-				voms => 'emi.voms.voms-api-devel',
-				libtar => 'libtar-devel',
-				log4c => 'log4c-devel',
-				postgresql => 'postgresql-devel',
-				curl => 'curl-devel',
-				libxml2 => 'libxml2-devel',
-				openssl => 'openssl-devel',
-				gridsite=>'emi.gridsite.devel',
-				jdk=>'java-devel',
-			},
-			deb6_x86_64_gcc445 => {
-				# mappings in ETICS project configuration
-				#cares => 'libc-ares-dev',
-				#cppunit => 'libcppunit-dev',
-				#expat => 'libexpat1-dev',
-				#libtar => 'libtar-dev',
-				#log4c => 'liblog4c-dev',
-				#postgresql => 'libpq-dev',
-				#curl => 'libcurl4-openssl-dev',
-				#libxml2 => 'libxml2-dev',
-				#openssl => 'libssl-dev',
-				#'tetex-latex' => 'texlive-latex-extra',
-				#libxslt=>'xsltproc',
-				#'httpd-devel' => 'apache2-prefork-dev',
-				#'fuse-devel' => 'libfuse-dev',
-				#gsoap => 'gsoap',
-				#'krb5-devel' => 'libkrb5-dev',
-			},
-		},
-		etics_projects => {
-			'emi'=>[qw/voms voms-devel gridsite lcas gip_service bdii glite_version glue_schema yaim_core yaim_bdii trustmanager trustmanager_axis/],
-		},
-		etics_locations => {
-			axis => 'axis',
-		},
-		need_externs_aux => {
-			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ],
-			'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ],
-			'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ],
-			'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/],
-			'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ],
-		},
-		supported_platforms => {
-			sl5_x86_64_gcc412EPEL => 1,
-			sl5_ia32_gcc412EPEL => 1,
-			sl6_x86_64_gcc446EPEL => 1,
-			deb6_x86_64_gcc445 => 1,
-		},
-		modules => {
-			'lb' => [ qw/emi-lb/ ],
-			'px' => [ qw/emi-px/ ],
-		},
-	},
-);
-
-%platform_properties = (
-	'jobid.api-java' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.types' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.doc' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.ws-interface' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.yaim' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'lb.nagios' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'px.yaim' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'px.myproxy-config' => {
-		default => { 'package.buildarch' => 'noarch' },
-	},
-	'gridsite.devel' => {
-		default => { 'packageName' => 'gridsite-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' },
-	},
-	'canl.c-devel' => {
-		default => { 'packageName' => 'canl-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' },
-	},
-	'jobid.api-c-devel' => {
-		default => { 'packageName' => 'glite-jobid-api-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' },
-	},
-	'jobid.api-cpp-devel' => {
-		default => { 'packageName' => 'glite-jobid-api-cpp-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' },
-	},
-	'lbjp-common.db-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-db-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' },
-	},
-	'lbjp-common.gsoap-plugin-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' },
-	},
-	'lbjp-common.gss-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-gss-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' },
-	},
-	'lbjp-common.jp-interface-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' },
-	},
-	'lbjp-common.log-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-log-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' },
-	},
-	'lbjp-common.maildir-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-maildir-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' },
-	},
-	'lbjp-common.server-bones-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' },
-	},
-	'lbjp-common.trio-devel' => {
-		default => { 'packageName' => 'glite-lbjp-common-trio-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' },
-	},
-	'lb.client-devel' => {
-		default => { 'packageName' => 'glite-lb-client-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' },
-	},
-	'lb.common-devel' => {
-		default => { 'packageName' => 'glite-lb-common-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' },
-	},
-	'lb.state-machine-devel' => {
-		default => { 'packageName' => 'glite-lb-state-machine-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' },
-	},
-	'lb.logger-devel' => {
-		default => { 'packageName' => 'glite-lb-logger-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' },
-	},
-	'px.proxyrenewal-devel' => {
-		default => { 'packageName' => 'glite-px-proxyrenewal-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' },
-	},
-	'canl.c-devel' => {
-		default => { 'packageName' => 'canl-c-devel' },
-		deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' },
-	},
-);
-
-my @k = keys %deps_aux;
-@buildroot{@k} = ('') x ($#k+1);
-
-$buildroot{'gridsite.core'} = 'src';
-}
-
-sub full
-{
-	my ($short) = @_;
-	my $subsys = $short;
-	$subsys =~ s/\..*//;
-
-	my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite';
-	return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short";
-}
-
-sub get_version
-{
-	my ($fmod, $top_srcdir) = @_;
-
-	my ($subsys,$mod) = split /\./,$fmod,2;
-	my ($major,$minor,$rev,$age);
-	my $old_;
-
-	if ($force_version) {
-		$force_version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/;
-		($major,$minor,$rev,$age) = ($1,$2,$3,$4);
-	}
-	else {
-		my $path = "$top_srcdir/project";
-		if ($subsys eq 'gridsite') {
-			$path = "$cvs_prefix{$subsys}.$subsys.core/project";
-		}
-		open V,"$path/version.properties"
-			or die "$path/version.properties: $!\n";
-
-		$old_ = $_;
-		while () {
-			chomp;
-			($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/;
-			$age = $1 if /module\.age\s*=\s*([[:digit:]]+)/;
-		}
-		close V;
-		$_ = $old_;
-	}
-	$version = "$major.$minor.$rev-$age";
-
-	return ($major, $minor, $rev, $age);
-}
-
-sub get_description
-{
-	my ($top_srcdir) = @_;
-
-	my $cvs_module = $top_srcdir;
-	my $package_description = "";
-	my $package_summary = "";
-
-	if (-e "$cvs_module/project/package.description") {
-		open V, "$cvs_module/project/package.description";
-		$package_description = join ("", );
-		close V;
-		chomp $package_description;
-	}
-	else {
-		print STDERR "package.description not found for $subsys.$module!\n"; }
-
-	if (-e "$cvs_module/project/package.summary") {
-		open V, "$cvs_module/project/package.summary";
-		$package_summary = join ("", );
-		close V;
-		chomp $package_summary;
-		$package_summary =~ s/\n/\\n/g;
-	}
-	else {
-		print STDERR "package.summary not found for $subsys.$module!\n"; }
-
-	return ($package_summary, $package_description);
-}
-
-sub mkinc
-{
-	my %aux;
-	undef %aux;
-	my @m=qw/
-lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb
-lbjp-common.gss lbjp-common.gsoap-plugin
-jobid.api-c jobid.api-cpp jobid.api-java
-lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin
-jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface
-px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px
-canl.c
-/;
-	@aux{@m} = (1) x ($#m+1);
-
-	my ($short) = @_;
-	my $full = full $short;
-	my ($subsys,$mod) = split /\./,$short,2;
-	my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}";
-
-	unless ($aux{$short}) {
-		print "Makefile.inc not needed in $full\n";
-		return;
-	}
-
-	my $top_srcdir = '.';
-	my $abs_srcdir = '';
-	my $build = '';
-
-	if ($module) {
-		$top_srcdir = $0;
-		$top_srcdir =~ s,/?[^/]*$,,;
-		$abs_srcdir = $top_srcdir;
-		$top_srcdir =~ s,^$,\.,;
-	} else {
-		$build = "$full/";
-		$abs_srcdir = "$full/";
-		unless ($buildroot{$_} eq '') {
-			$top_srcdir = '..';
-			$build .= "$buildroot{$_}/";
-			unless (-d "$build") {
-				mkdir "$build" or die "mkdir $build: $!\n";
-			}
-		}
-	}
-
-	my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir;
-	my ($package_summary, $package_description) = get_description $abs_srcdir;
-	if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; }
-	my $package_description_debian = $package_description;
-	$package_description_debian =~ s/^/ /mg;
-
-	my ($old_locale, $specdate, $debdate);
-
-	# files for ETICS always in root source directory
-	mkdir $abs_srcdir."project" unless (-d $abs_srcdir."project");
-	open PKGCHL,">".$abs_srcdir."project/changelog"
-		or die $abs_srcdir."project/changelog: $!\n";
-	$old_locale = setlocale(LC_TIME);
-	setlocale(LC_TIME, "C");
-	$specdate = strftime("%a %b %d %Y", gmtime());
-	$debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime());
-	setlocale(LC_TIME, $old_locale);
-	print PKGCHL qq{* $specdate CESNET team 
-- automatically generated package
-};
-	close PKGCHL;
-
-	unless ($top_srcdir eq '.') {
-		unlink $build."Makefile";
-		symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n";
-	}
-
-	open MKINC,">".$build."Makefile.inc"
-		or die $build."Makefile.inc: $!\n";
-
-	print "Creating ".$build."Makefile.inc\n";
-
-	print MKINC qq{project = $project
-PREFIX = $root
-prefix = $prefix
-stagedir = $stagedir
-sysroot = $sysroot
-sysconfdir = $sysconfdir
-localstatedir = $localstatedir
-thrflavour = $thrflavour
-nothrflavour = $nothrflavour
-libdir = $libdir
-top_srcdir = $top_srcdir
-};
-
-	for (@{$need_externs{$short}}) {
-		next unless defined $externs{$_} and defined $externs{$_}{prefix};
-		print MKINC "${_}_prefix = $externs{$_}{prefix}\n";
-		print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags};
-	}
-
-	for (@{$need_jars{$short}}) {
-		print MKINC "${_}_jar = $jar{$_}\n"
-	}
-
-	my $need_gsoap = 0;
-	for (@{$need_externs{$short}})  { $need_gsoap = 1 if $_ eq 'gsoap'; }
-
-	print MKINC "gsoap_default_version=".gsoap_version()."\n"  if $need_gsoap;
-
-	close MKINC;
-
-	my $dh;
-	my $debian = 0;
-
-	opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!";
-	for my $dir (readdir $dh) {
-		if ($dir=~/^(.*)\.spec$/) {
-			if ($1 ne $packageName) {
-				printf STDERR "Changed RPM name: $packageName --> $1\n" if ($debug);;
-				$packageName=$1;
-			}
-			last;
-		}
-	}
-	closedir $dh;
-
-	for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") {
-		if (-f "$abs_srcdir/project/$file") {
-			my $old_ = $_;
-			printf STDERR "Creating $build$file\n" if ($debug);;
-			open DST, ">$build$file";
-			open SRC, "<$abs_srcdir/project/$file";
-			while () {
-				if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; }
-				if (/\@URL\@/) { s/\@URL\@/$package{url}/g; }
-				if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; }
-				if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; }
-				if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; }
-				if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; }
-				if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; }
-				if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; }
-				if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; }
-				if (/\@AGE\@/) { s/\@AGE\@/$age/g; }
-				if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; }
-				if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; }
-				if (/\@DEBIAN_VCS\@/) { s/\@DEBIAN_VCS\@/$package{debian_vcs}/g; }
-				if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; }
-				if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; }
-				if (/^\s*.+\/configure\s/ and $force_version) {
-					print "Version forced to $version\n" if ($debug);;
-					s/--version\s+\S+\s?//;
-					s/$/ --version $version/;
-				}
-				printf DST "%s", "$_";
-			}
-			close SRC;
-			close DST;
-			$_ = $old_;
-		}
-	}
-
-	print "Creating ${build}debian/\n" if ($debug);;
-
-	`rm -rfv  ${build}debian`;
-	mkdir $build."debian" or die $!;
-	`cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`;
-	`mv ${build}debian.* ${build}debian/ 2>/dev/null`;
-	`rm -f ${build}debian/*.orig`;
-	opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!";
-	for $_ (readdir $dh) {
-		if (/^debian\.(.*)/) {
-			`mv ${build}debian/$_ ${build}debian/$1`;
-			$debian = 1;
-		}
-	}
-	closedir $dh;
-
-	if ($debian) {
-		my ($dir, $file);
-
-		chmod 0755, "${build}debian/rules";
-		$file="${build}debian/docs"; if (not -f $file) { `touch $file`; }
-		$dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; }
-		$file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` }
-		$file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` }
-		$file="${build}debian/changelog"; if (not -f $file) {
-			open FH, ">$file" or die $!;
-			print FH qq{$packageName ($major.$minor.$rev-$age) unstable; urgency=low
-
-  * Automatically generated package
-
- -- $package{maintainer}  $debdate
-};
-			close FH;
-		}
-
-	} else {
-		`rm -rf ${build}debian`;
-	}
-}
-
-BEGIN{
-};
-
-sub mode_etics_packaging {
-	my ($fmod, $cmd, $rpmprepare, $debprepare) = @_;
-	my ($workspaceDir, $srcPackageName, $srcAge, $topDir);
-
-	# old-school packaging by ETICS for EMI-1
-	if ($project eq 'emi' and $project_version == 1) { return; }
-
-	if ($fmod eq 'gridsite.core') {
-		$workspaceDir = '..';
-		$srcPackageName = 'gridsite';
-		$srcAge = '';
-		$topDir = '../';
-	} else {
-		$workspaceDir = '${workspaceDir}';
-		$srcPackageName = '${packageName}';
-		$srcAge = '-${age}';
-		$topDir = '';
-	}
-
-	$cmd->{clean} = 'make clean
-	rm -rfv ${package.tgzLocation} ${package.SRPMSLocation}';
-	$cmd->{default}{packaging} = $rpmprepare;
-	$cmd->{default}{packaging} .= "dir=\${workspaceDir}/rpm_build_src_\$\$
-	mkdir -p \${package.tgzLocation} \${package.SRPMSLocation} \$dir/{BUILD,RPMS,SOURCES,SRPMS} 2>/dev/null || true
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/SOURCES/
-	rpmbuild -bs --nodeps --define \"_topdir \$dir\" $srcPackageName.spec
-	cp -v \$dir/SRPMS/*.src.rpm \${package.SRPMSLocation}/
-	rm -rf \$dir";
-
-	for my $p ('deb5_x86_64_gcc432', 'deb5_ia32_gcc432', 'deb6_x86_64_gcc445', 'deb6_ia32_gcc445') {
-		for my $c (keys %{$cmd->{default}}) { $cmd->{$p}{$c} = $cmd->{default}{$c}; }
-		$cmd->{$p}{clean} = 'make clean
-	rm -rfv ${package.tgzLocation} ${package.SDEBSLocation}';
-		$cmd->{$p}{packaging} = $debprepare;
-		$cmd->{$p}{packaging} .= "dir=\${workspaceDir}/dpkg_build_src_\$\$
-	mkdir -p \${package.tgzLocation} \${package.SDEBSLocation} \$dir 2>/dev/null || true
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \${package.tgzLocation}/
-	cp -vf $workspaceDir/$srcPackageName-\${version}${srcAge}.src.tar.gz \$dir/${srcPackageName}_\${version}.orig.tar.gz
-	tar xzf \$dir/${srcPackageName}_\${version}.orig.tar.gz -C \$dir
-	cp -rf ${topDir}debian/ \$dir/$srcPackageName-\${version}/
-	cd \$dir/$srcPackageName-\${version}
-	dpkg-buildpackage -S -d -nc
-	cd -
-	cp -v \$dir/*.tar.gz \$dir/*.dsc \${package.SDEBSLocation}/
-	rm -rf \$dir";
-	}
-}
-
-sub mode_etics {
-	$fmod = shift;
-
-	die "$0: --module required with --etics\n" unless $fmod;
-	
-	my ($subsys,$module) = split /\./,$fmod,2;
-	my $full = full "$subsys.$module";
-
-	my ($major,$minor,$rev,$age) = get_version $fmod, $full;
-
-	# XXX: --with ignored for platform-dependend packages
-	my @copts = ();
-	my %ge;
-	@ge{@{$etics_projects{$project{etics_name}}}} = (1) x ($#{$etics_projects{$project{etics_name}}}+1);
-
-	for (@{$need_externs{"$subsys.$module"}}) {
-	    if ($need_externs_type{"$subsys.$module"}->{$_}=~/B/ and (defined $externs{$_} or defined $jar{$_})) {
-		my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_;
-		next if ($eext eq '-');
-		if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_}) {
-			$eext = $project{etics_locations}{$_} if ($project{etics_locations}{$_});
-			push @copts,$ge{$_} ? "--with-$_=\${stageDir}" : "--with-$_=\${$eext.location}";
-		} else {
-			if ($ge{$_} and not defined $externs{$_}{pkg}) {
-				push @copts, "--with-$_=\${stageDir}";
-			}
-		}
-	    }
-	}
-
-	for (@{$need_jars{"$subsys.$module"}}) {
-		my $eext = $etics_externs{default}{$_} ? $etics_externs{default}{$_} : $_;
-
-		push @copts,"--with-$_ \${$eext.location}$jar{$_}" if (defined $project{etics_locations}{'*'} or defined $project{etics_locations}{$_});
-	}
-
-	my $conf;
-	my $conftag;
-	my ($confprefix, $nameprefix, $packageName);
-
-	$dwpath = "path = \${projectName}/\${moduleName}/\${version}/\${platformName}/\${packageName}-\${version}-\${age}.tar.gz\n";
-
-	$confprefix = $project{conf_prefix}{$subsys};
-	$nameprefix = $confprefix;
-	$nameprefix =~ s/-$//;
-	$nameprefix =~ s/-/\./g;
-	$packageName = "$project{tag_prefix}{$subsys}$subsys-${module}";
-
-	if ($branch) {
-		$conf = "$confprefix${subsys}-${module}_$branch"; 
-		$conftag = $branch;
-		# forced low age number
-		$age = $branch eq 'HEAD' ? '0head' : '0dev';
-		push @copts, '--version ${version}-${age}';
-	}
-	else {
-		$conf = "$confprefix$subsys-${module}_R_${major}_${minor}_${rev}_${age}";
-# XXX: gridsite hack
-		$conftag = $subsys eq 'gridsite' ? "$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}" : 
-			"$project{tag_prefix}{$subsys}$subsys-${module}_R_${major}_${minor}_${rev}_${age}";
-
-		# lowering age for older packaging
-		if ($project eq 'emi' and $project_version == 1) {
-			$age = $age - 1;
-		}
-	}
-
-	# emi1 suffix for older packaging
-	if ($project eq 'emi' and $project_version == 1) {
-		$age = $age.$project.$project_version;
-		$conf = $conf.$project.$project_version;
-	}
-
-	my $file = $output ? $output : "$conf.ini";
-	open C,">$file" or die "$file: $!\n";
-
-	my $buildroot = $buildroot{"$subsys.$module"} eq '' ? '#no build.root' : "build.root = " . $buildroot{"$subsys.$module"};
-
-	my $confdir = $buildroot{"$subsys.$module"} eq '' ? '.' : '..';
-
-	my $cvs_module = full "$subsys.$module";
-	my ($package_summary, $package_description) = get_description $cvs_module;
-	if ($package_description) {
-		$package_description =~ s/\n/\\n/g;
-		$package_description = "package.description = $package_description\n";
-	}
-	if ($package_summary) {
-		$package_summary = "package.summary = $package_summary\n";
-	}
-
-	my %cmd;
-	$cmd_vcs{checkout} = "cvs -d \${vcsroot} co -d \${moduleName} ".($conftag eq 'HEAD' ? '-A' : '-r ${tag}')." $cvs_module 2>/dev/null";
-	#$cmd_vcs{checkout} = "((test -d jra1mw/.git && (cd jra1mw; git pull)) || (git clone -q http://scientific.zcu.cz/git/jra1mw.git";
-	#$cmd_vcs{checkout} .= " && (cd jra1mw; git checkout -b \${tag} --track origin/\${tag})" unless ($conftag eq /HEAD/);
-	#$cmd_vcs{checkout} .= ")) && (test -d \${moduleName} || ln -s jra1mw/$cvs_module \${moduleName})";
-	$cmd_vcs{checkout} .= "\n\ttest -f \${packageName}-\${version}-\${age}.src.tar.gz || (ln -s \${moduleName} \${packageName}-\${version}; tar -chf - \${packageName}-\${version} --exclude CVS --exclude .git --exclude .etics | gzip --best > \${packageName}-\${version}-\${age}.src.tar.gz; rm \${packageName}-\${version})";
-	$cmd_vcs{tag} = "cvs -d \${vcsroot} tag -R \${tag} ${moduleName}";
-
-	$cmd{default}{init} = 'None';
-	$cmd{default}{configure} = 'None';
-	$cmd{default}{compile} = 'None';
-	$cmd{default}{test} = 'None';
-	$cmd{default}{install} = 'None';
-	$cmd{default}{packaging} = 'None';
-	$cmd{default}{clean} = 'make clean';
-
-	if (exists $subpackages{$fmod}) {
-		$cmd{default}{clean} = 'None';
-		$cmd{default}{packaging} = "echo building nothing, $subpackages{$fmod} will build this package";
-		$cmd_vcs{checkout} = "mkdir -v \${moduleName} 2>/dev/null || true";
-	} elsif ($subsys eq 'gridsite') {
-		$cmd_vcs{tag} = 'None';
-
-		if ($module eq 'core') {
-			my $flags;
-
-			if ($project ne 'glite') {
-				# don't evaluate pkg-config calls to get them into source package
-				$flags = 'RELEASE_VERSION=${age}
-	GSOAPDIR=\`pkg-config gsoap --variable=prefix\`
-	OPENSSL_GLOBUS_FLAGS=\`pkg-config globus-openssl --cflags\`
-	OPENSSL_GLOBUS_LIBS=\`pkg-config globus-openssl --libs\`';
-			} else {
-				$flags = 'RELEASE_VERSION=${age}
-	GSOAPDIR=${gsoap.location}
-	OPENSSL_GLOBUS_FLAGS=-I${globus.location}/include/${globus.dbg.nothr.flavor}
-	OPENSSL_GLOBUS_LIBS=-L${globus.location}/${libdir}
-	HTTPD_FLAGS=-I${httpd-devel.location}/include/httpd -I${httpd-devel.location}/include/apache2 -I${httpd-devel.location}/include/apr-1 -I${httpd-devel.location}/include/apr-1.0 -I${httpd-devel.location}/include/apr-0 -I${httpd-devel.location}/include/pcre';
-			}
-
-			$cmd{default}{configure} = "cat > Makefile.inc </dev/null";
-			$cmd{default}{init} = 'echo "/sbin/ldconfig" > project/.post
-	echo "/sbin/ldconfig" > project/.postun';
-			$cmd{default}{configure} = "cat > src/Makefile.inc <{default}}) {
-		$defprops .= $p . ' = ' . $platform_properties{"$subsys.$module"}->{default}->{$p} . "\n";
-	}
-
-	print STDERR "Writing $file\n";
-	print C qq{
-[Configuration-$conf]
-profile = None
-moduleName = $project{etics_name}.$subsys.$module
-displayName = $conf
-description = $cvs_prefix{$subsys}.$subsys.$module
-projectName = $project{etics_name}
-age = $age
-deploymentType = None
-vcsroot = :pserver:anonymous\@glite.cvs.cern.ch:/cvs/glite
-tag = $conftag
-version = $major.$minor.$rev
-$dwpath
-[Platform-default:VcsCommand]
-displayName = None
-description = None
-tag = $cmd_vcs{tag}
-branch = None
-commit = None
-checkout = $cmd_vcs{checkout}
-
-};
-
-	for my $p (keys %cmd) {
-		next if $p ne 'default' and exists $project{supported_platforms} and not exists $project{supported_platforms}{$p};
-
-		print C qq{[Platform-$p:BuildCommand]
-postpublish = None
-packaging = $cmd{$p}{packaging}
-displayName = None
-description = None
-doc = None
-prepublish = None
-publish = None
-compile = $cmd{$p}{compile}
-init = $cmd{$p}{init}
-install = $cmd{$p}{install}
-clean = $cmd{$p}{clean}
-test = $cmd{$p}{test}
-configure = $cmd{$p}{configure}
-checkstyle = None
-
-};
-	}
-
-	print C qq{[Platform-default:Property]
-$buildroot
-package.preserve.libtool = false
-$package_description$package_summary$defprops};
-
-	for (@{$obsoletes{"$subsys.$module"}}) {
-		print C "package.obsoletes = $_\n";
-		print C "package.replaces = $_\n";
-	}
-	for (@{$conflicts{"$subsys.$module"}}) {
-		print C "package.conflicts = $_\n";
-	}
-	for (@{$provides{"$subsys.$module"}}) {
-		print C "package.provides = $_\n";
-	}
-	print C "\n";
-
-	for my $pp (keys %{$platform_properties{"$subsys.$module"}}) {
-		next if $pp eq 'default';
-		next if exists $project{supported_platforms} and not exists $project{supported_platforms}{$pp};
-
-		print C "[Platform-$pp:Property]\n$buildroot\n";
-
-		for my $p (keys %{$platform_properties{"$subsys.$module"}->{$pp}}) {
-			print C $p . ' = ' . $platform_properties{"$subsys.$module"}->{$pp}->{$p} . "\n";
-		}
-		print C "$package_description$package_summary\n";
-	}
-
-	for my $platform ('default', keys %{$project{supported_platforms}}) {
-		my $used = 0;
-		my $output = '';
-
-		for (@{$need_externs{"$subsys.$module"}},@{$need_jars{"$subsys.$module"}}) {
-			my $eext = $etics_externs{$platform}{$_};
-			my $edev = $project{etics_externs_devel}{$platform}{$_};
-
-			# for the default platform using package of the same
-			# name for runtime dependency
-			if (not $eext) {
-				if ($platform eq 'default') {
-#print "default runtime $_ on default\n";
-					$eext = $_; }
-				else {
-#print "no runtime $_ on $platform\n";
-					$eext = '-'; }
-			}
-			if ($eext eq '-' and $edev eq '-') {
-#print "skipping $_ on $platform\n";
-				next;
-			}
-
-			my $proj = 'externals';
-			for my $p (keys %etics_projects) {
-				for $m (@{$etics_projects{$p}}) {
-					$proj = $p if $m eq $_;
-				}
-			}
-
-			my $type = $need_externs_type{"$subsys.$module"}->{$_};
-
-			if ($edev) {
-				if ($type eq 'B') {
-					# no runtime - change to devel pkg
-					$eext = $edev;
-				} elsif ($type eq 'BR' or $type eq 'RB') {
-					# additional devel pkg
-					if ($edev ne '-') { $output .= "$proj|$edev = B\n"; }
-				}
-			}
-			if ($eext ne '-') { $output .= "$proj|$eext = $type\n"; }
-		}
-
-		if ($platform eq 'default') {
-			for (@{$deps{"$subsys.$module"}}) {
-				my $type = $deps_type{"$subsys.$module"}->{$_};
-				if (not $used) {
-					$used = 1;
-				}
-				$output .= "$project{etics_name}|$project{etics_name}.$_ = $type\n";
-			}
-		}
-
-		if ($output) {
-					print C qq{
-[Platform-$platform:DynamicDependency]
-$output};
-		}
-	}
-
-	close C;
-
-	for $file ("$cvs_module/project/debian.rules", "$cvs_module/project/$packageName.spec") {
-		my $lib;
-		my $main_module;
-		@copts = ();
-
-		if ($file =~ /debian\.rules$/) { $lib = 'lib'; }
-		else { $lib = '%{_lib}'; }
-
-		my $main_module = "$subsys.$module";
-		if (exists $subpackages{$main_module}) { $main_module = $subpackages{$main_module}; }
-
-		# locations hacks
-		if ($file =~ /$packageName\.spec$/) {
-			if ($fmod eq 'lb.client-java') {
-				push @copts, '';
-				push @copts, '--with-axis=/usr/local/axis1.4';
-			}
-		}
-
-		if (-f $file) {
-			open DST,">$file.new" or die "$file.new: $!\n";
-			open SRC,"<$file" or die "$file: $!\n";
-			while () {
-				if (/^(\s*).+\/configure\s/) {
-					printf DST "%s", "$1";
-					printf DST "/usr/bin/perl $confdir/configure $project{flavours} --root=/ --prefix=$project{local_prefix} --libdir=$lib --project=$project --module $main_module@copts\n";
-				} else {
-					printf DST "%s", "$_";
-				}
-			}
-			close SRC;
-			close DST;
-
-			`diff -b "$file" "$file.new"`;
-			if ($? == 0) {
-				print STDERR "($file not changed)\n";
-				unlink "$file.new";
-			} else {
-				print STDERR "Writing $file\n";
-				rename "$file", "$file.orig" unless -f "$file.orig";
-				rename "$file.new", "$file";
-			}
-		}
-	}
-}
-
-sub gsoap_version {
-	local $_;
-	my $gsoap_version;
-	open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n";
-
-	while ($_ = ) {
-		chomp;
-
-		$gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/;
-		$gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/;
-	}
-	close S;
-	return $gsoap_version;
-}
-
-sub getlibdir {
-	if ( -e "/etc/debian_version") { # We are on Debian
-		$lib64="lib";
-		$lib32="lib32";	}
-	else { # Another distribution
-		$lib64="lib64";
-		$lib32="lib";	}
-        $libdir=$lib32;
-
-        open INP, "uname -s | "; # Check kernel name
-        $kname= ;
-        chomp($kname);
-        close INP;
-
-        if ( $kname eq "Linux") {
-                $arch = ("x86_64\npowerpc\nppc64\n");
-
-                open INP, "uname -p | "; # Check processor type
-                $procname= ;
-                chomp($procname);
-                close INP;
-
-                if ($arch =~/^$procname\n/) {
-                        return ($lib64); }
-
-                open INP, "uname -m | "; # Check machine hardware
-                $machname= ;
-                chomp($machname);
-                close INP;
-
-                if ($arch =~/^$machname\n/) {
-                        return ($lib64); }
-
-                # special cases (hyperlink lib64, Debian)
-                if (-l "/usr/lib64") {
-                        $libdir=$lib32; }
-
-                # if /usr/lib64 doesn't exist at all (AIX)
-                unless ( -e "/usr/lib64" ) {
-                        $libdir=$lib32; }
-        }
-
-        if ( $kname eq "SunOS") {
-                if (-e "/usr/lib/64") {
-                $libdir="lib/64"; }
-        }
-
-        return $libdir;
-}
-
-sub reshuffle_platforms($$) {
-	my ($data, $platforms) = @_;
-	my ($platform, %blacklist, $value);
-
-	return if not $platforms;
-
-	for $platform (keys %$data) {
-#print "plat: $platform: $data->{$platform}\n";
-		next if $platform eq 'default';
-		for $_ (keys %{$data->{$platform}}) {
-#print "  blacklist: $_ = $data->{$platform}{$_}\n";
-			$blacklist{$_} = 1;
-		}
-	}
-
-	for $_ (keys %blacklist) {
-		$value = $data->{default}{$_} ? $data->{default}{$_} : $_;
-		for $platform (keys %$platforms) {
-			next if $platform eq 'default';
-			if (not defined $data->{$platform}{$_}) {
-				$data->{$platform}{$_} = $value;
-#print "added $value to $platform\n"
-			}
-		}
-		$data->{default}{$_} = '-';
-#print "deleted $_ from default\n";
-	}
-
-	# merge dependencies across the supported platforms
-	%blacklist = [];
-	for $platform (keys %$platforms) {
-		next if $platform eq 'default';
-		for $_ (keys %{$data->{$platform}}) {
-			$blacklist{$_} = 1;
-		}
-	}
-	for $_ (keys %blacklist) {
-		$value = undef;
-		$same = 1;
-		for $platform (keys %$platforms) {
-			if (not $value) { $value = $data->{$platform}{$_}; }
-			if (not $data->{$platform}{$_} or $value ne $data->{$platform}{$_}) {
-				$same = 0;
-				last;
-			}
-		}
-		if ($same and $value) {
-#print "merged dependency $_\n";
-			$data->{default}{$_} = $value;
-			for $platform (keys %$platforms) {
-				delete $data->{$platform}{$_};
-			}
-		}
-	}
-}
-
-sub usage {
-	my @ext = keys %externs;
-	my @myjars = keys %jar;
-
-	print STDERR qq{
-Usage: $0 options
-
-General options (defaults in []):
-  --prefix=PREFIX		destination directory [./stage]
-  --stage=DIR			staging directory [./stage]
-  --root=DIR			installation root (custom relocation root -> sysroot) [./stage]
-  --sysroot=DIR			system root (custom relocation root -> sysroot) []
-  --sysconfdir=DIR              system configuration directory [PREFIX/etc]
-  --staged=module,module,...	what is already in PREFIX (specify without org.glite.)
-  --thrflavour=flavour
-  --nothrflavour=flavour	threaded and non-treaded flavours [gcc64dbgpthr,gcc64dbg]
-  --listmodules=subsys          list modules of a subsystem
-  --listmodules=module          list subpackages of a module
-  --version=maj.min.rev-age	version used instead of reading version.properties
-  --branch=branch		CVS branch/etics name suffix (HEAD, branch_2_1, ...)
-  --libdir=libdir		typically [lib,lib64] postfix
-  --project=PROJECT		build or generate etics for a project (glite/emi1/emi) [emi]
-  --debug			print more details
-  
-Mode of operation:
-  --mode=\{checkout|build|etics\}	what to do [build]
-  
-What to build:
-  --module=module		build this module only
-  --enable-NODE			build this "node" (set of modules) only
-  --disable-NODE		don't build this node
-  --lb-tag=tag			checkout LB modules with specific tag
-  --jp-tag=tag			checkout JP modules with specific tag
-  --lbjp-common-tag=tag         checkout lbjp-common modules with specific tag
-  --jobid-tag=tag		checkout jobid modules with specific tag
-  --canl-tag=tag		checkout canl modules with specific tag
-
-Dependencies (summary of what will be used is always printed):
-  --with-EXTERNAL=PATH		where to look for an external [autodetect]
-  --with-JAR=JAR		where to look for jars
-
-Available nodes:
-    @nodes
-
-Default nodes:
-    @default_nodes
-
-Externals (not all for all modules) are:
-    @ext
-
-External jars are:
-    @myjars
-
-};
-
-}
diff --git a/org.glite.lb.nagios/project/ChangeLog b/org.glite.lb.nagios/project/ChangeLog
deleted file mode 100644
index db93354..0000000
--- a/org.glite.lb.nagios/project/ChangeLog
+++ /dev/null
@@ -1,21 +0,0 @@
-1.0.0-1
-- Initial version of the nagios module
-
-1.0.0-2
-- Module rebuilt
-
-1.1.0-1
-- Preparation for a new multiplatform release
-
-1.1.1-1
-- Packaging fixes
-
-1.1.1-2
-- Module rebuilt
-
-1.1.1-3
-- Module rebuilt
-
-1.1.1-4
-- Module rebuilt
-
diff --git a/org.glite.lb.nagios/project/debian.control b/org.glite.lb.nagios/project/debian.control
deleted file mode 100644
index e6b8f45..0000000
--- a/org.glite.lb.nagios/project/debian.control
+++ /dev/null
@@ -1,18 +0,0 @@
-Source: emi-lb-nagios-plugins
-Priority: extra
-Maintainer: @MAINTAINER@
-Uploaders: @UPLOADERS@
-Build-Depends: debhelper (>= 7.0.50~)
-Standards-Version: 3.9.1
-Section: net
-Homepage: @URL@
-DM-Upload-Allowed: yes
-@DEBIAN_VCS@
-
-Package: emi-lb-nagios-plugins
-Section: net
-Architecture: all
-Depends: ${misc:Depends}, glite-lb-client-progs, glite-lb-utils, glite-lb-ws-test, globus-proxy-utils
-Provides: glite-lb-nagios-plugins
-Description: @SUMMARY@
-@DEBIAN_DESCRIPTION@
diff --git a/org.glite.lb.nagios/project/debian.copyright b/org.glite.lb.nagios/project/debian.copyright
deleted file mode 100644
index 3d762ae..0000000
--- a/org.glite.lb.nagios/project/debian.copyright
+++ /dev/null
@@ -1,38 +0,0 @@
-This work was packaged for Debian by:
-
-    @MAINTAINER@ on Thu, 08 Dec 2011 00:46:07 +0100
-
-It was downloaded from:
-
-    @URL@
-
-Upstream Author(s):
-
-    @MAINTAINER@
-
-Copyright:
-
-    
-
-License:
-
-   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.
-
-On Debian systems, the complete text of the Apache version 2.0 license
-can be found in "/usr/share/common-licenses/Apache-2.0".
-
-The Debian packaging is:
-
-    Copyright (C) 2004-2011 Members of the EGEE Collaboration
-
-and is licensed under the Apache License, Version 2.0.
diff --git a/org.glite.lb.nagios/project/debian.emi-lb-nagios-plugins.dirs b/org.glite.lb.nagios/project/debian.emi-lb-nagios-plugins.dirs
deleted file mode 100644
index ef6a7fa..0000000
--- a/org.glite.lb.nagios/project/debian.emi-lb-nagios-plugins.dirs
+++ /dev/null
@@ -1,6 +0,0 @@
-usr/share/doc/emi-lb-nagios-plugins
-usr/libexec/grid-monitoring
-usr/libexec/grid-monitoring/probes
-usr/libexec/grid-monitoring/probes/emi.lb
-var/lib/grid-monitoring
-var/lib/grid-monitoring/emi.lb
diff --git a/org.glite.lb.nagios/project/debian.emi-lb-nagios-plugins.install b/org.glite.lb.nagios/project/debian.emi-lb-nagios-plugins.install
deleted file mode 100644
index 909c0df..0000000
--- a/org.glite.lb.nagios/project/debian.emi-lb-nagios-plugins.install
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/share/doc/emi-lb-nagios-plugins/*
-usr/libexec/grid-monitoring/probes/emi.lb/*
diff --git a/org.glite.lb.nagios/project/debian.postinst b/org.glite.lb.nagios/project/debian.postinst
deleted file mode 100644
index b87808a..0000000
--- a/org.glite.lb.nagios/project/debian.postinst
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-set -e
-chown nagios:nagios /usr/libexec/grid-monitoring/probes/emi.lb >/dev/null 2>&1 || :
-#DEBHELPER#
diff --git a/org.glite.lb.nagios/project/debian.rules b/org.glite.lb.nagios/project/debian.rules
deleted file mode 100644
index a92b20d..0000000
--- a/org.glite.lb.nagios/project/debian.rules
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile -*-
-
--include /usr/share/dpkg/buildflags.mk
-
-# Uncomment this to turn on verbose mode.
-export DH_VERBOSE=1
-
-configure: configure-stamp
-configure-stamp:
-	dh_testdir
-	/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=lib --project=emi --module lb.nagios
-	touch $@
-
-build: build-indep
-
-build-indep: build-stamp
-
-build-stamp: configure-stamp
-	dh_testdir
-	CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE)
-	CFLAGS="$(CFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) check
-	touch $@
-
-clean: configure-stamp
-	dh_testdir
-	dh_testroot
-	rm -f configure-stamp build-stamp
-	$(MAKE) clean
-	rm -f Makefile.inc config.status
-	dh_clean
-
-install: build-stamp
-	dh_testdir
-	dh_testroot
-	dh_prep
-	dh_installdirs
-	$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
-	mv $(CURDIR)/debian/tmp/usr/share/doc/emi-lb-nagios-plugins-@MAJOR@.@MINOR@.@REVISION@ $(CURDIR)/debian/tmp/usr/share/doc/emi-lb-nagios-plugins
-	(cd $(CURDIR)/debian/tmp/usr/share/doc/emi-lb-nagios-plugins; \
-	 rm -fv ChangeLog LICENSE; \
-	 cat $(CURDIR)/project/ChangeLog | gzip -9 > changelog.gz)
-
-binary-indep: install
-	dh_testdir
-	dh_testroot
-	dh_installchangelogs
-	dh_installdocs
-	dh_installexamples
-	dh_installman
-	dh_installlogrotate
-	dh_installcron
-	dh_install --fail-missing
-	dh_link
-	dh_compress
-	dh_fixperms
-	dh_makeshlibs
-	dh_installdeb
-	dh_shlibdeps
-	dh_gencontrol
-	dh_md5sums
-	dh_builddeb
-
-binary: binary-indep
diff --git a/org.glite.lb.nagios/project/emi-lb-nagios-plugins.spec b/org.glite.lb.nagios/project/emi-lb-nagios-plugins.spec
deleted file mode 100644
index bd8ca9c..0000000
--- a/org.glite.lb.nagios/project/emi-lb-nagios-plugins.spec
+++ /dev/null
@@ -1,69 +0,0 @@
-Summary: @SUMMARY@
-Name: emi-lb-nagios-plugins
-Version: @MAJOR@.@MINOR@.@REVISION@
-Release: @AGE@%{?dist}
-Url: @URL@
-License: ASL 2.0
-Vendor: EMI
-Group: System Environment/Daemons
-BuildArch: noarch
-Requires: glite-lb-client
-Requires: glite-lb-utils
-Requires: glite-lb-ws-test
-Requires: globus-proxy-utils
-Provides: glite-lb-nagios-plugins = %{name}-%{version}-%{release}
-BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
-AutoReqProv: yes
-Source: http://eticssoft.web.cern.ch/eticssoft/repository/emi/emi.lb.nagios/%{version}/src/%{name}-@VERSION@.src.tar.gz
-
-
-%description
-@DESCRIPTION@
-
-
-%prep
-%setup -q
-
-
-%build
-/usr/bin/perl ./configure --thrflavour= --nothrflavour= --root=/ --prefix=/usr --libdir=%{_lib} --project=emi --module lb.nagios
-make
-
-
-%check
-make check
-
-
-%install
-rm -rf $RPM_BUILD_ROOT
-mkdir -p $RPM_BUILD_ROOT
-make install DESTDIR=$RPM_BUILD_ROOT
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-
-%post
-chown nagios:nagios /usr/libexec/grid-monitoring/probes/emi.lb >/dev/null 2>&1 || :
-exit 0
-
-
-%files
-%defattr(-,root,root)
-%dir /usr/share/doc/%{name}-%{version}/
-%dir /usr/libexec/
-%dir /usr/libexec/grid-monitoring/
-%dir /usr/libexec/grid-monitoring/probes/
-%dir /usr/libexec/grid-monitoring/probes/emi.lb/
-%dir /var/lib/grid-monitoring/
-%dir /var/lib/grid-monitoring/emi.lb/
-/usr/share/doc/%{name}-%{version}/package.summary
-/usr/share/doc/%{name}-%{version}/ChangeLog
-/usr/share/doc/%{name}-%{version}/package.description
-/usr/libexec/grid-monitoring/probes/emi.lb/LB-probe
-
-
-%changelog
-* @SPEC_DATE@ @MAINTAINER@ - @MAJOR@.@MINOR@.@REVISION@-@AGE@%{?dist}
-- automatically generated package
diff --git a/org.glite.lb.nagios/project/package.description b/org.glite.lb.nagios/project/package.description
deleted file mode 100644
index a0d9316..0000000
--- a/org.glite.lb.nagios/project/package.description
+++ /dev/null
@@ -1 +0,0 @@
-This is a nagios probe, a shell script to check the L&B server.
diff --git a/org.glite.lb.nagios/project/package.summary b/org.glite.lb.nagios/project/package.summary
deleted file mode 100644
index 0a76a30..0000000
--- a/org.glite.lb.nagios/project/package.summary
+++ /dev/null
@@ -1 +0,0 @@
-This is a package to distribute a nagios probe that checks the EMI L&B server
diff --git a/org.glite.lb.nagios/project/version.properties b/org.glite.lb.nagios/project/version.properties
deleted file mode 100644
index dfaad81..0000000
--- a/org.glite.lb.nagios/project/version.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# $Header
-module.version=1.1.1
-module.age=4
diff --git a/org.glite.lb.nagios/src/LB-probe b/org.glite.lb.nagios/src/LB-probe
deleted file mode 100755
index 5bd11a6..0000000
--- a/org.glite.lb.nagios/src/LB-probe
+++ /dev/null
@@ -1,420 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-showHelp()
-{
-cat << EndHelpHeader
-Nagios probe for testing the status of L&B
-
-Tests called:
-    1. Register job
-    2. Register to receive notifications 
-    3. Log events
-    4. Check job state
-    5. Receive notifications
-
-Return values:
-    0: Passed
-    1: Warning
-    2: Critical
-    3: Unknown
-
-Console output:
-    OK|"
-end_blue="$ENDFONT"
-end_magenta="$ENDFONT"
-end_cyan="$ENDFONT"
-end_white="$ENDFONT"
-
-set_test
-}
-
-function reset_error()
-{
-	rm -f $testerrfile
-}
-
-function set_error()
-{
-	printf "%s ${lf}" "$*" > $testerrfile
-}
-
-function update_error()
-{
-	printf "%s; " "$*" >> $testerrfile
-}
-
-function print_error()
-{
-	printf "\t${begin_red}Error${end_red}: %s ${lf}" "$*"
-
-	if [ -f $testerrfile ]; then
-		printf "\t${begin_red}Error${end_red}: %s ${lf}" "`cat $testerrfile`"
-	fi
-	reset_error
-}
-
-function print_warning()
-{
-	printf "${begin_magenta}Warning${end_magenta}: %s ${lf}" "$*"
-}
-
-function print_info()
-{
-	printf "${begin_blue}Info${end_blue}: %s ${lf}" "$*"
-}
-
-function print_newline()
-{
-	printf "${lf}"
-}
-
-function syslog() 
-{
-        local tmp="`date +'%b %d %H:%M:%S'` `hostname` $progname"
-	printf "${begin_bold}${tmp}${end_bold}: %s ${lf}" "$*"
-}
-
-function dprintf()
-{
-	if [ $DEBUG -gt 0 ]; then 
-		printf "%s${lf}" "$*"
-	fi
-}
-
-# by default set output to color if possible
-if test -t 1 -a "$TERM" != "raw" -a "$TERM" != "dumb" && stty size <&1 > /dev/null 2>&1 ; then
-	setOutputColor
-else
-	setOutputASCII
-fi
-
diff --git a/org.glite.testsuites.ctb/LB/LB-certconfig b/org.glite.testsuites.ctb/LB/LB-certconfig
deleted file mode 100644
index 2cee273..0000000
--- a/org.glite.testsuites.ctb/LB/LB-certconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-#Defining arguments for the test scripts
-
-#LB hostname
-LB_HOST="lxbra2303.cern.ch"
-
-#address of the glite-lb-bkserver daemon host:port
-export GLITE_WMS_QUERY_SERVER="lxbra2303.cern.ch:9000"
-
-#address of the glite-lb-logd daemon host:port
-export GLITE_WMS_LOG_DESTINATION="lxbra2303.cern.ch:9002"
diff --git a/org.glite.testsuites.ctb/LB/LB-certtest.sh b/org.glite.testsuites.ctb/LB/LB-certtest.sh
deleted file mode 100755
index 837ee01..0000000
--- a/org.glite.testsuites.ctb/LB/LB-certtest.sh
+++ /dev/null
@@ -1,153 +0,0 @@
-#!/bin/sh
-##############################################################################
-# Copyright (c) Members of the EGEE Collaboration. 2004.
-# See http://www.eu-egee.org/partners/ for details on the copyright
-# holders.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS
-# OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##############################################################################
-#
-# AUTHORS: Gianni Pucciani, CERN
-#
-##############################################################################
-
-showUsage ()
-{
- echo "                                           "
- echo "Usage:  LB-certtest.sh                   "
- echo "                                           "
-}
-
-exitFailure ()
-{
-echo "------------------------------------------------"
-echo "END `date`"
-echo "-TEST FAILED-"
-exit -1
-}
-
-#######################
-#Parsing the arguments#
-#######################
-if [ "$1" = "-h" ] || [ "$1" = "-help" ] || [ "$1" = "--help" ] || [ $# -gt 0 ]; then
-  showUsage
-  exit 2
-fi
-
-###################################
-# Check for environment variables #
-###################################
-
-if [ -e "LB-certconfig" ]; then
-  source ./LB-certconfig
-else
-  echo "The file ./LB-certconfig must be sourced in order to run the tests"
-  exitFailure
-fi
-
-if [ -z "$LB_HOST" ]; then
-  echo "You need to set LB_HOST in order to run the tests"
-  exitFailure
-fi
-
-if [ -z "$GLITE_WMS_QUERY_SERVER" ]; then
-  echo "You need to set GLITE_WMS_QUERY_SERVER in order to run the tests"
-  exitFailure
-fi
-#########
-# START #
-#########
-
-echo "START `date` "
-echo "------------------------------------------------"
-
-####################################
-# Checking if there is valid proxy #
-####################################
-
-#ProxyExist=`voms-proxy-info 2>/dev/null | grep timeleft | wc -l`
-
-#ProxyExpired=`voms-proxy-info 2>/dev/null | grep  "timeleft  : 0:00:00" | wc -l`
-
-#if [ $ProxyExist -gt 0 -a $ProxyExpired -eq 0 ]; then
-  #nop
-  :
-#else
-#  echo "Valid proxy is needed for this test!"
-#  if [ $ProxyExpired -gt 0 ]; then
-#    echo "Proxy credential expired!"
-#  fi
-#  exitFailure
-#fi
-
-########################
-# Launch all the tests #
-########################
-
-declare -a tests_failed
-failed=no
-
-testdir=./tests
-tests_list=( lb-test-server-remote.sh lb-test-logger-remote.sh \
-lb-test-normal-event-delivery-remote.sh lb-test-job-registration.sh )
-
-pushd $testdir >> /dev/null
-touch testfile 2> /dev/null
-if [ $? -ne 0 ]; then
-  echo "LB test directory is not writable, if you are on AFS be sure to have a valid token"
-  exitFailure
-fi
-
-for item in ${tests_list[*]}
-do
-  rm -rf ${item}_result.txt testfile
-  echo "Executing $item"
-  if [ "$item" = "lb-test-server-remote.sh" -o "$item" = "lb-test-logger-remote.sh" ]; then
-    echo "./$item  $LB_HOST" > ${item}_result.txt
-    ./$item  $LB_HOST >> ${item}_result.txt
-  elif [ "$item" = "lb-test-normal-event-delivery-remote.sh" -o "$item" = "lb-test-job-registration.sh" ]; then
-    echo "./$item" > ${item}_result.txt
-    ./$item  >> ${item}_result.txt 2>&1
-  fi
-  res=$?
-  grep '\-TEST FAILED\-' ${item}_result.txt >> /dev/null
-  if [ "$?" = 0 -o "$res" != 0 ]; then
-    echo "$item FAILED"
-    failed=yes
-    tests_failed=( "${tests_failed[@]}" "$item" )
-  else
-    echo "$item PASSED"
-  fi
-done
-popd >> /dev/null
-
-echo "------------------------------------------------"
-echo "END `date`"
-
-#########################
-# Analyse tests outcome #
-#########################
-
-if [ $failed = "yes" ]; then
-
-  echo "TEST_FAILED"
-  echo "The following tests failed:"
-  for item in ${tests_failed[*]}
-  do
-    echo "$item: results in tests/${item}_result.txt"
-  done
-else
-    echo "TEST_PASSED"
-fi
-
diff --git a/org.glite.testsuites.ctb/LB/Makefile b/org.glite.testsuites.ctb/LB/Makefile
deleted file mode 100644
index b50f0ca..0000000
--- a/org.glite.testsuites.ctb/LB/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-CC=gcc
-CFLAGS=
-EXEC=testSocket
-
-all: $(EXEC)
-
-testSocket: testSocket.c
-	$(CC) -o $@ $< $(CFLAGS) 
-	rm -f tests 
-	ln -fs . tests
-
-clean:
-	rm -rf *.o tests $(EXEC) *.tmp *.err
-
diff --git a/org.glite.testsuites.ctb/LB/manual/Readme.txt b/org.glite.testsuites.ctb/LB/manual/Readme.txt
deleted file mode 100644
index 36fb213..0000000
--- a/org.glite.testsuites.ctb/LB/manual/Readme.txt
+++ /dev/null
@@ -1,147 +0,0 @@
-$Header$
-
-Readme file for basic LB Integration tests 
-
-Service ping tests:
-===================
-
-Prerequisities for all service ping tests:
------------------------------
-- the following environment variables set:
-
-   GLITE_LOCATION - PATH to gLite software
-   SAME_SENSOR_HOME - PATH to sensors (might be set to "." for testSocket sensor)
-
-- one may also need to run make to build the testSocket binary
-  and create link tests -> . (to be used for local SAME_SENSOR_HOME)
-
-
-lb-test-logger-remote.sh
-------------------------
-Script for remote testing of LB logger
-
-Run ./lb-test-logger-remote.sh -h for test description and usage.
- 
-Example:
-
-$ ./lb-test-logger-remote.sh sci.civ.zcu.cz
-Aug 13 15:57:02 scientific lb-test-logger-remote.sh:                 start
-Testing if all binaries are available                                done
-Testing ping to LB logger sci.civ.zcu.cz                             done
-Testing LB logger at sci.civ.zcu.cz:9002 (logging)                   done
-Aug 13 15:57:04 scientific lb-test-logger-remote.sh:                 end
-
-
-
-lb-test-server-remote.sh
-------------------------
-Script for remote testing of LB server
-
-Run ./lb-test-server-remote.sh -h for test description and usage.
- 
-Example:
-
-$ ./lb-test-server-remote.sh sci.civ.zcu.cz
-Aug 13 15:58:22 scientific lb-test-server-remote.sh:                 start
-Testing if all binaries are available                                done
-Testing ping to LB server sci.civ.zcu.cz                             done
-Testing LB server at sci.civ.zcu.cz:9000 (logging)                   done
-Testing LB server at sci.civ.zcu.cz:9001 (queries)                   done
-Testing LB server at sci.civ.zcu.cz:9003 (web services)              done
-Aug 13 15:58:26 scientific lb-test-server-remote.sh:                 end
-
-
-
-lb-test-server-local.sh
------------------------
-Script for testing an LB server running locally
-
-Run ./lb-test-server-local.sh -h for test description and usage.
- 
-Example:
-
-$ lb-test-server-local.sh
-Oct 22 10:59:17 scientific lb-test-server-local.sh:				start 
-Testing if all binaries are available						done
-Testing if mySQL is running							done
-Testing if mySQL is accessible							done
-Testing if LB Server is running							done
-Testing if LB Server is listening on port 9010					done
-Testing if LB Server is listening on port 9011					done
-Testing if LB Server is listening on port 9013					done
-Testing if Interlogger is running						done
-Testing if interlogger is listening on socket /tmp/intelogger_sustr.sock	done
-Oct 22 10:59:17 scientific lb-test-server-local.sh:				end 
-
-
-
-lb-test-logger-local.sh
------------------------
-Testing a local logger and interlogger running on a local machine.
-
-Run ./lb-test-logger-local.sh -h for test description and usage.
- 
-Example: 
-
-$ lb-test-logger-local.sh 
-Oct 22 11:02:04 scientific lb-test-logger-local.sh:				start 
-Testing if all binaries are available						done
-Testing if LB logger is running							done
-Testing if LB logger is listening on port 9012					done
-Testing if Interlogger is running						done
-Testing if interlogger is listening on socket /tmp/intelogger_sustr.sock	done
-Oct 22 11:02:05 scientific lb-test-logger-local.sh:				end 
-
-
-System Functionality Tests
-==========================
-
-Prerequisities for all system functionality tests:
------------------------------
-- the following environment variables set:
-
-   GLITE_WMS_QUERY_SERVER - LB server address:port
-   GLITE_LOCATION - PATH to gLite software
-   SAME_SENSOR_HOME - PATH to sensors (might be set to "." for testSocket sensor)
-
-- one may also need to run make to build the testSocket binary
-  and create link tests -> . (to be used for local SAME_SENSOR_HOME)
-
-
-lb-test-job-registration.sh
----------------------------
-Tests if it is possible to register jobs and query for their states. 
-
-Example:
-
-$ lb-test-job-registration.sh
-Oct 22 11:32:18 scientific lb-test-job-registration.sh:								start 
-Testing if all binaries are available										done
-Testing credentials												done
-Registering testing job												done
-Is the testing job (https://scientific.civ.zcu.cz:9010/jf1Mgogl4-FvdQdrPe0a4Q) in a correct state? Submitted	done
-Oct 22 11:32:19 scientific lb-test-job-registration.sh:								end 
-
-
-
-lb-test-event-delivery.sh
--------------------------
-Tests jobs registration, event deliver and proper state modification.
-
-Example:
-
-$ lb-test-event-delivery.sh 
-Oct 22 14:14:43 scientific lb-test-event-delivery.sh:								start 
-Testing if all binaries are available										done
-Testing credentials												done
-Registering testing job												done
-Registered job: https://scientific.civ.zcu.cz:9010/jiOm5Wy7w4Q34JcOqVv_jQ
-Logging events resulting in READY state
-Sleeping for 10 seconds (waiting for events to deliver)...
-Is the testing job (https://scientific.civ.zcu.cz:9010/jiOm5Wy7w4Q34JcOqVv_jQ) in a correct state? Ready	done
-Logging events resulting in RUNNING state
-Logging events resulting in DONE state
-Sleeping for 10 seconds (waiting for events to deliver)...
-Testing job (https://scientific.civ.zcu.cz:9010/jiOm5Wy7w4Q34JcOqVv_jQ) is in state: Done			done
-Oct 22 14:15:07 scientific lb-test-event-delivery.sh:								end 
-
diff --git a/org.glite.testsuites.ctb/LB/manual/Readme2.txt.old b/org.glite.testsuites.ctb/LB/manual/Readme2.txt.old
deleted file mode 100644
index b32404f..0000000
--- a/org.glite.testsuites.ctb/LB/manual/Readme2.txt.old
+++ /dev/null
@@ -1,158 +0,0 @@
-Readme file for lb2 v1.0*************************************
-Date: 19.03.2007					*		
-Author:							*
-*************************************************************
-
-lb-l2.sh
-********
-
-Normal event delivery and Normal Job States 
-
-* Prerequisities: All services running (LBProxy not used), user must have a valid proxy on the UI
-
-* Test:
-Registers jobs with glite-lb-job-reg preferably pointing to remote LB Server
-Check of the job status
-Logs sequences of events with glite-lb-..... sh scripts (ex: gite-lb-ready.sh)
-Checks with glite-lb-job_log that the events got delivered aftewards
-Checks with glite-lb-job_status that the status of the jobs are correct
-       
-* Options:       
-echo  " -h | --help                   Show this help message."        
-echo  " -r | --retries                Number of test retries (2 by default)"        
-echo  " -n | --nbjobs                 Number of jobs (10 by default)"        
-echo  " -m | --bkserver               Host address of the BKServer ex:pc900.iihe.ac.be "        
-echo  " -s | --states                 List of states in which could tested jobs fall."        
-echo  " -l | --large-stress 'size'    Do a large stress logging ('size' random data added to the messages."
-
-
-* The name of the bkserver has to be specified everytime
-
-* The option -l 'size' addes random data to the messages send to the BKServer with glite-lb-logevent. 
-
-* With the option -s you can specify the list of states that will be submitted randomly to the jobs created
-
-* When you specify a state, the script will send all the events the job has to pass trough.
-
-
-
-lb-l2Stat.sh
-************
-
-* This script is mainly the same than lb-l2.sh but it includes a mesure of time. 
-
-* You can specify one more option
-
- echo  " -t | --tags                   Number of user tags to load to each job."
- 
-
-
-
-
-examples
-********
-
-./lb-l2.sh -n 4 -m gliterb.iihe.ac.be -s "Running Done"
-
-Registering 4 jobs....................
-https://pc900.iihe.ac.be:9000/3E8xyyH_FCb4z1rN5TymFw
-https://pc900.iihe.ac.be:9000/aTLnW6Mmm_whpt_tbxHjPQ
-https://pc900.iihe.ac.be:9000/TnuSJvVZCLcYDDv1GXdocw
-https://pc900.iihe.ac.be:9000/WW-0FU8g4tID1TMMPZCEBg
-Logging events to the 4 jobs....................................
-
-Logging tags to the 4 jobs....................................
-
-Checking the Events.............................................
-Job 0 ....................[OK]
-Job 1 ....................[OK]
-Job 2 ....................[OK]
-Job 3 ....................[OK]
-
-A detailed list of the sequence of events logged to each job has been printed to 1174296170.log
-
-Checking the Jobs Status........................................
-
-Job: 0 ..Logged state:running-Recorded state : Running.......[OK]
-Job: 1 ..Logged state:done-Recorded state : Done.......[OK]
-Job: 2 ..Logged state:done-Recorded state : Done.......[OK]
-Job: 3 ..Logged state:done-Recorded state : Done.......[OK]
-
-Final test result .........................................[OK]
-
-
-1174296170.log (this file contains a detailed list of the sequence of events logged to each job during the test)
-
-...
-Events Sent.....
-     1  UserTag
-     2  RegJob
-     3  Accepted
-     4  EnQueued
-     5  DeQueued
-     6  HelperCall
-     7  Match
-     8  HelperReturn
-     9  EnQueued
-    10  DeQueued
-    11  Transfer
-    12  Accepted
-    13  Transfer
-    14  Running
-    15  Done
-Events recorded in the LB server.....
-     1  UserTag
-     2  RegJob
-     3  Accepted
-     4  EnQueued
-     5  DeQueued
-     6  HelperCall
-     7  Match
-     8  HelperReturn
-     9  EnQueued
-    10  DeQueued
-    11  Transfer
-    12  Accepted
-    13  Transfer
-    14  Running
-    15  Done
-...
-
-
-
-./lb-l2Stat.sh -n 3 -m gliterb.iihe.ac.be
-...
-Sending events took for individual jobs the following time
-https://pc900.iihe.ac.be:9000/QZUecSg86IXtZeMmU4Rd6Q    11.061101000 seconds
-https://pc900.iihe.ac.be:9000/-R0CDDoicKdwqAZHEI32gA    9.438249000 seconds
-https://pc900.iihe.ac.be:9000/x6qFebsaNOR1a31NlAhJIQ    3.167140000 seconds
-Total time for 3 jobs:  23.666490000
-Average time for event:         7.888830000
-Average time for event and tags:        .157776600
-Event throughput (events/sec):  6.338075481
-...
-
-
-List of possible job Status 
-***************************
-
-"Submitted Waiting Ready Cancelled Scheduled Aborted Running Done Cleared"
-
-* Submitted: The job has been submitted by the user but not yet processed by the Network Server
-
-* Waiting: The job has been accepted by the Network Server but not yet processed by the workload manager
-
-* Ready: The job has been assigned to a Computing Element but not yet transferred to it
-
-* Scheduled: The job is wainting in the CE's queue
-
-* Running: The job is running
-
-* Done: The job has finished
-
-* Aborted: The job has been aborted by the WMS (it was too long or the proxy certificate expired)
-
-* Cancelled: The job has been cancelled by the user
-
-* Cleared: The output sandbox has been transferred to the UserInterface
-
diff --git a/org.glite.testsuites.ctb/LB/tests/Makefile b/org.glite.testsuites.ctb/LB/tests/Makefile
deleted file mode 100644
index b50f0ca..0000000
--- a/org.glite.testsuites.ctb/LB/tests/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-CC=gcc
-CFLAGS=
-EXEC=testSocket
-
-all: $(EXEC)
-
-testSocket: testSocket.c
-	$(CC) -o $@ $< $(CFLAGS) 
-	rm -f tests 
-	ln -fs . tests
-
-clean:
-	rm -rf *.o tests $(EXEC) *.tmp *.err
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-autonomous-test.sh b/org.glite.testsuites.ctb/LB/tests/lb-autonomous-test.sh
deleted file mode 100755
index 0d44222..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-autonomous-test.sh
+++ /dev/null
@@ -1,178 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-showHelp()
-{
-cat << EndHelpHeader
-This script is intended for running a fully automated deployment and functionality test of an L&B server
-
-Prerequisities:
-New empty machine, certificates
-
-Tests called:
-	Deployment
-	The full L&B Functional Test Suite
-
-EndHelpHeader
-
-	echo "Usage: $progname [OPTIONS] hostname"
-	echo "Options:"
-	echo " -h | --help            Show this help message."
-}
-
-egrep -i "Debian|Ubuntu" /etc/issue
-if [ \$? = 0 ]; then
-        INSTALLCMD="apt-get install -q --yes"
-        INSTALLPKGS="lintian"
-else
-        INSTALLCMD="yum install -q -y --nogpgcheck"
-        INSTALLPKGS="rpmlint"
-fi
-
-$INSTALLCMD wget
-
-# read common definitions and functions
-for COMMON in lb-common.sh test-common.sh lb-common-testbeds.sh
-do
-	if [ ! -r ${COMMON} ]; then
-		printf "Downloading common definitions '${COMMON}'"
-		wget -O ${COMMON} http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/LB/tests/$COMMON?view=co > /dev/null
-		if [ ! -r ${COMMON} ]; then
-			exit 2
-		else 
-			test_done
-		fi
-	fi
-done
-source lb-common.sh
-source lb-common-testbeds.sh
-
-STARTTIME=`date +%s`
-
-printf "Getting the 'install' script... "
-# Example script, for real tests it should be downloaded or otherwise obtained
-SCENARIO=${SCENARIO:-"Clean installation"}
-test -s LBinstall.sh || cat << EndInstallScript > LBinstall.sh 
-rpm -ivh http://dl.fedoraproject.org/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm
-yum install -y yum-priorities yum-protectbase
-rpm -i http://emisoft.web.cern.ch/emisoft/dist/EMI/1/sl5/x86_64/base/emi-release-1.0.0-1.sl5.noarch.rpm
-
-
-
-yum install -y --nogpgcheck emi-lb
-yum install -y --nogpgcheck emi-lb-nagios-plugins
-
-cd ~/
-mkdir -m 700 yaim
-cd yaim
-
-cat << EOF > site-info.def
-MYSQL_PASSWORD=[Edited]
-SITE_NAME=delwin
-SITE_EMAIL="[Edited]"
-GLITE_LB_TYPE=both
-GLITE_LB_SUPER_USERS="/C=UG/L=Tropic/O=Utopia/OU=Relaxation/CN=glite"
-EOF
-
-sed -i 's/155/255/g' /opt/glite/yaim/examples/edgusers.conf
-
-/opt/glite/yaim/bin/yaim -c -s ./site-info.def -n glite-LB
-EndInstallScript
-test_done
-
-
-printf "Generating the 'arrange' script... "
-gen_arrange_script `hostname -f` 0
-test_done
-
-
-printf "Installing... "
-sh LBinstall.sh > Install_log.txt 2> Install_err.log
-test_done
-
-printf "Running tests... "
-sh arrange_lb_test_root.sh none glite 80 '-x' > test_log.txt 2> test_err.log
-test_done
-
-printf "Collecting package list... "
-gen_repo_lists ./prod_packages.txt ./repo_packages.txt
-test_done
-
-ENDTIME=`date +%s`
-
-#Generating report section
-gen_deployment_header $ENDTIME $STARTTIME "$SCENARIO" > report.twiki
-
-echo "$SCENARIO" | grep -E -i "upgrade|update" > /dev/null
-if [ $? -eq 0 ]; then
-        printf "\n---++++ Production Repo Contents
-
-\n" >> report.twiki
-        cat ./prod_packages.txt >> report.twiki
-        printf "\n" >> report.twiki
-fi
-
-printf "\n---++++ Test Repo Contents
-
-\n" >> report.twiki
-cat ./repo_packages.txt >> report.twiki
-printf "
-
----++++ Process
-
-\n" >> report.twiki
-
-
-cat LBinstall.sh >> report.twiki
-printf "
-
----++++ Full Output of the Installation
-
-\n" >> report.twiki
-cat Install_log.txt >> report.twiki
-
-printf "
-
----+++ Tests
-
-| TestPlan | https://twiki.cern.ch/twiki/bin/view/EGEE/LBTestPlan |
-| TestPlan Tests | http://glite.cvs.cern.ch/cgi-bin/glite.cgi/org.glite.testsuites.ctb/LB/tests/ |
-| TestPlan Test Documentation | http://egee.cesnet.cz/cvsweb/LB/LBTP.pdf |
-
-\n" >> report.twiki
-cat test_log.txt >> report.twiki
-
-PRODUCT="emi.lb"
-UNITESTEXEC="YES"
-REMARKS=""
-PERFORMANCEEXEC="YES"
-TESTREPOCONTENTS="`cat ./repo_packages.txt`"
-PRODREPOCONTENTS="`cat ./prod_packages.txt`"
-INSTALLCOMMAND="`cat LBinstall.sh`"
-INSTALLLOG="`cat Install_log.txt`"
-CONFIGLOG="Configuration log shown with the installation log, see directly above."
-#UPGRADECMD
-UNITTESTURL="See Build Report. Unit tests are an integral part of the build."
-TESTPLANURL="http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/LB/tests/"
-FUNCTIONALITYTESTURL="https://twiki.cern.ch/twiki/bin/view/EGEE/SA3Testing#LB"
-
-gen_test_report > TestRep.txt
-
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-common-testbeds.sh b/org.glite.testsuites.ctb/LB/tests/lb-common-testbeds.sh
deleted file mode 100755
index f9a6d76..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-common-testbeds.sh
+++ /dev/null
@@ -1,372 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-
-function gen_arrange_script()
-{
-remotehost=$1
-COPYPROXY=$2
-
-egrep -i "Debian|Ubuntu" /etc/issue
-if [ $? = 0 ]; then
-	INSTALLCMD="apt-get install -q --yes"
-	INSTALLPKGS="lintian"
-else
-	INSTALLCMD="yum install -q -y --nogpgcheck"
-	INSTALLPKGS="rpmlint postgresql-server"
-fi
-
-cat << EndArrangeScript > arrange_lb_test_root.sh 
-CERTFILE=\$1
-GLITE_USER=\$2
-LBTSTCOLS=\$3
-OUTPUT_OPT=\$4
-
-echo "Certificate file: \$CERTFILE "
-echo "gLite user:       \$GLITE_USER "
-echo "Terminal width:   \$LBTSTCOLS "
-echo "Output format:    \$OUTPUT_OPT "
-
-export LBTSTCOLS
-
-${INSTALLCMD} globus-proxy-utils postgresql voms-clients curl wget sudo bc $INSTALLPKGS
-
-/etc/init.d/postgresql initdb >/dev/null 2>&1
-/etc/init.d/postgresql start
-for conf in /etc/postgresql/8.4/main/pg_hba.conf /var/lib/pgsql/data/pg_hba.conf; do
-	if [ -f \$conf ]; then
-		break;
-	fi
-done
-mv \$conf \$conf.orig
-cat >\$conf < /dev/null 2>/dev/null
-	FAKE_CAS=\`./org.glite.testsuites.ctb/LB/tests/lb-generate-fake-proxy.sh | grep -E "^X509_CERT_DIR" | sed 's/X509_CERT_DIR=//'\`
-	if [ "\$FAKE_CAS" = "" ]; then
-                echo "Failed generating proxy" >&2
-                exit 2
-        else
-                cp -rv \$FAKE_CAS/* /etc/grid-security/certificates/
-        fi
-fi
-
-#Allow glite user to read certain system files. Talk about dirty hacks.
-grep -E "\$GLITE_USER.*/bin/cat" /etc/sudoers > /dev/null 2> /dev/null
-if [ ! \$? = 0 ]; then
-	printf "\n\$GLITE_USER\tALL=NOPASSWD: /bin/cat /etc/cron.d/glite-lb-purge.cron,/bin/cat /var/log/messages\n\n" >> /etc/sudoers
-fi
-sed -i 's/^Defaults[ \t]*requiretty/#Defaults\trequiretty/' /etc/sudoers
-visudo -c
-
-echo cd > arrange_lb_test_user.sh
-echo export LBTSTCOLS=\$LBTSTCOLS >> arrange_lb_test_user.sh
-echo 'export GLITE_MYSQL_ROOT_PASSWORD="[Edited]"' >> arrange_lb_test_user.sh
-echo mkdir -p LB_testing >> arrange_lb_test_user.sh
-echo cd LB_testing >> arrange_lb_test_user.sh
-echo cvs -d :pserver:anonymous@glite.cvs.cern.ch:/cvs/jra1mw co org.glite.testsuites.ctb/LB >> arrange_lb_test_user.sh
-echo ls >> arrange_lb_test_user.sh
-echo cd org.glite.testsuites.ctb/LB/tests >> arrange_lb_test_user.sh
-echo ulimit -c unlimited >> arrange_lb_test_user.sh
-echo 'export HNAME=\`hostname -f\`' >> arrange_lb_test_user.sh
-echo 'export GLITE_WMS_QUERY_SERVER=\$HNAME:9000' >> arrange_lb_test_user.sh
-echo 'export GLITE_WMS_NOTIF_SERVER=\$HNAME:9000' >> arrange_lb_test_user.sh
-echo 'export GLITE_WMS_LOG_DESTINATION=\$HNAME:9002' >> arrange_lb_test_user.sh
-echo export GLITE_LB_SERVER_WPORT=9003 >> arrange_lb_test_user.sh
-echo export GLITE_LB_SERVER_PORT=9000 >> arrange_lb_test_user.sh
-echo export GLITE_LB_LOGGER_PORT=9002 >> arrange_lb_test_user.sh
-echo export GLITE_WMS_LBPROXY_STORE_SOCK=/tmp/lb_proxy_ >> arrange_lb_test_user.sh
-echo 'env | egrep "GLITE|\$HNAME|PATH"' >> arrange_lb_test_user.sh
-echo pwd >> arrange_lb_test_user.sh
-echo id >> arrange_lb_test_user.sh
-if [ "\$OUTPUT_OPT" = "-i" ]; then
-echo echo ======================== >> arrange_lb_test_user.sh
-echo echo "  THE CONSOLE IS YOURS" >> arrange_lb_test_user.sh
-echo echo ======================== >> arrange_lb_test_user.sh
-echo '/bin/bash -i' >> arrange_lb_test_user.sh 
-else
-echo echo ======================== >> arrange_lb_test_user.sh
-echo echo "  REAL TESTS START HERE" >> arrange_lb_test_user.sh
-echo echo ======================== >> arrange_lb_test_user.sh
-echo 'echo ""' >> arrange_lb_test_user.sh
-echo 'echo ""' >> arrange_lb_test_user.sh
-echo ./lb-test-permissions.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-event-delivery.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-il-recovery.sh -f /var/glite/log/dglogd.log \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-job-registration.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-https.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-job-states.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-logevent.sh /var/glite/log/dglogd.log \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-collections.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-notif-recovery.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-notif-msg.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-notif.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-notif-switch.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-notif-stream.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-notif-keeper.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-proxy-delivery.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-ws.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-bdii.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-sandbox-transfer.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-changeacl.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-statistics.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-threaded.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-harvester.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-nagios-probe.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo ./lb-test-packaging.sh \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo perl ./lb-test-purge.pl --i-want-to-purge $remotehost:9000 \$OUTPUT_OPT >> arrange_lb_test_user.sh
-echo 'echo ""' >> arrange_lb_test_user.sh
-echo 'echo ""' >> arrange_lb_test_user.sh
-echo echo ================== >> arrange_lb_test_user.sh
-echo echo "  TESTS END HERE" >> arrange_lb_test_user.sh
-echo echo ================== >> arrange_lb_test_user.sh
-fi
-#echo "" >> arrange_lb_test_user.sh
-
-chown \$GLITE_USER:\$GLITE_USER arrange_lb_test_user.sh
-chmod +x arrange_lb_test_user.sh
-
-#su -l \$GLITE_USER
-su -l \$GLITE_USER --command=/tmp/arrange_lb_test_user.sh
-echo ""
-
-EndArrangeScript
-}
-
-function gen_deployment_header()
-{
-DURATION=`expr $1 - $2`
-SCENARIO="$3"
-
-ISSUE=`cat /etc/issue | head -n 1`
-PLATFORM=`uname -i`
-TESTBED=`hostname -f`
-DISTRO=`cat /etc/issue | head -n 1 | sed 's/\s.*$//'`
-VERSION=`cat /etc/issue | head -n 1 | grep -E -o "[0-9]+\.[0-9]+"`
-MAJOR=`echo $VERSION | sed 's/\..*$//'`
-
-printf "
----++ $SCENARIO, $DISTRO $MAJOR ($PLATFORM)
-
----+++ Environment
-#CleanInstallation
-
-Clean installation according to EMI guidelines (CA certificates, proxy certificate...).
-
-| OS Issue | $ISSUE |
-| Platform | $PLATFORM |
-| Host | =$TESTBED= |
-| Duration | `expr $DURATION / 60` min |
-| Testbed uptime | =`uptime | sed 's/^\s*//'`= |
-
-"
-}
-
-function gen_repo_lists()
-{
-	egrep -i "Debian|Ubuntu" /etc/issue
-	if [ $? = 0 ]; then
-		apt-cache showpkg `apt-cache pkgnames` | awk '\
-			/^Package:/ { pkg=$2; }
-			/^Versions:/ {
-				getline
-			        print pkg, $0
-			}
-			/.*/ { next }' | sed 's/[()]//g' > /tmp/allpkgs.$$.txt
-
-		#
-		# rough distinguish between PROD and TEST repo on Debian
-		#   1) filtering by name
-		#   2) OS vs non-OS packages
-		#
-		#cat /tmp/allpkgs.$$.txt | cut -f3- -d' ' | sed 's/ /\n/g' | sort | uniq > /tmp/allrepos.$$.txt
-		cat /tmp/allpkgs.$$.txt | grep -Ei '\<(lib)?(glite|emi|canl|gridsite|voms|myproxy|globus)' | grep -Ev '(^emil |canlock)' > /tmp/somepkgs.$$.txt
-		cat /tmp/somepkgs.$$.txt | grep -E 'debian.*(sid|wheezy|squeeze)' > $1
-		cat /tmp/somepkgs.$$.txt | grep -v -E 'debian.*(sid|wheezy|squeeze)' > $2
-	else
-		yum install -y -q yum-utils
-		repoquery -a --qf "%{name} %{version} %{repoid}" > /tmp/allpkgs.$$.txt
-		repoquery -a --qf "%{repoid}" | sort | uniq > /tmp/allrepos.$$.txt
-
-		grep -i etics /tmp/allrepos.$$.txt > /dev/null
-		if [ $? = 0 ]; then
-			PRODREPO="EMI"
-			TESTREPO="ETICS"
-		else
-			printf " etics repo not found, trying to distinguish between EMI repos "
-			PRODREPO=`cat /tmp/allrepos.$$.txt | grep -o -E "EMI-[0-9]+" | sort | uniq | head -n 1`
-			TESTREPO=`cat /tmp/allrepos.$$.txt | grep -o -E "EMI-[0-9]+" | sort | uniq | tail -n 1`
-		fi
-
-		cat /tmp/allpkgs.$$.txt | grep " $PRODREPO" > $1
-		cat /tmp/allpkgs.$$.txt | grep " $TESTREPO" > $2
-	fi
-
-	rm -f /tmp/allpkgs.$$.txt /tmp/allrepos.$$.txt /tmp/somepkgs.$$.txt
-}
-
-function gen_test_report()
-{
-cat </dev/null | ${SYS_GREP} " 0% packet loss"| wc -l`
-	if [ $result -gt 0 ]; then
-		return $TEST_OK
-	else 
-		return $TEST_ERROR
-	fi
-}
-
-
-# check the binaries
-function check_exec()
-{
-	if [ -z $1 ]; then
-		set_error "No binary to check"
-		return $TEST_ERROR
-	fi
-	# XXX: maybe use bash's command type?
-	local ret=`which $1 2> /dev/null`
-	if [ -n "$ret" -a -x "$ret" ]; then
-		return $TEST_OK
-	else
-		return $TEST_ERROR
-	fi
-}
-
-function check_binaries()
-{
-# TODO: test only the binaries that are needed - it can differ in each test
-	local ret=$TEST_OK
-	for file in $@
-	do	
-		check_exec $file 
-		if [ $? -gt 0 ]; then
-			print_error "command $file not found"
-			ret=$TEST_ERROR
-		fi
-	done
-	return $ret
-}
-
-# check socket
-function check_socket()
-{
-	if [ $# -lt 2 ]; then
-		set_error "No host:port to check"
-		return $TEST_ERROR
-	fi
-	$TEST_SOCKET $1 $2 2> $testerrfile
-	if [ $? -eq 0 ];  then 
-		return $TEST_OK
-	else
-		return $TEST_ERROR
-	fi
-}
-
-# Check listener
-# Arguments:
-#  $1: program expected to listen on the given port
-#  $2: TCP port to check
-function check_listener()
-{
-	req_program=$1
-	req_port=$2
-        if [ -z $1 ]; then
-                set_error "No program name entered"
-                return $TEST_ERROR
-        fi
-
-	pid=`lsof -F p -i TCP:$req_port | sed "s/^p//"`
-	if [ -z $pid ]; then
-		return $TEST_ERROR
-	fi
-	program=`ps -p ${pid} -o args= | grep -E "[\/]*$req_program[ \t]*"`
-	if [ -z "$program" ];  then 
-		return $TEST_ERROR
-	else
-		return $TEST_OK
-	fi
-}
-
-
-# Check socket listener
-# Arguments:
-#  $1: program expected to listen on the given socket
-#  $2: socket to check
-function check_socket_listener()
-{
-	req_program=$1
-	req_socket=$2
-        if [ -z $1 ]; then
-                set_error "No program name entered"
-                return $TEST_ERROR
-        fi
-
-	pid=`lsof -F p $req_socket | sed "s/^p//" | head -n 1`
-	if [ -z $pid ]; then
-		return $TEST_ERROR
-	fi
-	program=`ps -p ${pid} -o args= | grep -E "[\/]*$req_program[ \t]*"`
-	if [ -z "$program" ];  then 
-		return $TEST_ERROR
-	else
-		return $TEST_OK
-	fi
-}
-
-#df /var/lib/mysql/ | tail -n 1 | awk '{ print $4 }'
-
-function try_purge()
-{
-                        #Purge test job
-                        joblist=$1
-
-                        printf "Purging test job (Trying the best, result will not be tested)\n"
-
-                        ${LBPURGE} -j ${joblist}
-
-                        $SYS_RM ${joblist}
-	
-}
-
-function test_args()
-{
-        echo $@
-}
-
-function check_credentials()
-{
-	my_GRIDPROXYINFO=${GRIDPROXYINFO}
-	if [ "$1" != "" ]; then
-		my_GRIDPROXYINFO="${GRIDPROXYINFO} -f $1"
-	fi
-
-	timeleft=`${my_GRIDPROXYINFO} 2>/dev/null | ${SYS_GREP} -E "^timeleft" | ${SYS_SED} "s/timeleft\s*:\s//"`
-	if [ "$timeleft" = "" ]; then
-		printf "... No credentials... "
-		return 1
-	fi
-	if [ "$timeleft" = "0:00:00" ]; then
-		printf "... Credentials expired... "
-		return 1
-	fi
-	return 0
-}
-
-function check_srv_version()
-{
-        check_binaries $LBWSGETVERSION
-        if [ $? -gt 0 ]; then
-		return 2
-        else
-		servername=`echo ${GLITE_WMS_QUERY_SERVER} | ${SYS_SED} "s/:.*//"`
-                wsglservver=`$LBWSGETVERSION -m ${servername}:${GLITE_LB_SERVER_WPORT} | $SYS_SED 's/^.*Server version:\s*//'`
-                if [ "$wsglservver" = "" ]; then
-               		return 2
-                else
-	
-			SRVVER=`$SYS_ECHO $wsglservver | $SYS_GREP -o -E "^[0-9]+\.[0-9]+"`
-			CHKVER=`$SYS_ECHO $2 | $SYS_GREP -o -E "^[0-9]*\.[0-9*]"`
-
-			printf "Srv. version $SRVVER $1 $CHKVER? "
-		        cresult=`$SYS_EXPR $SRVVER $1 $CHKVER`
-	                if [ "$cresult" -eq "1" ]; then
-				printf "yes "
-				return 0
-                	else
-				printf "no "
-				return 1
-        	        fi
-		fi
-	fi
-	return 0
-}
-
-function notif_wait() {
-	timeout="$1"
-	jobid="$2"
-	f="$3"
-
-	while ! $SYS_GREP ${jobid} "$f" > /dev/null 2>&1; do
-		sleep 1
-		printf "."
-		timeout=$((timeout-1))
-		if [ $timeout -le 0 ]; then
-			printf "timeout"
-			break;
-		fi
-	done
-	sleep 1
-	echo
-	$SYS_GREP ${jobid} $$_notifications.txt > /dev/null
-}
-
-function check_rpmlint() {
-	local pkg=''
-	local out=''
-	local ret=0
-
-	echo "Packages compliance check output:"
-	while test -n "$1"; do
-		for pkg in `rpm -qa --queryformat '%{NAME} ' $1`; do
-			echo $pkg
-			out="`rpmlint $pkg`"
-			echo "$out"
-			echo
-			if echo $out | grep -i '^E:' >/dev/null; then
-				ret=1
-			fi
-		done
-
-		shift
-	done
-
-	return $ret
-}
-
-function check_lintian() {
-	local dir=/tmp/lintian-check.$$
-	local pkgs=''
-	local pkg=''
-	local src=''
-	local out=''
-	local ret=0
-
-	rm -rf $dir
-	mkdir $dir
-	while test -n "$1"; do
-		pkgs="$pkgs `dpkg-query -W "$1" 2>>$dir/query.log | cut -f1`
-"
-		shift
-	done
-	for pkg in $pkgs; do
-		src=`dpkg-query -W -f '${Source}' $pkg 2>>$dir/query.log`
-		if [ $? -eq 0 ]; then
-			if [ -z "$src" ]; then src="$pkg"; fi
-			pkgs="$pkgs
-$src"
-		fi
-	done
-	pkgs=`echo "$pkgs" | sort | uniq | sed 's/^ //'`
-
-	if test -z "$pkgs"; then
-		echo "No packages to check"
-		return 0
-	fi
-
-	printf "Downloading packages..."
-	(cd $dir; apt-get -d source $pkgs >$dir/download.log)
-	if test $? -eq 0; then
-		test_done
-	else
-		test_skipped
-	fi
-
-	echo "Packages compliance check output:"
-	for pkg in $pkgs; do
-		echo $pkg:
-		out="`lintian $dir/${pkg}_*.dsc`"
-		echo "$out"
-		if echo $out | grep -i '^E:' >/dev/null; then
-			ret=1
-		fi
-	done
-
-	rm -rf $dir
-	return $ret
-}
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-generate-events.sh b/org.glite.testsuites.ctb/LB/tests/lb-generate-events.sh
deleted file mode 100755
index f57e246..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-generate-events.sh
+++ /dev/null
@@ -1,192 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-showHelp()
-{
-cat << EndHelpHeader
-Script for generating test events at a pre-determined rate.
-
-Prerequisities:
-   - LB local logger, interlogger, and server running
-   - environment variables set:
-
-     GLITE_LB_SERVER_PORT - if nondefault port (9000) is used
-     GLITE_LB_LOGGER_PORT - if nondefault port (9002) is used 	
-     GLITE_WMS_QUERY_SERVER
-     GLITE_WMS_LOG_DESTINATION
-
-Ops called:
-
-    job registration
-    event logging
-
-EndHelpHeader
-
-	echo "Usage: $progname [OPTIONS] [event file prefix]"
-	echo "Options:"
-	echo " -h | --help            Show this help message."
-	echo " -n | --n-per-sec       Number of events to send between each 1-s pause."
-	echo " -N | --no-of-jobs      Number of jobs to keep unfinished simultaneously."
-	echo ""
-}
-
-
-send_next_event ()
-{
-	NO=$1
-	EDG_WL_SEQUENCE=${seq[$NO]}
-	currjobid=${jobid[$NO]}
-
-	case "${state[${NO}]}" in
-
-	0)
-		printf "%-25s" "Registering testing job "
-		currjobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application 2>&1 | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'`
-		jobid[${NO}]=$currjobid
-		EDG_WL_SEQUENCE="UI=000000:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000002:LBS=000000"
-		let "JOBS++"
-		;;
-	1)
-		printf "%-25s" "logging Accepted"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s NetworkServer -e Accepted --from="UserInterface" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid="new jobId (Condor Globus ...)"`
-		;;
-	2)
-		printf "%-25s" "logging EnQueued"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s NetworkServer -e EnQueued --queue="destination queue" --job="job description in receiver language" --result=OK --reason="detailed description of transfer"`
-		;;
-	3)
-		printf "%-25s" "logging DeQueued"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e DeQueued --queue="queue name" --local_jobid="new jobId assigned by the receiving component"`
-		;;
-	4)
-		printf "%-25s" "logging HelperCall"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e HelperCall --helper_name="name of the called component" --helper_params="parameters of the call" --src_role=CALLING`
-		;;
-	5)
-		printf "%-25s" "logging Match"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e Match --dest_id="${DESTINATION:-destination CE/queue}"`
-		;;
-	6)
-		printf "%-25s" "logging HelperReturn"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e HelperReturn --helper_name="name of the called component" --retval="returned data" --src_role=CALLING`
-		;;
-	7)
-		printf "%-25s" "logging EnQueued"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e EnQueued --queue="destination queue" --job="job description in receiver language" --result=OK --reason="detailed description of transfer"`
-		;;
-	8)
-		printf "%-25s" "logging DeQueued"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s JobController -e DeQueued --queue="queue name" --local_jobid="new jobId assigned by the receiving component"`
-		;;
-	9)
-		printf "%-25s" "logging Transfer"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s JobController -e Transfer --destination="LRMS" --dest_host="destination hostname" --dest_instance="destination instance" --job="job description in receiver language" --result=OK --reason="detailed description of transfer" --dest_jobid="destination internal jobid"`
-		;;
-	10)
-		printf "%-25s" "logging Accepted"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Accepted --from="JobController" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid="new jobId (Condor Globus ...)"`
-		;;
-	11)
-		printf "%-25s" "logging Transfer"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Transfer --destination="LRMS" --dest_host="destination hostname" --dest_instance="destination instance" --job="job description in receiver language" --result=OK --reason="detailed description of transfer" --dest_jobid="destination internal jobid"`
-		;;
-	12)
-		printf "%-25s" "logging Running"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Running --node="${CE_NODE:-worker node}"`
-		;;
-	13)
-		printf "%-25s" "logging Done"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Done --status_code=OK --reason="reason for the change" --exit_code=0`
-		;;
-	14)
-		printf "%-25s" "logging Clear"
-		EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $currjobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Clear --reason=USER`
-		;;
-	esac
-	seq[$NO]="$EDG_WL_SEQUENCE"
-}
-
-MAXnoJOBS=20
-PerSec=5
-JOBS=0
-
-COMMON=lb-common.sh
-if [ ! -r ${COMMON} ]; then
-        printf "Common definitions '${COMMON}' missing! Some checks will be skipped."
-	unset COMMON
-fi
-source ${COMMON}
-
-
-while test -n "$1"
-do
-	case "$1" in
-		"-h" | "--help") showHelp && exit 2 ;;
-		"-n" | "--n-per-sec") shift && PerSec=$1 ;;
-		"-N" | "--no-of-jobs") shift && MAXnoJOBS=$1 ;;
-	esac
-	shift
-done
-
-	if [ ! -z "$COMMON" ]; then
-	        printf "Testing if all binaries are available"
-	        check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $SYS_CAT
-	        if [ $? -gt 0 ]; then
-			echo "Required binary not present"
-			exit 1
-	        fi
-
-		# check credentials
-		printf "Testing credentials"
-		check_credentials_and_generate_proxy
-		if [ $? != 0 ]; then
-			echo "No proxy available"
-			exit 1
-		fi
-	fi
-
-	for (( i=0; i<$MAXnoJOBS; i++ ))
-	do
-		state[$i]=0
-	done
-
-	CONT="yes"
-	while [ "$CONT" = "yes" ]; do
-
-		for (( j=0; j<$PerSec; j++ ))
-		do
-			let "curr = ($RANDOM + $RANDOM) % $MAXnoJOBS"
-
-			printf "%4d " "$curr"
-			send_next_event $curr
-			printf "${jobid[$curr]}\n"
-
-			let "state[${curr}] = ${state[${curr}]} + 1"
-			if [ ${state[${curr}]} -gt 14 ]; then
-				state[${curr}]=0
-			fi
-		done
-		printf "$JOBS jobs so far...\n"
-		sleep 1
-	done
-
-test_end
-
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-generate-fake-proxy.sh b/org.glite.testsuites.ctb/LB/tests/lb-generate-fake-proxy.sh
deleted file mode 100755
index 7d141b9..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-generate-fake-proxy.sh
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-user_id=`id -u`
-CERTS_ROOT=/tmp/test-certs.`id -un`
-USER=trusted_client00
-USER_BOB=trusted_client01
-USER_SHA512=trusted_clientsha512
-VOMS_SERVER=trusted_host
-VO=vo.org
-
-showHelp()
-{
-cat << EndHelpHeader
-Script for making fake proxy certificates out of fake credentials
-Thist script generates 2 proxy certificates with voms attributes
-and sets \$X509_USER_PROXY and \$X509_USER_PROXY_BOB
-Prerequisities:
-
-Tests called:
-
-Returned values:
-    Exit 0: Certificate generated
-    Exit 1: Certificete not generated
-
-EndHelpHeader
-	echo "Usage: $progname [OPTIONS]"
-        echo "Options:"
-        echo " -h | --help            Show this help message."
-        echo " -H | --hours           Proxy will be valid for given No. of hours (default is 12)"
-        echo " -l | --lsc             Generate VOMS lsc file."
-        echo " -V | --novoms          Skip VOMS stuff."
-	echo " -o | --old	      Create old-style non-RFC proxy."
-	echo " -a | --all	      Generate all certificates."
-
-}
-
-GENLSC=0
-VOMS=1
-RFCSWITCH="-rfc"
-GEN_ALL=""
-while test -n "$1"
-do
-        case "$1" in
-                "-h" | "--help") showHelp && exit 2 ;;
-                "-H" | "--hours") shift ; PROXYHOURS="-hours $1 " ;;
-                "-l" | "--lsc") GENLSC=1 ;;
-                "-V" | "--novoms") VOMS=0 ;;
-                "-o" | "--old") RFCSWITCH="" ;;
-		"-a" | "--all")	GEN_ALL="--all" ;;
-        esac
-        shift
-done
-
-PWD=`pwd`
-
-if [ ! -d "$CERTS_ROOT" ]; then
-	echo "Generating fake proxy certificate - this may take a few minutes"
-	echo ""
-
-	mkdir -p $CERTS_ROOT
-	cd $CERTS_ROOT
-	wget -q -O org.glite.security.test-utils.tar.gz \
-		'http://jra1mw.cvs.cern.ch:8180/cgi-bin/jra1mw.cgi/org.glite.security.test-utils.tar.gz?view=tar' &> /dev/null || exit 1
-	tar xzf org.glite.security.test-utils.tar.gz || exit 1
-	# keep using system default hash (even when different across openssl versions)
-	sed -i.orig 's/openssl x509 -subject_hash_old/openssl x509 -hash/' org.glite.security.test-utils/bin/generate-test-certificates.sh
-	org.glite.security.test-utils/bin/generate-test-certificates.sh\
-	$GEN_ALL $CERTS_ROOT &> /dev/null || exit 1
-fi
-
-cd $CERTS_ROOT/trusted-certs
-
-for p in $USER $VOMS_SERVER $USER_BOB $USER_SHA512; do
-	openssl rsa -in ${p}.priv -out ${p}.priv-clear -passin pass:changeit &> /dev/null
-	chmod 600 ${p}.priv-clear
-	done
-
-if [ $VOMS -eq 1 ]; then
-	for p in $USER $USER_BOB; do
-		voms-proxy-fake -cert ${p}.cert -key ${p}.priv-clear $RFCSWITCH\
-			-hostcert ${VOMS_SERVER}.cert -hostkey ${VOMS_SERVER}.priv-clear $PROXYHOURS\
-			-voms ${VO} -out /tmp/x509up_u${p} \
-			-fqan "/${VO}/Role=NULL/Capability=NULL" &> /dev/null || exit 1
-		done
-	mv "/tmp/x509up_u${USER}" "/tmp/x509up_u${user_id}"
-	mv "/tmp/x509up_u${USER_BOB}" "/tmp/x509up_u.${user_id}"
-	export X509_USER_PROXY=/tmp/x509up_u${user_id}
-	export X509_USER_PROXY_BOB=/tmp/x509up_u.${user_id}
-	echo "/tmp/x509up_u${user_id} proxy certificate has been generated"
-	echo "/tmp/x509up_u.${user_id} proxy certificate has been generated" 
-fi
-
-export x509_USER_CERT=$CERTS_ROOT/trusted-certs/trusted_client00.cert
-export x509_USER_KEY=$CERTS_ROOT/trusted-certs/trusted_client00.priv-clear
-
-echo ""
-echo "======================================================================"
-echo "Credentials have been generated, adapt your configuration accordingly:"
-echo "======================================================================"
-
-echo X509_CERT_DIR=$CERTS_ROOT/grid-security/certificates
-echo TRUSTED_CERTS=$CERTS_ROOT/trusted-certs
-echo HOST_CERT_DIR=$CERTS_ROOT/grid-security
-if [ $VOMS -eq 1 ]; then
-	echo X509_USER_PROXY=/tmp/x509up_u${user_id}
-	#BOB'S FAKE PROXY
-	echo X509_USER_PROXY_BOB=/tmp/x509up_u.${user_id}
-	if [ $GENLSC -eq 1 ]; then
-		mkdir -p /etc/grid-security/vomsdir/$VO
-		openssl x509 -noout -subject -issuer -in $CERTS_ROOT/trusted-certs/${VOMS_SERVER}.cert | cut -d ' ' -f 2- > /etc/grid-security/vomsdir/$VO/`hostname -f`.lsc
-	else
-		echo mkdir /etc/grid-security/vomsdir/$VO
-		echo "openssl x509 -noout -subject -issuer -in $CERTS_ROOT/trusted-certs/${VOMS_SERVER}.cert | cut -d ' ' -f 2- > /etc/grid-security/vomsdir/$VO/`hostname -f`.lsc"
-	fi
-fi
-echo "======================================================================"
-echo ""
-
-cd $PWD
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-l2.sh b/org.glite.testsuites.ctb/LB/tests/lb-l2.sh
deleted file mode 100755
index 585ad93..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-l2.sh
+++ /dev/null
@@ -1,280 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-#3.1.4 et 3.2.1: Normal event delivery and Normal Job States
-
-#Prerequisities: All services running 
-
-#Actions:
-#Registers jobs with glite-lb-job-reg prferably pointing to remote LB Server
-#Check of the job status
-#Logs sequences of events with glite-lb-logevent
-#Checks with glite-lb-job_log that the events got delivered aftewards
-#Checks with glite-lb-job_status that the status of the jobs are correct
-
-
-PATH=/opt/glite/examples:$PATH
-#echo $PATH
-LBJOBREG=${LBJOBREG:-glite-lb-job_reg}
-LBLOGEVENT=${LBLOGEVENT:-glite-lb-logevent}
-LBJOBSTATUS=${LBJOBSTATUS:-glite-lb-job_status}
-LBJOBLOG=${LBJOBLOG:-glite-lb-job_log}
-LBJOBSTAT=${LBJOBSTAT:-glite-lb-job_status}
-LBPURGE=${PURGE:-glite-lb-purge}
-
-BKSERVER="localhost"
-STATES="aborted cancelled done ready running scheduled waiting submitted "
-SOURCES="NetworkServer WorkloadManager BigHelper JobController LogMonitor LRMS Application UserInterface"
-
-dtest=1
-i=0
-JOBS_ARRAY_SIZE=10
-INTERVAL=2
-DATE_S=`date +"%s"`
-DATE=`date`
-LOG_FILE="$DATE_S.log"
-
-
-init()
-{
-echo "Date: $DATE" > $LOG_FILE
-export EDG_WL_QUERY_SERVER="$BKSERVER:9000"
-export EDG_WL_LOG_DESTINATION="$BKSERVER:9002"
-BKSERVER_HOST="$BKSERVER:9000"
-BKSERVER_OPT="-m $BKSERVER"
-}
-
-
-getJobId()
-{
-cat jobreg |grep "EDG_JOBID" |cut -c12- > jobList2
-res=`cat jobList2 |wc -c`
-res=$[$res-2]
-cat jobList2 |cut -c1-`echo $res` > jobreg
-rm jobList2
-}
-
-#registrating a job
-job_reg()
-{
-eval $LBJOBREG $BKSERVER_OPT -s $1 > jobreg
-getJobId
-job=`cat jobreg`
-rm jobreg
-}
-
-#registering a list of jobs which jobid's are placed in an array
-array_job_reg()
-{
-echo "Registering $JOBS_ARRAY_SIZE jobs...................."
-job_id=0
-st_count=`echo $SOURCES | wc -w`
-while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do
-        tmp=`echo $RANDOM % $st_count + 1 | bc`
-        jsource=`echo $SOURCES | cut -d " " -f $tmp | tr A-Z a-z`
-        job_reg $jsource
-        echo $job
-        SAMPLE_JOBS_ARRAY[$job_id]=$job
-        job_id=$[$job_id+1]
-        done
-}
-
-#Event delivery  test
-testLB()
-{
-echo "Checking the Events............................................."
-echo
-job_id=0
-while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do
-        #sleep 2
-        #out is the list of events sent, we count the number of events and then we extract the job status
-        nbEvents=`cat out[$job_id] |grep glite-lb-logevent | wc -l`
-        nbEvents=$[$nbEvents+1]
-        cat out[$job_id] |gawk -F"-e " '{ print $2 }' > eventsTemp
-        echo "UserTag"> events
-        echo "RegJob">> events
-        cat eventsTemp|gawk -F" --" '{ print $1 }'>> events
-        rm eventsTemp
-        events3="blank"
-        i=0
-        cmp -s events events3
-        while [ $? -ne 0 ] && [ $i -lt $INTERVAL ] ; do
-
-
-        #we use glite-lb-job_log and apply the same treatment as above to the output
-                eval $LBJOBLOG -r $INTERVAL -d 2  ${SAMPLE_JOBS_ARRAY[$job_id]} > joblog2
-                nbevents=`cat joblog2 | grep DATE | wc -l`
-                cat joblog2|gawk -F"DG.EVNT=\"" '{ print $2 }' > eventsTemp2
-                cat eventsTemp2|gawk -F"\"" '{ print $1 }'> events2
-                cat events2|sed /^$/d > events3
-                rm eventsTemp2 events2 joblog2
-                #Comparison of the outputs and intermediary printout
-                echo "Events Sent....." >> $LOG_FILE
-                cat -n events >> $LOG_FILE
-#               cat -n events
-                echo "Events recorded in the LB server....." >> $LOG_FILE
-                cat -n events3 >> $LOG_FILE
-#               cat -n events3
-                i=$[$i+1]
-                cmp -s events events3
-        done
-        cmp -s events events3
-        if [ $? -eq 0 ]; then
-                echo "Job $job_id ....................[OK]"  
-                i=0
-
-        else
-                echo "Job $job_id.....................[FAILED]" 
-                dtest=0
-        fi
-        rm events events3 out[$job_id]
-        job_id=$[$job_id+1]
-done
-echo
-echo "A detailed list of events logged has been printed to $LOG_FILE"
-echo
-}
-
-#job status test
-testLB2()
-{
-echo "Checking the Jobs Status........................................" 
-echo
-job_id=0
- while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do
-        #sleep 1
-        eval $LBJOBSTATUS ${SAMPLE_JOBS_ARRAY[$job_id]} > status
-        testStatus=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}|wc -l`
-        i=0
-        while [ $testStatus -ne 1 ] && [ $i -lt $INTERVAL ] ; do
-                bkserver_state=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}`
-                testStatus=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}|wc -l`
-                i=$[$i+1]
-        done
-        if [ $testStatus -eq 1 ] ; then
-                echo "Job: $job_id ..Logged state:${SAMPLE_JOBS_STATES[$job_id]}-Recorded `cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}`.......[OK]"
-        else
-                echo "Job: $job_id ..Logged state:${SAMPLE_JOBS_STATES[$job_id]}-Recorded `cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}`.......[FAILED]"
-                cat status > errorStatus.tmp
-                echo "Detailed status has been copied to errorStatus.tmp"
-                echo
-                dtest=0
-        fi
-        rm status
-job_id=$[$job_id+1]
-done
-}
-
-#logging events to the jobs. Events are selected randomly from a list.
-logEvents()
-{
-echo "Logging events to the $JOBS_ARRAY_SIZE jobs...................................."
-echo
-job_id2=0
-st_count=`echo $STATES | wc -w`
-        while [ $job_id2 -lt $JOBS_ARRAY_SIZE ] ; do
-         tmp=`echo $RANDOM % $st_count + 1 | bc`
-        state=`echo $STATES | cut -d " " -f $tmp | tr A-Z a-z`
-        SAMPLE_JOBS_STATES[$job_id2]=$state
-        echo >> $LOG_FILE
-        echo "Submitting events to the job: ${SAMPLE_JOBS_ARRAY[$job_id2]} " >> $LOG_FILE
-        echo >> $LOG_FILE
-
-        echo "event submitted.......................................[$state]" >> $LOG_FILE
-        eval glite-lb-$state.sh $LARGE_STRESS -j ${SAMPLE_JOBS_ARRAY[$job_id2]} 2>out[$job_id2]
-        job_id2=$(($job_id2 + 1))
-done
-}
-
-#logging tags to the jobs
-logTags()
-{
-echo "Logging tags to the $JOBS_ARRAY_SIZE jobs...................................."
-echo
-
-job_id=0
-while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do
-        eval $LBLOGEVENT -s Application -e UserTag -j ${SAMPLE_JOBS_ARRAY[$job_id]} -name testTag -value 12345  >> $LOG_FILE
-job_id=$[$job_id+1]
-done
-}
-
-showHelp()
-{        
-echo  "Usage: $0 [OPTIONS] "        
-echo  "Options:"        
-echo  " -h | --help                   Show this help message."        
-echo  " -r | --retries                Number of test retries (2 by default)"        
-echo  " -n | --nbjobs                 Number of jobs (10 by default)"        
-echo  " -m | --bkserver               Host address of the BKServer ex:pc900.iihe.ac.be "        
-echo  " -s | --states                 List of states in which could tested jobs fall."        
-echo  " -l | --large-stress 'size'    Do a large stress logging ('size' random data added to the messages."
-echo  ""
-
-#       echo  "For proper operation check your grid-proxy-info"
-#       grid-proxy-info
-}
-
-
-#input
-if [ -z "$1" ]; then
-  showHelp
-  exit 2
-fi
-BK=0
-while test -n "$1"
-do
-        case "$1" in
-        "-h" | "--help") showHelp && exit 2 ;;
-        "-r" | "--retries") shift ; INTERVAL=$1 ;;
-        "-n" | "--nbjobs") shift ; JOBS_ARRAY_SIZE=$1 ;;
-        "-m" | "--bkserver") shift ; BKSERVER=$1 BK=1;;
-        "-s" | "--states") shift; STATES="$1" ;;
-        "-l" | "--large-stress") shift ; LARGE_STRESS="-l $1" ;;
-#       "-g" | "--log") shift ; logfile=$1 ;;
-
-        *) echo "Unrecognized option $1 try -h for help"; exit 2 ;;
-
-        esac
-        shift
-done
-if [ $BK -ne 1 ]; then
-        echo
-        echo "You must specify the hostname of the LB Server with the option -m (ex: -m pf435.ulb.ac.be)" 
-        echo
-        exit 2
-fi
-echo
-
-
-#main..................................................................
-init
-array_job_reg
-logEvents
-logTags
-testLB
-testLB2
-#testProxy
-#eval $LBPURGE -h
-echo
-if [ $dtest -eq 1  ];then
-        echo "Final test result .........................................[OK]"
-        exit 1
-else    echo "Final test result .........................................[FAILED]"
-        exit 0
- fi
-echo
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-l2ILR.sh b/org.glite.testsuites.ctb/LB/tests/lb-l2ILR.sh
deleted file mode 100755
index b8ee45c..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-l2ILR.sh
+++ /dev/null
@@ -1,278 +0,0 @@
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-#3.1.3: Interlogger Recovery
-##############################################################################################
-#Prerequisities: locallogger(glite-lb-logd) and BKServer (glite-lb-bkserv) must be running.
-#The interlogger(glite-lb-interl) must be stopped. (kill the process manually on the LB machine)
-
-#Actions:
-#Registers jobs with glite-lb-job-reg 
-#Logs sequences of events with glite-lb-logevent
-#User starts the interlogger daemon
-#(/opt/glite/etc/config/scripts/glite-lb-cofig.py --start on your LB machine (as root))
-#Checks with glite-lb-job_log that the events got delivered aftewards 
-#by the interloger to the bookkeeping server. (from the localloger which is linked to the WMS)
-#Checks with glite-lb-job_status that the status of the jobs are correct in the BKserver
-###############################################################################################
-
-PATH=/opt/glite/examples:$PATH
-#echo $PATH
-LBJOBREG=${LBJOBREG:-glite-lb-job_reg}
-LBLOGEVENT=${LBLOGEVENT:-glite-lb-logevent}
-LBJOBSTATUS=${LBJOBSTATUS:-glite-lb-job_status}
-LBJOBLOG=${LBJOBLOG:-glite-lb-job_log}
-LBJOBSTAT=${LBJOBSTAT:-glite-lb-job_status}
-LBPURGE=${PURGE:-glite-lb-purge}
-
-STATES="aborted cancelled done ready running scheduled waiting submitted "
-SOURCES="NetworkServer WorkloadManager BigHelper JobController LogMonitor LRMS Application UserInterface"
-dtest=1
-i=0
-JOBS_ARRAY_SIZE=10
-INTERVAL=2
-DATE_S=`date +"%s"`
-DATE=`date`
-LOG_FILE="$DATE_S.log"
-
-#initialisation
-init()
-{
-echo "Date: $DATE" > $LOG_FILE
-export EDG_WL_QUERY_SERVER="$BKSERVER:9000"
-export EDG_WL_LOG_DESTINATION="$BKSERVER:9002"
-BKSERVER_HOST="$BKSERVER:9000"
-BKSERVER_OPT="-m $BKSERVER"
-}
-
-#extracting the job id 
-getJobId()
-{
-cat jobreg |grep "EDG_JOBID" |cut -c12- > jobList2
-res=`cat jobList2 |wc -c`
-res=$[$res-2]
-cat jobList2 |cut -c1-`echo $res` > jobreg
-rm jobList2
-}
-
-#registrating a job
-job_reg()
-{
-eval $LBJOBREG $BKSERVER_OPT -s $1 > jobreg
-getJobId
-job=`cat jobreg`
-rm jobreg
-}
-
-#registering a list of jobs which jobid's are placed in an array
-array_job_reg()
-{
-echo "Registering $JOBS_ARRAY_SIZE jobs...................."
-job_id=0
-st_count=`echo $SOURCES | wc -w`
-while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do
-        tmp=`echo $RANDOM % $st_count + 1 | bc`
-        jsource=`echo $SOURCES | cut -d " " -f $tmp | tr A-Z a-z`
-        job_reg $jsource
-        echo $job
-        SAMPLE_JOBS_ARRAY[$job_id]=$job
-        job_id=$[$job_id+1]
-        done
-}
-
-#Event delivery  test
-testLB()
-{
-echo "Checking the Events............................................."
-echo
-job_id=0
-while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do
-        #sleep 2
-        #out is the list of events sent, we count the number of events and then we extract the job status
-        nbEvents=`cat out[$job_id] |grep glite-lb-logevent | wc -l`
-        nbEvents=$[$nbEvents+1]
-        cat out[$job_id] |gawk -F"-e " '{ print $2 }' > eventsTemp
-        echo "RegJob">> events
-        cat eventsTemp|gawk -F" --" '{ print $1 }'>> events
-        rm eventsTemp
-        events3="blank"
-        i=0
-        cmp -s events events3
-        while [ $? -ne 0 ] && [ $i -lt $INTERVAL ] ; do
-
-
-        #we use glite-lb-job_log and apply the same treatment as above to the output
-                eval $LBJOBLOG -r $INTERVAL -d 2  ${SAMPLE_JOBS_ARRAY[$job_id]} > joblog2
-                nbevents=`cat joblog2 | grep DATE | wc -l`
-                cat joblog2|gawk -F"DG.EVNT=\"" '{ print $2 }' > eventsTemp2
-                cat eventsTemp2|gawk -F"\"" '{ print $1 }'> events2
-                cat events2|sed /^$/d > events3
-                rm eventsTemp2 events2 joblog2
-                #Comparison of the outputs and intermediary printout
-                echo "Events Sent....." >> $LOG_FILE
-                cat -n events >> $LOG_FILE
-#               cat -n events
-                echo "Events recorded in the LB server....." >> $LOG_FILE
-                cat -n events3 >> $LOG_FILE
-#               cat -n events3
-                i=$[$i+1]
-                cmp -s events events3
-        done
-        cmp -s events events3
-        if [ $? -eq 0 ]; then
-                echo "Job $job_id ....................[OK]"  
-                i=0
-
-        else
-                echo "Job $job_id.....................[FAILED]" 
-                dtest=0
-        fi
-        rm events events3 out[$job_id]
-        job_id=$[$job_id+1]
-done
-echo
-echo "A detailed list of events logged has been printed to $LOG_FILE"
-echo
-}
-
-#job status test
-testLB2()
-{
-echo "Checking the Jobs Status........................................" 
-echo
-job_id=0
- while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do
-        #sleep 1
-        eval $LBJOBSTATUS ${SAMPLE_JOBS_ARRAY[$job_id]} > status
-        testStatus=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}|wc -l`
-        i=0
-        while [ $testStatus -ne 1 ] && [ $i -lt $INTERVAL ] ; do
-                bkserver_state=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}`
-                testStatus=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}|wc -l`
-                i=$[$i+1]
-        done
-        if [ $testStatus -eq 1 ] ; then
-                echo "Job: $job_id ..Logged state:${SAMPLE_JOBS_STATES[$job_id]}-Recorded `cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}`.......[OK]"
-        else
-                echo "Job: $job_id ..Logged state:${SAMPLE_JOBS_STATES[$job_id]}-Recorded `cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}`.......[FAILED]"
-                cat status > errorStatus.tmp
-                echo "Detailed status has been copied to errorStatus.tmp"
-                echo
-                dtest=0
-        fi
-        rm status
-job_id=$[$job_id+1]
-done
-}
-
-#logging events to the jobs. Events are selected randomly from a list.
-logEvents()
-{
-echo "Logging events to the $JOBS_ARRAY_SIZE jobs...................................."
-echo
-job_id2=0
-st_count=`echo $STATES | wc -w`
-        while [ $job_id2 -lt $JOBS_ARRAY_SIZE ] ; do
-         tmp=`echo $RANDOM % $st_count + 1 | bc`
-        state=`echo $STATES | cut -d " " -f $tmp | tr A-Z a-z`
-        SAMPLE_JOBS_STATES[$job_id2]=$state
-        echo >> $LOG_FILE
-        echo "Submitting events to the job: ${SAMPLE_JOBS_ARRAY[$job_id2]} " >> $LOG_FILE
-        echo >> $LOG_FILE
-
-        echo "event submitted.......................................[$state]" >> $LOG_FILE
-        eval glite-lb-$state.sh $LARGE_STRESS -j ${SAMPLE_JOBS_ARRAY[$job_id2]} 2>out[$job_id2]
-        job_id2=$(($job_id2 + 1))
-done
-}
-
-
-showHelp()
-{        
-echo  "Usage: $0 [OPTIONS] "        
-echo  "Options:"        
-echo  " -h | --help                   Show this help message."        
-echo  " -r | --retries                Number of test retries (2 by default)"        
-echo  " -n | --nbjobs                 Number of jobs (10 by default)"        
-echo  " -m | --bkserver               Host address of the BKServer ex:pc900.iihe.ac.be "        
-echo  " -s | --states                 List of states in which could tested jobs fall."        
-echo  " -l | --large-stress 'size'    Do a large stress logging ('size' random data added to the messages."
-echo  ""
-
-#       echo  "For proper operation check your grid-proxy-info"
-#       grid-proxy-info
-}
-
-
-#input
-if [ -z "$1" ]; then
-  showHelp
-  exit 2
-fi
-BK=0
-while test -n "$1"
-do
-        case "$1" in
-        "-h" | "--help") showHelp && exit 2 ;;
-        "-r" | "--retries") shift ; INTERVAL=$1 ;;
-        "-n" | "--nbjobs") shift ; JOBS_ARRAY_SIZE=$1 ;;
-        "-m" | "--bkserver") shift ; BKSERVER=$1 BK=1;;
-        "-s" | "--states") shift; STATES="$1" ;;
-        "-l" | "--large-stress") shift ; LARGE_STRESS="-l $1" ;;
-#       "-g" | "--log") shift ; logfile=$1 ;;
-
-        *) echo "Unrecognized option $1 try -h for help"; exit 2 ;;
-
-        esac
-        shift
-done
-if [ $BK -ne 1 ]; then
-        echo
-        echo "You must specify the hostname of the LB Server with the option -m (ex: -m pf435.ulb.ac.be)" 
-        echo
-        exit 2
-fi
-echo
-
-
-#main..................................................................
-
-#main..................................................................
-init
-echo "Be sure you have stopped glite-lb-interlogd .........................."
-echo "You have to log on on your LB machine and kill the process manually..."
-echo "Press any key........................................................."
-read x
-array_job_reg
-logEvents
-echo "Please start the glite-lb-interlogd..................................."
-echo "Please use /opt/glite/etc/config/scripts/glite-lb-cofig.py --start...."
-echo "Press any key........................................................."
-read x
-echo "Sleeping 10 seconds......................................................"
-sleep 10
-testLB
-testLB2
-#testProxy
-#eval $LBPURGE -h
-echo
-if [ $dtest -eq 1  ];then
-        echo "Final test result .........................................[OK]"
-        exit 1
-else    echo "Final test result .........................................[FAILED]"
-        exit 0
- fi
-echo
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-l2Stat.sh b/org.glite.testsuites.ctb/LB/tests/lb-l2Stat.sh
deleted file mode 100755
index 301443d..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-l2Stat.sh
+++ /dev/null
@@ -1,239 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Normal event delivery and Normal Job States with internal BKsrever performance
-
-#Prerequisities: All services running 
-#Actions:
-#Registers jobs with glite-lb-job-reg prferably pointing to remote LB Server
-#Check of the job status
-#Logs sequences of events with glite-lb-logevent
-#Check with glite-lb-job_status that the status of the jobs are correct and mesures how long it took to get results
-
-
-PATH=/opt/glite/examples:$PATH
-#echo $PATH
-LBJOBREG=${LBJOBREG:-glite-lb-job_reg}
-LBLOGEVENT=${LBLOGEVENT:-glite-lb-logevent}
-LBJOBSTATUS=${LBJOBSTATUS:-glite-lb-job_status}
-LBJOBLOG=${LBJOBLOG:-glite-lb-job_log}
-LBJOBSTAT=${LBJOBSTAT:-glite-lb-job_status}
-LBPURGE=${PURGE:-glite-lb-purge}
-
-
-STATES="aborted cancelled done ready running scheduled waiting submitted "
-SOURCES="NetworkServer WorkloadManager BigHelper JobController LogMonitor LRMS Application UserInterface"
-dtest=1
-i=0
-JOBS_ARRAY_SIZE=10
-# timeouts for polling the bkserver
-timeout=10
-maxtimeout=300
-NB_TAGS=50
-INTERVAL=2
-DATE_S=`date +"%s"`
-DATE=`date`
-LOG_FILE="$DATE_S.log"
-
-init()
-{
-echo "Date: $DATE" > $LOG_FILE
-export EDG_WL_QUERY_SERVER="$BKSERVER:9000"
-export EDG_WL_LOG_DESTINATION="$BKSERVER:9002"
-BKSERVER_HOST="$BKSERVER:9000"
-BKSERVER_OPT="-m $BKSERVER"
-}
-
-get_time()
-{
-    sec=`date +%s`
-    nsec=`date +%N`
-    time=`echo "1000000000*$sec + $nsec"|bc`
-#    time=$sec
-    return 0
-}
-
-getJobId()
-{
-cat jobreg |grep "EDG_JOBID" |cut -c12- > jobList2
-res=`cat jobList2 |wc -c`
-res=$[$res-2]
-cat jobList2 |cut -c1-`echo $res` > jobreg
-rm jobList2
-}
-
-#registrating a job
-job_reg()
-{
-eval $LBJOBREG $BKSERVER_OPT -s $1 > jobreg
-getJobId
-job=`cat jobreg`
-rm jobreg
-}
-
-array_job_reg()
-{
-echo "Registering $JOBS_ARRAY_SIZE jobs...................."
-job_id=0
-st_count=`echo $SOURCES | wc -w`
-while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do
-        tmp=`echo $RANDOM % $st_count + 1 | bc`
-        jsource=`echo $SOURCES | cut -d " " -f $tmp | tr A-Z a-z`
-        job_reg $jsource
-        echo $job
-        SAMPLE_JOBS_ARRAY[$job_id]=$job
-        job_id=$[$job_id+1]
-        done
-}
-
-#job status test
-testLBP()
-{
-echo "Checking the Events............................................."
-echo
-job_id=0
-while [ $job_id -lt $JOBS_ARRAY_SIZE ] ; do
-        get_time
-        start=$time
-        logEvent $job_id
-        logTag $job_id
-
-
-        eval $LBJOBSTATUS ${SAMPLE_JOBS_ARRAY[$job_id]} > status
-        testStatus=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}|wc -l`
-        response=0
-        while [ $testStatus -ne 1 ];do
-                bkserver_state=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}`
-                testStatus=`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}|wc -l`
-                echo "**Retrying**"
-                sleep $timeout
-                response=$(($response + $timeout ))
-                if test $response -gt $maxtimeout ; then
-                        echo -e "ERROR\n\tstatus of job ${SAMPLE_JOBS_ARRAY[$job_id]} as queried from bkserver ($bkserver_state) has not become ${SAMPLE_JOBS_STATES[$job_id]} for more than $response seconds!"
-                        echo "Detailed status has been copied to errorStatus.tmp"
-                        echo
-                        dtest=0
-                fi
-        done
-        get_time
-        response=`echo "scale=9; ($time - $start)/1000000000"|bc`
-        SAMPLE_JOBS_RESPONSES[$job_id]=$response
-        echo "Job: $job_id ....[`cat status |grep -i state.*${SAMPLE_JOBS_STATES[$job_id]}`].......[OK]"
-        echo
-        rm status
-        job_id=$[$job_id+1]
-        done
-        j=0
-        total=0
-        echo "Sending events took for individual jobs the following time"
-        while [ $j -lt $JOBS_ARRAY_SIZE ] ; do
-                total=`echo "scale=9; $total + ${SAMPLE_JOBS_RESPONSES[$j]}" |bc`
-                echo -e "${SAMPLE_JOBS_ARRAY[$j]} \t${SAMPLE_JOBS_RESPONSES[$j]} seconds"
-                        j=$(($j + 1))
-        done
-        echo -e "Total time for $JOBS_ARRAY_SIZE jobs: \t$total"
-        echo -e -n "Average time for event: \t" 
-        echo "scale=9; $total / $JOBS_ARRAY_SIZE "|bc
-         echo -e -n "Average time for event and tags: \t" 
-        echo "scale=9; $total / $JOBS_ARRAY_SIZE / $NB_TAGS"|bc
-        echo -e -n "Event throughput (events/sec): \t"
-        echo "scale=9; $NB_TAGS * $JOBS_ARRAY_SIZE / $total"|bc
-        echo
-        echo "A detailed list of events logged has been printed to $LOG_FILE"
-        echo
-}
-
-logEvent()
-#ARG1: Number of the job considered in the jobs array
-{
-st_count=`echo $STATES | wc -w`
-tmp=`echo $RANDOM % $st_count + 1 | bc`
-state=`echo $STATES | cut -d " " -f $tmp | tr A-Z a-z`
-SAMPLE_JOBS_STATES[$1]=$state
-echo "Logging event to the job($1).........................[$state]"
-echo > LoggedEvents.log
-echo "Submitting events to the job: ${SAMPLE_JOBS_ARRAY[$1]} " >> $LOG_FILE
-echo >> LoggedEvents.log
-echo "event submitted.......................................[$state]" >> $LOG_FILE
-eval glite-lb-$state.sh $LARGE_STRESS -j ${SAMPLE_JOBS_ARRAY[$1]} 2>out
-}
-logTag()
-{
-i=0
-echo "Logging $NB_TAGS tags to the job................"
-eval $LBLOGEVENT -s Application -n $NB_TAGS -e UserTag -j ${SAMPLE_JOBS_ARRAY[$1]} -name testTag -value 12345  >> $LOG_FILE
-}
-
-showHelp()
-{
-        echo  "Usage: $0 [OPTIONS] "
-        echo  "Options:"
-        echo  " -h | --help                   Show this help message."
-        echo  " -n | --nbjobs                 Number of jobs"
-        echo  " -s | --states                 List of states in which could tested jobs fall."
-        echo  " -m | --bkserver               Host address of the BKServer "
-        echo  " -t | --tags                   Number of user tags to load to each job."
-        echo  " -l | --large-stress 'size'    Do a large stress logging ('size' rand om data added to the messages."
-        echo  ""
-
-#       echo  "For proper operation check your grid-proxy-info"
-#       grid-proxy-info
-}
-
-#input
-if [ -z "$1" ]; then
-  showHelp
-  exit 2
-fi
-BK=0
-while test -n "$1"
-do
-        case "$1" in
-        "-h" | "--help") showHelp && exit 2 ;;
-        "-n" | "--nbjobs") shift ; JOBS_ARRAY_SIZE=$1 ;;
-        "-s" | "--states") shift; STATES="$1" ;;
-        "-m" | "--bkserver") shift ; BKSERVER=$1 BK=1 ;;
-        "-t" | "--tags") shift ; NB_TAGS=$1 ;;
-        "-l" | "--large-stress") shift ; LARGE_STRESS="-l $1" ;;
-#       "-g" | "--log") shift ; logfile=$1 ;;
-
-        *) echo "Unrecognized option $1 try -h for help"; exit 2 ;;
-
-        esac
-        shift
-done
-if [ $BK -ne 1 ]; then
-        echo
-        echo "You must specify the hostname of the LB Server with the option -m (ex: -m pf435.ulb.ac.be)" 
-        echo
-        exit 2
-fi
-
-echo
-init
-array_job_reg
-testLBP
-echo
-if [ $dtest -eq 1  ];then
-        echo "Final test result .........................................[OK]"
-        exit 1
-else    echo "Final test result .........................................[FAILED]"
-        exit 0
- fi
-echo
-
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-run-tests.sh b/org.glite.testsuites.ctb/LB/tests/lb-run-tests.sh
deleted file mode 100755
index aa1bde3..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-run-tests.sh
+++ /dev/null
@@ -1,145 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-showHelp()
-{
-cat << EndHelpHeader
-This script logs to an indicated server, downloads the L&B test suite and executes it
-
-Prerequisities:
-   - LB server (hostname given as a cmdline argument)
-   - Valid proxy certificate (will be imported and used in testing)
-
-Tests called:
-
-	The full L&B Functional Test Suite
-
-EndHelpHeader
-
-	echo "Usage: $progname [OPTIONS] hostname"
-	echo "Options:"
-	echo " -h | --help            Show this help message."
-	echo " -P | --no-proxy        Do not copy existing user proxy."
-	echo " hostname               L&B server to use for testing."
-}
-
-# read common definitions and functions
-COMMON=lb-common.sh
-if [ ! -r ${COMMON} ]; then
-	printf "Common definitions '${COMMON}' missing!"
-	exit 2
-fi
-source ${COMMON}
-COMMONTESTBEDS=lb-common-testbeds.sh
-if [ ! -r ${COMMONTESTBEDS} ]; then
-	printf "Common definitions '${COMMONTESTBEDS}' missing!"
-	exit 2
-fi
-source ${COMMONTESTBEDS}
-
-COPYPROXY=1
-
-#logfile=$$.tmp
-#flag=0
-while test -n "$1"
-do
-	case "$1" in
-		"-h" | "--help") showHelp && exit 2 ;;
-		"-P" | "--no-proxy") COPYPROXY=0 ;;
-		*) remotehost=$1 
-			shift
-			outformat=$1
-			shift ;;
-	esac
-	shift
-done
-
-if [ -z $outformat ]; then
-	outformat='-c'
-fi 
-
-# check_binaries
-printf "\nTesting if all binaries are available"
-check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $SYS_SCP
-if [ $? -gt 0 ]; then
-	test_failed
-else
-	test_done
-fi
-
-printf "L&B server: '$remotehost'\n"
-if [ "$remotehost" = "" ]; then
-	printf "L&B server not specified, exittig...\n\n"
-	exit 1
-fi
-
-if [ $COPYPROXY -eq 1 ]; then
-	printf "Testing credentials... "
-	timeleft=`${GRIDPROXYINFO} | ${SYS_GREP} -E "^timeleft" | ${SYS_SED} "s/timeleft\s*:\s//" 2> /dev/null`
-
-	if [ "$timeleft" = "" ]; then
-	        printf "No credentials"
-		COPYPROXY=0
-        	test_skipped
-	else
-        	if [ "$timeleft" = "0:00:00" ]; then
-	                printf "Credentials expired"
-			COPYPROXY=0
-                	test_skipped
-        	else
-                	test_done
-
-			# Get path to the proxy cert
-			printf "Getting proxy cert path... "
-
-			PROXYCERT=`${GRIDPROXYINFO} | ${SYS_GREP} -E "^path" | ${SYS_SED} "s/path\s*:\s//"`
-
-		        if [ "$PROXYCERT" = "" ]; then
-                		printf "Unable to identify the path to your proxy certificate"
-				COPYPROXY=0
-        		        test_skipped
-		        else
-				printf "$PROXYCERT"
-        		        test_done
-
-				scp $PROXYCERT root@$remotehost:/tmp/
-			fi
-		fi
-	fi
-fi
-
-if [ "$PROXYCERT" = "" ]; then
-	PROXYCERT="none"
-fi
-
-printf "Generating the 'arrange' script... "
-gen_arrange_script $remotehost $COPYPROXY
-test_done
-
-TERMCOLS=`stty size | awk '{print $2}'`
-
-chmod +x arrange_lb_test_root.sh
-
-scp arrange_lb_test_root.sh root@$remotehost:/tmp/
-
-ssh -l root $remotehost "sh /tmp/arrange_lb_test_root.sh "$PROXYCERT" glite $TERMCOLS $outformat"
-
-		
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-acl-authz.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-acl-authz.sh
deleted file mode 100755
index 3150ae5..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-test-acl-authz.sh
+++ /dev/null
@@ -1,270 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners/ for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-showHelp()
-{
-cat << EndHelpHeader
-Script for testing correct interpretation of ChangeACL events
-
-Prerequisities:
-   - LB server, logger, interlogger
-   - environment variables set:
-
-     GLITE_WMS_QUERY_SERVER
-     X509_USER_PROXY_BOB
-     set TEST_TAG_ACL=yes if you want to test ACL with TAGs
-
-Tests called:
-
-    job registration
-    sending a ChangeACL-type event
-    chcking result
-
-Returned values:
-    Exit TEST_OK: Test Passed
-    Exit TEST_ERROR: Test Failed
-    Exit 2: Wrong Input
-
-EndHelpHeader
-
-	echo "Usage: $progname [OPTIONS]"
-	echo "Options:"
-	echo " -h | --help            Show this help message."
-	echo " -o | --output 'file'   Redirect all output to the 'file' (stdout by default)."
-	echo " -t | --text            Format output as plain ASCII text."
-	echo " -c | --color           Format output as text with ANSI colours (autodetected by default)."
-	echo " -x | --html            Format output as html."
-}
-
-
-check_credentials()
-{
-	my_GRIDPROXYINFO=${GRIDPROXYINFO}
-	if [ "$1" != "" ]; then
-		my_GRIDPROXYINFO="${GRIDPROXYINFO} -f $1"
-	fi
-
-	timeleft=`${my_GRIDPROXYINFO} | ${SYS_GREP} -E "^timeleft" | ${SYS_SED} "s/timeleft\s*:\s//"`
-
-	if [ "$timeleft" = "" ]; then
-        	print_error "No credentials"
-		return 1
-	fi
-        if [ "$timeleft" = "0:00:00" ]; then
-          	print_error "Credentials expired"
-		return 1
-	fi
-	return 0
-}
-
-
-# read common definitions and functions
-COMMON=lb-common.sh
-if [ ! -r ${COMMON} ]; then
-	printf "Common definitions '${COMMON}' missing!"
-	exit 2
-fi
-source ${COMMON}
-
-logfile=$$.tmp
-flag=0
-while test -n "$1"
-do
-	case "$1" in
-		"-h" | "--help") showHelp && exit 2 ;;
-		"-o" | "--output") shift ; logfile=$1 flag=1 ;;
-		"-t" | "--text")  setOutputASCII ;;
-		"-c" | "--color") setOutputColor ;;
-		"-x" | "--html")  setOutputHTML ;;
-	esac
-	shift
-done
-
-# redirecting all output to $logfile
-touch $logfile
-if [ ! -w $logfile ]; then
-	echo "Cannot write to output file $logfile"
-	exit $TEST_ERROR
-fi
-
-DEBUG=2
-
-##
-#  Starting the test
-#####################
-
-test_tag_acl=${TEST_TAG_ACL:-"no"}
-
-{
-test_start
-
-CONT="yes"
-while [ "$CONT" = "yes" ]; do
-	CONT="no"
-
-	# check_binaries
-	printf "Testing if all binaries are available"
-	check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $LBLOGEVENT $LBJOBREG
-	if [ $? -gt 0 ]; then
-		test_failed
-		break
-	fi
-	test_done
-
-	printf "Testing credentials"	
-	check_credentials_and_generate_proxy
-	if [ $? != 0 ]; then
-		test_end
-		exit 2
-	fi
-
-	printf "Testing snd proxy certificate"
-	if [ "$X509_USER_PROXY_BOB" = "" ]; then
-		test_failed
-		print_error "\$X509_USER_PROXY_BOB must be set"
-		break
-	fi
-	check_credentials $X509_USER_PROXY_BOB
-	if [ $? -ne 0 ]; then
-		test_failed
-		break
-	fi
-	test_done
-
-	printf "Testing Tags permissions "
-	if [ "$test_tag_acl" != "yes" ]; then
-        	test_skipped
-	else
-		test_done
-	fi
-
-	identity=`${GRIDPROXYINFO} -f $X509_USER_PROXY_BOB| ${SYS_GREP} -E "^identity" | ${SYS_SED} "s/identity\s*:\s//"`
-
-	# Register job:
-	printf "Registering testing job "
-	jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'`
-
-	if [ -z $jobid  ]; then
-		test_failed
-		print_error "Failed to register job"
-		break
-	fi
-	test_done
-
-	printf "Checking not-allowed access"
-#try unauthorized read
-	X509_USER_PROXY=$X509_USER_PROXY_BOB $LBJOBSTATUS $jobid 2>&1 >/dev/null| grep -E "edg_wll_JobStatus: Operation not permitted" > /dev/null
-	if [ "$?" != "0" ]; then
-		test_failed
-		print_error "Ungranted READ access allowed!"
-		break
-	fi
-
-#try unauthorized tagging
-	X509_USER_PROXY=$X509_USER_PROXY_BOB $LBLOGEVENT -e UserTag -s Application -j $jobid --name "hokus" --value "pokus" > /dev/null
-	if [ $? -ne 0 ]; then
-		test_failed
-		print_error "Sending UserTag failed"
-		break
-	fi
-#	sleep 10
-
-	res=`$LBJOBSTATUS $jobid 2>/dev/null`
-	if [ $? -ne 0 ]; then
-		test_failed
-		print_error "Server doesn't respond"
-		break
-	fi
-	echo $res | grep "hokus = \"pokus\"" > /dev/null
-	if [ $? -eq 0 ]; then
-		test_failed
-		print_error "Adding UserTag allowed"
-		break
-	fi
-	test_done
-
-	printf "Changing ACL setting "
-	perms="READ"
-	[ "$test_tag_acl" = "yes" ] && perms="$perms TAG"
-	res=0
-	for p in $perms; do
-		$LBLOGEVENT -e ChangeACL -s UserInterface -p -j $jobid --user_id "$identity" --user_id_type DN --permission $p --permission_type ALLOW --operation ADD > /dev/null
-		if [ $? -ne 0 ]; then
-			print_error "Adding $p permission to ACL failed"
-			res=1
-		fi
-	done
-	if [ $res -ne 0 ]; then
-		test_failed
-		break
-	fi
-	test_done
-
-	printf "Checking allowed access "
-#try querying status
-	X509_USER_PROXY=$X509_USER_PROXY_BOB $LBJOBSTATUS $jobid 2>/dev/null| grep "^state : Submitted" > /dev/null
-	if [ $? -ne 0 ]; then
-		test_failed
-		print_error "ACL permission doesn't work"
-		break
-	fi
-
-#try adding a usertag
-	if [ "$test_tag_acl" = "yes" ]; then
-		X509_USER_PROXY=$X509_USER_PROXY_BOB $LBLOGEVENT -e UserTag -s Application -j $jobid --name "hokus" --value "pokus" > /dev/null
-		if [ $? -ne 0 ]; then
-			test_failed
-			print_error "Sending UserTag failed"
-			break
-		fi
-
-	#	sleep 10
-
-		res=`$LBJOBSTATUS $jobid 2>/dev/null`
-		if [ $? -ne 0 ]; then
-			test_failed
-			print_error "Server doesn't respond"
-			break
-		fi
-		echo $res | grep "hokus = \"pokus\"" > /dev/null
-		if [ $? -ne 0 ]; then
-			test_failed
-			print_error "Adding UserTag not allowed"
-			break
-		fi
-	fi
-
-	test_done
-
-	#Purge test job
-	joblist=$$_jobs_to_purge.txt
-	echo $jobid > ${joblist}
-	try_purge ${joblist}
-done
-
-test_end
-} &> $logfile
-
-if [ $flag -ne 1 ]; then
- 	cat $logfile
- 	$SYS_RM $logfile
-fi
-exit $TEST_OK
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-bdii.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-bdii.sh
deleted file mode 100755
index a90b82a..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-test-bdii.sh
+++ /dev/null
@@ -1,221 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-showHelp()
-{
-cat << EndHelpHeader
-Script for testing correct reporting of LB server properties over BDII/LDAP.
-This should also be thought of as a regression test for ggus ticket #62737.
-
-Prerequisities:
-   - LB server
-   - environment variables set:
-
-     GLITE_WMS_QUERY_SERVER 
-
-Tests called:
-
-    ldap query to the server, checking the output
-
-Returned values:
-    Exit TEST_OK: Test Passed
-    Exit TEST_ERROR: Test Failed
-    Exit 2: Wrong Input
-
-EndHelpHeader
-
-	echo "Usage: $progname [OPTIONS]"
-	echo "Options:"
-	echo " -h | --help            Show this help message."
-	echo " -o | --output 'file'   Redirect all output to the 'file' (stdout by default)."
-	echo " -t | --text            Format output as plain ASCII text."
-	echo " -c | --color           Format output as text with ANSI colours (autodetected by default)."
-	echo " -x | --html            Format output as html."
-}
-
-# read common definitions and functions
-COMMON=lb-common.sh
-if [ ! -r ${COMMON} ]; then
-	printf "Common definitions '${COMMON}' missing!"
-	exit 2
-fi
-source ${COMMON}
-
-logfile=$$.tmp
-flag=0
-while test -n "$1"
-do
-	case "$1" in
-		"-h" | "--help") showHelp && exit 2 ;;
-		"-o" | "--output") shift ; logfile=$1 flag=1 ;;
-		"-t" | "--text")  setOutputASCII ;;
-		"-c" | "--color") setOutputColor ;;
-		"-x" | "--html")  setOutputHTML ;;
-	esac
-	shift
-done
-
-# redirecting all output to $logfile
-touch $logfile
-if [ ! -w $logfile ]; then
-	echo "Cannot write to output file $logfile"
-	exit $TEST_ERROR
-fi
-
-DEBUG=2
-
-##
-#  Starting the test
-#####################
-
-{
-test_start
-
-
-# check_binaries
-printf "Testing if all essential binaries are available"
-check_binaries $SYS_GREP $SYS_SED $SYS_AWK $SYS_LDAPSEARCH
-if [ $? -gt 0 ]; then
-	test_failed
-else
-	test_done
-fi
-
-printf "Testing optional WS client binary"
-check_binaries $LBWSGETVERSION
-if [ $? -gt 0 ]; then
-	printf " ... not present. Some tests will be skipped\n"
-	WSBIN="no"
-else
-	test_done
-
-	printf "Testing credentials"
-	check_credentials
-	if [ $? -gt 0 ]; then
-		WSBIN="no"
-	else
-		WSBIN="yes"
-	fi
-
-fi
-
-# Register job:
-
-server=`${SYS_ECHO} ${GLITE_WMS_QUERY_SERVER} | ${SYS_SED} 's/:.*$//'`
-
-printf "Checking if BDII operational... "
-$SYS_LDAPSEARCH -x -H ldap://${server}:2170 -b 'o=infosys' > ldap.$$.out
-if [ $? -gt 0 ]; then	
-	test_failed
-	print_error "No reply"
-else
-	test_done
-fi
-
-printf "Checking Glue 1 root entry... "
-$SYS_LDAPSEARCH -x -H ldap://${server}:2170 -b 'o=grid' 'GlueServiceType=org.glite.lb.Server' > ldap.$$.out
-if [ $? -gt 0 ]; then	
-	test_failed
-	print_error "No reply"
-else
-	test_done
-fi
-
-printf "Checking ServiceStatus (Regression into bug #76174)... "
-health=`$SYS_GREP GlueServiceStatus: ldap.$$.out | $SYS_SED 's/^[^:]*: *//'`
-if [ "$health" = "" ]; then
-	print_error "GlueServiceStatus not specified"
-	test_failed
-else
-	printf "$health"
-	if [ "$health" = "OK" ]; then
-		test_done
-	else
-		test_failed
-	fi
-fi
-
-printf "Checking Glue 2.0 entry with 'o=glue'... "
-$SYS_LDAPSEARCH -x -H ldap://${server}:2170 -b 'o=glue' -S GLUE2EntityCreationTime 'GLUE2EndpointInterfaceName=org.glite.lb.Server' > ldap.$$.out
-if [ $? -gt 0 ]; then	
-	test_failed
-	print_error "No reply"
-else
-	test_done
-fi
-
-printf "Checking GLUE2 HealthStatus (Regression into bug #76173)... "
-health=`$SYS_GREP GLUE2EndpointHealthState: ldap.$$.out | $SYS_TAIL -n 1 | $SYS_SED 's/^[^:]*: *//'`
-if [ "$health" = "" ]; then
-	print_error "GLUE2EndpointHealthState not specified"
-	test_failed
-else
-	printf "$health"
-	if [ "$health" = "ok" ]; then
-		test_done
-	else
-		test_failed
-	fi
-fi
-
-printf "Checking GlueServiceVersion (Regression into bug #55482)... "
-glservver=`$SYS_GREP GLUE2EndpointImplementationVersion ldap.$$.out | $SYS_TAIL -n 1 | $SYS_SED 's/^.*GLUE2EndpointImplementationVersion:\s*//'`
-if [ "$glservver" = "" ]; then	
-	print_error "GLUE2EndpointImplementationVersion not specified"
-	test_failed
-else
-	printf "$glservver"
-	test_done
-
-	printf "Reading version through WS... "
-	if [ "$WSBIN" = "yes" ]; then
-		servername=`echo ${GLITE_WMS_QUERY_SERVER} | ${SYS_SED} "s/:.*//"`
-		wsglservver=`$LBWSGETVERSION -m ${servername}:${GLITE_LB_SERVER_WPORT} | $SYS_SED 's/^.*Server version:\s*//'`
-		if [ "$wsglservver" = "" ]; then	
-			test_failed
-		else
-			printf "$wsglservver"
-			test_done
-
-			printf "Comparing versions: '$glservver' = '$wsglservver'"
-			if [ "$glservver" = "$wsglservver" ]; then
-				test_done
-			else
-				test_failed
-			fi
-		fi
-	else
-		test_skipped
-	fi
-fi
-
-rm ldap.$$.out
-
-		
-
-test_end
-} &> $logfile
-
-if [ $flag -ne 1 ]; then
- 	cat $logfile
- 	$SYS_RM $logfile
-fi
-exit $TEST_OK
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-binaries.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-binaries.sh
deleted file mode 100755
index 96aad3a..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-test-binaries.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/bash
-# $Header$
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# read common definitions and functions
-COMMON=lb-common.sh
-if [ ! -r ${COMMON} ]; then
-	printf "Common definitions '${COMMON}' missing!"
-	exit 2
-fi
-source ${COMMON}
-
-##
-#  Starting the test
-#####################
-
-test_start
-
-# check_binaries
-printf "Testing if all binaries are available"
-check_binaries
-if [ $? -gt 0 ]; then
-	test_failed
-	print_error "Some binaries are missing"
-	exit $TEST_ERR
-else
-	test_done
-fi
-
-test_end
-
-exit $TEST_OK
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-changeacl.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-changeacl.sh
deleted file mode 100755
index 37ebbc0..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-test-changeacl.sh
+++ /dev/null
@@ -1,255 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners/ for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-showHelp()
-{
-cat << EndHelpHeader
-Script for testing correct interpretation of ChangeACL events
-
-Prerequisities:
-   - LB server, logger, interlogger
-   - environment variables set:
-
-     GLITE_WMS_QUERY_SERVER
-     set TEST_TAG_ACL=yes if the you want to test ACL with TAGs
-
-
-Tests called:
-
-    job registration
-    sending a ChangeACL-type event
-    chcking result
-
-Returned values:
-    Exit TEST_OK: Test Passed
-    Exit TEST_ERROR: Test Failed
-    Exit 2: Wrong Input
-
-EndHelpHeader
-
-	echo "Usage: $progname [OPTIONS]"
-	echo "Options:"
-	echo " -h | --help            Show this help message."
-	echo " -o | --output 'file'   Redirect all output to the 'file' (stdout by default)."
-	echo " -t | --text            Format output as plain ASCII text."
-	echo " -c | --color           Format output as text with ANSI colours (autodetected by default)."
-	echo " -x | --html            Format output as html."
-}
-
-# read common definitions and functions
-COMMON=lb-common.sh
-if [ ! -r ${COMMON} ]; then
-	printf "Common definitions '${COMMON}' missing!"
-	exit 2
-fi
-source ${COMMON}
-
-logfile=$$.tmp
-flag=0
-while test -n "$1"
-do
-	case "$1" in
-		"-h" | "--help") showHelp && exit 2 ;;
-		"-o" | "--output") shift ; logfile=$1 flag=1 ;;
-		"-t" | "--text")  setOutputASCII ;;
-		"-c" | "--color") setOutputColor ;;
-		"-x" | "--html")  setOutputHTML ;;
-	esac
-	shift
-done
-
-# redirecting all output to $logfile
-touch $logfile
-if [ ! -w $logfile ]; then
-	echo "Cannot write to output file $logfile"
-	exit $TEST_ERROR
-fi
-
-DEBUG=2
-
-change_acl()
-{
-	jobid=$1; op=$2; perm=$3; id=$4
-
-	$LBLOGEVENT -e ChangeACL -s UserInterface -p -j "$jobid" --user_id "$id" --user_id_type DN --permission "$perm" --permission_type ALLOW --operation "$op" > /dev/null
-	res=$?
-	if [ $res -ne 0 ]; then
-		print_error "Changing ACL ($op $perm) failed"
-	fi
-	return $res
-}
-
-##
-#  Starting the test
-#####################
-
-identity="ThisIsJustATestingIdentity"
-identwity="ThisIsanotherTestingIdentity"
-
-{
-test_start
-
-CONT="yes"
-while [ "$CONT" = "yes" ]; do
-	CONT="no"
-
-	# check_binaries
-	printf "Testing if all binaries are available"
-	check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $LBLOGEVENT $LBJOBREG
-	if [ $? -gt 0 ]; then
-		test_failed
-		break
-	fi
-	test_done
-
-	printf "Testing credentials"
-	timeleft=`${GRIDPROXYINFO} | ${SYS_GREP} -E "^timeleft" | ${SYS_SED} "s/timeleft\s*:\s//"`
-	if [ "$timeleft" = "" ]; then
-        	test_failed
-        	print_error "No credentials"
-		break
-	fi
-
-        if [ "$timeleft" = "0:00:00" ]; then
-                test_failed
-                print_error "Credentials expired"
-		break
-	fi
-	test_done
-
-        check_srv_version '>=' "2.2"
-        if [ $? -gt 0 ]; then
-		test_tag_acl="no"
-		test_done
-        else
-		test_tag_acl="yes"
-		test_done
-        fi
-
-        check_srv_version '>=' "2.3"
-        if [ $? -gt 0 ]; then
-		identities="$identity"
-		test_done
-        else
-		test_tag_acl="yes"
-		printf "Multiple identities will be tested: Regression into Savannah Bug #92766..."
-		identities="$identity $identwity"
-		test_done
-        fi
-
-
-	printf "Testing Tags permissions... "
-	if [ "$test_tag_acl" != "yes" ]; then
-		printf "Capability not detected..."
-        	test_skipped
-	else
-		test_done
-	fi
-
-	# Register job:
-	printf "Registering testing job "
-	jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'`
-	if [ -z $jobid  ]; then
-		test_failed
-		print_error "Failed to register job"
-		break
-	fi
-	printf " $jobid"
-	test_done
-
-	printf "Changing ACL..."
-	for i in $identities; do
-		change_acl "$jobid" "ADD" "READ" $i
-		if [ $? -ne 0 ]; then
-			test_failed
-			break;
-		fi
-
-		if [ "$test_tag_acl" = "yes" ]; then
-			change_acl "$jobid" "ADD" "TAG" $i
-			if [ $? -ne 0 ]; then
-				test_failed
-				break
-			fi
-		fi
-	done
-	test_done
-
-	printf "Checking ACL for new values... "
-	ops="read"
-	[ "$test_tag_acl" = "yes" ] && ops="$ops write"
-	res=0
-	for operation in $ops; do
-		for i in $identities; do
-			$LBJOBSTATUS $jobid | grep -E "^acl :.*dn:${i}<${operation}/>" > /dev/null
-			if [ $? -ne 0 ]; then
-				res=1
-			fi
-		done
-	done
-	if [ $res -ne 0 ]; then
-		test_failed
-		print_error "ACL not modified properly"
-		break;
-	fi
-	test_done
-
-
-	printf "Removing ACL entries..."
-	perms="READ"
-	[ "$test_tag_acl" = "yes" ] && perms="$perms TAG"
-	res=0
-	for p in $perms; do
-		for i in $identities; do
-			change_acl "${jobid}" "REMOVE" $p $i
-			if [ $? -ne 0 ]; then
-				res=1
-			fi
-		done
-	done
-	if [ $res -ne 0 ]; then
-		test_failed
-		break;
-	fi
-
-	$LBJOBSTATUS $jobid | grep -E "^acl :$" > /dev/null
-	if [ $res -ne 0 ]; then
-		test_failed
-		print_error "Entries not removed properly"
-	fi
-	test_done
-
-		
-	#Purge test job
-	joblist=$$_jobs_to_purge.txt
-	echo $jobid > ${joblist}
-	try_purge ${joblist}
-
-done
-
-test_end
-} &> $logfile
-
-if [ $flag -ne 1 ]; then
- 	cat $logfile
- 	$SYS_RM $logfile
-fi
-exit $TEST_OK
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-collections.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-collections.sh
deleted file mode 100755
index aa295ac..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-test-collections.sh
+++ /dev/null
@@ -1,153 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-showHelp()
-{
-cat << EndHelpHeader
-Script for testing collection-specific features
-
-Prerequisities:
-   - LB local logger, interlogger, and server running
-   - environment variables set:
-
-     GLITE_LB_SERVER_PORT - if nondefault port (9000) is used
-     GLITE_LB_LOGGER_PORT - if nondefault port (9002) is used   
-     GLITE_WMS_QUERY_SERVER
-
-Tests called:
-
-    collection registration
-    status queries
-
-Returned values:
-    Exit TEST_OK: Test Passed
-    Exit TEST_ERROR: Test Failed
-    Exit 2: Wrong Input
-
-EndHelpHeader
-
-	echo "Usage: $progname [OPTIONS]"
-	echo "Options:"
-	echo " -h | --help            Show this help message."
-	echo " -o | --output 'file'   Redirect all output to the 'file' (stdout by default)."
-	echo " -t | --text            Format output as plain ASCII text."
-	echo " -c | --color           Format output as text with ANSI colours (autodetected by default)."
-	echo " -x | --html            Format output as html."
-}
-
-# read common definitions and functions
-COMMON=lb-common.sh
-if [ ! -r ${COMMON} ]; then
-	printf "Common definitions '${COMMON}' missing!"
-	exit 2
-fi
-source ${COMMON}
-
-logfile=$$.tmp
-flag=0
-while test -n "$1"
-do
-	case "$1" in
-		"-h" | "--help") showHelp && exit 2 ;;
-		"-o" | "--output") shift ; logfile=$1 flag=1 ;;
-		"-t" | "--text")  setOutputASCII ;;
-		"-c" | "--color") setOutputColor ;;
-		"-x" | "--html")  setOutputHTML ;;
-	esac
-	shift
-done
-
-# redirecting all output to $logfile
-touch $logfile
-if [ ! -w $logfile ]; then
-	echo "Cannot write to output file $logfile"
-	exit $TEST_ERROR
-fi
-
-DEBUG=2
-
-##
-#  Starting the test
-#####################
-
-{
-test_start
-
-
-# check_binaries
-printf "Testing if all binaries are available"
-check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $LBJOBREG $LBQUERYEXT
-if [ $? -gt 0 ]; then
-	test_failed
-else
-	test_done
-fi
-
-printf "Testing credentials"
-check_credentials_and_generate_proxy
-if [ $? != 0 ]; then
-	test_end
-	exit 2
-fi
-
-		# Register job:
-		printf "Registering testing collection "
-		jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application -C -n 5 | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'`
-
-		if [ -z $jobid  ]; then test_failed
-			print_error "Failed to register job"
-		else
-			printf "($jobid)"
-			test_done
-
-			printf "Request children with only the parent ID (Regression into bug #47774)... "
-			echo parent_job=$jobid > query.$$.ext
-
-			$LBQUERYEXT -i query.$$.ext > query.$$.res 2> query.$$.err
-
-			CHILDREN=`wc -l query.$$.res | $SYS_AWK ' { print $1 }'`
-
-			if [ $CHILDREN -eq 5 ]; then
-				printf "$CHILDREN returned"
-				test_done
-			else
-				$SYS_GREP -i "No indexed condition" query.$$.err
-				if [ $? -eq 0 ]; then
-					test_failed
-					print_error "built-in index on parent job not used, query refused."
-				else
-					test_failed
-					print_error "built-in index on parent job not used, query refused, error message NULL!"
-				fi
-			fi
-
-			$SYS_RM query.$$.ext query.$$.res query.$$.err
-
-			#Purge test job
-			joblist=$$_jobs_to_purge.txt
-			echo $jobid > ${joblist}
-			try_purge ${joblist}
-			$SYS_RM ${joblist}
-		fi
-
-test_end
-}
-exit $TEST_OK
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-cream.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-cream.sh
deleted file mode 100755
index fa57b93..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-test-cream.sh
+++ /dev/null
@@ -1,374 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-showHelp()
-{
-cat << EndHelpHeader
-Script for testing if jobs pass through correct states through their lifetimes
-
-Prerequisities:
-   - LB local logger, interlogger, and server running
-   - environment variables set:
-
-     GLITE_LB_SERVER_PORT - if nondefault port (9000) is used
-     GLITE_LB_LOGGER_PORT - if nondefault port (9002) is used 	
-     GLITE_WMS_QUERY_SERVER
-     GLITE_WMS_LOG_DESTINATION
-
-Tests called:
-
-    job registration
-    event logging
-
-Returned values:
-    Exit TEST_OK: Test Passed
-    Exit TEST_ERROR: Test Failed
-    Exit 2: Wrong Input
-
-EndHelpHeader
-
-	echo "Usage: $progname [OPTIONS] [event file prefix]"
-	echo "Options:"
-	echo " -h | --help            Show this help message."
-	echo " -o | --output 'file'   Redirect all output to the 'file' (stdout by default)."
-	echo " -t | --text            Format output as plain ASCII text."
-	echo " -c | --color           Format output as text with ANSI colours (autodetected by default)."
-	echo " -x | --html            Format output as html."
-	echo ""
-}
-
-test_state () {
-
-        wmsstate=`${LBJOBSTATUS} $1 | ${SYS_GREP} -w "state :" | ${SYS_AWK} '{ print $3 }'`
-	creamstate=`${LBJOBSTATUS} $1 | ${SYS_GREP} -w "cream_state :" | ${SYS_AWK} '{ print $3 }'`
-        #printf "Testing job ($1) is in state: $wmsstate (should be $2) and $creamstate (should be $3)"
-        printf "Testing job is in state: $wmsstate $creamstate (should be $2 $3)"
-
-        if [ "${wmsstate}" = "$2" -a "${creamstate}" = "$3" ]; then
-                test_done
-        else
-                test_failed
-                print_error "Job is not in appropriate state"
-        fi
-
-}
-
-check_return_and_test_state ()
-{
-# 1: previous return value
-# 2: jobid
-# 3: expected wms state
-# 4: expected cream state
-#	printf "Sleeping for 10 seconds (waiting for events to deliver)...\n"
-	if [ $1 = 0 ]; then
-		test_done
-	else
-		test_failed
-	fi
-
-        sleep 2
-
-	test_state $2 $3 $4
-}
-
-
-# read common definitions and functions
-COMMON=lb-common.sh
-if [ ! -r ${COMMON} ]; then
-	printf "Common definitions '${COMMON}' missing!"
-	exit 2
-fi
-source ${COMMON}
-
-logfile=$$.tmp
-flag=0
-while test -n "$1"
-do
-	case "$1" in
-		"-h" | "--help") showHelp && exit 2 ;;
-		"-o" | "--output") shift ; logfile=$1 flag=1 ;;
-		"-t" | "--text")  setOutputASCII ;;
-		"-c" | "--color") setOutputColor ;;
-		"-x" | "--html")  setOutputHTML ;;
-		*) EVENTFILE=$1 ;;
-	esac
-	shift
-done
-
-# redirecting all output to $logfile
-#touch $logfile
-#if [ ! -w $logfile ]; then
-#	echo "Cannot write to output file $logfile"
-#	exit $TEST_ERROR
-#fi
-
-DEBUG=2
-
-##
-#  Starting the test
-#####################
-
-{
-test_start
-
-CONT="yes"
-while [ "$CONT" = "yes" ]; do
-	CONT="no"
-	
-	# check_binaries
-	printf "Testing if all binaries are available"
-	check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $LBJOBREG $SYS_AWK $LBJOBSTATUS
-	if [ $? -gt 0 ]; then
-		test_failed
-		print_error "Some binaries are missing"
-		break
-	else
-		test_done
-	fi
-	
-	# check credentials
-	printf "Testing credentials"
-	check_credentials_and_generate_proxy
-	if [ $? != 0 ]; then
-		break
-	fi
-
-	printf "Testing job sumbitted directly to CREAM-CE\n"
-	
-	# Register job:
-	printf "Registering testing job "
-	local_jobid="CREAM-test-"`date +%s`
-	jobid="https://"$GLITE_WMS_QUERY_SERVER/"$local_jobid"
-	${LBJOBREG} -j $jobid -m ${GLITE_WMS_QUERY_SERVER} -s CREAMExecutor -c > /dev/null
-	if [ $? != 0 ]; then
-		test_failed
-		print_error "Failed to register job"
-		break
-	else
-		test_done
-	fi
-
-	printf "Jobid: ($jobid)\n"
-
-	test_state $jobid Submitted Registered
-
-	EDG_WL_SEQUENCE="UI=000003:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000"	
-
-	printf "logging Accepted"
-	EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMAccepted --from="CREAMExecutor" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid=$local_jobid`
-	check_return_and_test_state $? $jobid Submitted Registered
-
-	printf "logging CREAMStatus Pending"
-	EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Registered --new_state=Pending --result=Arrived`
-	EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Registered --new_state=Pending --result=Done`
-	check_return_and_test_state $? $jobid Waiting Pending
-
-	printf "logging CREAMStatus Idle"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Pending --new_state=Idle --result=Arrived`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Pending --new_state=Idle --result=Done`
-        check_return_and_test_state $? $jobid Scheduled Idle
-
-	printf "logging CREAMStatus Running"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Idle --new_state=Running --result=Arrived`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Idle --new_state=Running --result=Done`
-        check_return_and_test_state $? $jobid Running Running
-
-	printf "logging CREAMStatus Really-running"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Running --new_state=Really-running --result=Arrived`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Running --new_state=Really-running --result=Done`
-        check_return_and_test_state $? $jobid Running Really-running
-
-	printf "logging CREAMStatus Done-ok"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Really-running --new_state=Done-ok --result=Arrived`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Really-running --new_state=Done-ok --result=Done`
-        check_return_and_test_state $? $jobid Done Done-ok
-
-	#Purge test job
-        joblist=$$_jobs_to_purge.txt
-        echo $jobid > ${joblist}
-        try_purge ${joblist}
-
-	printf "\nTesting job submitted to CREAM-CE via WMS\n"
-
-	jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application`
-        if [ $? != 0 ]; then
-                test_failed
-                print_error "Failed to register job"
-                break
-        else
-                test_done
-        fi
-
-	#parse job id
-        jobid=`echo "${jobid}" | ${SYS_GREP} "new jobid" | ${SYS_AWK} '{ print $3 }'`
-        if [ -z $jobid  ]; then
-                print_error "Failed to parse job "
-                break
-        else
-                printf "($jobid)\n"
-        fi
-
-        test_state $jobid Submitted
-
-	EDG_WL_SEQUENCE="UI=000003:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000"
-
-	printf "logging Accepted"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s NetworkServer -e Accepted --from="UserInterface" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid="new jobId (Condor Globus ...)"`
-#        check_return_and_test_state $? $jobid Waiting 
-
-	printf "\nlogging DeQueued"
-	EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e DeQueued --queue="queue name" --local_jobid="new jobId assigned by the receiving component"`
-#	check_return_and_test_state $? $jobid Waiting
-
-	printf "\nlogging HelperCall"
-	EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e HelperCall --helper_name="name of the called component" --helper_params="parameters of the call" --src_role=CALLING`
-#	check_return_and_test_state $? $jobid Waiting
-#
-	printf "\nlogging Match"
-	EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e Match --dest_id="${DESTINATION:-destination CE/queue}"`
-#	check_return_and_test_state $? $jobid Waiting
-#
-	printf "\nlogging HelperReturn"
-	EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e HelperReturn --helper_name="name of the called component" --retval="returned data" --src_role=CALLING`
-	check_return_and_test_state $? $jobid Waiting
-
-	printf "logging CREAMAccepted"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMAccepted --from="CREAMExecutor" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid="CREAM_FAKE_JOBID"`
-        check_return_and_test_state $? $jobid Waiting
-
-	printf "logging CREAMStore CmdStart"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMInterface -e CREAMStore --command=CmdStart --result=Start`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMInterface -e CREAMStore --command=CmdStart --result=Ok`
-        check_return_and_test_state $? $jobid Waiting Pending
-
-        printf "logging CREAMStatus Pending"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Registered --new_state=Pending --result=Arrived`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Registered --new_state=Pending --result=Done`
-        check_return_and_test_state $? $jobid Waiting Pending
-
-	printf "logging EnQueued"
-	EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e EnQueued --queue="destination queue" --job="job description in receiver language" --result=OK --reason="detailed description of transfer"`
-#	check_return_and_test_state $? $jobid Ready Pending
-
-	printf "\nlogging DeQueued"
-	EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s JobController -e DeQueued --queue="queue name" --local_jobid="new jobId assigned by the receiving component"`
-#	check_return_and_test_state $? $jobid Ready Pending
-
-#	printf "logging CREAMAccepted"
-#        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMAccepted --from="CREAMExecutor" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid="CREAM_FAKE_JOBID"`
-#       check_return_and_test_state $? $jobid Ready Registered
-
-	printf "\nlogging Transfer"
-	EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s JobController -e Transfer --destination="LRMS" --dest_host="destination hostname" --dest_instance="destination instance" --job="job description in receiver language" --result=OK --reason="detailed description of transfer" --dest_jobid="destination internal jobid"`
-	check_return_and_test_state $? $jobid Ready Pending
-
-#	printf "logging CREAMStore CmdStart"
-#        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMInterface -e CREAMStore --command=CmdStart --result=Start`
-#        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMInterface -e CREAMStore --command=CmdStart --result=Ok`
-#        check_return_and_test_state $? $jobid Ready Pending	
-
-#	printf "logging CREAMStatus Pending"
-#        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Registered --new_state=Pending --result=Arrived`
-#        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Registered --new_state=Pending --result=Done`
-#        check_return_and_test_state $? $jobid Ready Pending
-
-        printf "logging CREAMStatus Idle"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Pending --new_state=Idle --result=Arrived`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Pending --new_state=Idle --result=Done`
-        check_return_and_test_state $? $jobid Scheduled Idle
-
-        printf "logging CREAMStatus Running"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Idle --new_state=Running --result=Arrived`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Idle --new_state=Running --result=Done`
-        check_return_and_test_state $? $jobid Running Running
-
-	printf "logging CREAMStore CmdSuspend (bug #45971)"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMInterface -e CREAMStore --command=CmdSuspend --result=Start`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMInterface -e CREAMStore --command=CmdSuspend --result=Ok`
-        check_return_and_test_state $? $jobid Running Running
-
-	printf "testing if job is suspended (bug #45971)"
-	susp=`${LBJOBSTATUS} $jobid | ${SYS_GREP} "suspended :" | ${SYS_AWK} '{ print $3 }'`
-	if [ $susp = "1" ]; then
-		test_done
-	else
-		test_failed
-	fi
-
-	printf "logging CREAMStatus Idle (bug #45971)"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Running --new_state=Idle --result=Arrived`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Running --new_state=Idle --result=Done`
-        check_return_and_test_state $? $jobid Scheduled Idle
-
-	printf "testing if job is suspended (bug #45971)"
-        susp=`${LBJOBSTATUS} $jobid | ${SYS_GREP} "suspended :" | ${SYS_AWK} '{ print $3 }'`
-        if [ $susp = "0" ]; then
-               test_done
-        else
-               test_failed
-        fi
-
-	printf "logging CREAMStatus Running (bug #45971)"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Idle --new_state=Running --result=Arrived`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Idle --new_state=Running --result=Done`
-        check_return_and_test_state $? $jobid Running Running
-
-	printf "testing if job is suspended (bug #45971)"
-        susp=`${LBJOBSTATUS} $jobid | ${SYS_GREP} "suspended :" | ${SYS_AWK} '{ print $3 }'`
-        if [ $susp = "0" ]; then
-                test_done
-        else
-                test_failed
-        fi
-
-	printf "logging CREAMStatus Really-running"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Running --new_state=Really-running --result=Arrived`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Running --new_state=Really-running --result=Done`
-        check_return_and_test_state $? $jobid Running Really-running
-
-	printf "logging CREAMStatus Done-ok"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Really-running --new_state=Done-ok --result=Arrived`
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s CREAMExecutor -e CREAMStatus --old_state=Really-running --new_state=Done-ok --result=Done`
-        check_return_and_test_state $? $jobid Done Done-ok
-
-	printf "logging Done"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Done --status_code=OK --reason="reason for the change" --exit_code=0`
-        check_return_and_test_state $? $jobid Done Done-ok
-
-	printf "logging Clear"
-        EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Clear --reason=USER`
-        check_return_and_test_state $? $jobid Cleared Done-ok	
-
-	#Purge test job
-	joblist=$$_jobs_to_purge.txt
-	echo $jobid > ${joblist}
-	try_purge ${joblist}
-done
-
-test_end
-}
-#} &> $logfile
-
-#if [ $flag -ne 1 ]; then
-# 	cat $logfile
-# 	$SYS_RM $logfile
-#fi
-exit $TEST_OK
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-event-delivery.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-event-delivery.sh
deleted file mode 100755
index cf3cd0e..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-test-event-delivery.sh
+++ /dev/null
@@ -1,345 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-showHelp()
-{
-cat << EndHelpHeader
-Script for testing correct event delivery
-
-Prerequisities:
-   - LB delivery chain - logger, interlogger, server
-   - environment variables set:
-
-     GLITE_LB_SERVER_PORT - if nondefault port (9000) is used
-     GLITE_LB_IL_SOCK - if nondefault socket at /tmp/interlogger.sock is used
-     GLITE_LB_LOGGER_PORT - if nondefault port (9002) is used 	
-
-Tests called:
-
-    job registration
-    event logging
-    checking events 
-
-Returned values:
-    Exit TEST_OK: Test Passed
-    Exit TEST_ERROR: Test Failed
-    Exit 2: Wrong Input
-
-EndHelpHeader
-
-	echo "Usage: $progname [OPTIONS]"
-	echo "Options:"
-	echo " -h | --help            Show this help message."
-	echo " -o | --output 'file'   Redirect all output to the 'file' (stdout by default)."
-	echo " -t | --text            Format output as plain ASCII text."
-	echo " -c | --color           Format output as text with ANSI colours (autodetected by default)."
-	echo " -x | --html            Format output as html."
-}
-
-# read common definitions and functions
-COMMON=lb-common.sh
-if [ ! -r ${COMMON} ]; then
-	printf "Common definitions '${COMMON}' missing!"
-	exit 2
-fi
-source ${COMMON}
-
-logfile=$$.tmp
-flag=0
-while test -n "$1"
-do
-	case "$1" in
-		"-h" | "--help") showHelp && exit 2 ;;
-		"-o" | "--output") shift ; logfile=$1 flag=1 ;;
-		"-t" | "--text")  setOutputASCII ;;
-		"-c" | "--color") setOutputColor ;;
-		"-x" | "--html")  setOutputHTML ;;
-	esac
-	shift
-done
-
-# redirecting all output to $logfile
-#touch $logfile
-#if [ ! -w $logfile ]; then
-#	echo "Cannot write to output file $logfile"
-#	exit $TEST_ERROR
-#fi
-
-DEBUG=2
-
-##
-#  Starting the test
-#####################
-
-{
-test_start
-
-CONT="yes"
-while [ "$CONT" = "yes" ]; do
-	CONT="no"
-
-	# check_binaries
-	printf "Testing if all binaries are available"
-	check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $LBJOBREG $SYS_AWK $LB_READY_SH $LB_RUNNING_SH $LB_DONE_SH $SYS_AWK $LBJOBLOG
-	if [ $? -gt 0 ]; then
-		test_failed
-	else
-		test_done
-	fi
-
-	printf "Testing credentials"
-	check_credentials_and_generate_proxy
-	if [ $? != 0 ]; then
-		test_end
-		break
-	fi
-
-	# Register job:
-	printf "Registering testing job "
-	jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application`
-	if [ $? != 0 ]; then
-		test_failed
-		print_error "Failed to register job"
-		break
-	else
-		test_done
-	fi
-	jobid=`echo "${jobid}" | ${SYS_GREP} "new jobid" | ${SYS_AWK} '{ print $3 }'`
-	if [ -z $jobid  ]; then
-		print_error "Failed to parse job "
-		test_end
-		exit 4
-	else
-		printf "($jobid)"
-	fi
-	
-	# log events:
-	printf "Logging events resulting in READY state... "
-	$LB_READY_SH -j ${jobid} > /dev/null 2> /dev/null
-
-	printf "Sleeping for 10 seconds...\n"
-
-	sleep 10
-
-	jobstate=`${LBJOBSTATUS} ${jobid} | ${SYS_GREP} "state :" | ${SYS_AWK} '{print $3}'`
-	printf "Is the testing job ($jobid) in a correct state? $jobstate"
-
-	if [ "${jobstate}" = "Ready" ]; then
-		test_done
-	else
-		test_failed
-		print_error "Job is not in appropriate state"
-	fi
-
-#	printf "Logging events resulting in RUNNING state\n"
-#	$LB_RUNNING_SH -j ${jobid} > /dev/null 2> /dev/null
-
-	printf "Logging events resulting in DONE state... "
-	$LB_DONE_SH -j ${jobid} > /dev/null 2> /dev/null
-
-	printf "Sleeping for 10 seconds...\n"
-
-	sleep 10
-
-	jobstate=`${LBJOBSTATUS} ${jobid} | ${SYS_GREP} "state :" | ${SYS_AWK} '{print $3}'`
-	printf "Testing job ($jobid) is in state: $jobstate"
-
-	if [ "${jobstate}" = "Done" ]; then
-		test_done
-	else
-		test_failed
-		print_error "Job is not in appropriate state"
-	fi
-
-	#Purge test job
-	joblist=$$_jobs_to_purge.txt
-	echo $jobid > ${joblist}
-
-        printf "Registering collection "
-        ${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application -C -n 2 -S > $$_test_coll_registration.txt
-	jobid=`$SYS_CAT $$_test_coll_registration.txt | ${SYS_GREP} "new jobid" | ${SYS_AWK} '{ print $3 }'`
-	if [ -z $jobid  ]; then
-		test_failed
-		print_error "Failed to register job"
-	else
-		test_done
-		subjobs=( $(cat $$_test_coll_registration.txt | $SYS_GREP EDG_WL_SUB_JOBID | $SYS_SED 's/EDG_WL_SUB_JOBID.*="//' | $SYS_SED 's/"$//') )
-		printf "Collection ID: $jobid\n     Subjob 1: ${subjobs[0]}\n     Subjob 2: ${subjobs[1]}\nChecking if subjob registration worked... "
-	
-		${LBJOBLOG} ${subjobs[0]} | $SYS_GREP 'DG.EVNT="RegJob"' >> /dev/null
-		if [ $? = 0 ]; then
-			printf "Registration event recorded"
-			test_done
-		else
-			test_failed
-			print_error "Subjob registration did not work (Registration event not recorded)"
-		fi
-	
-
-		job1jdl=`${LBJOBSTATUS} ${subjobs[1]} | ${SYS_GREP} -E "^jdl :" | ${SYS_AWK} '{print $3}'`
-		if [ "${job1jdl}" = "(null)" ]; then
-			test_failed
-			print_error "Subjob registration did not work (JDL not present: "${job1jdl}")"
-		else
-			printf "JDL present"
-			test_done
-		fi
-
-		printf "Logging events for subjobs... "
-		$LB_READY_SH -j ${subjobs[0]} > /dev/null 2> /dev/null
-		$LB_DONE_SH -j ${subjobs[1]} > /dev/null 2> /dev/null
-
-		printf "Sleeping for 10 seconds (waiting for events to deliver)...\n"
-		sleep 10
-
-		jobstate=`${LBJOBSTATUS} ${subjobs[0]} | ${SYS_GREP} "state :" | ${SYS_AWK} '{print $3}'`
-		printf "Is the testing job (${subjobs[0]}) in a correct state? $jobstate"
-
-		if [ "${jobstate}" = "Ready" ]; then
-			test_done
-		else
-			test_failed
-			print_error "State ${jobstate}: Job is not in appropriate state (Ready)"
-		fi
-		jobstate=`${LBJOBSTATUS} ${subjobs[1]} | ${SYS_GREP} "state :" | ${SYS_AWK} '{print $3}'`
-		printf "Is the testing job (${subjobs[1]}) in a correct state? $jobstate"
-
-		if [ "${jobstate}" = "Done" ]; then
-			test_done
-		else
-			test_failed
-			print_error "State ${jobstate}: Job is not in appropriate state (Done)"
-		fi
-
-
-		jobstate=`${LBJOBSTATUS} -fullhist $jobid | ${SYS_GREP} -E "^state :" | ${SYS_AWK} '{print $3}'`
-		printf "Is the collection ($jobid) in a correct state? $jobstate"
-
-		if [ "${jobstate}" = "Waiting" ]; then
-			test_done
-		else
-			test_failed
-			print_error "State ${jobstate}: Job is not in appropriate state (Waiting)"
-		fi
-
-		printf "Logging events to clear subjobs... "
-		$LB_CLEARED_SH -j ${subjobs[0]} > /dev/null 2> /dev/null
-		$LB_CLEARED_SH -j ${subjobs[1]} > /dev/null 2> /dev/null
-
-		printf "Sleeping for 10 seconds (waiting for events to deliver)...\n"
-		sleep 10
-
-		jobstate=`${LBJOBSTATUS} -fullhist $jobid | ${SYS_GREP} -E "^state :" | ${SYS_AWK} '{print $3}'`
-		printf "Is the collection ($jobid) in a correct state? $jobstate"
-
-		if [ "${jobstate}" = "Cleared" ]; then
-			test_done
-		else
-			test_failed
-			print_error "State ${jobstate}: Job is not in appropriate state (Cleared)"
-		fi
-
-		echo $jobid > $$_jobs_to_purge_test.txt
-
-		printf "Purging collection... " 
-
-		$LBPURGE -j $$_jobs_to_purge_test.txt
-
-		printf "Sleeping for 10 seconds... " 
-
-		sleep 10
-
-		printf "Checking state of collection... " 
-
-		${LBJOBSTATUS} $jobid > $$_collstate.tmp 2> $$_collstate_err.tmp
-		jobstate=`$SYS_CAT $$_collstate.tmp | ${SYS_GREP} -E "^state :" | ${SYS_AWK} '{print $3}' 2> $$_collstate.tmp`
-		$SYS_GREP "Identifier removed" $$_collstate_err.tmp > /dev/null
-		if [ "$?" = "0" -o "${jobstate}" = "Purged" ]; then
-
-			if [ "${jobstate}" = "Purged" ]; then
-				printf "${jobstate}"
-			else
-			printf "Identifier removed"
-			fi
-			test_done
-
-			printf "Checking state of subjob #1... "
-			${LBJOBSTATUS} ${subjobs[0]} > $$_collstate.tmp 2> $$_collstate_err.tmp
-			jobstate=`$SYS_CAT $$_collstate.tmp | ${SYS_GREP} -E "^state :" | ${SYS_AWK} '{print $3}' 2> $$_collstate.tmp`
-			$SYS_GREP "Identifier removed" $$_collstate_err.tmp > /dev/null
-			if [ "$?" = "0" -o "${jobstate}" = "Purged" ]; then
-				if [ "${jobstate}" = "Purged" ]; then
-					printf "${jobstate}"
-				else
-					printf "Identifier removed"
-				fi
-				test_done
-			else
-				test_failed
-				print_error "State ${jobstate}: Job is not in appropriate state (Cleared)"
-			fi
-
-			printf "Checking state of subjob #2... "
-			${LBJOBSTATUS} ${subjobs[1]} > $$_collstate.tmp 2> $$_collstate_err.tmp
-			jobstate=`$SYS_CAT $$_collstate.tmp | ${SYS_GREP} -E "^state :" | ${SYS_AWK} '{print $3}' 2> $$_collstate.tmp`
-			$SYS_GREP "Identifier removed" $$_collstate_err.tmp > /dev/null
-			if [ "$?" = "0" -o "${jobstate}" = "Purged" ]; then
-				if [ "${jobstate}" = "Purged" ]; then
-					printf "${jobstate}"
-				else
-					printf "Identifier removed"
-				fi
-				test_done
-			else
-				test_failed
-				print_error "State ${jobstate}: Job is not in appropriate state (Cleared)"
-			fi
-
-		else
-			printf "${jobstate}"
-			test_skipped
-		fi
-
-		$SYS_RM $$_jobs_to_purge_test.txt
-		$SYS_RM $$_collstate.tmp
-		$SYS_RM $$_collstate_err.tmp
-
-	fi
-
-	echo ${subjobs[0]} >> ${joblist}
-	echo ${subjobs[1]} >> ${joblist}
-	echo $jobid >> ${joblist}
-	try_purge ${joblist}
-
-	$SYS_RM $$_test_coll_registration.txt
-
-
-done
-
-test_end
-#} &> $logfile
-}
-
-#if [ $flag -ne 1 ]; then
-# 	cat $logfile
-# 	$SYS_RM $logfile
-#fi
-exit $TEST_OK
-
diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-harvester.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-harvester.sh
deleted file mode 100755
index 354d311..0000000
--- a/org.glite.testsuites.ctb/LB/tests/lb-test-harvester.sh
+++ /dev/null
@@ -1,207 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
-# See http://www.eu-egee.org/partners for details on the copyright holders.
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# show help and usage
-progname=`basename $0`
-showHelp()
-{
-cat << EndHelpHeader
-Script for local testing of L&B harvester.
-
-Prerequisities:
-   - posgtgresql server running, with appropriate user access
-   - mysql server running, with appropriate user access
-   - environment variables set (may be specified in site-info.def):
-
-  GLITE_LOCATION ................... gLite location
-  GLITE_MYSQL_ROOT_PASSWORD ........ mysql root password
-  GLITE_RTM_TEST_ADDITIONAL_ARGS ... L&B harvester additional arguments
-                                     (--old required for L&B < 2.0)
-
-  For full list of the possible environment variables, see '`which glite-lb-harvester.sh` --help'.
-
-Tests called (glite-lb-harvester.sh script):
-
-  basic:   notifications for basic events (submitted/waiting/running)
-  rebind:  rebinding of the notifications
-  cleanup: proper dropping of the notifications on quit
-  refresh: renewing of the notifications
-  JDL:     getting of the attributes from JDL
-
-Returned values:
-    Exit TEST_OK: Test Passed
-    Exit TEST_ERROR: Test Failed
-    Exit 2: Wrong Input
-
-EndHelpHeader
-
-	echo "Usage: $progname [OPTIONS] LB_SERVER_1 [LB_SERVER_2 ...] "
-	echo "Options:"
-	echo " -h | --help             Show this help message."
-	echo " -o | --output 'file'    Redirect all output to the 'file' (stdout by default)."
-	echo " -t | --text             Format output as plain ASCII text."
-	echo " -c | --color            Format output as text with ANSI colours (autodetected by default)."
-	echo " -x | --html             Format output as html."
-	echo " -s | --site-info 'file' site-info.def file (mysql password, ...)."
-	echo ""
-}
-
-# read common definitions and functions
-COMMON=lb-common.sh
-if [ ! -r ${COMMON} ]; then
-	printf "Common definitions '${COMMON}' missing!"
-	exit 2
-fi
-source ${COMMON}
-while test -n "$1"
-do
-	case "$1" in
-		"-h" | "--help") showHelp && exit 2 ;;
-		"-t" | "--text")  setOutputASCII ;;
-		"-c" | "--color") setOutputColor ;;
-		"-x" | "--html")  setOutputHTML ;;
-		"-s" | "--site")
-			shift
-			cat "$1" | grep -v '^#' | grep -v '^[ \t]*$' | sed 's/^/export /' > site-info.def.tmp.$$
-			source "site-info.def.tmp.$$"
-			rm -f "site-info.def.tmp.$$"
-			site=1
-			if test -z "$GLITE_MYSQL_ROOT_PASSWORD"; then
-				export GLITE_MYSQL_ROOT_PASSWORD="$MYSQL_PASSWORD"
-			fi
-			;;
-		*) showHelp && exit 2 ;;
-	esac
-	shift
-done
-
-DEBUG=2
-
-##
-#  Starting the test
-#####################
-
-{
-test_start
-
-
-##
-# ==== Various sanity checks first ====
-##
-
-# check_binaries
-# (harvester test script is using own names of the all binaries)
-printf "Testing if all binaries are available"
-check_binaries $SYS_GREP $SYS_SED $SYS_CAT $SYS_TAIL $SYS_DATE $GRIDPROXYINFO $LBJOBREG $LBLOGEV $LBPURGE mysqladmin mysql createdb dropdb psql
-if [ $? = 0 ]; then
-	test_done
-else
-	test_failed
-	print_error "Some binaries missing!"
-	test_end
-	exit 2
-fi
-
-printf "Testing credentials"
-check_credentials_and_generate_proxy
-if [ $? != 0 ]; then
-	test_end
-	exit 2
-fi
-
-printf "Testing access to MySQL"
-if [ -z "$GLITE_LB_TEST_DB" ]; then
-	MYSQL_ARGS="-u ${GLITE_MYSQL_ROOT_USER:-root}"
-	[ -z "$GLITE_MYSQL_ROOT_PASSWORD" ] || MYSQL_ARGS="--password=${GLITE_MYSQL_ROOT_PASSWORD} $MYSQL_ARGS"
-	mysqladmin $MYSQL_ARGS status >/dev/null
-	if [ $? = 0 ]; then
-		test_done
-	else
-		test_failed
-		print_error "MySQL not running or access denied!"
-		if [ -z "$GLITE_MYSQL_ROOT_PASSWORD" ]; then
-			print_warning "\$GLITE_MYSQL_ROOT_PASSWORD not specified"
-		fi
-		if [ -z "$site" ]; then
-			print_warning "site-info.def file not specified"
-		fi
-		test_end
-		exit 2
-	fi
-else
-	printf " ... using $GLITE_LB_TEST_DB, not tested"
-	test_skipped
-fi
-
-printf "Testing access to PostgreSQL"
-if [ -z "$GLITE_RTM_TEST_DB" ]; then
-	PG_ARGS="-U ${GLITE_PG_ROOT_USER:-postgres}"
-	echo "SHOW server_version;" | psql -At $PG_ARGS >/dev/null
-	if [ $? = 0 ]; then
-		test_done
-	else
-		test_failed
-		print_error "PosgreSQL not running or access denied!"
-		exit 2
-	fi
-else
-	printf " ... using $GLITE_RTM_TEST_DB, not tested"
-	test_skipped
-fi
-
-printf "L&B harvester test script in PATH"
-if which glite-lb-harvester-test.sh >/dev/null 2>&1; then
-	test_done
-else
-	test_failed
-	print_error "glite-lb-harvester-test.sh not found"
-	exit 2
-fi
-
-##
-# ==== L&B harvester test ====
-##
-
-printf "Launching the L&B harvester test..."
-print_newline
-if [ -n "$is_html" ]; then
-	local_amp='&'
-	printf "
"
-else
-	local_amp='&'
-fi
-glite-lb-harvester-test.sh stop
-(glite-lb-harvester-test.sh 2>&1; echo $? > res.$$.txt) | sed "s,&,$local_amp,"
-err=`cat res.$$.txt`; rm -f res.$$.txt
-if [ -n "$is_html" ]; then
-	printf "
" -fi - -if [ "$err" = "0" ]; then - test_done -else - test_failed - print_error "L&B harvester test failed!" - test_end - exit 1 -fi - -test_end -} - -exit $TEST_OK diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-https.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-https.sh deleted file mode 100755 index 74ad343..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-https.sh +++ /dev/null @@ -1,378 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing correct job registration - -Prerequisities: - - LB server - - environment variables set: - - GLITE_LB_SERVER_PORT - if nondefault port (9000) is used - GLITE_WMS_QUERY_SERVER - GLITE_WMS_NOTIF_SERVER - -Tests called: - - job registration - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -#touch $logfile -#if [ ! -w $logfile ]; then -# echo "Cannot write to output file $logfile" -# exit $TEST_ERROR -#fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $SYS_CURL -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi -X509_USER_PROXY=`${GRIDPROXYINFO} | ${SYS_GREP} -E "^path" | ${SYS_SED} "s/path\s*:\s//"` - -printf "Using SSL client: " -$SYS_CURL --version | head -n 1 | grep -i NSS/ >/dev/null 2>&1 -if [ $? -eq 0 ]; then - SSL_CMD="wget --timeout=60 --no-check-certificate --secure-protocol=SSLv3 --quiet --private-key $X509_USER_PROXY --certificate $X509_USER_PROXY --ca-directory /etc/grid-security/certificates --ca-certificate $X509_USER_PROXY --output-document https.$$.tmp" - SSL_CLIENT=wget -else - SSL_CMD="$SYS_CURL --max-time 60 --insecure -3 --silent --key $X509_USER_PROXY --cert $X509_USER_PROXY --capath /etc/grid-security/certificates --output https.$$.tmp" - SSL_CLIENT=curl -fi -printf "$SSL_CLIENT" -test_done - - # Register job: - printf "Registering testing job " - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - else - test_done - - # Get list of jobs - printf "Evaluating job list... " - - $SSL_CMD https://${GLITE_WMS_QUERY_SERVER}/ - - if [ "$?" != "0" ]; then - test_failed - print_error "Job list not returned" - else - test_done - - printf "Looking up the test job..." - - $SYS_GREP $jobid https.$$.tmp > /dev/null 2> /dev/null - - if [ "$?" != "0" ]; then - test_failed - print_error "Test job not found in the list" - else - test_done - fi - - $SYS_RM https.$$.tmp - - fi - - # Get job status - printf "Evaluating job status listing... " - - $SSL_CMD "${jobid}" - - if [ "$?" != "0" ]; then - test_failed - print_error "Job status not returned" - else - test_done - - printf "Checking for jobid (verifying content)..." - - $SYS_GREP $jobid https.$$.tmp > /dev/null 2> /dev/null - - if [ "$?" != "0" ]; then - test_failed - print_error "JobID not found among data returned" - else - test_done - fi - - $SYS_RM https.$$.tmp - - fi - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - try_purge ${joblist} - - fi - - # Register notification: - printf "Registering notification " - - notifid=`${LBNOTIFY} new -j ${jobid} | $SYS_GREP "notification ID" | ${SYS_AWK} '{ print $3 }'` - echo ${LBNOTIFY} new -j ${jobid} - - if [ -z $notifid ]; then - test_failed - print_error "Failed to register notification" - else - printf "(${notifid}) " - test_done - - # Get notification status - printf "Evaluating notification status listing... " - - $SSL_CMD "${notifid}" - - if [ "$?" != "0" ]; then - test_failed - print_error "Job status not returned" - else - test_done - - printf "Checking for jobid (verifying content)..." - - notifunique=`${SYS_ECHO} ${notifid} | ${SYS_SED} 's/^.*NOTIF://'` - - $SYS_GREP $notifunique https.$$.tmp > /dev/null 2> /dev/null - - if [ "$?" != "0" ]; then - test_failed - print_error "Notification ID not found among data returned" - else - test_done - fi - - printf "Checking for validity period (to distinguis from job listing)... " - $SYS_GREP -E "Valid until:[0-9 :-]+" https.$$.tmp > /dev/null 2> /dev/null - - if [ "$?" != "0" ]; then - test_failed - print_error "Validity period inot listed" - else - test_done - fi - - $SYS_RM https.$$.tmp - - fi - - #Drop notification - printf "Dropping the test notification (${notifid})" - dropresult=`${LBNOTIFY} drop ${notifid} 2>&1` - if [ -z $dropresult ]; then - test_done - else - test_failed - print_error "Failed to drop notification ${dropresult}" - fi - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - try_purge ${joblist} - - - fi - - printf "Trying excessively long request (Regression into bug #80263)..." - URL="https://${GLITE_WMS_QUERY_SERVER}/" - for i in {1..2000} - do - URL="${URL}$RANDOM" - done - printf "${#URL} characters" - - if [ "$SSL_CLIENT" = "curl" ]; then - $SSL_CMD -D http.header.dump.$$ $URL - else - $SSL_CMD --server-response $URL 2> http.header.dump.$$ - fi - $SYS_GREP -E "400.*Bad.*Request" http.header.dump.$$ > /dev/null - if [ "$?" != "0" ]; then - test_failed - print_error "Incorrect HTTP header or header dump failed:" - $SYS_CAT http.header.dump.$$ - else - test_done - fi - $SYS_RM http.header.dump.$$ - - printf "Trying request with normal length..." - URL="https://${GLITE_WMS_QUERY_SERVER}/$RANDOM" - if [ "$SSL_CLIENT" = "curl" ]; then - $SSL_CMD -D http.header.dump.$$ $URL - else - $SSL_CMD --server-response $URL 2> http.header.dump.$$ - fi - $SYS_GREP -E "404.*Not.*Found" http.header.dump.$$ > /dev/null - if [ "$?" != "0" ]; then - test_failed - print_error "Incorrect HTTP header or header dump failed:" - $SYS_CAT http.header.dump.$$ - else - test_done - fi - $SYS_RM http.header.dump.$$ - - $SYS_RM https.$$.tmp - - check_srv_version '>=' "2.3" - if [ $? = 0 ]; then - printf "Downloading remote configuration... " - $SSL_CMD https://${GLITE_WMS_QUERY_SERVER}/?configuration > https.$$.tmp - LineNO=`$SYS_WC -l https.$$.tmp | $SYS_AWK '{ print $1 }' ` - if [ ! "$LineNO" = "0" ]; then - test_done - printf "Checking for items... " - for item in msg_brokers msg_prefixes - do - printf "$item... " - $SYS_GREP -E "$item.*=" https.$$.tmp > /dev/null - if [ "$?" = "0" ]; then - test_done - else - test_failed - print_error "Value $item not returned" - fi - done - else - test_failed - print_error "Statistics not returned" - fi - - printf "Checking statistics... " - $SSL_CMD https://${GLITE_WMS_QUERY_SERVER}/?stats > https.$$.tmp - LineNO=`$SYS_WC -l https.$$.tmp | $SYS_AWK '{ print $1 }' ` - if [ ! "$LineNO" = "0" ]; then - test_done - printf "Checking for items that should be > 0... " - for item in "gLite job regs" "Notification regs.*legacy" "HTML accesses" "Plain text accesses" - do - printf "$item... " - ItLine=`$SYS_GREP -E "$item" https.$$.tmp` - if [ "$?" = "0" ]; then - ItValue=`$SYS_ECHO $ItLine | $SYS_GREP -o -E -i "[0-9]+" | $SYS_GREP -o -E -i "[0-9]+"` - printf "$ItValue " - if [ "$ItValue" != "" -a $ItValue -gt 0 ]; then - test_done - else - test_failed - print_error "A numeric value greater tha zero should have been returned" - fi - else - test_failed - print_error "Value $item not returned" - fi - done - printf "Checking stat file location... " - grep -i -E "[ \t]*WARNING" https.$$.tmp > /dev/null - if [ $? -eq 0 ]; then - printf "Files are in tmp!" - test_warning - else - test_done - fi - else - test_failed - print_error "Statistics not returned" - fi - - $SYS_RM https.$$.tmp - else - printf "Statistics and remote configuration tests... " - test_skipped - fi - -test_end -} -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-il-recovery.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-il-recovery.sh deleted file mode 100755 index f5f23ed..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-il-recovery.sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing interlogger recovery - -Prerequisities: - - LB server, interlogger either running or startable - - environment variables set: - - GLITE_LB_SERVER_PORT - if nondefault port (9000) is used - GLITE_LB_IL_SOCK - if nondefault socket at /tmp/interlogger.sock is used - GLITE_LB_LOGGER_PORT - if nondefault port (9002) is used - -Tests called: - - job registration - event logging - through interlogger - checking jobs states - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." - echo " --stop Command to stop the interlogger." - echo " --start Command to start the interlogger." - echo " -f | --file-prefix IL file prefix." - echo " -u | --user-name Name of user account used to run the IL. (default GLITE_USER or 'glite')" -} - -function generate_done_events() -{ -#outfile = $1 -#user = $2 -#host = $3 -#jobid = $4 - - echo DG.LLLID=28000000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"NetworkServer\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"Accepted\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000001:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000\" DG.ACCEPTED.FROM=\"UserInterface\" DG.ACCEPTED.FROM_HOST=\"sending component hostname\" DG.ACCEPTED.FROM_INSTANCE=\"sending component instance\" DG.ACCEPTED.LOCAL_JOBID=\"new jobId \(Condor Globus ...\)\" >> $1 - echo DG.LLLID=28003000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"NetworkServer\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"EnQueued\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000003:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000\" DG.ENQUEUED.QUEUE=\"destination queue\" DG.ENQUEUED.JOB=\"job description in receiver language\" DG.ENQUEUED.RESULT=\"OK\" DG.ENQUEUED.REASON=\"detailed description of transfer\" >> $1 - echo DG.LLLID=28006000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"WorkloadManager\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"DeQueued\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000001:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000\" DG.DEQUEUED.QUEUE=\"queue name\" DG.DEQUEUED.LOCAL_JOBID=\"new jobId assigned by the receiving component\" >> $1 - echo DG.LLLID=28009000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"WorkloadManager\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"HelperCall\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000003:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000\" DG.HELPERCALL.HELPER_NAME=\"name of the called component\" DG.HELPERCALL.HELPER_PARAMS=\"parameters of the call\" DG.HELPERCALL.SRC_ROLE=\"CALLING\" >> $1 - echo DG.LLLID=28012000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"WorkloadManager\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"Match\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000005:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000\" DG.MATCH.DEST_ID=\"destination CE/queue\" >> $1 - echo DG.LLLID=28015000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"WorkloadManager\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"HelperReturn\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000007:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000\" DG.HELPERRETURN.HELPER_NAME=\"name of the called component\" DG.HELPERRETURN.RETVAL=\"returned data\" DG.HELPERRETURN.SRC_ROLE=\"CALLING\" >> $1 - echo DG.LLLID=28018000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"WorkloadManager\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"EnQueued\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000009:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000\" DG.ENQUEUED.QUEUE=\"destination queue\" DG.ENQUEUED.JOB=\"job description in receiver language\" DG.ENQUEUED.RESULT=\"OK\" DG.ENQUEUED.REASON=\"detailed description of transfer\" >> $1 - echo DG.LLLID=28021000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"JobController\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"DeQueued\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000010:BH=0000000000:JSS=000001:LM=000000:LRMS=000000:APP=000000:LBS=000000\" DG.DEQUEUED.QUEUE=\"queue name\" DG.DEQUEUED.LOCAL_JOBID=\"new jobId assigned by the receiving component\" >> $1 - echo DG.LLLID=28024000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"JobController\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"Transfer\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000010:BH=0000000000:JSS=000003:LM=000000:LRMS=000000:APP=000000:LBS=000000\" DG.TRANSFER.DESTINATION=\"LRMS\" DG.TRANSFER.DEST_HOST=\"destination hostname\" DG.TRANSFER.DEST_INSTANCE=\"destination instance\" DG.TRANSFER.JOB=\"job description in receiver language\" DG.TRANSFER.RESULT=\"OK\" DG.TRANSFER.REASON=\"detailed description of transfer\" DG.TRANSFER.DEST_JOBID=\"destination internal jobid\" >> $1 - echo DG.LLLID=28027000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"LogMonitor\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"Accepted\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000001:LRMS=000000:APP=000000:LBS=000000\" DG.ACCEPTED.FROM=\"JobController\" DG.ACCEPTED.FROM_HOST=\"sending component hostname\" DG.ACCEPTED.FROM_INSTANCE=\"sending component instance\" DG.ACCEPTED.LOCAL_JOBID=\"new jobId \(Condor Globus ...\)\" >> $1 - echo DG.LLLID=28030000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"LogMonitor\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"Transfer\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000003:LRMS=000000:APP=000000:LBS=000000\" DG.TRANSFER.DESTINATION=\"LRMS\" DG.TRANSFER.DEST_HOST=\"destination hostname\" DG.TRANSFER.DEST_INSTANCE=\"destination instance\" DG.TRANSFER.JOB=\"job description in receiver language\" DG.TRANSFER.RESULT=\"OK\" DG.TRANSFER.REASON=\"detailed description of transfer\" DG.TRANSFER.DEST_JOBID=\"destination internal jobid\" >> $1 - echo DG.LLLID=28033000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"LogMonitor\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"Running\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000005:LRMS=000000:APP=000000:LBS=000000\" DG.RUNNING.NODE=\"worker node\" >> $1 - echo DG.LLLID=28036000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"LogMonitor\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"Done\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000007:LRMS=000000:APP=000000:LBS=000000\" DG.DONE.STATUS_CODE=\"OK\" DG.DONE.REASON=\"reason for the change\" DG.DONE.EXIT_CODE=\"0\" >> $1 - echo DG.LLLID=28039000 DG.USER=\"$2\" DATE=\"$($SYS_DATE --universal +'%Y%m%d%H%M%S.%N' | sed 's/...$//')\" HOST=\"$3\" PROG=edg-wms LVL=SYSTEM DG.PRIORITY=4 DG.SOURCE=\"LogMonitor\" DG.SRC_INSTANCE=\"\" DG.EVNT=\"Clear\" DG.JOBID=\"$4\" DG.SEQCODE=\"UI=000003:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000009:LRMS=000000:APP=000000:LBS=000000\" DG.CLEAR.REASON=\"USER\" >> $1 -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -if [ -z "$GLITE_USER" ]; then - USER="glite" -else - USER="$GLITE_USER" -fi -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - "--stop") shift ; STOPCOMMAND="$1" ;; - "--start") shift ; STARTCOMMAND="$1" ;; - "-f" | "--file-prefix") shift ; EVENTFILE=$1 ;; - "-u" | "--user-name") shift ; USER=$1 ;; - esac - shift -done - -# redirecting all output to $logfile -#touch $logfile -#if [ ! -w $logfile ]; then -# echo "Cannot write to output file $logfile" -# exit $TEST_ERROR -#fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $LBJOBREG $SYS_AWK $SYS_DOMAINNAME $LBJOBSTATUS $SYS_FIND $SYS_WC $SYS_EXPR -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi - USERIDENTITY=`${GRIDPROXYINFO} | ${SYS_GREP} -E "^identity" | ${SYS_SED} "s/identity\s*:\s//"` - - # Register job: - printf "Registering testing job " - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application | ${SYS_GREP} "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - else - printf "($jobid)" - test_done - - printf "Getting No. of sockets (user $USER) for a later test... " - SOCKS_PRE=`$SYS_FIND /tmp -maxdepth 1 -type s -user $USER | wc -l` - printf "$SOCKS_PRE" - test_done - - #Stopping interlogger (if required) - if [ -z $STOPCOMMAND ]; then - $SYS_ECHO Info: No command to stop was given - else - $SYS_ECHO Stoping the interlogger using the stop command supplied - $STOPCOMMAND - fi - - UNIQUE=`$SYS_ECHO ${jobid} | ${SYS_SED} 's/.*\///'` - - if [ -z $EVENTFILE ]; then - #Set the default event file prefix if none has been supplied - EVENTFILE=/var/glite/log/dglogd.log - fi - - DOMAINNAME=`${SYS_DOMAINNAME} -f` - - # log events: - printf "Generating events resulting in CLEARED state\n" - - #Make sure the il is able to access the file, whatever account it is running under. - $SYS_TOUCH $EVENTFILE.$UNIQUE - $SYS_CHMOD 666 $EVENTFILE.$UNIQUE - - generate_done_events "$EVENTFILE.$UNIQUE" "$USERIDENTITY" "$DOMAINNAME" $jobid - - #Starting interlogger or waiting - if [ -z "$STARTCOMMAND" ]; then - $SYS_ECHO Info: No command to start was given - printf "Sleeping for 70 seconds (waiting for interlogger to notice and deliver events)...\n" - sleep 70 - else - $SYS_ECHO Starting the interlogger using the start command supplied - $STARTCOMMAND > /dev/null 2> /dev/null & - printf "Sleeping for 10 seconds (waiting for events to deliver)...\n" - sleep 10 - fi - - - - jobstate=`${LBJOBSTATUS} ${jobid} | ${SYS_GREP} "state :" | ${SYS_AWK} '{print $3}'` - printf "Testing job ($jobid) is in state: $jobstate\n" - - if [ "${jobstate}" = "Cleared" ]; then - test_done - else - test_failed - print_error "Job is not in appropriate state" - fi - - - printf "Getting No. of sockets (regression into Savannah Bug #92708)... " - SOCKS_POST=`find /tmp -maxdepth 1 -type s -user $USER | wc -l` - printf "$SOCKS_POST" - test_done - - check_srv_version '>=' "2.3" - if [ $? = 0 ]; then - printf "Comparing No. of sockets... " - $SYS_EXPR $SOCKS_POST \> $SOCKS_PRE > /dev/null - if [ $? -gt 0 ]; then - printf "OK, less or equal" - test_done - else - test_failed - print_error "There are more sockets after IL handled messages" - fi - else - printf "Comparing No. of sockets... " - test_skipped - fi - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - try_purge ${joblist} - - fi - -test_end -} -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-job-registration.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-job-registration.sh deleted file mode 100755 index bcf1a2c..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-job-registration.sh +++ /dev/null @@ -1,261 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing correct job registration - -Prerequisities: - - LB server - - environment variables set: - - GLITE_LB_SERVER_PORT - if nondefault port (9000) is used - -Tests called: - - job registration - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $LBJOBREG $LBJOBSTATUS -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi - - # Register job: - printf "Registering testing job " - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - else - printf "($jobid)" - test_done - - # Check result - jobstate=`${LBJOBSTATUS} ${jobid} | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Is the job in a correct state? $jobstate" - - if [ "${jobstate}" = "Submitted" ]; then - test_done - else - test_failed - print_error "Job has not been submitted" - fi - - printf "Regression into bug #27268: Trying to re-register job with the same jobid..." - ${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application -j $jobid > /dev/null - - noofevents=`${LBHISTORY} $jobid | $SYS_NL | $SYS_TAIL -n 1 | ${SYS_AWK} '{print $1}'` - - printf "(Event No. $noofevents)..." - - if [ "${noofevents}" = "2" ]; then - test_done - else - test_failed - print_error "Second registration did not take place" - fi - - - printf "Trying to re-register job with the same jobid, 'exclusive' flag on..." - ${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application -j $jobid -E > /dev/null 2> /dev/null - - if [ "$?" = "0" ]; then - test_failed - print_error "Registration should not have returned 0" - else - printf " Returned $?" - test_done - fi - - printf "Checking events... " - noofevents=`${LBHISTORY} $jobid | $SYS_NL | $SYS_TAIL -n 1 | ${SYS_AWK} '{print $1}'` - - printf "(There are $noofevents events)..." - - if [ "${noofevents}" = "2" ]; then - test_done - else - test_failed - print_error "Wrong number of registration events" - fi - - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - ${LBPURGE} -j ${joblist} > /dev/null - $SYS_RM ${joblist} - - printf "Test job purged. Testing state..." - ${LBJOBSTATUS} $jobid > $$_jobreg.tmp 2> $$_jobreg_err.tmp - jobstate=`$SYS_CAT $$_jobreg.tmp | ${SYS_GREP} -E "^state :" | ${SYS_AWK} '{print $3}' 2> $$_jobreg.tmp` - $SYS_GREP "Identifier removed" $$_jobreg_err.tmp > /dev/null - if [ "$?" = "0" -o "${jobstate}" = "Purged" ]; then - test_done - - ${LBJOBREG} -h 2>&1 | $SYS_GREP '\-E' > /dev/null - - if [ $? = 0 ]; then - printf "Trying to re-register. Same JobID, exclusive flag..." - ${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application -j $jobid -E > /dev/null 2> /dev/null - if [ "$?" = "0" ]; then - test_failed - print_error "Registration should not have returned 0" - else - printf " Returned $?" - test_done - fi - - printf "Checking state (expecting state 'Purged' or EIDRM). " - ${LBJOBSTATUS} $jobid > $$_jobreg.tmp 2> $$_jobreg_err.tmp - jobstate=`$SYS_CAT $$_jobreg.tmp | ${SYS_GREP} -E "^state :" | ${SYS_AWK} '{print $3}' 2> $$_jobreg.tmp` - $SYS_GREP "Identifier removed" $$_jobreg_err.tmp > /dev/null - if [ "$?" = "0" -o "${jobstate}" = "Purged" ]; then - test_done - else - printf " Option may be off on server side" - test_skipped - - echo $jobid > ${joblist} - ${LBPURGE} -j ${joblist} > /dev/null - $SYS_RM ${joblist} - fi - - printf "Trying to re-register same JobID, exclusive flag off." - ${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application -j $jobid > /dev/null - if [ "$?" = "0" ]; then - printf " Returned $?" - test_done - else - test_failed - print_error "Registration should not have returned 0" - fi - - printf "Checking state (expecting state 'Submitted'). " - jobstate=`${LBJOBSTATUS} ${jobid} | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - - if [ "${jobstate}" = "Submitted" ]; then - test_done - echo $jobid > ${joblist} - ${LBPURGE} -j ${joblist} > /dev/null - $SYS_RM ${joblist} - else - test_failed - print_error "Falied to re-register a purged JobID event with the 'exclusive' flag off." - fi - - else - printf "Client does not support the 'exclusive' flag." - test_skipped - fi - - - else - printf "Job has not been purged, re-registration test will be skipped" - - test_skipped - fi - - $SYS_RM $$_jobreg.tmp - $SYS_RM $$_jobreg_err.tmp - - fi - - - - -test_end -} -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-job-states.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-job-states.sh deleted file mode 100755 index 1a674f1..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-job-states.sh +++ /dev/null @@ -1,246 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing if jobs pass through correct states through their lifetimes - -Prerequisities: - - LB local logger, interlogger, and server running - - environment variables set: - - GLITE_LB_SERVER_PORT - if nondefault port (9000) is used - GLITE_LB_LOGGER_PORT - if nondefault port (9002) is used - GLITE_WMS_QUERY_SERVER - GLITE_WMS_LOG_DESTINATION - -Tests called: - - job registration - event logging - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS] [event file prefix]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." - echo "" -} - -test_state () { - - jobstate=`${LBJOBSTATUS} $1 | ${SYS_GREP} "state :" | ${SYS_AWK} '{print $3}'` - #printf "Testing job ($1) is in state: $jobstate (should be $2)" - printf "Testing job is in state: $jobstate (should be $2)" - - if [ "${jobstate}" = "$2" ]; then - test_done - else - test_failed - print_error "Job is not in appropriate state" - fi - -} - -check_return_and_test_state () -{ -# 1: previous return value -# 2: jobid -# 2> expected state -# printf "Sleeping for 10 seconds (waiting for events to deliver)...\n" - if [ $1 = 0 ]; then - test_done - else - test_failed - fi - - sleep 10 - - test_state $2 $3 -} - - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - *) EVENTFILE=$1 ;; - esac - shift -done - -# redirecting all output to $logfile -#touch $logfile -#if [ ! -w $logfile ]; then -# echo "Cannot write to output file $logfile" -# exit $TEST_ERROR -#fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - -CONT="yes" -while [ "$CONT" = "yes" ]; do - CONT="no" - - # check_binaries - printf "Testing if all binaries are available" - check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $LBJOBREG $SYS_AWK $LBJOBSTATUS - if [ $? -gt 0 ]; then - test_failed - print_error "Some binaries are missing" - break - else - test_done - fi - - # check credentials - printf "Testing credentials" - check_credentials_and_generate_proxy - if [ $? != 0 ]; then - break - fi - - # Register job: - printf "Registering testing job " - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application` - if [ $? != 0 ]; then - test_failed - print_error "Failed to register job" - break - else - test_done - fi - - #parse job id - jobid=`echo "${jobid}" | ${SYS_GREP} "new jobid" | ${SYS_AWK} '{ print $3 }'` - if [ -z $jobid ]; then - print_error "Failed to parse job " - break - else - printf "($jobid)" - fi - - test_state $jobid Submitted - - EDG_WL_SEQUENCE="UI=000003:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000" - - printf "logging Accepted" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s NetworkServer -e Accepted --from="UserInterface" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid="new jobId (Condor Globus ...)"` - check_return_and_test_state $? $jobid Waiting - - printf "logging EnQueued" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s NetworkServer -e EnQueued --queue="destination queue" --job="job description in receiver language" --result=OK --reason="detailed description of transfer"` - check_return_and_test_state $? $jobid Waiting - - printf "logging DeQueued" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e DeQueued --queue="queue name" --local_jobid="new jobId assigned by the receiving component"` - check_return_and_test_state $? $jobid Waiting - - printf "logging HelperCall" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e HelperCall --helper_name="name of the called component" --helper_params="parameters of the call" --src_role=CALLING` - check_return_and_test_state $? $jobid Waiting - - printf "logging Match" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e Match --dest_id="${DESTINATION:-destination CE/queue}"` - check_return_and_test_state $? $jobid Waiting - - printf "logging HelperReturn" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e HelperReturn --helper_name="name of the called component" --retval="returned data" --src_role=CALLING` - check_return_and_test_state $? $jobid Waiting - - printf "logging EnQueued" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e EnQueued --queue="destination queue" --job="job description in receiver language" --result=OK --reason="detailed description of transfer"` - check_return_and_test_state $? $jobid Ready - - printf "logging DeQueued" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s JobController -e DeQueued --queue="queue name" --local_jobid="new jobId assigned by the receiving component"` - check_return_and_test_state $? $jobid Ready - - printf "logging Transfer" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s JobController -e Transfer --destination="LRMS" --dest_host="destination hostname" --dest_instance="destination instance" --job="job description in receiver language" --result=OK --reason="detailed description of transfer" --dest_jobid="destination internal jobid"` - check_return_and_test_state $? $jobid Ready - - printf "logging Accepted" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Accepted --from="JobController" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid="new jobId (Condor Globus ...)"` - check_return_and_test_state $? $jobid Ready - - printf "logging Transfer" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Transfer --destination="LRMS" --dest_host="destination hostname" --dest_instance="destination instance" --job="job description in receiver language" --result=OK --reason="detailed description of transfer" --dest_jobid="destination internal jobid"` - check_return_and_test_state $? $jobid Scheduled - - printf "logging Running" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Running --node="${CE_NODE:-worker node}"` - check_return_and_test_state $? $jobid Running - - printf "logging Done" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Done --status_code=OK --reason="reason for the change" --exit_code=0` - check_return_and_test_state $? $jobid Done - - printf "logging Clear" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Clear --reason=USER` - check_return_and_test_state $? $jobid Cleared - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - try_purge ${joblist} -done - -test_end -} -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-logevent.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-logevent.sh deleted file mode 100755 index cc88c47..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-logevent.sh +++ /dev/null @@ -1,330 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing if local logger is accepting events - -Prerequisities: - - LB local logger, server - - environment variables set: - - GLITE_LB_SERVER_PORT - if nondefault port (9000) is used - GLITE_LB_LOGGER_PORT - if nondefault port (9002) is used - -Tests called: - - job registration - event logging - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS] [event file prefix]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." - echo "" - echo "Give the same prefix you pass to your local logger on startup (-f or --file-prefix option)" - echo "If no event file prefix is given, the default will be used (/var/glite/log/dglogd.log)." -} - - -generate_reference_file() -{ - echo "line 1: edg_wll_ParseEvent() o.k. (event Accepted), edg_wll_UnparseEvent() o.k." > $1 - echo "line 2: edg_wll_ParseEvent() o.k. (event EnQueued), edg_wll_UnparseEvent() o.k." >> $1 - echo "line 3: edg_wll_ParseEvent() o.k. (event DeQueued), edg_wll_UnparseEvent() o.k." >> $1 - echo "line 4: edg_wll_ParseEvent() o.k. (event HelperCall), edg_wll_UnparseEvent() o.k." >> $1 - echo "line 5: edg_wll_ParseEvent() o.k. (event Match), edg_wll_UnparseEvent() o.k." >> $1 - echo "line 6: edg_wll_ParseEvent() o.k. (event HelperReturn), edg_wll_UnparseEvent() o.k." >> $1 - echo "line 7: edg_wll_ParseEvent() o.k. (event EnQueued), edg_wll_UnparseEvent() o.k." >> $1 - echo "line 8: edg_wll_ParseEvent() o.k. (event DeQueued), edg_wll_UnparseEvent() o.k." >> $1 - echo "line 9: edg_wll_ParseEvent() o.k. (event Transfer), edg_wll_UnparseEvent() o.k." >> $1 - echo "line 10: edg_wll_ParseEvent() o.k. (event Accepted), edg_wll_UnparseEvent() o.k." >> $1 - echo "line 11: edg_wll_ParseEvent() o.k. (event Transfer), edg_wll_UnparseEvent() o.k." >> $1 - echo "line 12: edg_wll_ParseEvent() o.k. (event Running), edg_wll_UnparseEvent() o.k." >> $1 - echo "line 13: edg_wll_ParseEvent() o.k. (event Done), edg_wll_UnparseEvent() o.k." >> $1 -} - - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - *) EVENTFILE=$1 ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $LBJOBREG $SYS_AWK $LBPARSEEFILE -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi - - joblist=$$_jobs_to_purge.txt - - # if we will hit the time when the logger pick and delete the event - # file, we may need to repeat the test once more - for i in 1 2; do - # Register job: - printf "Registering testing job " - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application | ${SYS_GREP} "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - else - printf "($jobid)" - test_done - fi - - echo $jobid > ${joblist} - - printf "Logging events\n" - - EDG_WL_SEQUENCE="UI=000003:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000" - - printf "logging Accepted" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s NetworkServer -e Accepted --from="UserInterface" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid="new jobId (Condor Globus ...)"` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging EnQueued" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s NetworkServer -e EnQueued --queue="destination queue" --job="job description in receiver language" --result=OK --reason="detailed description of transfer"` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging DeQueued" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e DeQueued --queue="queue name" --local_jobid="new jobId assigned by the receiving component"` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging HelperCall" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e HelperCall --helper_name="name of the called component" --helper_params="parameters of the call" --src_role=CALLING` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging Match" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e Match --dest_id="${DESTINATION:-destination CE/queue}"` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging HelperReturn" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e HelperReturn --helper_name="name of the called component" --retval="returned data" --src_role=CALLING` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging EnQueued" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s WorkloadManager -e EnQueued --queue="destination queue" --job="job description in receiver language" --result=OK --reason="detailed description of transfer"` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging DeQueued" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s JobController -e DeQueued --queue="queue name" --local_jobid="new jobId assigned by the receiving component"` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging Transfer" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s JobController -e Transfer --destination="LRMS" --dest_host="destination hostname" --dest_instance="destination instance" --job="job description in receiver language" --result=OK --reason="detailed description of transfer" --dest_jobid="destination internal jobid"` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging Accepted" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Accepted --from="JobController" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid="new jobId (Condor Globus ...)"` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging Transfer" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Transfer --destination="LRMS" --dest_host="destination hostname" --dest_instance="destination instance" --job="job description in receiver language" --result=OK --reason="detailed description of transfer" --dest_jobid="destination internal jobid"` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging Running" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Running --node="${CE_NODE:-worker node}"` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - printf "logging Done" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $jobid -c $EDG_WL_SEQUENCE -s LogMonitor -e Done --status_code=OK --reason="reason for the change" --exit_code=0` - if [ $? = 0 ]; then - test_done - else - test_failed - fi - - UNIQUE=`$SYS_ECHO ${jobid} | ${SYS_SED} 's/.*\///'` - - if [ -z $EVENTFILE ]; then - #Set the default event file prefix if none has been supplied - EVENTFILE=/var/glite/log/dglogd.log - fi - - printf "Testing if event file exists ($EVENTFILE.$UNIQUE) " - EVENTFILE_RAW=events.tested.original.$$.txt - cp $EVENTFILE.$UNIQUE $EVENTFILE_RAW 2>/dev/null - if [ $? = 0 ]; then - test_done - - #Test the contents of the file - - #process events file - $LBPARSEEFILE -f $EVENTFILE_RAW 2>&1 | $SYS_GREP -v "Parsing file" > events.tested.$$.txt - - generate_reference_file events.reference.$$.txt - - printf "Comparing results (<) with expectations (>) ... " - diff events.tested.$$.txt events.reference.$$.txt - - if [ $? = 0 ]; then - printf "(MATCH)" - test_done - break - else - printf "Comparison failed, " - if [ $i -ge 2 ]; then - printf "details above. It shouldn't happen second time." - test_failed - else - printf "repeating test once more" - test_skipped - fi - fi - else - printf "Test file not found, " - if [ $i -ge 2 ]; then - printf "it shouldn't happend second time." - test_failed - - echo "* Test file not found. Possible reasons:" - echo "* - Local logger is not running and the file was never created." - echo "* - You have not specified a correct event file prefix." - echo "* Note that you need to give the same prefix used to start" - echo "* the local logger daemon." - echo "" - else - printf "repeating test once more" - fi - fi - done - - echo Cleaning up - $SYS_RM events.tested.$$.txt - $SYS_RM events.reference.$$.txt - $SYS_RM $EVENTFILE_RAW - - #Purge test job - try_purge ${joblist} - - -test_end -} &> $logfile - -if [ $flag -ne 1 ]; then - cat $logfile - $SYS_RM $logfile -fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-logger-local.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-logger-local.sh deleted file mode 100755 index 66520df..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-logger-local.sh +++ /dev/null @@ -1,151 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing the LB logger locally - -Prerequisities: - - LB logger running on local machine - - environment variables set: - - GLITE_LB_LOGGER_PORT - if nondefault port (9002) is used - -Tests called: - - pidof - return instance PIDs of the given binary - mysqladmin ping - check for response by the mysql server - check_socket() - simple tcp echo to all LB server ports - (9002 by default) - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $SYS_LSOF $SYS_GREP $SYS_SED $SYS_PS $SYS_MYSQLADMIN $SYS_PIDOF -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -# logger running: -printf "Testing if LB logger is running" -if [ "$(${SYS_PIDOF} ${LB_LOGD})" ]; then - test_done -else - test_failed - print_error "${LB_LOGD} is not running" -fi - -# logger listening: -printf "Testing if LB logger is listening on port ${GLITE_LB_LOGGER_PORT}" -check_listener ${LB_LOGD} ${GLITE_LB_LOGGER_PORT} -if [ $? -gt 0 ]; then - test_failed - print_error "LB logger is not listening on port ${GLITE_LB_LOGGER_PORT}" -else - test_done -fi - -# interlogger running: -printf "Testing if Interlogger is running" -if [ "$(${SYS_PIDOF} ${LB_INTERLOGD})" ]; then - test_done -else - test_failed - print_error "${LB_INTERLOGD} server is not running" -fi - - -# Interlogger listening on socket: -printf "Testing if interlogger is listening on socket ${GLITE_LB_IL_SOCK}" -check_socket_listener ${LB_INTERLOGD} ${GLITE_LB_IL_SOCK} -if [ $? -gt 0 ]; then - test_failed - print_error "LB interlogger is not listening on socket ${GLITE_LB_IL_SOCK}" -else - test_done -fi - - - -test_end -} &> $logfile - -if [ $flag -ne 1 ]; then - cat $logfile - $SYS_RM $logfile -fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-logger-remote.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-logger-remote.sh deleted file mode 100755 index 2fa55a0..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-logger-remote.sh +++ /dev/null @@ -1,137 +0,0 @@ -#!/bin/bash -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing remotely the LB logger - -Prerequisities: - - LB logger running on remote machine - - environment variables set: - - GLITE_LB_LOGGER_PORT - if nondefault port (9002) is used - -Tests called: - check_binaries() - check if all necessary binaries are locally available - ping_host() - network ping to LB server host - check_socket() - simple tcp echo to the LB logger port - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS] host" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." - echo "" - echo "where host is the LB logger host, it must be specified everytime." -} -if [ -z "$1" ]; then - showHelp - exit 2 -fi - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - *) LB_HOST=$1 ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -###################### -# Starting the test # -###################### - -{ -test_start - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $TEST_SOCKET $SYS_PING $SYS_GREP -if [ $? -gt 0 ]; then - test_failed - print_error "Some binaries are missing" -else - test_done -fi - -# ping_host: -printf "Testing ping to LB logger ${LB_HOST}" -ping_host ${LB_HOST} -if [ $? -gt 0 ]; then - test_failed - print_error "Destination host might be unreachable" -else - test_done -fi - -# check_services -printf "Testing LB logger at ${LB_HOST}:${GLITE_LB_LOGGER_PORT} (logging)" -check_socket ${LB_HOST} ${GLITE_LB_LOGGER_PORT} -if [ $? -gt 0 ]; then - test_failed - print_error "LB logger at ${LB_HOST}:${GLITE_LB_LOGGER_PORT} might be unreachable" -else - test_done -fi - -test_end -} &> $logfile - -if [ $flag -ne 1 ]; then - cat $logfile - $SYS_RM $logfile -fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-nagios-probe.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-nagios-probe.sh deleted file mode 100755 index 66f69a5..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-nagios-probe.sh +++ /dev/null @@ -1,139 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing correct job registration - -Prerequisities: - - LB server - - environment variables set: - - GLITE_WMS_QUERY_SERVER - -Tests called: - - L&B's nagios probe - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -printf "Checking if the probe is available..." - -PROBE="$GLITE_LOCATION/libexec/grid-monitoring/probes/emi.lb/LB-probe" - -if [ -f "$PROBE" ]; then - test_done - - # check_binaries - printf "Testing if all binaries are available" - check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $SYS_CAT - if [ $? -gt 0 ]; then - test_failed - else - test_done - fi - - printf "Testing credentials" - check_credentials_and_generate_proxy - if [ $? != 0 ]; then - test_end - exit 2 - fi - - printf "Running the nagios probe..." - PROBEOUTPUT=`${PROBE} -H $GLITE_WMS_QUERY_SERVER 2> /dev/null` - PROBECODE=$? - - printf " \"$PROBEOUTPUT\", ret. code $PROBECODE" - $SYS_ECHO $PROBEOUTPUT | $SYS_GREP -E "^OK" > /dev/null 2> /dev/null - if [ $? -eq 0 -a $PROBECODE -eq 0 ]; then - test_done - else - if [ "$PROBEOUTPUT" != "" -a $PROBECODE -ne 0 ]; then - test_warning - else - test_failed - fi - fi - -else - printf " Probe not available" - test_skipped -fi - -test_end -} - -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-notif-keeper.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-notif-keeper.sh deleted file mode 100755 index 683fcf8..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-notif-keeper.sh +++ /dev/null @@ -1,331 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing the notif-keeper tool - -Prerequisities: - - LB server - - Event logging chain - - Notification delivery chain (notification interlogger) - - environment variables set: - - GLITE_LOCATION - GLITE_WMS_QUERY_SERVER - GLITE_WMS_LOG_DESTINATION - GLITE_WMS_NOTIF_SERVER - -Tests called: - - notif-keeper on various site-notif wording - registering jobs/sending events - receiving notifications - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." - echo " -f | --file-prefix Notification file prefix, if other than default." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -NOTIFPREFIX="/var/tmp/glite-lb-notif" -NL="\n" -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ; NL="
" ;; - "-f" | "--file-prefix") shift ; NOTIFPREFIX=$1 ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $LBCMSCLIENT $SYS_EXPR $SYS_CURL -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Checking for presence of the notif-keeper tool... " -NOTIFKEEPER=`which $LBNOTIFKEEPER` -if [ ! -f "$NOTIFKEEPER" ]; then - printf "Not present" - test_skipped - exit 0 -fi -test_done - -printf "Checking for presence of the config file (site-notif.conf)... " -if [ ! -f "/etc/glite-lb/site-notif.conf" ]; then - printf "/etc/glite-lb/site-notif.conf not found!" - test_warning -else - test_done -fi - - -printf "Checking for presence of the cron script... " -if [ ! -f "/etc/cron.d/glite-lb-notif-keeper" ]; then - printf "/etc/cron.d/glite-lb-notif-keeper not found!" - test_warning -else - test_done -fi - - - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi -X509_USER_PROXY=`${GRIDPROXYINFO} | ${SYS_GREP} -E "^path" | ${SYS_SED} "s/path\s*:\s//"` -X509_USER=`${GRIDPROXYINFO} | ${SYS_GREP} -E "^identity" | ${SYS_SED} "s/identity\s*:\s//"` - -printf "Using SSL client: " -$SYS_CURL --version | head -n 1 | grep -i NSS/ >/dev/null 2>&1 -if [ $? -eq 0 ]; then - SSL_CMD="wget --no-check-certificate --secure-protocol=SSLv3 --quiet --private-key $X509_USER_PROXY --certificate $X509_USER_PROXY --ca-directory /etc/grid-security/certificates --ca-certificate $X509_USER_PROXY --output-document configuration.$$.tmp" - SSL_CLIENT=wget -else - SSL_CMD="$SYS_CURL --insecure -3 --silent --key $X509_USER_PROXY --cert $X509_USER_PROXY --capath /etc/grid-security/certificates --output configuration.$$.tmp" - SSL_CLIENT=curl -fi -printf "$SSL_CLIENT" -test_done - printf "Reading server configuration" - $SSL_CMD "https://${GLITE_WMS_QUERY_SERVER}/?configuration" - if [ "$?" != "0" ]; then - test_failed - print_error "Could not read server configuration" - exit 2 - else - BROKER=`$SYS_CAT configuration.$$.tmp | $SYS_GREP -E "^msg_brokers=" | $SYS_SED -r 's/^msg_brokers=\s*//' | $SYS_SED -r 's/\s+.*$//' | $SYS_SED 's/tcp:\/\///' | $SYS_SED 's/,.*$//'` - rm configuration.$$.tmp - test_done - fi - - printf "Starting messaging client, listening to broker $BROKER, topic grid.emi.lbtest$$... " - ${LBCMSCLIENT} -o $$_notifications.txt ${BROKER} grid.emi.lbtest$$ > /dev/null & - recpid=$! - - if [ "$recpid" == "" ]; then - test_failed - print_error "Failed to start client" - exit 2 - fi - printf "(PID $recpid)" - test_done - - printf "Giving client time to connect... " - sleep 3 - test_done - - printf "Generating fresh site-notif.conf for testing... " - SITENOTIF=site-notif.$$.conf - - printf "test_x$$\t-o $X509_USER -a x-msg://grid.emi.lbtest$$\n#test_y$$\t-T -a x-msg://grid.emi.lbtest$$\n" > $SITENOTIF - test_done - - printf "Running notif-keeper (notify on all my jobs)... $NL" - $LBNOTIFKEEPER --file-prefix $NOTIFPREFIX --site-notif $SITENOTIF - - printf "Registering job..." - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application 2>&1 | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - if [ "$jobid" == "" ]; then - test_failed - print_error "Failed to register job" - else - test_done - fi - - printf "Waiting for notifications... " - notif_wait 10 ${jobid} $$_notifications.txt - - printf "Checking number of messages delivered... " - NOofMESSAGES=`$SYS_GREP -E "Message #[0-9]* Received" $$_notifications.txt | $SYS_WC -l` - - printf "$NOofMESSAGES. Checking if $NOofMESSAGES = 1... " - cresult=`$SYS_EXPR ${NOofMESSAGES} = 1` - - if [ "$cresult" -eq "1" ]; then - test_done - else - test_failed - print_error "Received $NOofMESSAGES messages" - fi - - > $$_notifications.txt - - printf "Modifying site-notif.conf to notify only on state 'running'" - printf "test_x$$\t-o $X509_USER -c --state running -a x-msg://grid.emi.lbtest$$\n#test_y$$\t-T -a x-msg://grid.emi.lbtest$$\n" > $SITENOTIF - test_done - - printf "Re-running notif-keeper... $NL" - $LBNOTIFKEEPER --file-prefix $NOTIFPREFIX --site-notif $SITENOTIF - - printf "Registering job..." - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application 2>&1 | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - if [ "$jobid" == "" ]; then - test_failed - print_error "Failed to register job" - else - test_done - printf "Sending events resulting in state 'cleared'" - $LB_CLEARED_SH -j $jobid > /dev/null 2> /dev/null - test_done - fi - - printf "Waiting for notifications... " - notif_wait 10 ${jobid} $$_notifications.txt - - printf "Checking number of messages delivered... " - NOofMESSAGES=`$SYS_GREP -E "Message #[0-9]* Received" $$_notifications.txt | $SYS_WC -l` - - printf "$NOofMESSAGES. Checking if $NOofMESSAGES = 1... " - cresult=`$SYS_EXPR ${NOofMESSAGES} = 1` - - if [ "$cresult" -eq "1" ]; then - test_done - else - test_failed - print_error "Received $NOofMESSAGES messages" - fi - - printf "Checking if owner DN is present in the message... " - $SYS_GREP "$X509_USER" $$_notifications.txt >> /dev/null - if [ $? -eq 0 ]; then - test_done - else - test_failed - print_error "Expected owner DN not present in message." - fi - - > $$_notifications.txt - - printf "Modifying site-notif.conf to anonymize states" - printf "test_x$$\t-o $X509_USER -N -a x-msg://grid.emi.lbtest$$\n#test_y$$\t-T -a x-msg://grid.emi.lbtest$$\n" > $SITENOTIF - test_done - - printf "Re-running notif-keeper... $NL" - $LBNOTIFKEEPER --file-prefix $NOTIFPREFIX --site-notif $SITENOTIF - - printf "Registering job..." - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application 2>&1 | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - if [ "$jobid" == "" ]; then - test_failed - print_error "Failed to register job" - else - test_done - printf "Sending events resulting in state 'cleared'" - $LB_CLEARED_SH -j $jobid > /dev/null 2> /dev/null - test_done - fi - - - printf "Waiting for notifications... " - notif_wait 10 ${jobid} $$_notifications.txt - - printf "Checking number of messages delivered... " - NOofMESSAGES=`$SYS_GREP -E "Message #[0-9]* Received" $$_notifications.txt | $SYS_WC -l` - - printf "$NOofMESSAGES. Checking if $NOofMESSAGES >= 1... " - cresult=`$SYS_EXPR ${NOofMESSAGES} \>= 1` - - if [ "$cresult" -eq "1" ]; then - test_done - else - test_failed - print_error "Received $NOofMESSAGES messages" - fi - - printf "Checking if owner DN is present in the message (should not be)... " - $SYS_GREP "$X509_USER" $$_notifications.txt - if [ $? -eq 0 ]; then - test_failed - print_error "Owner DN present in message. Should have been anonymized." - else - printf "nay" - test_done - fi - - - printf "Modifying site-notif.conf to match on nonsensical owner" - printf "test_x$$\t-o nemo -a x-msg://grid.emi.lbtest$$\n#test_y$$\t-T -a x-msg://grid.emi.lbtest$$\n" > $SITENOTIF - test_done - - printf "Re-running notif-keeper... $NL" - $LBNOTIFKEEPER --file-prefix $NOTIFPREFIX --site-notif $SITENOTIF - - kill $recpid >/dev/null 2>&1 - - $SYS_RM $$_notifications.txt $SITENOTIF - -test_end -#} &> $logfile -} - -if [ $flag -ne 1 ]; then - cat $logfile - $SYS_RM $logfile -fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-notif-msg.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-notif-msg.sh deleted file mode 100755 index 43829b0..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-notif-msg.sh +++ /dev/null @@ -1,254 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing notification delivery - -Prerequisities: - - LB server - - Event logging chain - - Notification delivery chain (notification interlogger) - - environment variables set: - - GLITE_LOCATION - GLITE_WMS_QUERY_SERVER - GLITE_WMS_LOG_DESTINATION - GLITE_WMS_NOTIF_SERVER - -Tests called: - - job registration - notification registration - logging events - receiving notifications - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $LBCMSCLIENT $SYS_EXPR $SYS_CURL -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi -X509_USER_PROXY=`${GRIDPROXYINFO} | ${SYS_GREP} -E "^path" | ${SYS_SED} "s/path\s*:\s//"` - -printf "Using SSL client: " -$SYS_CURL --version | head -n 1 | grep -i NSS/ >/dev/null 2>&1 -if [ $? -eq 0 ]; then - SSL_CMD="wget --no-check-certificate --secure-protocol=SSLv3 --quiet --private-key $X509_USER_PROXY --certificate $X509_USER_PROXY --ca-directory /etc/grid-security/certificates --ca-certificate $X509_USER_PROXY --output-document configuration.$$.tmp" - SSL_CLIENT=wget -else - SSL_CMD="$SYS_CURL --insecure -3 --silent --key $X509_USER_PROXY --cert $X509_USER_PROXY --capath /etc/grid-security/certificates --output configuration.$$.tmp" - SSL_CLIENT=curl -fi -printf "$SSL_CLIENT" -test_done - - # Register job: - printf "Registering testing job " - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application 2>&1 | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - else - printf "(${jobid}) " - test_done - fi - - # Register notification: - printf "Registering notification " - - notifid=`${LBNOTIFY} new -j ${jobid} -a x-msg://grid.emi.lbtest | $SYS_GREP "notification ID" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $notifid ]; then - test_failed - print_error "Failed to register notification" - else - printf "(${notifid}) " - test_done - - check_srv_version '>=' "2.3" - if [ $? -eq 0 ]; then - printf "Reading server configuration" - $SSL_CMD "https://${GLITE_WMS_QUERY_SERVER}/?configuration" - if [ "$?" != "0" ]; then - test_failed - print_error "Could not read server configuration" - else - BROKER=`$SYS_CAT configuration.$$.tmp | $SYS_GREP -E "^msg_brokers=" | $SYS_SED -r 's/^msg_brokers=\s*//' | $SYS_SED -r 's/\s+.*$//' | $SYS_SED 's/tcp:\/\///'` - rm configuration.$$.tmp - test_done - fi - - else - printf "Reading from config file" - BROKERLINE=`grep -E "^broker" /etc/glite-lb/msg.conf` - BROKER=`$SYS_ECHO $BROKERLINE | $SYS_AWK '{print $3}' | $SYS_SED 's/^.*\/\///' | $SYS_SED 's/\///g'` - test_done - fi - - if [ ! $BROKER = "" ]; then - - - #Start listening for notifications - - printf "Checking if client supports output files... " - rudver=`${LBCMSCLIENT} | $SYS_GREP '\-o'` - if [ "$rudver" = "" ]; then - printf "No. Connecting to broker $BROKER, topic grid.emi.lbtest" - ${LBCMSCLIENT} ${BROKER} grid.emi.lbtest 2>&1 > $$_notifications.txt & - recpid=$! - else - printf "Yes. Connecting to broker $BROKER, topic grid.emi.lbtest" - ${LBCMSCLIENT} -o $$_notifications.txt ${BROKER} grid.emi.lbtest > /dev/null & - recpid=$! - fi - - test_done - - sleep 2 - - printf "Logging events resulting in DONE state... " - $LB_DONE_SH -j ${jobid} > /dev/null 2> /dev/null - test_done - - printf "Sleep for 20 seconds to give messages time to deliver... " - - sleep 20 - test_done - - kill -n 15 $recpid - - printf "Checking number of messages delivered... " - - NOofMESSAGES=`$SYS_GREP -E "Message #[0-9]* Received" $$_notifications.txt | $SYS_WC -l` - - printf "$NOofMESSAGES. Checking if >= 10... " - - cresult=`$SYS_EXPR ${NOofMESSAGES} \>= 10` - - if [ "$cresult" -eq "1" ]; then - printf "OK" - test_done - else - test_failed - print_error "Fewer messages than expected" - fi - - $SYS_RM $$_notifications.txt - else - printf "Cannot determine broker address" - test_skipped - fi - - - - #Drop notification - printf "Dropping the test notification (${notifid})" - dropresult=`${LBNOTIFY} drop ${notifid} 2>&1` - if [ -z $dropresult ]; then - test_done - else - test_failed - print_error "Failed to drop notification ${dropresult}" - fi - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - try_purge ${joblist} - - fi - -test_end -#} &> $logfile -} - -if [ $flag -ne 1 ]; then - cat $logfile - $SYS_RM $logfile -fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-notif-recovery.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-notif-recovery.sh deleted file mode 100755 index cc4d791..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-notif-recovery.sh +++ /dev/null @@ -1,190 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing delayed notification delivery - -Prerequisities: - - LB server - - Event logging chain - - Notification delivery chain (notification interlogger) - - environment variables set: - - GLITE_LOCATION - GLITE_WMS_QUERY_SERVER - GLITE_WMS_LOG_DESTINATION - GLITE_WMS_NOTIF_SERVER - -Tests called: - - job registration - notification registration - logging events - receiving notifications - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -#touch $logfile -#if [ ! -w $logfile ]; then -# echo "Cannot write to output file $logfile" -# exit $TEST_ERROR -#fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi - # Register job: - printf "Registering testing job " - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application 2>&1 | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - else - printf "(${jobid}) " - test_done - fi - - # Register notification: - printf "Registering notification " - - notifid=`${LBNOTIFY} new -j ${jobid} | $SYS_GREP "notification ID" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $notifid ]; then - test_failed - print_error "Failed to register notification" - else - printf "(${notifid}) " - test_done - - printf "Logging events resulting in DONE state\n" - $LB_DONE_SH -j ${jobid} > /dev/null 2> /dev/null - - sleep 10 - - #Start listening for notifications - ${LBNOTIFY} receive -i 10 ${notifid} > $$_notifications.txt & - recpid=$! - disown $recpid - - printf "Receiving notifications " - notif_wait 10 ${jobid} $$_notifications.txt - kill $recpid >/dev/null 2>&1 - - $SYS_GREP ${jobid} $$_notifications.txt > /dev/null - - if [ $? = 0 ]; then - printf "Notifications were delivered" - test_done - else - printf "Notifications were NOT delivered" - test_failed - fi - - $SYS_RM $$_notifications.txt - - #Drop notification - printf "Dropping the test notification (${notifid})" - dropresult=`${LBNOTIFY} drop ${notifid} 2>&1` - if [ -z $dropresult ]; then - test_done - else - test_failed - print_error "Failed to drop notification ${dropresult}" - fi - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - try_purge ${joblist} - - fi - -test_end -} -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-notif-stream.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-notif-stream.sh deleted file mode 100755 index 54ba937..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-notif-stream.sh +++ /dev/null @@ -1,211 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing stream notifications - -Prerequisities: - - LB server - - Event logging chain - - Notification delivery chain (notification interlogger) - - environment variables set: - - GLITE_LOCATION - GLITE_WMS_QUERY_SERVER - GLITE_WMS_LOG_DESTINATION - GLITE_WMS_NOTIF_SERVER - -Tests called: - - job registration - logging events - notification registration with stream flag - receiving notifications - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input/Other Error - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -#touch $logfile -#if [ ! -w $logfile ]; then -# echo "Cannot write to output file $logfile" -# exit $TEST_ERROR -#fi - -DEBUG=2 -RETURN=2 - -## -# Starting the test -##################### - -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK -if [ $? -gt 0 ]; then - test_failed - exit $RETURN -else - test_done -fi - -printf "Testing credentials" - -while true; do - check_credentials_and_generate_proxy - if [ $? != 0 ]; then - test_end - RETURN=2 - break - fi - RETURN=1 - - check_srv_version '>=' "2.2" - if [ $? -gt 0 ]; then - printf "Capability not detected. This test will be" - test_skipped - break - else - test_done - fi - - # Register job: - printf "Registering job " - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application 2>&1 | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - break - else - printf "(${jobid}) " - test_done - fi - - # and log something: - printf "Logging events resulting in DONE state" - $LB_DONE_SH -j ${jobid} > /dev/null 2> /dev/null - if [ $? -eq 0 ]; then - test_done - else - test_failed - print_error "Failed logging" - break - fi - - sleep 5 - - # Register stream notification: - printf "Registering notification " - - notifid=`${LBNOTIFY} new -j ${jobid} -f 256 | $SYS_GREP "notification ID" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $notifid ]; then - test_failed - print_error "Failed to register notification" - break - fi - printf "(${notifid}) " - test_done - - #Start listening for notifications - ${LBNOTIFY} receive -i 10 ${notifid} > $$_notifications.txt & - recpid=$! - disown $recpid - - printf "Receiving the stream " - notif_wait 10 ${jobid} $$_notifications.txt - kill $recpid >/dev/null 2>&1 - - $SYS_GREP ${jobid} $$_notifications.txt > /dev/null - if [ $? = 0 ]; then - printf "Notifications were delivered" - test_done - else - printf "Notifications were NOT delivered" - test_failed - break - fi - - RETURN=0 - break -done - -$SYS_RM $$_notifications.txt - -#Drop notification -if [ ! -z "${notifid}" ]; then - printf "Dropping the test notification (${notifid})" - dropresult=`${LBNOTIFY} drop ${notifid} 2>&1` - if [ -z $dropresult ]; then - test_done - else - test_failed - print_error "Failed to drop notification ${dropresult}" - fi -fi - -#Purge test job -if [ ! -z "${jobid}" ]; then - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - try_purge ${joblist} -fi - -test_end - -exit $RETURN diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-notif-switch.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-notif-switch.sh deleted file mode 100755 index f02860e..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-notif-switch.sh +++ /dev/null @@ -1,255 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing notification delivery - -Prerequisities: - - LB server - - Event logging chain - - Notification delivery chain (notification interlogger) - - environment variables set: - - GLITE_LOCATION - GLITE_WMS_QUERY_SERVER - GLITE_WMS_LOG_DESTINATION - GLITE_WMS_NOTIF_SERVER - -Tests called: - - job registration - notification registration - logging events - receiving notifications - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi - # Register job: - printf "Registering testing jobs" - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application 2>&1 | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - otherjobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application 2>&1 | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $jobid ] || [ -z $otherjobid ] ; then - test_failed - print_error "Failed to register job" - else - printf "\nold: ${jobid}\nnew:$otherjobid" - test_done - fi - - # Register notification: - printf "Registering notification " - - notifid=`${LBNOTIFY} new -j ${jobid} | $SYS_GREP "notification ID" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $notifid ]; then - test_failed - print_error "Failed to register notification" - else - printf "(${notifid}) " - test_done - - - #Start listening for notifications - ${LBNOTIFY} receive -i 15 ${notifid} > $$_notifications.txt & - recpid=$! - disown $recpid - - printf "Logging events resulting in RUNNING state\n" - $LB_RUNNING_SH -j ${jobid} > /dev/null 2> /dev/null - - sleep 10 - - #$SYS_CAT $$_notifications.txt - - $SYS_GREP ${jobid} $$_notifications.txt > /dev/null - - if [ $? = 0 ]; then - printf "Notifications were delivered" - test_done - else - printf "Notifications were NOT delivered" - test_failed - fi - - $SYS_RM $$_notifications.txt - - - printf "Changing notification ... " - $LBNOTIFY change ${notifid} ${otherjobid} - sleep 5 - - if [ $? = 0 ]; then - printf "$LBNOTIFY change returned OK" - test_done - else - printf "Error on return from $LBNOTIFY change" - test_failed - fi - - kill $recpid >/dev/null 2>&1 - - #Start listening for notifications - ${LBNOTIFY} receive -i 10 ${notifid} > $$_notifications.txt & - recpid=$! - disown $recpid - - printf "Logging events resulting in DONE state for both jobs\n" - $LB_DONE_SH -j ${jobid} > /dev/null 2> /dev/null - $LB_DONE_SH -j ${otherjobid} > /dev/null 2> /dev/null - - sleep 10 - - kill $recpid >/dev/null 2>&1 - - #$SYS_CAT $$_notifications.txt - - #There may be old notifications still arriving for the 1st job - $SYS_GREP ${jobid} $$_notifications.txt > $$_notifications_old.txt - $SYS_GREP -E "Waiting|Ready|Scheduled|Running" $$_notifications_old.txt >> /dev/null - - if [ $? = 0 ]; then - printf "Old notifications for the 1st job still arriving." - test_running - fi - - #There should be no notifications for the 1st job - $SYS_GREP ${jobid} $$_notifications_old.txt | $SYS_GREP -w "Done">> /dev/null - - if [ $? = 0 ]; then - printf "Notifications for the old job were delivered" - test_failed - else - printf "Notifications for the old job were not delivered" - test_done - fi - - #There should be notifications for the 2nd job - $SYS_GREP ${otherjobid} $$_notifications.txt >> /dev/null - - if [ $? = 0 ]; then - printf "Notifications for the new job were delivered" - test_done - else - printf "Notifications for the new job were NOT delivered" - test_failed - fi - - $SYS_RM $$_notifications.txt - $SYS_RM $$_notifications_old.txt - - #Drop notification - printf "Dropping the test notification (${notifid})" - dropresult=`${LBNOTIFY} drop ${notifid} 2>&1` - if [ -z $dropresult ]; then - test_done - else - test_failed - print_error "Failed to drop notification ${dropresult}" - fi - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - echo $otherjobid >> ${joblist} - try_purge ${joblist} - - fi - -test_end -} -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-notif.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-notif.sh deleted file mode 100755 index 44cbfd7..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-notif.sh +++ /dev/null @@ -1,210 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing notification delivery - -Prerequisities: - - LB server - - Event logging chain - - Notification delivery chain (notification interlogger) - - environment variables set: - - GLITE_LOCATION - GLITE_WMS_QUERY_SERVER - GLITE_WMS_LOG_DESTINATION - GLITE_WMS_NOTIF_SERVER - -Tests called: - - job registration - notification registration - logging events - receiving notifications - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -#touch $logfile -#if [ ! -w $logfile ]; then -# echo "Cannot write to output file $logfile" -# exit $TEST_ERROR -#fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" - -timeleft=`${GRIDPROXYINFO} | ${SYS_GREP} -E "^timeleft" | ${SYS_SED} "s/timeleft\s*:\s//"` - -if [ "$timeleft" = "" ]; then - test_failed - print_error "No credentials" -else - if [ "$timeleft" = "0:00:00" ]; then - test_failed - print_error "Credentials expired" - else - test_done - - - # Register job: - printf "Registering testing job " - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application 2>&1 | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - else - printf "(${jobid}) " - test_done - fi - - # Register notification: - printf "Registering notification " - - notifid=`${LBNOTIFY} new -j ${jobid} | $SYS_GREP "notification ID" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $notifid ]; then - test_failed - print_error "Failed to register notification" - else - printf "(${notifid}) " - test_done - - #Start listening for notifications - ${LBNOTIFY} receive ${notifid} > $$_notifications.txt & - recpid=$! - disown $recpid - - printf "Logging events resulting in DONE state\n" - $LB_DONE_SH -j ${jobid} > /dev/null 2> /dev/null - - printf "Receiving notifications " - notif_wait 10 ${jobid} $$_notifications.txt - kill $recpid >/dev/null 2>&1 - - $SYS_GREP ${jobid} $$_notifications.txt > /dev/null - - if [ $? = 0 ]; then - printf "Notifications were delivered" - test_done - else - printf "Notifications were NOT delivered" - test_failed - fi - - $SYS_RM $$_notifications.txt - - #Regress #86772 - printf "Trying to drop invalid NotifID (Regression into bug #86772)..." - ${LBNOTIFY} drop ${jobid} 2>&1 | ${SYS_GREP} "Invalid" > /dev/null - if [ $? = 0 ]; then - printf " EINVAL" - test_done - else - printf " no error reported!" - test_failed - fi - - #Drop notification - printf "Dropping the test notification (${notifid})" - dropresult=`${LBNOTIFY} drop ${notifid} 2>&1` - if [ -z $dropresult ]; then - test_done - else - test_failed - print_error "Failed to drop notification ${dropresult}" - fi - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - try_purge ${joblist} - - fi - fi -fi - -test_end -} -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-packaging.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-packaging.sh deleted file mode 100755 index d41fa99..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-packaging.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script producing errors and warnings due to packaging. - -Prerequisities: - - installed all tested packages - - Scientific Linux: installed rpmlint - - Debian: installed lintian - -Tests called: - - called rpmlint or lintian on the packages - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - - -## -# Starting the test -##################### - -test_start - - -if egrep -i "Debian|Ubuntu" /etc/issue >/dev/null; then - check_lintian \*glite-jobid\* \*glite-lbu\* \*glite-lbjp-\* \*glite-lb-\* emi-lb\* \*glite-security-gss\* \*glite-security-gsoap-plugin\* \*glite-jp-\* - ret=$? -else - check_rpmlint glite-jobid-\* glite-lbjp-\* glite-lb-\* emi-lb-\* - ret=$? -fi - -#printf "Packages compliance..." -#if test $ret -eq 0; then -# test_done -#else -# test_failed -#fi - - -test_end - -exit $TEST_OK diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-permissions.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-permissions.sh deleted file mode 100755 index d78e5a0..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-permissions.sh +++ /dev/null @@ -1,222 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing permission settings on L&B files - -Prerequisities: - - L&B installed, configured and running - - GLITE_USER - GLITE_LOCATION - GLITE_LB_LOCATION_ETC - -Tests called: - - checking file permissions - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -test_perms() -{ -FAIL=0 -for line in `$SYS_CAT $4`;do - if [ -e $line ]; then - $SYS_STAT -c=%A%U%G $line | $SYS_GREP -E "^=$1$2$3" > /dev/null - if [ $? -gt 0 ]; then - print_error "Incorrect permissions for $line" - $SYS_LS -l $line - FAIL=2 - fi - else - printf "File $line does not exist. " - if [ $FAIL = 0 ]; then - FAIL=1 - fi - fi -done - -if [ $FAIL = 2 ]; then - test_failed -else - if [ $FAIL = 1 ]; then - test_skipped - else - test_done - fi -fi -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_CAT $SYS_STAT $SYS_LS -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -if [ "$GLITE_USER" = "" ]; then - GLITE_USER="glite" -fi -if [ "$GLITE_LOCATION" = "" ]; then - GLITE_LOCATION="/opt/glite" -fi -if [ "$GLITE_LB_LOCATION_ETC" = "" ]; then - GLITE_LB_LOCATION_ETC="/opt/glite/etc" -fi -GLITE_HOME=`getent passwd ${GLITE_USER} | cut -d: -f6` - - -#lrwxrwxrwx 1 root root 29 Aug 2 10:31 /etc/glite-lb-dbsetup.sql -> glite-lb/glite-lb-dbsetup.sql -#lrwxrwxrwx 1 root root 37 Aug 2 10:31 /etc/glite-lb-index.conf.template -> glite-lb/glite-lb-index.conf.template -#-r--r--r-- 1 root root 990 May 10 07:50 /etc/glite-lb/harvester-test-dbsetup.sql - -$SYS_CAT << EOF > 400glite -$GLITE_HOME/.certs/hostkey.pem -EOF - -$SYS_CAT << EOF > 644glite -/var/log/glite/glite-lb-lcas.log -/var/log/glite/glite-lb-pproxy-purge.log -/var/log/glite/glite-lb-server-purge.log -$GLITE_HOME/.bashrc -$GLITE_HOME/.certs/hostcert.pem -$GLITE_HOME/.bash_profile -$GLITE_HOME/.bash_logout -EOF - -$SYS_CAT << EOF > 644root -$GLITE_LB_LOCATION_ETC/glite-lb/msg.conf -$GLITE_LB_LOCATION_ETC/glite-lb/log4crc -$GLITE_LB_LOCATION_ETC/glite-lb/glite-lb-index.conf.template -$GLITE_LB_LOCATION_ETC/glite-lb/glite-lb-harvester.conf -$GLITE_LB_LOCATION_ETC/glite-lb/msg.conf.example -$GLITE_LB_LOCATION_ETC/glite-lb/glite-lb-dbsetup.sql -$GLITE_LB_LOCATION_ETC/glite-lb/lcas.db -$GLITE_LB_LOCATION_ETC/glite-lb/glite-lb-authz.conf -$GLITE_LB_LOCATION_ETC/glite-lb/site-notif.conf -$GLITE_LB_LOCATION_ETC/gLiteservices -$GLITE_LB_LOCATION_ETC/logrotate.d/glite-lb-lcas -$GLITE_LB_LOCATION_ETC/logrotate.d/glite-lb-purge -$GLITE_LB_LOCATION_ETC/mysql/conf.d/glite-lb-server.cnf -$GLITE_LOCATION/share/wsdl/glite-lb/glue2.xsd -$GLITE_LOCATION/share/wsdl/glite-lb/LB.wsdl -$GLITE_LOCATION/share/wsdl/glite-lb/LBTypes.wsdl -$GLITE_LOCATION/interface/glite-lb/lb-job-attrs2.xsd -$GLITE_LOCATION/interface/glite-lb/lb-job-record.xsd -$GLITE_LOCATION/interface/glite-lb/lb-job-attrs.xsd -EOF - -$SYS_CAT << EOF > 644or664glite -$GLITE_LB_LOCATION_VAR/glite-lb-bkserverd.pid -$GLITE_LB_LOCATION_VAR/glite-lb-interlogd.pid -$GLITE_LB_LOCATION_VAR/glite-lb-logd.pid -$GLITE_LB_LOCATION_VAR/glite-lb-notif-interlogd.pid -$GLITE_LB_LOCATION_VAR/glite-lb-proxy-interlogd.pid -EOF - -$SYS_CAT << EOF > 755root -$GLITE_LB_LOCATION_ETC/glite-lb/glite-lb-migrate_db2version20 -$GLITE_LOCATION/share/glite-lb/msg-brokers -EOF - -$SYS_CAT << EOF > s700glite -/tmp/lb_proxy_serve.sock -/tmp/lb_proxy_store.sock -/tmp/glite-lb-notif.sock -/tmp/glite-lbproxy-ilog.sock -/tmp/interlogger.sock -EOF - -printf "Checking permissions and ownership for\n Host key... " -test_perms "-r..------" $GLITE_USER $GLITE_USER 400glite - -printf " $GLITE_USER's home dir files... " -test_perms ".rw.r-.r-." $GLITE_USER $GLITE_USER 644glite - -printf " Config files..." -test_perms ".rw.r-.r-." root root 644root - -printf " PIDs..." -test_perms "-rw-r.-r--" $GLITE_USER $GLITE_USER 644or664glite - -printf " Admin scripts..." -test_perms "-rwxr-xr-x" root root 755root - -printf " Sockets... " -test_perms "srw.------" $GLITE_USER $GLITE_USER s700glite - - -$SYS_RM 400glite 644glite 644root 664glite 755root s700glite - -test_end -} - -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-proxy-delivery.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-proxy-delivery.sh deleted file mode 100755 index f0334ce..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-proxy-delivery.sh +++ /dev/null @@ -1,276 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing correct event delivery - -Prerequisities: - - LB delivery chain - logger, interlogger, server - - environment variables set: - - GLITE_LB_SERVER_PORT - if nondefault port (9000) is used - GLITE_WMS_LBPROXY_STORE_SOCK - if nondefault socket /tmp/lb_proxy_store.sock - -Tests called: - - job registration - proxy-based event logging - checking events - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -#touch $logfile -#if [ ! -w $logfile ]; then -# echo "Cannot write to output file $logfile" -# exit $TEST_ERROR -#fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $LBJOBREG $SYS_AWK $LB_READY_SH $LB_RUNNING_SH $LB_DONE_SH $SYS_AWK -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi - # Register job: - printf "Registering testing job " - jobid=`${LBJOBREG} -X ${GLITE_WMS_LBPROXY_STORE_SOCK}store.sock -m ${GLITE_WMS_QUERY_SERVER} -s application | ${SYS_GREP} "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - else - test_done - printf "\nRegistered job: $jobid\n" - fi - - jobstate=`${LBJOBSTATUS} ${jobid} | ${SYS_GREP} "state :" | ${SYS_AWK} '{print $3}'` - printf "Is the testing job ($jobid) in a correct state? $jobstate" - - if [ "${jobstate}" = "Submitted" ]; then - test_done - else - test_failed - print_error "State ${jobstate}: Job is not in appropriate state (Submitted)" - fi - - # log events: - printf "Logging events resulting in READY state... " - $LB_READY_SH -X ${GLITE_WMS_LBPROXY_STORE_SOCK}store.sock -j ${jobid} > /dev/null 2> /dev/null - - printf "Sleeping for 10 seconds... \n" - sleep 10 - - jobstate=`${LBJOBSTATUS} ${jobid} | ${SYS_GREP} "state :" | ${SYS_AWK} '{print $3}'` - printf "Is the testing job ($jobid) in a correct state? $jobstate" - if [ "${jobstate}" = "Ready" ]; then - test_done - else - test_failed - print_error "State ${jobstate}: Job is not in appropriate state (Ready)" - fi - - printf "Logging events for the testing job... " - $LB_RUNNING_SH -X ${GLITE_WMS_LBPROXY_STORE_SOCK}store.sock -j ${jobid} > /dev/null 2> /dev/null - $LB_DONE_SH -X ${GLITE_WMS_LBPROXY_STORE_SOCK}store.sock -j ${jobid} > /dev/null 2> /dev/null - - printf "Sleeping for 10 seconds...\n" - sleep 10 - - jobstate=`${LBJOBSTATUS} ${jobid} | ${SYS_GREP} "state :" | ${SYS_AWK} '{print $3}'` - printf "Testing job ($jobid) is in state: $jobstate" - - if [ "${jobstate}" = "Done" ]; then - test_done - else - test_failed - print_error "State ${jobstate}: Job is not in appropriate state (Done)" - fi - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - - printf "Registering collection (Regression into bug #73206)" - ${LBJOBREG} -X ${GLITE_WMS_LBPROXY_STORE_SOCK}store.sock -m ${GLITE_WMS_QUERY_SERVER} -s application -C -n 2 -S > $$_test_coll_registration.txt - jobid=`$SYS_CAT $$_test_coll_registration.txt | ${SYS_GREP} "new jobid" | ${SYS_AWK} '{ print $3 }'` - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - else - test_done - subjobs=( $(cat $$_test_coll_registration.txt | $SYS_GREP EDG_WL_SUB_JOBID | $SYS_SED 's/EDG_WL_SUB_JOBID.*="//' | $SYS_SED 's/"$//') ) - printf "Collection ID: $jobid\n Subjob 1: ${subjobs[0]}\n Subjob 2: ${subjobs[1]}\nChecking if subjob registration worked... " - - job1jdl=`${LBJOBSTATUS} ${subjobs[0]} | ${SYS_GREP} -E "^jdl :" | ${SYS_AWK} '{print $3}'` - if [ "${job1jdl}" = "(null)" ]; then - test_failed - print_error "Subjob registration did not work (JDL not present: "${job1jdl}")" - else - printf "JDL present" - test_done - fi - - printf "Checking if subjob has stateEnterTime set and > 0 (Regressison into bug #71913)... " - j1stateenter=`${LBJOBSTATUS} ${subjobs[0]} | $SYS_GREP "stateEnterTime :" | $SYS_SED 's/stateEnterTime :\s*//' ` - cresult=`$SYS_EXPR $j1stateenter= \> 0` - if [ "$cresult" -eq "1" ]; then - printf "$j1stateenter (`$SYS_DATE -d @$j1stateenter`)" - test_done - else - test_failed - print_error "stateEnterTime not set" - fi - - - - printf "Logging events for subjobs... " - $LB_READY_SH -X ${GLITE_WMS_LBPROXY_STORE_SOCK}store.sock -j ${subjobs[0]} > /dev/null 2> /dev/null - $LB_DONE_SH -X ${GLITE_WMS_LBPROXY_STORE_SOCK}store.sock -j ${subjobs[1]} > /dev/null 2> /dev/null - - printf "Sleeping for 10 seconds (waiting for events to deliver)...\n" - sleep 10 - - jobstate=`${LBJOBSTATUS} ${subjobs[0]} | ${SYS_GREP} "state :" | ${SYS_AWK} '{print $3}'` - printf "Is the testing job (${subjobs[0]}) in a correct state? $jobstate" - - if [ "${jobstate}" = "Ready" ]; then - test_done - else - test_failed - print_error "State ${jobstate}: Job is not in appropriate state (Ready)" - fi - - jobstate=`${LBJOBSTATUS} ${subjobs[1]} | ${SYS_GREP} "state :" | ${SYS_AWK} '{print $3}'` - printf "Is the testing job (${subjobs[1]}) in a correct state? $jobstate" - - if [ "${jobstate}" = "Done" ]; then - test_done - else - test_failed - print_error "State ${jobstate}: Job is not in appropriate state (Done)" - fi - - - jobstate=`${LBJOBSTATUS} -fullhist $jobid | ${SYS_GREP} -E "^state :" | ${SYS_AWK} '{print $3}'` - printf "Is the collection ($jobid) in a correct state? $jobstate" - - if [ "${jobstate}" = "Waiting" ]; then - test_done - else - test_failed - print_error "State ${jobstate}: Job is not in appropriate state (Waiting)" - fi - - printf "Logging events to clear subjobs... " - $LB_CLEARED_SH -X ${GLITE_WMS_LBPROXY_STORE_SOCK}store.sock -j ${subjobs[0]} > /dev/null 2> /dev/null - $LB_CLEARED_SH -X ${GLITE_WMS_LBPROXY_STORE_SOCK}store.sock -j ${subjobs[1]} > /dev/null 2> /dev/null - - printf "Sleeping for 10 seconds (waiting for events to deliver)...\n" - sleep 10 - - jobstate=`${LBJOBSTATUS} -fullhist $jobid | ${SYS_GREP} -E "^state :" | ${SYS_AWK} '{print $3}'` - printf "Is the collection ($jobid) in a correct state? $jobstate" - - if [ "${jobstate}" = "Cleared" ]; then - test_done - else - test_failed - print_error "State ${jobstate}: Job is not in appropriate state (Cleared)" - fi - fi - - - - - echo ${subjobs[0]} >> ${joblist} - echo ${subjobs[1]} >> ${joblist} - echo $jobid >> ${joblist} - try_purge ${joblist} - - $SYS_RM $$_test_coll_registration.txt - - -test_end -} -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-purge.pl b/org.glite.testsuites.ctb/LB/tests/lb-test-purge.pl deleted file mode 100755 index 5c8e1dc..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-purge.pl +++ /dev/null @@ -1,361 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -use Term::ANSIColor; - -BEGIN{ -$inst = $ENV{GLITE_LB_LOCATION}; -$inst = $ENV{GLITE_LOCATION} unless $inst; -$inst = "/opt/glite" unless $inst; -$sbin = "$inst/sbin"; -$bin = "$inst/bin"; -$test = "$inst/examples"; -$t = "$inst/lib/glite-lb/examples"; if (-d $t) { $test = $t; } -$t = "$inst/lib64/glite-lb/examples"; if (-d $t) { $test = $t; } -$purge = "glite-lb-purge"; -$status = "$test/glite-lb-job_status"; -$log = "$test/glite-lb-job_log"; -$prefix = "/tmp/purge_test_$$"; -$delay = 60; -$html_output = 0; - -$ENV{PATH} .= ":$bin"; -} - -$option = shift; -$server = shift; -$moreopts = shift; - -if ($moreopts =~ m/-x/) { $html_output = 1; } - -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 [-x]\n" unless $server; - -sub logit { - my $ids = shift; - my $prefix = shift; - my $failed = 0; - - for (qw/aborted cleared cancelled waiting done/) { - my $key = $_ eq waiting ? 'other' : $_; - $id = `$test/glite-lb-$_.sh -m $server 2> /dev/null`; - chomp $id; - if ($?) { - test_failed(); - die "$test/glite-lb-$_.sh"; } - $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; -} - -sub print_result { - my ($format,$text) = @_; - print color $format; -# ($c)=qx(stty size)=~/\d+\s+(\d+)/; -# printf "\015%${c}s\n","[ $text ]"; - printf "%s\n","[ $text ]"; - print color 'reset'; -} -sub test_done() { - if ($html_output) { printf ("done
\n"); } - else { print_result ('bold green','done'); } -} -sub test_failed() { - if ($html_output) { printf ("-TEST FAILED-
\n"); } - else { print_result ('bold red','-TEST FAILED-'); } -} -sub test_skipped() { - if ($html_output) { printf ("skipped
\n"); } - else { print_result ('bold yellow','skipped'); } -} -sub test_printf { - if ($html_output) { printf("
"); } - printf "@_\n"; - if ($html_output) { printf("
"); } -} - - -test_printf ("** Hey, purging the whole database..."); -system "$purge --server $server --return-list --aborted=0 --cleared=0 --cancelled=0 --done=0 --other=0"; -if ($!) { - test_failed(); - die "$purge: $!\n"; -} - -test_done(); - -test_printf ("** Logging test jobs\n"); - -if (!logit \%old,"${prefix}_old") { - test_failed(); - die "!! failed\n"; -} - -test_printf ("** So far so good "); -test_done(); - -test_printf ("** sleeping $delay seconds...\n"); -sleep $delay; -test_printf ("** OK, another set of jobs"); -if (!logit \%new,"${prefix}_new") { - test_failed(); - die "!! failed\n"; -} - -test_done(); - -$drain = $delay/10; -test_printf ("** draining other $drain seconds ...\n"); -sleep $drain; - -test_printf ("** test jobs:\n"); - -for (qw/aborted cleared cancelled done other/) { - print "$_:\n\t$old{$_}\n\t$new{$_}\n"; -} - -test_printf ("** Dry run\n"); -$failed = 0; - -$half = $delay/2; -for (qw/aborted cleared cancelled done other/) { - open LIST,"$purge --server $server --dry-run --return-list --$_=${half}s| grep '^https://'|" or die "!! run $purge\n"; - - $id = ; chomp $id; - if ($old{$_} ne $id) { - $failed = 1; - print "!! $old{$_} (old $_) is not there"; - test_failed(); - } - else { - print "${half}s $_ $id "; - test_done(); - } - $id = ; - if ($id) { - $failed = 1; - chomp $id; - print "!! $id should not be there"; - test_failed(); - } - close LIST; - - open LIST,"$purge --server $server --dry-run --return-list --$_=0s | grep '^https://'|" or die "!! run $purge\n"; - - - $cnt = 0; - while ($id = ) { - chomp $id; - if ($old{$_} ne $id && $new{$_} ne $id) { - $failed = 1; - print "!! $id should not be there"; - test_failed(); - } - else { - print "0s $_ $id "; - test_done(); - } - $cnt++; - } - - close LIST; - if ($cnt != 2) { - $failed = 1; - print "!! bad number of $_ jobs ($cnt)"; - test_failed(); - } -} - -if ($failed) { - printf("aborting"); - test_failed(); - die "!! failed!"; } - -test_printf ("** Server defaults\n"); - -open LIST,"$purge --server $server --dry-run --return-list | grep '^https://'|" or die "!! run $purge\n"; - -$failed = 0; -while ($id = ) { - $failed = 1; - printf "$id"; - test_failed(); } - -if ($failed) { - printf "!! Oops, should not do anything, too short defaults?"; - test_failed(); - die "!! failed!"; } - -print "Nothing purged as expected "; -test_done(); - -test_printf ("** Purge the first set of jobs\n"); - -open DUMP,"$purge --server $server --server-dump --aborted=${half}s --cleared=${half}s --cancelled=${half}s --done=${half}s --other=${half}s | grep '^Server dump:'|" - or die "!! run $purge\n"; - -$dump = ; chomp $dump; $dump =~ s/Server dump: //; -close DUMP; - -unless ($dump) { - printf "!! no dump file reported"; - test_failed(); - die "!! failed!"; } -#print "DEBUG: dump file: '$dump'\n"; -@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 "; -test_done(); - -test_printf ("** Purge the rest\n"); -open DUMP,"$purge --server $server --server-dump --aborted=0 --cleared=0 --cancelled=0 --done=0 --other=0 | grep '^Server dump:'|" - or die "!! run $purge\n"; - -$dump = ; chomp $dump; $dump =~ s/Server dump: //; -close DUMP; - -die "!! no dump file reported\n" unless $dump; -#print "DEBUG: dump file: '$dump'\n"; -@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 "; -test_done(); - - -test_printf ("** Anything left?\n"); -open LIST,"$purge --server $server --return-list --dry-run --aborted=0 --cleared=0 --cancelled=0 --done=0 --other=0 | grep '^https://'|" or die "!! $purge\n"; - -$id = ; -close LIST; -die "!! Yes, but should not\n" if $id; -print "No, OK "; -test_done(); - -test_printf ("** Check zombies\n"); -$failed = 0; - -$errfile = $prefix . "_stat_err.tmp"; -$statfile = $prefix . "_stat.tmp"; - -for (values(%old),values(%new)) { - $jobid = $_; - $stat = 'nic moc'; - system("$status $jobid > $statfile 2> $errfile"); - $stat = `cat $statfile | head -2 | tail -1`; - chomp $stat; - $stat =~ s/state :\s*//; - - $exitcode = system("grep \"Identifier removed\" $errfile > /dev/null"); - if ( ! $exitcode ) { print "$jobid returned EIDRM"; } - else { print "$jobid $stat "; } - if ($stat ne 'Purged' && $exitcode ne 0) { $failed = 1; test_failed(); } - else { test_done(); } -} - -die "EIDRM or state Purged should have been returned for zombies\n" if $failed; - -test_printf ("** Check purge by cron"); - -#Trying purger log -$sudoerr=system("sudo -n /bin/cat /etc/cron.d/glite-lb-purge.cron | grep -E \"^[0-9,\\-\\*]\\s[0-9,\\-\\*]\\s[0-9,\\-\\*]\\s[0-9,\\-\\*]\\s[0-9,\\-\\*]\" > /tmp/glite-lb-purge.cron.$$"); -if($sudoerr) { - printf "user not allowed to 'sudo'"; - test_skipped(); - #XXX Just for debugging: - printf("sudoerr=$sudoerr \n"); - system("sudo -n /bin/cat /etc/cron.d/glite-lb-purge.cron"); -} -else { - printf("\nChecking if purge by cron has been set up at all... "); - $purgecronlines = `cat /tmp/glite-lb-purge.cron.$$ | wc -l`; - if ($purgecronlines > 0) { - test_done(); - } - else { - test_failed(); - die "Purging by cron not set up"; - } - - printf("Checking for Common Logging Format headers in cron logfile (Regression into bug #88502)...\n"); - # Store old crontab - system("crontab -l > /tmp/crontab.glite.$$ 2> /dev/null"); - - # Add a new crontab line, change frequency to max. and output to tmp - system("cat /tmp/glite-lb-purge.cron.$$ | sed 's/^[0-9,\\-\\*]\\s[0-9,\\-\\*]\\s[0-9,\\-\\*]\\s[0-9,\\-\\*]\\s[0-9,\\-\\*]/\* \* \* \* \*/' | sed 's/\\/var\\/log\\/glite\\/glite-lb-purger.log/\\/tmp\\/lite-lb-purger.log.$$/g' | crontab"); - - #Give cron time to make a run - system("sleep 60"); - - #Check for expected format - $datepresent=system("grep -E -o '^[a-zA-Z]+\\s+[0-9]+\\s+[0-9]+:[0-9]+:[0-9]+\\s+[a-zA-Z]+\\s+[a-zA-Z0-9.\\-]+:' /tmp/lite-lb-purger.log.$$"); - if ($datepresent) { - test_failed(); - die "Common Logging Format headers not found in the log file."; - } - else { - test_done(); - } - - #Reinstate old crontab - system("cat /tmp/crontab.glite.$$ | crontab"); -} -system("rm -f /tmp/glite-lb-purge.cron.$$ /tmp/crontab.glite.$$ /tmp/lite-lb-purger.log.$$"); - -test_printf ("\n** All tests passed **"); -test_done(); -exit 0; - -END{ unlink glob "${prefix}*" if $prefix; } diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-sandbox-transfer.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-sandbox-transfer.sh deleted file mode 100755 index 8c16ced..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-sandbox-transfer.sh +++ /dev/null @@ -1,766 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing support for logging sandbox transfers - -Prerequisities: - - LB event delivery chain (local logger, interlogger, server) - - environment variables set: - - GLITE_WMS_QUERY_SERVER - LB server address and port - GLITE_LB_LOGGER_PORT - if nondefault port (9002) is used - -Tests called: - - job registration - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $SYS_CAT -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi - # Register job: - printf "Registering testing job " - - ${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application > sbtestjob.$$.out - - jobid=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - seqcode=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "EDG_WL_SEQUENCE" | ${SYS_SED} 's/EDG_WL_SEQUENCE=//' | ${SYS_SED} 's/"//g'` - - $SYS_RM sbtestjob.$$.out - - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - else - test_done - - # Check result - jobstate=`${LBJOBSTATUS} ${jobid} | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Is the testing job ($jobid) in a correct state? $jobstate" - - if [ "${jobstate}" = "Submitted" ]; then - test_done - else - test_failed - print_error "Job has not been submitted" - fi - - printf "Registering input SandBox... " - - $LBREGSANDBOX --jobid $jobid --input --from http://users.machine/path/to/sandbox.file --to file://where/it/is/sandbox.file --sequence $seqcode > sbtestjob.$$.out - - - isbjobid=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "GLITE_LB_ISB_JOBID" | ${SYS_SED} 's/GLITE_LB_ISB_JOBID=//' | ${SYS_SED} 's/"//g'` - isbseqcode=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "GLITE_LB_ISB_SEQUENCE" | ${SYS_SED} 's/GLITE_LB_ISB_SEQUENCE=//' | ${SYS_SED} 's/"//g'` - seqcode=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "GLITE_WMS_SEQUENCE_CODE" | ${SYS_SED} 's/GLITE_WMS_SEQUENCE_CODE=//' | ${SYS_SED} 's/"//g'` - - $SYS_RM sbtestjob.$$.out - - if [ -z $isbjobid ]; then - test_failed - print_error "Failed to register job" - else - printf "$isbjobid" - test_done - - printf "Registering output SandBox... " - $LBREGSANDBOX --jobid $jobid --output --from file://where/it/is/sandbox.file2 --to http://users.machine/path/to/sandbox.file2 --sequence $seqcode > sbtestjob.$$.out - - osbjobid=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "GLITE_LB_OSB_JOBID" | ${SYS_SED} 's/GLITE_LB_OSB_JOBID=//' | ${SYS_SED} 's/"//g'` - osbseqcode=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "GLITE_LB_OSB_SEQUENCE" | ${SYS_SED} 's/GLITE_LB_OSB_SEQUENCE=//' | ${SYS_SED} 's/"//g'` - - $SYS_RM sbtestjob.$$.out - - if [ -z $osbjobid ]; then - test_failed - print_error "Failed to register job" - else - printf "$osbjobid" - test_done - - # *************** Input SB transfer -- will be OK ************************************ - printf "Input SB transfer starting... " - isbseqcode=`$LBLOGEVENT --source LRMS --jobid $isbjobid --sequence $isbseqcode --event FileTransfer --result START` - - if [ -z $isbseqcode ]; then - test_failed - print_error "LogEvent failed" - else - test_done - fi - - sleep 2 - - isbjobstate=`$LBJOBSTATUS $isbjobid | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state... $isbjobstate" - - if [ "${isbjobstate}" = "Running" ]; then - test_done - else - test_failed - print_error "'Running' was expected" - fi - - printf "Input SB transfer finishing... " - isbseqcode=`$LBLOGEVENT --source LRMS --jobid $isbjobid --sequence $isbseqcode --event FileTransfer --result OK` - - if [ -z $isbseqcode ]; then - test_failed - print_error "LogEvent failed" - else - test_done - fi - - sleep 2 - - isbjobstate=`$LBJOBSTATUS $isbjobid | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state... $isbjobstate" - - if [ "${isbjobstate}" = "Done" ]; then - test_done - else - test_failed - print_error "'Done' was expected" - fi - - # *************** Output SB transfer -- will fail ************************************ - printf "Output SB transfer starting... " - osbseqcode=`$LBLOGEVENT --source LRMS --jobid $osbjobid --sequence $osbseqcode --event FileTransfer --result START` - - if [ -z $osbseqcode ]; then - test_failed - print_error "LogEvent failed" - else - test_done - fi - - sleep 2 - - osbjobstate=`$LBJOBSTATUS $osbjobid | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state... $osbjobstate" - - if [ "${osbjobstate}" = "Running" ]; then - test_done - else - test_failed - print_error "'Running' was expected" - fi - - printf "Output SB transfer failing... " - osbseqcode=`$LBLOGEVENT --source LRMS --jobid $osbjobid --sequence $osbseqcode --event FileTransfer --result FAIL --reason "by design"` - - if [ -z $osbseqcode ]; then - test_failed - print_error "LogEvent failed" - else - test_done - fi - - sleep 2 - - osbjobstate=`$LBJOBSTATUS $osbjobid | $SYS_GREP "done_code :" | ${SYS_AWK} '{print $3}'` - printf "Checking Done Code... $osbjobstate" - - if [ "${osbjobstate}" = "DONE_CODE_FAILED" ]; then - test_done - else - test_failed - print_error "'DONE_CODE_FAILED' was expected" - fi - - # ******************** Check relationships ******************************* - printf "Check ISB transfer JobID for computing job... " - isbjobidreported=`$LBJOBSTATUS $jobid | $SYS_GREP "isb_transfer :" | ${SYS_AWK} '{print $3}'` - printf "$isbjobidreported" - - if [ "$isbjobidreported" = "$isbjobid" ]; then - test_done - else - test_failed - print_error "Not returned or no match" - fi - printf "Check OSB transfer JobID for computing job... " - osbjobidreported=`$LBJOBSTATUS $jobid | $SYS_GREP "osb_transfer :" | ${SYS_AWK} '{print $3}'` - printf "$osbjobidreported" - - if [ "$osbjobidreported" = "$osbjobid" ]; then - test_done - else - test_failed - print_error "Not returned or no match" - fi - printf "Check computing Job ID for ISB... " - jobidreported=`$LBJOBSTATUS $isbjobid | $SYS_GREP "ft_compute_job :" | ${SYS_AWK} '{print $3}'` - printf "$jobidreported" - - if [ "$jobidreported" = "$jobid" ]; then - test_done - else - test_failed - print_error "Not returned or no match" - fi - fi - - - fi - - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - echo $isbjobid >> ${joblist} - echo $osbjobid >> ${joblist} - try_purge ${joblist} - - fi - - #******************************* Test sandbox collection ********************************* - - #check_srv_version '>=' "2.2" - #if [ $? = 0 ]; then - test_done - - - # Register job: - printf "Registering testing job " - - ${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application > sbtestjob.$$.out - - jobid=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - seqcode=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "EDG_WL_SEQUENCE" | ${SYS_SED} 's/EDG_WL_SEQUENCE=//' | ${SYS_SED} 's/"//g'` - - $SYS_RM sbtestjob.$$.out - - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - else - test_done - - # register sandbox collection - - printf "Registering input SandBox collection... " - - $LBREGSANDBOX --jobid $jobid --input --from http://users.machine/path/to/sandbox.file --to file://where/it/is/sandbox.file --sequence $seqcode -n 2 > sbtestjob.$$.out 2> sbtestjob.$$.err - - $SYS_GREP "invalid option -- n" sbtestjob.$$.err > /dev/null - - if [ $? -eq 0 ]; then - printf "Capability not detected..." - test_skipped - else - - isbjobid=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "GLITE_LB_ISB_JOBID" | ${SYS_SED} 's/GLITE_LB_ISB_JOBID=//' | ${SYS_SED} 's/"//g'` - isbseqcode=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "GLITE_LB_ISB_SEQUENCE" | ${SYS_SED} 's/GLITE_LB_ISB_SEQUENCE=//' | ${SYS_SED} 's/"//g'` - seqcode=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "GLITE_WMS_SEQUENCE_CODE" | ${SYS_SED} 's/GLITE_WMS_SEQUENCE_CODE=//' | ${SYS_SED} 's/"//g'` - isbsubjobid0=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "EDG_WL_SUB_JOBID\[0\]" | ${SYS_SED} 's/EDG_WL_SUB_JOBID\[0\]=//' | ${SYS_SED} 's/"//g'` - isbsubjobid1=`$SYS_CAT sbtestjob.$$.out | $SYS_GREP "EDG_WL_SUB_JOBID\[1\]" | ${SYS_SED} 's/EDG_WL_SUB_JOBID\[1\]=//' | ${SYS_SED} 's/"//g'` - - printf "Subjobs: " $isbsubjobid0 $isbsubjobid1 - - $SYS_RM sbtestjob.$$.out - - if [ -z $isbjobid ]; then - test_failed - print_error "Failed to register job" - else - printf "$isbjobid" - test_done - - # Prepare list for future purge - - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - echo $isbjobid >> ${joblist} - echo $isbsubjobid0 >> ${joblist} - echo $isbsubjobid1 >> ${joblist} - - # Check relations - - printf "Check ISB transfer JobID for computing job... " - isbjobidreported=`$LBJOBSTATUS $jobid | $SYS_GREP -m 1 "isb_transfer :" | ${SYS_AWK} '{print $3}'` - printf "$isbjobidreported" - - if [ "$isbjobidreported" = "$isbjobid" ]; then - test_done - else - test_failed - print_error "Not returned or no match" - fi - - printf "Check computing Job ID for ISB... " - jobidreported=`$LBJOBSTATUS $isbjobid | $SYS_GREP -m 1 "ft_compute_job :" | ${SYS_AWK} '{print $3}'` - printf "$jobidreported" - - if [ "$jobidreported" = "$jobid" ]; then - test_done - else - test_failed - print_error "Not returned or no match" - fi - - printf "Check computing Job ID for subjob 0... " - jobidreported=`$LBJOBSTATUS $isbsubjobid0 | $SYS_GREP "ft_compute_job :" | ${SYS_AWK} '{print $3}'` - printf "$jobidreported" - - if [ "$jobidreported" = "$jobid" ]; then - test_done - else - test_failed - print_error "Not returned or no match" - fi - - printf "Check transfer Job ID for subjob 0... " - jobidreported=`$LBJOBSTATUS $isbsubjobid0 | $SYS_GREP "parent_job :" | ${SYS_AWK} '{print $3}'` - printf "$jobidreported" - - if [ "$jobidreported" = "$isbjobid" ]; then - test_done - else - test_failed - print_error "Not returned or no match" - fi - - - # Check states - - isbjobstate=`$LBJOBSTATUS $isbjobid | $SYS_GREP -m 1 "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbjobid... $isbjobstate" - - if [ "${isbjobstate}" = "Submitted" ]; then - test_done - else - test_failed - print_error "'Submitted' was expected" - fi - - isbjobstate=`$LBJOBSTATUS $isbsubjobid0 | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbsubjobid0... $isbjobstate" - - if [ "${isbjobstate}" = "Submitted" ]; then - test_done - else - test_failed - print_error "'Submitted' was expected" - fi - - isbjobstate=`$LBJOBSTATUS $isbsubjobid1 | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbsubjobid1... $isbjobstate" - - if [ "${isbjobstate}" = "Submitted" ]; then - test_done - else - test_failed - print_error "'Submitted' was expected" - fi - - # log src/dest for subjob 1 - printf "Logging source and destination for subjob 1" - isbseqcode=`$LBLOGEVENT --source LRMS --jobid $isbsubjobid1 --sequence $isbseqcode --event FileTransferRegister --src http://users.machine/path/to/sandbox.file.1 --dest file://where/it/is/sandbox.file.1` - if [ -z $isbseqcode ]; then - test_failed - print_error "LogEvent failed" - else - test_done - fi - - # Check source - sleep 10 - - isbsubjobsrc1=`$LBJOBSTATUS $isbsubjobid1 | $SYS_GREP "ft_src :" | ${SYS_AWK} '{print $3}'` - - printf "Checking source of $isbsubjobid1... $isbsubjobsrc1" - - if [ "${isbsubjobsrc1}" = "http://users.machine/path/to/sandbox.file.1" ]; then - test_done - else - test_failed - printf "http://users.machine/path/to/sandbox.file.1 was expected" - fi - - # Check destination - - isbsubjobdest1=`$LBJOBSTATUS $isbsubjobid1 | $SYS_GREP "ft_dest :" | ${SYS_AWK} '{print $3}'` - - printf "Checking destination of $isbsubjobid1... $isbsubjobdest1" - - if [ "${isbsubjobdest1}" = "file://where/it/is/sandbox.file.1" ]; then - test_done - else - test_failed - printf "file://where/it/is/sandbox.file.1 was expected" - fi - - - # log START for subjob 1 - printf "Subjob 1 transfer starting... " - isbseqcode=`$LBLOGEVENT --source LRMS --jobid $isbsubjobid1 --sequence $isbseqcode --event FileTransfer --result START` - - if [ -z $isbseqcode ]; then - test_failed - print_error "LogEvent failed" - else - test_done - fi - - # Check states - sleep 2 - - isbjobstate=`$LBJOBSTATUS $isbjobid | $SYS_GREP -m 1 "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbjobid... $isbjobstate" - - if [ "${isbjobstate}" = "Running" ]; then - test_done - else - test_failed - print_error "'Running' was expected" - fi - - isbjobstate=`$LBJOBSTATUS $isbsubjobid1 | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbsubjobid1... $isbjobstate" - - if [ "${isbjobstate}" = "Running" ]; then - test_done - else - test_failed - print_error "'Running' was expected" - fi - - # log OK for subjob 1 - printf "Subjob 1 transfer ending... " - isbseqcode=`$LBLOGEVENT --source LRMS --jobid $isbsubjobid1 --sequence $osbseqcode --event FileTransfer --result OK` - - if [ -z $isbseqcode ]; then - test_failed - print_error "LogEvent failed" - else - test_done - fi - - # Check states - sleep 2 - - isbjobstate=`$LBJOBSTATUS $isbjobid | $SYS_GREP -m 1 "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbjobid... $isbjobstate" - - if [ "${isbjobstate}" = "Waiting" ]; then - test_done - else - test_failed - print_error "'Waiting' was expected" - fi - - isbjobstate=`$LBJOBSTATUS $isbsubjobid1 | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbsubjobid1... $isbjobstate" - - if [ "${isbjobstate}" = "Done" ]; then - test_done - else - test_failed - print_error "'Done' was expected" - fi - - isbjobstate=`$LBJOBSTATUS $isbsubjobid1 | $SYS_GREP "done_code :" | ${SYS_AWK} '{print $3}'` - printf "Checking Done Code... $isbjobstate" - - if [ "${isbjobstate}" = "DONE_CODE_OK" ]; then - test_done - else - test_failed - print_error "'DONE_CODE_OK' was expected" - fi - - # log src/dest for subjob 0 - printf "Logging source and destination for subjob 0" - isbseqcode=`$LBLOGEVENT --source LRMS --jobid $isbsubjobid0 --sequence $isbseqcode --event FileTransferRegister --src http://users.machine/path/to/sandbox.file.0 --dest file://where/it/is/sandbox.file.0` - if [ -z $isbseqcode ]; then - test_failed - print_error "LogEvent failed" - else - test_done - fi - - # Check source - sleep 10 - - isbsubjobsrc0=`$LBJOBSTATUS $isbsubjobid0 | $SYS_GREP "ft_src :" | ${SYS_AWK} '{print $3}'` - - printf "Checking source of $isbsubjobid0... $isbsubjobsrc0" - - if [ "${isbsubjobsrc0}" = "http://users.machine/path/to/sandbox.file.0" ]; then - test_done - else - test_failed - printf "http://users.machine/path/to/sandbox.file.1 was expected" - fi - - # Check destination - - isbsubjobdest0=`$LBJOBSTATUS $isbsubjobid0 | $SYS_GREP "ft_dest :" | ${SYS_AWK} '{print $3}'` - - printf "Checking destination of $isbsubjobid0... $isbsubjobdest0" - - if [ "${isbsubjobdest0}" = "file://where/it/is/sandbox.file.0" ]; then - test_done - else - test_failed - printf "file://where/it/is/sandbox.file.0 was expected" - fi - - # log START for subjob 0 - printf "Subjob 0 transfer starting... " - isbseqcode=`$LBLOGEVENT --source LRMS --jobid $isbsubjobid0 --sequence $osbseqcode --event FileTransfer --result START` - - if [ -z $isbseqcode ]; then - test_failed - print_error "LogEvent failed" - else - test_done - fi - - # Check states - sleep 2 - - isbjobstate=`$LBJOBSTATUS $isbjobid | $SYS_GREP -m 1 "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbjobid... $isbjobstate" - - if [ "${isbjobstate}" = "Running" ]; then - test_done - else - test_failed - print_error "'Running' was expected" - fi - - isbjobstate=`$LBJOBSTATUS $isbsubjobid0 | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbsubjobid0... $isbjobstate" - - if [ "${isbjobstate}" = "Running" ]; then - test_done - else - test_failed - print_error "'Running' was expected" - fi - - # log FAIL for subjob 0 - printf "Subjob 0 transfer ending... " - isbseqcode=`$LBLOGEVENT --source LRMS --jobid $isbsubjobid0 --sequence $osbseqcode --event FileTransfer --result FAIL` - - if [ -z $isbseqcode ]; then - test_failed - print_error "LogEvent failed" - else - test_done - fi - - # Check states - sleep 2 - - isbjobstate=`$LBJOBSTATUS $isbjobid | $SYS_GREP -m 1 "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbjobid... $isbjobstate" - - if [ "${isbjobstate}" = "Waiting" ]; then - test_done - else - test_failed - print_error "'Waiting' was expected" - fi - - isbjobstate=`$LBJOBSTATUS $isbsubjobid0 | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbsubjobid0... $isbjobstate" - - if [ "${isbjobstate}" = "Done" ]; then - test_done - else - test_failed - print_error "'Done' was expected" - fi - - isbjobstate=`$LBJOBSTATUS $isbsubjobid0 | $SYS_GREP "done_code :" | ${SYS_AWK} '{print $3}'` - printf "Checking Done Code... $isbjobstate" - - if [ "${isbjobstate}" = "DONE_CODE_FAILED" ]; then - test_done - else - test_failed - print_error "'DONE_CODE_FAILED' was expected" - fi - - # START and OK subjob 0 - - printf "Subjob 0 starting and ending..." - isbseqcode=`$LBLOGEVENT --source LRMS --jobid $isbsubjobid0 --sequence $osbseqcode --event FileTransfer --result START` - isbseqcode=`$LBLOGEVENT --source LRMS --jobid $isbsubjobid0 --sequence $osbseqcode --event FileTransfer --result OK` - - # Check states - sleep 2 - - isbjobstate=`$LBJOBSTATUS $isbjobid | $SYS_GREP -m 1 "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbjobid... $isbjobstate" - - if [ "${isbjobstate}" = "Done" ]; then - test_done - else - test_failed - print_error "'Done' was expected" - fi - - isbjobstate=`$LBJOBSTATUS $isbjobid | $SYS_GREP -m 1 "done_code :" | ${SYS_AWK} '{print $3}'` - printf "Checking Done Code... $isbjobstate" - - if [ "${isbjobstate}" = "DONE_CODE_OK" ]; then - test_done - else - test_failed - print_error "'DONE_CODE_OK' was expected" - fi - - isbjobstate=`$LBJOBSTATUS $isbsubjobid0 | $SYS_GREP "state :" | ${SYS_AWK} '{print $3}'` - printf "Checking state of $isbsubjobid... $isbjobstate" - - if [ "${isbjobstate}" = "Done" ]; then - test_done - else - test_failed - print_error "'Done' was expected" - fi - - isbjobstate=`$LBJOBSTATUS $isbsubjobid0 | $SYS_GREP "done_code :" | ${SYS_AWK} '{print $3}'` - printf "Checking Done Code... $isbjobstate" - - if [ "${isbjobstate}" = "DONE_CODE_OK" ]; then - test_done - else - test_failed - print_error "'DONE_CODE_OK' was expected" - fi - - try_purge ${joblist} - - printf "Check if purging was allowed..." - $LBJOBSTATUS $jobid > /dev/null 2>/dev/null - if [ $? -gt 0 ]; then - test_done - printf "Test if SB Collection was purged..." - $LBJOBSTATUS $isbjobid > /dev/null 2>/dev/null - if [ $? -gt 0 ]; then - test_done - else - test_failed - fi - - printf "Test if SB Collection subjob was purged..." - $LBJOBSTATUS $isbsubjobid0 > /dev/null 2>/dev/null - if [ $? -gt 0 ]; then - test_done - else - test_failed - fi - - else - test_skipped - fi - fi - fi - $SYS_RM sbtestjob.$$.err - fi - #else - # printf "SB colection capability not detected..." - # test_skipped - #fi - -test_end - -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK -} diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-server-local.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-server-local.sh deleted file mode 100755 index 629bfc0..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-server-local.sh +++ /dev/null @@ -1,190 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing the LB server locally - -Prerequisities: - - LB server running on local machine - - environment variables set: - - GLITE_LB_SERVER_PORT - if nondefault port (9000) is used - -Tests called: - - pidof - return instance PIDs of the given binary - mysqladmin ping - check for response by the mysql server - check_socket() - simple tcp echo to all LB server ports - (by default 9000 for logging, 9001 for querying, 9003 for web services) - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $SYS_LSOF $SYS_GREP $SYS_SED $SYS_PS $SYS_MYSQLADMIN $SYS_PIDOF -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -# mySQL running: -printf "Testing if mySQL is running" -if [ "$(${SYS_PIDOF} ${SYS_MYSQLD})" ]; then - test_done -else - test_failed - print_error "mySQL server is not running" -fi - -# mySQL accessible: -printf "Testing if mySQL is accessible" -if [ "$(${SYS_MYSQLADMIN} ${SYS_PING})" ]; then - test_done -else - test_failed - print_error "mySQL server is not answering" -fi - -# server running: -printf "Testing if LB Server is running" -if [ "$(${SYS_PIDOF} ${LB_SERVER})" ]; then - test_done -else - test_failed - print_error "${LB_SERVER} server is not running" -fi - -# Server listening: -printf "Testing if LB Server is listening on port ${GLITE_LB_SERVER_PORT}" -check_listener ${LB_SERVER} ${GLITE_LB_SERVER_PORT} -if [ $? -gt 0 ]; then - test_failed - print_error "LB server is not listening on port ${GLITE_LB_SERVER_PORT}" -else - test_done -fi - -# Server listening: -printf "Testing if LB Server is listening on port ${GLITE_LB_SERVER_QPORT}" -check_listener ${LB_SERVER} ${GLITE_LB_SERVER_QPORT} -if [ $? -gt 0 ]; then - test_failed - print_error "LB server is not listening on port ${GLITE_LB_SERVER_QPORT}" -else - test_done -fi - -# Server listening: -printf "Testing if LB Server is listening on port ${GLITE_LB_SERVER_WPORT}" -check_listener ${LB_SERVER} ${GLITE_LB_SERVER_WPORT} -if [ $? -gt 0 ]; then - test_failed - print_error "LB server is not listening on port ${GLITE_LB_SERVER_WPORT}" -else - test_done -fi - - -# Interlogger running: -printf "Testing if Interlogger is running" -if [ "$(${SYS_PIDOF} ${LB_INTERLOGD})" ]; then - test_done -else - test_failed - print_error "${LB_INTERLOGD} server is not running" -fi - - -# Interlogger listening on socket: -printf "Testing if interlogger is listening on socket ${GLITE_LB_IL_SOCK}" -check_socket_listener ${LB_INTERLOGD} ${GLITE_LB_IL_SOCK} -if [ $? -gt 0 ]; then - test_failed - print_error "LB interlogger is not listening on socket ${GLITE_LB_IL_SOCK}" -else - test_done -fi - - - -test_end -} &> $logfile - -if [ $flag -ne 1 ]; then - cat $logfile - $SYS_RM $logfile -fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-server-remote.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-server-remote.sh deleted file mode 100755 index 34698c3..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-server-remote.sh +++ /dev/null @@ -1,156 +0,0 @@ -#!/bin/bash -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing remotely the LB server - -Prerequisities: - - LB server running on remote machine - - environment variables set: - - GLITE_LB_SERVER_PORT - if nondefault port (9000) is used - -Tests called: - check_binaries() - check if all necessary binaries are locally available - ping_host() - network ping to LB server host - check_socket() - simple tcp echo to all LB server ports - (by default 9000 for logging, 9001 for querying, 9003 for web services) - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS] host" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." - echo "" - echo "where host is the LB server host, it must be specified everytime." -} -if [ -z "$1" ]; then - showHelp - exit 2 -fi - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - *) LB_HOST=$1 ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $TEST_SOCKET $SYS_PING $SYS_GREP -if [ $? -gt 0 ]; then - test_failed - print_error "Some binaries are missing" -else - test_done -fi - -# ping_host: -printf "Testing ping to LB server ${LB_HOST}" -ping_host ${LB_HOST} -if [ $? -gt 0 ]; then - test_failed - print_error "Destination host might be unreachable" -else - test_done -fi - -# check_services -printf "Testing LB server at ${LB_HOST}:${GLITE_LB_SERVER_PORT} (logging)" -check_socket ${LB_HOST} ${GLITE_LB_SERVER_PORT} -if [ $? -gt 0 ]; then - test_failed - print_error "LB server at ${LB_HOST}:${GLITE_LB_SERVER_PORT} might be unreachable" -else - test_done -fi -# -printf "Testing LB server at ${LB_HOST}:${GLITE_LB_SERVER_QPORT} (queries)" -check_socket ${LB_HOST} ${GLITE_LB_SERVER_QPORT} -if [ $? -gt 0 ]; then - test_failed - print_error "LB server at ${LB_HOST}:${GLITE_LB_SERVER_QPORT} might be unreachable" -else - test_done -fi -# -printf "Testing LB server at ${LB_HOST}:${GLITE_LB_SERVER_WPORT} (web services)" -check_socket ${LB_HOST} ${GLITE_LB_SERVER_WPORT} -if [ $? -gt 0 ]; then - test_failed - print_error "LB server at ${LB_HOST}:${GLITE_LB_SERVER_WPORT} might be unreachable" -else - test_done -fi - -test_end -} &> $logfile - -if [ $flag -ne 1 ]; then - cat $logfile - $SYS_RM $logfile -fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-statistics.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-statistics.sh deleted file mode 100755 index d7a43fe..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-statistics.sh +++ /dev/null @@ -1,325 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing statistic functions provided by the L&B Service - -Prerequisities: - - LB local logger, interlogger, and server running - - environment variables set: - - GLITE_LB_SERVER_PORT - if nondefault port (9000) is used - GLITE_LB_LOGGER_PORT - if nondefault port (9002) is used - GLITE_WMS_QUERY_SERVER - GLITE_WMS_LOG_DESTINATION - -Tests called: - - job registration - event logging - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS] [event file prefix]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." - echo "" -} - -submitted_to_running () { - - EDG_WL_SEQUENCE="UI=000003:NS=0000000000:WM=000000:BH=0000000000:JSS=000000:LM=000000:LRMS=000000:APP=000000:LBS=000000" - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s NetworkServer -e Accepted --from="UserInterface" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid="new jobId (Condor Globus ...)"` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s NetworkServer -e EnQueued --queue="destination queue" --job="job description in receiver language" --result=OK --reason="detailed description of transfer"` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s WorkloadManager -e DeQueued --queue="queue name" --local_jobid="new jobId assigned by the receiving component"` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s WorkloadManager -e HelperCall --helper_name="name of the called component" --helper_params="parameters of the call" --src_role=CALLING` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s WorkloadManager -e Match --dest_id="CE$datestr$$"` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s WorkloadManager -e HelperReturn --helper_name="name of the called component" --retval="returned data" --src_role=CALLING` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s WorkloadManager -e EnQueued --queue="destination queue" --job="job description in receiver language" --result=OK --reason="detailed description of transfer"` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s JobController -e DeQueued --queue="queue name" --local_jobid="new jobId assigned by the receiving component"` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s JobController -e Transfer --destination="LRMS" --dest_host="destination hostname" --dest_instance="destination instance" --job="job description in receiver language" --result=OK --reason="detailed description of transfer" --dest_jobid="destination internal jobid"` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s LogMonitor -e Accepted --from="JobController" --from_host="sending component hostname" --from_instance="sending component instance" --local_jobid="new jobId (Condor Globus ...)"` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s LogMonitor -e Transfer --destination="LRMS" --dest_host="destination hostname" --dest_instance="destination instance" --job="job description in receiver language" --result=OK --reason="detailed description of transfer" --dest_jobid="destination internal jobid"` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s LogMonitor -e Running --node="${CE_NODE:-worker node}"` -} - -running_to_done () { - - EDG_WL_SEQUENCE="UI=000003:NS=0000000004:WM=000010:BH=0000000000:JSS=000004:LM=000006:LRMS=000000:APP=000000:LBS=000000" - - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s LogMonitor -e Done --status_code=OK --reason="reason for the change" --exit_code=0` - EDG_WL_SEQUENCE=`${LBLOGEVENT} -j $1 -c $EDG_WL_SEQUENCE -s LogMonitor -e Clear --reason=USER` -} - - - -# read common definitions and functions -COMMON=lb-common.sh -NOOFJOBS=10 -SEC_COVERAGE=600 -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - "-n" | "--noofjobs") shift ; NOOFJOBS=$1 ;; - *) EVENTFILE=$1 ;; - esac - shift -done - -# redirecting all output to $logfile -#touch $logfile -#if [ ! -w $logfile ]; then -# echo "Cannot write to output file $logfile" -# exit $TEST_ERROR -#fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $LBJOBREG $SYS_AWK $LBJOBSTATUS $SYS_DATE $LB_STATS $LB_FROMTO $SYS_BC -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi - datestr=`$SYS_DATE +%Y%m%d%H%M` - - SEQUENCE=`eval "echo {1..${NOOFJOBS}}"` - - for i in $SEQUENCE - do - # Register job: - jobid[$i]=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application | ${SYS_GREP} "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z ${jobid[$i]} ]; then - test_failed - print_error "Failed to register job" - fi - done - printf "Test jobs registered." - test_done - - printf "Sleeping for 10 seconds... " - - sleep 10 - - printf "Sending events for all test jobs, Submitted => Running " - for i in $SEQUENCE - do - submitted_to_running ${jobid[$i]} - done - test_done - - printf "Sleeping for 10 seconds... " - - sleep 10 - - printf "Sending events for all test jobs, Running => Done " - for i in $SEQUENCE - do - running_to_done ${jobid[$i]} - done - test_done - - printf "Sleeping for 10 seconds... " - - sleep 10 - -# printf "Sending events for all test jobs, Running => Done" -# for i in $SEQUENCE -# do -# running_to_done ${jobid[$i]} -# done -# test_done - - expected_rate=`echo "scale=7;$NOOFJOBS/$SEC_COVERAGE" | bc` - printf "Getting job rate (should be around $expected_rate, testing if > 0): " - #rate=`$LB_STATS -n $SEC_COVERAGE CE$datestr$$ 5 | ${SYS_GREP} "Average" | ${SYS_AWK} '{ print $6 }'` - rate=`$LB_STATS CE$datestr$$ 5 | ${SYS_GREP} "Average" | ${SYS_AWK} '{ print $6 }'` - cresult=`$SYS_ECHO "$rate > 0" | $SYS_BC` - printf "$rate" - if [ "$cresult" -eq "1" ]; then - test_done - else - test_failed - print_error "Rate other than expected" - fi - - printf "Getting average 'Submitted' -> 'Running' transfer time (should be a number > 10): " - $LB_FROMTO CE$datestr$$ 1 5 > fromto.out.$$ - average=`$SYS_CAT fromto.out.$$ | ${SYS_GREP} "Average duration" | ${SYS_AWK} '{ print $5 }'` - cresult=`$SYS_ECHO "$average > 10" | $SYS_BC` - printf "$average" - if [ "$cresult" -eq "1" ]; then - test_done - else - test_failed - print_error "Average value other than expected" - fi - - printf "Getting the dispersion index (should be a number >= 0): " - dispersion=`$SYS_CAT fromto.out.$$ | ${SYS_GREP} "Dispersion index" | ${SYS_AWK} '{ print $3 }'` - cresult=`$SYS_ECHO "$dispersion >= 0" | $SYS_BC` - printf "$dispersion" - if [ "$cresult" -eq "1" ]; then - test_done - else - test_failed - print_error "Dispersion index value other than expected" - fi - - $SYS_RM fromto.out.$$ - - - printf "Getting average 'Submitted' -> 'Done/OK' transfer time (should be a number > 20): " - $LB_FROMTO CE$datestr$$ 1 6 0 > fromto.out.$$ - doneaverage=`$SYS_CAT fromto.out.$$ | ${SYS_GREP} "Average duration" | ${SYS_AWK} '{ print $5 }'` - donecresult=`$SYS_ECHO "$doneaverage > 20" | $SYS_BC` - printf "$doneaverage" - if [ "$donecresult" -eq "1" ]; then - test_done - else - test_failed - print_error "Average value other than expected" - fi - - printf "Comparing. 'Submitted' -> 'Running' should take longer than 'Submitted' -> 'Done/OK': " - - donecresult=`$SYS_ECHO "$doneaverage > $average" | $SYS_BC` - if [ "$donecresult" -eq "1" ]; then - printf "OK" - test_done - else - test_failed - print_error "Done earlier than Running" - fi - - printf "Long term (Regression into bug #73716): Getting average 'Submitted' -> 'Running' transfer times (should be numbers >= 0):" - $LB_FROMTO ALL 1 5 > fromto.out.$$ - averages=( $($SYS_CAT fromto.out.$$ | ${SYS_GREP} "Average duration" | ${SYS_SED} 's/^.*": //' | ${SYS_SED} 's/ s.*$//') ) - $SYS_CAT fromto.out.$$ | ${SYS_GREP} "Average duration" | $SYS_SED 's/":.*$//' | $SYS_SED 's/^.*"//' > fromto.out.ces.$$ - dispersions=( $($SYS_CAT fromto.out.$$ | ${SYS_GREP} "Dispersion index" | ${SYS_AWK} '{ print $3 }') ) - printf "\n" - - let i=0 - $SYS_CAT fromto.out.ces.$$ | while read ce; do - printf "$i.\t$ce:\t${averages[$i]}\t${dispersions[$i]}" - cresult=`$SYS_ECHO "${averages[$i]} >= 0" | $SYS_BC` - if [ "$cresult" -ne "1" ]; then - test_failed - print_error "Bad average value" - fi - # Also check dispersion - cresult=`$SYS_ECHO "${dispersions[$i]} >= 0" | $SYS_BC` - if [ "$cresult" -eq "1" ]; then - test_done - else - test_failed - print_error "Bad dispersion value" - fi - - let i++ - done - - $SYS_RM fromto.out.$$ - $SYS_RM fromto.out.ces.$$ - - printf "Long term: Getting average 'Running' rates (should be numbers >= 0):" - $LB_STATS -n 7200 ALL 5 > rates.out.$$ - rates=( $(${SYS_GREP} "Average" rates.out.$$ | ${SYS_SED} 's/^.*": //' | ${SYS_SED} 's/ jobs.*$//') ) - $SYS_CAT rates.out.$$ | ${SYS_GREP} "Average" | $SYS_SED 's/":.*$//' | $SYS_SED 's/^.*"//' > rates.out.ces.$$ - printf "\n" - - let i=0 - $SYS_CAT rates.out.ces.$$ | while read ce; do - printf "$i.\t$ce:\t${rates[$i]}" - cresult=`$SYS_ECHO "${rates[$i]} >= 0" | $SYS_BC` - if [ "$cresult" -eq "1" ]; then - test_done - else - test_failed - print_error "Bad dispersion value" - fi - - let i++ - done - - $SYS_RM rates.out.$$ - $SYS_RM rates.out.ces.$$ - - - #Purge test job - joblist=$$_jobs_to_purge.txt - for i in $SEQUENCE - do - echo ${jobid[$i]} >> ${joblist} - done - try_purge ${joblist} - - -test_end -} -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-switch-owner.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-switch-owner.sh deleted file mode 100755 index 1335fe3..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-switch-owner.sh +++ /dev/null @@ -1,205 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners/ for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing correct interpretation of ChangeACL events - -Prerequisities: - - LB server, logger, interlogger - - environment variables set: - - GLITE_WMS_QUERY_SERVER - X509_USER_PROXY_BOB - -Tests called: - - job registration - sending a GrantOwnership event - sending a TakeOwnership event - quering and tagging the job using the Bob's certificate - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - -CONT="yes" -while [ "$CONT" = "yes" ]; do - CONT="no" - - # check_binaries - printf "Testing if all binaries are available" - check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK $LBLOGEVENT $LBJOBREG - if [ $? -gt 0 ]; then - test_failed - break - fi - test_done - - printf "Testing credentials" - check_credentials - if [ $? -ne 0 ]; then - test_failed - break - fi - if [ "$X509_USER_PROXY_BOB" = "" ]; then - test_failed - print_error "\$X509_USER_PROXY_BOB must be set" - break - fi - check_credentials $X509_USER_PROXY_BOB - if [ $? -ne 0 ]; then - test_failed - break - fi - test_done - - identity=`${GRIDPROXYINFO} -f $X509_USER_PROXY_BOB| ${SYS_GREP} -E "^identity" | ${SYS_SED} "s/identity\s*:\s//"` - - # Register job: - printf "Registering testing job " - jobid=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - if [ -z $jobid ]; then - test_failed - print_error "Failed to register job" - break - fi - test_done - - printf "Setting payload owner ..." - $LBLOGEVENT -e GrantPayloadOwnership -s UserInterface --payload_owner "$identity" -j "$jobid" > /dev/null - if [ $? -ne 0 ]; then - test_skipped - print_error "Failed to send GrantPayloadOwnership event, skipping the rest" - break - fi - - X509_USER_PROXY=$X509_USER_PROXY_BOB $LBLOGEVENT -e TakePayloadOwnership -s UserInterface -j "$jobid" > /dev/null - if [ $? -ne 0 ]; then - test_failed - print_error "Sending GrantPayloadOwnership failed" - break - fi - test_done - -# sleep 10 - - printf "Testing acquired permissions" - id=`X509_USER_PROXY=$X509_USER_PROXY_BOB $LBJOBSTATUS $jobid | grep "^payload_owner :" | sed 's/^payload_owner : //'` - if [ $? -ne 0 ]; then - test_failed - print_error "Quering server failed" - break - fi - if [ "$id" != "$identity" ]; then - test_failed - print_error "Payload owner not set in status" - break - fi - - X509_USER_PROXY=$X509_USER_PROXY_BOB $LBLOGEVENT -e UserTag -s Application -j $jobid --name "hokus" --value "pokus" > /dev/null - if [ $? -ne 0 ]; then - test_failed - print_error "Sending UserTag failed" - break - fi - -# sleep 10 - - res=`X509_USER_PROXY=$X509_USER_PROXY_BOB $LBJOBSTATUS $jobid 2>/dev/null` - if [ $? -ne 0 ]; then - test_failed - print_error "Quering server failed" - break - fi - echo $res | grep "hokus = \"pokus\"" > /dev/null - if [ $? -ne 0 ]; then - test_failed - print_error "Adding UserTag not allowed" - break - fi - - test_done - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - try_purge ${joblist} -done - -test_end -} &> $logfile - -if [ $flag -ne 1 ]; then - cat $logfile - $SYS_RM $logfile -fi -exit $TEST_OK diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-threaded.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-threaded.sh deleted file mode 100755 index 6fd6115..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-threaded.sh +++ /dev/null @@ -1,178 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for tebasic sting of threaded client - -Prerequisities: - - LB server - - environment variables set: - - GLITE_LB_SERVER_PORT - if nondefault port (9000) is used - -Tests called: - - job registration - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - -# redirecting all output to $logfile -#touch $logfile -#if [ ! -w $logfile ]; then -# echo "Cannot write to output file $logfile" -# exit $TEST_ERROR -#fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $GRIDPROXYINFO $SYS_GREP $SYS_SED $SYS_AWK - -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy -if [ $? != 0 ]; then - test_end - exit 2 -fi - # Register jobs: - - reg_error="0" - printf "Registering testing jobs " - for i in {0..30} - do - printf " $i" - jobid[$i]=`${LBJOBREG} -m ${GLITE_WMS_QUERY_SERVER} -s application | $SYS_GREP "new jobid" | ${SYS_AWK} '{ print $3 }'` - - if [ -z ${jobid[$i]} ]; then - test_failed - print_error "Failed to register a job" - reg_error="1" - fi - done - if [ "$reg_error" = "0" ]; then - test_done - - # Check results - printf "Asking for states of all 30 jobs (Regression into bug #76175)..." - for i in {0..30} - do - jobids="$jobids ${jobid[$i]}" - done - - - #echo $LBTHRJOBSTATUS $jobids - $LBTHRJOBSTATUS $jobids > threads.$$.tmp 2>/dev/null - test_done - - printf "Checking if states were returned for all jobs..." - let grep_error=0 - for i in {0..30} - do - printf " $i" - $SYS_GREP ${jobid[$i]} threads.$$.tmp > /dev/null 2> /dev/null - if [ $? != 0 ]; then - printf "(!)" - let grep_error++ - fi - done - - if [ "$grep_error" = "0" ]; then - test_done - else - test_failed - print_error "Status not retrieved for $grep_error jobs" - fi - - rm threads.$$.tmp - - #Purge test jobs -# joblist=$$_jobs_to_purge.txt -# for i in {0..30} -# do -# echo ${jobid[$i]} >> ${joblist} -# done -# try_purge ${joblist} - - fi - - -test_end -} -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/lb-test-wild.sh b/org.glite.testsuites.ctb/LB/tests/lb-test-wild.sh deleted file mode 100755 index 63308f0..0000000 --- a/org.glite.testsuites.ctb/LB/tests/lb-test-wild.sh +++ /dev/null @@ -1,515 +0,0 @@ -#! /bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# read common definitions and functions -COMMON=lb-common.sh -if [ ! -r ${COMMON} ]; then - echo -en "Common definitions '${COMMON}' missing!\n" - exit 2 -fi -source ${COMMON} - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader - -Launch test in the wild real world against WMS. - -Tests (everything with normal jobs and collections): - - submit - - cancel - - output - - check proper end states (done, aborted, cancelled, cleared) - - all appropriate components send events - -Prerequisities: - - LB server - -Returned values: - Exit $TEST_OK: Test Passed - Exit $TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS] HOST" - echo "Options:" - echo " -h | --help Show this help message." - echo " -n | --number Number of batches (default: 2)." - echo " -v | --vo Virtual organization (default: \`voms-proxy-info --vo\`)" - echo " -w | --world World test (by default limited on CESNET node)" - echo " -t | --test Type of test (default: all). Possible tests:" - echo " done fail cancel done_coll fail_coll cancel_coll all" - echo " -f | --format output format (default: color), color/html/text" - echo "" - echo "where HOST is the LB server host, it must be specified everytime." - echo "" - echo "Example for low intrusive test (one job only per test and sequentially):" - echo " for t in done fail cancel done_coll fail_coll cancel_coll; do" - echo " ./lb-test-wild.sh -n 1 -w -f html --test \$t" - echo " done" -} - - -function fatal() { - ret=$1 - shift - print_error " $@" - exit $ret -} - - -if [ -z "$1" ]; then - showHelp - exit 2 -fi -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-n" | "--number") shift && N=$1 ;; - "-v" | "--vo") shift && VO="$1" ;; - "-w" | "--world") NOREQ='#' ;; - "-t" | "--test") - shift - TEST="$1" - if test x"$TEST" = x"all"; then unset TEST; fi - ;; - "-f" | "--format") - shift - case "$1" in - "text") setOutputASCII ;; - "color") setOutputColor ;; - "html") setOutputHTML ;; - esac - ;; - -*) ;; - *) LB_HOST=$1 ;; - esac - shift -done - - -N=${N:-2} -voms-proxy-info >/dev/null || fatal 2 "No VOMS proxy certificate!" -if test -z "$VO"; then - VO=`voms-proxy-info --vo` -fi -if test -z "$VO"; then - fatal 2 "No VO!" -fi - -JDL_HEADER="LBAddress = \"$LB_HOST\"; -VirtualOrganisation = \"$VO\"; -${NOREQ}Requirements = other.GlueCEInfoHostname==\"ce2.egee.cesnet.cz\"; - -RetryCount=2;" - - -# $1 - description -# $2 - file prefix -function submit() { - echo -n "[wild] submit ($1 test): " - glite-wms-job-submit -a $2.jdl >"submit-$2.log" || fatal $TEST_ERROR "Can't submit job ($1 test)" - date '+%Y-%m-%d %H:%M:%S' >> log - cat "submit-$2.log" >> log - jobid=`cat "submit-$2.log" | $SYS_GREP ^https:` - echo -en "$jobid${lf}" - echo "$jobid $2" >> wild-joblist.txt - rm -f "submit-$2.log" - - i=${#jobs[*]} - jobs[$i]=$jobid - job_cats[$i]="$2"; -} - - -# $2 - jobid -function cancel() { - echo -en "[wild] cancel $1${lf}" - echo "y" | glite-wms-job-cancel $1 >>log || fatal $TEST_ERROR "Can't cancel job $1" -} - - -function submit_fail() { -cat > fail.jdl < launch.sh < done.jdl < launch.sh < fail_coll.jdl < launch.sh < done_coll.jdl <$$.stat.log || fatal 2 "Can't get job status" - status=`cat $$.stat.log | $SYS_GREP '^Current Status: ' | $SYS_SED -e 's/^Current Status: [ \t]*\([a-zA-Z]*\).*/\1/'` - if [ x"$status" != x"$prev_status" ]; then - date '+%Y-%m-%d %H:%M:%S' >> log - cat $$.stat.log >> log - - if [ x"${job_cats[$1]}" != x"" ]; then - desc=" (${job_cats[$1]} test)"; - else - desc="" - fi - date '+[wild] %Y-%m-%d %H:%M:%S ' | tr -d '\n' - echo -en "$jobid $status$desc${lf}" - stats[$1]="$status" - fi - rm -f $$.stat.log -} - - -# -- init -- - -rm -f log -touch $$.err -[ ! -z "${LB_HOST}" ] || fatal 2 "No L&B server specified!" - -check_binaries $SYS_GREP $SYS_SED || fatal 2 "not all needed system binaries available" - -fail=$TEST_OK - -# -- launch the beast -- - -{ -test_start - -for ((pass=0;pass> log -done - - -# -- check states -- -for ((i=0;i $$.ulm.log || fatal $TEST_ERROR "Can't query events for '$jobid'" - components=`cat $$.ulm.log | head -n -1 | $SYS_GREP -v '^$' | $SYS_SED -e 's/.*DG\.SOURCE="\([^"]*\)".*/\1/' | sort -f | uniq | tr '\n' ' ' | $SYS_SED 's/ $//'` - rm -f $$.ulm.log - - expected_status='' - expected_components='' - nocategory='' - case "${job_cats[$i]}" in - done) - expected_status='Done' - expected_components='JobController LogMonitor LRMS NetworkServer WorkloadManager' - ;; - done_coll) - expected_status='Done' - expected_components='LBServer NetworkServer WorkloadManager' - ;; - fail) - expected_status='Aborted' - expected_components='JobController LogMonitor LRMS NetworkServer WorkloadManager' - ;; - fail_coll) - expected_status='Aborted' - expected_components='LBServer NetworkServer WorkloadManager' - ;; - cancel) - expected_status='Cancelled' - expected_components='JobController LogMonitor NetworkServer WorkloadManager' - ;; - cancel_coll) - expected_status='Cancelled' - expected_components='NetworkServer WorkloadManager' - ;; - *) - nocategory="no category" - ;; - esac - - if test x"$nocategory" != x""; then - printf "[wild] $jobid: '$status' OK (no category)" && test_done - else - if test x"$expected_status" = x"$status"; then - printf "[wild] $jobid: '$status' OK (${job_cats[$i]})" && test_done - else - if test x"${job_cats[$i]}" = x"cancel_coll" -a x"$status" = x"Cleared"; then - printf "[wild] $jobid: expected '$expected_status', got '$status' (${job_cats[$i]}), so be it!" && test_done - else - print_error "$jobid: expected '$expected_status', got '$status'!" && test_failed - fail=$TEST_ERROR - fi - fi - - if test x"$expected_components" = x"$components"; then - printf "[wild] components: $components OK" && test_done - else - case "${job_cats[$i]}" in - cancel|cancel_coll) - echo -en "[wild] components: $components ?${lf}" - ;; - *) - print_error " components: $components DIFFERS " && test_failed - fail=$TEST_ERROR - ;; - esac - fi - fi -done -echo -en "[wild] ================================${lf}" - - -# -- only for done jobs: fetch output -- - -echo -en "[wild] job output test${lf}" -mkdir -p "jobOutput.$$" 2>/dev/null -for ((i=0; i<${#job_cats[*]}; i++)); do - jobid="${jobs[$i]}" - case "${job_cats[$i]}" in - done) - echo -en "[wild] fetching output from $jobid${lf}" - echo "y" | glite-wms-job-output --dir "jobOutput.$$/$i" "$jobid" >> log - if test "$?" = "0"; then - printf "[wild] output of '$jobid' fetched" && test_done - else - print_error "can't fetch output from $jobid!" && test_failed - fail=$TEST_ERROR - fi - ;; - done_coll) - echo -en "[wild] fetching output from $jobid${lf}" - glite-wms-job-status -v 0 "$jobid" | $SYS_GREP '^ .*https:' | $SYS_SED 's/.*https:/https:/' > $$.subjobs.log - if test x"`wc -l $$.subjobs.log | $SYS_SED 's/\s*\([0-9]*\).*/\1/'`" != x"2"; then - print_error "error, some offspring of $jobid were spawned or eaten!" && test_failed - fail=$TEST_ERROR - fi - j=1 - for subjobid in `cat $$.subjobs.log`; do - echo "y" | glite-wms-job-output --dir "jobOutput.$$/$i-$j" "$subjobid" >> log - if test "$?" = "0"; then - printf "[wild] output of $subjobid ($j. offspring of $jobid) fetched" && test_done - else - print_error "can't fetch output from $subjobid!" && test_failed - fail=$TEST_ERROR - fi - j=$((j+1)) - done - rm -f $$.subjobs.log - ;; - esac -done - - -# -- result data -- -echo -n "[wild] outputs: " -find "jobOutput.$$" -type f -echo -en "${lf}" - - -# -- only for done jobs: wait for cleared -- - -n=${#jobs[*]} -quit=0 -cleared_fail=0 -echo -en "[wild] waiting for cleared states...${lf}" -while test $quit -eq 0; do - quit=1 - for ((i=0;iSUBMITTED" >> /dev/null - if [ $? = 0 ]; then - test_done - else - test_failed - print_error "Job has not been submitted" - fi - - #(regresion-test Savannah Bug 77002) - printf "Checking if doneCode unset for job not yet done (Regression into bug #77002)... " - check_srv_version '>=' "2.2" - if [ $? = 0 ]; then - doneCode=`${LBWSJOBSTATUS} -m ${servername}:${GLITE_LB_SERVER_WPORT} -j ${jobid} | ${SYS_GREP} status | ${SYS_GREP} doneCode | ${SYS_SED} 's/^.*//' | ${SYS_SED} 's/<\/doneCode>.*$//'` - - printf "($doneCode)" - - if [ "$doneCode" = "" ]; then - test_done - else - test_failed - print_error "doneCode value $doneCode unexpected" - fi - else - test_skipped - fi - - printf "Is it possible to retrieve events?" - - ${LBWSJOBLOG} -j ${jobid} -m ${servername}:${GLITE_LB_SERVER_WPORT} | $SYS_GREP "" >> /dev/null - if [ $? = 0 ]; then - test_done - else - test_failed - print_error "Job has not been submitted" - fi - - printf "Is it possible to retrieve AGU activity info?" - check_binaries ${LB4AGUACTINFO} ${LB4AGUACTSTATUS} - if [ $? -gt 0 ]; then - test_missed - else - ${LB4AGUACTINFO} -j ${jobid} -m ${servername}:${GLITE_LB_SERVER_WPORT} | $SYS_GREP "${jobid}" >> /dev/null - if [ $? = 0 ]; then - test_done - else - test_failed - print_error "Job Activity Info returned" - fi - - printf "Does AGU activity status return correct state?" - - ${LB4AGUACTSTATUS} -j ${jobid} -m ${servername}:${GLITE_LB_SERVER_WPORT} | $SYS_GREP "urn:org.glite.lb:Submitted" >> /dev/null - if [ $? = 0 ]; then - test_done - else - test_failed - print_error "Reported status is Running" - fi - fi - - #Purge test job - joblist=$$_jobs_to_purge.txt - echo $jobid > ${joblist} - try_purge ${joblist} - - fi - - printf "Getting server version... " - servername=`echo ${GLITE_WMS_QUERY_SERVER} | ${SYS_SED} "s/:.*//"` - wsglservver=`$LBWSGETVERSION -m ${servername}:${GLITE_LB_SERVER_WPORT} | $SYS_SED 's/^.*Server version:\s*//'` - if [ "$wsglservver" = "" ]; then - test_failed - else - printf "$wsglservver" - test_done - fi - - printf "Getting WS interface version (Regression into bug #37335)... " - check_srv_version '>=' "2.2" - if [ $? = 0 ]; then - wsglifver=`$LBWSGETVERSION -i -m ${servername}:${GLITE_LB_SERVER_WPORT} | $SYS_SED 's/^.*Interface version:\s*//'` - if [ "$wsglifver" = "" ]; then - test_failed - else - printf "$wsglifver" - test_done - fi - - printf "Check if test runs on server... " - localname=`$SYS_HOSTNAME -f` - - if [ "$servername" = "$localname" ]; then - egrep -i "Debian|Ubuntu" /etc/issue >/dev/null 2>&1 - if [ $? = 0 ]; then - printf "Get dpkg version... " - sysversion=`$SYS_DPKG_QUERY -W glite-lb-ws-interface | $SYS_SED 's/^[^ \t]*\s\+//' | $SYS_SED 's/-.*//'` - else - printf "Get rpm version... " - sysversion=`$SYS_RPM -qi glite-lb-ws-interface | $SYS_GREP -E "^Version" | $SYS_SED 's/^Version\s*:\s*//' | $SYS_SED 's/\s.*$//'` - fi - - if [ "$sysversion" = "" ]; then - printf "Unable to detect installed package version" - test_skipped - else - printf "$sysversion" - test_done - - printf "Comparing versions ($wsglifver = $sysversion)... " - - if [ "$wsglifver" = "$sysversion" ]; then - test_done - else - test_failed - print_error "Reported version differs from that indicated by RPM" - fi - fi - else - printf "No" - test_skipped - fi - else - test_skipped - fi - -test_end -#} &> $logfile -} - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/LB/tests/test-common.sh b/org.glite.testsuites.ctb/LB/tests/test-common.sh deleted file mode 100644 index 15ed38e..0000000 --- a/org.glite.testsuites.ctb/LB/tests/test-common.sh +++ /dev/null @@ -1,260 +0,0 @@ -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# ------------------------------------------------------------------------------ -# Definition of test script return messages -# -# The test scripts should use the variables test_done and test_failed to -# report whether they failed or succeeded. -# -# The variable test_reset is used to turn off all attributes and switch -# to the standard character set. -# -# \033 ascii ESCape -# \033[G move to column (linux console, xterm, not vt100) -# \033[C move columns forward but only upto last column -# \033[D move columns backward but only upto first column -# \033[A move rows up -# \033[B move rows down -# \033[1m switch on bold -# \033[31m switch on red -# \033[32m switch on green -# \033[33m switch on yellow -# \033[m switch off color/bold -# \017 exit alternate mode (xterm, vt100, linux console) -# \033[10m exit alternate mode (linux console) -# \015 carriage return (without newline) -# -# See also United Linux or OpenSUSE /etc/rc.status script -# -# ------------------------------------------------------------------------------ - -# Do _not_ be fooled by non POSIX locale -LC_ALL=POSIX -export LC_ALL - -# Seek for terminal size and, if needed, set default size -if [ -z "${LINES}" -o -z "${COLUMNS}" ]; then - stty_size=`stty size 2> /dev/null` - if [ $? = 0 ]; then - LINES=`echo ${stty_size} | awk '{print $1}'` - COLUMNS=`echo ${stty_size} | awk '{print $2}'` - else - LINES=24 - if [ $LBTSTCOLS -gt 0 ]; then - COLUMNS=$LBTSTCOLS - else - COLUMNS=80 - fi - fi -fi -if [ ! $LINES -ge 0 ]; then LINES=24; fi -if [ ! $COLUMNS -ge 0 ]; then COLUMNS=80; fi -export LINES COLUMNS - -# default return values -TEST_ERROR=1 -TEST_OK=0 - -# test error file -testerrfile=$$.err - -function set_test() -{ -test_done="${spacefill}${begin_green}done${end_green}" -test_running="${spacefill}${begin_green}running${end_green}" -test_failed="${spacefill}${begin_red}-TEST FAILED-${end_red}" -test_missed="${spacefill}${begin_red}missing${end_red}" -test_skipped="${spacefill}${begin_yellow}skipped${end_yellow}" -test_warning="${spacefill}${begin_yellow}warning${end_yellow}" -test_dead="${spacefill}${begin_red}dead${end_red}" -test_unused="${spacefill}${begin_bold}unused${end_bold}" -test_unknown="${spacefill}${begin_yellow}unknown${end_yellow}" - -test_start="${spacefill}${begin_green}start${end_green}" -test_end="${spacefill}${begin_green}end${end_green}" -} - -function test_done() { printf "${test_done}${lf}"; } -function test_running() { printf "${test_running}${lf}"; } -function test_failed() { printf "${test_failed}${lf}"; } -function test_missed() { printf "${test_missed}${lf}"; } -function test_skipped() { printf "${test_skipped}${lf}"; } -function test_warning() { printf "${test_warning}${lf}"; } -function test_dead() { printf "${test_dead}${lf}"; } -function test_unused() { printf "${test_unused}${lf}"; } -function test_unknown { printf "${test_unknown}${lf}"; } -function test_start() { - syslog "${test_start}"; - reset_error -} -function test_end() { - syslog "${test_end}"; - reset_error -} - -# set output to ASCII (without colors) -function setOutputASCII() -{ -lf="\n" -spacefill="..." - -begin_bold="" -begin_black="" -begin_red="" -begin_green="" -begin_yellow="" -begin_blue="" -begin_magenta="" -begin_cyan="" -begin_white="" - -end_bold="" -end_black="" -end_red="" -end_green="" -end_yellow="" -end_blue="" -end_magenta="" -end_cyan="" -end_white="" - -set_test -} - -# set output to ASCII with ANSI colors -function setOutputColor() -{ -local esc=`echo -en "\033"` -local normal="${esc}[0m" # unsets color to term's fg color -lf="\n" -spacefill=`echo -en "\015${esc}[${COLUMNS}C${esc}[15D"` - -begin_bold="${esc}[0;1m" -begin_black="${esc}[0;30m" -begin_red="${esc}[0;31m" -begin_green="${esc}[0;32m" -begin_yellow="${esc}[0;33m" -begin_blue="${esc}[0;34m" -begin_magenta="${esc}[0;35m" -begin_cyan="${esc}[0;36m" -begin_white="${esc}[0;37m" - -end_bold="$normal" -end_black="$normal" -end_red="$normal" -end_green="$normal" -end_yellow="$normal" -end_blue="$normal" -end_magenta="$normal" -end_cyan="$normal" -end_white="$normal" - -set_test -} - -# set output to HTML -function setOutputHTML() -{ -local ENDFONT="
" -lf="
\n" -spacefill="   " -is_html=1 - -begin_bold="" -begin_black="" -begin_red="" -begin_green="" -begin_yellow="" -begin_blue="" -begin_magenta="" -begin_cyan="" -begin_white="" - -end_bold="" -end_black="$ENDFONT" -end_red="$ENDFONT" -end_green="$ENDFONT
" -end_yellow="$ENDFONT
" -end_blue="$ENDFONT
" -end_magenta="$ENDFONT
" -end_cyan="$ENDFONT
" -end_white="$ENDFONT" - -set_test -} - -function reset_error() -{ - rm -f $testerrfile -} - -function set_error() -{ - printf "%s ${lf}" "$*" > $testerrfile -} - -function update_error() -{ - printf "%s; " "$*" >> $testerrfile -} - -function print_error() -{ - printf "\t${begin_red}Error${end_red}: %s ${lf}" "$*" - - if [ -f $testerrfile ]; then - printf "\t${begin_red}Error${end_red}: %s ${lf}" "`cat $testerrfile`" - fi - reset_error -} - -function print_warning() -{ - printf "${begin_magenta}Warning${end_magenta}: %s ${lf}" "$*" -} - -function print_info() -{ - printf "${begin_blue}Info${end_blue}: %s ${lf}" "$*" -} - -function print_newline() -{ - printf "${lf}" -} - -function syslog() -{ - local tmp="`date +'%b %d %H:%M:%S'` `hostname` $progname" - printf "${begin_bold}${tmp}${end_bold}: %s ${lf}" "$*" -} - -function dprintf() -{ - if [ $DEBUG -gt 0 ]; then - printf "%s${lf}" "$*" - fi -} - -# by default set output to color if possible -if test -t 1 -a "$TERM" != "raw" -a "$TERM" != "dumb" && stty size <&1 > /dev/null 2>&1 ; then - setOutputColor -else - setOutputASCII -fi - diff --git a/org.glite.testsuites.ctb/LB/tests/testSocket.c b/org.glite.testsuites.ctb/LB/tests/testSocket.c deleted file mode 100755 index aedcd9b..0000000 --- a/org.glite.testsuites.ctb/LB/tests/testSocket.c +++ /dev/null @@ -1,73 +0,0 @@ -#ident "$Header$" -/* -Copyright (c) Members of the EGEE Collaboration. 2004-2010. -See http://www.eu-egee.org/partners for details on the copyright holders. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUFFSIZE 32 - -int main (int argc, char *argv[]) { - int sock; - struct hostent *hip; - char *adrIPp; - struct in_addr adrIP; - struct sockaddr_in echoserver; - char buffer[BUFFSIZE]; - unsigned int echolen; - int received = 0; - if (argc != 3) { - fprintf(stderr, "USAGE: TCPecho \n"); - exit(1); - } -/* conversion from DNS to IPv4 */ - if ((hip = gethostbyname (argv[1])) == NULL) { - fprintf(stderr,"Error with gethostbyname: %s",strerror(errno)); -// exit(1); - } - adrIP.s_addr = *(int *) hip->h_addr; - adrIPp = (char *) inet_ntoa (adrIP); -/* Create the TCP socket */ - if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - fprintf(stderr,"Failed to create socket: %s",strerror(errno)); - exit(1); - } -/* Construct the server sockaddr_in structure */ - memset (&echoserver, 0, sizeof (echoserver)); /* Clear struct */ - echoserver.sin_family = AF_INET; /* Internet/IP */ - echoserver.sin_addr.s_addr = inet_addr (adrIPp); /* IP address */ - echoserver.sin_port = htons (atoi (argv[2])); /* server port */ -// fprintf(stdout,"Connecting to: %s:%s\n", adrIPp, argv[2]); -/* Establish connection */ - if (connect (sock, (struct sockaddr *) &echoserver, sizeof (echoserver)) < 0) { - //Die ("Failed to connect with server"); - fprintf(stderr,"Failed to connect with server (%s:%d): %s",adrIPp,atoi(argv[2]),strerror(errno)); - exit(1); - } - shutdown (sock, 2); -// fprintf(stdout," [OK]\n"); - exit(0); -} diff --git a/org.glite.testsuites.ctb/PX/tests/px-autonomous-test.sh b/org.glite.testsuites.ctb/PX/tests/px-autonomous-test.sh deleted file mode 100755 index 0e142d9..0000000 --- a/org.glite.testsuites.ctb/PX/tests/px-autonomous-test.sh +++ /dev/null @@ -1,199 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -This script is intended for running a fully automated deployment and functionality test of MyProxy configurations and proxy renewal - -Prerequisities: -New empty machine, certificates - -Tests called: - Deployment - The full PX Functional Test Suite - -EndHelpHeader - - echo "Usage: $progname [OPTIONS] hostname" - echo "Options:" - echo " -h | --help Show this help message." -} - -STARTTIME=`date +%s` - -egrep -i "Debian|Ubuntu" /etc/issue -if [ \$? = 0 ]; then - INSTALLCMD="apt-get install -q --yes" - INSTALLPKGS="lintian" -else - INSTALLCMD="yum install -q -y --nogpgcheck" - INSTALLPKGS="rpmlint" -fi - -$INSTALLCMD wget - -# read common definitions and functions -for COMMON in px-common.sh test-common.sh px-common-testbeds.sh -do - if [ ! -r ${COMMON} ]; then - printf "Downloading common definitions '${COMMON}'" - wget -O ${COMMON} http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/PX/tests/$COMMON?view=co > /dev/null - if [ ! -r ${COMMON} ]; then - exit 2 - else - test_done - fi - fi -done -source px-common.sh -source px-common-testbeds.sh -#also read L&B common definitions for common functions. -if [ ! -r lb-common-testbeds.sh ]; then - printf "Downloading common definitions 'lb-common-testbeds.sh'" - wget -O lb-common-testbeds.sh http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/LB/tests/lb-common-testbeds.sh?view=co > /dev/null - if [ ! -r lb-common-testbeds.sh ]; then - exit 2 - else - test_done - fi -fi -source lb-common-testbeds.sh - - -printf "Getting the 'install' script... " -# Example script, for real tests it should be downloaded or otherwise obtained -SCENARIO=${SCENARIO:-"Clean installation"} -test -s PXinstall.sh || cat << EndInstallScript > PXinstall.sh -rpm -Uvhi http://dl.fedoraproject.org/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm -yum install -y yum-priorities yum-protectbase -rpm -i http://emisoft.web.cern.ch/emisoft/dist/EMI/1/sl5/x86_64/base/emi-release-1.0.0-1.sl5.noarch.rpm - -#cd /etc/yum.repos.d -#wget http://etics-repository.cern.ch/repository/pm/registered/repomd/id/f850dc7c-4774-4b6f-98cf-5bb7eb205d18/sl5_x86_64_gcc412EPEL/etics-registered-build-by-id-protect.repo -#echo priority=45 >> etics-registered-build-by-id-protect.repo - -yum install -y emi-px glite-px-proxyrenewal - -cd ~/ -mkdir -m 700 yaim -cd yaim - -cat << EOF > site-info.def -SITE_NAME=krakonosovo -PX_HOST=\`hostname -f\` -GRID_AUTHORIZED_RETRIEVERS="\*" -GRID_AUTHORIZED_RENEWERS="\`openssl x509 -in /etc/grid-security/hostcert.pem -noout -subject |sed -e 's/subject= //'\`" -EOF - -sed -i 's/155/255/g' /opt/glite/yaim/examples/edgusers.conf -sed -i 's/156/256/g' /opt/glite/yaim/examples/edgusers.conf - -/opt/glite/yaim/bin/yaim -c -s ./site-info.def -n glite-PX - -mkdir ~glite/.certs -cp /etc/grid-security/host* ~glite/.certs/ -chown -R glite ~glite/.certs/ - -export GLITE_USER=glite -export GLITE_HOST_KEY=/home/glite/.certs/hostkey.pem -export GLITE_HOST_CERT=/home/glite/.certs/hostcert.pem - -/etc/init.d/glite-proxy-renewald start -EndInstallScript -test_done - - -printf "Generating the 'arrange' script... " -gen_arrange_script_px `hostname -f` 0 -test_done - - -printf "Installing... " -sh PXinstall.sh > Install_log.txt 2> Install_err.log -test_done - -printf "Running tests... " -sh arrange_px_test_root.sh none glite 80 '-x' > test_log.txt 2> test_err.log -test_done - -printf "Collecting package list... " -gen_repo_lists ./prod_packages.txt ./repo_packages.txt -test_done - -ENDTIME=`date +%s` - -#Generating report section -gen_deployment_header $ENDTIME $STARTTIME "$SCENARIO" > report.twiki - -echo "$SCENARIO" | grep -E -i "upgrade|update" > /dev/null -if [ $? -eq 0 ]; then - printf "\n---++++ Production Repo Contents - -\n" >> report.twiki - cat ./prod_packages.txt >> report.twiki - printf "\n" >> report.twiki -fi - -printf "\n---++++ Test Repo Contents - -\n" >> report.twiki -cat ./repo_packages.txt >> report.twiki -printf " - ----++++ Process - -\n" >> report.twiki -cat PXinstall.sh >> report.twiki -printf " - ----++++ Full Output of the Installation - -\n" >> report.twiki -cat Install_log.txt >> report.twiki - -printf " - ----+++ Tests - -| !TestPlan | https://twiki.cern.ch/twiki/bin/view/EGEE/GridSiteTestPlan | -| Tests | https://twiki.cern.ch/twiki/bin/view/EGEE/PXSoftwareVerificationandValidationPlan | - -\n" >> report.twiki -cat test_log.txt >> report.twiki - -#Generating test report - -PRODUCT="emi.px" -UNITESTEXEC="NO" -REMARKS="No unit tests implemented" -PERFORMANCEEXEC="NO" -TESTREPOCONTENTS="`cat ./repo_packages.txt`" -PRODREPOCONTENTS="`cat ./prod_packages.txt`" -INSTALLCOMMAND="`cat PXinstall.sh`" -INSTALLLOG="`cat Install_log.txt`" -CONFIGLOG="Configuration log shown with the installation log, see directly above" -#UPGRADECMD -UNITTESTURL="NA" -TESTPLANURL="http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/PX/tests/" -FUNCTIONALITYTESTURL="https://twiki.cern.ch/twiki/bin/view/EGEE/SA3Testing#PX" - -gen_test_report > TestRep.txt - diff --git a/org.glite.testsuites.ctb/PX/tests/px-common-testbeds.sh b/org.glite.testsuites.ctb/PX/tests/px-common-testbeds.sh deleted file mode 100755 index c33a0a9..0000000 --- a/org.glite.testsuites.ctb/PX/tests/px-common-testbeds.sh +++ /dev/null @@ -1,137 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -function gen_arrange_script_px() -{ -remotehost=$1 -COPYPROXY=$2 - -egrep -i "Debian|Ubuntu" /etc/issue -if [ $? = 0 ]; then - INSTALLCMD="apt-get install -q --yes" - # install myproxy too for client utils - INSTALLPKGS="lintian myproxy" -else - INSTALLCMD="yum install -q -y --nogpgcheck" - INSTALLPKGS="rpmlint" -fi - -cat << EndArrangeScript > arrange_px_test_root.sh -CERTFILE=\$1 -GLITE_USER=\$2 -PXTSTCOLS=\$3 -OUTPUT_OPT=\$4 - -echo "Certificate file: \$CERTFILE " -echo "gLite user: \$GLITE_USER " -echo "Terminal width: \$PXTSTCOLS " -echo "Output format: \$OUTPUT_OPT " - -export PXTSTCOLS - -${INSTALLCMD} globus-proxy-utils voms-clients curl wget $INSTALLPKGS - -cd /tmp - -CVSPATH=\`which cvs\` - -if [ "\$CVSPATH" = "" ]; then - printf "CVS binary not present" - ${INSTALLCMD} cvs -fi - -glite_id=\`id -u \$GLITE_USER\` - -echo \$GLITE_USER user ID is \$glite_id - -if [ $COPYPROXY -eq 1 ]; then - mv \$CERTFILE x509up_u\$glite_id - chown \$GLITE_USER:\$GLITE_USER x509up_u\${glite_id} -else - rm -rf /tmp/test-certs/grid-security - cvs -d :pserver:anonymous@glite.cvs.cern.ch:/cvs/jra1mw co org.glite.testsuites.ctb/LB > /dev/null 2>/dev/null - FAKE_CAS=\`./org.glite.testsuites.ctb/LB/tests/lb-generate-fake-proxy.sh --lsc | grep -E "^X509_CERT_DIR" | sed 's/X509_CERT_DIR=//'\` - if [ "\$FAKE_CAS" = "" ]; then - echo "Failed generating proxy" >&2 - exit 2 - else - cp -rv \$FAKE_CAS/* /etc/grid-security/certificates/ - fi -fi - -if [ ! -d /etc/vomses ]; then - echo Installing experimental VOMS server - if [ ! -f ./px-voms-install.sh ]; then - wget -O px-voms-install.sh http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/PX/tests/px-voms-install.sh?view=co - chmod +x px-voms-install.sh - fi - source ./px-voms-install.sh -u glite -else - printf "Using external voms server:\n===========================\n" - find /etc/vomses -type f -exec printf "{}: " \; -exec cat {} \; - printf "===========================\n" - -fi - - -cd /tmp/ - -echo cd > arrange_px_test_user.sh -echo export PXTSTCOLS=\$PXTSTCOLS >> arrange_px_test_user.sh -echo 'export GLITE_MYSQL_ROOT_PASSWORD="[Edited]"' >> arrange_px_test_user.sh -echo mkdir PX_testing >> arrange_px_test_user.sh -echo cd PX_testing >> arrange_px_test_user.sh -echo cvs -d :pserver:anonymous@glite.cvs.cern.ch:/cvs/jra1mw co org.glite.testsuites.ctb/PX >> arrange_px_test_user.sh -echo ls >> arrange_px_test_user.sh -echo cd org.glite.testsuites.ctb/PX/tests >> arrange_px_test_user.sh -echo ulimit -c unlimited >> arrange_px_test_user.sh -echo 'export HNAME=\`hostname -f\`' >> arrange_px_test_user.sh -echo 'env | egrep "GLITE|\$HNAME|PATH"' >> arrange_px_test_user.sh -echo pwd >> arrange_px_test_user.sh -echo id >> arrange_px_test_user.sh -if [ "\$OUTPUT_OPT" = "-i" ]; then -echo echo ======================== >> arrange_px_test_user.sh -echo echo " THE CONSOLE IS YOURS" >> arrange_px_test_user.sh -echo echo ======================== >> arrange_px_test_user.sh -echo '/bin/bash -i' >> arrange_px_test_user.sh -else -echo echo ======================== >> arrange_px_test_user.sh -echo echo " REAL TESTS START HERE" >> arrange_px_test_user.sh -echo echo ======================== >> arrange_px_test_user.sh -echo 'echo ""' >> arrange_px_test_user.sh -echo 'echo ""' >> arrange_px_test_user.sh -echo ./px-test-all.sh \$OUTPUT_OPT >> arrange_px_test_user.sh -echo ./px-test-packaging.sh \$OUTPUT_OPT >> arrange_px_test_user.sh -echo 'echo ""' >> arrange_px_test_user.sh -echo 'echo ""' >> arrange_px_test_user.sh -echo echo ================== >> arrange_px_test_user.sh -echo echo " TESTS END HERE" >> arrange_px_test_user.sh -echo echo ================== >> arrange_px_test_user.sh -fi -#echo "" >> arrange_px_test_user.sh - -chown \$GLITE_USER:\$GLITE_USER arrange_px_test_user.sh -chmod +x arrange_px_test_user.sh - -#su -l \$GLITE_USER -su -l \$GLITE_USER --command=/tmp/arrange_px_test_user.sh -echo "" - -EndArrangeScript -} - diff --git a/org.glite.testsuites.ctb/PX/tests/px-common.sh b/org.glite.testsuites.ctb/PX/tests/px-common.sh deleted file mode 100755 index 003ef64..0000000 --- a/org.glite.testsuites.ctb/PX/tests/px-common.sh +++ /dev/null @@ -1,180 +0,0 @@ -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# ------------------------------------------------------------------------------ -# Definitions of functions and variables common to LB test scripts -# -# ping_host() - basic network ping -# check_binaries() - check for binary executables, calls check_exec() -# check_socket() - TCPecho to host:port -# -# ------------------------------------------------------------------------------ - -# read common definitions and functions -TEST_COMMON=test-common.sh -if [ ! -r ${TEST_COMMON} ]; then - printf "Common definitions '${TEST_COMMON}' not found!\n" - exit 2 -fi -source ${TEST_COMMON} - - -# define variables -GLITE_LOCATION=${GLITE_LOCATION:-/opt/glite} -SAME_SENSOR_HOME=${SAME_SENSOR_HOME:-.} -PATH=$GLITE_LOCATION/bin:$GLITE_LOCATION/examples:$PATH -export PATH - -GRIDPROXYINFO=grid-proxy-info - -# binaries -SYS_LSOF=lsof -SYS_GREP=grep -SYS_SED=sed -SYS_PS=ps -SYS_PIDOF=pidof -if test -f /usr/sbin/apache2; then - SYS_APACHE=apache2 -else - SYS_APACHE=httpd -fi -if test -f /usr/sbin/apache2ctl; then - SYS_APACHECTL=apache2ctl -else - SYS_APACHECTL=apachectl -fi -SYS_PING=ping -SYS_AWK=awk -SYS_ECHO=echo -SYS_DOMAINNAME=domainname -SYS_CURL=curl -SYS_RM="rm -f" -SYS_CHMOD=chmod -SYS_CAT=cat -SYS_NL=nl -SYS_TAIL=tail -SYS_DATE=date -SYS_EXPR=expr -SYS_BC=bc -SYS_SCP=scp -SYS_NC=nc -SYS_CURL=curl -VOMSPROXYINFO=voms-proxy-info - -# not used at the moment -DEBUG=2 - -# ping host -function ping_host() -{ - if [ -z $1 ]; then - set_error "No host to ping" - return $TEST_ERROR - fi - PING_HOST=$1 - # XXX: there might be a better way to test the network reachability - result=`${SYS_PING} -c 3 $PING_HOST 2>/dev/null | ${SYS_GREP} " 0% packet loss"| wc -l` - if [ $result -gt 0 ]; then - return $TEST_OK - else - return $TEST_ERROR - fi -} - - -# check the binaries -function check_exec() -{ - if [ -z $1 ]; then - set_error "No binary to check" - return $TEST_ERROR - fi - # XXX: maybe use bash's command type? - local ret=`which $1 2> /dev/null` - if [ -n "$ret" -a -x "$ret" ]; then - return $TEST_OK - else - return $TEST_ERROR - fi -} - -function check_binaries() -{ -# TODO: test only the binaries that are needed - it can differ in each test - local ret=$TEST_OK - for file in $@ - do - check_exec $file - if [ $? -gt 0 ]; then - update_error "file $file not found" - ret=$TEST_ERROR - fi - done - return $ret -} - -# check socket -function check_socket() -{ - if [ $# -lt 2 ]; then - set_error "No host:port to check" - return $TEST_ERROR - fi - $SYS_NC -z $1 $2 > $testerrfile - if [ $? -eq 0 ]; then - return $TEST_OK - else - return $TEST_ERROR - fi -} - -# Check listener -# Arguments: -# $1: program expected to listen on the given port -# $2: TCP port to check -function check_listener() -{ - req_program=$1 - req_port=$2 - if [ -z $1 ]; then - set_error "No program name entered" - return $TEST_ERROR - fi - - pid=`lsof -F p -i TCP:$req_port | sed "s/^p//" | head -n 1` - if [ -z "$pid" ]; then - return $TEST_ERROR - fi - program=`ps -p ${pid} -o args= | grep -E "[\/]*$req_program[ \t]*"` - if [ -z "$program" ]; then - return $TEST_ERROR - else - return $TEST_OK - fi -} - -# make HTTP request using curl -# Arguments: Options to be passed to curl, at least the URL -# return http_code containing resulting code - -function call_curl() -{ - http_code=`curl --cert ${X509_USER_PROXY} --key ${X509_USER_PROXY} \ - --capath ${X509_CERT_DIR} \ - --output /dev/null --silent --write-out '%{http_code}\n' \ - "$@"` -} diff --git a/org.glite.testsuites.ctb/PX/tests/px-test-all.sh b/org.glite.testsuites.ctb/PX/tests/px-test-all.sh deleted file mode 100755 index 233aff7..0000000 --- a/org.glite.testsuites.ctb/PX/tests/px-test-all.sh +++ /dev/null @@ -1,312 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing PX and proxyrenewal functions - -Prerequisities: - - PX configured, proxy-renewal installed - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=px-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} -WRKDIR=`pwd` -for COMMON in lb-common.sh lb-generate-fake-proxy.sh -do - if [ ! -r $COMMON ]; then - printf "Downloading common definitions '$COMMON'" - wget -O $COMMON http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/LB/tests/$COMMON?view=co > /dev/null - if [ ! -r $COMMON ]; then - exit 2 - else - test_done - fi - fi -done -source lb-common.sh -chmod +x lb-generate-fake-proxy.sh - - -logfile=$$.tmp -flag=0 -NL="\n" -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML; NL="
" ;; - esac - shift -done - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries curl rm chown openssl sleep voms-proxy-info grep sed glite-proxy-renew wget myproxy-store -if [ $? -gt 0 ]; then - test_failed - exit 2 -else - test_done -fi - -printf "Testing credentials" -check_credentials_and_generate_proxy 1 -if [ $? != 0 ]; then - test_end - exit 2 -fi - -if [ "$x509_USER_CERT" = "" -o "$x509_USER_KEY" = "" ]; then - source ./lb-generate-fake-proxy.sh --hours 1 -fi -cd $WRKDIR - -printf "User Cert $x509_USER_CERT$NL" -printf "User Key $x509_USER_KEY$NL" -chmod 600 $x509_USER_CERT $x509_USER_KEY - -JOBID=https://fake.job.id/xxx - -ORIG_PROXY=`voms-proxy-info | grep -E "^path" | sed 's/^path\s*:\s*//'` -PROXYDN=`voms-proxy-info | grep -E "^identity" | sed 's/^identity\s*:\s*//'` -#myproxy-store --certfile $ORIG_PROXY --keyfile $ORIG_PROXY -s localhost -d -printf "Registering proxy by calling myproxy-init -s localhost -d -n -t 1 -c 1 --certfile $x509_USER_CERT --keyfile $x509_USER_KEY$NL" -#myproxy-init -s localhost -d -n -t 1 -c 1 --certfile $x509_USER_CERT --keyfile $x509_USER_KEY -myproxy-init -s localhost -d -n --certfile $x509_USER_CERT --keyfile $x509_USER_KEY -#myproxy-info -s localhost -l "$PROXYDN" - -printf "Getting registered proxy... " -REGISTERED_PROXY=`glite-proxy-renew -s localhost -f $ORIG_PROXY -j $JOBID start` - -if [ "$REGISTERED_PROXY" = "" ]; then - test_failed - print_error "Could not set renewal" - exit 1 -fi -test_done - -printf "\tProxy:\t$ORIG_PROXY$NL\tRenew:\t$REGISTERED_PROXY$NL"; - -printf "Checking time left on registered proxy... " -REGISTEREDTIMELEFT=`voms-proxy-info -file $REGISTERED_PROXY | grep timeleft | grep -E -o "[0-9]+:[0-9]+:[0-9]+"` -#Use this for conversion: date --utc --date "1970-1-1 0:0:0" +%s -REGISTEREDTIMELEFTSEC=`date --utc --date "1970-1-1 $REGISTEREDTIMELEFT" +%s` -printf "($REGISTEREDTIMELEFT, i.e. $REGISTEREDTIMELEFTSEC s)" -if [ ! $REGISTEREDTIMELEFTSEC -gt 0 ]; then - test_failed - print_error "Failed to retrieve time left" - exit 1 -fi -test_done - -printf "sleeping 1800 (Sorry, no other way to let the proxy age enough)... "; -sleep 1805; -test_done - - -printf "Checking time left on registered proxy... " -REGISTEREDTIMELEFT=`voms-proxy-info -file $REGISTERED_PROXY | grep timeleft | grep -E -o "[0-9]+:[0-9]+:[0-9]+"` -REGISTEREDTIMELEFTSEC=`date --utc --date "1970-1-1 $REGISTEREDTIMELEFT" +%s` -printf "($REGISTEREDTIMELEFT, i.e. $REGISTEREDTIMELEFTSEC s)" -if [ ! $REGISTEREDTIMELEFTSEC -gt 0 ]; then - test_failed - print_error "Failed to retrieve time left" - exit 1 -fi -test_done - -printf "Checking time left on original proxy... " -ORIGINALTIMELEFT=`voms-proxy-info -file $ORIG_PROXY | grep timeleft | grep -E -o "[0-9]+:[0-9]+:[0-9]+"` -ORIGINALTIMELEFTSEC=`date --utc --date "1970-1-1 $ORIGINALTIMELEFT" +%s` -printf "($ORIGINALTIMELEFT, i.e. $ORIGINALTIMELEFTSEC s)" -if [ ! $ORIGINALTIMELEFTSEC -gt 0 ]; then - test_failed - print_error "Failed to retrieve time left" - exit 1 -fi -test_done - -printf "Checking renewal ($REGISTEREDTIMELEFTSEC > $ORIGINALTIMELEFTSEC)? " -expr $REGISTEREDTIMELEFTSEC \> $ORIGINALTIMELEFTSEC > /dev/null -if [ $? -eq 0 ]; then - test_done -else - test_failed - print_error "Proxy was not renewed" -fi - -printf "Other particulars:$NL" -printf "Registered proxy `voms-proxy-info -file $REGISTERED_PROXY -fqan -actimeleft`$NL" -printf "Original proxy `voms-proxy-info -file $ORIG_PROXY -fqan -actimeleft`$NL" -printf "Registered proxy `voms-proxy-info -file $REGISTERED_PROXY -identity`$NL" -printf "Original proxy `voms-proxy-info -file $ORIG_PROXY -identity`$NL" - -printf "Checking if test uses fake proxy... " -voms-proxy-info | grep -E "^subject.*.L=Tropic.O=Utopia.OU=Relaxation" > /dev/null -if [ $? -eq 0 ]; then - printf "yes." - test_done - printf "Generating new proxy... " - cd "$WRKDIR" - ./lb-generate-fake-proxy.sh - if [ $? -eq 0 ]; then - test_done - printf "Registering new proxy for renewal (regression into Savannah Bug #90610)... " - NEW_REGISTERED=`glite-proxy-renew -s localhost -f $ORIG_PROXY -j $JOBID start` - if [ "$NEW_REGISTERED" == "$REGISTERED_PROXY" ]; then - test_done - printf "Checking time left on new proxy... " - NEWTIMELEFT=`voms-proxy-info -file $REGISTERED_PROXY | grep timeleft | grep -E -o "[0-9]+:[0-9]+:[0-9]+"` - NEWTIMELEFTSEC=`date --utc --date "1970-1-1 $NEWTIMELEFT" +%s` - printf "$NEWTIMELEFT ($NEWTIMELEFTSEC)" - test_done - printf "Checking if old proxy ($REGISTEREDTIMELEFTSEC) was replaced by new ($NEWTIMELEFTSEC)... " - expr $NEWTIMELEFTSEC \> $REGISTEREDTIMELEFTSEC > /dev/null - if [ $? -eq 0 ]; then - test_done - else - test_failed - print_error "Proxy was not replaced" - fi - else - test_failed - print_error "Not created as the same registration!${NL}Old proxy: $REGISTERED_PROXY${NL}New proxy: $NEW_REGISTERED" - fi - printf "Removing 2nd registration... " - glite-proxy-renew -j $JOBID stop; - if [ $? -eq 0 ]; then - test_done - else - test_failed - print_error "Failed to stop" - fi - - else - test_failed - print_error "Failed to generate proxy" - fi - - -else - printf "no." - test_skipped -fi - - -printf "Stopping renewal... " -glite-proxy-renew -j $JOBID stop; -if [ $? -eq 0 ]; then - test_done -else - test_failed - print_error "Failed to stop" -fi - - -printf "Checking if registered proxy was removed... " -if [ -f $REGISTERED_PROXY ]; then - test_failed - print_error "Registered proxy still exists ($REGISTERED_PROXY)" -else - test_done -fi - -UTOPIA=`voms-proxy-info -all | grep -A 100 "extension information" | grep "^issuer" | grep "L=Tropic" | grep "O=Utopia" | grep "OU=Relaxation"` -if [ "$UTOPIA" != "" ]; then - printf "Possibly fake VOMS extensions. Regenerating... " - voms-proxy-init -voms vo.org -key $x509_USER_KEY -cert $x509_USER_CERT | sed "s/\$/$NL/" -fi - - -printf "Checking VOMS attributes size to decide if it's possible to determine the status of bug #92806 (regression into bug #92806)... " -attrsize=`voms-proxy-info -all | grep ^attribute | sed -r 's/attribute\s*:\s*//' | wc -c` -if [ "$attrsize" == "" ]; then - attrsize=0 -fi -if [ $attrsize -gt 1024 ]; then - printf "Registering proxy for renewal" - ORIG_PROXY=`voms-proxy-info | grep -E "^path" | sed 's/^path\s*:\s*//'` - REGISTERED=`glite-proxy-renew -s localhost -f $ORIG_PROXY -j $JOBID start` - - if [ "$REGISTERED" = "" ]; then - printf "failed to renew with $attrsize bytes of attributes" - test_failed - print_error "Could not set renewal" - else - printf "renewed with $attrsize bytes of attributes" - test_done - - printf "Stopping renewal... " - glite-proxy-renew -j $JOBID stop; - if [ $? -eq 0 ]; then - test_done - else - test_failed - print_error "Failed to stop" - fi - - fi -else - printf "only $attrsize bytes of attributes" - test_skipped -fi - - - -test_end -} - -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/PX/tests/px-test-packaging.sh b/org.glite.testsuites.ctb/PX/tests/px-test-packaging.sh deleted file mode 100755 index 5501409..0000000 --- a/org.glite.testsuites.ctb/PX/tests/px-test-packaging.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script producing errors and warnings due to packaging. - -Prerequisities: - - installed all tested packages - - Scientific Linux: installed rpmlint - - Debian: installed lintian - -Tests called: - - called rpmlint or lintian on the packages - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -for COMMON in PX/px-common.sh LB/lb-common.sh -do - SUBSYS=`dirname $COMMON` - FILE=`basename $COMMON` - if [ ! -r ${FILE} ]; then - printf "Downloading common definitions '${COMMON}'" - wget -q -O ${FILE} http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/$SUBSYS/tests/$FILE?view=co > /dev/null - if [ ! -r ${FILE} ]; then - exit 2 - else - chmod +x $FILE - test_done - fi - fi - source $FILE -done - -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - - -## -# Starting the test -##################### - -test_start - - -if egrep -i "Debian|Ubuntu" /etc/issue >/dev/null; then - check_lintian glite-px-\* libglite-security-proxyrenewal-\* emi-px-\* - ret=$? -else - check_rpmlint glite-px-\* emi-px\* - ret=$? -fi - -#printf "Packages compliance..." -#if test $ret -eq 0; then -# test_done -#else -# test_failed -#fi - - -test_end - -exit $TEST_OK diff --git a/org.glite.testsuites.ctb/PX/tests/px-voms-install.sh b/org.glite.testsuites.ctb/PX/tests/px-voms-install.sh deleted file mode 100755 index 9b1fd38..0000000 --- a/org.glite.testsuites.ctb/PX/tests/px-voms-install.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -function add_voms_user_w_attrs() { - longrand="" - for it in {0..40}; do longrand="${longrand}$RANDOM"; done - voms-admin --nousercert --vo vo.org create-user "$1" "$2" "$3" "$4" - voms-admin --nousercert --vo vo.org set-user-attribute "$1" "$2" attribute1 $RANDOM - voms-admin --nousercert --vo vo.org set-user-attribute "$1" "$2" attribute2 $RANDOM - voms-admin --nousercert --vo vo.org set-user-attribute "$1" "$2" attribute3 $longrand - voms-admin --nousercert --vo vo.org set-user-attribute "$1" "$2" attribute4 $longrand - voms-admin --nousercert --vo vo.org set-user-attribute "$1" "$2" attribute5 $longrand - voms-admin --nousercert --vo vo.org set-user-attribute "$1" "$2" attribute6 $longrand - voms-admin --nousercert --vo vo.org set-user-attribute "$1" "$2" attribute7 $longrand - voms-admin --nousercert --vo vo.org set-user-attribute "$1" "$2" attribute8 $longrand - voms-admin --nousercert --vo vo.org set-user-attribute "$1" "$2" attribute9 $longrand - voms-admin --nousercert --vo vo.org add-member "/vo.org/Testers" "$1" "$2" - voms-admin --nousercert --vo vo.org assign-role "/vo.org/Testers" Tester "$1" "$2" -} - -USERNAME="root" -while test -n "$1" -do - case "$1" in - "-u" | "--user") shift; USERNAME="$1" ;; - esac - shift -done - -egrep -i "Debian|Ubuntu" /etc/issue -if [ $? = 0 ]; then - INSTALLCMD="apt-get install -q --yes" - INSTALLPKGS="" -else - INSTALLCMD="yum install -q -y --nogpgcheck" - INSTALLPKGS="xml-commons-apis" -fi - -${INSTALLCMD} emi-voms-mysql wget ${INSTALLPKGS} - -#get CAS -if [ ! -f lb-generate-fake-proxy.sh ]; then - wget -O lb-generate-fake-proxy.sh http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/LB/tests/lb-generate-fake-proxy.sh?view=co - chmod +x lb-generate-fake-proxy.sh -fi - -FAKE_CAS=`sh ./lb-generate-fake-proxy.sh --lsc | grep -E "^X509_CERT_DIR" | sed 's/X509_CERT_DIR=//'` -if [ "$FAKE_CAS" = "" ]; then - echo "Failed generating proxy" >&2 - exit 2 -else - cp -rv $FAKE_CAS/* /etc/grid-security/certificates/ -fi - -service mysqld start - -sleep 2 - -/usr/bin/mysqladmin -u root password [Edited]; - -mysql --user=root --password=[Edited] -e "grant all on *.* to 'root'@'`hostname`' identified by '[Edited]';" -mysql --user=root --password=[Edited] -e "grant all on *.* to 'root'@'`hostname -f`' identified by '[Edited]';" - - -cd -mkdir -p yaim/services -cd yaim - -cat << EOF > site-info-voms.def -MYSQL_PASSWORD="[Edited]" -SITE_NAME="`hostname -f`" -VOS="vo.org" -BDII_DELETE_DELAY=0 -EOF - -cat << EOF > services/glite-voms -# VOMS server hostname -VOMS_HOST=`hostname -f` -VOMS_DB_HOST='localhost' - -VO_VO_ORG_VOMS_PORT=15000 -VO_VO_ORG_VOMS_DB_USER=cert_mysql_user -VO_VO_ORG_VOMS_DB_PASS="[Edited]" -VO_VO_ORG_VOMS_DB_NAME=voms_cert_mysql_db - -VOMS_ADMIN_SMTP_HOST=[Edited] -VOMS_ADMIN_MAIL=[Edited] -EOF - -sed -i 's/155/255/g' /opt/glite/yaim/examples/edgusers.conf -sed -i 's/156/256/g' /opt/glite/yaim/examples/edgusers.conf - -/opt/glite/yaim/bin/yaim -c -s site-info-voms.def -n VOMS - -source /etc/profile.d/grid-env.sh - -voms-admin --vo vo.org create-attribute-class "attribute1" "The first test attribute" 0 -voms-admin --vo vo.org create-attribute-class "attribute2" "The second test attribute" 0 -voms-admin --vo vo.org create-attribute-class "attribute3" "The third test attribute" 0 -voms-admin --vo vo.org create-attribute-class "attribute4" "The fourth test attribute" 0 -voms-admin --vo vo.org create-attribute-class "attribute5" "The fifth test attribute" 0 -voms-admin --vo vo.org create-attribute-class "attribute6" "The sixth test attribute" 0 -voms-admin --vo vo.org create-attribute-class "attribute7" "The seventh test attribute" 0 -voms-admin --vo vo.org create-attribute-class "attribute8" "The eighth test attribute" 0 -voms-admin --vo vo.org create-attribute-class "attribute9" "The ninth test attribute" 0 - -voms-admin --vo vo.org create-group Testers -voms-admin --vo vo.org create-role Tester -voms-admin --vo vo.org set-role-attribute "/vo.org/Testers" Role=Tester attribute3 "TestAttr$RANDOM" - -add_voms_user_w_attrs "/C=UG/L=Tropic/O=Utopia/OU=Relaxation/CN=$USERNAME" "/C=UG/L=Tropic/O=Utopia/OU=Relaxation/CN=the trusted CA" "$USERNAME" "root@`hostname -f`" -add_voms_user_w_attrs "/C=UG/L=Tropic/O=Utopia/OU=Relaxation/CN=$USERNAME client01" "/C=UG/L=Tropic/O=Utopia/OU=Relaxation/CN=the trusted CA" "$USERNAME" "root@`hostname -f`" -add_voms_user_w_attrs "/DC=org/DC=terena/DC=tcs/C=CZ/O=CESNET/CN=Zdenek Sustr 4040" "/C=NL/O=TERENA/CN=TERENA eScience Personal CA" "$USERNAME" "root@`hostname -f`" -add_voms_user_w_attrs "/DC=cz/DC=cesnet-ca/O=University of West Bohemia/CN=Frantisek Dvorak" "/DC=cz/DC=cesnet-ca/O=CESNET CA/CN=CESNET CA 3" "$USERNAME" "root@`hostname -f`" - -mkdir -p /etc/vomses -cat /etc/voms-admin/vo.org/vomses > /etc/vomses/`hostname -f` - -echo Experimental VOMS set up with users: -voms-admin --vo vo.org list-users -echo groups: -voms-admin --vo vo.org list-groups -echo roles: -voms-admin --vo vo.org list-roles - diff --git a/org.glite.testsuites.ctb/PX/tests/test-common.sh b/org.glite.testsuites.ctb/PX/tests/test-common.sh deleted file mode 100644 index 15ed38e..0000000 --- a/org.glite.testsuites.ctb/PX/tests/test-common.sh +++ /dev/null @@ -1,260 +0,0 @@ -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# ------------------------------------------------------------------------------ -# Definition of test script return messages -# -# The test scripts should use the variables test_done and test_failed to -# report whether they failed or succeeded. -# -# The variable test_reset is used to turn off all attributes and switch -# to the standard character set. -# -# \033 ascii ESCape -# \033[G move to column (linux console, xterm, not vt100) -# \033[C move columns forward but only upto last column -# \033[D move columns backward but only upto first column -# \033[A move rows up -# \033[B move rows down -# \033[1m switch on bold -# \033[31m switch on red -# \033[32m switch on green -# \033[33m switch on yellow -# \033[m switch off color/bold -# \017 exit alternate mode (xterm, vt100, linux console) -# \033[10m exit alternate mode (linux console) -# \015 carriage return (without newline) -# -# See also United Linux or OpenSUSE /etc/rc.status script -# -# ------------------------------------------------------------------------------ - -# Do _not_ be fooled by non POSIX locale -LC_ALL=POSIX -export LC_ALL - -# Seek for terminal size and, if needed, set default size -if [ -z "${LINES}" -o -z "${COLUMNS}" ]; then - stty_size=`stty size 2> /dev/null` - if [ $? = 0 ]; then - LINES=`echo ${stty_size} | awk '{print $1}'` - COLUMNS=`echo ${stty_size} | awk '{print $2}'` - else - LINES=24 - if [ $LBTSTCOLS -gt 0 ]; then - COLUMNS=$LBTSTCOLS - else - COLUMNS=80 - fi - fi -fi -if [ ! $LINES -ge 0 ]; then LINES=24; fi -if [ ! $COLUMNS -ge 0 ]; then COLUMNS=80; fi -export LINES COLUMNS - -# default return values -TEST_ERROR=1 -TEST_OK=0 - -# test error file -testerrfile=$$.err - -function set_test() -{ -test_done="${spacefill}${begin_green}done${end_green}" -test_running="${spacefill}${begin_green}running${end_green}" -test_failed="${spacefill}${begin_red}-TEST FAILED-${end_red}" -test_missed="${spacefill}${begin_red}missing${end_red}" -test_skipped="${spacefill}${begin_yellow}skipped${end_yellow}" -test_warning="${spacefill}${begin_yellow}warning${end_yellow}" -test_dead="${spacefill}${begin_red}dead${end_red}" -test_unused="${spacefill}${begin_bold}unused${end_bold}" -test_unknown="${spacefill}${begin_yellow}unknown${end_yellow}" - -test_start="${spacefill}${begin_green}start${end_green}" -test_end="${spacefill}${begin_green}end${end_green}" -} - -function test_done() { printf "${test_done}${lf}"; } -function test_running() { printf "${test_running}${lf}"; } -function test_failed() { printf "${test_failed}${lf}"; } -function test_missed() { printf "${test_missed}${lf}"; } -function test_skipped() { printf "${test_skipped}${lf}"; } -function test_warning() { printf "${test_warning}${lf}"; } -function test_dead() { printf "${test_dead}${lf}"; } -function test_unused() { printf "${test_unused}${lf}"; } -function test_unknown { printf "${test_unknown}${lf}"; } -function test_start() { - syslog "${test_start}"; - reset_error -} -function test_end() { - syslog "${test_end}"; - reset_error -} - -# set output to ASCII (without colors) -function setOutputASCII() -{ -lf="\n" -spacefill="..." - -begin_bold="" -begin_black="" -begin_red="" -begin_green="" -begin_yellow="" -begin_blue="" -begin_magenta="" -begin_cyan="" -begin_white="" - -end_bold="" -end_black="" -end_red="" -end_green="" -end_yellow="" -end_blue="" -end_magenta="" -end_cyan="" -end_white="" - -set_test -} - -# set output to ASCII with ANSI colors -function setOutputColor() -{ -local esc=`echo -en "\033"` -local normal="${esc}[0m" # unsets color to term's fg color -lf="\n" -spacefill=`echo -en "\015${esc}[${COLUMNS}C${esc}[15D"` - -begin_bold="${esc}[0;1m" -begin_black="${esc}[0;30m" -begin_red="${esc}[0;31m" -begin_green="${esc}[0;32m" -begin_yellow="${esc}[0;33m" -begin_blue="${esc}[0;34m" -begin_magenta="${esc}[0;35m" -begin_cyan="${esc}[0;36m" -begin_white="${esc}[0;37m" - -end_bold="$normal" -end_black="$normal" -end_red="$normal" -end_green="$normal" -end_yellow="$normal" -end_blue="$normal" -end_magenta="$normal" -end_cyan="$normal" -end_white="$normal" - -set_test -} - -# set output to HTML -function setOutputHTML() -{ -local ENDFONT="
" -lf="
\n" -spacefill="   " -is_html=1 - -begin_bold="" -begin_black="" -begin_red="" -begin_green="" -begin_yellow="" -begin_blue="" -begin_magenta="" -begin_cyan="" -begin_white="" - -end_bold="" -end_black="$ENDFONT" -end_red="$ENDFONT" -end_green="$ENDFONT" -end_yellow="$ENDFONT" -end_blue="$ENDFONT" -end_magenta="$ENDFONT" -end_cyan="$ENDFONT" -end_white="$ENDFONT" - -set_test -} - -function reset_error() -{ - rm -f $testerrfile -} - -function set_error() -{ - printf "%s ${lf}" "$*" > $testerrfile -} - -function update_error() -{ - printf "%s; " "$*" >> $testerrfile -} - -function print_error() -{ - printf "\t${begin_red}Error${end_red}: %s ${lf}" "$*" - - if [ -f $testerrfile ]; then - printf "\t${begin_red}Error${end_red}: %s ${lf}" "`cat $testerrfile`" - fi - reset_error -} - -function print_warning() -{ - printf "${begin_magenta}Warning${end_magenta}: %s ${lf}" "$*" -} - -function print_info() -{ - printf "${begin_blue}Info${end_blue}: %s ${lf}" "$*" -} - -function print_newline() -{ - printf "${lf}" -} - -function syslog() -{ - local tmp="`date +'%b %d %H:%M:%S'` `hostname` $progname" - printf "${begin_bold}${tmp}${end_bold}: %s ${lf}" "$*" -} - -function dprintf() -{ - if [ $DEBUG -gt 0 ]; then - printf "%s${lf}" "$*" - fi -} - -# by default set output to color if possible -if test -t 1 -a "$TERM" != "raw" -a "$TERM" != "dumb" && stty size <&1 > /dev/null 2>&1 ; then - setOutputColor -else - setOutputASCII -fi - diff --git a/org.glite.testsuites.ctb/gridsite/tests/gridsite-autonomous-test.sh b/org.glite.testsuites.ctb/gridsite/tests/gridsite-autonomous-test.sh deleted file mode 100755 index d3733c6..0000000 --- a/org.glite.testsuites.ctb/gridsite/tests/gridsite-autonomous-test.sh +++ /dev/null @@ -1,179 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -This script is intended for running a fully automated deployment and functionality test of a Web server with gridsite extensions - -Prerequisities: -New empty machine, certificates - -Tests called: - Deployment - The full GridSite Functional Test Suite - -EndHelpHeader - - echo "Usage: $progname [OPTIONS] hostname" - echo "Options:" - echo " -h | --help Show this help message." -} - -STARTTIME=`date +%s` - -egrep -i "Debian|Ubuntu" /etc/issue -if [ $? = 0 ]; then - INSTALLCMD="apt-get install -q --yes" - INSTALLPKGS="lintian" - UPGRADECMD="apt-get upgrade" -else - INSTALLCMD="yum install -q -y --nogpgcheck" - INSTALLPKGS="rpmlint" - UPGRADECMD="yum update" -fi - -$INSTALLCMD wget - -# read common definitions and functions -for COMMON in gridsite-common.sh test-common.sh gridsite-common-testbeds.sh -do - if [ ! -r ${COMMON} ]; then - printf "Downloading common definitions '${COMMON}'" - wget -O ${COMMON} http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/gridsite/tests/$COMMON?view=co > /dev/null - if [ ! -r ${COMMON} ]; then - exit 2 - else - chmod +x $COMMON - test_done - fi - fi -done -source gridsite-common.sh -source gridsite-common-testbeds.sh -#also read L&B common definitions for common functions. -if [ ! -r lb-common-testbeds.sh ]; then - printf "Downloading common definitions 'lb-common-testbeds.sh'" - wget -O lb-common-testbeds.sh http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/LB/tests/lb-common-testbeds.sh?view=co > /dev/null - if [ ! -r lb-common-testbeds.sh ]; then - exit 2 - else - chmod +x lb-common-testbeds.sh - test_done - fi -fi -source lb-common-testbeds.sh - - -printf "Getting the 'install' script... " -# Example script, for real tests it should be downloaded or otherwise obtained -SCENARIO=${SCENARIO:-"Clean installation"} -test -s GridSiteInstall.sh || cat << EndInstallScript > GridSiteInstall.sh -rpm -Uvhi http://dl.fedoraproject.org/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm -yum install -y yum-priorities yum-protectbase -rpm -i http://emisoft.web.cern.ch/emisoft/dist/EMI/1/sl5/x86_64/base/emi-release-1.0.0-1.sl5.noarch.rpm - -#cd /etc/yum.repos.d/ -#wget http://etics-repository.cern.ch/repository/pm/registered/repomd/id/2efadb29-61fb-4d5f-be8f-17b799a269e0/sl5_x86_64_gcc412EPEL/etics-registered-build-by-id-protect.repo -#echo priority=45 >> etics-registered-build-by-id-protect.repo - -yum install -y gridsite-apache gridsite-commands gridsite-debuginfo gridsite-devel.x86_64 gridsite-gsexec gridsite-service-clients gridsite-services gridsite-shared -EndInstallScript -test_done - - -printf "Generating the 'arrange' script... " -gen_arrange_script_gridsite `hostname -f` 0 -test_done - - -printf "Installing... " -sh GridSiteInstall.sh > Install_log.txt 2> Install_err.log -test_done - -printf "Running tests... " -sh arrange_gridsite_test_root.sh none glite 80 '-x' > test_log.txt 2> test_err.log -test_done - -printf "Collecting package list... " -gen_repo_lists ./prod_packages.txt ./repo_packages.txt -test_done - -ENDTIME=`date +%s` - -#Generating report section -gen_deployment_header $ENDTIME $STARTTIME "$SCENARIO" > report.twiki - - -echo "$SCENARIO" | grep -E -i "upgrade|update" > /dev/null -if [ $? -eq 0 ]; then - printf "\n---++++ Production Repo Contents - -\n" >> report.twiki - cat ./prod_packages.txt >> report.twiki - printf "\n" >> report.twiki -fi - -printf "\n---++++ Test Repo Contents - -\n" >> report.twiki -cat ./repo_packages.txt >> report.twiki -printf " - ----++++ Process - -\n" >> report.twiki - -cat GridSiteInstall.sh >> report.twiki -printf " - ----++++ Full Output of the Installation - -\n" >> report.twiki -cat Install_log.txt >> report.twiki - -printf " - ----+++ Tests - -| !TestPlan | https://twiki.cern.ch/twiki/bin/view/EGEE/GridSiteTestPlan | -| Tests | http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/gridsite/tests/ | - -\n" >> report.twiki -cat test_log.txt >> report.twiki - -#Generating test report - -PRODUCT="emi.gridsite" -UNITESTEXEC="NO" -REMARKS="No unit tests implemented" -PERFORMANCEEXEC="NO" -TESTREPOCONTENTS="`cat ./repo_packages.txt`" -PRODREPOCONTENTS="`cat ./prod_packages.txt`" -INSTALLCOMMAND="`cat GridSiteInstall.sh`" -INSTALLLOG="`cat Install_log.txt`" -CONFIGLOG="GridSite does not use any specific configuration procedure. No log provided" -#UPGRADECMD -UNITTESTURL="NA" -TESTPLANURL="http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/gridsite/tests/" -FUNCTIONALITYTESTURL="https://twiki.cern.ch/twiki/bin/view/EGEE/SA3Testing#GridSite" - -gen_test_report > TestRep.txt - diff --git a/org.glite.testsuites.ctb/gridsite/tests/gridsite-common-testbeds.sh b/org.glite.testsuites.ctb/gridsite/tests/gridsite-common-testbeds.sh deleted file mode 100755 index a88698e..0000000 --- a/org.glite.testsuites.ctb/gridsite/tests/gridsite-common-testbeds.sh +++ /dev/null @@ -1,172 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -function gen_arrange_script_gridsite() -{ -remotehost=$1 -COPYPROXY=$2 - -egrep -i "Debian|Ubuntu" /etc/issue -if [ $? = 0 ]; then - INSTALLCMD="apt-get install -q --yes" - INSTALLPKGS="lintian apache2 netcat-traditional psmisc" - HTTPD_SERVER_ROOT=/etc/apache2 -else - INSTALLCMD="yum install -q -y --nogpgcheck" - INSTALLPKGS="rpmlint httpd nc mod_ssl" - HTTPD_SERVER_ROOT=/etc/httpd -fi - -cat << EndArrangeScript > arrange_gridsite_test_root.sh -CERTFILE=\$1 -GLITE_USER=\$2 -GSTSTCOLS=\$3 -OUTPUT_OPT=\$4 - -echo "Certificate file: \$CERTFILE " -echo "gLite user: \$GLITE_USER " -echo "Terminal width: \$GSTSTCOLS " -echo "Output format: \$OUTPUT_OPT " - -export GSTSTCOLS - -${INSTALLCMD} voms-clients curl wget lsof $INSTALLPKGS - -if test -f /usr/sbin/apache2; then - SYS_APACHE=apache2 -else - SYS_APACHE=httpd -fi - -if [ -d /etc/apache2 -a ! -d /etc/apache2/modules ]; then - ln -s ../../var/log/apache2 /etc/apache2/logs - ln -s ../../usr/lib/apache2/modules /etc/apache2/modules - ln -s ../../var/run/apache2 /etc/apache2/run -fi - -HTTPD_CONFDIR=/tmp -for dir in /etc/httpd /etc/apache /etc/apache2; do - if [ -d \$dir ]; then - HTTPD_CONFDIR=\$dir - break - fi -done -HTTPD_CONF=\$HTTPD_CONFDIR/gridsite-webserver.conf - -if getent passwd www-data >/dev/null; then - HTTPD_USER=www-data -else - HTTPD_USER=apache -fi - -# Debian compress everything inside /usr/share/doc -HTTPD_CONF_SRC=\`ls -1 /usr/share/doc/gridsite-*/httpd-webserver.conf* | head -n 1\` -if echo \$HTTPD_CONF_SRC | grep '\.gz$' >/dev/null 2>&1; then - gzip -dc < \$HTTPD_CONF_SRC > /tmp/httpd-webserver.conf - HTTPD_CONF_SRC=/tmp/httpd-webserver.conf -fi -if [ -z "\$HTTPD_CONF_SRC" ]; then - echo "gridsite apache config example not found" >&2 - exit 2 -fi - -sed \\ - -e '1,\$s!/usr/lib/httpd/modules/!modules/!' \\ - -e 's!/var/www/html!/var/www/htdocs!' \\ - -e "s/FULL.SERVER.NAME/\$(hostname -f)/" \\ - -e "s/\(GridSiteGSIProxyLimit\)/# \1/" \\ - -e "s!^\(ServerRoot\).*!\1 $HTTPD_SERVER_ROOT!" \\ - -e "s/^User .*/User \$HTTPD_USER/" \\ - -e "s/^Group .*/Group \$HTTPD_USER/" \\ - \$HTTPD_CONF_SRC > \$HTTPD_CONF -echo "AddHandler cgi-script .cgi" >> \$HTTPD_CONF -echo "ScriptAlias /gridsite-delegation.cgi /usr/sbin/gridsite-delegation.cgi" >> \$HTTPD_CONF -# internal module? -if [ ! -f $HTTPD_SERVER_ROOT/modules/mod_log_config.so ]; then - sed -i 's/^\(LoadModule\\s\\+log_config_module.*\)/# \1/' \$HTTPD_CONF -fi -mkdir -p /var/www/htdocs -killall httpd apache2 >/dev/null 2>&1 -sleep 2 -killall -9 httpd apache2 >/dev/null 2>&1 -echo Starting \$SYS_APACHE -f \$HTTPD_CONF -\$SYS_APACHE -f \$HTTPD_CONF - -cd /tmp - -CVSPATH=\`which cvs\` - -if [ "\$CVSPATH" = "" ]; then - printf "CVS binary not present" - ${INSTALLCMD} cvs -fi - -if [ $COPYPROXY -eq 1 ]; then - mv \$CERTFILE x509up_u\`id -u\` - chown \`id -un\`:\`id -gn\` x509up_u\`id -u\` -else - rm -rf /tmp/test-certs/grid-security - cvs -d :pserver:anonymous@glite.cvs.cern.ch:/cvs/jra1mw co org.glite.testsuites.ctb/LB > /dev/null 2>/dev/null - ./org.glite.testsuites.ctb/LB/tests/lb-generate-fake-proxy.sh > fake-prox.out.\$\$ - FAKE_CAS=\`cat fake-prox.out.\$\$ | grep -E "^X509_CERT_DIR" | sed 's/X509_CERT_DIR=//'\` - if [ "\$FAKE_CAS" = "" ]; then - echo "Failed generating proxy" >&2 - exit 2 - else - cp -rv \$FAKE_CAS/* /etc/grid-security/certificates/ - fi - - TRUSTED_CERTS=\`cat fake-prox.out.\$\$ | grep -E "^TRUSTED_CERTS" | sed 's/TRUSTED_CERTS=//'\` - export x509_USER_CERT=\${TRUSTED_CERTS}/trusted_client00.cert - export x509_USER_KEY=\${TRUSTED_CERTS}/trusted_client00.priv-clear - rm fake-prox.out.\$\$ -fi - -if [ ! -d /etc/vomses ]; then - echo Installing experimental VOMS server - if [ ! -f ./px-voms-install.sh ]; then - wget -O px-voms-install.sh http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/PX/tests/px-voms-install.sh?view=co - chmod +x px-voms-install.sh - fi - source ./px-voms-install.sh -u root -fi - -cd ~/ -mkdir GridSite_testing -cd GridSite_testing -cvs -d :pserver:anonymous@glite.cvs.cern.ch:/cvs/jra1mw co org.glite.testsuites.ctb/gridsite -cd org.glite.testsuites.ctb/gridsite/tests -echo ======================== -echo " REAL TESTS START HERE" -echo ======================== -echo "" -echo "" -./ping-remote.sh $remotehost \$OUTPUT_OPT -./ping-local.sh \$OUTPUT_OPT -f \$HTTPD_CONF -./gridsite-test-all.sh \$OUTPUT_OPT -./gridsite-test-packaging.sh \$OUTPUT_OPT -echo "" -echo "" -echo ================== -echo " TESTS END HERE" -echo ================== -echo "" - -EndArrangeScript -} - diff --git a/org.glite.testsuites.ctb/gridsite/tests/gridsite-common.sh b/org.glite.testsuites.ctb/gridsite/tests/gridsite-common.sh deleted file mode 100755 index 003ef64..0000000 --- a/org.glite.testsuites.ctb/gridsite/tests/gridsite-common.sh +++ /dev/null @@ -1,180 +0,0 @@ -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# ------------------------------------------------------------------------------ -# Definitions of functions and variables common to LB test scripts -# -# ping_host() - basic network ping -# check_binaries() - check for binary executables, calls check_exec() -# check_socket() - TCPecho to host:port -# -# ------------------------------------------------------------------------------ - -# read common definitions and functions -TEST_COMMON=test-common.sh -if [ ! -r ${TEST_COMMON} ]; then - printf "Common definitions '${TEST_COMMON}' not found!\n" - exit 2 -fi -source ${TEST_COMMON} - - -# define variables -GLITE_LOCATION=${GLITE_LOCATION:-/opt/glite} -SAME_SENSOR_HOME=${SAME_SENSOR_HOME:-.} -PATH=$GLITE_LOCATION/bin:$GLITE_LOCATION/examples:$PATH -export PATH - -GRIDPROXYINFO=grid-proxy-info - -# binaries -SYS_LSOF=lsof -SYS_GREP=grep -SYS_SED=sed -SYS_PS=ps -SYS_PIDOF=pidof -if test -f /usr/sbin/apache2; then - SYS_APACHE=apache2 -else - SYS_APACHE=httpd -fi -if test -f /usr/sbin/apache2ctl; then - SYS_APACHECTL=apache2ctl -else - SYS_APACHECTL=apachectl -fi -SYS_PING=ping -SYS_AWK=awk -SYS_ECHO=echo -SYS_DOMAINNAME=domainname -SYS_CURL=curl -SYS_RM="rm -f" -SYS_CHMOD=chmod -SYS_CAT=cat -SYS_NL=nl -SYS_TAIL=tail -SYS_DATE=date -SYS_EXPR=expr -SYS_BC=bc -SYS_SCP=scp -SYS_NC=nc -SYS_CURL=curl -VOMSPROXYINFO=voms-proxy-info - -# not used at the moment -DEBUG=2 - -# ping host -function ping_host() -{ - if [ -z $1 ]; then - set_error "No host to ping" - return $TEST_ERROR - fi - PING_HOST=$1 - # XXX: there might be a better way to test the network reachability - result=`${SYS_PING} -c 3 $PING_HOST 2>/dev/null | ${SYS_GREP} " 0% packet loss"| wc -l` - if [ $result -gt 0 ]; then - return $TEST_OK - else - return $TEST_ERROR - fi -} - - -# check the binaries -function check_exec() -{ - if [ -z $1 ]; then - set_error "No binary to check" - return $TEST_ERROR - fi - # XXX: maybe use bash's command type? - local ret=`which $1 2> /dev/null` - if [ -n "$ret" -a -x "$ret" ]; then - return $TEST_OK - else - return $TEST_ERROR - fi -} - -function check_binaries() -{ -# TODO: test only the binaries that are needed - it can differ in each test - local ret=$TEST_OK - for file in $@ - do - check_exec $file - if [ $? -gt 0 ]; then - update_error "file $file not found" - ret=$TEST_ERROR - fi - done - return $ret -} - -# check socket -function check_socket() -{ - if [ $# -lt 2 ]; then - set_error "No host:port to check" - return $TEST_ERROR - fi - $SYS_NC -z $1 $2 > $testerrfile - if [ $? -eq 0 ]; then - return $TEST_OK - else - return $TEST_ERROR - fi -} - -# Check listener -# Arguments: -# $1: program expected to listen on the given port -# $2: TCP port to check -function check_listener() -{ - req_program=$1 - req_port=$2 - if [ -z $1 ]; then - set_error "No program name entered" - return $TEST_ERROR - fi - - pid=`lsof -F p -i TCP:$req_port | sed "s/^p//" | head -n 1` - if [ -z "$pid" ]; then - return $TEST_ERROR - fi - program=`ps -p ${pid} -o args= | grep -E "[\/]*$req_program[ \t]*"` - if [ -z "$program" ]; then - return $TEST_ERROR - else - return $TEST_OK - fi -} - -# make HTTP request using curl -# Arguments: Options to be passed to curl, at least the URL -# return http_code containing resulting code - -function call_curl() -{ - http_code=`curl --cert ${X509_USER_PROXY} --key ${X509_USER_PROXY} \ - --capath ${X509_CERT_DIR} \ - --output /dev/null --silent --write-out '%{http_code}\n' \ - "$@"` -} diff --git a/org.glite.testsuites.ctb/gridsite/tests/gridsite-test-all.sh b/org.glite.testsuites.ctb/gridsite/tests/gridsite-test-all.sh deleted file mode 100755 index dae8f3e..0000000 --- a/org.glite.testsuites.ctb/gridsite/tests/gridsite-test-all.sh +++ /dev/null @@ -1,556 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing gridsite functions - -Prerequisities: - - GridSite and httpd with mod_ssl installe - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -COMMON=gridsite-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -NL="" -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ; NL="
";; - esac - shift -done - -# redirecting all output to $logfile -#touch $logfile -#if [ ! -w $logfile ]; then -# echo "Cannot write to output file $logfile" -# exit $TEST_ERROR -#fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - - -# check_binaries -printf "Testing if all binaries are available" -check_binaries curl rm chown openssl htcp htls htmv htcp htrm htls htls htproxydestroy awk sed openssl tail head sort -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -if getent passwd www-data >/dev/null; then - HTTPD_USER=www-data -else - HTTPD_USER=apache -fi - - - if [ ! -e /var/www/htdocs ]; then - mkdir /var/www/htdocs - fi - - printf "READ (Read Permissions)\n" - -cat >/var/www/htdocs/test.html <

Hello Grid

-EOF - - $SYS_RM /var/www/htdocs/.gacl - - printf "Plain read... " - code=`curl --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates --output /dev/null --silent --write-out '%{http_code}\n' https://$(hostname -f)/test.html` - printf "Return code $code" - if [ "$code" = "403" ]; then - test_done - else - test_failed - fi - -cat >/var/www/htdocs/.gacl < - - - - - -EOF - - - printf "With gacl... " - code=`curl --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates --output /dev/null --silent --write-out '%{http_code}\n' https://$(hostname -f)/test.html` - printf "Return code $code" - if [ "$code" = "200" ]; then - test_done - else - test_failed - fi - - - printf "Get index (list & read permissions)\n" - - printf "Plain read... " - code=`curl --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates --output /dev/null --silent --write-out '%{http_code}\n' https://$(hostname -f)/` - printf "Return code $code" - if [ "$code" = "403" ]; then - test_done - else - test_failed - fi - -cat >/var/www/htdocs/.gacl < - - - `openssl x509 -noout -subject -in /etc/grid-security/hostcert.pem | sed -e 's/^subject= //'` - - - - -EOF - - printf "With gacl... " - code=`curl --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates --output /dev/null --silent --write-out '%{http_code}\n' \ -https://$(hostname -f)/` - printf "Return code $code" - if [ "$code" = "200" ]; then - test_done - else - test_failed - fi - - - - - printf "WRITE & DELETE (write permissions)\n" - - rm -f /var/www/htdocs/.gacl /var/www/htdocs/test.txt - date > /tmp/test.txt - chown $HTTPD_USER /var/www/htdocs/ - - printf "Plain write... " - code=`curl --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates --output /dev/null --silent --write-out '%{http_code}\n' --upload-file /tmp/test.txt https://$(hostname -f)/test.txt` - printf "Return code $code" - if [ "$code" = "403" ]; then - test_done - else - test_failed - fi - -cat >/var/www/htdocs/.gacl < - - - `openssl x509 -noout -subject -in /etc/grid-security/hostcert.pem | sed -e 's/^subject= //'` - - - - -EOF - - printf "With gacl... " - code=`curl --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates --output /dev/null --silent --write-out '%{http_code}\n' --upload-file /tmp/test.txt https://$(hostname -f)/test.txt` - cmp -s /tmp/test.txt /var/www/htdocs/test.txt - printf "Return code $code" - if [ $? -eq 0 -a "$code" = "201" ]; then - test_done - else - test_failed - fi - - printf "Try deletion... " - mv /var/www/htdocs/.gacl /var/www/htdocs/.gacl.bak - code=`curl --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates --output /dev/null --silent --write-out '%{http_code}\n' -X DELETE https://$(hostname -f)/test.txt` - printf "Return code $code" - if [ $? -eq 0 -a "$code" = "403" ]; then - test_done - else - test_failed - fi - - mv /var/www/htdocs/.gacl.bak /var/www/htdocs/.gacl - - printf "With gacl... " - code=`curl --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates --output /dev/null --silent --write-out '%{http_code}\n' -X DELETE https://$(hostname -f)/test.txt` - printf "Return code $code" - if [ $? -eq 0 -a "$code" = "200" ]; then - test_done - else - test_failed - fi - chown root /var/www/htdocs - - - printf "Checking attributes passed on to the environment\n" - -cat >/var/www/htdocs/.gacl < - - - `openssl x509 -noout -subject -in /etc/grid-security/hostcert.pem | sed -e 's/^subject= //'` - - - - -EOF - -cat >/var/www/htdocs/test.cgi </dev/null 2>/dev/null - if [ $? -eq 0 ]; then - test_done - else - test_failed - fi - - - printf "Test the basic commands (htcp, htls, htmkdir, htmv, htrm)\n" - -cat >/var/www/htdocs/.gacl < - - - `openssl x509 -noout -subject -in /etc/grid-security/hostcert.pem | sed -e 's/^subject= //'` - - - - -EOF - - chown $HTTPD_USER /var/www/htdocs/ - - date > /tmp/test.txt - - printf "Testing htcp... " - htcp --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates/ /tmp/test.txt https://$(hostname -f)/ - if [ $? -eq 0 ]; then - test_done - else - test_failed - fi - printf "Checking by htls... " - htls --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates/ https://$(hostname -f)/test.txt > /dev/null - if [ $? -eq 0 ]; then - test_done - else - test_failed - fi - printf "Testing htmv... " - htmv --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates/ https://$(hostname -f)/test.txt https://$(hostname -f)/test2.txt - if [ $? -eq 0 ]; then - test_done - else - test_failed - fi - printf "htcp, file 2... " - htcp --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates/ https://$(hostname -f)/test2.txt /tmp - if [ $? -eq 0 ]; then - test_done - else - test_failed - fi - printf "Testing htrm... " - htrm --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates/ https://$(hostname -f)/test2.txt - if [ $? -eq 0 ]; then - test_done - else - test_failed - fi - printf "Checking by htls... " - htls --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates/ https://$(hostname -f)/test2.txt 2> /dev/null - if [ $? -eq 22 ]; then - test_done - else - test_failed - fi - printf "Checking directory contents with htls... " - htls --cert /etc/grid-security/hostcert.pem --key /etc/grid-security/hostkey.pem --capath /etc/grid-security/certificates/ https://$(hostname -f)/ > /dev/null - if [ $? -eq 0 ]; then - test_done - else - test_failed - fi - printf "File compare... " - cmp /tmp/test.txt /tmp/test2.txt - if [ $? -eq 0 ]; then - test_done - else - test_failed - fi - - chown root /var/www/htdocs/ - - printf "Test proxy delegation\n" - - if [ ! -e /var/www/proxycache ]; then - mkdir /var/www/proxycache - fi - chown $HTTPD_USER /var/www/proxycache - - #delegation - id=`htproxyput --cert /tmp/x509up_u0 --key /tmp/x509up_u0 --capath /etc/grid-security/certificates https://$(hostname -f)/gridsite-delegation.cgi` - printf "id: $id" - if [ $? -eq 0 -a -n "$id" ]; then - test_done - else - test_failed - fi - - expiry=`htproxyunixtime --cert /tmp/x509up_u0 --key /tmp/x509up_u0 --capath /etc/grid-security/certificates --delegation-id $id https://$(hostname -f)/gridsite-delegation.cgi` - - newid=`htproxyrenew --cert /tmp/x509up_u0 --key /tmp/x509up_u0 --capath /etc/grid-security/certificates --delegation-id $id https://$(hostname -f)/gridsite-delegation.cgi` - printf "newid: $newid" - if [ $? -eq 0 -a -n "$newid" ]; then - test_done - else - test_failed - fi - - htproxydestroy --cert /tmp/x509up_u0 --key /tmp/x509up_u0 --capath /etc/grid-security/certificates --delegation-id $id https://$(hostname -f)/gridsite-delegation.cgi - - - printf "Test handling of VOMS .lsc files (Regression test for bug #39254 and #82023)\n" - - if [ -e /tmp/x509up_u`id -u` ]; then - - # Add read permissions for any user to .gacl - sed -i 's/<\/gacl>/<\/allow><\/entry><\/gacl>/' /var/www/htdocs/.gacl - - FQAN=`voms-proxy-info --fqan` - - mkdir -p /tmp/vomsdir.$$ - mv -f /etc/grid-security/vomsdir/* /tmp/vomsdir.$$/ - printf "Trying with empty vomsdir. GRST_CRED_2 should not be present... " - GRST_CRED_2=`curl --cert /tmp/x509up_u0 --key /tmp/x509up_u0 --capath /etc/grid-security/certificates --cacert /tmp/x509up_u0 --silent https://$(hostname -f)/test.cgi|grep GRST_CRED_2` - if [ "$GRST_CRED_2" = "" ]; then - test_done - else - print_error "returned: $GRST_CRED_2\n" - test_failed - fi - mv -f /tmp/vomsdir.$$/* /etc/grid-security/vomsdir/ - rm -rf /tmp/vomsdir.$$ - - printf "Setting up .lsc file and trying again\n" - - UTOPIA=`voms-proxy-info -all | grep -A 100 "extension information" | grep "^issuer" | grep "L=Tropic" | grep "O=Utopia" | grep "OU=Relaxation"` - if [ "$UTOPIA" != "" ]; then - printf "Possibly fake VOMS extensions. Regenerating... " -# voms-proxy-info -all | grep -A 100 "extension information" | sed "s/\$/$NL/" - voms-proxy-init -voms vo.org -key $x509_USER_KEY -cert $x509_USER_CERT | sed "s/\$/$NL/" - fi; -# voms-proxy-info -all | grep -A 100 "extension information" | sed "s/\$/$NL/" - - for vomsfile in /etc/vomses/* - do - if [ -f $vomsfile ]; then - VOMSHOSTONLY=`cat $vomsfile | awk '{ print $2 }' | sed 's/"//g'` - VONAME=`cat $vomsfile | awk '{ print $1 }' | sed 's/"//g'` -# if [ ! -f /etc/grid-security/vomsdir/$VONAME/$VOMSHOSTONLY.lsc ]; then - VOMSHOST=`cat $vomsfile | awk '{ print $2 ":" $3; }' | sed 's/"//g'` - openssl s_client -connect $VOMSHOST 2>&1 | grep "^depth" | sed 's/^depth=//' | sort -r -n > $VOMSHOSTONLY.$$.DNs.txt - VOMSCERT=`tail -n 1 $VOMSHOSTONLY.$$.DNs.txt | sed -r 's/^[0-9]+\s+//'` - VOMSCA=`grep -E "^1[ \t]" $VOMSHOSTONLY.$$.DNs.txt | sed -r 's/^[0-9]+\s+//'` - - mkdir -p /etc/grid-security/vomsdir/$VONAME - printf "$VOMSCERT\n$VOMSCA\n" > /etc/grid-security/vomsdir/$VONAME/$VOMSHOSTONLY.lsc - - printf "Generated /etc/grid-security/vomsdir/$VONAME/$VOMSHOSTONLY.lsc\n$NL" - - rm $VOMSHOSTONLY.$$.DNs.txt -# else -# printf "/etc/grid-security/vomsdir/$VONAME/$VOMSHOSTONLY.lsc already exists\n$NL" -# fi - -# cat /etc/grid-security/vomsdir/$VONAME/$VOMSHOSTONLY.lsc | sed "s/\$/$NL/" - fi - done - -exit 0 - GRST_CRED_2=`curl --cert /tmp/x509up_u0 --key /tmp/x509up_u0 --capath /etc/grid-security/certificates --cacert /tmp/x509up_u0 --silent https://$(hostname -f)/test.cgi|grep GRST_CRED_2` - - if [ "$GRST_CRED_2" = "" ]; then - print_error "GRST_CRED_2 not returned" - test_failed - else - test_done - - printf "Checking for presence of FQAN... " - echo "$GRST_CRED_2" | grep "$FQAN" > /dev/null - if [ $? = 0 ]; then - test_done - else - print_error "returned: $GRST_CRED_2" - test_failed - fi - fi - - printf "Test listing of VOMS attributes (Regression test for bug #92077)\n" - - printf "Getting list of Role attributes from voms-proxy-info... " - voms-proxy-info -all | grep -E "^attribute[ \t]+:" | grep "Role=" | sed -r 's/^attribute[ \t]+:[ \t]*//' > info-roles.$$.out - - if [ ! -s info-roles.$$.out ]; then - printf "EMPTY!" - test_skipped - else - test_done - printf "Getting list of Role attributes from test.cgi... " - - curl --cert /tmp/x509up_u0 --key /tmp/x509up_u0 --capath /etc/grid-security/certificates --cacert /tmp/x509up_u0 --silent https://$(hostname -f)/test.cgi|grep -E "^GRST_CRED_AURI_.*Role=" | sed -r 's/^GRST_CRED_AURI_[0-9]+=fqan://' > test-roles-pre.$$.out - - if [ ! -s info-roles.$$.out ]; then - printf "EMPTY!" - test_failed - print_error "No role attributes found, even before re-running init" - else - test_done - printf "re-running voms extensions... " - voms-proxy-init -noregen > /dev/null 2> /dev/null - test_done - printf "Getting another set of Role attributes from test.cgi... " - curl --cert /tmp/x509up_u0 --key /tmp/x509up_u0 --capath /etc/grid-security/certificates --cacert /tmp/x509up_u0 --silent https://$(hostname -f)/test.cgi|grep -E "^GRST_CRED_AURI_.*Role=" | sed -r 's/^GRST_CRED_AURI_[0-9]+=fqan://' > test-roles-post.$$.out - if [ ! -s test-roles-post.$$.out ]; then - test_failed - print_error "List of role attributes is empty!" - else - test_done - printf "Comparing attributes... " - diff --ignore-case test-roles-pre.$$.out test-roles-post.$$.out > /dev/null - if [ $? -eq 0 ]; then - test_done - else - sort test-roles-pre.$$.out > test-roles-pre.$$.out.sorted - sort test-roles-post.$$.out > test-roles-post.$$.out.sorted - diff --ignore-case test-roles-pre.$$.out.sorted test-roles-post.$$.out.sorted > /dev/null - if [ $? -eq 0 ]; then - printf "Matching, but out of order!" - test_warning - else - test_error - print_error "A non-matching set of role attributes has been returned" - fi - fi - fi - fi - fi - - rm info-roles.$$.out test-roles-pre.$$.out* test-roles-post.$$.out* - else - printf "No proxy certificate" - test_skipped - fi - - printf "Test flavours and sonames\n" - for prefix in /usr /opt/glite; do - for libdir in 'lib64' 'lib'; do - if test -f $prefix/$libdir/libgridsite.so.*.*.*; then - path="$prefix/$libdir" - fi - done - done - for flavour in '' '_nossl' '_globus'; do - printf " flavour '$flavour' " - if test -f $path/libgridsite$flavour.so.*.*.*; then - printf "$path/libgridsite$flavour.so " - readelf -a $path/libgridsite$flavour.so.*.*.* | grep -i soname | grep libgridsite$flavour\.so\. >/dev/null - if test $? = 0; then - test_done - else - print_error "bad soname" - test_failed - fi - else - print_error "not present" - test_failed - fi - done - - printf "Check interpretable DEFVERSION... " - DEFVERSION=`cat /usr/share/doc/*gridsite*/VERSION | grep "^DEFVERSION" | head -n 1 | sed 's/DEFVERSION[ \t]*=[ \t]*//'` - printf "Oct %o, Hex %x" $DEFVERSION $DEFVERSION - if [ $? -eq 0 ]; then - test_done - else - test_failed - print_error "Failed to interpret DEFVERSION as a number" - fi - -test_end -} -#} &> $logfile - -#if [ $flag -ne 1 ]; then -# cat $logfile -# $SYS_RM $logfile -#fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/gridsite/tests/gridsite-test-packaging.sh b/org.glite.testsuites.ctb/gridsite/tests/gridsite-test-packaging.sh deleted file mode 100755 index 3cdb2f4..0000000 --- a/org.glite.testsuites.ctb/gridsite/tests/gridsite-test-packaging.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/bin/bash -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script producing errors and warnings due to packaging. - -Prerequisities: - - installed all tested packages - - Scientific Linux: installed rpmlint - - Debian: installed lintian - -Tests called: - - called rpmlint or lintian on the packages - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." -} - -# read common definitions and functions -for COMMON in gridsite/gridsite-common.sh LB/lb-common.sh -do - SUBSYS=`dirname $COMMON` - FILE=`basename $COMMON` - if [ ! -r ${FILE} ]; then - printf "Downloading common definitions '${COMMON}'" - wget -q -O ${FILE} http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi/org.glite.testsuites.ctb/$SUBSYS/tests/$FILE?view=co > /dev/null - if [ ! -r ${FILE} ]; then - exit 2 - else - chmod +x $FILE - test_done - fi - fi - source $FILE -done - -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - esac - shift -done - - -## -# Starting the test -##################### - -test_start - - -if egrep -i "Debian|Ubuntu" /etc/issue >/dev/null; then - check_lintian libgridsite\* - ret=$? -else - check_rpmlint gridsite-\* - ret=$? -fi - -#printf "Packages compliance..." -#if test $ret -eq 0; then -# test_done -#else -# test_failed -#fi - - -test_end - -exit $TEST_OK diff --git a/org.glite.testsuites.ctb/gridsite/tests/ping-local.sh b/org.glite.testsuites.ctb/gridsite/tests/ping-local.sh deleted file mode 100755 index 6fa1aba..0000000 --- a/org.glite.testsuites.ctb/gridsite/tests/ping-local.sh +++ /dev/null @@ -1,120 +0,0 @@ -#!/bin/bash -# $Id$ - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing the GridSite components locally - -Prerequisities: - - Apache with the GridSite module enabled running on local machine - -Tests: - - Checks that Apache is running and listening to port 443. - - Checks that the GridSite module is loaded in the Apache configuration - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS]" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." - echo " -f | --config Apache config file." -} - -# read common definitions and functions -COMMON=gridsite-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - "-f" | "--config") shift; apache_config_arg="-f $1" ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $SYS_LSOF $SYS_GREP $SYS_SED $SYS_PS $SYS_PIDOF $SYS_APACHECTL -if [ $? -gt 0 ]; then - test_failed -else - test_done -fi - -# Apache running: -printf "Testing if Apache is running" -if [ "$(${SYS_PIDOF} ${SYS_APACHE})" ]; then - test_done -else - test_failed - print_error "Apache server is not running" -fi - -# GridSite module loaded: -printf "Testing if GridSite is loaded" -${SYS_APACHECTL} ${apache_config_arg} -t -D DUMP_MODULES 2>&1| grep gridsite_module >/dev/null 2>&1 -if [ $? -eq 0 ]; then - test_done -else - test_failed - print_error "GridSite is not loaded in Apache" -fi - -# Server listening: -printf "Testing if Apache is listening on port 443" -check_listener ${SYS_APACHE} 443 -if [ $? -eq 0 ]; then - test_done -else - test_failed - print_error "Apache server is not listening on port 443" -fi - -test_end -} &> $logfile - -if [ $flag -ne 1 ]; then - cat $logfile - $SYS_RM $logfile -fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/gridsite/tests/ping-remote.sh b/org.glite.testsuites.ctb/gridsite/tests/ping-remote.sh deleted file mode 100755 index 91bc0b0..0000000 --- a/org.glite.testsuites.ctb/gridsite/tests/ping-remote.sh +++ /dev/null @@ -1,117 +0,0 @@ -#!/bin/bash -# $Id$ - -# show help and usage -progname=`basename $0` -showHelp() -{ -cat << EndHelpHeader -Script for testing The GridSite components remotely - -Prerequisities: - - Apache with the GridSite module enabled running on remote machine - -Tests: - - ping_host() - network ping to Apache server host - - check_socket() - simple tcp echo to port 443 of the host - -Returned values: - Exit TEST_OK: Test Passed - Exit TEST_ERROR: Test Failed - Exit 2: Wrong Input - -EndHelpHeader - - echo "Usage: $progname [OPTIONS] host" - echo "Options:" - echo " -h | --help Show this help message." - echo " -o | --output 'file' Redirect all output to the 'file' (stdout by default)." - echo " -t | --text Format output as plain ASCII text." - echo " -c | --color Format output as text with ANSI colours (autodetected by default)." - echo " -x | --html Format output as html." - echo "" - echo "where host is the Apache server host, it must be specified everytime." -} -if [ -z "$1" ]; then - showHelp - exit 2 -fi - -# read common definitions and functions -COMMON=gridsite-common.sh -if [ ! -r ${COMMON} ]; then - printf "Common definitions '${COMMON}' missing!" - exit 2 -fi -source ${COMMON} - -logfile=$$.tmp -flag=0 -while test -n "$1" -do - case "$1" in - "-h" | "--help") showHelp && exit 2 ;; - "-o" | "--output") shift ; logfile=$1 flag=1 ;; - "-t" | "--text") setOutputASCII ;; - "-c" | "--color") setOutputColor ;; - "-x" | "--html") setOutputHTML ;; - *) APACHE_HOST=$1 ;; - esac - shift -done - -# redirecting all output to $logfile -touch $logfile -if [ ! -w $logfile ]; then - echo "Cannot write to output file $logfile" - exit $TEST_ERROR -fi - -DEBUG=2 - -## -# Starting the test -##################### - -{ -test_start - -# check_binaries -printf "Testing if all binaries are available" -check_binaries $SYS_NC $SYS_PING $SYS_GREP -if [ $? -gt 0 ]; then - test_failed - print_error "Some binaries are missing" -else - test_done -fi - -# ping_host: -printf "Testing ping to Apache server ${APACHE_HOST}" -ping_host ${APACHE_HOST} -if [ $? -gt 0 ]; then - test_failed - print_error "Destination host might be unreachable" -else - test_done -fi - -# check_services -printf "Testing Apache server at ${APACHE_HOST}:443" -check_socket ${APACHE_HOST} 443 -if [ $? -gt 0 ]; then - test_failed - print_error "Apache server at ${APACHE_HOST}:443 might be unreachable" -else - test_done -fi - -test_end -} &> $logfile - -if [ $flag -ne 1 ]; then - cat $logfile - $SYS_RM $logfile -fi -exit $TEST_OK - diff --git a/org.glite.testsuites.ctb/gridsite/tests/test-common.sh b/org.glite.testsuites.ctb/gridsite/tests/test-common.sh deleted file mode 100644 index 15ed38e..0000000 --- a/org.glite.testsuites.ctb/gridsite/tests/test-common.sh +++ /dev/null @@ -1,260 +0,0 @@ -# $Header$ -# -# Copyright (c) Members of the EGEE Collaboration. 2004-2010. -# See http://www.eu-egee.org/partners for details on the copyright holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# ------------------------------------------------------------------------------ -# Definition of test script return messages -# -# The test scripts should use the variables test_done and test_failed to -# report whether they failed or succeeded. -# -# The variable test_reset is used to turn off all attributes and switch -# to the standard character set. -# -# \033 ascii ESCape -# \033[G move to column (linux console, xterm, not vt100) -# \033[C move columns forward but only upto last column -# \033[D move columns backward but only upto first column -# \033[A move rows up -# \033[B move rows down -# \033[1m switch on bold -# \033[31m switch on red -# \033[32m switch on green -# \033[33m switch on yellow -# \033[m switch off color/bold -# \017 exit alternate mode (xterm, vt100, linux console) -# \033[10m exit alternate mode (linux console) -# \015 carriage return (without newline) -# -# See also United Linux or OpenSUSE /etc/rc.status script -# -# ------------------------------------------------------------------------------ - -# Do _not_ be fooled by non POSIX locale -LC_ALL=POSIX -export LC_ALL - -# Seek for terminal size and, if needed, set default size -if [ -z "${LINES}" -o -z "${COLUMNS}" ]; then - stty_size=`stty size 2> /dev/null` - if [ $? = 0 ]; then - LINES=`echo ${stty_size} | awk '{print $1}'` - COLUMNS=`echo ${stty_size} | awk '{print $2}'` - else - LINES=24 - if [ $LBTSTCOLS -gt 0 ]; then - COLUMNS=$LBTSTCOLS - else - COLUMNS=80 - fi - fi -fi -if [ ! $LINES -ge 0 ]; then LINES=24; fi -if [ ! $COLUMNS -ge 0 ]; then COLUMNS=80; fi -export LINES COLUMNS - -# default return values -TEST_ERROR=1 -TEST_OK=0 - -# test error file -testerrfile=$$.err - -function set_test() -{ -test_done="${spacefill}${begin_green}done${end_green}" -test_running="${spacefill}${begin_green}running${end_green}" -test_failed="${spacefill}${begin_red}-TEST FAILED-${end_red}" -test_missed="${spacefill}${begin_red}missing${end_red}" -test_skipped="${spacefill}${begin_yellow}skipped${end_yellow}" -test_warning="${spacefill}${begin_yellow}warning${end_yellow}" -test_dead="${spacefill}${begin_red}dead${end_red}" -test_unused="${spacefill}${begin_bold}unused${end_bold}" -test_unknown="${spacefill}${begin_yellow}unknown${end_yellow}" - -test_start="${spacefill}${begin_green}start${end_green}" -test_end="${spacefill}${begin_green}end${end_green}" -} - -function test_done() { printf "${test_done}${lf}"; } -function test_running() { printf "${test_running}${lf}"; } -function test_failed() { printf "${test_failed}${lf}"; } -function test_missed() { printf "${test_missed}${lf}"; } -function test_skipped() { printf "${test_skipped}${lf}"; } -function test_warning() { printf "${test_warning}${lf}"; } -function test_dead() { printf "${test_dead}${lf}"; } -function test_unused() { printf "${test_unused}${lf}"; } -function test_unknown { printf "${test_unknown}${lf}"; } -function test_start() { - syslog "${test_start}"; - reset_error -} -function test_end() { - syslog "${test_end}"; - reset_error -} - -# set output to ASCII (without colors) -function setOutputASCII() -{ -lf="\n" -spacefill="..." - -begin_bold="" -begin_black="" -begin_red="" -begin_green="" -begin_yellow="" -begin_blue="" -begin_magenta="" -begin_cyan="" -begin_white="" - -end_bold="" -end_black="" -end_red="" -end_green="" -end_yellow="" -end_blue="" -end_magenta="" -end_cyan="" -end_white="" - -set_test -} - -# set output to ASCII with ANSI colors -function setOutputColor() -{ -local esc=`echo -en "\033"` -local normal="${esc}[0m" # unsets color to term's fg color -lf="\n" -spacefill=`echo -en "\015${esc}[${COLUMNS}C${esc}[15D"` - -begin_bold="${esc}[0;1m" -begin_black="${esc}[0;30m" -begin_red="${esc}[0;31m" -begin_green="${esc}[0;32m" -begin_yellow="${esc}[0;33m" -begin_blue="${esc}[0;34m" -begin_magenta="${esc}[0;35m" -begin_cyan="${esc}[0;36m" -begin_white="${esc}[0;37m" - -end_bold="$normal" -end_black="$normal" -end_red="$normal" -end_green="$normal" -end_yellow="$normal" -end_blue="$normal" -end_magenta="$normal" -end_cyan="$normal" -end_white="$normal" - -set_test -} - -# set output to HTML -function setOutputHTML() -{ -local ENDFONT="
" -lf="
\n" -spacefill="   " -is_html=1 - -begin_bold="" -begin_black="" -begin_red="" -begin_green="" -begin_yellow="" -begin_blue="" -begin_magenta="" -begin_cyan="" -begin_white="" - -end_bold="" -end_black="$ENDFONT" -end_red="$ENDFONT" -end_green="$ENDFONT" -end_yellow="$ENDFONT" -end_blue="$ENDFONT" -end_magenta="$ENDFONT" -end_cyan="$ENDFONT" -end_white="$ENDFONT" - -set_test -} - -function reset_error() -{ - rm -f $testerrfile -} - -function set_error() -{ - printf "%s ${lf}" "$*" > $testerrfile -} - -function update_error() -{ - printf "%s; " "$*" >> $testerrfile -} - -function print_error() -{ - printf "\t${begin_red}Error${end_red}: %s ${lf}" "$*" - - if [ -f $testerrfile ]; then - printf "\t${begin_red}Error${end_red}: %s ${lf}" "`cat $testerrfile`" - fi - reset_error -} - -function print_warning() -{ - printf "${begin_magenta}Warning${end_magenta}: %s ${lf}" "$*" -} - -function print_info() -{ - printf "${begin_blue}Info${end_blue}: %s ${lf}" "$*" -} - -function print_newline() -{ - printf "${lf}" -} - -function syslog() -{ - local tmp="`date +'%b %d %H:%M:%S'` `hostname` $progname" - printf "${begin_bold}${tmp}${end_bold}: %s ${lf}" "$*" -} - -function dprintf() -{ - if [ $DEBUG -gt 0 ]; then - printf "%s${lf}" "$*" - fi -} - -# by default set output to color if possible -if test -t 1 -a "$TERM" != "raw" -a "$TERM" != "dumb" && stty size <&1 > /dev/null 2>&1 ; then - setOutputColor -else - setOutputASCII -fi - diff --git a/org.glite.wms-utils.exception/.cvsignore b/org.glite.wms-utils.exception/.cvsignore deleted file mode 100644 index e970233..0000000 --- a/org.glite.wms-utils.exception/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project \ No newline at end of file diff --git a/org.glite.wms-utils.exception/LICENSE b/org.glite.wms-utils.exception/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.wms-utils.exception/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.wms-utils.exception/Makefile.am b/org.glite.wms-utils.exception/Makefile.am deleted file mode 100755 index b66c2bb..0000000 --- a/org.glite.wms-utils.exception/Makefile.am +++ /dev/null @@ -1,67 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -## Process this file with automake to produce Makefile.in -EXTRA_DIST = LICENSE - -docdir = $(datadir)/doc/@PACKAGE@-@VERSION@ -doc_DATA = LICENSE -## Subdirectories list -SUBDIRS = interface src - -## Default flags to run aclocal -ACLOCAL_AMFLAGS = -I project - -stage: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target="install"; \ - prefix_arg="@prefix@"; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target $$prefix_arg in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target $$prefix_arg) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" $$prefix_arg || exit 1; \ - fi; test -z "$$fail" - -distsrc: dist - mv $(distdir).tar.gz $(DISTTAR)/$(distdir)_src.tar.gz - -distbin: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target="install"; \ - tmpdistbin="$(WORKDIR)/dist_bin"; \ - prefix_arg="prefix=$$tmpdistbin"; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target $$prefix_arg in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target $$prefix_arg) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" $$prefix_arg || exit 1; \ - fi; test -z "$$fail"; \ - pushd $$tmpdistbin; \ - $(AMTAR) -zcf $(DISTTAR)/$(distdir)_bin.tar.gz .; \ - popd; \ - rm -rf $$tmpdistbin - diff --git a/org.glite.wms-utils.exception/bootstrap b/org.glite.wms-utils.exception/bootstrap deleted file mode 100755 index 168aca4..0000000 --- a/org.glite.wms-utils.exception/bootstrap +++ /dev/null @@ -1,28 +0,0 @@ -#! /bin/sh - -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://www.eu-egee.org/partners/ for details on the copyright -# holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -[ $# -ne 0 ] && ac_dir="-I $1" - -mkdir -p src/autogen -set -x -aclocal ${ac_dir} -I project -libtoolize --force -autoheader -automake --foreign --add-missing --copy -autoconf - diff --git a/org.glite.wms-utils.exception/build.xml b/org.glite.wms-utils.exception/build.xml deleted file mode 100755 index d12e8c2..0000000 --- a/org.glite.wms-utils.exception/build.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.exception/configure.ac b/org.glite.wms-utils.exception/configure.ac deleted file mode 100755 index 0ba6571..0000000 --- a/org.glite.wms-utils.exception/configure.ac +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://www.eu-egee.org/partners/ for details on the copyright -# holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# $Id$ - -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.57) -AC_INIT([org.glite.wms-utils.exception], [3.1.1]) -AC_CONFIG_AUX_DIR([./project]) -AM_INIT_AUTOMAKE([1.6.3 subdir-objects]) -AC_CONFIG_SRCDIR([src/Exception.cpp]) - -# Notices. -AC_COPYRIGHT([Copyright (c) 2004 The EU EGEE Project -See LICENCE file for details -]) -AC_REVISION([$Revision$]) - -# Checks for programs. -AC_PROG_CC -AC_PROG_CXX -AC_PROG_LIBTOOL - -# Checks for libraries. - -# Checks for header files. - -# Checks for typedefs, structures, and compiler characteristics. - -# Checks for library functions. - -GLITE_BASE - -# Configuration items -AC_PREFIX_DEFAULT([/opt/glite]) -AM_CONFIG_HEADER([src/autogen/config.h]) -AC_CONFIG_FILES([Makefile]) -AC_CONFIG_FILES([src/Makefile]) -AC_CONFIG_FILES([interface/Makefile]) - -AC_OUTPUT - diff --git a/org.glite.wms-utils.exception/interface/Makefile.am b/org.glite.wms-utils.exception/interface/Makefile.am deleted file mode 100755 index 3c4ccb7..0000000 --- a/org.glite.wms-utils.exception/interface/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -exceptiondir = $(includedir) -nobase_exception_HEADERS = \ - glite/wmsutils/exception/exception_codes.h \ - glite/wmsutils/exception/Exception.h - -MAINTAINERCLEANFILES = Makefile.in diff --git a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h b/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h deleted file mode 100644 index 19ca7c7..0000000 --- a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/Exception.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef GLITE_WMS_UTILS_EXCEPTION_EXCEPTION_H -#define GLITE_WMS_UTILS_EXCEPTION_EXCEPTION_H - -/* - * Exception.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - * Contributors are mentioned in the code where appropriate. - */ - -#include -#include -//#include -#include // For logging exceptions to log file -#include // list the exception codes -#include -#include -#include // base ancestor stl::exception - - -namespace glite { - namespace wmsutils { - namespace exception { - -extern pthread_mutex_t METHOD_MUTEX; // used in order to store info into a file (rather then syslog) -#define GLITE_STACK_TRY(method_name) std::string METHOD = method_name ; int LINE = __LINE__ ; try { -#define GLITE_STACK_CATCH() } catch (glite::wmsutils::exception::Exception &exc){ exc.push_back ( __FILE__ , LINE, METHOD ); throw exc ; } catch (std::exception &ex){ glite::wmsutils::exception::Exception exc( __FILE__ , LINE, METHOD, 0, "Standard exception: " + std::string(ex.what()) ); throw exc; } - -/** - * The Exception base classe contains attributes into which are placed exception information and provides - * constructor that beyond the error code take parameters specifying the source file and line number - * (e.g. through __FILE__ and __LINE__) where the error has been generated and string messages, - * allowing an easy way of storing the origin of the exception. - * Moreover it provides methods for getting all the exception information and for logging them either - * in a log file or to the syslog daemon. - * Each of the derived types may contain its private attributes describing the actual error instance in detail. - * Moreover each exception has an attribute representing the exception identifier that is set by the - * class constructor and allows the identification of the original exception. - * - * @version 0.1 - * @date 22 July 2004 - * @author Alessandro Maraschini -*/ - -class Exception : public std::exception{ - public: - /** - * Constructor Update all mandatory fields - * @param method the name of the method that raised the exception - * @param source The source that raised the exception (could be the file path, the class Name, etc etc) - * @param exc the previous exception as in the stack trace */ - Exception ( const std::string& source, const std::string& method, Exception *exc); - /** - * Constructor Update all mandatory fields - * @param code the code representing the thrown exception - * @param exception the name of the thrown exception - * @param method the name of the method that raised the exception - * @param source The source that raised the exception (could be the file path, the class Name, etc etc) */ - Exception ( const std::string& source, const std::string& method, int code, const std::string& exception); - - /** - * Constructor Update all mandatory fields - * @param source the path of the file that raised the exception - * @param line_number the number of the line in the file that raised the exception - * @param method the name of the method that raised the exception - * @param code the code representing the thrown exception - * @param exception the name of the thrown exception */ - Exception (const std::string& source, int line_number, const std::string& method, int code, const std::string& exception); - /** - * Default Destructor - */ - virtual ~Exception() throw (); - /** - * Return a string debug message containing information about Exception thrown - * Debug message contains all the attributes stored in an exception instance such as the method, the file and the line - * that threw the exception. - *@return the debug message string representation - */ - virtual std::string dbgMessage(); - /** - * Return the error code - * @return The integer representing the code of the error that generated the exception - */ - virtual int getCode(); - - /** - * return the Error Message associated to the Exception - * @return The Exception string message representation - */ - virtual const char* what() const throw (); - - /** - * Print Exception error information into a log file - * @param logfile the file where to log exception information - */ - virtual void log(const std::string& logfile = ""); - /** - * Retrieve the Exception name - * @return the name of the Exception thrown - */ - virtual std::string getExceptionName(); - - /** - * Retrieve the Stack of the exception as a list of previous generated exceptions - *@return the string representation of the stack trace: each line correspond to an exception message - */ - virtual std::string printStackTrace() ; - /** - * Return the list of methods that caused the Exception - */ - virtual std::vector getStackTrace() ; - /** - * Update stack information - */ - virtual void push_back ( const std::string& source, int line_number, const std::string& method ) ; - protected: - /** Empty constructor*/ - Exception(); - /** integer error code representing the cause of the error */ - int error_code; - /** string exception message representation*/ - std::string error_message ; - /** line number where the exception was raised */ - int line; - /** The name of the file where the exception was raised */ - std::string source_file; - /** the name of the exception */ - std::string exception_name; - /** the name of the method where the expceiton was raised */ - std::string method_name ; - /** a string representation of the stacktrace */ - std::string stack; - /** the actual internal stacktrace representation */ - std::vector< std::string> stack_strings ; - /** the name of the ancestor exception */ - std::string ancestor ; -}; //End Exception Class -}}} // Closing namespace -#endif diff --git a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h b/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h deleted file mode 100755 index fce99aa..0000000 --- a/org.glite.wms-utils.exception/interface/glite/wmsutils/exception/exception_codes.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef GLITE_WMSUTILS_EXCEPTION_CODES_H -#define GLITE_WMSUTILS_EXCEPTION_CODES_H -// pure C-style code (needed by some libraries) -#define GLITE_WMS_COMMON_ERROR_BASE 900 -#define GLITE_WMS_USERINTERFACE_ERROR_BASE 1000 -#define GLITE_WMS_NETWORKSERVER_ERROR_BASE 1200 -#define GLITE_WMS_SOCKET_ERROR_BASE 1300 -#define GLITE_WMS_LDAP_ERROR_BASE 1350 -#define GLITE_WMS_LOGGING_ERROR_BASE 1400 -#define GLITE_WMS_REQUESTAD_ERROR_BASE 1500 -#define GLITE_WMS_CHECKPOINT_ERROR_BASE 1600 -#define GLITE_WMS_CONFIGURATION_ERROR_BASE 1800 -#ifdef __cplusplus -namespace glite { -namespace wmsutils { -namespace exception { - /** - * The Error Code - */ - enum { - WMS_COMMON_BASE = GLITE_WMS_COMMON_ERROR_BASE, - THREAD_INIT , // pthread_attr_init method failed - THREAD_DETACH , // pthread_attr_setdetachstate method failed - THREAD_CREATE , // pthread_create method failed - THREAD_JOIN, - THREAD_SSL, - WMS_FATAL_ERROR, - WMS_UI_ERROR_BASE = GLITE_WMS_USERINTERFACE_ERROR_BASE, - WMS_NS_ERROR_BASE = GLITE_WMS_NETWORKSERVER_ERROR_BASE, - WMS_SOCKET_ERROR_BASE = GLITE_WMS_SOCKET_ERROR_BASE, - WMS_LDAP_ERROR_BASE = GLITE_WMS_LDAP_ERROR_BASE, - WMS_LB_ERROR_BASE = GLITE_WMS_LOGGING_ERROR_BASE , - WMS_REQUESTAD_ERROR_BASE = GLITE_WMS_REQUESTAD_ERROR_BASE, - WMS_CHKPT_ERROR_BASE = GLITE_WMS_CHECKPOINT_ERROR_BASE, - WMS_CONFIGURATION_ERROR_BASE = GLITE_WMS_CONFIGURATION_ERROR_BASE - }; -} // exception namespace -} // wmsutils namespace -} // glite namespace -#endif //ifdef c++ -#endif diff --git a/org.glite.wms-utils.exception/project/build.number b/org.glite.wms-utils.exception/project/build.number deleted file mode 100644 index 95bc38e..0000000 --- a/org.glite.wms-utils.exception/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Oct 15 02:08:14 CEST 2005 -module.build=154 diff --git a/org.glite.wms-utils.exception/project/build.properties b/org.glite.wms-utils.exception/project/build.properties deleted file mode 100755 index f4aef51..0000000 --- a/org.glite.wms-utils.exception/project/build.properties +++ /dev/null @@ -1,2 +0,0 @@ -build.package.summary="files for gLite wms utils exception" -build.package.description="exception api" diff --git a/org.glite.wms-utils.exception/project/configure.properties.xml b/org.glite.wms-utils.exception/project/configure.properties.xml deleted file mode 100644 index 04d3b17..0000000 --- a/org.glite.wms-utils.exception/project/configure.properties.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/org.glite.wms-utils.exception/project/properties.xml b/org.glite.wms-utils.exception/project/properties.xml deleted file mode 100755 index 1e49af0..0000000 --- a/org.glite.wms-utils.exception/project/properties.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.exception/project/version.properties b/org.glite.wms-utils.exception/project/version.properties deleted file mode 100755 index 40c3916..0000000 --- a/org.glite.wms-utils.exception/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=3.1.1 -module.age=1 diff --git a/org.glite.wms-utils.exception/src/Exception.cpp b/org.glite.wms-utils.exception/src/Exception.cpp deleted file mode 100644 index 546f253..0000000 --- a/org.glite.wms-utils.exception/src/Exception.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* ************************************************************************** -* filename : Exceptions.cpp -* author : Alessandro Maraschini -* copyright : (C) 2002 by DATAMAT -***************************************************************************/ - -#include "glite/wmsutils/exception/Exception.h" -#include "glite/wmsutils/exception/exception_codes.h" - -namespace glite { -namespace wmsutils{ -namespace exception { -using namespace std ; -pthread_mutex_t METHOD_MUTEX ; // This mutex is used in order to lock the file for writing log infornation - -/* ********************************* -* Exception Class Implementation -************************************/ -//Constructor/Destructor - -Exception::Exception () { - line = 0; -}; - -Exception::~Exception() throw(){ } - -/** -* Exception chainig -*/ -void Exception::push_back (const string& source, int line_number, const string& method){ - stack_strings.push_back (dbgMessage()); - ancestor = what(); - source_file = source; - line = line_number; - method_name = method; - error_message = ""; - exception_name = ""; -} - -Exception::Exception( const std::string& file, int line_number, const std::string& method, int code, const std::string& name) - : error_code(code), exception_name(name){ - source_file = file; - line = line_number; - method_name = method; -}; - -Exception::Exception (const string& source, const string& method, int code, const string& exception) - : error_code(code), exception_name(exception){ - source_file = source; - method_name = method; - // stack= ""; - line = 0; -}; - -int Exception::getCode(){ - if (error_code != 0) return error_code; - else - return WMS_COMMON_BASE; -}; - -const char* Exception::what() const throw(){ - if (!ancestor.empty()) return ancestor.c_str(); - - return error_message.c_str(); -}; - -string Exception::getExceptionName(){ - return exception_name; -}; - -void Exception::log(const std::string& logfile) -{ - if (logfile == "") - syslog (LOG_PERROR, (char *)(dbgMessage()).c_str()); - else{ - pthread_mutex_lock( &METHOD_MUTEX); // LOCK - //TBD : test if file exist-->>Create HEADER ?? - ofstream fout ((char *) logfile.c_str() , ios::app ); //Open the file for writing (if it doesn't exist then it will be created) - fout << "\n" << dbgMessage() ; //write (append) the message - fout.close(); //close the file - pthread_mutex_unlock( &METHOD_MUTEX); // UNLOCK - } -}; - -string Exception::printStackTrace(){ - string stack = "" ; - for (unsigned int i = 0 ; i < stack_strings.size() ; i++ ){ - stack+=stack_strings[i] +"\n" ; - } - return stack +dbgMessage(); -}; - -vector Exception::getStackTrace(){ - // make a copy of the stack - vector stack = stack_strings ; - stack.push_back(dbgMessage()) ; - return stack; -}; - -string Exception::dbgMessage(){ - string result ; - //Adding exception Name - result = exception_name; - - //Adding error msg - if (error_message!="") result +=": " + string(what()); - - if (result != "") result+="\n"; - - //Adding Source - result +="\tat " + method_name +"[" +source_file; - - //Adding line number - if (line!=0){ - char buffer [1024] ; - sprintf (buffer, "%i" , line) ; - result += ":" + string ( buffer ); - } - result +="]" ; - return result; -} - -}}} // Closing namespace - diff --git a/org.glite.wms-utils.exception/src/Makefile.am b/org.glite.wms-utils.exception/src/Makefile.am deleted file mode 100755 index 0c5caac..0000000 --- a/org.glite.wms-utils.exception/src/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -lib_LTLIBRARIES = libglite_wmsutils_exception.la - -libglite_wmsutils_exception_la_SOURCES = \ - Exception.cpp - -AM_CPPFLAGS = -I$(top_srcdir)/interface \ - -I$(top_srcdir)/src - -MAINTAINERCLEANFILES = Makefile.in *.*~ diff --git a/org.glite.wms-utils.exception/test/Makefile.am b/org.glite.wms-utils.exception/test/Makefile.am deleted file mode 100755 index a972450..0000000 --- a/org.glite.wms-utils.exception/test/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -EXCEPTION_LIBS = $(top_builddir)/src/libglite_wmsutils_exception.la - -TESTS = glite-wmsutils-exception - -check_PROGRAMS = $(TESTS) - -glite_wmsutils_exception_SOURCES = exception_cu_suite.cpp \ - exception_cu_suite.h \ - exception_cu_main.cpp - -glite_wmsutils_exception_LDADD = \ - $(GLITE_WMSUTILS_EXCEPTION_LIBS) \ - $(GLOBUS_GSS_THR_LIBS) \ - $(EXCEPTION_LIBS) \ - $(CPPUNIT_LIBS) - -AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/test \ - $(GLITE_CFLAGS) \ - $(GLOBUS_THR_CFLAGS) \ - $(CPPUNIT_CFLAGS) - -MAINTAINERCLEANFILES = Makefile.in *~ - diff --git a/org.glite.wms-utils.exception/test/exception_cu_main.cpp b/org.glite.wms-utils.exception/test/exception_cu_main.cpp deleted file mode 100644 index 182df4c..0000000 --- a/org.glite.wms-utils.exception/test/exception_cu_main.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include "exception_cu_suite.h" - -#include -#include -#include -#include -#include - -using namespace CppUnit; -using namespace std; - -int main (int argc , char** argv) -{ - std::ofstream xml("./cppUnit_output.xml",ios::app); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - TestRunner runner; - runner.addTest(Exception_test::suite()); - runner.run(controller); - - CppUnit::XmlOutputter outputter( &result, xml ); - CppUnit::TextOutputter outputter2( &result, std::cerr ); - outputter.write(); - outputter2.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} diff --git a/org.glite.wms-utils.exception/test/exception_cu_suite.cpp b/org.glite.wms-utils.exception/test/exception_cu_suite.cpp deleted file mode 100644 index f749af9..0000000 --- a/org.glite.wms-utils.exception/test/exception_cu_suite.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "exception_cu_suite.h" -#include "glite/wmsutils/exception/Exception.h" -#include -#include - -using namespace CppUnit; -using namespace std; -using namespace glite::wmsutils::exception; - -void Exception_test::setUp() -{} - -void Exception_test::tearDown() -{} - - -void Exception_test::constructor_case() -{ - - //constructor class name, line number, method name, code, exception name - glite::wmsutils::exception::Exception exc_5("TEST_Class", 3, "test_method", 1, "exception_test"); - - //constructor class name, method name, code, exception name - glite::wmsutils::exception::Exception exc_4("TEST_Class", "test_method", 1, "exception_test"); - - CPPUNIT_ASSERT(exc_5.getExceptionName() == "exception_test"); - CPPUNIT_ASSERT(exc_5.getCode() == 1); -} - -void Exception_test::tostring_case() -{ - cout<<"TEST TO STRING METHODS"< msgvec = exc_5.getStackTrace(); - - for (int i=0; i -#include -#include - -#include - - -class Exception_test : public CppUnit::TestFixture { - - CPPUNIT_TEST_SUITE(Exception_test); - CPPUNIT_TEST(constructor_case); - CPPUNIT_TEST(tostring_case); - CPPUNIT_TEST(stackTrace_case); - CPPUNIT_TEST_SUITE_END(); - - -public: - - void setUp(); - void tearDown(); - - void constructor_case(); - void tostring_case(); - void stackTrace_case(); - -}; - - - diff --git a/org.glite.wms-utils.jobid/.cvsignore b/org.glite.wms-utils.jobid/.cvsignore deleted file mode 100755 index 1df717b..0000000 --- a/org.glite.wms-utils.jobid/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -.project -.cdtproject \ No newline at end of file diff --git a/org.glite.wms-utils.jobid/LICENSE b/org.glite.wms-utils.jobid/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.wms-utils.jobid/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.wms-utils.jobid/Makefile.am b/org.glite.wms-utils.jobid/Makefile.am deleted file mode 100755 index bf956e1..0000000 --- a/org.glite.wms-utils.jobid/Makefile.am +++ /dev/null @@ -1,69 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = LICENSE - -docdir = $(datadir)/doc/@PACKAGE@-@VERSION@ -doc_DATA = LICENSE - -## Subdirectories list -SUBDIRS = interface src examples - -## Default flags to run aclocal -ACLOCAL_AMFLAGS = -I project - -stage: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target="install"; \ - prefix_arg="@prefix@"; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target $$prefix_arg in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target $$prefix_arg) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" $$prefix_arg || exit 1; \ - fi; test -z "$$fail" - -distsrc: dist - mv $(distdir).tar.gz $(DISTTAR)/$(distdir)_src.tar.gz - -distbin: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target="install"; \ - tmpdistbin="$(WORKDIR)/dist_bin"; \ - prefix_arg="prefix=$$tmpdistbin"; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target $$prefix_arg in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target $$prefix_arg) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" $$prefix_arg || exit 1; \ - fi; test -z "$$fail"; \ - pushd $$tmpdistbin; \ - $(AMTAR) -zcf $(DISTTAR)/$(distdir)_bin.tar.gz .; \ - popd; \ - rm -rf $$tmpdistbin - diff --git a/org.glite.wms-utils.jobid/bootstrap b/org.glite.wms-utils.jobid/bootstrap deleted file mode 100755 index ceeb099..0000000 --- a/org.glite.wms-utils.jobid/bootstrap +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/sh - -mkdir -p src/autogen -set -x -aclocal -I project -libtoolize --force -autoheader -automake --foreign --add-missing --copy -autoconf diff --git a/org.glite.wms-utils.jobid/build.xml b/org.glite.wms-utils.jobid/build.xml deleted file mode 100755 index 44c110c..0000000 --- a/org.glite.wms-utils.jobid/build.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.jobid/configure.ac b/org.glite.wms-utils.jobid/configure.ac deleted file mode 100755 index e255849..0000000 --- a/org.glite.wms-utils.jobid/configure.ac +++ /dev/null @@ -1,147 +0,0 @@ -# -# Copyright (c) 2004 on behalf of the EU EGEE Project: -# The European Organization for Nuclear Research (CERN), -# Istituto Nazionale di Fisica Nucleare (INFN), Italy -# Datamat Spa, Italy -# Centre National de la Recherche Scientifique (CNRS), France -# CS Systeme d'Information (CSSI), France -# Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -# Universiteit van Amsterdam (UvA), Netherlands -# University of Helsinki (UH.HIP), Finland -# University of Bergen (UiB), Norway -# Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom -# -# Common configure.ac file for the GLite WMS Common module -# -# Authors: Alberto Di Meglio -# Version info: $Id$ -# Release: $Name$ -# -# Revision history: -# $Log$ -# Revision 1.19 2006/03/20 15:30:43 eronchie -# Increased version -# -# Revision 1.18 2005/10/15 07:55:00 eronchie -# Increased version -# -# Revision 1.17 2005/09/20 10:41:49 eronchie -# Started merging with rc1.4 -# -# Revision 1.16 2004/12/10 07:33:42 eronchie -# Increased version -# -# Revision 1.15 2004/11/16 15:35:22 eronchie -# Increased version -# -# Revision 1.14 2004/11/16 15:15:45 eronchie -# Increased version -# -# Revision 1.13 2004/09/22 00:25:17 glbuild -# Fixed missing parenthesis -# -# Revision 1.12 2004/09/21 19:22:09 glbuild -# modified module.version -# -# Revision 1.11 2004/08/17 13:46:28 eronchie -# Added interface -# -# Revision 1.10 2004/08/17 13:41:20 eronchie -# Moved out JobIdExceptions.h cjobid.h JobId.h -# Put in interface/glite/wmsutils/jobid -# -# Revision 1.9 2004/08/17 10:40:34 eronchie -# Added optimize option -# -# Revision 1.8 2004/07/27 09:14:19 eronchie -# Removed AC_WMSUTILS_EXCEPTION and AC_GLOBUS_SSL_UTILS checks -# Set directly exception library macro -# -# Revision 1.7 2004/07/21 17:53:36 eronchie -# Moved out org.glite.wms.jobid from org.glite.wms and put in org.glite.wms-utils -# -# -# - -# Process this file with autoconf to produce a configure script. - -AC_PREREQ(2.57) -AC_INIT([GLite WMS Utils Jobid], [3.1.1]) -AC_CONFIG_AUX_DIR([./project]) -AM_INIT_AUTOMAKE([1.6.3 subdir-objects]) -AC_CONFIG_SRCDIR([src/jobid/strmd5.h]) - -# Notices. -AC_COPYRIGHT([Copyright (c) 2004 The EU EGEE Project -See LICENCE file for details -]) -AC_REVISION([$Revision$]) - -#Environment. -WORKDIR=`pwd` -AC_SUBST(WORKDIR) - -# Checks for programs. -AC_PROG_CC -AC_PROG_CPP -AC_PROG_CXX -AC_PROG_CXXCPP -AM_PROG_CC_C_O -AC_PROG_LIBTOOL - -# Checks for libraries. - -# Checks for header files. -AC_CHECK_HEADERS([fcntl.h mntent.h sys/vfs.h syslog.h unistd.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_HEADER_STDBOOL -AC_C_CONST -AC_C_INLINE -AC_TYPE_OFF_T -AC_TYPE_SIZE_T -AC_CHECK_MEMBERS([struct stat.st_rdev]) -AC_TYPE_UID_T -AC_CHECK_TYPES([ptrdiff_t]) - -# Checks for library functions. -AC_HEADER_STDC -AC_FUNC_ERROR_AT_LINE -AC_FUNC_GETMNTENT -AC_FUNC_MEMCMP -AC_FUNC_STAT -AC_FUNC_STRFTIME -AC_FUNC_VPRINTF -AC_CHECK_FUNCS([bzero endpwent ftruncate getmntent memset mkdir pow strerror strtol]) - -have_globus=no - -AC_GLOBUS([], have_globus=yes, have_globus=no) -AC_MSG_RESULT(["GLOBUS found $have_globus"]) - -if test "$have_globus" = "no"; then - AC_MSG_RESULT(["Please verify GLOBUS package"]) -fi - -if test "$have_globus" = "no"; then - AC_MSG_ERROR([Cannot continue building]) -fi -AC_GLITE - -GLITE_WMSUTILS_EXCEPTION_LIBS="-L$GLITE_LOCATION/lib -lglite_wmsutils_exception" - -AC_SUBST(GLITE_WMSUTILS_EXCEPTION_LIBS) - -AC_OPTIMIZE - -# Configuration items -AC_PREFIX_DEFAULT([/opt/glite]) -AM_CONFIG_HEADER([src/autogen/config.h]) -AC_CONFIG_FILES([Makefile]) -AC_CONFIG_FILES([examples/Makefile]) -AC_CONFIG_FILES([interface/Makefile]) -AC_CONFIG_FILES([src/Makefile]) -AC_CONFIG_FILES([src/jobid/Makefile]) - -AC_OUTPUT - diff --git a/org.glite.wms-utils.jobid/examples/Makefile.am b/org.glite.wms-utils.jobid/examples/Makefile.am deleted file mode 100755 index fa9a407..0000000 --- a/org.glite.wms-utils.jobid/examples/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -STDCPP = -lstdc++ - -JOBID = $(top_builddir)/src/jobid/libglite_wmsutils_cjobid.la - -check_PROGRAMS = testjobid - -testjobid_SOURCES = testjobid.c -testjobid_LDADD = \ - $(JOBID) \ - $(GLITE_WMSUTILS_EXCEPTION_LIBS) \ - $(GLOBUS_SSL_THR_LIBS) \ - $(STDCPP) - -AM_CPPFLAGS = -I$(top_srcdir)/src \ - -I$(top_srcdir)/interface \ - $(GLITE_CFLAGS) \ - $(GLOBUS_THR_CFLAGS) - -MAINTAINERCLEANFILES = Makefile.in *~ - diff --git a/org.glite.wms-utils.jobid/examples/testjobid.c b/org.glite.wms-utils.jobid/examples/testjobid.c deleted file mode 100755 index 56f6cba..0000000 --- a/org.glite.wms-utils.jobid/examples/testjobid.c +++ /dev/null @@ -1,33 +0,0 @@ -/* test code for jobid routines */ - -#include -#include - -#include "glite/wmsutils/jobid/cjobid.h" - -int main(int argc, char* argv[]) -{ - char* ju; - char* bkserver = "ujsa.uhjs"; - - edg_wlc_JobId ji = 0; - edg_wlc_JobId ji2 = 0; - - int r = edg_wlc_JobIdCreate(bkserver, 0, &ji); - printf("Create: %d\n", r); - - ju = edg_wlc_JobIdUnparse(ji); - printf("Unparse: %s\n", ju); - - edg_wlc_JobIdParse(ju, &ji2); - free(ju); - - ju = edg_wlc_JobIdUnparse(ji); - printf("Unparse2: %s\n", ju); - free(ju); - - edg_wlc_JobIdFree(ji); - edg_wlc_JobIdFree(ji2); - - return 0; -} diff --git a/org.glite.wms-utils.jobid/interface/Makefile.am b/org.glite.wms-utils.jobid/interface/Makefile.am deleted file mode 100755 index 8737f19..0000000 --- a/org.glite.wms-utils.jobid/interface/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -jobiddir = $(includedir) -nobase_jobid_HEADERS = \ - glite/wmsutils/jobid/cjobid.h \ - glite/wmsutils/jobid/manipulation.h \ - glite/wmsutils/jobid/JobIdExceptions.h \ - glite/wmsutils/jobid/JobId.h - -MAINTAINERCLEANFILES = Makefile.in diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h deleted file mode 100755 index 8d0b7b4..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobId.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_JOBID_H -#define GLITE_WMSUTILS_JOBID_JOBID_H - -/* - * JobId.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - * - */ - -#include -#include - -#include "glite/wmsutils/jobid/cjobid.h" - -typedef struct _edg_wlc_jobid_s* edg_wlc_jobid_t; - -namespace glite { -namespace wmsutils { -namespace jobid { - -/** - * Managing Identification, checking, retreiving info from a job - * File name: JobId.h - * The JobId class provides a representation of the Datagrid job identifier - * (dg_jobId) and the methods for manipulating it. - * We remind that the format of the dg_jobId is as follows: - * :/ - * - * @ingroup common - * @version 0.1 - * @date 15 April 2002 - * @author Alessandro Maraschini */ - -class JobId { -public: - /**@name Constructors/Destructor */ - //@{ - /** Instantiates an empty JobId object */ - JobId() ; - /** - * Instantiates a JobId object from the passed dg_jobId in string format. - * @param job_id_string a string representig a classAd expression - * @throws WrongIdException When a string is passed in a wrong format - */ - JobId(const std::string& job_id_string); - JobId(const JobId&); - JobId(const edg_wlc_JobId&); - /** - * Destructor - * Destroy the Job Id instance - */ - ~JobId() ; - //@} - - /**@name Miscellaneous */ - //@{ - /** Unsets the JobId instance. Clear all it's memebers */ - void clear() ; - /** - * Check wheater the jobId has been already created (true) or not (false) - *@return true (jobId created) or false (jobId not yet created) - */ - bool isSet() { return ( m_JobId != 0 ) ; } - /** - * Set the JobId instance according to the LB and RB server addresses and the unique string passed as input parameters. - * @param lb_server Loggin and Bookkeeping server address - * @param port Loggin and Bookkeeping port ( dafault value is 9000 ) - * @param unique A Unique identification ( automatically generatad by md5 protocol ) - * @throws WrongIdException When one parameter has been passed in a wrong format */ - void setJobId(const std::string& lb_server, int port = 0, const std::string& unique = ""); - //@} - /**@name Get Methods */ - //@{ - /** @return the LB address into its string format - * @throws EmptyIdException If the jobId has not been initialised yet */ - std::string getServer() const; - /** @return the Unique string into its string format - * @throws EmptyIdException If the jobId has not been initialised yet */ - std::string getUnique() const; - //@} - /** This method sets the JobId instance from the JobId in string format given - * as input. - * @param dg_JobId the string representing the job - * @throws WrongIdException When a string is passed in a wrong format */ - void fromString ( const std::string& dg_JobId ); - /** Converts the jobId into a string - @return the string representation of a JobId*/ - std::string toString() const; - /** casting operator */ - operator const edg_wlc_JobId() const { return m_JobId; } - /** Operator "=" create a deep copy of the JobId instance*/ - JobId & operator=(JobId const &); - /** Operator "=" create a deep copy of the JobId instance*/ - JobId & operator=(const edg_wlc_JobId &); - /** Retrieve the internal id reference - *@return the JobId internal reference used by some LB methods */ - edg_wlc_JobId getId() const ; -private: - // This Variable stores the Job unique identification String - edg_wlc_JobId m_JobId; - mutable char* m_pStr; - mutable char* m_pBkserver; - mutable char* m_pUnique; - /** Operator "<"*/ - friend bool operator<(JobId const& lhs, JobId const& rhs); - /** Operator "=="*/ - friend bool operator==(JobId const& lhs, JobId const& rhs); -}; - -inline bool operator<(JobId const& lhs, JobId const& rhs) -{ - return strcmp ( lhs.m_pStr , rhs.m_pStr ) <0 ; -} - -inline bool operator==(JobId const& lhs, JobId const& rhs) -{ -return strcmp ( lhs.m_pStr , rhs.m_pStr ) ==0 ; -} - -std::ostream& operator<<(std::ostream& os, JobId const& id); - -} // namespace jobid -} // namespace wmsutils -} // namespace glite - -#endif // GLITE_WMSUTILS_JOBID_JOBID_H diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h deleted file mode 100755 index cd414e1..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/JobIdExceptions.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_EXCEPTIONS_H -#define GLITE_WMSUTILS_JOBID_EXCEPTIONS_H - -/* - * JobIdExceptions.h - * Copyright (c) 2001 The European Datagrid Project - IST programme, all rights reserved. - */ - -#include "glite/wmsutils/exception/Exception.h" - -namespace glite { -namespace wmsutils { -namespace jobid { - -/** - * JobIdException - Exception thrown by JobId Class - * @ingroup Common - * @version 0.1 - * @date 15 April 2002 - * @author Alessandro Maraschini -*/ - -class JobIdException : public glite::wmsutils::exception::Exception { -public: - /** - * Update all mandatory Exception Information - */ - JobIdException (const std::string& file, - int line, - const std::string& method, - int code, - const std::string& exception_name) ; -};//End CLass JobIdException - -/** -* WrongIdFieldException -* This Exception is thrown when a Job Id syntax error is found -* A valid Job Identification string should be made as follows: -* :/ */ -class WrongIdException : public JobIdException { -public: - /** - * Constructor - * @param file - The source file which has generated the Exception - * @param line - The line number in the source file where the Exception has been thrown - * @param method - The Name of the method which has thrown the Exception - * @param code - The Code of the Error raised - * @param field - The wrong expression catched */ - WrongIdException(const std::string& file, - int line, - const std::string& method, - int code ); -}; //End CLass WrongIdException -/** -* EmptyIdException -* This Exception is thrown when the user tries to get information from a JobId -* which has not been initialized yet, i.e tries to use the get Methods -*/ -class EmptyIdException : public JobIdException { -public: - /** - * Constructor - * @param file - The source file which has generated the Exception - * @param line - The line number in the source file where the Exception has been thrown - * @param method - The Name of the method which has thrown the Exception - * @param code - The Code of the Error raised - * @param field - The Empty filed requested for */ - EmptyIdException(const std::string& file, - int line, - const std::string& method, - int code , - const std::string& field ); -}; //End CLass EmptyIdException - -} // namespace jobid -} // namespace wmsutils -} // namespace glite - -#endif // GLITE_WMSUTILS_JOBID_EXCEPTIONS_H - diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h deleted file mode 100755 index e8f84f5..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/cjobid.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef _GLITE_JOBID_H -#define _GLITE_JOBID_H - -/*! - * \file cjobid.h - * \brief L&B consumer API - */ - -#ident "$Header$" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _edg_wlc_JobId *edg_wlc_JobId; - -#define GLITE_WMSC_JOBID_DEFAULT_PORT 9000 /**< Default port where bookkeeping server listens */ -#define GLITE_WMSC_JOBID_PROTO_PREFIX "https://" /**< JobId protocol prefix */ - - -/* All the pointer functions return malloc'ed objects (or NULL on error) */ - -/** - * Create a Job ID. - * See the lb_draft document for details on its construction and components - * \param bkserver book keeping server hostname - * \param port port for the bk service - * \param jobid new created job id - * \ret al 0 success - * \retval EINVAL invalid bkserver - * \retval ENOMEM if memory allocation fails - */ -int edg_wlc_JobIdCreate(const char * bkserver, int port, edg_wlc_JobId * jobid); - -/** - * Recreate a Job ID - * \param bkserver bookkeeping server hostname - * \param port port for the bk service - * \param unique string which represent created jobid (if NULL then new - * one is created) - * \param jobid new created job id - * \retval 0 success - * \retval EINVAL invalid bkserver - * \retval ENOMEM if memory allocation fails - */ -int edg_wlc_JobIdRecreate(const char *bkserver, int port, const char * unique, edg_wlc_JobId * jobid); - -/** - * Create copy of Job ID - * \param in jobid for duplication - * \param jobid duplicated jobid - * \retval 0 for success - * \retval EINVAL invalid jobid - * \retval ENOMEM if memory allocation fails - */ -int edg_wlc_JobIdDup(const edg_wlc_JobId in, edg_wlc_JobId * jobid); - -/* - * Free jobid structure - * \param jobid for dealocation - */ -void edg_wlc_JobIdFree(edg_wlc_JobId jobid); - -/** - * Parse Job ID string and creates jobid structure - * \param jobidstr string representation of jobid - * \param jobid parsed job id - * \retval 0 for success - * \retval EINVAL jobidstr can't be parsed - * \retval ENOMEM if memory allocation fails - */ -int edg_wlc_JobIdParse(const char* jobidstr, edg_wlc_JobId * jobid); - -/** - * Unparse Job ID (produce the string form of JobId). - * \param jobid to be converted to string - * \return allocated string which represents jobid - */ -char* edg_wlc_JobIdUnparse(const edg_wlc_JobId jobid); - -/** - * Extract bookkeeping server address (address:port) - * \param jobid from which the bkserver address should be extracted - * \retval pointer to allocated string with bkserver address - * \retval NULL if jobid is 0 or memory allocation fails - */ -char* edg_wlc_JobIdGetServer(const edg_wlc_JobId jobid); - -/** - * Extract bookkeeping server address and port - * \param jobid from which the bkserver address should be extracted - * \param srvName pointer where to return server name - * \param srvPort pointer where to return server port - * */ -void edg_wlc_JobIdGetServerParts(const edg_wlc_JobId jobid, char **srvName, unsigned int *srvPort); - -/** - * Extract unique string - * \param jobid - * \retval pointer to allocated unique string representing jobid - * \retval NULL if jobid is 0 or memory allocation fails - */ -char* edg_wlc_JobIdGetUnique(const edg_wlc_JobId jobid); - -#ifdef __cplusplus -} -#endif - -#endif /* _GLITE_JOBID_H */ diff --git a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h b/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h deleted file mode 100755 index 9f862ae..0000000 --- a/org.glite.wms-utils.jobid/interface/glite/wmsutils/jobid/manipulation.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef GLITE_WMSUTILS_JOBID_MANIPULATION_H -#define GLITE_WMSUTILS_JOBID_MANIPULATION_H - -#include - -namespace glite { -namespace wmsutils { -namespace jobid { - -class JobId; - -std::string get_reduced_part( const JobId &id, int level = 0 ); -std::string to_filename( const JobId &id ); -JobId from_filename( const std::string &filename ); - -} // namespace jobid -} // namespace wmsutils -} // namespace glite - -#endif /* GLITE_WMSUTILS_JOBID_MANIPULATION_H */ - -// Local Variables: -// mode: c++ -// End: diff --git a/org.glite.wms-utils.jobid/project/build.number b/org.glite.wms-utils.jobid/project/build.number deleted file mode 100644 index 1acc27a..0000000 --- a/org.glite.wms-utils.jobid/project/build.number +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Oct 15 02:12:40 CEST 2005 -module.build=152 diff --git a/org.glite.wms-utils.jobid/project/build.properties b/org.glite.wms-utils.jobid/project/build.properties deleted file mode 100755 index f5a9095..0000000 --- a/org.glite.wms-utils.jobid/project/build.properties +++ /dev/null @@ -1,2 +0,0 @@ -build.package.summary="files for gLite wms utils jobid" -build.package.description="jobid api" diff --git a/org.glite.wms-utils.jobid/project/configure.properties.xml b/org.glite.wms-utils.jobid/project/configure.properties.xml deleted file mode 100644 index 04d3b17..0000000 --- a/org.glite.wms-utils.jobid/project/configure.properties.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/org.glite.wms-utils.jobid/project/properties.xml b/org.glite.wms-utils.jobid/project/properties.xml deleted file mode 100755 index 9662658..0000000 --- a/org.glite.wms-utils.jobid/project/properties.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.glite.wms-utils.jobid/project/version.properties b/org.glite.wms-utils.jobid/project/version.properties deleted file mode 100755 index 40c3916..0000000 --- a/org.glite.wms-utils.jobid/project/version.properties +++ /dev/null @@ -1,2 +0,0 @@ -module.version=3.1.1 -module.age=1 diff --git a/org.glite.wms-utils.jobid/src/Makefile.am b/org.glite.wms-utils.jobid/src/Makefile.am deleted file mode 100755 index 5225c64..0000000 --- a/org.glite.wms-utils.jobid/src/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -## Subdirectories list -SUBDIRS = jobid - -MAINTAINERCLEANFILES = Makefile.in diff --git a/org.glite.wms-utils.jobid/src/jobid/JobId.cpp b/org.glite.wms-utils.jobid/src/jobid/JobId.cpp deleted file mode 100755 index 273f9f9..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/JobId.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* ************************************************************************** - * filename : JobId.cpp - * author : Alessandro Maraschini - * copyright : (C) 2002 by DATAMAT - ***************************************************************************/ - -#include "glite/wmsutils/jobid/JobId.h" - -#include - -#include "glite/wmsutils/jobid/JobIdExceptions.h" - -namespace glite { -namespace wmsutils { -namespace jobid { - -using namespace std ; - -/****************************************************************** - Constructor / Destructor - *******************************************************************/ -JobId::JobId() : m_JobId( 0 ), m_pStr( 0 ), m_pBkserver( 0 ), m_pUnique( 0 ) -{ -} - -JobId::JobId(const std::string& job_id_string ) - : m_JobId( 0 ), m_pStr( 0 ), m_pBkserver( 0 ), m_pUnique( 0 ) -{ - fromString( job_id_string ) ; -} - -JobId::JobId(const JobId &old) -{ - edg_wlc_JobIdDup(old.m_JobId,&m_JobId); - m_pStr = old.m_pStr ? strdup(old.m_pStr) : 0; - m_pBkserver = old.m_pBkserver ? strdup(old.m_pBkserver) : 0; - m_pUnique = old.m_pUnique ? strdup(old.m_pUnique) : 0; -} - -JobId & JobId::operator=(JobId const &old) -{ - clear(); - edg_wlc_JobIdDup(old.m_JobId,&m_JobId); - m_pStr = old.m_pStr ? strdup(old.m_pStr) : 0; - m_pBkserver = old.m_pBkserver ? strdup(old.m_pBkserver) : 0; - m_pUnique = old.m_pUnique ? strdup(old.m_pUnique) : 0; - - return *this; -} - - -JobId::JobId(const edg_wlc_JobId &old) - : m_pStr(0), m_pBkserver(0), m_pUnique(0) -{ - edg_wlc_JobIdDup(old,&m_JobId); -} - - -JobId & JobId::operator=(const edg_wlc_JobId &old) -{ - clear(); - edg_wlc_JobIdDup(old,&m_JobId); - m_pStr = 0; - m_pBkserver = 0; - m_pUnique = 0; - return(*this); -} - -JobId::~JobId() -{ - clear(); -} - -/****************************************************************** - method : clear - unsets the JobId instance. - *******************************************************************/ -void JobId::clear() -{ - if ( m_JobId ) - { - edg_wlc_JobIdFree( m_JobId ); - m_JobId = 0; - if (m_pStr) - free(m_pStr); - if (m_pBkserver) - free(m_pBkserver); - if (m_pUnique) - free(m_pUnique); - m_pStr = m_pBkserver = m_pUnique = NULL; - } -} - - -/****************************************************************** - method : setJobId - sets the JobId instance according to the LB and RB - server addresses and the unique string passed as input parameters. - *******************************************************************/ -void JobId::setJobId(const string& bkserver, int port, const string& unique) -{ - int code = edg_wlc_JobIdRecreate(bkserver.c_str(), port, unique.size() ? unique.c_str() : NULL, &m_JobId) ; - if ( code != 0 ) - throw WrongIdException(__FILE__ , __LINE__ , "setJobId(const string& bkserver, int port, const string& unique)" , code ) ; -} - - -/****************************************************************** - Protected method : fromString - sets the JobId instance from the dg_jobId in string format given as input. - *******************************************************************/ -void JobId::fromString (const string& dg_JobId) -{ - clear(); - int code = edg_wlc_JobIdParse(dg_JobId.c_str(), &m_JobId) ; - if ( code != 0 ) - throw WrongIdException(__FILE__ , __LINE__ , "fromString (const string& dg_JobId)" , code ) ; -} - -/****************************************************************** - method : ToString - converts the JobId instance into its string format. - and put it in the dg_jobId output variable - *******************************************************************/ -std::string JobId::toString() const -{ - if ( m_JobId && !m_pStr ) - m_pStr = edg_wlc_JobIdUnparse(m_JobId) ; - if ( !m_pStr ) - throw EmptyIdException (__FILE__ , __LINE__ ,"toString()" ,ENOENT , "JobId") ; - return m_pStr; -} - -/****************************************************************** - method : getServer - return a string containing the LB server address, - *******************************************************************/ -std::string JobId::getServer() const -{ - if ( m_JobId && !m_pBkserver ) - m_pBkserver = edg_wlc_JobIdGetServer( m_JobId ) ; - - if ( !m_pBkserver ) - throw EmptyIdException (__FILE__ , __LINE__ , "getServer()", ENOENT , "LB server Address") ; - - return m_pBkserver; -} - -/****************************************************************** - method : getUnique - return a string containing unique jobid string - *******************************************************************/ -std::string JobId::getUnique() const -{ - if ( m_JobId && !m_pUnique ) - m_pUnique = edg_wlc_JobIdGetUnique( m_JobId ) ; - - if ( !m_pUnique ) - throw EmptyIdException (__FILE__ , __LINE__ , "getUnique()" , ENOENT , "Unique") ; - - return m_pUnique; -} -/****************************************************************** - method : getId - return the c JobId struct representing this instance - *******************************************************************/ -edg_wlc_JobId JobId::getId() const -{ - edg_wlc_JobId out ; - if ( edg_wlc_JobIdDup(m_JobId, &out) ) - throw EmptyIdException (__FILE__ , __LINE__ , "getId()" , ENOENT , "JobId") ; - return out ; -} - -std::ostream& -operator<<(std::ostream& os, JobId const& id) -{ - return os << id.toString(); -} - -} // namespace jobid -} // namespace wmsutils -} // namespace glite diff --git a/org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp b/org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp deleted file mode 100755 index 6be40b7..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/JobIdExceptions.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* ************************************************************************** -* filename : JobIdExecptions.cpp -* author : Alessandro Maraschini -* copyright : (C) 2002 by DATAMAT -***************************************************************************/ - -#include "glite/wmsutils/jobid/JobIdExceptions.h" - -namespace glite { -namespace wmsutils { -namespace jobid { - -using namespace std; -using namespace glite::wmsutils::exception; - -/***************************** -* JobIdException -*****************************/ -JobIdException::JobIdException (const string& file, - int line, - const string& method, - int code, - const string& exception_name) - : Exception(file, line, method, code, exception_name) -{ -} - -/***************************** -* WrongIdException -*****************************/ -WrongIdException::WrongIdException(const string& file, - int line, - const string& method, - int code ) - : JobIdException(file, line, method, code, - "WrongIdException") -{ - error_message = "Wrong Field caught while parsing Job Id" ; -} - -/***************************** -* EmptyIdException -*****************************/ -EmptyIdException::EmptyIdException(const string& file, - int line, - const string& method, - int code , - const string& field ) - : JobIdException(file, line, method, code, - "EmptyIdException") -{ - error_message = "Unable to retrieve " + field + ": the instance has not been initialized yet"; -} - -} // namespace jobid -} // namespace wmsutils -} // namespace glite - diff --git a/org.glite.wms-utils.jobid/src/jobid/Makefile.am b/org.glite.wms-utils.jobid/src/jobid/Makefile.am deleted file mode 100755 index 7a23118..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/Makefile.am +++ /dev/null @@ -1,30 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -lib_LTLIBRARIES = libglite_wmsutils_jobid.la libglite_wmsutils_cjobid.la - -libglite_wmsutils_jobid_la_SOURCES = \ - JobId.cpp \ - JobIdExceptions.cpp \ - manipulation.cpp - -libglite_wmsutils_cjobid_la_SOURCES = \ - cjobid.c \ - strmd5.c - -jobidincludedir = $(includedir)/glite/wmsutils/jobid -jobidinclude_HEADERS = \ - strmd5.h - -AM_CPPFLAGS = -I$(top_srcdir)/src \ - -I$(top_srcdir)/interface \ - $(GLITE_CFLAGS) \ - $(GLOBUS_THR_CFLAGS) \ - -D_GNU_SOURCE - -MAINTAINERCLEANFILES = Makefile.in diff --git a/org.glite.wms-utils.jobid/src/jobid/cjobid.c b/org.glite.wms-utils.jobid/src/jobid/cjobid.c deleted file mode 100755 index 2fa0010..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/cjobid.c +++ /dev/null @@ -1,258 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "glite/wmsutils/jobid/cjobid.h" -#include "strmd5.h" - -struct _edg_wlc_JobId { - char *id; /* unique job identification */ - /* additional information */ - char *BShost;/* bookkeeping server hostname */ - unsigned int BSport; /* bookkeeping server port */ - char *info; /* additional information (after ? in URI) */ -}; - -int edg_wlc_JobIdCreate(const char *bkserver, int port, edg_wlc_JobId *jobId) -{ - return edg_wlc_JobIdRecreate(bkserver, port, NULL, jobId); -} - - -int edg_wlc_JobIdRecreate(const char* bkserver, int port, const char *unique, edg_wlc_JobId *jobId) -{ - edg_wlc_JobId out; - char hostname[200]; /* used to hold string for encrypt */ - struct timeval tv; - int skip; - char* portbeg; - - struct hostent* he; - - if (!bkserver) - return EINVAL; - - if (unique == NULL) { - gethostname(hostname, 100); - he = gethostbyname(hostname); - assert(he->h_length > 0); - gettimeofday(&tv, NULL); - srandom(tv.tv_usec); - - skip = strlen(hostname); - skip += sprintf(hostname + skip, "-IP:0x%x-pid:%d-rnd:%d-time:%d:%d", - *((int*)he->h_addr_list[0]), getpid(), (int)random(), - (int)tv.tv_sec, (int)tv.tv_usec); - } - - *jobId = NULL; - out = (edg_wlc_JobId) malloc (sizeof(*out)); - if (!out) - return ENOMEM; - - memset(out, 0, sizeof(*out)); - - /* check if it begins with prefix */ - /* unsupported */ - if (strncmp(bkserver, GLITE_WMSC_JOBID_PROTO_PREFIX, sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX)-1) == 0) - return EINVAL; - - out->BShost = strdup(bkserver); - portbeg = strchr(out->BShost, ':'); - if (portbeg) { - *portbeg = 0; - /* try to get port number */ - if (port == 0) - port = atoi(portbeg + 1); - } - - if (port == 0) - port = GLITE_WMSC_JOBID_DEFAULT_PORT; - - out->BSport = port; - - out->id = (unique) ? strdup(unique) : str2md5base64(hostname); - //printf("Encrypt: %s\nBASE64 %s\n", hostname, out->id); - - if (!out->id || !out->BShost) { - edg_wlc_JobIdFree(out); - return ENOMEM; - } - - *jobId = out; - return 0; -} - - -int edg_wlc_JobIdDup(const edg_wlc_JobId in, edg_wlc_JobId *out) -{ - edg_wlc_JobId jid; - *out = NULL; - if (in == NULL) - return 0; - - jid = malloc(sizeof(*jid)); - if (!jid) - return ENOMEM; - - memset(jid, 0,sizeof(*jid)); - jid->BShost = strdup(in->BShost); - jid->id = strdup(in->id); - if (in->info) - jid->info = strdup(in->info); - - if (jid->BShost == NULL || jid->id == NULL) { - edg_wlc_JobIdFree(jid); - return ENOMEM; - } - - jid->BSport = in->BSport; - *out = jid; - return 0; -} - - -// XXX -// use recreate -// parse name, port, unique -int edg_wlc_JobIdParse(const char *idString, edg_wlc_JobId *jobId) -{ - char *pom, *pom1, *pom2; - edg_wlc_JobId out; - - *jobId = NULL; - - out = (edg_wlc_JobId) malloc (sizeof(*out)); - if (out == NULL ) - return ENOMEM; - - memset(out,0,sizeof(*out)); - - if (strncmp(idString, GLITE_WMSC_JOBID_PROTO_PREFIX, sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX) - 1)) { - out->BShost = (char *) NULL; - out->BSport = 0; - - free(out); - return EINVAL; - } - - pom = strdup(idString + sizeof(GLITE_WMSC_JOBID_PROTO_PREFIX) - 1); - pom1 = strchr(pom, '/'); - pom2 = strchr(pom, ':'); - - if (!pom1) { free(pom); free(out); return EINVAL; } - - if ( pom2 && (pom1 > pom2)) { - pom[pom2-pom] = '\0'; - out->BShost = strdup(pom); - pom[pom1-pom] = '\0'; - out->BSport = (unsigned int) strtoul(pom2 + 1,NULL,10); - } else { - pom[pom1-pom] = '\0'; - out->BShost = strdup(pom); - out->BSport = GLITE_WMSC_JOBID_DEFAULT_PORT; - } - - /* XXX: localhost not supported in jobid - if (!strncmp(out->BShost,"localhost",9) { - free(pom); - free(out->BShost); - free(out); - return EINVAL; - } - */ - - /* additional info from URI */ - pom2 = strchr(pom1+1,'?'); - if (pom2) { - *pom2 = 0; - out->info = strdup(pom2+1); - } - - /* extract the unique part */ - out->id = strdup(pom1+1); - - for (pom1 = out->BShost; *pom1; pom1++) - if (isspace(*pom1)) break; - - for (pom2 = out->id; *pom2; pom2++) - if (isspace(*pom2)) break; - - if (*pom1 || *pom2) { - free(pom); - edg_wlc_JobIdFree(out); - return EINVAL; - } - - free(pom); - *jobId = out; - return 0; -} - - -void edg_wlc_JobIdFree(edg_wlc_JobId job) -{ - if (job) { - free(job->id); - free(job->BShost); - free(job->info); - free(job); - } -} - - -char* edg_wlc_JobIdUnparse(const edg_wlc_JobId jobid) -{ - char *out, port[40]; - - if (!jobid) - return NULL; - - if (jobid->BSport) - sprintf(port,":%d",jobid->BSport); - else - *port = 0; - - asprintf(&out, GLITE_WMSC_JOBID_PROTO_PREFIX"%s%s/%s%s%s", - jobid->BShost,port, - jobid->id, - (jobid->info ? "?" : ""), - (jobid->info ? jobid->info : "")); - - return out; -} - - -char* edg_wlc_JobIdGetServer(const edg_wlc_JobId jobid) -{ - char *bs = NULL; - - if (jobid) - asprintf(&bs, "%s:%u", jobid->BShost, - jobid->BSport ? jobid->BSport : GLITE_WMSC_JOBID_DEFAULT_PORT); - - return bs; -} - - -void edg_wlc_JobIdGetServerParts(const edg_wlc_JobId jobid, char **srvName, unsigned int *srvPort) -{ - if (jobid) { - *srvName = strdup(jobid->BShost); - *srvPort = jobid->BSport ? jobid->BSport : GLITE_WMSC_JOBID_DEFAULT_PORT; - } -} - - -char* edg_wlc_JobIdGetUnique(const edg_wlc_JobId jobid) -{ - return jobid ? strdup(jobid->id) : NULL; -} diff --git a/org.glite.wms-utils.jobid/src/jobid/manipulation.cpp b/org.glite.wms-utils.jobid/src/jobid/manipulation.cpp deleted file mode 100755 index cf3a710..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/manipulation.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include - -#include -#include - -#include "glite/wmsutils/jobid/JobId.h" - -using namespace std; - -namespace glite { -namespace wmsutils { -namespace jobid { - -namespace { - -class HexInt { -public: - HexInt( unsigned int i = 0 ); - HexInt( const string &str ); - HexInt( string::const_iterator begin, string::const_iterator end ); - ~HexInt( void ); - - inline operator unsigned int( void ) const { return this->hi_int; } - inline operator const string &( void ) const { return this->hi_str; } - - static unsigned int least( void ) { return hi_s_least; } - static void least( unsigned int least ) { hi_s_least = least; } - -private: - void parseString( void ); - - unsigned int hi_int; - string hi_str; - - static unsigned int hi_s_least; - static const char *hi_s_map; -}; - -class BadChar { -public: - BadChar( void ); - ~BadChar( void ); - - inline bool operator()( char c ) - { return( !(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9')) || - (c == '.') || (c == '-') || (c == ' ')) ); } -}; - -unsigned int HexInt::hi_s_least = 2; -const char *HexInt::hi_s_map = "0123456789abcdef"; - -HexInt::HexInt( unsigned int ui ) : hi_int( ui ), hi_str( hi_s_least, '0' ) -{ - int n; - string::reverse_iterator pos = this->hi_str.rbegin(); - - while( ui != 0 ) { - n = ui % 16; - if( pos != this->hi_str.rend() ) { - *pos = hi_s_map[n]; - pos += 1; - } - else this->hi_str.insert( this->hi_str.begin(), hi_s_map[n] ); - - ui /= 16; - } - - if( this->hi_str.length() < hi_s_least ) - this->hi_str.insert( this->hi_str.begin(), (hi_s_least - this->hi_str.length()), '0' ); -} - -HexInt::HexInt( const string &str ) : hi_int( 0 ), hi_str( str ) -{ - this->parseString(); -} - -HexInt::HexInt( string::const_iterator begin, string::const_iterator end ) : hi_int( 0 ), hi_str( begin, end ) -{ - this->parseString(); -} - -void HexInt::parseString( void ) -{ - int hexbase; - char *pos, *end = (char *) hi_s_map + 16; - string::reverse_iterator it; - - for( it = this->hi_str.rbegin(), hexbase = 1; it != this->hi_str.rend(); ++it, hexbase *= 16 ) { - pos = find( (char *) hi_s_map, end, (char) tolower(*it) ); - - if( pos != end ) this->hi_int += hexbase * (pos - hi_s_map); - else { - this->hi_int = 0; - break; - } - } - - return; -} - -HexInt::~HexInt( void ) {} - -BadChar::BadChar( void ) {} - -BadChar::~BadChar( void ) {} - -/* - Helper function for the get_reduced_part(...) -*/ -string get_reduced_part_internal( const string &unique, int level ) -{ - string::size_type length = unique.length(); - string piece( unique.substr(0, 2) ), answer; - - if( (level == 0) || (length <= 2) ) answer.assign( piece ); - else if( length != 0 ) { - answer.assign( piece ); - answer.append( 1, '/' ); - answer.append( get_reduced_part_internal(unique.substr(2, length - 2), level - 1) ); - } - - return answer; -} - -}; // Unnamed namespace - -string get_reduced_part( const JobId &id, int level ) -{ - return get_reduced_part_internal( id.getUnique(), level ); -} - -string to_filename( const JobId &id ) -{ - string sid( id.toString() ), coded; - string::iterator last, next; - - last = sid.begin(); - do { - next = find_if( last, sid.end(), BadChar() ); - - if( next != sid.end() ) { - if( last != next ) coded.append( last, next ); - coded.append( 1, '_' ); - coded.append( HexInt(*next) ); - - last = next + 1; - } - else coded.append( last, sid.end() ); - } while( next != sid.end() ); - - return coded; -} - -JobId from_filename( const string &filename ) -{ - char c; - string decoded; - string::const_iterator last, next; - - last = filename.begin(); - do { - next = find( last, filename.end(), '_' ); - - if( next != filename.end() ) { - c = HexInt( next + 1, next + 3 ); - - if( last != next ) decoded.append( last, next ); - decoded.append( 1, c ); - - last = next + 3; - } - else decoded.append( last, filename.end() ); - } while( next != filename.end() ); - - return JobId( decoded ); -} - -} // namespace jobid -} // namespace wmsutils -} // namespace glite diff --git a/org.glite.wms-utils.jobid/src/jobid/strmd5.c b/org.glite.wms-utils.jobid/src/jobid/strmd5.c deleted file mode 100755 index e1f6134..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/strmd5.c +++ /dev/null @@ -1,118 +0,0 @@ -#ident "$Header$" - -#include -#include -#include -#include - -#include "jobid/strmd5.h" - -#warning Thread unsafe! -static char mbuf[33]; - -static int base64_encode(const void *enc, int enc_size, char *out, int out_max_size) -{ - static const char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - - unsigned char* enc_buf = (unsigned char*)enc; - int out_size = 0; - unsigned int bits = 0; - unsigned int shift = 0; - - while ( out_size < out_max_size ) { - if ( enc_size>0 ) { - // Shift in byte - bits <<= 8; - bits |= *enc_buf; - shift += 8; - // Next byte - enc_buf++; - enc_size--; - } else if ( shift>0 ) { - // Pad last bits to 6 bits - will end next loop - bits <<= 6 - shift; - shift = 6; - } else { - // Terminate with Mime style '=' - *out = '='; - out_size++; - - return out_size; - } - - // Encode 6 bit segments - while ( shift>=6 ) { - shift -= 6; - *out = b64[ (bits >> shift) & 0x3F ]; - out++; - out_size++; - } - } - - // Output overflow - return -1; -} - -char *strmd5(const char *s, unsigned char *digest) -{ - MD5_CTX md5; - unsigned char d[16]; - int i; - - MD5_Init(&md5); - MD5_Update(&md5,s,strlen(s)); - MD5_Final(d,&md5); - - if (digest) memcpy(digest,d,sizeof(d)); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - mbuf[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - mbuf[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - mbuf[32] = 0; - return (char *) mbuf; -} - -char *str2md5(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char* ret = malloc(33); - int i; - - if (!ret) - return NULL; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - for (i=0; i<16; i++) { - int dd = d[i] & 0x0f; - ret[2*i+1] = dd<10 ? dd+'0' : dd-10+'a'; - dd = d[i] >> 4; - ret[2*i] = dd<10 ? dd+'0' : dd-10+'a'; - } - ret[32] = 0; - return ret; -} - -char *str2md5base64(const char *s) -{ - MD5_CTX md5; - unsigned char d[16]; - char buf[50]; - int l; - - MD5_Init(&md5); - MD5_Update(&md5, s, strlen(s)); - MD5_Final(d, &md5); - - l = base64_encode(d, 16, buf, sizeof(buf) - 1); - if (l < 1) - return NULL; - buf[l - 1] = 0; - return strdup(buf); -} diff --git a/org.glite.wms-utils.jobid/src/jobid/strmd5.h b/org.glite.wms-utils.jobid/src/jobid/strmd5.h deleted file mode 100755 index c5d76b6..0000000 --- a/org.glite.wms-utils.jobid/src/jobid/strmd5.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _GLITE_STRMD5_H -#define _GLITE_STRMD5_H - -#ident "$Header$" - -/* Compute MD5 sum of the first argument. - * The sum is returned in the 16-byte array pointed to by 2nd argument - * (if not NULL) - * - * Return value: ASCII string of the sum, i.e. 32 characters [0-9a-f] - * (pointer to static area, changed by subsequent calls) - */ - -char *strmd5(const char *src, unsigned char *dst); - -/** - * Returns: allocated 32bytes long ASCII string with md5 sum - * of the first argument - */ -char *str2md5(const char *src); - -/** - * Returns: allocated 22bytes long ASCII string with md5 sum in base64 - * format of the source argument - */ -char *str2md5base64(const char *src); - -#endif /* _GLITE_STRMD5_H */ diff --git a/org.glite.wms-utils.jobid/test/Makefile.am b/org.glite.wms-utils.jobid/test/Makefile.am deleted file mode 100755 index 5111c30..0000000 --- a/org.glite.wms-utils.jobid/test/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -## ********************************************************************* -## * -## * Copyright (c) 2002 CERN and INFN on behalf of the EU DataGrid. -## * For license conditions see LICENSE file or -## * http://www.edg.org/license.html -## * -## ********************************************************************* - -JOBID_LIBS = $(top_builddir)/src/jobid/libglite_wmsutils_jobid.la -CJOBID_LIBS = $(top_builddir)/src/jobid/libglite_wmsutils_cjobid.la - -TESTS = glite-wmsutils-jobid \ - glite-wmsutils-manipulation - -check_PROGRAMS = $(TESTS) - -glite_wmsutils_jobid_SOURCES = jobid_cu_suite.cpp \ - jobid_cu_suite.h \ - jobid_cu_main.cpp - -glite_wmsutils_jobid_LDADD = \ - $(GLITE_WMSUTILS_EXCEPTION_LIBS) \ - $(GLOBUS_GSS_THR_LIBS) \ - $(CPPUNIT_LIBS) \ - $(JOBID_LIBS) \ - $(CJOBID_LIBS) - -glite_wmsutils_manipulation_SOURCES = manipulation_cu_suite.cpp \ - manipulation_cu_suite.h \ - manipulation_cu_main.cpp - -glite_wmsutils_manipulation_LDADD = \ - $(GLITE_WMSUTILS_EXCEPTION_LIBS) \ - $(GLOBUS_GSS_THR_LIBS) \ - $(CPPUNIT_LIBS) \ - $(JOBID_LIBS) \ - $(CJOBID_LIBS) - - -AM_CPPFLAGS = -I$(top_srcdir)/interface \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/test \ - $(GLITE_CFLAGS) \ - $(GLOBUS_THR_CFLAGS) \ - $(CPPUNIT_CFLAGS) - -MAINTAINERCLEANFILES = Makefile.in *~ - diff --git a/org.glite.wms-utils.jobid/test/jobid_cu_main.cpp b/org.glite.wms-utils.jobid/test/jobid_cu_main.cpp deleted file mode 100644 index 770e306..0000000 --- a/org.glite.wms-utils.jobid/test/jobid_cu_main.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include "jobid_cu_suite.h" - -#include -#include -#include -#include -#include - -using namespace CppUnit; -using namespace std; - -int main (int argc , char** argv) -{ - std::ofstream xml("./cppUnit_output.xml",ios::app); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - TestRunner runner; - runner.addTest(Jobid_test::suite()); - runner.run(controller); - - CppUnit::XmlOutputter outputter( &result, xml ); - CppUnit::TextOutputter outputter2( &result, std::cerr ); - outputter.write(); - outputter2.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} diff --git a/org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp b/org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp deleted file mode 100644 index ebe04da..0000000 --- a/org.glite.wms-utils.jobid/test/jobid_cu_suite.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "jobid_cu_suite.h" - - -using namespace CppUnit; -using namespace std; -using namespace glite::wmsutils::jobid; - - -void Jobid_test::setUp() -{} - -void Jobid_test::tearDown() -{} - -void Jobid_test::Constructor_case() -{ - //EMPTY CONSTRUCTOR - JobId empty; - - CPPUNIT_ASSERT(empty.isSet()==false); - - //create a string with cjobid - string bkserver="grid012g.cnaf.infn.it"; - edg_wlc_JobId jobid; - int bkport=6000; - int ok=edg_wlc_JobIdCreate(bkserver.c_str(), bkport, &jobid); - CPPUNIT_ASSERT(ok == 0); - if (ok==0) - { - string jobstring=edg_wlc_JobIdUnparse(jobid); - - //STRING CONSTRUCTOR - JobId stringCons(jobstring); - - //EDG_WLC CONSTRUCTOR - JobId edg_wlc_Cons(jobid); - - //test copy constructor - JobId copycon(stringCons); - - CPPUNIT_ASSERT(stringCons.isSet()); - CPPUNIT_ASSERT(edg_wlc_Cons.isSet()); - CPPUNIT_ASSERT(copycon.isSet()); - - //test = - JobId testequal; - testequal=stringCons; - CPPUNIT_ASSERT(testequal.isSet()); - - JobId testoperator; - testoperator=jobid; - CPPUNIT_ASSERT(testoperator.isSet()); - - edg_wlc_JobId testget = edg_wlc_Cons.getId(); - char *server; - unsigned int port; - edg_wlc_JobIdGetServerParts(testget, &server, &port); - string serverstring = server; - CPPUNIT_ASSERT(port==bkport); - CPPUNIT_ASSERT(serverstring==bkserver); - } - - CPPUNIT_ASSERT_THROW( JobId stringwrong("grid012"), WrongIdException); -} - -void Jobid_test::Clear_case() -{ - JobId *element; - string jobstring="https://grid012g.cnaf.infn.it:6000/qaKyEoV3G144rmoyXeW6QA"; - CPPUNIT_ASSERT_NO_THROW(element= new JobId(jobstring)); - - CPPUNIT_ASSERT(element->isSet()); - element->clear(); - CPPUNIT_ASSERT(element->isSet()==false); - delete element; -} - -void Jobid_test::SetandGet_case() -{ - JobId element; - string lbserver="grid012g.cnaf.infn.it"; - int port=6000; - string unique ="qaKyEoV3G144rmoyXeW6QA"; - element.setJobId(lbserver, port, unique); - - string server=element.getServer(); - lbserver=lbserver+":6000"; - - CPPUNIT_ASSERT(server==lbserver); - string lonely=element.getUnique(); - CPPUNIT_ASSERT(lonely==unique); - - string descr=element.toString(); - cout << "!!! BEGIN TEST toString() METHOD!!!"<< endl; - cout << descr < -#include -#include - -#include - -#include "glite/wmsutils/jobid/JobId.h" -#include "glite/wmsutils/jobid/cjobid.h" -#include "glite/wmsutils/jobid/JobIdExceptions.h" - -class Jobid_test : public CppUnit::TestFixture { - - CPPUNIT_TEST_SUITE(Jobid_test); - - CPPUNIT_TEST(Constructor_case); - CPPUNIT_TEST(Clear_case); - CPPUNIT_TEST(SetandGet_case); - - CPPUNIT_TEST_SUITE_END(); - - -public: - - void setUp(); - void tearDown(); - - void Constructor_case(); - void Clear_case(); - void SetandGet_case(); - -}; - - - diff --git a/org.glite.wms-utils.jobid/test/manipulation_cu_main.cpp b/org.glite.wms-utils.jobid/test/manipulation_cu_main.cpp deleted file mode 100644 index 07d2914..0000000 --- a/org.glite.wms-utils.jobid/test/manipulation_cu_main.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include "manipulation_cu_suite.h" - -#include -#include -#include -#include -#include - -using namespace CppUnit; -using namespace std; - -int main (int argc , char** argv) -{ - std::ofstream xml("./cppUnit_output.xml",ios::app); - - CppUnit::TestResult controller; - CppUnit::TestResultCollector result; - controller.addListener( &result ); - - TestRunner runner; - runner.addTest(Manipulation_test::suite()); - runner.run(controller); - - CppUnit::XmlOutputter outputter( &result, xml ); - CppUnit::TextOutputter outputter2( &result, std::cerr ); - outputter.write(); - outputter2.write(); - - return result.wasSuccessful() ? 0 : 1 ; -} diff --git a/org.glite.wms-utils.jobid/test/manipulation_cu_suite.cpp b/org.glite.wms-utils.jobid/test/manipulation_cu_suite.cpp deleted file mode 100644 index a6a69d8..0000000 --- a/org.glite.wms-utils.jobid/test/manipulation_cu_suite.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "manipulation_cu_suite.h" - - -using namespace CppUnit; -using namespace std; -using namespace glite::wmsutils::jobid; - - -void Manipulation_test::setUp() -{} - -void Manipulation_test::tearDown() -{} - -void Manipulation_test::to_fromfile_case() -{ - JobId element; - - string lbserver="grid012g.cnaf.infn.it"; - int port=6000; - string unique ="qaKyEoV3G144rmoyXeW6QA"; - element.setJobId(lbserver, port, unique); - - string filename=to_filename(element); - - JobId newelement = from_filename(filename); - - string reduced = get_reduced_part(element, 7); - - string newreduced = get_reduced_part(newelement, 7); - - CPPUNIT_ASSERT(reduced==newreduced); -} - diff --git a/org.glite.wms-utils.jobid/test/manipulation_cu_suite.h b/org.glite.wms-utils.jobid/test/manipulation_cu_suite.h deleted file mode 100644 index 287b902..0000000 --- a/org.glite.wms-utils.jobid/test/manipulation_cu_suite.h +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include - -#include - -#include "glite/wmsutils/jobid/JobId.h" -#include "glite/wmsutils/jobid/manipulation.h" - -class Manipulation_test : public CppUnit::TestFixture { - - CPPUNIT_TEST_SUITE(Manipulation_test); - - CPPUNIT_TEST(to_fromfile_case); - - CPPUNIT_TEST_SUITE_END(); - - -public: - - void setUp(); - void tearDown(); - - void to_fromfile_case(); - -}; - - - diff --git a/org.glite.yaim.lb/.cvsignore b/org.glite.yaim.lb/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.yaim.lb/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.yaim.lb/LICENSE b/org.glite.yaim.lb/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.yaim.lb/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.yaim.lb/Makefile b/org.glite.yaim.lb/Makefile deleted file mode 100644 index 7fc5e75..0000000 --- a/org.glite.yaim.lb/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -prefix=/opt/glite -package=glite-yaim-lb -name=$Name$ -tag:=$(shell echo $(name) | sed 's/^[^:]*: //' ) -version:=$(shell echo "$(tag)" | sed 's/^.*R_//' | sed 's/_/\./g') -release:=$(shell echo "$(version)" | sed 's/.*\.//') -version:=$(shell echo "$(version)" | sed 's/\(.*\)\.[0-9]*/\1/') - -.PHONY: configure install clean rpm - -all: configure - -install: - @echo installing ... - @mkdir -p $(prefix)/yaim/functions/ - @mkdir -p $(prefix)/yaim/functions/local - @mkdir -p $(prefix)/yaim/node-info.d - @mkdir -p $(prefix)/yaim/defaults - @mkdir -p $(prefix)/yaim/etc/versions - @install -m 0644 config/functions/config* $(prefix)/yaim/functions - @install -m 0644 config/node-info.d/glite* $(prefix)/yaim/node-info.d - @install -m 0644 config/defaults/glite* $(prefix)/yaim/defaults - @echo "$(package) $(version)-$(release)" > $(prefix)/yaim/etc/versions/$(package) - -clean:: - rm -f *~ test/*~ etc/*~ doc/*~ src/*~ - rm -rf rpmbuild - -rpm: - @mkdir -p RPMS - @mkdir -p rpmbuild/RPMS/noarch - @mkdir -p rpmbuild/SRPMS/ - @mkdir -p rpmbuild/SPECS/ - @mkdir -p rpmbuild/SOURCES/ - @mkdir -p rpmbuild/BUILD/ - echo "|$(tag)|" -ifneq ("$(tag)","ame:") - @sed -i 's/^Version:.*/Version: $(version)/' $(package).spec - @sed -i 's/^Release:.*/Release: $(release)/' $(package).spec -endif - @tar --gzip --exclude='*CVS*' -cf rpmbuild/SOURCES/${package}.src.tgz * - rpmbuild -ba ${package}.spec - - - - diff --git a/org.glite.yaim.lb/config/defaults/glite-lb.pre b/org.glite.yaim.lb/config/defaults/glite-lb.pre deleted file mode 100644 index 765eb59..0000000 --- a/org.glite.yaim.lb/config/defaults/glite-lb.pre +++ /dev/null @@ -1,3 +0,0 @@ -### Default values to some glite-LB variables -# backward compatible default location of GLITE_LOCATION_VAR -GLITE_LOCATION_VAR=/var/glite diff --git a/org.glite.yaim.lb/config/defaults/glite-lb_30.pre b/org.glite.yaim.lb/config/defaults/glite-lb_30.pre deleted file mode 100644 index 4b697ab..0000000 --- a/org.glite.yaim.lb/config/defaults/glite-lb_30.pre +++ /dev/null @@ -1,3 +0,0 @@ -### Default values to some glite-LB variables -GLITE_USER=glite -GLITE_WMS_LCGMON_FILE="/var/glite/logging/status.log" diff --git a/org.glite.yaim.lb/config/functions/config_gip_lb b/org.glite.yaim.lb/config/functions/config_gip_lb deleted file mode 100644 index dde5c00..0000000 --- a/org.glite.yaim.lb/config/functions/config_gip_lb +++ /dev/null @@ -1,14 +0,0 @@ -function config_gip_lb_check () { - - yaimlog DEBUG "This function currently doesn't set any environment variables." - -} - -function config_gip_lb () { - - SERVICE_TYPE=org.glite.lb.Server - - rm -f $INSTALL_ROOT/glite/var/tmp/gip/service-${SERVICE_TYPE}.conf - rm -f $INSTALL_ROOT/glite/etc/gip/ldif/service-${SERVICE_TYPE}.ldif - -} diff --git a/org.glite.yaim.lb/config/functions/config_gip_lb_30 b/org.glite.yaim.lb/config/functions/config_gip_lb_30 deleted file mode 100644 index ac15a5e..0000000 --- a/org.glite.yaim.lb/config/functions/config_gip_lb_30 +++ /dev/null @@ -1,44 +0,0 @@ -function config_gip_lb_30_check () { - - requires $1 SITE_NAME - retcode=$? - return ${retcode} - -} - -function config_gip_lb_30 () { - - SERVICE_HOST=`hostname -f` - - SERVICE_TYPE=org.glite.lb.Server - SERVICE_PORT=9003 - SERVICE_VERSION=1.6.2 - SERVICE_ENDPOINT="https://${SERVICE_HOST}:${SERVICE_PORT}/lb" - - conffile=$INSTALL_ROOT/glite/var/tmp/gip/service-${SERVICE_TYPE}.conf - cat << EOF > $conffile -dn: GlueServiceUniqueID=${SERVICE_ENDPOINT} -GlueServiceName: ${SITE_NAME}-${SERVICE_TYPE} -GlueServiceType: ${SERVICE_TYPE} -GlueServiceVersion: ${SERVICE_VERSION} -GlueServiceEndpoint: ${SERVICE_ENDPOINT} -GlueServiceURI: unset -GlueServiceAccessPointURL: ${SERVICE_ENDPOINT} -GlueServiceStatus: OK -GlueServiceStatusInfo: No Problems -GlueServiceWSDL: unset -GlueServiceSemantics: unset -GlueServiceStartTime: 1970-01-01T00:00:00Z -GlueForeignKey: GlueSiteUniqueID=${SITE_NAME} -EOF - - for VO in $VOS; do - echo "GlueServiceAccessControlRule: $VO" >> $conffile - echo "GlueServiceOwner: $VO" >> $conffile - done - - $INSTALL_ROOT/lcg/sbin/lcg-info-static-create -c $conffile -t \ - $INSTALL_ROOT/lcg/etc/GlueService.template > \ - $INSTALL_ROOT/glite/etc/gip/ldif/service-${SERVICE_TYPE}.ldif - -} diff --git a/org.glite.yaim.lb/config/functions/config_glite_lb b/org.glite.yaim.lb/config/functions/config_glite_lb deleted file mode 100644 index d999714..0000000 --- a/org.glite.yaim.lb/config/functions/config_glite_lb +++ /dev/null @@ -1,253 +0,0 @@ -function config_glite_lb_check(){ - requires $1 MYSQL_PASSWORD INSTALL_ROOT GLITE_LOCATION GLITE_LOCATION_VAR GLITE_USER -} - -function config_glite_lb_setenv(){ - - yaimgridenv_set GLITE_USER ${GLITE_USER:-glite} - # Redefine GLITE_HOME_DIR to make sure we retrieve the correct HOME directory of user glite - GLITE_HOME_DIR=`getent passwd ${GLITE_USER} | cut -d: -f6` - if [ "x${GLITE_HOME_DIR}" = "x" ]; then - yaimlog ERROR "The home directory of ${GLITE_USER} doesn't exist. Check whether the user ${GLITE_USER} was properly created" - exit ${YEX_NOSUCHFILE} - fi - yaimgridenv_set GLITE_JP_LOCATION ${GLITE_JP_LOCATION:-} - yaimgridenv_set GLITE_WMS_QUERY_TIMEOUT ${GLITE_WMS_QUERY_TIMEOUT:-300} - yaimgridenv_set GLITE_HOST_CERT ${GLITE_HOME_DIR:-/home/glite}/.certs/hostcert.pem - yaimgridenv_set GLITE_HOST_KEY ${GLITE_HOME_DIR:-/home/glite}/.certs/hostkey.pem - yaimgridenv_set X509_CERT_DIR /etc/grid-security/certificates - yaimgridenv_set X509_VOMS_DIR /etc/grid-security/vomsdir - - yaimgridenv_set GLITE_LB_EXPORT_ENABLED ${GLITE_LB_EXPORT_ENABLED:-false} - yaimgridenv_set GLITE_LB_EXPORT_PURGE_ARGS "${GLITE_LB_EXPORT_PURGE_ARGS:---cleared 2d --aborted 15d --cancelled 15d --other 60d}" - yaimgridenv_set GLITE_LB_EXPORT_JPPS ${GLITE_LB_EXPORT_JPPS:-} - yaimgridenv_set GLITE_LB_RTM_ENABLED ${GLITE_LB_RTM_ENABLED:-false} - yaimgridenv_set GLITE_LB_RTM_DN "${GLITE_LB_RTM_DN:-/C=UK/O=eScience/OU=Imperial/L=Physics/CN=heppc24.hep.ph.ic.ac.uk/Email=janusz.martyniak@imperial.ac.uk}" - yaimgridenv_set GLITE_LB_SUPER_USERS "${GLITE_LB_SUPER_USERS:-}" - yaimgridenv_set GLITE_LB_HARVESTER_ENABLED ${GLITE_LB_HARVESTER_ENABLED:-false} - yaimgridenv_set GLITE_LB_HARVESTER_MSG_OPTIONS "${GLITE_LB_HARVESTER_MSG_OPTIONS:---wlcg}" - - yaimgridenv_set GLITE_LB_TYPE ${GLITE_LB_TYPE:-server} - - cares_prefix=${INSTALL_ROOT:-/opt}/c-ares - classads_prefix=${INSTALL_ROOT:-/opt}/classads - if [ x`uname -m` = xx86_64 ]; then - if [ -d "$cares_prefix/lib64" ]; then - cares_libarch=lib64 - fi - if [ -d "$classads_prefix/lib64" ]; then - classads_libarch=lib64 - fi - fi - yaimgridpath_append LD_LIBRARY_PATH $cares_prefix/${cares_libarch:-lib} - yaimgridpath_append LD_LIBRARY_PATH $classads_prefix/${classads_libarch:-lib} -} - -function config_glite_lb() { - - ############################################# - # Logging and Bookkeeping configuration # - ############################################# - - HOSTNAME=`hostname -f` - - # Redefine GLITE_HOME_DIR to make sure we retrieve the correct HOME directory of user glite - GLITE_HOME_DIR=`getent passwd ${GLITE_USER} | cut -d: -f6` - if [ "x${GLITE_HOME_DIR}" = "x" ]; then - yaimlog ERROR "The home directory of ${GLITE_USER} doesn't exist. Check whether the user ${GLITE_USER} was properly created" - exit ${YEX_NOSUCHFILE} - fi - - # Let Job Provenance Primary Storage as localhost:8901 in LB startup script. - # More strict check of GLITE_LB_EXPORT_JPPS variable only here. - if [ x"$GLITE_LB_EXPORT_ENABLED" = x"true" -a -z "$GLITE_LB_EXPORT_JPPS" ]; then - yaimlog ABORT "Job Provenance Primary Storage for export not set! (GLITE_LB_EXPORT_JPPS)" - return 1 - fi - - LB_PURGE="$GLITE_LOCATION/bin/glite-lb-purge" - if [ ! -x "$LB_PURGE" ]; then - LB_PURGE="$GLITE_LOCATION/sbin/glite-lb-purge" - fi - if [ ! -x "$LB_PURGE" ]; then - yaimlog ABORT "Purge utility not found! Install glite-lb-utils (or glite-lb-client in older version)" - return 1 - fi - - chmod og+rx /var/lib/mysql/ - chown mysql:mysql /var/run/mysqld/ - - # add option --max_allowed_packet=17M - if [ ! -f /etc/my.cnf ]; then - echo "[mysqld]" >> /etc/my.cnf - echo "max_allowed_packet=17M" >> /etc/my.cnf - else - grep "^[mysqld]" /etc/my.cnf > /dev/null - if [ ! $? = 0 ]; then - echo "[mysqld]" >> /etc/my.cnf - echo "max_allowed_packet=17M" >> /etc/my.cnf - fi - fi - - /sbin/chkconfig mysqld on - ps ax | grep -v grep |grep mysqld_safe > /dev/null 2>&1 - if [ ! $? = 0 ] ; then - /etc/init.d/mysqld start - sleep 1 - fi - - ls /tmp/mysql.sock > /dev/null 2>&1 - if [ ! $? = 0 ]; then - ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock - fi - - # set mysql password - set_mysql_passwd || return 1 # the function uses $MYSQL_PASSWORD - - # Check if database exist - mysqlshow --password="$MYSQL_PASSWORD" | grep "\" > /dev/null 2>&1 - - if [ ! $? = 0 ]; then - mysql -u root --password="$MYSQL_PASSWORD" -e "CREATE DATABASE lbserver20" - mysql --password="$MYSQL_PASSWORD" lbserver20 < ${INSTALL_ROOT}/glite/etc/glite-lb-dbsetup.sql - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on lbserver20.* to lbserver IDENTIFIED BY '' WITH GRANT OPTION;" - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on lbserver20.* to lbserver@'$HOSTNAME' IDENTIFIED BY '' WITH GRANT OPTION;" - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on lbserver20.* to lbserver@localhost IDENTIFIED BY '' WITH GRANT OPTION;" - mysql -u root --password="$MYSQL_PASSWORD" -e "ALTER TABLE short_fields MAX_ROWS=1000000000;" lbserver20 - mysql -u root --password="$MYSQL_PASSWORD" -e "ALTER TABLE long_fields MAX_ROWS=55000000;" lbserver20 - mysql -u root --password="$MYSQL_PASSWORD" -e "ALTER TABLE states MAX_ROWS=9500000;" lbserver20 - mysql -u root --password="$MYSQL_PASSWORD" -e "ALTER TABLE events MAX_ROWS=175000000;" lbserver20 - else - yaimlog WARNING "Database lbserver20 already exists" - fi - - # adjust indexes - # 1) if L&B with local harvester or L&B for Real Time Monitoring ==> lastUpdateTime needed - # 2) if GLITE_LB_INDEX_OWNER specified ==> create/destroy owner index - need_reindex=0 - $GLITE_LOCATION/bin/glite-lb-bkindex -d 2>/dev/null | tail -n +3 | head -n -2 | sed 's/\([^,]\)$/\1,/' > /var/tmp/glite-lb-bkindexes.txt - if [ x"$GLITE_LB_RTM_ENABLED" = x"true" -o x"GLITE_LB_HARVESTER_ENABLED" = x"true" ]; then - # index for querying older jobs by real time monitor - grep '\[ type = "system"; name = "lastUpdateTime" \]' /var/tmp/glite-lb-bkindexes.txt >/dev/null - if [ $? != 0 ]; then - need_reindex=1 - yaimlog INFO "Index 'lastUpdateTime' will be added" - echo '[ type = "system"; name = "lastUpdateTime" ],' >> /var/tmp/glite-lb-bkindexes.txt - fi - fi - if [ x"$GLITE_LB_INDEX_OWNER" = x"true" ]; then - grep 'name = "owner"' /var/tmp/glite-lb-bkindexes.txt >/dev/null - if [ $? != 0 ]; then - need_reindex=1 - yaimlog INFO "Index 'owner' will be added" - echo '[ type = "system"; name = "owner" ],' >> /var/tmp/glite-lb-bkindexes.txt - fi - elif [ x"$GLITE_LB_INDEX_OWNER" = x"false" ]; then - grep 'name = "owner"' /var/tmp/glite-lb-bkindexes.txt >/dev/null - if [ $? = 0 ]; then - need_reindex=1 - yaimlog INFO "Index 'owner' will be deleted" - mv /var/tmp/glite-lb-bkindexes.txt /var/tmp/glite-lb-bkindexes.txt.2 - grep -v 'name = "owner"' /var/tmp/glite-lb-bkindexes.txt.2 > /var/tmp/glite-lb-bkindexes.txt - rm -f /var/tmp/glite-lb-bkindexes.txt.2 - fi - fi - if [ $need_reindex = 1 ]; then - cat << EOF | $GLITE_LOCATION/bin/glite-lb-bkindex -rv -[ - JobIndices = { -`cat /var/tmp/glite-lb-bkindexes.txt` - } -] -EOF - fi - rm -f /var/tmp/glite-lb-bkindexes.txt - - mkdir -p $GLITE_LOCATION_VAR # Needed to store PID of LB server - - chown $GLITE_USER:$GLITE_USER $GLITE_LOCATION_VAR - chmod 0755 $GLITE_LOCATION_VAR - - mkdir -p $GLITE_HOME_DIR/.certs - chown $GLITE_USER:$GLITE_USER $GLITE_HOME_DIR/.certs - chmod 0755 $GLITE_HOME_DIR/.certs - cp -f /etc/grid-security/hostcert.pem /etc/grid-security/hostkey.pem $GLITE_HOME_DIR/.certs/ - if [ ! $? = 0 ] ; then - yaimlog WARNING "Please copy host certificate and key into /etc/grid-security and" - yaimlog WARNING " $GLITE_HOME_DIR/.certs/, change the owner of the ones in" - yaimlog WARNING " $GLITE_HOME_DIR/.certs/ to $GLITE_USER" - fi - chown $GLITE_USER:$GLITE_USER $GLITE_HOME_DIR/.certs/hostcert.pem $GLITE_HOME_DIR/.certs/hostkey.pem - chmod 0644 $GLITE_HOME_DIR/.certs/hostcert.pem - chmod 0400 $GLITE_HOME_DIR/.certs/hostkey.pem - - # Create cron for purging - mkdir -p /var/log/glite - logfile=/var/log/glite/glite-lb-purger.log - if $LB_PURGE --help 2>&1 | grep 'target-runtime' > /dev/null; then - purge_target_runtime_cmd='export GLITE_LB_PURGE_TARGET_RUNTIME=84600s; ' - fi - cat << EOF > /etc/cron.d/glite-lb-purge.cron -HOME=/ -MAILTO=$SITE_EMAIL - -1 1 * * * $GLITE_USER . /opt/glite/etc/profile.d/grid-env.sh ; export GLITE_LB_EXPORT_BKSERVER=$HOSTNAME; $purge_target_runtime_cmd/opt/glite/sbin/glite-lb-export.sh >> $logfile 2>&1 -EOF - - touch $logfile - chown $GLITE_USER:$GLITE_USER $logfile - - cat > /etc/logrotate.d/lb-purger < /dev/null - if [ ! $? = 0 ] ; then - echo "${GLITE_LOCATION}/etc/init.d/glite-lb-bkserverd" >> ${GLITE_LOCATION}/etc/gLiteservices - fi - - if [ -z "$GLITE_LB_SUPER_USERS" ]; then - touch ${GLITE_LOCATION}/etc/LB-super-users - else - echo "$GLITE_LB_SUPER_USERS" > ${GLITE_LOCATION}/etc/LB-super-users - fi - if [ x"$GLITE_LB_RTM_ENABLED" = x"true" ]; then - echo "$GLITE_LB_RTM_DN" >> ${GLITE_LOCATION}/etc/LB-super-users - fi - - if [ ! -f ${GLITE_LOCATION}/etc/glite-lb-harvester.conf ]; then - echo $HOSTNAME > ${GLITE_LOCATION}/etc/glite-lb-harvester.conf - fi - - . /opt/glite/etc/profile.d/grid-env.sh - ${GLITE_LOCATION}/etc/init.d/glite-lb-bkserverd stop - #Temporary workaround to kill glite-lb-*-interlogd - ps ax | grep -v grep | grep glite-lb-notif-interlogd > /dev/null - if [ $? = 0 ]; then - killall -9 /opt/glite/bin/glite-lb-notif-interlogd - fi - ps ax | grep -v grep | grep glite-lb-interlogd > /dev/null - if [ $? = 0 ]; then - killall -9 /opt/glite/bin/glite-lb-interlogd - fi - ${GLITE_LOCATION}/etc/init.d/glite-lb-bkserverd start - - if [ ! $? = 0 ] ; then - yaimlog ABORT "Service glite-lb-bkserverd failed to start!" - return 1 - fi - - return 0 - -} diff --git a/org.glite.yaim.lb/config/functions/config_glite_lb_30 b/org.glite.yaim.lb/config/functions/config_glite_lb_30 deleted file mode 100644 index 9ac8cb6..0000000 --- a/org.glite.yaim.lb/config/functions/config_glite_lb_30 +++ /dev/null @@ -1,141 +0,0 @@ -function config_glite_lb_30_check(){ - requires $1 MYSQL_PASSWORD -} - -function config_glite_lb_30_setenv(){ - - yaimgridenv_set GLITE_LOCATION ${INSTALL_ROOT:-opt}/glite - yaimgridenv_set GLITE_LOCATION_VAR /var/glite - yaimgridenv_set GLITE_USER ${GLITE_USER:-glite} - yaimgridenv_set GLITE_WMS_QUERY_TIMEOUT 300 - yaimgridenv_set GLITE_HOST_CERT ${GLITE_HOME_DIR:-/home/glite}/.certs/hostcert.pem - yaimgridenv_set GLITE_HOST_KEY ${GLITE_HOME_DIR:-/home/glite}/.certs/hostkey.pem - yaimgridenv_set X509_CERT_DIR /etc/grid-security/certificates - yaimgridenv_set X509_VOMS_DIR /etc/grid-security/vomsdir - - yaimgridpath_append LD_LIBRARY_PATH ${INSTALL_ROOT:-opt}/glite/lib - yaimgridpath_append LD_LIBRARY_PATH ${INSTALL_ROOT:-opt}/globus/lib - yaimgridpath_append LD_LIBRARY_PATH ${INSTALL_ROOT:-opt}/c-ares/lib -} - -function config_glite_lb_30() { - - ############################################# - # Logging and Bookkeeping configuration # - ############################################# - - HOSTNAME=`hostname -f` - - chmod og+rx /var/lib/mysql/ - - # add option --max_allowed_packet=17M - if [ ! -f /etc/my.cnf ]; then - echo "[mysqld]" >> /etc/my.cnf - echo "max_allowed_packet=17M" >> /etc/my.cnf - else - grep "^[mysqld]" /etc/my.cnf > /dev/null - if [ ! $? = 0 ]; then - echo "[mysqld]" >> /etc/my.cnf - echo "max_allowed_packet=17M" >> /etc/my.cnf - fi - fi - - /sbin/chkconfig mysql on - ps ax | grep -v grep |grep mysqld_safe > /dev/null 2>&1 - if [ ! $? = 0 ] ; then - /etc/init.d/mysql start - sleep 1 - fi - - ls /tmp/mysql.sock > /dev/null 2>&1 - if [ ! $? = 0 ]; then - ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock - fi - - # set mysql password - set_mysql_passwd || return 1 # the function uses $MYSQL_PASSWORD - - # Check if database exist - mysqlshow --password="$MYSQL_PASSWORD" | grep "lbserver20" > /dev/null 2>&1 - - if [ ! $? = 0 ]; then - mysql -u root --password="$MYSQL_PASSWORD" -e "CREATE DATABASE lbserver20" - mysql --password="$MYSQL_PASSWORD" lbserver20 < ${INSTALL_ROOT}/glite/etc/glite-lb-dbsetup.sql - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on lbserver20.* to lbserver IDENTIFIED BY '' WITH GRANT OPTION;" - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on lbserver20.* to lbserver@'$HOSTNAME' IDENTIFIED BY '' WITH GRANT OPTION;" - mysql -u root --password="$MYSQL_PASSWORD" -e "GRANT ALL PRIVILEGES on lbserver20.* to lbserver@localhost IDENTIFIED BY '' WITH GRANT OPTION;" - mysql -u root --password="$MYSQL_PASSWORD" -e "ALTER TABLE short_fields MAX_ROWS=1000000000;" lbserver20 - mysql -u root --password="$MYSQL_PASSWORD" -e "ALTER TABLE long_fields MAX_ROWS=55000000;" lbserver20 - mysql -u root --password="$MYSQL_PASSWORD" -e "ALTER TABLE states MAX_ROWS=9500000;" lbserver20 - mysql -u root --password="$MYSQL_PASSWORD" -e "ALTER TABLE events MAX_ROWS=175000000;" lbserver20 - else - yaimlog WARNING "Database lbserver20 already exists" - fi - - # do we need bkindex? - - GLITE_LOCATION_VAR=${GLITE_LOCATION_VAR:-/var/glite} - mkdir -p $GLITE_LOCATION_VAR # Needed to store PID of LB server - - chown $GLITE_USER:$GLITE_USER $GLITE_LOCATION_VAR - chmod 0755 $GLITE_LOCATION_VAR - - mkdir -p $GLITE_HOME_DIR/.certs - chown $GLITE_USER:$GLITE_USER $GLITE_HOME_DIR/.certs - chmod 0755 $GLITE_HOME_DIR/.certs - cp -f /etc/grid-security/hostcert.pem /etc/grid-security/hostkey.pem $GLITE_HOME_DIR/.certs/ - if [ ! $? = 0 ] ; then - echo "Please copy host certificate and key into /etc/grid-security and" - echo " $GLITE_HOME_DIR/.certs/, change the owner of the ones in" - echo " $GLITE_HOME_DIR/.certs/ to $GLITE_USER" - fi - chown $GLITE_USER:$GLITE_USER $GLITE_HOME_DIR/.certs/hostcert.pem $GLITE_HOME_DIR/.certs/hostkey.pem - chmod 0644 $GLITE_HOME_DIR/.certs/hostcert.pem - chmod 0400 $GLITE_HOME_DIR/.certs/hostkey.pem - - # Create cron for purging - mkdir -p /var/log/glite - logfile=/var/log/glite/glite-lb-purger.log - cat << EOF > /etc/cron.d/glite-lb-purge.cron -HOME=/ -MAILTO=$SITE_EMAIL - -1 1 * * * $GLITE_USER . /opt/glite/etc/profile.d/grid-env.sh ; export GLITE_LB_EXPORT_BKSERVER=$HOSTNAME; export GLITE_LB_EXPORT_ENABLED=false; export GLITE_LB_EXPORT_PURGE_ARGS="--cleared 2d --aborted 15d --cancelled 15d --other 60d"; /opt/glite/sbin/glite-lb-export.sh >> $logfile 2>&1 -EOF - - touch $logfile - chown $GLITE_USER:$GLITE_USER $logfile - - cat > /etc/logrotate.d/lb-purger < /dev/null - if [ ! $? = 0 ] ; then - echo "${GLITE_LOCATION}/etc/init.d/glite-lb-bkserverd" >> ${GLITE_LOCATION}/etc/gLiteservices - fi - - touch ${GLITE_LOCATION}/etc/LB-super-users - - . /opt/glite/etc/profile.d/grid-env.sh - ${GLITE_LOCATION}/etc/init.d/glite-lb-bkserverd restart - - if [ ! $? = 0 ] ; then - yaimlog ABORT "Service glite-lb-bkserverd failed to start!" - return 1 - fi - - return 0 - -} diff --git a/org.glite.yaim.lb/config/functions/config_info_service_lb b/org.glite.yaim.lb/config/functions/config_info_service_lb deleted file mode 100644 index 9154391..0000000 --- a/org.glite.yaim.lb/config/functions/config_info_service_lb +++ /dev/null @@ -1,92 +0,0 @@ -############################################################################## -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://www.eu-egee.org/partners/ for details on the copyright -# holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## -# -# NAME : config_info_service_lb -# -# DESCRIPTION : This function configures the dynamic service publisher -# for site LB server node. -# -# AUTHORS : Maria.Alandes.Pradillo@cern.ch -# salvet@ics.muni.cz -# -# NOTES : -# -# YAIM MODULE: glite-yaim-lb -# -############################################################################## - -config_info_service_lb_check () { - requires $1 SITE_NAME INSTALL_ROOT -} - -config_info_service_lb_setenv () { - yaimlog DEBUG "This function currently doesn't set any environment variables." -} - -config_info_service_lb () { - -INFO_SERVICE_CONFIG=${INFO_SERVICE_CONFIG:-${INSTALL_ROOT}/glite/etc} -INFO_SERVICE_SCRIPT=${INFO_SERVICE_SCRIPT:-${INSTALL_ROOT}/glite/libexec} -INFO_PROVIDER_PATH=${INFO_PROVIDER_PATH:-${INSTALL_ROOT}/glite/etc/gip/provider} - -SERVICE=LBSERVER -SERVICE_LC=lbserver - -SERVICE_HOST=`hostname -f` - -if [ ! -f ${INFO_SERVICE_CONFIG}/glite-info-service-${SERVICE_LC}.conf.template ]; then - yaimlog ERROR "The template file for glite-info-service-${SERVICE_LC}.conf.template was not found in ${INFO_SERVICE_CONFIG}." - exit 1 -fi - -if [ ! -f ${INFO_SERVICE_SCRIPT}/glite-info-service ]; then - yaimlog ERROR "The script file for glite-info-service was not found in ${INFO_SERVICE_SCRIPT}." - exit 1 -fi - -yaimlog DEBUG "Delete a previous version of the glite-info-service-${SERVICE_LC}.conf if it exists" -rm -rf ${INFO_SERVICE_CONFIG}/glite-info-service-${SERVICE_LC}.conf - -yaimlog DEBUG "Create the glite-info-service-${SERVICE_LC}.conf file out of the template file" -cp ${INFO_SERVICE_CONFIG}/glite-info-service-${SERVICE_LC}.conf.template ${INFO_SERVICE_CONFIG}/glite-info-service-${SERVICE_LC}.conf - -# Note: the configuration file may need to be altered if non standard values have been used. - -yaimlog DEBUG "Delete a previous version of the glite-info-provider-service-${SERVICE_LC}-wrapper if it exists" -rm -rf ${INFO_PROVIDER_PATH}/glite-info-provider-service-${SERVICE_LC}-wrapper - -yaimlog DEBUG "Create the ${INFO_PROVIDER_PATH} in case it doesn't exist" -mkdir -p ${INFO_PROVIDER_PATH} - -yaimlog DEBUG "Create the glite-info-provider-service-${SERVICE_LC}-wrapper file" -cat << EOF > ${INFO_PROVIDER_PATH}/glite-info-provider-service-${SERVICE_LC}-wrapper -#!/bin/sh -export PATH=$PATH:${INFO_SERVICE_SCRIPT} -export ${SERVICE}_HOST=${SERVICE_HOST} -${INFO_SERVICE_SCRIPT}/glite-info-service ${INFO_SERVICE_CONFIG}/glite-info-service-${SERVICE_LC}.conf $SITE_NAME -${INFO_SERVICE_SCRIPT}/glite-info-service-glue2 ${INFO_SERVICE_CONFIG}/glite-info-service-${SERVICE_LC}.conf $SITE_NAME -EOF - -chmod +x ${INFO_PROVIDER_PATH}/glite-info-provider-service-${SERVICE_LC}-wrapper - - -return 0 - -} - - diff --git a/org.glite.yaim.lb/config/functions/config_jobmon b/org.glite.yaim.lb/config/functions/config_jobmon deleted file mode 100644 index 717aabd..0000000 --- a/org.glite.yaim.lb/config/functions/config_jobmon +++ /dev/null @@ -1,87 +0,0 @@ -############################################################################## -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://www.eu-egee.org/partners/ for details on the copyright -# holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS -# OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## -# -# NAME : config_jobmon -# -# DESCRIPTION : Monitoring using RGMA export (deprecated). -# -# AUTHORS : Di.Qing@cern.ch -# -# NOTES : -# -# YAIM MODULE: glite-yaim-lb -# -############################################################################## - -function config_jobmon_check(){ - - requires $1 GLITE_WMS_LCGMON_FILE GLITE_USER - retcode=$? - return ${retcode} - -} - -function config_jobmon_setenv(){ - - yaimgridenv_set GLITE_LB_SERVER_OTHER_OPTIONS "${GLITE_LB_SERVER_OTHER_OPTIONS} --rgmaexport" - yaimgridenv_set GLITE_WMS_LCGMON_FILE "${GLITE_WMS_LCGMON_FILE}" - -} - - -function config_jobmon(){ - - mkdir -p `dirname ${GLITE_WMS_LCGMON_FILE}` - chown $GLITE_USER:root `dirname ${GLITE_WMS_LCGMON_FILE}` - - if [ ! -d /opt/lcg/etc ]; then - mkdir -p /opt/lcg/etc - fi - - cat > /opt/lcg/etc/lcg-mon-job-status.conf < /etc/logrotate.d/glite-lb-bkserver-rgma << EOF -# Logrotation for bkserver R-GMA status file. -$GLITE_WMS_LCGMON_FILE { -daily -rotate 9 -missingok -} -EOF - - if [ -f /opt/lcg/etc/init.d/lcg-mon-logfile-daemon ]; then - ln -sf /opt/lcg/etc/init.d/lcg-mon-logfile-daemon /etc/rc.d/init.d/lcg-mon-job-status - /sbin/chkconfig lcg-mon-job-status on - /etc/rc.d/init.d/lcg-mon-job-status restart - fi - - return 0; -} - diff --git a/org.glite.yaim.lb/config/node-info.d/glite-lb b/org.glite.yaim.lb/config/node-info.d/glite-lb deleted file mode 100644 index 4a44960..0000000 --- a/org.glite.yaim.lb/config/node-info.d/glite-lb +++ /dev/null @@ -1,14 +0,0 @@ -LB_FUNCTIONS=" -config_add_pool_env -config_crl -config_host_certs -config_edgusers -config_gip_only -config_gip_lb -config_info_service_lb -config_gip_service_release -config_globus_clients -config_glite_lb -config_glite_locallogger -config_bdii_only -config_glite_initd" diff --git a/org.glite.yaim.lb/config/node-info.d/glite-lb_30 b/org.glite.yaim.lb/config/node-info.d/glite-lb_30 deleted file mode 100644 index acd1d95..0000000 --- a/org.glite.yaim.lb/config/node-info.d/glite-lb_30 +++ /dev/null @@ -1,15 +0,0 @@ -LB_FUNCTIONS=" -config_add_pool_env -config_crl -config_host_certs -config_edgusers -config_java_30 -config_rgma_client -config_gip_only -config_gip_lb_30 -config_globus_clients -config_jobmon -config_glite_lb_30 -config_glite_locallogger -config_bdii -config_glite_initd" diff --git a/org.glite.yaim.lb/glite-yaim-lb.spec b/org.glite.yaim.lb/glite-yaim-lb.spec deleted file mode 100644 index 88af220..0000000 --- a/org.glite.yaim.lb/glite-yaim-lb.spec +++ /dev/null @@ -1,39 +0,0 @@ -%define topdir %(pwd)/rpmbuild -%define _topdir %{topdir} -Summary: glite-yaim-lb -Name: glite-yaim-lb -Version: 4.0.1 -Vendor: EGEE -Release: 3 -License: EGEE -Group: EGEE -Source: %{name}.src.tgz -BuildArch: noarch -Requires: glite-yaim-core -Prefix: /opt/glite -BuildRoot: %{_tmppath}/%{name}-%{version}-build -Packager: EGEE - -%description -This package contains the yaim functions to configuration of the LB node. - -%prep - -%setup -c - -%build -make install prefix=%{buildroot}%{prefix} - -%files -%defattr(0644,root,root) -%{prefix}/yaim/functions/config_* -%{prefix}/yaim/defaults/glite-* -%{prefix}/yaim/etc/versions/%{name} -%config(noreplace) %{prefix}/yaim/node-info.d/glite-* -%doc LICENSE - -%clean -rm -rf %{buildroot} - - - diff --git a/org.glite.yaim.myproxy/.cvsignore b/org.glite.yaim.myproxy/.cvsignore deleted file mode 100644 index 3a4edf6..0000000 --- a/org.glite.yaim.myproxy/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project diff --git a/org.glite.yaim.myproxy/Changelog b/org.glite.yaim.myproxy/Changelog deleted file mode 100644 index 394b3a7..0000000 --- a/org.glite.yaim.myproxy/Changelog +++ /dev/null @@ -1,38 +0,0 @@ -#################################################################### -############### TAG glite-yaim-myproxy_R_4_0_4_2 ################### -#################################################################### - -09/08/2009 -> - -by Maria Alandes - -config/functions/config_myproxy_server -- Fix for bug #54094: host cert and key is now copied for the bdii user - -config/node-info.d/glite-px -- config_myproxy_libs is now removed. - -#################################################################### -############### TAG glite-yaim-myproxy_R_4_0_4_1 ################### -#################################################################### - -06/07/2009 -> - -by Maria Alandes - -glite-yaim-myproxy.spec -- Force dependency on glite-yaim-core >= 4.0.10 - -config/node-info.d/glite-px -- Fix for bug #i52822 configuration changes -> new config_myproxy_libs is now added. - -config/services/glite-px -- Fix for bug #48440: Extra spaces have been removed - -14/11/2008 -> - -by Maria Alandes - -Makefile, spec file -- Fix for bug #44000: RPM_BUILD_ROOT is not used anymore in the Makefile. -- Fix for bug #40565: version for myproxy and fix in spec file for man pages diff --git a/org.glite.yaim.myproxy/LICENSE b/org.glite.yaim.myproxy/LICENSE deleted file mode 100755 index 01b973b..0000000 --- a/org.glite.yaim.myproxy/LICENSE +++ /dev/null @@ -1,69 +0,0 @@ -LICENSE file for EGEE Middleware -================================ - -Copyright (c) 2004 on behalf of the EU EGEE Project: -The European Organization for Nuclear Research (CERN), -Istituto Nazionale di Fisica Nucleare (INFN), Italy -Datamat Spa, Italy -Centre National de la Recherche Scientifique (CNRS), France -CS Systeme d'Information (CSSI), France -Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden -Universiteit van Amsterdam (UvA), Netherlands -University of Helsinki (UH.HIP), Finlan -University of Bergen (UiB), Norway -Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -3. The end-user documentation included with the redistribution, if -any, must include the following acknowledgment: "This product includes -software developed by The EU EGEE Project (http://cern.ch/eu-egee/)." -Alternatively, this acknowledgment may appear in the software itself, if -and wherever such third-party acknowledgments normally appear. - -4. The names EGEE and the EU EGEE Project must not be -used to endorse or promote products derived from this software without -prior written permission. For written permission, please contact -. - -5. You are under no obligation whatsoever to provide anyone with any -bug fixes, patches, or upgrades to the features, functionality or -performance of the Software ("Enhancements") that you may develop over -time; however, if you choose to provide your Enhancements to The EU -EGEE Project, or if you choose to otherwise publish or distribute your -Enhancements, in source code form without contemporaneously requiring -end users of The EU EGEE Proejct to enter into a separate written license -agreement for such Enhancements, then you hereby grant The EU EGEE Project -a non-exclusive, royalty-free perpetual license to install, use, copy, -modify, prepare derivative works, incorporate into the EGEE Middleware -or any other computer software, distribute, and sublicense your -Enhancements or derivative works thereof, in binary and source code -form (if any), whether developed by The EU EGEE Project or third parties. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -This software consists of voluntary contributions made by many -individuals on behalf of the EU EGEE Prject. For more information on The -EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on -EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/ - - diff --git a/org.glite.yaim.myproxy/Makefile b/org.glite.yaim.myproxy/Makefile deleted file mode 100644 index 9d8707d..0000000 --- a/org.glite.yaim.myproxy/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -prefix=/opt/glite -package=glite-yaim-myproxy -name=$Name$ -tag:=$(shell echo $(name) | sed 's/^[^:]*: //' ) -version:=$(shell echo "$(tag)" | sed 's/^.*R_//' | sed 's/_/\./g') -release:=$(shell echo "$(version)" | sed 's/.*\.//') -version:=$(shell echo "$(version)" | sed 's/\(.*\)\.[0-9]*/\1/') - -.PHONY: configure install clean rpm - -all: configure - -install: - @echo installing ... - @mkdir -p $(prefix)/yaim/functions - @mkdir -p $(prefix)/yaim/node-info.d - @mkdir -p $(prefix)/yaim/examples - @mkdir -p $(prefix)/yaim/examples/siteinfo - @mkdir -p $(prefix)/yaim/examples/siteinfo/services - @mkdir -p ${prefix}/share/man/man1 - @mkdir -p $(prefix)/yaim/etc/versions - - @install -m 0644 config/functions/config* $(prefix)/yaim/functions - @install -m 0644 config/node-info.d/glite* $(prefix)/yaim/node-info.d - @install -m 0644 config/services/glite* $(prefix)/yaim/examples/siteinfo/services/. - @install -m 0644 config/man/yaim-myproxy.1 ${prefix}/share/man/man1/ - @echo "$(package) $(version)-$(release)" > $(prefix)/yaim/etc/versions/$(package) - - -clean:: - rm -f *~ test/*~ etc/*~ doc/*~ src/*~ - rm -rf rpmbuild - -rpm: - @mkdir -p rpmbuild/RPMS/noarch - @mkdir -p rpmbuild/SRPMS/ - @mkdir -p rpmbuild/SPECS/ - @mkdir -p rpmbuild/SOURCES/ - @mkdir -p rpmbuild/BUILD/ - -ifneq ("$(tag)","ame:") - @sed -i 's/^Version:.*/Version: $(version)/' $(package).spec - @sed -i 's/^Release:.*/Release: $(release)/' $(package).spec -endif - @tar --gzip --exclude='*CVS*' -cf rpmbuild/SOURCES/${package}.src.tgz * - @rpmbuild -ba ${package}.spec - diff --git a/org.glite.yaim.myproxy/config/functions/config_gip_px b/org.glite.yaim.myproxy/config/functions/config_gip_px deleted file mode 100755 index e7f49e8..0000000 --- a/org.glite.yaim.myproxy/config/functions/config_gip_px +++ /dev/null @@ -1,52 +0,0 @@ -############################################################################## -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://www.eu-egee.org/partners/ for details on the copyright -# holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## -# -# NAME : config_gip_px -# -# DESCRIPTION : This function configures the generic information providor (GIP) -# for MyProxy (PX) node. -# -# AUTHORS : Shu-Ting.Liao@cern.ch -# -# NOTES : The config_gip_ function creates the ldif file. -# This is currently done by the function config_info_service_. -# This function is still included in the function list for cleaning tasks. -# -# -# YAIM MODULE: glite-yaim-myproxy -# -############################################################################## -config_gip_px_check () { - yaimlog DEBUG "This function currently doesn't set any environment variables." -} - -config_gip_px_setenv () { - yaimlog DEBUG "This function currently doesn't set any environment variables." -} - -config_gip_px () { - -CONF_DIR="$INSTALL_ROOT/glite/var/tmp/gip" -LDIF_DIR="${INSTALL_ROOT}/glite/etc/gip/ldif" - -rm -rf ${CONF_DIR}/glite-info-static-px.conf -rm -rf ${LDIF_DIR}/static-file-PX.ldif - -return 0 - -} diff --git a/org.glite.yaim.myproxy/config/functions/config_info_service_px b/org.glite.yaim.myproxy/config/functions/config_info_service_px deleted file mode 100644 index 06725d6..0000000 --- a/org.glite.yaim.myproxy/config/functions/config_info_service_px +++ /dev/null @@ -1,88 +0,0 @@ -############################################################################## -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://www.eu-egee.org/partners/ for details on the copyright -# holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## -# -# NAME : config_info_service_px -# -# DESCRIPTION : This function configures the dynamic service publisher -# for MyProxy (PX) node. -# -# AUTHORS : Maria.Alandes.Pradillo@cern.ch -# -# NOTES : -# -# YAIM MODULE: glite-yaim-myproxy -# -############################################################################## - -config_info_service_px_check () { - requires $1 SITE_NAME INSTALL_ROOT PX_HOST -} - -config_info_service_px_setenv () { - yaimlog DEBUG "This function currently doesn't set any environment variables." -} - -config_info_service_px () { - -INFO_SERVICE_CONFIG=${INFO_SERVICE_CONFIG:-${INSTALL_ROOT}/glite/etc} -INFO_SERVICE_SCRIPT=${INFO_SERVICE_SCRIPT:-${INSTALL_ROOT}/glite/libexec} -INFO_PROVIDER_PATH=${INFO_PROVIDER_PATH:-${INSTALL_ROOT}/glite/etc/gip/provider} - -SERVICE=MYPROXY -SERVICE_HOST=${PX_HOST} - -SERVICE_LC=`echo ${SERVICE} | tr '[:upper:]' '[:lower:]'` - -if [ ! -f ${INFO_SERVICE_CONFIG}/glite-info-service-${SERVICE_LC}.conf.template ]; then - yaimlog ERROR "The template file for glite-info-service-${SERVICE_LC}.conf.template was not found in ${INFO_SERVICE_CONFIG}." - exit 1 -fi - -if [ ! -f ${INFO_SERVICE_SCRIPT}/glite-info-service ]; then - yaimlog ERROR "The script file for glite-info-service was not found in ${INFO_SERVICE_SCRIPT}." - exit 1 -fi - -yaimlog DEBUG "Delete a previous version of the glite-info-service-${SERVICE_LC}.conf if it exists" -rm -rf ${INFO_SERVICE_CONFIG}/glite-info-service-${SERVICE_LC}.conf - -yaimlog DEBUG "Create the glite-info-service-${SERVICE_LC}.conf file out of the template file" -cp ${INFO_SERVICE_CONFIG}/glite-info-service-${SERVICE_LC}.conf.template ${INFO_SERVICE_CONFIG}/glite-info-service-${SERVICE_LC}.conf - -# Note: the configuration file may need to be altered if non standard values have been used. - -yaimlog DEBUG "Delete a previous version of the glite-info-provider-service-${SERVICE_LC}-wrapper if it exists" -rm -rf ${INFO_PROVIDER_PATH}/glite-info-provider-service-${SERVICE_LC}-wrapper - -yaimlog DEBUG "Create the ${INFO_PROVIDER_PATH} in case it doesn't exist" -mkdir -p ${INFO_PROVIDER_PATH} - -yaimlog DEBUG "Create the glite-info-provider-service-${SERVICE_LC}-wrapper file" -cat << EOF > ${INFO_PROVIDER_PATH}/glite-info-provider-service-${SERVICE_LC}-wrapper -#!/bin/sh -export PATH=$PATH:${INFO_SERVICE_SCRIPT} -export ${SERVICE}_HOST=${SERVICE_HOST} -${INFO_SERVICE_SCRIPT}/glite-info-service ${INFO_SERVICE_CONFIG}/glite-info-service-${SERVICE_LC}.conf $SITE_NAME -EOF - -chmod +x ${INFO_PROVIDER_PATH}/glite-info-provider-service-${SERVICE_LC}-wrapper - - -return 0 - -} diff --git a/org.glite.yaim.myproxy/config/functions/config_proxy_server b/org.glite.yaim.myproxy/config/functions/config_proxy_server deleted file mode 100644 index eb6a60b..0000000 --- a/org.glite.yaim.myproxy/config/functions/config_proxy_server +++ /dev/null @@ -1,132 +0,0 @@ -############################################################################## -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://www.eu-egee.org/partners/ for details on the copyright -# holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS -# OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## -# -# NAME : config_proxy_server -# -# DESCRIPTION : This function configures the 3.0 proxy server. -# -# AUTHORS : Robert.Harakaly@cern.ch -# -# NOTES : -# -# YAIM MODULE: glite-yaim-myproxy -# UPDATES: Ulrich.Schwickerath@cern.ch, Steve.Traylen@cern.ch -# -############################################################################## -# -# 21/05/2008 US,ML rewrite to support more configuration options -# - -config_proxy_server_check () { - -requires $1 BDII_USER BDII_GROUP BDII_HOME_DIR X509_HOST_CERT X509_HOST_KEY -return $? - -} - -config_proxy_server_setenv () { - -return 0 - -} - -config_proxy_server () { - -# Fix for bug 54094: BDII_USER needs copies of host cert and key -mkdir -p ${BDII_HOME_DIR}/.globus -cp ${X509_HOST_CERT} ${BDII_HOME_DIR}/.globus/usercert.pem -cp ${X509_HOST_KEY} ${BDII_HOME_DIR}/.globus/userkey.pem -chown -R ${BDII_USER}.${BDII_GROUP} ${BDII_HOME_DIR}/.globus - - -MYPROXY_CONF=${INSTALL_ROOT}/glite/etc/myproxy-server.conf -MYPROXY_CONF_NEW=${INSTALL_ROOT}/glite/etc/myproxy-server.conf_NEW - - -# Special case where we are upgrading from the old style configuration. -# with a configuration file myproxy-server.config file. -pgrep -lf myproxy-server.config 2>&1 > /dev/null -if [ $? = "0" ] ; then - yaimlog INFO "MyProxy Running with old style configuration, stopping" - /sbin/service myproxy stop -fi - - -yaimlog DEBUG "Creating Minimal myproxy configuration." -cat < $MYPROXY_CONF_NEW -# YAIM generated configuration file for MyProxy -# -# We allow anyone to use this service. They are checked against the -# installed CAs anyway. -# -accepted_credentials "*" - -EOF - -if [ "x$GRID_TRUSTED_BROKERS" != "x" ] ; then - yaimlog WARNING "Use of GRID_TRUSTED_BROKERS is deprecated in YAIM, use GRID_AUTHORIZED_RENEWERS" - echo "# Adding GRID_TRUSTED_BROKERS as authorized_renewers - Deprecated" >> $MYPROXY_CONF_NEW - split_quoted_variable $GRID_TRUSTED_BROKERS | while read x; do - test "x$x" != "x" && echo "authorized_renewers \"$x\"" >> $MYPROXY_CONF_NEW - done - echo "" >> $MYPROXY_CONF_NEW -fi - -for VALUE in GRID_AUTHORIZED_RENEWERS GRID_DEFAULT_RENEWERS \ - GRID_AUTHORIZED_RETRIEVERS GRID_DEFAULT_RETRIEVERS \ - GRID_AUTHORIZED_KEY_RETRIEVERS GRID_DEFAULT_KEY_RETRIEVERS \ - GRID_TRUSTED_RETRIEVERS GRID_DEFAULT_TRUSTED_RETRIEVERS - -do - KEY=`echo $VALUE | sed 's/^GRID_//' | tr "[:upper:]" "[:lower:]"` - echo "#Adding YAIM value $VALUE if any as $KEY values" >> $MYPROXY_CONF_NEW - split_quoted_variable ${!VALUE} | while read x; do - test "x$x" != "x" && echo "$KEY \"$x\"" >> $MYPROXY_CONF_NEW - done - echo "" >> $MYPROXY_CONF_NEW -done - -/sbin/chkconfig --add myproxy - -# -# check if the configuration changed and reload/replace only if necessary -# - -[ -f $MYPROXY_CONF ] && diff $MYPROXY_CONF_NEW $MYPROXY_CONF 2>&1 > /dev/null -rc=$? - -if [ $rc == 0 ]; then - yaimlog INFO "MyProxy server configuration unchanged" - rm -f $MYPROXY_CONF_NEW -else - yaimlog INFO "Reloading MyProxy server" - mv $MYPROXY_CONF_NEW $MYPROXY_CONF - /etc/init.d/myproxy reload < /dev/null -fi - -/etc/init.d/myproxy status 2>&1 > /dev/null -if [ $? != "0" ] ; then - yaimlog INFO "MyProxy server not running so starting" - /etc/init.d/myproxy start -fi - - - -return 0 -} diff --git a/org.glite.yaim.myproxy/config/man/yaim-myproxy.1 b/org.glite.yaim.myproxy/config/man/yaim-myproxy.1 deleted file mode 100644 index e8b3824..0000000 --- a/org.glite.yaim.myproxy/config/man/yaim-myproxy.1 +++ /dev/null @@ -1,86 +0,0 @@ -.TH "YAIM - Yet Another Installation Manager" 1 -.SH NAME -yaim \- YAIM (YAIM Aint an Installation Manager) is, as the name suggests, a way of configuring Grid Services. -The aim of YAIM is to provide a simple installation and configuration method that can be used to set up a simple Grid Site -but can be easily adapted and extended to meet the need of larger sites. The yaim-myproxy module is configuring the MyProxy server. - -.SH DESCRIPTION -The yaim-myproxy module allows you to configure the MyProxy server. - -.SH CONFIGURATION VARIABLES -This is the list of variables needed to set up in order to configure the MyProxy server. -.TP -For more details, please check: -.TP -.B https://twiki.cern.ch/twiki/bin/view/LCG/PX_configuration_variables -.TP -.B Mandatory Variables: -Site admins must ensure these variables are properly defined according to the features of the site -.TP -site-info.def variables: These variables are defined in /opt/glite/yaim/examples/site-info.def. -.TP -INSTALL_ROOT : Installation root - change if using the re-locatable distribution. -.TP -SITE_NAME : The GIIS of the site where the MyProxy server belongs to. -.TP -GLOBUS_TCP_PORT_RANGE: Port range for Globus IO. It should be specified as "num1,num2". YAIM automatically handles the syntax of this variable depending on the version of VDT. If it's VDT 1.6 it leaves "num1,num2". If it's a version < VDT 1.6 it changes to "num1 num2". -.TP -.TP -node specific variables: These variables are defined in /opt/glite/yaim/examples/services/glite-px. -.TP -GRID_TRUSTED_BROKERS : List of the DNs of the Resource Brokers host certificates which are trusted by the Proxy node. (ex: /O=Grid/O=CERN/OU=cern.ch/CN=host/testbed013.cern.ch). Now deprecated, use GRID_DEFAULT_RENEWERS instead. -.TP -GRID_AUTHORIZED_RENEWERS : List of authorized_renewrs. -.TP -GRID_DEFAULT_RENEWERS : List of default_renewers -.TP -GRID_AUTHORIZED_RETRIEVERS : List of authorized_retrievers. -.TP -GRID_DEFAULT_RETRIEVERS : List of default_retrievers. -.TP -GRID_AUTHORIZED_KEY_RETRIEVERS : List of authorized_key_retrievers. -.TP -GRID_DEFAULT_KEY_RETRIEVERS : List default_key_retrievers. -.TP -GRID_TRUSTED_RETRIEVERS : List of trusted_retrievers. -.TP -GRID_DEFAULT_TRUSTED_RETRIEVERS List of default_trusted_retrievers. -.TP - -.SH EXAMPLES -How to configure the Myproxy node. -.TP -.B ./yaim -c -s /root/site-info.def -n glite-PX -.TP -To debug the configuration process: -.TP -.B ./yaim -c -s /root/site-info.def -n glite-PX -d 6 - -.SH DOCUMENTATION -You can find useful information on these web pages: -.TP -Entry point for YAIM documentation: -.TP -.B https://twiki.cern.ch/twiki/bin/view/EGEE/YAIM -.TP -The Generic Installation and Configuration guides as well as the YAIM guides: -.TP -.B https://twiki.cern.ch/twiki/bin/view/LCG/LcgDocs -.TP -Useful links: -.TP -.B http://lcg.web.cern.ch/LCG/Sites/the-LCG-directory.html - -.SH AUTHORS -YAIM is a collaborative project where different modules are developed and maintened by different -groups. Here are some of the present contributors: -.TP -.B Maria Allandes Pradillo, Gergely Debreczeni, Laurence Field, \ -Di Qing, Andreas Unterkircher, Oliver Keeble, Steve Traylen, Owen Synge, Gavin Mccance , Maarten Litmaath, \ -and we are happy to receive patches from everybody ! - -.SH CONTACT -To contact YAIM people use the -.B yaim-contact@cern.ch -email address. - diff --git a/org.glite.yaim.myproxy/config/node-info.d/glite-px b/org.glite.yaim.myproxy/config/node-info.d/glite-px deleted file mode 100644 index 8230ef9..0000000 --- a/org.glite.yaim.myproxy/config/node-info.d/glite-px +++ /dev/null @@ -1,45 +0,0 @@ -############################################################################## -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://www.eu-egee.org/partners/ for details on the copyright -# holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS -# OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## -# -# NAME : glite-px -# -# DESCRIPTION : This function contains the function list that configures the 3.1 proxy server. -# -# AUTHORS : Shu-Ting.Liao@cern.ch -# -# NOTES : -# -# YAIM MODULE: glite-yaim-myproxy -# -############################################################################## - -PX_FUNCTIONS=" -config_crl -config_host_certs -config_edgusers -config_gip_only -config_gip_px -config_gip_service_release -config_globus_clients -config_proxy_server -config_bdii_only -config_info_service_px -" - - diff --git a/org.glite.yaim.myproxy/config/node-info.d/glite-px_30 b/org.glite.yaim.myproxy/config/node-info.d/glite-px_30 deleted file mode 100644 index 260ce8f..0000000 --- a/org.glite.yaim.myproxy/config/node-info.d/glite-px_30 +++ /dev/null @@ -1,48 +0,0 @@ -############################################################################## -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://www.eu-egee.org/partners/ for details on the copyright -# holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS -# OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## -# -# NAME : glite-px -# -# DESCRIPTION : This function contains the function list that configures the 3.0 proxy server. -# -# AUTHORS : Robert.Harakaly@cern.ch -# -# NOTES : -# -# YAIM MODULE: glite-yaim-myproxy -# -############################################################################## - -BASE1_FUNCTIONS=" -config_ldconf -config_sysconfig_edg -config_sysconfig_globus -config_sysconfig_lcg -config_crl -config_rfio" - -PX_FUNCTIONS="${BASE1_FUNCTIONS} -config_host_certs -config_edgusers -config_java -config_rgma_client -config_gip -config_globus -config_proxy_server" - diff --git a/org.glite.yaim.myproxy/config/services/glite-px b/org.glite.yaim.myproxy/config/services/glite-px deleted file mode 100644 index cd80a88..0000000 --- a/org.glite.yaim.myproxy/config/services/glite-px +++ /dev/null @@ -1,55 +0,0 @@ -############################################################################## -# Copyright (c) Members of the EGEE Collaboration. 2004. -# See http://www.eu-egee.org/partners/ for details on the copyright -# holders. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS -# OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -############################################################################## -# -# NAME : glite-px -# -# DESCRIPTION : This configuration file contains the list of variables needed -# to configure Myproxy together with site-info.def. -# -# AUTHORS : yaim-contact@cern.ch -# -# NOTES : -# -# YAIM MODULE: glite-yaim-myproxy -# -############################################################################## - -# GRID_TRUSTED_BROKERS: DNs of services (RBs) allowed to renew/retrives -# credentials from/at the myproxy server. Put single quotes around each trusted DN !!! - -# Deprecated -#GRID_TRUSTED_BROKERS=" -#'broker one' -#'broker two' -#" - - -GRID_AUTHORIZED_RENEWERS=${GRID_AUTHORIZED_RENEWERS:-""} -# WMS has traditionally used this next one. -GRID_DEFAULT_RENEWERS=${GRID_DEFAULT_RENEWERS:-""} -GRID_AUTHORIZED_RETRIEVERS=${GRID_AUTHORIZED_RETRIEVERS:-""} -GRID_DEFAULT_RETRIEVERS=${GRID_DEFAULT_RETRIEVERS:-""} -GRID_AUTHORIZED_KEY_RETRIEVERS=${GRID_AUTHORIZED_KEY_RETRIEVERS:-""} -GRID_DEFAULT_KEY_RETRIEVERS=${GRID_DEFAULT_KEY_RETRIEVERS:-""} - -# This is what NCG nagios solution uses this next one. -GRID_TRUSTED_RETRIEVERS=${GRID_TRUSTED_RETRIEVERS:-""} -GRID_DEFAULT_TRUSTED_RETRIEVERS=${GRID_DEFAULT_TRUSTED_RETRIEVERS:-""} - - diff --git a/org.glite.yaim.myproxy/glite-yaim-myproxy.spec b/org.glite.yaim.myproxy/glite-yaim-myproxy.spec deleted file mode 100644 index 7327334..0000000 --- a/org.glite.yaim.myproxy/glite-yaim-myproxy.spec +++ /dev/null @@ -1,41 +0,0 @@ -%define topdir %(pwd)/rpmbuild -%define _topdir %{topdir} -Summary: glite-yaim-myproxy module configures myproxy server. -Name: glite-yaim-myproxy -Version: x -Vendor: EGEE -Release: x -License: EGEE -Group: EGEE -Source: %{name}.src.tgz -BuildArch: noarch -Prefix: /opt/glite -Requires: glite-yaim-core >= 4.0.10-1 -BuildRoot: %{_tmppath}/%{name}-%{version}-build -Packager: EGEE - -%description -This package contains the yaim functions necessary to configure myproxy server. - -%prep - -%setup -c - -%build -make install prefix=%{buildroot}%{prefix} - -%files -%defattr(-,root,root) -%{prefix}/yaim/functions/config_* -%config(noreplace) %{prefix}/yaim/node-info.d/glite-* -%{prefix}/yaim/examples/siteinfo/services/glite-* -%{prefix}/share/man/man1/yaim-myproxy.1 -%{prefix}/yaim/etc/versions/%{name} -%doc LICENSE - - -%clean -rm -rf %{buildroot} - - - diff --git a/org.gridsite.core/.cvsignore b/org.gridsite.core/.cvsignore deleted file mode 100644 index e970233..0000000 --- a/org.gridsite.core/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -.project \ No newline at end of file diff --git a/org.gridsite.core/CHANGES b/org.gridsite.core/CHANGES deleted file mode 100644 index 5c086d4..0000000 --- a/org.gridsite.core/CHANGES +++ /dev/null @@ -1,534 +0,0 @@ -- ==== GridSite version 1.7.21 ==== -* Mon Apr 16 2012 FrantiÅ¡ek Dvořák -- Partially harmonize package names with EPEL -- Packaging fixes (library dependencies, ...) -* Thu Apr 12 2012 FrantiÅ¡ek Dvořák -- mod_gridsite location on Debian -* Tue Apr 10 2012 FrantiÅ¡ek Dvořák -- Cleanup of the libraries used in linking -- Missing documentation in Debian packages -- ==== GridSite version 1.7.20 ==== -* Fri Apr 02 2012 Zdeněk Å ustr -- Make sure the module is loaded only after mod_ssl. -- ==== GridSite version 1.7.19 ==== -* Fri Mar 03 2012 Zdeněk Å ustr -- GridSiteGSIProxyLimit wors as documented and set high enough to be "unlimited" -- ==== GridSite version 1.7.18 ==== -* Tue Mar 01 2012 Zdeněk Å ustr -- Storing reference in chain for FAQN lists -- ==== GridSite version 1.7.17 ==== -* Mon Feb 20 2012 FrantiÅ¡ek Dvořák -- Fix age version in RPM packaging -- Minor Debian packaging fixes -- New rpm-prepare and deb-prepare targets to build only source package files -* Sun Nov 27 2011 FrantiÅ¡ek Dvořák -- Prevent possible crash in htproxyput due to gsoap incompatibility -- Using libraries only in $(libdir) when linking -- ==== GridSite version 1.7.16 ==== -* Fri Oct 7 2011 FrantiÅ¡ek Dvořák -- Packaging cleanups and rpmlint fixes -- Typos in slashgrid.8 -- Packaging for Debian -* Tue Sep 6 Daniel Kouřil -- dependency fix in Makefile from Mattias Ellert (bug #86230) -* Wed Aug 17 Daniel Kouřil -- using GRSTx509NameCmp() for DN comparation (bug #85223) -- ==== GridSite version 1.7.15 ==== -* Wed Jun 29 2011 Daniel Kouřil -- Fixing memleak in GRSTx509MakeProxyCert -- ==== GridSite version 1.7.14 ==== -* Wed Jun 22 2011 Daniel Kouřil -- Not relying on hard-coded positions of certificates (fixes using VOMS .lsc files) -* Mon Jun 27 2011 FrantiÅ¡ek Dvořák -- Fixes from Mattias Ellert (bugs #69632, #83449, and #83450): - - extern "C" declarations and include protections in public headers - - integer/pointer portability fix - - proper link ordering -- IPv6 portability -* Tue Jun 28 2011 FrantiÅ¡ek Dvořák -- Fix static declaration in public header, - function GACLparseEntry() added into gridsite-gacl.h -- ==== GridSite version 1.7.13 ==== -* Tue Apr 5 13:00:24 2011 FrantiÅ¡ek Dvořák -- adding gridsite-1.5-compat in separated patch -* Tue Apr 5 12:58:10 2011 FrantiÅ¡ek Dvořák -- rpm packaging updates (guidelines, rpmbuild vs make rpm, optional build - dependencies) -- ==== GridSite version 1.7.12 ==== -* Tue Mar 18 19:04:15 CET 2011 Frantisek Dvorak -- Makefile distinguishes between -lgsoap and -lgsoapssl in cflags. -- Makefile: CFLAGS cleanup, HTTPD_FLAGS replaces httpd-specific cflags. -- Unresolved symbols from xml in _globus and _nossl library versions fixed. -- Compile and link flags of dependencies unified. -- Portability improvements -- ==== GridSite version 1.7.11 ==== -* Tue Mar 1 10:31:27 CET 2011 Daniel Kouril -- Support for using IPv6 -* Tue Feb 22 2011 Zdenek Sustr - - Extended formulation of dependencies btw. packages - to fix conflicts when upgrading from EPEL. -* Tue Nov 23 2010 Andrew McNab -- ==== GridSite version 1.7.10 ==== -* Mon Nov 22 2010 Andrew McNab -- Patch to grst_x509.c VOMS verification from - Daniel Kouril -* Tue Nov 2 2010 Andrew McNab -- ==== GridSite version 1.7.9 ==== -* Tue Nov 2 2010 Andrew McNab -- Fix free of grst->serial string in grst_x509.c -* Wed Oct 29 2010 Andrew McNab -- ==== GridSite version 1.7.8 ==== -* Tue Oct 12 2010 Andrew McNab -- Cert serial number now represented as a string - rather than an int -* Wed Sep 1 2010 Andrew McNab -- Support hashes other than MD5 for VOMS ACs to - address Bug #72185 -* Wed Apr 7 2010 Andrew McNab -- ==== GridSite version 1.7.7 ==== -* Wed Mar 31 2010 Andrew McNab -- Introduce SSLSrvConfigRec_server macro to take - this into account when accessing the *server member -* Tue Mar 30 2010 Andrew McNab -- Apply patch to mod_gridsite.c from Jan Just Keijser - to detect change to - SSLSrvConfigRec etc in "sslireneg" patch to mod_ssl -* Fri Nov 27 2009 Andrew McNab -- GRSTx509MakeProxyCert() now creates RFC 3280 - proxies if any earlier proxies are RFC style -* Tue Nov 10 2009 Andrew McNab -- Discard X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED - errors in GRST_callback_SSLVerify_wrapper(), needed - for newer OpenSSL -* Mon Oct 19 2009 Andrew McNab -- Discard X509_V_ERR_INVALID_PURPOSE errors in - GRST_callback_SSLVerify_wrapper(), needed by - OpenSSL 0.9.8e -* Thu Sep 17 2009 Andrew McNab -- GRSThttpUrlEncode rather than GRSThttpUrlMildencode - in mod_gridsite directory listings. -* Fri Sep 11 2009 Andrew McNab -- Include GRSTgaclUserFree() memory leak fix in - mod_gridsite_perm_handler() in mod_gridsite.c -* Mon Aug 10 2009 Andrew McNab -- Fix %016lx specification when creating passcodes. -* Fri Aug 7 2009 Andrew McNab -- ==== GridSite version 1.7.6 ==== -* Wed Jul 29 2009 Andrew McNab -- When creating proxies with GRSTx509MakeProxyCert, - use 2=v3 rather than the old 3=v4 Globus behaviour. - See Bug #53721 from Joni Hahkala. -* Fri Jul 23 2009 Andrew McNab -- ==== GridSite version 1.7.5 ==== -* Thu Jul 23 2009 Andrew McNab -- Check multiple VOMS issuer certs if present, and - use most permissive time range they provide to - resolve Bug #53497 -- Change (GRSTerrorLogFunc) to return int, to allow - if-less C macro using && instead. -- Remove 2 argument open(...O_CREAT...) instance in - grst_admin_file.c -- Fix Bug #53314 due to change in VOMS (user cert DN - vs user cert issuer's DN) -* Fri Jul 03 2009 Andrew McNab -- ==== GridSite version 1.7.4 ==== -* Thu Jul 02 2009 Andrew McNab -- Use lib/lib64 for mod_gridsite.so location in - Makefile and make-gridsite-spec -* Wed Jul 01 2009 Andrew McNab -- ==== GridSite version 1.7.3 ==== -* Wed Jul 01 2009 Andrew McNab -- Tidy up debugging messages -- Fix URL encoding bug in DN lists (' ' vs '+') -* Tue Jun 30 2009 Andrew McNab -- ==== GridSite version 1.7.2 ==== -* Tue Jun 30 2009 Andrew McNab -- Merge in VOMS LSC support -* Tue Jun 30 2009 Andrew McNab -- ==== GridSite version 1.7.1 ==== -* Thu Jan 29 2009 Andrew McNab -- Merge in private version changes from Yibiao Li. -- Merge in major 1.7.x vs 1.5.x divergences. -* Fri Feb 8 2008 Andrew McNab -- ==== GridSite version 1.7.0 ==== -* Thu Nov 15 2007 Andrew McNab -- Add libgridsite_nossl.[so|a] with no dependencies - on OpenSSL (for gLite L&B.) -* Thu Nov 15 2007 Andrew McNab -- ==== GridSite version 1.5.7 ==== -* Fri Nov 9 2007 Andrew McNab -- Many changes, including switch to AURI internal - format for credentials -* Fri Nov 9 2007 Andrew McNab -- ==== GridSite version 1.5.5 ==== -* Wed Jun 13 2007 Andrew McNab -- Include ctx->param->flags fix in mod_gridsite for - OpenSSL 0.9.8 from Bruno Harbulot. -- Restrict export of VOMS attributes to ones present - in the last proxy of the chain to contain attributes -* Fri May 10 2007 Andrew McNab -- ==== GridSite version 1.5.1 ==== -* Fri Feb 16 2007 Andrew McNab -- ==== GridSite version 1.5.0 ==== -* Fri Feb 16 2007 Andrew McNab -- ==== GridSite version 1.4.0 ==== -* Thu Feb 15 2007 Andrew McNab -- Final preparations for 1.4.x -* Fri Sep 22 2006 Andrew McNab -- Transfer htproxyinfo utility functions into - grst_x509.c (GRSTx509ChainLoadCheck etc) -* Wed Aug 6 2006 Andrew McNab -- ==== GridSite version 1.3.4 ==== -* Mon Jul 17 2006 Andrew McNab -- Add Shibboleth handling from Joseph Dada's branch to - mod_gridsite in main GridSite tree. -* Tue Jun 27 2006 Andrew McNab -- Merge delegation services back into core. -- Add OCSP options -* Thu Jun 22 2006 Andrew McNab -- Lots of additions to SiteCast/SlashGrid, including - /grid/local/ filesystem with DNs from gridmapdir -- GridSiteCastAlias now allows any URL scheme (gsiftp, - xrootd, ...) not just HTTP(S). -- Replace static gridsite.spec with make-gridsite-spec -* Fri Jun 9 2006 Andrew McNab -- Add patch from Jan Pospisil to - Makefile, to allow standalone building of libraries. -- Include code for June 2006 version of delegation - protocol (ie userproxy.pem rather than usercert.pem - and userkey.pem) -* Thu Jun 8 2006 Andrew McNab -- SiteCast support in SlashGrid -* Mon Jun 5 2006 Andrew McNab -- ==== GridSite version 1.3.1 ==== -* Sun May 26 2006 Andrew McNab -- Include SlashGrid code, and in gridsite.spec etc -- Add sample fuse.spec to docs for use with SlashGrid -* Fri May 26 2006 Andrew McNab -- ==== GridSite version 1.3.0 ==== -* Mon Apr 24 2006 Andrew McNab -- Reworked SSL session caching: passcodes directory now - because /var/www/sessions by default, and also used - to cache credentials according to SSL Session ID. -* Mon Apr 10 2006 Andrew McNab -- Patch from Alberto di Meglio - to allow use of relocated httpd include files. -* Mon Apr 3 2006 Andrew McNab -- Use dist for building tar balls -* Mon Apr 3 2006 Andrew McNab -- ==== GridSite version 1.1.19 ==== -* Fri Mar 31 2006 Andrew McNab -- Final tidy up for gLite 3.1 -* Fri Mar 31 2006 Andrew McNab -- ==== GridSite version 1.1.18 ==== -* Wed Mar 29 2006 Andrew McNab -- New proxy destroy and time functions. -* Tue Mar 28 2006 Shiv Kaushal -- Fixed bug in GACL admin interface that would cause - internal server erorr sometimes when adding new - entries to and ACL. -* Sat Mar 25 2006 Shiv Kaushal -- Change delegation header to Proxy-Delegation-Service - instead of Grst- -* Wed Mar 22 2006 Andrew McNab -- Add GRSTx509MakeDelegationID() to grst_x509.c -- Include code for new style delegation proxy storage -* Fri Mar 17 2006 Andrew McNab -- Associate ldconfig %post in spec with -shared RPM -* Thu Mar 16 2006 Andrew McNab -- Fixes for 200/201 error pages produced by Apache -- Fixes for onetime passcode non-removal if HTTPS -- Include new multi-RPM spec file: gridsite-shared, - gridsite-devel, gridsite-apache, gridsite-commands - (replacing htcp) and gridsite-gsexec -* Fri Mar 03 2006 Shiv Kaushal -- Modify GridSiteDelegationURI directive to insert HTTP - headers instead of modifying HTML -* Mon Feb 6 2006 Shiv Kaushal -- Add GridSiteDelegationURI directive to mod_gridsite - to allow Firefox extension to locate delegation service -* ==== GridSite version 1.1.17 ==== -* Thu Jan 12 2005 Andrew McNab -- Add 5 minute window for VOMS attributes valid slightly - in the future. -- Include Content-Range PUT support in mod_gridsite, - adapted from mod_dav by David O Callaghan -- Return 201 Created when PUT creates a file -* Mon Dec 5 2005 Andrew McNab -- Change GRIDHTTP_ONETIME to GRIDHTTP_PASSCODE -- Remove onetime=yes default from mod_gridsite -- Update gridsite.spec and Makefile for gridsite-copy.cgi -* Wed Nov 16 2005 Andrew McNab -- ==== GridSite version 1.1.16 ==== -* Wed Nov 16 2005 Andrew McNab -- Add -fPIC option to Makefile for IA64, as suggested - by Andreas Unterkircher. -* Wed Oct 12 2005 Andrew McNab -- ==== GridSite version 1.1.15 ==== -* Wed Oct 12 2005 Andrew McNab -- Fix for older OpenSSL to grst_x509.c from - Zoltan.Farkas -* Wed Oct 12 2005 Andrew McNab -- ==== GridSite version 1.1.14 ==== -* Tue Oct 11 2005 Andrew McNab -- Modify VOMS AC parsing to handle multiple ACs inside - the same X.509 AC extension. -* Mon Oct 10 2005 Andrew McNab -- ==== GridSite version 1.1.13 ==== -* Mon Oct 10 2005 Andrew McNab -- Add target_gname patch to gsexec from - Gerben Venekamp -* Thu Oct 6 2005 Andrew McNab -- Fix session reuse with Shared-Memory SSL Session - Cache bug #8856 in mod_gridsite. -- Add SiteCast support to file copying in htcp. -* Tue Oct 4 2005 Andrew McNab -- Move User, Config, Admin and Install guides from - doc directory into GridSite Wiki. -- Create/update man pages for htcp, mod_gridsite and - gsexec to be distributed with source/binaries. -* Mon Oct 3 2005 Andrew McNab -- Fix to gsexec GRST_CRED_0/SSL_CLIENT_S_DN bug found - by Ian Stokes-Rees -* Fri Sep 30 2005 Andrew McNab -- Add SiteCast ping (NOP) support to htcp -* Thu Sep 29 2005 Andrew McNab -- Add SiteCast support to mod_gridsite (file location - discovery via UDP multicast of HTCP messages.) -* Wed Sep 21 2005 Andrew McNab -- Add ports 777 and 488 to example httpd.conf files in - docs. See http://www.gridsite.org/wiki/IP_Ports -* Tue Sep 13 2005 Andrew McNab -- ==== GridSite version 1.1.12 ==== -* Tue Sep 13 2005 Andrew McNab -- Fix bug #10031 submitted by Fabrizio Pacini - (invalid free in - GRSTgaclAclLoadFile if ACL format not valid.) -* Mon Sep 12 2005 Andrew McNab -- Accept GRIDHTTP_ONETIME when passed in HTTP query - (still overridden by a GRIDHTTP_ONETIME in a cookie.) -* Sat Sep 10 2005 Andrew McNab -- Fix problem with attempted upgrades to GridHTTP when - already on the HTTP virtual server. -* Fri Sep 9 2005 Andrew McNab -- GRST_DESTINATION_TRANSLATED and GRST_DESTINATION_PERM - environment variables, for use with CGI-based COPY. -- Rework GridHTTP (ex-Downgrade) code to store method - and URI with permission, rather than credentials. -- Restrict use of GridSiteOnetimesDir to main server. -* Fri Aug 26 2005 Andrew McNab -- Fix for HTTP PUT lack-of-truncation bug found by - Mike Jones, and support for HTTP/WebDAV MOVE. -- Add MOVE support to htcp and update htcp manpage. -- Unset CURLOPT_SSL_VERIFYPEER in htcp etc when using - --noverify option. -* Fri Jun 10 2005 Andrew McNab -- ==== GridSite version 1.1.11 ==== -* Fri Jun 10 2005 Andrew McNab -- Tidy up gsexec vs GridSiteDiskMode -* Fri Jun 10 2005 Andrew McNab -- ==== GridSite version 1.1.10 ==== -* Wed Jun 8 2005 Andrew McNab -- Add GridSiteDiskMode Apache directive to set file - permissions. -- Add GridSiteExecMethod and GridSiteUserGroup to - configure suexec or extended gsexec functionality. -* Thu Jun 2 2005 Andrew McNab -- HTML improvements for Bug #4083 -- Note that GridSite currently doesn't work with SHM - SSL session cache, in httpd-*.conf and config guide. -- Add GridSiteExecMethod for use with gsexec -* Thu May 26 2005 Andrew McNab -- Include gsexec, a drop-in replacement for suexec, - which can do suexec execution of CGI programs or - pool-account mapping based on client DN. -* Tue May 24 2005 Shiv Kaushal -- Add XACML support to GACL code in libgridsite. -* Tue May 24 2005 Andrew McNab -- ==== GridSite version 1.1.9 ==== -* Mon Apr 25 2005 Andrew McNab -- Avoid build problems when using pre-0.9.7 OpenSSL - (ie with Globus compatibility.) -* Mon Apr 25 2005 Andrew McNab -- ==== GridSite version 1.1.8 ==== -* Mon Feb 28 2005 Andrew McNab -- Fix to GRSTgaclUndenyPerm in gridsite.h (bug #7135) - from Marco Sottilaro -* Mon Feb 28 2005 Andrew McNab -- ==== GridSite version 1.1.7 ==== -* Thu Feb 24 2005 Andrew McNab -- Add more sanity checking (signatures, dates, issuer,) - holder) to VOMS attribute parser. -* Mon Feb 21 2005 Andrew McNab -- Add bugfix for Bug #6357 from Fabrizio Pacini - to fix delegation proxy - cache names in OpenSSL 0.9.7. -* Sun Feb 20 2005 Andrew McNab -- Add basic VOMS support (signature checking not yet - in) for X.509 Attribute Certificates. -* Tue Feb 8 2005 Andrew McNab -- ==== GridSite version 1.1.6 ==== -* Tue Feb 8 2005 Andrew McNab -- Include GRSTx509MakeProxyFileName() and - GRSTx509StringToChain() (code to used hashes in cached - proxy file names.) Bug #6357 -- Change ordering of output proxy file produced by - GRSTx509CacheProxy so proxy private key is the 2nd PEM - encoded block (rather than at the end.) Bug #6365 -- Add libgridsite_globus[.so|.a] in preparation for - separate Globus OpenSSL and system OpenSSL versions -* Tue Feb 8 2005 Andrew McNab -- ==== GridSite version 1.1.5 ==== -* Tue Dec 14 2004 Andrew McNab -- Patch from Daniel Kouril to allow - switching Globus vs system OpenSSL libraries/headers. -* Tue Dec 14 2004 Andrew McNab -- ==== GridSite version 1.1.4 ==== -* Mon Nov 15 2004 Andrew McNab -- Back out of (most of) redone VOMS support for committing - to JRA1 CVS. -* Thu Oct 19 2004 Andrew McNab -- ==== GridSite version 1.1.3 ==== -* Thu Oct 19 2004 Andrew McNab -- Fix Bug #5203 from Martijn Steenbakkers - by fixing GACLparseEntry in gridsite-gacl.h -- Change to C style comments (mostly) in gridsite.h and - gridsite-gacl.h (fixes part of Bug #4222 from - ) -- Fix Bug #4225 from in - GRSTgaclCredsFree() -- Add GRSTx509CachedProxyFind() and findproxyfile - command to allow proxies to be found in proxy cache -- Change GRSTx509StoreProxy() to GRSTx509CacheProxy() for - consistency with this and GRSTx509CachedProxyKeyFind() -* Wed Oct 18 2004 Andrew McNab -- ==== GridSite version 1.1.2 ==== -* Tue Oct 19 2004 Andrew McNab -- Copy code from delegation prototype into grst_x509.c - and include htproxyput.c and grst-delegation.c - optional targets (which depend on gSOAP.) -* Wed Oct 13 2004 Andrew McNab -- Include per-file patch to GRSTgaclFileFindAclname: - .gacl:FILENAME controls FILENAME if it exists. -* Tue Jul 27 2004 Andrew McNab -- ==== GridSite version 1.1.1 ==== -* Tue Jul 27 2004 Andrew McNab -- Include HTTP Downgrade support in htcp -* Sat Jul 24 2004 Andrew McNab -- Include HTTP Downgrade support in mod_gridsite. -* Thu Jul 22 2004 Andrew McNab -- Begin development version 1.1.x -* Thu Jul 22 2004 Andrew McNab -- ==== GridSite version 1.1.0 ==== -* Mon Jul 19 2004 Andrew McNab -- Changes in line with EGEE SCM - most importantly - the top level directory becomes org.gridsite.core -* Mon Jul 19 2004 Andrew McNab -- ==== GridSite version 1.0.3 ==== -* Mon Jun 28 2004 Andrew McNab -- In GRSTx509CheckChain() and GRSTx509CompactCreds() - we now accept the first cert in a chain as a CA - even if it is X509v3 but without the CA bits set. - (On the basis that the first chain is from the - administrator-installed CA files store.) -* Sun Jun 27 2004 Andrew McNab -- ==== GridSite version 1.0.2 ==== -* Sun Jun 27 2004 Andrew McNab -- Fix for Bug #2860 (so can now read DN Lists over - HTTPS when have no user certificate if relevant - .gacl gives permission but not ) -- Include gridsite-gacl.h mods from Daniel Kouril - to fix faulty definitions - of GACLnewEntry() and GACLnewAcl() and to make - a legacy non-static GACLparseEntry() wrapper. -* Thu Jun 17 2004 Andrew McNab -- Changes to mod_gridsite.h for Fedora Core 2 / - Apache 2.0.49+ mod_ssl changes (mod_ssl-private.h) -* Wed Jun 9 2004 Andrew McNab -- Incorporate EGEE CVS layout changes in production - branch. -* Wed Jun 9 2004 Andrew McNab -- ==== GridSite version 1.0.1 ==== -* Sun Dec 14 2003 Andrew McNab -- 1.0.0 is first full production release - (development now in 1.1.x branch) -* Sun Dec 14 2003 Andrew McNab -- ==== GridSite version 1.0.0 ==== -* Sat Dec 13 2003 Andrew McNab -- Remove need for modified mod_ssl-gridsite: now - mod_gridsite intercepts callbacks with wrappers. -- Add GRSTx509NameCmp() which compares string reps of - DNs across OpenSSL version changes (ie Email=) -* Fri Dec 12 2003 Andrew McNab -- ==== GridSite version 0.9.11 ==== -* Thu Dec 11 2003 Andrew McNab -- Simplify checking of cert/proxy chain in - mod_ssl-gridsite: rely on mod_ssl/OpenSSL more. -* Wed Dec 2 2003 Andrew McNab -- ==== GridSite version 0.9.10 ==== -* Tue Dec 1 2003 Andrew McNab -- GACL ignores leading/trailing spaces in values. -* Sat Nov 29 2003 Andrew McNab -- Better directory listing in htcp. -- htcp now built as separate binary RPM. -- gridsite-admin.cgi upload now redirects to same - directory after upload (Bug #1939); allows - optional new name for file (Request / Bug #1940); - and has better checking of ../dir/file attacks. -* Sat Nov 29 2003 Andrew McNab -- ==== GridSite version 0.9.8 ==== -* Thu Nov 27 2003 Andrew McNab -- Shiv's updated GACL editor, with redirects. -* Wed Nov 26 2003 Andrew McNab -- Include Daniel Stenberg's roffit script to make - HTML man pages for htcp and urlencode. -- Various fixes found when installing GridPP WWW. -* Wed Nov 26 2003 Andrew McNab -- ==== GridSite version 0.9.7 ==== -* Thu Nov 20 2003 Andrew McNab -- Major updates to htcp (htrm/htls/htll) -- GACL now recurses subdirectories when examining - the DN List directories path. -* Sat Nov 15 2003 Andrew McNab -- ==== GridSite version 0.9.6 ==== -* Fri Nov 14 2003 Andrew McNab -- Function call fixes in grst-admin.cgi -* Thu Nov 13 2003 Andrew McNab -- Add htcp (curl-url-get reborn) -* Thu Nov 13 2003 Andrew McNab -- ==== GridSite version 0.9.5 ==== -* Thu Nov 13 2003 Andrew McNab -- More grst-admin.cgi GACL updates from Shiv. -- .gacl security improvements to grst-admin.cgi from - Shiv Kaushal and Peter Moore. -* Tue Nov 11 2003 Andrew McNab -- One RPM instead of three, with version from VERSION -- Textarea for HTML/Text editing now 80 columns -* Mon Nov 10 2003 Andrew McNab -- Add delegation level and GridSiteGSIProxyLimit - support. -- Add GridSiteAdminList handling to mod_gridsite - and real-gridsite-admin.cgi -* Sun Nov 9 2003 Andrew McNab -- Add directory create/delete, and file/dir rename. -- Add ZIP listing/unzipping via external unzip - utility from http://www.info-zip.org/pub/infozip/ -* Mon Nov 3 2003 Andrew McNab -- Include next version of Shiv's GACL editor. -- Add rpm-usr target to Makefile, to make RPMs - out-of-the-box compatible with RH9 and its Apache2 -- Use REMOTE_DOUBLE_REV for GACL hostname creds in - mod_gridsite.c/mod_gridsite_perm_handler() -* Sun Oct 26 2003 Andrew McNab -- Include GACL editor in real-gridsite-admin.cgi - from Shiv Kaushal -* Sun Oct 26 2003 Andrew McNab -- Reorganise into a single build tree, including - Apache 2.0 .h files to remove circular dependency. -* Sun Oct 26 2003 Andrew McNab -- ==== GridSite version 0.9.4 ==== -* Sun Oct 19 2003 Andrew McNab -- Include many pieces of GridSite code from 0.3.x (CGI) - fileGridSite and mod_gridsite 0.9.0 -* Sun Oct 19 2003 Andrew McNab -- ==== GridSite version 0.9.3 ==== diff --git a/org.gridsite.core/INSTALL b/org.gridsite.core/INSTALL deleted file mode 100644 index 4943047..0000000 --- a/org.gridsite.core/INSTALL +++ /dev/null @@ -1,37 +0,0 @@ -BUILDING/INSTALLING GRIDSITE -============================ - -For more detailed instructions, see the Installation and Build -pages in the GridSite Wiki http://www.gridsite.org/wiki/ - -GridSite is currently only supported on Linux, but should be -trivially portable to other Unix platforms where the GNU build -tools are available. - -When building from source, two routes are available: building -with Make or with RPM. - -BUILDING WITH MAKE -================== - -make -make install - -will build all components and install them all under the default -locations of /usr/local/[lib|bin|include|sbin] The default prefix -/usr/local is set by the prefix variable in the top level Makefile - -BUILDING WITH RPM -================= - -For RedHat Linux and derivatives, building with RPM is recommended. -The command - -make rpm - -will build the gridsite and htcp binary RPMs in the directory -../RPMTMP/RPMS/i386 relative to the working directory. A SRPM is -put into ../RPMTMP/SRPMS - -Building with RPM uses the default prefix /usr, although the -resulting RPMs are relocatable to other hierarchies. diff --git a/org.gridsite.core/LICENSE b/org.gridsite.core/LICENSE deleted file mode 100644 index befd74b..0000000 --- a/org.gridsite.core/LICENSE +++ /dev/null @@ -1,47 +0,0 @@ -Copyright (c) 2002-5, Andrew McNab and Shiv Kaushal, -University of Manchester. All rights reserved. - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the following -conditions are met: - - o Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - o Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - -Clearly marked portions of the published GridSite source code -are derived from Apache httpd or its modules, and are covered -by the Apache Software License: - -Copyright 2001-2005 The Apache Software Foundation - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/org.gridsite.core/README b/org.gridsite.core/README deleted file mode 100644 index df81f32..0000000 --- a/org.gridsite.core/README +++ /dev/null @@ -1,6 +0,0 @@ -See INSTALL for build and installation instructions, and the -man pages for reference information. - -The GridSite Wiki at http://www.gridsite.org/wiki/ has guides -( http://www.gridsite.org/wiki/Category:Guides ) and cookbook -examples ( http://www.gridsite.org/wiki/Category:Cookbooks ) diff --git a/org.gridsite.core/VERSION b/org.gridsite.core/VERSION deleted file mode 100644 index bbc3306..0000000 --- a/org.gridsite.core/VERSION +++ /dev/null @@ -1,5 +0,0 @@ -MAJOR_VERSION=1 -MINOR_VERSION=1.7 -PATCH_VERSION=1.7.21 -DEFVERSION=0x010721 -VERSION=$(PATCH_VERSION) diff --git a/org.gridsite.core/build.xml b/org.gridsite.core/build.xml deleted file mode 100644 index 0f47b59..0000000 --- a/org.gridsite.core/build.xml +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - Ant build file to build the Gridsite Core Component - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${global.prefix} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - New tag is ${cvs.label} - - - - - - - - - - - - - - - - - - New tag is ${cvs.label} - - - - - - - - - - - - - - - - - diff --git a/org.gridsite.core/doc/README.htcp-bin b/org.gridsite.core/doc/README.htcp-bin deleted file mode 100644 index ac546fc..0000000 --- a/org.gridsite.core/doc/README.htcp-bin +++ /dev/null @@ -1,13 +0,0 @@ -Binaries (and links) are in ./bin; man pages are in ./man/man1 - -Install by copying binaries/links onto your path, or by copying htcp -and making symbolic links to htcp from htls, htll, htrm and htmkdir. - -All the .1 man pages should be copied to a suitable ./man/man1 -directory on your man path. - -If you just want to install htcp in /usr/local, then unpacking this -tgz file in /usr/local should do the trick. (Delete this README when -you're finished!) - -For more about htcp see http://www.gridsite.org/ diff --git a/org.gridsite.core/doc/build-apache2.sh b/org.gridsite.core/doc/build-apache2.sh deleted file mode 100644 index 507be31..0000000 --- a/org.gridsite.core/doc/build-apache2.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2002-3, Andrew McNab, University of Manchester -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or -# without modification, are permitted provided that the following -# conditions are met: -# -# o Redistributions of source code must retain the above -# copyright notice, this list of conditions and the following -# disclaimer. -# o Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials -# provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -#--------------------------------------------------------------- -# For more information about GridSite: http://www.gridsite.org/ -#--------------------------------------------------------------- -# -# This script takes an Apache .tar.gz as the single command line argument, -# unpacks the file, modifies the httpd.spec it contains to work without -# the "-C" option to configure (which RedHat 7.3 doesnt like) and -# outputs source and binary RPMs in SRPMS and RPMS/i386 - -if [ "$1" = "" ] ; then - echo Must give a tar.gz file name - exit -fi - -export MYTOPDIR=`pwd` - -if [ -x /usr/bin/rpmbuild ] ; then - export RPMCMD=rpmbuild -else - export RPMCMD=rpm -fi - -echo "$1" | grep '\.tar\.gz$' >/dev/null 2>&1 -if [ $? = 0 ] ; then # a gzipped source tar ball - - rm -Rf $MYTOPDIR/BUILD $MYTOPDIR/BUILDROOT $MYTOPDIR/SOURCES - mkdir -p $MYTOPDIR/SOURCES $MYTOPDIR/SPECS $MYTOPDIR/BUILD \ - $MYTOPDIR/SRPMS $MYTOPDIR/RPMS/i386 $MYTOPDIR/BUILDROOT - - shortname=`echo $1 | sed 's:^.*/::' | sed 's:\.tar\.gz$::'` - - cp -f $1 SOURCES - - tar zxvf SOURCES/$shortname.tar.gz $shortname/httpd.spec - cp -f $shortname/httpd.spec SPECS - - sed -e 's/configure -C /configure /' \ - SPECS/httpd.spec >SPECS/httpd-2.spec - - $RPMCMD --define "_topdir $MYTOPDIR" \ - -ba --buildroot $MYTOPDIR/BUILDROOT SPECS/httpd-2.spec - - exit -fi - -echo I dont recognise the file type (must be .tar.gz) - -exit diff --git a/org.gridsite.core/doc/delegation-1.1.0.wsdl b/org.gridsite.core/doc/delegation-1.1.0.wsdl deleted file mode 100644 index df7e1f2..0000000 --- a/org.gridsite.core/doc/delegation-1.1.0.wsdl +++ /dev/null @@ -1,459 +0,0 @@ - - - - - - - - - - The cause of the delegation exception on the server side. - - - - - - - - - - New proxy certificate request, containing the certificate - request and a generated delegation ID. - - - - - - - The new RFC 3280 style proxy certificate request - in PEM format with Base64 encoding. - - - - - - - The ID associated with the new delegation session. - - - - - - - - - - - - The ID of the new delegation session, specified by the client. - The ID can be empty. - - - - - - - The new RFC 3280 style proxy certificate request - in PEM format with Base64 encoding. - - - - - - - - The ID of an already existing delegation session, - initiated by getProxyReq() or getNewProxyReq(). - - - - - RFC 3280 style proxy certificate, signed by the - client, in PEM format with Base64 encoding. - - - - - - - - - The ID of an already existing delegation session, - where the client wants to renew the delegated - credential. - - - - - - - The new RFC 3280 style proxy certificate request, - which is to replace the existing one, - in PEM format with Base64 encoding. - - - - - - - - - The server side generated ID of the new delegation - session and the new RFC 3280 style proxy certificate - request in PEM format with Base64 encoding. - - - - - - - - The ID of an already existing delegation session to be queried. - - - - - - - The date and time when the delegated credentials will expire. - - - - - - - - The ID of an already existing delegation session to be destroyed. - - - - - - - - - - - - Delegation interface. - - - - - - Starts the delegation procedure by asking for a certificate - signing request from the server. The server answers with a - certificate signing request which includes the public key - for the new delegated credentials. putProxy() has to be - called to finish the procedure. - - - - Check if a delegation ID was provided. If not, generate a delegation - id by hashing the client DN and client VOMS attributes. - - - Check if the delegation ID already exists in the - storage-area. If it does - (a credential renewal is happening), check - existing info (DN and VOMS attributes) against client info. - Throw exception if they do not match. - - - Create a new private/public key-pair (see also Key - Generation Semantics). - - - Generate a new proxy certificate request. - - - Store private key and cert request in - storage-cache-area, along with the - requesting DN and VOMS attributes. - - - - - - - - The client's DN and VOMS attributes do not match the stored ones, - i.e. the client is not authorized. - - - - - - - - Starts the delegation procedure by asking for a certificate - signing request from the server. The server answers with a - certificate signing request which includes the public key - for the new delegated credentials. putProxy() has to be - called to finish the procedure. - - - - Generate a delegation - ID by hashing the client DN and client VOMS attributes. - - - Check if the delegation ID already exists in the - storage-area. If it does, check - existing info (DN and VOMS attributes) against client info. - Throw exception if they do not match, because then this is - the rare case of hash collision, i.e. two different clients - are mapped to the same delegation ID. - - - Create a new private/public key-pair (see also Key - Generation Semantics). - - - Generate a new certificate request. - - - Store private key and cert request in - storage-cache-area, along with the - requesting DN and VOMS attributes. - - - - - - - - There were already credentials associated to the delegation ID. - - - - - - - - Finishes the delegation procedure by sending the signed - proxy certificate to the server. - - - - Check if a delegation ID was provided. If not, generate a - delegation id by hashing the client DN and client VOMS - attributes. - - - Check if the delegation ID already exists in the - storage-area. If it does, check - existing info (DN and VOMS attributes) against client info. - Throw exception if it does not match. - - - Check, if client information matches proxy information. - - - Check given proxy against private key of delegation ID in - storage-cache-area. If they do not - match, throw exception. - - - Store proxy in storage-area - and clean up the storage-cache-area. - - - - - - - - - There were no cached credentials associated to the delegation ID - (neither - getNewProxyReq() nor - - renewProxyReq() was called previously), - or the client's DN and VOMS attributes do not match the stored ones, - i.e. the client is not authorized. - - - - - - - - - Restarts the delegation procedure by asking for a certificate - signing request from the server for an already existing delegation ID. - The server answers with a certificate signing request which includes - the public key for new delegated credentials. putProxy() has to be - called to finish the procedure. - - - - Check if a delegation ID was provided. If not, generate a delegation - id by hashing the client DN and client VOMS attributes. - - - Check if the delegation ID already exists in the - storage-area. If it does - not, then throw an exception. - - - Check if the existing info (DN and VOMS attributes) against client info. - Throw exception if they do not match. - - - Create a new private/public key-pair (see also Key - Generation Semantics). - - - Generate a new certificate request. - - - Store private key and cert request in - storage-cache-area, along with the - requesting DN and VOMS attributes. - - - - - - - - There were no credentials associated to the delegation ID, or the - client's DN and VOMS attributes do not match the stored ones, i.e. - the client is not authorized. - - - - - - - Returns the termination (expiration) date and time of the credential, - associated with the given delegaion ID. If there was no delegation ID, - then generate one by hashing the client DN and client VOMS attributes. - - - - - - There were no credentials associated to the delegation ID, or the - client's DN and VOMS attributes do not match the stored ones, i.e. - the client is not authorized. - - - - - - - - Destroys the delegated credentials associated with the - given delegation ID immediately. If there was no delegation ID, - then generate one by hashing the client DN and client VOMS attributes. - - - - - - There were no credentials associated to the delegation ID, or the - client's DN and VOMS attributes do not match the stored ones, i.e. - the client is not authorized. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.gridsite.core/doc/doc_gridsite.pl b/org.gridsite.core/doc/doc_gridsite.pl deleted file mode 100755 index 38c79ab..0000000 --- a/org.gridsite.core/doc/doc_gridsite.pl +++ /dev/null @@ -1,1064 +0,0 @@ -#!/usr/bin/perl -use Switch; -use File::Copy; -use Getopt::Std; - - # ****************************** - # CMDline args - # ****************************** - - getopts('hv'); - -$usage = qq{ -$0 downloads the contents of the GridSite Wiki and uses that to produce EMI-style PDF documentation. - -usage: $0 [-h] [-v] - --h Print this help and exit --v Verbose output - -}; - if (defined $opt_h) {die $usage}; - - if (defined $opt_v) { - $qopt_devnull=""; - $qopt_q=""; - } - else { - $qopt_devnull=" > /dev/null 2> /dev/null"; - $qopt_q="-q"; - } - - - # ****************************** - # Init All - # ****************************** - - printf("Checking for required binaries..."); - check_req("rm", "mv", "mkdir", "grep", "egrep", "wget", "cat", "awk", "sed", "gnuhtml2latex", "pdflatex", "base64", "convert"); - - printf("\nSetting up..."); - $TMPDIR=$ENV{'TMPDIR'}; - if ($TMPDIR eq "") {$TMPDIR="/tmp";} - -# $WRKDIR="/tmp/gsdoc_2989"; # XXX: back to autodetect - $WRKDIR="$TMPDIR/gsdoc_$$"; - system("mkdir -p $WRKDIR"); - chdir($WRKDIR); - -# system("rm -f striphead_* striptail_* *.html *.tex *.cls *.pdf GridSite_all.* GridSite_UG.* GridSite_AG.* GridSite_DESC.* .* *.gif *.png"); - - # ****************************** - # Hard-code contents - # ****************************** - - # This is a set of arrays that define contents of various documents. - # Give names of individual wiki pages to include them into the doc - # 'all' will first include all the listed pages and then all unlisted - # ones - - %docs = ( - UG => [ qw/User_Guide/ ], - AG => [ qw/Build_and_Install_Guide Config_Guide Administration_Guide/ ], - DESC => [ qw/Module_Architecture Delegation_protocol/ ], - all => [ qw/ GridSite Module_Architecture / ] - ); - - %titles = ( - UG => 'GridSite -- User Guide', - AG => 'GridSite -- Administrator Guide', - DESC => 'GridSite -- Functional Description', - all => 'GridSite' - ); - - # ****************************** - # Get Content - # ****************************** - - printf("\nDownloading content..."); - system("wget --no-check-certificate $qopt_q -r -l 1 -nd -k -p -I wiki --no-parent https://www.gridsite.org/wiki/Special:Allpages"); - system("rm -f $WRKDIR/*:*"); - - - opendir(WRKD, $WRKDIR) || die("Cannot open directory $WRKDIR"); - @allfiles = readdir(WRKD); - closedir(WRKD); - - # ****************************** - # Prepare LaTeX structures - # ****************************** - - gen_emi_cls(); - gen_emi_logo(); - gen_wget(); - - # ****************************** - # Produce LaTeX chapters - # ****************************** - - printf("\nProcessing files..."); - - foreach $f (@allfiles) { - unless ( ($f eq ".") || ($f eq "..") ) { - #Get and prepend Title - $title=`egrep -a "class=.firstHeading.>" $f `; - $title=~s/<\/{0,1}h1.*?>//g; - chomp($title); - system("echo '

$title

' > $f.html"); - - # Strip front and tail matter - system("awk '!p;/-- end content --/{p=1}' $f | awk '/-- start content --/{p=1}p' >> $f.html"); - - # Remove Table of Contents, if present - $toc_present=`grep -E 'table.*toctitle' $f.html`; - unless ($toc_present eq "") { - system("awk '!p;/ $f.front.html"); - system("awk '/<.table>/{p=1}p' $f.html | tail -n +2 > $f.rear.html"); - - system("cat $f.front.html > $f.html"); - system("cat $f.rear.html >> $f.html"); - - system("rm $f.front.html $f.rear.html"); - } - - # Add false beginings and ends - system("echo '' >> $f.html"); - system("echo '' >> $f.html"); - - # Convert format, making sure that fake wget gets called first :-/ - # This is a workaround for an apparent bug in gnuhtml2latex v 0.4-1, - # which sticks option -nc between -O and the actual file name. - system("PATH=.:\$PATH gnuhtml2latex -a EMI -n -g $f.html $qopt_devnull"); - - # Strip LaTeX matter - system("mv $f.tex $f.latex"); - system("awk '!p;/end{document}/{p=1}' $f.latex | awk '/begin{document}/{p=1}p' | egrep -v 'end{document}' | egrep -v 'begin{document}' >> $f.tex"); - system("rm $f.latex"); - - # Custom fixes - system("sed -i 's/^\\\\par \\\\\\\\//' $f.tex"); #Remove empty paragraphs - system("sed -i 's/^\\[edit\\]//' $f.tex"); #Remove remaining [edit] clauses - system("sed -i 's/^Retrieved from.*//' $f.tex"); #Remove "retrieved from" remarks - system("sed -i 's/^Categories:.*//' $f.tex"); #Remove wiki categories - system("sed -i 's/\\\\par Categories:.*//' $f.tex"); #Remove wiki categories, take 2 - -# printf("\n$f ready"); - - } - } - - # ************************************* - # Convert unsupported graphics formats - # ************************************* - - printf("\nConverting unsupported graphic formats..."); - - @presentfiles = <*>; - - @extensions = ( "gif", "jpg", "jpeg", "tif", "tiff" ); - - $i = 0; - - foreach $img (@presentfiles) { - foreach $ext (@extensions) { - if ($img=~m/\.$ext$/i) { - move($img,"inclfile$i.$ext"); - system("convert inclfile$i.$ext inclfile$i.png"); - system("sed -i 's/$img/inclfile$i.png/' *.tex"); - $i++; - } - } - } - - # ****************************** - # Generate overall LaTeX files - # ****************************** - - printf ("\nGenerating LaTeX doc files..."); - - for $doc ( keys %docs ) { - - $texfilename = sprintf "GridSite_$doc.tex"; - - if (defined $opt_v) { printf "\n* $doc ($titles{$doc}): $texfilename"; } - - gen_LaTeX_files($texfilename); - - system("sed -i 's/XXTITLEXX/$titles{$doc}/' $texfilename"); - system("sed -i 's/XXAUTHORXX/CESNET/' $texfilename"); - system("sed -i 's/XXVERSIONXX/1.0.0-1/' $texfilename"); - system("sed -i 's/XXEMIVERSIONXX/1.x/' $texfilename"); - - foreach $chapter (@{ $docs{$doc} }) { - if (defined $opt_v) { printf "\n - $chapter"; } - # Add to final document - system("echo \"\\input{$chapter.tex}\" >> $texfilename"); - } - } - - - # Special treatment of 'all' - printf("\nAdding all unlisted to 'GridSite_all'..."); - foreach $f (@allfiles) { - unless ( ($f eq ".") || ($f eq "..") ) { - unless(grep $_ eq $f, @{ $docs{all} }) { - system("echo \"\\input{$f.tex}\" >> GridSite_all.tex"); - if (defined $opt_v) { printf("\n - $f"); } - } - } - } - - for $doc ( keys %docs ) { - - $texfilename = sprintf "GridSite_$doc.tex"; - system("echo '\\end{document}' >> $texfilename"); - } - - # ****************************** - # Build - # ****************************** - - printf("\nBuilding PDFs..."); - for $doc ( keys %docs ) { - $texfilename = sprintf "GridSite_$doc.tex"; - system("pdflatex $texfilename $qopt_devnull"); - system("pdflatex $texfilename $qopt_devnull"); #Twice for TOC, page and ref. numbers to regenerate correctly. - } - - # ****************************** - # Final Bows - # ****************************** - - - printf("\n\nOutput is in $WRKDIR\n"); - for $doc ( keys %docs ) { - $pdffilename = sprintf "GridSite_$doc.pdf"; - printf("$WRKDIR/$pdffilename\n"); - } - printf ("\n"); - - # ****************************** - # Subroutines - # ****************************** - - -sub check_req { - - my $fail=0; - - for($i=0;$i<=$#_;$i++){ - system("which $_[$i] > /dev/null"); - if ($? >> 8) { printf "\n$_[$i]... Not found"; $fail = 1; } - else { - if (defined $opt_v) { printf "\n$_[$i]... OK"; } - } - } - - if ($fail) {printf "\n\nSome required binaries were not found!\n"; die; } -} - - -sub gen_wget { - - open T,">wget.b64" or die "wget.b64: $!\n"; - - print T q{IyEvdXNyL2Jpbi9wZXJsCgokYXJncyA9IGpvaW4gIiAiLCBAQVJHVjsKCiRhcmdzPX5zLy1uYyAv -LzsKc3lzdGVtKCJYWFdHRVRYWCAtLW5vLWNoZWNrLWNlcnRpZmljYXRlICRhcmdzIik7Cg==}; - - close T; - system("base64 -d -i wget.b64 > wget"); - system("rm wget.b64"); - - $wgetpath=`which wget`; - chomp($wgetpath); - system("sed -i 's!XXWGETXX!$wgetpath!' ./wget"); - system ("chmod +x ./wget"); - -} - -sub gen_LaTeX_files { - -# printf "gen_LaTeX_files: $_[0]"; - - open T,">$_[0].b64" or die "$_[0].b64: $!\n"; - - print T q{XGRvY3VtZW50Y2xhc3NbXXtlbWl9Clx1c2VwYWNrYWdlW3V0Zjhde2lucHV0ZW5jfQpcdXNlcGFj -a2FnZVtwZGZ0ZXhde2dyYXBoaWN4fQpcdXNlcGFja2FnZVtde2NvbW1lbnR9CgpcdGl0bGV7WFhU -SVRMRVhYfQpcYXV0aG9ye1hYQVVUSE9SWFh9ClxEYXRle1x0b2RheX0KXERvY1ZlcnNpb257WFhW -RVJTSU9OWFh9ClxFTUlDb21wVmVyc2lvbntYWEVNSVZFUlNJT05YWH0KClxiZWdpbntkb2N1bWVu -dH0KClx0YWJsZW9mY29udGVudHMKClxuZXdwYWdlCgo=}; - - close T; - system("base64 -d -i $_[0].b64 > $_[0]"); - system("rm $_[0].b64"); - -} - -sub gen_emi_cls { - open T,">emi.cls.b64" or die "emi.cls.b64: $!\n"; - - print T q{CgpcTmVlZHNUZVhGb3JtYXR7TGFUZVgyZX0KXFByb3ZpZGVzQ2xhc3N7ZW1pfVsyMDExLzAzLzI0 -IEVNSSBMYVRlWCBDbGFzc10KXHR5cGVvdXR7RU1JIExhVGVYIGNsYXNzIC0tIDIwMTEvMDMvMjR9 -CgoKXERlY2xhcmVPcHRpb24qe1xQYXNzT3B0aW9uc1RvQ2xhc3N7XEN1cnJlbnRPcHRpb259e2Fy -dGljbGV9fQpcUHJvY2Vzc09wdGlvbnMKCgpcTG9hZENsYXNzWzExcHRde2FydGljbGV9CgpcUmVx -dWlyZVBhY2thZ2V7bGFzdHBhZ2V9ClxSZXF1aXJlUGFja2FnZXt0YWJ1bGFyeH0KXFJlcXVpcmVQ -YWNrYWdle3BzbGF0ZXh9ClxSZXF1aXJlUGFja2FnZXt0aW1lc30KXFJlcXVpcmVQYWNrYWdle3Zl -cmJhdGltfQpcUmVxdWlyZVBhY2thZ2V7Z2VvbWV0cnl9ClxSZXF1aXJlUGFja2FnZXt1cmx9Cgpc -dXNlcGFja2FnZVtoYW5nLGJmLHNtYWxsXXtjYXB0aW9ufQpcdXNlcGFja2FnZVtUMV17Zm9udGVu -Y30KXHVzZXBhY2thZ2Vbc2NhbGVkXXtoZWx2ZXR9ClxyZW5ld2NvbW1hbmQqXGZhbWlseWRlZmF1 -bHR7XHNmZGVmYXVsdH0KClxuZXdpZlxpZnBkZgpcaWZ4XHBkZm91dHB1dFx1bmRlZmluZWQKICAg -ICAgICBccGRmZmFsc2UKICAgICAgICAlIFx0eXBlb3V0e1BERiBfbm90XyBkZWZpbmVkfQpcZWxz -ZQogICAgICAgIFxwZGZvdXRwdXQ9MQogICAgICAgIFxwZGZ0cnVlCiAgICAgICAgJSBcdHlwZW91 -dHtQREYgX2lzXyBkZWZpbmVkfQpcZmkKClxpZnBkZgogICAgICAgIFx1c2VwYWNrYWdlW3BkZnRl -eCwKICAgICAgICAgICAgICAgIHBkZnBhZ2Vtb2RlPXtVc2VPdXRsaW5lc30sYm9va21hcmtzPXRy -dWUsYm9va21hcmtzb3Blbj10cnVlLAogICAgICAgICAgICAgICAgYm9va21hcmtzb3BlbmxldmVs -PTAsYm9va21hcmtzbnVtYmVyZWQ9dHJ1ZSwKICAgICAgICAgICAgICAgIGh5cGVydGV4bmFtZXM9 -ZmFsc2UsY29sb3JsaW5rcyxsaW5rY29sb3I9e2JsdWV9LAogICAgICAgICAgICAgICAgY2l0ZWNv -bG9yPXtibHVlfSx1cmxjb2xvcj17cmVkfSwKICAgICAgICAgICAgICAgIHBkZnN0YXJ0dmlldz17 -Rml0Vn1de2h5cGVycmVmfQpcZWxzZQogICAgICAgIFx1c2VwYWNrYWdlW2h5cGVydGV4XXtoeXBl -cnJlZn0KXGZpCiAgICAKXGlmcGRmCiAgICAgICAgXHVzZXBhY2thZ2VbcGRmdGV4XXtncmFwaGlj -eH0KICAgICAgICBccGRmY29tcHJlc3NsZXZlbCA5CiAgICAgICAgXHBkZmFkanVzdHNwYWNpbmcg -MQpcZWxzZQogICAgICAgIFx1c2VwYWNrYWdlW2R2aXBzXXtncmFwaGljeH0KXGZpCgpcdXNlcGFj -a2FnZXtjb2xvcn0KClxkZWZcZm9vdHNpemV7NW1tfQoKXGdlb21ldHJ5e2NlbnRlcmluZyxpbmNs -dWRlaGVhZGZvb3R9ClxnZW9tZXRyeXthNHBhcGVyLHRvcD0xNS41bW0saGVhZGhlaWdodD0yMG1t -LGhlYWRzZXA9NW1tLGZvb3Q9XGZvb3RzaXplLGZvb3Rza2lwPTEzLjNtbSxib3R0b209MTIuNW1t -fQpcZ2VvbWV0cnl7cmlnaHQ9MjVtbSxsZWZ0PTI1bW19CgoKCgoKCgoKXGRlZlxiaWJuYW1le1Jl -ZmVyZW5jZXN9Cgpcc2V0bGVuZ3Roe1xwYXJpbmRlbnR9ezBwdH0KXHNldGxlbmd0aHtccGFyc2tp -cH17MS40bW0gcGx1cyAwLjRtbSBtaW51cyAwLjJtbX0KClxkZWZcQGRlZmF1bHRmb290ZXJ7CiAg -XGRlZlxAb2RkZm9vdHtcdmJveCB0byBcZm9vdHNpemUgeyUKICAgIHtcY29sb3J7Ymx1ZX1caHJ1 -bGUgd2lkdGggXHRleHR3aWR0aCBoZWlnaHQgMXB0IGRlcHRoIDBwdH0lCiAgICBcdmZpbAogICAg -JVxzbWFsbFxoYm94IHRvIFx0ZXh0d2lkdGh7XElTVE51bWJlciUKICAgIFxzbWFsbFxoYm94IHRv -IFx0ZXh0d2lkdGh7JQogICAgICAgICAgICAgICAgJVxoZmlsCiAgICAgICAgICAgICAgICAlXGhi -b3h7XGNvbG9yYm94e3llbGxvd317XE1ha2VVcHBlcmNhc2V7XEBEaXNzZW1pbmF0aW9ufX19JQog -ICAgICAgICAgICAgICAgXGhmaWwKICAgICAgICAgICAgICAgIFxoYm94e1x0aGVwYWdlL1xwYWdl -cmVme0xhc3RQYWdlfX19JQogICAgfSUKICB9JQp9CgoKXGRlZlxwc0B0aXRsZXslCiAgXEBkZWZh -dWx0Zm9vdGVyCiAgXGRlZlxAb2RkaGVhZHtcaGJveCB0byBcdGV4dHdpZHRoe1xFTUlMb2dvfX0K -JSAgXGRlZlxAb2RkaGVhZHtcaGJveCB0byBcdGV4dHdpZHRoe1xFTUlMb2dvXGhmaWxcTGFyZ2VD -RVNORVRMb2dvfX0KfQoKXGRlZlxwc0BoZWFkaW5nc3slCiAgXEBkZWZhdWx0Zm9vdGVyCiAgXGRl -ZlxAb2RkaGVhZHtcdmJveCB0byBcaGVhZGhlaWdodHslCiAgICAgIFx2Ym94IHRvIDAuNzVcaGVh -ZGhlaWdodHslCiAgICAgICAgXGhib3ggdG8gXHRleHR3aWR0aHslCiAgICAgICAgICBcaGJveCB0 -byAwcHR7XEVNSUxvZ29caHNzfSUKICAgICAgICAgIFxoZmlsCgoKICAgICAgICAgXGhmaWwKClxo -Ym94IHRvIDBwdHtcaHNzXHZib3ggdG8gMC43NVxoZWFkaGVpZ2h0eyVcaHJ1bGUKXHNtYWxsClxw -YXJmaWxsc2tpcDBwdApcbGVmdHNraXAgMHB0IHBsdXMgMWZpbApccGFyc2tpcDBleApcdGV4dHNj -e1RpdGxlfToKXHBhcgpcdGV4dGJme1xAdGl0bGV9CgoKXHRleHRpdHtEYXRlfTogXHRleHRiZntc -QERhdGV9Clx2ZmlsCn19JQogICAgICAgIH0lCiAgICAgIH0lCiAgICAgIFx2ZmlsXHZza2lwIDIu -NW1tXHJlbGF4CiAgICAgIHtcY29sb3J7Ymx1ZX1caHJ1bGUgd2lkdGggXHRleHR3aWR0aCBoZWln -aHQgMXB0IGRlcHRoIDBwdH0lCiAgICB9JQogIH0lCn0KClxwYWdlc3R5bGV7aGVhZGluZ3N9Cgpc -c2V0bGVuZ3Roe1xjYXB0aW9ubWFyZ2lufXsxY219CgpcaWZwZGYKICAgICAgICBcRGVjbGFyZUdy -YXBoaWNzRXh0ZW5zaW9uc3suanBnLC5wZGYsLnBuZ30KICAgICAgICBccGRmY29tcHJlc3NsZXZl -bD05CglccGRmaW5mb3sgL1RpdGxlIChFTUkpIH0KXGVsc2UgICAKICAgICAgICBcRGVjbGFyZUdy -YXBoaWNzRXh0ZW5zaW9uc3suZXBzfQpcZmkKClxkZWZcZnJvbnRib3h3aWR0aHsxMWNtfSUKClxk -ZWZpbmVjb2xvcntNeVRlYWx9e3JnYn17MCwwLjQ2LDAuNDZ9ClxkZWZpbmVjb2xvcntibHVlfXty -Z2J9ezAuMDUsMC4yNiwwLjV9ClxkZWZpbmVjb2xvcntsaWdodGdyZXl9e2dyYXl9ezAuNjV9Cgpc -QXRCZWdpbkRvY3VtZW50ewpccGFnZXN0eWxle3RpdGxlfSUKXGhib3h7fSUgRm9yY2UgdG9wIG9m -IHBhZ2UKXHZmaWxsCntcY2VudGVyaW5nCiAgICAgICAgXGZvbnRzaXplezMwfXs1MH17XHRleHRi -ZntcdGV4dHNje1x0ZXh0Y29sb3J7Ymx1ZX17RXVyb3BlYW4gTWlkZGxld2FyZSBJbml0aWF0aXZl -fX19fVxcWzQwbW1dJQogICAgICAgICVcSHVnZXtcdGV4dGJme1x0ZXh0c2N7XHRleHRjb2xvcnti -bHVlfXtFdXJvcGVhbiBNaWRkbGV3YXJlIEluaXRpYXRpdmV9fX19XFxbMjBtbV0lCgogICAgICAg -IFxmb250c2l6ZXsyMn17Mjh9e1x0ZXh0YmZ7XHRleHRzY3tcQHRpdGxlfX19XFxbMm1tXSUKICAg -ICAgICAlXGlmeFxAU3VidGl0bGVcQGVtcHR5XGVsc2UKICAgICAgICAlICAgIFxub3JtYWxzaXpl -XHRleHRzZntcQFN1YnRpdGxlfVxcWzEwbW1dJQogICAgICAgICVcZmkKfQpcdmZpbGwKClxiZWdp -bntjZW50ZXJ9ClxoYm94IHRvIFx0ZXh0d2lkdGh7CiAgICAgCiAgICAgIFx2Ym94ewogICAgIAog -ICAgICB7XGNvbG9ye015VGVhbH1caHJ1bGUgd2lkdGggXGZyb250Ym94d2lkdGggaGVpZ2h0IDFt -bSBkZXB0aCAwcHR9ICAKICAgICAgCiAgICAgIFxoYm94IHRvIFxmcm9udGJveHdpZHRoe1xzZgog -ICAgICBcYmVnaW57dGFidWxhcnh9e1xmcm9udGJveHdpZHRofXtsPntccmFnZ2VkcmlnaHRcYXJy -YXliYWNrc2xhc2h9WH0gClxcIAogICAgICAgICAgICAgICAgRG9jdW1lbnQgdmVyc2lvbjogJiBc -dGV4dGJme1xARG9jVmVyc2lvbn1cXFszbW1dCiAgICAgICAgICAgICAgICBFTUkgQ29tcG9uZW50 -IFZlcnNpb246ICYgXHRleHRiZntcQEVNSUNvbXBWZXJzaW9ufVxcWzNtbV0KICAgICAgICAgICAg -ICAgIERhdGU6ICYgXHRleHRiZntcQERhdGV9XFxbM21tXQogICAgICAgICAgICAgICAgJURvY3Vt -ZW50IHN0YXR1czogJiBcdGV4dGJme1xARG9jU3RhdHVzfVxcWzNtbV0KICAgICAgICAgICAgICAg -IAogICAgICBcZW5ke3RhYnVsYXJ4fQogIAogICAgIH0KICAgICAKICAgICAgIHtcY29sb3J7TXlU -ZWFsfVxocnVsZSB3aWR0aCBcZnJvbnRib3h3aWR0aCBoZWlnaHQgMW1tIGRlcHRoIDBwdH0KICAg -ICAlfSVjZW50ZXJpbmcKICAgICB9Cgp9ClxlbmR7Y2VudGVyfQoKXHZmaWxsClxuZXdwYWdlICAl -IGVuZCBvZiB0aGUgZmlyc3QgcGFnZQpccGFnZXN0eWxle2hlYWRpbmdzfQpcc2V0Y291bnRlcnt0 -b2NkZXB0aH17M30KfSAlIEVuZCBvZiBBdEJlZ2lubmluZ0RvY3VtZW50CgoKXG5ld2NvbW1hbmR7 -XHNlY3Rpb25icmVha317XG5ld3BhZ2V9CgpccmVuZXdjb21tYW5kXHNlY3Rpb257XEBzdGFydHNl -Y3Rpb24ge3NlY3Rpb259ezF9e1x6QH0lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgey0zLjVleCBcQHBsdXMgLTFleCBcQG1pbnVzIC0uMmV4fSUKICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICB7Mi4zZXggXEBwbHVzLjJleH0lCiAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAge1xub3JtYWxmb250XExhcmdlXGJmc2VyaWVzXHNmZmFtaWx5XHNjc2hh -cGV9fQoKXHJlbmV3Y29tbWFuZFxzdWJzZWN0aW9ue1xAc3RhcnRzZWN0aW9ue3N1YnNlY3Rpb259 -ezJ9e1x6QH0lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7LTMuMjVleFxA -cGx1cyAtMWV4IFxAbWludXMgLS4yZXh9JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgezEuNWV4IFxAcGx1cyAuMmV4fSUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgIHtcbm9ybWFsZm9udFxsYXJnZVxiZnNlcmllc1xzZmZhbWlseVxzY3NoYXBlfX0KXHJl -bmV3Y29tbWFuZFxzdWJzdWJzZWN0aW9ue1xAc3RhcnRzZWN0aW9ue3N1YnN1YnNlY3Rpb259ezN9 -e1x6QH0lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7LTMuMjVleFxAcGx1 -cyAtMWV4IFxAbWludXMgLS4yZXh9JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgezEuNWV4IFxAcGx1cyAuMmV4fSUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgIHtcbm9ybWFsZm9udFxub3JtYWxzaXplXGJmc2VyaWVzXHNmZmFtaWx5XHNjc2hhcGV9fQoK -CgoKCgpcbmV3c2F2ZWJveHtcQEVNSUxvZ299ClxzYXZlYm94e1xARU1JTG9nb317XGluY2x1ZGVn -cmFwaGljc1toZWlnaHQ9MC45NVxoZWFkaGVpZ2h0XXtFTUlfTG9nb19zdGR9fQpcZGVmXEVNSUxv -Z297XHVzZWJveHtcQEVNSUxvZ299fQpcZGVmXFNtYWxsRU1JTG9nb3tcaW5jbHVkZWdyYXBoaWNz -W2hlaWdodD1caGVhZGhlaWdodF17RU1JX0xvZ29fc3RkfX0KJVxkZWZcTGFyZ2VDRVNORVRMb2dv -e1xpbmNsdWRlZ3JhcGhpY3NbaGVpZ2h0PVxoZWFkaGVpZ2h0XXtjZXNuZXR9fQoKCgogICAgICAg -IApcZGVmXERvY1ZlcnNpb24jMXtcZ2RlZlxARG9jVmVyc2lvbnsjMX19ClxnZGVmXEBEb2NWZXJz -aW9ue1xAbGF0ZXhAd2FybmluZ0Bub0BsaW5le05vIFxub2V4cGFuZFxEb2NWZXJzaW9uIGdpdmVu -ICUKICAgICAgICAoZS5nLiAwLjEuMil9fQoKXGRlZlxFTUlDb21wVmVyc2lvbiMxe1xnZGVmXEBF -TUlDb21wVmVyc2lvbnsjMX19ClxnZGVmXEBFTUlDb21wVmVyc2lvbntcQGxhdGV4QHdhcm5pbmdA -bm9AbGluZXtObyBcbm9leHBhbmRcRU1JQ29tcFZlcnNpb24gZ2l2ZW4gJQogICAgICAgIChlLmcu -IDEuMi4zKX19CgpcZGVmXERhdGUjMXtcZ2RlZlxARGF0ZXsjMX19ClxnZGVmXEBEYXRle1xAbGF0 -ZXhAd2FybmluZ0Bub0BsaW5le05vIFxub2V4cGFuZFxEYXRlIGdpdmVuICUKICAgICAgICAoZS5n -LiAwMS8wNC8yMDEwKX19CgoKCgoKClxsb25nXGRlZlxBYnN0cmFjdCMxe1xnZGVmXEBBYnN0cmFj -dHsjMX19ClxnZGVmXEBBYnN0cmFjdHtcQGxhdGV4QHdhcm5pbmdAbm9AbGluZXtObyBcbm9leHBh -bmRcQWJzdHJhY3QgZ2l2ZW59fQoKClx1cmxzdHlsZXtzZn0KXGlmcGRmCiAgXG5ld2NvbW1hbmR7 -XEVtYWlsfVsxXXtcaHJlZnttYWlsdG86IzF9ezx7IzF9Pn19CiAgXG5ld2NvbW1hbmR7XEhUVFB9 -WzFde1xocmVmeyMxfXtcdXJseyMxfX19ClxlbHNlCiAgXG5ld2NvbW1hbmR7XEVtYWlsfVsxXXtc -dGV4dHNmezx7IzF9Pn19CiAgXG5ld2NvbW1hbmR7XEhUVFB9WzFde1x1cmx7IzF9fQpcZmkKCgpc -ZGVmXEBwYXJ0WyMxXSMyeyUKICAgIFxpZm51bSBcY0BzZWNudW1kZXB0aCA+XG1AbmUKICAgICAg -XHJlZnN0ZXBjb3VudGVye3BhcnR9JQogICAgICBcYWRkY29udGVudHNsaW5le3RvY317cGFydH17 -XHRoZXBhcnRcaHNwYWNlezFlbX1cdXBwZXJjYXNleyMxfX0lCiAgICBcZWxzZQogICAgICBcYWRk -Y29udGVudHNsaW5le3RvY317cGFydH17XHVwcGVyY2FzZXsjMX19JQogICAgXGZpCiAgICB7XHBh -cmluZGVudCBcekAgXHJhZ2dlZHJpZ2h0CiAgICAgXGludGVybGluZXBlbmFsdHkgXEBNCiAgICAg -XG5vcm1hbGZvbnQKICAgICBcaWZudW0gXGNAc2VjbnVtZGVwdGggPlxtQG5lCiAgICAgICBcTGFy -Z2VcYmZzZXJpZXMgXHBhcnRuYW1lXG5vYnJlYWtzcGFjZVx0aGVwYXJ0CiAgICAgICBccGFyXG5v -YnJlYWsKICAgICBcZmkKICAgICBcaHVnZSBcYmZzZXJpZXMgIzIlCiAgICAgXG1hcmtib3Roe317 -fVxwYXJ9JQogICAgXG5vYnJlYWsKICAgIFx2c2tpcCAzZXgKICAgIFxAYWZ0ZXJoZWFkaW5nfQoK -XGRlZlxAc2VjdCMxIzIjMyM0IzUjNlsjN10jOHslCiAgXGlmbnVtICMyPlxjQHNlY251bWRlcHRo -CiAgICBcbGV0XEBzdnNlY1xAZW1wdHkKICBcZWxzZQogICAgXHJlZnN0ZXBjb3VudGVyeyMxfSUK -ICAgIFxwcm90ZWN0ZWRAZWRlZlxAc3ZzZWN7XEBzZWNjbnRmb3JtYXR7IzF9XHJlbGF4fSUKICBc -ZmkKICBcQHRlbXBza2lwYSAjNVxyZWxheAogIFxpZmRpbSBcQHRlbXBza2lwYT5cekAKICAgIFxi -ZWdpbmdyb3VwCiAgICAgICM2eyUKICAgICAgICBcQGhhbmdmcm9te1xoc2tpcCAjM1xyZWxheFxA -c3ZzZWN9JQogICAgICAgICAgXGludGVybGluZXBlbmFsdHkgXEBNICM4XEBAcGFyfSUKICAgIFxl -bmRncm91cAogICAgXGNzbmFtZSAjMW1hcmtcZW5kY3NuYW1le1x1cHBlcmNhc2V7Izd9fSUKICAg -IFxhZGRjb250ZW50c2xpbmV7dG9jfXsjMX17JQogICAgICBcaWZudW0gIzI+XGNAc2VjbnVtZGVw -dGggXGVsc2UKICAgICAgICBccHJvdGVjdFxudW1iZXJsaW5le1xjc25hbWUgdGhlIzFcZW5kY3Nu -YW1lfSUKICAgICAgXGZpCiAgICAgIFx0ZXhvcnBkZnN0cmluZ3tcdXBwZXJjYXNleyM3fX17Izd9 -fSUKICBcZWxzZQogICAgXGRlZlxAc3ZzZWNoZHslCiAgICAgICM2e1xoc2tpcCAjM1xyZWxheAog -ICAgICBcQHN2c2VjICM4fSUKICAgICAgXGNzbmFtZSAjMW1hcmtcZW5kY3NuYW1le1x1cHBlcmNh -c2V7Izd9fSUKICAgICAgXGFkZGNvbnRlbnRzbGluZXt0b2N9eyMxfXslCiAgICAgICAgXGlmbnVt -ICMyPlxjQHNlY251bWRlcHRoIFxlbHNlCiAgICAgICAgICBccHJvdGVjdFxudW1iZXJsaW5le1xj -c25hbWUgdGhlIzFcZW5kY3NuYW1lfSUKICAgICAgICBcZmkKICAgICAgICBcdGV4b3JwZGZzdHJp -bmd7XHVwcGVyY2FzZXsjN319eyM3fX19JQogIFxmaQogIFxAeHNlY3R7IzV9fQoKClxkZWZcbEBw -YXJ0e1xAZG90dGVkdG9jbGluZXsxfXs0ZW19ezIuMGVtfX0KXGRlZlxsQHN1YnNlY3Rpb257XEBk -b3R0ZWR0b2NsaW5lezJ9ezEuNWVtfXsyLjNlbX19ClxkZWZcbEBzdWJzdWJzZWN0aW9ue1xAZG90 -dGVkdG9jbGluZXszfXszLjhlbX17My4yZW19fQpcZGVmXGxAcGFyYWdyYXBoe1xAZG90dGVkdG9j -bGluZXs0fXs3LjBlbX17NC4xZW19fQpcZGVmXGxAc3VicGFyYWdyYXBoe1xAZG90dGVkdG9jbGlu -ZXs1fXsxMGVtfXs1ZW19fQoK}; - - close T; - - system("base64 -d -i emi.cls.b64 > emi.cls"); - system("rm emi.cls.b64"); - -} - -sub gen_emi_logo { - open T,">EMI_Logo_std.pdf.b64" or die "EMI_Logo_std.pdf.b64: $!\n"; - - print T q{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 -TY6W7LvXqoyBR7Lvx62v29i78f2XDqmTJfNp5t0B8IGYbYt8lBfTuX1xFoyOrOCvV7oBK/Qbde7I -Cv16pRuwyUgf/R35Smq6nf/RZ03mutdf8P//C2FSev5lbmRzdHJlYW0KZW5kb2JqCjcgMCBvYmoK -NTQ5MwplbmRvYmoKNSAwIG9iago8PC9UeXBlL1BhZ2UvTWVkaWFCb3ggWzAgMCAyNzIuMjkgMTE4 -LjM5XQovUGFyZW50IDMgMCBSCi9SZXNvdXJjZXM8PC9Qcm9jU2V0Wy9QREZdCi9Db2xvclNwYWNl -IDc5IDAgUgovRXh0R1N0YXRlIDgwIDAgUgovUGF0dGVybiA4MSAwIFIKL1NoYWRpbmcgODIgMCBS -Cj4+Ci9Db250ZW50cyA2IDAgUgo+PgplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL0tp -ZHMgWwo1IDAgUgpdIC9Db3VudCAxCj4+CmVuZG9iagoxIDAgb2JqCjw8L1R5cGUgL0NhdGFsb2cg -L1BhZ2VzIDMgMCBSCi9NZXRhZGF0YSA4MyAwIFIKPj4KZW5kb2JqCjggMCBvYmoKPDwvVHlwZS9F -eHRHU3RhdGUKL09QTSAxPj5lbmRvYmoKOSAwIG9iagpbL1BhdHRlcm5dCmVuZG9iagoxNSAwIG9i -ago8PC9UeXBlL0V4dEdTdGF0ZQovU0EgdHJ1ZT4+ZW5kb2JqCjQgMCBvYmoKPDwvRmlsdGVyL0Zs -YXRlRGVjb2RlCi9UeXBlL01ldGFkYXRhCi9TdWJ0eXBlL1hNTC9MZW5ndGggMTU3ODc+PnN0cmVh -bQp4nJy819LrSpI1dj9PceL8EbqBpuFda7r/AAkQhnCEIcwdLOE9QACvpgs9kl5BxY/79HT335oJ -iRHk3psoJMpkrlwrq7j/43/uQ5TU2fJbnL3K7i+//9//5//1+29l+pffPVJDtOGaFaV0Tpl96k5y -1gmb/v4///pv/7H/eW+HNlui3/a26eY/73/5PUr7OPsz+Pvna/j3336aLPVffuc+F37zNfO3az9l -vxF/wv6E/XuCUPhvJP4nnERpnPzff8MQhIERGsawf0eZP6Pon1Hst1+v3//6b+DzP6Y0/7PF3349 -EPzrL78XyzL8GYbf7/ef3vif+ukFoyzLwgj2MQNa/Pt8dEu0/3s3/4+vkT/s8NmcTOWwlH332+ff -Udyvy19+//3ffvu71/dBafK35wzr1Pw8JU3grMnarFtmGP0TCv/N+Md+mvw576c2Wv4aDUNTJtHn -KfDQz8v3mf8B/2eLP/oE/1On/v92Fsz433rbzX/6WZI/JX0L79EAeorA/y83iXL7+q9vfMFl+/rH -gYL7/nydsmjpJ6fvm79+11lumnVeps+3v11t4j/gf272ryxkPHj/FUNQ9N8R/N8x0kEp4AMQgv4Z -Qf7OwrfZPxnQ+rTMj//WwN81+2cDwF/TaIn+exN/3/CfjDjF2sZdVDbzX/9hin9WkGuWf/z2jwtN -+bOiQzTNmXMM2V9+t7K5X6ck+/1/ueHXkz5L9ed3mS7FXzGS+unY3331X91UZOWrWP6Koth/3vXr -u//qtl+uqpiC+J/3/aP//sv7yjZ6ZX+F2QomOO5h16FivbgL9xI4m7vIHMfD9IObXbHYUpE9I5F9 -y7y2ahxHPOpG5yCE+3ldOND+8xK4/+1/7Nz/wT0+N4PXg7vAEMHx9a2OMaXhROd7Qw7HnAwuvh7C -hXOFy8u9XV61eHkEyvX9Ei+vl8pz/f367u8/BvkLp/Hc+/N+8BxhChxj8BfNuV0ejrC/Y3GfE2ln -8r+934J0eSc6zyEBeEIgFq51s/qfaz8G/6Hx/8c3zICBPl5cAobLvQXrO2ROtriHZoGhCVz0M3qJ -+4zuIXD/+XrcuLcsgmmRrlwNhgeuvWT+n9v9mkPuCkYL5iWRr49eBZev4AE893pcwXdgRoChTgOL -pVlg/m+yJe+PpyAKmFAmgeBqg1hcdm9/lOblx6C7SIW2hyVztY7XJjSP03Lq8X4EuHnV3UdXU8ap -F6kbSg6PrLKs9JpyLV5hoYCpG23kuejP+2U6CNgUfgyihoOEvndrIg/dU79hvRArhqhd5tgjtwC3 -0LRLicwf6FxCoRw3hCKIpFJu7yVx6FUPXWvSfjZDFrThj8Ex7hQs68h7Ndy9dqDKYRzXeYqorbfA -/ILhy/zlAdzlEQhX4BDxZ84Kgb9cBVtzhZtr6YX8CvdXKBw/BvtYet80ySJs/Xp7KmWyCafCW/yr -iGz38MqAVq8X3LT1TBFee+rW79fPkJUqvIllWqc3F2dG43wfr+HHIAKZZ6HY9aI5LmlaTRp4zyH2 -b2jmo1YTtmkfecMUi+gaY//d8H8MQnyjeF5DlmE7rEkXUnk9GvUQRd14b8eROpZphDY4Ao7GfzxC -+LgYz3BkxScdUuNwKFEz1cqVrxA/BlvQDfwOUydN3nv2UBu8wdEO30czWQ76OKYDhzy8o08lKOH3 -RUJKO9sV2SZToheSVy0hp8bkGvcqR/THoBhgzjMIxOpkz4ZYbl2r3lAapO/39SnC7QaMeG7OcPYz -ytnnPMFmkL9FHHJSC7rScGNt5AS/+WcjwfaPwW+7/MQk5pKTOioR6gb9mGI4FphilecAjP7rJjAa -WjDSeB38jCWG/TFYwJz/fdwRM69URU0LPj3Ut1OnZK/QoqutRxTkHb5VZjSb5WMesHhOdjY1NCbQ -MvZYTy0hwsFqzh+DE+uAWHBXNpCgLL7lx4Tur8i9LTB6e5M15UBsSYC+cGrrkBI0QxBwlIwkDTIl -UzZkmajC1WRl1hvy/jEoy8GrSoRYkMSefXugGSAmdg4lr01vX3OzjKfkp7qIiynl3/k8DQ9RZbO6 -yTkhnBjoVamZsafDsCLkj8E31lEFO+H04UPhVsNnITm2+r4ybjKkxsrJU3MhmKstSZBbBBkUdeqr -4egCbyX3ffBI03hPneZhjt+gH4MRXuNHVimjjlNQf+0kR/UrJYkRmVRdVbyLiy9P2NRg6uWeKzuD -DUVFdvmaBVAAG3m3nXww5RGeK5D/YxBvrsGzvKjLqGMDh5WVX5kKPD+tSN8OMXS1BOQfw/Axg68P -UilJ6U3kkd9sre9vioNRmNRMVij3yE36ok3lKqS/hY63qUiPe1jFmLO+EJIG314t4L0MR+H6qAW3 -gIAFbO/928Vew8aiO271Mw+ezK0CqxSDiPgxyL7yGiFzZl4uQTtoKgucuNKgBB83MK1btiA+e0q4 -hhzF0e1gnpVCIl9QQPWDSVnrWL9ymo2NCmmy2zen4KZMEdI+ZGzl37nU9emitWZisWnETyg/95Yh -xptzYOrbkDLbuOzq9bAO5p5sTvji0Ds7F5LCtcVz+TFYz4Ytzxjn92YjMcWmbW38UB1f9UiEuiIb -t5cAxqCeqxYxe3jyhDozFmS+/y7kncicjsgO8iyVxNe1H4OpBZP7yGBYOpipmlGh3GwiMnFtaD9K -pnLYAy/qC9Zw8Hup10N73Rgf39TUQA4I1QcBoR0yRomgMrXvHG5XZFKEgQuxbz4bk5MMZYtE1DTk -eeC/fDhcAarWoh5VQfmiSE1UAsGWMmx4qVzWriRzqUPUCh/fJEUUa7XJeCM9c30d4B561+VC9LK3 -xhS0isTDYzfJ6RQZf90BAgWjVZIaUYi4sUcBqbhiIDFjrmLTG/8mKbOeziKGAj1chOjJqhleL1Jr -cfa+YGnLLzQfw9x17sWpNqfqkbwoUSgoxfNbc6pjKYAup050HCGt2zf0dijZtLyhD5yUkMnSHy1y -oLndD4O3+NHdOmY3kq+UoO/uE5OqDTuflC+J7iA+Flycj7MQ5TLCYmaBv3NIQzm0RnocjaaesBWf -yfMs6OioE4ojErxMX/WQ22RxuUaQLIpZfOX9ayUNrCX7O9Lm8L3fTgimOuC/X4Ot0eesy1RQ8Ibf -3N5BT1RiYBoHDf7WFl4DqoBRZ4e1ICdLuAG+YTLcluUwp7zwjpwza/Ff36y3gdVoSNNMPAq3zQhH -seMipgQloaajR3u3tFYhqrIq+AJ6OYPKql0A+VAS6c622LAGu/QBrYq60t8hI204xGWI1XVSEsvj -emq2M2sT+uZenMEutKEYj5qhcgeKFtzhzJPWzaNFCeiK4bDr86015PTbUCcLor6RAunwJG0tS3Tt -esHRCt+JhpByz8yl0n891Wfc0mswRWiZEWvYXh9v6+6neBzcx8mtu7fIndytqTVL+eZl5Ry7xj8n -MqvKjbWRFkIwzdh6PKnd+uE96PGiPBIfw/AJEKl3twRqlOp1sVk8Wh1sCnfLJDXBNBlL92PwQMmw -4LL8vIwP4YYFzt6PJqOd6PT0TKlByG5oefNtqUFi0Ws1z+F5VFT13mloEuLq3EmV6Vckr7PT+JKl -6BjgLItY72G88xXtotnQMmKcVsN3xdXnb0aOtgV+2c+2qOB1TzZyD25ju1LdiLJKTnXpgS+06qDq -j8EyPeiaD64Dzc/G61RfF8HlCO9xtHEdPzYwp0cuoAy/gYmudvVtQHMGmcIGVIB5OHp+zMwm7a8c -rplfOUVyYbxgaQSq4bWHyBZyjQekmsbaOdEExd4WxbwZY+cZdckLv5Fas13EvlFCUlGuQFUQcddz -ztLS+5cfZpJgJgzZvdssejD44pM5yKLHk5n23X/C5AupvDS6XVE08dM56DEKeLlNAsJx6s8tSbW3 -hsWq2T+k8Os2uUMkuSvMEUweCXNAPusupvpGOpd2XLGs10pTvcwIetG7dyqCRU0UPw8giXZl6Wmn -BsxYxFK4PsmT+RJOzyRDSopwbI1ANkySpG8Wkh6vhmWH5NWwtXcQi2uA9YVMXqNks0O5uglCUUNr -lucy0pZRIUlkiSxftJGWobFuW5zU9V6DKYHWp7UfW+1RmXeTErM74U6c/FRCtnPIT2rKPbbgsNa2 -BjW1h2uRAOcsxfr+ar+xrAztgaKtPKBmOAhhC5EUSdKIw9S5Ibh1Q05ZjbXjzFPZ6KFkNGhiz5ku -ZFZ3fa3YtRADT1Wa4lgw8TuHt+LgkxI/HXJi1u4gpxy96fbMeosXN7HPFqakS3KTY43VanG1TvnD -1hls1mBJaqxUrRH8onZBqENffhhj2Bwp5Jupp3QIqI0sZsJEfFPGL6GiPrFwSroJYshXnM/MUrVK -p4va+kpo57rfTc9O8qaAXLjzj/MXWXoxZxYFRS8WFOcDZg41bSkHd6AJByo2PJ6hBPZ6r+jn5XVG -pdYj+uF5HYL0NjHEnClvmje9o4Z8oc5XSU2Z9nj4C24m73cVyDUyGeMrJ+WoDTW9fxlSfTuUbAQY -aFgOE0uHSlP3DuYuoqn5dkd1GvraCvYw4G8Pj31VAlj3Ss9e3zPBGqTlAQ4azWHn1ioyPsqKuryQ -HKwayzykukgFkMhz5gTKaCnG2ZgwLTF6DwFU+UvaqYNpvEizOd2Knlys2OjrMrZaepFfIgIynn5t -oNiEJnSAYe7MGYQwz55ufaY7aGyHzzIkF8nxaC6nvwZjuO0khjHInDQafGZgZWIqNmXKLFI7T4Xd -OKKLbg5VK+gvssib+k05TI1zByEZTurl3FxSbJFhP9YvP5zXoGo380OCeYfpc01hbssG9aukLiAR -eZKE5izm7w6Fby1BdBZAHo9lMiW7vFtFv6wOIv6gT/tV9FASmAeMqk41+q3jsWqzKGRP9KncrE9C -CzpS1ygZ36uGuYnyzUJoclr8hhg5ddH5lxbXDxaWL5g84fiXHy7MuwvMFkzOdowwCDVlLNYJ83C0 -RR8rOkReQr3f77sdXYIBtqB7Rz89hV7avDgDolrTcNTNpk1ZvPoxuM6QnRtYOfqo/6Cps7wQ0KLG -x9XYXso94VkorBPEOdTX8bYlIL7Dkn+wFgpg901I2UITjP3HJHzx8HLDjZbaImx+4gn23C+Rk+P6 -rgiUtcHj+r52lFZqL/Op7EIqYQNk7RP0lJo3pK84rKAMauTUQZ/grh+DQXg2agYF25nBcuf3cXfq -JAbbzzGW0HCCOWNEatZ/0cxqOpWf72cQ6PZdiNLnqIuxRtv+gcJn5ZPrVzzCD91EVwy13+XCWi+b -LKtaw/Vn7dccLmrlhpCGN3O6+y56XuYw0cjbEHK9LW/gCNPPMaUj3PbpTRK/SSo4nu7+Epg1UmC9 -aVW3DKMZqw0tboxNAdyFr1ASMNzMU9WTD6MmeHsLI2mJu7fsI+tkxCITN0hdJim+/PBZKmN7Sr1z -17GW3QFhIkYoDQJFadHcKWd7JjmNje53mKYPk0TSU2Y7m34zDKzGzLY8GTg6k+g5LF/xeImA9pzj -AQeALozTID2SW4JOsrYd5M55BAToqxzxSA73gCRx9EcbEwhOkzDDjU0jkUR61vCRqtv18QXYBoUs -Y4MS9iYuWAZo5sI1B7sGQyH7080eoJutU6SqjoWAOjzfn5of7zRa8q5YAH8+0tm40Qt81mbyY/Ds -jgv03COrZX1HyrxBIXXWn88j3g3yFN/5UznYh1pJeD5mQja1z91Q3lsMQrX2hjB7bLnlwkQltfq3 -KnKeLN1EdWyxhwpIebJJBJQuIkyHPUyaR6Df07LzriSPmz3NbCbkcswMhhvf5xzqQ+1NAlJn7LBt -Jt+6DS/PeDDSNz8YGRrk5hugfymzS7D8CyESCS161ERujBOlYVSNTxzk9DQ68Aa/Z9pz4yrb1hzs -Ol5/DDrtoY2pK3vsA0x8J8FAzd5Sj6GpIcpckJ6mY5OedAMXqmsLmlli0OEBqFOOmnolPb0QyE4e -5lUgCvjHoDYxrQlQBGiAu3Pyk5tm4hYNzP1ODHum2H0AQFYbrQ6+H5cCMDHxhV0TObdVE7hm1ICV -J295O2XUeftF56g1fjw0r5jj9GZjXAzGHvLZaPLodZdipbpw1zE6u9ZJx88IOplmdlMXa33Q5mYb -lk7rBvw1C5n+Y5Bs9Pt4rkx1H4ZVkMf7CxUxTROCFjlRgby2QuSTGINRtp1q6AjNIxzdtuTYX7B2 -f1+O915mQWTdH+TtS9q9JmfIS96iw5wPewQrpuQt6miIhAlzXDJqYEXf2MMQL5Ten6f0BCt61r45 -CuVCDkxH3abG2ts2w9gvgyWS9A6N+HRxmOaQXs9D4dX9yEfuLi+w4X9iOR+ZWBnxGoIQm0iqygx8 -/rz3pgvfFPECH3dDDy+HPmXfMgtDIKwE38+PjyU5CC3uvUcd6aNR7MXU7p7TsBAH84RDoXjVrzJd -L0HMclGGPUOttUc1L9/ENMeb911lkxEEuPZPXjJFwMgRigp6glefgRc6D+jCyadUsI+kk007T+qc -vIkbaWdeBR68gqTKAYTtWmiedfOXNHuIKenimgobLwS+T6cBGjV7DXvavOeuOJns5Qlu7ln4eDNT -zs4YBpN6Jams5fMsx57HR56d17jqv7KiAXG06Tt8xI7K3tODgObby3yAUM0qkMxzdYAPtYNHtT06 -kw3jRWe5EB9zWNJXgDwVr8C7QHoiARL/t/YFcv8dVk94xJfBBZzlJrzDluqh2tiQgLXYkzrPS1oy -NWAgBWD9aG3C0fFjDHTBYp0q8imzhFTxm5eJimHOOBEu9AYigrzpDrNtQLrQoQMDYqmHYUVkYApP -HtlZnOpesKnS0T0jwdQY9unOsCzBsejApfZdZZfIti2eCUxaLR82gthlaJANsM+Ez0H9jhJaW2zz -yUg9XAOfJA8NvueOeTfKKM6i4d7goXebYvx6/SapVeTqsnhKnGwXkJKMTVHbHiZmMneNwbAe50Ya -H5TGWpiy1AosQH+YryOEWxkM+1p0+ZGCP6dFh5GvkvIl4LxWRQgNrFlZj6H7LcGQ53nNXO1QFRG9 -3kdi5B/QfgzrdSinswPxnCCwsp1gpNzV+5G5zSp9dcoLoSrqyigM4HykhHn1244c6IkVHt5AO3Tz -UIUIzsQuzLlDKK0r78ftyAMSICF96KuRoLF1M8UlZN5fg+iUUig73VhzvBHQ6eBCZZuPmHsG7Usq -mneftCDJI/z5xsouYWLvX33UBDNB7vbFQ7id3CfyyffNRtcIedVy7qUMR52OcgnRAs+FrwQpL0pv -JvndeMENCdlQP0x4C/vFaHZX3EILRLWrbw+3vn06IlErxGt5g5XFA5ejL0vVCIPdzYaTX7UknLu0 -Wfu8S9Mshg8A5xEdeByy2u+7p9mmrBzIE0G+WS+eo/HFJ6GHDfWlGh98kAwNB4isnOdMv6kmgL0c -cibSb6B+ATPPnfgdQwufRGHI7hkEdEID4cKr2rfCiV6mM3/4R9oPIEWJsHXroAI0EjpKYW/maKI+ -hVNSj0A8AklvJkrvYdO9tqy7SJKHwlGNd812+rcl+qINgcM2/L745MI6sL1NTJZeDhbwJ9ZYtEbY -KblWUhDnxwGEHvx4TnDRwYJJ8T2OmlTBRtDkksvJmgj81XoQfkzO5ssHoeKDlhnLNGiDA0D5pBxo -NHV/SByqUyl6BwRk8hfnQpmKSZ9Qw058rvBZfo4uiKDXxMpfOjeoiMMGsOWP0EJJSsRsFqQWJwGh -UWhY0rMQpP60N9hw8IL88MUOl/MVVjqIgYc8YgkAGp7aMZP5JZxNllPWuj6zJX9NrdlBw5HqrEos -gVTnXRsQQe5mQ+Z8FAGIEdU8njcyQ0dkSX1mxV7LtO6rOFJoWX7pHNCvopfm5fJyx23n2Hlf1Vcd -U6vzZhLLwnkxh0A6/sQzmrEaTGUmNGY2k8iwCqL4bMLApnKTvM/KV97yh5e14gX3NmER3Ef9pOOA -4NM5fdz7zAGsbB9hAkccGNB+thJaoyO1xWL9d8Yhhr8aVLE/Zw4V7xvyVQHMCjM9PHSwplwA1Lfo -6dvkelaHw3MNeX4wUojhGiUrIGZigNzFcfLsI0pg5Eb4AP5Nw+jqFurx5qtGmT1V166O2TPC3dm8 -A5G78fJ526DM86F71kfmVbIftvoEWcHLz2gmxdsQAZFvcU8vQtcA5XlMgPsF+g5ZCPveEP3kfbof -oNYm51ZnLDNTjXS7savrIdVe4WQvet3mK2VgPiftalTiMNn0K67MK+Nk/Pg0iUqZv6HnjtLNX0Fu -zBni8KWWPmCeLFDcDXVtVjdiErHC8tu6usis1QbIQ6iItHJjOn72B1BRl20nMtkbsnT7pfWeprG2 -0R57cFMUU1OkzIbTjZoS1+Vq6WdcPF7w9WnALy0gX9Y6z8IrXRAzzZsTenZkuhwMFB255n0NWnR1 -oD0pV8/CK3H9nakf1mQWQfpK5Ob+GeVenXq38tKmdSSRhTT2zq1cTQSpMQ8sKlIdWSyBnh7TlyxF -BCfUlbaeXaDjoi1qybm6kpw9MP5sSlrzAjSg6y6pyQDd/Pz+fAdgeWLYFDIcqoFusWgIqd0Wh7/M -IXzK2az3Zm9uIJeRfA7ZBTPnzBuAj7G1OgCt9VlAtcYeyxI4UNrB9QDrEvyDWQqxjbzfQvUIEpX7 -rSzB9ZTfQU4WT+BmNaYlHXpLfKQgFfhsAfvSEukj5m6fZHaNfTU10Sh1kKyAGYICkBgyC4gi0SDg -L2KX5AwA0fXwC6AY7D9TDE4vSLOm4Y4/NoY7ZskzIexTJUYBv2iiqiayFpoIc5o06/wCbAWg5ywP -WGUWZXdoccQj2KQvcNVgOdVJCI5s1aWBZNjUqI67OKoFAAJI/zZNRWRlUKXG09i4esnEfAHWeY7B -9WHEMgcC6NOLEWZOgCzjUw/BvNRXCqYGwjDMTIDEjICV+xIwSxYsQltU6Oaom6MoL6+wmdeXEr9C -9NLbff2MXhkmCFK911cjyFCQpYty62ILGF9a+IMLbhTXpDh8hsjfkMltXW0ZtKc8XmVclk3kW+Gs -DTPOKRl14KbqYPK2wc4tTnQZtTeISWCwEGoOtQBLPGYbD4ofxvk6qdGbe9GCYE3t3JzpJNUVc/W/ -/NCEASzDYLTap/xUfVbsgyj4H4jCqElyUmkemcjpsxkyhuGioXdqDmvoVGLHtjSzduVdi90vOKyO -loIZ3xg8vY+yqaW7MQzPeA/oaaDPkeYpvgnfu2nNYvSg5vcM5rm7w+eIrs00tRUFJOu2UNtomV+D -Z4X3p4XCmPgwOsnqoLBB+4EO8o6G7LZPahQwXDVDn8XM3JYQz0jGPryTJyu5483ee5wPas9AmCjp -l3C2T8jf2nYv5+3OkmKHGopcIwPKXoGI17P7ODt59Hze7oPL3xWC5FtSNBXRe2cxWDcZ7vTL4NUq -GTLT17GXHT2IBsblE4tfS/xWXF0Mb9Au0wjmMi8uQqYtfu3+6k1mMwU3ptWPsDyFplrt9HBa3ykw -uqrsz8ePQRtjLSTIuk+tgcoC7wJvbL4E7YURCp4OXYva6RaREAnfRokpYFixMg8wi/YGlNY1zbUP -0U5AVuDCb3WuiaP3xFCgoZtFwOfaSw0XTatSLzTcenUHyeWTV5zMg1W8kSyW74AHtS2CIeUyKHUm -309rvCmcMn1rDsgBeZ2irybvvrhrK+ZdB6VZnQPFjzXeUgzoHuoDg8zTYhyaKJTF47JDnrMH1a1o -zuSptbAKNKoSH989evLBlNSTTNZFWuk2d9DmSRJdddWp+jzKV4BiPHJozKWOw4B9yPvYWngORCDe -RBnaFuILf2uj9lIyNa5/DF5NSa4caQu7J79mOlxXUNh2eUOSzbZ422REbLlO+vQMiOsIfNEznDrz -I/AOk1y4R5rnFPoWATawmz8G78BR0UCl4TrkYf9uHjuNy7DOr87Ht3YnAfPadImhv4BmdTgJt2VS -cnP3+MGheloT7GYsC6tn2deguS5w00HPnMw9sxEemBMtYe7FbUigTVzPGpDtHKzkeN0cdro1jmYI -F8NazpDkr0JEbcYGFe12vmDqWzKtJdhWYphBwhTygH5sQ5aWzU94iXS3bYzgL+8HuifUk0JOjuM2 -5R1Wj1Q/a90wYtPtGrpx4E7jnszXbSL1q5raXKmGzHJGeJTW3DbJDDDiC/nBRMwJYPZxhMUJ8ktY -QXVG1qIVrvsTu4MPwI3fHMnDv+Rt3ZlaDg0f1fQjX3jq/aNcIHE1YqPzvD/C4O8/2BKQwvC1ILBm -M6hB5gihK8j4dZuVlMwg6QkMJp5HsrMOqxvWsI3byh82vIbxAa/x4TZD3D5JP2Dtc/YUEyczjmBH -SeL/7kE/BkHkzT23fWoL4SigKc4gVm/BoxcBfJTx4wXj3Tsu4BQmASzCcgcfbt6Aa0rhgKF2/smf -uecb7/zxha8sdLH5DhsTfDzN9mfzNDTRCogE9DJ+9EGbg3XrRJpZ2ISpKWm6MQvNJuj1KFa1Qkjo -zpACr++S8BWPou+ch1CKnTQQraxeTCgpzOPF9NmD1ZCMQASfq7dhCEh4EkBWL8u75RDPAT3wS62V -cbRYpXAfmo60v1mPIVi4ockBiHqLzVArBuIhm7QQtjtC8YzM1ly/jPLr69jUthEtLiRmIbQu6l3F -4e4GyLocG9kT8Mnkl5Jal7h2x7Gu2ErmXTvmh37jzYOD1e2gSZJBfaihKKWKwNqip0TxUIuPqi62 -JJDCCt86gNmXb2K9cu0vP8Q7uH86zLiRwL85yrbg02pVKKjJnPRU8ORn/TQPdHX98Il6FCfNQvmm -OqqOfCovIS9Xujo/L+TxVfSHCSBugb3Vu9RNHTBB378eYt3EbGO5GWn8nFM4BStM0+oVii+WgvXz -UDMo3hS/iQ5miqoBW324pr8cGy9Q+5jjQRlaOPWYMLrd8KhYMEwXjTenYKfwPoVQZKfk1LmjNKS8 -yHXp2u5iyBp8jJ0ACoXnvMk+HP8YvP3UM4K2hctkcpkeIm8wQ2bXD2nYICwyIYdpeZtHGmM2P1Fp -4Z+o5O4cyAQQ9gzANLlaG2QO9c0pNP6rgMrL2j/WTmGmpsnPWS8bg6mSSFYE/D2IdIe95Dwu6ZMz -Tum+D/EziO9kW7bfRSnLyDYw1zSoVy1PGnBRpzccgB3O6z76f4ssNoaVuBjwemMAnQZIkEFV5RA7 -seUN4sKPQ231LxW5HaWpH5oyahVpKoYR6oDsrIauRpMZ4Ppa86eliw3wF+QSuOTOYE69LYdVsCIX -j0OS6GqMPs3Xp8L8pcTD7WcHPOJgVgz0HLqd4sTSjCRvLAp35uAz5QYrNuRtUBBuH21fhPCkdlEO -xP12b0nyhFKpdQ76GymcNlLMScVQE5usnD8VGR5ztFTRNcPfUHeQT3YM06LMZF3MAsJW/bwJyTcz -eMBvIW/KSHR9v1Z5MZZvLDdFvfZu6gnB5dmEr4dVNa9MptWik14iEEFwp/L+ckV9a1OpCAidKTdv -idNacRQZwXgtX7dXpYNsrwhfRd/iEpq8H3fVgA+JQaHnJDHDwi0q7qkiuvb1arqvdg0C8jal9mzY -81sGxP8+M87ehSvCECWHh8todvm33OdhHW5PE9Q21U3mLulbqEGOaEhXltbYqStfM4EW6G7xM70j -23mONTT49a26Qq1RHrhWWndP36+ZHB7fgxPTQ4o1+mkp5T3hbZtrNtwcVVgyawCi95Z3gBMP2gsm -p5MjlPScTaHCC9L6cCEUCnM1a+EGxBjUR18lFWIJCbJCYvm3/SaQ7iRZqzrzD+SAXUtpGElCwCDp -bmRmWBFsqgDEjc08/d540mlOeiUAonrsiy5x3w2alnhZh8W4pWl3xZoWvjYZd83OnJLKE7s0QhD2 -A3lj2OgJBWkz3diBRfusoRxqxqaoyC0zfgzcbLHWNwVErswfvMtuS3qpRq12xGJ9IpDx6MIbZ2qw -tqCBj7fmM8YdYnvM6sisymTzw7uom7D/hGM5cKdcCKX8i3CSx0UZqA0+6+SOmTVI8nQw5oxVnTdk -Y5yamiAJ8FHgP/WToShwnZ2RnOlILb2xijPlADKy2OvI7xzCrRNisz5EUDBhIrYQaPkqbLdwq8fl -+bQIQPHCy/tBdxLwa2rE4TuRnzZMtRmQHCDfvvOGSI/8FCD2W7f55wY7rL7pBtYcGp+A5NDNDj87 -smBYHG2mbPa93quz5jgV3iBDS152rg/4nVgt1gi+eXncrUpwjamJHPXujgoFwle7ALEMcrVy8IBR -KCYUbOx/gtjPDtBnh1jaz8SlMjxJIg+f8V+xzJfsYHTUQs4o7ejWyyPn+LSGPi4vUCWjO3fVl50W -4kozn/WLg+KG0rhDNpP3xqD5gaH8oZADoMiu/uvgBMKGi7oBSH4p2EXujSgHVNJB5IPma2EnFyMW -AnsoNkkdoymbKO4ydLBhdK1Hc5M6rTMINlhRA+ULXxzsMI9TqNXjlb6T1sCEblOPqgJ6ofJOnGnh -Y1tzc2uLOHrot36p9hb1SDcVFEhUHIQ8EFl63bus0fZvoof8l9TihOZL6hFegPPAIbZ0UNAMkVfb -b2/Zhud0u1xf176UmXEcXynHacWgE/Ctm/QBvpAqHzvOMX33pC4iIPhtufdXsPJvEQotLHFNX3eR -lZ0/xFNsT5susqsdn3J4ke6T/OYWUoYq1/Q0stxlI47XZHzI7++iAE4lwfKnxtXoINOTRftTvLh1 -0LzmA9zzxjzE3RslYeRAUJUhck1vUp8xWsuhumRi05UjC6uSgXb9Knpe43KxxfM415dKETVxSvX6 -Rl7VKW0RoJb4MiS3rqi6F3raZBA++d3ukfN+zAAUZpkShJRvfPKdnum3smQ3eFFsZAvX57QB5r5U -CdVl2II1sMwkwbK541BxAbNGA6w3q2Qo7Uuc9Jdhtl1XA8Ikfk7CjMzifVVAez1RY38tE+tlxj1G -N9e903Lm30TpmUuygz7KaOgqZB6ubxddAduzYSPRhPqM9mHwFC95idlyu+Us++tEEENKayhZv7ag -fWZJ3b9tQaN/7D53f7f7HPzafbY4z6v4UjsfWQWz1xL6DjmHpn3Y8POzxWHezRNQ/MM83JUxVdOA -G1E6lomPHKihnec0ShEVAV+XBALAFtrgz4cvJarXPWhUDL94aOSCOnbi8SCcJ9bchgR/DgC+n4PG -bslbU+SQaO9GNUZFE0aCIK3aSjysFbk+pdBMI1gzT3RqXrqJxt9CUHwwc7o+N+W+W6syGsHNSK93 -+ObL1vtxmS9z03Wya+941Sz6cyJDZXhcZNr85AuhfTEX//IeiG7wSfZXieBC5gyTBayJSpbpQROG -tmrmoAirr/m4Qu8RQ0UxwJr38bpeSWMEbPTxYA6CbFxiWQkC+X5s0a/j04ljOcy+WB/FZH7Q2Hou -7W3aBmlL6Efu5Qk0J2i8+B3IgnwN4Oxqv5g3TDXfM+X5sNFvwxw3ev4WJMu8aqkBab6PiQEDtnfn -ZMcOju81QMBAe6cpK7N0F/HUCeQfTvZwgw54tx2bPiSEbcDlpA4p8dZ/He1462MdMxJ0EIwO9WJg -qPfAXjAxFpR9YMxoGcQ+ssb0HNr+vcQ42snIc7/iT9+lWb00uWpqqdKSve8RI+u4lJGKSmcyZ+1n -r86UatxpnEodsd43+lPLBlY+9gl+12WetkqFn4Cfkp4T80JKZlHmbyo2ZoEefU876yKyCieO0rJM -1NLjiatadoz3ead5bUwKwfPFQjj0C3sAfkKCPHg4pL8swmzilQIxm9qXlYPzXEJev/vLb6zv6Tun -Q2vkK7V2himApFKIeHIEvLi75adefhYsBpqjUxLMKKGKWBd0Z/N31ucMsUDP5baYCp99k5RMEEPq -o9csMiJi8Oz7XVmv76eJPTJzFDuvnxAxWOfWMdZXMlkP6ZK7cw2edUW8NwrkDetHdPzCukLFvltI -tSJzbQVS0oKSI61sBOkPg+Dw4di/iKMyDx1mGpNM/oDKFyqhjdHC6/uc7h7LyHn7/hQyhfP8Ve7D -kKmDayLBs07q+X75OF9WbQcLG845kfL97d3e6mZHaGzT4/QuF9sRHw8kxCdG6R30chi+Y3U05v0Y -VN2joGuQ5PkGNlQbPnnEtPpevcYODX0288kybepykMcid2rp1kLn9rzUujmcV2urT1QcxMeF9iEL -/lWQPPIob4r+WaURObBb9raOSY9O39WSUTgP3arD1xuTTUdT3UcDWOu56HX15hPtjebnh23IrLaW -cKt+pdnFE53SnOqLAgk0d6FqWL0XVZPLCzLPEeAgXV43UJDV0GPTgIdvoyuwx8y+2OXCx0VmNZFn -PJKSvt++Q67DMYWbFkFF4eS41Bnm98u2W598AYXGQ2muu+5ShC5i2sp9ZLfYcEy5wIjjRFyEra8v -lvdlYpFEg/ySJVVVJ8XGxDcQ0WnVup+fBGxDAhys9DhOgpQhh2orh8Y1ohkoIzEAIApB4znA6AhE -FuvoKgBbufyjzPL0pU+7nDSljIZ713FgaGgbmLJuMDUScHfiKvxjgeEefdt9yjGArbHAAvtM8pME -VK1mUnqDiu+P1z7nE34svK+gIww3ThWUm8nGdNWWwshd+ZwSvGnIBtvyBv/j47n7TUA+or2NfHgQ -vogN/ysLnz68eWCB4dDnDpvd6kPOjs/758RGOfkHTxarHpZowT6iDMlOjX9f5e+QTVVSTvKCU1lj -NwbkkqydvMYWvgxWpeMxamrhUb8YCHIJWMebz/6eijRHrKuE9cLvA1X4COk20GEv0Zcs3dOkq7r3 -cYmY1azKYBM/06Gb8B8DAWNow88gCP+/GcWXOXyGgnyGUsX+cZmWc0S86bPtoo/oGPgv4cFFlmL4 -sgFDEOUOjZG7nXwftnfkBmeKsY9TTAaygaIvcyAFSiJp1MBRn8KwJqpEkME0xn3UbHphq/Z65ELn -NEScFq1ToMpernFJsnet2Gq3Qje4k/JnmiCbzX5/RIk6Z6MmUd4jeU/FnG4uxC50N3fw9DqEi8pP -Dwcy7GJchfqVYAIrhxx3YFJ9mMwIHy7iHBczxecUwb7nvqgu5awpPaxSRXrr0QiuBmMtHqA0TwUh -+0iq8IW8dyjMqrBabaaHNZopVP/Eydr3yDTM3mGcGRh7Cb6//rjfrflMVqt2ppPRjtkYDe3plCEr -a/W08JCXHypzQk/a9k5EOukU0yddoeb6iiXqGN4v9luotkd956LvWRFRYx+KeN4EXb1zvf3cNInU -siTXjNYcsjlvLymeFvdjUeP2KCzvLtWbiuBuzdGImV94U1RmyzGdo75/f0GztDlkw6qWN/mxDNjL -wi9rjUDaXhLho8im28g8vIGd9qNTzLJ28NWqivfO0TV18DoRktPn4O7rUzY9fs3hFALmEEtu3Nqk -vrEOz/DyHlcHG0bIRIQtwUbBzk01IToPoFpjcngCV7xdYFR3claWYfqudR8//aoAENn52QHsKB45 -67g4bF9N6Kj+FrIMicOc8Mf9DPcvLj96VwLxrn8B9ucZ7+u/auOiOoy8Knju/xbOsJH+L737A3Hy -b5L6HF4T7lzZQff2gzgC6EVo/Q0voOQ8D4mEwdMiczR6fYDqR6Skjr2vFlChPldr03u2ru7gfpmD -tDC+o+VKVUjRGdcEU5MxcnccyzyvK2vBd5D6EHYQG6Tt/AZSNW2vSK9vZL/Oyx4fYlL0tGvOk3P/ -5djXJL+RijqaZJ8l1fhsokjqlyFvYBXdyHILyKkgJOI0ju0m4Dd0NOThOB67NSVgsST1zhbIIoF5 -BpLwWwjCA8gn8nvb6uNn57G10Rsbee4JVbfYe3OsHZH1MI8LIw9szxroQzNIoppF64z54lZPMpjf -Lj7gyfimUczsNpu+S87itzYysxHSep6Nl2to0qtI2MmdYk4kHyDlmiS2WmZ+9goVS7clc7XhZ35m -zE75o7jh85fBVhiCN85Bj1rWRUU6JNqC9bUWsM+gnO6whBaMrDt1UZQPHXYfL3Lguhh59S0Ba/yJ -Z1nIpsj0SE2k+NYcHGsgel4fb6gaH0YYPJvLdazy033zksAJNT0Ydlg/OB2IJo6/AmhwAMGnRBXg -IDWlyg302571+X7Nvr9sHU0sOKg8r7VMLZemOZhbFm/nBdawN1NTXX+PmquPbE98lemWrC4hYVpP -UdiEJylzO8lScTU8VvO2c98q8XkltY2zcrmnfdMI5iVgRqyp5yceQqFa2rJvb+5VV9MBzbTp6ZFJ -vr6tItBZ0R0QIGhuWW7qAAr84ysrxq29IN6DyrlQ7jHlut33qyXbxmlr/TsgEvclkAqj2W7LHHm7 -9F4dKWSERnqhx1A4rchrudpmUaxX8bu/3EQFjLsFDtBibO2qVBQpeXctx5lZYRo+2eLrKyrIegmm -+z1MeSSTnkGbtpc680JAh12Ku0R0eBdlgf8O+a617q4wr/4Bt09yRiIWQU0DKx6e10SbKn1+fEHl -iZhd71GQr4CRp27KAV6P7MZduRDOKvCqLCQP7JtTShAOgIoleNdecwtW9WnEaoofXag9LAt3LH8u -lvc0H/KhVflF1l9RTfM8kdxvbfmo9hCLbq+brmuw/jV4oJ27KWPkCIpuMOiDKu5MDRD6bQZyoYXu -U1Lb/bk1S+2UvQhVWjhpEYUVacawUHpjaDAfCbNhRmt/k9SALrEvzFCPa83qQTMzXrL7yjtFUVXV -G4uD47CJ8mJHILsY3oD7bcswM+DpGDuN7rOKqCZcYgOpXeabAg5GffXe4FoOam+Ja1gd9wTqqnXu -ZZ9Z2/lEzPOpkrUQT/ylvx1UNjuM1rS97JEXk1bNG5j/S1Xvov5NUpGWBfZ22CPg6NfoDd+ZLKVx -p5CU/Gx0AXlruduWdS2/1C4n2vI58M5S78Wle2O7kZSfszUgYTYkbHxL95klm7pYWJZPbN68h6q2 -23qzhYJl795wM91D0NKjn5nW7jHRjBooXlfK6vO2jraeuS1kxcxvDH2jy7cQZCDoZPLpKlhofe0P -BB+nmNSCh3039uhs5cscF03e8M/cWOgEv0JBHNuE7D5EjoqTLTEAETr5sbk49y/AljLpYcEpM5Qd -nwUUomQvDlkwPdW7kZmPRVnYpzufd6RoukjpT4c2gRPlkgJS6SsLg/NoFbMWAqB6v3TOyeBmH/1O -su7+BYGwtmnmcByUm3ndlF5BRUrjYTcOpXeplIpD9Bovy4YKmMiCmk/9AaBr+RSfKGT+VkX0rYcn -F6mT+Ao9sdqdxzV/ETm/bPXGl5fQzKpdEZALrvAB3KIkGTMbPZ1LRpkDk7WjW85ALZIgxN1fZzib -SlZu99e9H2nuBYmOIZq396tjLi8NgaRSlghVNc87rJ1OLiNZracDdUZNpl6pcgnoZyQSq74i9mx+ -SwTHdCsJOk5W9zFc89YhT4aEPGyOJ2sxZ5W248PGllu7KqTQQIvvDtXj4j4b1ugEZoQMTLpdtTXU -52T97o262eMmZxSIoyx2XCUVWqQ8axRSH2rnwSMjzHMdH28/KOyLeB93chckQHXioRANBd8i6pHU -r0/l01r/KDsX0QNuziCL9fvrRqfRzvoF0jmQNamZr14uF5cfqwQQhzEREn8iHCS0D6gqpefdZ2C4 -ldIsALmtsr+LYiJhjdie+Dk4qa4etykKVw/3uxAT0WyBhSkeioIHmaLVLy7WHrAC25vqddugbyNe -m56c63WKJzc2/fVDVCxV0yu73xFnMXb3YglHuUl8UzuHcWju4z7HY9pMfutb5rGs8LHmxzSyO9lB -E+7VGMLosz8r9YrXz2+pqomnWvA0RXFrlkdpxLGa3Z/7+UFEuAubgO94Uju5erbI0/1KdEYBufRV -7xENSZtRWIbUpKBuU0X3uwMeynB5ZUawaD7P3wHwuw4g7filhvphXEsKJVNY8x+m2uDmYFI339Id -ZtnfujTqXXz10f68xfNNFZX9+38RhDmfxHHJ6a9dAbpCcC2ZH2z8vEztlLdpGvlkjsSPxUZgS1Yp -fFsitHuqAVZOUqwpFh9PcuYc2ptTvtIMgzxIs95xTU9ym73FQwZqoRmGdsxSU/fmLEg/Z/V4P5+M -RjHY/RYdFzkoa+qNenevQiX5VS2V+vn/YL6braok8HLN0uLiItOB8lCQtxDBoNmDDZi3ChaQp8IM -a9sTd/1BjfaR8Cy7hGMpWm2hepeVw+2SEN+GbwpIswesd915SuQLTacK5tfmeoHVtvWynooQZm7K -m3s6+8igawC7jUKY9nJhCfFhcZI51sQp18xaNr33C2CjmH7CsthAwaKsIcwYvrFEzojiagwE5olR -GP/A2Lef2kW1Cvfx6jDOU/Jj4eAu02SDRF7yyPL8/Aj8x6DWNR3zzu+J0WgAS/iFtVa1xUA0HVSs -mrE9Ir7cDgsewJyDGDuue7lwKWNoyK9aeN2GMIeiD3Gb3F8Ha/MDvkQ2fivyaOOTaAeebHJNF7xw -XtEI6WY+U/eZWTjF35lwPEm9df0Hg/8cixtyPx42HWr8PvLtb/2Qm+kWZ0qrfg5KtrAZKeN+I7zt -+4an2srEdQa3CHRNd0RSnsyBme3px9Kpjg6l5iWNmkc6MFahT5r0RWxWOHWdG5t7a9kpKrI6I4Tc -k0aO0gkn6GakyWZqQCh6YJafqnrsY1ZFRs1O+uTN0cmzDrF70+VotutXVtzwFHM5ibkDOq8/dOxo -kv0Zq/qV+ewr3jFA5VljyRVsiYbR6yk4w7HWsbChmqWqAalM79bhWhY2En4F+PtFBwfXeLAVHFqM -mbo6xQc74fWVhrkruwGInWAvnBz2s/yVNXk2zYoEevt/2ruyJkWxJfw+Efc/TMw8GjXsm9HXCVY3 -UNoN9e3IIiibgAj8+jlK2V1VYlV1T03E3LjlY5LbyeTkyQT9XE0PworbRgNy5zjeVNuvvfq5DSJ4 -/a4usQvdKKJxDOvbYZzba6dvHOkiDiJgrZCIUtCDbUy7E33OLdYLYd7HaUyZeeKku/2abqVhKRqT -+rYJNpSBHTgW8nMb1jPSYwD1sJq1W+Pz/WZSFsA5zId4Ag/+jd/NWrDVWNg9Ocz2pnkSJ4Nwv53y -KzgAPX5DctibM4ZeVjHhC/g22xzxWVlQXvB1vs7Gqmgl7lZ3KedI8QXD0rCxXIZOvqpO7FY3gzyQ -ypAK2aIFd3pVvwG3iqjnI+UCFEmMcsQqM/EzVpC2/up1R8TWmKz6vEKZu2LTLwKh55i+PxS0LNt2 -h0s4j1TuyvGpRKes5ag+U2zaC3w6jNHjHsTAQMt4tCJG5T7dusNWUgB8E5Y9jZ3MUi0Y7DwySE99 -b5VBZZLBDRB1ViHUFPmaMTZdDz5LN/CwcjwkjwZmCzEKlHyuHxaBOz3kco7bUW9OelYp5BvG18T+ -fgF3iM0JyLClllMfscOSo0YYvD+11SOuiO3MVdEojYVtlH10Nyr7Y047lN3lHMfJQjbdWVevJmhv -yVRGrs/9MM4wsyAcP8AyZkKuBgNBHWcoM1Lq9ymLOUuIQTzfwNG7z0tEqu2nU8eE1TpsGeN8Rks2 -oCgV4XvddNkKuxV7ArAcApdfHXXVzZBYWzICjBmj1I8IqImljGcySAdYawlLc7xpOSPjyHhV6MLW -S0KNYZfc76wVsfd2e26imNuhMY0o3tJ2WiskfX+3o3fMtrgiTpw4yj3/EgY46KTlMTmnIkZrSY85 -cUlXBTIjkgXX21UxvSw4PWU4LSykQkV6A/fUO9FIb9SjE6rHEi1Hrx/d94LeIjwWkeEbrJb7xCyx -ERQO3TEDx8hj4g2WflZu9/uBOBWzRbc4iSuP173A0MqBrkbuWlUr//yFvSKu97LPzLNxru4WueoE -w1MaHmGXO82qNZ6V8S7vV4U+VFFgBgcw19VuUci7gzy3ZZ4TqwWnYzIS7qRDP1vnjz8n0VUtO24I -FOf4WTjvE/LyMCfNFq+aAItz32p5+ShNMILSFmzq+HGy8FsgZUel6Ay67rQCFWW7/birVovaQxdo -Tro3qknpT7DlXmphcBT1C7Y87by+TwmD0fsPw/oFzeOJKE91cTjSZrI5SQ0EWX8HiKvR325A75Aa -9e4FRh5yC5JXI+7doup9JFSipr2OeRgEjXiJaTaxndcl0zOYH3LF8oPsvzcrkvPsRxTJuR1mv78E -YdS0thSZxzMcZV/qQMIflme1MYySFBZjFJyiZRTDeIEVZEoSSZQXOIzkLwF+Lnqjth+mGQhN+1Gt -9wNqn4jeqJ3YoeWdcyT6IE07cRJFTju2nKvsi+s38uPE23oh8J+4fjxC3yicJXkOkxmBZCUFwwRB -ljgUhWcDhSokgV71N8jfRtROvNy2lCQK3gnR+OVyX7S97wu/OLWxUJMANv5AMMB+IGnSemA3qPlA -bEyOJTDHAhv6C3Ij26Taus2yzDGYyAmcJLPUZcmEILA8zgskAxfNK1fNVtNSv2uOfjqid+WbzCR3 -E994/UU1eJ6V25T1vDSLkrIBf3NqHz4Gf/OyY9vAvBSeFEBXzq4/od0X8hr2ksBSMsswkkKJl+jy -OM0zMoujCioTGH/Vfe+2eKb/5NrhGb0UfUCpB4yYYWgbJdoE20LxC4DpE677StLIyU5wzOa3MImN -gK7UVdNz1vsqTReEW9vqIFfBK+F9Z8O/I1O8QkqKTMsiT8nnTHEyxcskyXACrnAKSv2tTOEwQXgb -+8zUR2TqPQXxZzLFPKD4DKPaBNUmuQ/OFPl/mam3O4mfyFQjdvP/aJpq6vOz63oQvjjrPqwrjt0o -i1I3ugMj/u1yDSb+1LFvl9pi5EeJFll2B0asifwPtPIz/Q38cjipbu9085IXvKcJh2x2mEJ30sZm -/jz4vAWh/rJzh163RzoclNIOdsnsE8ItZw+kCy/1Nr49S0CYwm1rh2bZUYCf2t+k7zC9pm2c20mc -ePBWvqfqO8etHg0UZ4enXmW/v1GGsWyfOjhD/EFTNEOw5w1S05o43Q6GwwBePldOt5HzGHpZR4+g -p+mV8UJ6sYFe+N2wKt0HmT0Cgd0E5/5KO9kRSxC+VXU7GjhXDvAm38r2/ej0JpvgA3P/gzXk7iKv -EZieQGa63SQ6xj8Ygx+HtG9vz2bOnnQk2wFHP/u1Nv/rxX79VOEJ0+t6zlY76FOhC+VvFt17MWmu -YjV1IimdX6D09c8ymhz/+M+nkU8jn0Y+jXwa+TTyaeRfZeSXL9/+bssOrf/+dvrtz85//gL31ZfA -CmVuZHN0cmVhbQplbmRvYmoKNzkgMCBvYmoKPDwvUjkKOSAwIFI+PgplbmRvYmoKODAgMCBvYmoK -PDwvUjE1CjE1IDAgUi9SOAo4IDAgUj4+CmVuZG9iago4MSAwIG9iago8PC9SNzcKNzcgMCBSL1I3 -NQo3NSAwIFIvUjczCjczIDAgUi9SNzEKNzEgMCBSL1I2OQo2OSAwIFIvUjY3CjY3IDAgUi9SNjUK -NjUgMCBSL1I2Mwo2MyAwIFIvUjYxCjYxIDAgUi9SNTkKNTkgMCBSL1I1Nwo1NyAwIFIvUjU1CjU1 -IDAgUi9SNTMKNTMgMCBSL1I1MQo1MSAwIFIvUjQ5CjQ5IDAgUi9SNDcKNDcgMCBSL1I0NQo0NSAw -IFIvUjQzCjQzIDAgUi9SNDEKNDEgMCBSL1IzOQozOSAwIFIvUjM3CjM3IDAgUi9SMzUKMzUgMCBS -L1IzMwozMyAwIFIvUjMxCjMxIDAgUi9SMjkKMjkgMCBSL1IyNwoyNyAwIFIvUjI1CjI1IDAgUi9S -MjAKMjAgMCBSL1IxOAoxOCAwIFIvUjE2CjE2IDAgUi9SMTAKMTAgMCBSPj4KZW5kb2JqCjc3IDAg -b2JqCjw8L1BhdHRlcm5UeXBlIDIKL1NoYWRpbmcgNzggMCBSCi9NYXRyaXhbLTAuMDAwMDAwOTAK -LTIwLjY4NzUKLTIwLjY4NzUKMC4wMDAwMDA5MAoxMzkuODA0CjE1Ljk1N10+PmVuZG9iago3NSAw -IG9iago8PC9QYXR0ZXJuVHlwZSAyCi9TaGFkaW5nIDc2IDAgUgovTWF0cml4Wy0wLjAwMDAwMDkw -Ci0yMC42ODc1Ci0yMC42ODc1CjAuMDAwMDAwOTAKMTM5LjgwNAoxNS45NTddPj5lbmRvYmoKNzMg -MCBvYmoKPDwvUGF0dGVyblR5cGUgMgovU2hhZGluZyA3NCAwIFIKL01hdHJpeFstMC4wMDAwMDA5 -MAotMjAuNjg3NQotMjAuNjg3NQowLjAwMDAwMDkwCjEzOS44MDQKMTUuOTU3XT4+ZW5kb2JqCjcx -IDAgb2JqCjw8L1BhdHRlcm5UeXBlIDIKL1NoYWRpbmcgNzIgMCBSCi9NYXRyaXhbLTAuMDAwMDAw -OTAKLTIwLjY4NzUKLTIwLjY4NzUKMC4wMDAwMDA5MAoxMzkuODA0CjE1Ljk1N10+PmVuZG9iago2 -OSAwIG9iago8PC9QYXR0ZXJuVHlwZSAyCi9TaGFkaW5nIDcwIDAgUgovTWF0cml4Wy0wLjAwMDAw -MDkwCi0yMC42ODc1Ci0yMC42ODc1CjAuMDAwMDAwOTAKMTM5LjgwNAoxNS45NTddPj5lbmRvYmoK -NjcgMCBvYmoKPDwvUGF0dGVyblR5cGUgMgovU2hhZGluZyA2OCAwIFIKL01hdHJpeFstMC4wMDAw -MDA5MAotMjAuNjg3NQotMjAuNjg3NQowLjAwMDAwMDkwCjEzOS44MDQKMTUuOTU3XT4+ZW5kb2Jq -CjY1IDAgb2JqCjw8L1BhdHRlcm5UeXBlIDIKL1NoYWRpbmcgNjYgMCBSCi9NYXRyaXhbLTAuMDAw -MDAwOTAKLTIwLjY4NzUKLTIwLjY4NzUKMC4wMDAwMDA5MAoxMzkuODA0CjE1Ljk1N10+PmVuZG9i -ago2MyAwIG9iago8PC9QYXR0ZXJuVHlwZSAyCi9TaGFkaW5nIDY0IDAgUgovTWF0cml4Wy0wLjAw -MDAwMDkwCi0yMC42ODc1Ci0yMC42ODc1CjAuMDAwMDAwOTAKMTM5LjgwNAoxNS45NTddPj5lbmRv -YmoKNjEgMCBvYmoKPDwvUGF0dGVyblR5cGUgMgovU2hhZGluZyA2MiAwIFIKL01hdHJpeFstMC4w -MDAwMDA5MAotMjAuNjg3NQotMjAuNjg3NQowLjAwMDAwMDkwCjEzOS44MDQKMTUuOTU3XT4+ZW5k -b2JqCjU5IDAgb2JqCjw8L1BhdHRlcm5UeXBlIDIKL1NoYWRpbmcgNjAgMCBSCi9NYXRyaXhbLTAu -MDAwMDAwOTAKLTIwLjY4NzUKLTIwLjY4NzUKMC4wMDAwMDA5MAoxMzkuODA0CjE1Ljk1N10+PmVu -ZG9iago1NyAwIG9iago8PC9QYXR0ZXJuVHlwZSAyCi9TaGFkaW5nIDU4IDAgUgovTWF0cml4Wy0w -LjAwMDAwMDkwCi0yMC42ODc1Ci0yMC42ODc1CjAuMDAwMDAwOTAKMTM5LjgwNAoxNS45NTddPj5l -bmRvYmoKNTUgMCBvYmoKPDwvUGF0dGVyblR5cGUgMgovU2hhZGluZyA1NiAwIFIKL01hdHJpeFst -MC4wMDAwMDA5MAotMjAuNjg3NQotMjAuNjg3NQowLjAwMDAwMDkwCjEzOS44MDQKMTUuOTU3XT4+ -ZW5kb2JqCjUzIDAgb2JqCjw8L1BhdHRlcm5UeXBlIDIKL1NoYWRpbmcgNTQgMCBSCi9NYXRyaXhb -LTAuMDAwMDAwOTAKLTIwLjY4NzUKLTIwLjY4NzUKMC4wMDAwMDA5MAoxMzkuODA0CjE1Ljk1N10+ -PmVuZG9iago1MSAwIG9iago8PC9QYXR0ZXJuVHlwZSAyCi9TaGFkaW5nIDUyIDAgUgovTWF0cml4 -Wy0wLjAwMDAwMDkwCi0yMC42ODc1Ci0yMC42ODc1CjAuMDAwMDAwOTAKMTM5LjgwNAoxNS45NTdd -Pj5lbmRvYmoKNDkgMCBvYmoKPDwvUGF0dGVyblR5cGUgMgovU2hhZGluZyA1MCAwIFIKL01hdHJp -eFstMC4wMDAwMDA5MAotMjAuNjg3NQotMjAuNjg3NQowLjAwMDAwMDkwCjEzOS44MDQKMTUuOTU3 -XT4+ZW5kb2JqCjQ3IDAgb2JqCjw8L1BhdHRlcm5UeXBlIDIKL1NoYWRpbmcgNDggMCBSCi9NYXRy -aXhbLTAuMDAwMDAwOTAKLTIwLjY4NzUKLTIwLjY4NzUKMC4wMDAwMDA5MAoxMzkuODA0CjE1Ljk1 -N10+PmVuZG9iago0NSAwIG9iago8PC9QYXR0ZXJuVHlwZSAyCi9TaGFkaW5nIDQ2IDAgUgovTWF0 -cml4Wy0wLjAwMDAwMDkwCi0yMC42ODc1Ci0yMC42ODc1CjAuMDAwMDAwOTAKMTM5LjgwNAoxNS45 -NTddPj5lbmRvYmoKNDMgMCBvYmoKPDwvUGF0dGVyblR5cGUgMgovU2hhZGluZyA0NCAwIFIKL01h -dHJpeFstMC4wMDAwMDA5MAotMjAuNjg3NQotMjAuNjg3NQowLjAwMDAwMDkwCjEzOS44MDQKMTUu -OTU3XT4+ZW5kb2JqCjQxIDAgb2JqCjw8L1BhdHRlcm5UeXBlIDIKL1NoYWRpbmcgNDIgMCBSCi9N -YXRyaXhbLTAuMDAwMDAwOTAKLTIwLjY4NzUKLTIwLjY4NzUKMC4wMDAwMDA5MAoxMzkuODA0CjE1 -Ljk1N10+PmVuZG9iagozOSAwIG9iago8PC9QYXR0ZXJuVHlwZSAyCi9TaGFkaW5nIDQwIDAgUgov -TWF0cml4Wy0wLjAwMDAwMDkwCi0yMC42ODc1Ci0yMC42ODc1CjAuMDAwMDAwOTAKMTM5LjgwNAox -NS45NTddPj5lbmRvYmoKMzcgMCBvYmoKPDwvUGF0dGVyblR5cGUgMgovU2hhZGluZyAzOCAwIFIK -L01hdHJpeFstMC4wMDAwMDA5MAotMjAuNjg3NQotMjAuNjg3NQowLjAwMDAwMDkwCjEzOS44MDQK -MTUuOTU3XT4+ZW5kb2JqCjM1IDAgb2JqCjw8L1BhdHRlcm5UeXBlIDIKL1NoYWRpbmcgMzYgMCBS -Ci9NYXRyaXhbLTAuMDAwMDAwOTAKLTIwLjY4NzUKLTIwLjY4NzUKMC4wMDAwMDA5MAoxMzkuODA0 -CjE1Ljk1N10+PmVuZG9iagozMyAwIG9iago8PC9QYXR0ZXJuVHlwZSAyCi9TaGFkaW5nIDM0IDAg -UgovTWF0cml4Wy0wLjAwMDAwMDkwCi0yMC42ODc1Ci0yMC42ODc1CjAuMDAwMDAwOTAKMTM5Ljgw -NAoxNS45NTddPj5lbmRvYmoKMzEgMCBvYmoKPDwvUGF0dGVyblR5cGUgMgovU2hhZGluZyAzMiAw -IFIKL01hdHJpeFstMC4wMDAwMDA5MAotMjAuNjg3NQotMjAuNjg3NQowLjAwMDAwMDkwCjEzOS44 -MDQKMTUuOTU3XT4+ZW5kb2JqCjI5IDAgb2JqCjw8L1BhdHRlcm5UeXBlIDIKL1NoYWRpbmcgMzAg -MCBSCi9NYXRyaXhbLTAuMDAwMDAwOTAKLTIwLjY4NzUKLTIwLjY4NzUKMC4wMDAwMDA5MAoxMzku -ODA0CjE1Ljk1N10+PmVuZG9iagoyNyAwIG9iago8PC9QYXR0ZXJuVHlwZSAyCi9TaGFkaW5nIDI4 -IDAgUgovTWF0cml4Wy0wLjAwMDAwMDkwCi0yMC42ODc1Ci0yMC42ODc1CjAuMDAwMDAwOTAKMTM5 -LjgwNAoxNS45NTddPj5lbmRvYmoKMjUgMCBvYmoKPDwvUGF0dGVyblR5cGUgMgovU2hhZGluZyAy -NiAwIFIKL01hdHJpeFstMC4wMDAwMDA5MAotMjAuNjg3NQotMjAuNjg3NQowLjAwMDAwMDkwCjEz -OS44MDQKMTUuOTU3XT4+ZW5kb2JqCjIwIDAgb2JqCjw8L1BhdHRlcm5UeXBlIDIKL1NoYWRpbmcg -MjEgMCBSCi9NYXRyaXhbLTAuMDAwMDAwOTAKLTIwLjY4NzUKLTIwLjY4NzUKMC4wMDAwMDA5MAox -MzkuODA0CjE1Ljk1N10+PmVuZG9iagoxOCAwIG9iago8PC9QYXR0ZXJuVHlwZSAyCi9TaGFkaW5n -IDE5IDAgUgovTWF0cml4Wy0wLjAwMDAwNDIzCjk2Ljc1Cjk2Ljc1CjAuMDAwMDA0MjMKMzYuNzM3 -MwoyMS4xNF0+PmVuZG9iagoxNiAwIG9iago8PC9QYXR0ZXJuVHlwZSAyCi9TaGFkaW5nIDE3IDAg -UgovTWF0cml4Wy0wLjAwMDAwNDIzCjk2Ljc0OTUKOTYuNzQ5NQowLjAwMDAwNDIzCjE0MC4xNTkK -MjEuMTRdPj5lbmRvYmoKMTAgMCBvYmoKPDwvUGF0dGVyblR5cGUgMgovU2hhZGluZyAxMSAwIFIK -L01hdHJpeFstMC4wMDAwMDQyNQo5Ny4xODkKOTcuMTg5CjAuMDAwMDA0MjUKMjM4Ljk3MgoyMC45 -NTA1XT4+ZW5kb2JqCjgyIDAgb2JqCjw8L1I3OAo3OCAwIFIvUjc2Cjc2IDAgUi9SNzQKNzQgMCBS -L1I3Mgo3MiAwIFIvUjcwCjcwIDAgUi9SNjgKNjggMCBSL1I2Ngo2NiAwIFIvUjY0CjY0IDAgUi9S -NjIKNjIgMCBSL1I2MAo2MCAwIFIvUjU4CjU4IDAgUi9SNTYKNTYgMCBSL1I1NAo1NCAwIFIvUjUy -CjUyIDAgUi9SNTAKNTAgMCBSL1I0OAo0OCAwIFIvUjQ2CjQ2IDAgUi9SNDQKNDQgMCBSL1I0Mgo0 -MiAwIFIvUjQwCjQwIDAgUi9SMzgKMzggMCBSL1IzNgozNiAwIFIvUjM0CjM0IDAgUi9SMzIKMzIg -MCBSL1IzMAozMCAwIFIvUjI4CjI4IDAgUi9SMjYKMjYgMCBSL1IyMQoyMSAwIFIvUjE5CjE5IDAg -Ui9SMTcKMTcgMCBSL1IxMQoxMSAwIFI+PgplbmRvYmoKNzggMCBvYmoKPDwvU2hhZGluZ1R5cGUg -MgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAg -UgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKNzYgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgov -Q29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgov -RXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKNzQgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29s -b3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0 -ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKNzIgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JT -cGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5k -IFt0cnVlIHRydWVdPj5lbmRvYmoKNzAgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFj -ZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0 -cnVlIHRydWVdPj5lbmRvYmoKNjggMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9E -ZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVl -IHRydWVdPj5lbmRvYmoKNjYgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZp -Y2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRy -dWVdPj5lbmRvYmoKNjQgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VD -TVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVd -Pj5lbmRvYmoKNjIgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlL -Ci9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5l -bmRvYmoKNjAgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9D -b29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRv -YmoKNTggMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29y -ZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoK -NTYgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNb -MAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKNTQg -MCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAow -CjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKNTIgMCBv -YmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEK -MF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKNTAgMCBvYmoK -PDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0K -L0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKNDggMCBvYmoKPDwv -U2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1 -bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKNDYgMCBvYmoKPDwvU2hh -ZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0 -aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKNDQgMCBvYmoKPDwvU2hhZGlu -Z1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9u -IDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKNDIgMCBvYmoKPDwvU2hhZGluZ1R5 -cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0 -IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKNDAgMCBvYmoKPDwvU2hhZGluZ1R5cGUg -MgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAg -UgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKMzggMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgov -Q29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgov -RXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKMzYgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29s -b3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0 -ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKMzQgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JT -cGFjZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5k -IFt0cnVlIHRydWVdPj5lbmRvYmoKMzIgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFj -ZS9EZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0 -cnVlIHRydWVdPj5lbmRvYmoKMzAgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9E -ZXZpY2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVl -IHRydWVdPj5lbmRvYmoKMjggMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZp -Y2VDTVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRy -dWVdPj5lbmRvYmoKMjYgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VD -TVlLCi9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVd -Pj5lbmRvYmoKMjEgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlL -Ci9Db29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDI0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5l -bmRvYmoKMTkgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9D -b29yZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDE0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRv -YmoKMTcgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29y -ZHNbMAowCjEKMF0KL0Z1bmN0aW9uIDE0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoK -MTEgMCBvYmoKPDwvU2hhZGluZ1R5cGUgMgovQ29sb3JTcGFjZS9EZXZpY2VDTVlLCi9Db29yZHNb -MAowCjEKMF0KL0Z1bmN0aW9uIDE0IDAgUgovRXh0ZW5kIFt0cnVlIHRydWVdPj5lbmRvYmoKMjMg -MCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlCi9GdW5jdGlvblR5cGUgMAovRG9tYWluWzAKMV0K -L1JhbmdlWzAKMQowCjEKMAoxCjAKMV0KL0JpdHNQZXJTYW1wbGUgOAovRW5jb2RlWzAKNjNdCi9E -ZWNvZGVbMAoxCjAKMQowCjEKMAoxXQovU2l6ZVs2NF0vTGVuZ3RoIDE1Pj5zdHJlYW0KeJx7d6R1 -8bsRjAHFlbaBCmVuZHN0cmVhbQplbmRvYmoKMjIgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2Rl -Ci9GdW5jdGlvblR5cGUgMAovRG9tYWluWzAKMV0KL1JhbmdlWzAKMQowCjEKMAoxCjAKMV0KL0Jp -dHNQZXJTYW1wbGUgOAovRW5jb2RlWzAKNjNdCi9EZWNvZGVbMAoxCjAKMQowCjEKMAoxXQovU2l6 -ZVs2NF0vTGVuZ3RoIDIzOT4+c3RyZWFtCnicDcMPLwJxGAfw92VmZmbMzMwMSZIkSZKUc9V1V6yZ -GTMM8yfeyu+6iHue3kh/yP/x9Xy2T0Pt3DdkUxXvZLmpCuWWKty2lHXTtq3rtm1evdjm5Wslf9Gp -5M87jnH25hin707u5KOaPf6sZo++HjKH34/6wU9N3/+tbe/9PWklPGu7cLeKcNMW3JQJd9MAJXOg -jYzUQQkNtJ4GxVOgtaRMgGNx8GpMRsHRiAyDV0IyCI4EpB/1ZZ/0oh72gJemwKFJ8OIEODgOXhgD -B0bB8yNyGOwfAs8Ngn0DoNl+2Qfy9oJmekCebrjTXf/QGasiCmVuZHN0cmVhbQplbmRvYmoKMjQg -MCBvYmoKPDwvRnVuY3Rpb25zWzIyIDAgUgoyMyAwIFJdCi9GdW5jdGlvblR5cGUgMwovRG9tYWlu -WzAKMV0KL0JvdW5kc1swLjg3MjcyN10KL0VuY29kZVsxCjAKMAoxXT4+ZW5kb2JqCjEzIDAgb2Jq -Cjw8L0ZpbHRlci9GbGF0ZURlY29kZQovRnVuY3Rpb25UeXBlIDAKL0RvbWFpblswCjFdCi9SYW5n -ZVswCjEKMAoxCjAKMQowCjFdCi9CaXRzUGVyU2FtcGxlIDgKL0VuY29kZVswCjYzXQovRGVjb2Rl -WzAKMQowCjEKMAoxCjAKMV0KL1NpemVbNjRdL0xlbmd0aCAyNjc+PnN0cmVhbQp4nAEAAf/+7sSF -o+7EhaPuw4Wi78OEou/EhKHwxIOg8MSDnvHEgp3yxIGb88SBmfTFgJf1xYCV98Z/k/nHfpD6x32N -/Mh8i/7JfIj/yXuF/8l6g//JeYD/yXh+/8h2e//IdXn/yHR2/8dzc//HcnD/x3Js/8dxaf/HcGX/ -x29j/8ZuYP/GbF3/xWta/8RqV//DaFP/w2dQ/8JmTP/CZEn/wWNG/8BhQ/+/YD//vl48/71cOf+8 -Wjb/u1kz/7lXMP+4VS3+tlQq/bVSJ/20TyT8sk0h+7BLHvquSRz5rEcZ96pFF/aoQxT1pkAS9aQ+ -EPSiOw7ynzkM8Z02Cu+aNAnulzEH7ZUvBnMfnRcKZW5kc3RyZWFtCmVuZG9iagoxMiAwIG9iago8 -PC9GaWx0ZXIvRmxhdGVEZWNvZGUKL0Z1bmN0aW9uVHlwZSAwCi9Eb21haW5bMAoxXQovUmFuZ2Vb -MAoxCjAKMQowCjEKMAoxXQovQml0c1BlclNhbXBsZSA4Ci9FbmNvZGVbMAo2M10KL0RlY29kZVsw -CjEKMAoxCjAKMQowCjFdCi9TaXplWzY0XS9MZW5ndGggMjMxPj5zdHJlYW0KeJwNwwsvgnEUB+Dv -pbGMsRpjTNNFSrqolC7S201vYrPWmpmZGbP6Km8l9D+nL1IyuYz5Oc/2QNmnQA4TyDktZ0Aus5wF -bc3JebB7Aby9KC1gjxXsXZLL4J0VsG9VroF318H+DXDAJjfBQTsGIScGey7pBoc90guO+KRfBsHR -kAyD96MyBo7FZQIUT4EO0jIDSmRBSQ2UyoPSBdBhCSpThjrSobIVKK2Kvnb295I7/33O1X6e8vXv -XqHx1StefD4WLz+6patJ9/j6vVO+eevot+O2fjduV+5fjZOHkVFtDo3T1j9t4KkGCmVuZHN0cmVh -bQplbmRvYmoKMTQgMCBvYmoKPDwvRnVuY3Rpb25zWzEyIDAgUgoxMyAwIFJdCi9GdW5jdGlvblR5 -cGUgMwovRG9tYWluWzAKMV0KL0JvdW5kc1swLjUyNzI2N10KL0VuY29kZVswCjEKMAoxXT4+ZW5k -b2JqCjgzIDAgb2JqCjw8L1R5cGUvTWV0YWRhdGEKL1N1YnR5cGUvWE1ML0xlbmd0aCAxMzE5Pj5z -dHJlYW0KPD94cGFja2V0IGJlZ2luPSfvu78nIGlkPSdXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQn -Pz4KPD9hZG9iZS14YXAtZmlsdGVycyBlc2M9IkNSTEYiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSdh -ZG9iZTpuczptZXRhLycgeDp4bXB0az0nWE1QIHRvb2xraXQgMi45LjEtMTMsIGZyYW1ld29yayAx -LjYnPgo8cmRmOlJERiB4bWxuczpyZGY9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRm -LXN5bnRheC1ucyMnIHhtbG5zOmlYPSdodHRwOi8vbnMuYWRvYmUuY29tL2lYLzEuMC8nPgo8cmRm -OkRlc2NyaXB0aW9uIHJkZjphYm91dD0nMzFkMWMwNjktOGYxMC0xMWViLTAwMDAtM2VlNDM2OTQw -ZjQ5JyB4bWxuczpwZGY9J2h0dHA6Ly9ucy5hZG9iZS5jb20vcGRmLzEuMy8nIHBkZjpQcm9kdWNl -cj0nR1BMIEdob3N0c2NyaXB0IDguNzEnLz4KPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9JzMx -ZDFjMDY5LThmMTAtMTFlYi0wMDAwLTNlZTQzNjk0MGY0OScgeG1sbnM6eG1wPSdodHRwOi8vbnMu -YWRvYmUuY29tL3hhcC8xLjAvJz48eG1wOk1vZGlmeURhdGU+MjAxMS0wMy0yNVQxNjoyMjowNysw -MTowMDwveG1wOk1vZGlmeURhdGU+Cjx4bXA6Q3JlYXRlRGF0ZT4yMDExLTAzLTI1VDE2OjIyOjA3 -KzAxOjAwPC94bXA6Q3JlYXRlRGF0ZT4KPHhtcDpDcmVhdG9yVG9vbD5Vbmtub3duQXBwbGljYXRp -b248L3htcDpDcmVhdG9yVG9vbD48L3JkZjpEZXNjcmlwdGlvbj4KPHJkZjpEZXNjcmlwdGlvbiBy -ZGY6YWJvdXQ9JzMxZDFjMDY5LThmMTAtMTFlYi0wMDAwLTNlZTQzNjk0MGY0OScgeG1sbnM6eGFw -TU09J2h0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8nIHhhcE1NOkRvY3VtZW50SUQ9JzMx -ZDFjMDY5LThmMTAtMTFlYi0wMDAwLTNlZTQzNjk0MGY0OScvPgo8cmRmOkRlc2NyaXB0aW9uIHJk -ZjphYm91dD0nMzFkMWMwNjktOGYxMC0xMWViLTAwMDAtM2VlNDM2OTQwZjQ5JyB4bWxuczpkYz0n -aHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8nIGRjOmZvcm1hdD0nYXBwbGljYXRpb24v -cGRmJz48ZGM6dGl0bGU+PHJkZjpBbHQ+PHJkZjpsaSB4bWw6bGFuZz0neC1kZWZhdWx0Jz5VbnRp -dGxlZDwvcmRmOmxpPjwvcmRmOkFsdD48L2RjOnRpdGxlPjwvcmRmOkRlc2NyaXB0aW9uPgo8L3Jk -ZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAg -ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBh -Y2tldCBlbmQ9J3cnPz4KZW5kc3RyZWFtCmVuZG9iagoyIDAgb2JqCjw8L1Byb2R1Y2VyKEdQTCBH -aG9zdHNjcmlwdCA4LjcxKQovQ3JlYXRpb25EYXRlKEQ6MjAxMTAzMjUxNjIyMDcrMDEnMDAnKQov -TW9kRGF0ZShEOjIwMTEwMzI1MTYyMjA3KzAxJzAwJyk+PmVuZG9iagp4cmVmCjAgODQKMDAwMDAw -MDAwMCA2NTUzNSBmIAowMDAwMDA1ODQ2IDAwMDAwIG4gCjAwMDAwMzI4MDcgMDAwMDAgbiAKMDAw -MDAwNTc4NyAwMDAwMCBuIAowMDAwMDA2MDIyIDAwMDAwIG4gCjAwMDAwMDU1OTggMDAwMDAgbiAK -MDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDA1NTc4IDAwMDAwIG4gCjAwMDAwMDU5MTEgMDAwMDAg -biAKMDAwMDAwNTk1MiAwMDAwMCBuIAowMDAwMDI1Nzc5IDAwMDAwIG4gCjAwMDAwMjk1ODMgMDAw -MDAgbiAKMDAwMDAzMDg4NCAwMDAwMCBuIAowMDAwMDMwNDMwIDAwMDAwIG4gCjAwMDAwMzEzMDIg -MDAwMDAgbiAKMDAwMDAwNTk3OCAwMDAwMCBuIAowMDAwMDI1NjY3IDAwMDAwIG4gCjAwMDAwMjk0 -NzIgMDAwMDAgbiAKMDAwMDAyNTU1OSAwMDAwMCBuIAowMDAwMDI5MzYxIDAwMDAwIG4gCjAwMDAw -MjU0NDQgMDAwMDAgbiAKMDAwMDAyOTI1MCAwMDAwMCBuIAowMDAwMDI5ODk1IDAwMDAwIG4gCjAw -MDAwMjk2OTQgMDAwMDAgbiAKMDAwMDAzMDMyMSAwMDAwMCBuIAowMDAwMDI1MzI5IDAwMDAwIG4g -CjAwMDAwMjkxMzkgMDAwMDAgbiAKMDAwMDAyNTIxNCAwMDAwMCBuIAowMDAwMDI5MDI4IDAwMDAw -IG4gCjAwMDAwMjUwOTkgMDAwMDAgbiAKMDAwMDAyODkxNyAwMDAwMCBuIAowMDAwMDI0OTg0IDAw -MDAwIG4gCjAwMDAwMjg4MDYgMDAwMDAgbiAKMDAwMDAyNDg2OSAwMDAwMCBuIAowMDAwMDI4Njk1 -IDAwMDAwIG4gCjAwMDAwMjQ3NTQgMDAwMDAgbiAKMDAwMDAyODU4NCAwMDAwMCBuIAowMDAwMDI0 -NjM5IDAwMDAwIG4gCjAwMDAwMjg0NzMgMDAwMDAgbiAKMDAwMDAyNDUyNCAwMDAwMCBuIAowMDAw -MDI4MzYyIDAwMDAwIG4gCjAwMDAwMjQ0MDkgMDAwMDAgbiAKMDAwMDAyODI1MSAwMDAwMCBuIAow -MDAwMDI0Mjk0IDAwMDAwIG4gCjAwMDAwMjgxNDAgMDAwMDAgbiAKMDAwMDAyNDE3OSAwMDAwMCBu -IAowMDAwMDI4MDI5IDAwMDAwIG4gCjAwMDAwMjQwNjQgMDAwMDAgbiAKMDAwMDAyNzkxOCAwMDAw -MCBuIAowMDAwMDIzOTQ5IDAwMDAwIG4gCjAwMDAwMjc4MDcgMDAwMDAgbiAKMDAwMDAyMzgzNCAw -MDAwMCBuIAowMDAwMDI3Njk2IDAwMDAwIG4gCjAwMDAwMjM3MTkgMDAwMDAgbiAKMDAwMDAyNzU4 -NSAwMDAwMCBuIAowMDAwMDIzNjA0IDAwMDAwIG4gCjAwMDAwMjc0NzQgMDAwMDAgbiAKMDAwMDAy -MzQ4OSAwMDAwMCBuIAowMDAwMDI3MzYzIDAwMDAwIG4gCjAwMDAwMjMzNzQgMDAwMDAgbiAKMDAw -MDAyNzI1MiAwMDAwMCBuIAowMDAwMDIzMjU5IDAwMDAwIG4gCjAwMDAwMjcxNDEgMDAwMDAgbiAK -MDAwMDAyMzE0NCAwMDAwMCBuIAowMDAwMDI3MDMwIDAwMDAwIG4gCjAwMDAwMjMwMjkgMDAwMDAg -biAKMDAwMDAyNjkxOSAwMDAwMCBuIAowMDAwMDIyOTE0IDAwMDAwIG4gCjAwMDAwMjY4MDggMDAw -MDAgbiAKMDAwMDAyMjc5OSAwMDAwMCBuIAowMDAwMDI2Njk3IDAwMDAwIG4gCjAwMDAwMjI2ODQg -MDAwMDAgbiAKMDAwMDAyNjU4NiAwMDAwMCBuIAowMDAwMDIyNTY5IDAwMDAwIG4gCjAwMDAwMjY0 -NzUgMDAwMDAgbiAKMDAwMDAyMjQ1NCAwMDAwMCBuIAowMDAwMDI2MzY0IDAwMDAwIG4gCjAwMDAw -MjIzMzkgMDAwMDAgbiAKMDAwMDAyNjI1MyAwMDAwMCBuIAowMDAwMDIxOTA2IDAwMDAwIG4gCjAw -MDAwMjE5MzYgMDAwMDAgbiAKMDAwMDAyMTk3NyAwMDAwMCBuIAowMDAwMDI1ODkxIDAwMDAwIG4g -CjAwMDAwMzE0MTEgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSA4NCAvUm9vdCAxIDAgUiAvSW5m -byAyIDAgUgovSUQgWzxGQjg0MTMxMTBDRjI5MkEwMzZEQjNBQzFGQTE3N0RGMT48RkI4NDEzMTEw -Q0YyOTJBMDM2REIzQUMxRkExNzdERjE+XQo+PgpzdGFydHhyZWYKMzI5MzAKJSVFT0YK}; - - system("base64 -d -i EMI_Logo_std.pdf.b64 > EMI_Logo_std.pdf"); - system("rm EMI_Logo_std.pdf.b64"); - -} - diff --git a/org.gridsite.core/doc/findproxyfile.1 b/org.gridsite.core/doc/findproxyfile.1 deleted file mode 100644 index 9de4d47..0000000 --- a/org.gridsite.core/doc/findproxyfile.1 +++ /dev/null @@ -1,63 +0,0 @@ -.TH findproxyfile 1 "October 2004" "findproxyfile" "GridSite Manual" -.SH NAME -.B findproxyfile -\- returns full path to GSI Proxy file -.SH SYNOPSIS -.B findproxyfile -[--proxycache=PATH] [--delegation-id=ID] [--user-dn=DN] [--outsidecache] -.SH DESCRIPTION -.B findproxyfile -returns full path to a GSI Proxy file, either in the proxy cache maintained -by the GridSite G-HTTPS and delegation portType functions, or in other -standard places. - -If a User DN is given -.B findproxyfile -uses the value of the -.B --proxycache -argument, the GRST_PROXY_PATH or the -compile time default to detemine the location of the proxy cache directory. -The directory is searched for a proxy having the given User DN and -Delegation ID. (If no Delegation ID is specificed, then the default value is -used.) - -If -.B findproxyfile -does not find a proxy or if a User DN is not given, but -.B --outsidecache -was given, then the environment variable X509_USER_PROXY and the standard -location /tmp/x509up_uUID are searched as well. - -.SH OPTIONS - -.IP "--proxycache=PATH" -Give the path of the proxy cache directory explicitly, overriding the -default and the GRST_PROXY_PATH environment variable if present. - -.IP "--delegation-id=ID" -The optional delegation ID is search for in the proxy cache in addition to -the User DN. If absent, the default Delegation ID value is searched for. - -.IP "--user-dn=DN" -The DN of the full user certificate associated with the proxy to be searched -for in the proxy cache. (This is not the DN of any proxy earlier in the -chain: it is a the DN of a certificate issued by a recognised CA.) - -.IP "--outsidecache" -If a User DN is not given, or a proxy not found in the cache, then search -for a proxy using X509_USER_PROXY environment variable and file name of -form /tmp/x509up_uUID as well. - -.SH RETURN VALUE -If a proxy is found, its full path is output on standard out. - -.SH EXIT CODES -0 is returned on succcess. Non-zero otherwise. - -.SH BUGS -In this version, no attempt is made to verify or validate the proxies. - -.SH AUTHOR -Andrew McNab - -findproxyfile is part of GridSite: http://www.gridsite.org/ diff --git a/org.gridsite.core/doc/fuse.spec b/org.gridsite.core/doc/fuse.spec deleted file mode 100644 index ac785a2..0000000 --- a/org.gridsite.core/doc/fuse.spec +++ /dev/null @@ -1,139 +0,0 @@ -# -# You should be able to build your own FUSE RPMs for use with SlashGrid -# by fetching an up-to-date stable FUSE tar file from SourceForge, -# putting it in /usr/src/redhat/SOURCES, updating the Version: header in -# this file, and then executing rpmbuild -ba fuse.spec -# -Name: fuse -Version: 2.5.3 -URL: http://fuse.sourceforge.net -Source: %{name}-%{version}.tar.gz -Release: 3%(sed 's/^\([A-Z]\)[^ ]* \([A-Z]\)[^0-9]*\([0-9][^ ]*\).*/\1\2\3/g' /etc/redhat-release | sed 's/[^A-Z,a-z,0-9]//g')_%(uname -r | sed 's/-/_/g') -Summary: File System in Userspace (FUSE) utilities -Group: System Environment/Base -License: GPL -Packager: Andrew McNab -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - -%description -With FUSE it is possible to implement a fully functional filesystem in a -userspace program. This package contains the FUSE userspace tools to -mount a FUSE filesystem. - -(This version is designed for use with the SlashGrid daemon: - http://www.gridsite.org/slashgrid/ ) - -%package libs -Summary: File System in Userspace (FUSE) libraries -Group: System Environment/Libraries -License: LGPL - -%description libs -Devel With FUSE it is possible to implement a fully functional filesystem in a -userspace program. This package contains the FUSE libraries. - -%package devel -Summary: File System in Userspace (FUSE) devel files -Group: Development/Libraries -Requires: %{name}-libs = %{version}-%{release} -Requires: pkgconfig -License: LGPL - -%description devel -With FUSE it is possible to implement a fully functional filesystem in a -userspace program. This package contains development files (headers, -pgk-config) to develop FUSE based applications/filesystems. - -%prep -%setup -q -#disable device creation during build/install -sed -i 's|mknod|echo Disabled: mknod |g' util/Makefile.in -sed -i 's|install-data-local | |g' util/Makefile.in -sed -i 's| install-data-local| |g' util/Makefile.in - -%build -%configure --disable-static -make %{?_smp_mflags} - -%install -rm -rf $RPM_BUILD_ROOT -make install DESTDIR=$RPM_BUILD_ROOT -find $RPM_BUILD_ROOT -type f -name "*.la" -exec rm -f {} ';' - -# change from 4755 to 0755 to allow stripping (setuid not needed by SlashGrid) -chmod 0755 $RPM_BUILD_ROOT/%{_bindir}/fusermount - -%clean -rm -rf $RPM_BUILD_ROOT - -%post -mknod --mode=0660 /dev/fuse c 10 229 -chown root.root /dev/fuse -depmod - -%postun - -%post libs -p /sbin/ldconfig - -%postun libs -p /sbin/ldconfig - -%files -%doc AUTHORS ChangeLog COPYING FAQ Filesystems NEWS README README.NFS -/sbin/mount.fuse -%attr(0755,root,root) %{_bindir}/fusermount -/lib/modules/%(uname -r)/kernel/fs/fuse/fuse.*o - -%files libs -%doc COPYING.LIB -%{_libdir}/libfuse.so.* - -%files devel -%defattr(-,root,root,-) -%{_libdir}/libfuse.so -%{_libdir}/pkgconfig/*.pc -%{_includedir}/fuse.h -%{_includedir}/fuse - -%changelog - -* Sun May 28 2006 Andrew McNab 2.5.3-3 -- Simplify for use with SlashGrid daemon (which only runs as root) on - Scientific Linux 3.*/4.* too - -* Wed May 03 2006 Peter Lemenkov 2.5.3-1%{?dist} -- Update to 2.5.3 - -* Thu Mar 30 2006 Peter Lemenkov 2.5.2-4%{?dist} -- rebuild - -* Mon Feb 13 2006 Peter Lemenkov - 2.5.2-3 -- Proper udev rule - -* Mon Feb 13 2006 Peter Lemenkov - 2.5.2-2 -- Added missing requires - -* Tue Feb 07 2006 Peter Lemenkov - 2.5.2-1 -- Update to 2.5.2 -- Dropped fuse-mount.fuse.patch - -* Wed Nov 23 2005 Thorsten Leemhuis - 2.4.2-1 -- Use dist - -* Wed Nov 23 2005 Thorsten Leemhuis - 2.4.2-1 -- Update to 2.4.2 (solves CVE-2005-3531) -- Update README.fedora - -* Sat Nov 12 2005 Thorsten Leemhuis - 2.4.1-3 -- Add README.fedora -- Add hint to README.fedora and that you have to be member of the group "fuse" - in the description -- Use groupadd instead of fedora-groupadd - -* Fri Nov 04 2005 Thorsten Leemhuis - 2.4.1-2 -- Rename packages a bit -- use makedev.d/40-fuse.nodes -- fix /sbin/mount.fuse -- Use a fuse group to restict access to fuse-filesystems - -* Fri Oct 28 2005 Thorsten Leemhuis - 2.4.1-1 -- Initial RPM release. diff --git a/org.gridsite.core/doc/gridsite-delegation.8 b/org.gridsite.core/doc/gridsite-delegation.8 deleted file mode 100644 index 41ce1e3..0000000 --- a/org.gridsite.core/doc/gridsite-delegation.8 +++ /dev/null @@ -1,19 +0,0 @@ -.TH gridsite-delegation 8 "March 2006" "gridsite-delegation" "GridSite Manual" -.SH NAME -.B gridsite-delegation.cgi -\- CGI implementation of GridSite/gLite GSI delegation Web Service -.SH SYNOPSIS -.B gridsite-delegation.cgi - -.SH DESCRIPTION -.B gridsite-delegation.cgi -is a server-side implementation of the GridSite/gLite GSI delegation Web -Service - -.SH AUTHOR -Andrew McNab - -gridsite-delegation.cgi is part of GridSite: http://www.gridsite.org/ - -.SH "SEE ALSO" -.BR htproxyput(1) diff --git a/org.gridsite.core/doc/gsexec.8 b/org.gridsite.core/doc/gsexec.8 deleted file mode 100644 index e229663..0000000 --- a/org.gridsite.core/doc/gsexec.8 +++ /dev/null @@ -1,134 +0,0 @@ -.TH GSEXEC 8 "October 2005" "gsexec" "GridSite Manual" -.SH NAME -.B gsexec -\- Switch user before executing external programs - -.SH "SYNOPSIS" - -.BR gsexec -[-V] - -.SH "SUMMARY" - -gsexec is used by the Apache HTTP Server to switch to another user before -executing CGI programs\&. In order to achieve this, it must run as root\&. -Since the HTTP daemon normally doesn't run as root, the gsexec executable -needs the setuid bit set and must be owned by root\&. It should never be -writable for any other person than root\&. - -gsexec is based on Apache's suexec, and its behaviour is controlled with -the Apache configuration file directives -.BR GridSiteExecMethod -and -.BR GridSiteUserGroup -added to Apache by -.BR mod_gridsite(8) -Four execution methods are supported: nosetuid, suexec, X509DN and directory, -and these may be set on a per-directory basis within the Apache configuration -file. - -.SH "NOSETUID METHOD" - -This is the default behaviour, but can also be produced by giving -.BR "GridSiteExecMethod nosetuid" - -CGI programs will then be executed without using gsexec, and will -run as the Unix user given by the User and Group Apache directives (normally -apache.apache on Red Hat derived systems.) - -.SH "SUEXEC METHOD" - -If -.BR "GridSiteExecMethod suexec" -is given for this virtual host or directory, then CGI programs will be -executed using the user and group given by the -.BR "GridSiteUserGroup user group" -directive, which may also be set on a per-directory basis (unlike suexec's -.BR SuexecUserGroup -which is per-server only.) The CGI program must either be owned by root, -the Apache user -and group specified at gsexec build-time (normally apache.apache) or by -the user and group given with the -.BR GridSiteUserGroup -directive. - -.SH "X509DN METHOD" - -If -.BR "GridSiteExecMethod X509DN" -is given, then the CGI program runs as a pool user, detemined using lock -files in the exec mapping directory chosen as build time of gsexec. -The pool user is chosen according -to the client's full certificate X.509 DN (ie with any trailing GSI proxy -name components stripped off.) Subsequent requests by the same X.509 -identity will be mapped to the same pool user. The CGI program must either be -owned by root, the Apache user -and group specified at gsexec build-time (normally apache.apache) or by -the pool user selected. - -.SH "DIRECTORY METHOD" - -If -.BR "GridSiteExecMethod directory" -is given, then the CGI program runs as a pool user chosen according -to the directory in which the CGI is located: all CGIs in that directory -run as the same pool user. The CGI program must either be -owned by root, the Apache user -and group specified at gsexec build-time (normally apache.apache) or by -the pool user selected. - - -.SH "EXECMAPDIR" - -The default exec mapping directory is /var/www/execmapdir and this is fixed -when the gsexec executable is built. The exec mapping directory and all -of its lock files must be owned and only writable by root. To initialise the -lock files, create an empty lock file for each pool user, with the pool -username as the filename (eg user0001, user0002, ...) As the pool users are -leased to X.509 identities or directories, they will become hard linked to -lock files with the URL-encoded X.509 DN or full directory path. - -You can recycle pool users by removing the corresponding URL-encoded -hard link. -.BR stat(1) -and -.BR "ls(1)" -with option -.BR "-i" -can be used to print the inodes of lock files to match up the hard links. - -.BR "However, you must ensure that all files and processes owned by the pool" -.BR "user are deleted before recycling!" - -.SH "OPTIONS" - -.TP --V -If you are root, this option displays the compile options of gsexec\&. -For security reasons all configuration options are changeable only at -compile time\&. - -.SH "MORE INFORMATION" -For further information about the concepts and the security model of -the original Apache suexec -please refer to the suexec documentation: - -http://httpd\&.apache\&.org/docs-2\&.0/suexec\&.html - -For examples using the gsexec extensions, please see the GridSite gsexec -page: - -http://www.gridsite.org/wiki/Gsexec - -.SH AUTHORS - -Apache project, for original suexec - -Andrew McNab for gsexec modifications. - -gsexec is part of GridSite: http://www.gridsite.org/ - -.SH "SEE ALSO" -.BR httpd(8), -.BR suexec(8), -.BR mod_gridsite(8) diff --git a/org.gridsite.core/doc/gsoap-devel.spec b/org.gridsite.core/doc/gsoap-devel.spec deleted file mode 100644 index 1eb61f0..0000000 --- a/org.gridsite.core/doc/gsoap-devel.spec +++ /dev/null @@ -1,52 +0,0 @@ -# -# You can use this spec file and the gSOAP source tar file from sourceforge -# to build a binary development RPM of gSOAP, suitable for building the -# gridsite-ws components. Installing the resulting RPM puts the gSOAP files -# directory in /usr, where the gridsite-ws Makefile expects them by default. -# -# See http://www.gridsite.org/wiki/GSOAP for more about GridSite and gSOAP -# -Name: gsoap-devel -Version: %(echo ${MYVERSION:-2.7.6b}) -Release: 1%(sed 's/^\([A-Z]\)[^ ]* \([A-Z]\)[^0-9]*\([0-9][^ ]*\).*/\1\2\3/g' /etc/redhat-release | sed 's/[^A-Z,a-z,0-9]//g') -Summary: gSOAP development compilers/libraries/headers -License: Modified BSD -Group: Development/Libraries -Source: gsoap_%{version}.tar.gz -Prefix: %(echo ${MYPREFIX:-/usr}) -URL: http://www.cs.fsu.edu/~engelen/soap.html -Packager: Andrew McNab - -%description -Enough of gSOAP to build clients and servers based on gSOAP, using its headers -and static libraries. -By default, everything is installed in /usr/lib|bin|include/ - -%prep - -%setup -n gsoap-2.7 - -%build - -./configure --prefix=$RPM_BUILD_ROOT/%{prefix} -make - -%install -make install - -%files -%attr(-, root, root) %{prefix}/bin/soapcpp2 -%attr(-, root, root) %{prefix}/bin/wsdl2h -%attr(-, root, root) %{prefix}/include/stdsoap2.h -%attr(-, root, root) %{prefix}/lib/libgsoap++.a -%attr(-, root, root) %{prefix}/lib/libgsoap.a -%attr(-, root, root) %{prefix}/lib/libgsoapck++.a -%attr(-, root, root) %{prefix}/lib/libgsoapck.a -%attr(-, root, root) %{prefix}/lib/libgsoapssl++.a -%attr(-, root, root) %{prefix}/lib/libgsoapssl.a -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoap++.pc -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoap.pc -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoapck++.pc -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoapck.pc -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoapssl++.pc -%attr(-, root, root) %{prefix}/lib/pkgconfig/gsoapssl.pc diff --git a/org.gridsite.core/doc/htcp.1 b/org.gridsite.core/doc/htcp.1 deleted file mode 100644 index 0731d33..0000000 --- a/org.gridsite.core/doc/htcp.1 +++ /dev/null @@ -1,200 +0,0 @@ -.TH HTCP 1 "October 2005" "htcp" "GridSite Manual" -.SH NAME -.B htcp, htmv, htrm, htls, htll, htmkdir, htfind, htping -\- file transfers and queries via HTTP/HTTPS/SiteCast -.SH SYNOPSIS -.B htcp, htmv -[options] Source-URL[s] Destination-URL - -.B htrm, htls, htll, htmkir, htfind -[options] Target-URL[s] - -.B htping -[options] -.SH DESCRIPTION -.B htcp -is a client to fetch files or directory listings from remote servers using -HTTP or HTTPS, or to put or delete files or directories onto remote servers -using HTTPS. htcp is similar to scp(1), but uses HTTP/HTTPS rather than ssh -as its transfer protocol. htcp can also use the HTCP protocol to query -HTTP(S) fileservers via SiteCast. - -When talking to a fileserver with HTTPS, htcp can run "anonymously", with a -standard X.509 user certificate and key, or with a GSI Proxy. This makes -htcp very useful in Grid environments where many users have certificates -and where jobs and users have access to GSI proxies. - -.SH URLs -htcp supports the file:, http: and https: URL schemes as sources and -destinations. If no scheme is given, the URL scheme is assumed to be file: -and relative to the current directory if not an absolute path. - -If multiple sources are given during a copy, they will be used in turn and -the destination must be a directory (directories are indicated by a trailing -/) However, source and destination cannot both refer to remote servers. - -.SH OPTIONS -.IP "-v/--verbose" -Turn on debugging information. Used once, this option will enable htcp's -messages to stderr. Used twice, will also enable the underlying libcurl -messages. - -.IP "--delete" -Instead of copying files, delete all the URLs given on the command line. -Calling the program as htrm has the same effect. - -.IP "--list" -Instead of copying files, output lists of files located in the URL-directories -given on the command line. Calling the program as htls has the same effect. - -.IP "--long-list" -Instead of copying files, output long listings of files located in the -URL-directories given on the command line. If available, the size in bytes -and modification time of each file is given. Calling the program as -htll has the same effect. - -.IP "--mkdir" -Instead of copying files, attempt to create a directory on a remote server -with HTTP PUT. The server must support the convention that PUT to a URL with -a trailing slash means create a directory. No file body is sent. Calling the -program as htmkdir has the same effect. - -.IP "--move" -Move/rename files on a single remote server, given the two, absolute URLs -of the remote file names. Server must support HTTP/WebDAV MOVE. Calling the -program as htmv has the same effect. - -.IP "--ping" -Query specified multicast groups with the HTCP NOP ("No Operation") code. -SiteCast enabled servers will respond immediately with a NOP reply, and all -of the responses will be listed, with the round trip time in milliseconds. -Any waiting times specified in the --groups option will be ignored. Calling -the program as htping has the same effect. -(--groups must be used for this option to work.) - -.IP "--find" -Query specified multicast groups with the HTCP TST code. SiteCast enabled -servers will respond with TST replies if they have the files corresponding -to the given SiteCast target URL(s). All of the transfer URLs returned -will be listed. Waiting times specified in the --groups option will be used -to space out the multicast queries, but the program listens for responses -continuously. Calling the program as htfind has the same effect. -(--groups must be used for this option to work.) - -.IP "--groups " -IP multicast groups to use for SiteCast queries. IP Groups is a comma -separated list of groups, in the format: nnn.nnn.nnn.nnn:port[:ttl[:seconds]] -The IP number and port must be specified. The IP time-to-live, ttl, controls -how many networks the multicast packets may pass through - the default, 1, -limits packets to the local network. Multiple groups may be specified, -separated by commas. If multiple groups are specified, then seconds is the -time to wait before making the next multicast - 1 second is the default. - -.IP "--timeout " -A request timeout used for multicast ping. - -.IP "--anon" -Do not attempt to use X.509 user certificates or GSI proxies to authenticate -to the remote HTTPS server. This means you are "anonymous", but the server's -identity may still be verified and the connection is still encrypted. - -.IP "--cert and --key " -Path to the PEM-encoded -X.509 or GSI Proxy user certificate and key to use for HTTPS -connections, intead of "anonymous mode." If only one of --key or --cert -is given, then that will be tried for both. If neither is given, then the -following order of precedence is used: -the file name held by the variable X509_USER_PROXY; the file -/tmp/x509up_uID (with Unix UID equal to ID); the file names held by -X509_USER_CERT / X509_USER_KEY; the files ~/.globus/usercert.pem and -~/.globus/userkey.pem (where ~/ is the home directory of the user.) - -.IP "--capath " -Path to the PEM-encoded CA root certificates to use when -verifying remote servers' host certificates in HTTPS connections. Ideally -this should be a directory of hash.0 files as described in the OpenSSL -verify(1) man page, but a file may be used instead. If --capath is not -given, the value of the environment variable X509_CERT_DIR will be tried. -If this is not valid, then /etc/grid-security/certificates will be used. - -.IP "--no-verify" -Do not use CA root certificates to verify remote servers' host certificates. -This is useful for testing sites before their certificate is set up properly, -but leaves you vulnerable to "man in the middle" attacks by hostile servers -masquerading as your target. - -.IP "--grid-http" -Try to use GridHTTP redirection for HTTPS URLs. Compatible servers will perform -authentication and authorization on the HTTPS connection and then redirect -to HTTP for the GET or PUT file transfer. htcp makes the HTTP request using -the GRID_AUTH_PASSCODE single-use passcode obtained via HTTPS. The --grid-http -option will be ignored for directory operations or HTTP URLs. If a redirected -transfer isn't possible, a normal HTTPS data transfer will be attempted. - -.IP "--sitecast" -Try to use SiteCast to locate remote files which are to be copied (currently -only for the -.BR fetching -of remote files.) If no location is found via SiteCast, then a direct request -for the given URL is tried. (--groups must be used for this option to work.) - -.IP "--domain " -Try to use SiteCast to locate remote files which are to be copied (currently -only for the -.BR fetching -of remote files) -.BR "if the domain component of the URL matches" -the SiteCast domain given. -If no location is found via SiteCast, then a direct request -for the given URL is tried. (--groups must be used for this option to work.) - -.SH FILES -.IP /tmp/x509up_uID -Default GSI Proxy file for Unix UID equal to ID. - -.IP /etc/grid-security/certificates -Default location for trusted Certification Authority root certificates to use -when checking server certificates. - -.IP /tmp/.ca-roots-XXXXXX -Prior to 7.9.8, the underlying curl library did not support the CA root -certificates directory. -If built with an old version of libcurl, htcp will concatenate the -certificates in the CA roots directory into a unique temporary file and use -that. - -.SH ENVIRONMENT - -.IP X509_CERT_DIR -Holds directory to search for Certification Authority root certificates when -verifying server certificates. (Tried if --capath is not given on the -command line.) - -.IP X509_USER_PROXY -Holds file name of a GSI Proxy to use as user certificate. (Tried if --cert or ---key are not given on the command line.) - -.IP "X509_USER_CERT and X509_USER_KEY" -Holds file name of X.509 user certificate and key. (Tried if X509_USER_PROXY -is not valid.) - -.SH EXIT CODES -0 is returned on complete success. Curl error codes are returned when -reported by the underlying curl library, and CURLE_HTTP_RETURNED_ERROR (22) -is returned when the HTTP(S) server returns a code outside the range 200-299. -The manpage libcurl-errors(3) lists all the curl error codes. - -.SH TO DO -Recursive copying. Server-side wildcards. Parallel streams. Better error -recovery. - -.SH AUTHOR -Andrew McNab - -htcp is part of GridSite: http://www.gridsite.org/ -.SH "SEE ALSO" -.BR scp(1), -.BR curl(1), -.BR wget(1), -.BR verify(1), -.BR libcurl-errors(3) diff --git a/org.gridsite.core/doc/htfind.1 b/org.gridsite.core/doc/htfind.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htfind.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htll.1 b/org.gridsite.core/doc/htll.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htll.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htls.1 b/org.gridsite.core/doc/htls.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htls.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htmkdir.1 b/org.gridsite.core/doc/htmkdir.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htmkdir.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htmv.1 b/org.gridsite.core/doc/htmv.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htmv.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htping.1 b/org.gridsite.core/doc/htping.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htping.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/htproxydestroy.1 b/org.gridsite.core/doc/htproxydestroy.1 deleted file mode 100644 index 57f80ce..0000000 --- a/org.gridsite.core/doc/htproxydestroy.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htproxyput.1 diff --git a/org.gridsite.core/doc/htproxyinfo.1 b/org.gridsite.core/doc/htproxyinfo.1 deleted file mode 100644 index 57f80ce..0000000 --- a/org.gridsite.core/doc/htproxyinfo.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htproxyput.1 diff --git a/org.gridsite.core/doc/htproxyput.1 b/org.gridsite.core/doc/htproxyput.1 deleted file mode 100644 index a917054..0000000 --- a/org.gridsite.core/doc/htproxyput.1 +++ /dev/null @@ -1,121 +0,0 @@ -.TH HTPROXYPUT 1 "March 2006" "htproxyput" "GridSite Manual" -.SH NAME -.B htproxyput, htproxydestroy, htproxytime, htproxyunixtime, htproxyrenew -\- GSI proxy delegations and querying, using GridSite/gLite delegation API -.SH SYNOPSIS -.B htproxyput, htproxydestroy, htproxytime, htproxyunixtime, htproxyrenew -[options] Service-URL - -.B htproxyinfo -[options] - -.SH DESCRIPTION -.B htproxyput -is a client to perform GSI proxy delegations using the GridSite/gLite -delegation Web Service portType. The gridsite-delegation(8) CGI program is -the complementary server-side implementation. - -.B htproxyinfo -examines a local copy of a GSI proxy, and outputs a summary of its X.509 and -VOMS contents. - -.SH OPTIONS -.IP "-v/--verbose" -Turn on debugging information. - -.IP "--delegation-id " -Explicitly specify the Delegation ID to use. - -.IP "--destroy" -Instead of delegating a proxy, delete the proxy from the service's proxy -cache. Calling the program as htproxydestroy has the same effect. - -.IP "--time" -Instead of delegating a proxy, report the expiration time of the proxy, -in the local time of the client. Calling the program as htproxytime has the -same effect. - -.IP "--unixtime" -Instead of delegating a proxy, report the expiration time of the proxy, as -the number of seconds since 00:00:00 1970-01-01 UTC. Calling the program as -htproxyunixtime has the same effect. - -.IP "--renew" -Delegate an updated version of an existing proxy. The Delegation ID -.B must -be given when using this option. Calling the program as htproxyrenew has the -same effect. - -.IP "--info" -Examine a local proxy file, and output a summary of the X.509 certificates -and VOMS attributes it contains. Calling the program as htproxyinfo has the -same effect. - -.IP "--cert and --key " -Path to the PEM-encoded -X.509 or GSI Proxy user certificate and key to use for HTTPS -connections, intead of "anonymous mode." If only one of --key or --cert -is given, then that will be tried for both. If neither is given, then the -following order of precedence is used: -the file name held by the variable X509_USER_PROXY; the file -/tmp/x509up_uID (with Unix UID equal to ID); the file names held by -X509_USER_CERT / X509_USER_KEY; the files ~/.globus/usercert.pem and -~/.globus/userkey.pem (where ~/ is the home directory of the user.) - -.IP "--capath " -Path to the PEM-encoded CA root certificates to use when -verifying remote servers' host certificates in HTTPS connections. Ideally -this should be a directory of hash.0 files as described in the OpenSSL -verify(1) man page, but a file may be used instead. If --capath is not -given, the value of the environment variable X509_CERT_DIR will be tried. -If this is not valid, then /etc/grid-security/certificates will be used. - -.IP "--no-verify" -Do not use CA root certificates to verify remote servers' host certificates. -This is useful for testing sites before their certificate is set up properly, -but leaves you vulnerable to "man in the middle" attacks by hostile servers -masquerading as your target. - -.SH FILES -.IP /tmp/x509up_uID -Default GSI Proxy file for Unix UID equal to ID. - -.IP /etc/grid-security/certificates -Default location for trusted Certification Authority root certificates to use -when checking server certificates. - -.IP /tmp/.ca-roots-XXXXXX -Prior to 7.9.8, the underlying curl library did not support the CA root -certificates directory. -If built with an old version of libcurl, htproxyput will concatenate the -certificates in the CA roots directory into a unique temporary file and use -that. - -.SH ENVIRONMENT - -.IP X509_CERT_DIR -Holds directory to search for Certification Authority root certificates when -verifying server certificates. (Tried if --capath is not given on the -command line.) - -.IP X509_USER_PROXY -Holds file name of a GSI Proxy to use as user certificate. (Tried if --cert or ---key are not given on the command line.) - -.IP "X509_USER_CERT and X509_USER_KEY" -Holds file name of X.509 user certificate and key. (Tried if X509_USER_PROXY -is not valid.) - -.SH EXIT CODES -0 is returned on complete success, and non-zero on error. - -.SH TO DO -Better error recovery. - -.SH AUTHOR -Andrew McNab - -htproxyput is part of GridSite: http://www.gridsite.org/ -.SH "SEE ALSO" -.BR htcp(1), -.BR gridsite-delegation(8) diff --git a/org.gridsite.core/doc/htproxyrenew.1 b/org.gridsite.core/doc/htproxyrenew.1 deleted file mode 100644 index 57f80ce..0000000 --- a/org.gridsite.core/doc/htproxyrenew.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htproxyput.1 diff --git a/org.gridsite.core/doc/htproxytime.1 b/org.gridsite.core/doc/htproxytime.1 deleted file mode 100644 index 57f80ce..0000000 --- a/org.gridsite.core/doc/htproxytime.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htproxyput.1 diff --git a/org.gridsite.core/doc/htproxyunixtime.1 b/org.gridsite.core/doc/htproxyunixtime.1 deleted file mode 100644 index 57f80ce..0000000 --- a/org.gridsite.core/doc/htproxyunixtime.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htproxyput.1 diff --git a/org.gridsite.core/doc/htrm.1 b/org.gridsite.core/doc/htrm.1 deleted file mode 100644 index 11a60d1..0000000 --- a/org.gridsite.core/doc/htrm.1 +++ /dev/null @@ -1 +0,0 @@ -.so man1/htcp.1 diff --git a/org.gridsite.core/doc/httpd-fileserver.conf b/org.gridsite.core/doc/httpd-fileserver.conf deleted file mode 100644 index 5d701fb..0000000 --- a/org.gridsite.core/doc/httpd-fileserver.conf +++ /dev/null @@ -1,155 +0,0 @@ -############################################################################## -## GridSite httpd-fileserver.conf - Andrew McNab -## -## For GridSite documentation, see http://www.gridsite.org/ -## -## Example configuration file for GridSite as an HTTP(S) fileserver, -## listening on ports 80/777 (HTTP) and 443/488 (HTTPS) -## -## (777/488 is to allow firewalls to distinguish between Grid and -## Web HTTP(S) traffic. See http://www.gridsite.org/wiki/IP_Ports ) -## -## This file should be renamed /etc/httpd/conf/httpd.conf and Apache -## restarted to use Apache2/GridSite as a simple HTTP(S) fileserver. -## -## We assume that you have mod_gridsite.so in /usr/lib/httpd/modules -## and that you have (a) the host's hostcert.pem and hostkey.pem -## in /etc/grid-security/ and (b) the Certification Authorities' you -## trust have their root certs in /etc/grid-security/certificates -## -## (You can get RPMs for many European and North American Grid CAs -## from http://www.igtf.net/ ) -## -## If you want to use DN Lists in ACLs, they should be placed/downloaded -## in /etc/grid-security/dn-lists/ -## -## To start serving files, make a directory /var/www/html owned by -## apache.apache, including the file .gacl containing: -## -## -## -## -## -## -## -## -## -## To enable writing, add DN List, Person or VOMS entries to the GACL -## (see the GridSite GACL document for the syntax.) For example: -## -## -## -## -## -## -## -## -## -## /C=UK/O=eScience/OU=Manchester/L=HEP/CN=Andrew McNab -## -## -## -## -## -## and add the following directive to the HTTPS section: -## -## GridSiteMethods GET PUT DELETE MOVE -## -## If you wish to accept Globus GSI Proxies as well as full X.509 user -## certificates, set GridSiteGSIProxyLimit to the depth of proxy you -## wish to accept. -## -## (As a _rough_ guide: 0=No Proxies; 1=Proxy on user's machine; 2=Proxy -## owned by running Globus job; 3=Proxy delegated by a Globus job.) -## -## With this done and Apache restarted, you can upload a file with: -## -## curl -v --cert ~/.globus/usercert.pem --key ~/.globus/userkey.pem \ -## --capath /etc/grid-security/certificates --upload-file /tmp/tmp.txt \ -## https://INSERT.HOSTNAME.HERE/tmp.txt -## -## (or with --cert /tmp/x509up_u`id -u` --key /tmp/x509up_u`id -u` to use -## a Globus GSI Proxy created with grid-proxy-init.) -## -############################################################################## - -ServerRoot "/etc/httpd" - -PidFile logs/httpd.pid - -Timeout 300 -KeepAlive On -MaxKeepAliveRequests 100 -KeepAliveTimeout 300 - -# (Replace /lib/ with /lib64/ if on x86_64!) -LoadModule log_config_module /usr/lib/httpd/modules/mod_log_config.so -LoadModule ssl_module /usr/lib/httpd/modules/mod_ssl.so -LoadModule gridsite_module /usr/lib/httpd/modules/mod_gridsite.so -LoadModule mime_module /usr/lib/httpd/modules/mod_mime.so -LoadModule dir_module /usr/lib/httpd/modules/mod_dir.so - -TypesConfig /etc/mime.types - -# User and group who will own files created by Apache -User apache -Group apache - -DocumentRoot "/var/www/html" - - - AllowOverride None - - -LogLevel debug -LogFormat "%h \"%{SSL_CLIENT_S_DN}x\" %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined - -CustomLog logs/httpd-gridsite-access combined -ErrorLog logs/httpd-gridsite-errors - -HostnameLookups On - -###################################################################### -# Plain unauthenticated HTTP on ports 80 and 777 -###################################################################### - -Listen 80 -Listen 777 - - - - GridSiteIndexes on - GridSiteAuth on - GridSiteDNlists /etc/grid-security/dn-lists/ - - - - -###################################################################### -# Secured and possibly authenticated HTTPS on ports 443 and 488 -###################################################################### -Listen 443 -Listen 488 -SSLSessionCacheTimeout 300 -SSLSessionCache shm:/var/cache/mod_ssl/shm_cache - - - -SSLEngine on -SSLCertificateFile /etc/grid-security/hostcert.pem -SSLCertificateKeyFile /etc/grid-security/hostkey.pem -SSLCACertificatePath /etc/grid-security/certificates -#SSLCARevocationPath YOUR CRL DIRECTORY WOULD GO HERE -SSLVerifyClient optional -SSLVerifyDepth 10 -SSLOptions +ExportCertData +StdEnvVars - - - GridSiteIndexes on - GridSiteAuth on - GridSiteDNlists /etc/grid-security/dn-lists/ - GridSiteGSIProxyLimit 9 - GridSiteMethods GET PUT DELETE MOVE - - - diff --git a/org.gridsite.core/doc/httpd-storage.conf b/org.gridsite.core/doc/httpd-storage.conf deleted file mode 100644 index eeba72f..0000000 --- a/org.gridsite.core/doc/httpd-storage.conf +++ /dev/null @@ -1,220 +0,0 @@ - -############################################################################## -## GridSite httpd-storage.conf - Andrew McNab -## -## For GridSite documentation, see http://www.gridsite.org/ -## -## Example configuration file for GridSite as an HTTP(S) storage server, -## listening on ports 80/777 (HTTP) and 443/488 (HTTPS), and -## multicast UDP 224.0.1.111:488 for SiteCast file location. -## -## (777/488 is to allow firewalls to distinguish between Grid and -## Web HTTP(S) traffic. See http://www.gridsite.org/wiki/IP_Ports ) -## -## This file should be renamed /etc/httpd/conf/httpd.conf and Apache -## restarted to use Apache2/GridSite as a simple HTTP(S) fileserver. -## -## We assume that you have mod_gridsite.so in /usr/lib/httpd/modules -## and that you have (a) the host's hostcert.pem and hostkey.pem -## in /etc/grid-security/ and (b) the Certification Authorities' you -## trust have their root certs in /etc/grid-security/certificates -## -## (You can get RPMs for many European and North American Grid CAs -## from http://www.igtf.net/ ) -## -## If you want to use DN Lists in ACLs, they should be placed/downloaded -## in /etc/grid-security/dn-lists/ -## -## To start serving files, make a directory /var/www/html owned by -## apache.apache, including the file .gacl containing: -## -## -## -## -## -## -## -## -## -## To enable writing, add DN List, Person or VOMS entries to the GACL -## (see the GridSite GACL document for the syntax.) For example: -## -## -## -## -## -## -## -## -## -## /C=UK/O=eScience/OU=Manchester/L=HEP/CN=Andrew McNab -## -## -## -## -## -## and add the following directive to the HTTPS section: -## -## GridSiteMethods GET PUT DELETE MOVE -## -## If you wish to accept Globus GSI Proxies as well as full X.509 user -## certificates, set GridSiteGSIProxyLimit to the depth of proxy you -## wish to accept. -## -## (As a _rough_ guide: 0=No Proxies; 1=Proxy on user's machine; 2=Proxy -## owned by running Globus job; 3=Proxy delegated by a Globus job.) -## -## With this done and Apache restarted, you can upload a file with: -## -## curl -v --cert ~/.globus/usercert.pem --key ~/.globus/userkey.pem \ -## --capath /etc/grid-security/certificates --upload-file /tmp/tmp.txt \ -## https://INSERT.HOSTNAME.HERE/tmp.txt -## -## (or with --cert /tmp/x509up_u`id -u` --key /tmp/x509up_u`id -u` to use -## a Globus GSI Proxy created with grid-proxy-init.) -## -############################################################################## - -ServerRoot "/etc/httpd" - -PidFile logs/httpd.pid - -Timeout 300 -KeepAlive On -MaxKeepAliveRequests 100 -KeepAliveTimeout 300 - -# (Replace /lib/ with /lib64/ if on x86_64!) -LoadModule log_config_module /usr/lib/httpd/modules/mod_log_config.so -LoadModule ssl_module /usr/lib/httpd/modules/mod_ssl.so -LoadModule gridsite_module /usr/lib/httpd/modules/mod_gridsite.so -LoadModule mime_module /usr/lib/httpd/modules/mod_mime.so -LoadModule dir_module /usr/lib/httpd/modules/mod_dir.so - -# used for gridsite-storage tests -LoadModule alias_module /usr/lib/httpd/modules/mod_alias.so -LoadModule cgi_module /usr/lib/httpd/modules/mod_cgi.so -LoadModule env_module /usr/lib/httpd/modules/mod_env.so - -LoadModule php4_module modules/libphp4.so -AddType application/x-httpd-php .php - -TypesConfig /etc/mime.types - -# User and group who will own files created by Apache -User apache -Group apache - -DocumentRoot "/var/www/html" -DirectoryIndex index.html - - - AllowOverride None - - -LogLevel debug -LogFormat "%h \"%{SSL_CLIENT_S_DN}x\" %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined - -CustomLog logs/httpd-gridsite-access combined -ErrorLog logs/httpd-gridsite-errors - -HostnameLookups On - -# Enable SiteCast location of files via multicast -GridSiteCastGroup 224.0.1.111:488 - -###################################################################### -# Plain unauthenticated HTTP on ports 80 and 777 -###################################################################### - -Listen 80 -Listen 777 -NameVirtualHost 127.0.0.1:80 - - - -GridSiteGridHTTP on -GridSiteCastAlias http://sitecast.domain:777/ /var/www/html/ - - - GridSiteIndexes on - GridSiteAuth on - GridSiteDNlists /etc/grid-security/dn-lists/ - GridSiteHtmlFormat on - - - - -###################################################################### -# Secured and possibly authenticated HTTPS on ports 443 and 488 -###################################################################### -Listen 443 -Listen 488 -SSLSessionCacheTimeout 300 -SSLSessionCache shm:/var/cache/mod_ssl/shm_cache - - - -ServerName pc63.hep.man.ac.uk - -SSLEngine on -SSLCertificateFile /etc/grid-security/hostcert.pem -SSLCertificateKeyFile /etc/grid-security/hostkey.pem -SSLCACertificatePath /etc/grid-security/certificates -#SSLCARevocationPath YOUR CRL DIRECTORY WOULD GO HERE -SSLVerifyClient optional -SSLVerifyDepth 10 -SSLOptions +ExportCertData +StdEnvVars - -GridSiteGridHTTP on -GridSiteCastAlias https://sitecast.domain:488/ /var/www/html/ - - - SetEnv GRST_FOOTER_BLOB '