client session CHANGE check server schemas retrieval

If it fails, try other means. Allow creating sessions
with some missing schemas.
diff --git a/src/session_client.c b/src/session_client.c
index b6ca7cf..f1db4bf 100644
--- a/src/session_client.c
+++ b/src/session_client.c
@@ -74,8 +74,8 @@
     /* parse module */
     ptr = strstr(cpblt, "module=");
     if (!ptr) {
-        WRN("Unknown capability \"%s\" could not be parsed.", cpblt);
-        return 1;
+        ERR("Unknown capability \"%s\" could not be parsed.", cpblt);
+        return -1;
     }
     ptr += 7;
     ptr2 = strchr(ptr, '&');
@@ -101,11 +101,13 @@
         module = ly_ctx_load_module(session->ctx, model_name, revision);
     }
 
-    free(model_name);
     free(revision);
     if (!module) {
+        WRN("Failed to load model \"%s\".", model_name);
+        free(model_name);
         return 1;
     }
+    free(model_name);
 
     /* parse features */
     ptr = strstr(cpblt, "features=");
@@ -250,10 +252,11 @@
     return model_data;
 }
 
+/* return 0 - ok, 1 - some models failed to load, -1 - error */
 int
 nc_ctx_check_and_fill(struct nc_session *session)
 {
-    int i, get_schema_support = 0;
+    int i, get_schema_support = 0, ret = 0, r;
     ly_module_clb old_clb = NULL;
     void *old_data = NULL;
 
@@ -283,7 +286,7 @@
         if (old_clb) {
             ly_ctx_set_module_clb(session->ctx, old_clb, old_data);
         }
-        return 1;
+        return -1;
     }
 
     /* load all other models */
@@ -293,13 +296,39 @@
             continue;
         }
 
-        ctx_check_and_load_model(session, session->cpblts[i]);
+        r = ctx_check_and_load_model(session, session->cpblts[i]);
+        if (r == -1) {
+            ret = -1;
+            break;
+        }
+
+        /* failed to load schema, but let's try to find it using user callback (or locally, if not set),
+         * if it was using get-schema */
+        if (r == 1) {
+            if (get_schema_support) {
+                VRB("Trying to load the schema from a different source.");
+                /* works even if old_clb is NULL */
+                ly_ctx_set_module_clb(session->ctx, old_clb, old_data);
+                r = ctx_check_and_load_model(session, session->cpblts[i]);
+            }
+
+            /* fail again (or no other way to try), too bad */
+            if (r) {
+                ret = 1;
+            }
+
+            /* set get-schema callback back */
+            ly_ctx_set_module_clb(session->ctx, &libyang_module_clb, session);
+        }
     }
 
     if (old_clb) {
         ly_ctx_set_module_clb(session->ctx, old_clb, old_data);
     }
-    return 0;
+    if (ret == 1) {
+        WRN("Some models failed to be loaded, any data from these models will be ignored.");
+    }
+    return ret;
 }
 
 API struct nc_session *
@@ -340,7 +369,7 @@
     }
     session->status = NC_STATUS_RUNNING;
 
-    if (nc_ctx_check_and_fill(session)) {
+    if (nc_ctx_check_and_fill(session) == -1) {
         goto fail;
     }
 
diff --git a/src/session_client_ssh.c b/src/session_client_ssh.c
index 22f163e..cfa0f55 100644
--- a/src/session_client_ssh.c
+++ b/src/session_client_ssh.c
@@ -752,7 +752,7 @@
         case NC_SSH_AUTH_PASSWORD:
             userauthlist &= ~SSH_AUTH_METHOD_PASSWORD;
 
-            VRB("Password authentication (host %s, user %s).", session->host, session->username);
+            VRB("Password authentication (host \"%s\", user \"%s\").", session->host, session->username);
             s = sshauth_password(session->username, session->host);
             if ((ret_auth = ssh_userauth_password(ssh_sess, session->username, s)) != SSH_AUTH_SUCCESS) {
                 memset(s, 0, strlen(s));
@@ -798,7 +798,7 @@
             }
 
             for (j = 0; j < ssh_opts.key_count; j++) {
-                VRB("Trying to authenticate using %spair %s %s.",
+                VRB("Trying to authenticate using %spair \"%s\" \"%s\".",
                      ssh_opts.keys[j].privkey_crypt ? "password-protected " : "", ssh_opts.keys[j].privkey_path,
                      ssh_opts.keys[j].pubkey_path);
 
@@ -970,7 +970,7 @@
     }
     session->status = NC_STATUS_RUNNING;
 
-    if (nc_ctx_check_and_fill(session)) {
+    if (nc_ctx_check_and_fill(session) == -1) {
         goto fail;
     }
 
@@ -1087,7 +1087,7 @@
     }
     session->status = NC_STATUS_RUNNING;
 
-    if (nc_ctx_check_and_fill(session)) {
+    if (nc_ctx_check_and_fill(session) == -1) {
         goto fail;
     }
 
@@ -1164,7 +1164,7 @@
 
     pthread_mutex_unlock(new_session->ti_lock);
 
-    if (nc_ctx_check_and_fill(new_session)) {
+    if (nc_ctx_check_and_fill(new_session) == -1) {
         goto fail;
     }
 
diff --git a/src/session_client_tls.c b/src/session_client_tls.c
index d817c25..cb1bc9b 100644
--- a/src/session_client_tls.c
+++ b/src/session_client_tls.c
@@ -294,7 +294,7 @@
     }
     session->status = NC_STATUS_RUNNING;
 
-    if (nc_ctx_check_and_fill(session)) {
+    if (nc_ctx_check_and_fill(session) == -1) {
         goto fail;
     }
 
@@ -355,7 +355,7 @@
     }
     session->status = NC_STATUS_RUNNING;
 
-    if (nc_ctx_check_and_fill(session)) {
+    if (nc_ctx_check_and_fill(session) == -1) {
         goto fail;
     }
 
diff --git a/src/session_p.h b/src/session_p.h
index 9317f30..93e2844 100644
--- a/src/session_p.h
+++ b/src/session_p.h
@@ -256,7 +256,7 @@
  *        for in the directory set using nc_schema_searchpath().
  *
  * @param[in] session Session to create the context for.
- * @return 0 on success, non-zero on failure.
+ * @return 0 on success, 1 on some missing schemas, -1 on error.
  */
 int nc_ctx_check_and_fill(struct nc_session *session);