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);