srp_load.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <assert.h>
  4. #include <getopt.h>
  5. #include <faux/faux.h>
  6. #include <faux/str.h>
  7. #include <faux/file.h>
  8. #include <faux/argv.h>
  9. #include <sysrepo.h>
  10. #include <sysrepo/xpath.h>
  11. #include <sysrepo/netconf_acm.h>
  12. #include "klish_plugin_sysrepo.h"
  13. #ifndef VERSION
  14. #define VERSION "1.0.0"
  15. #endif
  16. #define DEFAULT_USER "root"
  17. #define DEFAULT_DATASTORE SR_DS_CANDIDATE
  18. typedef struct cmd_opts_s {
  19. bool_t verbose;
  20. char *cfg;
  21. char *file;
  22. char *user;
  23. bool_t stop_on_error;
  24. sr_datastore_t datastore;
  25. } cmd_opts_t;
  26. int srp_mass_set(int fd, sr_datastore_t ds, pline_opts_t *opts,
  27. const char *user, bool_t stop_on_error);
  28. // Command line options
  29. static cmd_opts_t *cmd_opts_init(void);
  30. static void cmd_opts_free(cmd_opts_t *opts);
  31. static int cmd_opts_parse(int argc, char *argv[], cmd_opts_t *opts);
  32. static void help(int status, const char *argv0);
  33. int main(int argc, char **argv)
  34. {
  35. int ret = -1;
  36. pline_opts_t opts;
  37. cmd_opts_t *cmd_opts = NULL;
  38. int fd = STDIN_FILENO;
  39. cmd_opts = cmd_opts_init();
  40. if (cmd_opts_parse(argc, argv, cmd_opts) < 0) {
  41. fprintf(stderr, "Error: Illegal command line options\n");
  42. goto out;
  43. }
  44. if (cmd_opts->file) {
  45. fd = open(cmd_opts->file, O_RDONLY, 0);
  46. if (fd < 0) {
  47. fprintf(stderr, "Error: Can't open \"%s\"\n", cmd_opts->file);
  48. goto out;
  49. }
  50. }
  51. pline_opts_init(&opts);
  52. ret = srp_mass_set(fd, cmd_opts->datastore, &opts,
  53. cmd_opts->user, cmd_opts->stop_on_error);
  54. out:
  55. if (cmd_opts->file)
  56. close(fd);
  57. cmd_opts_free(cmd_opts);
  58. return ret;
  59. }
  60. int srp_mass_set(int fd, sr_datastore_t ds, pline_opts_t *opts,
  61. const char *user, bool_t stop_on_error)
  62. {
  63. int ret = -1;
  64. int err = SR_ERR_OK;
  65. sr_conn_ctx_t *conn = NULL;
  66. sr_session_ctx_t *sess = NULL;
  67. faux_file_t *file = NULL;
  68. char *line = NULL;
  69. size_t err_num = 0;
  70. sr_subscription_ctx_t *nacm_sub = NULL;
  71. err = sr_connect(SR_CONN_DEFAULT, &conn);
  72. if (err) {
  73. fprintf(stderr, "Error: Can't connect to sysrepo\n");
  74. goto out;
  75. }
  76. err = sr_session_start(conn, ds, &sess);
  77. if (err) {
  78. fprintf(stderr, "Error: Can't start session\n");
  79. goto out;
  80. }
  81. sr_session_set_orig_name(sess, user);
  82. // Init NACM session
  83. if (opts->enable_nacm) {
  84. if (sr_nacm_init(sess, 0, &nacm_sub) != SR_ERR_OK) {
  85. fprintf(stderr, "Error: Can't init NACM\n");
  86. goto out;
  87. }
  88. sr_nacm_set_user(sess, user);
  89. }
  90. file = faux_file_fdopen(fd);
  91. if (!file) {
  92. fprintf(stderr, "Error: Can't open input stream\n");
  93. goto out;
  94. }
  95. while ((line = faux_file_getline(file))) {
  96. pline_t *pline = NULL;
  97. faux_argv_t *args = NULL;
  98. args = faux_argv_new();
  99. faux_argv_parse(args, line);
  100. pline = pline_parse(sess, args, opts);
  101. faux_argv_free(args);
  102. if (!pline || pline->invalid) {
  103. err_num++;
  104. fprintf(stderr, "Error: Illegal: %s\n", line);
  105. } else {
  106. faux_list_node_t *iter = NULL;
  107. pexpr_t *expr = NULL;
  108. iter = faux_list_head(pline->exprs);
  109. while ((expr = (pexpr_t *)faux_list_each(&iter))) {
  110. if (!(expr->pat & PT_SET)) {
  111. err_num++;
  112. fprintf(stderr, "Error: Illegal expression for set operation\n");
  113. break;
  114. }
  115. if (sr_set_item_str(sess, expr->xpath, expr->value, NULL, 0) !=
  116. SR_ERR_OK) {
  117. err_num++;
  118. fprintf(stderr, "Error: Can't set data\n");
  119. break;
  120. }
  121. }
  122. }
  123. if (stop_on_error && (err_num > 0)) {
  124. sr_discard_changes(sess);
  125. goto out;
  126. }
  127. pline_free(pline);
  128. faux_str_free(line);
  129. }
  130. if (sr_has_changes(sess)) {
  131. if (sr_apply_changes(sess, 0) != SR_ERR_OK) {
  132. sr_discard_changes(sess);
  133. fprintf(stderr, "Error: Can't apply changes\n");
  134. goto out;
  135. }
  136. }
  137. ret = 0;
  138. out:
  139. faux_file_close(file);
  140. if (opts->enable_nacm) {
  141. sr_unsubscribe(nacm_sub);
  142. sr_nacm_destroy();
  143. }
  144. sr_disconnect(conn);
  145. return ret;
  146. }
  147. static cmd_opts_t *cmd_opts_init(void)
  148. {
  149. cmd_opts_t *opts = NULL;
  150. opts = faux_zmalloc(sizeof(*opts));
  151. assert(opts);
  152. // Initialize
  153. opts->verbose = BOOL_FALSE;
  154. opts->stop_on_error = BOOL_FALSE;
  155. opts->cfg = NULL;
  156. opts->file = NULL;
  157. opts->user = NULL;
  158. opts->datastore = DEFAULT_DATASTORE;
  159. return opts;
  160. }
  161. static void cmd_opts_free(cmd_opts_t *opts)
  162. {
  163. if (!opts)
  164. return;
  165. faux_str_free(opts->cfg);
  166. faux_str_free(opts->file);
  167. faux_str_free(opts->user);
  168. faux_free(opts);
  169. }
  170. static int cmd_opts_parse(int argc, char *argv[], cmd_opts_t *opts)
  171. {
  172. static const char *shortopts = "hf:veu:d:";
  173. static const struct option longopts[] = {
  174. {"conf", 1, NULL, 'f'},
  175. {"help", 0, NULL, 'h'},
  176. {"verbose", 0, NULL, 'v'},
  177. {"user", 1, NULL, 'u'},
  178. {"stop-on-error", 0, NULL, 'e'},
  179. {"datastore", 1, NULL, 'd'},
  180. {NULL, 0, NULL, 0}
  181. };
  182. optind = 1;
  183. while(1) {
  184. int opt = 0;
  185. opt = getopt_long(argc, argv, shortopts, longopts, NULL);
  186. if (-1 == opt)
  187. break;
  188. switch (opt) {
  189. case 'v':
  190. opts->verbose = BOOL_TRUE;
  191. break;
  192. case 'e':
  193. opts->stop_on_error = BOOL_TRUE;
  194. break;
  195. case 'h':
  196. help(0, argv[0]);
  197. _exit(0);
  198. break;
  199. case 'u':
  200. faux_str_free(opts->user);
  201. opts->user = faux_str_dup(optarg);
  202. break;
  203. case 'f':
  204. faux_str_free(opts->cfg);
  205. opts->cfg = faux_str_dup(optarg);
  206. break;
  207. case 'd':
  208. if (!kly_str2ds(optarg, strlen(optarg), &opts->datastore))
  209. return BOOL_FALSE;
  210. break;
  211. default:
  212. help(-1, argv[0]);
  213. _exit(-1);
  214. break;
  215. }
  216. }
  217. // Input file
  218. if(optind < argc) {
  219. faux_str_free(opts->file);
  220. opts->file = faux_str_dup(argv[optind]);
  221. }
  222. // Validate options
  223. if (!opts->user)
  224. opts->user = faux_str_dup(DEFAULT_USER);
  225. return 0;
  226. }
  227. static void help(int status, const char *argv0)
  228. {
  229. const char *name = NULL;
  230. if (!argv0)
  231. return;
  232. // Find the basename
  233. name = strrchr(argv0, '/');
  234. if (name)
  235. name++;
  236. else
  237. name = argv0;
  238. if (status != 0) {
  239. fprintf(stderr, "Try `%s -h' for more information.\n",
  240. name);
  241. } else {
  242. printf("Version : %s\n", VERSION);
  243. printf("Usage : %s [options] [filename]\n", name);
  244. printf("Load mass of config strings to Sysrepo repository\n");
  245. printf("Options :\n");
  246. printf("\t-h, --help Print this help.\n");
  247. printf("\t-v, --verbose Be verbose.\n");
  248. printf("\t-e, --stop-on-error Stop script execution on error.\n");
  249. printf("\t-u <name>, --user=<name> NACM user.\n");
  250. printf("\t-f <path>, --conf=<path> Config file.\n");
  251. printf("\t-d <ds>, --datastore=<ds> Datastore.\n");
  252. }
  253. }