diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ccbcc4cbc6ba3a410822a1c6b6ccc1ae2946a650..8fedf05d2762a64e720caaaf07e3aea86097204e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,30 +1,22 @@
+image: ikus060/docker-wine-py2-py3:latest
stages:
- build
+- publish
build:windows:
stage: build
- image: ikus060/docker-wine-py2-py3:stretch
script:
- # Compile librsync
- - wget https://pilotfiber.dl.sourceforge.net/project/librsync/librsync/0.9.7/librsync-0.9.7.tar.gz
- - tar -zxvf librsync-0.9.7.tar.gz
- - cp librsync-patches/* librsync-0.9.7/
- - patch -d librsync-0.9.7 < librsync-0.9.7/lfs_support.patch
- - (Xvfb :99 &)
- - export DISPLAY=:99
- - wine MSBuild.exe "librsync-0.9.7\librsync.sln" /t:Build /p:Configuration=Release
- - mkdir librsync-0.9.7/include librsync-0.9.7/lib
- - cp librsync-0.9.7/librsync.h librsync-0.9.7/librsync-config.h librsync-0.9.7/include
- - cp librsync-0.9.7/Release/rsync.lib librsync-0.9.7/lib/
-
- # Compile rdiff-backup
- - wget https://nongnu.freemirror.org/nongnu/rdiff-backup/rdiff-backup-1.2.8.tar.gz
- - tar -zxvf rdiff-backup-1.2.8.tar.gz
- - cd rdiff-backup-1.2.8
- - pip install pywin32
- - python setup.py build --librsync-dir="C:\target\librsync-0.9.7" --lflags="/NODEFAULTLIB:libcmt.lib msvcrt.lib"
- - python setup.py py2exe --single-file 2>&1 || true
- - cp "$WINEPREFIX/drive_c/Python27/python27.dll" build/bdist.win32/winexe/bundle-2.7/
- - python setup.py py2exe --single-file
-
+ - bash ./build.sh
+ artifacts:
+ paths:
+ - rdiff-backup-*-win32.zip
+
+publish:
+ stage: publish
+ script:
+ # Publish to kalo
+ - eval $(ssh-agent -s)
+ - echo "$KALO_WWWDATA_PRIVATEKEY" | tr -d '\r' | ssh-add - > /dev/null
+ - mkdir -p ~/.ssh && chmod 700 ~/.ssh
+ - scp -o StrictHostKeyChecking=no rdiff-backup-*-win32.zip www-data@kalo.patrikdufresne.com:/var/www/patrikdufresne/archive/rdiff-backup/
diff --git a/README.md b/README.md
index cd776b62c64897631d38c939d4360809687c6e16..c711080350ddfc9f6482babfd996e4aefbcdea91 100644
--- a/README.md
+++ b/README.md
@@ -1,32 +1,4 @@
# rdiff-backup-build
-CICD Pipeline to build rdiff-backup
-
-
------
-
-1. Install Visual Studio 2008 Express http://download.microsoft.com/download/8/B/5/8B5804AD-4990-40D0-A6AA-CE894CBBB3DC/VS2008ExpressENUX1397868.iso
-2. Install python 2.7.16 https://www.python.org/ftp/python/2.7/python-2.7.msi
-3. Install patch.exe https://iweb.dl.sourceforge.net/project/gnuwin32/patch/2.5.9-7/patch-2.5.9-7-bin.zip
- Add it to you PATH
-
-
-Execute build.py in a Visual Stution Command Prompt
-
-Fix the build script line ending
-
-Change the URL of librsync.
-
-Apply patch to librsync
-
-
-wget https://pilotfiber.dl.sourceforge.net/project/librsync/librsync/0.9.7/librsync-0.9.7.tar.gz
-tar -zxvf librsync-0.9.7.tar.gz
-
-
-MSBuild.exe librsync-0.9.7\librsync.sln /t:Build /p:Configuration=Release
-
-
-
-wget http://savannah.nongnu.org/download/rdiff-backup/rdiff-backup-1.3.3.tar.gz
+CICD Pipeline to build rdiff-backup for Windows
diff --git a/build.py b/build.py
deleted file mode 100644
index 880d453d7e2b4b1bde6684444e3aaa908bdea7d5..0000000000000000000000000000000000000000
--- a/build.py
+++ /dev/null
@@ -1,504 +0,0 @@
-import glob
-import os
-import shutil
-import sys
-import tarfile
-import urllib
-
-RDIFF_BACKUP_VERSION = '1.3.3'
-RDIFF_BACKUP_NAME = 'rdiff-backup-'+RDIFF_BACKUP_VERSION
-
-RDIFF_BACKUP_URL = 'http://savannah.nongnu.org/download/rdiff-backup/'+RDIFF_BACKUP_NAME+'.tar.gz'
-LIBRSYNC_URL = 'https://pilotfiber.dl.sourceforge.net/project/librsync/librsync/0.9.7/librsync-0.9.7.tar.gz'
-
-LIBRSYNC_VCPROJ_TEXT = r"""
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-"""
-
-LIBRSYNC_SLN_TEXT = r"""Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual C++ Express 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "librsync", "librsync.vcproj", "{B7D1448D-017B-4035-86A1-12B5B736101F}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {B7D1448D-017B-4035-86A1-12B5B736101F}.Debug|Win32.ActiveCfg = Debug|Win32
- {B7D1448D-017B-4035-86A1-12B5B736101F}.Debug|Win32.Build.0 = Debug|Win32
- {B7D1448D-017B-4035-86A1-12B5B736101F}.Release|Win32.ActiveCfg = Release|Win32
- {B7D1448D-017B-4035-86A1-12B5B736101F}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
-"""
-
-LIBRSYNC_PATCH_TEXT="""diff -w -Nur librsync-0.9.7/buf.c librsync-0.9.7dev/buf.c
---- librsync-0.9.7/buf.c 2004-02-07 18:17:57.000000000 -0500
-+++ librsync-0.9.7-win/buf.c 2008-11-20 12:28:23.000000000 -0500
-@@ -59,6 +59,11 @@
- #define fseek fseeko
- #endif
-
-+#ifdef NEED_FSEEKI64
-+int __cdecl _fseeki64(FILE *, __int64, int);
-+#define fseek _fseeki64
-+#endif
-+
- /**
- * File IO buffer sizes.
- */
-diff -urN librsync-0.9.7/mdfour.h librsync-0.9.7dev/mdfour.h
---- librsync-0.9.7/mdfour.h 2004-02-07 18:17:57.000000000 -0500
-+++ librsync-0.9.7dev/mdfour.h 2006-03-06 03:21:46.000000000 -0500
-@@ -24,7 +24,7 @@
- #include "types.h"
-
- struct rs_mdfour {
-- int A, B, C, D;
-+ unsigned int A, B, C, D;
- #if HAVE_UINT64
- uint64_t totalN;
- #else
-diff -urN librsync-0.9.7/patch.c librsync-0.9.7dev/patch.c
---- librsync-0.9.7/patch.c 2004-09-17 17:35:50.000000000 -0400
-+++ librsync-0.9.7dev/patch.c 2006-03-06 03:21:06.000000000 -0500
-@@ -214,12 +214,12 @@
- void *buf, *ptr;
- rs_buffers_t *buffs = job->stream;
-
-- len = job->basis_len;
--
- /* copy only as much as will fit in the output buffer, so that we
- * don't have to block or store the input. */
-- if (len > buffs->avail_out)
-+ if (job->basis_len > buffs->avail_out)
- len = buffs->avail_out;
-+ else
-+ len = job->basis_len;
-
- if (!len)
- return RS_BLOCKED;
-"""
-
-CONFIG_H_TEXT = """
-#define SIZEOF_UNSIGNED_INT 4
-
-#define PACKAGE "librsync"
-#define VERSION "0.9.7"
-#define RS_CANONICAL_HOST "librsync.sourceforge.net"
-
-#define inline
-#define NEED_FSEEKI64
-"""
-
-
-class BuildError(Exception):
- pass
-
-def copy(src_pattern, dest_dir):
- if '*' in src_pattern:
- files = glob.glob(src_pattern)
- else:
- files = [src_pattern]
- for file in files:
- shutil.copyfile(file, os.path.join(dest_dir,
-os.path.basename(file)))
-
-def unzip(src_file, target_dir):
- print 'Extracting %s...' % src_file
- extension = src_file.rpartition('.')[2]
- tar = tarfile.open(src_file, 'r:'+extension)
- for tarinfo in tar:
- dest_path = os.path.join(target_dir, tarinfo.name.replace('/', os.sep))
- if tarinfo.isreg():
- tar.extract(tarinfo, target_dir)
- elif tarinfo.isdir():
- if not os.path.isdir(dest_path):
- os.mkdir(dest_path)
- elif tarinfo.issym():
- pass # We don't care about symlinks
- else:
- raise ValueError, 'Unhandled .tar.gz file:'+str(tarinfo)
- tar.close()
-
-def verify_env(require_cvs):
- for path in os.environ['PATH'].split(';'):
- if os.path.exists(os.path.join(path, 'MSBuild.exe')):
- break
- else:
- raise BuildError, '''This script must be run from \
-the Visual Studio 2008 Commandline.'''
-
- if require_cvs:
- for path in os.environ['PATH'].split(';'):
- if os.path.exists(os.path.join(path, 'cvs.exe')):
- break
- else:
- raise BuildError, '''Cvs.exe (CVSNT) must be in the
-path.'''
-
-def download_file(url, target_dir):
- filename = os.path.basename(url)
- target_name = os.path.join(target_dir, filename)
- if not os.path.exists(target_name):
- print 'Downloading %s...' % url
- urllib.urlretrieve(url, target_name)
-
- unzip(target_name, target_dir)
-
-def write_text(filepath, text):
- file = open(filepath, 'w')
- file.write(text)
- file.close()
-
-def build_librsync(root_dir):
- # Download package if necessary
- download_file(LIBRSYNC_URL, root_dir)
-
- # Add in support files
- librsync_dir = os.path.join(root_dir, 'librsync-0.9.7')
- write_text(os.path.join(librsync_dir, 'librsync.sln'),
-LIBRSYNC_SLN_TEXT)
- write_text(os.path.join(librsync_dir, 'librsync.vcproj'),
-LIBRSYNC_VCPROJ_TEXT)
- write_text(os.path.join(librsync_dir, 'config.h'), CONFIG_H_TEXT)
-
- # Patch for 4GB support
- large_file_patch = os.path.join(librsync_dir, 'lfs_support.patch')
- write_text(large_file_patch, LIBRSYNC_PATCH_TEXT)
- os.chdir(root_dir)
- #if os.system('patch.exe -p0 < %s' % large_file_patch):
- # raise BuildError, 'Unable to patch librsync.'
-
- # Build
- sln_path = os.path.join(librsync_dir, 'librsync.sln')
- cmd = 'MSBuild.exe %s /t:Build /p:Configuration=Release' % sln_path
- print(cmd)
- if os.system(cmd):
- raise BuildError, 'Unable to build librsync.'
-
- # Copy built library to where rdiff-backup's setup.py expects it
- output_dir = os.path.join(librsync_dir, 'lib')
- if not os.path.isdir(output_dir):
- os.mkdir(output_dir)
- lib_path = os.path.join(librsync_dir, 'Release', 'rsync.lib')
- copy(lib_path, output_dir)
-
- # Copy include files to where rdiff-backup expects them
- include_dir = os.path.join(librsync_dir, 'include')
- if not os.path.isdir(include_dir):
- os.mkdir(include_dir)
- for file in ('librsync.h', 'librsync-config.h'):
- copy(os.path.join(librsync_dir, file), include_dir)
-
-def build_rdiff_backup(use_cvs, rebuild, root_dir, output_dir):
- rdiff_dir = os.path.join(root_dir, 'rdiff-backup')
- librsync_dir = os.path.join(root_dir, 'librsync-0.9.7')
-
- # Check out rdiff-backup
- if rebuild:
- if os.path.exists(rdiff_dir):
- shutil.rmtree(rdiff_dir)
-
- if use_cvs:
- if not os.path.isdir(rdiff_dir):
- os.chdir(root_dir)
- if os.system('cvs -z3 -d:pserver:address@hidden:/sources/rdiff-backup co .'):
- raise BuildError, 'Unable to check out rdiff-backup!'
-
- # Patch rdiff-backup
- os.chdir(rdiff_dir)
- patch_exe = 'patch.exe'
- for patch in ('rdiff-backup-windows-drive.patch',):
- patch_path = os.path.join(root_dir, '..', patch)
- print 'patching:', patch
- if os.system('%s -N -p0 < %s' % (patch_exe, patch_path)):
- raise BuildError, 'Unable to patch rdiff-backup!'
-
- # Make an rdiff-backup dist package
- os.chdir(rdiff_dir)
- if os.system('python dist\\makedist ' + RDIFF_BACKUP_VERSION):
- raise BuildError, 'Unable to make rdiff-backup dist package.'
-
- # There is now a built version in the rdiff-backup dir.
- # Extract it, build it, and copy the exe to output_dir.
- rdiff_output_name = 'rdiff-backup-'+RDIFF_BACKUP_VERSION
- target_dir = os.path.join(rdiff_dir, rdiff_output_name)
- if os.path.exists(target_dir):
- shutil.rmtree(target_dir)
- rdiff_tar = target_dir + '.tar.gz'
- unzip(rdiff_tar, rdiff_dir)
- else:
- if not os.path.exists(rdiff_dir):
- os.mkdir(rdiff_dir)
- download_file(RDIFF_BACKUP_URL, rdiff_dir)
- rdiff_output_name = RDIFF_BACKUP_NAME
-
- rdiff_output_dir = os.path.join(rdiff_dir, rdiff_output_name)
- os.chdir(rdiff_output_dir)
-
- # Build rdiff-backup
- if os.system('setup.py build --librsync-dir=%s --lflags=%s' % \
- (librsync_dir, '"/NODEFAULTLIB:libcmt.lib msvcrt.lib"')):
- raise BuildError, 'Unable to build rdiff-backup.'
- if os.system('setup.py py2exe --single-file > NUL'):
- raise BuildError, 'Unable to rdiff-backup via py2exe.'
-
- copy(os.path.join(rdiff_output_dir, 'dist', 'rdiff-backup.exe'),
-output_dir)
-
-if __name__ == '__main__':
- root_dir = os.path.dirname(__file__)
- target_dir = os.path.join(root_dir, 'temp')
- output_dir = os.path.join(root_dir, 'output')
- rebuild = '--rebuild' in sys.argv[1:]
- use_cvs = '--cvs' in sys.argv[1:]
- for dir in (target_dir, output_dir):
- if not os.path.isdir(dir):
- os.makedirs(dir)
-
- verify_env(use_cvs)
- build_librsync(target_dir)
- build_rdiff_backup(use_cvs, rebuild, target_dir, output_dir)
\ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..cda8f0933fb7e193149e9b4af91aa0e5c1c3c885
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+# Copyright (C) 2019 Patrik Dufresne Service Logiciel inc. All rights reserved.
+# Patrik Dufresne Service Logiciel PROPRIETARY/CONFIDENTIAL.
+# Use is subject to license terms.
+set -e
+set -x
+
+# Input variable
+LIBRSYNC_VERSION=${LIBRSYNC_VERSION:-0.9.7}
+RDIFFBACKUP_VERSION=${RDIFFBACKUP_VERSION:-1.2.8}
+
+# Intermediate variable
+LIBRSYNC_DIR=librsync-$LIBRSYNC_VERSION
+RDIFFBACKUP_DIR=rdiff-backup-$RDIFFBACKUP_VERSION
+
+#
+# Compile librsync
+#
+wget https://pilotfiber.dl.sourceforge.net/project/librsync/librsync/$LIBRSYNC_VERSION/librsync-$LIBRSYNC_VERSION.tar.gz
+tar -zxvf librsync-$LIBRSYNC_VERSION.tar.gz
+cp patches/librsync/* $LIBRSYNC_DIR/
+for FILE in patches/librsync/*.diff; do patch -p0 < $FILE; done
+(Xvfb :99 &)
+export DISPLAY=:99
+wineserver -p
+wine MSBuild.exe "$LIBRSYNC_DIR\librsync.sln" /t:Build /p:Configuration=Release
+mkdir $LIBRSYNC_DIR/include $LIBRSYNC_DIR/lib
+cp $LIBRSYNC_DIR/librsync.h $LIBRSYNC_DIR/librsync-config.h $LIBRSYNC_DIR/include
+cp $LIBRSYNC_DIR/Release/rsync.lib $LIBRSYNC_DIR/lib/
+# Export variable for Wine.
+export LIBRSYNC_DIR=Z:${PWD//\//\\}\\$LIBRSYNC_DIR
+
+#
+# Compile rdiff-backup
+#
+wget https://nongnu.freemirror.org/nongnu/rdiff-backup/rdiff-backup-$RDIFFBACKUP_VERSION.tar.gz
+tar -zxvf rdiff-backup-$RDIFFBACKUP_VERSION.tar.gz
+for FILE in patches/rdiff-backup/*.diff; do patch -p0 < $FILE; done
+pip install pywin32
+cd "$RDIFFBACKUP_DIR"
+python setup.py build --librsync-dir="$LIBRSYNC_DIR" --lflags="/NODEFAULTLIB:libcmt.lib msvcrt.lib"
+python setup.py py2exe --single-file 2>&1 || true
+cp "$WINEPREFIX/drive_c/Python27/python27.dll" build/bdist.win32/winexe/bundle-2.7/
+python setup.py py2exe --single-file
+
+#
+# Package
+#
+apt-get update && apt-get install zip dos2unix
+mv dist/rdiff-backup.exe ./rdiff-backup.exe
+unix2dos -k -n CHANGELOG CHANGELOG.txt
+unix2dos -k -n COPYING COPYING.txt
+unix2dos -k -n README README.txt
+cd ..
+zip $RDIFFBACKUP_DIR-1-win32.zip \
+ $RDIFFBACKUP_DIR/rdiff-backup.exe \
+ $RDIFFBACKUP_DIR/*.txt \
+ $RDIFFBACKUP_DIR/*.html
diff --git a/librsync-patches/lfs_support.patch b/patches/librsync/01_lfs_support.diff
similarity index 96%
rename from librsync-patches/lfs_support.patch
rename to patches/librsync/01_lfs_support.diff
index d9170e613196935ca13a87fbbe47555c4c17b27d..5d42864bc536ebe945583b872cd7b29c8213aa54 100644
--- a/librsync-patches/lfs_support.patch
+++ b/patches/librsync/01_lfs_support.diff
@@ -1,46 +1,46 @@
-diff -w -Nur librsync-0.9.7/buf.c librsync-0.9.7dev/buf.c
---- librsync-0.9.7/buf.c 2004-02-07 18:17:57.000000000 -0500
-+++ librsync-0.9.7-win/buf.c 2008-11-20 12:28:23.000000000 -0500
-@@ -59,6 +59,11 @@
- #define fseek fseeko
- #endif
-
-+#ifdef NEED_FSEEKI64
-+int __cdecl _fseeki64(FILE *, __int64, int);
-+#define fseek _fseeki64
-+#endif
-+
- /**
- * File IO buffer sizes.
- */
-diff -urN librsync-0.9.7/mdfour.h librsync-0.9.7dev/mdfour.h
---- librsync-0.9.7/mdfour.h 2004-02-07 18:17:57.000000000 -0500
-+++ librsync-0.9.7dev/mdfour.h 2006-03-06 03:21:46.000000000 -0500
-@@ -24,7 +24,7 @@
- #include "types.h"
-
- struct rs_mdfour {
-- int A, B, C, D;
-+ unsigned int A, B, C, D;
- #if HAVE_UINT64
- uint64_t totalN;
- #else
-diff -urN librsync-0.9.7/patch.c librsync-0.9.7dev/patch.c
---- librsync-0.9.7/patch.c 2004-09-17 17:35:50.000000000 -0400
-+++ librsync-0.9.7dev/patch.c 2006-03-06 03:21:06.000000000 -0500
-@@ -214,12 +214,12 @@
- void *buf, *ptr;
- rs_buffers_t *buffs = job->stream;
-
-- len = job->basis_len;
--
- /* copy only as much as will fit in the output buffer, so that we
- * don't have to block or store the input. */
-- if (len > buffs->avail_out)
-+ if (job->basis_len > buffs->avail_out)
- len = buffs->avail_out;
-+ else
-+ len = job->basis_len;
-
- if (!len)
+diff -w -Nur librsync-0.9.7/buf.c librsync-0.9.7dev/buf.c
+--- librsync-0.9.7/buf.c 2004-02-07 18:17:57.000000000 -0500
++++ librsync-0.9.7-win/buf.c 2008-11-20 12:28:23.000000000 -0500
+@@ -59,6 +59,11 @@
+ #define fseek fseeko
+ #endif
+
++#ifdef NEED_FSEEKI64
++int __cdecl _fseeki64(FILE *, __int64, int);
++#define fseek _fseeki64
++#endif
++
+ /**
+ * File IO buffer sizes.
+ */
+diff -urN librsync-0.9.7/mdfour.h librsync-0.9.7dev/mdfour.h
+--- librsync-0.9.7/mdfour.h 2004-02-07 18:17:57.000000000 -0500
++++ librsync-0.9.7dev/mdfour.h 2006-03-06 03:21:46.000000000 -0500
+@@ -24,7 +24,7 @@
+ #include "types.h"
+
+ struct rs_mdfour {
+- int A, B, C, D;
++ unsigned int A, B, C, D;
+ #if HAVE_UINT64
+ uint64_t totalN;
+ #else
+diff -urN librsync-0.9.7/patch.c librsync-0.9.7dev/patch.c
+--- librsync-0.9.7/patch.c 2004-09-17 17:35:50.000000000 -0400
++++ librsync-0.9.7dev/patch.c 2006-03-06 03:21:06.000000000 -0500
+@@ -214,12 +214,12 @@
+ void *buf, *ptr;
+ rs_buffers_t *buffs = job->stream;
+
+- len = job->basis_len;
+-
+ /* copy only as much as will fit in the output buffer, so that we
+ * don't have to block or store the input. */
+- if (len > buffs->avail_out)
++ if (job->basis_len > buffs->avail_out)
+ len = buffs->avail_out;
++ else
++ len = job->basis_len;
+
+ if (!len)
return RS_BLOCKED;
\ No newline at end of file
diff --git a/librsync-patches/config.h b/patches/librsync/config.h
similarity index 100%
rename from librsync-patches/config.h
rename to patches/librsync/config.h
diff --git a/librsync-patches/librsync.sln b/patches/librsync/librsync.sln
similarity index 100%
rename from librsync-patches/librsync.sln
rename to patches/librsync/librsync.sln
diff --git a/librsync-patches/librsync.vcproj b/patches/librsync/librsync.vcproj
similarity index 100%
rename from librsync-patches/librsync.vcproj
rename to patches/librsync/librsync.vcproj
diff --git a/patches/rdiff-backup/01_fix_restricted_test-server_option.diff b/patches/rdiff-backup/01_fix_restricted_test-server_option.diff
new file mode 100644
index 0000000000000000000000000000000000000000..d7880f81a942083438bc04f8fdd843cd2269164c
--- /dev/null
+++ b/patches/rdiff-backup/01_fix_restricted_test-server_option.diff
@@ -0,0 +1,48 @@
+# Description: 01_fix_restricted_test-server_option.diff
+# Author: Carl Chenet
+
+diff -urNad rdiff-backup-1.2.8~/rdiff_backup/Main.py rdiff-backup-1.2.8/rdiff_backup/Main.py
+--- rdiff-backup-1.2.8~/rdiff_backup/Main.py 2009-03-16 15:36:21.000000000 +0100
++++ rdiff-backup-1.2.8/rdiff_backup/Main.py 2010-02-20 11:26:27.000000000 +0100
+@@ -288,7 +288,7 @@
+ elif action == "remove-older-than": RemoveOlderThan(rps[0])
+ elif action == "restore": Restore(*rps)
+ elif action == "restore-as-of": Restore(rps[0], rps[1], 1)
+- elif action == "test-server": SetConnections.TestConnections()
++ elif action == "test-server": SetConnections.TestConnections(rps)
+ elif action == "verify": Verify(rps[0])
+ else: raise AssertionError("Unknown action " + action)
+
+diff -urNad rdiff-backup-1.2.8~/rdiff_backup/SetConnections.py rdiff-backup-1.2.8/rdiff_backup/SetConnections.py
+--- rdiff-backup-1.2.8~/rdiff_backup/SetConnections.py 2009-03-16 15:36:21.000000000 +0100
++++ rdiff-backup-1.2.8/rdiff_backup/SetConnections.py 2010-02-20 11:29:43.000000000 +0100
+@@ -241,20 +241,25 @@
+ Globals.backup_reader = Globals.isbackup_reader = \
+ Globals.backup_writer = Globals.isbackup_writer = None
+
+-def TestConnections():
++def TestConnections(rpaths):
+ """Test connections, printing results"""
+ if len(Globals.connections) == 1: print "No remote connections specified"
+ else:
+- for i in range(1, len(Globals.connections)): test_connection(i)
++ assert len(Globals.connections) == len(rpaths) + 1
++ for i in range(1, len(Globals.connections)):
++ test_connection(i, rpaths[i-1])
+
+-def test_connection(conn_number):
++def test_connection(conn_number, rp):
+ """Test connection. conn_number 0 is the local connection"""
+ print "Testing server started by: ", __conn_remote_cmds[conn_number]
+ conn = Globals.connections[conn_number]
+ try:
+ assert conn.Globals.get('current_time') is None
+- assert type(conn.os.listdir('.')) is list
+ version = conn.Globals.get('version')
++ try:
++ assert type(conn.os.getuid()) is int
++ except AttributeError: # Windows doesn't support os.getuid()
++ assert type(conn.os.listdir(rp.path)) is list
+ except:
+ sys.stderr.write("Server tests failed\n")
+ raise
diff --git a/patches/rdiff-backup/02_python_2.6_deprecationwarning.diff b/patches/rdiff-backup/02_python_2.6_deprecationwarning.diff
new file mode 100644
index 0000000000000000000000000000000000000000..547ecd18247c32d676ee454ce10cbbd5cd8b8d28
--- /dev/null
+++ b/patches/rdiff-backup/02_python_2.6_deprecationwarning.diff
@@ -0,0 +1,25 @@
+# Description: 02_python_2.6_deprecationwarning.diff
+# Author: by converted to Quilt by Carl Chenet
+# from the nmu suggestion by Carlos Alberto Lopez Perez
+# patch adapted from the one at https://savannah.nongnu.org/bugs/?26064
+# This fix the following warning: "DeprecationWarning: os.popen2 is
+# deprecated. Use the subprocess module."
+# Also, the *nix version of rdiff-backup requires shell=True instead of
+# shell=False in the subprocess.Popen call
+
+diff -urNad rdiff-backup-1.2.8~/rdiff_backup/SetConnections.py rdiff-backup-1.2.8/rdiff_backup/SetConnections.py
+--- rdiff-backup-1.2.8~/rdiff_backup/SetConnections.py 2009-03-16 15:36:21.000000000 +0100
++++ rdiff-backup-1.2.8/rdiff_backup/SetConnections.py 2009-10-03 19:27:54.935647306 +0200
+@@ -135,10 +135,10 @@
+ if not remote_cmd: return Globals.local_connection
+
+ Log("Executing " + remote_cmd, 4)
+- if os.name == "nt":
++ if map(int, sys.version.split()[0].split('.')[:2]) >= [2, 6]:
+ import subprocess
+ try:
+- process = subprocess.Popen(remote_cmd, shell=False, bufsize=0,
++ process = subprocess.Popen(remote_cmd, shell=True, bufsize=0,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE)
+ (stdin, stdout) = (process.stdin, process.stdout)
diff --git a/patches/rdiff-backup/03_fix_hardlinks.diff b/patches/rdiff-backup/03_fix_hardlinks.diff
new file mode 100644
index 0000000000000000000000000000000000000000..ee0c285645783f258335960190d61f7f960df6e6
--- /dev/null
+++ b/patches/rdiff-backup/03_fix_hardlinks.diff
@@ -0,0 +1,96 @@
+# Description: fix_hardlinks.diff
+# Author: by converted to Quilt format by Carl Chenet
+# from the nmu suggestion by Carlos Alberto Lopez Perez
+# Apply hard-links bug fix patch
+# https://savannah.nongnu.org/bugs/index.php?26848
+
+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' rdiff-backup-1.2.8~/rdiff_backup/Hardlink.py rdiff-backup-1.2.8/rdiff_backup/Hardlink.py
+--- rdiff-backup-1.2.8~/rdiff_backup/Hardlink.py 2009-03-16 14:36:21.000000000 +0000
++++ rdiff-backup-1.2.8/rdiff_backup/Hardlink.py 2012-01-03 11:44:21.708987145 +0000
+@@ -95,7 +95,13 @@
+ src_rorp.getnumlinks() == dest_rorp.getnumlinks() == 1):
+ return 1 # Hard links don't apply
+
+- if src_rorp.getnumlinks() < dest_rorp.getnumlinks(): return 0
++ """The sha1 of linked files is only stored in the metadata of the first
++ linked file on the dest side. If the first linked file on the src side is
++ deleted, then the sha1 will also be deleted on the dest side, so we test for this
++ & report not equal so that another sha1 will be stored with the next linked
++ file on the dest side"""
++ if (not islinked(src_rorp) and not dest_rorp.has_sha1()): return 0
++ if src_rorp.getnumlinks() != dest_rorp.getnumlinks(): return 0
+ src_key = get_inode_key(src_rorp)
+ index, remaining, dest_key, digest = _inode_index[src_key]
+ if dest_key == "NA":
+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' rdiff-backup-1.2.8~/rdiff_backup/compare.py rdiff-backup-1.2.8/rdiff_backup/compare.py
+--- rdiff-backup-1.2.8~/rdiff_backup/compare.py 2009-03-16 14:36:21.000000000 +0000
++++ rdiff-backup-1.2.8/rdiff_backup/compare.py 2012-01-03 11:43:33.792989189 +0000
+@@ -25,7 +25,7 @@
+ """
+
+ from __future__ import generators
+-import Globals, restore, rorpiter, log, backup, static, rpath, hash, robust
++import Globals, restore, rorpiter, log, backup, static, rpath, hash, robust, Hardlink
+
+ def Compare(src_rp, mirror_rp, inc_rp, compare_time):
+ """Compares metadata in src_rp dir with metadata in mirror_rp at time"""
+@@ -80,14 +80,15 @@
+ bad_files = 0
+ for repo_rorp in repo_iter:
+ if not repo_rorp.isreg(): continue
+- if not repo_rorp.has_sha1():
++ verify_sha1 = get_hash(repo_rorp)
++ if not verify_sha1:
+ log.Log("Warning: Cannot find SHA1 digest for file %s,\n"
+ "perhaps because this feature was added in v1.1.1"
+ % (repo_rorp.get_indexpath(),), 2)
+ continue
+ fp = RepoSide.rf_cache.get_fp(base_index + repo_rorp.index, repo_rorp)
+ computed_hash = hash.compute_sha1_fp(fp)
+- if computed_hash == repo_rorp.get_sha1():
++ if computed_hash == verify_sha1:
+ log.Log("Verified SHA1 digest of " + repo_rorp.get_indexpath(), 5)
+ else:
+ bad_files += 1
+@@ -95,11 +96,24 @@
+ "doesn't match recorded digest of\n %s\n"
+ "Your backup repository may be corrupted!" %
+ (repo_rorp.get_indexpath(), computed_hash,
+- repo_rorp.get_sha1()), 2)
++ verify_sha1), 2)
+ RepoSide.close_rf_cache()
+ if not bad_files: log.Log("Every file verified successfully.", 3)
+ return bad_files
+
++def get_hash (repo_rorp):
++ """ Try to get a sha1 digest from the repository. If hardlinks
++ are saved in the metadata, get the sha1 from the first hardlink """
++ Hardlink.add_rorp(repo_rorp)
++ if Hardlink.islinked(repo_rorp):
++ verify_sha1 = Hardlink.get_sha1(repo_rorp)
++ elif repo_rorp.has_sha1():
++ verify_sha1 = repo_rorp.get_sha1()
++ else:
++ verify_sha1 = None
++ Hardlink.del_rorp(repo_rorp)
++ return verify_sha1
++
+ def print_reports(report_iter):
+ """Given an iter of CompareReport objects, print them to screen"""
+ assert not Globals.server
+@@ -199,12 +213,13 @@
+ """Like above, but also compare sha1 sums of any regular files"""
+ def hashes_changed(src_rp, mir_rorp):
+ """Return 0 if their data hashes same, 1 otherwise"""
+- if not mir_rorp.has_sha1():
++ verify_sha1 = get_hash(mir_rorp)
++ if not verify_sha1:
+ log.Log("Warning: Metadata file has no digest for %s, "
+ "unable to compare." % (mir_rorp.get_indexpath(),), 2)
+ return 0
+ elif (src_rp.getsize() == mir_rorp.getsize() and
+- hash.compute_sha1(src_rp) == mir_rorp.get_sha1()):
++ hash.compute_sha1(src_rp) == verify_sha1):
+ return 0
+ return 1
+