diff options
| -rw-r--r-- | .gitignore | 18 | ||||
| -rw-r--r-- | Makefile.am | 21 | ||||
| -rw-r--r-- | configure.ac | 33 | ||||
| -rw-r--r-- | src/Makefile.am | 23 | ||||
| -rw-r--r-- | src/channel.c | 241 | ||||
| -rw-r--r-- | src/channel.h | 8 | ||||
| -rw-r--r-- | src/channel.scm | 32 | ||||
| -rw-r--r-- | src/session.c | 382 | ||||
| -rw-r--r-- | src/session.h | 8 | ||||
| -rw-r--r-- | src/session.scm | 31 | ||||
| -rw-r--r-- | src/ssh-error.c | 31 | ||||
| -rw-r--r-- | src/ssh-error.h | 8 |
12 files changed, 836 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5300564 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# -*- shell-script -*- + +# Backup files +*\~ + +# Object files and static libraries +*.o + +# Auto-generated Makefile +Makefile + +config.log +config.status +.deps +autom4te.cache + +TAGS +tags
\ No newline at end of file diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..7d72ec0 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,21 @@ +## Config file for GNU Automake. +## +## Copyright (C) 2013 Artyom V. Poptsov <poptsov.artyom@gmail.com> +## +## This file is part of libguile-ssh. +## +## libguile-ssh is free software: you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation, either version 3 of the +## License, or (at your option) any later version. +## +## libguile-ssh is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with libguile-ssh. If not, see <http://www.gnu.org/licenses/>. + +SUBDIRS = src + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..f995ee4 --- /dev/null +++ b/configure.ac @@ -0,0 +1,33 @@ +## Copyright (C) 2013 Artyom V. Poptsov <poptsov.artyom@gmail.com> +## +## This file is part of libguile-ssh. +## +## libguile-ssh is free software: you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation, either version 3 of the +## License, or (at your option) any later version. +## +## libguile-ssh is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with libguile-ssh. If not, see <http://www.gnu.org/licenses/>. + +AC_INIT([libguile-ssh], [0.1], [poptsov.artyom@gmail.com]) + +AM_INIT_AUTOMAKE + +AC_PROG_CC + +GUILE_PROGS +GUILE_FLAGS + +# Check for libssh +AC_SEARCH_LIBS([ssh_new], [ssh], [], AC_MSG_ERROR([libssh is not found.], [1])) + +AC_CONFIG_FILES([Makefile]) + +# Generate a Makefile, based on the results. +AC_OUTPUT() diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..f2492e5 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,23 @@ +## Copyright (C) 2013 Artyom V. Poptsov <poptsov.artyom@gmail.com> +## +## This file is part of libguile-ssh. +## +## libguile-ssh is free software: you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation, either version 3 of the +## License, or (at your option) any later version. +## +## libguile-ssh is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with libguile-ssh. If not, see <http://www.gnu.org/licenses/>. + +AM_CFLAGS = @GUILE_CFLAGS@ -lssh `pkg-config --cflags guile-1.8` +AM_LDFLAGS=`pkg-config --libs guile-1.8` -lssh + +lib_LTLIBRARIES = libguile-ssh.la + +libguile_ssh_la_SOURCES = channel.c session.c diff --git a/src/channel.c b/src/channel.c new file mode 100644 index 0000000..55c10e4 --- /dev/null +++ b/src/channel.c @@ -0,0 +1,241 @@ +/* channel.c -- SSH channel smob. + * + * Copyright (C) 2013 Artyom V. Poptsov <poptsov.artyom@gmail.com> + * + * This file is part of libguile-ssh + * + * libguile-ssh is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * libguile-ssh is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libguile-ssh. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libguile.h> +#include <libssh/libssh.h> + +#include "session.h" +#include "channel.h" +#include "ssh-error.h" + +static scm_t_bits channel_tag; /* Smob tag. */ + + +/* Smob specific procedures */ + +SCM +mark_channel (SCM channel_smob) +{ + return SCM_BOOL_F; +} + +size_t +free_channel (SCM channel_smob) +{ + struct channel_data *data + = (struct channel_data *) SCM_SMOB_DATA (channel_smob); + + ssh_channel_free (data->ssh_channel); + + return 0; +} + +/* Allocate a new SSH channel. */ +SCM +guile_ssh_make_channel (SCM session_smob) +{ + SCM smob; + + struct session_data *session_data + = (struct session_data *) SCM_SMOB_DATA (session_smob); + + struct channel_data *channel_data + = (struct channel_data *) scm_gc_malloc (sizeof (struct channel_data), + "channel"); + channel_data->ssh_channel = ssh_channel_new (session_data->ssh_session); + if (channel_data->ssh_channel == NULL) + { + ssh_error (__func__, "Couldn't allocate a new channel.", + SCM_BOOL_F, SCM_BOOL_F); + } + + SCM_NEWSMOB (smob, channel_tag, channel_data); + + return smob; +} + + +/* SSH channel specific procedures. */ + +/* Close a channel. */ +SCM +guile_ssh_channel_close (SCM channel_smob) +{ + struct channel_data *data + = (struct channel_data *) SCM_SMOB_DATA (channel_smob); + + int res; /* Result of a function call. */ + + res = ssh_channel_close (data->ssh_channel); + + return res ? SCM_BOOL_T : SCM_BOOL_F; +} + +SCM +guile_ssh_channel_open_session (SCM channel_smob) +{ + struct channel_data *data + = (struct channel_data *) SCM_SMOB_DATA (channel_smob); + + int res; /* Result of a function call. */ + + res = ssh_channel_open_session (data->ssh_channel); + + return (res == SSH_OK) ? SCM_BOOL_T : SCM_BOOL_F; +} + +/* Run a shell command without an interactive shell. */ +SCM +guile_ssh_channel_request_exec (SCM channel_smob, SCM cmd) +{ + struct channel_data *data + = (struct channel_data *) SCM_SMOB_DATA (channel_smob); + + int res; /* Result of a function call. */ + char *c_cmd; /* Command to execute. */ + + SCM_ASSERT (scm_is_string (cmd), cmd, SCM_ARG2, __func__); + + c_cmd = scm_to_locale_string (cmd); + + res = ssh_channel_request_exec (data->ssh_channel, c_cmd); + + free (c_cmd); + + return (res == SSH_OK) ? SCM_BOOL_T : SCM_BOOL_F; +} + +/* Poll a channel for data to read. + * + * Return amount of data that can be read, or #f on error. + */ +SCM +guile_ssh_channel_pool (SCM channel_smob, SCM is_stderr) +{ + struct channel_data *data + = (struct channel_data *) SCM_SMOB_DATA (channel_smob); + + int res; /* Result of a function call. */ + + SCM_ASSERT (scm_is_boolean (is_stderr), is_stderr, SCM_ARG2, __func__); + + res = ssh_channel_poll (data->ssh_channel, scm_is_true (is_stderr)); + + if (res >= 0) + return scm_from_int (res); + else + return SCM_BOOL_F; +} + +SCM +guile_ssh_channel_read (SCM channel_smob, SCM count, SCM is_stderr) +{ + struct channel_data *data + = (struct channel_data *) SCM_SMOB_DATA (channel_smob); + + int res; /* Result of a function call. */ + char *buffer; /* Buffer for data. */ + uint32_t c_count; /* Size of buffer. */ + SCM data; /* Obtained data from the channel. */ + + scm_dynwind_begin (0); + + SCM_ASSERT (scm_is_unsigned_integer (count, 0, UINT32_MAX), count, + SCM_ARG2, __func__); + SCM_ASSERT (scm_is_boolean (is_stderr), is_stderr, SCM_ARG3, __func__); + + c_count = scm_to_unsigned_integer (count, 0, UINT32_MAX); + + buffer = scm_gc_malloc (sizeof (char) * c_count, "data buffer"); + scm_dynwind_free (buffer); + + res = ssh_channel_read (data->ssh_channel, buffer, count, + scm_is_true (is_stderr)); + + if (res > 0) + { + data = scm_from_locale_string (buffer); + } + else if (res == 0) + { + data = SCM_BOOL_F; + } + else + { + ssh_error (__func__, "Couldn't read data from a channel.", + SCM_BOOL_F, SCM_BOOL_F); + } + + scm_dynwind_end (); + + return data; +} + + +/* Predicates */ + +SCM +guile_ssh_channel_is_open (SCM channel_smob) +{ + struct channel_data *data + = (struct channel_data *) SCM_SMOB_DATA (channel_smob); + + int res; /* Result of a function call. */ + + res = ssh_channel_is_open (data->ssh_channel); + + return res ? SCM_BOOL_T : SCM_BOOL_F; +} + +SCM +guile_ssh_channel_is_eof (SCM channel_smob) +{ + struct channel_data *data + = (struct channel_data *) SCM_SMOB_DATA (channel_smob); + + int res; /* Result of a function call. */ + + res = ssh_channel_is_eof (data->ssh_channel); + + return res ? SCM_BOOL_T : SCM_BOOL_F; +} + + +/* channel smob initialization. */ +void +init_channel_type (void) +{ + channel_tag = scm_make_smob_type ("ssh:channel", sizeof (struct channel_data)); + scm_set_smob_mark (channel_tag, mark_channel); + scm_set_smob_free (channel_tag, free_channel); + + scm_c_define_gsubr ("ssh:make-channel", 1, 0, 0, guile_ssh_make_channel); + scm_c_define_gsubr ("ssh:close-channel!", 1, 0, 0, guile_ssh_channel_close); + scm_c_define_gsubr ("ssh:channel-request-exec", 2, 0, 0, + guile_ssh_channel_request_exec); + + scm_c_define_gsubr ("ssh:channel-poll", 2, 0, 0, guile_ssh_channel_pool); + scm_c_define_gsubr ("ssh:channel-read", 3, 0, 0, guile_ssh_channel_read); + + scm_c_define_gsubr ("ssh:channel-open?", 1, 0, 0, guile_ssh_channel_is_open); + scm_c_define_gsubr ("ssh:channel-eof?", 1, 0, 0, guile_ssh_channel_is_eof); +} + +/* channel.c ends here */ diff --git a/src/channel.h b/src/channel.h new file mode 100644 index 0000000..f0df8ac --- /dev/null +++ b/src/channel.h @@ -0,0 +1,8 @@ +#ifndef __CHANNEL_H__ +#define __CHANNEL_H__ + +struct channel_data { + ssh_channel ssh_channel; +}; + +#endif /* ifndef __CHANNEL_H__ */ diff --git a/src/channel.scm b/src/channel.scm new file mode 100644 index 0000000..7e45387 --- /dev/null +++ b/src/channel.scm @@ -0,0 +1,32 @@ +;;; channel.scm -- + +;; Copyright (C) 2013 Artyom V. Poptsov <poptsov.artyom@gmail.com> +;; +;; + + +;;; Commentary: + +;; +;; +;; These methods are exported: +;; +;; + + +;;; Code: + +(define-module (ssh channel) + #:use-module (ssh session) + #:export (ssh:channel + ssh:make-channel + ssh:close-channel! + ssh:channel-request-exec + ssh:channel-poll + ssh:channel-read + ssh:channel-open? + ssh:channel-eof?)) + +(load-extension "libguile-ssh" "init_channel_type") + +;;; channel.scm ends here. diff --git a/src/session.c b/src/session.c new file mode 100644 index 0000000..4d8cec2 --- /dev/null +++ b/src/session.c @@ -0,0 +1,382 @@ +/* session.c -- SSH session smob. + * + * Copyright (C) 2013 Artyom V. Poptsov <poptsov.artyom@gmail.com> + * + * This file is part of libguile-ssh + * + * libguile-ssh is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * libguile-ssh is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libguile-ssh. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libguile.h> +#include <libssh/libssh.h> +#include <string.h> + +#include "session.h" +#include "ssh-error.h" + +#define PRINT_DEBUG(data)\ + scm_display (data, scm_current_output_port ()) + +static scm_t_bits session_tag; /* Smob tag. */ + +/* SSH options mapping to Guile symbols. */ +struct option session_options[] = { + { "host", SSH_OPTIONS_HOST }, + { "port", SSH_OPTIONS_PORT }, + { "port-str", SSH_OPTIONS_PORT_STR }, + { "fd", SSH_OPTIONS_FD }, + { "user", SSH_OPTIONS_USER }, + { "ssh-dir", SSH_OPTIONS_SSH_DIR }, + { "identity", SSH_OPTIONS_IDENTITY }, + { "add-identity", SSH_OPTIONS_ADD_IDENTITY }, + { "knownhosts", SSH_OPTIONS_KNOWNHOSTS }, + { "timeout", SSH_OPTIONS_TIMEOUT }, + { "timeout-usec", SSH_OPTIONS_TIMEOUT_USEC }, + { "ssh1", SSH_OPTIONS_SSH1 }, + { "ssh2", SSH_OPTIONS_SSH2 }, + { "log-verbosity", SSH_OPTIONS_LOG_VERBOSITY }, + { "log-verbosity-str", SSH_OPTIONS_LOG_VERBOSITY_STR }, + { "ciphers-c-s", SSH_OPTIONS_CIPHERS_C_S }, + { "ciphers-s-c", SSH_OPTIONS_CIPHERS_S_C }, + { "compression-c-s", SSH_OPTIONS_COMPRESSION_C_S }, + { "compression-s-c", SSH_OPTIONS_COMPRESSION_S_C }, + { "proxycommand", SSH_OPTIONS_PROXYCOMMAND }, + { "bindaddr", SSH_OPTIONS_BINDADDR }, + { "strcthostkeycheck", SSH_OPTIONS_STRICTHOSTKEYCHECK }, + { "compression", SSH_OPTIONS_COMPRESSION }, + { "compression-level", SSH_OPTIONS_COMPRESSION_LEVEL }, + { NULL, -1 } +}; + +SCM +mark_session (SCM session_smob) +{ + return SCM_BOOL_F; +} + +/* Handle GC'ing of the session smob. */ +size_t +free_session (SCM session_smob) +{ + struct session_data *data + = (struct session_data *) SCM_SMOB_DATA (session_smob); + + ssh_disconnect (data->ssh_session); + ssh_free (data->ssh_session); + return 0; +} + +/* Blocking flush of the outgoing buffer. */ +SCM +guile_ssh_blocking_flush (SCM session_smob, SCM timeout) +{ + struct session_data *data + = (struct session_data *) SCM_SMOB_DATA (session_smob); + + int c_timeout; /* Timeout */ + int res; /* Result of a function call. */ + + SCM_ASSERT (scm_is_integer (timeout), timeout, SCM_ARG2, __func__); + + c_timeout = scm_to_int (timeout); + + res = scm_blockign_flush (data->ssh_session, c_timeout); + switch (res) + { + case SSH_OK: + return scm_from_locale_symbol ("ok"); + + case SSH_ERROR: + return scm_from_locale_symbol ("error"); + + case SSH_AGAIN: + return scm_from_locale_symbol ("again"); + } +} + +/* Set an SSH session option. */ +static void +set_option (ssh_session session, int type, SCM value) +{ +#define OPTION_ASSERT(pred, value) \ + do { SCM_ASSERT (pred, value, SCM_ARG2, __func__); } while (0) + + int res = 0; /* Result of an option setting */ + + switch (type) + { + case SSH_OPTIONS_HOST: + { + char *host; + + OPTION_ASSERT (scm_is_string (value), value); + + host = scm_to_locale_string (value); + + res = ssh_options_set (session, type, host); + free (host); + + if (res < 0) + goto err; + } + return; + + case SSH_OPTIONS_PORT: + { + unsigned int port; + + OPTION_ASSERT (scm_is_unsigned_integer (value, 0, UINT32_MAX), value); + + port = scm_to_unsigned_integer (value, 0, UINT32_MAX); + res = ssh_options_set (session, type, &port); + if (res < 0) + goto err; + } + return; + + case SSH_OPTIONS_PORT_STR: + { + char *port_str = scm_to_locale_string (value); + + OPTION_ASSERT (scm_is_string (value), value); + + res = ssh_options_set (session, type, port_str); + free (port_str); + if (res < 0) + goto err; + } + return; + + case SSH_OPTIONS_USER: + { + char *user; + + OPTION_ASSERT (scm_is_string (value), value); + + user = scm_to_locale_string (value); + res = ssh_options_set (session, type, user); + free (user); + if (res < 0) + goto err; + } + return; + + case SSH_OPTIONS_LOG_VERBOSITY: + { + int verbosity_level; + + OPTION_ASSERT (scm_is_integer (value), value); + + verbosity_level = scm_to_int (value); + res = ssh_options_set (session, type, &verbosity_level); + if (res < 0) + goto err; + } + return; + + case SSH_OPTIONS_LOG_VERBOSITY_STR: + { + char *verbosity_str; + + OPTION_ASSERT (scm_is_string (value), value); + + verbosity_str = scm_to_locale_string (value); + res = ssh_options_set (session, type, verbosity_str); + free (verbosity_str); + if (res < 0) + goto err; + } + return; + + /* TODO: Implement all this. */ + + case SSH_OPTIONS_FD: + case SSH_OPTIONS_SSH_DIR: + case SSH_OPTIONS_IDENTITY: + case SSH_OPTIONS_ADD_IDENTITY: + case SSH_OPTIONS_KNOWNHOSTS: + case SSH_OPTIONS_TIMEOUT: + case SSH_OPTIONS_TIMEOUT_USEC: + case SSH_OPTIONS_SSH1: + case SSH_OPTIONS_SSH2: + case SSH_OPTIONS_CIPHERS_C_S: + case SSH_OPTIONS_CIPHERS_S_C: + case SSH_OPTIONS_COMPRESSION_C_S: + case SSH_OPTIONS_COMPRESSION_S_C: + case SSH_OPTIONS_PROXYCOMMAND: + case SSH_OPTIONS_BINDADDR: + case SSH_OPTIONS_STRICTHOSTKEYCHECK: + case SSH_OPTIONS_COMPRESSION: + case SSH_OPTIONS_COMPRESSION_LEVEL: + goto notsupported; + } + + err: + ssh_error (__func__, "Couldn't set an option.", + SCM_BOOL_F, SCM_BOOL_F); + return; + + notsupported: + ssh_error (__func__, "Operation is not supported yet.", + SCM_BOOL_F, SCM_BOOL_F); + +#undef OPTION_ASSERT +} + +/* Set a SSH option. */ +SCM +guile_ssh_session_set (SCM session_smob, SCM type, SCM value) +{ + struct session_data* data + = (struct session_data *) SCM_SMOB_DATA (session_smob); + + char *c_type_name; /* Name of an option */ + struct option *option; /* SSH option mapping */ + int is_found = 0; /* Is a parameter found? */ + int res; /* Result of a function call */ + + if (scm_symbol_p (type) == SCM_BOOL_F) + { + ssh_error (__func__, "Wrong function call: " + "expected symbol as the second parameter", + SCM_BOOL_F, SCM_BOOL_F); + } + + c_type_name = scm_to_locale_string (scm_symbol_to_string (type)); + + for (option = session_options; option->symbol != NULL; ++option) + { + if (! strcmp (c_type_name, option->symbol)) + { + is_found = 1; + break; + } + } + + if(! is_found) + { + ssh_error (__func__, "Wrong option", + SCM_BOOL_F, SCM_BOOL_F); + } + + /* FIXME: There is an error here. */ + scm_remember_upto_here_1 (session_smob); + + return SCM_UNDEFINED; +} + +/* Get SSH version. + * + * Return 1 for SSH1, 2 for SSH2 or negative value on error. + */ +SCM +guile_ssh_get_version (SCM session_smob) +{ + struct session_data* data + = (struct session_data *) SCM_SMOB_DATA (session_smob); + + int version = ssh_get_version (data->ssh_session); + + return scm_from_int (version); +} + +/* Create a new session. */ +SCM +guile_ssh_make_session (void) +{ + SCM smob; + + struct session_data *session_data + = (struct session_data *) scm_gc_malloc (sizeof (struct session_data), + "session"); + + session_data->ssh_session = ssh_new (); + if (session_data->ssh_session == NULL) + { + ssh_error (__func__, "Couldn't create a new SSH session.", + SCM_BOOL_F, SCM_BOOL_F); + } + + SCM_NEWSMOB (smob, session_tag, session_data); + + return smob; +} + +/* Connect to the SSH server. */ +SCM +guile_ssh_connect (SCM session_smob) +{ + struct session_data* data + = (struct session_data *) SCM_SMOB_DATA (session_smob); + + int res = ssh_connect (data->ssh_session); + + switch (res) + { + case SSH_OK: + return scm_from_locale_symbol ("ok"); + + case SSH_ERROR: + return scm_from_locale_symbol ("error"); + + case SSH_AGAIN: + return scm_from_locale_symbol ("again"); + } +} + +/* Disconnect from a session (client or server). */ +SCM +guile_ssh_disconnect (SCM session_smob) +{ + struct session_data* data + = (struct session_data *) SCM_SMOB_DATA (session_smob); + ssh_disconnect (data->ssh_session); + return SCM_UNDEFINED; +} + + +/* Predicates */ + +/* Check if we are connected. */ +SCM +guile_ssh_is_connected (SCM session_smob) +{ + struct session_data* data + = (struct session_data *) SCM_SMOB_DATA (session_smob); + + int res = ssh_is_connected (data->ssh_session); + + return res ? SCM_BOOL_T : SCM_BOOL_F; +} + + +/* session smob initialization. */ +void +init_session_type (void) +{ + session_tag = scm_make_smob_type ("ssh:session", sizeof (struct session_data)); + scm_set_smob_mark (session_tag, mark_session); + scm_set_smob_free (session_tag, free_session); + + scm_c_define_gsubr ("ssh:make-session", 0, 0, 0, guile_ssh_make_session); + scm_c_define_gsubr ("ssh:blocking-flush!", 2, 0, 0, guile_ssh_blocking_flush); + scm_c_define_gsubr ("ssh:session-set!", 3, 0, 0, guile_ssh_session_set); + scm_c_define_gsubr ("ssh:get-version", 1, 0, 0, guile_ssh_get_version); + scm_c_define_gsubr ("ssh:connect!", 1, 0, 0, guile_ssh_connect); + scm_c_define_gsubr ("ssh:disconnect!", 1, 0, 0, guile_ssh_disconnect); + + scm_c_define_gsubr ("ssh:connected?", 1, 0, 0, guile_ssh_is_connected); +} + +/* session.c ends here */ diff --git a/src/session.h b/src/session.h new file mode 100644 index 0000000..b99f74d --- /dev/null +++ b/src/session.h @@ -0,0 +1,8 @@ +struct session_data { + ssh_session ssh_session; +}; + +struct option { + char* symbol; + int type; +}; diff --git a/src/session.scm b/src/session.scm new file mode 100644 index 0000000..576e9e9 --- /dev/null +++ b/src/session.scm @@ -0,0 +1,31 @@ +;;; session.scm -- + +;; Copyright (C) 2013 Artyom V. Poptsov <poptsov.artyom@gmail.com> +;; +;; + + +;;; Commentary: + +;; +;; +;; These methods are exported: +;; +;; + + +;;; Code: + +(define-module (ssh session) + #:export (ssh:session + ssh:make-session + ssh:blocking-flush! + ssh:session-set! + ssh:get-version + ssh:connect! + ssh:disconnect! + ssh:connected?)) + +(load-extension "libguile-ssh" "init_session_type") + +;;; session.scm ends here diff --git a/src/ssh-error.c b/src/ssh-error.c new file mode 100644 index 0000000..ae212a8 --- /dev/null +++ b/src/ssh-error.c @@ -0,0 +1,31 @@ +/* ssh-error.c -- Error reporting to Guile. + * + * Copyright (C) 2013 Artyom V. Poptsov <poptsov.artyom@gmail.com> + * + * This file is part of libguile-ssh + * + * LazyCat is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LazyCat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LazyCat. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ssh-error.h" + +/* Report an error */ +inline void +ssh_error (const char *subr, char *message, SCM args, SCM rest) +{ + SCM key = scm_from_locale_symbol (GUILE_SSH_EXCEPTION); + scm_error (key, subr, message, args, rest); +} + +/* ssh-error.c ends here */ diff --git a/src/ssh-error.h b/src/ssh-error.h new file mode 100644 index 0000000..73cf991 --- /dev/null +++ b/src/ssh-error.h @@ -0,0 +1,8 @@ +#ifndef __SSH_ERROR_H__ +#define __SSH_ERROR_H__ + +#define GUILE_SSH_EXCEPTION "guile-ssh-exception" + +inline void ssh_error (const char *subr, char *message, SCM args, SCM rest); + +#endif /* ifndef __SSH_ERROR_H__ */ |
