Using-libcurl-with-SSH-support-in-Visual-Studio-2010
Using-libcurl-with-SSH-support-in-Visual-Studio-2010
Using-libcurl-with-SSH-support-in-Visual-Studio-2010
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong><br />
<strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong><br />
Version 1.3<br />
© Andrei Jakab (andrei.jakab@tut.fi)<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 1
Revision History<br />
Revision Date By Comment<br />
1.0 11 Jul 2011 Andrei Jakab Initial version<br />
1.1 17 Jul 2012 Andrei Jakab Updated the guide to reflect the latest<br />
versions of:<br />
o ActivePerl (5.14.2.1402)<br />
o <strong>libcurl</strong> (7.26.0)<br />
o lib<strong>SSH</strong>2 (1.4.2)<br />
o NASM (2.10.01)<br />
o OpenSSL (1.0.1c)<br />
1.2 22 Sep 2012 Andrei Jakab Appendix A: corrected preprocessor<br />
def<strong>in</strong>itions<br />
1.3 05 Feb 2013 Andrei Jakab Updated the guide to reflect the latest<br />
versions of:<br />
o ActivePerl (5.16.2.1602)<br />
o <strong>libcurl</strong> (7.28.1)<br />
o lib<strong>SSH</strong>2 (1.4.3)<br />
o NASM (2.10.07)<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 2
Acknowledgements<br />
I would like to thank the follow<strong>in</strong>g people for help<strong>in</strong>g me make this guide what it is today by<br />
lett<strong>in</strong>g me know about typos and by suggest<strong>in</strong>g improvements:<br />
<br />
<br />
<br />
<br />
<br />
<br />
Chengwei L<strong>in</strong><br />
Jon Woellhaf<br />
Philipp Leusmann<br />
Re<strong>in</strong>hard Gentz<br />
Jack Schmidt<br />
Huu M<strong>in</strong>h Nguyen<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 3
Table of Contents<br />
REVISION HISTORY 2<br />
ACKNOWLEDGEMENTS 3<br />
CONVENTIONS 5<br />
1. INTRODUCTION 6<br />
2. DOWNLOADING THE LATEST SOFTWARE 7<br />
3. INSTALLATION / COMPILATION 8<br />
3.1 ActivePerl 8<br />
3.2 Netwide Assembler 9<br />
3.3 OpenSSL 9<br />
3.4 lib<strong>SSH</strong>2 11<br />
3.5 <strong>libcurl</strong> 13<br />
4. USING THE LIBCURL LIBRARY IN YOUR VISUAL STUDIO PROJECT 15<br />
4.1 Prepar<strong>in</strong>g the project’s file structure 15<br />
4.2 Creat<strong>in</strong>g the test project 16<br />
4.3 How to use the <strong>libcurl</strong> library 19<br />
4.3.1 Sample source code 19<br />
4.3.2 Add<strong>in</strong>g <strong>libcurl</strong> to the list of libraries 22<br />
4.3.3 The test-drive 24<br />
5. FINAL NOTES 25<br />
APPENDIX A – ADDING OPENSSL SUPPORT DIRECTLY TO LIBCURL 26<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 4
Conventions<br />
The follow<strong>in</strong>g font conventions are used <strong>in</strong> this document:<br />
<br />
<br />
<br />
<br />
italic is used for filenames, directory names, and URLs<br />
constant width is used to <strong>in</strong>dicate commands and code sections<br />
red, bold and underl<strong>in</strong>ed text <strong>in</strong>dicates important items<br />
bold is used to represent GUI items (e.g. menus, menu items, list nodes etc.)<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 5
1. Introduction<br />
Libcurl is a widely-used open-source library for transferr<strong>in</strong>g files. It <strong>support</strong>s many protocols<br />
(e.g. FTP, HTTP, SFTP etc.) and it is very well designed.<br />
One of <strong>libcurl</strong>’s strengths is its portability. You can build it on numerous platforms and you can<br />
be sure that it will work the same way on all of them. This wide <strong>support</strong> also means that the<br />
developers cannot constantly update the readme files for all the <strong>support</strong>ed platforms. Thus, I<br />
have decided to create this document <strong>in</strong> order to share my experiences while compil<strong>in</strong>g a static<br />
version of the curl library <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong>.<br />
This document is based on my previous guide “<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong><br />
2008”, which was <strong>in</strong>spired from Rosso Salmanzadeh's excellent “<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong>”<br />
guide.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 6
2. Download<strong>in</strong>g the latest software<br />
Libcurl requires two additional open-source libraries <strong>in</strong> order to provide the <strong>SSH</strong> functionality:<br />
lib<strong>SSH</strong>2 and OpenSSL. Also, s<strong>in</strong>ce the compilation of OpenSSL makes use of Perl scripts, you<br />
need to have a Perl distribution <strong>in</strong>stalled on your mach<strong>in</strong>e. I have chosen ActivePerl, a free<br />
distribution by ActiveState, for this purpose. OpenSSL also requires the Netwide Assembler to<br />
be present on your computer.<br />
The OpenSSL and lib<strong>SSH</strong>2 libraries are distributed as tarballs compressed us<strong>in</strong>g gzip. Hence,<br />
you will need a utility to uncompress and subsequently open the tar file. I recommend the opensource<br />
archiver 7-Zip.<br />
In order to obta<strong>in</strong> the latest version of the Netwide Assembler, click on the l<strong>in</strong>k <strong>in</strong> the table<br />
below and, on the webpage that appears, follow the l<strong>in</strong>k that takes you to the latest stable version<br />
of NASM. You have the choice between download<strong>in</strong>g the source code or pre-compiled b<strong>in</strong>aries.<br />
I strongly encourage you to download the b<strong>in</strong>ary files s<strong>in</strong>ce I will not cover the compilation of<br />
NASM <strong>in</strong> this guide. The archives that conta<strong>in</strong> the b<strong>in</strong>ary distributions are located <strong>in</strong> folders<br />
named after their <strong>in</strong>tended architecture e.g. w<strong>in</strong>32, dos, os2 etc.<br />
Software URL Current Version<br />
ActivePerl http://www.activestate.com/activeperl/downloads 5.16.2.1602<br />
OpenSSL http://www.openssl.org/source 1.0.1c<br />
lib<strong>SSH</strong>2 http://www.libssh2.org 1.4.3<br />
<strong>libcurl</strong> http://curl.haxx.se/download.html 7.28.1<br />
Netwide Assembler http://www.nasm.us 2.10.07<br />
7-Zip http://www.7-zip.org 9.20<br />
NOTE: This guide assumes that you already have successfully <strong>in</strong>stalled Microsoft <strong>Visual</strong><br />
<strong>Studio</strong> <strong>2010</strong> (VS<strong>2010</strong>). The examples <strong>in</strong> this document were built us<strong>in</strong>g version<br />
10.0.40219.1 SP1 of VS<strong>2010</strong>.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 7
3. Installation / Compilation<br />
3.1 ActivePerl<br />
Install<strong>in</strong>g ActivePerl is fairly straightforward as long as you are logged <strong>in</strong> <strong>with</strong> an Adm<strong>in</strong>istrator<br />
account. Below are screenshots from each step of the <strong>in</strong>stallation process. Please pay particular<br />
attention to Step 4 because choos<strong>in</strong>g the wrong option there will make your life harder later.<br />
Step 1 - Introduction<br />
Step 2 - EULA<br />
Step 3 - Customization 1<br />
Note 1: The “Documentation” and<br />
“Examples” are only useful if you<br />
wish to learn how to use ActivePerl;<br />
for the purposes of this document,<br />
these items are not needed.<br />
Note 2: The default <strong>in</strong>stallation location is not<br />
<strong>in</strong> the Program Files folder. Make sure<br />
to change this if you like to keep your<br />
C: folder tidy.<br />
Step 4 - Customization 2<br />
NOTE: Make sure that there’s a checkmark<br />
besides the “Add Perl to the PATH<br />
environment variable” option.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 8
Step 5 - Installation Confirmation<br />
Step 6 - Installation Complete<br />
3.2 Netwide Assembler<br />
1. Extract the nasm-2.10.07 folder from the zip file and place it <strong>in</strong> the C: root directory<br />
3.3 OpenSSL<br />
Compil<strong>in</strong>g the OpenSSL library is a bit tricky. The follow<strong>in</strong>g step-by-step guide should help you<br />
get through the compilation process as quickly and as pa<strong>in</strong>lessly as possible.<br />
1. Extract the openssl-1.0.1c.tar file from the gzip file to a temporary directory<br />
2. Extract the openssl-1.0.1c folder from the tar file and place it <strong>in</strong> the C: root directory<br />
3. Close the VS<strong>2010</strong> IDE and open a <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> command prompt. If you’ve<br />
<strong>in</strong>stalled VS <strong>2010</strong> <strong>with</strong> the default sett<strong>in</strong>gs, the command prompt shortcut should be<br />
located <strong>in</strong> Start -> All Programs -> Microsoft <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> -> <strong>Visual</strong> <strong>Studio</strong><br />
Tools -> <strong>Visual</strong> <strong>Studio</strong> Command Prompt (<strong>2010</strong>)<br />
4. Add the NASM executable to the PATH environment variable:<br />
path = %PATH%;C:\nasm-2.10.07<br />
5. Create the directory where the output of the compilation process will be stored:<br />
mkdir c:\openssl_lib<br />
6. Change the work<strong>in</strong>g directory to the OpenSSL directory:<br />
cd /D c:\openssl-1.0.1c<br />
7. Configure the OpenSSL <strong>in</strong>stallation <strong>with</strong>:<br />
perl Configure VC-WIN32 --prefix=c:/openssl_lib<br />
where the --prefix argument specifies where OpenSSL header and library files will<br />
be copied at the end of the compilation process.<br />
NOTE: The path that is passed to the --prefix argument must be <strong>in</strong> the UNIX<br />
format i.e. forward slashes are used to separate directories and not backward<br />
slashes like it is customary <strong>in</strong> W<strong>in</strong>dows.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 9
The output of this command should look like this:<br />
8. Create the required assembly files:<br />
ms\do_nasm<br />
Note: <strong>Us<strong>in</strong>g</strong> assembly files makes the execution of library functions much faster. If you<br />
do not wish to use assembly files, use the follow<strong>in</strong>g command <strong>in</strong>stead and jump to<br />
step 8:<br />
ms\do_ms<br />
9. Compile the static library:<br />
nmake -f ms\nt.mak<br />
10. The compilation process takes a while so you can go grab some coffee/tea at this po<strong>in</strong>t.<br />
11. If all is well, at the end of the compilation you will have some libraries and a number of<br />
executables <strong>in</strong> C:\openssl-1.0.1c\out32<br />
12. The library conta<strong>in</strong>s some built <strong>in</strong> tests that allow you to check if everyth<strong>in</strong>g has<br />
compiled properly and if the library is <strong>in</strong> work<strong>in</strong>g order:<br />
nmake -f ms\nt.mak test<br />
If the library has compiled properly, you should obta<strong>in</strong> a “passed all tests” message once<br />
this command f<strong>in</strong>ishes execut<strong>in</strong>g.<br />
13. To <strong>in</strong>stall OpenSSL to the location you specified <strong>in</strong> step 6, run:<br />
nmake -f ms\nt.mak <strong>in</strong>stall<br />
Note: You can f<strong>in</strong>d additional compil<strong>in</strong>g <strong>in</strong>structions <strong>in</strong> C:\openssl-1.0.1c\INSTALL.W32; this<br />
file also conta<strong>in</strong>s a troubleshoot<strong>in</strong>g section that could help you out if someth<strong>in</strong>g goes<br />
wrong dur<strong>in</strong>g the compilation process.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 10
3.4 lib<strong>SSH</strong>2<br />
1. Extract the libssh2-1.4.3.tar file from the gzip file to a temporary directory.<br />
2. Extract the libssh2-1.4.3 directory from the tar file and place it <strong>in</strong> the C: root directory.<br />
3. Open C:\libssh2-1.4.3\w<strong>in</strong>32\libssh2.dsp <strong>in</strong> the <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> IDE. S<strong>in</strong>ce this<br />
project file was created us<strong>in</strong>g an older version of <strong>Visual</strong> <strong>Studio</strong>, the follow<strong>in</strong>g message<br />
box will appear:<br />
Click on “Yes”. Once the conversion is completed, you should see the follow<strong>in</strong>g <strong>in</strong> the<br />
Solution Explorer w<strong>in</strong>dow:<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 11
4. Set the LIB Debug as the active solution configuration. On the Build menu <strong>in</strong> <strong>Visual</strong><br />
<strong>Studio</strong>, click Configuration Manager… and <strong>in</strong> the w<strong>in</strong>dow that appears select LIB<br />
Debug from the Active solution configuration drop-down list. Close the Configuration<br />
Manager.<br />
5. Next, you must tell the compiler and the librarian where the OpenSSL library is located<br />
and how to compile the library:<br />
a. Right-click on the libssh2 project <strong>in</strong> the Solution Explorer w<strong>in</strong>dow and select<br />
Properties from the pop-up menu.<br />
b. Expand the Configuration Properties node, click on the C/C++ node<br />
i. Select General, choose the Additional Include Directories property and<br />
add the follow<strong>in</strong>g:<br />
;C:\openssl_lib\<strong>in</strong>clude<br />
(the semicolon needed s<strong>in</strong>ce other paths are already present)<br />
ii. Next, click on Code Generation and <strong>in</strong> the Runtime Library field, select<br />
the Multi-threaded Debug DLL (/MDd) option.<br />
c. Also <strong>in</strong> the Configuration Properties node, expand the Librarian node, and<br />
select General.<br />
i. Change the Output File property to:<br />
Debug_lib\libssh2.lib<br />
ii. Click on the Additional Dependencies property and set it to:<br />
libeay32.lib;ssleay32.lib<br />
iii. Choose the Additional Library Directories and add the follow<strong>in</strong>g path:<br />
C:\openssl_lib\lib<br />
d. Click on the OK button.<br />
6. Now we are ready to compile. Right-click on the libssh2 project and select Build from<br />
the pop-up menu. VS<strong>2010</strong> will prompt you to save the solution file that was created for<br />
this project. Once you save it, compilation will beg<strong>in</strong>.<br />
7. The compiler might display a couple of security warn<strong>in</strong>gs and/or “possible loss of data”<br />
warn<strong>in</strong>gs. Also the l<strong>in</strong>ker might display a number of LNK4221 warn<strong>in</strong>gs. For our<br />
purposes, both of these types of warn<strong>in</strong>gs can be safely ignored.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 12
3.5 <strong>libcurl</strong><br />
1. Extract the curl-7.28.1 folder from the archive and place it <strong>in</strong> the C: root directory. For<br />
our purposes, we will need the files located <strong>in</strong> the lib and <strong>in</strong>clude directories.<br />
2. Open C:\curl-7.28.1\lib\<strong>libcurl</strong>.vcproj <strong>in</strong> the <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> IDE. S<strong>in</strong>ce this is a<br />
<strong>Visual</strong> <strong>Studio</strong> 2005 project file, the “<strong>Visual</strong> <strong>Studio</strong> Conversion Wizard” will appear. The<br />
wizard should not encounter any problems convert<strong>in</strong>g the project to the VS<strong>2010</strong> format<br />
but will generate a couple of warn<strong>in</strong>gs, which can be safely ignored.<br />
3. Next, you must tell the compiler and the librarian to use the lib<strong>SSH</strong>2 library and where<br />
this library is located:<br />
a. Right-click on the <strong>libcurl</strong> project <strong>in</strong> the Solution Explorer w<strong>in</strong>dow and select<br />
Properties from the pop-up menu.<br />
b. Expand the Configuration Properties node, then the C/C++ node.<br />
i. Click on the General node. Next to Additional Include Directories, add<br />
the follow<strong>in</strong>g:<br />
;C:\libssh2-1.4.3\<strong>in</strong>clude<br />
(the semicolon is needed s<strong>in</strong>ce there are already two additional <strong>in</strong>clude<br />
directories specified)<br />
ii. Select the Preprocessor node and click on the Preprocessor Def<strong>in</strong>itions<br />
property. Add <strong>in</strong> the follow<strong>in</strong>g to the exist<strong>in</strong>g def<strong>in</strong>itions:<br />
;CURL_STATICLIB;USE_LIB<strong>SSH</strong>2;CURL_DISABLE_LDAP;HAVE_<br />
LIB<strong>SSH</strong>2;HAVE_LIB<strong>SSH</strong>2_H;LIB<strong>SSH</strong>2_WIN32 ;LIB<strong>SSH</strong>2_LIBRARY<br />
c. In the Configuration Properties node, expand the Librarian node, and select<br />
General.<br />
i. Select Additional Dependencies and type <strong>in</strong>:<br />
libssh2.lib<br />
ii. Next to Additional Library Directories, type <strong>in</strong> the path:<br />
C:\libssh2-1.4.3\w<strong>in</strong>32\Debug_lib<br />
d. Click on the OK button.<br />
4. After all this work, we are f<strong>in</strong>ally ready to compile the <strong>libcurl</strong> library. Right-click on the<br />
curllib project <strong>in</strong> the Solution Explorer and select Build from the pop-up menu. VS<strong>2010</strong><br />
will prompt you to save the solution file that was created for this project. Once you save<br />
it, compilation will beg<strong>in</strong>:<br />
1>------ Build started: Project: <strong>libcurl</strong>, Configuration: Debug W<strong>in</strong>32 ------<br />
1> wildcard.c<br />
1> warnless.c<br />
1> version.c<br />
1> url.c<br />
1> transfer.c<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 13
1> timeval.c<br />
…<br />
1> curl_darw<strong>in</strong>ssl.c<br />
1> curl_addr<strong>in</strong>fo.c<br />
1> cookie.c<br />
1> content_encod<strong>in</strong>g.c<br />
1> Generat<strong>in</strong>g Code...<br />
1> Compil<strong>in</strong>g...<br />
1> connect.c<br />
1> base64.c<br />
1> axtls.c<br />
1> asyn-thread.c<br />
1> asyn-ares.c<br />
1> amigaos.c<br />
1> Generat<strong>in</strong>g Code...<br />
1>libssh2.lib(ecp_nistputil.obj) : warn<strong>in</strong>g LNK4221: This object file does not def<strong>in</strong>e any<br />
previously undef<strong>in</strong>ed public symbols, so it will not be used by any l<strong>in</strong>k operation that<br />
consumes this library<br />
1>libssh2.lib(ecp_nistp521.obj) : warn<strong>in</strong>g LNK4221: This object file does not def<strong>in</strong>e any<br />
previously undef<strong>in</strong>ed public symbols, so it will not be used by any l<strong>in</strong>k operation that<br />
consumes this library<br />
1>libssh2.lib(ecp_nistp256.obj) : warn<strong>in</strong>g LNK4221: This object file does not def<strong>in</strong>e any<br />
previously undef<strong>in</strong>ed public symbols, so it will not be used by any l<strong>in</strong>k operation that<br />
consumes this library<br />
1>libssh2.lib(ecp_nistp224.obj) : warn<strong>in</strong>g LNK4221: This object file does not def<strong>in</strong>e any<br />
previously undef<strong>in</strong>ed public symbols, so it will not be used by any l<strong>in</strong>k operation that<br />
consumes this library<br />
1>libssh2.lib(fips_ers.obj) : warn<strong>in</strong>g LNK4221: This object file does not def<strong>in</strong>e any<br />
previously undef<strong>in</strong>ed public symbols, so it will not be used by any l<strong>in</strong>k operation that<br />
consumes this library<br />
1> <strong>libcurl</strong>.vcxproj -> C:\curl-7.28.1\lib\.\Debug\<strong>libcurl</strong>.lib<br />
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========<br />
The LNK4221 warn<strong>in</strong>gs can be safely ignored.<br />
By default, the output directory is C:\curl-7.28.1\lib\Debug. In order to create an<br />
application that uses the <strong>libcurl</strong> library, we only need the <strong>libcurl</strong>.lib file from the output<br />
directory and the C:\curl-7.28.1\<strong>in</strong>clude\curl directory, which conta<strong>in</strong>s the library’s<br />
header files.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 14
4. <strong>Us<strong>in</strong>g</strong> the <strong>libcurl</strong> library <strong>in</strong> your <strong>Visual</strong> <strong>Studio</strong> project<br />
In this section we will create a test project, which will at the same time test the library’s<br />
functionality and demonstrate how to <strong>in</strong>tegrate <strong>libcurl</strong> <strong>in</strong>to one of your projects. I suggest that<br />
you follow the example step by step (i.e. use the same project names, paths etc.) so that you<br />
obta<strong>in</strong> the same figures as the ones shown below. This will make your life easier <strong>in</strong> case you<br />
encounter any problems along the way.<br />
4.1 Prepar<strong>in</strong>g the project’s file structure<br />
Create the follow<strong>in</strong>g folder structure <strong>in</strong> you C: root directory:<br />
Copy the curl folder from the C:\curl-7.28.1\<strong>in</strong>clude directory <strong>in</strong>to the C:\Projects\custom<br />
libraries\<strong>in</strong>clude directory. The curl directory should conta<strong>in</strong> the follow<strong>in</strong>g files:<br />
Notice that there are also 4 make files <strong>in</strong> this directory. We won’t need them so they can be<br />
safely deleted, if you wish.<br />
F<strong>in</strong>ally, you need to copy liburl.lib from C:\curl-7.28.1\lib\Debug to C:\Projects\custom<br />
libraries\lib_dbg.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 15
4.2 Creat<strong>in</strong>g the test project<br />
The <strong>libcurl</strong> library can be used <strong>in</strong> any type of application. In order to keep th<strong>in</strong>gs simple, we will<br />
create a simple W<strong>in</strong>32 console application.<br />
1. Fire up VS<strong>2010</strong> and go to: File -> New -> Project…<br />
2. First expand the <strong>Visual</strong> C++ node, then select the W<strong>in</strong>32 node and click on the W<strong>in</strong>32<br />
Console Application item <strong>in</strong> the middle panel:<br />
3. Type <strong>in</strong> “test_curl” for the project name. The project location should be:<br />
C:\Projects<br />
Make sure that the checkbox Create directory for solution is checked and click on OK.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 16
4. The W<strong>in</strong>32 Application Wizard will appear. In the first w<strong>in</strong>dow click on Next:<br />
5. In the follow<strong>in</strong>g w<strong>in</strong>dow:<br />
a. Make sure that Console application is selected from the Application type: list<br />
b. In Additional options, uncheck the Precompiled header option.<br />
c. Ensure that both ATL and MFC are unchecked <strong>in</strong> the Add common header files<br />
for: list.<br />
Now you can press on the F<strong>in</strong>ish button and wait for VS<strong>2010</strong> to set up your project.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 17
6. In the Solution Explorer w<strong>in</strong>dow you should see the follow<strong>in</strong>g project structure:<br />
Double-click on test_curl.cpp to open it (if VS<strong>2010</strong> didn’t already do so for you). The<br />
source code should look like this:<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 18
4.3 How to use the <strong>libcurl</strong> library<br />
4.3.1 Sample source code<br />
Replace all the code <strong>in</strong> test_curl.cpp <strong>with</strong> this code:<br />
// headers<br />
#<strong>in</strong>clude "stdafx.h"<br />
#<strong>in</strong>clude <br />
#<strong>in</strong>clude <br />
#<strong>in</strong>clude <br />
// prototypes<br />
<strong>in</strong>t<br />
<strong>libcurl</strong>_progress_callback (void * clientp, double dltotal,<br />
double dlnow, double ultotal,<br />
double ulnow);<br />
size_t <strong>libcurl</strong>_read_callback(void * pBuffer, size_t size, size_t nmemb,<br />
void * hFile);<br />
void <strong>SSH</strong>Upload(char * strFileName, char * strFilePath);<br />
<strong>in</strong>t _tma<strong>in</strong>(<strong>in</strong>t argc, _TCHAR* argv[])<br />
{<br />
<strong>SSH</strong>Upload("test.txt", "C:\\");<br />
pr<strong>in</strong>tf("Press any key to cont<strong>in</strong>ue...");<br />
_getch();<br />
}<br />
return 0;<br />
void <strong>SSH</strong>Upload(char * strFileName, char * strFilePath)<br />
{<br />
char strBuffer[1024];<br />
CURL * hCurl;<br />
CURLcode ccCurlResult = CURL_LAST;<br />
curl_off_t cotFileSize;<br />
HANDLE hFile;<br />
LARGE_INTEGER liFileSize;<br />
// check parameters<br />
if((strFileName == NULL || strlen(strFileName) == 0) ||<br />
(strFilePath == NULL || strlen(strFilePath) == 0))<br />
return;<br />
// parse file path<br />
if(strFilePath[strlen(strFilePath) - 1] == '\\')<br />
spr<strong>in</strong>tf_s(strBuffer, 1024, "%s%s", strFilePath, strFileName);<br />
else<br />
spr<strong>in</strong>tf_s(strBuffer, 1024, "%s\\%s", strFilePath, strFileName);<br />
// create a handle to the file<br />
hFile = CreateFileA(strBuffer,<br />
GENERIC_READ,<br />
FILE_SHARE_READ,<br />
NULL,<br />
OPEN_EXISTING,<br />
FILE_ATTRIBUTE_NORMAL,<br />
NULL);<br />
// file to open<br />
// open for read<strong>in</strong>g<br />
// share for read<strong>in</strong>g<br />
// default security<br />
// exist<strong>in</strong>g file only<br />
// normal file<br />
// no attr. template<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 19
if(hFile != INVALID_HANDLE_VALUE)<br />
{<br />
// global <strong>libcurl</strong> <strong>in</strong>itialisation<br />
ccCurlResult = curl_global_<strong>in</strong>it(CURL_GLOBAL_WIN32);<br />
if(ccCurlResult == 0)<br />
{<br />
// start <strong>libcurl</strong> easy session<br />
hCurl = curl_easy_<strong>in</strong>it();<br />
if(hCurl)<br />
{<br />
// enable verbose operation<br />
curl_easy_setopt(hCurl, CURLOPT_VERBOSE, TRUE);<br />
// enable upload<strong>in</strong>g<br />
curl_easy_setopt(hCurl, CURLOPT_UPLOAD, TRUE);<br />
// <strong>in</strong>form <strong>libcurl</strong> of the file's size<br />
GetFileSizeEx(hFile, &liFileSize);<br />
cotFileSize = liFileSize.QuadPart;<br />
curl_easy_setopt(hCurl,<br />
CURLOPT_INFILESIZE_LARGE,<br />
cotFileSize);<br />
// enable progress report function<br />
curl_easy_setopt(hCurl, CURLOPT_NOPROGRESS, FALSE);<br />
curl_easy_setopt(hCurl,<br />
CURLOPT_PROGRESSFUNCTION,<br />
<strong>libcurl</strong>_progress_callback);<br />
// use custom read function<br />
curl_easy_setopt(hCurl,<br />
CURLOPT_READFUNCTION,<br />
<strong>libcurl</strong>_read_callback);<br />
// specify which file to upload<br />
curl_easy_setopt(hCurl, CURLOPT_READDATA, hFile);<br />
// specify full path of uploaded file (i.e. server<br />
// address plus remote path)<br />
spr<strong>in</strong>tf_s(strBuffer,<br />
1024,<br />
"sftp://123.123.123.123/home/user/%s",<br />
strFileName);<br />
curl_easy_setopt(hCurl, CURLOPT_URL, strBuffer);<br />
// set <strong>SSH</strong> server port<br />
curl_easy_setopt(hCurl, CURLOPT_PORT, 22);<br />
// set <strong>SSH</strong> user name and password <strong>in</strong> <strong>libcurl</strong> <strong>in</strong> this<br />
// format "user:password"<br />
curl_easy_setopt(hCurl,<br />
CURLOPT_USERPWD,<br />
"user:password");<br />
// set <strong>SSH</strong> authentication to user name and password<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 20
}<br />
}<br />
curl_easy_setopt(hCurl,<br />
CURLOPT_<strong>SSH</strong>_AUTH_TYPES,<br />
CURL<strong>SSH</strong>_AUTH_PASSWORD);<br />
// execute command<br />
ccCurlResult = curl_easy_perform(hCurl);<br />
// end <strong>libcurl</strong> easy session<br />
curl_easy_cleanup(hCurl);<br />
}<br />
}<br />
else<br />
// release file handle<br />
CloseHandle(hFile);<br />
// global <strong>libcurl</strong> cleanup<br />
curl_global_cleanup();<br />
if (ccCurlResult == CURLE_OK)<br />
pr<strong>in</strong>tf("File uploaded successfully.\n");<br />
else<br />
pr<strong>in</strong>tf("File upload failed. Curl error: %d\n",<br />
ccCurlResult);<br />
pr<strong>in</strong>tf("File upload failed! Could not open local file");<br />
size_t <strong>libcurl</strong>_read_callback(void * pBuffer, size_t size,<br />
size_t nmemb, void * hFile)<br />
{<br />
DWORD dwNumberOfBytesRead = 0;<br />
BOOL bResult = ReadFile((HANDLE) hFile, pBuffer, size * nmemb,<br />
&dwNumberOfBytesRead, NULL);<br />
}<br />
return dwNumberOfBytesRead;<br />
<strong>in</strong>t <strong>libcurl</strong>_progress_callback (void * clientp, double dltotal, double dlnow,<br />
double ultotal, double ulnow)<br />
{<br />
pr<strong>in</strong>tf("Uploaded: %d / %d\n", (<strong>in</strong>t) ulnow, (<strong>in</strong>t) ultotal);<br />
}<br />
return 0;<br />
NOTE: You must replace some of the <strong>in</strong>formation <strong>in</strong> the sample code:<br />
l<strong>in</strong>e 17: enter a file name to be uploaded and its location on your computer<br />
l<strong>in</strong>e 93: type <strong>in</strong> your server’s IP address and the remote path where the file should<br />
be stored (here I assume that you have access to a computer that is<br />
runn<strong>in</strong>g a <strong>SSH</strong> server)<br />
l<strong>in</strong>e 104: the log<strong>in</strong> credentials for the <strong>SSH</strong> server<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 21
4.3.2 Add<strong>in</strong>g <strong>libcurl</strong> to the list of libraries<br />
Now let’s tell the compiler where to f<strong>in</strong>d the <strong>libcurl</strong> header files and the library itself:<br />
1. In the Solution Explorer w<strong>in</strong>dow, right-click on the test_curl project w<strong>in</strong>dow and select<br />
Properties from the pop-up menu.<br />
2. Expand the Configuration Properties node.<br />
3. Expand the C/C++ node<br />
a. Select the General node, choose the Additional Include Directories property<br />
and add the path:<br />
C:\Projects\custom_libraries\<strong>in</strong>clude<br />
NOTE: While you might be tempted to <strong>in</strong>clude the "C:\Projects\custom<br />
libraries\<strong>in</strong>clude\curl" directory <strong>in</strong>stead, we must add the parent directory<br />
s<strong>in</strong>ce some <strong>libcurl</strong> files use #<strong>in</strong>clude statements like this one: “#<strong>in</strong>clude<br />
”.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 22
. Select the Preprocessor node and click on the Preprocessor Def<strong>in</strong>itions<br />
property. Add <strong>in</strong> the follow<strong>in</strong>g to the exist<strong>in</strong>g def<strong>in</strong>itions:<br />
;CURL_STATICLIB<br />
4. Expand the L<strong>in</strong>ker node.<br />
a. Select the General node, chose the Additional Library Directories property and<br />
add the path:<br />
C:\Projects\custom_libraries\lib_dbg<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 23
. Select the Input node, click on the Additional Dependencies property and add<br />
the follow<strong>in</strong>g to the exist<strong>in</strong>g list of libraries:<br />
;<strong>libcurl</strong>.lib;ws2_32.lib<br />
5. Click on the OK button.<br />
4.3.3 The test-drive<br />
Now we are f<strong>in</strong>ally ready to reap the fruits of our labor: compile and run the program. Depend<strong>in</strong>g<br />
on the size of the file you chose to upload, the output should look similar to the figure on the<br />
next page.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 24
5. F<strong>in</strong>al Notes<br />
Congratulations! You are now ready to use <strong>libcurl</strong> <strong>in</strong> your own projects. If you run <strong>in</strong>to trouble<br />
down the road, don’t hesitate to post a message on <strong>libcurl</strong>’s very active mail<strong>in</strong>g list:<br />
http://cool.haxx.se/mailman/list<strong>in</strong>fo/curl-library. However, please take a moment and read the<br />
mail<strong>in</strong>g list etiquette (http://curl.haxx.se/mail/etiquette.html) before post<strong>in</strong>g.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 25
Appendix A – Add<strong>in</strong>g OpenSSL <strong>support</strong> directly to <strong>libcurl</strong><br />
Some of you might f<strong>in</strong>d it useful to have SSL/TLS <strong>support</strong> directly built <strong>in</strong>to <strong>libcurl</strong>. In this case,<br />
compilation procedure that was presented <strong>in</strong> section 3.5 is identical <strong>with</strong> the exception of step 3,<br />
which must be replaced <strong>with</strong> the follow<strong>in</strong>g:<br />
3. Next, you must tell the compiler and the librarian to use the OpenSSL library and where<br />
this library is located:<br />
a. Right-click on the <strong>libcurl</strong> project <strong>in</strong> the Solution Explorer w<strong>in</strong>dow and select<br />
Properties from the pop-up menu.<br />
b. Expand the Configuration Properties node, then the C/C++ node.<br />
i. Click on the General node. Next to Additional Include Directories, add<br />
the follow<strong>in</strong>g:<br />
;C:\libssh2-1.4.3\<strong>in</strong>clude;c:\openssl_lib\<strong>in</strong>clude\;c:\openssl_lib\<strong>in</strong>clude\openssl<br />
(the semicolon is needed s<strong>in</strong>ce there are already two additional <strong>in</strong>clude<br />
directories specified)<br />
ii. Select the Preprocessor node and click on the Preprocessor Def<strong>in</strong>itions<br />
property. Add <strong>in</strong> the follow<strong>in</strong>g to the exist<strong>in</strong>g def<strong>in</strong>itions:<br />
;CURL_STATICLIB;USE_LIB<strong>SSH</strong>2;CURL_DISABLE_LDAP;HAVE_<br />
LIB<strong>SSH</strong>2;HAVE_LIB<strong>SSH</strong>2_H;LIB<strong>SSH</strong>2_WIN32<br />
;LIB<strong>SSH</strong>2_LIBRARY;USE_SSLEAY;USE_OPENSSL<br />
c. In the Configuration Properties node, expand the Librarian node, and select<br />
General.<br />
i. Select Additional Dependencies and type <strong>in</strong>:<br />
libssh2.lib;libeay32.lib;ssleay32.lib<br />
ii. Next to Additional Library Directories, type <strong>in</strong> the path:<br />
C:\libssh2-1.4.3\w<strong>in</strong>32\Debug_lib;c:\openssl_lib\lib<br />
S<strong>in</strong>ce the OpenSSL library was already <strong>in</strong>cluded as part of the lib<strong>SSH</strong>2 compilation, at the end<br />
of the <strong>libcurl</strong> compilation, the l<strong>in</strong>ker will present a whole bunch of “second def<strong>in</strong>ition ignored”<br />
warn<strong>in</strong>gs, which can be safely ignored.<br />
<strong>Us<strong>in</strong>g</strong> <strong>libcurl</strong> <strong>with</strong> <strong>SSH</strong> <strong>support</strong> <strong>in</strong> <strong>Visual</strong> <strong>Studio</strong> <strong>2010</strong> 26