From 9e54f0602fdedbb191a92a85e6f7830c86fa03f6 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Fri, 22 Dec 2023 22:27:54 +0100 Subject: [PATCH] Changed ca_errmsg callback to a more generic variant Includes all error, log and debug messages See [Customized NETCONF error message](https://github.com/clicon/clixon/issues/454) --- CHANGELOG.md | 4 + apps/cli/cli_common.c | 8 +- apps/cli/cli_plugin.c | 4 +- apps/netconf/netconf_main.c | 14 +-- apps/restconf/restconf_err.c | 12 +- example/main/example_cli.c | 134 ++++++++++++++++----- example/main/example_cli.cli | 8 +- lib/clixon/clixon.h.in | 4 +- lib/clixon/clixon_debug.h | 8 +- lib/clixon/clixon_err.h | 13 +- lib/clixon/clixon_log.h | 16 ++- lib/clixon/clixon_netconf_lib.h | 12 -- lib/clixon/clixon_plugin.h | 40 +++++-- lib/clixon/clixon_xml.h | 3 - lib/src/clixon_api_path_parse.l | 4 +- lib/src/clixon_api_path_parse.y | 4 +- lib/src/clixon_client.c | 6 +- lib/src/clixon_data.c | 4 +- lib/src/clixon_datastore.c | 4 +- lib/src/clixon_datastore_read.c | 4 +- lib/src/clixon_datastore_write.c | 4 +- lib/src/clixon_debug.c | 79 ++++++++----- lib/src/clixon_err.c | 158 ++++++++++++++++++------- lib/src/clixon_event.c | 3 + lib/src/clixon_file.c | 2 + lib/src/clixon_handle.c | 6 +- lib/src/clixon_hash.c | 2 + lib/src/clixon_instance_id_parse.l | 4 +- lib/src/clixon_instance_id_parse.y | 4 +- lib/src/clixon_json.c | 4 +- lib/src/clixon_json_parse.l | 3 +- lib/src/clixon_json_parse.y | 4 +- lib/src/clixon_log.c | 96 ++++++++------- lib/src/clixon_nacm.c | 4 +- lib/src/clixon_netconf_input.c | 4 +- lib/src/clixon_netconf_lib.c | 127 +------------------- lib/src/clixon_netconf_monitoring.c | 4 +- lib/src/clixon_netns.c | 2 + lib/src/clixon_options.c | 4 +- lib/src/clixon_path.c | 6 +- lib/src/clixon_plugin.c | 97 ++++++++++----- lib/src/clixon_proc.c | 4 +- lib/src/clixon_proto.c | 4 +- lib/src/clixon_proto_client.c | 6 +- lib/src/clixon_regex.c | 3 +- lib/src/clixon_sig.c | 2 + lib/src/clixon_stream.c | 4 +- lib/src/clixon_string.c | 2 + lib/src/clixon_text_syntax.c | 4 +- lib/src/clixon_text_syntax_parse.y | 4 +- lib/src/clixon_uid.c | 2 + lib/src/clixon_validate.c | 6 +- lib/src/clixon_validate_minmax.c | 4 +- lib/src/clixon_xml.c | 137 +-------------------- lib/src/clixon_xml_bind.c | 9 +- lib/src/clixon_xml_changelog.c | 9 +- lib/src/clixon_xml_default.c | 6 +- lib/src/clixon_xml_io.c | 4 +- lib/src/clixon_xml_map.c | 6 +- lib/src/clixon_xml_nsctx.c | 4 +- lib/src/clixon_xml_parse.y | 4 +- lib/src/clixon_xml_sort.c | 4 +- lib/src/clixon_xml_vec.c | 4 +- lib/src/clixon_xpath.c | 4 +- lib/src/clixon_xpath_ctx.c | 4 +- lib/src/clixon_xpath_eval.c | 4 +- lib/src/clixon_xpath_function.c | 4 +- lib/src/clixon_xpath_optimize.c | 4 +- lib/src/clixon_xpath_parse.l | 4 +- lib/src/clixon_xpath_parse.y | 4 +- lib/src/clixon_xpath_yang.c | 4 +- lib/src/clixon_yang.c | 6 +- lib/src/clixon_yang_cardinality.c | 3 +- lib/src/clixon_yang_module.c | 6 +- lib/src/clixon_yang_parse.y | 3 +- lib/src/clixon_yang_parse_lib.c | 8 +- lib/src/clixon_yang_schema_mount.c | 4 +- lib/src/clixon_yang_schemanode_parse.y | 6 +- lib/src/clixon_yang_sub_parse.c | 3 +- lib/src/clixon_yang_sub_parse.y | 8 +- lib/src/clixon_yang_type.c | 3 +- test/test_cli_err.sh | 110 +++++++++++++++++ test/test_client.sh | 8 +- 83 files changed, 739 insertions(+), 616 deletions(-) create mode 100755 test/test_cli_err.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index dfeede38..63321267 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,10 @@ Expected: February 2024 ### C/CLI-API changes on existing features Developers may need to change their code +* Changed ca_errmsg callback to a more generic variant + * Includes all error, log and debug messages + * See [Customized NETCONF error message](https://github.com/clicon/clixon/issues/454) + * See https://clixon-docs.readthedocs.io/en/latest/errors.html#customized-errors for more info * Refactoring basic clixon modules and some API changes * Changes marked in code with `COMPAT_6_5` * Most common functions have backward compatible macros through the 6.6 release diff --git a/apps/cli/cli_common.c b/apps/cli/cli_common.c index e0d6f870..771d9c97 100644 --- a/apps/cli/cli_common.c +++ b/apps/cli/cli_common.c @@ -462,13 +462,7 @@ cli_dbxml(clixon_handle h, if ((ret = api_path2xml(api_path, yspec0, xtop, YC_DATANODE, 1, &xbot, &y, &xerr)) < 0) goto done; if (ret == 0){ - if ((cb = cbuf_new()) == NULL){ - clixon_err(OE_UNIX, errno, "cbuf_new"); - goto done; - } - if (netconf_err2cb(h, xerr, cb) < 0) - goto done; - clixon_err(OE_CFG, EINVAL, "api-path syntax error \"%s\": %s", api_path_fmt, cbuf_get(cb)); + clixon_err_netconf(h, OE_CFG, EINVAL, xerr, "api-path syntax error \"%s\"", api_path_fmt); goto done; } } diff --git a/apps/cli/cli_plugin.c b/apps/cli/cli_plugin.c index 50fda063..41b8ddfc 100644 --- a/apps/cli/cli_plugin.c +++ b/apps/cli/cli_plugin.c @@ -488,7 +488,9 @@ cli_handler_err(FILE *f) if (clixon_err_category()){ /* Check if error is already logged on stderr */ if ((clixon_get_logflags() & CLIXON_LOG_STDERR) == 0){ - fprintf(f, "%s: %s", clixon_err_str(), clixon_err_reason()); + if (clixon_err_category() != -1) + fprintf(f, "%s: ", clixon_err_str()); + fprintf(f, "%s", clixon_err_reason()); if (clixon_err_subnr()) fprintf(f, ": %s", strerror(clixon_err_subnr())); fprintf(f, "\n"); diff --git a/apps/netconf/netconf_main.c b/apps/netconf/netconf_main.c index 694445ab..96bff6e2 100644 --- a/apps/netconf/netconf_main.c +++ b/apps/netconf/netconf_main.c @@ -713,7 +713,7 @@ main(int argc, if (sscanf(optarg, "%d", &dbg) != 1) usage(h, argv[0]); break; - case 'f': /* override config file */ + case 'f': /* override config file */ if (!strlen(optarg)) usage(h, argv[0]); clicon_option_str_set(h, "CLICON_CONFIGFILE", optarg); @@ -723,14 +723,14 @@ main(int argc, usage(h, argv[0]); clicon_option_str_set(h, "CLICON_CONFIGDIR", optarg); break; - case 'l': /* Log destination: s|e|o */ + case 'l': /* Log destination: s|e|o */ if ((logdst = clixon_log_opt(optarg[0])) < 0) usage(h, argv[0]); if (logdst == CLIXON_LOG_FILE && strlen(optarg)>1 && clixon_log_file(optarg+1) < 0) goto done; - break; + break; } /* @@ -889,7 +889,7 @@ main(int argc, /* Load clixon lib yang module */ if (yang_spec_parse_module(h, "clixon-lib", NULL, yspec) < 0) goto done; - /* Load yang module library, RFC7895 */ + /* Load yang module library, RFC7895 */ if (yang_modules_init(h) < 0) goto done; /* Add netconf yang spec, used by netconf client and as internal protocol */ @@ -935,7 +935,7 @@ main(int argc, } #ifdef __AFL_HAVE_MANUAL_CONTROL /* American fuzzy loop deferred init, see CLICON_NETCONF_HELLO_OPTIONAL=true, see a speedup of x10 */ - __AFL_INIT(); + __AFL_INIT(); #endif if (clixon_event_reg_fd(0, netconf_input_cb, h, "netconf socket") < 0) goto done; @@ -950,12 +950,12 @@ main(int argc, goto done; ok: retval = 0; - done: + done: if (ignore_packet_errors) retval = 0; clixon_exit_set(1); /* This is to disable resend mechanism in close-session */ - netconf_terminate(h); clixon_log_init(h, __PROGRAM__, LOG_INFO, 0); /* Log on syslog no stderr */ clixon_log(h, LOG_NOTICE, "%s: %u Terminated", __PROGRAM__, getpid()); + netconf_terminate(h); return retval; } diff --git a/apps/restconf/restconf_err.c b/apps/restconf/restconf_err.c index d0a24821..8c644149 100644 --- a/apps/restconf/restconf_err.c +++ b/apps/restconf/restconf_err.c @@ -353,17 +353,17 @@ api_return_err(clixon_handle h, * @see api_return_err where top level is expected to be */ int -api_return_err0(clixon_handle h, - void *req, - cxobj *xerr, - int pretty, +api_return_err0(clixon_handle h, + void *req, + cxobj *xerr, + int pretty, restconf_media media, - int code) + int code) { int retval = -1; cxobj *xe; - if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ + if ((xe = xml_find_type(xerr, NULL, "rpc-error", CX_ELMNT)) == NULL){ clixon_err(OE_XML, EINVAL, "Expected xml on the form .."); goto done; } diff --git a/example/main/example_cli.c b/example/main/example_cli.c index a6acb246..0147a058 100644 --- a/example/main/example_cli.c +++ b/example/main/example_cli.c @@ -44,11 +44,11 @@ #include #include #include +#include #include #include #include #include -#include /* matching strings */ /* clixon */ #include @@ -56,6 +56,13 @@ #include #include +/*! Error/log message callback + * + * Start cli with -- -e + * make errmsg/logmsg callback + */ +static errmsg_t *_errmsg_callback_fn = NULL; + /*! Yang schema mount * * Start cli with -- -m -M @@ -64,6 +71,8 @@ static char *_mount_yang = NULL; static char *_mount_namespace = NULL; +static clixon_plugin_api api; + /*! Example cli function */ int @@ -234,43 +243,112 @@ example_cli_yang_mount(clixon_handle h, return retval; } -/*! Callback to customize Netconf error message +/*! Callback to customize log, error, or debug message * - * @param[in] h Clixon handle - * @param[in] xerr Netconf error message on the level: - * @param[out] cberr Translation from netconf err to cbuf. - * @retval 0 OK, with cberr set - * @retval -1 Error - * @see netconf_err2cb this errmsg is the same as the default + * @param[in] h Clixon handle + * @param[in] fn Inline function name (when called from clixon_err() macro) + * @param[in] line Inline file line number (when called from clixon_err() macro) + * @param[in] type Log message type + * @param[in,out] category Clixon error category, See enum clixon_err + * @param[in,out] suberr Error number, typically errno + * @param[in] xerr Netconf error xml tree on the form: + * @param[in] format Format string + * @param[in] ap Variable argument list + * @param[out] cbmsg Log string as cbuf, if set bypass ordinary logging + * @retval 0 OK + * @retval -1 Error + * When cbmsg is set by a plugin, no other plugins are called. category and suberr + * can be rewritten by any plugin. */ int -example_cli_errmsg(clixon_handle h, - cxobj *xerr, - cbuf *cberr) +myerrmsg(clixon_handle h, + const char *fn, + const int line, + enum clixon_log_type type, + int *category, + int *suberr, + cxobj *xerr, + const char *format, + va_list ap, + cbuf **cbmsg) { int retval = -1; - cxobj *x; - - if ((x = xml_find_type(xerr, NULL, "error-type", CX_ELMNT)) != NULL) - cprintf(cberr, "%s ", xml_body(x)); - if ((x = xml_find_type(xerr, NULL, "error-tag", CX_ELMNT)) != NULL) - cprintf(cberr, "%s ", xml_body(x)); - if ((x = xml_find_type(xerr, NULL, "error-message", CX_ELMNT)) != NULL) - cprintf(cberr, "%s ", xml_body(x)); - if ((x = xml_find_type(xerr, NULL, "error-info", CX_ELMNT)) != NULL && - xml_child_nr(x) > 0){ - if (clixon_xml2cbuf(cberr, xml_child_i(x, 0), 0, 0, NULL, -1, 0) < 0) - goto done; + cbuf *cb = NULL; + + if ((cb = cbuf_new()) == NULL){ + fprintf(stderr, "cbuf_new: %s\n", strerror(errno)); /* dont use clixon_err here due to recursion */ + goto done; } - if ((x = xml_find_type(xerr, NULL, "error-app-tag", CX_ELMNT)) != NULL) - cprintf(cberr, ": %s ", xml_body(x)); - if ((x = xml_find_type(xerr, NULL, "error-path", CX_ELMNT)) != NULL) - cprintf(cberr, ": %s ", xml_body(x)); + // XXX Number of args in ap (eg %:s) must be known + // vcprintf(cb, "My new err-string %s : %s", ap); + cprintf(cb, "My new err-string"); + if (category) + *category = -1; + if (suberr) + *suberr = 0; + *cbmsg = cb; retval = 0; done: return retval; } +/*! Example cli function which redirects customized error to myerrmsg above + */ +int +myerror(clixon_handle h, + cvec *cvv, + cvec *argv) +{ + int retval = -1; + cxobj *xret = NULL; + errmsg_t *oldfn = NULL; + + _errmsg_callback_fn = myerrmsg; + if (cli_remove(h, cvv, argv) < 0) + goto done; + retval = 0; + done: + _errmsg_callback_fn = oldfn; + if (xret) + xml_free(xret); + return retval; +} + +/*! Callback to customize log, error, or debug message + * + * @param[in] h Clixon handle + * @param[in] fn Inline function name (when called from clixon_err() macro) + * @param[in] line Inline file line number (when called from clixon_err() macro) + * @param[in] type Log message type + * @param[in,out] category Clixon error category, See enum clixon_err + * @param[in,out] suberr Error number, typically errno + * @param[in] xerr Netconf error xml tree on the form: + * @param[in] format Format string + * @param[in] ap Variable argument list + * @param[out] cbmsg Log string as cbuf, if set bypass ordinary logging + * @retval 0 OK + * @retval -1 Error + * When cbmsg is set by a plugin, no other plugins are called. category and suberr + * can be rewritten by any plugin. + */ +int +example_cli_errmsg(clixon_handle h, + const char *fn, + const int line, + enum clixon_log_type type, + int *category, + int *suberr, + cxobj *xerr, + const char *format, + va_list ap, + cbuf **cbmsg) +{ + if (_errmsg_callback_fn != NULL){ + return (_errmsg_callback_fn)(h, fn, line, type, category, suberr, xerr, format, ap, cbmsg); + } + return 0; +} + /*! Callback for printing version output and exit * * A plugin can customize a version (or banner) output on stdout. @@ -297,7 +375,7 @@ static clixon_plugin_api api = { NULL, /* start */ NULL, /* exit */ .ca_yang_mount= example_cli_yang_mount, /* RFC 8528 schema mount */ - .ca_errmsg = example_cli_errmsg, /* customize errmsg */ + .ca_errmsg = example_cli_errmsg, /* customize log, error, debug message */ .ca_version = example_version /* Customized version string */ }; diff --git a/example/main/example_cli.cli b/example/main/example_cli.cli index 1a049d71..5981fc18 100644 --- a/example/main/example_cli.cli +++ b/example/main/example_cli.cli @@ -157,7 +157,13 @@ load("Load configuration from XML file") ("Filename (local file text("Merge candidate with file containing TEXT"), load_config_file("filename", "merge", "text"); } } -example("This is a comment") ("Just a random number"), mycallback("myarg"); +example("Example callback") { + ("Just a random number"), mycallback("myarg"); + error { + customized, myerror(); # Customized error message + orig, cli_remove(); # Original + } +} rpc("example rpc") ("routing instance"), example_client_rpc(""); notify("Get notifications from backend"), cli_notify("EXAMPLE", "1", "text"); no("Negate") notify("Get notifications from backend"), cli_notify("EXAMPLE", "0", "xml"); diff --git a/lib/clixon/clixon.h.in b/lib/clixon/clixon.h.in index d83575cc..f9329e18 100644 --- a/lib/clixon/clixon.h.in +++ b/lib/clixon/clixon.h.in @@ -71,17 +71,17 @@ extern "C" { #include #include #include +#include +#include #include #include #include #include -#include #include #include #include #include #include -#include #include #include #include diff --git a/lib/clixon/clixon_debug.h b/lib/clixon/clixon_debug.h index e33501d0..b6e19d55 100644 --- a/lib/clixon/clixon_debug.h +++ b/lib/clixon/clixon_debug.h @@ -50,11 +50,17 @@ #define CLIXON_DBG_DETAIL 4 /* Details: traces, parse trees, etc */ #define CLIXON_DBG_EXTRA 8 /* Extra Detailed logs */ +/* + * Macros + */ +#define clixon_debug(l, _fmt, args...) clixon_debug_fn(NULL, (l), NULL, _fmt , ##args) +#define clixon_debug_xml(l, x, _fmt, args...) clixon_debug_fn(NULL, (l), (x), _fmt , ##args) + /* * Prototypes */ -int clixon_debug(int dbglevel, const char *format, ...) __attribute__ ((format (printf, 2, 3))); int clixon_debug_init(clixon_handle h, int dbglevel); int clixon_debug_get(void); +int clixon_debug_fn(clixon_handle h, int dbglevel, cxobj *x, const char *format, ...) __attribute__ ((format (printf, 4, 5))); #endif /* _CLIXON_DEBUG_H_ */ diff --git a/lib/clixon/clixon_err.h b/lib/clixon/clixon_err.h index 92a207d3..8a7c0968 100644 --- a/lib/clixon/clixon_err.h +++ b/lib/clixon/clixon_err.h @@ -94,7 +94,8 @@ typedef int (clixon_cat_log_cb)(void *handle, int suberr, cbuf *cb); /* * Macros */ -#define clixon_err(e,s,_fmt, args...) clixon_err_fn(__FUNCTION__, __LINE__, (e), (s), _fmt , ##args) +#define clixon_err(c,s,_fmt, args...) clixon_err_fn(NULL, __FUNCTION__, __LINE__, (c), (s), NULL, _fmt , ##args) +#define clixon_err_netconf(h,c,s,x,_fmt, args...) clixon_err_fn((h), __FUNCTION__, __LINE__, (c), (s), (x), _fmt , ##args) /* * Prototypes @@ -105,8 +106,8 @@ int clixon_err_subnr(void); char *clixon_err_reason(void); char *clixon_err_str(void); int clixon_err_reset(void); -int clixon_err_args(clixon_handle h, const char *fn, const int line, int category, int suberr, char *msg); -int clixon_err_fn(const char *fn, const int line, int category, int err, const char *format, ...) __attribute__ ((format (printf, 5, 6))); +int clixon_err_fn(clixon_handle h, const char *fn, const int line, int category, int suberr, cxobj *xerr, const char *format, ...) __attribute__ ((format (printf, 7, 8))); +int netconf_err2cb(clixon_handle h, cxobj *xerr, cbuf *cberr); void *clixon_err_save(void); int clixon_err_restore(void *handle); @@ -114,12 +115,16 @@ int clixon_err_cat_reg(enum clixon_err category, void *handle, clixon_cat_log_ int clixon_err_exit(void); #if 1 /* COMPAT_6_5 */ -#define clicon_err(e,s,_fmt, args...) clixon_err_fn(__FUNCTION__, __LINE__, (e), (s), _fmt , ##args) +#define clicon_err(c,s,_fmt, args...) clixon_err_fn(NULL, __FUNCTION__, __LINE__, (c), (s), NULL, _fmt , ##args) #define clicon_err_reset() clixon_err_reset() #define clicon_errno clixon_err_category() #define clicon_suberrno clixon_err_subnr() #define clicon_err_reason clixon_err_reason() + +/* doesnt work if arg != NULL */ +#define clixon_netconf_error(h, x, f, a) clixon_err_fn((h), __FUNCTION__, __LINE__, OE_XML, 0,(x), (f) , NULL) + #endif #endif /* _CLIXON_ERR_H_ */ diff --git a/lib/clixon/clixon_log.h b/lib/clixon/clixon_log.h index 67778314..0bfe7e07 100644 --- a/lib/clixon/clixon_log.h +++ b/lib/clixon/clixon_log.h @@ -49,6 +49,19 @@ #define CLIXON_LOG_STDOUT 4 /* print logs on stdout */ #define CLIXON_LOG_FILE 8 /* print logs on clicon_log_filename */ +/* What kind of log (only for customizable error/logs) */ +enum clixon_log_type{ + LOG_TYPE_LOG, + LOG_TYPE_ERR, + LOG_TYPE_DEBUG +}; + +/* + * Macros + */ +#define clixon_log(h, l, _fmt, args...) clixon_log_fn((h), 1, (l), NULL, _fmt , ##args) +#define clixon_log_xml(h, l, x, _fmt, args...) clixon_log_fn((h), 1, (l), x, _fmt , ##args) + /* * Prototypes */ @@ -60,8 +73,7 @@ int clixon_log_string_limit_set(size_t sz); size_t clixon_log_string_limit_get(void); int clixon_get_logflags(void); int clixon_log_str(int level, char *msg); -int clixon_log(clixon_handle h, int level, const char *format, ...) __attribute__ ((format (printf, 3, 4))); -char *clixon_log_mon2name(int md); +int clixon_log_fn(clixon_handle h, int user, int level, cxobj *x, const char *format, ...) __attribute__ ((format (printf, 5, 6))); #if 1 /* COMPAT_6_5 */ #define CLICON_LOG_SYSLOG CLIXON_LOG_SYSLOG diff --git a/lib/clixon/clixon_netconf_lib.h b/lib/clixon/clixon_netconf_lib.h index 4213acde..d87d11b2 100644 --- a/lib/clixon/clixon_netconf_lib.h +++ b/lib/clixon/clixon_netconf_lib.h @@ -206,16 +206,4 @@ int netconf_output(int s, cbuf *xf, char *msg); int netconf_output_encap(netconf_framing_type framing, cbuf *cb); int netconf_input_chunked_framing(char ch, int *state, size_t *size); -/* Netconf error handling */ -#define clixon_err_netconf(h,c,s,x,_fmt, args...) clixon_err_netconf_fn((h), __FUNCTION__, __LINE__, (c), (s), (x), _fmt , ##args) - -int netconf_err2cb(clixon_handle h, cxobj *xerr, cbuf *cberr); -int clixon_err_netconf_fn(clixon_handle h, const char *fn, const int line, int category, - int suberr, cxobj *xerr, const char *format, ...) __attribute__ ((format (printf, 7, 8)));; - -#if 1 /* COMPAT_6_5 */ -/* doesnt work if arg != NULL */ -#define clixon_netconf_error(h, x, f, a) clixon_err_netconf_fn((h), __FUNCTION__, __LINE__, OE_XML, 0,(x), (f) , NULL) -#endif - #endif /* _CLIXON_NETCONF_LIB_H */ diff --git a/lib/clixon/clixon_plugin.h b/lib/clixon/clixon_plugin.h index 7983d830..8730cf54 100644 --- a/lib/clixon/clixon_plugin.h +++ b/lib/clixon/clixon_plugin.h @@ -314,15 +314,27 @@ typedef int (yang_mount_t)(clixon_handle h, cxobj *xt, int *config, */ typedef int (yang_patch_t)(clixon_handle h, yang_stmt *ymod); -/*! Callback to customize Netconf error message +/*! Callback to customize log, error, or debug message * - * @param[in] h Clixon handle - * @param[in] xerr Netconf error message on the level: - * @param[out] cberr Translation from netconf err to cbuf. - * @retval 0 OK, with cberr set - * @retval -1 Error + * @param[in] h Clixon handle + * @param[in] fn Inline function name (when called from clixon_err() macro) + * @param[in] line Inline file line number (when called from clixon_err() macro) + * @param[in] type Log message type + * @param[in,out] category Clixon error category, See enum clixon_err + * @param[in,out] suberr Error number, typically errno + * @param[in] xerr Netconf error xml tree on the form: + * @param[in] format Format string + * @param[in] ap Variable argument list + * @param[out] cbmsg Log string as cbuf, if set bypass ordinary logging + * @retval 0 OK + * @retval -1 Error + * When cbmsg is set by a plugin, no other plugins are called. category and suberr + * can be rewritten by any plugin. */ -typedef int (netconf_errmsg_t)(clixon_handle, cxobj *xerr, cbuf *cberr); +typedef int (errmsg_t)(clixon_handle h, const char *fn, const int line, + enum clixon_log_type type, + int *category, int *suberr, cxobj *xerr, + const char *format, va_list ap, cbuf **cbmsg); /*! Callback for printing version output and exit * @@ -366,7 +378,7 @@ struct clixon_plugin_api{ plgextension_t *ca_extension; /* Yang extension/unknown handler */ yang_mount_t *ca_yang_mount; /* RFC 8528 schema mount */ yang_patch_t *ca_yang_patch; /* Patch yang after parse */ - netconf_errmsg_t *ca_errmsg; /* Customize error message callback */ + errmsg_t *ca_errmsg; /* Customize log/error/debug callback */ plgversion_t *ca_version; /* Output a customized version message */ union { struct { /* cli-specific */ @@ -497,8 +509,16 @@ int clixon_plugin_yang_mount_all(clixon_handle h, cxobj *xt, int *config, valida int clixon_plugin_yang_patch_one(clixon_plugin_t *cp, clixon_handle h, yang_stmt *ymod); int clixon_plugin_yang_patch_all(clixon_handle h, yang_stmt *ymod); -int clixon_plugin_netconf_errmsg_one(clixon_plugin_t *cp, clixon_handle h, cxobj *xerr, cbuf *cberr); -int clixon_plugin_netconf_errmsg_all(clixon_handle h, cxobj *xerr, cbuf *cberr); +int clixon_plugin_errmsg_one(clixon_plugin_t *cp, clixon_handle h, + const char *fn, const int line, + enum clixon_log_type type, + int *category, int *suberr, cxobj *xerr, + const char *format, va_list ap, cbuf **cbmsg); +int clixon_plugin_errmsg_all(clixon_handle h, + const char *fn, const int line, + enum clixon_log_type type, + int *category, int *suberr, cxobj *xerr, + const char *format, va_list ap, cbuf **cbmsg); int clixon_plugin_version_one(clixon_plugin_t *cp, clixon_handle h, FILE *f); int clixon_plugin_version_all(clixon_handle h, FILE *f); diff --git a/lib/clixon/clixon_xml.h b/lib/clixon/clixon_xml.h index 073afb2d..9fdb3a6b 100644 --- a/lib/clixon/clixon_xml.h +++ b/lib/clixon/clixon_xml.h @@ -307,9 +307,6 @@ int xml_operation(char *opstr, enum operation_type *op); char *xml_operation2str(enum operation_type op); int xml_attr_insert2val(char *instr, enum insert_type *ins); cxobj *xml_add_attr(cxobj *xn, char *name, char *value, char *prefix, char *ns); -int clixon_log_xml(clixon_handle h, int level, cxobj *x, const char *format, ...) __attribute__ ((format (printf, 4, 5))); -int clixon_debug_xml(int dbglevel, cxobj *x, const char *format, ...) __attribute__ ((format (printf, 3, 4))); - #ifdef XML_EXPLICIT_INDEX int xml_search_index_p(cxobj *x); int xml_search_vector_get(cxobj *x, char *name, clixon_xvec **xvec); diff --git a/lib/src/clixon_api_path_parse.l b/lib/src/clixon_api_path_parse.l index 473f915c..d9333f39 100644 --- a/lib/src/clixon_api_path_parse.l +++ b/lib/src/clixon_api_path_parse.l @@ -67,10 +67,10 @@ #include "clixon_hash.h" #include "clixon_handle.h" #include "clixon_yang.h" -#include "clixon_log.h" -#include "clixon_debug.h" #include "clixon_string.h" #include "clixon_xml.h" +#include "clixon_log.h" +#include "clixon_debug.h" #include "clixon_path.h" #include "clixon_api_path_parse.h" diff --git a/lib/src/clixon_api_path_parse.y b/lib/src/clixon_api_path_parse.y index 053128db..52bfcac1 100644 --- a/lib/src/clixon_api_path_parse.y +++ b/lib/src/clixon_api_path_parse.y @@ -108,11 +108,11 @@ #include "clixon_string.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_path.h" #include "clixon_api_path_parse.h" diff --git a/lib/src/clixon_client.c b/lib/src/clixon_client.c index c6c089e3..c74b3a92 100644 --- a/lib/src/clixon_client.c +++ b/lib/src/clixon_client.c @@ -53,13 +53,13 @@ #include "clixon_string.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" +#include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_err.h" -#include "clixon_yang.h" #include "clixon_options.h" #include "clixon_proc.h" -#include "clixon_xml.h" #include "clixon_xml_nsctx.h" #include "clixon_xml_io.h" #include "clixon_xpath_ctx.h" diff --git a/lib/src/clixon_data.c b/lib/src/clixon_data.c index 94f11254..1bfba5c1 100644 --- a/lib/src/clixon_data.c +++ b/lib/src/clixon_data.c @@ -64,11 +64,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_sort.h" #include "clixon_yang_module.h" #include "clixon_options.h" diff --git a/lib/src/clixon_datastore.c b/lib/src/clixon_datastore.c index ec11ba79..7db1d1ba 100644 --- a/lib/src/clixon_datastore.c +++ b/lib/src/clixon_datastore.c @@ -65,13 +65,13 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_string.h" #include "clixon_file.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_yang_module.h" #include "clixon_plugin.h" #include "clixon_options.h" diff --git a/lib/src/clixon_datastore_read.c b/lib/src/clixon_datastore_read.c index 58731f88..780db2a9 100644 --- a/lib/src/clixon_datastore_read.c +++ b/lib/src/clixon_datastore_read.c @@ -60,12 +60,12 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_file.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_sort.h" #include "clixon_xml_bind.h" #include "clixon_options.h" diff --git a/lib/src/clixon_datastore_write.c b/lib/src/clixon_datastore_write.c index 4c77970e..0bbd27d2 100644 --- a/lib/src/clixon_datastore_write.c +++ b/lib/src/clixon_datastore_write.c @@ -60,12 +60,12 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_file.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_sort.h" #include "clixon_options.h" #include "clixon_data.h" diff --git a/lib/src/clixon_debug.c b/lib/src/clixon_debug.c index da152226..41b8e521 100644 --- a/lib/src/clixon_debug.c +++ b/lib/src/clixon_debug.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -60,14 +61,22 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" +#include "clixon_xml_io.h" +#include "clixon_yang_module.h" +#include "clixon_plugin.h" /* * Local Variables */ +/* Cache handle since debug calls do not have handle parameter */ +static clixon_handle _debug_clixon_h = NULL; + /*! The global debug level. 0 means no debug * * @note There are pros and cons in having the debug state as a global variable. The @@ -96,6 +105,7 @@ int clixon_debug_init(clixon_handle h, int dbglevel) { + _debug_clixon_h = h; _debug_level = dbglevel; /* Global variable */ return 0; } @@ -110,56 +120,65 @@ clixon_debug_get(void) /*! Print a debug message with debug-level. Settings determine where msg appears. * + * Do not use this fn directly, use the clixon_debug() macro * If the dbglevel passed in the function is equal to or lower than the one set by * clixon_debug_init(level). That is, only print debug messages <= than what you want: * print message if level >= dbglevel. * The message is sent to clixon_log. EIther to syslog, stderr or both, depending on * clixon_log_init() setting + * @param[in] h Clixon handle * @param[in] dbglevel Mask of CLIXON_DBG_DEFAULT and other masks + * @param[in] x XML tree logged without prettyprint * @param[in] format Message to print as argv. * @retval 0 OK * @retval -1 Error - * @see clixon_debug_xml Specialization for XML tree * @see CLIXON_DBG_DEFAULT and other flags */ int -clixon_debug(int dbglevel, - const char *format, ...) +clixon_debug_fn(clixon_handle h, + int dbglevel, + cxobj *x, + const char *format, ...) { int retval = -1; - va_list args; - size_t len; - char *msg = NULL; + va_list ap; size_t trunc; + cbuf *cb = NULL; /* Mask debug level with global dbg variable */ if ((dbglevel & clixon_debug_get()) == 0) return 0; - /* first round: compute length of debug message */ - va_start(args, format); - len = vsnprintf(NULL, 0, format, args); - va_end(args); - + if (h == NULL) /* Accept NULL, use saved clixon handle */ + h = _debug_clixon_h; + va_start(ap, format); + if (clixon_plugin_errmsg_all(h, NULL, 0, LOG_TYPE_DEBUG, + NULL, NULL, x, format, ap, &cb) < 0) + goto done; + va_end(ap); + if (cb != NULL){ /* Customized: expand clixon_err_args */ + clixon_log_str(LOG_DEBUG, cbuf_get(cb)); + goto ok; + } + if ((cb = cbuf_new()) == NULL){ + fprintf(stderr, "cbuf_new: %s\n", strerror(errno)); + goto done; + } + va_start(ap, format); + vcprintf(cb, format, ap); + va_end(ap); + if (x){ + cprintf(cb, ": "); + if (clixon_xml2cbuf(cb, x, 0, 0, NULL, -1, 0) < 0) + goto done; + } /* Truncate long debug strings */ - if ((trunc = clixon_log_string_limit_get()) && trunc < len) - len = trunc; - /* allocate a message string exactly fitting the message length */ - if ((msg = malloc(len+1)) == NULL){ - clixon_err(OE_UNIX, errno, "malloc"); - goto done; - } - /* second round: compute write message from format and args */ - va_start(args, format); - if (vsnprintf(msg, len+1, format, args) < 0){ - va_end(args); - clixon_err(OE_UNIX, errno, "vsnprintf"); - goto done; - } - va_end(args); - clixon_log_str(LOG_DEBUG, msg); + if ((trunc = clixon_log_string_limit_get()) && trunc < cbuf_len(cb)) + cbuf_trunc(cb, trunc); + clixon_log_str(LOG_DEBUG, cbuf_get(cb)); + ok: retval = 0; - done: - if (msg) - free(msg); + done: + if (cb) + cbuf_free(cb); return retval; } diff --git a/lib/src/clixon_err.c b/lib/src/clixon_err.c index 5610024b..30aa7c79 100644 --- a/lib/src/clixon_err.c +++ b/lib/src/clixon_err.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -62,9 +63,14 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_err.h" +#include "clixon_xml_io.h" +#include "clixon_yang_module.h" +#include "clixon_plugin.h" /* * Types @@ -258,7 +264,7 @@ find_category(int category) * @retval -1 Error * @see clixon_err_fn for a variable-argument variant */ -int +static int clixon_err_args(clixon_handle h, const char *fn, const int line, @@ -272,7 +278,7 @@ clixon_err_args(clixon_handle h, /* Set the global variables */ strncpy(_err_reason, msg, ERR_STRLEN-1); - _err_category = category; + _err_category = category; _err_subnr = suberr; /* Check category callbacks as defined in clixon_err_cat_reg */ if ((cec = find_category(category)) != NULL && @@ -285,14 +291,14 @@ clixon_err_args(clixon_handle h, goto done; /* Here we could take care of specific errno, like application-defined errors */ if (fn) - clixon_log(h, LOG_ERR, "%s: %d: %s: %s: %s", + clixon_log_fn(h, 0, LOG_ERR, NULL, "%s: %d: %s: %s: %s", fn, line, clixon_strerror1(category, EV), cbuf_get(cb), msg); else - clixon_log(h, LOG_ERR, "%s: %s: %s", + clixon_log_fn(h, 0, LOG_ERR, NULL, "%s: %s: %s", clixon_strerror1(category, EV), cbuf_get(cb), msg); @@ -300,27 +306,27 @@ clixon_err_args(clixon_handle h, else if (suberr){ /* Actually log it */ /* Here we could take care of specific errno, like application-defined errors */ if (fn) - clixon_log(h, LOG_ERR, "%s: %d: %s: %s: %s", - fn, - line, - clixon_strerror1(category, EV), - msg, - suberr==XMLPARSE_ERRNO?"XML parse error":strerror(suberr)); + clixon_log_fn(h, 0, LOG_ERR, NULL, "%s: %d: %s: %s: %s", + fn, + line, + clixon_strerror1(category, EV), + msg, + suberr==XMLPARSE_ERRNO?"XML parse error":strerror(suberr)); else - clixon_log(h, LOG_ERR, "%s: %s: %s", + clixon_log_fn(h, 0, LOG_ERR, NULL, "%s: %s: %s", clixon_strerror1(category, EV), msg, suberr==XMLPARSE_ERRNO?"XML parse error":strerror(suberr)); } else{ if (fn) - clixon_log(h, LOG_ERR, "%s: %d: %s: %s", + clixon_log_fn(h, 0, LOG_ERR, NULL, "%s: %d: %s: %s", fn, line, clixon_strerror1(category, EV), msg); else - clixon_log(h, LOG_ERR, "%s: %s", + clixon_log_fn(h, 0, LOG_ERR, NULL, "%s: %s", clixon_strerror1(category, EV), msg); } @@ -331,8 +337,55 @@ clixon_err_args(clixon_handle h, return retval; } +/*! Generate netconf error msg to cbuf using callback to use in string printout or logs + * + * If no callback is registered, a default error message is genereated + * @param[in] xerr Netconf error message on the level: + * @param[out] cberr Translation from netconf err to cbuf. + * @retval 0 OK, with cberr set + * @retval -1 Error + * @code + * cbuf *cb = NULL; + * if ((cb = cbuf_new()) ==NULL){ + * err; + * if (netconf_err2cb(h, xerr, cb) < 0) + * err; + * printf("%s", cbuf_get(cb)); + * cbuf_free(cb); + * @endcode + * @see clixon_err_netconf_fn + */ +int +netconf_err2cb(clixon_handle h, + cxobj *xerr, + cbuf *cberr) +{ + int retval = -1; + cxobj *x; + + if ((x = xml_find_type(xerr, NULL, "error-type", CX_ELMNT)) != NULL) + cprintf(cberr, "%s ", xml_body(x)); + if ((x = xml_find_type(xerr, NULL, "error-tag", CX_ELMNT)) != NULL) + cprintf(cberr, "%s ", xml_body(x)); + if ((x = xml_find_type(xerr, NULL, "error-message", CX_ELMNT)) != NULL) + cprintf(cberr, "%s ", xml_body(x)); + if ((x = xml_find_type(xerr, NULL, "error-info", CX_ELMNT)) != NULL && + xml_child_nr(x) > 0){ + if (clixon_xml2cbuf(cberr, xml_child_i(x, 0), 0, 0, NULL, -1, 0) < 0) + goto done; + } + if ((x = xml_find_type(xerr, NULL, "error-app-tag", CX_ELMNT)) != NULL) + cprintf(cberr, ": %s ", xml_body(x)); + if ((x = xml_find_type(xerr, NULL, "error-path", CX_ELMNT)) != NULL) + cprintf(cberr, ": %s ", xml_body(x)); + retval = 0; + done: + return retval; +} + /*! Report an error. * + * Do not use this fn directly, use the clixon_err() macro * Library routines should call this function when an error occurs. * The function does he following: * - Logs to syslog with LOG_ERR @@ -351,46 +404,71 @@ clixon_err_args(clixon_handle h, * @param[in] line Inline file line number (when called from clixon_err() macro) * @param[in] category Clixon error category, See enum clixon_err * @param[in] suberr Error number, typically errno + * @param[in] xerr Optional netconf error xml tree on the form: [rpc-reply/]rpc-error * @param[in] format Error string, format with argv * @retval 0 OK * @retval -1 Error - * @see clixon_err_netconf For variant with netconf error message + * @see clixon_err_netconf_fn For variant with netconf error message */ int -clixon_err_fn(const char *fn, - const int line, - int category, - int suberr, - const char *format, ...) +clixon_err_fn(clixon_handle h, + const char *fn, + const int line, + int category, + int suberr, + cxobj *xerr, + const char *format, ...) { - int retval = -1; - va_list args; - int len; - char *msg = NULL; + int retval = -1; + va_list ap; + cbuf *cb = NULL; - /* first round: compute length of error message */ - va_start(args, format); - len = vsnprintf(NULL, 0, format, args); - va_end(args); - /* allocate a message string exactly fitting the message length */ - if ((msg = malloc(len+1)) == NULL){ - fprintf(stderr, "malloc: %s\n", strerror(errno)); /* dont use clixon_err here due to recursion */ + if (h == NULL) /* Accept NULL, use saved clixon handle */ + h = _err_clixon_h; + if (xerr){ + /* Accept xml errors on formats: + * , + * + */ + if (strcmp(xml_name(xerr), "rpc-reply") == 0) + xerr = xml_find_type(xerr, NULL, "rpc-error", CX_ELMNT); + if (strcmp(xml_name(xerr), "rpc-error") != 0){ + errno = EINVAL; + goto done; + } + } + va_start(ap, format); + if (clixon_plugin_errmsg_all(h, fn, line, LOG_TYPE_ERR, + &category, &suberr, xerr, format, ap, &cb) < 0) + goto done; + va_end(ap); + if (cb != NULL){ /* Customized: expand clixon_err_args */ + strncpy(_err_reason, cbuf_get(cb), ERR_STRLEN-1); + _err_category = category; + _err_subnr = suberr; + clixon_log_fn(h, 0, LOG_ERR, xerr, "%s", cbuf_get(cb)); + goto ok; + } + if ((cb = cbuf_new()) == NULL){ + fprintf(stderr, "cbuf_new: %s\n", strerror(errno)); goto done; } - /* second round: compute write message from format and args */ - va_start(args, format); - if (vsnprintf(msg, len+1, format, args) < 0){ - va_end(args); - fprintf(stderr, "vsnprintf: %s\n", strerror(errno)); /* dont use clixon_err here due to recursion */ - goto done; + va_start(ap, format); + vcprintf(cb, format, ap); + va_end(ap); + if (xerr) { + cprintf(cb, ": "); + /* Translate netconf error to string */ + if (netconf_err2cb(h, xerr, cb) < 0) + goto done; } - va_end(args); - if (clixon_err_args(_err_clixon_h, fn, line, category, suberr, msg) < 0) + if (clixon_err_args(h, fn, line, category, suberr, cbuf_get(cb)) < 0) goto done; + ok: retval = 0; done: - if (msg) - free(msg); + if (cb) + cbuf_free(cb); return retval; } diff --git a/lib/src/clixon_event.c b/lib/src/clixon_event.c index 8c6cbba7..a1eca051 100644 --- a/lib/src/clixon_event.c +++ b/lib/src/clixon_event.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -58,6 +59,8 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_err.h" diff --git a/lib/src/clixon_file.c b/lib/src/clixon_file.c index 41b2e693..91122cf7 100644 --- a/lib/src/clixon_file.c +++ b/lib/src/clixon_file.c @@ -60,6 +60,8 @@ #include "clixon_hash.h" #include "clixon_handle.h" #include "clixon_string.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" diff --git a/lib/src/clixon_handle.c b/lib/src/clixon_handle.c index e7703dad..72045085 100644 --- a/lib/src/clixon_handle.c +++ b/lib/src/clixon_handle.c @@ -53,11 +53,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" -#include "clixon_log.h" -#include "clixon_debug.h" -#include "clixon_err.h" #include "clixon_yang.h" #include "clixon_xml.h" +#include "clixon_err.h" +#include "clixon_log.h" +#include "clixon_debug.h" #include "clixon_stream.h" #include "clixon_data.h" #include "clixon_options.h" diff --git a/lib/src/clixon_hash.c b/lib/src/clixon_hash.c index 0805a3b3..eba99f13 100644 --- a/lib/src/clixon_hash.c +++ b/lib/src/clixon_hash.c @@ -97,6 +97,8 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #define HASH_SIZE 1031 /* Number of hash buckets. Should be a prime */ diff --git a/lib/src/clixon_instance_id_parse.l b/lib/src/clixon_instance_id_parse.l index 6a1e72a6..f669d692 100644 --- a/lib/src/clixon_instance_id_parse.l +++ b/lib/src/clixon_instance_id_parse.l @@ -64,10 +64,10 @@ #include "clixon_hash.h" #include "clixon_handle.h" #include "clixon_yang.h" -#include "clixon_log.h" -#include "clixon_debug.h" #include "clixon_string.h" #include "clixon_xml.h" +#include "clixon_log.h" +#include "clixon_debug.h" #include "clixon_path.h" #include "clixon_instance_id_parse.h" diff --git a/lib/src/clixon_instance_id_parse.y b/lib/src/clixon_instance_id_parse.y index 4e8e7c46..ff5792a5 100644 --- a/lib/src/clixon_instance_id_parse.y +++ b/lib/src/clixon_instance_id_parse.y @@ -119,11 +119,11 @@ #include "clixon_string.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_path.h" #include "clixon_instance_id_parse.h" diff --git a/lib/src/clixon_json.c b/lib/src/clixon_json.c index 7b5770e6..716b2761 100644 --- a/lib/src/clixon_json.c +++ b/lib/src/clixon_json.c @@ -62,12 +62,12 @@ #include "clixon_string.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_options.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_yang_type.h" #include "clixon_yang_module.h" #include "clixon_xml_sort.h" diff --git a/lib/src/clixon_json_parse.l b/lib/src/clixon_json_parse.l index 15d73d1d..2af66130 100644 --- a/lib/src/clixon_json_parse.l +++ b/lib/src/clixon_json_parse.l @@ -45,6 +45,7 @@ #include #include #include +#include #include #include "clixon_json_parse.tab.h" /* generated */ @@ -56,9 +57,9 @@ #include "clixon_handle.h" #include "clixon_string.h" #include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_xml.h" #include "clixon_json_parse.h" /* Redefine main lex function so that you can send arguments to it: _yy is added to arg list */ diff --git a/lib/src/clixon_json_parse.y b/lib/src/clixon_json_parse.y index 344202d2..97c77604 100644 --- a/lib/src/clixon_json_parse.y +++ b/lib/src/clixon_json_parse.y @@ -128,12 +128,12 @@ object. #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_string.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_json_parse.h" diff --git a/lib/src/clixon_log.c b/lib/src/clixon_log.c index b9c57710..ace8046d 100644 --- a/lib/src/clixon_log.c +++ b/lib/src/clixon_log.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -60,9 +61,14 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_debug.h" #include "clixon_log.h" +#include "clixon_xml_io.h" +#include "clixon_yang_module.h" +#include "clixon_plugin.h" /* * Local Variables @@ -320,58 +326,68 @@ clixon_log_str(int level, /*! Make a logging call to syslog using variable arg syntax. * - * @param[in] h Clixon handle (may be NULL) - * @param[in] level Log level, eg LOG_DEBUG,LOG_INFO,...,LOG_EMERG. This - * is OR:d with facility == LOG_USER - * @param[in] format Message to print as argv. - * @retval 0 OK - * @retval -1 Error + * Do not use this fn directly, use the clixon_log() macro + * @param[in] h Clixon handle (may be NULL) + * @param[in] user If set, invoke user callback + * @param[in] level Log level, eg LOG_DEBUG,LOG_INFO,...,LOG_EMERG. This + * is OR:d with facility == LOG_USER + * @param[in] x XML tree that is logged without prettyprint + * @param[in] format Message to print as argv. + * @retval 0 OK + * @retval -1 Error * @code clixon_log(h, LOG_NOTICE, "%s: dump to dtd not supported", __PROGRAM__); * @endcode * @see clixon_log_init clixon_log_str - * @see clixon_log_xml + * The reason the "user" parameter is present is that internal calls (eg from clixon_err) may not + * want to invoke user callbacks a second time. */ int -clixon_log(clixon_handle h, - int level, - const char *format, ...) +clixon_log_fn(clixon_handle h, + int user, + int level, + cxobj *x, + const char *format, ...) { int retval = -1; - va_list args; - size_t len; - char *msg = NULL; + va_list ap; size_t trunc; + cbuf *cb = NULL; - /* first round: compute length of debug message */ - va_start(args, format); - len = vsnprintf(NULL, 0, format, args); - va_end(args); - + if (h == NULL) /* Accept NULL, use saved clixon handle */ + h = _log_clixon_h; + if (user){ + va_start(ap, format); + if (clixon_plugin_errmsg_all(h, NULL, 0, LOG_TYPE_LOG, + NULL, NULL, x, format, ap, &cb) < 0) + goto done; + va_end(ap); + if (cb != NULL){ /* Customized: expand clixon_err_args */ + clixon_log(h, LOG_ERR, "%s", cbuf_get(cb)); + goto ok; + } + } + if ((cb = cbuf_new()) == NULL){ + fprintf(stderr, "cbuf_new: %s\n", strerror(errno)); + goto done; + } + va_start(ap, format); + vcprintf(cb, format, ap); + va_end(ap); + if (x){ + cprintf(cb, ": "); + if (clixon_xml2cbuf(cb, x, 0, 0, NULL, -1, 0) < 0) + goto done; + } /* Truncate long debug strings */ - if ((trunc = clixon_log_string_limit_get()) && trunc < len) - len = trunc; - - /* allocate a message string exactly fitting the message length */ - if ((msg = malloc(len+1)) == NULL){ - fprintf(stderr, "malloc: %s\n", strerror(errno)); /* dont use clixon_err here due to recursion */ - goto done; - } - - /* second round: compute write message from format and args */ - va_start(args, format); - if (vsnprintf(msg, len+1, format, args) < 0){ - va_end(args); - fprintf(stderr, "vsnprintf: %s\n", strerror(errno)); /* dont use clixon_err here due to recursion */ - goto done; - } - va_end(args); + if ((trunc = clixon_log_string_limit_get()) && trunc < cbuf_len(cb)) + cbuf_trunc(cb, trunc); /* Actually log it */ - clixon_log_str(level, msg); - + clixon_log_str(level, cbuf_get(cb)); + ok: retval = 0; - done: - if (msg) - free(msg); + done: + if (cb) + cbuf_free(cb); return retval; } diff --git a/lib/src/clixon_nacm.c b/lib/src/clixon_nacm.c index 9555c6f2..1cbe9604 100644 --- a/lib/src/clixon_nacm.c +++ b/lib/src/clixon_nacm.c @@ -58,11 +58,11 @@ #include "clixon_hash.h" #include "clixon_string.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_options.h" #include "clixon_data.h" #include "clixon_netconf_lib.h" diff --git a/lib/src/clixon_netconf_input.c b/lib/src/clixon_netconf_input.c index 61ce9900..88d67c6a 100644 --- a/lib/src/clixon_netconf_input.c +++ b/lib/src/clixon_netconf_input.c @@ -66,11 +66,11 @@ #include "clixon_hash.h" #include "clixon_string.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_io.h" #include "clixon_proto.h" #include "clixon_netconf_lib.h" diff --git a/lib/src/clixon_netconf_lib.c b/lib/src/clixon_netconf_lib.c index c1110243..a829242c 100644 --- a/lib/src/clixon_netconf_lib.c +++ b/lib/src/clixon_netconf_lib.c @@ -60,11 +60,11 @@ #include "clixon_hash.h" #include "clixon_string.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_options.h" #include "clixon_data.h" #include "clixon_xml_bind.h" @@ -2337,126 +2337,3 @@ netconf_input_chunked_framing(char ch, retval = -1; /* Error */ goto done; } - -/*! Generate netconf error msg to cbuf using callback to use in string printout or logs - * - * If no callback is registered, a default error message is genereated - * @param[in] xerr Netconf error message on the level: - * @param[out] cberr Translation from netconf err to cbuf. - * @retval 0 OK, with cberr set - * @retval -1 Error - * @code - * cbuf *cb = NULL; - * if ((cb = cbuf_new()) ==NULL){ - * err; - * if (netconf_err2cb(h, xerr, cb) < 0) - * err; - * printf("%s", cbuf_get(cb)); - * cbuf_free(cb); - * @endcode - * @see clixon_err_netconf_fn - */ -int -netconf_err2cb(clixon_handle h, - cxobj *xerr, - cbuf *cberr) -{ - int retval = -1; - cxobj *x; - size_t len; - - // XXX: some calls are , change calls instead - if (strcmp(xml_name(xerr), "rpc-error") != 0) - xerr = xml_child_i_type(xerr, 0, CX_ELMNT); - len = cbuf_len(cberr); - if (clixon_plugin_netconf_errmsg_all(h, xerr, cberr) < 0) - goto done; - if (cbuf_len(cberr) == len){ /* Same as on-entry, use default */ - if ((x=xpath_first(xerr, NULL, "//error-type"))!=NULL) - cprintf(cberr, "%s ", xml_body(x)); - if ((x=xpath_first(xerr, NULL, "//error-tag"))!=NULL) - cprintf(cberr, "%s ", xml_body(x)); - if ((x=xpath_first(xerr, NULL, "//error-message"))!=NULL) - cprintf(cberr, "%s ", xml_body(x)); - if ((x=xpath_first(xerr, NULL, "//error-info")) != NULL && - xml_child_nr(x) > 0){ - if (clixon_xml2cbuf(cberr, xml_child_i(x, 0), 0, 0, NULL, -1, 0) < 0) - goto done; - } - if ((x=xpath_first(xerr, NULL, "//error-app-tag"))!=NULL) - cprintf(cberr, ": %s ", xml_body(x)); - if ((x=xpath_first(xerr, NULL, "//error-path"))!=NULL) - cprintf(cberr, ": %s ", xml_body(x)); - } - retval = 0; - done: - return retval; -} - -/*! Generate and print textual error log from Netconf error message - * - * Get a text error message from netconf error message and generate error logmsg: - * : "": or : - * - * @param[in] h Clixon handle - * @param[in] fn Inline function name (when called from clixon_err() macro) - * @param[in] line Inline file line number (when called from clixon_err() macro) - * @param[in] xerr Netconf error xml tree on the form: - * @param[in] format Format string - * @param[in] arg String argument to format (optional) - * @retval 0 OK - * @retval -1 Error - * @see netconf_err2cb - * @see clixon_err_netconf macro - */ -int -clixon_err_netconf_fn(clixon_handle h, - const char *fn, - const int line, - int category, - int suberr, - cxobj *xerr, - const char *format, ...) -{ - int retval = -1; - va_list args; - int len; - char *msg = NULL; - cbuf *cb = NULL; - - /* first round: compute length of error message */ - va_start(args, format); - len = vsnprintf(NULL, 0, format, args); - va_end(args); - - /* allocate a message string exactly fitting the message length */ - if ((msg = malloc(len+1)) == NULL){ - fprintf(stderr, "malloc: %s\n", strerror(errno)); /* dont use clixon_err here due to recursion */ - goto done; - } - /* second round: compute write message from format and args */ - va_start(args, format); - if (vsnprintf(msg, len+1, format, args) < 0){ - va_end(args); - fprintf(stderr, "vsnprintf: %s\n", strerror(errno)); /* dont use clixon_err here due to recursion */ - goto done; - } - va_end(args); - if ((cb = cbuf_new()) == NULL){ - clixon_err(OE_XML, errno, "cbuf_new"); - goto done; - } - cprintf(cb, "%s: ", msg); - /* Translate netconf error to string */ - if (netconf_err2cb(h, xerr, cb) < 0) - goto done; - if (clixon_err_args(h, fn, line, category, suberr, cbuf_get(cb)) < 0) - goto done; - retval = 0; - done: - if (msg) - free(msg); - if (cb) - cbuf_free(cb); - return retval; -} diff --git a/lib/src/clixon_netconf_monitoring.c b/lib/src/clixon_netconf_monitoring.c index cf6664a5..cbb49876 100644 --- a/lib/src/clixon_netconf_monitoring.c +++ b/lib/src/clixon_netconf_monitoring.c @@ -55,11 +55,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_yang_module.h" #include "clixon_xml_io.h" #include "clixon_netconf_lib.h" diff --git a/lib/src/clixon_netns.c b/lib/src/clixon_netns.c index 1eb17fae..e42ddcea 100644 --- a/lib/src/clixon_netns.c +++ b/lib/src/clixon_netns.c @@ -44,6 +44,8 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" diff --git a/lib/src/clixon_options.c b/lib/src/clixon_options.c index de304782..f3082409 100644 --- a/lib/src/clixon_options.c +++ b/lib/src/clixon_options.c @@ -66,13 +66,13 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_string.h" #include "clixon_file.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_sort.h" #include "clixon_json.h" #include "clixon_text_syntax.h" diff --git a/lib/src/clixon_path.c b/lib/src/clixon_path.c index 9bc8b16b..5e913e23 100644 --- a/lib/src/clixon_path.c +++ b/lib/src/clixon_path.c @@ -88,12 +88,12 @@ #include "clixon_hash.h" #include "clixon_handle.h" #include "clixon_string.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_options.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_nsctx.h" #include "clixon_xml_vec.h" #include "clixon_xml_sort.h" @@ -1215,7 +1215,7 @@ api_path2xml_vec(char **vec, * @param[in] strict Break if api-path is not "complete" otherwise ignore and continue * @param[out] xbotp Resulting xml tree (end of xpath) (optional) * @param[out] ybotp Yang spec matching xbotp - * @param[out] xerr Netconf error message (if retval=0) + * @param[out] xerr Netconf error message as rpc-reply/rpc-error (if retval=0) * @retval 1 OK * @retval 0 Invalid api_path or associated XML, netconf error * @retval -1 Fatal error diff --git a/lib/src/clixon_plugin.c b/lib/src/clixon_plugin.c index 49bc96aa..7f2e06c9 100644 --- a/lib/src/clixon_plugin.c +++ b/lib/src/clixon_plugin.c @@ -59,13 +59,13 @@ #include "clixon_string.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_file.h" -#include "clixon_yang.h" #include "clixon_options.h" -#include "clixon_xml.h" #include "clixon_xml_nsctx.h" #include "clixon_xml_map.h" #include "clixon_yang_module.h" @@ -797,7 +797,6 @@ clixon_plugin_datastore_upgrade_one(clixon_plugin_t *cp, const char *db, cxobj *xt, modstate_diff_t *msd) - { int retval = -1; datastore_upgrade_t *fn; @@ -985,32 +984,47 @@ clixon_plugin_yang_patch_all(clixon_handle h, return retval; } -/*! Callback plugin to customize Netconf error message +/*! Call plugin to customize log, error, or debug message * - * @param[in] cp Plugin handle - * @param[in] h Clixon handle - * @param[in] xerr Netconf error message on the level: - * @param[out] cberr Translation from netconf err to cbuf. - * @retval 0 OK - * @retval -1 Error + * The plugin creates cbmsg as a positive result, it may also modify category and suberr + * @param[in] cp Plugin handle + * @param[in] h Clixon handle + * @param[in] fn Inline function name (when called from clixon_err() macro) + * @param[in] line Inline file line number (when called from clixon_err() macro) + * @param[in] type Log message type + * @param[in,out] category Clixon error category, See enum clixon_err + * @param[in,out] suberr Error number, typically errno + * @param[in] xerr Netconf error xml tree on the form: + * @param[in] format Format string + * @param[in] ap Variable argument list + * @param[out] cbmsg Log string as cbuf, if set bypass ordinary logging + * @retval 0 OK + * @retval -1 Error */ int -clixon_plugin_netconf_errmsg_one(clixon_plugin_t *cp, - clixon_handle h, - cxobj *xerr, - cbuf *cberr) +clixon_plugin_errmsg_one(clixon_plugin_t *cp, + clixon_handle h, + const char *fn0, + const int line, + enum clixon_log_type type, + int *category, + int *suberr, + cxobj *xerr, + const char *format, + va_list ap, + cbuf **cbmsg) { - int retval = -1; - netconf_errmsg_t *fn; - void *wh = NULL; + int retval = -1; + errmsg_t *fn; + void *wh = NULL; if ((fn = cp->cp_api.ca_errmsg) != NULL){ wh = NULL; if (clixon_resource_check(h, &wh, cp->cp_name, __FUNCTION__) < 0) goto done; - if (fn(h, xerr, cberr) < 0) { + if (fn(h, fn0, line, type, category, suberr, xerr, format, ap, cbmsg) < 0) { if (clixon_err_category() < 0) - clixon_log(h, LOG_WARNING, "%s: Internal error: Netconf err callback in plugin: %s returned -1 but did not make a clixon_err call", + clixon_log(h, LOG_WARNING, "%s: Internal error: Logmsg callback in plugin: %s returned -1 but did not make a clixon_err call", __FUNCTION__, cp->cp_name); clixon_resource_check(h, &wh, cp->cp_name, __FUNCTION__); goto done; @@ -1023,25 +1037,44 @@ clixon_plugin_netconf_errmsg_one(clixon_plugin_t *cp, return retval; } -/*! Call plugin customize Netconf error message +/*! Call plugin to customize log, error, or debug message * - * @param[in] h Clixon handle - * @param[in] xerr Netconf error message on the level: - * @param[out] cberr Translation from netconf err to cbuf. - * @retval 0 OK - * @retval -1 Error + * @param[in] h Clixon handle + * @param[in] fn Inline function name (when called from clixon_err() macro) + * @param[in] line Inline file line number (when called from clixon_err() macro) + * @param[in] type Log message type + * @param[in,out] category Clixon error category, See enum clixon_err + * @param[in,out] suberr Error number, typically errno + * @param[in] xerr Netconf error xml tree on the form: + * @param[in] format Format string + * @param[in] ap Variable argument list + * @param[out] cbmsg Log string as cbuf, if set bypass ordinary logging + * @retval 0 OK + * @retval -1 Error */ int -clixon_plugin_netconf_errmsg_all(clixon_handle h, - cxobj *xerr, - cbuf *cberr) +clixon_plugin_errmsg_all(clixon_handle h, + const char *fn, + const int line, + enum clixon_log_type type, + int *category, + int *suberr, + cxobj *xerr, + const char *format, + va_list ap, + cbuf **cbmsg) { - int retval = -1; + int retval = -1; clixon_plugin_t *cp = NULL; - while ((cp = clixon_plugin_each(h, cp)) != NULL) { - if (clixon_plugin_netconf_errmsg_one(cp, h, xerr, cberr) < 0) - goto done; + if (h != NULL){ /* Silently ignore if not properly init:d */ + *cbmsg = NULL; + while ((cp = clixon_plugin_each(h, cp)) != NULL) { + if (clixon_plugin_errmsg_one(cp, h, fn, line, type, category, suberr, xerr, format, ap, cbmsg) < 0) + goto done; + if (*cbmsg != NULL) + break; + } } retval = 0; done: diff --git a/lib/src/clixon_proc.c b/lib/src/clixon_proc.c index c5fbccc9..297a0785 100644 --- a/lib/src/clixon_proc.c +++ b/lib/src/clixon_proc.c @@ -115,6 +115,8 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" @@ -124,8 +126,6 @@ #include "clixon_sig.h" #include "clixon_string.h" #include "clixon_queue.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_netconf_lib.h" #include "clixon_proc.h" diff --git a/lib/src/clixon_proto.c b/lib/src/clixon_proto.c index 788333f1..2c0a67f5 100644 --- a/lib/src/clixon_proto.c +++ b/lib/src/clixon_proto.c @@ -69,12 +69,12 @@ #include "clixon_hash.h" #include "clixon_handle.h" #include "clixon_event.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" #include "clixon_sig.h" -#include "clixon_xml.h" #include "clixon_xml_io.h" #include "clixon_netconf_lib.h" #include "clixon_options.h" diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c index eccdccbd..29fafba4 100644 --- a/lib/src/clixon_proto_client.c +++ b/lib/src/clixon_proto_client.c @@ -61,11 +61,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_options.h" #include "clixon_data.h" #include "clixon_yang_module.h" @@ -1441,7 +1441,7 @@ clicon_rpc_validate(clixon_handle h, goto done; if (clicon_rpc_msg(h, msg, &xret) < 0) goto done; - if ((xerr = xpath_first(xret, NULL, "//rpc-error")) != NULL){ + if ((xerr = xpath_first(xret, NULL, "rpc-reply/rpc-error")) != NULL){ clixon_err_netconf(h, OE_NETCONF, 0, xerr, CLIXON_ERRSTR_VALIDATE_FAILED); retval = 0; goto done; diff --git a/lib/src/clixon_regex.c b/lib/src/clixon_regex.c index df169e27..4545a3b8 100644 --- a/lib/src/clixon_regex.c +++ b/lib/src/clixon_regex.c @@ -59,10 +59,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" #include "clixon_options.h" #include "clixon_regex.h" diff --git a/lib/src/clixon_sig.c b/lib/src/clixon_sig.c index ce8cdc79..a2faa7ae 100644 --- a/lib/src/clixon_sig.c +++ b/lib/src/clixon_sig.c @@ -55,6 +55,8 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" diff --git a/lib/src/clixon_stream.c b/lib/src/clixon_stream.c index b44aa1b8..0c2d76bf 100644 --- a/lib/src/clixon_stream.c +++ b/lib/src/clixon_stream.c @@ -74,12 +74,12 @@ #include "clixon_string.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_event.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_io.h" #include "clixon_netconf_lib.h" #include "clixon_options.h" diff --git a/lib/src/clixon_string.c b/lib/src/clixon_string.c index a6fb5668..14d72fc6 100644 --- a/lib/src/clixon_string.c +++ b/lib/src/clixon_string.c @@ -52,6 +52,8 @@ #include "clixon_hash.h" #include "clixon_handle.h" #include "clixon_string.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" /*! Split string into a vector based on character delimiters. Using malloc diff --git a/lib/src/clixon_text_syntax.c b/lib/src/clixon_text_syntax.c index fd4ce936..8f8b7a13 100644 --- a/lib/src/clixon_text_syntax.c +++ b/lib/src/clixon_text_syntax.c @@ -56,12 +56,12 @@ #include "clixon_string.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_options.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_io.h" #include "clixon_xml_sort.h" #include "clixon_xml_nsctx.h" diff --git a/lib/src/clixon_text_syntax_parse.y b/lib/src/clixon_text_syntax_parse.y index f0e9e70a..e7dcf08b 100644 --- a/lib/src/clixon_text_syntax_parse.y +++ b/lib/src/clixon_text_syntax_parse.y @@ -73,12 +73,12 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_string.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_nsctx.h" #include "clixon_xml_vec.h" #include "clixon_data.h" diff --git a/lib/src/clixon_uid.c b/lib/src/clixon_uid.c index 27b5835a..7cc8ed28 100644 --- a/lib/src/clixon_uid.c +++ b/lib/src/clixon_uid.c @@ -62,6 +62,8 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" diff --git a/lib/src/clixon_validate.c b/lib/src/clixon_validate.c index 9bbaee83..9bc18e90 100644 --- a/lib/src/clixon_validate.c +++ b/lib/src/clixon_validate.c @@ -61,11 +61,11 @@ #include "clixon_hash.h" #include "clixon_handle.h" #include "clixon_string.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_data.h" #include "clixon_netconf_lib.h" #include "clixon_options.h" @@ -985,7 +985,7 @@ check_mandatory(cxobj *xt, * 1. Check if mandatory leafs present as subs. * 2. Check leaf values, eg int ranges and string regexps. * @param[in] xt XML node to be validated - * @param[out] xret Error XML tree. Free with xml_free after use + * @param[out] xret Error XML tree, as rpc-reply/rpc-error. Free with xml_free after use * @retval 1 Validation OK * @retval 0 Validation failed (cbret set) * @retval -1 Error diff --git a/lib/src/clixon_validate_minmax.c b/lib/src/clixon_validate_minmax.c index a158dbd9..367de9b5 100644 --- a/lib/src/clixon_validate_minmax.c +++ b/lib/src/clixon_validate_minmax.c @@ -61,11 +61,11 @@ #include "clixon_hash.h" #include "clixon_handle.h" #include "clixon_string.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_data.h" #include "clixon_netconf_lib.h" #include "clixon_options.h" diff --git a/lib/src/clixon_xml.c b/lib/src/clixon_xml.c index 25b6f5d2..7a211899 100644 --- a/lib/src/clixon_xml.c +++ b/lib/src/clixon_xml.c @@ -62,11 +62,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_options.h" /* xml_bind_yang */ #include "clixon_yang_module.h" #include "clixon_xml_map.h" /* xml_bind_yang */ @@ -2699,139 +2699,6 @@ xml_add_attr(cxobj *xn, goto ret; } -/*! Specialization of clixon_log with xml tree - * - * @param[in] h Clixon handle - * @param[in] dbglevel - * @param[in] level log level, eg LOG_DEBUG,LOG_INFO,...,LOG_EMERG. - * @param[in] x XML tree that is logged without prettyprint - * @param[in] format Message to print as argv. - * @retval 0 OK - * @retval -1 Error - * @see clixon_debug_xml which uses debug setting instead of direct syslog - */ -int -clixon_log_xml(clixon_handle h, - int level, - cxobj *x, - const char *format, ...) -{ - int retval = -1; - va_list args; - size_t len; - char *msg = NULL; - cbuf *cb = NULL; - size_t trunc; - - /* Print xml as cbuf */ - if ((cb = cbuf_new()) == NULL){ - clixon_err(OE_XML, errno, "cbuf_new"); - goto done; - } - if (clixon_xml2cbuf(cb, x, 0, 0, NULL, -1, 0) < 0) - goto done; - /* first round: compute length of debug message */ - va_start(args, format); - len = vsnprintf(NULL, 0, format, args); - va_end(args); - /* Truncate long debug strings */ - if ((trunc = clixon_log_string_limit_get()) && trunc < len) - len = trunc; - - /* allocate a message string exactly fitting the message length */ - if ((msg = malloc(len+1)) == NULL){ - fprintf(stderr, "malloc: %s\n", strerror(errno)); /* dont use clixon_err here due to recursion */ - goto done; - } - - /* second round: compute write message from format and args */ - va_start(args, format); - if (vsnprintf(msg, len+1, format, args) < 0){ - va_end(args); - fprintf(stderr, "vsnprintf: %s\n", strerror(errno)); /* dont use clixon_err here due to recursion */ - goto done; - } - va_end(args); - - /* Actually log it */ - clixon_log(h, level, "%s: %s", msg, cbuf_get(cb)); - - retval = 0; - done: - if (cb) - cbuf_free(cb); - if (msg) - free(msg); - return retval; -} - -/*! Specialization of clixon_debug with xml tree - * - * @param[in] dbglevel Mask of CLIXON_DBG_DEFAULT and other masks - * @param[in] x XML tree that is logged without prettyprint - * @param[in] format Message to print as argv. - * @retval 0 OK - * @retval -1 Error - * @see clicon_log_xml For syslog - * @see clixon_debug base function and see CLIXON_DBG_* flags -*/ -int -clixon_debug_xml(int dbglevel, - cxobj *x, - const char *format, ...) -{ - int retval = -1; - va_list args; - size_t len; - char *msg = NULL; - cbuf *cb = NULL; - size_t trunc; - - /* Mask debug level with global dbg variable */ - if ((dbglevel & clixon_debug_get()) == 0) - return 0; - /* Print xml as cbuf */ - if ((cb = cbuf_new()) == NULL){ - clixon_err(OE_XML, errno, "cbuf_new"); - goto done; - } - if (clixon_xml2cbuf(cb, x, 0, 0, NULL, -1, 0) < 0) - goto done; - /* first round: compute length of debug message */ - va_start(args, format); - len = vsnprintf(NULL, 0, format, args); - va_end(args); - /* Truncate long debug strings */ - if ((trunc = clixon_log_string_limit_get()) && trunc < len) - len = trunc; - - /* allocate a message string exactly fitting the message length */ - if ((msg = malloc(len+1)) == NULL){ - fprintf(stderr, "malloc: %s\n", strerror(errno)); /* dont use clixon_err here due to recursion */ - goto done; - } - - /* second round: compute write message from format and args */ - va_start(args, format); - if (vsnprintf(msg, len+1, format, args) < 0){ - va_end(args); - fprintf(stderr, "vsnprintf: %s\n", strerror(errno)); /* dont use clixon_err here due to recursion */ - goto done; - } - va_end(args); - - /* Actually log it */ - clixon_debug(dbglevel, "%s: %s", msg, cbuf_get(cb)); - - retval = 0; - done: - if (cb) - cbuf_free(cb); - if (msg) - free(msg); - return retval; -} - #ifdef XML_EXPLICIT_INDEX /*! Is this XML object a search index, ie it is registered as a yang clixon cc:search_index * diff --git a/lib/src/clixon_xml_bind.c b/lib/src/clixon_xml_bind.c index 5ab094f6..23c5be9f 100644 --- a/lib/src/clixon_xml_bind.c +++ b/lib/src/clixon_xml_bind.c @@ -61,21 +61,20 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" -#include "clixon_log.h" -#include "clixon_debug.h" -#include "clixon_err.h" #include "clixon_string.h" #include "clixon_yang.h" #include "clixon_xml.h" +#include "clixon_log.h" +#include "clixon_debug.h" +#include "clixon_err.h" #include "clixon_options.h" #include "clixon_data.h" -#include "clixon_yang_module.h" #include "clixon_yang_schema_mount.h" -#include "clixon_plugin.h" #include "clixon_xml_nsctx.h" #include "clixon_xpath_ctx.h" #include "clixon_xpath.h" #include "clixon_netconf_lib.h" +#include "clixon_yang_module.h" #include "clixon_plugin.h" #include "clixon_xml_sort.h" #include "clixon_yang_type.h" diff --git a/lib/src/clixon_xml_changelog.c b/lib/src/clixon_xml_changelog.c index 404a98ba..2e7868f4 100644 --- a/lib/src/clixon_xml_changelog.c +++ b/lib/src/clixon_xml_changelog.c @@ -61,11 +61,11 @@ #include "clixon_hash.h" #include "clixon_string.h" #include "clixon_handle.h" -#include "clixon_err.h" #include "clixon_yang.h" +#include "clixon_xml.h" +#include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_xml.h" #include "clixon_options.h" #include "clixon_data.h" #include "clixon_yang_module.h" @@ -469,10 +469,7 @@ clixon_xml_changelog_init(clixon_handle h) clixon_err(OE_XML, errno, "cbuf_new"); goto done; } - if (netconf_err2cb(h, xret, cbret) < 0) - goto done; - clixon_err(OE_YANG, 0, "validation failed: %s", cbuf_get(cbret)); - goto done; + clixon_err_netconf(h, OE_YANG, 0, xret, "validation failed"); } if (clicon_xml_changelog_set(h, xt) < 0) goto done; diff --git a/lib/src/clixon_xml_default.c b/lib/src/clixon_xml_default.c index 509f21de..50923124 100644 --- a/lib/src/clixon_xml_default.c +++ b/lib/src/clixon_xml_default.c @@ -60,11 +60,11 @@ #include "clixon_hash.h" #include "clixon_string.h" #include "clixon_handle.h" -#include "clixon_log.h" -#include "clixon_debug.h" -#include "clixon_err.h" #include "clixon_yang.h" #include "clixon_xml.h" +#include "clixon_err.h" +#include "clixon_log.h" +#include "clixon_debug.h" #include "clixon_xpath_ctx.h" #include "clixon_xpath.h" #include "clixon_data.h" diff --git a/lib/src/clixon_xml_io.c b/lib/src/clixon_xml_io.c index 53fd455a..ca39b1e9 100644 --- a/lib/src/clixon_xml_io.c +++ b/lib/src/clixon_xml_io.c @@ -61,11 +61,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_options.h" #include "clixon_yang_module.h" #include "clixon_xml_bind.h" diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index f70e4e16..d3f47145 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -61,12 +61,12 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" -#include "clixon_log.h" -#include "clixon_debug.h" -#include "clixon_err.h" #include "clixon_string.h" #include "clixon_yang.h" #include "clixon_xml.h" +#include "clixon_log.h" +#include "clixon_debug.h" +#include "clixon_err.h" #include "clixon_options.h" #include "clixon_data.h" #include "clixon_yang_module.h" diff --git a/lib/src/clixon_xml_nsctx.c b/lib/src/clixon_xml_nsctx.c index 02c8953f..c860faf3 100644 --- a/lib/src/clixon_xml_nsctx.c +++ b/lib/src/clixon_xml_nsctx.c @@ -62,12 +62,12 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_options.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_yang_module.h" #include "clixon_netconf_lib.h" #include "clixon_xml_sort.h" diff --git a/lib/src/clixon_xml_parse.y b/lib/src/clixon_xml_parse.y index 6cc31384..1b19a55f 100644 --- a/lib/src/clixon_xml_parse.y +++ b/lib/src/clixon_xml_parse.y @@ -76,13 +76,13 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_string.h" #include "clixon_handle.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_sort.h" #include "clixon_xml_parse.h" diff --git a/lib/src/clixon_xml_sort.c b/lib/src/clixon_xml_sort.c index 1ab8385c..7101c5ac 100644 --- a/lib/src/clixon_xml_sort.c +++ b/lib/src/clixon_xml_sort.c @@ -58,11 +58,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_nsctx.h" #include "clixon_xml_io.h" #include "clixon_xpath_ctx.h" diff --git a/lib/src/clixon_xml_vec.c b/lib/src/clixon_xml_vec.c index 564e4e62..0906addd 100644 --- a/lib/src/clixon_xml_vec.c +++ b/lib/src/clixon_xml_vec.c @@ -57,11 +57,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_io.h" #include "clixon_xml_vec.h" diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index e3f3caad..1fc52e37 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -85,11 +85,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_nsctx.h" #include "clixon_netconf_lib.h" #include "clixon_yang_module.h" diff --git a/lib/src/clixon_xpath_ctx.c b/lib/src/clixon_xpath_ctx.c index 0f6548cc..d290f3d3 100644 --- a/lib/src/clixon_xpath_ctx.c +++ b/lib/src/clixon_xpath_ctx.c @@ -55,11 +55,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xpath_ctx.h" #include "clixon_xpath.h" #include "clixon_xpath_parse.h" diff --git a/lib/src/clixon_xpath_eval.c b/lib/src/clixon_xpath_eval.c index c99c090f..ea117fdc 100644 --- a/lib/src/clixon_xpath_eval.c +++ b/lib/src/clixon_xpath_eval.c @@ -77,12 +77,12 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" #include "clixon_yang_type.h" -#include "clixon_xml.h" #include "clixon_xml_sort.h" #include "clixon_xml_nsctx.h" #include "clixon_xpath_ctx.h" diff --git a/lib/src/clixon_xpath_function.c b/lib/src/clixon_xpath_function.c index 28c6e4ec..03ac6893 100644 --- a/lib/src/clixon_xpath_function.c +++ b/lib/src/clixon_xpath_function.c @@ -59,13 +59,13 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_options.h" -#include "clixon_yang.h" #include "clixon_yang_type.h" -#include "clixon_xml.h" #include "clixon_xml_map.h" #include "clixon_yang_module.h" #include "clixon_validate.h" diff --git a/lib/src/clixon_xpath_optimize.c b/lib/src/clixon_xpath_optimize.c index 901eccba..d597e13c 100644 --- a/lib/src/clixon_xpath_optimize.c +++ b/lib/src/clixon_xpath_optimize.c @@ -59,11 +59,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_vec.h" #include "clixon_xml_sort.h" #include "clixon_xpath_ctx.h" diff --git a/lib/src/clixon_xpath_parse.l b/lib/src/clixon_xpath_parse.l index 6fb08176..29c92edf 100644 --- a/lib/src/clixon_xpath_parse.l +++ b/lib/src/clixon_xpath_parse.l @@ -72,10 +72,10 @@ There are some special lexical rules in https://www.w3.org/TR/xpath-10 #include "clixon_hash.h" #include "clixon_handle.h" #include "clixon_yang.h" -#include "clixon_log.h" -#include "clixon_debug.h" #include "clixon_string.h" #include "clixon_xml.h" +#include "clixon_log.h" +#include "clixon_debug.h" #include "clixon_xpath_ctx.h" #include "clixon_xpath.h" #include "clixon_xpath_parse.h" diff --git a/lib/src/clixon_xpath_parse.y b/lib/src/clixon_xpath_parse.y index 772d43e0..21a19da8 100644 --- a/lib/src/clixon_xpath_parse.y +++ b/lib/src/clixon_xpath_parse.y @@ -121,12 +121,12 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_string.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xpath_ctx.h" #include "clixon_xpath.h" #include "clixon_xpath_function.h" diff --git a/lib/src/clixon_xpath_yang.c b/lib/src/clixon_xpath_yang.c index 2744ccad..1bc92882 100644 --- a/lib/src/clixon_xpath_yang.c +++ b/lib/src/clixon_xpath_yang.c @@ -58,11 +58,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_nsctx.h" #include "clixon_yang_module.h" #include "clixon_xpath_ctx.h" diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index 2976e5c1..6d2dfe4c 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -68,13 +68,13 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" -#include "clixon_log.h" -#include "clixon_debug.h" -#include "clixon_err.h" #include "clixon_file.h" #include "clixon_yang.h" #include "clixon_hash.h" #include "clixon_xml.h" +#include "clixon_err.h" +#include "clixon_log.h" +#include "clixon_debug.h" #include "clixon_xml_nsctx.h" #include "clixon_yang_module.h" #include "clixon_plugin.h" diff --git a/lib/src/clixon_yang_cardinality.c b/lib/src/clixon_yang_cardinality.c index b55fe875..09f60cb2 100644 --- a/lib/src/clixon_yang_cardinality.c +++ b/lib/src/clixon_yang_cardinality.c @@ -63,8 +63,9 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" -#include "clixon_err.h" #include "clixon_yang.h" +#include "clixon_xml.h" +#include "clixon_err.h" #include "clixon_yang_cardinality.h" /* diff --git a/lib/src/clixon_yang_module.c b/lib/src/clixon_yang_module.c index f6087cb2..428b1fc1 100644 --- a/lib/src/clixon_yang_module.c +++ b/lib/src/clixon_yang_module.c @@ -65,12 +65,12 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" -#include "clixon_log.h" -#include "clixon_debug.h" -#include "clixon_err.h" #include "clixon_file.h" #include "clixon_yang.h" #include "clixon_xml.h" +#include "clixon_err.h" +#include "clixon_log.h" +#include "clixon_debug.h" #include "clixon_xml_io.h" #include "clixon_xml_nsctx.h" #include "clixon_xpath_ctx.h" diff --git a/lib/src/clixon_yang_parse.y b/lib/src/clixon_yang_parse.y index 9383aa4c..df74e5fd 100644 --- a/lib/src/clixon_yang_parse.y +++ b/lib/src/clixon_yang_parse.y @@ -191,10 +191,11 @@ #include "clixon_string.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" #include "clixon_yang_parse_lib.h" #include "clixon_yang_parse.h" diff --git a/lib/src/clixon_yang_parse_lib.c b/lib/src/clixon_yang_parse_lib.c index d42bd7ce..4b379423 100644 --- a/lib/src/clixon_yang_parse_lib.c +++ b/lib/src/clixon_yang_parse_lib.c @@ -79,13 +79,13 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_file.h" +#include "clixon_hash.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_err.h" -#include "clixon_file.h" -#include "clixon_yang.h" -#include "clixon_hash.h" -#include "clixon_xml.h" #include "clixon_xml_nsctx.h" #include "clixon_xpath_ctx.h" #include "clixon_xpath.h" diff --git a/lib/src/clixon_yang_schema_mount.c b/lib/src/clixon_yang_schema_mount.c index cf9df236..55803fe7 100644 --- a/lib/src/clixon_yang_schema_mount.c +++ b/lib/src/clixon_yang_schema_mount.c @@ -71,11 +71,11 @@ #include "clixon_hash.h" #include "clixon_string.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_xml_io.h" #include "clixon_xml_map.h" #include "clixon_data.h" diff --git a/lib/src/clixon_yang_schemanode_parse.y b/lib/src/clixon_yang_schemanode_parse.y index e2456819..df221a92 100644 --- a/lib/src/clixon_yang_schemanode_parse.y +++ b/lib/src/clixon_yang_schemanode_parse.y @@ -83,11 +83,11 @@ #include "clixon_hash.h" #include "clixon_string.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_yang_module.h" #include "clixon_xml_vec.h" #include "clixon_data.h" @@ -107,7 +107,7 @@ clixon_yang_schemanode_parseerror(void *arg, { clixon_yang_schemanode_yacc *ife = (clixon_yang_schemanode_yacc *)arg; - clixon_err_fn(NULL, 0, OE_YANG, 0, "yang_schemanode_parse: file:%s:%d \"%s\" %s: at or before: %s", + clixon_err(OE_YANG, 0, "yang_schemanode_parse: file:%s:%d \"%s\" %s: at or before: %s", ife->if_mainfile, ife->if_linenum, ife->if_parse_string, diff --git a/lib/src/clixon_yang_sub_parse.c b/lib/src/clixon_yang_sub_parse.c index 4edc6a53..fe5868b2 100644 --- a/lib/src/clixon_yang_sub_parse.c +++ b/lib/src/clixon_yang_sub_parse.c @@ -51,10 +51,11 @@ #include "clixon_queue.h" #include "clixon_hash.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_log.h" #include "clixon_debug.h" #include "clixon_err.h" -#include "clixon_yang.h" #include "clixon_yang_sub_parse.h" #include "clixon_yang_schemanode_parse.h" diff --git a/lib/src/clixon_yang_sub_parse.y b/lib/src/clixon_yang_sub_parse.y index 23e0704d..63a56eaf 100644 --- a/lib/src/clixon_yang_sub_parse.y +++ b/lib/src/clixon_yang_sub_parse.y @@ -94,11 +94,11 @@ #include "clixon_hash.h" #include "clixon_string.h" #include "clixon_handle.h" +#include "clixon_yang.h" +#include "clixon_xml.h" #include "clixon_err.h" #include "clixon_log.h" #include "clixon_debug.h" -#include "clixon_yang.h" -#include "clixon_xml.h" #include "clixon_yang_module.h" #include "clixon_xml_vec.h" #include "clixon_data.h" @@ -113,11 +113,11 @@ void clixon_yang_sub_parseerror(void *arg, - char *s) + char *s) { clixon_yang_sub_parse_yacc *ife = (clixon_yang_sub_parse_yacc *)arg; - clixon_err_fn(NULL, 0, OE_YANG, 0, "yang_sub_parse: file:%s:%d \"%s\" %s: at or before: %s", + clixon_err(OE_YANG, 0, "yang_sub_parse: file:%s:%d \"%s\" %s: at or before: %s", ife->if_mainfile, ife->if_linenum, ife->if_parse_string, diff --git a/lib/src/clixon_yang_type.c b/lib/src/clixon_yang_type.c index 3b86576e..a4406e9f 100644 --- a/lib/src/clixon_yang_type.c +++ b/lib/src/clixon_yang_type.c @@ -89,9 +89,10 @@ #include "clixon_hash.h" #include "clixon_handle.h" #include "clixon_regex.h" -#include "clixon_err.h" #include "clixon_yang.h" #include "clixon_xml.h" +#include "clixon_log.h" +#include "clixon_err.h" #include "clixon_xml_nsctx.h" #include "clixon_xpath_ctx.h" #include "clixon_xpath.h" diff --git a/test/test_cli_err.sh b/test/test_cli_err.sh new file mode 100755 index 00000000..cb1709b7 --- /dev/null +++ b/test/test_cli_err.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash +# Customixed error test + +# Magic line must be first in script (see README.md) +s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi + +APPNAME=example + +# include err() and new() functions and creates $dir + +cfg=$dir/conf_yang.xml +fyang=$dir/$APPNAME.yang +clidir=$dir/cli +if [ -d $clidir ]; then + rm -rf $clidir/* +else + mkdir $clidir +fi + +# Generate autocli for these modules +AUTOCLI=$(autocli_config ${APPNAME} kw-all false) + +cat < $cfg + + $cfg + ${YANG_INSTALLDIR} + $dir + $fyang + $clidir + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/run/$APPNAME.sock + /usr/local/var/run/$APPNAME.pidfile + /usr/local/var/$APPNAME + ${AUTOCLI} + +EOF + +cat < $fyang +module $APPNAME { + namespace "urn:example:m"; + prefix m; + container x { + list m1 { + key "a b"; + leaf a { + type string; + } + leaf b { + type string; + } + leaf c { + type string; + } + } + } +} +EOF + +cat < $clidir/ex.cli +CLICON_MODE="example"; +CLICON_PROMPT="%U@%H> "; +CLICON_PLUGIN="example_cli"; + +show config @datamodel, cli_show_auto("candidate", "cli"); +example("Example callback") { + ("Just a random number"), mycallback("myarg"); + error { + customized, myerror(); # Customized error message + orig, cli_remove(); # Original + } +} + + +EOF + +new "test params: -f $cfg" +if [ $BE -ne 0 ]; then + new "kill old backend" + sudo clixon_backend -z -f $cfg + if [ $? -ne 0 ]; then + err + fi + new "start backend -s init -f $cfg" + start_backend -s init -f $cfg +fi + +new "wait backend" +wait_backend + +new "orig error" +expectpart "$($clixon_cli -1 -f $cfg -l n example error orig)" 255 "Config error: api-path syntax error " ": application invalid-value Invalid api-path: (must start with '/')" + +new "customized error" +expectpart "$($clixon_cli -1 -f $cfg -l n example error custom)" 255 "My new err-string" + +if [ $BE -ne 0 ]; then + new "Kill backend" + # Check if premature kill + pid=$(pgrep -u root -f clixon_backend) + if [ -z "$pid" ]; then + err "backend already dead" + fi + # kill backend + stop_backend -f $cfg +fi + +endtest + +rm -rf $dir diff --git a/test/test_client.sh b/test/test_client.sh index 43b093f1..b86a409c 100755 --- a/test/test_client.sh +++ b/test/test_client.sh @@ -75,19 +75,17 @@ cat< $cfile #include #include #include -#include // debug #include #include #include -#include // debug #include int main(int argc, char **argv) { - int retval = -1; + int retval = -1; clixon_handle h = NULL; /* clixon handle */ clixon_client_handle ch = NULL; /* clixon client handle */ int s; @@ -95,10 +93,6 @@ main(int argc, /* Provide a clixon config-file, get a clixon handle */ if ((h = clixon_client_init("$cfg")) == NULL) return -1; - clixon_log_init(h, "client", LOG_DEBUG, CLIXON_LOG_STDERR); - clixon_err_init(h); - clixon_debug_init(h, $debug, NULL); - /* Make a connection over netconf or ssh/netconf */ if ((ch = clixon_client_connect(h, CLIXON_CLIENT_NETCONF, NULL)) == NULL) return -1;