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