* Internal backend socket protocol changed: uint32_t session-id added, see clixon_proto.h
* * Changed session-id handing. Instead of using pid of peer process, a proper session id generated by the server is used, following RFC6241.
This commit is contained in:
parent
a387c599e2
commit
b624e911b8
23 changed files with 230 additions and 155 deletions
|
|
@ -18,6 +18,8 @@
|
|||
* `except` means exact match is done except for root and www user.This is necessary for Restconf. This is default.
|
||||
|
||||
### API changes on existing features (you may need to change your code)
|
||||
* Internal backend socket protocol changed: uint32_t session-id added, see clixon_proto.h
|
||||
* C-code: added `id` parameter to `clicon_msg_encode()` and `clicon_msg_decode()`
|
||||
* NACM users are cross-checked with client user credentials (see new features).
|
||||
* Changed "Demon error" to "Daemon error" in logs and debug.
|
||||
* Stricter handling of multi-namespace handling
|
||||
|
|
@ -51,6 +53,8 @@
|
|||
* Replaced JSON `null` with `[null]` as proper empty JSON leaf/leaf-list encoding.
|
||||
|
||||
### Minor changes
|
||||
* Changed session-id handing. Instead of using pid of peer process, a proper session id generated by the server is used, following RFC6241.
|
||||
* Code in kill_session is removed where this fact was used to actually kill the client process.
|
||||
* XPATH canonical form implemented for NETCONF get and get-config. This means that all callbacks (including state callbacks) will have the prefixes that corresponds to module prefixes. If an xpath have other prefixes (or null as default), they will be translated to canonical form before any callbacks.
|
||||
* Example of a canonical form: `/a:x/a:y`, then symbols must belong to a yang module with prefix `a`.
|
||||
* Configure and test modification for better Freebsd port
|
||||
|
|
|
|||
|
|
@ -69,14 +69,18 @@
|
|||
#include "backend_client.h"
|
||||
#include "backend_handle.h"
|
||||
|
||||
/*! Find client by session-id
|
||||
* @param[in] ce_list List of clients
|
||||
* @param[in] id Session id
|
||||
*/
|
||||
static struct client_entry *
|
||||
ce_find_bypid(struct client_entry *ce_list,
|
||||
int pid)
|
||||
ce_find_byid(struct client_entry *ce_list,
|
||||
uint32_t id)
|
||||
{
|
||||
struct client_entry *ce;
|
||||
|
||||
for (ce = ce_list; ce; ce = ce->ce_next)
|
||||
if (ce->ce_pid == pid)
|
||||
if (ce->ce_id == id)
|
||||
return ce;
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -104,7 +108,7 @@ ce_event_cb(clicon_handle h,
|
|||
backend_client_rm(h, ce);
|
||||
break;
|
||||
default:
|
||||
if (send_msg_notify_xml(ce->ce_s, event) < 0){
|
||||
if (send_msg_notify_xml(h, ce->ce_s, event) < 0){
|
||||
if (errno == ECONNRESET || errno == EPIPE){
|
||||
clicon_log(LOG_WARNING, "client %d reset", ce->ce_nr);
|
||||
}
|
||||
|
|
@ -483,12 +487,13 @@ from_client_edit_config(clicon_handle h,
|
|||
{
|
||||
int retval = -1;
|
||||
struct client_entry *ce = (struct client_entry *)arg;
|
||||
int mypid = ce->ce_pid;
|
||||
uint32_t myid = ce->ce_id;
|
||||
uint32_t iddb;
|
||||
char *target;
|
||||
cxobj *xc;
|
||||
cxobj *x;
|
||||
enum operation_type operation = OP_MERGE;
|
||||
int piddb;
|
||||
|
||||
int non_config = 0;
|
||||
yang_stmt *yspec;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
|
@ -517,9 +522,9 @@ from_client_edit_config(clicon_handle h,
|
|||
goto ok;
|
||||
}
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, target);
|
||||
if (piddb && mypid != piddb){
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
iddb = xmldb_islocked(h, target);
|
||||
if (iddb && myid != iddb){
|
||||
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
|
|
@ -608,13 +613,13 @@ from_client_copy_config(clicon_handle h,
|
|||
void *arg,
|
||||
void *regarg)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
struct client_entry *ce = (struct client_entry *)arg;
|
||||
char *source;
|
||||
char *target;
|
||||
int piddb;
|
||||
int mypid = ce->ce_pid;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
char *source;
|
||||
char *target;
|
||||
uint32_t iddb;
|
||||
uint32_t myid = ce->ce_id;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
if ((source = netconf_db_find(xe, "source")) == NULL){
|
||||
if (netconf_missing_element(cbret, "protocol", "source", NULL) < 0)
|
||||
|
|
@ -643,9 +648,9 @@ from_client_copy_config(clicon_handle h,
|
|||
goto ok;
|
||||
}
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, target);
|
||||
if (piddb && mypid != piddb){
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
iddb = xmldb_islocked(h, target);
|
||||
if (iddb && myid != iddb){
|
||||
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Copy failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
|
|
@ -683,9 +688,9 @@ from_client_delete_config(clicon_handle h,
|
|||
int retval = -1;
|
||||
struct client_entry *ce = (struct client_entry *)arg;
|
||||
char *target;
|
||||
int piddb;
|
||||
uint32_t iddb;
|
||||
uint32_t myid = ce->ce_id;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
int mypid = ce->ce_pid;
|
||||
|
||||
if ((target = netconf_db_find(xe, "target")) == NULL ||
|
||||
strcmp(target, "running")==0){
|
||||
|
|
@ -704,9 +709,9 @@ from_client_delete_config(clicon_handle h,
|
|||
goto ok;
|
||||
}
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, target);
|
||||
if (piddb && mypid != piddb){
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
iddb = xmldb_islocked(h, target);
|
||||
if (iddb && myid != iddb){
|
||||
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
|
|
@ -749,9 +754,9 @@ from_client_lock(clicon_handle h,
|
|||
{
|
||||
int retval = -1;
|
||||
struct client_entry *ce = (struct client_entry *)arg;
|
||||
int pid = ce->ce_pid;
|
||||
uint32_t id = ce->ce_id;
|
||||
uint32_t iddb;
|
||||
char *db;
|
||||
int piddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
if ((db = netconf_db_find(xe, "target")) == NULL){
|
||||
|
|
@ -775,15 +780,15 @@ from_client_lock(clicon_handle h,
|
|||
* 2) The target configuration is <candidate>, it has already been modified, and
|
||||
* these changes have not been committed or rolled back.
|
||||
*/
|
||||
piddb = xmldb_islocked(h, db);
|
||||
if (piddb){
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
iddb = xmldb_islocked(h, db);
|
||||
if (iddb != 0){
|
||||
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
else{
|
||||
if (xmldb_lock(h, db, pid) < 0)
|
||||
if (xmldb_lock(h, db, id) < 0)
|
||||
goto done;
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
}
|
||||
|
|
@ -814,9 +819,9 @@ from_client_unlock(clicon_handle h,
|
|||
{
|
||||
int retval = -1;
|
||||
struct client_entry *ce = (struct client_entry *)arg;
|
||||
int pid = ce->ce_pid;
|
||||
uint32_t id = ce->ce_id;
|
||||
uint32_t iddb; /* DBs lock, if any */
|
||||
char *db;
|
||||
int piddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
if ((db = netconf_db_find(xe, "target")) == NULL){
|
||||
|
|
@ -834,7 +839,7 @@ from_client_unlock(clicon_handle h,
|
|||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
piddb = xmldb_islocked(h, db);
|
||||
iddb = xmldb_islocked(h, db);
|
||||
/*
|
||||
* An unlock operation will not succeed if any of the following
|
||||
* conditions are true:
|
||||
|
|
@ -842,8 +847,8 @@ from_client_unlock(clicon_handle h,
|
|||
* 2) the session issuing the <unlock> operation is not the same
|
||||
* session that obtained the lock
|
||||
*/
|
||||
if (piddb==0 || piddb != pid){
|
||||
cprintf(cbx, "<session-id>pid=%d piddb=%d</session-id>", pid, piddb);
|
||||
if (iddb == 0 || iddb != id){
|
||||
cprintf(cbx, "<session-id>id=%u iddb=%d</session-id>", id, iddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Unlock failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
|
|
@ -1013,9 +1018,9 @@ from_client_close_session(clicon_handle h,
|
|||
void *regarg)
|
||||
{
|
||||
struct client_entry *ce = (struct client_entry *)arg;
|
||||
int pid = ce->ce_pid;
|
||||
uint32_t id = ce->ce_id;
|
||||
|
||||
xmldb_unlock_all(h, pid);
|
||||
xmldb_unlock_all(h, id);
|
||||
stream_ss_delete_all(h, ce_event_cb, (void*)ce);
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
return 0;
|
||||
|
|
@ -1031,6 +1036,7 @@ from_client_close_session(clicon_handle h,
|
|||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
#if 1
|
||||
static int
|
||||
from_client_kill_session(clicon_handle h,
|
||||
cxobj *xe,
|
||||
|
|
@ -1039,11 +1045,13 @@ from_client_kill_session(clicon_handle h,
|
|||
void *regarg)
|
||||
{
|
||||
int retval = -1;
|
||||
uint32_t pid; /* other pid */
|
||||
uint32_t id; /* session id */
|
||||
char *str;
|
||||
struct client_entry *ce;
|
||||
char *db = "running"; /* XXX */
|
||||
cxobj *x;
|
||||
int ret;
|
||||
char *reason = NULL;
|
||||
|
||||
if ((x = xml_find(xe, "session-id")) == NULL ||
|
||||
(str = xml_find_value(x, "body")) == NULL){
|
||||
|
|
@ -1051,36 +1059,28 @@ from_client_kill_session(clicon_handle h,
|
|||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
pid = atoi(str);
|
||||
if ((ret = parse_uint32(str, &id, &reason)) < 0){
|
||||
clicon_err(OE_XML, errno, "parse_uint32");
|
||||
goto done;
|
||||
}
|
||||
if (ret == 0){
|
||||
if (netconf_bad_element(cbret, "protocol", "session-id", reason) < 0)
|
||||
goto done;
|
||||
goto done;
|
||||
}
|
||||
/* may or may not be in active client list, probably not */
|
||||
if ((ce = ce_find_bypid(backend_client_list(h), pid)) != NULL){
|
||||
xmldb_unlock_all(h, pid);
|
||||
if ((ce = ce_find_byid(backend_client_list(h), id)) != NULL){
|
||||
xmldb_unlock_all(h, id);
|
||||
backend_client_rm(h, ce);
|
||||
}
|
||||
|
||||
if (kill (pid, 0) != 0 && errno == ESRCH) /* Nothing there */
|
||||
;
|
||||
else{
|
||||
killpg(pid, SIGTERM);
|
||||
kill(pid, SIGTERM);
|
||||
#if 0 /* Hate sleeps we assume it died, see also 0 in next if.. */
|
||||
sleep(1);
|
||||
#endif
|
||||
}
|
||||
if (1 || (kill (pid, 0) != 0 && errno == ESRCH)){ /* Nothing there */
|
||||
/* clear from locks */
|
||||
if (xmldb_islocked(h, db) == pid)
|
||||
xmldb_unlock(h, db);
|
||||
}
|
||||
else{ /* failed to kill client */
|
||||
if (netconf_operation_failed(cbret, "application", "Failed to kill session")< 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
if (xmldb_islocked(h, db) == id)
|
||||
xmldb_unlock(h, db);
|
||||
cprintf(cbret, "<rpc-reply><ok/></rpc-reply>");
|
||||
ok:
|
||||
retval = 0;
|
||||
done:
|
||||
if (reason)
|
||||
free(reason);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -1328,6 +1328,7 @@ from_client_msg(clicon_handle h,
|
|||
yang_stmt *ymod;
|
||||
cxobj *xnacm = NULL;
|
||||
cxobj *xret = NULL;
|
||||
uint32_t id;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
|
|
@ -1338,12 +1339,13 @@ from_client_msg(clicon_handle h,
|
|||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
if (clicon_msg_decode(msg, yspec, &xt) < 0){
|
||||
/* Decode msg from client -> xml top (ct) and session id */
|
||||
if (clicon_msg_decode(msg, yspec, &id, &xt) < 0){
|
||||
if (netconf_malformed_message(cbret, "XML parse error")< 0)
|
||||
goto done;
|
||||
goto reply;
|
||||
}
|
||||
|
||||
ce->ce_id = id;
|
||||
if ((x = xpath_first_nsc(xt, NULL, "/rpc")) == NULL){
|
||||
if (netconf_malformed_message(cbret, "rpc keyword expected")< 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct client_entry{
|
|||
int ce_nr; /* Client number (for dbg/tracing) */
|
||||
int ce_stat_in; /* Nr of received msgs from client */
|
||||
int ce_stat_out;/* Nr of sent msgs to client */
|
||||
int ce_pid; /* Peer Process id */
|
||||
int ce_id; /* Session id */
|
||||
char *ce_username;/* Translated from peer user cred */
|
||||
clicon_handle ce_handle; /* clicon config handle (all clients have same?) */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -607,19 +607,19 @@ from_client_commit(clicon_handle h,
|
|||
{
|
||||
int retval = -1;
|
||||
struct client_entry *ce = (struct client_entry *)arg;
|
||||
int mypid = ce->ce_pid;
|
||||
int piddb;
|
||||
uint32_t myid = ce->ce_id;
|
||||
uint32_t iddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
int ret;
|
||||
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, "running");
|
||||
if (piddb && mypid != piddb){
|
||||
iddb = xmldb_islocked(h, "running");
|
||||
if (iddb && myid != iddb){
|
||||
if ((cbx = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
|
|
@ -662,18 +662,18 @@ from_client_discard_changes(clicon_handle h,
|
|||
{
|
||||
int retval = -1;
|
||||
struct client_entry *ce = (struct client_entry *)arg;
|
||||
int mypid = ce->ce_pid;
|
||||
int piddb;
|
||||
uint32_t myid = ce->ce_id;
|
||||
uint32_t iddb;
|
||||
cbuf *cbx = NULL; /* Assist cbuf */
|
||||
|
||||
/* Check if target locked by other client */
|
||||
piddb = xmldb_islocked(h, "candidate");
|
||||
if (piddb && mypid != piddb){
|
||||
iddb = xmldb_islocked(h, "candidate");
|
||||
if (iddb && myid != iddb){
|
||||
if ((cbx = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cbx, "<session-id>%d</session-id>", piddb);
|
||||
cprintf(cbx, "<session-id>%u</session-id>", iddb);
|
||||
if (netconf_lock_denied(cbret, cbuf_get(cbx), "Operation failed, lock is already held") < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
|
|
|
|||
|
|
@ -886,6 +886,9 @@ main(int argc,
|
|||
if (check_drop_priv(h, gid) < 0)
|
||||
goto done;
|
||||
|
||||
/* Start session-id for clients */
|
||||
clicon_session_id_set(h, 0);
|
||||
|
||||
if (stream_timer_setup(0, h) < 0)
|
||||
goto done;
|
||||
if (event_loop() < 0)
|
||||
|
|
|
|||
|
|
@ -216,26 +216,26 @@ backend_socket_init(clicon_handle h)
|
|||
}
|
||||
|
||||
/*! Accept new socket client
|
||||
* XXX: credentials not properly implemented
|
||||
* @param[in] fd Socket (unix or ip)
|
||||
* @param[in] arg typecast clicon_handle
|
||||
*/
|
||||
int
|
||||
backend_accept_client(int fd,
|
||||
void *arg)
|
||||
void *arg)
|
||||
{
|
||||
int retval = -1;
|
||||
clicon_handle h = (clicon_handle)arg;
|
||||
int s;
|
||||
struct sockaddr from = {0,};
|
||||
socklen_t len;
|
||||
int retval = -1;
|
||||
clicon_handle h = (clicon_handle)arg;
|
||||
int s;
|
||||
struct sockaddr from = {0,};
|
||||
socklen_t len;
|
||||
struct client_entry *ce;
|
||||
int i;
|
||||
char *name = NULL;
|
||||
#ifdef HAVE_SO_PEERCRED
|
||||
socklen_t clen;
|
||||
struct ucred cr = {0,}; /* Linux. */
|
||||
#elif defined(HAVE_GETPEEREID)
|
||||
uid_t euid;
|
||||
uid_t guid;
|
||||
char *name = NULL;
|
||||
#ifdef HAVE_SO_PEERCRED /* Linux. */
|
||||
socklen_t clen;
|
||||
struct ucred cr = {0,};
|
||||
#elif defined(HAVE_GETPEEREID) /* FreeBSD */
|
||||
uid_t euid;
|
||||
uid_t guid;
|
||||
#endif
|
||||
|
||||
clicon_debug(2, "%s", __FUNCTION__);
|
||||
|
|
@ -259,7 +259,6 @@ backend_accept_client(int fd,
|
|||
clicon_err(OE_UNIX, errno, "getsockopt");
|
||||
goto done;
|
||||
}
|
||||
ce->ce_pid = cr.pid; /* XXX no use session-id */
|
||||
if (uid2name(cr.uid, &name) < 0)
|
||||
goto done;
|
||||
#elif defined(HAVE_GETPEEREID)
|
||||
|
|
@ -275,10 +274,7 @@ backend_accept_client(int fd,
|
|||
goto done;
|
||||
}
|
||||
break;
|
||||
case AF_INET: /* XXX: HACK ce->ce_pid */
|
||||
ce->ce_pid = 0;
|
||||
for (i=0; i<len; i++)
|
||||
ce->ce_pid ^= from.sa_data[i];
|
||||
case AF_INET:
|
||||
break;
|
||||
case AF_INET6:
|
||||
default:
|
||||
|
|
@ -295,5 +291,3 @@ backend_accept_client(int fd,
|
|||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -983,7 +983,7 @@ cli_notification_cb(int s,
|
|||
event_unreg_fd(s, cli_notification_cb);
|
||||
goto done;
|
||||
}
|
||||
if (clicon_msg_decode(reply, NULL, &xt) < 0) /* XXX pass yang_spec */
|
||||
if (clicon_msg_decode(reply, NULL, NULL, &xt) < 0) /* XXX pass yang_spec */
|
||||
goto done;
|
||||
if ((xe = xpath_first(xt, "//event")) != NULL){
|
||||
x = NULL;
|
||||
|
|
|
|||
|
|
@ -595,6 +595,11 @@ main(int argc, char **argv)
|
|||
if (result < 0)
|
||||
goto done;
|
||||
}
|
||||
#if 1
|
||||
/* XXX get session id from backend hello */
|
||||
clicon_session_id_set(h, getpid());
|
||||
#endif
|
||||
|
||||
/* Go into event-loop unless -1 command-line */
|
||||
if (!once)
|
||||
retval = cli_interactive(h);
|
||||
|
|
|
|||
|
|
@ -529,6 +529,11 @@ main(int argc,
|
|||
/* Call start function is all plugins before we go interactive */
|
||||
if (clixon_plugin_start(h) < 0)
|
||||
goto done;
|
||||
#if 1
|
||||
/* XXX get session id from backend hello */
|
||||
clicon_session_id_set(h, getpid());
|
||||
#endif
|
||||
|
||||
if (!quiet)
|
||||
send_hello(h, 1);
|
||||
if (event_reg_fd(0, netconf_input_cb, h, "netconf socket") < 0)
|
||||
|
|
|
|||
|
|
@ -443,7 +443,7 @@ netconf_notification_cb(int s,
|
|||
goto done;
|
||||
}
|
||||
yspec = clicon_dbspec_yang(h);
|
||||
if (clicon_msg_decode(reply, yspec, &xt) < 0)
|
||||
if (clicon_msg_decode(reply, yspec, NULL, &xt) < 0)
|
||||
goto done;
|
||||
|
||||
if ((nsc = xml_nsctx_init(NULL, "urn:ietf:params:xml:ns:netconf:notification:1.0")) == NULL)
|
||||
|
|
|
|||
|
|
@ -779,6 +779,10 @@ main(int argc,
|
|||
clicon_err(OE_CFG, errno, "FCGX_OpenSocket");
|
||||
goto done;
|
||||
}
|
||||
#if 1
|
||||
/* XXX get session id from backend hello */
|
||||
clicon_session_id_set(h, getpid());
|
||||
#endif
|
||||
if (clicon_socket_set(h, sock) < 0)
|
||||
goto done;
|
||||
/* umask settings may interfer: we want group to write: this is 774 */
|
||||
|
|
|
|||
|
|
@ -684,8 +684,7 @@ api_data_write(clicon_handle h,
|
|||
if (cbx)
|
||||
cbuf_free(cbx);
|
||||
return retval;
|
||||
} /* api_data_put */
|
||||
|
||||
} /* api_data_write */
|
||||
|
||||
/*! Generic REST PUT method
|
||||
* @param[in] h CLIXON handle
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ restconf_stream_cb(int s,
|
|||
clicon_exit_set();
|
||||
goto done;
|
||||
}
|
||||
if (clicon_msg_decode(reply, NULL, &xtop) < 0) /* XXX pass yang_spec */
|
||||
if (clicon_msg_decode(reply, NULL, NULL, &xtop) < 0) /* XXX pass yang_spec */
|
||||
goto done;
|
||||
/* create event */
|
||||
if ((cb = cbuf_new()) == NULL){
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@
|
|||
*/
|
||||
/* Struct per database in hash */
|
||||
typedef struct {
|
||||
int de_pid;
|
||||
cxobj *de_xml; /* cache */
|
||||
uint32_t de_id; /* session id */
|
||||
cxobj *de_xml; /* cache */
|
||||
} db_elmnt;
|
||||
|
||||
/*
|
||||
|
|
@ -98,4 +98,7 @@ int clicon_xml_changelog_set(clicon_handle h, cxobj *xchlog);
|
|||
int clicon_argv_get(clicon_handle h, int *argc, char ***argv);
|
||||
int clicon_argv_set(clicon_handle h, char *argv0, int argc, char **argv);
|
||||
|
||||
int clicon_session_id_set(clicon_handle h, uint32_t id);
|
||||
uint32_t clicon_session_id_get(clicon_handle h);
|
||||
|
||||
#endif /* _CLIXON_DATA_H_ */
|
||||
|
|
|
|||
|
|
@ -57,10 +57,10 @@ int xmldb_get0_clear(clicon_handle h, cxobj *x);
|
|||
int xmldb_get0_free(clicon_handle h, cxobj **xp);
|
||||
int xmldb_put(clicon_handle h, const char *db, enum operation_type op, cxobj *xt, char *username, cbuf *cbret); /* in clixon_datastore_write.[ch] */
|
||||
int xmldb_copy(clicon_handle h, const char *from, const char *to);
|
||||
int xmldb_lock(clicon_handle h, const char *db, int pid);
|
||||
int xmldb_lock(clicon_handle h, const char *db, uint32_t id);
|
||||
int xmldb_unlock(clicon_handle h, const char *db);
|
||||
int xmldb_unlock_all(clicon_handle h, int pid);
|
||||
int xmldb_islocked(clicon_handle h, const char *db);
|
||||
int xmldb_unlock_all(clicon_handle h, uint32_t id);
|
||||
uint32_t xmldb_islocked(clicon_handle h, const char *db);
|
||||
int xmldb_exists(clicon_handle h, const char *db);
|
||||
int xmldb_delete(clicon_handle h, const char *db);
|
||||
int xmldb_create(clicon_handle h, const char *db);
|
||||
|
|
|
|||
|
|
@ -51,8 +51,9 @@ enum format_enum{
|
|||
|
||||
/* Protocol message header */
|
||||
struct clicon_msg {
|
||||
uint32_t op_len; /* length of message. network byte order. */
|
||||
char op_body[0]; /* rest of message, actual data */
|
||||
uint32_t op_len; /* length of message. network byte order. */
|
||||
uint32_t op_id; /* session-id. network byte order. */
|
||||
char op_body[0]; /* rest of message, actual data */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -62,11 +63,11 @@ char *format_int2str(enum format_enum showas);
|
|||
enum format_enum format_str2int(char *str);
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
struct clicon_msg *clicon_msg_encode(char *format, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
struct clicon_msg *clicon_msg_encode(uint32_t id, char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
#else
|
||||
struct clicon_msg *clicon_msg_encode(char *format, ...);
|
||||
struct clicon_msg *clicon_msg_encode(uint32_t id, char *format, ...);
|
||||
#endif
|
||||
int clicon_msg_decode(struct clicon_msg *msg, yang_stmt *yspec, cxobj **xml);
|
||||
int clicon_msg_decode(struct clicon_msg *msg, yang_stmt *yspec, uint32_t *id, cxobj **xml);
|
||||
|
||||
int clicon_connect_unix(char *sockpath);
|
||||
|
||||
|
|
@ -87,7 +88,7 @@ int clicon_msg_send(int s, struct clicon_msg *msg);
|
|||
|
||||
int clicon_msg_rcv(int s, struct clicon_msg **msg, int *eof);
|
||||
|
||||
int send_msg_notify_xml(int s, cxobj *xev);
|
||||
int send_msg_notify_xml(clicon_handle h, int s, cxobj *xev);
|
||||
|
||||
int send_msg_reply(int s, char *data, uint32_t datalen);
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ int clicon_rpc_lock(clicon_handle h, char *db);
|
|||
int clicon_rpc_unlock(clicon_handle h, char *db);
|
||||
int clicon_rpc_get(clicon_handle h, char *xpath, cvec *nsc, netconf_content content, int32_t depth, cxobj **xret);
|
||||
int clicon_rpc_close_session(clicon_handle h);
|
||||
int clicon_rpc_kill_session(clicon_handle h, int session_id);
|
||||
int clicon_rpc_kill_session(clicon_handle h, uint32_t session_id);
|
||||
int clicon_rpc_validate(clicon_handle h, char *db);
|
||||
int clicon_rpc_commit(clicon_handle h);
|
||||
int clicon_rpc_discard_changes(clicon_handle h);
|
||||
|
|
|
|||
|
|
@ -495,3 +495,35 @@ clicon_db_elmnt_set(clicon_handle h,
|
|||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Get session id
|
||||
* @param[in] h Clicon handle
|
||||
* @retval id Session identifier
|
||||
* Two uses: the backend assigns session-id for clients.
|
||||
*/
|
||||
uint32_t
|
||||
clicon_session_id_get(clicon_handle h)
|
||||
{
|
||||
clicon_hash_t *cdat = clicon_data(h);
|
||||
void *p;
|
||||
|
||||
if ((p = clicon_hash_value(cdat, "session-id", NULL)) == NULL)
|
||||
return 0;
|
||||
return *(uint32_t*)p;
|
||||
}
|
||||
|
||||
/*! Set session id
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] id Session id
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
clicon_session_id_set(clicon_handle h,
|
||||
uint32_t id)
|
||||
{
|
||||
clicon_hash_t *cdat = clicon_data(h);
|
||||
|
||||
clicon_hash_add(cdat, "session-id", &id, sizeof(uint32_t));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,30 +254,29 @@ xmldb_copy(clicon_handle h,
|
|||
/*! Lock database
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] db Database
|
||||
* @param[in] pid Process id
|
||||
* @param[in] id Session id
|
||||
* @retval -1 Error
|
||||
* @retval 0 OK
|
||||
*/
|
||||
int
|
||||
xmldb_lock(clicon_handle h,
|
||||
const char *db,
|
||||
int pid)
|
||||
uint32_t id)
|
||||
{
|
||||
db_elmnt *de = NULL;
|
||||
db_elmnt de0 = {0,};
|
||||
|
||||
if ((de = clicon_db_elmnt_get(h, db)) != NULL)
|
||||
de0 = *de;
|
||||
de0.de_pid = pid;
|
||||
de0.de_id = id;
|
||||
clicon_db_elmnt_set(h, db, &de0);
|
||||
clicon_debug(1, "%s: locked by %u", db, pid);
|
||||
clicon_debug(1, "%s: locked by %u", db, id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Unlock database
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] db Database
|
||||
* @param[in] pid Process id
|
||||
* @retval -1 Error
|
||||
* @retval 0 OK
|
||||
* Assume all sanity checks have been made
|
||||
|
|
@ -289,21 +288,21 @@ xmldb_unlock(clicon_handle h,
|
|||
db_elmnt *de = NULL;
|
||||
|
||||
if ((de = clicon_db_elmnt_get(h, db)) != NULL){
|
||||
de->de_pid = 0;
|
||||
de->de_id = 0;
|
||||
clicon_db_elmnt_set(h, db, de);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! Unlock all databases locked by pid (eg process dies)
|
||||
/*! Unlock all databases locked by session-id (eg process dies)
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] pid Process / Session id
|
||||
* @param[in] id Session id
|
||||
* @retval -1 Error
|
||||
* @retval 0 OK
|
||||
*/
|
||||
int
|
||||
xmldb_unlock_all(clicon_handle h,
|
||||
int pid)
|
||||
uint32_t id)
|
||||
{
|
||||
int retval = -1;
|
||||
char **keys = NULL;
|
||||
|
|
@ -315,8 +314,8 @@ xmldb_unlock_all(clicon_handle h,
|
|||
goto done;
|
||||
for (i = 0; i < klen; i++)
|
||||
if ((de = clicon_db_elmnt_get(h, keys[i])) != NULL &&
|
||||
de->de_pid == pid){
|
||||
de->de_pid = 0;
|
||||
de->de_id == id){
|
||||
de->de_id = 0;
|
||||
clicon_db_elmnt_set(h, keys[i], de);
|
||||
}
|
||||
retval = 0;
|
||||
|
|
@ -333,7 +332,7 @@ xmldb_unlock_all(clicon_handle h,
|
|||
* @retval 0 Not locked
|
||||
* @retval >0 Id of locker
|
||||
*/
|
||||
int
|
||||
uint32_t
|
||||
xmldb_islocked(clicon_handle h,
|
||||
const char *db)
|
||||
{
|
||||
|
|
@ -341,7 +340,7 @@ xmldb_islocked(clicon_handle h,
|
|||
|
||||
if ((de = clicon_db_elmnt_get(h, db)) == NULL)
|
||||
return 0;
|
||||
return de->de_pid;
|
||||
return de->de_id;
|
||||
}
|
||||
|
||||
/*! Check if db exists
|
||||
|
|
|
|||
|
|
@ -122,14 +122,17 @@ format_str2int(char *str)
|
|||
}
|
||||
|
||||
/*! Encode a clicon netconf message using variable argument lists
|
||||
* @param[in] id Session id of client
|
||||
* @param[in] format Variable agrument list format an XML netconf string
|
||||
* @retval msg Clicon message to send to eg clicon_msg_send()
|
||||
* @retval NULL Error
|
||||
* @retval msg Clicon message to send to eg clicon_msg_send()
|
||||
* @note if format includes %, they will be expanded according to printf rules.
|
||||
* if this is a problem, use ("%s", xml) instaead of (xml)
|
||||
* Notaly this may an issue of RFC 3896 encoded strings
|
||||
*/
|
||||
struct clicon_msg *
|
||||
clicon_msg_encode(char *format, ...)
|
||||
clicon_msg_encode(uint32_t id,
|
||||
char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
uint32_t xmllen;
|
||||
|
|
@ -149,7 +152,8 @@ clicon_msg_encode(char *format, ...)
|
|||
memset(msg, 0, len);
|
||||
/* hdr */
|
||||
msg->op_len = htonl(len);
|
||||
|
||||
msg->op_id = htonl(id);
|
||||
|
||||
/* body */
|
||||
va_start(args, format);
|
||||
vsnprintf(msg->op_body, xmllen, format, args);
|
||||
|
|
@ -161,16 +165,21 @@ clicon_msg_encode(char *format, ...)
|
|||
/*! Decode a clicon netconf message
|
||||
* @param[in] msg CLICON msg
|
||||
* @param[in] yspec Yang specification, (can be NULL)
|
||||
* @param[out] id Session id
|
||||
* @param[out] xml XML parse tree
|
||||
*/
|
||||
int
|
||||
clicon_msg_decode(struct clicon_msg *msg,
|
||||
yang_stmt *yspec,
|
||||
uint32_t *id,
|
||||
cxobj **xml)
|
||||
{
|
||||
int retval = -1;
|
||||
char *xmlstr;
|
||||
|
||||
/* hdr */
|
||||
if (id)
|
||||
*id = ntohl(msg->op_id);
|
||||
/* body */
|
||||
xmlstr = msg->op_body;
|
||||
clicon_debug(1, "%s %s", __FUNCTION__, xmlstr);
|
||||
|
|
@ -569,13 +578,13 @@ send_msg_reply(int s,
|
|||
* @see send_msg_notify_xml
|
||||
*/
|
||||
static int
|
||||
send_msg_notify(int s,
|
||||
char *event)
|
||||
send_msg_notify(int s,
|
||||
char *event)
|
||||
{
|
||||
int retval = -1;
|
||||
struct clicon_msg *msg = NULL;
|
||||
|
||||
if ((msg=clicon_msg_encode("%s", event)) == NULL)
|
||||
if ((msg=clicon_msg_encode(0, "%s", event)) == NULL)
|
||||
goto done;
|
||||
if (clicon_msg_send(s, msg) < 0)
|
||||
goto done;
|
||||
|
|
@ -596,8 +605,9 @@ send_msg_notify(int s,
|
|||
* @see send_msg_notify XXX beauty contest
|
||||
*/
|
||||
int
|
||||
send_msg_notify_xml(int s,
|
||||
cxobj *xev)
|
||||
send_msg_notify_xml(clicon_handle h,
|
||||
int s,
|
||||
cxobj *xev)
|
||||
{
|
||||
int retval = -1;
|
||||
cbuf *cb = NULL;
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ clicon_rpc_netconf(clicon_handle h,
|
|||
int retval = -1;
|
||||
struct clicon_msg *msg = NULL;
|
||||
|
||||
if ((msg = clicon_msg_encode("%s", xmlstr)) < 0)
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h), "%s", xmlstr)) < 0)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, xret, sp) < 0)
|
||||
goto done;
|
||||
|
|
@ -318,7 +318,8 @@ clicon_rpc_get_config(clicon_handle h,
|
|||
cprintf(cb, "/>");
|
||||
}
|
||||
cprintf(cb, "</get-config></rpc>");
|
||||
if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL)
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"%s", cbuf_get(cb))) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
|
|
@ -384,7 +385,8 @@ clicon_rpc_edit_config(clicon_handle h,
|
|||
if (xmlstr)
|
||||
cprintf(cb, "%s", xmlstr);
|
||||
cprintf(cb, "</edit-config></rpc>");
|
||||
if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL)
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"%s", cbuf_get(cb))) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
|
|
@ -428,7 +430,8 @@ clicon_rpc_copy_config(clicon_handle h,
|
|||
char *username;
|
||||
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><copy-config><source><%s/></source><target><%s/></target></copy-config></rpc>",
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"<rpc username=\"%s\"><copy-config><source><%s/></source><target><%s/></target></copy-config></rpc>",
|
||||
username?username:"",
|
||||
db1, db2)) == NULL)
|
||||
goto done;
|
||||
|
|
@ -468,7 +471,8 @@ clicon_rpc_delete_config(clicon_handle h,
|
|||
char *username;
|
||||
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><edit-config><target><%s/></target><default-operation>none</default-operation><config operation=\"delete\"/></edit-config></rpc>",
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"<rpc username=\"%s\"><edit-config><target><%s/></target><default-operation>none</default-operation><config operation=\"delete\"/></edit-config></rpc>",
|
||||
username?username:"", db)) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
|
|
@ -503,7 +507,8 @@ clicon_rpc_lock(clicon_handle h,
|
|||
char *username;
|
||||
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><lock><target><%s/></target></lock></rpc>",
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"<rpc username=\"%s\"><lock><target><%s/></target></lock></rpc>",
|
||||
username?username:"", db)) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
|
|
@ -538,7 +543,8 @@ clicon_rpc_unlock(clicon_handle h,
|
|||
char *username;
|
||||
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><unlock><target><%s/></target></unlock></rpc>", username?username:"", db)) == NULL)
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"<rpc username=\"%s\"><unlock><target><%s/></target></unlock></rpc>", username?username:"", db)) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
|
|
@ -634,7 +640,8 @@ clicon_rpc_get(clicon_handle h,
|
|||
cprintf(cb, "/>");
|
||||
}
|
||||
cprintf(cb, "</get></rpc>");
|
||||
if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL)
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"%s", cbuf_get(cb))) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
|
|
@ -676,7 +683,8 @@ clicon_rpc_close_session(clicon_handle h)
|
|||
char *username;
|
||||
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><close-session/></rpc>",
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"<rpc username=\"%s\"><close-session/></rpc>",
|
||||
username?username:"")) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
|
|
@ -702,7 +710,7 @@ clicon_rpc_close_session(clicon_handle h)
|
|||
*/
|
||||
int
|
||||
clicon_rpc_kill_session(clicon_handle h,
|
||||
int session_id)
|
||||
uint32_t session_id)
|
||||
{
|
||||
int retval = -1;
|
||||
struct clicon_msg *msg = NULL;
|
||||
|
|
@ -711,7 +719,8 @@ clicon_rpc_kill_session(clicon_handle h,
|
|||
char *username;
|
||||
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><kill-session><session-id>%d</session-id></kill-session></rpc>",
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"<rpc username=\"%s\"><kill-session><session-id>%u</session-id></kill-session></rpc>",
|
||||
username?username:"", session_id)) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
|
|
@ -746,7 +755,8 @@ clicon_rpc_validate(clicon_handle h,
|
|||
char *username;
|
||||
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><validate><source><%s/></source></validate></rpc>", username?username:"", db)) == NULL)
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"<rpc username=\"%s\"><validate><source><%s/></source></validate></rpc>", username?username:"", db)) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
|
|
@ -778,7 +788,8 @@ clicon_rpc_commit(clicon_handle h)
|
|||
char *username;
|
||||
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><commit/></rpc>", username?username:"")) == NULL)
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"<rpc username=\"%s\"><commit/></rpc>", username?username:"")) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
|
|
@ -810,7 +821,8 @@ clicon_rpc_discard_changes(clicon_handle h)
|
|||
char *username;
|
||||
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><discard-changes/></rpc>", username?username:"")) == NULL)
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"<rpc username=\"%s\"><discard-changes/></rpc>", username?username:"")) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
|
|
@ -850,7 +862,8 @@ clicon_rpc_create_subscription(clicon_handle h,
|
|||
char *username;
|
||||
|
||||
username = clicon_username_get(h);
|
||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">"
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"<rpc username=\"%s\"><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">"
|
||||
"<stream>%s</stream>"
|
||||
"<filter type=\"xpath\" select=\"%s\" />"
|
||||
"</create-subscription></rpc>",
|
||||
|
|
@ -890,7 +903,8 @@ clicon_rpc_debug(clicon_handle h,
|
|||
|
||||
username = clicon_username_get(h);
|
||||
/* XXX: hardcoded example yang, should be clixon-config!!! */
|
||||
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><debug xmlns=\"http://clicon.org/lib\"><level>%d</level></debug></rpc>", username?username:"", level)) == NULL)
|
||||
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
|
||||
"<rpc username=\"%s\"><debug xmlns=\"http://clicon.org/lib\"><level>%d</level></debug></rpc>", username?username:"", level)) == NULL)
|
||||
goto done;
|
||||
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ main(int argc, char **argv)
|
|||
char *xmlfilename = NULL;
|
||||
char *dbdir = NULL;
|
||||
int ret;
|
||||
int pid;
|
||||
uint32_t id;
|
||||
enum operation_type op;
|
||||
cxobj *xt = NULL;
|
||||
int i;
|
||||
|
|
@ -277,8 +277,8 @@ main(int argc, char **argv)
|
|||
else if (strcmp(cmd, "lock")==0){
|
||||
if (argc != 2)
|
||||
usage(argv0);
|
||||
pid = atoi(argv[1]);
|
||||
if (xmldb_lock(h, db, pid) < 0)
|
||||
id = atoi(argv[1]);
|
||||
if (xmldb_lock(h, db, id) < 0)
|
||||
goto done;
|
||||
}
|
||||
else if (strcmp(cmd, "unlock")==0){
|
||||
|
|
@ -290,8 +290,8 @@ main(int argc, char **argv)
|
|||
else if (strcmp(cmd, "unlock_all")==0){
|
||||
if (argc != 2)
|
||||
usage(argv0);
|
||||
pid = atoi(argv[1]);
|
||||
if (xmldb_unlock_all(h, pid) < 0)
|
||||
id = atoi(argv[1]);
|
||||
if (xmldb_unlock_all(h, id) < 0)
|
||||
goto done;
|
||||
}
|
||||
else if (strcmp(cmd, "islocked")==0){
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ main(int argc,
|
|||
}
|
||||
if (clicon_xml2cbuf(cb, xc, 0, 0, -1) < 0)
|
||||
goto done;
|
||||
if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) < 0)
|
||||
if ((msg = clicon_msg_encode(getpid(), "%s", cbuf_get(cb))) < 0)
|
||||
goto done;
|
||||
if (strcmp(family, "UNIX")==0){
|
||||
if (clicon_rpc_connect_unix(msg, sockpath, &retdata, NULL) < 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue