Sophie

Sophie

distrib > Fedora > 18 > i386 > by-pkgid > ee8fafc31a7ba3ce3ae4499cedf4e1bc > files > 96

libssh-devel-0.5.5-1.fc18.i686.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<title>libssh: Chapter 3: Opening a remote shell</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">libssh
   &#160;<span id="projectnumber">0.5.5</span>
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li class="current"><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="index.html">index</a></li><li class="navelem"><a class="el" href="libssh_tutorial.html">The Tutorial</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Chapter 3: Opening a remote shell </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="opening_shell"></a>
Opening a remote shell</h1>
<p>We already mentioned that a single SSH connection can be shared between several "channels". Channels can be used for different purposes.</p>
<p>This chapter shows how to open one of these channels, and how to use it to start a command interpreter on a remote computer.</p>
<h2><a class="anchor" id="open_channel"></a>
Opening and closing a channel</h2>
<p>The <a class="el" href="group__libssh__channel.html#gada8ccda7bf65165fe145d3096a252dcc" title="Allocate a new channel.">ssh_channel_new()</a> function creates a channel. It returns the channel as a variable of type ssh_channel.</p>
<p>Once you have this channel, you open a SSH session that uses it with <a class="el" href="group__libssh__channel.html#gaf051dd30d75bf6dc45d1a5088cf970bd" title="Open a session channel (suited for a shell, not TCP forwarding).">ssh_channel_open_session()</a>.</p>
<p>Once you don't need the channel anymore, you can send an end-of-file to it with <a class="el" href="group__libssh__channel.html#ga238f07e0455456a5bfd8a49ead917732" title="Close a channel.">ssh_channel_close()</a>. At this point, you can destroy the channel with <a class="el" href="group__libssh__channel.html#gad1417f9eae8928fed20faafe2d9dbfff" title="Close and free a channel.">ssh_channel_free()</a>.</p>
<p>The code sample below achieves these tasks:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> shell_session(ssh_session session)</div>
<div class="line">{</div>
<div class="line">  ssh_channel channel;</div>
<div class="line">  <span class="keywordtype">int</span> rc;</div>
<div class="line"></div>
<div class="line">  channel = <a class="code" href="group__libssh__channel.html#gada8ccda7bf65165fe145d3096a252dcc" title="Allocate a new channel.">ssh_channel_new</a>(session);</div>
<div class="line">  <span class="keywordflow">if</span> (channel == NULL)</div>
<div class="line">    <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line"></div>
<div class="line">  rc = <a class="code" href="group__libssh__channel.html#gaf051dd30d75bf6dc45d1a5088cf970bd" title="Open a session channel (suited for a shell, not TCP forwarding).">ssh_channel_open_session</a>(channel);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK)</div>
<div class="line">  {</div>
<div class="line">    <a class="code" href="group__libssh__channel.html#gad1417f9eae8928fed20faafe2d9dbfff" title="Close and free a channel.">ssh_channel_free</a>(channel);</div>
<div class="line">    <span class="keywordflow">return</span> rc;</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  ...</div>
<div class="line"></div>
<div class="line">  <a class="code" href="group__libssh__channel.html#ga238f07e0455456a5bfd8a49ead917732" title="Close a channel.">ssh_channel_close</a>(channel);</div>
<div class="line">  <a class="code" href="group__libssh__channel.html#ga072f82fdf3e50514f747653af2c99004" title="Send an end of file on the channel.">ssh_channel_send_eof</a>(channel);</div>
<div class="line">  <a class="code" href="group__libssh__channel.html#gad1417f9eae8928fed20faafe2d9dbfff" title="Close and free a channel.">ssh_channel_free</a>(channel);</div>
<div class="line"></div>
<div class="line">  <span class="keywordflow">return</span> SSH_OK;</div>
<div class="line">}</div>
</div><!-- fragment --><h2><a class="anchor" id="interactive"></a>
Interactive and non-interactive sessions</h2>
<p>A "shell" is a command interpreter. It is said to be "interactive" if there is a human user typing the commands, one after the other. The contrary, a non-interactive shell, is similar to the execution of commands in the background: there is no attached terminal.</p>
<p>If you plan using an interactive shell, you need to create a pseud-terminal on the remote side. A remote terminal is usually referred to as a "pty", for "pseudo-teletype". The remote processes won't see the difference with a real text-oriented terminal.</p>
<p>If needed, you request the pty with the function <a class="el" href="group__libssh__channel.html#ga37c1cec33fe5a2f184768aba52e3a0db" title="Request a PTY.">ssh_channel_request_pty()</a>. Then you define its dimensions (number of rows and columns) with <a class="el" href="group__libssh__channel.html#gaf5d55c90f3d98c583df23d21905c1127" title="Change the size of the terminal associated to a channel.">ssh_channel_change_pty_size()</a>.</p>
<p>Be your session interactive or not, the next step is to request a shell with <a class="el" href="group__libssh__channel.html#gaed4c5fb30c9df2b2548421ccf4e81bf1" title="Request a shell.">ssh_channel_request_shell()</a>.</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> interactive_shell_session(ssh_channel channel)</div>
<div class="line">{</div>
<div class="line">  <span class="keywordtype">int</span> rc;</div>
<div class="line"></div>
<div class="line">  rc = <a class="code" href="group__libssh__channel.html#ga37c1cec33fe5a2f184768aba52e3a0db" title="Request a PTY.">ssh_channel_request_pty</a>(channel);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK) <span class="keywordflow">return</span> rc;</div>
<div class="line"></div>
<div class="line">  rc = <a class="code" href="group__libssh__channel.html#gaf5d55c90f3d98c583df23d21905c1127" title="Change the size of the terminal associated to a channel.">ssh_channel_change_pty_size</a>(channel, 80, 24);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK) <span class="keywordflow">return</span> rc;</div>
<div class="line"></div>
<div class="line">  rc = <a class="code" href="group__libssh__channel.html#gaed4c5fb30c9df2b2548421ccf4e81bf1" title="Request a shell.">ssh_channel_request_shell</a>(channel);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK) <span class="keywordflow">return</span> rc;</div>
<div class="line"></div>
<div class="line">  ...</div>
<div class="line"></div>
<div class="line">  <span class="keywordflow">return</span> rc;</div>
<div class="line">}</div>
</div><!-- fragment --><h2><a class="anchor" id="read_data"></a>
Displaying the data sent by the remote computer</h2>
<p>In your program, you will usually need to receive all the data "displayed" into the remote pty. You will usually analyse, log, or display this data.</p>
<p><a class="el" href="group__libssh__channel.html#gac92381c4c5d4a7eab35f6e84686f033d" title="Reads data from a channel.">ssh_channel_read()</a> and <a class="el" href="group__libssh__channel.html#gaaca5a3fbe9839c3ffb37b746afc35f4c" title="Do a nonblocking read on the channel.">ssh_channel_read_nonblocking()</a> are the simplest way to read data from a channel. If you only need to read from a single channel, they should be enough.</p>
<p>The example below shows how to wait for remote data using <a class="el" href="group__libssh__channel.html#gac92381c4c5d4a7eab35f6e84686f033d" title="Reads data from a channel.">ssh_channel_read()</a>:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> interactive_shell_session(ssh_channel channel)</div>
<div class="line">{</div>
<div class="line">  <span class="keywordtype">int</span> rc;</div>
<div class="line">  <span class="keywordtype">char</span> buffer[256];</div>
<div class="line">  <span class="keywordtype">int</span> nbytes;</div>
<div class="line"></div>
<div class="line">  rc = <a class="code" href="group__libssh__channel.html#ga37c1cec33fe5a2f184768aba52e3a0db" title="Request a PTY.">ssh_channel_request_pty</a>(channel);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK) <span class="keywordflow">return</span> rc;</div>
<div class="line"></div>
<div class="line">  rc = <a class="code" href="group__libssh__channel.html#gaf5d55c90f3d98c583df23d21905c1127" title="Change the size of the terminal associated to a channel.">ssh_channel_change_pty_size</a>(channel, 80, 24);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK) <span class="keywordflow">return</span> rc;</div>
<div class="line"></div>
<div class="line">  rc = <a class="code" href="group__libssh__channel.html#gaed4c5fb30c9df2b2548421ccf4e81bf1" title="Request a shell.">ssh_channel_request_shell</a>(channel);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK) <span class="keywordflow">return</span> rc;</div>
<div class="line"></div>
<div class="line">  <span class="keywordflow">while</span> (<a class="code" href="group__libssh__channel.html#gaaafcda943c96ddb91e5c28c0bdee7045" title="Check if the channel is open or not.">ssh_channel_is_open</a>(channel) &amp;&amp;</div>
<div class="line">         !<a class="code" href="group__libssh__channel.html#gab535264029443d77214c0615a0788b0a" title="Check if remote has sent an EOF.">ssh_channel_is_eof</a>(channel))</div>
<div class="line">  {</div>
<div class="line">    nbytes = <a class="code" href="group__libssh__channel.html#gac92381c4c5d4a7eab35f6e84686f033d" title="Reads data from a channel.">ssh_channel_read</a>(channel, buffer, <span class="keyword">sizeof</span>(buffer), 0);</div>
<div class="line">    <span class="keywordflow">if</span> (nbytes &lt; 0)</div>
<div class="line">      <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line"></div>
<div class="line">    <span class="keywordflow">if</span> (nbytes &gt; 0)</div>
<div class="line">      write(1, buffer, nbytes);</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  <span class="keywordflow">return</span> rc;</div>
<div class="line">}</div>
</div><!-- fragment --><p>Unlike <a class="el" href="group__libssh__channel.html#gac92381c4c5d4a7eab35f6e84686f033d" title="Reads data from a channel.">ssh_channel_read()</a>, <a class="el" href="group__libssh__channel.html#gaaca5a3fbe9839c3ffb37b746afc35f4c" title="Do a nonblocking read on the channel.">ssh_channel_read_nonblocking()</a> never waits for remote data to be ready. It returns immediately.</p>
<p>If you plan to use <a class="el" href="group__libssh__channel.html#gaaca5a3fbe9839c3ffb37b746afc35f4c" title="Do a nonblocking read on the channel.">ssh_channel_read_nonblocking()</a> repeatedly in a loop, you should use a "passive wait" function like usleep(3) in the same loop. Otherwise, your program will consume all the CPU time, and your computer might become unresponsive.</p>
<h2><a class="anchor" id="write_data"></a>
Sending user input to the remote computer</h2>
<p>User's input is sent to the remote site with <a class="el" href="group__libssh__channel.html#ga5d658df773ba854b35ff9f905341e2fb" title="Blocking write on a channel.">ssh_channel_write()</a>.</p>
<p>The following example shows how to combine a nonblocking read from a SSH channel with a nonblocking read from the keyboard. The local input is then sent to the remote computer:</p>
<div class="fragment"><div class="line"><span class="comment">/* Under Linux, this function determines whether a key has been pressed.</span></div>
<div class="line"><span class="comment">   Under Windows, it is a standard function, so you need not redefine it.</span></div>
<div class="line"><span class="comment">*/</span></div>
<div class="line"><span class="keywordtype">int</span> kbhit()</div>
<div class="line">{</div>
<div class="line">    <span class="keyword">struct </span>timeval tv = { 0L, 0L };</div>
<div class="line">    fd_set fds;</div>
<div class="line"></div>
<div class="line">    FD_ZERO(&amp;fds);</div>
<div class="line">    FD_SET(0, &amp;fds);</div>
<div class="line"></div>
<div class="line">    <span class="keywordflow">return</span> select(1, &amp;fds, NULL, NULL, &amp;tv);</div>
<div class="line">}</div>
<div class="line"></div>
<div class="line"><span class="comment">/* A very simple terminal emulator:</span></div>
<div class="line"><span class="comment">   - print data received from the remote computer</span></div>
<div class="line"><span class="comment">   - send keyboard input to the remote computer</span></div>
<div class="line"><span class="comment">*/</span></div>
<div class="line"><span class="keywordtype">int</span> interactive_shell_session(ssh_channel channel)</div>
<div class="line">{</div>
<div class="line">  <span class="comment">/* Session and terminal initialization skipped */</span></div>
<div class="line">  ...</div>
<div class="line"></div>
<div class="line">  <span class="keywordtype">char</span> buffer[256];</div>
<div class="line">  <span class="keywordtype">int</span> nbytes, nwritten;</div>
<div class="line"></div>
<div class="line">  <span class="keywordflow">while</span> (<a class="code" href="group__libssh__channel.html#gaaafcda943c96ddb91e5c28c0bdee7045" title="Check if the channel is open or not.">ssh_channel_is_open</a>(channel) &amp;&amp;</div>
<div class="line">         !<a class="code" href="group__libssh__channel.html#gab535264029443d77214c0615a0788b0a" title="Check if remote has sent an EOF.">ssh_channel_is_eof</a>(channel))</div>
<div class="line">  {</div>
<div class="line">    nbytes = <a class="code" href="group__libssh__channel.html#gaaca5a3fbe9839c3ffb37b746afc35f4c" title="Do a nonblocking read on the channel.">ssh_channel_read_nonblocking</a>(channel, buffer, <span class="keyword">sizeof</span>(buffer), 0);</div>
<div class="line">    <span class="keywordflow">if</span> (nbytes &lt; 0) <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line">    <span class="keywordflow">if</span> (nbytes &gt; 0)</div>
<div class="line">    {</div>
<div class="line">      nwritten = write(1, buffer, nbytes);</div>
<div class="line">      <span class="keywordflow">if</span> (nwritten != nbytes) <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line"></div>
<div class="line">    <span class="keywordflow">if</span> (!kbhit())</div>
<div class="line">    {</div>
<div class="line">      usleep(50000L); <span class="comment">// 0.05 second</span></div>
<div class="line">      <span class="keywordflow">continue</span>;</div>
<div class="line">    }</div>
<div class="line"></div>
<div class="line">    nbytes = read(0, buffer, <span class="keyword">sizeof</span>(buffer));</div>
<div class="line">    <span class="keywordflow">if</span> (nbytes &lt; 0) <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line">    <span class="keywordflow">if</span> (nbytes &gt; 0)</div>
<div class="line">    {</div>
<div class="line">      nwritten = <a class="code" href="group__libssh__channel.html#ga5d658df773ba854b35ff9f905341e2fb" title="Blocking write on a channel.">ssh_channel_write</a>(channel, buffer, nbytes);</div>
<div class="line">      <span class="keywordflow">if</span> (nwritten != nbytes) <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line">    }</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  <span class="keywordflow">return</span> rc;</div>
<div class="line">}</div>
</div><!-- fragment --><p>Of course, this is a poor terminal emulator, since the echo from the keys pressed should not be done locally, but should be done by the remote side. Also, user's input should not be sent once "Enter" key is pressed, but immediately after each key is pressed. This can be accomplished by setting the local terminal to "raw" mode with the cfmakeraw(3) function. cfmakeraw() is a standard function under Linux, on other systems you can recode it with:</p>
<div class="fragment"><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span> cfmakeraw(<span class="keyword">struct</span> termios *termios_p)</div>
<div class="line">{</div>
<div class="line">    termios_p-&gt;c_iflag &amp;= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);</div>
<div class="line">    termios_p-&gt;c_oflag &amp;= ~OPOST;</div>
<div class="line">    termios_p-&gt;c_lflag &amp;= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);</div>
<div class="line">    termios_p-&gt;c_cflag &amp;= ~(CSIZE|PARENB);</div>
<div class="line">    termios_p-&gt;c_cflag |= CS8;</div>
<div class="line">}</div>
</div><!-- fragment --><p>If you are not using a local terminal, but some kind of graphical environment, the solution to this kind of "echo" problems will be different.</p>
<h2><a class="anchor" id="select_loop"></a>
A more elaborate way to get the remote data</h2>
<pre class="fragment">Warning: ssh_select() and ssh_channel_select() are not relevant anymore,
since libssh is about to provide an easier system for asynchronous
communications. This subsection should be removed then. ***
</pre><p><a class="el" href="group__libssh__channel.html#gac92381c4c5d4a7eab35f6e84686f033d" title="Reads data from a channel.">ssh_channel_read()</a> and <a class="el" href="group__libssh__channel.html#gaaca5a3fbe9839c3ffb37b746afc35f4c" title="Do a nonblocking read on the channel.">ssh_channel_read_nonblocking()</a> functions are simple, but they are not adapted when you expect data from more than one SSH channel, or from other file descriptors. Last example showed how getting data from the standard input (the keyboard) at the same time as data from the SSH channel was complicated. The functions <a class="el" href="group__libssh__session.html#ga86cbf041bced56d18a2a5248c46cecb4" title="A wrapper for the select syscall.">ssh_select()</a> and <a class="el" href="group__libssh__channel.html#ga1026cfa48ecfc0b4898d4ea443acfc5d" title="Act like the standard select(2) on channels.">ssh_channel_select()</a> provide a more elegant way to wait for data coming from many sources.</p>
<p>The functions <a class="el" href="group__libssh__session.html#ga86cbf041bced56d18a2a5248c46cecb4" title="A wrapper for the select syscall.">ssh_select()</a> and <a class="el" href="group__libssh__channel.html#ga1026cfa48ecfc0b4898d4ea443acfc5d" title="Act like the standard select(2) on channels.">ssh_channel_select()</a> remind of the standard UNIX select(2) function. The idea is to wait for "something" to happen: incoming data to be read, outcoming data to block, or an exception to occur. Both these functions do a "passive wait", i.e. you can safely use them repeatedly in a loop, it will not consume exaggerate processor time and make your computer unresponsive. It is quite common to use these functions in your application's main loop.</p>
<p>The difference between <a class="el" href="group__libssh__session.html#ga86cbf041bced56d18a2a5248c46cecb4" title="A wrapper for the select syscall.">ssh_select()</a> and <a class="el" href="group__libssh__channel.html#ga1026cfa48ecfc0b4898d4ea443acfc5d" title="Act like the standard select(2) on channels.">ssh_channel_select()</a> is that <a class="el" href="group__libssh__channel.html#ga1026cfa48ecfc0b4898d4ea443acfc5d" title="Act like the standard select(2) on channels.">ssh_channel_select()</a> is simpler, but allows you only to watch SSH channels. <a class="el" href="group__libssh__session.html#ga86cbf041bced56d18a2a5248c46cecb4" title="A wrapper for the select syscall.">ssh_select()</a> is more complete and enables watching regular file descriptors as well, in the same function call.</p>
<p>Below is an example of a function that waits both for remote SSH data to come, as well as standard input from the keyboard:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> interactive_shell_session(ssh_session session, ssh_channel channel)</div>
<div class="line">{</div>
<div class="line">  <span class="comment">/* Session and terminal initialization skipped */</span></div>
<div class="line">  ...</div>
<div class="line"></div>
<div class="line">  <span class="keywordtype">char</span> buffer[256];</div>
<div class="line">  <span class="keywordtype">int</span> nbytes, nwritten;</div>
<div class="line"></div>
<div class="line">  <span class="keywordflow">while</span> (<a class="code" href="group__libssh__channel.html#gaaafcda943c96ddb91e5c28c0bdee7045" title="Check if the channel is open or not.">ssh_channel_is_open</a>(channel) &amp;&amp;</div>
<div class="line">         !<a class="code" href="group__libssh__channel.html#gab535264029443d77214c0615a0788b0a" title="Check if remote has sent an EOF.">ssh_channel_is_eof</a>(channel))</div>
<div class="line">  {</div>
<div class="line">    <span class="keyword">struct </span>timeval timeout;</div>
<div class="line">    ssh_channel in_channels[2], out_channels[2];</div>
<div class="line">    fd_set fds;</div>
<div class="line">    <span class="keywordtype">int</span> maxfd;</div>
<div class="line"></div>
<div class="line">    timeout.tv_sec = 30;</div>
<div class="line">    timeout.tv_usec = 0;</div>
<div class="line">    in_channels[0] = channel;</div>
<div class="line">    in_channels[1] = NULL;</div>
<div class="line">    FD_ZERO(&amp;fds);</div>
<div class="line">    FD_SET(0, &amp;fds);</div>
<div class="line">    FD_SET(<a class="code" href="group__libssh__session.html#gafe509fcea47714b5cd277d1e35e83276" title="Get the fd of a connection.">ssh_get_fd</a>(session), &amp;fds);</div>
<div class="line">    maxfd = <a class="code" href="group__libssh__session.html#gafe509fcea47714b5cd277d1e35e83276" title="Get the fd of a connection.">ssh_get_fd</a>(session) + 1;</div>
<div class="line"></div>
<div class="line">    <a class="code" href="group__libssh__session.html#ga86cbf041bced56d18a2a5248c46cecb4" title="A wrapper for the select syscall.">ssh_select</a>(in_channels, out_channels, maxfd, &amp;fds, &amp;timeout);</div>
<div class="line"></div>
<div class="line">    <span class="keywordflow">if</span> (out_channels[0] != NULL)</div>
<div class="line">    {</div>
<div class="line">      nbytes = <a class="code" href="group__libssh__channel.html#gac92381c4c5d4a7eab35f6e84686f033d" title="Reads data from a channel.">ssh_channel_read</a>(channel, buffer, <span class="keyword">sizeof</span>(buffer), 0);</div>
<div class="line">      <span class="keywordflow">if</span> (nbytes &lt; 0) <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line">      <span class="keywordflow">if</span> (nbytes &gt; 0)</div>
<div class="line">      {</div>
<div class="line">        nwritten = write(1, buffer, nbytes);</div>
<div class="line">        <span class="keywordflow">if</span> (nwritten != nbytes) <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line">      }</div>
<div class="line">    }</div>
<div class="line"></div>
<div class="line">    <span class="keywordflow">if</span> (FD_ISSET(0, &amp;fds))</div>
<div class="line">    {</div>
<div class="line">      nbytes = read(0, buffer, <span class="keyword">sizeof</span>(buffer));</div>
<div class="line">      <span class="keywordflow">if</span> (nbytes &lt; 0) <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line">      <span class="keywordflow">if</span> (nbytes &gt; 0)</div>
<div class="line">      {</div>
<div class="line">        nwritten = <a class="code" href="group__libssh__channel.html#ga5d658df773ba854b35ff9f905341e2fb" title="Blocking write on a channel.">ssh_channel_write</a>(channel, buffer, nbytes);</div>
<div class="line">        <span class="keywordflow">if</span> (nbytes != nwritten) <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line">      }</div>
<div class="line">    }</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  <span class="keywordflow">return</span> rc;</div>
<div class="line">}</div>
</div><!-- fragment --><h2><a class="anchor" id="x11"></a>
Using graphical applications on the remote side</h2>
<p>If your remote application is graphical, you can forward the X11 protocol to your local computer.</p>
<p>To do that, you first declare that you accept X11 connections with <a class="el" href="group__libssh__channel.html#ga548bd0f77a50b7c8180942544b375866" title="Accept an X11 forwarding channel.">ssh_channel_accept_x11()</a>. Then you create the forwarding tunnel for the X11 protocol with <a class="el" href="group__libssh__channel.html#gadfa34624c28164bd73453cd04aa64c1f" title="Sends the &quot;x11-req&quot; channel request over an existing session channel.">ssh_channel_request_x11()</a>.</p>
<p>The following code performs channel initialization and shell session opening, and handles a parallel X11 connection:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> interactive_shell_session(ssh_channel channel)</div>
<div class="line">{</div>
<div class="line">  <span class="keywordtype">int</span> rc;</div>
<div class="line">  ssh_channel x11channel;</div>
<div class="line"></div>
<div class="line">  rc = <a class="code" href="group__libssh__channel.html#ga37c1cec33fe5a2f184768aba52e3a0db" title="Request a PTY.">ssh_channel_request_pty</a>(channel);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK) <span class="keywordflow">return</span> rc;</div>
<div class="line"></div>
<div class="line">  rc = <a class="code" href="group__libssh__channel.html#gaf5d55c90f3d98c583df23d21905c1127" title="Change the size of the terminal associated to a channel.">ssh_channel_change_pty_size</a>(channel, 80, 24);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK) <span class="keywordflow">return</span> rc;</div>
<div class="line"></div>
<div class="line">  rc = <a class="code" href="group__libssh__channel.html#gadfa34624c28164bd73453cd04aa64c1f" title="Sends the &quot;x11-req&quot; channel request over an existing session channel.">ssh_channel_request_x11</a>(channel, 0, NULL, NULL, 0);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK) <span class="keywordflow">return</span> rc;</div>
<div class="line"></div>
<div class="line">  rc = <a class="code" href="group__libssh__channel.html#gaed4c5fb30c9df2b2548421ccf4e81bf1" title="Request a shell.">ssh_channel_request_shell</a>(channel);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK) <span class="keywordflow">return</span> rc;</div>
<div class="line"></div>
<div class="line">  <span class="comment">/* Read the data sent by the remote computer here */</span></div>
<div class="line">  ...</div>
<div class="line">}</div>
</div><!-- fragment --><p>Don't forget to set the $DISPLAY environment variable on the remote side, or the remote applications won't try using the X11 tunnel:</p>
<div class="fragment"><div class="line">$ export DISPLAY=:0</div>
<div class="line">$ xclock &amp;</div>
</div><!-- fragment --> </div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.3.1
</small></address>
</body>
</html>