diff options
Diffstat (limited to 'lib/ssh/src/ssh_connection.erl')
-rw-r--r-- | lib/ssh/src/ssh_connection.erl | 196 |
1 files changed, 172 insertions, 24 deletions
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl index 5d773c50b0..c5316bf133 100644 --- a/lib/ssh/src/ssh_connection.erl +++ b/lib/ssh/src/ssh_connection.erl @@ -66,6 +66,115 @@ -type connection_ref() :: ssh:connection_ref(). -type channel_id() :: ssh:channel_id(). +-type req_status() :: success | failure . +-type reason() :: closed | timeout . + +-type result() :: req_status() | {error, reason()} . + +-type ssh_data_type_code() :: non_neg_integer(). % Only 0 and 1 are used + + +%%% The SSH Connection Protocol + +-export_type([event/0, + channel_msg/0, + want_reply/0, + data_ch_msg/0, + eof_ch_msg/0, + signal_ch_msg/0, + exit_signal_ch_msg/0, + exit_status_ch_msg/0, + closed_ch_msg/0, + env_ch_msg/0, + pty_ch_msg/0, + shell_ch_msg/0, + window_change_ch_msg/0, + exec_ch_msg/0 + ]). + +-type event() :: {ssh_cm, ssh:connection_ref(), channel_msg()}. +-type channel_msg() :: data_ch_msg() + | eof_ch_msg() + | closed_ch_msg() + | pty_ch_msg() + | env_ch_msg() + | shell_ch_msg() + | exec_ch_msg() + | signal_ch_msg() + | window_change_ch_msg() + | exit_status_ch_msg() + | exit_signal_ch_msg() + . + +-type want_reply() :: boolean(). + +-type data_ch_msg() :: {data, + ssh:channel_id(), + ssh_data_type_code(), + Data :: binary() + } . +-type eof_ch_msg() :: {eof, + ssh:channel_id() + } . +-type signal_ch_msg() :: {signal, + ssh:channel_id(), + SignalName :: string() + } . +-type exit_signal_ch_msg() :: {exit_signal, ssh:channel_id(), + ExitSignal :: string(), + ErrorMsg :: string(), + LanguageString :: string()} . +-type exit_status_ch_msg() :: {exit_status, + ssh:channel_id(), + ExitStatus :: non_neg_integer() + } . +-type closed_ch_msg() :: {closed, + ssh:channel_id() + } . +-type env_ch_msg() :: {env, + ssh:channel_id(), + want_reply(), + Var :: string(), + Value :: string() + } . +-type pty_ch_msg() :: {pty, + ssh:channel_id(), + want_reply(), + {Terminal :: string(), + CharWidth :: non_neg_integer(), + RowHeight :: non_neg_integer(), + PixelWidth :: non_neg_integer(), + PixelHeight :: non_neg_integer(), + TerminalModes :: [term_mode()] + } + } . + +-type term_mode() :: {Opcode :: atom() | byte(), + Value :: non_neg_integer()} . + +-type shell_ch_msg() :: {shell, + ssh:channel_id(), + want_reply() + } . +-type window_change_ch_msg() :: {window_change, + ssh:channel_id(), + CharWidth :: non_neg_integer(), + RowHeight :: non_neg_integer(), + PixelWidth :: non_neg_integer(), + PixelHeight :: non_neg_integer() + } . +-type exec_ch_msg() :: {exec, + ssh:channel_id(), + want_reply(), + Command :: string() + } . + +%%% This function is soley to convince all +%%% checks that the type event() exists... +-export([dummy/1]). +-spec dummy(event()) -> false. +dummy(_) -> false. + %%-------------------------------------------------------------------- %%% API %%-------------------------------------------------------------------- @@ -76,14 +185,21 @@ %% application, a system command, or some built-in subsystem. %% -------------------------------------------------------------------- --spec session_channel(connection_ref(), timeout()) -> - {ok, channel_id()} | {error, timeout | closed}. +-spec session_channel(ConnectionRef, Timeout) -> Result when + ConnectionRef :: ssh:connection_ref(), + Timeout :: timeout(), + Result :: {ok, ssh:channel_id()} | {error, reason()} . session_channel(ConnectionHandler, Timeout) -> session_channel(ConnectionHandler, ?DEFAULT_WINDOW_SIZE, ?DEFAULT_PACKET_SIZE, Timeout). --spec session_channel(connection_ref(), integer(), integer(), timeout()) -> - {ok, channel_id()} | {error, timeout | closed}. + +-spec session_channel(ConnectionRef, InitialWindowSize, MaxPacketSize, Timeout) -> Result when + ConnectionRef :: ssh:connection_ref(), + InitialWindowSize :: pos_integer(), + MaxPacketSize :: pos_integer(), + Timeout :: timeout(), + Result :: {ok, ssh:channel_id()} | {error, reason()} . session_channel(ConnectionHandler, InitialWindowSize, MaxPacketSize, Timeout) -> case ssh_connection_handler:open_channel(ConnectionHandler, "session", <<>>, @@ -99,8 +215,11 @@ session_channel(ConnectionHandler, InitialWindowSize, MaxPacketSize, Timeout) -> %% Description: Will request that the server start the %% execution of the given command. %%-------------------------------------------------------------------- --spec exec(connection_ref(), channel_id(), string(), timeout()) -> - success | failure | {error, timeout | closed}. +-spec exec(ConnectionRef, ChannelId, Command, Timeout) -> result() when + ConnectionRef :: ssh:connection_ref(), + ChannelId :: ssh:channel_id(), + Command :: string(), + Timeout :: timeout(). exec(ConnectionHandler, ChannelId, Command, TimeOut) -> ssh_connection_handler:request(ConnectionHandler, self(), ChannelId, "exec", @@ -111,8 +230,10 @@ exec(ConnectionHandler, ChannelId, Command, TimeOut) -> %% defined in /etc/passwd in UNIX systems) be started at the other %% end. %%-------------------------------------------------------------------- --spec shell(connection_ref(), channel_id()) -> - ok | success | failure | {error, timeout}. +-spec shell(ConnectionRef, ChannelId) -> Result when + ConnectionRef :: ssh:connection_ref(), + ChannelId :: ssh:channel_id(), + Result :: ok | success | failure | {error, timeout} . shell(ConnectionHandler, ChannelId) -> ssh_connection_handler:request(ConnectionHandler, self(), ChannelId, @@ -121,8 +242,11 @@ shell(ConnectionHandler, ChannelId) -> %% %% Description: Executes a predefined subsystem. %%-------------------------------------------------------------------- --spec subsystem(connection_ref(), channel_id(), string(), timeout()) -> - success | failure | {error, timeout | closed}. +-spec subsystem(ConnectionRef, ChannelId, Subsystem, Timeout) -> result() when + ConnectionRef :: ssh:connection_ref(), + ChannelId :: ssh:channel_id(), + Subsystem :: string(), + Timeout :: timeout(). subsystem(ConnectionHandler, ChannelId, SubSystem, TimeOut) -> ssh_connection_handler:request(ConnectionHandler, self(), @@ -133,12 +257,13 @@ subsystem(ConnectionHandler, ChannelId, SubSystem, TimeOut) -> %%-------------------------------------------------------------------- -spec send(connection_ref(), channel_id(), iodata()) -> ok | {error, timeout | closed}. + send(ConnectionHandler, ChannelId, Data) -> send(ConnectionHandler, ChannelId, 0, Data, infinity). --spec send(connection_ref(), channel_id(), integer()| iodata(), timeout() | iodata()) -> - ok | {error, timeout | closed}. +-spec send(connection_ref(), channel_id(), iodata(), timeout()) -> ok | {error, reason()}; + (connection_ref(), channel_id(), ssh_data_type_code(), iodata()) -> ok | {error, reason()}. send(ConnectionHandler, ChannelId, Data, TimeOut) when is_integer(TimeOut) -> send(ConnectionHandler, ChannelId, 0, Data, TimeOut); @@ -150,14 +275,15 @@ send(ConnectionHandler, ChannelId, Type, Data) -> send(ConnectionHandler, ChannelId, Type, Data, infinity). --spec send(connection_ref(), channel_id(), integer(), iodata(), timeout()) -> - ok | {error, timeout | closed}. +-spec send(connection_ref(), channel_id(), ssh_data_type_code(), iodata(), timeout()) -> ok | {error, reason()}. send(ConnectionHandler, ChannelId, Type, Data, TimeOut) -> ssh_connection_handler:send(ConnectionHandler, ChannelId, Type, Data, TimeOut). %%-------------------------------------------------------------------- --spec send_eof(connection_ref(), channel_id()) -> ok | {error, closed}. +-spec send_eof(ConnectionRef, ChannelId) -> ok | {error, closed} when + ConnectionRef :: ssh:connection_ref(), + ChannelId :: ssh:channel_id(). %% %% %% Description: Sends eof on the channel <ChannelId>. @@ -166,7 +292,10 @@ send_eof(ConnectionHandler, Channel) -> ssh_connection_handler:send_eof(ConnectionHandler, Channel). %%-------------------------------------------------------------------- --spec adjust_window(connection_ref(), channel_id(), integer()) -> ok. +-spec adjust_window(ConnectionRef, ChannelId, NumOfBytes) -> ok when + ConnectionRef :: ssh:connection_ref(), + ChannelId :: ssh:channel_id(), + NumOfBytes :: integer(). %% %% %% Description: Adjusts the ssh flowcontrol window. @@ -175,8 +304,12 @@ adjust_window(ConnectionHandler, Channel, Bytes) -> ssh_connection_handler:adjust_window(ConnectionHandler, Channel, Bytes). %%-------------------------------------------------------------------- --spec setenv(connection_ref(), channel_id(), string(), string(), timeout()) -> - success | failure | {error, timeout | closed}. +-spec setenv(ConnectionRef, ChannelId, Var, Value, Timeout) -> result() when + ConnectionRef :: ssh:connection_ref(), + ChannelId :: ssh:channel_id(), + Var :: string(), + Value :: string(), + Timeout :: timeout(). %% %% %% Description: Environment variables may be passed to the shell/command to be @@ -188,7 +321,9 @@ setenv(ConnectionHandler, ChannelId, Var, Value, TimeOut) -> %%-------------------------------------------------------------------- --spec close(connection_ref(), channel_id()) -> ok. +-spec close(ConnectionRef, ChannelId) -> ok when + ConnectionRef :: ssh:connection_ref(), + ChannelId :: ssh:channel_id(). %% %% %% Description: Sends a close message on the channel <ChannelId>. @@ -197,7 +332,11 @@ close(ConnectionHandler, ChannelId) -> ssh_connection_handler:close(ConnectionHandler, ChannelId). %%-------------------------------------------------------------------- --spec reply_request(connection_ref(), boolean(), success | failure, channel_id()) -> ok. +-spec reply_request(ConnectionRef, WantReply, Status, ChannelId) -> ok when + ConnectionRef :: ssh:connection_ref(), + WantReply :: boolean(), + Status :: req_status(), + ChannelId :: ssh:channel_id(). %% %% %% Description: Send status replies to requests that want such replies. @@ -210,15 +349,20 @@ reply_request(_,false, _, _) -> %%-------------------------------------------------------------------- %% Description: Sends a ssh connection protocol pty_req. %%-------------------------------------------------------------------- --spec ptty_alloc(connection_ref(), channel_id(), proplists:proplist()) -> - success | failure | {error, timeout}. +-spec ptty_alloc(ConnectionRef, ChannelId, Options) -> result() when + ConnectionRef :: ssh:connection_ref(), + ChannelId :: ssh:channel_id(), + Options :: proplists:proplist(). ptty_alloc(ConnectionHandler, Channel, Options) -> ptty_alloc(ConnectionHandler, Channel, Options, infinity). --spec ptty_alloc(connection_ref(), channel_id(), proplists:proplist(), timeout()) -> - success | failure | {error, timeout | closed}. +-spec ptty_alloc(ConnectionRef, ChannelId, Options, Timeout) -> result() when + ConnectionRef :: ssh:connection_ref(), + ChannelId :: ssh:channel_id(), + Options :: proplists:proplist(), + Timeout :: timeout(). ptty_alloc(ConnectionHandler, Channel, Options0, TimeOut) -> TermData = backwards_compatible(Options0, []), % FIXME @@ -251,6 +395,10 @@ signal(ConnectionHandler, Channel, Sig) -> "signal", false, [?string(Sig)], 0). +-spec exit_status(ConnectionRef, ChannelId, Status) -> ok when + ConnectionRef :: ssh:connection_ref(), + ChannelId :: ssh:channel_id(), + Status :: integer(). exit_status(ConnectionHandler, Channel, Status) -> ssh_connection_handler:request(ConnectionHandler, Channel, "exit-status", false, [?uint32(Status)], 0). |