blob: f8cc0fbf5dd035db6c54a9fe26ebe65d22a20004 [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
romane2cd2ab2023-10-26 14:55:17 +020049 NC_CHECK_ARG_RET(NULL, data, NULL);
romanadf25892023-10-26 15:45:31 +020050 if (data->next || (data->prev != data)) {
roman40672412023-05-04 11:10:22 +020051 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);
roman3a95bb22023-10-26 11:07:17 +020056 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +010057
Michal Vasko90e8e692016-07-13 12:27:57 +020058 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010059 rpc->has_data = 1;
60 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
Michal Vasko77367452021-02-16 16:32:18 +010061 if (lyd_dup_single(data, NULL, LYD_DUP_RECURSIVE, &rpc->content.data)) {
62 free(rpc);
63 return NULL;
64 }
Michal Vasko7bcb48e2016-01-15 10:28:54 +010065 } else {
66 rpc->content.data = (struct lyd_node *)data;
67 }
68 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
69
70 return (struct nc_rpc *)rpc;
71}
72
73API struct nc_rpc *
Michal Vasko90e8e692016-07-13 12:27:57 +020074nc_rpc_act_generic_xml(const char *xml_str, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +010075{
Michal Vasko90e8e692016-07-13 12:27:57 +020076 struct nc_rpc_act_generic *rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010077
roman40672412023-05-04 11:10:22 +020078 NC_CHECK_ARG_RET(NULL, xml_str, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +010079
Michal Vasko7bcb48e2016-01-15 10:28:54 +010080 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +020081 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +010082
Michal Vasko90e8e692016-07-13 12:27:57 +020083 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010084 rpc->has_data = 0;
85 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
86 rpc->content.xml_str = strdup(xml_str);
87 } else {
88 rpc->content.xml_str = (char *)xml_str;
89 }
90 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
91
92 return (struct nc_rpc *)rpc;
93}
94
95API struct nc_rpc *
96nc_rpc_getconfig(NC_DATASTORE source, const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
97{
98 struct nc_rpc_getconfig *rpc;
99
roman40672412023-05-04 11:10:22 +0200100 NC_CHECK_ARG_RET(NULL, source, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100101
Michal Vaskof3c647b2016-03-08 12:17:33 +0100102 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200103 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 +0100104 return NULL;
105 }
106
107 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200108 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100109
110 rpc->type = NC_RPC_GETCONFIG;
111 rpc->source = source;
112 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
113 rpc->filter = strdup(filter);
114 } else {
115 rpc->filter = (char *)filter;
116 }
117 rpc->wd_mode = wd_mode;
118 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
119
120 return (struct nc_rpc *)rpc;
121}
122
123API struct nc_rpc *
124nc_rpc_edit(NC_DATASTORE target, NC_RPC_EDIT_DFLTOP default_op, NC_RPC_EDIT_TESTOPT test_opt,
Michal Vasko96f247a2021-03-15 13:32:10 +0100125 NC_RPC_EDIT_ERROPT error_opt, const char *edit_content, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100126{
127 struct nc_rpc_edit *rpc;
128
roman40672412023-05-04 11:10:22 +0200129 NC_CHECK_ARG_RET(NULL, target, edit_content, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100130
Michal Vasko7793bc62016-09-16 11:58:41 +0200131 if (edit_content[0] && (edit_content[0] != '<') && !isalpha(edit_content[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200132 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 +0100133 return NULL;
134 }
135
136 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200137 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100138
139 rpc->type = NC_RPC_EDIT;
140 rpc->target = target;
141 rpc->default_op = default_op;
142 rpc->test_opt = test_opt;
143 rpc->error_opt = error_opt;
144 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
145 rpc->edit_cont = strdup(edit_content);
146 } else {
147 rpc->edit_cont = (char *)edit_content;
148 }
149 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
150
151 return (struct nc_rpc *)rpc;
152}
153
154API struct nc_rpc *
155nc_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 +0100156 NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100157{
158 struct nc_rpc_copy *rpc;
159
roman40672412023-05-04 11:10:22 +0200160 NC_CHECK_ARG_RET(NULL, target, source, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100161
Michal Vasko7793bc62016-09-16 11:58:41 +0200162 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 +0200163 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 +0100164 return NULL;
165 }
166
167 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200168 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100169
170 rpc->type = NC_RPC_COPY;
171 rpc->target = target;
172 if (url_trg && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
173 rpc->url_trg = strdup(url_trg);
174 } else {
175 rpc->url_trg = (char *)url_trg;
176 }
177 rpc->source = source;
178 if (url_or_config_src && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
179 rpc->url_config_src = strdup(url_or_config_src);
180 } else {
181 rpc->url_config_src = (char *)url_or_config_src;
182 }
183 rpc->wd_mode = wd_mode;
184 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
185
186 return (struct nc_rpc *)rpc;
187}
188
189API struct nc_rpc *
190nc_rpc_delete(NC_DATASTORE target, const char *url, NC_PARAMTYPE paramtype)
191{
192 struct nc_rpc_delete *rpc;
193
roman40672412023-05-04 11:10:22 +0200194 NC_CHECK_ARG_RET(NULL, target, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100195
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100196 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200197 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100198
199 rpc->type = NC_RPC_DELETE;
200 rpc->target = target;
201 if (url && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
202 rpc->url = strdup(url);
203 } else {
204 rpc->url = (char *)url;
205 }
206 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
207
208 return (struct nc_rpc *)rpc;
209}
210
211API struct nc_rpc *
212nc_rpc_lock(NC_DATASTORE target)
213{
214 struct nc_rpc_lock *rpc;
215
roman40672412023-05-04 11:10:22 +0200216 NC_CHECK_ARG_RET(NULL, target, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100217
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100218 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200219 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100220
221 rpc->type = NC_RPC_LOCK;
222 rpc->target = target;
223
224 return (struct nc_rpc *)rpc;
225}
226
227API struct nc_rpc *
228nc_rpc_unlock(NC_DATASTORE target)
229{
230 struct nc_rpc_lock *rpc;
231
roman40672412023-05-04 11:10:22 +0200232 NC_CHECK_ARG_RET(NULL, target, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100233
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100234 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200235 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100236
237 rpc->type = NC_RPC_UNLOCK;
238 rpc->target = target;
239
240 return (struct nc_rpc *)rpc;
241}
242
243API struct nc_rpc *
244nc_rpc_get(const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
245{
246 struct nc_rpc_get *rpc;
247
Michal Vaskof3c647b2016-03-08 12:17:33 +0100248 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200249 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 +0100250 return NULL;
251 }
252
253 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200254 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100255
256 rpc->type = NC_RPC_GET;
257 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
258 rpc->filter = strdup(filter);
259 } else {
260 rpc->filter = (char *)filter;
261 }
262 rpc->wd_mode = wd_mode;
263 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
264
265 return (struct nc_rpc *)rpc;
266}
267
268API struct nc_rpc *
269nc_rpc_kill(uint32_t session_id)
270{
271 struct nc_rpc_kill *rpc;
272
roman40672412023-05-04 11:10:22 +0200273 NC_CHECK_ARG_RET(NULL, session_id, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100274
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100275 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200276 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100277
278 rpc->type = NC_RPC_KILL;
279 rpc->sid = session_id;
280
281 return (struct nc_rpc *)rpc;
282}
283
284API struct nc_rpc *
285nc_rpc_commit(int confirmed, uint32_t confirm_timeout, const char *persist, const char *persist_id,
Michal Vasko96f247a2021-03-15 13:32:10 +0100286 NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100287{
288 struct nc_rpc_commit *rpc;
289
290 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200291 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100292
293 rpc->type = NC_RPC_COMMIT;
294 rpc->confirmed = confirmed;
295 rpc->confirm_timeout = confirm_timeout;
296 if (persist && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
297 rpc->persist = strdup(persist);
298 } else {
299 rpc->persist = (char *)persist;
300 }
301 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
302 rpc->persist_id = strdup(persist_id);
303 } else {
304 rpc->persist_id = (char *)persist_id;
305 }
306 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
307
308 return (struct nc_rpc *)rpc;
309}
310
311API struct nc_rpc *
312nc_rpc_discard(void)
313{
314 struct nc_rpc *rpc;
315
316 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200317 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100318
319 rpc->type = NC_RPC_DISCARD;
320
321 return rpc;
322}
323
324API struct nc_rpc *
325nc_rpc_cancel(const char *persist_id, NC_PARAMTYPE paramtype)
326{
327 struct nc_rpc_cancel *rpc;
328
329 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200330 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100331
332 rpc->type = NC_RPC_CANCEL;
333 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
334 rpc->persist_id = strdup(persist_id);
335 } else {
336 rpc->persist_id = (char *)persist_id;
337 }
338 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
339
340 return (struct nc_rpc *)rpc;
341}
342
343API struct nc_rpc *
344nc_rpc_validate(NC_DATASTORE source, const char *url_or_config, NC_PARAMTYPE paramtype)
345{
346 struct nc_rpc_validate *rpc;
347
roman40672412023-05-04 11:10:22 +0200348 NC_CHECK_ARG_RET(NULL, source, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100349
Michal Vasko7793bc62016-09-16 11:58:41 +0200350 if (url_or_config && url_or_config[0] && (url_or_config[0] != '<') && !isalpha(url_or_config[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200351 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 +0100352 return NULL;
353 }
354
355 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200356 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100357
358 rpc->type = NC_RPC_VALIDATE;
359 rpc->source = source;
360 if (url_or_config && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
361 rpc->url_config_src = strdup(url_or_config);
362 } else {
363 rpc->url_config_src = (char *)url_or_config;
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_getschema(const char *identifier, const char *version, const char *format, NC_PARAMTYPE paramtype)
372{
373 struct nc_rpc_getschema *rpc;
374
roman40672412023-05-04 11:10:22 +0200375 NC_CHECK_ARG_RET(NULL, identifier, NULL);
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100376
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100377 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200378 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100379
380 rpc->type = NC_RPC_GETSCHEMA;
381 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
382 rpc->identifier = strdup(identifier);
383 } else {
384 rpc->identifier = (char *)identifier;
385 }
386 if (version && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
387 rpc->version = strdup(version);
388 } else {
389 rpc->version = (char *)version;
390 }
391 if (format && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
392 rpc->format = strdup(format);
393 } else {
394 rpc->format = (char *)format;
395 }
396 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
397
398 return (struct nc_rpc *)rpc;
399}
400
401API struct nc_rpc *
402nc_rpc_subscribe(const char *stream_name, const char *filter, const char *start_time, const char *stop_time,
Michal Vasko96f247a2021-03-15 13:32:10 +0100403 NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100404{
405 struct nc_rpc_subscribe *rpc;
406
Michal Vaskof3c647b2016-03-08 12:17:33 +0100407 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200408 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 +0100409 return NULL;
410 }
411
412 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200413 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100414
415 rpc->type = NC_RPC_SUBSCRIBE;
416 if (stream_name && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
417 rpc->stream = strdup(stream_name);
418 } else {
419 rpc->stream = (char *)stream_name;
420 }
421 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
422 rpc->filter = strdup(filter);
423 } else {
424 rpc->filter = (char *)filter;
425 }
426 if (start_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
427 rpc->start = strdup(start_time);
428 } else {
429 rpc->start = (char *)start_time;
430 }
431 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
432 rpc->stop = strdup(stop_time);
433 } else {
434 rpc->stop = (char *)stop_time;
435 }
436 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
437
438 return (struct nc_rpc *)rpc;
439}
440
Michal Vaskoc1171a42019-11-05 12:06:46 +0100441API struct nc_rpc *
442nc_rpc_getdata(const char *datastore, const char *filter, const char *config_filter, char **origin_filter,
Michal Vasko96f247a2021-03-15 13:32:10 +0100443 int origin_filter_count, int negated_origin_filter, uint16_t max_depth, int with_origin, NC_WD_MODE wd_mode,
444 NC_PARAMTYPE paramtype)
Michal Vaskoc1171a42019-11-05 12:06:46 +0100445{
446 struct nc_rpc_getdata *rpc = NULL;
447 int i;
448
roman40672412023-05-04 11:10:22 +0200449 NC_CHECK_ARG_RET(NULL, datastore, NULL);
450
Michal Vaskoc1171a42019-11-05 12:06:46 +0100451 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200452 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 +0100453 return NULL;
Michal Vaskoc1171a42019-11-05 12:06:46 +0100454 }
455
456 rpc = calloc(1, sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200457 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vaskoc1171a42019-11-05 12:06:46 +0100458 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
459
460 rpc->type = NC_RPC_GETDATA;
461 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
462 rpc->datastore = strdup(datastore);
463 } else {
464 rpc->datastore = (char *)datastore;
465 }
466 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
467 rpc->filter = strdup(filter);
468 } else {
469 rpc->filter = (char *)filter;
470 }
471 if (config_filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
472 rpc->config_filter = strdup(config_filter);
473 } else {
474 rpc->config_filter = (char *)config_filter;
475 }
476 if (origin_filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
477 rpc->origin_filter = malloc(origin_filter_count * sizeof *rpc->origin_filter);
roman124a4362023-10-26 15:36:22 +0200478 NC_CHECK_ERRMEM_GOTO(!rpc->origin_filter, , error);
Michal Vaskoc1171a42019-11-05 12:06:46 +0100479 for (i = 0; i < origin_filter_count; ++i) {
480 rpc->origin_filter[i] = strdup(origin_filter[i]);
roman124a4362023-10-26 15:36:22 +0200481 NC_CHECK_ERRMEM_GOTO(!rpc->origin_filter[i], , error);
Michal Vaskoc1171a42019-11-05 12:06:46 +0100482 ++rpc->origin_filter_count;
483 }
484 } else {
485 rpc->origin_filter = origin_filter;
486 rpc->origin_filter_count = origin_filter_count;
487 }
488 rpc->negated_origin_filter = negated_origin_filter;
489 rpc->max_depth = max_depth;
490 rpc->with_origin = with_origin;
491 rpc->wd_mode = wd_mode;
492
493 return (struct nc_rpc *)rpc;
494
495error:
496 nc_rpc_free((struct nc_rpc *)rpc);
497 return NULL;
498}
499
500API struct nc_rpc *
501nc_rpc_editdata(const char *datastore, NC_RPC_EDIT_DFLTOP default_op, const char *edit_content, NC_PARAMTYPE paramtype)
502{
503 struct nc_rpc_editdata *rpc;
504
roman40672412023-05-04 11:10:22 +0200505 NC_CHECK_ARG_RET(NULL, datastore, edit_content, NULL);
Michal Vaskoc1171a42019-11-05 12:06:46 +0100506
507 if (edit_content[0] && (edit_content[0] != '<') && !isalpha(edit_content[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200508 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 +0100509 return NULL;
510 }
511
512 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200513 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vaskoc1171a42019-11-05 12:06:46 +0100514
515 rpc->type = NC_RPC_EDITDATA;
516 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
517 rpc->datastore = strdup(datastore);
518 } else {
519 rpc->datastore = (char *)datastore;
520 }
521 rpc->default_op = default_op;
522 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
523 rpc->edit_cont = strdup(edit_content);
524 } else {
525 rpc->edit_cont = (char *)edit_content;
526 }
527 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
528
529 return (struct nc_rpc *)rpc;
530}
531
Michal Vasko96f247a2021-03-15 13:32:10 +0100532API struct nc_rpc *
533nc_rpc_establishsub(const char *filter, const char *stream_name, const char *start_time,
534 const char *stop_time, const char *encoding, NC_PARAMTYPE paramtype)
535{
536 struct nc_rpc_establishsub *rpc;
537
roman40672412023-05-04 11:10:22 +0200538 NC_CHECK_ARG_RET(NULL, stream_name, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100539
540 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200541 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
542 filter[0]);
Michal Vasko96f247a2021-03-15 13:32:10 +0100543 return NULL;
544 }
545
546 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200547 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100548
549 rpc->type = NC_RPC_ESTABLISHSUB;
550 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
551 rpc->filter = strdup(filter);
552 } else {
553 rpc->filter = (char *)filter;
554 }
555 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
556 rpc->stream = strdup(stream_name);
557 } else {
558 rpc->stream = (char *)stream_name;
559 }
560 if (start_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
561 rpc->start = strdup(start_time);
562 } else {
563 rpc->start = (char *)start_time;
564 }
565 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
566 rpc->stop = strdup(stop_time);
567 } else {
568 rpc->stop = (char *)stop_time;
569 }
570 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
571 rpc->encoding = strdup(encoding);
572 } else {
573 rpc->encoding = (char *)encoding;
574 }
575 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
576
577 return (struct nc_rpc *)rpc;
578}
579
580API struct nc_rpc *
581nc_rpc_modifysub(uint32_t id, const char *filter, const char *stop_time, NC_PARAMTYPE paramtype)
582{
583 struct nc_rpc_modifysub *rpc;
584
roman40672412023-05-04 11:10:22 +0200585 NC_CHECK_ARG_RET(NULL, id, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100586
587 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200588 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
589 filter[0]);
Michal Vasko96f247a2021-03-15 13:32:10 +0100590 return NULL;
591 }
592
593 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200594 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100595
596 rpc->type = NC_RPC_MODIFYSUB;
597 rpc->id = id;
598 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
599 rpc->filter = strdup(filter);
600 } else {
601 rpc->filter = (char *)filter;
602 }
603 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
604 rpc->stop = strdup(stop_time);
605 } else {
606 rpc->stop = (char *)stop_time;
607 }
608 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
609
610 return (struct nc_rpc *)rpc;
611}
612
613API struct nc_rpc *
614nc_rpc_deletesub(uint32_t id)
615{
616 struct nc_rpc_deletesub *rpc;
617
roman40672412023-05-04 11:10:22 +0200618 NC_CHECK_ARG_RET(NULL, id, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100619
620 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200621 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100622
623 rpc->type = NC_RPC_DELETESUB;
624 rpc->id = id;
625
626 return (struct nc_rpc *)rpc;
627}
628
629API struct nc_rpc *
630nc_rpc_killsub(uint32_t id)
631{
632 struct nc_rpc_killsub *rpc;
633
roman40672412023-05-04 11:10:22 +0200634 NC_CHECK_ARG_RET(NULL, id, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100635
636 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200637 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko96f247a2021-03-15 13:32:10 +0100638
639 rpc->type = NC_RPC_KILLSUB;
640 rpc->id = id;
641
642 return (struct nc_rpc *)rpc;
643}
644
Michal Vasko305faca2021-03-25 09:16:02 +0100645API struct nc_rpc *
646nc_rpc_establishpush_periodic(const char *datastore, const char *filter, const char *stop_time, const char *encoding,
647 uint32_t period, const char *anchor_time, NC_PARAMTYPE paramtype)
648{
649 struct nc_rpc_establishpush *rpc;
650
roman40672412023-05-04 11:10:22 +0200651 NC_CHECK_ARG_RET(NULL, datastore, period, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100652
653 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200654 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
655 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100656 return NULL;
657 }
658
659 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200660 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100661
662 rpc->type = NC_RPC_ESTABLISHPUSH;
663 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
664 rpc->datastore = strdup(datastore);
665 } else {
666 rpc->datastore = (char *)datastore;
667 }
668 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
669 rpc->filter = strdup(filter);
670 } else {
671 rpc->filter = (char *)filter;
672 }
673 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
674 rpc->stop = strdup(stop_time);
675 } else {
676 rpc->stop = (char *)stop_time;
677 }
678 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
679 rpc->encoding = strdup(encoding);
680 } else {
681 rpc->encoding = (char *)encoding;
682 }
683 rpc->periodic = 1;
684 rpc->period = period;
685 if (anchor_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
686 rpc->anchor_time = strdup(anchor_time);
687 } else {
688 rpc->anchor_time = (char *)anchor_time;
689 }
690 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
691
692 return (struct nc_rpc *)rpc;
693}
694
695API struct nc_rpc *
696nc_rpc_establishpush_onchange(const char *datastore, const char *filter, const char *stop_time, const char *encoding,
697 uint32_t dampening_period, int sync_on_start, const char **excluded_change, NC_PARAMTYPE paramtype)
698{
699 struct nc_rpc_establishpush *rpc;
700 uint32_t i;
romanc31b16e2023-11-09 13:42:25 +0100701 void *tmp;
Michal Vasko305faca2021-03-25 09:16:02 +0100702
roman40672412023-05-04 11:10:22 +0200703 NC_CHECK_ARG_RET(NULL, datastore, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100704
705 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200706 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
707 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100708 return NULL;
709 }
710
711 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200712 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100713
714 rpc->type = NC_RPC_ESTABLISHPUSH;
715 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
716 rpc->datastore = strdup(datastore);
717 } else {
718 rpc->datastore = (char *)datastore;
719 }
720 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
721 rpc->filter = strdup(filter);
722 } else {
723 rpc->filter = (char *)filter;
724 }
725 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
726 rpc->stop = strdup(stop_time);
727 } else {
728 rpc->stop = (char *)stop_time;
729 }
730 if (encoding && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
731 rpc->encoding = strdup(encoding);
732 } else {
733 rpc->encoding = (char *)encoding;
734 }
735 rpc->periodic = 0;
736 rpc->dampening_period = dampening_period;
737 rpc->sync_on_start = sync_on_start;
738 if (excluded_change && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
739 rpc->excluded_change = NULL;
740 for (i = 0; excluded_change[i]; ++i) {
romanc31b16e2023-11-09 13:42:25 +0100741 tmp = realloc(rpc->excluded_change, (i + 2) * sizeof *rpc->excluded_change);
742 if (!tmp) {
743 /* in case we fail to alloc, just free all the excluded changes, but return the rpc anyways */
744 ERRMEM;
745 free(rpc->excluded_change);
746 rpc->excluded_change = NULL;
747 break;
748 }
749 rpc->excluded_change = tmp;
Michal Vasko305faca2021-03-25 09:16:02 +0100750 rpc->excluded_change[i] = strdup(excluded_change[i]);
751 rpc->excluded_change[i + 1] = NULL;
752 }
753 } else {
754 rpc->excluded_change = (char **)excluded_change;
755 }
756 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
757
758 return (struct nc_rpc *)rpc;
759}
760
761API struct nc_rpc *
762nc_rpc_modifypush_periodic(uint32_t id, const char *datastore, const char *filter, const char *stop_time, uint32_t period,
763 const char *anchor_time, NC_PARAMTYPE paramtype)
764{
765 struct nc_rpc_modifypush *rpc;
766
roman40672412023-05-04 11:10:22 +0200767 NC_CHECK_ARG_RET(NULL, id, datastore, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100768
769 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200770 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
771 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100772 return NULL;
773 }
774
775 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200776 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100777
778 rpc->type = NC_RPC_MODIFYPUSH;
779 rpc->id = id;
780 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
781 rpc->datastore = strdup(datastore);
782 } else {
783 rpc->datastore = (char *)datastore;
784 }
785 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
786 rpc->filter = strdup(filter);
787 } else {
788 rpc->filter = (char *)filter;
789 }
790 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
791 rpc->stop = strdup(stop_time);
792 } else {
793 rpc->stop = (char *)stop_time;
794 }
795 rpc->periodic = 1;
796 rpc->period = period;
797 if (anchor_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
798 rpc->anchor_time = strdup(anchor_time);
799 } else {
800 rpc->anchor_time = (char *)anchor_time;
801 }
802 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
803
804 return (struct nc_rpc *)rpc;
805}
806
807API struct nc_rpc *
808nc_rpc_modifypush_onchange(uint32_t id, const char *datastore, const char *filter, const char *stop_time,
809 uint32_t dampening_period, NC_PARAMTYPE paramtype)
810{
811 struct nc_rpc_modifypush *rpc;
812
roman40672412023-05-04 11:10:22 +0200813 NC_CHECK_ARG_RET(NULL, id, datastore, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100814
815 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko05532772021-06-03 12:12:38 +0200816 ERR(NULL, "Filter is not an XML subtree, an XPath expression, not a filter reference (invalid first char '%c').",
817 filter[0]);
Michal Vasko305faca2021-03-25 09:16:02 +0100818 return NULL;
819 }
820
821 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200822 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100823
824 rpc->type = NC_RPC_MODIFYPUSH;
825 rpc->id = id;
826 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
827 rpc->datastore = strdup(datastore);
828 } else {
829 rpc->datastore = (char *)datastore;
830 }
831 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
832 rpc->filter = strdup(filter);
833 } else {
834 rpc->filter = (char *)filter;
835 }
836 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
837 rpc->stop = strdup(stop_time);
838 } else {
839 rpc->stop = (char *)stop_time;
840 }
841 rpc->periodic = 0;
842 rpc->dampening_period = dampening_period;
843 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
844
845 return (struct nc_rpc *)rpc;
846}
847
848API struct nc_rpc *
849nc_rpc_resyncsub(uint32_t id)
850{
851 struct nc_rpc_resyncsub *rpc;
852
roman40672412023-05-04 11:10:22 +0200853 NC_CHECK_ARG_RET(NULL, id, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100854
855 rpc = malloc(sizeof *rpc);
roman3a95bb22023-10-26 11:07:17 +0200856 NC_CHECK_ERRMEM_RET(!rpc, NULL);
Michal Vasko305faca2021-03-25 09:16:02 +0100857
858 rpc->type = NC_RPC_RESYNCSUB;
859 rpc->id = id;
860
861 return (struct nc_rpc *)rpc;
862}
863
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100864API void
865nc_rpc_free(struct nc_rpc *rpc)
866{
Michal Vasko90e8e692016-07-13 12:27:57 +0200867 struct nc_rpc_act_generic *rpc_generic;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100868 struct nc_rpc_getconfig *rpc_getconfig;
869 struct nc_rpc_edit *rpc_edit;
870 struct nc_rpc_copy *rpc_copy;
871 struct nc_rpc_delete *rpc_delete;
872 struct nc_rpc_get *rpc_get;
873 struct nc_rpc_commit *rpc_commit;
874 struct nc_rpc_cancel *rpc_cancel;
875 struct nc_rpc_validate *rpc_validate;
876 struct nc_rpc_getschema *rpc_getschema;
877 struct nc_rpc_subscribe *rpc_subscribe;
Michal Vaskoc1171a42019-11-05 12:06:46 +0100878 struct nc_rpc_getdata *rpc_getdata;
879 struct nc_rpc_editdata *rpc_editdata;
Michal Vasko96f247a2021-03-15 13:32:10 +0100880 struct nc_rpc_establishsub *rpc_establishsub;
881 struct nc_rpc_modifysub *rpc_modifysub;
Michal Vasko305faca2021-03-25 09:16:02 +0100882 struct nc_rpc_establishpush *rpc_establishpush;
883 struct nc_rpc_modifypush *rpc_modifypush;
Michal Vaskoc1171a42019-11-05 12:06:46 +0100884 int i;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100885
886 if (!rpc) {
887 return;
888 }
889
890 switch (rpc->type) {
Michal Vasko90e8e692016-07-13 12:27:57 +0200891 case NC_RPC_ACT_GENERIC:
892 rpc_generic = (struct nc_rpc_act_generic *)rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100893 if (rpc_generic->free) {
894 if (rpc_generic->has_data) {
Michal Vasko77367452021-02-16 16:32:18 +0100895 lyd_free_tree(rpc_generic->content.data);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100896 } else {
897 free(rpc_generic->content.xml_str);
898 }
899 }
900 break;
901 case NC_RPC_GETCONFIG:
902 rpc_getconfig = (struct nc_rpc_getconfig *)rpc;
903 if (rpc_getconfig->free) {
904 free(rpc_getconfig->filter);
905 }
906 break;
907 case NC_RPC_EDIT:
908 rpc_edit = (struct nc_rpc_edit *)rpc;
909 if (rpc_edit->free) {
910 free(rpc_edit->edit_cont);
911 }
912 break;
913 case NC_RPC_COPY:
914 rpc_copy = (struct nc_rpc_copy *)rpc;
915 if (rpc_copy->free) {
916 free(rpc_copy->url_config_src);
David Sedlák35419a32018-10-07 23:23:33 +0200917 free(rpc_copy->url_trg);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100918 }
919 break;
920 case NC_RPC_DELETE:
921 rpc_delete = (struct nc_rpc_delete *)rpc;
922 if (rpc_delete->free) {
923 free(rpc_delete->url);
924 }
925 break;
926 case NC_RPC_GET:
927 rpc_get = (struct nc_rpc_get *)rpc;
928 if (rpc_get->free) {
929 free(rpc_get->filter);
930 }
931 break;
932 case NC_RPC_COMMIT:
933 rpc_commit = (struct nc_rpc_commit *)rpc;
934 if (rpc_commit->free) {
935 free(rpc_commit->persist);
936 free(rpc_commit->persist_id);
937 }
938 break;
939 case NC_RPC_CANCEL:
940 rpc_cancel = (struct nc_rpc_cancel *)rpc;
941 if (rpc_cancel->free) {
942 free(rpc_cancel->persist_id);
943 }
944 break;
945 case NC_RPC_VALIDATE:
946 rpc_validate = (struct nc_rpc_validate *)rpc;
947 if (rpc_validate->free) {
948 free(rpc_validate->url_config_src);
949 }
950 break;
951 case NC_RPC_GETSCHEMA:
952 rpc_getschema = (struct nc_rpc_getschema *)rpc;
953 if (rpc_getschema->free) {
954 free(rpc_getschema->identifier);
955 free(rpc_getschema->version);
956 free(rpc_getschema->format);
957 }
958 break;
959 case NC_RPC_SUBSCRIBE:
960 rpc_subscribe = (struct nc_rpc_subscribe *)rpc;
961 if (rpc_subscribe->free) {
962 free(rpc_subscribe->stream);
963 free(rpc_subscribe->filter);
964 free(rpc_subscribe->start);
965 free(rpc_subscribe->stop);
966 }
967 break;
Michal Vaskoc1171a42019-11-05 12:06:46 +0100968 case NC_RPC_GETDATA:
969 rpc_getdata = (struct nc_rpc_getdata *)rpc;
970 if (rpc_getdata->free) {
971 free(rpc_getdata->datastore);
972 free(rpc_getdata->filter);
973 free(rpc_getdata->config_filter);
974 for (i = 0; i < rpc_getdata->origin_filter_count; ++i) {
975 free(rpc_getdata->origin_filter[i]);
976 }
977 free(rpc_getdata->origin_filter);
978 }
979 break;
980 case NC_RPC_EDITDATA:
981 rpc_editdata = (struct nc_rpc_editdata *)rpc;
982 if (rpc_editdata->free) {
983 free(rpc_editdata->datastore);
984 free(rpc_editdata->edit_cont);
985 }
986 break;
Michal Vasko96f247a2021-03-15 13:32:10 +0100987 case NC_RPC_ESTABLISHSUB:
988 rpc_establishsub = (struct nc_rpc_establishsub *)rpc;
989 if (rpc_establishsub->free) {
990 free(rpc_establishsub->filter);
991 free(rpc_establishsub->stream);
992 free(rpc_establishsub->start);
993 free(rpc_establishsub->stop);
994 free(rpc_establishsub->encoding);
995 }
996 break;
997 case NC_RPC_MODIFYSUB:
998 rpc_modifysub = (struct nc_rpc_modifysub *)rpc;
999 if (rpc_modifysub->free) {
1000 free(rpc_modifysub->filter);
1001 free(rpc_modifysub->stop);
1002 }
1003 break;
Michal Vasko305faca2021-03-25 09:16:02 +01001004 case NC_RPC_ESTABLISHPUSH:
1005 rpc_establishpush = (struct nc_rpc_establishpush *)rpc;
1006 if (rpc_establishpush->free) {
1007 free(rpc_establishpush->datastore);
1008 free(rpc_establishpush->filter);
1009 free(rpc_establishpush->stop);
1010 free(rpc_establishpush->encoding);
1011 if (rpc_establishpush->periodic) {
1012 free(rpc_establishpush->anchor_time);
1013 } else {
1014 if (rpc_establishpush->excluded_change) {
1015 for (i = 0; rpc_establishpush->excluded_change[i]; ++i) {
1016 free(rpc_establishpush->excluded_change[i]);
1017 }
1018 free(rpc_establishpush->excluded_change);
1019 }
1020 }
1021 }
1022 break;
1023 case NC_RPC_MODIFYPUSH:
1024 rpc_modifypush = (struct nc_rpc_modifypush *)rpc;
1025 if (rpc_modifypush->free) {
1026 free(rpc_modifypush->datastore);
1027 free(rpc_modifypush->filter);
1028 free(rpc_modifypush->stop);
1029 if (rpc_modifypush->periodic) {
1030 free(rpc_modifypush->anchor_time);
1031 }
1032 }
1033 break;
Michal Vasko96f247a2021-03-15 13:32:10 +01001034 case NC_RPC_UNKNOWN:
1035 case NC_RPC_LOCK:
1036 case NC_RPC_UNLOCK:
1037 case NC_RPC_KILL:
1038 case NC_RPC_DISCARD:
1039 case NC_RPC_DELETESUB:
1040 case NC_RPC_KILLSUB:
Michal Vasko305faca2021-03-25 09:16:02 +01001041 case NC_RPC_RESYNCSUB:
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001042 /* nothing special needed */
1043 break;
1044 }
1045
1046 free(rpc);
1047}
1048
1049API void
Radek Krejci36d2ee42017-10-13 13:55:59 +02001050nc_client_err_clean(struct nc_err *err, struct ly_ctx *ctx)
1051{
1052 int i;
1053
1054 assert(ctx);
1055
1056 if (!err) {
1057 return;
1058 }
1059
1060 lydict_remove(ctx, err->type);
1061 lydict_remove(ctx, err->tag);
1062 lydict_remove(ctx, err->severity);
1063 lydict_remove(ctx, err->apptag);
1064 lydict_remove(ctx, err->path);
1065 lydict_remove(ctx, err->message);
1066 lydict_remove(ctx, err->message_lang);
1067 lydict_remove(ctx, err->sid);
1068 for (i = 0; i < err->attr_count; ++i) {
1069 lydict_remove(ctx, err->attr[i]);
1070 }
1071 free(err->attr);
1072 for (i = 0; i < err->elem_count; ++i) {
1073 lydict_remove(ctx, err->elem[i]);
1074 }
1075 free(err->elem);
1076 for (i = 0; i < err->ns_count; ++i) {
1077 lydict_remove(ctx, err->ns[i]);
1078 }
1079 free(err->ns);
Michal Vasko77367452021-02-16 16:32:18 +01001080 lyd_free_siblings(err->other);
Radek Krejci36d2ee42017-10-13 13:55:59 +02001081 free(err->other);
1082}