Quellcode durchsuchen

添加实例:example以及其中的CWinSsh2Proc类。

Jeff vor 5 Jahren
Ursprung
Commit
0f0ba4aafb

+ 40 - 0
libssh2/example/ReadMe.txt

@@ -0,0 +1,40 @@
+========================================================================
+    控制台应用程序:example 项目概述
+========================================================================
+
+应用程序向导已为您创建了此 example 应用程序。
+
+本文件概要介绍组成 example 应用程序的
+的每个文件的内容。
+
+
+example.vcproj
+    这是使用应用程序向导生成的 VC++ 项目的主项目文件,
+    其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
+
+example.cpp
+    这是主应用程序源文件。
+
+/////////////////////////////////////////////////////////////////////////////
+应用程序向导创建了下列资源:
+
+example.rc
+这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。
+此文件可以直接在 Microsoft Visual C++ 中进行编辑。
+
+Resource.h
+    这是标准头文件,可用于定义新的资源 ID。
+    Microsoft Visual C++ 将读取并更新此文件。
+
+/////////////////////////////////////////////////////////////////////////////
+其他标准文件:
+
+StdAfx.h, StdAfx.cpp
+    这些文件用于生成名为 example.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
+
+/////////////////////////////////////////////////////////////////////////////
+其他注释:
+
+应用程序向导使用“TODO:”注释来指示应添加或自定义的源代码部分。
+
+/////////////////////////////////////////////////////////////////////////////

+ 17 - 0
libssh2/example/Resource.h

@@ -0,0 +1,17 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by example.rc
+//
+
+#define IDS_APP_TITLE			103
+
+// жÔÏóµÄÏÂÒ»×éĬÈÏÖµ
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE	101
+#define _APS_NEXT_COMMAND_VALUE		40001
+#define _APS_NEXT_CONTROL_VALUE		1000
+#define _APS_NEXT_SYMED_VALUE		101
+#endif
+#endif

+ 343 - 0
libssh2/example/WinSsh2Proc.cpp

@@ -0,0 +1,343 @@
+#include "StdAfx.h"
+#include "WinSsh2Proc.h"
+
+CWinSsh2Proc::CWinSsh2Proc(void)
+{
+
+}
+
+CWinSsh2Proc::~CWinSsh2Proc(void)
+{
+
+}
+
+bool CWinSsh2Proc::InitSocket()
+{
+	WSADATA wsadata;
+	int err = WSAStartup(MAKEWORD(2, 0), &wsadata);
+	if( err != 0 ) {
+		fprintf(stderr, "WSAStartup failed with error: %d\n", err);
+		return false;
+	}
+
+	return true;
+}
+
+int CWinSsh2Proc::waitsocket(int socket_fd, LIBSSH2_SESSION *session)
+{
+	struct timeval timeout;
+	int rc;
+	fd_set fd;
+	fd_set *writefd = NULL;
+	fd_set *readfd = NULL;
+	int dir;
+
+	timeout.tv_sec = 10;
+	timeout.tv_usec = 0;
+
+	FD_ZERO(&fd);
+
+	FD_SET(socket_fd, &fd);
+
+	/* now make sure we wait in the correct direction */
+	dir = libssh2_session_block_directions(session);
+
+	if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
+		readfd = &fd;
+
+	if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
+		writefd = &fd;
+
+	rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
+
+	return rc;
+}
+
+bool CWinSsh2Proc::ssh2_connect(std::string host, std::string user, std::string pwd, int port /*=22*/)
+{
+	m_user = user;
+	m_pwd = pwd;
+	m_port = port;
+	m_host = host;
+	// 创建socket连接;
+	unsigned long hostaddr = inet_addr(host.c_str());
+	SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
+	m_sin.sin_family = AF_INET;
+	m_sin.sin_port = htons(port);
+	m_sin.sin_addr.s_addr = hostaddr;
+	if ( connect(sock, (const sockaddr*)&m_sin, sizeof(m_sin)) != 0 ) {
+		printf("failed to connect!\n");
+		return false;
+	}
+
+	closesocket(sock);
+
+	return true;
+}
+
+/*
+void CWinSsh2Proc::ssh2_disconnect()
+{
+	int rc;
+	int bytecount = 0;
+	int exitcode = 127;
+	char *exitsignal = (char *)"none";
+	m_bStatus = false;
+	if ( m_pChannel == NULL )
+		goto shutdown;
+
+	while((rc = libssh2_channel_close(m_pChannel)) == LIBSSH2_ERROR_EAGAIN)
+		waitsocket(m_sock, m_pSession);
+
+	if(rc == 0) {
+		exitcode = libssh2_channel_get_exit_status(m_pChannel);
+		libssh2_channel_get_exit_signal(m_pChannel, &exitsignal, NULL, NULL, NULL, NULL, NULL);
+	}
+
+	if(exitsignal)
+		fprintf(stderr, "\nGot signal: %s\n", exitsignal);
+	else
+		fprintf(stderr, "\nEXIT: %d bytecount: %d\n", exitcode, bytecount);
+
+	libssh2_channel_free(m_pChannel);
+	m_pChannel = NULL;
+
+shutdown:
+	libssh2_session_disconnect(m_pSession, "Normal Shutdown, Thank you for playing");
+	libssh2_session_free(m_pSession);
+	m_pSession = NULL;
+
+#ifdef WIN32
+	closesocket(m_sock);
+#else
+	close(m_sock);
+#endif
+	fprintf(stderr, "all done\n");
+
+	libssh2_exit();
+}
+*/
+
+bool CWinSsh2Proc::ssh2_execute_command(std::string cmd, std::string &result, DWORD dwTimeout /*= 1000*/)
+{
+	int rc;
+	bool bRet = false;
+	SOCKET sock = INVALID_SOCKET;
+	LIBSSH2_SESSION* pSession = NULL;
+	LIBSSH2_CHANNEL* pChannel = NULL;
+	if ( !ssh2_init_session(&pSession, sock) )
+		return false;
+
+	// 请求一个shell;
+	while((pChannel= libssh2_channel_open_session(pSession)) == NULL && 
+		libssh2_session_last_error(pSession, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN) {
+		waitsocket(sock, pSession);
+	}
+
+	if ( pChannel == NULL ) {
+		printf("Error\n");
+		goto shutdown;
+	}
+#if 0
+	// 请求一个模拟终端;
+	if( libssh2_channel_request_pty(pChannel,"VT100") != LIBSSH2_ERROR_NONE ) {
+		printf("ssh请求伪终端失败,退出。\n");
+		goto skip_shell;
+	}
+
+	// 在模拟终端上开户shell;
+	if(libssh2_channel_shell(pChannel) != LIBSSH2_ERROR_NONE ) {
+		printf("ssh shell请求失败,退出\n");
+		goto shutdown;
+	}
+#else	
+	while((rc = libssh2_channel_exec(pChannel, cmd.c_str())) == LIBSSH2_ERROR_EAGAIN) {
+			waitsocket(sock, pSession);
+	}
+	if ( rc != LIBSSH2_ERROR_NONE )
+		goto skip_shell;
+#endif
+
+	// 设置为阻塞模式;
+	libssh2_channel_set_blocking(pChannel,0);
+
+	if ( cmd.at(cmd.size()-1) != '\n' )
+		cmd.append("\n");
+
+	while((rc = libssh2_channel_write(pChannel, cmd.c_str(),  cmd.size())) == LIBSSH2_ERROR_EAGAIN ) {
+		printf("ssh写堵塞,重试\n");
+		waitsocket(sock, pSession);
+	}
+
+	if ( rc < 0 )
+		goto shutdown;
+
+	Sleep(dwTimeout);
+	ssh2_read_channel(pChannel, result);
+	bRet = true;
+
+skip_shell:
+	if(pChannel) {
+		libssh2_channel_free(pChannel);
+		pChannel = NULL;
+	}
+
+shutdown:
+	libssh2_session_disconnect(pSession,"Normal Shutdown, Thank you for playing");
+	libssh2_session_free(pSession);
+
+#ifdef WIN32
+	closesocket(sock);
+#else
+	close(sock);
+#endif
+	libssh2_exit();
+
+	return bRet;
+}
+
+void CWinSsh2Proc::ssh2_read_channel(LIBSSH2_CHANNEL* pChannel, std::string &buffer)
+{
+	if ( pChannel == NULL )
+		return;
+
+	int rc;
+	char buf[1024] = "";
+	buffer.clear();
+	do {
+		rc = libssh2_channel_read(pChannel, buf, sizeof(buf) - 1);
+		if(rc > 0) {
+			buf[rc] = 0;
+			buffer.append(buf, rc);
+			memset(buf, 0, sizeof(buf));
+		}
+	}while( rc > 0 );
+
+	printf("%s \n", buffer.c_str());
+}
+
+bool CWinSsh2Proc::ssh2_init_session(LIBSSH2_SESSION** pSession, SOCKET &sock)
+{
+	// 初始化库;
+	int rc = libssh2_init(0);
+	if ( rc != LIBSSH2_ERROR_NONE ) {
+		fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
+		return false;
+	}
+
+	sock = socket(AF_INET, SOCK_STREAM, 0);
+	if ( connect(sock, (const sockaddr*)&m_sin, sizeof(m_sin)) != 0 ) {
+		fprintf(stderr, "failed to connect!\n");
+		return false;
+	}
+
+	// 建立ssh会话实例;
+	*pSession = libssh2_session_init();
+	libssh2_session_set_blocking(*pSession, 1);
+
+	rc = libssh2_session_handshake(*pSession, sock);
+	if ( rc != LIBSSH2_ERROR_NONE ){
+		printf("Failure establishing SSH session: %d\n", rc);
+		// 释放资源;
+		SHUTDOWN(*pSession, sock)
+		return false;
+	}
+
+	// 登录linux;
+	rc = libssh2_userauth_password(*pSession, m_user.c_str(), m_pwd.c_str());
+	if( rc != LIBSSH2_ERROR_NONE ) {
+		printf("Authentication by password failed: %d\n", rc);
+		// 释放资源;
+		SHUTDOWN(*pSession, sock)
+		return false;
+	}
+	
+	return true;
+}
+
+bool CWinSsh2Proc::ssh2_sftp_download(std::string sftppath, std::string localpath)
+{
+	SOCKET sock = -1;
+	LIBSSH2_SESSION *session;
+	LIBSSH2_SFTP *sftp_session;
+	LIBSSH2_SFTP_HANDLE *sftp_handle;
+	// 初始化库;
+	int rc = libssh2_init(0);
+	if ( rc != LIBSSH2_ERROR_NONE ) {
+		fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
+		return false;
+	}
+
+	// 创建socket连接;
+	sock = socket(AF_INET, SOCK_STREAM, 0);
+	if ( connect(sock, (const sockaddr*)&m_sin, sizeof(m_sin)) != 0 ) {
+		fprintf(stderr, "failed to connect!\n");
+		return false;
+	}
+
+	// 建立ssh会话实例;
+	session = libssh2_session_init();
+	/* Since we have set non-blocking, tell libssh2 we are blocking */
+	libssh2_session_set_blocking(session, 1);
+
+	//while ( LIBSSH2_ERROR_EAGAIN == (rc = libssh2_session_handshake(m_pSession, m_sock)) );
+	rc = libssh2_session_handshake(session, sock);
+	if ( rc != LIBSSH2_ERROR_NONE ){
+		fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
+		return false;
+	}
+
+	// 登录linux;
+	bool bDone = false;
+	//while ( LIBSSH2_ERROR_EAGAIN == (rc = libssh2_userauth_password(m_pSession, user.c_str(), pwd.c_str())));
+	rc = libssh2_userauth_password(session, m_user.c_str(), m_pwd.c_str());
+	if( rc != LIBSSH2_ERROR_NONE ) {
+		fprintf(stderr, "Authentication by password failed: %d\n", rc);
+		goto shutdown;
+	}
+
+	sftp_session = libssh2_sftp_init(session);
+	if (!sftp_session) {
+		goto shutdown;
+	}
+
+	/* Request a file via SFTP */
+	sftp_handle = libssh2_sftp_open(sftp_session, sftppath.c_str(), LIBSSH2_FXF_READ, 0);
+
+
+	if (!sftp_handle) {
+		goto shutdown;
+	}
+
+	FILE *stream;
+	if (fopen_s(&stream, localpath.c_str(), "wb") == 0) {
+		do {
+			char mem[1024];
+
+			/* loop until we fail */
+			rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
+
+			if (rc > 0) {
+				//从内存到磁盘
+				fwrite(mem, 1, rc, stream);
+			}
+			else {
+				break;
+			}
+		} while (1);
+
+		bDone = true;
+		fclose(stream);
+	}
+
+
+	libssh2_sftp_close(sftp_handle);
+	libssh2_sftp_shutdown(sftp_session);
+
+shutdown:
+	libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
+	libssh2_session_free(session);
+	closesocket(sock);//INVALID_SOCKET
+	
+	return bDone;
+}

+ 45 - 0
libssh2/example/WinSsh2Proc.h

@@ -0,0 +1,45 @@
+#ifndef __WIN_SSH2_20200506__
+#define __WIN_SSH2_20200506__
+
+#include "libssh2_config.h"
+#include "libssh2.h"
+#include "libssh2_sftp.h"
+
+#include <winsock2.h>
+#pragma comment(lib, "ws2_32.lib")
+
+#pragma once
+
+#define SHUTDOWN(session, sock) \
+libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");\
+libssh2_session_free(session);\
+closesocket(sock);\
+libssh2_exit(); 
+
+class CWinSsh2Proc
+{
+public:
+	CWinSsh2Proc(void);
+	~CWinSsh2Proc(void);
+
+private:
+	int				m_port;
+	std::string		m_host;
+	std::string		m_user;
+	std::string		m_pwd;
+	sockaddr_in		m_sin;
+
+	void ssh2_read_channel(LIBSSH2_CHANNEL* pChannel, std::string &buffer);
+	bool ssh2_init_session(LIBSSH2_SESSION** pSession, SOCKET &sock);
+	void ssh2_free(LIBSSH2_SESSION*	pSession, LIBSSH2_CHANNEL*	pChannel);	
+public:
+	static bool InitSocket();
+	static int waitsocket(int socket_fd, LIBSSH2_SESSION *session);
+	bool ssh2_connect(std::string host, std::string user, std::string pwd, int port = 22);
+	void ssh2_disconnect();
+	bool ssh2_execute_command(std::string cmd, std::string &result, DWORD dwTimeout = 1000);
+	bool ssh2_sftp_download(std::string sftppath, std::string localpath);
+};
+
+
+#endif //__WIN_SSH2_20200506__

+ 246 - 0
libssh2/example/example.cpp

@@ -0,0 +1,246 @@
+// example.cpp : 定义控制台应用程序的入口点。
+//
+
+#include "stdafx.h"
+#include "example.h"
+
+
+#include "libssh2_config.h"
+#include <libssh2.h>
+#include "libssh2_sftp.h"
+
+#include <winsock2.h>
+#include <sys/types.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ctype.h>
+#pragma comment(lib,"libssh2.lib")
+#pragma comment(lib, "ws2_32.lib")
+
+#include "WinSsh2Proc.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// 唯一的应用程序对象
+
+CWinApp theApp;
+
+using namespace std;
+int download(std::string ip, unsigned short port, std::string username, std::string password, std::string sftppath, std::string localpath);
+
+static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
+{
+	struct timeval timeout;
+	int rc;
+	fd_set fd;
+	fd_set *writefd = NULL;
+	fd_set *readfd = NULL;
+	int dir;
+
+	timeout.tv_sec = 10;
+	timeout.tv_usec = 0;
+
+	FD_ZERO(&fd);
+
+	FD_SET(socket_fd, &fd);
+
+	/* now make sure we wait in the correct direction */
+	dir = libssh2_session_block_directions(session);
+
+	if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
+		readfd = &fd;
+
+	if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
+		writefd = &fd;
+
+	rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
+
+	return rc;
+}
+
+
+int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
+{
+	int nRetCode = 0;
+
+#ifdef WIN32
+	WSADATA wsadata;
+	int err;
+
+	err = WSAStartup(MAKEWORD(2, 0), &wsadata);
+	if(err != 0) {
+		fprintf(stderr, "WSAStartup failed with error: %d\n", err);
+		return 1;
+	}
+#endif	
+
+	// 初始化 MFC 并在失败时显示错误
+	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
+	{
+		// TODO: 更改错误代码以符合您的需要
+		_tprintf(_T("错误: MFC 初始化失败\n"));
+		nRetCode = 1;
+	}
+	else
+	{
+		// TODO: 在此处为应用程序的行为编写代码。
+		/*
+		download("10.201.251.254", 22,
+		"wjf", 
+		"wjf2019", 
+		"/scbc_data/wjf/rt2851/Buildimg/V8-T841T01-LF1V001/Images/USB/V8-T841T01-LF1V001.img", 
+		"D:\\sat\\a.img");
+		*/
+		CWinSsh2Proc winssh2;
+		if ( winssh2.InitSocket() )
+		{
+			if ( winssh2.ssh2_connect("10.201.251.254", "wjf", "wjf2019") )
+			{
+				std::string str;
+				// sha256sum 
+				winssh2.ssh2_execute_command("ls", str);
+				winssh2.ssh2_execute_command("md5sum rt2851/Buildimg/V8-T841T01-LF1V001/Images/USB/V8-T841T01-LF1V001.img", str, 8000);
+				winssh2.ssh2_execute_command("sha1sum rt2851/Buildimg/V8-T841T01-LF1V001/Images/USB/V8-T841T01-LF1V001.img", str, 10000);
+				winssh2.ssh2_execute_command("sha256sum rt2851/Buildimg/V8-T841T01-LF1V001/Images/USB/V8-T841T01-LF1V001.img", str, 12000);
+				str.size();
+				//printf("MD5=%s\n", str.c_str());
+			}
+
+			winssh2.ssh2_sftp_download("rt2851/Buildimg/V8-T841T01-LF1V001/Images/USB/build.prop", "D:\\sat\\b.img");
+		}
+	}
+
+
+	system("pause");
+	return nRetCode;
+}
+
+
+int download(std::string ip, unsigned short port, std::string username, std::string password, std::string sftppath, std::string localpath)
+{
+	unsigned long hostaddr;
+	int sock, i, auth_pw = 0;
+	struct sockaddr_in sin;
+	const char *fingerprint;
+	char *userauthlist;
+	LIBSSH2_SESSION *session;
+	int rc;
+	LIBSSH2_SFTP *sftp_session;
+	LIBSSH2_SFTP_HANDLE *sftp_handle;
+
+	hostaddr = inet_addr(ip.c_str()); //hostaddr = htonl(0x7F000001);
+
+	/*
+	* The application code is responsible for creating the socket
+	* and establishing the connection
+	*/
+	sock = socket(AF_INET, SOCK_STREAM, 0);
+
+	sin.sin_family = AF_INET;
+	sin.sin_port = htons(port);
+	sin.sin_addr.s_addr = hostaddr;
+	if (connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) {
+		return -1;
+	}
+
+	/* Create a session instance
+	*/
+	session = libssh2_session_init();
+
+	if (!session)
+		return -1;
+
+	/* Since we have set non-blocking, tell libssh2 we are blocking */
+	libssh2_session_set_blocking(session, 1);
+
+
+	/* ... start it up. This will trade welcome banners, exchange keys,
+	* and setup crypto, compression, and MAC layers
+	*/
+	rc = libssh2_session_handshake(session, sock);
+
+	if (rc) {
+		return -1;
+	}
+
+	/* At this point we havn't yet 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_SHA1);
+
+	for (int i = 0; i < 20; i++) {
+		unsigned char c = fingerprint[i];
+		int nT = c;
+	}
+
+	/* check what authentication methods are available */
+	userauthlist = libssh2_userauth_list(session, username.c_str(), username.length());
+	if (strstr(userauthlist, "password") == NULL)
+	{
+		goto shutdown;
+	}
+
+	/* We could authenticate via password */
+	if (libssh2_userauth_password(session, username.c_str(), password.c_str())) {
+		goto shutdown;
+	}
+
+	sftp_session = libssh2_sftp_init(session);
+	if (!sftp_session) {
+		goto shutdown;
+	}
+
+	/* Request a file via SFTP */
+	sftp_handle = libssh2_sftp_open(sftp_session, sftppath.c_str(), LIBSSH2_FXF_READ, 0);
+
+
+	if (!sftp_handle) {
+		goto shutdown;
+	}
+
+	FILE *stream;
+	if (fopen_s(&stream, localpath.c_str(), "wb") == 0)
+	{
+		do {
+			char mem[1024];
+
+			/* loop until we fail */
+			rc = libssh2_sftp_read(sftp_handle, mem, sizeof(mem));
+
+			if (rc > 0) {
+				//从内存到磁盘
+				fwrite(mem, 1, rc, stream);
+			}
+			else {
+				break;
+			}
+		} while (1);
+
+		fclose(stream);
+	}
+	else {
+		
+	}
+
+	libssh2_sftp_close(sftp_handle);
+
+	libssh2_sftp_shutdown(sftp_session);
+
+shutdown:
+
+	libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
+	libssh2_session_free(session);
+
+	closesocket(sock);//INVALID_SOCKET
+
+	return 0;
+}

+ 3 - 0
libssh2/example/example.h

@@ -0,0 +1,3 @@
+#pragma once
+
+#include "resource.h"

+ 69 - 0
libssh2/example/example.rc

@@ -0,0 +1,69 @@
+//Microsoft Visual C++ 生成的资源脚本。
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// 从 TEXTINCLUDE 2 资源生成。
+//
+#include "afxres.h"
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+LANGUAGE 4, 2
+#pragma code_page(936)
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// 字符串表
+//
+
+STRINGTABLE
+BEGIN
+   IDS_APP_TITLE       "example"
+END
+
+#endif
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// 从 TEXTINCLUDE 3 资源生成。
+//
+#ifndef _AFXDLL
+#include "l.CHS\\afxres.rc"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // 不是 APSTUDIO_INVOKED

+ 253 - 0
libssh2/example/example.vcproj

@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="gb2312"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="example"
+	ProjectGUID="{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}"
+	RootNamespace="example"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ProjectName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\libssh2\include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="libssh2.lib"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ProjectName)\$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="2"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="..\libssh2\include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="libssh2.lib"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="$(OutDir)"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Ô´Îļþ"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\example.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\WinSsh2Proc.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Í·Îļþ"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\example.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Resource.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath=".\targetver.h"
+				>
+			</File>
+			<File
+				RelativePath=".\WinSsh2Proc.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="×ÊÔ´Îļþ"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+			<File
+				RelativePath=".\example.rc"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

+ 8 - 0
libssh2/example/stdafx.cpp

@@ -0,0 +1,8 @@
+// stdafx.cpp : 只包括标准包含文件的源文件
+// example.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+// TODO: 在 STDAFX.H 中
+// 引用任何所需的附加头文件,而不是在此文件中引用

+ 32 - 0
libssh2/example/stdafx.h

@@ -0,0 +1,32 @@
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#include <stdio.h>
+#include <tchar.h>
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
+#endif
+
+#include <afx.h>
+#include <afxwin.h>         // MFC 核心组件和标准组件
+#include <afxext.h>         // MFC 扩展
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h>           // MFC 对 Internet Explorer 4 公共控件的支持
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>                     // MFC 对 Windows 公共控件的支持
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <iostream>
+
+
+
+// TODO: 在此处引用程序需要的其他头文件

+ 24 - 0
libssh2/example/targetver.h

@@ -0,0 +1,24 @@
+#pragma once
+
+// 以下宏定义要求的最低平台。要求的最低平台
+// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
+// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
+// 正常工作。
+
+// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
+// 有关不同平台对应值的最新信息,请参考 MSDN。
+#ifndef WINVER                          // 指定要求的最低平台是 Windows Vista。
+#define WINVER 0x0600           // 将此值更改为相应的值,以适用于 Windows 的其他版本。
+#endif
+
+#ifndef _WIN32_WINNT            // 指定要求的最低平台是 Windows Vista。
+#define _WIN32_WINNT 0x0600     // 将此值更改为相应的值,以适用于 Windows 的其他版本。
+#endif
+
+#ifndef _WIN32_WINDOWS          // 指定要求的最低平台是 Windows 98。
+#define _WIN32_WINDOWS 0x0410 // 将此值更改为适当的值,以适用于 Windows Me 或更高版本。
+#endif
+
+#ifndef _WIN32_IE                       // 指定要求的最低平台是 Internet Explorer 7.0。
+#define _WIN32_IE 0x0700        // 将此值更改为相应的值,以适用于 IE 的其他版本。
+#endif

+ 21 - 21
libssh2/libssh2.sln

@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 10.00
 # Visual Studio 2008
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libssh2", "libssh2\libssh2.vcproj", "{656EF6DD-759A-41F2-BB76-2107C27C910E}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests\tests.vcproj", "{8F6D8D67-8512-4810-8599-F9EE33E94F59}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example\example.vcproj", "{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}"
 	ProjectSection(ProjectDependencies) = postProject
 		{656EF6DD-759A-41F2-BB76-2107C27C910E} = {656EF6DD-759A-41F2-BB76-2107C27C910E}
 	EndProjectSection
@@ -42,26 +42,26 @@ Global
 		{656EF6DD-759A-41F2-BB76-2107C27C910E}.WinCNG LIB Debug|Win32.Build.0 = WinCNG LIB Debug|Win32
 		{656EF6DD-759A-41F2-BB76-2107C27C910E}.WinCNG LIB Release|Win32.ActiveCfg = WinCNG LIB Release|Win32
 		{656EF6DD-759A-41F2-BB76-2107C27C910E}.WinCNG LIB Release|Win32.Build.0 = WinCNG LIB Release|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.Debug|Win32.ActiveCfg = Debug|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.Debug|Win32.Build.0 = Debug|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.OpenSSL DLL Debug|Win32.ActiveCfg = Debug|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.OpenSSL DLL Debug|Win32.Build.0 = Debug|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.OpenSSL DLL Release|Win32.ActiveCfg = Release|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.OpenSSL DLL Release|Win32.Build.0 = Release|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.OpenSSL LIB Debug|Win32.ActiveCfg = Debug|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.OpenSSL LIB Debug|Win32.Build.0 = Debug|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.OpenSSL LIB Release|Win32.ActiveCfg = Release|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.OpenSSL LIB Release|Win32.Build.0 = Release|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.Release|Win32.ActiveCfg = Release|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.Release|Win32.Build.0 = Release|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.WinCNG DLL Debug|Win32.ActiveCfg = Debug|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.WinCNG DLL Debug|Win32.Build.0 = Debug|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.WinCNG DLL Release|Win32.ActiveCfg = Release|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.WinCNG DLL Release|Win32.Build.0 = Release|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.WinCNG LIB Debug|Win32.ActiveCfg = Debug|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.WinCNG LIB Debug|Win32.Build.0 = Debug|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.WinCNG LIB Release|Win32.ActiveCfg = Release|Win32
-		{8F6D8D67-8512-4810-8599-F9EE33E94F59}.WinCNG LIB Release|Win32.Build.0 = Release|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.Debug|Win32.Build.0 = Debug|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.OpenSSL DLL Debug|Win32.ActiveCfg = Debug|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.OpenSSL DLL Debug|Win32.Build.0 = Debug|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.OpenSSL DLL Release|Win32.ActiveCfg = Release|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.OpenSSL DLL Release|Win32.Build.0 = Release|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.OpenSSL LIB Debug|Win32.ActiveCfg = Debug|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.OpenSSL LIB Debug|Win32.Build.0 = Debug|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.OpenSSL LIB Release|Win32.ActiveCfg = Release|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.OpenSSL LIB Release|Win32.Build.0 = Release|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.Release|Win32.ActiveCfg = Release|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.Release|Win32.Build.0 = Release|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.WinCNG DLL Debug|Win32.ActiveCfg = Debug|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.WinCNG DLL Debug|Win32.Build.0 = Debug|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.WinCNG DLL Release|Win32.ActiveCfg = Release|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.WinCNG DLL Release|Win32.Build.0 = Release|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.WinCNG LIB Debug|Win32.ActiveCfg = Debug|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.WinCNG LIB Debug|Win32.Build.0 = Debug|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.WinCNG LIB Release|Win32.ActiveCfg = Release|Win32
+		{4B9B0B01-D3A2-45CF-A45B-ECEDC307CD06}.WinCNG LIB Release|Win32.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 35 - 30
libssh2/tests/simple.c

@@ -92,7 +92,7 @@ int main(int argc, char *argv[])
     size_t len;
     LIBSSH2_KNOWNHOSTS *nh;
     int type;
-
+	char buffer2[0x4000];
 #ifdef WIN32
     WSADATA wsadata;
     int err;
@@ -169,36 +169,24 @@ int main(int argc, char *argv[])
         /* eeek, do cleanup here */
         return 2;
     }
-
+#if 0
     /* read all hosts from here */
-    libssh2_knownhost_readfile(nh, "known_hosts",
-                               LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+    libssh2_knownhost_readfile(nh, "known_hosts", LIBSSH2_KNOWNHOST_FILE_OPENSSH);
 
     /* store all known hosts to here */
-    libssh2_knownhost_writefile(nh, "dumpfile",
-                                LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+    libssh2_knownhost_writefile(nh, "dumpfile", LIBSSH2_KNOWNHOST_FILE_OPENSSH);
 
     fingerprint = libssh2_session_hostkey(session, &len, &type);
     if(fingerprint) {
         struct libssh2_knownhost *host;
 #if LIBSSH2_VERSION_NUM >= 0x010206
         /* introduced in 1.2.6 */
-        int check = libssh2_knownhost_checkp(nh, hostname, 22,
-                                             fingerprint, len,
-                                             LIBSSH2_KNOWNHOST_TYPE_PLAIN|
-                                             LIBSSH2_KNOWNHOST_KEYENC_RAW,
-                                             &host);
+        int check = libssh2_knownhost_checkp(nh, hostname, 22, fingerprint, len, LIBSSH2_KNOWNHOST_TYPE_PLAIN| LIBSSH2_KNOWNHOST_KEYENC_RAW, &host);
 #else
         /* 1.2.5 or older */
-        int check = libssh2_knownhost_check(nh, hostname,
-                                            fingerprint, len,
-                                            LIBSSH2_KNOWNHOST_TYPE_PLAIN|
-                                            LIBSSH2_KNOWNHOST_KEYENC_RAW,
-                                            &host);
+        int check = libssh2_knownhost_check(nh, hostname, fingerprint, len,LIBSSH2_KNOWNHOST_TYPE_PLAIN|LIBSSH2_KNOWNHOST_KEYENC_RAW,&host);
 #endif
-        fprintf(stderr, "Host check: %d, key: %s\n", check,
-                (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
-                host->key:"<none>");
+        fprintf(stderr, "Host check: %d, key: %s\n", check, (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?host->key:"<none>");
 
         /*****
          * At this point, we could verify that 'check' tells us the key is
@@ -210,11 +198,11 @@ int main(int argc, char *argv[])
         return 3;
     }
     libssh2_knownhost_free(nh);
+#endif
 
     if(strlen(password) != 0) {
         /* We could authenticate via password */
-        while((rc = libssh2_userauth_password(session, username, password)) ==
-               LIBSSH2_ERROR_EAGAIN);
+        while((rc = libssh2_userauth_password(session, username, password)) == LIBSSH2_ERROR_EAGAIN);
         if(rc) {
             fprintf(stderr, "Authentication by password failed.\n");
             goto shutdown;
@@ -235,24 +223,43 @@ int main(int argc, char *argv[])
         }
     }
 
+
 #if 0
     libssh2_trace(session, ~0);
 #endif
 
     /* Exec non-blocking on the remove host */
-    while((channel = libssh2_channel_open_session(session)) == NULL &&
-          libssh2_session_last_error(session, NULL, NULL, 0) ==
-          LIBSSH2_ERROR_EAGAIN) {
+    while((channel = libssh2_channel_open_session(session)) == NULL && libssh2_session_last_error(session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN) {
         waitsocket(sock, session);
     }
     if(channel == NULL) {
         fprintf(stderr, "Error\n");
         exit(1);
     }
-    while((rc = libssh2_channel_exec(channel, commandline)) ==
-           LIBSSH2_ERROR_EAGAIN) {
+
+	// ½¨Á¢Ò»¸öÖÕ¶ËÁ¬½Ó(pty)
+	if ( libssh2_channel_request_pty(channel, "VT100") != 0 )
+	{
+		return -1;
+	}
+
+	commandline = "ls rt2851";
+    while((rc = libssh2_channel_exec(channel, commandline)) == LIBSSH2_ERROR_EAGAIN) {
         waitsocket(sock, session);
     }
+	memset(buffer2, 0, sizeof(buffer2));
+	rc = libssh2_channel_read(channel, buffer2, sizeof(buffer2) );
+
+	//commandline = "ls";
+	commandline = "ls rt2851/Buildimg/V8-T841T01-LF1V001/Images/USB";
+	while((rc = libssh2_channel_exec(channel, commandline)) == LIBSSH2_ERROR_EAGAIN) {
+		waitsocket(sock, session);
+	}
+
+	Sleep(5000);
+	memset(buffer2, 0, sizeof(buffer2));
+	rc = libssh2_channel_read(channel, buffer2, sizeof(buffer2) );
+
     if(rc != 0) {
         fprintf(stderr, "Error\n");
         exit(1);
@@ -293,8 +300,7 @@ int main(int argc, char *argv[])
 
     if(rc == 0) {
         exitcode = libssh2_channel_get_exit_status(channel);
-        libssh2_channel_get_exit_signal(channel, &exitsignal,
-                                        NULL, NULL, NULL, NULL, NULL);
+        libssh2_channel_get_exit_signal(channel, &exitsignal,NULL, NULL, NULL, NULL, NULL);
     }
 
     if(exitsignal)
@@ -307,8 +313,7 @@ int main(int argc, char *argv[])
 
 shutdown:
 
-    libssh2_session_disconnect(session,
-                               "Normal Shutdown, Thank you for playing");
+    libssh2_session_disconnect(session, "Normal Shutdown, Thank you for playing");
     libssh2_session_free(session);
 
 #ifdef WIN32