corosync-objctl.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. /*
  2. * Copyright (c) 2008 Allied Telesis Labs NZ
  3. *
  4. * All rights reserved.
  5. *
  6. * Author: Angus Salkeld <angus.salkeld@alliedtelesis.co.nz>
  7. *
  8. * This software licensed under BSD license, the text of which follows:
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. *
  13. * - Redistributions of source code must retain the above copyright notice,
  14. * this list of conditions and the following disclaimer.
  15. * - Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  26. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  32. * THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <errno.h>
  37. #include <signal.h>
  38. #include <unistd.h>
  39. #include <string.h>
  40. #include <sys/types.h>
  41. #include <sys/un.h>
  42. #include "saAis.h"
  43. #include "confdb.h"
  44. #define SEPERATOR '.'
  45. #define SEPERATOR_STR "."
  46. #define OBJ_NAME_SIZE 512
  47. typedef enum {
  48. ACTION_READ,
  49. ACTION_WRITE,
  50. ACTION_CREATE,
  51. ACTION_DELETE,
  52. ACTION_PRINT_ALL,
  53. ACTION_PRINT_DEFAULT,
  54. } action_types_t;
  55. typedef enum {
  56. FIND_OBJECT_ONLY,
  57. FIND_OBJECT_OR_KEY,
  58. FIND_KEY_ONLY
  59. } find_object_of_type_t;
  60. confdb_callbacks_t callbacks = {
  61. .confdb_change_notify_fn = NULL,
  62. };
  63. static int action;
  64. /* Recursively dump the object tree */
  65. static void print_config_tree(confdb_handle_t handle, unsigned int parent_object_handle, char * parent_name)
  66. {
  67. unsigned int object_handle;
  68. char object_name[OBJ_NAME_SIZE];
  69. int object_name_len;
  70. char key_name[OBJ_NAME_SIZE];
  71. int key_name_len;
  72. char key_value[OBJ_NAME_SIZE];
  73. int key_value_len;
  74. confdb_error_t res;
  75. int children_printed;
  76. /* Show the keys */
  77. res = confdb_key_iter_start(handle, parent_object_handle);
  78. if (res != CONFDB_OK) {
  79. fprintf(stderr, "error resetting key iterator for object %d: %d\n", parent_object_handle, res);
  80. exit(EXIT_FAILURE);
  81. }
  82. children_printed = 0;
  83. while ( (res = confdb_key_iter(handle,
  84. parent_object_handle,
  85. key_name,
  86. &key_name_len,
  87. key_value,
  88. &key_value_len)) == CONFDB_OK) {
  89. key_name[key_name_len] = '\0';
  90. key_value[key_value_len] = '\0';
  91. if (parent_name != NULL)
  92. printf("%s%c%s=%s\n", parent_name, SEPERATOR,key_name, key_value);
  93. else
  94. printf("%s=%s\n", key_name, key_value);
  95. children_printed++;
  96. }
  97. /* Show sub-objects */
  98. res = confdb_object_iter_start(handle, parent_object_handle);
  99. if (res != CONFDB_OK) {
  100. fprintf(stderr, "error resetting object iterator for object %d: %d\n", parent_object_handle, res);
  101. exit(EXIT_FAILURE);
  102. }
  103. while ( (res = confdb_object_iter(handle,
  104. parent_object_handle,
  105. &object_handle,
  106. object_name,
  107. &object_name_len)) == CONFDB_OK) {
  108. object_name[object_name_len] = '\0';
  109. if (parent_name != NULL) {
  110. snprintf(key_value, OBJ_NAME_SIZE, "%s%c%s", parent_name, SEPERATOR, object_name);
  111. } else {
  112. if ((action == ACTION_PRINT_DEFAULT) && strcmp(object_name, "internal_configuration") == 0) continue;
  113. snprintf(key_value, OBJ_NAME_SIZE, "%s", object_name);
  114. }
  115. print_config_tree(handle, object_handle, key_value);
  116. children_printed++;
  117. }
  118. if (children_printed == 0 && parent_name != NULL) {
  119. printf("%s\n", parent_name);
  120. }
  121. }
  122. static int print_all(void)
  123. {
  124. confdb_handle_t handle;
  125. int result;
  126. result = confdb_initialize (&handle, &callbacks);
  127. if (result != CONFDB_OK) {
  128. fprintf (stderr, "Could not initialize objdb library. Error %d\n", result);
  129. return 1;
  130. }
  131. print_config_tree(handle, OBJECT_PARENT_HANDLE, NULL);
  132. result = confdb_finalize (handle);
  133. return 0;
  134. }
  135. static int print_help(void)
  136. {
  137. printf("\n");
  138. printf ("usage: corosync-objctl object%ckey ...\n", SEPERATOR);
  139. printf (" corosync-objctl -c object%cchild_obj ...\n", SEPERATOR);
  140. printf (" corosync-objctl -d object%cchild_obj ...\n", SEPERATOR);
  141. printf (" corosync-objctl -w object%cchild_obj.key=value ...\n", SEPERATOR);
  142. printf (" corosync-objctl -a (print all objects)\n");
  143. printf("\n");
  144. return 0;
  145. }
  146. static confdb_error_t validate_name(char * obj_name_pt)
  147. {
  148. if ((strchr (obj_name_pt, SEPERATOR) == NULL) &&
  149. (strchr (obj_name_pt, '=') == NULL))
  150. return CONFDB_OK;
  151. else
  152. return CONFDB_ERR_INVALID_PARAM;
  153. }
  154. void get_child_name(char * name_pt, char * child_name)
  155. {
  156. char * tmp;
  157. char str_copy[OBJ_NAME_SIZE];
  158. strcpy(str_copy, name_pt);
  159. /* first remove the value (it could be a file path */
  160. tmp = strchr(str_copy, '=');
  161. if (tmp != NULL) *tmp = '\0';
  162. /* truncate the */
  163. tmp = strrchr(str_copy, SEPERATOR);
  164. if (tmp == NULL) tmp = str_copy;
  165. strcpy(child_name, tmp+1);
  166. }
  167. void get_parent_name(char * name_pt, char * parent_name)
  168. {
  169. char * tmp;
  170. strcpy(parent_name, name_pt);
  171. /* first remove the value (it could be a file path */
  172. tmp = strchr(parent_name, '=');
  173. if (tmp != NULL) *tmp = '\0';
  174. /* then truncate the child name */
  175. tmp = strrchr(parent_name, SEPERATOR);
  176. if (tmp != NULL) *tmp = '\0';
  177. }
  178. void get_key(char * name_pt, char * key_name, char * key_value)
  179. {
  180. char * tmp;
  181. char str_copy[OBJ_NAME_SIZE];
  182. strcpy(str_copy, name_pt);
  183. /* first remove the value (it could have a SEPERATOR in it */
  184. tmp = strchr(str_copy, '=');
  185. if (tmp != NULL && strlen(tmp) > 0) {
  186. strcpy(key_value, tmp+1);
  187. *tmp = '\0';
  188. } else {
  189. key_value[0] = '\0';
  190. }
  191. /* then remove the name */
  192. tmp = strrchr(str_copy, SEPERATOR);
  193. if (tmp == NULL) tmp = str_copy;
  194. strcpy(key_name, tmp+1);
  195. }
  196. static confdb_error_t find_object (confdb_handle_t handle,
  197. char * name_pt,
  198. find_object_of_type_t type,
  199. uint32_t * out_handle)
  200. {
  201. char * obj_name_pt;
  202. char * save_pt;
  203. uint32_t obj_handle;
  204. confdb_handle_t parent_object_handle = OBJECT_PARENT_HANDLE;
  205. char tmp_name[OBJ_NAME_SIZE];
  206. confdb_error_t res;
  207. strncpy (tmp_name, name_pt, OBJ_NAME_SIZE);
  208. obj_name_pt = strtok_r(tmp_name, SEPERATOR_STR, &save_pt);
  209. while (obj_name_pt != NULL) {
  210. res = confdb_object_find_start(handle, parent_object_handle);
  211. if (res != CONFDB_OK) {
  212. fprintf (stderr, "Could not start object_find %d\n", res);
  213. exit (EXIT_FAILURE);
  214. }
  215. res = confdb_object_find(handle, parent_object_handle,
  216. obj_name_pt, strlen (obj_name_pt), &obj_handle);
  217. if (res != CONFDB_OK) {
  218. return res;
  219. }
  220. parent_object_handle = obj_handle;
  221. obj_name_pt = strtok_r (NULL, SEPERATOR_STR, &save_pt);
  222. }
  223. *out_handle = parent_object_handle;
  224. return res;
  225. }
  226. static void read_object(confdb_handle_t handle, char * name_pt)
  227. {
  228. char parent_name[OBJ_NAME_SIZE];
  229. uint32_t obj_handle;
  230. confdb_error_t res;
  231. get_parent_name(name_pt, parent_name);
  232. res = find_object (handle, name_pt, FIND_OBJECT_OR_KEY, &obj_handle);
  233. if (res == CONFDB_OK) {
  234. print_config_tree(handle, obj_handle, parent_name);
  235. }
  236. }
  237. static void write_key(confdb_handle_t handle, char * path_pt)
  238. {
  239. uint32_t obj_handle;
  240. char parent_name[OBJ_NAME_SIZE];
  241. char key_name[OBJ_NAME_SIZE];
  242. char key_value[OBJ_NAME_SIZE];
  243. char old_key_value[OBJ_NAME_SIZE];
  244. int old_key_value_len;
  245. confdb_error_t res;
  246. /* find the parent object */
  247. get_parent_name(path_pt, parent_name);
  248. get_key(path_pt, key_name, key_value);
  249. if (validate_name(key_name) != CONFDB_OK) {
  250. fprintf(stderr, "Incorrect key name, can not have \"=\" or \"%c\"\n", SEPERATOR);
  251. exit(EXIT_FAILURE);
  252. }
  253. res = find_object (handle, parent_name, FIND_OBJECT_ONLY, &obj_handle);
  254. if (res != CONFDB_OK) {
  255. fprintf(stderr, "Can't find parent object of \"%s\"\n", path_pt);
  256. exit(EXIT_FAILURE);
  257. }
  258. /* get the current key */
  259. res = confdb_key_get (handle,
  260. obj_handle,
  261. key_name,
  262. strlen(key_name),
  263. old_key_value,
  264. &old_key_value_len);
  265. if (res == CONFDB_OK) {
  266. /* replace the current value */
  267. res = confdb_key_replace (handle,
  268. obj_handle,
  269. key_name,
  270. strlen(key_name),
  271. old_key_value,
  272. old_key_value_len,
  273. key_value,
  274. strlen(key_value));
  275. if (res != CONFDB_OK)
  276. fprintf(stderr, "Failed to replace the key %s=%s. Error %d\n", key_name, key_value, res);
  277. } else {
  278. /* not there, create a new key */
  279. res = confdb_key_create (handle,
  280. obj_handle,
  281. key_name,
  282. strlen(key_name),
  283. key_value,
  284. strlen(key_value));
  285. if (res != CONFDB_OK)
  286. fprintf(stderr, "Failed to create the key %s=%s. Error %d\n", key_name, key_value, res);
  287. }
  288. }
  289. static void create_object(confdb_handle_t handle, char * name_pt)
  290. {
  291. char * obj_name_pt;
  292. char * save_pt;
  293. uint32_t obj_handle;
  294. uint32_t parent_object_handle = OBJECT_PARENT_HANDLE;
  295. char tmp_name[OBJ_NAME_SIZE];
  296. confdb_error_t res;
  297. strncpy (tmp_name, name_pt, OBJ_NAME_SIZE);
  298. obj_name_pt = strtok_r(tmp_name, SEPERATOR_STR, &save_pt);
  299. while (obj_name_pt != NULL) {
  300. res = confdb_object_find_start(handle, parent_object_handle);
  301. if (res != CONFDB_OK) {
  302. fprintf (stderr, "Could not start object_find %d\n", res);
  303. exit (EXIT_FAILURE);
  304. }
  305. res = confdb_object_find(handle, parent_object_handle,
  306. obj_name_pt, strlen (obj_name_pt), &obj_handle);
  307. if (res != CONFDB_OK) {
  308. if (validate_name(obj_name_pt) != CONFDB_OK) {
  309. fprintf(stderr, "Incorrect object name \"%s\", \"=\" not allowed.\n",
  310. obj_name_pt);
  311. exit(EXIT_FAILURE);
  312. }
  313. res = confdb_object_create (handle,
  314. parent_object_handle,
  315. obj_name_pt,
  316. strlen (obj_name_pt),
  317. &obj_handle);
  318. if (res != CONFDB_OK)
  319. fprintf(stderr, "Failed to create object \"%s\". Error %d.\n",
  320. obj_name_pt, res);
  321. }
  322. parent_object_handle = obj_handle;
  323. obj_name_pt = strtok_r (NULL, SEPERATOR_STR, &save_pt);
  324. }
  325. }
  326. static void delete_object(confdb_handle_t handle, char * name_pt)
  327. {
  328. confdb_error_t res;
  329. uint32_t obj_handle;
  330. res = find_object (handle, name_pt, FIND_OBJECT_ONLY, &obj_handle);
  331. if (res == CONFDB_OK) {
  332. res = confdb_object_destroy (handle, obj_handle);
  333. if (res != CONFDB_OK)
  334. fprintf(stderr, "Failed to find object \"%s\" to delete. Error %d\n", name_pt, res);
  335. } else {
  336. char parent_name[OBJ_NAME_SIZE];
  337. char key_name[OBJ_NAME_SIZE];
  338. char key_value[OBJ_NAME_SIZE];
  339. /* find the parent object */
  340. get_parent_name(name_pt, parent_name);
  341. get_key(name_pt, key_name, key_value);
  342. res = find_object (handle, parent_name, FIND_OBJECT_ONLY, &obj_handle);
  343. if (res != CONFDB_OK) {
  344. fprintf(stderr, "Failed to find the key's parent object \"%s\". Error %d\n", parent_name, res);
  345. exit (EXIT_FAILURE);
  346. }
  347. res = confdb_key_delete (handle,
  348. obj_handle,
  349. key_name,
  350. strlen(key_name),
  351. key_value,
  352. strlen(key_value));
  353. if (res != CONFDB_OK)
  354. fprintf(stderr, "Failed to delete key \"%s=%s\" from object \"%s\". Error %d\n",
  355. key_name, key_value, parent_name, res);
  356. }
  357. }
  358. int main (int argc, char *argv[]) {
  359. confdb_handle_t handle;
  360. confdb_error_t result;
  361. char c;
  362. action = ACTION_READ;
  363. for (;;){
  364. c = getopt (argc,argv,"hawcdp:");
  365. if (c==-1) {
  366. break;
  367. }
  368. switch (c) {
  369. case 'h':
  370. return print_help();
  371. break;
  372. case 'a':
  373. action = ACTION_PRINT_ALL;
  374. break;
  375. case 'p':
  376. printf("%s:%d NOT Implemented yet.\n", __FUNCTION__, __LINE__);
  377. return -1;
  378. //return read_in_config_file();
  379. break;
  380. case 'c':
  381. action = ACTION_CREATE;
  382. break;
  383. case 'd':
  384. action = ACTION_DELETE;
  385. break;
  386. case 'w':
  387. action = ACTION_WRITE;
  388. break;
  389. default :
  390. action = ACTION_READ;
  391. break;
  392. }
  393. }
  394. if (argc == 1) {
  395. action = ACTION_PRINT_DEFAULT;
  396. return print_all();
  397. } else if (action == ACTION_PRINT_ALL) {
  398. return print_all();
  399. } else if (optind >= argc) {
  400. fprintf(stderr, "Expected an object path after options\n");
  401. exit(EXIT_FAILURE);
  402. }
  403. result = confdb_initialize (&handle, &callbacks);
  404. if (result != CONFDB_OK) {
  405. fprintf (stderr, "Failed to initialize the objdb API. Error %d\n", result);
  406. exit (EXIT_FAILURE);
  407. }
  408. while (optind < argc) {
  409. switch (action) {
  410. case ACTION_READ:
  411. read_object(handle, argv[optind++]);
  412. break;
  413. case ACTION_WRITE:
  414. write_key(handle, argv[optind++]);
  415. break;
  416. case ACTION_CREATE:
  417. create_object(handle, argv[optind++]);
  418. break;
  419. case ACTION_DELETE:
  420. delete_object(handle, argv[optind++]);
  421. break;
  422. }
  423. }
  424. result = confdb_finalize (handle);
  425. if (result != CONFDB_OK) {
  426. fprintf (stderr, "Error finalizing objdb API. Error %d\n", result);
  427. exit(EXIT_FAILURE);
  428. }
  429. return 0;
  430. }