blob: 04c0b3c0e877a158d303e281cd9d6b550502f8a8 [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>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020020#include <stdarg.h>
Michal Vasko7bcb48e2016-01-15 10:28:54 +010021#include <stdlib.h>
22#include <string.h>
Michal Vasko7bcb48e2016-01-15 10:28:54 +010023
24#include <libyang/libyang.h>
25
26#include "libnetconf.h"
Michal Vasko7bcb48e2016-01-15 10:28:54 +010027
28const char *rpcedit_dfltop2str[] = {NULL, "merge", "replace", "none"};
29const char *rpcedit_testopt2str[] = {NULL, "test-then-set", "set", "test-only"};
30const char *rpcedit_erropt2str[] = {NULL, "stop-on-error", "continue-on-error", "rollback-on-error"};
31
32API NC_RPC_TYPE
33nc_rpc_get_type(const struct nc_rpc *rpc)
34{
Michal Vasko7f1c78b2016-01-19 09:52:14 +010035 if (!rpc) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020036 ERRARG("rpc");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010037 return 0;
38 }
39
Michal Vasko7bcb48e2016-01-15 10:28:54 +010040 return rpc->type;
41}
42
43API struct nc_rpc *
Michal Vasko90e8e692016-07-13 12:27:57 +020044nc_rpc_act_generic(const struct lyd_node *data, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +010045{
Michal Vasko90e8e692016-07-13 12:27:57 +020046 struct nc_rpc_act_generic *rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010047
Michal Vasko90e8e692016-07-13 12:27:57 +020048 if (!data || data->next || (data->prev != data)) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020049 ERRARG("data");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010050 return NULL;
51 }
52
Michal Vasko7bcb48e2016-01-15 10:28:54 +010053 rpc = malloc(sizeof *rpc);
54 if (!rpc) {
55 ERRMEM;
56 return NULL;
57 }
58
Michal Vasko90e8e692016-07-13 12:27:57 +020059 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010060 rpc->has_data = 1;
61 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
Michal Vasko77367452021-02-16 16:32:18 +010062 if (lyd_dup_single(data, NULL, LYD_DUP_RECURSIVE, &rpc->content.data)) {
63 free(rpc);
64 return NULL;
65 }
Michal Vasko7bcb48e2016-01-15 10:28:54 +010066 } else {
67 rpc->content.data = (struct lyd_node *)data;
68 }
69 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
70
71 return (struct nc_rpc *)rpc;
72}
73
74API struct nc_rpc *
Michal Vasko90e8e692016-07-13 12:27:57 +020075nc_rpc_act_generic_xml(const char *xml_str, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +010076{
Michal Vasko90e8e692016-07-13 12:27:57 +020077 struct nc_rpc_act_generic *rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010078
Michal Vasko7f1c78b2016-01-19 09:52:14 +010079 if (!xml_str) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020080 ERRARG("xml_str");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010081 return NULL;
82 }
83
Michal Vasko7bcb48e2016-01-15 10:28:54 +010084 rpc = malloc(sizeof *rpc);
85 if (!rpc) {
86 ERRMEM;
87 return NULL;
88 }
89
Michal Vasko90e8e692016-07-13 12:27:57 +020090 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010091 rpc->has_data = 0;
92 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
93 rpc->content.xml_str = strdup(xml_str);
94 } else {
95 rpc->content.xml_str = (char *)xml_str;
96 }
97 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
98
99 return (struct nc_rpc *)rpc;
100}
101
102API struct nc_rpc *
103nc_rpc_getconfig(NC_DATASTORE source, const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
104{
105 struct nc_rpc_getconfig *rpc;
106
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100107 if (!source) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200108 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100109 return NULL;
110 }
111
Michal Vaskof3c647b2016-03-08 12:17:33 +0100112 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200113 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 +0100114 return NULL;
115 }
116
117 rpc = malloc(sizeof *rpc);
118 if (!rpc) {
119 ERRMEM;
120 return NULL;
121 }
122
123 rpc->type = NC_RPC_GETCONFIG;
124 rpc->source = source;
125 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
126 rpc->filter = strdup(filter);
127 } else {
128 rpc->filter = (char *)filter;
129 }
130 rpc->wd_mode = wd_mode;
131 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
132
133 return (struct nc_rpc *)rpc;
134}
135
136API struct nc_rpc *
137nc_rpc_edit(NC_DATASTORE target, NC_RPC_EDIT_DFLTOP default_op, NC_RPC_EDIT_TESTOPT test_opt,
Michal Vasko96f247a2021-03-15 13:32:10 +0100138 NC_RPC_EDIT_ERROPT error_opt, const char *edit_content, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100139{
140 struct nc_rpc_edit *rpc;
141
Michal Vasko45e53ae2016-04-07 11:46:03 +0200142 if (!target) {
143 ERRARG("target");
144 return NULL;
145 } else if (!edit_content) {
146 ERRARG("edit_content");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100147 return NULL;
148 }
149
Michal Vasko7793bc62016-09-16 11:58:41 +0200150 if (edit_content[0] && (edit_content[0] != '<') && !isalpha(edit_content[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200151 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 +0100152 return NULL;
153 }
154
155 rpc = malloc(sizeof *rpc);
156 if (!rpc) {
157 ERRMEM;
158 return NULL;
159 }
160
161 rpc->type = NC_RPC_EDIT;
162 rpc->target = target;
163 rpc->default_op = default_op;
164 rpc->test_opt = test_opt;
165 rpc->error_opt = error_opt;
166 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
167 rpc->edit_cont = strdup(edit_content);
168 } else {
169 rpc->edit_cont = (char *)edit_content;
170 }
171 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
172
173 return (struct nc_rpc *)rpc;
174}
175
176API struct nc_rpc *
177nc_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 +0100178 NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100179{
180 struct nc_rpc_copy *rpc;
181
Michal Vasko45e53ae2016-04-07 11:46:03 +0200182 if (!target) {
183 ERRARG("target");
184 return NULL;
185 } else if (!source) {
186 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100187 return NULL;
188 }
189
Michal Vasko7793bc62016-09-16 11:58:41 +0200190 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 +0200191 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 +0100192 return NULL;
193 }
194
195 rpc = malloc(sizeof *rpc);
196 if (!rpc) {
197 ERRMEM;
198 return NULL;
199 }
200
201 rpc->type = NC_RPC_COPY;
202 rpc->target = target;
203 if (url_trg && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
204 rpc->url_trg = strdup(url_trg);
205 } else {
206 rpc->url_trg = (char *)url_trg;
207 }
208 rpc->source = source;
209 if (url_or_config_src && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
210 rpc->url_config_src = strdup(url_or_config_src);
211 } else {
212 rpc->url_config_src = (char *)url_or_config_src;
213 }
214 rpc->wd_mode = wd_mode;
215 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
216
217 return (struct nc_rpc *)rpc;
218}
219
220API struct nc_rpc *
221nc_rpc_delete(NC_DATASTORE target, const char *url, NC_PARAMTYPE paramtype)
222{
223 struct nc_rpc_delete *rpc;
224
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100225 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200226 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100227 return NULL;
228 }
229
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100230 rpc = malloc(sizeof *rpc);
231 if (!rpc) {
232 ERRMEM;
233 return NULL;
234 }
235
236 rpc->type = NC_RPC_DELETE;
237 rpc->target = target;
238 if (url && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
239 rpc->url = strdup(url);
240 } else {
241 rpc->url = (char *)url;
242 }
243 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
244
245 return (struct nc_rpc *)rpc;
246}
247
248API struct nc_rpc *
249nc_rpc_lock(NC_DATASTORE target)
250{
251 struct nc_rpc_lock *rpc;
252
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100253 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200254 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100255 return NULL;
256 }
257
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100258 rpc = malloc(sizeof *rpc);
259 if (!rpc) {
260 ERRMEM;
261 return NULL;
262 }
263
264 rpc->type = NC_RPC_LOCK;
265 rpc->target = target;
266
267 return (struct nc_rpc *)rpc;
268}
269
270API struct nc_rpc *
271nc_rpc_unlock(NC_DATASTORE target)
272{
273 struct nc_rpc_lock *rpc;
274
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100275 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200276 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100277 return NULL;
278 }
279
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100280 rpc = malloc(sizeof *rpc);
281 if (!rpc) {
282 ERRMEM;
283 return NULL;
284 }
285
286 rpc->type = NC_RPC_UNLOCK;
287 rpc->target = target;
288
289 return (struct nc_rpc *)rpc;
290}
291
292API struct nc_rpc *
293nc_rpc_get(const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
294{
295 struct nc_rpc_get *rpc;
296
Michal Vaskof3c647b2016-03-08 12:17:33 +0100297 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200298 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 +0100299 return NULL;
300 }
301
302 rpc = malloc(sizeof *rpc);
303 if (!rpc) {
304 ERRMEM;
305 return NULL;
306 }
307
308 rpc->type = NC_RPC_GET;
309 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
310 rpc->filter = strdup(filter);
311 } else {
312 rpc->filter = (char *)filter;
313 }
314 rpc->wd_mode = wd_mode;
315 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
316
317 return (struct nc_rpc *)rpc;
318}
319
320API struct nc_rpc *
321nc_rpc_kill(uint32_t session_id)
322{
323 struct nc_rpc_kill *rpc;
324
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100325 if (!session_id) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200326 ERRARG("session_id");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100327 return NULL;
328 }
329
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100330 rpc = malloc(sizeof *rpc);
331 if (!rpc) {
332 ERRMEM;
333 return NULL;
334 }
335
336 rpc->type = NC_RPC_KILL;
337 rpc->sid = session_id;
338
339 return (struct nc_rpc *)rpc;
340}
341
342API struct nc_rpc *
343nc_rpc_commit(int confirmed, uint32_t confirm_timeout, const char *persist, const char *persist_id,
Michal Vasko96f247a2021-03-15 13:32:10 +0100344 NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100345{
346 struct nc_rpc_commit *rpc;
347
348 rpc = malloc(sizeof *rpc);
349 if (!rpc) {
350 ERRMEM;
351 return NULL;
352 }
353
354 rpc->type = NC_RPC_COMMIT;
355 rpc->confirmed = confirmed;
356 rpc->confirm_timeout = confirm_timeout;
357 if (persist && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
358 rpc->persist = strdup(persist);
359 } else {
360 rpc->persist = (char *)persist;
361 }
362 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
363 rpc->persist_id = strdup(persist_id);
364 } else {
365 rpc->persist_id = (char *)persist_id;
366 }
367 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
368
369 return (struct nc_rpc *)rpc;
370}
371
372API struct nc_rpc *
373nc_rpc_discard(void)
374{
375 struct nc_rpc *rpc;
376
377 rpc = malloc(sizeof *rpc);
378 if (!rpc) {
379 ERRMEM;
380 return NULL;
381 }
382
383 rpc->type = NC_RPC_DISCARD;
384
385 return rpc;
386}
387
388API struct nc_rpc *
389nc_rpc_cancel(const char *persist_id, NC_PARAMTYPE paramtype)
390{
391 struct nc_rpc_cancel *rpc;
392
393 rpc = malloc(sizeof *rpc);
394 if (!rpc) {
395 ERRMEM;
396 return NULL;
397 }
398
399 rpc->type = NC_RPC_CANCEL;
400 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
401 rpc->persist_id = strdup(persist_id);
402 } else {
403 rpc->persist_id = (char *)persist_id;
404 }
405 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
406
407 return (struct nc_rpc *)rpc;
408}
409
410API struct nc_rpc *
411nc_rpc_validate(NC_DATASTORE source, const char *url_or_config, NC_PARAMTYPE paramtype)
412{
413 struct nc_rpc_validate *rpc;
414
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100415 if (!source) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200416 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100417 return NULL;
418 }
419
Michal Vasko7793bc62016-09-16 11:58:41 +0200420 if (url_or_config && url_or_config[0] && (url_or_config[0] != '<') && !isalpha(url_or_config[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200421 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 +0100422 return NULL;
423 }
424
425 rpc = malloc(sizeof *rpc);
426 if (!rpc) {
427 ERRMEM;
428 return NULL;
429 }
430
431 rpc->type = NC_RPC_VALIDATE;
432 rpc->source = source;
433 if (url_or_config && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
434 rpc->url_config_src = strdup(url_or_config);
435 } else {
436 rpc->url_config_src = (char *)url_or_config;
437 }
438 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
439
440 return (struct nc_rpc *)rpc;
441}
442
443API struct nc_rpc *
444nc_rpc_getschema(const char *identifier, const char *version, const char *format, NC_PARAMTYPE paramtype)
445{
446 struct nc_rpc_getschema *rpc;
447
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100448 if (!identifier) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200449 ERRARG("identifier");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100450 return NULL;
451 }
452
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100453 rpc = malloc(sizeof *rpc);
454 if (!rpc) {
455 ERRMEM;
456 return NULL;
457 }
458
459 rpc->type = NC_RPC_GETSCHEMA;
460 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
461 rpc->identifier = strdup(identifier);
462 } else {
463 rpc->identifier = (char *)identifier;
464 }
465 if (version && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
466 rpc->version = strdup(version);
467 } else {
468 rpc->version = (char *)version;
469 }
470 if (format && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
471 rpc->format = strdup(format);
472 } else {
473 rpc->format = (char *)format;
474 }
475 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
476
477 return (struct nc_rpc *)rpc;
478}
479
480API struct nc_rpc *
481nc_rpc_subscribe(const char *stream_name, const char *filter, const char *start_time, const char *stop_time,
Michal Vasko96f247a2021-03-15 13:32:10 +0100482 NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100483{
484 struct nc_rpc_subscribe *rpc;
485
Michal Vaskof3c647b2016-03-08 12:17:33 +0100486 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200487 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 +0100488 return NULL;
489 }
490
491 rpc = malloc(sizeof *rpc);
492 if (!rpc) {
493 ERRMEM;
494 return NULL;
495 }
496
497 rpc->type = NC_RPC_SUBSCRIBE;
498 if (stream_name && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
499 rpc->stream = strdup(stream_name);
500 } else {
501 rpc->stream = (char *)stream_name;
502 }
503 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
504 rpc->filter = strdup(filter);
505 } else {
506 rpc->filter = (char *)filter;
507 }
508 if (start_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
509 rpc->start = strdup(start_time);
510 } else {
511 rpc->start = (char *)start_time;
512 }
513 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
514 rpc->stop = strdup(stop_time);
515 } else {
516 rpc->stop = (char *)stop_time;
517 }
518 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
519
520 return (struct nc_rpc *)rpc;
521}
522
Michal Vaskoc1171a42019-11-05 12:06:46 +0100523API struct nc_rpc *
524nc_rpc_getdata(const char *datastore, const char *filter, const char *config_filter, char **origin_filter,
Michal Vasko96f247a2021-03-15 13:32:10 +0100525 int origin_filter_count, int negated_origin_filter, uint16_t max_depth, int with_origin, NC_WD_MODE wd_mode,
526 NC_PARAMTYPE paramtype)
Michal Vaskoc1171a42019-11-05 12:06:46 +0100527{
528 struct nc_rpc_getdata *rpc = NULL;
529 int i;
530
531 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200532 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 +0100533 return NULL;
534 } else if (!datastore) {
535 ERRARG("datastore");
536 return NULL;
537 }
538
539 rpc = calloc(1, sizeof *rpc);
540 if (!rpc) {
541 ERRMEM;
542 return NULL;
543 }
544 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
545
546 rpc->type = NC_RPC_GETDATA;
547 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
548 rpc->datastore = strdup(datastore);
549 } else {
550 rpc->datastore = (char *)datastore;
551 }
552 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
553 rpc->filter = strdup(filter);
554 } else {
555 rpc->filter = (char *)filter;
556 }
557 if (config_filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
558 rpc->config_filter = strdup(config_filter);
559 } else {
560 rpc->config_filter = (char *)config_filter;
561 }
562 if (origin_filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
563 rpc->origin_filter = malloc(origin_filter_count * sizeof *rpc->origin_filter);
564 if (!rpc->origin_filter) {
565 ERRMEM;
566 goto error;
567 }
568 for (i = 0; i < origin_filter_count; ++i) {
569 rpc->origin_filter[i] = strdup(origin_filter[i]);
570 if (!rpc->origin_filter[i]) {
571 ERRMEM;
572 goto error;
573 }
574 ++rpc->origin_filter_count;
575 }
576 } else {
577 rpc->origin_filter = origin_filter;
578 rpc->origin_filter_count = origin_filter_count;
579 }
580 rpc->negated_origin_filter = negated_origin_filter;
581 rpc->max_depth = max_depth;
582 rpc->with_origin = with_origin;
583 rpc->wd_mode = wd_mode;
584
585 return (struct nc_rpc *)rpc;
586
587error:
588 nc_rpc_free((struct nc_rpc *)rpc);
589 return NULL;
590}
591
592API struct nc_rpc *
593nc_rpc_editdata(const char *datastore, NC_RPC_EDIT_DFLTOP default_op, const char *edit_content, NC_PARAMTYPE paramtype)
594{
595 struct nc_rpc_editdata *rpc;
596
597 if (!datastore) {
598 ERRARG("datastore");
599 return NULL;
600 } else if (!edit_content) {
601 ERRARG("edit_content");
602 return NULL;
603 }
604
605 if (edit_content[0] && (edit_content[0] != '<') && !isalpha(edit_content[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200606 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 +0100607 return NULL;
608 }
609
610 rpc = malloc(sizeof *rpc);
611 if (!rpc) {
612 ERRMEM;
613 return NULL;
614 }
615
616 rpc->type = NC_RPC_EDITDATA;
617 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
618 rpc->datastore = strdup(datastore);
619 } else {
620 rpc->datastore = (char *)datastore;
621 }
622 rpc->default_op = default_op;
623 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
624 rpc->edit_cont = strdup(edit_content);
625 } else {
626 rpc->edit_cont = (char *)edit_content;
627 }
628 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
629
630 return (struct nc_rpc *)rpc;
631}
632
Michal Vasko96f247a2021-03-15 13:32:10 +0100633API struct nc_rpc *
634nc_rpc_establishsub(const char *filter, const char *stream_name, const char *start_time,
635 const char *stop_time, const char *encoding, NC_PARAMTYPE paramtype)
636{
637 struct nc_rpc_establishsub *rpc;
638
639 if (!stream_name) {
640 ERRARG("stream_name");
641 return NULL;
642 }
643
644 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200645 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
646 filter[0]);
Michal Vasko96f247a2021-03-15 13:32:10 +0100647 return NULL;
648 }
649
650 rpc = malloc(sizeof *rpc);
651 if (!rpc) {
652 ERRMEM;
653 return NULL;
654 }
655
656 rpc->type = NC_RPC_ESTABLISHSUB;
657 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
658 rpc->filter = strdup(filter);
659 } else {
660 rpc->filter = (char *)filter;
661 }
662 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
663 rpc->stream = strdup(stream_name);
664 } else {
665 rpc->stream = (char *)stream_name;
666 }
667 if (start_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
668 rpc->start = strdup(start_time);
669 } else {
670 rpc->start = (char *)start_time;
671 }
672 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
673 rpc->stop = strdup(stop_time);
674 } else {
675 rpc->stop = (char *)stop_time;
676 }
677 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
678 rpc->encoding = strdup(encoding);
679 } else {
680 rpc->encoding = (char *)encoding;
681 }
682 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
683
684 return (struct nc_rpc *)rpc;
685}
686
687API struct nc_rpc *
688nc_rpc_modifysub(uint32_t id, const char *filter, const char *stop_time, NC_PARAMTYPE paramtype)
689{
690 struct nc_rpc_modifysub *rpc;
691
692 if (!id) {
693 ERRARG("id");
694 return NULL;
695 }
696
697 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200698 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
699 filter[0]);
Michal Vasko96f247a2021-03-15 13:32:10 +0100700 return NULL;
701 }
702
703 rpc = malloc(sizeof *rpc);
704 if (!rpc) {
705 ERRMEM;
706 return NULL;
707 }
708
709 rpc->type = NC_RPC_MODIFYSUB;
710 rpc->id = id;
711 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
712 rpc->filter = strdup(filter);
713 } else {
714 rpc->filter = (char *)filter;
715 }
716 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
717 rpc->stop = strdup(stop_time);
718 } else {
719 rpc->stop = (char *)stop_time;
720 }
721 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
722
723 return (struct nc_rpc *)rpc;
724}
725
726API struct nc_rpc *
727nc_rpc_deletesub(uint32_t id)
728{
729 struct nc_rpc_deletesub *rpc;
730
731 if (!id) {
732 ERRARG("id");
733 return NULL;
734 }
735
736 rpc = malloc(sizeof *rpc);
737 if (!rpc) {
738 ERRMEM;
739 return NULL;
740 }
741
742 rpc->type = NC_RPC_DELETESUB;
743 rpc->id = id;
744
745 return (struct nc_rpc *)rpc;
746}
747
748API struct nc_rpc *
749nc_rpc_killsub(uint32_t id)
750{
751 struct nc_rpc_killsub *rpc;
752
753 if (!id) {
754 ERRARG("id");
755 return NULL;
756 }
757
758 rpc = malloc(sizeof *rpc);
759 if (!rpc) {
760 ERRMEM;
761 return NULL;
762 }
763
764 rpc->type = NC_RPC_KILLSUB;
765 rpc->id = id;
766
767 return (struct nc_rpc *)rpc;
768}
769
Michal Vasko305faca2021-03-25 09:16:02 +0100770API struct nc_rpc *
771nc_rpc_establishpush_periodic(const char *datastore, const char *filter, const char *stop_time, const char *encoding,
772 uint32_t period, const char *anchor_time, NC_PARAMTYPE paramtype)
773{
774 struct nc_rpc_establishpush *rpc;
775
776 if (!datastore) {
777 ERRARG("datastore");
778 return NULL;
779 } else if (!period) {
780 ERRARG("period");
781 return NULL;
782 }
783
784 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200785 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
786 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100787 return NULL;
788 }
789
790 rpc = malloc(sizeof *rpc);
791 if (!rpc) {
792 ERRMEM;
793 return NULL;
794 }
795
796 rpc->type = NC_RPC_ESTABLISHPUSH;
797 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
798 rpc->datastore = strdup(datastore);
799 } else {
800 rpc->datastore = (char *)datastore;
801 }
802 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
803 rpc->filter = strdup(filter);
804 } else {
805 rpc->filter = (char *)filter;
806 }
807 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
808 rpc->stop = strdup(stop_time);
809 } else {
810 rpc->stop = (char *)stop_time;
811 }
812 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
813 rpc->encoding = strdup(encoding);
814 } else {
815 rpc->encoding = (char *)encoding;
816 }
817 rpc->periodic = 1;
818 rpc->period = period;
819 if (anchor_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
820 rpc->anchor_time = strdup(anchor_time);
821 } else {
822 rpc->anchor_time = (char *)anchor_time;
823 }
824 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
825
826 return (struct nc_rpc *)rpc;
827}
828
829API struct nc_rpc *
830nc_rpc_establishpush_onchange(const char *datastore, const char *filter, const char *stop_time, const char *encoding,
831 uint32_t dampening_period, int sync_on_start, const char **excluded_change, NC_PARAMTYPE paramtype)
832{
833 struct nc_rpc_establishpush *rpc;
834 uint32_t i;
835
836 if (!datastore) {
837 ERRARG("datastore");
838 return NULL;
839 }
840
841 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200842 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
843 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100844 return NULL;
845 }
846
847 rpc = malloc(sizeof *rpc);
848 if (!rpc) {
849 ERRMEM;
850 return NULL;
851 }
852
853 rpc->type = NC_RPC_ESTABLISHPUSH;
854 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
855 rpc->datastore = strdup(datastore);
856 } else {
857 rpc->datastore = (char *)datastore;
858 }
859 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
860 rpc->filter = strdup(filter);
861 } else {
862 rpc->filter = (char *)filter;
863 }
864 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
865 rpc->stop = strdup(stop_time);
866 } else {
867 rpc->stop = (char *)stop_time;
868 }
869 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
870 rpc->encoding = strdup(encoding);
871 } else {
872 rpc->encoding = (char *)encoding;
873 }
874 rpc->periodic = 0;
875 rpc->dampening_period = dampening_period;
876 rpc->sync_on_start = sync_on_start;
877 if (excluded_change && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
878 rpc->excluded_change = NULL;
879 for (i = 0; excluded_change[i]; ++i) {
880 rpc->excluded_change = realloc(rpc->excluded_change, (i + 2) * sizeof *rpc->excluded_change);
881 rpc->excluded_change[i] = strdup(excluded_change[i]);
882 rpc->excluded_change[i + 1] = NULL;
883 }
884 } else {
885 rpc->excluded_change = (char **)excluded_change;
886 }
887 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
888
889 return (struct nc_rpc *)rpc;
890}
891
892API struct nc_rpc *
893nc_rpc_modifypush_periodic(uint32_t id, const char *datastore, const char *filter, const char *stop_time, uint32_t period,
894 const char *anchor_time, NC_PARAMTYPE paramtype)
895{
896 struct nc_rpc_modifypush *rpc;
897
898 if (!id) {
899 ERRARG("id");
900 return NULL;
901 } else if (!datastore) {
902 ERRARG("datastore");
903 return NULL;
904 }
905
906 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200907 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
908 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100909 return NULL;
910 }
911
912 rpc = malloc(sizeof *rpc);
913 if (!rpc) {
914 ERRMEM;
915 return NULL;
916 }
917
918 rpc->type = NC_RPC_MODIFYPUSH;
919 rpc->id = id;
920 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
921 rpc->datastore = strdup(datastore);
922 } else {
923 rpc->datastore = (char *)datastore;
924 }
925 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
926 rpc->filter = strdup(filter);
927 } else {
928 rpc->filter = (char *)filter;
929 }
930 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
931 rpc->stop = strdup(stop_time);
932 } else {
933 rpc->stop = (char *)stop_time;
934 }
935 rpc->periodic = 1;
936 rpc->period = period;
937 if (anchor_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
938 rpc->anchor_time = strdup(anchor_time);
939 } else {
940 rpc->anchor_time = (char *)anchor_time;
941 }
942 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
943
944 return (struct nc_rpc *)rpc;
945}
946
947API struct nc_rpc *
948nc_rpc_modifypush_onchange(uint32_t id, const char *datastore, const char *filter, const char *stop_time,
949 uint32_t dampening_period, NC_PARAMTYPE paramtype)
950{
951 struct nc_rpc_modifypush *rpc;
952
953 if (!id) {
954 ERRARG("id");
955 return NULL;
956 } else if (!datastore) {
957 ERRARG("datastore");
958 return NULL;
959 }
960
961 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200962 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
963 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100964 return NULL;
965 }
966
967 rpc = malloc(sizeof *rpc);
968 if (!rpc) {
969 ERRMEM;
970 return NULL;
971 }
972
973 rpc->type = NC_RPC_MODIFYPUSH;
974 rpc->id = id;
975 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
976 rpc->datastore = strdup(datastore);
977 } else {
978 rpc->datastore = (char *)datastore;
979 }
980 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
981 rpc->filter = strdup(filter);
982 } else {
983 rpc->filter = (char *)filter;
984 }
985 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
986 rpc->stop = strdup(stop_time);
987 } else {
988 rpc->stop = (char *)stop_time;
989 }
990 rpc->periodic = 0;
991 rpc->dampening_period = dampening_period;
992 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
993
994 return (struct nc_rpc *)rpc;
995}
996
997API struct nc_rpc *
998nc_rpc_resyncsub(uint32_t id)
999{
1000 struct nc_rpc_resyncsub *rpc;
1001
1002 if (!id) {
1003 ERRARG("id");
1004 return NULL;
1005 }
1006
1007 rpc = malloc(sizeof *rpc);
1008 if (!rpc) {
1009 ERRMEM;
1010 return NULL;
1011 }
1012
1013 rpc->type = NC_RPC_RESYNCSUB;
1014 rpc->id = id;
1015
1016 return (struct nc_rpc *)rpc;
1017}
1018
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001019API void
1020nc_rpc_free(struct nc_rpc *rpc)
1021{
Michal Vasko90e8e692016-07-13 12:27:57 +02001022 struct nc_rpc_act_generic *rpc_generic;
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001023 struct nc_rpc_getconfig *rpc_getconfig;
1024 struct nc_rpc_edit *rpc_edit;
1025 struct nc_rpc_copy *rpc_copy;
1026 struct nc_rpc_delete *rpc_delete;
1027 struct nc_rpc_get *rpc_get;
1028 struct nc_rpc_commit *rpc_commit;
1029 struct nc_rpc_cancel *rpc_cancel;
1030 struct nc_rpc_validate *rpc_validate;
1031 struct nc_rpc_getschema *rpc_getschema;
1032 struct nc_rpc_subscribe *rpc_subscribe;
Michal Vaskoc1171a42019-11-05 12:06:46 +01001033 struct nc_rpc_getdata *rpc_getdata;
1034 struct nc_rpc_editdata *rpc_editdata;
Michal Vasko96f247a2021-03-15 13:32:10 +01001035 struct nc_rpc_establishsub *rpc_establishsub;
1036 struct nc_rpc_modifysub *rpc_modifysub;
Michal Vasko305faca2021-03-25 09:16:02 +01001037 struct nc_rpc_establishpush *rpc_establishpush;
1038 struct nc_rpc_modifypush *rpc_modifypush;
Michal Vaskoc1171a42019-11-05 12:06:46 +01001039 int i;
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001040
1041 if (!rpc) {
1042 return;
1043 }
1044
1045 switch (rpc->type) {
Michal Vasko90e8e692016-07-13 12:27:57 +02001046 case NC_RPC_ACT_GENERIC:
1047 rpc_generic = (struct nc_rpc_act_generic *)rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001048 if (rpc_generic->free) {
1049 if (rpc_generic->has_data) {
Michal Vasko77367452021-02-16 16:32:18 +01001050 lyd_free_tree(rpc_generic->content.data);
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001051 } else {
1052 free(rpc_generic->content.xml_str);
1053 }
1054 }
1055 break;
1056 case NC_RPC_GETCONFIG:
1057 rpc_getconfig = (struct nc_rpc_getconfig *)rpc;
1058 if (rpc_getconfig->free) {
1059 free(rpc_getconfig->filter);
1060 }
1061 break;
1062 case NC_RPC_EDIT:
1063 rpc_edit = (struct nc_rpc_edit *)rpc;
1064 if (rpc_edit->free) {
1065 free(rpc_edit->edit_cont);
1066 }
1067 break;
1068 case NC_RPC_COPY:
1069 rpc_copy = (struct nc_rpc_copy *)rpc;
1070 if (rpc_copy->free) {
1071 free(rpc_copy->url_config_src);
David Sedlák35419a32018-10-07 23:23:33 +02001072 free(rpc_copy->url_trg);
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001073 }
1074 break;
1075 case NC_RPC_DELETE:
1076 rpc_delete = (struct nc_rpc_delete *)rpc;
1077 if (rpc_delete->free) {
1078 free(rpc_delete->url);
1079 }
1080 break;
1081 case NC_RPC_GET:
1082 rpc_get = (struct nc_rpc_get *)rpc;
1083 if (rpc_get->free) {
1084 free(rpc_get->filter);
1085 }
1086 break;
1087 case NC_RPC_COMMIT:
1088 rpc_commit = (struct nc_rpc_commit *)rpc;
1089 if (rpc_commit->free) {
1090 free(rpc_commit->persist);
1091 free(rpc_commit->persist_id);
1092 }
1093 break;
1094 case NC_RPC_CANCEL:
1095 rpc_cancel = (struct nc_rpc_cancel *)rpc;
1096 if (rpc_cancel->free) {
1097 free(rpc_cancel->persist_id);
1098 }
1099 break;
1100 case NC_RPC_VALIDATE:
1101 rpc_validate = (struct nc_rpc_validate *)rpc;
1102 if (rpc_validate->free) {
1103 free(rpc_validate->url_config_src);
1104 }
1105 break;
1106 case NC_RPC_GETSCHEMA:
1107 rpc_getschema = (struct nc_rpc_getschema *)rpc;
1108 if (rpc_getschema->free) {
1109 free(rpc_getschema->identifier);
1110 free(rpc_getschema->version);
1111 free(rpc_getschema->format);
1112 }
1113 break;
1114 case NC_RPC_SUBSCRIBE:
1115 rpc_subscribe = (struct nc_rpc_subscribe *)rpc;
1116 if (rpc_subscribe->free) {
1117 free(rpc_subscribe->stream);
1118 free(rpc_subscribe->filter);
1119 free(rpc_subscribe->start);
1120 free(rpc_subscribe->stop);
1121 }
1122 break;
Michal Vaskoc1171a42019-11-05 12:06:46 +01001123 case NC_RPC_GETDATA:
1124 rpc_getdata = (struct nc_rpc_getdata *)rpc;
1125 if (rpc_getdata->free) {
1126 free(rpc_getdata->datastore);
1127 free(rpc_getdata->filter);
1128 free(rpc_getdata->config_filter);
1129 for (i = 0; i < rpc_getdata->origin_filter_count; ++i) {
1130 free(rpc_getdata->origin_filter[i]);
1131 }
1132 free(rpc_getdata->origin_filter);
1133 }
1134 break;
1135 case NC_RPC_EDITDATA:
1136 rpc_editdata = (struct nc_rpc_editdata *)rpc;
1137 if (rpc_editdata->free) {
1138 free(rpc_editdata->datastore);
1139 free(rpc_editdata->edit_cont);
1140 }
1141 break;
Michal Vasko96f247a2021-03-15 13:32:10 +01001142 case NC_RPC_ESTABLISHSUB:
1143 rpc_establishsub = (struct nc_rpc_establishsub *)rpc;
1144 if (rpc_establishsub->free) {
1145 free(rpc_establishsub->filter);
1146 free(rpc_establishsub->stream);
1147 free(rpc_establishsub->start);
1148 free(rpc_establishsub->stop);
1149 free(rpc_establishsub->encoding);
1150 }
1151 break;
1152 case NC_RPC_MODIFYSUB:
1153 rpc_modifysub = (struct nc_rpc_modifysub *)rpc;
1154 if (rpc_modifysub->free) {
1155 free(rpc_modifysub->filter);
1156 free(rpc_modifysub->stop);
1157 }
1158 break;
Michal Vasko305faca2021-03-25 09:16:02 +01001159 case NC_RPC_ESTABLISHPUSH:
1160 rpc_establishpush = (struct nc_rpc_establishpush *)rpc;
1161 if (rpc_establishpush->free) {
1162 free(rpc_establishpush->datastore);
1163 free(rpc_establishpush->filter);
1164 free(rpc_establishpush->stop);
1165 free(rpc_establishpush->encoding);
1166 if (rpc_establishpush->periodic) {
1167 free(rpc_establishpush->anchor_time);
1168 } else {
1169 if (rpc_establishpush->excluded_change) {
1170 for (i = 0; rpc_establishpush->excluded_change[i]; ++i) {
1171 free(rpc_establishpush->excluded_change[i]);
1172 }
1173 free(rpc_establishpush->excluded_change);
1174 }
1175 }
1176 }
1177 break;
1178 case NC_RPC_MODIFYPUSH:
1179 rpc_modifypush = (struct nc_rpc_modifypush *)rpc;
1180 if (rpc_modifypush->free) {
1181 free(rpc_modifypush->datastore);
1182 free(rpc_modifypush->filter);
1183 free(rpc_modifypush->stop);
1184 if (rpc_modifypush->periodic) {
1185 free(rpc_modifypush->anchor_time);
1186 }
1187 }
1188 break;
Michal Vasko96f247a2021-03-15 13:32:10 +01001189 case NC_RPC_UNKNOWN:
1190 case NC_RPC_LOCK:
1191 case NC_RPC_UNLOCK:
1192 case NC_RPC_KILL:
1193 case NC_RPC_DISCARD:
1194 case NC_RPC_DELETESUB:
1195 case NC_RPC_KILLSUB:
Michal Vasko305faca2021-03-25 09:16:02 +01001196 case NC_RPC_RESYNCSUB:
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001197 /* nothing special needed */
1198 break;
1199 }
1200
1201 free(rpc);
1202}
1203
1204API void
Radek Krejci36d2ee42017-10-13 13:55:59 +02001205nc_client_err_clean(struct nc_err *err, struct ly_ctx *ctx)
1206{
1207 int i;
1208
1209 assert(ctx);
1210
1211 if (!err) {
1212 return;
1213 }
1214
1215 lydict_remove(ctx, err->type);
1216 lydict_remove(ctx, err->tag);
1217 lydict_remove(ctx, err->severity);
1218 lydict_remove(ctx, err->apptag);
1219 lydict_remove(ctx, err->path);
1220 lydict_remove(ctx, err->message);
1221 lydict_remove(ctx, err->message_lang);
1222 lydict_remove(ctx, err->sid);
1223 for (i = 0; i < err->attr_count; ++i) {
1224 lydict_remove(ctx, err->attr[i]);
1225 }
1226 free(err->attr);
1227 for (i = 0; i < err->elem_count; ++i) {
1228 lydict_remove(ctx, err->elem[i]);
1229 }
1230 free(err->elem);
1231 for (i = 0; i < err->ns_count; ++i) {
1232 lydict_remove(ctx, err->ns[i]);
1233 }
1234 free(err->ns);
Michal Vasko77367452021-02-16 16:32:18 +01001235 lyd_free_siblings(err->other);
Radek Krejci36d2ee42017-10-13 13:55:59 +02001236 free(err->other);
1237}