[SCM] UNNAMED PROJECT branch, master, updated. debian/6.1.1c-1-35-ged85064
Picca Frédéric-Emmanuel
picca at synchrotron-soleil.fr
Sat Mar 13 13:44:14 UTC 2010
The following commit has been merged in the master branch:
commit ed850647d0469ce21e2c1548ec1354493154615a
Author: Picca Frédéric-Emmanuel <picca at synchrotron-soleil.fr>
Date: Sat Mar 13 14:20:28 2010 +0100
* work in progress with tango_admin
diff --git a/debian/changelog b/debian/changelog
index d5de690..f0e0a0e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,7 @@ tango (7.1.1~dfsg-1) unstable; urgency=low
* update to debian-policy 3.8.3 (nothing to do)
* switch to the 3.0 (quilt) source format
* starter install the right device in the database during installation.
+ * add the tango_admin program from the CVS upstream
-- Picca Frédéric-Emmanuel <picca at synchrotron-soleil.fr> Tue, 01 Dec 2009 15:59:16 +0100
diff --git a/debian/control b/debian/control
index d6fd63b..d5901e3 100644
--- a/debian/control
+++ b/debian/control
@@ -2,7 +2,13 @@ Source: tango
Section: science
Priority: extra
Maintainer: Picca Frédéric-Emmanuel <picca at synchrotron-soleil.fr>
-Build-Depends: debhelper (>= 7.0.50), po-debconf, autotools-dev, doxygen, libcos4-dev, libmysqlclient-dev
+Build-Depends: debhelper (>= 7.0.50),
+ po-debconf,
+ autotools-dev,
+ autoconf-archive,
+ doxygen,
+ libcos4-dev,
+ libmysqlclient-dev
Standards-Version: 3.8.3
Homepage: http://www.tango-controls.org
Vcs-Git: git://git.debian.org/git/debian-science/packages/tango.git
@@ -11,7 +17,8 @@ Vcs-Browser: http://git.debian.org/?p=debian-science/packages/tango.git
Package: liblog4tango4
Section: libs
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
+Depends: ${shlibs:Depends},
+ ${misc:Depends}
Description: logging for TANGO - shared library
Log for TANGO is a library of C++ classes for flexible logging to files,
syslog and other destinations. It is modeled after the Log for
@@ -24,7 +31,8 @@ Description: logging for TANGO - shared library
Package: liblog4tango4-dev
Section: libdevel
Architecture: any
-Depends: liblog4tango4 (= ${binary:Version}), ${misc:Depends}
+Depends: liblog4tango4 (= ${binary:Version}),
+ ${misc:Depends}
Description: logging for TANGO - development library
Log for TANGO is a library of C++ classes for flexible logging to files,
syslog and other destinations. It is modeled after the Log for
@@ -37,7 +45,8 @@ Package: liblog4tango4-dbg
Section: debug
Architecture: any
Priority: extra
-Depends: liblog4tango4 (= ${binary:Version}), ${misc:Depends}
+Depends: liblog4tango4 (= ${binary:Version}),
+ ${misc:Depends}
Description: logging for TANGO - debug library
Log for TANGO is a library of C++ classes for flexible logging to files,
syslog and other destinations. It is modeled after the Log for
@@ -61,7 +70,9 @@ Description: logging for TANGO - documentation
Package: libtango7
Section: libs
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
+Depends: ${shlibs:Depends},
+ ${misc:Depends},
+ tango-common
Description: TANGO distributed control system - shared library
TANGO is an object-oriented distributed control system using CORBA. In
TANGO all objects are representations of devices, which can be on the
@@ -82,7 +93,8 @@ Description: TANGO distributed control system - shared library
Package: libtango7-dev
Section: libdevel
Architecture: any
-Depends: libtango7 (= ${binary:Version}), ${misc:Depends}
+Depends: libtango7 (= ${binary:Version}),
+ ${misc:Depends}
Description: TANGO distributed control system - development library
TANGO is an object-oriented distributed control system using CORBA. In
TANGO all objects are representations of devices, which can be on the
@@ -104,7 +116,8 @@ Package: libtango7-dbg
Section: debug
Architecture: any
Priority: extra
-Depends: libtango7 (= ${binary:Version}), ${misc:Depends}
+Depends: libtango7 (= ${binary:Version}),
+ ${misc:Depends}
Description: TANGO distributed control system - debug library
TANGO is an object-oriented distributed control system using CORBA. In
TANGO all objects are representations of devices, which can be on the
@@ -145,8 +158,10 @@ Description: TANGO distributed control system - documentation
Package: tango-common
Section: net
-Architecture: all
-Depends: ${misc:Depends}, adduser
+Architecture: any
+Depends: ${shlibs:Depends},
+ ${misc:Depends},
+ adduser
Description: TANGO distributed control system - common files
This package provides shared files for the TANGO distributed control
system, and sets up the required infrastructure.
@@ -154,7 +169,10 @@ Description: TANGO distributed control system - common files
Package: tango-db
Section: net
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base (>= 3.0-6), tango-common, dbconfig-common
+Depends: ${shlibs:Depends},
+ ${misc:Depends},
+ lsb-base (>= 3.0-6),
+ dbconfig-common
Description: TANGO distributed control system - database server
TANGO is an object oriented distributed control system. It allows
communication between TANGO device processes running on the same
@@ -167,8 +185,10 @@ Description: TANGO distributed control system - database server
Package: tango-starter
Section: net
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base (>= 3.0-6),
- tango-common, dbconfig-common, omninotify
+Depends: ${shlibs:Depends},
+ ${misc:Depends},
+ lsb-base (>= 3.0-6),
+ omninotify
Description: TANGO distributed control system - control server
TANGO is an object oriented distributed control system. It allows
communication between TANGO device processes running on the same
@@ -182,7 +202,10 @@ Description: TANGO distributed control system - control server
Package: tango-accesscontrol
Section: net
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base (>= 3.0-6), tango-common, tango-starter
+Depends: ${shlibs:Depends},
+ ${misc:Depends},
+ lsb-base (>= 3.0-6),
+ tango-starter
Description: TANGO distributed control system - accesscontrol server
TANGO is an object oriented distributed control system. It allows
communication between TANGO device processes running on the same
@@ -197,7 +220,9 @@ Description: TANGO distributed control system - accesscontrol server
Package: tango-test
Section: net
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, tango-common, tango-starter
+Depends: ${shlibs:Depends},
+ ${misc:Depends},
+ tango-starter
Description: TANGO distributed control system - test device
TANGO is an object oriented distributed control system. It allows
communication between TANGO device processes running on the same
@@ -209,9 +234,10 @@ Description: TANGO distributed control system - test device
attribute types, and can be used for testing the installation.
Package: tango-test-dbg
-Section: net
+Section: debug
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, tango-common, tango-starter
+Depends: tango-test (= ${binary:Version}),
+ ${misc:Depends}
Description: TANGO distributed control system - test device
TANGO is an object oriented distributed control system. It allows
communication between TANGO device processes running on the same
diff --git a/debian/patches/features/fix-tangotest-string-image b/debian/patches/debian/notify_daemon
similarity index 65%
copy from debian/patches/features/fix-tangotest-string-image
copy to debian/patches/debian/notify_daemon
index 67564bb..9ada366 100644
--- a/debian/patches/features/fix-tangotest-string-image
+++ b/debian/patches/debian/notify_daemon
@@ -26,14 +26,29 @@ Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>
---- tango-7.1.1~dfsg.orig/cppserver/tangotest/TangoTest.cpp
-+++ tango-7.1.1~dfsg/cppserver/tangotest/TangoTest.cpp
-@@ -1081,7 +1081,7 @@ void TangoTest::write_string_image(Tango
- {
- for (i = 0; i < dimXStringImage; i++)
- {
-- str_index = i + j * dimYStringImage;
-+ str_index = i + j * dimXStringImage;
- CORBA::string_free(attr_string_image_read[str_index]);
- attr_string_image_read[str_index] = CORBA::string_dup(p[str_index]);
- }
+--- tango-7.1.1~dfsg.orig/scripts/notify_daemon.in
++++ tango-7.1.1~dfsg/scripts/notify_daemon.in
+@@ -16,8 +16,6 @@ SunOS) KILLALL=pkill
+ esac
+
+
+-BIN_DIR=@prefix@/bin
+-
+ ulimit -s 2048
+
+ #------------------------------------------------------------
+@@ -35,12 +33,12 @@ fi
+
+ echo "TANGO_HOST=$TANGO_HOST"
+ echo "Starting notifd....."
+-$BIN_DIR/notifd -n -DDeadFilterInterval=300 1>/dev/null 2>/tmp/notifd.err &
++notifd -n -DDeadFilterInterval=300 1>/dev/null 2>/tmp/notifd.err &
+
+
+ #---- Sleep a bit before write IOR in database
+ sleep 3
+-$BIN_DIR/notifd2db
++notifd2db
+
+ echo "ulimit has been set to:"
+ ulimit -s
diff --git a/debian/patches/debian/starter b/debian/patches/debian/starter
new file mode 100644
index 0000000..b4e0497
--- /dev/null
+++ b/debian/patches/debian/starter
@@ -0,0 +1,49 @@
+Description: Upstream changes introduced in version 7.1.1~dfsg-1
+ This patch has been created by dpkg-source during the package build.
+ Here's the last changelog entry, hopefully it gives details on why
+ those changes were made:
+ .
+ tango (7.1.1~dfsg-1) unstable; urgency=low
+ .
+ * remove the "." from the DsStarterPath
+ * use the right notifd2db path
+ .
+ The person named in the Author field signed this changelog entry.
+Author: Picca Frédéric-Emmanuel <picca at synchrotron-soleil.fr>
+
+---
+The information above should follow the Patch Tagging Guidelines, please
+checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
+are templates for supplementary fields that you might want to add:
+
+Origin: <vendor|upstream|other>, <url of original patch>
+Bug: <url in upstream bugtracker>
+Bug-Debian: http://bugs.debian.org/<bugnumber>
+Forwarded: <no|not-needed|url proving that it has been forwarded>
+Reviewed-By: <name and email of someone who approved the patch>
+Last-Update: <YYYY-MM-DD>
+
+--- tango-7.1.1~dfsg.orig/cppserver/starter/Starter.cpp
++++ tango-7.1.1~dfsg/cppserver/starter/Starter.cpp
+@@ -629,9 +629,7 @@ void Starter::get_device_property()
+ //-------------------------------------------------------------
+ if (dev_prop[0].is_empty())
+ cout << "WARNING : startDsPath NOT defined !!!!" << endl;
+- if (startDsPath.size()==0)
+- startDsPath.push_back(".");
+- else
++ if (startDsPath.size()!=0)
+ for (unsigned int i=0 ; i<startDsPath.size() ; i++)
+ INFO_STREAM << "startDsPath[" << i << "] = " << startDsPath[i] << endl;
+ INFO_STREAM << "WaitForDriverStartup = " << waitForDriverStartup << " seconds" << endl;
+--- tango-7.1.1~dfsg.orig/cppserver/starter/Starter.h
++++ tango-7.1.1~dfsg/cppserver/starter/Starter.h
+@@ -157,7 +157,7 @@
+ //-----------------------------------------------
+ #define PING_TIMEOUT 3 // seconds
+ #define TIME_BETWEEN_STARTUPS 500 // Milli seconds
+-#define NOTIFY_DAEMON_SCRIPT "notify_daemon"
++#define NOTIFY_DAEMON_SCRIPT "/usr/lib/tango/notify_daemon"
+
+ // Used onlyduring the Cpp Api bug fixing on
+ // specAtt->get_max_x() method.
diff --git a/debian/patches/debian/starter-mysql.in.diff b/debian/patches/debian/starter-mysql.in.diff
deleted file mode 100644
index 7e43542..0000000
--- a/debian/patches/debian/starter-mysql.in.diff
+++ /dev/null
@@ -1,56 +0,0 @@
-Description: Upstream changes introduced in version 7.1.1~dfsg-1
- This patch has been created by dpkg-source during the package build.
- Here's the last changelog entry, hopefully it gives details on why
- those changes were made:
- .
- tango (7.1.1~dfsg-1) UNRELEASED; urgency=low
- .
- * Imported Upstream version 7.1.1~dfsg
- * add the dversionmangle in the watch file
- * update to debian-policy 3.8.3 (nothing to do)
- * switch to the 3.0 (quilt) source format
- .
- The person named in the Author field signed this changelog entry.
-Author: Picca Frédéric-Emmanuel <picca at synchrotron-soleil.fr>
-
----
-The information above should follow the Patch Tagging Guidelines, please
-checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
-are templates for supplementary fields that you might want to add:
-
-Origin: <vendor|upstream|other>, <url of original patch>
-Bug: <url in upstream bugtracker>
-Bug-Debian: http://bugs.debian.org/<bugnumber>
-Forwarded: <no|not-needed|url proving that it has been forwarded>
-Reviewed-By: <name and email of someone who approved the patch>
-Last-Update: <YYYY-MM-DD>
-
---- /dev/null
-+++ tango-7.1.1~dfsg/cppserver/starter/mysql.in
-@@ -0,0 +1,26 @@
-+#
-+# Create entry for starter device server in device table
-+#
-+
-+INSERT INTO device VALUES ('tango/admin/_hostname_',NULL,'tango','admin','_hostname_', 'nada','nada','nada','Starter/_hostname_','nada','Starter','nada','nada','nada','nada');
-+INSERT INTO device VALUES ('dserver/Starter/_hostname_',NULL,'dserver','Starter','_hostname_','nada','nada','nada','Starter/_hostname_','nada','DServer','nada','nada','nada','nada');
-+
-+#
-+# Set the device property
-+#
-+
-+INSERT INTO property_device VALUES ('tango/admin/_hostname_', 'tango', 'admin', '_hostname_', 'polled_attr', 1, 'notifdstate', NULL, NULL, NULL);
-+INSERT INTO property_device VALUES ('tango/admin/_hostname_', 'tango', 'admin', '_hostname_', 'polled_attr', 2, '1000', NULL, NULL, NULL);
-+INSERT INTO property_device VALUES ('tango/admin/_hostname_', 'tango', 'admin', '_hostname_', 'polled_attr', 3, 'servers', NULL, NULL, NULL);
-+INSERT INTO property_device VALUES ('tango/admin/_hostname_', 'tango', 'admin', '_hostname_', 'polled_attr', 4, '1000', NULL, NULL, NULL);
-+INSERT INTO property_device VALUES ('tango/admin/_hostname_', 'tango', 'admin', '_hostname_', 'polled_attr', 5, 'state', NULL, NULL, NULL);
-+INSERT INTO property_device VALUES ('tango/admin/_hostname_', 'tango', 'admin', '_hostname_', 'polled_attr', 6, '1000', NULL, NULL, NULL);
-+
-+#
-+# Set the class property:
-+#
-+
-+INSERT INTO property_class VALUES ('Starter','AllowedAccessCmd',1,'DevReadLog',NULL,NULL,NULL);
-+INSERT INTO property_class VALUES ('Starter','AllowedAccessCmd',2,'DevStart',NULL,NULL,NULL);
-+INSERT INTO property_class VALUES ('Starter','AllowedAccessCmd',3,'DevGetRunningServers',NULL,NULL,NULL);
-+INSERT INTO property_class VALUES ('Starter','AllowedAccessCmd',4,'DevGetStopServers',NULL,NULL,NULL);
diff --git a/debian/patches/debian/tango-admin b/debian/patches/debian/tango-admin
new file mode 100644
index 0000000..51d6d5e
--- /dev/null
+++ b/debian/patches/debian/tango-admin
@@ -0,0 +1,2330 @@
+Description: Upstream changes introduced in version 7.1.1~dfsg-1
+ This patch has been created by dpkg-source during the package build.
+ Here's the last changelog entry, hopefully it gives details on why
+ those changes were made:
+ .
+ tango (7.1.1~dfsg-1) unstable; urgency=low
+ .
+ * Imported Upstream version 7.1.1~dfsg
+ * add the dversionmangle in the watch file
+ * update to debian-policy 3.8.3 (nothing to do)
+ * switch to the 3.0 (quilt) source format
+ * starter install the right device in the database during installation.
+ .
+ The person named in the Author field signed this changelog entry.
+Author: Picca Frédéric-Emmanuel <picca at synchrotron-soleil.fr>
+
+---
+The information above should follow the Patch Tagging Guidelines, please
+checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
+are templates for supplementary fields that you might want to add:
+
+Origin: <vendor|upstream|other>, <url of original patch>
+Bug: <url in upstream bugtracker>
+Bug-Debian: http://bugs.debian.org/<bugnumber>
+Forwarded: <no|not-needed|url proving that it has been forwarded>
+Reviewed-By: <name and email of someone who approved the patch>
+Last-Update: <YYYY-MM-DD>
+
+--- /dev/null
++++ tango-7.1.1~dfsg/utils/tango_admin/tango_admin.cpp
+@@ -0,0 +1,839 @@
++static const char *RcsId = "$Id: tango_admin.cpp,v 1.1 2010/03/12 12:34:36 taurel Exp $";
++
++//+============================================================================
++//
++// file : tango_admin.cpp
++//
++// description : C++ source code for the tango_admin utility
++// This utility is a Tango database command line interface
++// Obviously, not all the database features are interfaced
++// by this tool. Only the features needed for the Debian
++// packaging have been implemented. This means:
++// - ping the database server
++// - check if a device is defined in DB
++// - check if a server is defined in DB
++// - create a server in DB
++// - delete a server from the DB
++// - create a property in DB
++// - delete a property from DB
++//
++// project : TANGO
++//
++// author(s) : E.Taurel
++//
++// Copyright (C) : 2004,2005,2006,2007,2008,2009,2010
++// European Synchrotron Radiation Facility
++// BP 220, Grenoble 38043
++// FRANCE
++//
++// This file is part of Tango.
++//
++// Tango is free software: you can redistribute it and/or modify
++// it under the terms of the GNU Lesser General Public License as published by
++// the Free Software Foundation, either version 3 of the License, or
++// (at your option) any later version.
++//
++// Tango is distributed in the hope that it will be useful,
++// but WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++// GNU Lesser General Public License for more details.
++//
++// You should have received a copy of the GNU Lesser General Public License
++// along with Tango. If not, see <http://www.gnu.org/licenses/>.
++//
++// $Revision: 1.1 $
++//
++//-============================================================================
++
++#include <iostream>
++#include <anyoption.h>
++#include <tango.h>
++
++using namespace std;
++
++int ping_database();
++int check_device(char *);
++int add_server(char *,char *,char *);
++void list2vect(string &,vector<string> &);
++int check_server(char *);
++int delete_server(char *,bool);
++int add_property(char *,char *,char *);
++int delete_property(char *,char *);
++
++
++int main(int argc,char *argv[])
++{
++ AnyOption *opt = new AnyOption();
++
++//
++// Add usage menu
++//
++
++ opt->addUsage("Usage: " );
++ opt->addUsage(" --help Prints this help " );
++ opt->addUsage(" --ping-database Ping database " );
++ opt->addUsage(" --check-device <dev> Check if the device is defined in DB");
++ opt->addUsage(" --add-server <exec/inst> <class> <dev list (comma separated)> Add a server in DB" );
++ opt->addUsage(" --delete-server <exec/inst> [--with-properties] Delete a server from DB" );
++ opt->addUsage(" --check-server <exec/inst> Check if a device server is defined in DB");
++ opt->addUsage(" --add-property <dev> <prop_name> <prop_value (comma separated for array)> Add a device property in DB" );
++ opt->addUsage(" --delete-property <dev> <prop_name> Delete a device property from DB ");
++
++
++//
++// Define the command line options
++//
++
++ opt->setFlag("help",'h');
++ opt->setFlag("ping-database",'c');
++ opt->setOption("add-server");
++ opt->setOption("delete-server");
++ opt->setFlag("with-properties");
++ opt->setOption("add-property");
++ opt->setOption("delete-property");
++ opt->setOption("check-device");
++ opt->setOption("check-server");
++
++//
++// Process cmd line
++//
++
++ opt->processCommandArgs( argc, argv );
++
++ if (!opt->hasOptions())
++ {
++ opt->printUsage();
++ delete opt;
++ return 0;
++ }
++
++//
++// --help option
++//
++
++ if (opt->getFlag("help") || opt->getFlag('h'))
++ {
++ opt->printUsage();
++ delete opt;
++ return 0;
++ }
++
++//
++// --ping-database option
++//
++
++ if (opt->getFlag("ping-database") == true)
++ {
++ if (opt->getValue("add-server") != NULL ||
++ opt->getValue("delete-server") != NULL ||
++ opt->getValue("add-property") != NULL ||
++ opt->getValue("delete-property") != NULL ||
++ opt->getValue("check-device") != NULL ||
++ opt->getValue("check-server") != NULL ||
++ opt->getFlag("with-properties") == true)
++ cout << "Can't mix option --check-database with other option(s)" << endl;
++
++ if (argc != 2)
++ {
++ cout << "Bad argument number for option --check-database" << endl;
++ opt->printUsage();
++ delete opt;
++ return 0;
++ }
++
++ cout << "Check database" << endl;
++ int ret;
++ ret = ping_database();
++
++ delete opt;
++ return ret;
++ }
++
++//
++// --check-device option
++//
++
++
++ else if (opt->getValue("check-device") != NULL)
++ {
++ if (opt->getValue("delete-server") != NULL ||
++ opt->getValue("add-property") != NULL ||
++ opt->getValue("delete-property") != NULL ||
++ opt->getValue("add-server") != NULL ||
++ opt->getValue("check-server") != NULL ||
++ opt->getFlag("with-properties") == true)
++ cout << "Can't mix option --add-server with other option(s)" << endl;
++ else
++ {
++ if (argc != 3)
++ {
++ cout << "Bad argument number for option --check_device" << endl;
++ opt->printUsage();
++ delete opt;
++ return 0;
++ }
++
++ int ret;
++ ret = check_device(opt->getValue("check-device"));
++
++ delete opt;
++ return ret;
++ }
++ }
++
++//
++// --add-server option
++//
++
++
++ else if (opt->getValue("add-server") != NULL)
++ {
++ if (opt->getValue("delete-server") != NULL ||
++ opt->getValue("add-property") != NULL ||
++ opt->getValue("delete-property") != NULL ||
++ opt->getValue("check-device") != NULL ||
++ opt->getValue("check-server") != NULL ||
++ opt->getFlag("with-properties") == true)
++ cout << "Can't mix option --add-server with other option(s)" << endl;
++ else
++ {
++ if (argc != 5)
++ {
++ cout << "Bad argument number for option --add-server" << endl;
++ opt->printUsage();
++ delete opt;
++ return 0;
++ }
++
++ int ret;
++ ret = add_server(opt->getValue("add-server"),opt->getArgv(0),opt->getArgv(1));
++
++ delete opt;
++ return ret;
++ }
++ }
++
++//
++// --check-server option
++//
++
++
++ else if (opt->getValue("check-server") != NULL)
++ {
++ if (opt->getValue("delete-server") != NULL ||
++ opt->getValue("add-property") != NULL ||
++ opt->getValue("delete-property") != NULL ||
++ opt->getValue("add-server") != NULL ||
++ opt->getValue("check-device") != NULL ||
++ opt->getFlag("with-properties") == true)
++ cout << "Can't mix option --check-server with other option(s)" << endl;
++ else
++ {
++ if (argc != 3)
++ {
++ cout << "Bad argument number for option --check_server" << endl;
++ opt->printUsage();
++ delete opt;
++ return 0;
++ }
++
++ int ret;
++ ret = check_server(opt->getValue("check-server"));
++
++ delete opt;
++ return ret;
++ }
++ }
++
++//
++// --delete-server option
++//
++
++ else if (opt->getValue("delete-server") != NULL)
++ {
++ if (opt->getValue("add-server") != NULL ||
++ opt->getValue("add-property") != NULL ||
++ opt->getValue("check-server") != NULL ||
++ opt->getValue("check-device") != NULL ||
++ opt->getValue("delete-property") != NULL)
++ cout << "Can't mix option --delete-server with other option(s)" << endl;
++ else
++ {
++ if ((argc < 3 || argc > 4) ||
++ (argc == 3 && strcmp(argv[2],"--with-properties") == 0) ||
++ (strcmp(opt->getValue("delete-server"),"--with-properties") == 0))
++ {
++ cout << "Bad option delete-server usage" << endl;
++ opt->printUsage();
++ delete opt;
++ return 0;
++ }
++
++ int ret;
++ if (opt->getFlag("with-properties") == true)
++ ret = delete_server(opt->getValue("delete-server"),true);
++ else
++ ret = delete_server(opt->getValue("delete-server"),false);
++
++ delete opt;
++ return ret;
++ }
++ }
++
++//
++// --add-property option
++//
++
++ else if (opt->getValue("add-property") != NULL)
++ {
++ if (opt->getValue("delete-server") != NULL ||
++ opt->getValue("delete-property") != NULL ||
++ opt->getValue("add-server") != NULL ||
++ opt->getValue("check-device") != NULL ||
++ opt->getValue("check-server") != NULL ||
++ opt->getFlag("with-properties") == true ||
++ opt->getFlag("ping-database") == true)
++ cout << "Can't mix option --add-property with other option(s)" << endl;
++ else
++ {
++ if (argc != 5)
++ {
++ cout << "Bag argument number for option --add-property" << endl;
++ opt->printUsage();
++ delete opt;
++ return 0;
++ }
++
++ int ret;
++ ret = add_property(opt->getValue("add-property"),opt->getArgv(0),opt->getArgv(1));
++
++ delete opt;
++ return ret;
++ }
++ }
++
++//
++// --delete-property option
++//
++
++ else if (opt->getValue("delete-property") != NULL)
++ {
++ if (opt->getValue("delete-server") != NULL ||
++ opt->getValue("add-property") != NULL ||
++ opt->getValue("add-server") != NULL ||
++ opt->getValue("check-device") != NULL ||
++ opt->getValue("check-server") != NULL ||
++ opt->getFlag("with-properties") == true ||
++ opt->getFlag("ping-database") == true)
++ cout << "Can't mix option --delete-property with other option(s)" << endl;
++ else
++ {
++ if (argc != 4)
++ {
++ cout << "Bag argument number for option --add-property" << endl;
++ opt->printUsage();
++ delete opt;
++ return 0;
++ }
++
++ int ret;
++ ret = delete_property(opt->getValue("delete-property"),opt->getArgv(0));
++
++ delete opt;
++ return ret;
++ }
++ }
++//
++// Unknown choice
++//
++
++ else
++ {
++ cout << "Wrong usage" << endl;
++ opt->printUsage();
++ }
++
++ delete opt;
++}
++
++//+-------------------------------------------------------------------------
++//
++// method : ping_database
++//
++// description : This function connect to the database and executes
++// one of its command in order to check the database
++// connectivity
++//
++// The function returns 0 is everything is fine. Otherwise, it returns -1
++//
++//--------------------------------------------------------------------------
++
++int ping_database()
++{
++ int ret = 0;
++
++ try
++ {
++ Tango::Database db;
++
++ string db_info;
++ db_info = db.get_info();
++ }
++ catch (Tango::DevFailed &e)
++ {
++ ret = -1;
++ }
++ return ret;
++}
++
++//+-------------------------------------------------------------------------
++//
++// method : check_device
++//
++// description : This function checks if a device is defined in the DB
++//
++// argument : in : - name : The device name
++//
++// The function returns 0 is the device is defined. Otherwise, it returns -1
++//
++//--------------------------------------------------------------------------
++
++int check_device(char *name)
++{
++ int ret = 0;
++
++ try
++ {
++ Tango::Database db;
++
++ string d_name(name);
++ Tango::DbDevImportInfo dii = db.import_device(d_name);
++ }
++ catch (Tango::DevFailed &e)
++ {
++ ret = -1;
++ }
++ return ret;
++}
++
++//+-------------------------------------------------------------------------
++//
++// method : add_server
++//
++// description : This function adds a server definition in the DB
++//
++// argument : in : - d_name : The device server name (exec/inst)
++// - c_name : The class name
++// - d_list : The device list
++//
++// The function returns 0 is everything is fine. Otherwise, it returns -1
++//
++//--------------------------------------------------------------------------
++
++int add_server(char *d_name,char *c_name,char *d_list)
++{
++ int ret = 0;
++
++//
++// Check ds name syntax
++//
++
++ string ds_name(d_name);
++ string::size_type pos;
++
++ pos = ds_name.find('/');
++ if ((count(ds_name.begin(),ds_name.end(),'/') != 1) || pos == 0 || pos == (ds_name.size() - 1))
++ {
++ cout << "Wrong syntax for ds name" << endl;
++ ret = -1;
++ return ret;
++ }
++
++//
++// Check class name syntax
++//
++
++ string class_name(c_name);
++ if (count(class_name.begin(),class_name.end(),'/') != 0)
++ {
++ cout << "Wrong syntax for class name" << endl;
++ ret = -1;
++ return ret;
++ }
++
++//
++// Check device list and device syntax
++//
++
++ string dev_list(d_list);
++ vector<string> dev_names;
++
++ list2vect(dev_list,dev_names);
++
++ for (unsigned int loop = 0;loop < dev_names.size();++loop)
++ {
++ if (count(dev_names[loop].begin(),dev_names[loop].end(),'/') != 2)
++ {
++ cout << "Wrong syntax for device " << dev_names[loop] << endl;
++ ret = -1;
++ return ret;
++ }
++
++ string::size_type pos1,pos2;
++ pos1 = dev_names[loop].find('/');
++ pos2 = dev_names[loop].rfind('/');
++
++ if (pos1 == 0 || pos2 == dev_names[loop].length() - 1 || pos2 == pos1 + 1)
++ {
++ cout << "Wrong syntax for device " << dev_names[loop] << endl;
++ ret = -1;
++ return ret;
++ }
++ }
++
++//
++// Create server in DB
++// Dont forget to add the admin device
++//
++
++ try
++ {
++ Tango::Database db;
++
++ Tango::DbDevInfos ddi;
++ Tango::DbDevInfo tmp_dbi;
++
++ for (unsigned int loop = 0;loop < dev_names.size();++loop)
++ {
++ tmp_dbi.name = dev_names[loop];
++ tmp_dbi._class = class_name;
++ tmp_dbi.server = ds_name;
++ ddi.push_back(tmp_dbi);
++ }
++ tmp_dbi.name = "dserver/" + ds_name;
++ tmp_dbi._class = "DServer";
++ tmp_dbi.server = ds_name;
++
++ ddi.push_back(tmp_dbi);
++
++ db.add_server(ds_name,ddi);
++ }
++ catch (Tango::DevFailed &e)
++ {
++ ret = -1;
++ }
++ return ret;
++}
++
++//+-------------------------------------------------------------------------
++//
++// method : check_server
++//
++// description : This function checks if a device server is defined in the DB
++//
++// argument : in : - d_name : The device server name
++//
++// The function returns 0 is the device is defined. Otherwise, it returns -1
++//
++//--------------------------------------------------------------------------
++
++int check_server(char *d_name)
++{
++ int ret = 0;
++
++ string dev_name = "dserver/";
++ string ds_name = d_name;
++
++ dev_name = dev_name + ds_name;
++
++ ret = check_device((char *)dev_name.c_str());
++
++ return ret;
++}
++
++//+-------------------------------------------------------------------------
++//
++// method : delete_server
++//
++// description : This function deletes a device server from the DB
++//
++// argument : in : - d_name : The device server name
++// - with_res : If true, also delte device properties
++//
++// The function returns 0 is everything is fine. Otherwise, it returns -1
++//
++//--------------------------------------------------------------------------
++
++int delete_server(char *d_name,bool with_res)
++{
++ int ret = 0;
++
++ string ds_name(d_name);
++
++//
++// Check device server name syntax
++//
++
++ string::size_type pos;
++ pos = ds_name.find('/');
++
++ if (pos == 0 || pos == ds_name.size() - 1 ||
++ count(ds_name.begin(),ds_name.end(),'/') != 1)
++ {
++ ret = -1;
++ return ret;
++ }
++
++ ret = check_server(d_name);
++ if (ret != 0)
++ return ret;
++
++
++ try
++ {
++
++ Tango::Database db;
++
++//
++// If we need to remove prop
++//
++
++ if (with_res == true)
++ {
++
++//
++// First get the ds class list
++//
++
++ Tango::DbDatum db_res = db.get_device_class_list(ds_name);
++ vector<string> dev_list;
++ db_res >> dev_list;
++
++//
++// Get device property name for each device
++//
++
++ for (unsigned int loop = 0;loop < dev_list.size();++loop)
++ {
++ vector<string> prop_list;
++
++ db.get_device_property_list(dev_list[loop],"*",prop_list);
++
++//
++// Delete all device properties
++//
++
++ if (prop_list.size() != 0)
++ {
++ Tango::DbData dbd;
++
++ for (unsigned int ctr = 0;ctr < prop_list.size();++ctr)
++ dbd.push_back(Tango::DbDatum(prop_list[ctr]));
++
++ db.delete_device_property(dev_list[loop],dbd);
++ }
++
++ ++loop;
++ }
++
++ }
++
++//
++// Delete device server from db
++//
++
++
++ db.delete_server(ds_name);
++ }
++ catch (Tango::DevFailed &e)
++ {
++ ret = -1;
++ }
++
++ return ret;
++}
++
++//+-------------------------------------------------------------------------
++//
++// method : add_property
++//
++// description : This function adds a device property in the DB
++//
++// argument : in : - d_name : The device name
++// - p_name : The property name
++// - p_val : The property value
++//
++// The function returns 0 is everything is fine. Otherwise, it returns -1
++//
++//--------------------------------------------------------------------------
++
++int add_property(char *d_name,char *p_name,char *p_val)
++{
++ int ret = 0;
++
++//
++// Check dev name syntax
++//
++
++ string dev_name(d_name);
++ string::size_type pos1,pos2;
++
++ pos1 = dev_name.find('/');
++ pos2 = dev_name.rfind('/');
++
++ if ((count(dev_name.begin(),dev_name.end(),'/') != 2) ||
++ pos1 == 0 || pos2 == (dev_name.size() - 1) || pos2 == pos1 + 1)
++ {
++ cout << "Wrong syntax for device name" << endl;
++ ret = -1;
++ return ret;
++ }
++
++//
++// Check if the device is defined
++//
++
++ if (check_device(d_name) != 0)
++ return -1;
++
++//
++// Convert prop value(s) into a vector
++//
++
++ string prop_val(p_val);
++ vector<string> prop_val_list;
++
++ list2vect(prop_val,prop_val_list);
++
++//
++// Create server in DB
++// Dont forget to add the admin device
++//
++
++ try
++ {
++ Tango::Database db;
++
++ Tango::DbData dbd;
++ Tango::DbDatum db_s(p_name);
++
++ db_s << prop_val_list;
++ dbd.push_back(db_s);
++
++ db.put_device_property(dev_name,dbd);
++ }
++ catch (Tango::DevFailed &e)
++ {
++ ret = -1;
++ }
++ return ret;
++}
++
++//+-------------------------------------------------------------------------
++//
++// method : delete_property
++//
++// description : This function deletes a device property from the DB
++//
++// argument : in : - d_name : The device name
++// - p_name : The property name
++//
++// The function returns 0 is everything is fine. Otherwise, it returns -1
++//
++//--------------------------------------------------------------------------
++
++int delete_property(char *d_name,char *p_name)
++{
++ int ret = 0;
++
++//
++// Check dev name syntax
++//
++
++ string dev_name(d_name);
++ string::size_type pos1,pos2;
++
++ pos1 = dev_name.find('/');
++ pos2 = dev_name.rfind('/');
++
++ if ((count(dev_name.begin(),dev_name.end(),'/') != 2) ||
++ pos1 == 0 || pos2 == (dev_name.size() - 1) || pos2 == pos1 + 1)
++ {
++ cout << "Wrong syntax for device name" << endl;
++ ret = -1;
++ return ret;
++ }
++
++//
++// Check if the device is defined
++//
++
++ if (check_device(d_name) != 0)
++ return -1;
++
++//
++// Create server in DB
++// Dont forget to add the admin device
++//
++
++ try
++ {
++ Tango::Database db;
++
++ Tango::DbData dbd;
++ dbd.push_back(Tango::DbDatum(p_name));
++
++ db.delete_device_property(dev_name,dbd);
++ }
++ catch (Tango::DevFailed &e)
++ {
++ ret = -1;
++ }
++ return ret;
++}
++
++//+-------------------------------------------------------------------------
++//
++// method : list2vect
++//
++// description : This function converts a comma separated
++// device list into a vector of strings with one
++// element for each device
++//
++// argument : in : - dev_list : The device list
++// - dev_names : The device vector
++//
++//--------------------------------------------------------------------------
++
++void list2vect(string &dev_list,vector<string> &dev_names)
++{
++ string::size_type beg,end;
++
++ bool end_loop = false;
++ beg = 0;
++
++ while (end_loop == false)
++ {
++ end = dev_list.find(',',beg);
++ if (end == beg)
++ {
++ ++beg;
++ continue;
++ }
++
++ if (end == string::npos)
++ {
++ end = dev_list.length();
++ end_loop = true;
++ }
++
++ string one_dev;
++ one_dev = dev_list.substr(beg,end - beg);
++ dev_names.push_back(one_dev);
++
++ beg = end + 1;
++ if (beg == dev_list.size())
++ end_loop = true;
++ }
++}
++
+--- /dev/null
++++ tango-7.1.1~dfsg/utils/tango_admin/anyoption.h
+@@ -0,0 +1,295 @@
++//
++// anyoption.h - include file for command line options management
++//
++//
++// Copyright (C) : 2004,2005,2006,2007,2008,2009,2010
++// European Synchrotron Radiation Facility
++// BP 220, Grenoble 38043
++// FRANCE
++//
++// This file is part of Tango.
++//
++// Tango is free software: you can redistribute it and/or modify
++// it under the terms of the GNU Lesser General Public License as published by
++// the Free Software Foundation, either version 3 of the License, or
++// (at your option) any later version.
++//
++// Tango is distributed in the hope that it will be useful,
++// but WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++// GNU Lesser General Public License for more details.
++//
++// You should have received a copy of the GNU Lesser General Public License
++// along with Tango. If not, see <http://www.gnu.org/licenses/>.
++
++#ifndef _ANYOPTION_H
++#define _ANYOPTION_H
++
++#include <iostream>
++#include <fstream>
++#include <stdlib.h>
++#include <string.h>
++
++#define COMMON_OPT 1
++#define COMMAND_OPT 2
++#define FILE_OPT 3
++#define COMMON_FLAG 4
++#define COMMAND_FLAG 5
++#define FILE_FLAG 6
++
++#define COMMAND_OPTION_TYPE 1
++#define COMMAND_FLAG_TYPE 2
++#define FILE_OPTION_TYPE 3
++#define FILE_FLAG_TYPE 4
++#define UNKNOWN_TYPE 5
++
++#define DEFAULT_MAXOPTS 10
++#define MAX_LONG_PREFIX_LENGTH 2
++
++#define DEFAULT_MAXUSAGE 3
++#define DEFAULT_MAXHELP 10
++
++#define TRUE_FLAG "true"
++
++using namespace std;
++
++class AnyOption
++{
++
++public: /* the public interface */
++ AnyOption();
++ AnyOption(int maxoptions );
++ AnyOption(int maxoptions , int maxcharoptions);
++ ~AnyOption();
++
++ /*
++ * following set methods specifies the
++ * special characters and delimiters
++ * if not set traditional defaults will be used
++ */
++
++ void setCommandPrefixChar( char _prefix ); /* '-' in "-w" */
++ void setCommandLongPrefix( char *_prefix ); /* '--' in "--width" */
++ void setFileCommentChar( char _comment ); /* '#' in shellscripts */
++ void setFileDelimiterChar( char _delimiter );/* ':' in "width : 100" */
++
++ /*
++ * provide the input for the options
++ * like argv[] for commndline and the
++ * option file name to use;
++ */
++
++ void useCommandArgs( int _argc, char **_argv );
++ void useFiileName( const char *_filename );
++
++ /*
++ * turn off the POSIX style options
++ * this means anything starting with a '-' or "--"
++ * will be considered a valid option
++ * which alo means you cannot add a bunch of
++ * POIX options chars together like "-lr" for "-l -r"
++ *
++ */
++
++ void noPOSIX();
++
++ /*
++ * prints warning verbose if you set anything wrong
++ */
++ void setVerbose();
++
++
++ /*
++ * there are two types of options
++ *
++ * Option - has an associated value ( -w 100 )
++ * Flag - no value, just a boolean flag ( -nogui )
++ *
++ * the options can be either a string ( GNU style )
++ * or a character ( traditional POSIX style )
++ * or both ( --width, -w )
++ *
++ * the options can be common to the commandline and
++ * the optionfile, or can belong only to either of
++ * commandline and optionfile
++ *
++ * following set methods, handle all the aboove
++ * cases of options.
++ */
++
++ /* options comman to command line and option file */
++ void setOption( const char *opt_string );
++ void setOption( char opt_char );
++ void setOption( const char *opt_string , char opt_char );
++ void setFlag( const char *opt_string );
++ void setFlag( char opt_char );
++ void setFlag( const char *opt_string , char opt_char );
++
++ /* options read from commandline only */
++ void setCommandOption( const char *opt_string );
++ void setCommandOption( char opt_char );
++ void setCommandOption( const char *opt_string , char opt_char );
++ void setCommandFlag( const char *opt_string );
++ void setCommandFlag( char opt_char );
++ void setCommandFlag( const char *opt_string , char opt_char );
++
++ /* options read from an option file only */
++ void setFileOption( const char *opt_string );
++ void setFileOption( char opt_char );
++ void setFileOption( const char *opt_string , char opt_char );
++ void setFileFlag( const char *opt_string );
++ void setFileFlag( char opt_char );
++ void setFileFlag( const char *opt_string , char opt_char );
++
++ /*
++ * process the options, registerd using
++ * useCommandArgs() and useFileName();
++ */
++ void processOptions();
++ void processCommandArgs();
++ void processCommandArgs( int max_args );
++ bool processFile();
++
++ /*
++ * process the specified options
++ */
++ void processCommandArgs( int _argc, char **_argv );
++ void processCommandArgs( int _argc, char **_argv, int max_args );
++ bool processFile( const char *_filename );
++
++ /*
++ * get the value of the options
++ * will return NULL if no value is set
++ */
++ char *getValue( const char *_option );
++ bool getFlag( const char *_option );
++ char *getValue( char _optchar );
++ bool getFlag( char _optchar );
++
++ /*
++ * Print Usage
++ */
++ void printUsage();
++ void printAutoUsage();
++ void addUsage( const char *line );
++ void printHelp();
++ /* print auto usage printing for unknown options or flag */
++ void autoUsagePrint(bool flag);
++
++ /*
++ * get the argument count and arguments sans the options
++ */
++ int getArgc();
++ char* getArgv( int index );
++ bool hasOptions();
++
++private: /* the hidden data structure */
++ int argc; /* commandline arg count */
++ char **argv; /* commndline args */
++ const char* filename; /* the option file */
++ char* appname; /* the application name from argv[0] */
++
++ int *new_argv; /* arguments sans options (index to argv) */
++ int new_argc; /* argument count sans the options */
++ int max_legal_args; /* ignore extra arguments */
++
++
++ /* option strings storage + indexing */
++ int max_options; /* maximum number of options */
++ const char **options; /* storage */
++ int *optiontype; /* type - common, command, file */
++ int *optionindex; /* index into value storage */
++ int option_counter; /* counter for added options */
++
++ /* option chars storage + indexing */
++ int max_char_options; /* maximum number options */
++ char *optionchars; /* storage */
++ int *optchartype; /* type - common, command, file */
++ int *optcharindex; /* index into value storage */
++ int optchar_counter; /* counter for added options */
++
++ /* values */
++ char **values; /* common value storage */
++ int g_value_counter; /* globally updated value index LAME! */
++
++ /* help and usage */
++ const char **usage; /* usage */
++ int max_usage_lines; /* max usage lines reseverd */
++ int usage_lines; /* number of usage lines */
++
++ bool command_set; /* if argc/argv were provided */
++ bool file_set; /* if a filename was provided */
++ bool mem_allocated; /* if memory allocated in init() */
++ bool posix_style; /* enables to turn off POSIX style options */
++ bool verbose; /* silent|verbose */
++ bool print_usage; /* usage verbose */
++ bool print_help; /* help verbose */
++
++ char opt_prefix_char; /* '-' in "-w" */
++ char long_opt_prefix[MAX_LONG_PREFIX_LENGTH]; /* '--' in "--width" */
++ char file_delimiter_char; /* ':' in width : 100 */
++ char file_comment_char; /* '#' in "#this is a comment" */
++ char equalsign;
++ char comment;
++ char delimiter;
++ char endofline;
++ char whitespace;
++ char nullterminate;
++
++ bool set; //was static member
++ bool once; //was static member
++
++ bool hasoptions;
++ bool autousage;
++
++private: /* the hidden utils */
++ void init();
++ void init(int maxopt, int maxcharopt );
++ bool alloc();
++ void cleanup();
++ bool valueStoreOK();
++
++ /* grow storage arrays as required */
++ bool doubleOptStorage();
++ bool doubleCharStorage();
++ bool doubleUsageStorage();
++
++ bool setValue( const char *option , char *value );
++ bool setFlagOn( const char *option );
++ bool setValue( char optchar , char *value);
++ bool setFlagOn( char optchar );
++
++ void addOption( const char* option , int type );
++ void addOption( char optchar , int type );
++ void addOptionError( const char *opt);
++ void addOptionError( char opt);
++ bool findFlag( char* value );
++ void addUsageError( const char *line );
++ bool CommandSet();
++ bool FileSet();
++ bool POSIX();
++
++ char parsePOSIX( char* arg );
++ int parseGNU( char *arg );
++ bool matchChar( char c );
++ int matchOpt( char *opt );
++
++ /* dot file methods */
++ char *readFile();
++ char *readFile( const char* fname );
++ bool consumeFile( char *buffer );
++ void processLine( char *theline, int length );
++ char *chomp( char *str );
++ void valuePairs( char *type, char *value );
++ void justValue( char *value );
++
++ void printVerbose( const char *msg );
++ void printVerbose( char *msg );
++ void printVerbose( char ch );
++ void printVerbose( );
++
++
++};
++
++#endif /* ! _ANYOPTION_H */
++
+--- /dev/null
++++ tango-7.1.1~dfsg/utils/tango_admin/anyoption.cpp
+@@ -0,0 +1,1159 @@
++static const char *RcsId = "$Id: anyoption.cpp,v 1.1 2010/03/12 12:34:36 taurel Exp $";
++
++//+============================================================================
++//
++// file : anyoption.cpp
++//
++// description : C++ source code for the AnyOption
++// class. This class is used to manage the command line
++// line arguments. This code comes from the
++// http://www.hackorama.com/anyoption.
++//
++// project : TANGO
++//
++// author(s) : Kishan Thomas (E.Taurel)
++//
++// Copyright (C) : 2004,2005,2006,2007,2008,2009,2010
++// European Synchrotron Radiation Facility
++// BP 220, Grenoble 38043
++// FRANCE
++//
++// This code (and the associated include file) comes from the following
++// web page: http://www.hackorama.com/anyoption/
++//
++// It is available there without any licensing informations.
++//
++// This file is part of Tango.
++//
++// Tango is free software: you can redistribute it and/or modify
++// it under the terms of the GNU Lesser General Public License as published by
++// the Free Software Foundation, either version 3 of the License, or
++// (at your option) any later version.
++//
++// Tango is distributed in the hope that it will be useful,
++// but WITHOUT ANY WARRANTY; without even the implied warranty of
++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++// GNU Lesser General Public License for more details.
++//
++// You should have received a copy of the GNU Lesser General Public License
++// along with Tango. If not, see <http://www.gnu.org/licenses/>.
++//
++// $Revision: 1.1 $
++//
++//-============================================================================
++
++
++#include "anyoption.h"
++
++AnyOption::AnyOption()
++{
++ init();
++}
++
++AnyOption::AnyOption(int maxopt)
++{
++ init( maxopt , maxopt );
++}
++
++AnyOption::AnyOption(int maxopt, int maxcharopt)
++{
++ init( maxopt , maxcharopt );
++}
++
++AnyOption::~AnyOption()
++{
++ if( mem_allocated )
++ cleanup();
++}
++
++void
++AnyOption::init()
++{
++ init( DEFAULT_MAXOPTS , DEFAULT_MAXOPTS );
++}
++
++void
++AnyOption::init(int maxopt, int maxcharopt )
++{
++
++ max_options = maxopt;
++ max_char_options = maxcharopt;
++ max_usage_lines = DEFAULT_MAXUSAGE;
++ usage_lines = 0 ;
++ argc = 0;
++ argv = NULL;
++ posix_style = true;
++ verbose = false;
++ filename = NULL;
++ appname = NULL;
++ option_counter = 0;
++ optchar_counter = 0;
++ new_argv = NULL;
++ new_argc = 0 ;
++ max_legal_args = 0 ;
++ command_set = false;
++ file_set = false;
++ values = NULL;
++ g_value_counter = 0;
++ mem_allocated = false;
++ command_set = false;
++ file_set = false;
++ opt_prefix_char = '-';
++ file_delimiter_char = ':';
++ file_comment_char = '#';
++ equalsign = '=';
++ comment = '#' ;
++ delimiter = ':' ;
++ endofline = '\n';
++ whitespace = ' ' ;
++ nullterminate = '\0';
++ set = false;
++ once = true;
++ hasoptions = false;
++ autousage = false;
++
++ ::strcpy( long_opt_prefix , "--" );
++
++ if( alloc() == false ){
++ cout << endl << "OPTIONS ERROR : Failed allocating memory" ;
++ cout << endl ;
++ cout << "Exiting." << endl ;
++ exit (0);
++ }
++}
++
++bool
++AnyOption::alloc()
++{
++ int i = 0 ;
++ int size = 0 ;
++
++ if( mem_allocated )
++ return true;
++
++ size = (max_options+1) * sizeof(const char*);
++ options = (const char**)malloc( size );
++ optiontype = (int*) malloc( (max_options+1)*sizeof(int) );
++ optionindex = (int*) malloc( (max_options+1)*sizeof(int) );
++ if( options == NULL || optiontype == NULL || optionindex == NULL )
++ return false;
++ else
++ mem_allocated = true;
++ for( i = 0 ; i < max_options ; i++ ){
++ options[i] = NULL;
++ optiontype[i] = 0 ;
++ optionindex[i] = -1 ;
++ }
++ optionchars = (char*) malloc( (max_char_options+1)*sizeof(char) );
++ optchartype = (int*) malloc( (max_char_options+1)*sizeof(int) );
++ optcharindex = (int*) malloc( (max_char_options+1)*sizeof(int) );
++ if( optionchars == NULL ||
++ optchartype == NULL ||
++ optcharindex == NULL )
++ {
++ mem_allocated = false;
++ return false;
++ }
++ for( i = 0 ; i < max_char_options ; i++ ){
++ optionchars[i] = '0';
++ optchartype[i] = 0 ;
++ optcharindex[i] = -1 ;
++ }
++
++ size = (max_usage_lines+1) * sizeof(const char*) ;
++ usage = (const char**) malloc( size );
++
++ if( usage == NULL ){
++ mem_allocated = false;
++ return false;
++ }
++ for( i = 0 ; i < max_usage_lines ; i++ )
++ usage[i] = NULL;
++
++ return true;
++}
++
++bool
++AnyOption::doubleOptStorage()
++{
++ options = (const char**)realloc( options,
++ ((2*max_options)+1) * sizeof( const char*) );
++ optiontype = (int*) realloc( optiontype ,
++ ((2 * max_options)+1)* sizeof(int) );
++ optionindex = (int*) realloc( optionindex,
++ ((2 * max_options)+1) * sizeof(int) );
++ if( options == NULL || optiontype == NULL || optionindex == NULL )
++ return false;
++ /* init new storage */
++ for( int i = max_options ; i < 2*max_options ; i++ ){
++ options[i] = NULL;
++ optiontype[i] = 0 ;
++ optionindex[i] = -1 ;
++ }
++ max_options = 2 * max_options ;
++ return true;
++}
++
++bool
++AnyOption::doubleCharStorage()
++{
++ optionchars = (char*) realloc( optionchars,
++ ((2*max_char_options)+1)*sizeof(char) );
++ optchartype = (int*) realloc( optchartype,
++ ((2*max_char_options)+1)*sizeof(int) );
++ optcharindex = (int*) realloc( optcharindex,
++ ((2*max_char_options)+1)*sizeof(int) );
++ if( optionchars == NULL ||
++ optchartype == NULL ||
++ optcharindex == NULL )
++ return false;
++ /* init new storage */
++ for( int i = max_char_options ; i < 2*max_char_options ; i++ ){
++ optionchars[i] = '0';
++ optchartype[i] = 0 ;
++ optcharindex[i] = -1 ;
++ }
++ max_char_options = 2 * max_char_options;
++ return true;
++}
++
++bool
++AnyOption::doubleUsageStorage()
++{
++ usage = (const char**)realloc( usage,
++ ((2*max_usage_lines)+1) * sizeof( const char*) );
++ if ( usage == NULL )
++ return false;
++ for( int i = max_usage_lines ; i < 2*max_usage_lines ; i++ )
++ usage[i] = NULL;
++ max_usage_lines = 2 * max_usage_lines ;
++ return true;
++
++}
++
++
++void
++AnyOption::cleanup()
++{
++ free (options);
++ free (optiontype);
++ free (optionindex);
++ free (optionchars);
++ free (optchartype);
++ free (optcharindex);
++ free (usage);
++ if( values != NULL )
++ free (values);
++ if( new_argv != NULL )
++ free (new_argv);
++}
++
++void
++AnyOption::setCommandPrefixChar( char _prefix )
++{
++ opt_prefix_char = _prefix;
++}
++
++void
++AnyOption::setCommandLongPrefix( char *_prefix )
++{
++ if( strlen( _prefix ) > MAX_LONG_PREFIX_LENGTH ){
++ *( _prefix + MAX_LONG_PREFIX_LENGTH ) = '\0';
++ }
++
++ strcpy (long_opt_prefix, _prefix);
++}
++
++void
++AnyOption::setFileCommentChar( char _comment )
++{
++ file_delimiter_char = _comment;
++}
++
++
++void
++AnyOption::setFileDelimiterChar( char _delimiter )
++{
++ file_comment_char = _delimiter ;
++}
++
++bool
++AnyOption::CommandSet()
++{
++ return( command_set );
++}
++
++bool
++AnyOption::FileSet()
++{
++ return( file_set );
++}
++
++void
++AnyOption::noPOSIX()
++{
++ posix_style = false;
++}
++
++bool
++AnyOption::POSIX()
++{
++ return posix_style;
++}
++
++
++void
++AnyOption::setVerbose()
++{
++ verbose = true ;
++}
++
++void
++AnyOption::printVerbose()
++{
++ if( verbose )
++ cout << endl ;
++}
++void
++AnyOption::printVerbose( const char *msg )
++{
++ if( verbose )
++ cout << msg ;
++}
++
++void
++AnyOption::printVerbose( char *msg )
++{
++ if( verbose )
++ cout << msg ;
++}
++
++void
++AnyOption::printVerbose( char ch )
++{
++ if( verbose )
++ cout << ch ;
++}
++
++bool
++AnyOption::hasOptions()
++{
++ return hasoptions;
++}
++
++void
++AnyOption::autoUsagePrint(bool _autousage)
++{
++ autousage = _autousage;
++}
++
++void
++AnyOption::useCommandArgs( int _argc, char **_argv )
++{
++ argc = _argc;
++ argv = _argv;
++ command_set = true;
++ appname = argv[0];
++ if(argc > 1) hasoptions = true;
++}
++
++void
++AnyOption::useFiileName( const char *_filename )
++{
++ filename = _filename;
++ file_set = true;
++}
++
++/*
++ * set methods for options
++ */
++
++void
++AnyOption::setCommandOption( const char *opt )
++{
++ addOption( opt , COMMAND_OPT );
++ g_value_counter++;
++}
++
++void
++AnyOption::setCommandOption( char opt )
++{
++ addOption( opt , COMMAND_OPT );
++ g_value_counter++;
++}
++
++void
++AnyOption::setCommandOption( const char *opt , char optchar )
++{
++ addOption( opt , COMMAND_OPT );
++ addOption( optchar , COMMAND_OPT );
++ g_value_counter++;
++}
++
++void
++AnyOption::setCommandFlag( const char *opt )
++{
++ addOption( opt , COMMAND_FLAG );
++ g_value_counter++;
++}
++
++void
++AnyOption::setCommandFlag( char opt )
++{
++ addOption( opt , COMMAND_FLAG );
++ g_value_counter++;
++}
++
++void
++AnyOption::setCommandFlag( const char *opt , char optchar )
++{
++ addOption( opt , COMMAND_FLAG );
++ addOption( optchar , COMMAND_FLAG );
++ g_value_counter++;
++}
++
++void
++AnyOption::setFileOption( const char *opt )
++{
++ addOption( opt , FILE_OPT );
++ g_value_counter++;
++}
++
++void
++AnyOption::setFileOption( char opt )
++{
++ addOption( opt , FILE_OPT );
++ g_value_counter++;
++}
++
++void
++AnyOption::setFileOption( const char *opt , char optchar )
++{
++ addOption( opt , FILE_OPT );
++ addOption( optchar, FILE_OPT );
++ g_value_counter++;
++}
++
++void
++AnyOption::setFileFlag( const char *opt )
++{
++ addOption( opt , FILE_FLAG );
++ g_value_counter++;
++}
++
++void
++AnyOption::setFileFlag( char opt )
++{
++ addOption( opt , FILE_FLAG );
++ g_value_counter++;
++}
++
++void
++AnyOption::setFileFlag( const char *opt , char optchar )
++{
++ addOption( opt , FILE_FLAG );
++ addOption( optchar , FILE_FLAG );
++ g_value_counter++;
++}
++
++void
++AnyOption::setOption( const char *opt )
++{
++ addOption( opt , COMMON_OPT );
++ g_value_counter++;
++}
++
++void
++AnyOption::setOption( char opt )
++{
++ addOption( opt , COMMON_OPT );
++ g_value_counter++;
++}
++
++void
++AnyOption::setOption( const char *opt , char optchar )
++{
++ addOption( opt , COMMON_OPT );
++ addOption( optchar , COMMON_OPT );
++ g_value_counter++;
++}
++
++void
++AnyOption::setFlag( const char *opt )
++{
++ addOption( opt , COMMON_FLAG );
++ g_value_counter++;
++}
++
++void
++AnyOption::setFlag( const char opt )
++{
++ addOption( opt , COMMON_FLAG );
++ g_value_counter++;
++}
++
++void
++AnyOption::setFlag( const char *opt , char optchar )
++{
++ addOption( opt , COMMON_FLAG );
++ addOption( optchar , COMMON_FLAG );
++ g_value_counter++;
++}
++
++void
++AnyOption::addOption( const char *opt, int type )
++{
++ if( option_counter >= max_options ){
++ if( doubleOptStorage() == false ){
++ addOptionError( opt );
++ return;
++ }
++ }
++ options[ option_counter ] = opt ;
++ optiontype[ option_counter ] = type ;
++ optionindex[ option_counter ] = g_value_counter;
++ option_counter++;
++}
++
++void
++AnyOption::addOption( char opt, int type )
++{
++ if( !POSIX() ){
++ printVerbose("Ignoring the option character \"");
++ printVerbose( opt );
++ printVerbose( "\" ( POSIX options are turned off )" );
++ printVerbose();
++ return;
++ }
++
++
++ if( optchar_counter >= max_char_options ){
++ if( doubleCharStorage() == false ){
++ addOptionError( opt );
++ return;
++ }
++ }
++ optionchars[ optchar_counter ] = opt ;
++ optchartype[ optchar_counter ] = type ;
++ optcharindex[ optchar_counter ] = g_value_counter;
++ optchar_counter++;
++}
++
++void
++AnyOption::addOptionError( const char *opt )
++{
++ cout << endl ;
++ cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ;
++ cout << "While adding the option : \""<< opt << "\"" << endl;
++ cout << "Exiting." << endl ;
++ cout << endl ;
++ exit(0);
++}
++
++void
++AnyOption::addOptionError( char opt )
++{
++ cout << endl ;
++ cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ;
++ cout << "While adding the option: \""<< opt << "\"" << endl;
++ cout << "Exiting." << endl ;
++ cout << endl ;
++ exit(0);
++}
++
++void
++AnyOption::processOptions()
++{
++ if( ! valueStoreOK() )
++ return;
++}
++
++void
++AnyOption::processCommandArgs(int max_args)
++{
++ max_legal_args = max_args;
++ processCommandArgs();
++}
++
++void
++AnyOption::processCommandArgs( int _argc, char **_argv, int max_args )
++{
++ max_legal_args = max_args;
++ processCommandArgs( _argc, _argv );
++}
++
++void
++AnyOption::processCommandArgs( int _argc, char **_argv )
++{
++ useCommandArgs( _argc, _argv );
++ processCommandArgs();
++}
++
++void
++AnyOption::processCommandArgs()
++{
++ if( ! ( valueStoreOK() && CommandSet() ) )
++ return;
++
++ if( max_legal_args == 0 )
++ max_legal_args = argc;
++ new_argv = (int*) malloc( (max_legal_args+1) * sizeof(int) );
++ for( int i = 1 ; i < argc ; i++ ){/* ignore first argv */
++ if( argv[i][0] == long_opt_prefix[0] &&
++ argv[i][1] == long_opt_prefix[1] ) { /* long GNU option */
++ int match_at = parseGNU( argv[i]+2 ); /* skip -- */
++ if( match_at >= 0 && i < argc-1 ) /* found match */
++ setValue( options[match_at] , argv[++i] );
++ }else if( argv[i][0] == opt_prefix_char ) { /* POSIX char */
++ if( POSIX() ){
++ char ch = parsePOSIX( argv[i]+1 );/* skip - */
++ if( ch != '0' && i < argc-1 ) /* matching char */
++ setValue( ch , argv[++i] );
++ } else { /* treat it as GNU option with a - */
++ int match_at = parseGNU( argv[i]+1 ); /* skip - */
++ if( match_at >= 0 && i < argc-1 ) /* found match */
++ setValue( options[match_at] , argv[++i] );
++ }
++ }else { /* not option but an argument keep index */
++ if( new_argc < max_legal_args ){
++ new_argv[ new_argc ] = i ;
++ new_argc++;
++ }else{ /* ignore extra arguments */
++ printVerbose( "Ignoring extra argument: " );
++ printVerbose( argv[i] );
++ printVerbose( );
++ printAutoUsage();
++ }
++ printVerbose( "Unknown command argument option : " );
++ printVerbose( argv[i] );
++ printVerbose( );
++ printAutoUsage();
++ }
++ }
++}
++
++char
++AnyOption::parsePOSIX( char* arg )
++{
++
++ for( unsigned int i = 0 ; i < strlen(arg) ; i++ ){
++ char ch = arg[i] ;
++ if( matchChar(ch) ) { /* keep matching flags till an option */
++ /*if last char argv[++i] is the value */
++ if( i == strlen(arg)-1 ){
++ return ch;
++ }else{/* else the rest of arg is the value */
++ i++; /* skip any '=' and ' ' */
++ while( arg[i] == whitespace
++ || arg[i] == equalsign )
++ i++;
++ setValue( ch , arg+i );
++ return '0';
++ }
++ }
++ }
++ printVerbose( "Unknown command argument option : " );
++ printVerbose( arg );
++ printVerbose( );
++ printAutoUsage();
++ return '0';
++}
++
++int
++AnyOption::parseGNU( char *arg )
++{
++ int split_at = 0;
++ /* if has a '=' sign get value */
++ for( unsigned int i = 0 ; i < strlen(arg) ; i++ ){
++ if(arg[i] == equalsign ){
++ split_at = i ; /* store index */
++ i = strlen(arg); /* get out of loop */
++ }
++ }
++ if( split_at > 0 ){ /* it is an option value pair */
++ char* tmp = (char*) malloc( (split_at+1)*sizeof(char) );
++ for( int i = 0 ; i < split_at ; i++ )
++ tmp[i] = arg[i];
++ tmp[split_at] = '\0';
++
++ if ( matchOpt( tmp ) >= 0 ){
++ setValue( options[matchOpt(tmp)] , arg+split_at+1 );
++ free (tmp);
++ }else{
++ printVerbose( "Unknown command argument option : " );
++ printVerbose( arg );
++ printVerbose( );
++ printAutoUsage();
++ free (tmp);
++ return -1;
++ }
++ }else{ /* regular options with no '=' sign */
++ return matchOpt(arg);
++ }
++ return -1;
++}
++
++
++int
++AnyOption::matchOpt( char *opt )
++{
++ for( int i = 0 ; i < option_counter ; i++ ){
++ if( strcmp( options[i], opt ) == 0 ){
++ if( optiontype[i] == COMMON_OPT ||
++ optiontype[i] == COMMAND_OPT )
++ { /* found option return index */
++ return i;
++ }else if( optiontype[i] == COMMON_FLAG ||
++ optiontype[i] == COMMAND_FLAG )
++ { /* found flag, set it */
++ setFlagOn( opt );
++ return -1;
++ }
++ }
++ }
++ printVerbose( "Unknown command argument option : " );
++ printVerbose( opt ) ;
++ printVerbose( );
++ printAutoUsage();
++ return -1;
++}
++bool
++AnyOption::matchChar( char c )
++{
++ for( int i = 0 ; i < optchar_counter ; i++ ){
++ if( optionchars[i] == c ) { /* found match */
++ if(optchartype[i] == COMMON_OPT ||
++ optchartype[i] == COMMAND_OPT )
++ { /* an option store and stop scanning */
++ return true;
++ }else if( optchartype[i] == COMMON_FLAG ||
++ optchartype[i] == COMMAND_FLAG ) { /* a flag store and keep scanning */
++ setFlagOn( c );
++ return false;
++ }
++ }
++ }
++ printVerbose( "Unknown command argument option : " );
++ printVerbose( c ) ;
++ printVerbose( );
++ printAutoUsage();
++ return false;
++}
++
++bool
++AnyOption::valueStoreOK( )
++{
++ int size= 0;
++ if( !set ){
++ if( g_value_counter > 0 ){
++ size = g_value_counter * sizeof(char*);
++ values = (char**)malloc( size );
++ for( int i = 0 ; i < g_value_counter ; i++)
++ values[i] = NULL;
++ set = true;
++ }
++ }
++ return set;
++}
++
++/*
++ * public get methods
++ */
++char*
++AnyOption::getValue( const char *option )
++{
++ if( !valueStoreOK() )
++ return NULL;
++
++ for( int i = 0 ; i < option_counter ; i++ ){
++ if( strcmp( options[i], option ) == 0 )
++ return values[ optionindex[i] ];
++ }
++ return NULL;
++}
++
++bool
++AnyOption::getFlag( const char *option )
++{
++ if( !valueStoreOK() )
++ return false;
++ for( int i = 0 ; i < option_counter ; i++ ){
++ if( strcmp( options[i], option ) == 0 )
++ return findFlag( values[ optionindex[i] ] );
++ }
++ return false;
++}
++
++char*
++AnyOption::getValue( char option )
++{
++ if( !valueStoreOK() )
++ return NULL;
++ for( int i = 0 ; i < optchar_counter ; i++ ){
++ if( optionchars[i] == option )
++ return values[ optcharindex[i] ];
++ }
++ return NULL;
++}
++
++bool
++AnyOption::getFlag( char option )
++{
++ if( !valueStoreOK() )
++ return false;
++ for( int i = 0 ; i < optchar_counter ; i++ ){
++ if( optionchars[i] == option )
++ return findFlag( values[ optcharindex[i] ] ) ;
++ }
++ return false;
++}
++
++bool
++AnyOption::findFlag( char* val )
++{
++ if( val == NULL )
++ return false;
++
++ if( strcmp( TRUE_FLAG , val ) == 0 )
++ return true;
++
++ return false;
++}
++
++/*
++ * private set methods
++ */
++bool
++AnyOption::setValue( const char *option , char *value )
++{
++ if( !valueStoreOK() )
++ return false;
++ for( int i = 0 ; i < option_counter ; i++ ){
++ if( strcmp( options[i], option ) == 0 ){
++ values[ optionindex[i] ] = (char*) malloc((strlen(value)+1)*sizeof(char));
++ strcpy( values[ optionindex[i] ], value );
++ return true;
++ }
++ }
++ return false;
++}
++
++bool
++AnyOption::setFlagOn( const char *option )
++{
++ if( !valueStoreOK() )
++ return false;
++ for( int i = 0 ; i < option_counter ; i++ ){
++ if( strcmp( options[i], option ) == 0 ){
++ values[ optionindex[i] ] = (char*) malloc((strlen(TRUE_FLAG)+1)*sizeof(char));
++ strcpy( values[ optionindex[i] ] , TRUE_FLAG );
++ return true;
++ }
++ }
++ return false;
++}
++
++bool
++AnyOption::setValue( char option , char *value )
++{
++ if( !valueStoreOK() )
++ return false;
++ for( int i = 0 ; i < optchar_counter ; i++ ){
++ if( optionchars[i] == option ){
++ values[ optcharindex[i] ] = (char*) malloc((strlen(value)+1)*sizeof(char));
++ strcpy( values[ optcharindex[i] ], value );
++ return true;
++ }
++ }
++ return false;
++}
++
++bool
++AnyOption::setFlagOn( char option )
++{
++ if( !valueStoreOK() )
++ return false;
++ for( int i = 0 ; i < optchar_counter ; i++ ){
++ if( optionchars[i] == option ){
++ values[ optcharindex[i] ] = (char*) malloc((strlen(TRUE_FLAG)+1)*sizeof(char));
++ strcpy( values[ optcharindex[i] ] , TRUE_FLAG );
++ return true;
++ }
++ }
++ return false;
++}
++
++
++int
++AnyOption::getArgc( )
++{
++ return new_argc;
++}
++
++char*
++AnyOption::getArgv( int index )
++{
++ if( index < new_argc ){
++ return ( argv[ new_argv[ index ] ] );
++ }
++ return NULL;
++}
++
++/* dotfile sub routines */
++
++bool
++AnyOption::processFile()
++{
++ if( ! (valueStoreOK() && FileSet()) )
++ return false;
++ return ( consumeFile(readFile()) );
++}
++
++bool
++AnyOption::processFile( const char *filename )
++{
++ useFiileName(filename );
++ return ( processFile() );
++}
++
++char*
++AnyOption::readFile()
++{
++ return ( readFile(filename) );
++}
++
++/*
++ * read the file contents to a character buffer
++ */
++
++char*
++AnyOption::readFile( const char* fname )
++{
++ int length;
++ char *buffer;
++ ifstream is;
++ is.open ( fname , ifstream::in );
++ if( ! is.good() ){
++ is.close();
++ return NULL;
++ }
++ is.seekg (0, ios::end);
++ length = is.tellg();
++ is.seekg (0, ios::beg);
++ buffer = (char*) malloc(length*sizeof(char));
++ is.read (buffer,length);
++ is.close();
++ return buffer;
++}
++
++/*
++ * scans a char* buffer for lines that does not
++ * start with the specified comment character.
++ */
++bool
++AnyOption::consumeFile( char *buffer )
++{
++
++ if( buffer == NULL )
++ return false;
++
++ char *cursor = buffer;/* preserve the ptr */
++ char *pline = NULL ;
++ int linelength = 0;
++ bool newline = true;
++ for( unsigned int i = 0 ; i < strlen( buffer ) ; i++ ){
++ if( *cursor == endofline ) { /* end of line */
++ if( pline != NULL ) /* valid line */
++ processLine( pline, linelength );
++ pline = NULL;
++ newline = true;
++ }else if( newline ){ /* start of line */
++ newline = false;
++ if( (*cursor != comment ) ){ /* not a comment */
++ pline = cursor ;
++ linelength = 0 ;
++ }
++ }
++ cursor++; /* keep moving */
++ linelength++;
++ }
++ free (buffer);
++ return true;
++}
++
++
++/*
++ * find a valid type value pair separated by a delimiter
++ * character and pass it to valuePairs()
++ * any line which is not valid will be considered a value
++ * and will get passed on to justValue()
++ *
++ * assuming delimiter is ':' the behaviour will be,
++ *
++ * width:10 - valid pair valuePairs( width, 10 );
++ * width : 10 - valid pair valuepairs( width, 10 );
++ *
++ * :::: - not valid
++ * width - not valid
++ * :10 - not valid
++ * width: - not valid
++ * :: - not valid
++ * : - not valid
++ *
++ */
++
++void
++AnyOption::processLine( char *theline, int length )
++{
++ bool found = false;
++ char *pline = (char*) malloc( (length+1)*sizeof(char) );
++ for( int i = 0 ; i < length ; i ++ )
++ pline[i]= *(theline++);
++ pline[length] = nullterminate;
++ char *cursor = pline ; /* preserve the ptr */
++ if( *cursor == delimiter || *(cursor+length-1) == delimiter ){
++ justValue( pline );/* line with start/end delimiter */
++ }else{
++ for( int i = 1 ; i < length-1 && !found ; i++){/* delimiter */
++ if( *cursor == delimiter ){
++ *(cursor-1) = nullterminate; /* two strings */
++ found = true;
++ valuePairs( pline , cursor+1 );
++ }
++ cursor++;
++ }
++ cursor++;
++ if( !found ) /* not a pair */
++ justValue( pline );
++ }
++ free (pline);
++}
++
++/*
++ * removes trailing and preceeding whitespaces from a string
++ */
++char*
++AnyOption::chomp( char *str )
++{
++ while( *str == whitespace )
++ str++;
++ char *end = str+strlen(str)-1;
++ while( *end == whitespace )
++ end--;
++ *(end+1) = nullterminate;
++ return str;
++}
++
++void
++AnyOption::valuePairs( char *type, char *value )
++{
++ if ( strlen(chomp(type)) == 1 ){ /* this is a char option */
++ for( int i = 0 ; i < optchar_counter ; i++ ){
++ if( optionchars[i] == type[0] ){ /* match */
++ if( optchartype[i] == COMMON_OPT ||
++ optchartype[i] == FILE_OPT )
++ {
++ setValue( type[0] , chomp(value) );
++ return;
++ }
++ }
++ }
++ }
++ /* if no char options matched */
++ for( int i = 0 ; i < option_counter ; i++ ){
++ if( strcmp( options[i], type ) == 0 ){ /* match */
++ if( optiontype[i] == COMMON_OPT ||
++ optiontype[i] == FILE_OPT )
++ {
++ setValue( type , chomp(value) );
++ return;
++ }
++ }
++ }
++ printVerbose( "Unknown option in resourcefile : " );
++ printVerbose( type );
++ printVerbose( );
++}
++
++void
++AnyOption::justValue( char *type )
++{
++
++ if ( strlen(chomp(type)) == 1 ){ /* this is a char option */
++ for( int i = 0 ; i < optchar_counter ; i++ ){
++ if( optionchars[i] == type[0] ){ /* match */
++ if( optchartype[i] == COMMON_FLAG ||
++ optchartype[i] == FILE_FLAG )
++ {
++ setFlagOn( type[0] );
++ return;
++ }
++ }
++ }
++ }
++ /* if no char options matched */
++ for( int i = 0 ; i < option_counter ; i++ ){
++ if( strcmp( options[i], type ) == 0 ){ /* match */
++ if( optiontype[i] == COMMON_FLAG ||
++ optiontype[i] == FILE_FLAG )
++ {
++ setFlagOn( type );
++ return;
++ }
++ }
++ }
++ printVerbose( "Unknown option in resourcefile : " );
++ printVerbose( type );
++ printVerbose( );
++}
++
++/*
++ * usage and help
++ */
++
++
++void
++AnyOption::printAutoUsage()
++{
++ if( autousage ) printUsage();
++}
++
++void
++AnyOption::printUsage()
++{
++
++ if( once ) {
++ once = false ;
++ cout << endl ;
++ for( int i = 0 ; i < usage_lines ; i++ )
++ cout << usage[i] << endl ;
++ cout << endl ;
++ }
++}
++
++
++void
++AnyOption::addUsage( const char *line )
++{
++ if( usage_lines >= max_usage_lines ){
++ if( doubleUsageStorage() == false ){
++ addUsageError( line );
++ exit(1);
++ }
++ }
++ usage[ usage_lines ] = line ;
++ usage_lines++;
++}
++
++void
++AnyOption::addUsageError( const char *line )
++{
++ cout << endl ;
++ cout << "OPTIONS ERROR : Failed allocating extra memory " << endl ;
++ cout << "While adding the usage/help : \""<< line << "\"" << endl;
++ cout << "Exiting." << endl ;
++ cout << endl ;
++ exit(0);
++
++}
++
diff --git a/debian/patches/features/fix-tangotest-string-image b/debian/patches/features/tango-admin-pkg
similarity index 54%
copy from debian/patches/features/fix-tangotest-string-image
copy to debian/patches/features/tango-admin-pkg
index 67564bb..452b3cb 100644
--- a/debian/patches/features/fix-tangotest-string-image
+++ b/debian/patches/features/tango-admin-pkg
@@ -26,14 +26,38 @@ Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>
---- tango-7.1.1~dfsg.orig/cppserver/tangotest/TangoTest.cpp
-+++ tango-7.1.1~dfsg/cppserver/tangotest/TangoTest.cpp
-@@ -1081,7 +1081,7 @@ void TangoTest::write_string_image(Tango
- {
- for (i = 0; i < dimXStringImage; i++)
- {
-- str_index = i + j * dimYStringImage;
-+ str_index = i + j * dimXStringImage;
- CORBA::string_free(attr_string_image_read[str_index]);
- attr_string_image_read[str_index] = CORBA::string_dup(p[str_index]);
- }
+--- tango-7.1.1~dfsg.orig/configure.in
++++ tango-7.1.1~dfsg/configure.in
+@@ -413,6 +413,7 @@ AC_OUTPUT(Makefile
+ cppserver/tangoaccesscontrol/Makefile
+ utils/Makefile
+ utils/notifd2db/Makefile
++ utils/tango_admin/Makefile
+ scripts/Makefile
+ scripts/jive
+ scripts/logviewer
+--- tango-7.1.1~dfsg.orig/utils/Makefile.am
++++ tango-7.1.1~dfsg/utils/Makefile.am
+@@ -1,2 +1,2 @@
+
+-SUBDIRS = notifd2db
++SUBDIRS = notifd2db tango_admin
+--- /dev/null
++++ tango-7.1.1~dfsg/utils/tango_admin/Makefile.am
+@@ -0,0 +1,16 @@
++INCLUDES = -I$(top_srcdir)/lib/cpp/client \
++ -I$(top_srcdir)/lib/cpp/server $(ORB_INCLUDE_PREFIX) \
++ -I$(top_srcdir)/lib/cpp/log4tango/include \
++ -I$(top_builddir)/lib/cpp/log4tango/include
++
++LDADD = -L$(top_builddir)/lib/cpp/server -ltango \
++ -L$(top_builddir)/lib/cpp/log4tango/src -llog4tango
++
++bin_PROGRAMS=tango_admin
++
++tango_admin_SOURCES=\
++ tango_admin.cpp \
++ anyoption.cpp \
++ anyoption.h
++
++
diff --git a/debian/patches/series b/debian/patches/series
index 69e56ff..cc35b89 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,5 +1,8 @@
debian/fix_database_scripts.diff -p1
debian/my.cnf.in.diff -p1
-debian/starter-mysql.in.diff -p1
+debian/starter -p1
+debian/tango-admin -p1
+debian/notify_daemon -p1
features/fix_libtango_compilation.diff -p1
features/fix-tangotest-string-image -p1
+features/tango-admin-pkg -p1
diff --git a/debian/rules b/debian/rules
index 59a377d..1ca1c59 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,34 +1,44 @@
#!/usr/bin/make -f
+BUILDROOT=build
+
+get-orig-source:
+ uscan --verbose --force-download
+
override_dh_auto_configure:
- dh_auto_configure -- --with-omni=/usr --disable-dbcreate --disable-java
+ mkdir -p "$(CURDIR)/$(BUILDROOT)"
+ for f in "$(CURDIR)"/*; do cp -arf "$$f" "$(CURDIR)/$(BUILDROOT)/"; done
+ cd "$(CURDIR)/$(BUILDROOT)" && autoreconf -fi -I m4
+ cd "$(CURDIR)/$(BUILDROOT)" && dh_auto_configure -- --with-omni=/usr --disable-dbcreate --disable-java
+
+override_dh_auto_clean:
+ rm -rf "$(CURDIR)/$(BUILDROOT)"
-override_dh_clean:
- rm -f config.log
- rm -f ac_config.h
- rm -f ac_config.h.old
- dh_clean
+override_dh_auto_build:
+ cd "$(CURDIR)/$(BUILDROOT)" && dh_auto_build
+
+override_dh_auto_install:
+ cd "$(CURDIR)/$(BUILDROOT)" && dh_auto_install --destdir="$(CURDIR)/debian/tmp/"
override_dh_auto_install:
# install dbconfig-common scripts
install -d debian/tmp/usr/share/dbconfig-common/data/tango-db/install
- install -p -m 644 cppserver/database/create_db.sql debian/tmp/usr/share/dbconfig-common/data/tango-db/install/mysql
+ install -p -m 644 $(CURDIR)/$(BUILDROOT)/cppserver/database/create_db.sql debian/tmp/usr/share/dbconfig-common/data/tango-db/install/mysql
# install scripts used during the configuration
install -d debian/tmp/usr/share/tango-db
- install -p -m 644 cppserver/database/create_db_tables.sql debian/tmp/usr/share/tango-db/create_db_tables.sql
- install -p -m 644 cppserver/database/stored_proc.sql debian/tmp/usr/share/tango-db/stored_proc.sql
- install -p -m 600 cppserver/database/my.cnf debian/tmp/usr/share/tango-db/my.cnf
- # template for the starter installation
- install -d debian/tmp/usr/share/tango-starter
- install -p -m 600 cppserver/starter/mysql.in debian/tmp/usr/share/tango-starter/mysql.in
- dh_auto_install
+ install -p -m 644 $(CURDIR)/$(BUILDROOT)/cppserver/database/create_db_tables.sql debian/tmp/usr/share/tango-db/create_db_tables.sql
+ install -p -m 644 $(CURDIR)/$(BUILDROOT)/cppserver/database/stored_proc.sql debian/tmp/usr/share/tango-db/stored_proc.sql
+ install -p -m 600 $(CURDIR)/$(BUILDROOT)/cppserver/database/my.cnf debian/tmp/usr/share/tango-db/my.cnf
+ cd "$(CURDIR)/$(BUILDROOT)" && dh_auto_install --destdir="$(CURDIR)/debian/tmp/"
override_dh_strip:
dh_strip -plibtango7 --dbg-package=libtango7-dbg
dh_strip -pliblog4tango4 --dbg-package=liblog4tango4-dbg
dh_strip -ptango-test --dbg-package=tango-test-dbg
- dh_strip -a -Nlibtango7 -Nliblog4tango4 -Ntango-starter
+ dh_strip -a -Nlibtango7 -Nliblog4tango4 -Ntango-test
%:
dh $@
+.PHONY: get-orig-source
+
diff --git a/debian/tango-accesscontrol.init.d b/debian/tango-accesscontrol.init.d
index 843c1a2..f02bf51 100644
--- a/debian/tango-accesscontrol.init.d
+++ b/debian/tango-accesscontrol.init.d
@@ -64,7 +64,7 @@ do_stop()
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
- start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --exec $DAEMON
+ start-stop-daemon --stop --quiet --retry=TERM/5/KILL/5 --pidfile $PIDFILE --exec $DAEMON
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
@@ -73,7 +73,7 @@ do_stop()
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
- start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
+ start-stop-daemon --stop --quiet --oknodo --retry=0/5/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
diff --git a/debian/tango-common.install b/debian/tango-common.install
new file mode 100644
index 0000000..6c6d3ee
--- /dev/null
+++ b/debian/tango-common.install
@@ -0,0 +1 @@
+usr/bin/tango_admin usr/lib/tango
\ No newline at end of file
diff --git a/debian/tango-starter.config b/debian/tango-starter.config
deleted file mode 100644
index 95d1f1e..0000000
--- a/debian/tango-starter.config
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-# config maintainer script for foo-mysql
-
-set -e
-
-# source debconf stuff
-. /usr/share/debconf/confmodule
-
-# source dbconfig-common shell library, and call the hook function
-if [ -f /usr/share/dbconfig-common/dpkg/config.mysql ]; then
- dbc_dbname="tango"
- dbc_dbuser="tango"
- . /usr/share/dbconfig-common/dpkg/config.mysql
- dbc_go tango-starter $@
-fi
diff --git a/debian/tango-starter.init.d b/debian/tango-starter.init.d
index c5a5fde..96b5003 100644
--- a/debian/tango-starter.init.d
+++ b/debian/tango-starter.init.d
@@ -14,7 +14,7 @@
# Author: Picca Frédéric-Emmanuel <picca at synchrotron-soleil.fr>
-PATH=/sbin:/usr/sbin:/bin:/usr/bin
+PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/lib/tango
DESC="Tango Control System - starter"
NAME=tango-starter
NAME_REAL=Starter
@@ -42,7 +42,13 @@ do_start()
# Return
# 0 if daemon has been started
# 1 if daemon was already running
- # 2 if daemon could not be started
+ # 2 if daemon could not be started
+
+ # first check for a running tango-database and
+ tango_admin --ping-database || return 2
+ #register the tango-starter if necessary
+ tango_admin --check-device tango/admin/`hostname` || tango_admin --add-server Starter/`hostname` Starter tango/admin/`hostname` || return 2
+
start-stop-daemon --start --quiet --chuid tango:tango --background \
--make-pidfile --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
diff --git a/debian/tango-starter.install b/debian/tango-starter.install
index d31e28a..c344bec 100644
--- a/debian/tango-starter.install
+++ b/debian/tango-starter.install
@@ -1,3 +1,3 @@
usr/bin/Starter usr/lib/tango
-usr/share/tango-starter
-usr/bin/notify_daemon usr/lib/tango
\ No newline at end of file
+usr/bin/notify_daemon usr/lib/tango
+usr/bin/notifd2db usr/lib/tango
\ No newline at end of file
diff --git a/debian/tango-starter.postinst b/debian/tango-starter.postinst
deleted file mode 100644
index 3a76b58..0000000
--- a/debian/tango-starter.postinst
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-set -e
-
-#first generate the right template for dbconfig-common
-mkdir -p /usr/share/dbconfig-common/data/tango-starter/install
-hostname | xargs -I HOSTNAME sed -e 's/\_hostname\_/HOSTNAME/g' /usr/share/tango-starter/mysql.in > /usr/share/dbconfig-common/data/tango-starter/install/mysql
-
-. /usr/share/debconf/confmodule
-. /usr/share/dbconfig-common/dpkg/postinst.mysql
-
-dbc_go tango-starter $@
-
-#DEBHELPER#
diff --git a/debian/tango-starter.postrm b/debian/tango-starter.postrm
deleted file mode 100644
index 2516102..0000000
--- a/debian/tango-starter.postrm
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-set -e
-
-if [ -f /usr/share/debconf/confmodule ]; then
- . /usr/share/debconf/confmodule
-fi
-if [ -f /usr/share/dbconfig-common/dpkg/postrm.mysql ]; then
- . /usr/share/dbconfig-common/dpkg/postrm.mysql
- dbc_go tango-starter $@
-fi
-
-if [ "$1" = "purge" ]; then
- rm -f /usr/share/dbconfig-common/data/tango-starter/install/mysql
-fi
-
-#DEBHELPER#
diff --git a/debian/tango-starter.prerm b/debian/tango-starter.prerm
deleted file mode 100644
index a570aed..0000000
--- a/debian/tango-starter.prerm
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-set -e
-
-. /usr/share/debconf/confmodule
-. /usr/share/dbconfig-common/dpkg/prerm.mysql
-dbc_go tango-starter $@
-
-#DEBHELPER#
--
UNNAMED PROJECT
More information about the debian-science-commits
mailing list