int lipe_ssh_log_verbosity;
-static int lipe_ssh_session_start_cmd(ssh_session session, const char *cmd, ssh_channel *pchannel)
+static int
+lipe_ssh_session_start_cmd(struct lipe_ssh_context *ctx,
+ const char *cmd, ssh_channel *pchannel)
{
- ssh_channel channel = NULL;
+ ssh_session session = ctx->lsc_session;
+ char *host = ctx->lsc_host;
+ ssh_channel channel;
int rc;
assert(SSH_OK == 0);
channel = ssh_channel_new(session);
if (channel == NULL) {
- LX_ERROR("cannot create a new SSH channel: %s\n",
- ssh_get_error(session));
- rc = SSH_ERROR;
- goto out;
+ LX_ERROR("%s: cannot create new SSH channel to : %s\n",
+ host, ssh_get_error(session));
+ goto err;
}
rc = ssh_channel_open_session(channel);
if (rc != SSH_OK) {
- LX_ERROR("cannot open SSH session channel: %d: %s\n",
- rc, ssh_get_error(session));
- rc = SSH_ERROR;
- goto out;
+ LX_ERROR("%s: cannot open SSH session channel: %d: %s\n",
+ host, rc, ssh_get_error(session));
+ goto err;
}
/* This is always executed with SSH_TIMEOUT_DEFAULT internally */
rc = ssh_channel_request_exec(channel, cmd);
if (rc != SSH_OK) {
- LX_ERROR("cannot execute SSH command: %d: %s\n",
- rc, ssh_get_error(session));
- rc = SSH_ERROR;
- goto out;
+ LX_ERROR("%s: cannot execute SSH command: %d: %s\n",
+ host, rc, ssh_get_error(session));
+ goto err;
}
*pchannel = channel;
- channel = NULL;
- rc = SSH_OK;
-out:
+ return SSH_OK;
+err:
if (channel != NULL)
ssh_channel_close(channel);
ssh_channel_free(channel);
- assert(rc <= 0);
-
- return rc;
+ return SSH_ERROR;
}
/* Read std out/err back from ssh exec.
while (ssh_channel_is_open(channel) && !ssh_channel_is_eof(channel)) {
rc = ssh_channel_poll_timeout(channel, timeout_msec, is_stderr);
if (rc == SSH_ERROR) {
- LX_ERROR("polling ssh channel failed on '%s'\n", host);
+ LX_ERROR("%s: polling ssh channel failed\n", host);
break;
}
if (rc == SSH_EOF) {
rc = ssh_channel_read_nonblocking(channel, &buf[n],
bufsize-n-1, is_stderr);
if (rc == SSH_ERROR) {
- LX_ERROR("reading ssh std failed on '%s'\n", host);
+ LX_ERROR("%s: reading ssh std failed\n", host);
break;
}
return rc;
}
-static int lipe_ssh_session_exec_cmd(ssh_session session, const char *cmd,
- int *pstatus,
- char *stdout_buf, int stdout_size,
- char *stderr_buf, int stderr_size)
+static int
+lipe_ssh_session_exec_cmd(struct lipe_ssh_context *ctx,
+ const char *cmd, int *pstatus,
+ char *stdout_buf, int stdout_size,
+ char *stderr_buf, int stderr_size)
{
+ ssh_session session = ctx->lsc_session;
+ char *host = ctx->lsc_host;
ssh_channel channel = NULL;
- char *host;
- int rc, nr;
+ int rc;
- rc = lipe_ssh_session_start_cmd(session, cmd, &channel);
+ rc = lipe_ssh_session_start_cmd(ctx, cmd, &channel);
if (rc != SSH_OK)
return rc;
rc = ssh_channel_get_exit_status(channel);
if (rc < 0) {
- LX_ERROR("lipe_ssh_session_start_cmd failed: %d: %s\n",
- rc, ssh_get_error(session));
+ LX_ERROR("%s: lipe_ssh_session_start_cmd failed: %d: %s\n",
+ host, rc, ssh_get_error(session));
rc = SSH_ERROR;
goto out;
}
*pstatus = rc;
rc = SSH_OK;
out:
- ssh_options_get(session, SSH_OPTIONS_HOST, &host);
-
if (stdout_buf)
- lipe_ssh_read_std(channel, host, 5, stdout_buf, stdout_size, 0,
- NULL, NULL);
+ lipe_ssh_read_std(channel, host, 5,
+ stdout_buf, stdout_size, 0, NULL, NULL);
if (stderr_buf)
- lipe_ssh_read_std(channel, host, 5, stderr_buf, stderr_size, 1,
- NULL, NULL);
+ lipe_ssh_read_std(channel, host, 5,
+ stderr_buf, stderr_size, 1, NULL, NULL);
ssh_channel_send_eof(channel);
ssh_channel_close(channel);
static void lipe_ssh_session_destroy(ssh_session *psession)
{
- if (*psession != NULL)
- ssh_disconnect(*psession);
-
+ if (*psession == NULL)
+ return;
+ ssh_disconnect(*psession);
ssh_free(*psession);
*psession = NULL;
}
-static int lipe_ssh_session_create(ssh_session *psession, const char *host)
+/* Set SSH_TIMEOUT_DEFAULT option */
+static int
+lipe_ssh_set_session_timeout(struct lipe_ssh_context *ctx, const long timeout_sec)
+{
+ int rc = ssh_options_set(ctx->lsc_session,
+ SSH_OPTIONS_TIMEOUT, &timeout_sec);
+ if (rc == SSH_OK)
+ return rc;
+
+ LX_ERROR("%s: cannot set SSH timeout to %dsec: %d : %s\n",
+ ctx->lsc_host, timeout_sec, rc,
+ ssh_get_error(ctx->lsc_session));
+ return SSH_ERROR;
+}
+
+/* Initialize context with ne created channel */
+static int lipe_ssh_session_create(struct lipe_ssh_context *ctx)
{
- ssh_session session = NULL;
+ assert(ctx != NULL);
+ char *host = ctx->lsc_host;
+ ssh_session session;
const long timeout = 5; /* Default timeout used for ssh connect */
int rc;
assert(SSH_OK == 0);
assert(SSH_AUTH_SUCCESS == 0);
assert(SSH_ERROR < 0);
-
- assert(psession != NULL);
- assert(*psession == NULL);
assert(host != NULL);
- LX_DEBUG("creating new SSH session for host '%s'\n", host);
-
- session = ssh_new();
+ session = ctx->lsc_session = ssh_new();
if (session == NULL) {
- LX_ERROR("cannot create a new SSH session: '%s'\n",
- strerror(ENOMEM)); /* Probably. */
+ LX_ERROR("%s cannot create a new SSH session: %s\n",
+ host, strerror(ENOMEM)); /* Probably. */
rc = SSH_ERROR;
- goto out;
+ goto err;
}
/* This sets the log verbosity on the session and the thread
* local variable. */
if (lipe_ssh_log_verbosity != 0)
- ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &lipe_ssh_log_verbosity);
+ ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY,
+ &lipe_ssh_log_verbosity);
rc = ssh_options_set(session, SSH_OPTIONS_HOST, host);
if (rc != SSH_OK) {
- LX_ERROR("cannot set SSH session host to '%s': %d: %s\n",
+ LX_ERROR("%s: cannot set SSH_OPTIONS_HOST: %d: %s\n",
host, rc, ssh_get_error(session));
- rc = SSH_ERROR;
- goto out;
+ goto err;
}
- rc = ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &timeout);
- if (rc != SSH_OK) {
- LX_ERROR("cannot set SSH timeout to %ld: %d: %s\n",
- timeout, rc, ssh_get_error(session));
- rc = SSH_ERROR;
- goto out;
- }
+ rc = lipe_ssh_set_session_timeout(ctx, timeout);
+ if (rc != SSH_OK)
+ goto err;
ssh_set_blocking(session, 1);
/* Connect to the ssh server */
rc = ssh_connect(session);
if (rc != SSH_OK) {
- LX_ERROR("cannot connect SSH session to host '%s': %d: %s\n",
+ LX_ERROR("%s: cannot connect SSH session: %d: %s\n",
host, rc, ssh_get_error(session));
- rc = SSH_ERROR;
- goto out;
+ goto err;
}
/* Automatically authenticate with public key */
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
if (rc != SSH_AUTH_SUCCESS) {
- LX_ERROR("cannot authenticate SSH session to host '%s': %d: %s\n",
+ LX_ERROR("%s: cannot authenticate SSH session: %d: %s\n",
host, rc, ssh_get_error(session));
- rc = SSH_ERROR;
- goto out;
+ goto err;
}
- LX_DEBUG("created new SSH session for host '%s'\n", host);
- *psession = session;
- session = NULL;
- rc = SSH_OK;
-out:
- lipe_ssh_session_destroy(&session);
+ LX_DEBUG("%s: created new SSH session\n", host);
+ return SSH_OK;
+err:
+ lipe_ssh_session_destroy(&ctx->lsc_session);
- assert(rc <= 0);
+ assert(rc < 0);
return rc;
}
{
if (ctx->lsc_session)
return SSH_OK;
- return lipe_ssh_session_create(&ctx->lsc_session, ctx->lsc_host);
-}
-
-static void lipe_ssh_context_fail(struct lipe_ssh_context *ctx)
-{
- LX_DEBUG("failing SSH context for host '%s'\n", ctx->lsc_host);
- lipe_ssh_session_destroy(&ctx->lsc_session);
+ return lipe_ssh_session_create(ctx);
}
void lipe_ssh_context_destroy(struct lipe_ssh_context *ctx)
ctx->lsc_host = xstrdup(host);
- /* Session creation will be done on demand. */
-
return SSH_OK;
}
if (timeout_sec == LIPE_SSH_TIMEOUT_INFINITE)
timeout_sec = 0; /* Blocking with timeout 0 is infinite */
- rc = ssh_options_set(ctx->lsc_session, SSH_OPTIONS_TIMEOUT, &timeout_sec);
- if (rc != SSH_OK) {
- LX_ERROR("cannot set SSH timeout to %ld: %dsec: %s\n",
- timeout_sec, rc, ssh_get_error(ctx->lsc_session));
- return SSH_ERROR;
- }
+ rc = lipe_ssh_set_session_timeout(ctx, timeout_sec);
+ if (rc != SSH_OK)
+ return rc;
- rc = lipe_ssh_session_start_cmd(ctx->lsc_session, cmd, pchannel);
+ rc = lipe_ssh_session_start_cmd(ctx, cmd, pchannel);
if (rc != SSH_OK)
- lipe_ssh_context_fail(ctx);
+ lipe_ssh_session_destroy(&ctx->lsc_session);
assert(rc <= 0);
if (timeout_sec == LIPE_SSH_TIMEOUT_INFINITE)
timeout_sec = 0; /* Blocking call with timeout 0 is infinite */
- /* Set SSH_TIMEOUT_DEFAULT */
- rc = ssh_options_set(ctx->lsc_session, SSH_OPTIONS_TIMEOUT, &timeout_sec);
- if (rc != SSH_OK) {
- LX_ERROR("cannot set SSH timeout to %ld: %dsec: %s\n",
- timeout_sec, rc, ssh_get_error(ctx->lsc_session));
- return SSH_ERROR;
- }
+ rc = lipe_ssh_set_session_timeout(ctx, timeout_sec);
+ if (rc != SSH_OK)
+ return rc;
/* Execute a remote command */
- rc = lipe_ssh_session_exec_cmd(ctx->lsc_session, cmd, pstatus,
+ rc = lipe_ssh_session_exec_cmd(ctx, cmd, pstatus,
outbuf, outbuf_size, errbuf, errbuf_size);
if (rc < 0)
- lipe_ssh_context_fail(ctx);
+ lipe_ssh_session_destroy(&ctx->lsc_session);
assert(rc <= 0);