On Wed, Aug 01, 2007 at 05:56:53PM +0200, Thomas Harding wrote:
>
> >>On Tue, 31 Jul 2007, Thomas Harding wrote:
> >Daniel Stenberg <[EMAIL PROTECTED]>
> >
> >>My problem is that while using libssh2_channel_read_stderr, it seems to
> >>wait infinitely for data when no data is available, whatever channel is or
> >>is not in blocking mode.
> >
> >Can you please provide a complete small source snippet that reproduces the
> >problem?
>
> Well, maybe the better will be to me to write such this, but it is not
> done... hope following code will be enough explicit.
Here is the code snippet in attachment.
This can be compiled in lieue of example/simple/ssh2.c
Note I'm a "C" newbie, and have not network programming experience.
So, then running this example:
./ssh2 127.0.0.1 tom '*****' 'cat xulu' 1 100
>foo
^IP ^user ^pass ^command ^display errors if 1 ^if
given, poll timeout in ms. If not, running in blocking mode
* ./ssh2 127.0.0.1 tom '*****' 'cat xulu' 1 100 >foo
> display error message. OK
* ./ssh2 127.0.0.1 tom '*****' 'cat mbox' 1 100 >foo
> records mbox in foo. OK
* ./ssh2 127.0.0.1 tom '*****' 'cat xulu; cat mbox; cat mbox' 1 100 >foo
> display error messages
> records _partly_ mbox in foo. BAD
* ./ssh2 127.0.0.1 tom '*****' 'cat xulu; cat mbox; cat xulu' 1 >foo
or * ./ssh2 127.0.0.1 tom '*****' 'cat mbox' 1 >foo
> stops while reading stderr. BAD
* ./ssh2 127.0.0.1 tom '*****' 'cat xulu' 1 >foo
> display error and quit. OK
* ./ssh2 127.0.0.1 tom '*****' 'cat mbox' >foo
> records mbox in foo. OK
So, have someone a good method to read both completely stdout and
stderr?
--
Thomas Harding
/*
* $Id: ssh2.c,v 1.3 2007/04/26 23:59:15 gknauf Exp $
*
* Sample showing how to do SSH2 connect.
*
* The sample code has default values for host name, user name, password
* and path to copy, but you can specify them on the command line like:
*
* "ssh2 host user password"
*/
#include <libssh2.h>
#include <libssh2_sftp.h>
#include <libssh2_config.h>
#include <string.h>
#ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
int
main (int argc, char *argv[])
{
unsigned long hostaddr;
int sock, i, auth_pw = 1;
struct sockaddr_in sin;
const char *fingerprint;
LIBSSH2_SESSION *session;
LIBSSH2_CHANNEL *channel;
char *username = (char *) "username";
char *password = (char *) "password";
char *command = (char *) "cat mbox";
size_t bufsiz = 8193;
size_t ret = 0;
char *buf;
char *strout;
int retcount = 0;
int strlencount = 0;
int num;
int display_errors;
int set_non_blocking;
int nfds = 1;
LIBSSH2_POLLFD *fds;
LIBSSH2_POLLFD *fdserr;
int timeout;
int test_err;
#ifdef WIN32
WSADATA wsadata;
WSAStartup (WINSOCK_VERSION, &wsadata);
#endif
if (argc > 1)
{
hostaddr = inet_addr (argv[1]);
}
else
{
hostaddr = htonl (0x7F000001);
}
if (argc > 2)
{
username = argv[2];
}
if (argc > 3)
{
password = argv[3];
}
if (argc > 4)
{
command = argv[4];
}
else
{
fprintf (stderr,
"Usage: %s username password command [1 to display errors [timeout in ms]]",
argv[0]);
return 1;
}
if (argc > 5)
{
display_errors = (strtol (argv[5], NULL, 10) == 1) ? 1 : 0;
fprintf (stderr, "Display errors: %d\n", display_errors);
}
else
{
display_errors = 0;
}
if (argc > 6)
{
set_non_blocking = 1;
timeout = strtol (argv[6], NULL, 10);
fprintf (stderr, "Timeout %d\n", timeout);
}
else
{
set_non_blocking = 0;
}
/* Ultra basic "connect to port 22 on localhost"
* Your code is responsible for creating the socket establishing the connection
*/
sock = socket (AF_INET, SOCK_STREAM, 0);
#ifndef WIN32
fcntl (sock, F_SETFL, 0);
#endif
sin.sin_family = AF_INET;
sin.sin_port = htons (22);
sin.sin_addr.s_addr = hostaddr;
if (connect (sock, (struct sockaddr *) (&sin),
sizeof (struct sockaddr_in)) != 0)
{
fprintf (stderr, "failed to connect!\n");
return -1;
}
/* Create a session instance and start it up
* This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers
*/
session = libssh2_session_init ();
if (libssh2_session_startup (session, sock))
{
fprintf (stderr, "Failure establishing SSH session\n");
return -1;
}
/* At this point we havn't authenticated,
* The first thing to do is check the hostkey's fingerprint against our known hosts
* Your app may have it hard coded, may go to a file, may present it to the user, that's your call
*/
fingerprint = libssh2_hostkey_hash (session, LIBSSH2_HOSTKEY_HASH_MD5);
fprintf (stderr, "Fingerprint: ");
for (i = 0; i < 16; i++)
{
fprintf (stderr, "%02X ", (unsigned char) fingerprint[i]);
}
fprintf (stderr, "\n");
if (auth_pw)
{
/* We could authenticate via password */
if (libssh2_userauth_password (session, username, password))
{
printf ("Authentication by password failed.\n");
goto shutdown;
}
}
else
{
/* Or by public key */
if (libssh2_userauth_publickey_fromfile
(session, username, "/home/username/.ssh/id_rsa.pub",
"/home/username/.ssh/id_rsa", password))
{
printf ("\tAuthentication by public key failed\n");
goto shutdown;
}
}
/* Request a shell */
if (!(channel = libssh2_channel_open_session (session)))
{
fprintf (stderr, "Unable to open a session\n");
goto shutdown;
}
/* At this point the shell can be interacted with using
* libssh2_channel_read()
* libssh2_channel_read_stderr()
* libssh2_channel_write()
* libssh2_channel_write_stderr()
*
* Blocking mode may be (en|dis)abled with: libssh2_channel_set_blocking()
* If the server send EOF, libssh2_channel_eof() will return non-0
* To send EOF to the server use: libssh2_channel_send_eof()
* A channel can be closed with: libssh2_channel_close()
* A channel can be freed with: libssh2_channel_free()
*/
/* execute the command(s) */
if (libssh2_channel_exec (channel, command))
{
fprintf (stderr, "Unable to exec command\n");
goto skip_shell;
}
/* set the channel to blocking/non blocking mode */
if (set_non_blocking == 0)
{
libssh2_channel_set_blocking (channel, 1);
}
else
{
libssh2_channel_set_blocking (channel, 0);
}
/* receive std & err outputs, display them to stdout and stderr */
while (1)
{
fprintf (stderr, "\nMALLOC\n");
if ((buf = malloc (bufsiz)) == NULL)
break;
fprintf (stderr, "MALLOC OK\n");
test_err = 1;
if (set_non_blocking == 1)
{
/* poll for stdout */
if ((fds = malloc (sizeof (LIBSSH2_POLLFD) * 2)) == NULL)
{
fprintf (stderr, "Error while allocating poll struct\n");
goto skip_shell;
}
fds[0].type = LIBSSH2_POLLFD_CHANNEL;
fds[0].fd.channel = channel;
fds[0].events = LIBSSH2_POLLFD_POLLIN;
fds[0].revents = LIBSSH2_POLLFD_POLLIN;
fprintf (stderr, "POLLING\n");
test_err = libssh2_poll (fds, nfds, timeout);
fprintf (stderr, "POLL %d\n", test_err);
fprintf (stderr, "POLL REVENTS %d\n", fds[0].revents);
free (fds);
}
ret = 0;
if (test_err > 0)
{
/* gets stdout */
ret = libssh2_channel_read (channel, buf, bufsiz - 10);
fprintf (stderr, "STD BUFFER SIZE= %d\n", ret);
}
if (ret > 0)
{
/* display stdout */
strlencount += strlen (buf);
retcount += ret;
fprintf (stderr, "RET=%d\nLEN=%d\n", ret, strlen (buf));
if ((strout = malloc (ret + 1)) != NULL)
{
num = snprintf (strout, ret + 1, "%s", buf);
fprintf (stderr, "N=%d\n", num);
/* printf(strout); */
fprintf (stdout, "%s", strout);
free (strout);
}
}
else
{
fprintf (stderr, "\nRET=%d\n", ret);
}
free (buf);
if (display_errors == 1)
{
fprintf (stderr, "BEGIN LOOPERR\n");
if (set_non_blocking == 1)
{
/* poll for stderr */
if ((fdserr = malloc (sizeof (LIBSSH2_POLLFD) * 2)) == NULL)
{
fprintf (stderr, "Error while allocating poll struct\n");
goto skip_shell;
}
fdserr[0].type = LIBSSH2_POLLFD_CHANNEL;
fdserr[0].fd.channel = channel;
fdserr[0].events = LIBSSH2_POLLFD_POLLEXT;
fdserr[0].revents = LIBSSH2_POLLFD_POLLEXT;
/*
fdserr[1].type = LIBSSH2_POLLFD_CHANNEL;
fdserr[1].fd.channel = channel;
fdserr[1].events = ;
fdserr[1].revents = ;
*/
fprintf (stderr, "POLLING ERRORS\n");
usleep (timeout);
test_err = libssh2_poll (fdserr, nfds, timeout);
fprintf (stderr, "END POLLING ERRORS\n");
fprintf (stderr, "POLLERR %d\n", test_err);
fprintf (stderr, "POLLERR REVENTS %d\n", fdserr[0].revents);
free (fdserr);
}
else
{
test_err = 1;
}
if (test_err > 0)
{
/* gets and display stderr */
fprintf (stderr, "ERROR: ");
if ((buf = malloc (bufsiz)) == NULL)
break;
ret = libssh2_channel_read_stderr (channel, buf, bufsiz - 10);
fprintf (stderr, "STDERR BUFFER SIZE= %d\n", ret);
if (ret > 0)
{
if ((strout = malloc (ret + 1)) != NULL)
{
num = snprintf (strout, ret + 1, "%s", buf);
/* printf(strout); */
fprintf (stderr, "%s", strout);
fprintf (stderr, "NERR=%d\n", num);
}
else
{
fprintf (stderr, "NULL ASSIGNMENT");
}
free (strout);
}
else
{
fprintf (stderr, "\nSTDERR_RET=%d\n", ret);
}
free (buf);
}
}
fprintf (stderr, "BEF EOF\n", num);
if (libssh2_channel_eof (channel) == 1)
{
/* end read at remote EOF */
fprintf (stderr, "EOF\n", num);
fprintf (stderr, "\nEOF: RET %d octets, STRLEN %d octets\n",
retcount, strlencount);
break;
}
fprintf (stderr, "AFT EOF\n", num);
}
skip_shell:
if (channel)
{
libssh2_channel_free (channel);
channel = NULL;
}
/* Other channel types are supported via:
* libssh2_scp_send()
* libssh2_scp_recv()
* libssh2_channel_direct_tcpip()
*/
shutdown:
libssh2_session_disconnect (session,
"Normal Shutdown, Thank you for playing");
libssh2_session_free (session);
#ifdef WIN32
Sleep (1000);
closesocket (sock);
#else
sleep (1);
close (sock);
#endif
fprintf (stderr, "all done\n");
return 0;
}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
libssh2-devel mailing list
libssh2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libssh2-devel