release
[tango-nonfree.git] / utils / tango_admin / tango_admin.cpp
blob3dff5e96179dbb253f815044ba6249c187d9937c
1 static const char *RcsId = "$Id: tango_admin.cpp 27948 2015-05-05 14:29:24Z taurel $";
3 //+============================================================================
4 //
5 // file : tango_admin.cpp
6 //
7 // description : C++ source code for the tango_admin utility
8 // This utility is a Tango database command line interface
9 // Obviously, not all the database features are interfaced
10 // by this tool. Only the features needed for the Debian
11 // packaging have been implemented. This means:
12 // - ping the database server
13 // - check if a device is defined in DB
14 // - check if a server is defined in DB
15 // - create a server in DB
16 // - delete a server from the DB
17 // - create a property in DB
18 // - delete a property from DB
20 // project : TANGO
22 // author(s) : E.Taurel
24 // Copyright (C) : 2004,2005,2006,2007,2008,2009,2010
25 // European Synchrotron Radiation Facility
26 // BP 220, Grenoble 38043
27 // FRANCE
29 // This file is part of Tango.
31 // Tango is free software: you can redistribute it and/or modify
32 // it under the terms of the GNU General Public License as published by
33 // the Free Software Foundation, either version 3 of the License, or
34 // (at your option) any later version.
35 //
36 // Tango is distributed in the hope that it will be useful,
37 // but WITHOUT ANY WARRANTY; without even the implied warranty of
38 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 // GNU General Public License for more details.
40 //
41 // You should have received a copy of the GNU General Public License
42 // along with Tango. If not, see <http://www.gnu.org/licenses/>.
44 // $Revision: 27948 $
46 //-============================================================================
48 #if HAVE_CONFIG_H
49 #include <ac_config.h>
50 #endif
52 #include <iostream>
53 #include <anyoption.h>
54 #include <tango.h>
56 #include <time.h>
57 #include <sys/types.h>
58 #include <sys/socket.h>
59 #include <netdb.h>
61 #include <stdlib.h>
63 using namespace std;
66 int ping_database(int);
67 int check_device(char *);
68 int add_server(char *,char *,char *);
69 void list2vect(string &,vector<string> &);
70 int check_server(char *);
71 int server_list();
72 int server_instance_list(char *);
73 int delete_server(char *,bool);
74 int add_property(char *,char *,char *);
75 int delete_property(char *,char *);
76 int ping_network(int,bool);
77 int check_net(bool);
78 int tac_enabled(void);
79 int ping_device(char *,int);
80 int check_dev(char *);
83 int main(int argc,char *argv[])
85 AnyOption *opt = new AnyOption();
88 // Add usage menu
91 opt->addUsage("Usage: " );
92 opt->addUsage(" --help Prints this help " );
93 opt->addUsage(" --ping-database [max_time (s)] Ping database " );
94 opt->addUsage(" --check-device <dev> Check if the device is defined in DB");
95 opt->addUsage(" --add-server <exec/inst> <class> <dev list (comma separated)> Add a server in DB" );
96 opt->addUsage(" --delete-server <exec/inst> [--with-properties] Delete a server from DB" );
97 opt->addUsage(" --check-server <exec/inst> Check if a device server is defined in DB");
98 opt->addUsage(" --server-list Display list of server names");
99 opt->addUsage(" --server-instance-list <exec> Display list of server instances for the given server name");
100 opt->addUsage(" --add-property <dev> <prop_name> <prop_value (comma separated for array)> Add a device property in DB" );
101 opt->addUsage(" --delete-property <dev> <prop_name> Delete a device property from DB ");
102 opt->addUsage(" --tac-enabled Check if the TAC (Tango Access Control) is enabled");
103 opt->addUsage(" --ping-device <dev> [max_time (s)] Check if the device is running");
104 opt->addUsage(" --ping-network [max_time (s)] [-v] Ping network ");
107 // Define the command line options
110 opt->setFlag("help",'h');
111 opt->setFlag("ping-database");
112 opt->setOption("add-server");
113 opt->setOption("delete-server");
114 opt->setFlag("with-properties");
115 opt->setOption("add-property");
116 opt->setOption("delete-property");
117 opt->setOption("check-device");
118 opt->setOption("check-server");
119 opt->setFlag("server-list");
120 opt->setOption("server-instance-list");
121 opt->setOption("ping-device");
122 opt->setFlag("ping-network");
123 opt->setFlag("tac-enabled");
126 // Process cmd line
129 opt->processCommandArgs( argc, argv );
131 if (!opt->hasOptions())
133 opt->printUsage();
134 delete opt;
135 return 0;
139 // --help option
142 if (opt->getFlag("help") || opt->getFlag('h'))
144 opt->printUsage();
145 delete opt;
146 return 0;
150 // --ping-database option
153 if (opt->getFlag("ping-database") == true)
155 if (opt->getValue("add-server") != NULL ||
156 opt->getValue("delete-server") != NULL ||
157 opt->getValue("add-property") != NULL ||
158 opt->getValue("delete-property") != NULL ||
159 opt->getValue("check-device") != NULL ||
160 opt->getValue("check-server") != NULL ||
161 opt->getValue("server-instance-list") != NULL ||
162 opt->getFlag("server-list") == true ||
163 opt->getFlag("ping-network") == true ||
164 opt->getFlag("tac-enabled") == true ||
165 opt->getFlag("with-properties") == true)
166 cout << "Can't mix option --ping-database with other option(s)" << endl;
168 if (argc > 3)
170 cout << "Bad argument number for option --ping-database" << endl;
171 opt->printUsage();
172 delete opt;
173 return 0;
176 int ret;
177 if (argc == 2)
178 ret = ping_database(0);
179 else
181 int sec = atoi(argv[2]);
182 ret = ping_database(sec);
185 delete opt;
186 return ret;
190 // --check-device option
194 else if (opt->getValue("check-device") != NULL)
196 if (opt->getValue("delete-server") != NULL ||
197 opt->getValue("add-property") != NULL ||
198 opt->getValue("delete-property") != NULL ||
199 opt->getValue("add-server") != NULL ||
200 opt->getValue("check-server") != NULL ||
201 opt->getValue("server-instance-list") != NULL ||
202 opt->getFlag("server-list") == true ||
203 opt->getFlag("ping-network") == true ||
204 opt->getFlag("tac-enabled") == true ||
205 opt->getFlag("with-properties") == true)
206 cout << "Can't mix option --add-server with other option(s)" << endl;
207 else
209 if (argc != 3)
211 cout << "Bad argument number for option --check_device" << endl;
212 opt->printUsage();
213 delete opt;
214 return 0;
217 int ret;
218 ret = check_device(opt->getValue("check-device"));
220 delete opt;
221 return ret;
226 // --add-server option
230 else if (opt->getValue("add-server") != NULL)
232 if (opt->getValue("delete-server") != NULL ||
233 opt->getValue("add-property") != NULL ||
234 opt->getValue("delete-property") != NULL ||
235 opt->getValue("check-device") != NULL ||
236 opt->getValue("check-server") != NULL ||
237 opt->getValue("server-instance-list") != NULL ||
238 opt->getFlag("server-list") == true ||
239 opt->getFlag("ping-network") == true ||
240 opt->getFlag("tac-enabled") == true ||
241 opt->getFlag("with-properties") == true)
242 cout << "Can't mix option --add-server with other option(s)" << endl;
243 else
245 if (argc != 5)
247 cout << "Bad argument number for option --add-server" << endl;
248 opt->printUsage();
249 delete opt;
250 return 0;
253 int ret;
254 ret = add_server(opt->getValue("add-server"),opt->getArgv(0),opt->getArgv(1));
256 delete opt;
257 return ret;
262 // --check-server option
266 else if (opt->getValue("check-server") != NULL)
268 if (opt->getValue("delete-server") != NULL ||
269 opt->getValue("add-property") != NULL ||
270 opt->getValue("delete-property") != NULL ||
271 opt->getValue("add-server") != NULL ||
272 opt->getValue("check-device") != NULL ||
273 opt->getValue("server-instance-list") != NULL ||
274 opt->getFlag("server-list") == true ||
275 opt->getFlag("ping-network") == true ||
276 opt->getFlag("tac-enabled") == true ||
277 opt->getFlag("with-properties") == true)
278 cout << "Can't mix option --check-server with other option(s)" << endl;
279 else
281 if (argc != 3)
283 cout << "Bad argument number for option --check_server" << endl;
284 opt->printUsage();
285 delete opt;
286 return 0;
289 int ret;
290 ret = check_server(opt->getValue("check-server"));
292 delete opt;
293 return ret;
298 // --server-list option
302 else if (opt->getFlag("server-list") == true)
304 if (opt->getValue("delete-server") != NULL ||
305 opt->getValue("add-property") != NULL ||
306 opt->getValue("delete-property") != NULL ||
307 opt->getValue("add-server") != NULL ||
308 opt->getValue("check-device") != NULL ||
309 opt->getValue("server-instance-list") != NULL ||
310 opt->getFlag("ping-network") == true ||
311 opt->getFlag("tac-enabled") == true ||
312 opt->getFlag("with-properties") == true)
313 cout << "Can't mix option --server-list with other option(s)" << endl;
314 else
316 if (argc != 2)
318 cout << "Bad argument number for option --server-list" << endl;
319 opt->printUsage();
320 delete opt;
321 return 0;
324 int ret;
325 ret = server_list();
327 delete opt;
328 return ret;
333 // --server-instance-list option
337 else if (opt->getValue("server-instance-list") != NULL)
339 if (opt->getValue("delete-server") != NULL ||
340 opt->getValue("add-property") != NULL ||
341 opt->getValue("delete-property") != NULL ||
342 opt->getValue("add-server") != NULL ||
343 opt->getValue("check-device") != NULL ||
344 opt->getFlag("server-list") == true ||
345 opt->getFlag("ping-network") == true ||
346 opt->getFlag("tac-enabled") == true ||
347 opt->getFlag("with-properties") == true)
348 cout << "Can't mix option --server-instance-list with other option(s)" << endl;
349 else
351 if (argc != 3)
353 cout << "Bad argument number for option --server-instance-list" << endl;
354 opt->printUsage();
355 delete opt;
356 return 0;
359 int ret;
360 ret = server_instance_list(opt->getValue("server-instance-list"));
362 delete opt;
363 return ret;
368 // --delete-server option
371 else if (opt->getValue("delete-server") != NULL)
373 if (opt->getValue("add-server") != NULL ||
374 opt->getValue("add-property") != NULL ||
375 opt->getValue("check-server") != NULL ||
376 opt->getValue("check-device") != NULL ||
377 opt->getValue("server-instance-list") != NULL ||
378 opt->getFlag("server-list") == true ||
379 opt->getFlag("ping-network") == true ||
380 opt->getFlag("tac-enabled") == true ||
381 opt->getValue("delete-property") != NULL)
382 cout << "Can't mix option --delete-server with other option(s)" << endl;
383 else
385 if ((argc < 3 || argc > 4) ||
386 (argc == 3 && strcmp(argv[2],"--with-properties") == 0) ||
387 (strcmp(opt->getValue("delete-server"),"--with-properties") == 0))
389 cout << "Bad option delete-server usage" << endl;
390 opt->printUsage();
391 delete opt;
392 return 0;
395 int ret;
396 if (opt->getFlag("with-properties") == true)
397 ret = delete_server(opt->getValue("delete-server"),true);
398 else
399 ret = delete_server(opt->getValue("delete-server"),false);
401 delete opt;
402 return ret;
407 // --add-property option
410 else if (opt->getValue("add-property") != NULL)
412 if (opt->getValue("delete-server") != NULL ||
413 opt->getValue("delete-property") != NULL ||
414 opt->getValue("add-server") != NULL ||
415 opt->getValue("check-device") != NULL ||
416 opt->getValue("check-server") != NULL ||
417 opt->getValue("server-instance-list") != NULL ||
418 opt->getFlag("server-list") == true ||
419 opt->getFlag("with-properties") == true ||
420 opt->getFlag("tac-enabled") == true ||
421 opt->getFlag("ping-network") == true ||
422 opt->getFlag("ping-database") == true)
423 cout << "Can't mix option --add-property with other option(s)" << endl;
424 else
426 if (argc != 5)
428 cout << "Bag argument number for option --add-property" << endl;
429 opt->printUsage();
430 delete opt;
431 return 0;
434 int ret;
435 ret = add_property(opt->getValue("add-property"),opt->getArgv(0),opt->getArgv(1));
437 delete opt;
438 return ret;
443 // --delete-property option
446 else if (opt->getValue("delete-property") != NULL)
448 if (opt->getValue("delete-server") != NULL ||
449 opt->getValue("add-property") != NULL ||
450 opt->getValue("add-server") != NULL ||
451 opt->getValue("check-device") != NULL ||
452 opt->getValue("check-server") != NULL ||
453 opt->getValue("server-instance-list") != NULL ||
454 opt->getFlag("server-list") == true ||
455 opt->getFlag("with-properties") == true ||
456 opt->getFlag("ping-network") == true ||
457 opt->getFlag("tac-enabled") == true ||
458 opt->getFlag("ping-database") == true)
459 cout << "Can't mix option --delete-property with other option(s)" << endl;
460 else
462 if (argc != 4)
464 cout << "Bag argument number for option --add-property" << endl;
465 opt->printUsage();
466 delete opt;
467 return 0;
470 int ret;
471 ret = delete_property(opt->getValue("delete-property"),opt->getArgv(0));
473 delete opt;
474 return ret;
479 // --ping-network option
482 if (opt->getFlag("ping-network") == true)
484 bool verbose = false;
486 if (opt->getValue("add-server") != NULL ||
487 opt->getValue("delete-server") != NULL ||
488 opt->getValue("add-property") != NULL ||
489 opt->getValue("delete-property") != NULL ||
490 opt->getValue("check-device") != NULL ||
491 opt->getValue("check-server") != NULL ||
492 opt->getValue("server-instance-list") != NULL ||
493 opt->getFlag("server-list") == true ||
494 opt->getFlag("ping-database") == true ||
495 opt->getFlag("tac-enabled") == true ||
496 opt->getFlag("with-properties") == true)
497 cout << "Can't mix option --ping-network with other option(s)" << endl;
499 if (argc > 4)
501 cout << "Bad argument number for option --ping-network" << endl;
502 opt->printUsage();
503 delete opt;
504 return 0;
506 else if (argc == 4)
508 if (strcmp(argv[3],"-v") != 0)
510 cout << "Bad argument for option --ping-network" << endl;
511 opt->printUsage();
512 delete opt;
513 return 0;
515 else
516 verbose = true;
518 else if (argc == 3)
520 if (strcmp(argv[2],"-v") == 0)
522 verbose = true;
526 int ret;
527 if (argc == 2)
528 ret = ping_network(0,verbose);
529 else
531 int sec = 0;
532 sec = atoi(argv[2]);
533 if ((verbose == false) && (sec == 0))
535 cout << "Bad argument for option --ping-network" << endl;
536 opt->printUsage();
537 delete opt;
538 return 0;
540 ret = ping_network(sec,verbose);
543 delete opt;
544 return ret;
548 // --tac-enabled option
551 if (opt->getFlag("tac-enabled") == true)
553 if (opt->getValue("add-server") != NULL ||
554 opt->getValue("delete-server") != NULL ||
555 opt->getValue("add-property") != NULL ||
556 opt->getValue("delete-property") != NULL ||
557 opt->getValue("check-device") != NULL ||
558 opt->getValue("check-server") != NULL ||
559 opt->getValue("server-instance-list") != NULL ||
560 opt->getFlag("server-list") == true ||
561 opt->getFlag("ping-network") == true ||
562 opt->getFlag("with-properties") == true)
563 cout << "Can't mix option --tac-enabled with other option(s)" << endl;
565 if (argc > 2)
567 cout << "Bad argument number for option --tac-enabled" << endl;
568 opt->printUsage();
569 delete opt;
570 return 0;
573 int ret;
574 ret = tac_enabled();
576 delete opt;
577 return ret;
581 // --ping-device option
585 if (opt->getValue("ping-device") != NULL)
587 if (opt->getValue("delete-server") != NULL ||
588 opt->getValue("add-property") != NULL ||
589 opt->getValue("delete-property") != NULL ||
590 opt->getValue("add-server") != NULL ||
591 opt->getValue("check-server") != NULL ||
592 opt->getValue("server-instance-list") != NULL ||
593 opt->getFlag("server-list") == true ||
594 opt->getFlag("ping-network") == true ||
595 opt->getFlag("tac-enabled") == true ||
596 opt->getFlag("with-properties") == true)
597 cout << "Can't mix option --ping-device with other option(s)" << endl;
598 else
600 int ret;
601 int sec = 0;
603 if (argc < 3 || argc > 4)
605 cout << "Bad argument number for option --ping_device" << endl;
606 opt->printUsage();
607 delete opt;
608 return 0;
610 else if (argc == 4)
612 sec = atoi(argv[3]);
615 ret = ping_device(opt->getValue("ping-device"),sec);
617 delete opt;
618 return ret;
623 // Unknown choice
626 else
628 cout << "Wrong usage" << endl;
629 opt->printUsage();
632 delete opt;
635 //+-------------------------------------------------------------------------
637 // method : ping_database
639 // description : This function connect to the database and executes
640 // one of its command in order to check the database
641 // connectivity.
643 // argument : in : - nb_sec : Max time (in sec) to do re-try in case of failure
645 // The function returns 0 is everything is fine. Otherwise, it returns -1
647 //--------------------------------------------------------------------------
649 int ping_database(int nb_sec)
651 int ret = 0;
653 setenv("SUPER_TANGO","true",1);
655 int nb_loop;
656 bool infinite = false;
658 if (nb_sec == 0)
659 nb_loop = 1;
660 else if (nb_sec < 0)
662 infinite = true;
663 nb_loop = 2;
665 else
666 nb_loop = nb_sec << 1;
669 struct timespec ts;
670 ts.tv_sec = 0;
671 ts.tv_nsec = 500000000;
674 // First sleep for 1 sec before trying to access the db
675 // This was needed when ported to Natty (Ubuntu 11.04) in the
676 // tango-db startup script. Db process did not start if tango
677 // admin starts pinging db device too early !!
680 if (nb_loop != 1)
682 ts.tv_sec = 1;
683 ts.tv_nsec = 0;
685 nanosleep(&ts,NULL);
689 // re-try the call every 500 mS
692 ts.tv_sec = 0;
693 ts.tv_nsec = 500000000;
695 while(nb_loop > 0)
699 Tango::Database db;
701 string db_info;
702 db_info = db.get_info();
703 ret = 0;
704 nb_loop = 0;
706 catch (Tango::DevFailed &e)
708 ret = -1;
709 if (infinite == false)
710 --nb_loop;
713 if (nb_loop != 0)
714 nanosleep(&ts,NULL);
717 return ret;
720 //+-------------------------------------------------------------------------
722 // method : check_device
724 // description : This function checks if a device is defined in the DB
726 // argument : in : - name : The device name
728 // The function returns 0 is the device is defined. Otherwise, it returns -1
730 //--------------------------------------------------------------------------
732 int check_device(char *name)
734 int ret = 0;
738 Tango::Database db;
740 string d_name(name);
741 Tango::DbDevImportInfo dii = db.import_device(d_name);
743 catch (Tango::DevFailed &e)
745 ret = -1;
747 return ret;
750 //+-------------------------------------------------------------------------
752 // method : add_server
754 // description : This function adds a server definition in the DB
756 // argument : in : - d_name : The device server name (exec/inst)
757 // - c_name : The class name
758 // - d_list : The device list
760 // The function returns 0 is everything is fine. Otherwise, it returns -1
762 //--------------------------------------------------------------------------
764 int add_server(char *d_name,char *c_name,char *d_list)
766 int ret = 0;
769 // Check ds name syntax
772 string ds_name(d_name);
773 string::size_type pos;
775 pos = ds_name.find('/');
776 #ifdef __SUNPRO_CC
777 int n1 = 0;
778 count(ds_name.begin(),ds_name.end(),'/',n1);
779 if ((n1 != 1) || pos == 0 || pos == (ds_name.size() - 1))
781 #else
782 if ((count(ds_name.begin(),ds_name.end(),'/') != 1) || pos == 0 || pos == (ds_name.size() - 1))
784 #endif
785 cout << "Wrong syntax for ds name" << endl;
786 ret = -1;
787 return ret;
791 // Check class name syntax
794 string class_name(c_name);
795 #ifdef __SUNPRO_CC
796 count(class_name.begin(),class_name.end(),'/',n1);
797 if (n1 != 0)
799 #else
800 if (count(class_name.begin(),class_name.end(),'/') != 0)
802 #endif
803 cout << "Wrong syntax for class name" << endl;
804 ret = -1;
805 return ret;
809 // Check device list and device syntax
812 string dev_list(d_list);
813 vector<string> dev_names;
815 list2vect(dev_list,dev_names);
817 for (unsigned int loop = 0;loop < dev_names.size();++loop)
819 #ifdef __SUNPRO_CC
820 count(dev_names[loop].begin(),dev_names[loop].end(),'/',n1);
821 if (n1 != 2)
823 #else
824 if (count(dev_names[loop].begin(),dev_names[loop].end(),'/') != 2)
826 #endif
827 cout << "Wrong syntax for device " << dev_names[loop] << endl;
828 ret = -1;
829 return ret;
832 string::size_type pos1,pos2;
833 pos1 = dev_names[loop].find('/');
834 pos2 = dev_names[loop].rfind('/');
836 if (pos1 == 0 || pos2 == dev_names[loop].length() - 1 || pos2 == pos1 + 1)
838 cout << "Wrong syntax for device " << dev_names[loop] << endl;
839 ret = -1;
840 return ret;
845 // Create server in DB
846 // Dont forget to add the admin device
849 setenv("SUPER_TANGO","true",1);
853 Tango::Database db;
855 Tango::DbDevInfos ddi;
856 Tango::DbDevInfo tmp_dbi;
858 for (unsigned int loop = 0;loop < dev_names.size();++loop)
860 tmp_dbi.name = dev_names[loop];
861 tmp_dbi._class = class_name;
862 tmp_dbi.server = ds_name;
863 ddi.push_back(tmp_dbi);
865 tmp_dbi.name = "dserver/" + ds_name;
866 tmp_dbi._class = "DServer";
867 tmp_dbi.server = ds_name;
869 ddi.push_back(tmp_dbi);
871 db.add_server(ds_name,ddi);
873 catch (Tango::DevFailed &e)
875 ret = -1;
877 return ret;
880 //+-------------------------------------------------------------------------
882 // method : check_server
884 // description : This function checks if a device server is defined in the DB
886 // argument : in : - d_name : The device server name
888 // The function returns 0 is the device is defined. Otherwise, it returns -1
890 //--------------------------------------------------------------------------
892 int check_server(char *d_name)
894 int ret = 0;
896 string dev_name = "dserver/";
897 string ds_name = d_name;
899 dev_name = dev_name + ds_name;
901 ret = check_device((char *)dev_name.c_str());
903 return ret;
906 //+-------------------------------------------------------------------------
908 // method : server_list
910 // description : This function lists all server names
912 // The function returns 0 if at least one server is defined. Otherwise returns -1
914 //--------------------------------------------------------------------------
916 int server_list()
918 int ret = 0;
920 try
922 Tango::Database db;
924 vector<string> servers;
925 db.get_server_name_list() >> servers;
926 for(int idx = 0; idx < servers.size(); ++idx)
928 cout << servers[idx] << " ";
930 cout << endl;
932 catch (Tango::DevFailed &e)
934 ret = -1;
937 return ret;
940 //+-------------------------------------------------------------------------
942 // method : server_instance_list
944 // description : This function lists all server instances for the given
945 // server name
947 // argument : in : - s_name : The server name
949 // The function returns 0 is the server name is defined. Otherwise returns -1
951 //--------------------------------------------------------------------------
953 int server_instance_list(char *s_name)
955 int ret = 0;
957 try
959 Tango::Database db;
961 string server_name = s_name;
962 size_t start_pos = server_name.size() + 1;
963 server_name += "/*";
965 vector<string> servers;
966 db.get_server_list(server_name) >> servers;
967 for(int idx = 0; idx < servers.size(); ++idx)
969 cout << servers[idx].substr(start_pos) << " ";
971 cout << endl;
973 catch (Tango::DevFailed &e)
975 ret = -1;
978 return ret;
981 //+-------------------------------------------------------------------------
983 // method : delete_server
985 // description : This function deletes a device server from the DB
987 // argument : in : - d_name : The device server name
988 // - with_res : If true, also delte device properties
990 // The function returns 0 is everything is fine. Otherwise, it returns -1
992 //--------------------------------------------------------------------------
994 int delete_server(char *d_name,bool with_res)
996 int ret = 0;
998 string ds_name(d_name);
1001 // Check device server name syntax
1004 string::size_type pos;
1005 pos = ds_name.find('/');
1007 #ifdef __SUNPRO_CC
1008 int n1 = 0;
1009 count(ds_name.begin(),ds_name.end(),'/',n1);
1010 if (pos == 0 || pos == ds_name.size() - 1 || n1 != 1)
1012 #else
1013 if (pos == 0 || pos == ds_name.size() - 1 ||
1014 count(ds_name.begin(),ds_name.end(),'/') != 1)
1016 #endif
1017 ret = -1;
1018 return ret;
1021 ret = check_server(d_name);
1022 if (ret != 0)
1023 return ret;
1029 Tango::Database db;
1032 // If we need to remove prop
1035 if (with_res == true)
1039 // First get the ds class list
1042 Tango::DbDatum db_res = db.get_device_class_list(ds_name);
1043 vector<string> dev_list;
1044 db_res >> dev_list;
1047 // Get device property name for each device
1050 for (unsigned int loop = 0;loop < dev_list.size();++loop)
1052 vector<string> prop_list;
1054 db.get_device_property_list(dev_list[loop],"*",prop_list);
1057 // Delete all device properties
1060 if (prop_list.empty() == false)
1062 Tango::DbData dbd;
1064 for (unsigned int ctr = 0;ctr < prop_list.size();++ctr)
1065 dbd.push_back(Tango::DbDatum(prop_list[ctr]));
1067 db.delete_device_property(dev_list[loop],dbd);
1070 ++loop;
1076 // Delete device server from db
1080 db.delete_server(ds_name);
1082 catch (Tango::DevFailed &e)
1084 ret = -1;
1087 return ret;
1090 //+-------------------------------------------------------------------------
1092 // method : add_property
1094 // description : This function adds a device property in the DB
1096 // argument : in : - d_name : The device name
1097 // - p_name : The property name
1098 // - p_val : The property value
1100 // The function returns 0 is everything is fine. Otherwise, it returns -1
1102 //--------------------------------------------------------------------------
1104 int add_property(char *d_name,char *p_name,char *p_val)
1106 int ret = 0;
1109 // Check dev name syntax
1112 string dev_name(d_name);
1113 string::size_type pos1,pos2;
1115 pos1 = dev_name.find('/');
1116 pos2 = dev_name.rfind('/');
1118 #ifdef __SUNPRO_CC
1119 int n1 = 0;
1120 count(dev_name.begin(),dev_name.end(),'/',n1);
1121 if ((n1 != 2) || pos1 == 0 || pos2 == (dev_name.size() - 1) || pos2 == pos1 + 1)
1123 #else
1124 if ((count(dev_name.begin(),dev_name.end(),'/') != 2) ||
1125 pos1 == 0 || pos2 == (dev_name.size() - 1) || pos2 == pos1 + 1)
1127 #endif
1128 cout << "Wrong syntax for device name" << endl;
1129 ret = -1;
1130 return ret;
1134 // Check if the device is defined
1137 if (check_device(d_name) != 0)
1138 return -1;
1141 // Convert prop value(s) into a vector
1144 string prop_val(p_val);
1145 vector<string> prop_val_list;
1147 list2vect(prop_val,prop_val_list);
1150 // Create server in DB
1151 // Dont forget to add the admin device
1156 Tango::Database db;
1158 Tango::DbData dbd;
1159 Tango::DbDatum db_s(p_name);
1161 db_s << prop_val_list;
1162 dbd.push_back(db_s);
1164 db.put_device_property(dev_name,dbd);
1166 catch (Tango::DevFailed &e)
1168 ret = -1;
1170 return ret;
1173 //+-------------------------------------------------------------------------
1175 // method : delete_property
1177 // description : This function deletes a device property from the DB
1179 // argument : in : - d_name : The device name
1180 // - p_name : The property name
1182 // The function returns 0 is everything is fine. Otherwise, it returns -1
1184 //--------------------------------------------------------------------------
1186 int delete_property(char *d_name,char *p_name)
1188 int ret = 0;
1191 // Check dev name syntax
1194 string dev_name(d_name);
1195 string::size_type pos1,pos2;
1197 pos1 = dev_name.find('/');
1198 pos2 = dev_name.rfind('/');
1200 #ifdef __SUNPRO_CC
1201 int n1 = 0;
1202 count(dev_name.begin(),dev_name.end(),'/',n1);
1203 if ((n1 != 2) || pos2 == (dev_name.size() - 1) || pos2 == pos1 + 1)
1205 #else
1206 if ((count(dev_name.begin(),dev_name.end(),'/') != 2) ||
1207 pos1 == 0 || pos2 == (dev_name.size() - 1) || pos2 == pos1 + 1)
1209 #endif
1210 cout << "Wrong syntax for device name" << endl;
1211 ret = -1;
1212 return ret;
1216 // Check if the device is defined
1219 if (check_device(d_name) != 0)
1220 return -1;
1223 // Create server in DB
1224 // Dont forget to add the admin device
1229 Tango::Database db;
1231 Tango::DbData dbd;
1232 dbd.push_back(Tango::DbDatum(p_name));
1234 db.delete_device_property(dev_name,dbd);
1236 catch (Tango::DevFailed &e)
1238 ret = -1;
1240 return ret;
1243 //+-------------------------------------------------------------------------
1245 // method : list2vect
1247 // description : This function converts a comma separated
1248 // device list into a vector of strings with one
1249 // element for each device
1251 // argument : in : - dev_list : The device list
1252 // - dev_names : The device vector
1254 //--------------------------------------------------------------------------
1256 void list2vect(string &dev_list,vector<string> &dev_names)
1258 string::size_type beg,end;
1260 bool end_loop = false;
1261 beg = 0;
1263 while (end_loop == false)
1265 end = dev_list.find(',',beg);
1266 if (end == beg)
1268 ++beg;
1269 continue;
1272 if (end == string::npos)
1274 end = dev_list.length();
1275 end_loop = true;
1278 string one_dev;
1279 one_dev = dev_list.substr(beg,end - beg);
1280 dev_names.push_back(one_dev);
1282 beg = end + 1;
1283 if (beg == dev_list.size())
1284 end_loop = true;
1288 //+-------------------------------------------------------------------------
1290 // method : ping_network
1292 // description : This function periodically chechs the network avaibility
1294 // argument : in : - nb_sec : Max time (in sec) to do re-try in case of failure
1295 // - verbose : Boolean flag set to true if some printing is required
1297 // The function returns 0 is everything is fine. Otherwise, it returns -1
1299 //--------------------------------------------------------------------------
1301 int ping_network(int nb_sec,bool verbose)
1303 int ret = 0;
1305 int nb_loop;
1306 bool infinite = false;
1308 if (nb_sec == 0)
1309 nb_loop = 1;
1310 else if (nb_sec < 0)
1312 infinite = true;
1313 nb_loop = 2;
1315 else
1316 nb_loop = nb_sec << 1;
1319 // re-try the call every 500 mS
1322 struct timespec ts;
1323 ts.tv_sec = 0;
1324 ts.tv_nsec = 500000000;
1326 while(nb_loop > 0)
1329 int res = check_net(verbose);
1330 if (res == 0)
1332 ret = 0;
1333 nb_loop = 0;
1335 else
1337 ret = -1;
1338 if (infinite == false)
1339 --nb_loop;
1342 if (nb_loop != 0)
1343 nanosleep(&ts,NULL);
1346 return ret;
1349 //+-------------------------------------------------------------------------
1351 // method : check_net
1353 // description : This function connect to the network and check if it is
1354 // fully ready.
1356 // argument : in : - verbose : Flag set to true if some printing is required
1358 // The function returns 0 is everything is fine. Otherwise, it returns -1
1360 //--------------------------------------------------------------------------
1362 int check_net(bool verbose)
1364 int ret = 0;
1366 char buffer[80];
1367 string hostname;
1369 if (gethostname(buffer,80) == 0)
1371 hostname = buffer;
1372 if (verbose == true)
1373 cout << "Host name returned by gethostname function: " << hostname << endl;
1375 struct addrinfo hints;
1377 memset(&hints,0,sizeof(struct addrinfo));
1379 hints.ai_flags = AI_ADDRCONFIG;
1381 hints.ai_family = AF_INET;
1382 hints.ai_socktype = SOCK_STREAM;
1384 struct addrinfo *info;
1385 struct addrinfo *ptr;
1386 char tmp_host[512];
1387 int result;
1389 result = getaddrinfo(buffer, NULL, &hints, &info);
1391 if (result == 0)
1393 ptr = info;
1394 if (verbose == true)
1395 cout << "getaddrinfo() is a success" << endl;
1396 while (ptr != NULL)
1398 if (getnameinfo(ptr->ai_addr,ptr->ai_addrlen,tmp_host,512,0,0,0) != 0)
1400 if (verbose == true)
1401 cout << "getnameinfo() call failed" << endl;
1402 ret = -1;
1403 break;
1405 if (verbose == true)
1406 cout << "Host name as returned by getnameinfo call: " << tmp_host << endl;
1407 ptr = ptr->ai_next;
1410 freeaddrinfo(info);
1412 else
1414 if (verbose == true)
1415 cout << "getaddrinfo() call failed with returned value = " << result << endl;
1416 ret = -1;
1419 else
1421 cout << "Cant retrieve server host name" << endl;
1422 ret = -1;
1425 return ret;
1429 //+-------------------------------------------------------------------------
1431 // method : tac_enabled
1433 // description : This function check in DB if the TAC is enabled
1435 // The function returns 0 if the TAC is disabled. Otherwise, it returns 1
1437 //--------------------------------------------------------------------------
1439 int tac_enabled(void)
1442 int ret = 1;
1444 setenv("SUPER_TANGO","true",1);
1448 Tango::Database db;
1450 string servicename("AccessControl");
1451 string instname("tango");
1452 Tango::DbDatum db_datum = db.get_services(servicename,instname);
1453 vector<string> service_list;
1454 db_datum >> service_list;
1456 if (service_list.empty() == true)
1457 ret = 0;
1459 catch (Tango::DevFailed &e)
1461 ret = 0;
1464 return ret;
1467 //+-------------------------------------------------------------------------
1469 // method : ping_device
1471 // description : This function periodically chechs a device avaibility
1473 // argument : in : - nb_sec : Max time (in sec) to do re-try in case of failure
1474 // - dev_name : The device name
1476 // The function returns 0 is everything is fine. Otherwise, it returns -1
1478 //--------------------------------------------------------------------------
1480 int ping_device(char *dev_name,int nb_sec)
1482 int ret = 0;
1484 int nb_loop;
1485 bool infinite = false;
1487 if (nb_sec == 0)
1488 nb_loop = 1;
1489 else if (nb_sec < 0)
1491 infinite = true;
1492 nb_loop = 2;
1494 else
1495 nb_loop = nb_sec << 1;
1498 // re-try the call every 500 mS
1501 struct timespec ts;
1502 ts.tv_sec = 0;
1503 ts.tv_nsec = 500000000;
1505 while(nb_loop > 0)
1508 int res = check_dev(dev_name);
1509 if (res == 0)
1511 ret = 0;
1512 nb_loop = 0;
1514 else
1516 ret = -1;
1517 if (infinite == false)
1518 --nb_loop;
1521 if (nb_loop != 0)
1522 nanosleep(&ts,NULL);
1525 return ret;
1528 //+-------------------------------------------------------------------------
1530 // method : check_dev
1532 // description : This function connect to a device and try to ping it
1534 // argument : in : - dev_name : The device name
1536 // The function returns 0 is everything is fine. Otherwise, it returns -1
1538 //--------------------------------------------------------------------------
1540 int check_dev(char *dev_name)
1542 int ret = 0;
1546 Tango::DeviceProxy dev(dev_name);
1548 dev.ping();
1550 catch (Tango::DevFailed &e)
1552 ret = -1;
1555 return ret;