/* session-type.c -- SSH session smob. * * Copyright (C) 2013, 2014, 2015, 2016 Artyom V. Poptsov * * This file is part of Guile-SSH. * * Guile-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. * * Guile-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 Guile-SSH. If not, see . */ #include #include #include #include #include "session-type.h" #include "channel-type.h" #include "session-func.h" #include "error.h" #include "common.h" scm_t_bits session_tag; /* Smob tag. */ SCM mark_session (SCM session_smob) { struct session_data *sd = _scm_to_session_data (session_smob); return sd->callbacks; } /* Handle GC'ing of the session smob. */ size_t free_session (SCM session) { struct session_data *sd = (struct session_data *) SCM_SMOB_DATA (session); ssh_disconnect (sd->ssh_session); ssh_free (sd->ssh_session); SCM_SET_SMOB_DATA (session, NULL); return 0; } /* Create a new session. */ SCM_DEFINE (guile_ssh_make_session, "%make-session", 0, 0, 0, (), "\ Create a new session.\ ") { 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) return SCM_BOOL_F; session_data->callbacks = SCM_BOOL_F; SCM_NEWSMOB (smob, session_tag, session_data); return smob; } static int print_session (SCM session, SCM port, scm_print_state *pstate) { struct session_data *sd = _scm_to_session_data (session); char *user = NULL; char *host = NULL; unsigned int ssh_port; int res; scm_puts ("#ssh_session, SSH_OPTIONS_USER, &user); scm_display ((res == SSH_OK) ? scm_from_locale_string (user) : SCM_UNDEFINED, port); ssh_string_free_char (user); scm_putc ('@', port); res = ssh_options_get (sd->ssh_session, SSH_OPTIONS_HOST, &host); scm_display ((res == SSH_OK) ? scm_from_locale_string (host) : SCM_UNDEFINED, port); ssh_string_free_char (host); scm_putc (':', port); res = ssh_options_get_port (sd->ssh_session, &ssh_port); scm_display ((res == SSH_OK) ? scm_from_int (ssh_port) : SCM_UNDEFINED, port); scm_puts (ssh_is_connected (sd->ssh_session) ? " (connected) " : " (disconnected) ", port); scm_display (_scm_object_hex_address (session), port); scm_putc ('>', port); return 1; } /* Predicates */ SCM_DEFINE (guile_ssh_is_session_p, "session?", 1, 0, 0, (SCM x), "\ Return #t if X is a SSH session, #f otherwise.\ ") { return scm_from_bool (SCM_SMOB_PREDICATE (session_tag, x)); } SCM equalp_session (SCM x1, SCM x2) { struct session_data *session1 = _scm_to_session_data (x1); struct session_data *session2 = _scm_to_session_data (x2); if ((! session1) || (! session2)) return SCM_BOOL_F; else if (session1 != session2) return SCM_BOOL_F; else return SCM_BOOL_T; } /* Helper procedures */ /* Convert SCM object to a SSH session */ struct session_data* _scm_to_session_data (SCM x) { scm_assert_smob_type (session_tag, x); return (struct session_data *) SCM_SMOB_DATA (x); } /* session smob initialization. */ void init_session_type (void) { session_tag = scm_make_smob_type ("session", sizeof (struct session_data)); scm_set_smob_mark (session_tag, mark_session); scm_set_smob_free (session_tag, free_session); scm_set_smob_print (session_tag, print_session); scm_set_smob_equalp (session_tag, equalp_session); #include "session-type.x" } /* session.c ends here */