1616
1717#include "netconf_monitoring.h"
1818
19+ #include <errno.h>
1920#include <pthread.h>
2021#include <stdint.h>
2122#include <stdlib.h>
@@ -321,16 +322,18 @@ np2srv_ncm_oper_cb(sr_session_ctx_t *session, uint32_t UNUSED(sub_id), const cha
321322 lyd_new_term (list , NULL , "namespace" , mod -> ns , 0 , NULL );
322323 lyd_new_term (list , NULL , "location" , "NETCONF" , 0 , NULL );
323324
324- LY_ARRAY_FOR (mod -> parsed -> includes , u ) {
325- submod = mod -> parsed -> includes [u ].submodule ;
325+ if (mod -> parsed ) {
326+ LY_ARRAY_FOR (mod -> parsed -> includes , u ) {
327+ submod = mod -> parsed -> includes [u ].submodule ;
326328
327- lyd_new_list (cont , NULL , "schema" , 0 , & list , submod -> name , submod -> revs ? submod -> revs [0 ].date : "" , "yang" );
328- lyd_new_term (list , NULL , "namespace" , mod -> ns , 0 , NULL );
329- lyd_new_term (list , NULL , "location" , "NETCONF" , 0 , NULL );
329+ lyd_new_list (cont , NULL , "schema" , 0 , & list , submod -> name , submod -> revs ? submod -> revs [0 ].date : "" , "yang" );
330+ lyd_new_term (list , NULL , "namespace" , mod -> ns , 0 , NULL );
331+ lyd_new_term (list , NULL , "location" , "NETCONF" , 0 , NULL );
330332
331- lyd_new_list (cont , NULL , "schema" , 0 , & list , submod -> name , submod -> revs ? submod -> revs [0 ].date : "" , "yin" );
332- lyd_new_term (list , NULL , "namespace" , mod -> ns , 0 , NULL );
333- lyd_new_term (list , NULL , "location" , "NETCONF" , 0 , NULL );
333+ lyd_new_list (cont , NULL , "schema" , 0 , & list , submod -> name , submod -> revs ? submod -> revs [0 ].date : "" , "yin" );
334+ lyd_new_term (list , NULL , "namespace" , mod -> ns , 0 , NULL );
335+ lyd_new_term (list , NULL , "location" , "NETCONF" , 0 , NULL );
336+ }
334337 }
335338 }
336339
@@ -411,18 +414,91 @@ np2srv_ncm_oper_cb(sr_session_ctx_t *session, uint32_t UNUSED(sub_id), const cha
411414 return SR_ERR_INTERNAL ;
412415}
413416
417+ /**
418+ * @brief Print YANG (sub)module data.
419+ *
420+ * @param[in] mod Module to print, if @p submod not set.
421+ * @param[in] submod Submodule to print, if set.
422+ * @param[out] yang_data Printed YANG data.
423+ * @return NULL on success;
424+ * @return server reply on error.
425+ */
426+ static struct nc_server_reply *
427+ np_getschema_print_yang (const struct lys_module * mod , const struct lysp_submodule * submod , char * * yang_data )
428+ {
429+ struct nc_server_reply * reply = NULL ;
430+ const struct ly_ctx * ctx ;
431+ const struct lys_module * m ;
432+ const char * filepath , * name , * revision ;
433+ char * path = NULL , * msg ;
434+ FILE * f = NULL ;
435+ uint32_t idx ;
436+ int len ;
437+
438+ ctx = mod ? mod -> ctx : submod -> mod -> ctx ;
439+
440+ if (submod && submod -> filepath ) {
441+ filepath = submod -> filepath ;
442+ } else if (mod && mod -> filepath ) {
443+ filepath = mod -> filepath ;
444+ } else {
445+ /* find a module with filepath */
446+ idx = ly_ctx_internal_modules_count (ctx );
447+ while ((m = ly_ctx_get_module_iter (ctx , & idx ))) {
448+ if (m -> filepath ) {
449+ break ;
450+ }
451+ }
452+ if (!m ) {
453+ reply = np_reply_err_op_failed (NULL , ctx , "Failed to find a module with filepath." );
454+ free (msg );
455+ goto cleanup ;
456+ }
457+
458+ /* create the path to the file */
459+ len = strrchr (m -> filepath , '/' ) - m -> filepath ;
460+ name = submod ? submod -> name : mod -> name ;
461+ revision = submod ? (submod -> revs ? submod -> revs [0 ].date : NULL ) : mod -> revision ;
462+ asprintf (& path , "%.*s/%s%s%s.yang" , len , m -> filepath , name , revision ? "@" : "" , revision ? revision : "" );
463+ filepath = path ;
464+ }
465+
466+ /* open the file */
467+ f = fopen (filepath , "r" );
468+ if (!f ) {
469+ asprintf (& msg , "Failed to open \"%s\" (%s)." , filepath , strerror (errno ));
470+ reply = np_reply_err_op_failed (NULL , ctx , msg );
471+ free (msg );
472+ goto cleanup ;
473+ }
474+
475+ /* learn file size */
476+ fseek (f , 0 , SEEK_END );
477+ len = ftell (f );
478+ fseek (f , 0 , SEEK_SET );
479+
480+ /* read the data */
481+ * yang_data = malloc (len + 1 );
482+ fread (* yang_data , 1 , len , f );
483+ (* yang_data )[len ] = '\0' ;
484+
485+ cleanup :
486+ if (f ) {
487+ fclose (f );
488+ }
489+ free (path );
490+ return reply ;
491+ }
492+
414493struct nc_server_reply *
415494np2srv_rpc_getschema_cb (const struct lyd_node * rpc , struct np_user_sess * UNUSED (user_sess ))
416495{
417496 struct nc_server_reply * reply = NULL ;
418497 const char * identifier = NULL , * revision = NULL , * format = NULL ;
419- char * model_data = NULL ;
420- struct ly_out * out ;
498+ char * module_data = NULL ;
421499 const struct lys_module * module = NULL ;
422500 const struct lysp_submodule * submodule = NULL ;
423501 struct lyd_node * node , * output = NULL ;
424- LYS_OUTFORMAT outformat = 0 ;
425- LY_ERR lyrc ;
426502
427503 /* identifier */
428504 if (!lyd_find_path (rpc , "identifier" , 0 , & node )) {
@@ -472,25 +548,13 @@ np2srv_rpc_getschema_cb(const struct lyd_node *rpc, struct np_user_sess *UNUSED(
472548 }
473549
474550 /* check format */
475- if (!format || !strcmp (format , "yang" )) {
476- outformat = LYS_OUT_YANG ;
477- } else if (!strcmp (format , "yin" )) {
478- outformat = LYS_OUT_YIN ;
479- } else {
551+ if (format && strcmp (format , "yang" )) {
480552 reply = np_reply_err_invalid_val (LYD_CTX (rpc ), "The requested format is not supported." , "format" );
481553 goto cleanup ;
482554 }
483555
484- /* print */
485- ly_out_new_memory (& model_data , 0 , & out );
486- if (module ) {
487- lyrc = lys_print_module (out , module , outformat , 0 , 0 );
488- } else {
489- lyrc = lys_print_submodule (out , submodule , outformat , 0 , 0 );
490- }
491- ly_out_free (out , NULL , 0 );
492- if (lyrc ) {
493- reply = np_reply_err_op_failed (NULL , LYD_CTX (rpc ), ly_last_logmsg ());
556+ /* get module data */
557+ if ((reply = np_getschema_print_yang (module , submodule , & module_data ))) {
494558 goto cleanup ;
495559 }
496560
@@ -499,16 +563,16 @@ np2srv_rpc_getschema_cb(const struct lyd_node *rpc, struct np_user_sess *UNUSED(
499563 reply = np_reply_err_op_failed (NULL , LYD_CTX (rpc ), ly_last_logmsg ());
500564 goto cleanup ;
501565 }
502- if (lyd_new_any (output , NULL , "data" , NULL , model_data , 0 , LYD_NEW_ANY_USE_VALUE | LYD_NEW_VAL_OUTPUT , NULL )) {
566+ if (lyd_new_any (output , NULL , "data" , NULL , module_data , 0 , LYD_NEW_ANY_USE_VALUE | LYD_NEW_VAL_OUTPUT , NULL )) {
503567 reply = np_reply_err_op_failed (NULL , LYD_CTX (rpc ), ly_last_logmsg ());
504568 goto cleanup ;
505569 }
506- model_data = NULL ;
570+ module_data = NULL ;
507571 reply = np_reply_success (rpc , output );
508572 output = NULL ;
509573
510574cleanup :
511- free (model_data );
575+ free (module_data );
512576 lyd_free_siblings (output );
513577 return reply ;
514578}
0 commit comments