Guest User

Untitled

a guest
Apr 14th, 2018
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.90 KB | None | 0 0
  1. -define(TIMEOUT, 60000).
  2.  
  3. -behavior(ssh_channel).
  4.  
  5. %% API
  6. -export([start_link/2, send/2, send_wait/2, close/1, get_data/1]).
  7.  
  8. %% ssh_channel API
  9. -export([init/1, handle_call/3, handle_cast/2, handle_msg/2]).
  10. -export([handle_ssh_msg/2, code_change/3, terminate/2]).
  11.  
  12. -record(state, {cn,
  13. chan,
  14. shell_started=false,
  15. caller,
  16. buf=[]}).
  17.  
  18. start_link(ConnInfo, Host) ->
  19. User = proplists:get_value(user, ConnInfo),
  20. Password = proplists:get_value(password, ConnInfo),
  21. application:start(crypto),
  22. application:start(ssh),
  23. case ssh:connect(Host, 22, [{user, User},
  24. {password, Password},
  25. {silently_accept_hosts, true}]) of
  26. {ok, Cn} ->
  27. case ssh_connection:session_channel(Cn, ?TIMEOUT) of
  28. {ok, ChanId} ->
  29. ssh_channel:start_link(Cn, ChanId, ?MODULE, [Cn, ChanId]);
  30. Error ->
  31. ssh:close(Cn),
  32. throw(Error)
  33. end;
  34. Error ->
  35. throw(Error)
  36. end.
  37.  
  38. get_data(ChannelPid) ->
  39. ssh_channel:call(ChannelPid, get_data, infinity).
  40.  
  41. send(ChannelPid, Data) ->
  42. ssh_channel:call(ChannelPid, {send, Data}, infinity).
  43.  
  44. send_wait(ChannelPid, Data) ->
  45. Me = self(),
  46. ssh_channel:call(ChannelPid, {send_wait, Me, Data}, infinity),
  47. receive
  48. {response, Response} ->
  49. Response
  50. after ?TIMEOUT ->
  51. {error, timeout}
  52. end.
  53.  
  54. close(ChannelPid) ->
  55. ssh_channel:cast(ChannelPid, close).
  56.  
  57. init([Conn, ChanId]) ->
  58. {ok, #state{cn=Conn, chan=ChanId}}.
  59.  
  60. handle_call(get_data, _From, #state{buf=Buf}=State) ->
  61. {reply, Buf, State#state{buf=[]}};
  62.  
  63. handle_call({send, Data}, _From, #state{cn=Cn, chan=Chan}=State) ->
  64. {reply, ssh_connection:send(Cn, Chan, Data, ?TIMEOUT), State};
  65.  
  66. handle_call({send_wait, Caller, Data}, _From, #state{cn=Cn, chan=Chan, shell_started=ShellStarted}=State) ->
  67. case ShellStarted =:= true orelse ssh_connection:shell(Cn, Chan) =:= ok of
  68. true ->
  69. NewState = State#state{shell_started=true},
  70. case ssh_connection:send(Cn, Chan, Data, ?TIMEOUT) of
  71. ok ->
  72. {reply, ok, NewState#state{caller=Caller}};
  73. Error ->
  74. {reply, Error, NewState}
  75. end;
  76. false ->
  77. {reply, {error, no_shell}, State}
  78. end;
  79.  
  80. handle_call(_Msg, _From, State) ->
  81. {reply, ignored, State}.
  82.  
  83. handle_cast(close, State) ->
  84. {stop, normal, State};
  85.  
  86. handle_cast(_Msg, State) ->
  87. {noreply, State}.
  88.  
  89. handle_msg(_Msg, State) ->
  90. io:format("Msg: ~p~n", [_Msg]),
  91. {ok, State}.
  92.  
  93. handle_ssh_msg({ssh_cm, _, {data, _, _, Data}}, #state{caller=Caller}=State) when not(Caller =:= undefined) ->
  94. Caller ! {response, Data},
  95. {ok, State#state{caller=undefined}};
  96.  
  97. handle_ssh_msg({ssh_cm, _, {data, _, _, Data}}, #state{buf=Buf}=State) ->
  98. {ok, State#state{buf=[Data|Buf]}};
  99.  
  100. handle_ssh_msg(_Msg, State) ->
  101. io:format("SSH Message: ~p~n", [_Msg]),
  102. {ok, State}.
  103.  
  104. code_change(_OldVsn, State, _Extra) ->
  105. {ok, State}.
  106.  
  107. terminate(_Reason, _State) ->
  108. ok.
Add Comment
Please, Sign In to add comment