@@ -249,6 +249,64 @@ np2srv_err_nc(sr_error_info_err_t *err)
249
249
return NULL ;
250
250
}
251
251
252
+ /**
253
+ * @brief Find the nth substring delimited by quotes.
254
+ *
255
+ * For example: abcd"ef"ghij"kl"mn -> index 0 is "ef", index 1 is "kl".
256
+ *
257
+ * @param[in] msg Input string with quoted substring.
258
+ * @param[in] index Number starting from 0 specifying the nth substring.
259
+ * @return Copied nth substring without quotes.
260
+ */
261
+ static char *
262
+ np2srv_err_reply_get_quoted_string (const char * msg , uint32_t index )
263
+ {
264
+ char * ret ;
265
+ const char * start = NULL , * end = NULL , * iter , * tmp ;
266
+ uint32_t quote_cnt = 0 , last_quote ;
267
+
268
+ assert (msg );
269
+
270
+ last_quote = (index + 1 ) * 2 ;
271
+ for (iter = msg ; * iter ; ++ iter ) {
272
+ if (* iter != '\"' ) {
273
+ continue ;
274
+ }
275
+ /* updating the start and end pointers - swap */
276
+ tmp = end ;
277
+ end = iter ;
278
+ start = tmp ;
279
+ if (++ quote_cnt == last_quote ) {
280
+ /* nth substring found */
281
+ break ;
282
+ }
283
+ }
284
+
285
+ if (!start ) {
286
+ return NULL ;
287
+ }
288
+
289
+ /* Skip first quote */
290
+ ++ start ;
291
+ /* Copy substring */
292
+ ret = strndup (start , end - start );
293
+
294
+ return ret ;
295
+ }
296
+
297
+ /**
298
+ * @brief Check that the @p str starts with the @p prefix.
299
+ *
300
+ * @param[in] prefix Required prefix.
301
+ * @param[in] str Input string to check.
302
+ * @return True if @p str start with @p prefix otherwise False.
303
+ */
304
+ static ly_bool
305
+ np2srv_strstarts (const char * prefix , const char * str )
306
+ {
307
+ return strncmp (str , prefix , strlen (prefix )) == 0 ;
308
+ }
309
+
252
310
/**
253
311
* @brief Create NC error reply based on SR error info.
254
312
*
@@ -262,6 +320,9 @@ np2srv_err_reply_sr(const sr_error_info_t *err_info)
262
320
struct lyd_node * e ;
263
321
const struct ly_ctx * ly_ctx ;
264
322
size_t i ;
323
+ char * str , * path ;
324
+ const struct lysc_node * cn ;
325
+ NC_ERR_TYPE errtype ;
265
326
266
327
/* try to find a NETCONF error(s) */
267
328
for (i = 0 ; i < err_info -> err_count ; ++ i ) {
@@ -284,16 +345,34 @@ np2srv_err_reply_sr(const sr_error_info_t *err_info)
284
345
285
346
ly_ctx = sr_acquire_context (np2srv .sr_conn );
286
347
for (i = 0 ; i < err_info -> err_count ; ++ i ) {
287
- /* generic error */
288
- e = nc_err (ly_ctx , NC_ERR_OP_FAILED , NC_ERR_TYPE_APP );
289
- nc_err_set_msg (e , err_info -> err [i ].message , "en" );
348
+ if (np2srv_strstarts ("Mandatory node" , err_info -> err [i ].message ) ||
349
+ np2srv_strstarts ("Mandatory choice" , err_info -> err [i ].message )) {
350
+ str = np2srv_err_reply_get_quoted_string (err_info -> err [i ].message , 0 );
351
+ path = np2srv_err_reply_get_quoted_string (err_info -> err [i ].message , 1 );
352
+ cn = lys_find_path (ly_ctx , NULL , path , 0 );
353
+ if (cn && ((cn -> nodetype & LYS_RPC ) || (cn -> nodetype & LYS_INPUT ))) {
354
+ errtype = NC_ERR_TYPE_PROT ;
355
+ } else {
356
+ errtype = NC_ERR_TYPE_APP ;
357
+ }
358
+ e = nc_err (ly_ctx , NC_ERR_MISSING_ELEM , errtype , str );
359
+ free (str );
360
+ free (path );
361
+ } else if (err_info -> err -> err_code == SR_ERR_NO_MEMORY ) {
362
+ e = nc_err (ly_ctx , NC_ERR_RES_DENIED , NC_ERR_TYPE_APP );
363
+ } else {
364
+ /* generic error */
365
+ e = nc_err (ly_ctx , NC_ERR_OP_FAILED , NC_ERR_TYPE_APP );
366
+ }
290
367
368
+ nc_err_set_msg (e , err_info -> err [i ].message , "en" );
291
369
if (reply ) {
292
370
nc_server_reply_add_err (reply , e );
293
371
} else {
294
372
reply = nc_server_reply_err (e );
295
373
}
296
374
}
375
+ /* clear for other errors */
297
376
sr_release_context (np2srv .sr_conn );
298
377
299
378
return reply ;
0 commit comments