session CHANGE libyang context checking

Always check whether the context includes
everything and if not, try to correct
the situation. not only on new contexts.
diff --git a/src/session.c b/src/session.c
index 8dfa00b..af65377 100644
--- a/src/session.c
+++ b/src/session.c
@@ -164,8 +164,9 @@
     return 0;
 }
 
+/* SCHEMAS_DIR not used */
 static int
-ctx_load_model(struct nc_session *session, const char *cpblt)
+ctx_check_and_load_model(struct nc_session *session, const char *cpblt)
 {
     const struct lys_module *module;
     char *ptr, *ptr2;
@@ -243,13 +244,22 @@
     return 0;
 }
 
+/* SCHEMAS_DIR used */
 static int
-ctx_load_ietf_netconf(struct ly_ctx *ctx, const char **cpblts)
+ctx_check_and_load_ietf_netconf(struct ly_ctx *ctx, const char **cpblts, int from_file)
 {
     int i;
     const struct lys_module *ietfnc;
 
-    if (!(ietfnc = ly_ctx_load_module(ctx, "ietf-netconf", NULL))) {
+    ietfnc = ly_ctx_get_module(ctx, "ietf-netconf", NULL);
+    if (!ietfnc) {
+        if (from_file) {
+            ietfnc = lys_parse_path(ctx, SCHEMAS_DIR"/ietf-netconf.yin", LYS_IN_YIN);
+        } else {
+            ietfnc = ly_ctx_load_module(ctx, "ietf-netconf", NULL);
+        }
+    }
+    if (!ietfnc) {
         ERR("Loading base NETCONF schema failed.");
         return 1;
     }
@@ -323,11 +333,10 @@
     return model_data;
 }
 
-/* session with an empty context is assumed */
 int
-nc_ctx_fill(struct nc_session *session)
+nc_ctx_check_and_fill(struct nc_session *session)
 {
-    int i;
+    int i, get_schema_support = 0;
     ly_module_clb old_clb = NULL;
     void *old_data = NULL;
 
@@ -336,21 +345,27 @@
     /* check if get-schema is supported */
     for (i = 0; session->cpblts[i]; ++i) {
         if (!strncmp(session->cpblts[i], "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", 51)) {
-            /* it is supported, load local ietf-netconf-monitoring so we can create <get-schema> RPCs */
-            if (ly_ctx_load_module(session->ctx, "ietf-netconf-monitoring", NULL)) {
-                /* set module retrieval using <get-schema> */
-                old_clb = ly_ctx_get_module_clb(session->ctx, &old_data);
-                ly_ctx_set_module_clb(session->ctx, &libyang_module_clb, session);
-            } else {
-                WRN("Loading NETCONF monitoring schema failed, cannot use <get-schema>.");
-            }
+            get_schema_support = 1;
             break;
         }
     }
 
+    /* get-schema is supported, load local ietf-netconf-monitoring so we can create <get-schema> RPCs */
+    if (get_schema_support && !ly_ctx_get_module(session->ctx, "ietf-netconf-monitoring", NULL)) {
+        if (lys_parse_path(session->ctx, SCHEMAS_DIR"/ietf-netconf-monitoring.yin", LYS_IN_YIN)) {
+            /* set module retrieval using <get-schema> */
+            old_clb = ly_ctx_get_module_clb(session->ctx, &old_data);
+            ly_ctx_set_module_clb(session->ctx, &libyang_module_clb, session);
+        } else {
+            WRN("Loading NETCONF monitoring schema failed, cannot use <get-schema>.");
+        }
+    }
+
     /* load base model disregarding whether it's in capabilities (but NETCONF capabilities are used to enable features) */
-    if (ctx_load_ietf_netconf(session->ctx, session->cpblts)) {
-        ly_ctx_set_module_clb(session->ctx, old_clb, old_data);
+    if (ctx_check_and_load_ietf_netconf(session->ctx, session->cpblts, !get_schema_support)) {
+        if (old_clb) {
+            ly_ctx_set_module_clb(session->ctx, old_clb, old_data);
+        }
         return 1;
     }
 
@@ -361,23 +376,12 @@
             continue;
         }
 
-        ctx_load_model(session, session->cpblts[i]);
+        ctx_check_and_load_model(session, session->cpblts[i]);
     }
 
-    ly_ctx_set_module_clb(session->ctx, old_clb, old_data);
-    return 0;
-}
-
-int
-nc_ctx_check(struct nc_session *session)
-{
-    /* check presence of the required base schema */
-    if (!ly_ctx_get_module(session->ctx, "ietf-netconf", NULL)) {
-        if (ctx_load_ietf_netconf(session->ctx, session->cpblts)) {
-            return 1;
-        }
+    if (old_clb) {
+        ly_ctx_set_module_clb(session->ctx, old_clb, old_data);
     }
-
     return 0;
 }
 
@@ -419,15 +423,8 @@
     }
     session->status = NC_STATUS_RUNNING;
 
-    /* check/fill libyang context */
-    if (session->flags & NC_SESSION_SHAREDCTX) {
-        if (nc_ctx_check(session)) {
-            goto fail;
-        }
-    } else {
-        if (nc_ctx_fill(session)) {
-            goto fail;
-        }
+    if (nc_ctx_check_and_fill(session)) {
+        goto fail;
     }
 
     return session;
diff --git a/src/session_p.h b/src/session_p.h
index 4b11012..7cf06ea 100644
--- a/src/session_p.h
+++ b/src/session_p.h
@@ -159,17 +159,7 @@
  * @param[in] session Session to create the context for.
  * @return 0 on success, non-zero on failure.
  */
-int nc_ctx_fill(struct nc_session *session);
-
-/**
- * @brief Check whether the libyang context in \p session is suitable for NETCONF use
- *        meaning whether the ietf-netconf model is loaded.
- *
- * @param[in] session Session with the capabilities to be supported if loading ietf-netconf
- *                    explicitly.
- * @return 0 on success, non-zero on failure.
- */
-int nc_ctx_check(struct nc_session *session);
+int nc_ctx_check_and_fill(struct nc_session *session);
 
 /**
  * @brief Create and connect a socket.
diff --git a/src/session_ssh.c b/src/session_ssh.c
index cb8901d..22ae67a 100644
--- a/src/session_ssh.c
+++ b/src/session_ssh.c
@@ -944,15 +944,8 @@
     }
     session->status = NC_STATUS_RUNNING;
 
-    /* check/fill libyang context */
-    if (session->flags & NC_SESSION_SHAREDCTX) {
-        if (nc_ctx_check(session)) {
-            goto fail;
-        }
-    } else {
-        if (nc_ctx_fill(session)) {
-            goto fail;
-        }
+    if (nc_ctx_check_and_fill(session)) {
+        goto fail;
     }
 
     /* store information into the dictionary */
@@ -1069,15 +1062,8 @@
     }
     session->status = NC_STATUS_RUNNING;
 
-    /* check/fill libyang context */
-    if (session->flags & NC_SESSION_SHAREDCTX) {
-        if (nc_ctx_check(session)) {
-            goto fail;
-        }
-    } else {
-        if (nc_ctx_fill(session)) {
-            goto fail;
-        }
+    if (nc_ctx_check_and_fill(session)) {
+        goto fail;
     }
 
     /* store information into the dictionary */
@@ -1146,15 +1132,8 @@
     }
     new_session->status = NC_STATUS_RUNNING;
 
-    /* check/fill libyang context */
-    if (session->flags & NC_SESSION_SHAREDCTX) {
-        if (nc_ctx_check(session)) {
-            goto fail;
-        }
-    } else {
-        if (nc_ctx_fill(session)) {
-            goto fail;
-        }
+    if (nc_ctx_check_and_fill(session)) {
+        goto fail;
     }
 
     /* store information into session and the dictionary */
diff --git a/src/session_tls.c b/src/session_tls.c
index e52f31f..3cf67b1 100644
--- a/src/session_tls.c
+++ b/src/session_tls.c
@@ -353,15 +353,8 @@
     }
     session->status = NC_STATUS_RUNNING;
 
-    /* check/fill libyang context */
-    if (session->flags & NC_SESSION_SHAREDCTX) {
-        if (nc_ctx_check(session)) {
-            goto fail;
-        }
-    } else {
-        if (nc_ctx_fill(session)) {
-            goto fail;
-        }
+    if (nc_ctx_check_and_fill(session)) {
+        goto fail;
     }
 
     /* store information into session and the dictionary */
@@ -421,15 +414,8 @@
     }
     session->status = NC_STATUS_RUNNING;
 
-    /* check/fill libyang context */
-    if (session->flags & NC_SESSION_SHAREDCTX) {
-        if (nc_ctx_check(session)) {
-            goto fail;
-        }
-    } else {
-        if (nc_ctx_fill(session)) {
-            goto fail;
-        }
+    if (nc_ctx_check_and_fill(session)) {
+        goto fail;
     }
 
     return session;