blob: 461086f114ac4c3d26af19f838e4e9ec3ce17c5a [file] [log] [blame]
Radek Krejci0f3499a2017-10-13 13:39:36 +02001/**
2 * @file err.c
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief NETCONF reply errors
5 *
6 * Copyright (c) 2017 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15/* Python API header */
16#include <Python.h>
17#include <structmember.h>
18
19/* standard headers */
20#include <string.h>
21
22#include "netconf.h"
23#include "messages_p.h"
24
25static void
26ncErrFree(ncErrObject *self)
27{
28 nc_client_err_clean(self->err, self->ctx);
29
30 Py_TYPE(self)->tp_free((PyObject*)self);
31}
32
33static PyObject *
34ncErrStr(ncErrObject *self)
35{
Radek Krejcib5ac0602017-10-17 10:35:03 +020036 uint16_t u, f = 0;
37 char *str = NULL;
38
39 if (self->err->type) {
40 asprintf(&str, "\"type\":\"%s\"", self->err->type);
41 }
42 if (self->err->tag) {
43 asprintf(&str, "%s%s\"tag\":\"%s\"", str ? str : "", str ? "," : "", self->err->tag);
44 }
45 if (self->err->severity) {
46 asprintf(&str, "%s%s\"severity\":\"%s\"", str ? str : "", str ? "," : "", self->err->severity);
47 }
48 if (self->err->apptag) {
49 asprintf(&str, "%s%s\"app-tag\":\"%s\"", str ? str : "", str ? "," : "", self->err->apptag);
50 }
51 if (self->err->path) {
52 asprintf(&str, "%s%s\"path\":\"%s\"", str ? str : "", str ? "," : "", self->err->path);
53 }
54 if (self->err->message) {
55 asprintf(&str, "%s%s\"message\":\"%s", str ? str : "", str ? "," : "", self->err->message);
56 if (self->err->message_lang) {
57 asprintf(&str, "%s (%s)\"", str, self->err->message_lang);
58 } else {
59 asprintf(&str, "%s\"", str);
60 }
61 }
62 if (self->err->sid || self->err->attr || self->err->elem || self->err->ns || self->err->other) {
63 asprintf(&str, "%s%s\"info\":{", str ? str : "", str ? "," : "");
64
65 if (self->err->sid) {
66 asprintf(&str, "%s%s\"session-id\":\"%s\"", str, f ? "," : "", self->err->sid);
67 f = 1;
68 }
69 if (self->err->attr_count) {
70 asprintf(&str, "%s%s\"bad-attr\":[", str, f ? "," : "");
71 for (u = 0; u < self->err->attr_count; u++) {
72 asprintf(&str, "%s%s\"%s\"", str, u ? "," : "", self->err->attr[u]);
73 }
74 asprintf(&str, "%s]", str);
75 f = 1;
76 }
77 if (self->err->elem_count) {
78 asprintf(&str, "%s%s\"bad-element\":[", str, f ? "," : "");
79 for (u = 0; u < self->err->elem_count; u++) {
80 asprintf(&str, "%s%s\"%s\"", str, u ? "," : "", self->err->elem[u]);
81 }
82 asprintf(&str, "%s]", str);
83 f = 1;
84 }
85 if (self->err->ns_count) {
86 asprintf(&str, "%s%s\"bad-namespace\":[", str, f ? "," : "");
87 for (u = 0; u < self->err->ns_count; u++) {
88 asprintf(&str, "%s%s\"%s\"", str, u ? "," : "", self->err->ns[u]);
89 }
90 asprintf(&str, "%s]", str);
91 f = 1;
92 }
93 if (self->err->other_count) {
94 for (u = 0; u < self->err->other_count; u++) {
95 asprintf(&str, "%s%s\"%s\":\"%s\"", str, f ? "," : "", self->err->other[u]->name, self->err->other[u]->content);
96 }
97 f = 1;
98 }
99
100 asprintf(&str, "%s}", str);
101 }
102 return PyUnicode_FromFormat("{%s}", str);
Radek Krejci0f3499a2017-10-13 13:39:36 +0200103}
104
105/*
106 * tp_getset callbacs held by ncErrGetSetters[]
107 */
108
109static PyObject *
110ncErrGetType(ncErrObject *self, void *closure)
111{
112 if (!self->err->type) {
113 Py_RETURN_NONE;
114 }
115 return PyUnicode_FromString(self->err->type);
116}
117
118static PyObject *
119ncErrGetTag(ncErrObject *self, void *closure)
120{
121 if (!self->err->tag) {
122 Py_RETURN_NONE;
123 }
124 return PyUnicode_FromString(self->err->tag);
125}
126
127static PyObject *
Radek Krejcib5ac0602017-10-17 10:35:03 +0200128ncErrGetSeverity(ncErrObject *self, void *closure)
129{
130 if (!self->err->severity) {
131 Py_RETURN_NONE;
132 }
133 return PyUnicode_FromString(self->err->severity);
134}
135
136static PyObject *
137ncErrGetAppTag(ncErrObject *self, void *closure)
138{
139 if (!self->err->apptag) {
140 Py_RETURN_NONE;
141 }
142 return PyUnicode_FromString(self->err->apptag);
143}
144
145static PyObject *
146ncErrGetPath(ncErrObject *self, void *closure)
147{
148 if (!self->err->path) {
149 Py_RETURN_NONE;
150 }
151 return PyUnicode_FromString(self->err->path);
152}
153
154static PyObject *
Radek Krejci0f3499a2017-10-13 13:39:36 +0200155ncErrGetMessage(ncErrObject *self, void *closure)
156{
157 if (!self->err->message) {
158 Py_RETURN_NONE;
159 }
160 return PyUnicode_FromString(self->err->message);
161}
162
Radek Krejcib5ac0602017-10-17 10:35:03 +0200163static PyObject *
164ncErrGetMessageLang(ncErrObject *self, void *closure)
165{
166 if (!self->err->message_lang) {
167 Py_RETURN_NONE;
168 }
169 return PyUnicode_FromString(self->err->message_lang);
170}
171
172static PyObject *
173ncErrGetSID(ncErrObject *self, void *closure)
174{
175 if (!self->err->sid) {
176 Py_RETURN_NONE;
177 }
178 return PyUnicode_FromString(self->err->sid);
179}
180
181static PyObject *
182ncErrGetBadAttr(ncErrObject *self, void *closure)
183{
184 PyObject *list;
185 uint16_t u;
186
187 if (!self->err->attr_count) {
188 Py_RETURN_NONE;
189 }
190
191 list = PyList_New(self->err->attr_count);
192 if (!list) {
193 return NULL;
194 }
195 for (u = 0; u < self->err->attr_count; u++) {
196 PyList_SET_ITEM(list, u, PyUnicode_FromString(self->err->attr[u]));
197 }
198
199 return list;
200}
201
202static PyObject *
203ncErrGetBadElem(ncErrObject *self, void *closure)
204{
205 PyObject *list;
206 uint16_t u;
207
208 if (!self->err->elem_count) {
209 Py_RETURN_NONE;
210 }
211
212 list = PyList_New(self->err->elem_count);
213 if (!list) {
214 return NULL;
215 }
216 for (u = 0; u < self->err->elem_count; u++) {
217 PyList_SET_ITEM(list, u, PyUnicode_FromString(self->err->elem[u]));
218 }
219
220 return list;
221}
222
223static PyObject *
224ncErrGetBadNS(ncErrObject *self, void *closure)
225{
226 PyObject *list;
227 uint16_t u;
228
229 if (!self->err->ns_count) {
230 Py_RETURN_NONE;
231 }
232
233 list = PyList_New(self->err->ns_count);
234 if (!list) {
235 return NULL;
236 }
237 for (u = 0; u < self->err->ns_count; u++) {
238 PyList_SET_ITEM(list, u, PyUnicode_FromString(self->err->ns[u]));
239 }
240
241 return list;
242}
243
Radek Krejci0f3499a2017-10-13 13:39:36 +0200244/*
245 * Callback structures
246 */
247
248static PyGetSetDef ncErrGetSetters[] = {
249 {"type", (getter)ncErrGetType, NULL, "<error-type>", NULL},
250 {"tag", (getter)ncErrGetTag, NULL, "<error-tag>", NULL},
Radek Krejcib5ac0602017-10-17 10:35:03 +0200251 {"severity", (getter)ncErrGetSeverity, NULL, "<error-severity>", NULL},
252 {"app-tag", (getter)ncErrGetAppTag, NULL, "<error-app-tag>", NULL},
253 {"path", (getter)ncErrGetPath, NULL, "<error-path>", NULL},
Radek Krejci0f3499a2017-10-13 13:39:36 +0200254 {"message", (getter)ncErrGetMessage, NULL, "<error-message>", NULL},
Radek Krejcib5ac0602017-10-17 10:35:03 +0200255 {"lang", (getter)ncErrGetMessageLang, NULL, "<error-message xml:lang=\" \">", NULL},
256 {"session-id", (getter)ncErrGetSID, NULL, "<error-info><session-id/></error-info>", NULL},
257 {"bad-attr", (getter)ncErrGetBadAttr, NULL, "<error-info><bad-attr/></error-info>", NULL},
258 {"bad-elem", (getter)ncErrGetBadElem, NULL, "<error-info><bad-element/></error-info>", NULL},
259 {"bad-namespace", (getter)ncErrGetBadNS, NULL, "<error-info><bad-namespace/></error-info>", NULL},
Radek Krejci0f3499a2017-10-13 13:39:36 +0200260 {NULL} /* Sentinel */
261};
262
263PyDoc_STRVAR(ncErrDoc,
264 "NETCONF Error Reply information.\n\n");
265
266PyTypeObject ncErrType = {
267 PyVarObject_HEAD_INIT(NULL, 0)
268 "netconf2.Err", /* tp_name */
269 sizeof(ncErrObject), /* tp_basicsize */
270 0, /* tp_itemsize */
271 (destructor)ncErrFree, /* tp_dealloc */
272 0, /* tp_print */
273 0, /* tp_getattr */
274 0, /* tp_setattr */
275 0, /* tp_reserved */
276 (reprfunc)ncErrStr, /* tp_repr */
277 0, /* tp_as_number */
278 0, /* tp_as_sequence */
279 0, /* tp_as_mapping */
280 0, /* tp_hash */
281 0, /* tp_call */
282 (reprfunc)ncErrStr, /* tp_str */
283 0, /* tp_getattro */
284 0, /* tp_setattro */
285 0, /* tp_as_buffer */
286 Py_TPFLAGS_DEFAULT, /* tp_flags */
287 ncErrDoc, /* tp_doc */
288 0, /* tp_traverse */
289 0, /* tp_clear */
290 0, /* tp_richcompare */
291 0, /* tp_weaklistoffset */
292 0, /* tp_iter */
293 0, /* tp_iternext */
294 0, /* tp_methods */
295 0, /* tp_members */
296 ncErrGetSetters, /* tp_getset */
297 0, /* tp_base */
298 0, /* tp_dict */
299 0, /* tp_descr_get */
300 0, /* tp_descr_set */
301 0, /* tp_dictoffset */
302 0, /* tp_init */
303 0, /* tp_alloc */
304 0, /* tp_new */
305};
306