Building lftp on Windows

One of the best FTP clients I have ever seen is lftp, and what is even best it’s open source on Linux, if you want to use it on Windows you will have to compile it with Cygwin.

Why would someone use lftp, when there are alternatives like FileZilla, and a lot of other ones. Yes FileZilla is good and it’s free, but some of the options that are available with lftp are really good and helpful. And I know of a lot of people that use lftp for server backups on Windows Server and Linux machines to do recursive backups and mirroring.

For a complete feature list you can see this page.

Some interesting information about this application can be found on this page, there are various examples of how to use it on their page.

If you want to learn how to compile it on Windows, read bellow, or if you are just interested in the compiled version you can download it bellow, the following builds are built on Cygwin x86x64, also bundled in the package is SSH and BASH. If you have Cygwin installation you can just unpack this file in the root, and you are set.

At the bottom of the post you will find a script that was used to build these packages for anyone who want

So first things first, download the latest version of lftp, and unpack it somewhere where you can access it, in my case I uncompressed it in my home directory, so at the time of writing the latest version is 4.4.9.

Here are some of the perquisites for compiling the application successfully on Cygwin.

In short you need the following packages for you to be able to compile lftp, for a more complete list of packages that I use to compile you can find them at the end of the post.

bison, autoconf, gcc, gcc-c++, make, pkg-config, gnutls, gnutls-devel

In the main directory we run:

./configure
make

So after compilation let’s check what support do we have in lftp:

lftp.exe --version

It shows us that we are using: Readline 6.2, Expat 2.1.0, GnuTLS 3.2.0, libiconv 1.14, zlib 1.2.8

ldd.exe lftp.exe | grep --invert-match Windows

This shows you all the dependencies for the particular executable, in our case it shows the following.

ldd.exe lftp.exe | grep --invert-match Windows
        cygwin1.dll => /usr/bin/cygwin1.dll (0x180040000)
        cygexpat-1.dll => /usr/bin/cygexpat-1.dll (0x3ff980000)
        cyggnutls-28.dll => /usr/bin/cyggnutls-28.dll (0x3ff590000)
        cyggmp-10.dll => /usr/bin/cyggmp-10.dll (0x3ff690000)
        cyghogweed-2.dll => /usr/bin/cyghogweed-2.dll (0x3ff4d0000)
        cygnettle-4.dll => /usr/bin/cygnettle-4.dll (0x3ff0e0000)
        cygiconv-2.dll => /usr/bin/cygiconv-2.dll (0x3ff3c0000)
        cygintl-8.dll => /usr/bin/cygintl-8.dll (0x3ff360000)
        cygp11-kit-0.dll => /usr/bin/cygp11-kit-0.dll (0x3ff0a0000)
        cygffi-6.dll => /usr/bin/cygffi-6.dll (0x3ff970000)
        cygtasn1-6.dll => /usr/bin/cygtasn1-6.dll (0x3feba0000)
        cygz.dll => /usr/bin/cygz.dll (0x3feb40000)
        cygreadline7.dll => /usr/bin/cygreadline7.dll (0x3fede0000)
        cygncursesw-10.dll => /usr/bin/cygncursesw-10.dll (0x3ff120000)
        cyggcc_s-seh-1.dll => /usr/bin/cyggcc_s-seh-1.dll (0x3ff850000)

If you want to compile with OpenSSL support do the following, because by default it doesn’t compile with OpenSSL support, instead it uses GnuTLS.

./configure --without-gnutls --with-openssl
make

So after compilation let’s check what support do we have in lftp:

lftp.exe --version

It shows us that we are using: Readline 6.2, Expat 2.1.0, OpenSSL 1.0.1e 11 Feb 2013, libiconv 1.14, zlib 1.2.8

ldd.exe lftp.exe | grep --invert-match Windows

This shows you all the dependencies for the particular executable, in our case it shows the following.

ldd.exe lftp.exe | grep --invert-match Windows
        cygcrypto-1.0.0.dll => /usr/bin/cygcrypto-1.0.0.dll (0x3ffbf0000)
        cygwin1.dll => /usr/bin/cygwin1.dll (0x180040000)
        cygz.dll => /usr/bin/cygz.dll (0x3feb40000)
        cygexpat-1.dll => /usr/bin/cygexpat-1.dll (0x3ff980000)
        cygiconv-2.dll => /usr/bin/cygiconv-2.dll (0x3ff3c0000)
        cygintl-8.dll => /usr/bin/cygintl-8.dll (0x3ff360000)
        cygreadline7.dll => /usr/bin/cygreadline7.dll (0x3fede0000)
        cygncursesw-10.dll => /usr/bin/cygncursesw-10.dll (0x3ff120000)
        cygssl-1.0.0.dll => /usr/bin/cygssl-1.0.0.dll (0x3fecc0000)
        cyggcc_s-seh-1.dll => /usr/bin/cyggcc_s-seh-1.dll (0x3ff850000)

Long package list

autoconf, automake, bison, bzip2, cygwin-debuginfo, cygwin32, cygwin32-expat, cygwin32-libiconv, expat, expat-debuginfo, gcc-core, gcc-fortran, gcc-g++, gnutls, gnutls-devel, libexpat-devel, libexpat1, libiconv, libiconv-debuginfo, libiconv-devel, libiconv2, libmhash-devel, libmhash2, libreadline-devel, libreadline7, make, mhash-debuginfo, mingw-binutils, mingw-gcc-core, mingw-pthreads, mingw-runtime, mingw-w32api, mingw-zlib, mingw-zlib-devel, mingw-zlib1, mingw64-x86_64-binutils, mingw64-x86_64-gcc-core, mingw64-x86_64-gcc-fortran, mingw64-x86_64-gcc-g++, mingw64-x86_64-headers, mingw64-x86_64-runtime, mingw64-x86_64-winpthreads, mingw64-x86_64-zlib, openssl, openssl-devel, perl, perl-ExtUtils-PkgConfig, pkg-config, pkg-config-debuginfo, python, python-crypto, python-crypto-debuginfo, python-openssl, python-openssl-debuginfo, python-tkinter, zlib-devel, zlib0

Build and packaging script

#!/bin/bash
if [ $# -eq 0 ]
  then
    echo "<script> name"
	exit
fi

if [ ! -f lftp.exe ];
then
 echo "lftp.exe doesn't exist run this file from where it exists"
 exit
fi
cwd=`pwd`
items=`ldd.exe lftp.exe | grep --invert-match Windows | cut -d " " -f3`
tmpdir=`mktemp.exe --directory`
echo "Creating temporary directory $tmpdir"
mkdir $tmpdir/bin
mkdir $tmpdir/etc
for item in $items
do
 echo "Copying LFTP dependency file: $item to $tmpdir/bin"
 cp $item $tmpdir/bin
done
items=`ldd.exe /bin/ssh.exe | grep --invert-match Windows | cut -d " " -f3`
for item in $items
do
 echo "Copying SSH dependency file: $item"
 cp $item $tmpdir/bin
done
items=`ldd.exe /bin/bash.exe | grep --invert-match Windows | cut -d " " -f3`
for item in $items
do
 echo "Copying BASH dependency file: $item"
 cp $item $tmpdir/bin
done
echo "Copying required files"
cp lftp.exe $tmpdir/bin
cp ../lftp.conf $tmpdir/etc
cp /bin/ssh.exe $tmpdir/bin
cp /bin/bash.exe $tmpdir/bin
cd $tmpdir
tar -cvzf ../$1.tar.gz .
mv ../$1.tar.gz $cwd
cd $cwd
echo "File generated in $cwd/$1.tar.gz"