blob: 5cd1165c8fafe686697768b4cd88ee5a3a26eeba [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
Michal Vaskoba9f3582023-02-22 10:26:32 +010016#define _GNU_SOURCE /* pthread_rwlock_t, strdup */
17
Radek Krejci36d2ee42017-10-13 13:55:59 +020018#include <assert.h>
Michal Vasko7bcb48e2016-01-15 10:28:54 +010019#include <ctype.h>
20#include <stdlib.h>
21#include <string.h>
Michal Vasko7bcb48e2016-01-15 10:28:54 +010022
23#include <libyang/libyang.h>
24
roman3f9b65c2023-06-05 14:26:58 +020025#include "compat.h"
26#include "config.h"
27#include "log_p.h"
28#include "messages_client.h"
29#include "messages_p.h"
30#include "netconf.h"
Michal Vasko7bcb48e2016-01-15 10:28:54 +010031
32const char *rpcedit_dfltop2str[] = {NULL, "merge", "replace", "none"};
33const char *rpcedit_testopt2str[] = {NULL, "test-then-set", "set", "test-only"};
34const char *rpcedit_erropt2str[] = {NULL, "stop-on-error", "continue-on-error", "rollback-on-error"};
35
36API NC_RPC_TYPE
37nc_rpc_get_type(const struct nc_rpc *rpc)
38{
roman40672412023-05-04 11:10:22 +020039 NC_CHECK_ARG_RET(NULL, rpc, 0);
Michal Vasko7f1c78b2016-01-19 09:52:14 +010040
Michal Vasko7bcb48e2016-01-15 10:28:54 +010041 return rpc->type;
42}
43
44API struct nc_rpc *
Michal Vasko90e8e692016-07-13 12:27:57 +020045nc_rpc_act_generic(const struct lyd_node *data, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +010046{
Michal Vasko90e8e692016-07-13 12:27:57 +020047 struct nc_rpc_act_generic *rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010048
roman40672412023-05-04 11:10:22 +020049 NC_CHECK_ARG_RET(NULL, data, data->next, NULL);
50 if (data->prev != data) {
51 ERR(NULL, "nc_rpc_act_generic missing data");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010052 return NULL;
53 }
54
Michal Vasko7bcb48e2016-01-15 10:28:54 +010055 rpc = malloc(sizeof *rpc);
56 if (!rpc) {
57 ERRMEM;
58 return NULL;
59 }
60
Michal Vasko90e8e692016-07-13 12:27:57 +020061 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010062 rpc->has_data = 1;
63 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
Michal Vasko77367452021-02-16 16:32:18 +010064 if (lyd_dup_single(data, NULL, LYD_DUP_RECURSIVE, &rpc->content.data)) {
65 free(rpc);
66 return NULL;
67 }
Michal Vasko7bcb48e2016-01-15 10:28:54 +010068 } else {
69 rpc->content.data = (struct lyd_node *)data;
70 }
71 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
72
73 return (struct nc_rpc *)rpc;
74}
75
76API struct nc_rpc *
Michal Vasko90e8e692016-07-13 12:27:57 +020077nc_rpc_act_generic_xml(const char *xml_str, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +010078{
Michal Vasko90e8e692016-07-13 12:27:57 +020079 struct nc_rpc_act_generic *rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010080
roman40672412023-05-04 11:10:22 +020081 NC_CHECK_ARG_RET(NULL, xml_str, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +010082
Michal Vasko7bcb48e2016-01-15 10:28:54 +010083 rpc = malloc(sizeof *rpc);
84 if (!rpc) {
85 ERRMEM;
86 return NULL;
87 }
88
Michal Vasko90e8e692016-07-13 12:27:57 +020089 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010090 rpc->has_data = 0;
91 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
92 rpc->content.xml_str = strdup(xml_str);
93 } else {
94 rpc->content.xml_str = (char *)xml_str;
95 }
96 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
97
98 return (struct nc_rpc *)rpc;
99}
100
101API struct nc_rpc *
102nc_rpc_getconfig(NC_DATASTORE source, const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
103{
104 struct nc_rpc_getconfig *rpc;
105
roman40672412023-05-04 11:10:22 +0200106 NC_CHECK_ARG_RET(NULL, source, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100107
Michal Vaskof3c647b2016-03-08 12:17:33 +0100108 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200109 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 +0100110 return NULL;
111 }
112
113 rpc = malloc(sizeof *rpc);
114 if (!rpc) {
115 ERRMEM;
116 return NULL;
117 }
118
119 rpc->type = NC_RPC_GETCONFIG;
120 rpc->source = source;
121 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
122 rpc->filter = strdup(filter);
123 } else {
124 rpc->filter = (char *)filter;
125 }
126 rpc->wd_mode = wd_mode;
127 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
128
129 return (struct nc_rpc *)rpc;
130}
131
132API struct nc_rpc *
133nc_rpc_edit(NC_DATASTORE target, NC_RPC_EDIT_DFLTOP default_op, NC_RPC_EDIT_TESTOPT test_opt,
Michal Vasko96f247a2021-03-15 13:32:10 +0100134 NC_RPC_EDIT_ERROPT error_opt, const char *edit_content, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100135{
136 struct nc_rpc_edit *rpc;
137
roman40672412023-05-04 11:10:22 +0200138 NC_CHECK_ARG_RET(NULL, target, edit_content, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100139
Michal Vasko7793bc62016-09-16 11:58:41 +0200140 if (edit_content[0] && (edit_content[0] != '<') && !isalpha(edit_content[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200141 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 +0100142 return NULL;
143 }
144
145 rpc = malloc(sizeof *rpc);
146 if (!rpc) {
147 ERRMEM;
148 return NULL;
149 }
150
151 rpc->type = NC_RPC_EDIT;
152 rpc->target = target;
153 rpc->default_op = default_op;
154 rpc->test_opt = test_opt;
155 rpc->error_opt = error_opt;
156 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
157 rpc->edit_cont = strdup(edit_content);
158 } else {
159 rpc->edit_cont = (char *)edit_content;
160 }
161 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
162
163 return (struct nc_rpc *)rpc;
164}
165
166API struct nc_rpc *
167nc_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 +0100168 NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100169{
170 struct nc_rpc_copy *rpc;
171
roman40672412023-05-04 11:10:22 +0200172 NC_CHECK_ARG_RET(NULL, target, source, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100173
Michal Vasko7793bc62016-09-16 11:58:41 +0200174 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 +0200175 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 +0100176 return NULL;
177 }
178
179 rpc = malloc(sizeof *rpc);
180 if (!rpc) {
181 ERRMEM;
182 return NULL;
183 }
184
185 rpc->type = NC_RPC_COPY;
186 rpc->target = target;
187 if (url_trg && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
188 rpc->url_trg = strdup(url_trg);
189 } else {
190 rpc->url_trg = (char *)url_trg;
191 }
192 rpc->source = source;
193 if (url_or_config_src && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
194 rpc->url_config_src = strdup(url_or_config_src);
195 } else {
196 rpc->url_config_src = (char *)url_or_config_src;
197 }
198 rpc->wd_mode = wd_mode;
199 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
200
201 return (struct nc_rpc *)rpc;
202}
203
204API struct nc_rpc *
205nc_rpc_delete(NC_DATASTORE target, const char *url, NC_PARAMTYPE paramtype)
206{
207 struct nc_rpc_delete *rpc;
208
roman40672412023-05-04 11:10:22 +0200209 NC_CHECK_ARG_RET(NULL, target, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100210
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100211 rpc = malloc(sizeof *rpc);
212 if (!rpc) {
213 ERRMEM;
214 return NULL;
215 }
216
217 rpc->type = NC_RPC_DELETE;
218 rpc->target = target;
219 if (url && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
220 rpc->url = strdup(url);
221 } else {
222 rpc->url = (char *)url;
223 }
224 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
225
226 return (struct nc_rpc *)rpc;
227}
228
229API struct nc_rpc *
230nc_rpc_lock(NC_DATASTORE target)
231{
232 struct nc_rpc_lock *rpc;
233
roman40672412023-05-04 11:10:22 +0200234 NC_CHECK_ARG_RET(NULL, target, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100235
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100236 rpc = malloc(sizeof *rpc);
237 if (!rpc) {
238 ERRMEM;
239 return NULL;
240 }
241
242 rpc->type = NC_RPC_LOCK;
243 rpc->target = target;
244
245 return (struct nc_rpc *)rpc;
246}
247
248API struct nc_rpc *
249nc_rpc_unlock(NC_DATASTORE target)
250{
251 struct nc_rpc_lock *rpc;
252
roman40672412023-05-04 11:10:22 +0200253 NC_CHECK_ARG_RET(NULL, target, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100254
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100255 rpc = malloc(sizeof *rpc);
256 if (!rpc) {
257 ERRMEM;
258 return NULL;
259 }
260
261 rpc->type = NC_RPC_UNLOCK;
262 rpc->target = target;
263
264 return (struct nc_rpc *)rpc;
265}
266
267API struct nc_rpc *
268nc_rpc_get(const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
269{
270 struct nc_rpc_get *rpc;
271
Michal Vaskof3c647b2016-03-08 12:17:33 +0100272 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200273 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 +0100274 return NULL;
275 }
276
277 rpc = malloc(sizeof *rpc);
278 if (!rpc) {
279 ERRMEM;
280 return NULL;
281 }
282
283 rpc->type = NC_RPC_GET;
284 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
285 rpc->filter = strdup(filter);
286 } else {
287 rpc->filter = (char *)filter;
288 }
289 rpc->wd_mode = wd_mode;
290 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
291
292 return (struct nc_rpc *)rpc;
293}
294
295API struct nc_rpc *
296nc_rpc_kill(uint32_t session_id)
297{
298 struct nc_rpc_kill *rpc;
299
roman40672412023-05-04 11:10:22 +0200300 NC_CHECK_ARG_RET(NULL, session_id, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100301
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100302 rpc = malloc(sizeof *rpc);
303 if (!rpc) {
304 ERRMEM;
305 return NULL;
306 }
307
308 rpc->type = NC_RPC_KILL;
309 rpc->sid = session_id;
310
311 return (struct nc_rpc *)rpc;
312}
313
314API struct nc_rpc *
315nc_rpc_commit(int confirmed, uint32_t confirm_timeout, const char *persist, const char *persist_id,
Michal Vasko96f247a2021-03-15 13:32:10 +0100316 NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100317{
318 struct nc_rpc_commit *rpc;
319
320 rpc = malloc(sizeof *rpc);
321 if (!rpc) {
322 ERRMEM;
323 return NULL;
324 }
325
326 rpc->type = NC_RPC_COMMIT;
327 rpc->confirmed = confirmed;
328 rpc->confirm_timeout = confirm_timeout;
329 if (persist && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
330 rpc->persist = strdup(persist);
331 } else {
332 rpc->persist = (char *)persist;
333 }
334 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
335 rpc->persist_id = strdup(persist_id);
336 } else {
337 rpc->persist_id = (char *)persist_id;
338 }
339 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
340
341 return (struct nc_rpc *)rpc;
342}
343
344API struct nc_rpc *
345nc_rpc_discard(void)
346{
347 struct nc_rpc *rpc;
348
349 rpc = malloc(sizeof *rpc);
350 if (!rpc) {
351 ERRMEM;
352 return NULL;
353 }
354
355 rpc->type = NC_RPC_DISCARD;
356
357 return rpc;
358}
359
360API struct nc_rpc *
361nc_rpc_cancel(const char *persist_id, NC_PARAMTYPE paramtype)
362{
363 struct nc_rpc_cancel *rpc;
364
365 rpc = malloc(sizeof *rpc);
366 if (!rpc) {
367 ERRMEM;
368 return NULL;
369 }
370
371 rpc->type = NC_RPC_CANCEL;
372 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
373 rpc->persist_id = strdup(persist_id);
374 } else {
375 rpc->persist_id = (char *)persist_id;
376 }
377 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
378
379 return (struct nc_rpc *)rpc;
380}
381
382API struct nc_rpc *
383nc_rpc_validate(NC_DATASTORE source, const char *url_or_config, NC_PARAMTYPE paramtype)
384{
385 struct nc_rpc_validate *rpc;
386
roman40672412023-05-04 11:10:22 +0200387 NC_CHECK_ARG_RET(NULL, source, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100388
Michal Vasko7793bc62016-09-16 11:58:41 +0200389 if (url_or_config && url_or_config[0] && (url_or_config[0] != '<') && !isalpha(url_or_config[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200390 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 +0100391 return NULL;
392 }
393
394 rpc = malloc(sizeof *rpc);
395 if (!rpc) {
396 ERRMEM;
397 return NULL;
398 }
399
400 rpc->type = NC_RPC_VALIDATE;
401 rpc->source = source;
402 if (url_or_config && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
403 rpc->url_config_src = strdup(url_or_config);
404 } else {
405 rpc->url_config_src = (char *)url_or_config;
406 }
407 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
408
409 return (struct nc_rpc *)rpc;
410}
411
412API struct nc_rpc *
413nc_rpc_getschema(const char *identifier, const char *version, const char *format, NC_PARAMTYPE paramtype)
414{
415 struct nc_rpc_getschema *rpc;
416
roman40672412023-05-04 11:10:22 +0200417 NC_CHECK_ARG_RET(NULL, identifier, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100418
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100419 rpc = malloc(sizeof *rpc);
420 if (!rpc) {
421 ERRMEM;
422 return NULL;
423 }
424
425 rpc->type = NC_RPC_GETSCHEMA;
426 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
427 rpc->identifier = strdup(identifier);
428 } else {
429 rpc->identifier = (char *)identifier;
430 }
431 if (version && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
432 rpc->version = strdup(version);
433 } else {
434 rpc->version = (char *)version;
435 }
436 if (format && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
437 rpc->format = strdup(format);
438 } else {
439 rpc->format = (char *)format;
440 }
441 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
442
443 return (struct nc_rpc *)rpc;
444}
445
446API struct nc_rpc *
447nc_rpc_subscribe(const char *stream_name, const char *filter, const char *start_time, const char *stop_time,
Michal Vasko96f247a2021-03-15 13:32:10 +0100448 NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100449{
450 struct nc_rpc_subscribe *rpc;
451
Michal Vaskof3c647b2016-03-08 12:17:33 +0100452 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200453 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 +0100454 return NULL;
455 }
456
457 rpc = malloc(sizeof *rpc);
458 if (!rpc) {
459 ERRMEM;
460 return NULL;
461 }
462
463 rpc->type = NC_RPC_SUBSCRIBE;
464 if (stream_name && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
465 rpc->stream = strdup(stream_name);
466 } else {
467 rpc->stream = (char *)stream_name;
468 }
469 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
470 rpc->filter = strdup(filter);
471 } else {
472 rpc->filter = (char *)filter;
473 }
474 if (start_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
475 rpc->start = strdup(start_time);
476 } else {
477 rpc->start = (char *)start_time;
478 }
479 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
480 rpc->stop = strdup(stop_time);
481 } else {
482 rpc->stop = (char *)stop_time;
483 }
484 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
485
486 return (struct nc_rpc *)rpc;
487}
488
Michal Vaskoc1171a42019-11-05 12:06:46 +0100489API struct nc_rpc *
490nc_rpc_getdata(const char *datastore, const char *filter, const char *config_filter, char **origin_filter,
Michal Vasko96f247a2021-03-15 13:32:10 +0100491 int origin_filter_count, int negated_origin_filter, uint16_t max_depth, int with_origin, NC_WD_MODE wd_mode,
492 NC_PARAMTYPE paramtype)
Michal Vaskoc1171a42019-11-05 12:06:46 +0100493{
494 struct nc_rpc_getdata *rpc = NULL;
495 int i;
496
roman40672412023-05-04 11:10:22 +0200497 NC_CHECK_ARG_RET(NULL, datastore, NULL);
498
Michal Vaskoc1171a42019-11-05 12:06:46 +0100499 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200500 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 +0100501 return NULL;
Michal Vaskoc1171a42019-11-05 12:06:46 +0100502 }
503
504 rpc = calloc(1, sizeof *rpc);
505 if (!rpc) {
506 ERRMEM;
507 return NULL;
508 }
509 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
510
511 rpc->type = NC_RPC_GETDATA;
512 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
513 rpc->datastore = strdup(datastore);
514 } else {
515 rpc->datastore = (char *)datastore;
516 }
517 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
518 rpc->filter = strdup(filter);
519 } else {
520 rpc->filter = (char *)filter;
521 }
522 if (config_filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
523 rpc->config_filter = strdup(config_filter);
524 } else {
525 rpc->config_filter = (char *)config_filter;
526 }
527 if (origin_filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
528 rpc->origin_filter = malloc(origin_filter_count * sizeof *rpc->origin_filter);
529 if (!rpc->origin_filter) {
530 ERRMEM;
531 goto error;
532 }
533 for (i = 0; i < origin_filter_count; ++i) {
534 rpc->origin_filter[i] = strdup(origin_filter[i]);
535 if (!rpc->origin_filter[i]) {
536 ERRMEM;
537 goto error;
538 }
539 ++rpc->origin_filter_count;
540 }
541 } else {
542 rpc->origin_filter = origin_filter;
543 rpc->origin_filter_count = origin_filter_count;
544 }
545 rpc->negated_origin_filter = negated_origin_filter;
546 rpc->max_depth = max_depth;
547 rpc->with_origin = with_origin;
548 rpc->wd_mode = wd_mode;
549
550 return (struct nc_rpc *)rpc;
551
552error:
553 nc_rpc_free((struct nc_rpc *)rpc);
554 return NULL;
555}
556
557API struct nc_rpc *
558nc_rpc_editdata(const char *datastore, NC_RPC_EDIT_DFLTOP default_op, const char *edit_content, NC_PARAMTYPE paramtype)
559{
560 struct nc_rpc_editdata *rpc;
561
roman40672412023-05-04 11:10:22 +0200562 NC_CHECK_ARG_RET(NULL, datastore, edit_content, NULL);
Michal Vaskoc1171a42019-11-05 12:06:46 +0100563
564 if (edit_content[0] && (edit_content[0] != '<') && !isalpha(edit_content[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200565 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 +0100566 return NULL;
567 }
568
569 rpc = malloc(sizeof *rpc);
570 if (!rpc) {
571 ERRMEM;
572 return NULL;
573 }
574
575 rpc->type = NC_RPC_EDITDATA;
576 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
577 rpc->datastore = strdup(datastore);
578 } else {
579 rpc->datastore = (char *)datastore;
580 }
581 rpc->default_op = default_op;
582 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
583 rpc->edit_cont = strdup(edit_content);
584 } else {
585 rpc->edit_cont = (char *)edit_content;
586 }
587 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
588
589 return (struct nc_rpc *)rpc;
590}
591
Michal Vasko96f247a2021-03-15 13:32:10 +0100592API struct nc_rpc *
593nc_rpc_establishsub(const char *filter, const char *stream_name, const char *start_time,
594 const char *stop_time, const char *encoding, NC_PARAMTYPE paramtype)
595{
596 struct nc_rpc_establishsub *rpc;
597
roman40672412023-05-04 11:10:22 +0200598 NC_CHECK_ARG_RET(NULL, stream_name, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100599
600 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200601 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
602 filter[0]);
Michal Vasko96f247a2021-03-15 13:32:10 +0100603 return NULL;
604 }
605
606 rpc = malloc(sizeof *rpc);
607 if (!rpc) {
608 ERRMEM;
609 return NULL;
610 }
611
612 rpc->type = NC_RPC_ESTABLISHSUB;
613 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
614 rpc->filter = strdup(filter);
615 } else {
616 rpc->filter = (char *)filter;
617 }
618 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
619 rpc->stream = strdup(stream_name);
620 } else {
621 rpc->stream = (char *)stream_name;
622 }
623 if (start_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
624 rpc->start = strdup(start_time);
625 } else {
626 rpc->start = (char *)start_time;
627 }
628 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
629 rpc->stop = strdup(stop_time);
630 } else {
631 rpc->stop = (char *)stop_time;
632 }
633 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
634 rpc->encoding = strdup(encoding);
635 } else {
636 rpc->encoding = (char *)encoding;
637 }
638 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
639
640 return (struct nc_rpc *)rpc;
641}
642
643API struct nc_rpc *
644nc_rpc_modifysub(uint32_t id, const char *filter, const char *stop_time, NC_PARAMTYPE paramtype)
645{
646 struct nc_rpc_modifysub *rpc;
647
roman40672412023-05-04 11:10:22 +0200648 NC_CHECK_ARG_RET(NULL, id, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100649
650 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200651 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
652 filter[0]);
Michal Vasko96f247a2021-03-15 13:32:10 +0100653 return NULL;
654 }
655
656 rpc = malloc(sizeof *rpc);
657 if (!rpc) {
658 ERRMEM;
659 return NULL;
660 }
661
662 rpc->type = NC_RPC_MODIFYSUB;
663 rpc->id = id;
664 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
665 rpc->filter = strdup(filter);
666 } else {
667 rpc->filter = (char *)filter;
668 }
669 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
670 rpc->stop = strdup(stop_time);
671 } else {
672 rpc->stop = (char *)stop_time;
673 }
674 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
675
676 return (struct nc_rpc *)rpc;
677}
678
679API struct nc_rpc *
680nc_rpc_deletesub(uint32_t id)
681{
682 struct nc_rpc_deletesub *rpc;
683
roman40672412023-05-04 11:10:22 +0200684 NC_CHECK_ARG_RET(NULL, id, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100685
686 rpc = malloc(sizeof *rpc);
687 if (!rpc) {
688 ERRMEM;
689 return NULL;
690 }
691
692 rpc->type = NC_RPC_DELETESUB;
693 rpc->id = id;
694
695 return (struct nc_rpc *)rpc;
696}
697
698API struct nc_rpc *
699nc_rpc_killsub(uint32_t id)
700{
701 struct nc_rpc_killsub *rpc;
702
roman40672412023-05-04 11:10:22 +0200703 NC_CHECK_ARG_RET(NULL, id, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100704
705 rpc = malloc(sizeof *rpc);
706 if (!rpc) {
707 ERRMEM;
708 return NULL;
709 }
710
711 rpc->type = NC_RPC_KILLSUB;
712 rpc->id = id;
713
714 return (struct nc_rpc *)rpc;
715}
716
Michal Vasko305faca2021-03-25 09:16:02 +0100717API struct nc_rpc *
718nc_rpc_establishpush_periodic(const char *datastore, const char *filter, const char *stop_time, const char *encoding,
719 uint32_t period, const char *anchor_time, NC_PARAMTYPE paramtype)
720{
721 struct nc_rpc_establishpush *rpc;
722
roman40672412023-05-04 11:10:22 +0200723 NC_CHECK_ARG_RET(NULL, datastore, period, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100724
725 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200726 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
727 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100728 return NULL;
729 }
730
731 rpc = malloc(sizeof *rpc);
732 if (!rpc) {
733 ERRMEM;
734 return NULL;
735 }
736
737 rpc->type = NC_RPC_ESTABLISHPUSH;
738 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
739 rpc->datastore = strdup(datastore);
740 } else {
741 rpc->datastore = (char *)datastore;
742 }
743 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
744 rpc->filter = strdup(filter);
745 } else {
746 rpc->filter = (char *)filter;
747 }
748 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
749 rpc->stop = strdup(stop_time);
750 } else {
751 rpc->stop = (char *)stop_time;
752 }
753 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
754 rpc->encoding = strdup(encoding);
755 } else {
756 rpc->encoding = (char *)encoding;
757 }
758 rpc->periodic = 1;
759 rpc->period = period;
760 if (anchor_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
761 rpc->anchor_time = strdup(anchor_time);
762 } else {
763 rpc->anchor_time = (char *)anchor_time;
764 }
765 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
766
767 return (struct nc_rpc *)rpc;
768}
769
770API struct nc_rpc *
771nc_rpc_establishpush_onchange(const char *datastore, const char *filter, const char *stop_time, const char *encoding,
772 uint32_t dampening_period, int sync_on_start, const char **excluded_change, NC_PARAMTYPE paramtype)
773{
774 struct nc_rpc_establishpush *rpc;
775 uint32_t i;
776
roman40672412023-05-04 11:10:22 +0200777 NC_CHECK_ARG_RET(NULL, datastore, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100778
779 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200780 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
781 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100782 return NULL;
783 }
784
785 rpc = malloc(sizeof *rpc);
786 if (!rpc) {
787 ERRMEM;
788 return NULL;
789 }
790
791 rpc->type = NC_RPC_ESTABLISHPUSH;
792 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
793 rpc->datastore = strdup(datastore);
794 } else {
795 rpc->datastore = (char *)datastore;
796 }
797 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
798 rpc->filter = strdup(filter);
799 } else {
800 rpc->filter = (char *)filter;
801 }
802 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
803 rpc->stop = strdup(stop_time);
804 } else {
805 rpc->stop = (char *)stop_time;
806 }
807 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
808 rpc->encoding = strdup(encoding);
809 } else {
810 rpc->encoding = (char *)encoding;
811 }
812 rpc->periodic = 0;
813 rpc->dampening_period = dampening_period;
814 rpc->sync_on_start = sync_on_start;
815 if (excluded_change && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
816 rpc->excluded_change = NULL;
817 for (i = 0; excluded_change[i]; ++i) {
818 rpc->excluded_change = realloc(rpc->excluded_change, (i + 2) * sizeof *rpc->excluded_change);
819 rpc->excluded_change[i] = strdup(excluded_change[i]);
820 rpc->excluded_change[i + 1] = NULL;
821 }
822 } else {
823 rpc->excluded_change = (char **)excluded_change;
824 }
825 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
826
827 return (struct nc_rpc *)rpc;
828}
829
830API struct nc_rpc *
831nc_rpc_modifypush_periodic(uint32_t id, const char *datastore, const char *filter, const char *stop_time, uint32_t period,
832 const char *anchor_time, NC_PARAMTYPE paramtype)
833{
834 struct nc_rpc_modifypush *rpc;
835
roman40672412023-05-04 11:10:22 +0200836 NC_CHECK_ARG_RET(NULL, id, datastore, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100837
838 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200839 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
840 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100841 return NULL;
842 }
843
844 rpc = malloc(sizeof *rpc);
845 if (!rpc) {
846 ERRMEM;
847 return NULL;
848 }
849
850 rpc->type = NC_RPC_MODIFYPUSH;
851 rpc->id = id;
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 rpc->periodic = 1;
868 rpc->period = period;
869 if (anchor_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
870 rpc->anchor_time = strdup(anchor_time);
871 } else {
872 rpc->anchor_time = (char *)anchor_time;
873 }
874 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
875
876 return (struct nc_rpc *)rpc;
877}
878
879API struct nc_rpc *
880nc_rpc_modifypush_onchange(uint32_t id, const char *datastore, const char *filter, const char *stop_time,
881 uint32_t dampening_period, NC_PARAMTYPE paramtype)
882{
883 struct nc_rpc_modifypush *rpc;
884
roman40672412023-05-04 11:10:22 +0200885 NC_CHECK_ARG_RET(NULL, id, datastore, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100886
887 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200888 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
889 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100890 return NULL;
891 }
892
893 rpc = malloc(sizeof *rpc);
894 if (!rpc) {
895 ERRMEM;
896 return NULL;
897 }
898
899 rpc->type = NC_RPC_MODIFYPUSH;
900 rpc->id = id;
901 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
902 rpc->datastore = strdup(datastore);
903 } else {
904 rpc->datastore = (char *)datastore;
905 }
906 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
907 rpc->filter = strdup(filter);
908 } else {
909 rpc->filter = (char *)filter;
910 }
911 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
912 rpc->stop = strdup(stop_time);
913 } else {
914 rpc->stop = (char *)stop_time;
915 }
916 rpc->periodic = 0;
917 rpc->dampening_period = dampening_period;
918 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
919
920 return (struct nc_rpc *)rpc;
921}
922
923API struct nc_rpc *
924nc_rpc_resyncsub(uint32_t id)
925{
926 struct nc_rpc_resyncsub *rpc;
927
roman40672412023-05-04 11:10:22 +0200928 NC_CHECK_ARG_RET(NULL, id, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100929
930 rpc = malloc(sizeof *rpc);
931 if (!rpc) {
932 ERRMEM;
933 return NULL;
934 }
935
936 rpc->type = NC_RPC_RESYNCSUB;
937 rpc->id = id;
938
939 return (struct nc_rpc *)rpc;
940}
941
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100942API void
943nc_rpc_free(struct nc_rpc *rpc)
944{
Michal Vasko90e8e692016-07-13 12:27:57 +0200945 struct nc_rpc_act_generic *rpc_generic;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100946 struct nc_rpc_getconfig *rpc_getconfig;
947 struct nc_rpc_edit *rpc_edit;
948 struct nc_rpc_copy *rpc_copy;
949 struct nc_rpc_delete *rpc_delete;
950 struct nc_rpc_get *rpc_get;
951 struct nc_rpc_commit *rpc_commit;
952 struct nc_rpc_cancel *rpc_cancel;
953 struct nc_rpc_validate *rpc_validate;
954 struct nc_rpc_getschema *rpc_getschema;
955 struct nc_rpc_subscribe *rpc_subscribe;
Michal Vaskoc1171a42019-11-05 12:06:46 +0100956 struct nc_rpc_getdata *rpc_getdata;
957 struct nc_rpc_editdata *rpc_editdata;
Michal Vasko96f247a2021-03-15 13:32:10 +0100958 struct nc_rpc_establishsub *rpc_establishsub;
959 struct nc_rpc_modifysub *rpc_modifysub;
Michal Vasko305faca2021-03-25 09:16:02 +0100960 struct nc_rpc_establishpush *rpc_establishpush;
961 struct nc_rpc_modifypush *rpc_modifypush;
Michal Vaskoc1171a42019-11-05 12:06:46 +0100962 int i;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100963
964 if (!rpc) {
965 return;
966 }
967
968 switch (rpc->type) {
Michal Vasko90e8e692016-07-13 12:27:57 +0200969 case NC_RPC_ACT_GENERIC:
970 rpc_generic = (struct nc_rpc_act_generic *)rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100971 if (rpc_generic->free) {
972 if (rpc_generic->has_data) {
Michal Vasko77367452021-02-16 16:32:18 +0100973 lyd_free_tree(rpc_generic->content.data);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100974 } else {
975 free(rpc_generic->content.xml_str);
976 }
977 }
978 break;
979 case NC_RPC_GETCONFIG:
980 rpc_getconfig = (struct nc_rpc_getconfig *)rpc;
981 if (rpc_getconfig->free) {
982 free(rpc_getconfig->filter);
983 }
984 break;
985 case NC_RPC_EDIT:
986 rpc_edit = (struct nc_rpc_edit *)rpc;
987 if (rpc_edit->free) {
988 free(rpc_edit->edit_cont);
989 }
990 break;
991 case NC_RPC_COPY:
992 rpc_copy = (struct nc_rpc_copy *)rpc;
993 if (rpc_copy->free) {
994 free(rpc_copy->url_config_src);
David Sedlák35419a32018-10-07 23:23:33 +0200995 free(rpc_copy->url_trg);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100996 }
997 break;
998 case NC_RPC_DELETE:
999 rpc_delete = (struct nc_rpc_delete *)rpc;
1000 if (rpc_delete->free) {
1001 free(rpc_delete->url);
1002 }
1003 break;
1004 case NC_RPC_GET:
1005 rpc_get = (struct nc_rpc_get *)rpc;
1006 if (rpc_get->free) {
1007 free(rpc_get->filter);
1008 }
1009 break;
1010 case NC_RPC_COMMIT:
1011 rpc_commit = (struct nc_rpc_commit *)rpc;
1012 if (rpc_commit->free) {
1013 free(rpc_commit->persist);
1014 free(rpc_commit->persist_id);
1015 }
1016 break;
1017 case NC_RPC_CANCEL:
1018 rpc_cancel = (struct nc_rpc_cancel *)rpc;
1019 if (rpc_cancel->free) {
1020 free(rpc_cancel->persist_id);
1021 }
1022 break;
1023 case NC_RPC_VALIDATE:
1024 rpc_validate = (struct nc_rpc_validate *)rpc;
1025 if (rpc_validate->free) {
1026 free(rpc_validate->url_config_src);
1027 }
1028 break;
1029 case NC_RPC_GETSCHEMA:
1030 rpc_getschema = (struct nc_rpc_getschema *)rpc;
1031 if (rpc_getschema->free) {
1032 free(rpc_getschema->identifier);
1033 free(rpc_getschema->version);
1034 free(rpc_getschema->format);
1035 }
1036 break;
1037 case NC_RPC_SUBSCRIBE:
1038 rpc_subscribe = (struct nc_rpc_subscribe *)rpc;
1039 if (rpc_subscribe->free) {
1040 free(rpc_subscribe->stream);
1041 free(rpc_subscribe->filter);
1042 free(rpc_subscribe->start);
1043 free(rpc_subscribe->stop);
1044 }
1045 break;
Michal Vaskoc1171a42019-11-05 12:06:46 +01001046 case NC_RPC_GETDATA:
1047 rpc_getdata = (struct nc_rpc_getdata *)rpc;
1048 if (rpc_getdata->free) {
1049 free(rpc_getdata->datastore);
1050 free(rpc_getdata->filter);
1051 free(rpc_getdata->config_filter);
1052 for (i = 0; i < rpc_getdata->origin_filter_count; ++i) {
1053 free(rpc_getdata->origin_filter[i]);
1054 }
1055 free(rpc_getdata->origin_filter);
1056 }
1057 break;
1058 case NC_RPC_EDITDATA:
1059 rpc_editdata = (struct nc_rpc_editdata *)rpc;
1060 if (rpc_editdata->free) {
1061 free(rpc_editdata->datastore);
1062 free(rpc_editdata->edit_cont);
1063 }
1064 break;
Michal Vasko96f247a2021-03-15 13:32:10 +01001065 case NC_RPC_ESTABLISHSUB:
1066 rpc_establishsub = (struct nc_rpc_establishsub *)rpc;
1067 if (rpc_establishsub->free) {
1068 free(rpc_establishsub->filter);
1069 free(rpc_establishsub->stream);
1070 free(rpc_establishsub->start);
1071 free(rpc_establishsub->stop);
1072 free(rpc_establishsub->encoding);
1073 }
1074 break;
1075 case NC_RPC_MODIFYSUB:
1076 rpc_modifysub = (struct nc_rpc_modifysub *)rpc;
1077 if (rpc_modifysub->free) {
1078 free(rpc_modifysub->filter);
1079 free(rpc_modifysub->stop);
1080 }
1081 break;
Michal Vasko305faca2021-03-25 09:16:02 +01001082 case NC_RPC_ESTABLISHPUSH:
1083 rpc_establishpush = (struct nc_rpc_establishpush *)rpc;
1084 if (rpc_establishpush->free) {
1085 free(rpc_establishpush->datastore);
1086 free(rpc_establishpush->filter);
1087 free(rpc_establishpush->stop);
1088 free(rpc_establishpush->encoding);
1089 if (rpc_establishpush->periodic) {
1090 free(rpc_establishpush->anchor_time);
1091 } else {
1092 if (rpc_establishpush->excluded_change) {
1093 for (i = 0; rpc_establishpush->excluded_change[i]; ++i) {
1094 free(rpc_establishpush->excluded_change[i]);
1095 }
1096 free(rpc_establishpush->excluded_change);
1097 }
1098 }
1099 }
1100 break;
1101 case NC_RPC_MODIFYPUSH:
1102 rpc_modifypush = (struct nc_rpc_modifypush *)rpc;
1103 if (rpc_modifypush->free) {
1104 free(rpc_modifypush->datastore);
1105 free(rpc_modifypush->filter);
1106 free(rpc_modifypush->stop);
1107 if (rpc_modifypush->periodic) {
1108 free(rpc_modifypush->anchor_time);
1109 }
1110 }
1111 break;
Michal Vasko96f247a2021-03-15 13:32:10 +01001112 case NC_RPC_UNKNOWN:
1113 case NC_RPC_LOCK:
1114 case NC_RPC_UNLOCK:
1115 case NC_RPC_KILL:
1116 case NC_RPC_DISCARD:
1117 case NC_RPC_DELETESUB:
1118 case NC_RPC_KILLSUB:
Michal Vasko305faca2021-03-25 09:16:02 +01001119 case NC_RPC_RESYNCSUB:
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001120 /* nothing special needed */
1121 break;
1122 }
1123
1124 free(rpc);
1125}
1126
1127API void
Radek Krejci36d2ee42017-10-13 13:55:59 +02001128nc_client_err_clean(struct nc_err *err, struct ly_ctx *ctx)
1129{
1130 int i;
1131
1132 assert(ctx);
1133
1134 if (!err) {
1135 return;
1136 }
1137
1138 lydict_remove(ctx, err->type);
1139 lydict_remove(ctx, err->tag);
1140 lydict_remove(ctx, err->severity);
1141 lydict_remove(ctx, err->apptag);
1142 lydict_remove(ctx, err->path);
1143 lydict_remove(ctx, err->message);
1144 lydict_remove(ctx, err->message_lang);
1145 lydict_remove(ctx, err->sid);
1146 for (i = 0; i < err->attr_count; ++i) {
1147 lydict_remove(ctx, err->attr[i]);
1148 }
1149 free(err->attr);
1150 for (i = 0; i < err->elem_count; ++i) {
1151 lydict_remove(ctx, err->elem[i]);
1152 }
1153 free(err->elem);
1154 for (i = 0; i < err->ns_count; ++i) {
1155 lydict_remove(ctx, err->ns[i]);
1156 }
1157 free(err->ns);
Michal Vasko77367452021-02-16 16:32:18 +01001158 lyd_free_siblings(err->other);
Radek Krejci36d2ee42017-10-13 13:55:59 +02001159 free(err->other);
1160}