blob: f655b5b711e5c8fd4b4e4515208c9fa27025fdab [file] [log] [blame]
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001/**
Michal Vasko95ea9ff2021-11-09 12:29:14 +01002 * @file messages.c
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief libnetconf2 - NETCONF messages functions
Michal Vasko7bcb48e2016-01-15 10:28:54 +01005 *
Michal Vasko95ea9ff2021-11-09 12:29:14 +01006 * @copyright
Michal Vasko96f247a2021-03-15 13:32:10 +01007 * Copyright (c) 2015 - 2021 CESNET, z.s.p.o.
Michal Vasko7bcb48e2016-01-15 10:28:54 +01008 *
Radek Krejci9b81f5b2016-02-24 13:14:49 +01009 * This source code is licensed under BSD 3-Clause License (the "License").
10 * You may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
Michal Vaskoafd416b2016-02-25 14:51:46 +010012 *
Radek Krejci9b81f5b2016-02-24 13:14:49 +010013 * https://opensource.org/licenses/BSD-3-Clause
Michal Vasko7bcb48e2016-01-15 10:28:54 +010014 */
15
Radek Krejci36d2ee42017-10-13 13:55:59 +020016#include <assert.h>
Michal Vasko7bcb48e2016-01-15 10:28:54 +010017#include <ctype.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020018#include <stdarg.h>
Michal Vasko7bcb48e2016-01-15 10:28:54 +010019#include <stdlib.h>
20#include <string.h>
Michal Vasko7bcb48e2016-01-15 10:28:54 +010021
22#include <libyang/libyang.h>
23
24#include "libnetconf.h"
Michal Vasko7bcb48e2016-01-15 10:28:54 +010025
26const char *rpcedit_dfltop2str[] = {NULL, "merge", "replace", "none"};
27const char *rpcedit_testopt2str[] = {NULL, "test-then-set", "set", "test-only"};
28const char *rpcedit_erropt2str[] = {NULL, "stop-on-error", "continue-on-error", "rollback-on-error"};
29
30API NC_RPC_TYPE
31nc_rpc_get_type(const struct nc_rpc *rpc)
32{
Michal Vasko7f1c78b2016-01-19 09:52:14 +010033 if (!rpc) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020034 ERRARG("rpc");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010035 return 0;
36 }
37
Michal Vasko7bcb48e2016-01-15 10:28:54 +010038 return rpc->type;
39}
40
41API struct nc_rpc *
Michal Vasko90e8e692016-07-13 12:27:57 +020042nc_rpc_act_generic(const struct lyd_node *data, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +010043{
Michal Vasko90e8e692016-07-13 12:27:57 +020044 struct nc_rpc_act_generic *rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010045
Michal Vasko90e8e692016-07-13 12:27:57 +020046 if (!data || data->next || (data->prev != data)) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020047 ERRARG("data");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010048 return NULL;
49 }
50
Michal Vasko7bcb48e2016-01-15 10:28:54 +010051 rpc = malloc(sizeof *rpc);
52 if (!rpc) {
53 ERRMEM;
54 return NULL;
55 }
56
Michal Vasko90e8e692016-07-13 12:27:57 +020057 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010058 rpc->has_data = 1;
59 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
Michal Vasko77367452021-02-16 16:32:18 +010060 if (lyd_dup_single(data, NULL, LYD_DUP_RECURSIVE, &rpc->content.data)) {
61 free(rpc);
62 return NULL;
63 }
Michal Vasko7bcb48e2016-01-15 10:28:54 +010064 } else {
65 rpc->content.data = (struct lyd_node *)data;
66 }
67 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
68
69 return (struct nc_rpc *)rpc;
70}
71
72API struct nc_rpc *
Michal Vasko90e8e692016-07-13 12:27:57 +020073nc_rpc_act_generic_xml(const char *xml_str, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +010074{
Michal Vasko90e8e692016-07-13 12:27:57 +020075 struct nc_rpc_act_generic *rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010076
Michal Vasko7f1c78b2016-01-19 09:52:14 +010077 if (!xml_str) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020078 ERRARG("xml_str");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010079 return NULL;
80 }
81
Michal Vasko7bcb48e2016-01-15 10:28:54 +010082 rpc = malloc(sizeof *rpc);
83 if (!rpc) {
84 ERRMEM;
85 return NULL;
86 }
87
Michal Vasko90e8e692016-07-13 12:27:57 +020088 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010089 rpc->has_data = 0;
90 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
91 rpc->content.xml_str = strdup(xml_str);
92 } else {
93 rpc->content.xml_str = (char *)xml_str;
94 }
95 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
96
97 return (struct nc_rpc *)rpc;
98}
99
100API struct nc_rpc *
101nc_rpc_getconfig(NC_DATASTORE source, const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
102{
103 struct nc_rpc_getconfig *rpc;
104
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100105 if (!source) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200106 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100107 return NULL;
108 }
109
Michal Vaskof3c647b2016-03-08 12:17:33 +0100110 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200111 ERR(NULL, "Filter is neither an XML subtree nor an XPath expression (invalid first char '%c').", filter[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100112 return NULL;
113 }
114
115 rpc = malloc(sizeof *rpc);
116 if (!rpc) {
117 ERRMEM;
118 return NULL;
119 }
120
121 rpc->type = NC_RPC_GETCONFIG;
122 rpc->source = source;
123 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
124 rpc->filter = strdup(filter);
125 } else {
126 rpc->filter = (char *)filter;
127 }
128 rpc->wd_mode = wd_mode;
129 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
130
131 return (struct nc_rpc *)rpc;
132}
133
134API struct nc_rpc *
135nc_rpc_edit(NC_DATASTORE target, NC_RPC_EDIT_DFLTOP default_op, NC_RPC_EDIT_TESTOPT test_opt,
Michal Vasko96f247a2021-03-15 13:32:10 +0100136 NC_RPC_EDIT_ERROPT error_opt, const char *edit_content, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100137{
138 struct nc_rpc_edit *rpc;
139
Michal Vasko45e53ae2016-04-07 11:46:03 +0200140 if (!target) {
141 ERRARG("target");
142 return NULL;
143 } else if (!edit_content) {
144 ERRARG("edit_content");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100145 return NULL;
146 }
147
Michal Vasko7793bc62016-09-16 11:58:41 +0200148 if (edit_content[0] && (edit_content[0] != '<') && !isalpha(edit_content[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200149 ERR(NULL, "<edit-config> content is neither a URL nor an XML config (invalid first char '%c').", edit_content[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100150 return NULL;
151 }
152
153 rpc = malloc(sizeof *rpc);
154 if (!rpc) {
155 ERRMEM;
156 return NULL;
157 }
158
159 rpc->type = NC_RPC_EDIT;
160 rpc->target = target;
161 rpc->default_op = default_op;
162 rpc->test_opt = test_opt;
163 rpc->error_opt = error_opt;
164 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
165 rpc->edit_cont = strdup(edit_content);
166 } else {
167 rpc->edit_cont = (char *)edit_content;
168 }
169 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
170
171 return (struct nc_rpc *)rpc;
172}
173
174API struct nc_rpc *
175nc_rpc_copy(NC_DATASTORE target, const char *url_trg, NC_DATASTORE source, const char *url_or_config_src,
Michal Vasko96f247a2021-03-15 13:32:10 +0100176 NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100177{
178 struct nc_rpc_copy *rpc;
179
Michal Vasko45e53ae2016-04-07 11:46:03 +0200180 if (!target) {
181 ERRARG("target");
182 return NULL;
183 } else if (!source) {
184 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100185 return NULL;
186 }
187
Michal Vasko7793bc62016-09-16 11:58:41 +0200188 if (url_or_config_src && url_or_config_src[0] && (url_or_config_src[0] != '<') && !isalpha(url_or_config_src[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200189 ERR(NULL, "<copy-config> source is neither a URL nor an XML config (invalid first char '%c').", url_or_config_src[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100190 return NULL;
191 }
192
193 rpc = malloc(sizeof *rpc);
194 if (!rpc) {
195 ERRMEM;
196 return NULL;
197 }
198
199 rpc->type = NC_RPC_COPY;
200 rpc->target = target;
201 if (url_trg && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
202 rpc->url_trg = strdup(url_trg);
203 } else {
204 rpc->url_trg = (char *)url_trg;
205 }
206 rpc->source = source;
207 if (url_or_config_src && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
208 rpc->url_config_src = strdup(url_or_config_src);
209 } else {
210 rpc->url_config_src = (char *)url_or_config_src;
211 }
212 rpc->wd_mode = wd_mode;
213 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
214
215 return (struct nc_rpc *)rpc;
216}
217
218API struct nc_rpc *
219nc_rpc_delete(NC_DATASTORE target, const char *url, NC_PARAMTYPE paramtype)
220{
221 struct nc_rpc_delete *rpc;
222
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100223 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200224 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100225 return NULL;
226 }
227
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100228 rpc = malloc(sizeof *rpc);
229 if (!rpc) {
230 ERRMEM;
231 return NULL;
232 }
233
234 rpc->type = NC_RPC_DELETE;
235 rpc->target = target;
236 if (url && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
237 rpc->url = strdup(url);
238 } else {
239 rpc->url = (char *)url;
240 }
241 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
242
243 return (struct nc_rpc *)rpc;
244}
245
246API struct nc_rpc *
247nc_rpc_lock(NC_DATASTORE target)
248{
249 struct nc_rpc_lock *rpc;
250
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100251 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200252 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100253 return NULL;
254 }
255
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100256 rpc = malloc(sizeof *rpc);
257 if (!rpc) {
258 ERRMEM;
259 return NULL;
260 }
261
262 rpc->type = NC_RPC_LOCK;
263 rpc->target = target;
264
265 return (struct nc_rpc *)rpc;
266}
267
268API struct nc_rpc *
269nc_rpc_unlock(NC_DATASTORE target)
270{
271 struct nc_rpc_lock *rpc;
272
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100273 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200274 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100275 return NULL;
276 }
277
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100278 rpc = malloc(sizeof *rpc);
279 if (!rpc) {
280 ERRMEM;
281 return NULL;
282 }
283
284 rpc->type = NC_RPC_UNLOCK;
285 rpc->target = target;
286
287 return (struct nc_rpc *)rpc;
288}
289
290API struct nc_rpc *
291nc_rpc_get(const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
292{
293 struct nc_rpc_get *rpc;
294
Michal Vaskof3c647b2016-03-08 12:17:33 +0100295 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200296 ERR(NULL, "Filter is neither an XML subtree nor an XPath expression (invalid first char '%c').", filter[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100297 return NULL;
298 }
299
300 rpc = malloc(sizeof *rpc);
301 if (!rpc) {
302 ERRMEM;
303 return NULL;
304 }
305
306 rpc->type = NC_RPC_GET;
307 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
308 rpc->filter = strdup(filter);
309 } else {
310 rpc->filter = (char *)filter;
311 }
312 rpc->wd_mode = wd_mode;
313 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
314
315 return (struct nc_rpc *)rpc;
316}
317
318API struct nc_rpc *
319nc_rpc_kill(uint32_t session_id)
320{
321 struct nc_rpc_kill *rpc;
322
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100323 if (!session_id) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200324 ERRARG("session_id");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100325 return NULL;
326 }
327
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100328 rpc = malloc(sizeof *rpc);
329 if (!rpc) {
330 ERRMEM;
331 return NULL;
332 }
333
334 rpc->type = NC_RPC_KILL;
335 rpc->sid = session_id;
336
337 return (struct nc_rpc *)rpc;
338}
339
340API struct nc_rpc *
341nc_rpc_commit(int confirmed, uint32_t confirm_timeout, const char *persist, const char *persist_id,
Michal Vasko96f247a2021-03-15 13:32:10 +0100342 NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100343{
344 struct nc_rpc_commit *rpc;
345
346 rpc = malloc(sizeof *rpc);
347 if (!rpc) {
348 ERRMEM;
349 return NULL;
350 }
351
352 rpc->type = NC_RPC_COMMIT;
353 rpc->confirmed = confirmed;
354 rpc->confirm_timeout = confirm_timeout;
355 if (persist && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
356 rpc->persist = strdup(persist);
357 } else {
358 rpc->persist = (char *)persist;
359 }
360 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
361 rpc->persist_id = strdup(persist_id);
362 } else {
363 rpc->persist_id = (char *)persist_id;
364 }
365 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
366
367 return (struct nc_rpc *)rpc;
368}
369
370API struct nc_rpc *
371nc_rpc_discard(void)
372{
373 struct nc_rpc *rpc;
374
375 rpc = malloc(sizeof *rpc);
376 if (!rpc) {
377 ERRMEM;
378 return NULL;
379 }
380
381 rpc->type = NC_RPC_DISCARD;
382
383 return rpc;
384}
385
386API struct nc_rpc *
387nc_rpc_cancel(const char *persist_id, NC_PARAMTYPE paramtype)
388{
389 struct nc_rpc_cancel *rpc;
390
391 rpc = malloc(sizeof *rpc);
392 if (!rpc) {
393 ERRMEM;
394 return NULL;
395 }
396
397 rpc->type = NC_RPC_CANCEL;
398 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
399 rpc->persist_id = strdup(persist_id);
400 } else {
401 rpc->persist_id = (char *)persist_id;
402 }
403 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
404
405 return (struct nc_rpc *)rpc;
406}
407
408API struct nc_rpc *
409nc_rpc_validate(NC_DATASTORE source, const char *url_or_config, NC_PARAMTYPE paramtype)
410{
411 struct nc_rpc_validate *rpc;
412
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100413 if (!source) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200414 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100415 return NULL;
416 }
417
Michal Vasko7793bc62016-09-16 11:58:41 +0200418 if (url_or_config && url_or_config[0] && (url_or_config[0] != '<') && !isalpha(url_or_config[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200419 ERR(NULL, "<validate> source is neither a URL nor an XML config (invalid first char '%c').", url_or_config[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100420 return NULL;
421 }
422
423 rpc = malloc(sizeof *rpc);
424 if (!rpc) {
425 ERRMEM;
426 return NULL;
427 }
428
429 rpc->type = NC_RPC_VALIDATE;
430 rpc->source = source;
431 if (url_or_config && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
432 rpc->url_config_src = strdup(url_or_config);
433 } else {
434 rpc->url_config_src = (char *)url_or_config;
435 }
436 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
437
438 return (struct nc_rpc *)rpc;
439}
440
441API struct nc_rpc *
442nc_rpc_getschema(const char *identifier, const char *version, const char *format, NC_PARAMTYPE paramtype)
443{
444 struct nc_rpc_getschema *rpc;
445
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100446 if (!identifier) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200447 ERRARG("identifier");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100448 return NULL;
449 }
450
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100451 rpc = malloc(sizeof *rpc);
452 if (!rpc) {
453 ERRMEM;
454 return NULL;
455 }
456
457 rpc->type = NC_RPC_GETSCHEMA;
458 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
459 rpc->identifier = strdup(identifier);
460 } else {
461 rpc->identifier = (char *)identifier;
462 }
463 if (version && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
464 rpc->version = strdup(version);
465 } else {
466 rpc->version = (char *)version;
467 }
468 if (format && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
469 rpc->format = strdup(format);
470 } else {
471 rpc->format = (char *)format;
472 }
473 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
474
475 return (struct nc_rpc *)rpc;
476}
477
478API struct nc_rpc *
479nc_rpc_subscribe(const char *stream_name, const char *filter, const char *start_time, const char *stop_time,
Michal Vasko96f247a2021-03-15 13:32:10 +0100480 NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100481{
482 struct nc_rpc_subscribe *rpc;
483
Michal Vaskof3c647b2016-03-08 12:17:33 +0100484 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200485 ERR(NULL, "Filter is neither an XML subtree nor an XPath expression (invalid first char '%c').", filter[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100486 return NULL;
487 }
488
489 rpc = malloc(sizeof *rpc);
490 if (!rpc) {
491 ERRMEM;
492 return NULL;
493 }
494
495 rpc->type = NC_RPC_SUBSCRIBE;
496 if (stream_name && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
497 rpc->stream = strdup(stream_name);
498 } else {
499 rpc->stream = (char *)stream_name;
500 }
501 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
502 rpc->filter = strdup(filter);
503 } else {
504 rpc->filter = (char *)filter;
505 }
506 if (start_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
507 rpc->start = strdup(start_time);
508 } else {
509 rpc->start = (char *)start_time;
510 }
511 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
512 rpc->stop = strdup(stop_time);
513 } else {
514 rpc->stop = (char *)stop_time;
515 }
516 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
517
518 return (struct nc_rpc *)rpc;
519}
520
Michal Vaskoc1171a42019-11-05 12:06:46 +0100521API struct nc_rpc *
522nc_rpc_getdata(const char *datastore, const char *filter, const char *config_filter, char **origin_filter,
Michal Vasko96f247a2021-03-15 13:32:10 +0100523 int origin_filter_count, int negated_origin_filter, uint16_t max_depth, int with_origin, NC_WD_MODE wd_mode,
524 NC_PARAMTYPE paramtype)
Michal Vaskoc1171a42019-11-05 12:06:46 +0100525{
526 struct nc_rpc_getdata *rpc = NULL;
527 int i;
528
529 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200530 ERR(NULL, "Filter is neither an XML subtree nor an XPath expression (invalid first char '%c').", filter[0]);
Michal Vaskoc1171a42019-11-05 12:06:46 +0100531 return NULL;
532 } else if (!datastore) {
533 ERRARG("datastore");
534 return NULL;
535 }
536
537 rpc = calloc(1, sizeof *rpc);
538 if (!rpc) {
539 ERRMEM;
540 return NULL;
541 }
542 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
543
544 rpc->type = NC_RPC_GETDATA;
545 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
546 rpc->datastore = strdup(datastore);
547 } else {
548 rpc->datastore = (char *)datastore;
549 }
550 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
551 rpc->filter = strdup(filter);
552 } else {
553 rpc->filter = (char *)filter;
554 }
555 if (config_filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
556 rpc->config_filter = strdup(config_filter);
557 } else {
558 rpc->config_filter = (char *)config_filter;
559 }
560 if (origin_filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
561 rpc->origin_filter = malloc(origin_filter_count * sizeof *rpc->origin_filter);
562 if (!rpc->origin_filter) {
563 ERRMEM;
564 goto error;
565 }
566 for (i = 0; i < origin_filter_count; ++i) {
567 rpc->origin_filter[i] = strdup(origin_filter[i]);
568 if (!rpc->origin_filter[i]) {
569 ERRMEM;
570 goto error;
571 }
572 ++rpc->origin_filter_count;
573 }
574 } else {
575 rpc->origin_filter = origin_filter;
576 rpc->origin_filter_count = origin_filter_count;
577 }
578 rpc->negated_origin_filter = negated_origin_filter;
579 rpc->max_depth = max_depth;
580 rpc->with_origin = with_origin;
581 rpc->wd_mode = wd_mode;
582
583 return (struct nc_rpc *)rpc;
584
585error:
586 nc_rpc_free((struct nc_rpc *)rpc);
587 return NULL;
588}
589
590API struct nc_rpc *
591nc_rpc_editdata(const char *datastore, NC_RPC_EDIT_DFLTOP default_op, const char *edit_content, NC_PARAMTYPE paramtype)
592{
593 struct nc_rpc_editdata *rpc;
594
595 if (!datastore) {
596 ERRARG("datastore");
597 return NULL;
598 } else if (!edit_content) {
599 ERRARG("edit_content");
600 return NULL;
601 }
602
603 if (edit_content[0] && (edit_content[0] != '<') && !isalpha(edit_content[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200604 ERR(NULL, "<edit-data> content is neither a URL nor an XML config (invalid first char '%c').", edit_content[0]);
Michal Vaskoc1171a42019-11-05 12:06:46 +0100605 return NULL;
606 }
607
608 rpc = malloc(sizeof *rpc);
609 if (!rpc) {
610 ERRMEM;
611 return NULL;
612 }
613
614 rpc->type = NC_RPC_EDITDATA;
615 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
616 rpc->datastore = strdup(datastore);
617 } else {
618 rpc->datastore = (char *)datastore;
619 }
620 rpc->default_op = default_op;
621 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
622 rpc->edit_cont = strdup(edit_content);
623 } else {
624 rpc->edit_cont = (char *)edit_content;
625 }
626 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
627
628 return (struct nc_rpc *)rpc;
629}
630
Michal Vasko96f247a2021-03-15 13:32:10 +0100631API struct nc_rpc *
632nc_rpc_establishsub(const char *filter, const char *stream_name, const char *start_time,
633 const char *stop_time, const char *encoding, NC_PARAMTYPE paramtype)
634{
635 struct nc_rpc_establishsub *rpc;
636
637 if (!stream_name) {
638 ERRARG("stream_name");
639 return NULL;
640 }
641
642 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200643 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
644 filter[0]);
Michal Vasko96f247a2021-03-15 13:32:10 +0100645 return NULL;
646 }
647
648 rpc = malloc(sizeof *rpc);
649 if (!rpc) {
650 ERRMEM;
651 return NULL;
652 }
653
654 rpc->type = NC_RPC_ESTABLISHSUB;
655 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
656 rpc->filter = strdup(filter);
657 } else {
658 rpc->filter = (char *)filter;
659 }
660 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
661 rpc->stream = strdup(stream_name);
662 } else {
663 rpc->stream = (char *)stream_name;
664 }
665 if (start_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
666 rpc->start = strdup(start_time);
667 } else {
668 rpc->start = (char *)start_time;
669 }
670 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
671 rpc->stop = strdup(stop_time);
672 } else {
673 rpc->stop = (char *)stop_time;
674 }
675 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
676 rpc->encoding = strdup(encoding);
677 } else {
678 rpc->encoding = (char *)encoding;
679 }
680 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
681
682 return (struct nc_rpc *)rpc;
683}
684
685API struct nc_rpc *
686nc_rpc_modifysub(uint32_t id, const char *filter, const char *stop_time, NC_PARAMTYPE paramtype)
687{
688 struct nc_rpc_modifysub *rpc;
689
690 if (!id) {
691 ERRARG("id");
692 return NULL;
693 }
694
695 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200696 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
697 filter[0]);
Michal Vasko96f247a2021-03-15 13:32:10 +0100698 return NULL;
699 }
700
701 rpc = malloc(sizeof *rpc);
702 if (!rpc) {
703 ERRMEM;
704 return NULL;
705 }
706
707 rpc->type = NC_RPC_MODIFYSUB;
708 rpc->id = id;
709 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
710 rpc->filter = strdup(filter);
711 } else {
712 rpc->filter = (char *)filter;
713 }
714 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
715 rpc->stop = strdup(stop_time);
716 } else {
717 rpc->stop = (char *)stop_time;
718 }
719 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
720
721 return (struct nc_rpc *)rpc;
722}
723
724API struct nc_rpc *
725nc_rpc_deletesub(uint32_t id)
726{
727 struct nc_rpc_deletesub *rpc;
728
729 if (!id) {
730 ERRARG("id");
731 return NULL;
732 }
733
734 rpc = malloc(sizeof *rpc);
735 if (!rpc) {
736 ERRMEM;
737 return NULL;
738 }
739
740 rpc->type = NC_RPC_DELETESUB;
741 rpc->id = id;
742
743 return (struct nc_rpc *)rpc;
744}
745
746API struct nc_rpc *
747nc_rpc_killsub(uint32_t id)
748{
749 struct nc_rpc_killsub *rpc;
750
751 if (!id) {
752 ERRARG("id");
753 return NULL;
754 }
755
756 rpc = malloc(sizeof *rpc);
757 if (!rpc) {
758 ERRMEM;
759 return NULL;
760 }
761
762 rpc->type = NC_RPC_KILLSUB;
763 rpc->id = id;
764
765 return (struct nc_rpc *)rpc;
766}
767
Michal Vasko305faca2021-03-25 09:16:02 +0100768API struct nc_rpc *
769nc_rpc_establishpush_periodic(const char *datastore, const char *filter, const char *stop_time, const char *encoding,
770 uint32_t period, const char *anchor_time, NC_PARAMTYPE paramtype)
771{
772 struct nc_rpc_establishpush *rpc;
773
774 if (!datastore) {
775 ERRARG("datastore");
776 return NULL;
777 } else if (!period) {
778 ERRARG("period");
779 return NULL;
780 }
781
782 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200783 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
784 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100785 return NULL;
786 }
787
788 rpc = malloc(sizeof *rpc);
789 if (!rpc) {
790 ERRMEM;
791 return NULL;
792 }
793
794 rpc->type = NC_RPC_ESTABLISHPUSH;
795 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
796 rpc->datastore = strdup(datastore);
797 } else {
798 rpc->datastore = (char *)datastore;
799 }
800 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
801 rpc->filter = strdup(filter);
802 } else {
803 rpc->filter = (char *)filter;
804 }
805 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
806 rpc->stop = strdup(stop_time);
807 } else {
808 rpc->stop = (char *)stop_time;
809 }
810 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
811 rpc->encoding = strdup(encoding);
812 } else {
813 rpc->encoding = (char *)encoding;
814 }
815 rpc->periodic = 1;
816 rpc->period = period;
817 if (anchor_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
818 rpc->anchor_time = strdup(anchor_time);
819 } else {
820 rpc->anchor_time = (char *)anchor_time;
821 }
822 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
823
824 return (struct nc_rpc *)rpc;
825}
826
827API struct nc_rpc *
828nc_rpc_establishpush_onchange(const char *datastore, const char *filter, const char *stop_time, const char *encoding,
829 uint32_t dampening_period, int sync_on_start, const char **excluded_change, NC_PARAMTYPE paramtype)
830{
831 struct nc_rpc_establishpush *rpc;
832 uint32_t i;
833
834 if (!datastore) {
835 ERRARG("datastore");
836 return NULL;
837 }
838
839 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200840 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
841 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100842 return NULL;
843 }
844
845 rpc = malloc(sizeof *rpc);
846 if (!rpc) {
847 ERRMEM;
848 return NULL;
849 }
850
851 rpc->type = NC_RPC_ESTABLISHPUSH;
852 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
853 rpc->datastore = strdup(datastore);
854 } else {
855 rpc->datastore = (char *)datastore;
856 }
857 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
858 rpc->filter = strdup(filter);
859 } else {
860 rpc->filter = (char *)filter;
861 }
862 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
863 rpc->stop = strdup(stop_time);
864 } else {
865 rpc->stop = (char *)stop_time;
866 }
867 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
868 rpc->encoding = strdup(encoding);
869 } else {
870 rpc->encoding = (char *)encoding;
871 }
872 rpc->periodic = 0;
873 rpc->dampening_period = dampening_period;
874 rpc->sync_on_start = sync_on_start;
875 if (excluded_change && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
876 rpc->excluded_change = NULL;
877 for (i = 0; excluded_change[i]; ++i) {
878 rpc->excluded_change = realloc(rpc->excluded_change, (i + 2) * sizeof *rpc->excluded_change);
879 rpc->excluded_change[i] = strdup(excluded_change[i]);
880 rpc->excluded_change[i + 1] = NULL;
881 }
882 } else {
883 rpc->excluded_change = (char **)excluded_change;
884 }
885 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
886
887 return (struct nc_rpc *)rpc;
888}
889
890API struct nc_rpc *
891nc_rpc_modifypush_periodic(uint32_t id, const char *datastore, const char *filter, const char *stop_time, uint32_t period,
892 const char *anchor_time, NC_PARAMTYPE paramtype)
893{
894 struct nc_rpc_modifypush *rpc;
895
896 if (!id) {
897 ERRARG("id");
898 return NULL;
899 } else if (!datastore) {
900 ERRARG("datastore");
901 return NULL;
902 }
903
904 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200905 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
906 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100907 return NULL;
908 }
909
910 rpc = malloc(sizeof *rpc);
911 if (!rpc) {
912 ERRMEM;
913 return NULL;
914 }
915
916 rpc->type = NC_RPC_MODIFYPUSH;
917 rpc->id = id;
918 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
919 rpc->datastore = strdup(datastore);
920 } else {
921 rpc->datastore = (char *)datastore;
922 }
923 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
924 rpc->filter = strdup(filter);
925 } else {
926 rpc->filter = (char *)filter;
927 }
928 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
929 rpc->stop = strdup(stop_time);
930 } else {
931 rpc->stop = (char *)stop_time;
932 }
933 rpc->periodic = 1;
934 rpc->period = period;
935 if (anchor_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
936 rpc->anchor_time = strdup(anchor_time);
937 } else {
938 rpc->anchor_time = (char *)anchor_time;
939 }
940 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
941
942 return (struct nc_rpc *)rpc;
943}
944
945API struct nc_rpc *
946nc_rpc_modifypush_onchange(uint32_t id, const char *datastore, const char *filter, const char *stop_time,
947 uint32_t dampening_period, NC_PARAMTYPE paramtype)
948{
949 struct nc_rpc_modifypush *rpc;
950
951 if (!id) {
952 ERRARG("id");
953 return NULL;
954 } else if (!datastore) {
955 ERRARG("datastore");
956 return NULL;
957 }
958
959 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200960 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
961 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100962 return NULL;
963 }
964
965 rpc = malloc(sizeof *rpc);
966 if (!rpc) {
967 ERRMEM;
968 return NULL;
969 }
970
971 rpc->type = NC_RPC_MODIFYPUSH;
972 rpc->id = id;
973 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
974 rpc->datastore = strdup(datastore);
975 } else {
976 rpc->datastore = (char *)datastore;
977 }
978 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
979 rpc->filter = strdup(filter);
980 } else {
981 rpc->filter = (char *)filter;
982 }
983 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
984 rpc->stop = strdup(stop_time);
985 } else {
986 rpc->stop = (char *)stop_time;
987 }
988 rpc->periodic = 0;
989 rpc->dampening_period = dampening_period;
990 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
991
992 return (struct nc_rpc *)rpc;
993}
994
995API struct nc_rpc *
996nc_rpc_resyncsub(uint32_t id)
997{
998 struct nc_rpc_resyncsub *rpc;
999
1000 if (!id) {
1001 ERRARG("id");
1002 return NULL;
1003 }
1004
1005 rpc = malloc(sizeof *rpc);
1006 if (!rpc) {
1007 ERRMEM;
1008 return NULL;
1009 }
1010
1011 rpc->type = NC_RPC_RESYNCSUB;
1012 rpc->id = id;
1013
1014 return (struct nc_rpc *)rpc;
1015}
1016
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001017API void
1018nc_rpc_free(struct nc_rpc *rpc)
1019{
Michal Vasko90e8e692016-07-13 12:27:57 +02001020 struct nc_rpc_act_generic *rpc_generic;
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001021 struct nc_rpc_getconfig *rpc_getconfig;
1022 struct nc_rpc_edit *rpc_edit;
1023 struct nc_rpc_copy *rpc_copy;
1024 struct nc_rpc_delete *rpc_delete;
1025 struct nc_rpc_get *rpc_get;
1026 struct nc_rpc_commit *rpc_commit;
1027 struct nc_rpc_cancel *rpc_cancel;
1028 struct nc_rpc_validate *rpc_validate;
1029 struct nc_rpc_getschema *rpc_getschema;
1030 struct nc_rpc_subscribe *rpc_subscribe;
Michal Vaskoc1171a42019-11-05 12:06:46 +01001031 struct nc_rpc_getdata *rpc_getdata;
1032 struct nc_rpc_editdata *rpc_editdata;
Michal Vasko96f247a2021-03-15 13:32:10 +01001033 struct nc_rpc_establishsub *rpc_establishsub;
1034 struct nc_rpc_modifysub *rpc_modifysub;
Michal Vasko305faca2021-03-25 09:16:02 +01001035 struct nc_rpc_establishpush *rpc_establishpush;
1036 struct nc_rpc_modifypush *rpc_modifypush;
Michal Vaskoc1171a42019-11-05 12:06:46 +01001037 int i;
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001038
1039 if (!rpc) {
1040 return;
1041 }
1042
1043 switch (rpc->type) {
Michal Vasko90e8e692016-07-13 12:27:57 +02001044 case NC_RPC_ACT_GENERIC:
1045 rpc_generic = (struct nc_rpc_act_generic *)rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001046 if (rpc_generic->free) {
1047 if (rpc_generic->has_data) {
Michal Vasko77367452021-02-16 16:32:18 +01001048 lyd_free_tree(rpc_generic->content.data);
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001049 } else {
1050 free(rpc_generic->content.xml_str);
1051 }
1052 }
1053 break;
1054 case NC_RPC_GETCONFIG:
1055 rpc_getconfig = (struct nc_rpc_getconfig *)rpc;
1056 if (rpc_getconfig->free) {
1057 free(rpc_getconfig->filter);
1058 }
1059 break;
1060 case NC_RPC_EDIT:
1061 rpc_edit = (struct nc_rpc_edit *)rpc;
1062 if (rpc_edit->free) {
1063 free(rpc_edit->edit_cont);
1064 }
1065 break;
1066 case NC_RPC_COPY:
1067 rpc_copy = (struct nc_rpc_copy *)rpc;
1068 if (rpc_copy->free) {
1069 free(rpc_copy->url_config_src);
David Sedlák35419a32018-10-07 23:23:33 +02001070 free(rpc_copy->url_trg);
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001071 }
1072 break;
1073 case NC_RPC_DELETE:
1074 rpc_delete = (struct nc_rpc_delete *)rpc;
1075 if (rpc_delete->free) {
1076 free(rpc_delete->url);
1077 }
1078 break;
1079 case NC_RPC_GET:
1080 rpc_get = (struct nc_rpc_get *)rpc;
1081 if (rpc_get->free) {
1082 free(rpc_get->filter);
1083 }
1084 break;
1085 case NC_RPC_COMMIT:
1086 rpc_commit = (struct nc_rpc_commit *)rpc;
1087 if (rpc_commit->free) {
1088 free(rpc_commit->persist);
1089 free(rpc_commit->persist_id);
1090 }
1091 break;
1092 case NC_RPC_CANCEL:
1093 rpc_cancel = (struct nc_rpc_cancel *)rpc;
1094 if (rpc_cancel->free) {
1095 free(rpc_cancel->persist_id);
1096 }
1097 break;
1098 case NC_RPC_VALIDATE:
1099 rpc_validate = (struct nc_rpc_validate *)rpc;
1100 if (rpc_validate->free) {
1101 free(rpc_validate->url_config_src);
1102 }
1103 break;
1104 case NC_RPC_GETSCHEMA:
1105 rpc_getschema = (struct nc_rpc_getschema *)rpc;
1106 if (rpc_getschema->free) {
1107 free(rpc_getschema->identifier);
1108 free(rpc_getschema->version);
1109 free(rpc_getschema->format);
1110 }
1111 break;
1112 case NC_RPC_SUBSCRIBE:
1113 rpc_subscribe = (struct nc_rpc_subscribe *)rpc;
1114 if (rpc_subscribe->free) {
1115 free(rpc_subscribe->stream);
1116 free(rpc_subscribe->filter);
1117 free(rpc_subscribe->start);
1118 free(rpc_subscribe->stop);
1119 }
1120 break;
Michal Vaskoc1171a42019-11-05 12:06:46 +01001121 case NC_RPC_GETDATA:
1122 rpc_getdata = (struct nc_rpc_getdata *)rpc;
1123 if (rpc_getdata->free) {
1124 free(rpc_getdata->datastore);
1125 free(rpc_getdata->filter);
1126 free(rpc_getdata->config_filter);
1127 for (i = 0; i < rpc_getdata->origin_filter_count; ++i) {
1128 free(rpc_getdata->origin_filter[i]);
1129 }
1130 free(rpc_getdata->origin_filter);
1131 }
1132 break;
1133 case NC_RPC_EDITDATA:
1134 rpc_editdata = (struct nc_rpc_editdata *)rpc;
1135 if (rpc_editdata->free) {
1136 free(rpc_editdata->datastore);
1137 free(rpc_editdata->edit_cont);
1138 }
1139 break;
Michal Vasko96f247a2021-03-15 13:32:10 +01001140 case NC_RPC_ESTABLISHSUB:
1141 rpc_establishsub = (struct nc_rpc_establishsub *)rpc;
1142 if (rpc_establishsub->free) {
1143 free(rpc_establishsub->filter);
1144 free(rpc_establishsub->stream);
1145 free(rpc_establishsub->start);
1146 free(rpc_establishsub->stop);
1147 free(rpc_establishsub->encoding);
1148 }
1149 break;
1150 case NC_RPC_MODIFYSUB:
1151 rpc_modifysub = (struct nc_rpc_modifysub *)rpc;
1152 if (rpc_modifysub->free) {
1153 free(rpc_modifysub->filter);
1154 free(rpc_modifysub->stop);
1155 }
1156 break;
Michal Vasko305faca2021-03-25 09:16:02 +01001157 case NC_RPC_ESTABLISHPUSH:
1158 rpc_establishpush = (struct nc_rpc_establishpush *)rpc;
1159 if (rpc_establishpush->free) {
1160 free(rpc_establishpush->datastore);
1161 free(rpc_establishpush->filter);
1162 free(rpc_establishpush->stop);
1163 free(rpc_establishpush->encoding);
1164 if (rpc_establishpush->periodic) {
1165 free(rpc_establishpush->anchor_time);
1166 } else {
1167 if (rpc_establishpush->excluded_change) {
1168 for (i = 0; rpc_establishpush->excluded_change[i]; ++i) {
1169 free(rpc_establishpush->excluded_change[i]);
1170 }
1171 free(rpc_establishpush->excluded_change);
1172 }
1173 }
1174 }
1175 break;
1176 case NC_RPC_MODIFYPUSH:
1177 rpc_modifypush = (struct nc_rpc_modifypush *)rpc;
1178 if (rpc_modifypush->free) {
1179 free(rpc_modifypush->datastore);
1180 free(rpc_modifypush->filter);
1181 free(rpc_modifypush->stop);
1182 if (rpc_modifypush->periodic) {
1183 free(rpc_modifypush->anchor_time);
1184 }
1185 }
1186 break;
Michal Vasko96f247a2021-03-15 13:32:10 +01001187 case NC_RPC_UNKNOWN:
1188 case NC_RPC_LOCK:
1189 case NC_RPC_UNLOCK:
1190 case NC_RPC_KILL:
1191 case NC_RPC_DISCARD:
1192 case NC_RPC_DELETESUB:
1193 case NC_RPC_KILLSUB:
Michal Vasko305faca2021-03-25 09:16:02 +01001194 case NC_RPC_RESYNCSUB:
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001195 /* nothing special needed */
1196 break;
1197 }
1198
1199 free(rpc);
1200}
1201
1202API void
Radek Krejci36d2ee42017-10-13 13:55:59 +02001203nc_client_err_clean(struct nc_err *err, struct ly_ctx *ctx)
1204{
1205 int i;
1206
1207 assert(ctx);
1208
1209 if (!err) {
1210 return;
1211 }
1212
1213 lydict_remove(ctx, err->type);
1214 lydict_remove(ctx, err->tag);
1215 lydict_remove(ctx, err->severity);
1216 lydict_remove(ctx, err->apptag);
1217 lydict_remove(ctx, err->path);
1218 lydict_remove(ctx, err->message);
1219 lydict_remove(ctx, err->message_lang);
1220 lydict_remove(ctx, err->sid);
1221 for (i = 0; i < err->attr_count; ++i) {
1222 lydict_remove(ctx, err->attr[i]);
1223 }
1224 free(err->attr);
1225 for (i = 0; i < err->elem_count; ++i) {
1226 lydict_remove(ctx, err->elem[i]);
1227 }
1228 free(err->elem);
1229 for (i = 0; i < err->ns_count; ++i) {
1230 lydict_remove(ctx, err->ns[i]);
1231 }
1232 free(err->ns);
Michal Vasko77367452021-02-16 16:32:18 +01001233 lyd_free_siblings(err->other);
Radek Krejci36d2ee42017-10-13 13:55:59 +02001234 free(err->other);
1235}