1
%% ``The contents of this file are subject to the Erlang Public License,
2
%% Version 1.1, (the "License"); you may not use this file except in
3
%% compliance with the License. You should have received a copy of the
4
%% Erlang Public License along with this software. If not, it can be
5
%% retrieved via the world wide web at http://www.erlang.org/.
7
%% Software distributed under the License is distributed on an "AS IS"
8
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
%% the License for the specific language governing rights and limitations
12
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
%% AB. All Rights Reserved.''
19
%%% Description: ssh shell client
23
-export([connect/1, connect/2, connect/3]).
25
-export([input_loop/2, shell_loop/4]).
28
-include("ssh_connect.hrl").
30
-define(default_timeout, 10000).
35
connect(CM, Opts) when is_pid(Opts) ->
36
Timeout = proplists:get_value(connect_timeout, Opts, ?default_timeout),
37
case ssh_cm:attach(CM, Timeout) of
39
session(CMPid, Timeout);
43
connect(Host, Opts) ->
44
connect(Host, 22, Opts).
46
connect(Host, Port, Opts) ->
47
case ssh_cm:connect(Host, Port, Opts) of
49
session(CM, proplists:get_value(connect_timeout,
50
Opts, ?default_timeout));
55
session(CM, Timeout) ->
56
case ssh_cm:session_open(CM, Timeout) of
58
case ssh_cm:shell(CM, Channel) of
61
process_info(self(), group_leader),
62
IO = spawn(?MODULE, input_loop,
64
shell_loop(CM, Channel, IO, false);
66
ssh_cm:close(CM, Channel),
74
input_loop(Fd, Pid) ->
75
case io:get_line(Fd, '>') of
77
Pid ! {input, self(), eof},
78
ok; % input_loop(Fd, Pid);
80
Pid ! {input, self(), Line},
85
shell_loop(CM, Channel, IO, SentClose) ->
88
ssh_cm:send_eof(CM, Channel),
89
?MODULE:shell_loop(CM, Channel, IO, SentClose);
92
ssh_cm:send(CM, Channel, Line),
93
?MODULE:shell_loop(CM, Channel, IO, SentClose);
95
{ssh_cm, CM, {data, Channel, Type, Data}} ->
97
io:format("~s", [binary_to_list(Data)]);
98
Type == ?SSH_EXTENDED_DATA_STDERR ->
99
error_logger:format("ssh: STDERR: ~s",
100
[binary_to_list(Data)]);
104
ssh_cm:adjust_window(CM, Channel, size(Data)),
105
?MODULE:shell_loop(CM, Channel, IO, SentClose);
107
{ssh_cm, CM, {exit_signal, Channel, _SIG, _Err, _Lang}} ->
108
?dbg(true, "SIGNAL: ~s (~s)\n", [_SIG, _Err]),
109
send_close(SentClose, CM, Channel),
110
?MODULE:shell_loop(CM, Channel, IO, true);
112
{ssh_cm, CM, {exit_status,Channel,_Status}} ->
113
%send_close(SentClose, CM, Channel),
114
?MODULE:shell_loop(CM, Channel, IO, true);
116
{ssh_cm, CM, {eof, Channel}} ->
117
%send_close(SentClose, CM, Channel),
118
?MODULE:shell_loop(CM, Channel, IO, true);
120
{ssh_cm, CM, {closed, Channel}} ->
121
ssh_cm:detach(CM, ?default_timeout),
125
error_logger:format("ssh_ssh:shell_loop: unexpected msg ~p\n", [Other])
128
send_close(false, CM, Channel) ->
129
ssh_cm:close(CM, Channel);
130
send_close(_, _, _) ->