Added CLIXON_CLIENT_SSH to client API to communicate remotely via SSH netconf sub-system
configure: stringified SSH_BIN C-API: Added `sock_flags` parameter to `clixon_proc_socket()`
This commit is contained in:
parent
100f15b699
commit
6baa904039
10 changed files with 171 additions and 95 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -41,6 +41,16 @@
|
||||||
## 6.1.0
|
## 6.1.0
|
||||||
Expected: beginning of 2023
|
Expected: beginning of 2023
|
||||||
|
|
||||||
|
### C/CLI-API changes on existing features
|
||||||
|
Developers may need to change their code
|
||||||
|
|
||||||
|
* C-API
|
||||||
|
* Added `sock_flags` parameter to `clixon_proc_socket()`
|
||||||
|
|
||||||
|
### Minor features
|
||||||
|
|
||||||
|
* Added `CLIXON_CLIENT_SSH` to client API to communicate remotely via SSH netconf sub-system
|
||||||
|
|
||||||
### Corrected Bugs
|
### Corrected Bugs
|
||||||
|
|
||||||
* Fixed [Netconf monitoring](https://github.com/clicon/clixon/issues/370)
|
* Fixed [Netconf monitoring](https://github.com/clicon/clixon/issues/370)
|
||||||
|
|
|
||||||
2
configure
vendored
2
configure
vendored
|
|
@ -4607,7 +4607,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
#define SSH_BIN $SSH_BIN
|
#define SSH_BIN "$SSH_BIN"
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ fi
|
||||||
|
|
||||||
# SSH binary path
|
# SSH binary path
|
||||||
AC_PATH_PROG(SSH_BIN, ssh)
|
AC_PATH_PROG(SSH_BIN, ssh)
|
||||||
AC_DEFINE_UNQUOTED(SSH_BIN, $SSH_BIN, [SSH binary])
|
AC_DEFINE_UNQUOTED(SSH_BIN, "$SSH_BIN", [SSH binary])
|
||||||
|
|
||||||
# Get "bison" from bison -y or other string
|
# Get "bison" from bison -y or other string
|
||||||
if test "$YACC" = "${YACC##bison}" ; then
|
if test "$YACC" = "${YACC##bison}" ; then
|
||||||
|
|
|
||||||
|
|
@ -42,11 +42,25 @@
|
||||||
typedef void *clixon_handle;
|
typedef void *clixon_handle;
|
||||||
typedef void *clixon_client_handle;
|
typedef void *clixon_client_handle;
|
||||||
|
|
||||||
/* Connection type as parameter to connect */
|
/* Connection type as parameter to connect
|
||||||
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CLIXON_CLIENT_IPC, /* Internal IPC API, only experimental use */
|
/* Internal IPC API, connect directly on local UNIX domain socket to backend
|
||||||
CLIXON_CLIENT_NETCONF, /* External Netconf */
|
* or using IP according to CLICON_SOCK_FAMILY setting
|
||||||
CLIXON_CLIENT_SSH /* NYI External Netconf over SSH */
|
* see https://clixon-docs.readthedocs.io/en/latest/netconf.html#ipc
|
||||||
|
* Must be local on device
|
||||||
|
*/
|
||||||
|
CLIXON_CLIENT_IPC,
|
||||||
|
/* Regular NETCONF via local netconf binary
|
||||||
|
* Fork clixon_netconf locally which in turn communicates with backend
|
||||||
|
* Must be local on device
|
||||||
|
*/
|
||||||
|
CLIXON_CLIENT_NETCONF,
|
||||||
|
/* Regular NETCONF using ssh sub-system via local SSH (openssh) client binary
|
||||||
|
* Fork ssh locally which in turn communicates remotely to device
|
||||||
|
* Must have openssh installed locally and device must have ssh sub-subsystem
|
||||||
|
*/
|
||||||
|
CLIXON_CLIENT_SSH
|
||||||
} clixon_client_type;
|
} clixon_client_type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -59,7 +73,9 @@ extern "C" {
|
||||||
|
|
||||||
clixon_handle clixon_client_init(const char *config_file);
|
clixon_handle clixon_client_init(const char *config_file);
|
||||||
int clixon_client_terminate(clixon_handle h);
|
int clixon_client_terminate(clixon_handle h);
|
||||||
clixon_client_handle clixon_client_connect(clixon_handle h, clixon_client_type socktype);
|
int clixon_client_lock(int sock, const int lock, const char *db);
|
||||||
|
int clixon_client_hello(int sock, int version);
|
||||||
|
clixon_client_handle clixon_client_connect(clixon_handle h, clixon_client_type socktype, const char *dest);
|
||||||
int clixon_client_disconnect(clixon_client_handle ch);
|
int clixon_client_disconnect(clixon_client_handle ch);
|
||||||
int clixon_client_get_bool(clixon_client_handle ch, int *rval, const char *xnamespace, const char *xpath);
|
int clixon_client_get_bool(clixon_client_handle ch, int *rval, const char *xnamespace, const char *xpath);
|
||||||
int clixon_client_get_str(clixon_client_handle ch, char *rval, int n, const char *xnamespace, const char *xpath);
|
int clixon_client_get_str(clixon_client_handle ch, char *rval, int n, const char *xnamespace, const char *xpath);
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ enum error_option{ /* edit-config */
|
||||||
/* NETCONF framing
|
/* NETCONF framing
|
||||||
*/
|
*/
|
||||||
enum framing_type{
|
enum framing_type{
|
||||||
NETCONF_SSH_EOM, /* RFC 4742, RFC 6242 hello msg (end-of-msg: ]]>]]>)*/
|
NETCONF_SSH_EOM=0, /* RFC 4742, RFC 6242 hello msg (end-of-msg: ]]>]]>)*/
|
||||||
NETCONF_SSH_CHUNKED, /* RFC 6242 Chunked framing */
|
NETCONF_SSH_CHUNKED, /* RFC 6242 Chunked framing */
|
||||||
};
|
};
|
||||||
typedef enum framing_type netconf_framing_type;
|
typedef enum framing_type netconf_framing_type;
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ typedef int (proc_cb_t)(clicon_handle h, process_entry_t *pe, proc_operation *op
|
||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int clixon_proc_socket(char **argv, pid_t *pid, int *sock);
|
int clixon_proc_socket(char **argv, int sock_flags, pid_t *pid, int *sock);
|
||||||
int clixon_proc_socket_close(pid_t pid, int sock);
|
int clixon_proc_socket_close(pid_t pid, int sock);
|
||||||
int clixon_proc_background(char **argv, const char *netns, pid_t *pid);
|
int clixon_proc_background(char **argv, const char *netns, pid_t *pid);
|
||||||
int clixon_process_pid(clicon_handle h, const char *name, pid_t *pid);
|
int clixon_process_pid(clicon_handle h, const char *name, pid_t *pid);
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ clixon_client_terminate(clicon_handle h)
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
clixon_client_lock(int sock,
|
clixon_client_lock(int sock,
|
||||||
const int lock,
|
const int lock,
|
||||||
const char *db)
|
const char *db)
|
||||||
|
|
@ -204,15 +204,14 @@ clixon_client_lock(int sock,
|
||||||
|
|
||||||
/*! Internal function to construct the encoding and hello message
|
/*! Internal function to construct the encoding and hello message
|
||||||
*
|
*
|
||||||
* @param[in] sock Socket
|
* @param[in] sock Socket to netconf server
|
||||||
* @param[in] namespace Default namespace used for non-prefixed entries in xpath. (Alt use nsc)
|
* @param[in] version Netconf version for capability announcement
|
||||||
* @param[in] xpath XPath
|
* @retval 0 OK
|
||||||
* @param[out] xdata XML data tree (may or may not include the intended data)
|
* @retval -1 Error
|
||||||
* @retval 0 OK
|
|
||||||
* @retval -1 Error
|
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
clixon_client_hello(int sock)
|
clixon_client_hello(int sock,
|
||||||
|
int version)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cbuf *msg = NULL;
|
cbuf *msg = NULL;
|
||||||
|
|
@ -222,9 +221,11 @@ clixon_client_hello(int sock)
|
||||||
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
cprintf(msg, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
// cprintf(msg, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||||
cprintf(msg, "<hello xmlns=\"%s\">", NETCONF_BASE_NAMESPACE);
|
cprintf(msg, "<hello xmlns=\"%s\">", NETCONF_BASE_NAMESPACE);
|
||||||
cprintf(msg, "<capabilities><capability>%s</capability></capabilities>", NETCONF_BASE_CAPABILITY_1_1);
|
cprintf(msg, "<capabilities>");
|
||||||
|
cprintf(msg, "<capability>%s</capability>", version==0?NETCONF_BASE_CAPABILITY_1_0:NETCONF_BASE_CAPABILITY_1_1);
|
||||||
|
cprintf(msg, "</capabilities>");
|
||||||
cprintf(msg, "</hello>");
|
cprintf(msg, "</hello>");
|
||||||
cprintf(msg, "]]>]]>");
|
cprintf(msg, "]]>]]>");
|
||||||
if (clicon_msg_send1(sock, msg) < 0)
|
if (clicon_msg_send1(sock, msg) < 0)
|
||||||
|
|
@ -237,25 +238,112 @@ clixon_client_hello(int sock)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
clixon_client_connect_netconf(clicon_handle h,
|
||||||
|
struct clixon_client_handle *cch)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
int nr;
|
||||||
|
int i;
|
||||||
|
char **argv = NULL;
|
||||||
|
char *netconf_bin = NULL;
|
||||||
|
struct stat st = {0,};
|
||||||
|
char dbgstr[8];
|
||||||
|
|
||||||
|
nr = 7;
|
||||||
|
if (clicon_debug_get() != 0)
|
||||||
|
nr += 2;
|
||||||
|
if ((argv = calloc(nr, sizeof(char *))) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "calloc");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
if ((netconf_bin = getenv("CLIXON_NETCONF_BIN")) == NULL)
|
||||||
|
netconf_bin = CLIXON_NETCONF_BIN;
|
||||||
|
if (stat(netconf_bin, &st) < 0){
|
||||||
|
clicon_err(OE_NETCONF, errno, "netconf binary %s. Set with CLIXON_NETCONF_BIN=",
|
||||||
|
netconf_bin);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
argv[i++] = netconf_bin;
|
||||||
|
argv[i++] = "-q";
|
||||||
|
argv[i++] = "-f";
|
||||||
|
argv[i++] = clicon_option_str(h, "CLICON_CONFIGFILE");
|
||||||
|
argv[i++] = "-l"; /* log to syslog */
|
||||||
|
argv[i++] = "s";
|
||||||
|
if (clicon_debug_get() != 0){
|
||||||
|
argv[i++] = "-D";
|
||||||
|
snprintf(dbgstr, sizeof(dbgstr)-1, "%d", clicon_debug_get());
|
||||||
|
argv[i++] = dbgstr;
|
||||||
|
}
|
||||||
|
argv[i++] = NULL;
|
||||||
|
assert(i==nr);
|
||||||
|
if (clixon_proc_socket(argv, SOCK_DGRAM, &cch->cch_pid, &cch->cch_socket) < 0){
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
clixon_client_connect_ssh(clicon_handle h,
|
||||||
|
struct clixon_client_handle *cch,
|
||||||
|
const char *dest)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
int nr;
|
||||||
|
int i;
|
||||||
|
char **argv = NULL;
|
||||||
|
char *ssh_bin = SSH_BIN;
|
||||||
|
struct stat st = {0,};
|
||||||
|
|
||||||
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
|
nr = 5;
|
||||||
|
if ((argv = calloc(nr, sizeof(char *))) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "calloc");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
if (stat(ssh_bin, &st) < 0){
|
||||||
|
clicon_err(OE_NETCONF, errno, "ssh binary %s", ssh_bin);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
argv[i++] = ssh_bin;
|
||||||
|
argv[i++] = (char*)dest;
|
||||||
|
argv[i++] = "-s";
|
||||||
|
argv[i++] = "netconf";
|
||||||
|
argv[i++] = NULL;
|
||||||
|
assert(i==nr);
|
||||||
|
for (i=0;i<nr;i++)
|
||||||
|
clicon_debug(1, "%s: argv[%d]:%s", __FUNCTION__, i, argv[i]);
|
||||||
|
if (clixon_proc_socket(argv, SOCK_STREAM, &cch->cch_pid, &cch->cch_socket) < 0){
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Connect client to clixon backend according to config and return a socket
|
/*! Connect client to clixon backend according to config and return a socket
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] socktype Type of socket, internal/external/netconf/ssh
|
* @param[in] socktype Type of socket, internal/external/netconf/ssh
|
||||||
|
* @param[in] dest Destination for some types
|
||||||
* @retval ch Clixon session handler
|
* @retval ch Clixon session handler
|
||||||
* @retval NULL Error
|
* @retval NULL Error
|
||||||
* @see clixon_client_disconnect Close the socket returned here
|
* @see clixon_client_disconnect Close the socket returned here
|
||||||
*/
|
*/
|
||||||
clixon_client_handle
|
clixon_client_handle
|
||||||
clixon_client_connect(clicon_handle h,
|
clixon_client_connect(clicon_handle h,
|
||||||
clixon_client_type socktype)
|
clixon_client_type socktype,
|
||||||
|
const char *dest)
|
||||||
{
|
{
|
||||||
struct clixon_client_handle *cch = NULL;
|
struct clixon_client_handle *cch = NULL;
|
||||||
char **argv = NULL;
|
|
||||||
int nr;
|
|
||||||
int i;
|
|
||||||
char *netconf_bin = NULL;
|
|
||||||
struct stat st = {0,};
|
|
||||||
size_t sz = sizeof(struct clixon_client_handle);
|
size_t sz = sizeof(struct clixon_client_handle);
|
||||||
char dbgstr[8];
|
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
if ((cch = malloc(sz)) == NULL){
|
if ((cch = malloc(sz)) == NULL){
|
||||||
|
|
@ -271,48 +359,19 @@ clixon_client_connect(clicon_handle h,
|
||||||
goto err;
|
goto err;
|
||||||
break;
|
break;
|
||||||
case CLIXON_CLIENT_NETCONF:
|
case CLIXON_CLIENT_NETCONF:
|
||||||
nr = 7;
|
if (clixon_client_connect_netconf(h, cch) < 0)
|
||||||
if (clicon_debug_get() != 0)
|
|
||||||
nr += 2;
|
|
||||||
if ((argv = calloc(nr, sizeof(char *))) == NULL){
|
|
||||||
clicon_err(OE_UNIX, errno, "calloc");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
if ((netconf_bin = getenv("CLIXON_NETCONF_BIN")) == NULL)
|
|
||||||
netconf_bin = CLIXON_NETCONF_BIN;
|
|
||||||
if (stat(netconf_bin, &st) < 0){
|
|
||||||
clicon_err(OE_NETCONF, errno, "netconf binary %s. Set with CLIXON_NETCONF_BIN=",
|
|
||||||
netconf_bin);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
argv[i++] = netconf_bin;
|
|
||||||
argv[i++] = "-q";
|
|
||||||
argv[i++] = "-f";
|
|
||||||
argv[i++] = clicon_option_str(h, "CLICON_CONFIGFILE");
|
|
||||||
argv[i++] = "-l"; /* log to syslog */
|
|
||||||
argv[i++] = "s";
|
|
||||||
if (clicon_debug_get() != 0){
|
|
||||||
argv[i++] = "-D";
|
|
||||||
snprintf(dbgstr, sizeof(dbgstr)-1, "%d", clicon_debug_get());
|
|
||||||
argv[i++] = dbgstr;
|
|
||||||
}
|
|
||||||
argv[i++] = NULL;
|
|
||||||
assert(i==nr);
|
|
||||||
if (clixon_proc_socket(argv, &cch->cch_pid, &cch->cch_socket) < 0){
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
/* Start with encoding and hello message */
|
|
||||||
if (clixon_client_hello(cch->cch_socket) < 0)
|
|
||||||
goto err;
|
goto err;
|
||||||
break;
|
break;
|
||||||
|
#ifdef SSH_BIN
|
||||||
case CLIXON_CLIENT_SSH:
|
case CLIXON_CLIENT_SSH:
|
||||||
|
if (clixon_client_connect_ssh(h, cch, dest) < 0)
|
||||||
|
goto err;
|
||||||
|
#else
|
||||||
|
clicon_err(OE_UNIX, 0, "No ssh bin");
|
||||||
|
goto done;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
} /* switch */
|
} /* switch */
|
||||||
/* lock */
|
|
||||||
if (clixon_client_lock(cch->cch_socket, 1, "running") < 0)
|
|
||||||
goto err;
|
|
||||||
cch->cch_locked = 1;
|
|
||||||
done:
|
done:
|
||||||
clicon_debug(1, "%s retval:%p", __FUNCTION__, cch);
|
clicon_debug(1, "%s retval:%p", __FUNCTION__, cch);
|
||||||
return cch;
|
return cch;
|
||||||
|
|
@ -347,13 +406,12 @@ clixon_client_disconnect(clixon_client_handle ch)
|
||||||
case CLIXON_CLIENT_IPC:
|
case CLIXON_CLIENT_IPC:
|
||||||
close(cch->cch_socket);
|
close(cch->cch_socket);
|
||||||
break;
|
break;
|
||||||
|
case CLIXON_CLIENT_SSH:
|
||||||
case CLIXON_CLIENT_NETCONF:
|
case CLIXON_CLIENT_NETCONF:
|
||||||
if (clixon_proc_socket_close(cch->cch_pid,
|
if (clixon_proc_socket_close(cch->cch_pid,
|
||||||
cch->cch_socket) < 0)
|
cch->cch_socket) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
break;
|
break;
|
||||||
case CLIXON_CLIENT_SSH:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
free(cch);
|
free(cch);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
@ -403,6 +461,7 @@ clixon_xml_bottom(cxobj *xtop,
|
||||||
* @param[out] xdata XML data tree (may or may not include the intended data)
|
* @param[out] xdata XML data tree (may or may not include the intended data)
|
||||||
* @retval 0 OK
|
* @retval 0 OK
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
* @note configurable netconf framing type, now hardwired to 0
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
clixon_client_get_xdata(int sock,
|
clixon_client_get_xdata(int sock,
|
||||||
|
|
@ -445,9 +504,11 @@ clixon_client_get_xdata(int sock,
|
||||||
cprintf(msg, "/>");
|
cprintf(msg, "/>");
|
||||||
}
|
}
|
||||||
cprintf(msg, "</get-config></rpc>");
|
cprintf(msg, "</get-config></rpc>");
|
||||||
if (netconf_output_encap(NETCONF_SSH_CHUNKED, msg) < 0)
|
if (netconf_output_encap(0, msg) < 0) // XXX configurable session
|
||||||
goto done;
|
goto done;
|
||||||
if (clicon_rpc1(sock, msg, msgret, &eof) < 0)
|
if (clicon_msg_send1(sock, msg) < 0)
|
||||||
|
goto done;
|
||||||
|
if (clicon_msg_rcv1(sock, msgret, &eof) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (eof){
|
if (eof){
|
||||||
close(sock);
|
close(sock);
|
||||||
|
|
|
||||||
|
|
@ -163,15 +163,18 @@ clixon_proc_sigint(int sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Fork a child, exec a child and setup socket to child and return to caller
|
/*! Fork a child, exec a child and setup socket to child and return to caller
|
||||||
* @param[in] argv NULL-terminated Argument vector
|
* @param[in] argv NULL-terminated Argument vector
|
||||||
* @param[in] doerr If non-zero, stderr will be directed to the pipe as well.
|
* @param[in] sock_flags Socket type/flags, typically SOCK_DGRAM or SOCK_STREAM, see
|
||||||
* @param[out] s Socket
|
* @param[out] pid Process-id of child
|
||||||
* @retval O OK
|
* @param[out] sock Socket
|
||||||
* @retval -1 Error.
|
* @retval O OK
|
||||||
|
* @retval -1 Error.
|
||||||
* @see clixon_proc_socket_close close sockets, kill child and wait for child termination
|
* @see clixon_proc_socket_close close sockets, kill child and wait for child termination
|
||||||
|
* @see for flags usage see man sockerpair(2)
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clixon_proc_socket(char **argv,
|
clixon_proc_socket(char **argv,
|
||||||
|
int sock_flags,
|
||||||
pid_t *pid,
|
pid_t *pid,
|
||||||
int *sock)
|
int *sock)
|
||||||
{
|
{
|
||||||
|
|
@ -182,12 +185,6 @@ clixon_proc_socket(char **argv,
|
||||||
sigset_t oset;
|
sigset_t oset;
|
||||||
int sig = 0;
|
int sig = 0;
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
int sock_flags = SOCK_DGRAM;
|
|
||||||
#else
|
|
||||||
int sock_flags = SOCK_DGRAM | SOCK_CLOEXEC;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (argv == NULL){
|
if (argv == NULL){
|
||||||
clicon_err(OE_UNIX, EINVAL, "argv is NULL");
|
clicon_err(OE_UNIX, EINVAL, "argv is NULL");
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -197,18 +194,6 @@ clixon_proc_socket(char **argv,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
if (fcntl(sp[0], O_CLOEXEC)) {
|
|
||||||
clicon_err(OE_UNIX, errno, "fcntl, sp[0]");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fcntl(sp[1], O_CLOEXEC)) {
|
|
||||||
clicon_err(OE_UNIX, errno, "fcntl, sp[1]");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sigprocmask(0, NULL, &oset);
|
sigprocmask(0, NULL, &oset);
|
||||||
set_signal(SIGINT, clixon_proc_sigint, &oldhandler);
|
set_signal(SIGINT, clixon_proc_sigint, &oldhandler);
|
||||||
sig++;
|
sig++;
|
||||||
|
|
|
||||||
|
|
@ -433,6 +433,7 @@ clicon_msg_rcv(int s,
|
||||||
* @param[out] eof Set if eof encountered
|
* @param[out] eof Set if eof encountered
|
||||||
* @see netconf_input_cb()
|
* @see netconf_input_cb()
|
||||||
* @see clicon_msg_rcv using IPC message struct
|
* @see clicon_msg_rcv using IPC message struct
|
||||||
|
* @note only NETCONF version 1.0 EOM framing
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clicon_msg_rcv1(int s,
|
clicon_msg_rcv1(int s,
|
||||||
|
|
@ -502,7 +503,7 @@ clicon_msg_send1(int s,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
|
|
||||||
if (atomicio((ssize_t (*)(int, void *, size_t))write,
|
if (atomicio((ssize_t (*)(int, void *, size_t))write,
|
||||||
s, cbuf_get(cb), cbuf_len(cb)+1) < 0){
|
s, cbuf_get(cb), cbuf_len(cb)) < 0){
|
||||||
clicon_err(OE_CFG, errno, "atomicio");
|
clicon_err(OE_CFG, errno, "atomicio");
|
||||||
clicon_log(LOG_WARNING, "%s: write: %s", __FUNCTION__, strerror(errno));
|
clicon_log(LOG_WARNING, "%s: write: %s", __FUNCTION__, strerror(errno));
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -85,8 +85,9 @@ main(int argc,
|
||||||
char **argv)
|
char **argv)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
clixon_handle h = NULL; /* clixon handle */
|
clixon_handle h = NULL; /* clixon handle */
|
||||||
clixon_client_handle ch = NULL; /* clixon client handle */
|
clixon_client_handle ch = NULL; /* clixon client handle */
|
||||||
|
int s;
|
||||||
|
|
||||||
clicon_log_init("client", LOG_DEBUG, CLICON_LOG_STDERR); // debug
|
clicon_log_init("client", LOG_DEBUG, CLICON_LOG_STDERR); // debug
|
||||||
clicon_debug_init($debug, NULL); // debug
|
clicon_debug_init($debug, NULL); // debug
|
||||||
|
|
@ -95,9 +96,11 @@ main(int argc,
|
||||||
if ((h = clixon_client_init("$cfg")) == NULL)
|
if ((h = clixon_client_init("$cfg")) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
/* Make a connection over netconf or ssh/netconf */
|
/* Make a connection over netconf or ssh/netconf */
|
||||||
if ((ch = clixon_client_connect(h, CLIXON_CLIENT_NETCONF)) == NULL)
|
if ((ch = clixon_client_connect(h, CLIXON_CLIENT_NETCONF, NULL)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
s = clixon_client_socket_get(ch);
|
||||||
|
if (clixon_client_hello(s, 0) < 0)
|
||||||
|
return -1;
|
||||||
/* Here are read functions depending on an example YANG
|
/* Here are read functions depending on an example YANG
|
||||||
* (Need an example YANG and XML input to confd)
|
* (Need an example YANG and XML input to confd)
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue