diff --git a/cross/rdiff-backup/Makefile b/cross/rdiff-backup/Makefile index 80c8e94156bf..180d42ae5d3f 100644 --- a/cross/rdiff-backup/Makefile +++ b/cross/rdiff-backup/Makefile @@ -1,11 +1,12 @@ PKG_NAME = rdiff-backup -PKG_VERS = 1.2.8 +PKG_VERS = 1.3.3 PKG_EXT = tar.gz +# TODO: this pattern will change with future builds PKG_DIST_NAME = $(PKG_NAME)-$(PKG_VERS).$(PKG_EXT) -PKG_DIST_SITE = http://download.savannah.gnu.org/releases/rdiff-backup/ +PKG_DIST_SITE = http://download.savannah.nongnu.org/releases/rdiff-backup PKG_DIR = $(PKG_NAME)-$(PKG_VERS) -DEPENDS = cross/librsync +DEPENDS = cross/librsync cross/attr cross/acl HOMEPAGE = http://www.nongnu.org/rdiff-backup/ COMMENT = A remote incremental backup of all your files diff --git a/cross/rdiff-backup/digests b/cross/rdiff-backup/digests index 7f6f46dcc4d2..28b2ea54e860 100644 --- a/cross/rdiff-backup/digests +++ b/cross/rdiff-backup/digests @@ -1,3 +1,3 @@ -rdiff-backup-1.2.8.tar.gz SHA1 14ffe4f5b46a8a96ded536c1d03ae5e85faae318 -rdiff-backup-1.2.8.tar.gz SHA256 0d91a85b40949116fa8aaf15da165c34a2d15449b3cbe01c8026391310ac95db -rdiff-backup-1.2.8.tar.gz MD5 1a94dc537fcf74d6a3a80bd27808e77b +rdiff-backup-1.3.3.tar.gz SHA256 ee030ce638df0eb1047cf72578e0de15d9a3ee9ab24da2dc0023e2978be30c06 +rdiff-backup-1.3.3.tar.gz SHA1 b36c9b5c06941a86210242f8213f60153a1eba28 +rdiff-backup-1.3.3.tar.gz MD5 e3ec506c01e12b693adb79751daa7c63 diff --git a/cross/rdiff-backup/patches/01_fix_restricted_test-server_option.patch b/cross/rdiff-backup/patches/01_fix_restricted_test-server_option.patch new file mode 100644 index 000000000000..b609a1f5d177 --- /dev/null +++ b/cross/rdiff-backup/patches/01_fix_restricted_test-server_option.patch @@ -0,0 +1,48 @@ +# Description: 01_fix_restricted_test-server_option.diff +# Author: Carl Chenet + +diff -urNad rdiff_backup/Main.py rdiff-backup-1.2.8/rdiff_backup/Main.py +--- rdiff_backup/Main.py 2009-03-16 15:36:21.000000000 +0100 ++++ 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/SetConnections.py rdiff-backup-1.2.8/rdiff_backup/SetConnections.py +--- rdiff_backup/SetConnections.py 2009-03-16 15:36:21.000000000 +0100 ++++ 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/cross/rdiff-backup/patches/02_python_2.6_deprecationwarning.patch b/cross/rdiff-backup/patches/02_python_2.6_deprecationwarning.patch new file mode 100644 index 000000000000..7d0259caa8de --- /dev/null +++ b/cross/rdiff-backup/patches/02_python_2.6_deprecationwarning.patch @@ -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/SetConnections.py rdiff-backup-1.2.8/rdiff_backup/SetConnections.py +--- rdiff_backup/SetConnections.py 2009-03-16 15:36:21.000000000 +0100 ++++ 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/cross/rdiff-backup/patches/03_fix_hardlinks.patch b/cross/rdiff-backup/patches/03_fix_hardlinks.patch new file mode 100644 index 000000000000..abef01ab0b73 --- /dev/null +++ b/cross/rdiff-backup/patches/03_fix_hardlinks.patch @@ -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/Hardlink.py rdiff-backup-1.2.8/rdiff_backup/Hardlink.py +--- rdiff_backup/Hardlink.py 2009-03-16 14:36:21.000000000 +0000 ++++ 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/compare.py rdiff-backup-1.2.8/rdiff_backup/compare.py +--- rdiff_backup/compare.py 2009-03-16 14:36:21.000000000 +0000 ++++ 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 + diff --git a/cross/rdiff-backup/patches/04_librsync2.patch b/cross/rdiff-backup/patches/04_librsync2.patch new file mode 100644 index 000000000000..c2d9cef23ac2 --- /dev/null +++ b/cross/rdiff-backup/patches/04_librsync2.patch @@ -0,0 +1,573 @@ +--- _librsyncmodule.c ++++ _librsyncmodule.c +@@ -1,27 +1,29 @@ + /* ----------------------------------------------------------------------- * +- * +- * Copyright 2002 2003 Ben Escoto + * +- * This file is part of rdiff-backup. ++ * Copyright 2002 2003 Ben Escoto ++ * Copyright 2007 Kenneth Loafman + * +- * rdiff-backup is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License as +- * published by the Free Software Foundation; either version 2 of +- * the License, or (at your option) any later version. ++ * This file is part of duplicity. + * +- * rdiff-backup is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * duplicity is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published ++ * by the Free Software Foundation; either version 2 of the License, ++ * or (at your option) any later version. ++ * ++ * duplicity is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License +- * along with rdiff-backup; if not, write to the Free Software ++ * along with duplicity; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307 USA + * + * ----------------------------------------------------------------------- */ + + #include ++#include + #include + #define RS_JOB_BLOCKSIZE 65536 + +@@ -38,11 +40,10 @@ _librsync_seterror(rs_result result, cha + + + /* --------------- SigMaker Object for incremental signatures */ +-staticforward PyTypeObject _librsync_SigMakerType; ++static PyTypeObject _librsync_SigMakerType; + + typedef struct { + PyObject_HEAD +- PyObject *x_attr; + rs_job_t *sig_job; + } _librsync_SigMakerObject; + +@@ -51,16 +52,20 @@ _librsync_new_sigmaker(PyObject* self, P + { + _librsync_SigMakerObject* sm; + long blocklen; +- ++ + if (!PyArg_ParseTuple(args, "l:new_sigmaker", &blocklen)) +- return NULL; ++ return NULL; + + sm = PyObject_New(_librsync_SigMakerObject, &_librsync_SigMakerType); + if (sm == NULL) return NULL; +- sm->x_attr = NULL; + ++#ifdef RS_DEFAULT_STRONG_LEN /* librsync < 1.0.0 */ + sm->sig_job = rs_sig_begin((size_t)blocklen, +- (size_t)RS_DEFAULT_STRONG_LEN); ++ (size_t)RS_DEFAULT_STRONG_LEN); ++#else /* librsync >= 1.0.0 */ ++ sm->sig_job = rs_sig_begin((size_t)blocklen, ++ (size_t)8, RS_MD4_SIG_MAGIC); ++#endif + return (PyObject*)sm; + } + +@@ -84,8 +89,12 @@ _librsync_sigmaker_cycle(_librsync_SigMa + rs_buffers_t buf; + rs_result result; + ++#if PY_MAJOR_VERSION >= 3 ++ if (!PyArg_ParseTuple(args, "y#:cycle", &inbuf, &inbuf_length)) ++#else + if (!PyArg_ParseTuple(args, "s#:cycle", &inbuf, &inbuf_length)) +- return NULL; ++#endif ++ return NULL; + + buf.next_in = inbuf; + buf.avail_in = (size_t)inbuf_length; +@@ -96,13 +105,17 @@ _librsync_sigmaker_cycle(_librsync_SigMa + result = rs_job_iter(self->sig_job, &buf); + + if (result != RS_DONE && result != RS_BLOCKED) { +- _librsync_seterror(result, "signature cycle"); +- return NULL; ++ _librsync_seterror(result, "signature cycle"); ++ return NULL; + } + ++#if PY_MAJOR_VERSION >= 3 ++ return Py_BuildValue("(ily#)", (result == RS_DONE), ++#else + return Py_BuildValue("(ils#)", (result == RS_DONE), +- (long)inbuf_length - (long)buf.avail_in, +- outbuf, RS_JOB_BLOCKSIZE - (long)buf.avail_out); ++#endif ++ (long)inbuf_length - (long)buf.avail_in, ++ outbuf, RS_JOB_BLOCKSIZE - (long)buf.avail_out); + } + + static PyMethodDef _librsync_sigmaker_methods[] = { +@@ -110,64 +123,44 @@ static PyMethodDef _librsync_sigmaker_me + {NULL, NULL, 0, NULL} /* sentinel */ + }; + +-static PyObject * +-_librsync_sigmaker_getattr(_librsync_SigMakerObject *sm, +- char *name) +-{ +- if (sm->x_attr != NULL) { +- PyObject *v = PyDict_GetItemString(sm->x_attr, name); +- if (v != NULL) { +- Py_INCREF(v); +- return v; +- } +- } +- return Py_FindMethod(_librsync_sigmaker_methods, (PyObject *)sm, name); +-} +- +-static int +-_librsync_sigmaker_setattr(_librsync_SigMakerObject *sm, +- char *name, PyObject *v) +-{ +- if (sm->x_attr == NULL) { +- sm->x_attr = PyDict_New(); +- if (sm->x_attr == NULL) return -1; +- } +- if (v == NULL) { +- int rv = PyDict_DelItemString(sm->x_attr, name); +- if (rv < 0) +- PyErr_SetString(PyExc_AttributeError, +- "delete non-existing sigmaker attribute"); +- return rv; +- } +- else return PyDict_SetItemString(sm->x_attr, name, v); +-} +- + static PyTypeObject _librsync_SigMakerType = { +- PyObject_HEAD_INIT(NULL) +- 0, ++ PyVarObject_HEAD_INIT(NULL, 0) + "sigmaker", + sizeof(_librsync_SigMakerObject), + 0, + _librsync_sigmaker_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ +- (getattrfunc)_librsync_sigmaker_getattr, /*tp_getattr*/ +- (setattrfunc)_librsync_sigmaker_setattr, /*tp_setattr*/ ++ 0, /*tp_getattr*/ ++ 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ ++ 0, /*tp_call*/ ++ 0, /*tp_str*/ ++ PyObject_GenericGetAttr, /*tp_getattro*/ ++ PyObject_GenericSetAttr, /*tp_setattro*/ ++ 0, /*tp_as_buffer*/ ++ Py_TPFLAGS_DEFAULT, /*tp_flags*/ ++ 0, /*tp_doc*/ ++ 0, /*tp_traverse*/ ++ 0, /*tp_clear*/ ++ 0, /*tp_richcompare*/ ++ 0, /*tp_weaklistoffset*/ ++ 0, /*tp_iter*/ ++ 0, /*tp_iternext*/ ++ _librsync_sigmaker_methods, /*tp_methods*/ + }; + + + /* --------------- DeltaMaker Object for incremental deltas */ + +-staticforward PyTypeObject _librsync_DeltaMakerType; ++static PyTypeObject _librsync_DeltaMakerType; + + typedef struct { + PyObject_HEAD +- PyObject *x_attr; + rs_job_t *delta_job; + rs_signature_t *sig_ptr; + } _librsync_DeltaMakerObject; +@@ -184,12 +177,15 @@ _librsync_new_deltamaker(PyObject* self, + rs_buffers_t buf; + rs_result result; + ++#if PY_MAJOR_VERSION >= 3 ++ if (!PyArg_ParseTuple(args,"y#:new_deltamaker", &sig_string, &sig_length)) ++#else + if (!PyArg_ParseTuple(args,"s#:new_deltamaker", &sig_string, &sig_length)) +- return NULL; ++#endif ++ return NULL; + + dm = PyObject_New(_librsync_DeltaMakerObject, &_librsync_DeltaMakerType); + if (dm == NULL) return NULL; +- dm->x_attr = NULL; + + /* Put signature at sig_ptr and build hash */ + sig_loader = rs_loadsig_begin(&sig_ptr); +@@ -201,12 +197,12 @@ _librsync_new_deltamaker(PyObject* self, + result = rs_job_iter(sig_loader, &buf); + rs_job_free(sig_loader); + if (result != RS_DONE) { +- _librsync_seterror(result, "delta rs_signature_t builder"); +- return NULL; ++ _librsync_seterror(result, "delta rs_signature_t builder"); ++ return NULL; + } + if ((result = rs_build_hash_table(sig_ptr)) != RS_DONE) { +- _librsync_seterror(result, "delta rs_build_hash_table"); +- return NULL; ++ _librsync_seterror(result, "delta rs_build_hash_table"); ++ return NULL; + } + + dm->sig_ptr = sig_ptr; +@@ -238,8 +234,12 @@ _librsync_deltamaker_cycle(_librsync_Del + rs_buffers_t buf; + rs_result result; + ++#if PY_MAJOR_VERSION >= 3 ++ if (!PyArg_ParseTuple(args, "y#:cycle", &inbuf, &inbuf_length)) ++#else + if (!PyArg_ParseTuple(args, "s#:cycle", &inbuf, &inbuf_length)) +- return NULL; ++#endif ++ return NULL; + + buf.next_in = inbuf; + buf.avail_in = (size_t)inbuf_length; +@@ -249,13 +249,17 @@ _librsync_deltamaker_cycle(_librsync_Del + + result = rs_job_iter(self->delta_job, &buf); + if (result != RS_DONE && result != RS_BLOCKED) { +- _librsync_seterror(result, "delta cycle"); +- return NULL; ++ _librsync_seterror(result, "delta cycle"); ++ return NULL; + } + ++#if PY_MAJOR_VERSION >= 3 ++ return Py_BuildValue("(ily#)", (result == RS_DONE), ++#else + return Py_BuildValue("(ils#)", (result == RS_DONE), +- (long)inbuf_length - (long)buf.avail_in, +- outbuf, RS_JOB_BLOCKSIZE - (long)buf.avail_out); ++#endif ++ (long)inbuf_length - (long)buf.avail_in, ++ outbuf, RS_JOB_BLOCKSIZE - (long)buf.avail_out); + } + + static PyMethodDef _librsync_deltamaker_methods[] = { +@@ -263,66 +267,48 @@ static PyMethodDef _librsync_deltamaker_ + {NULL, NULL, 0, NULL} /* sentinel */ + }; + +-static PyObject * +-_librsync_deltamaker_getattr(_librsync_DeltaMakerObject *dm, char *name) +-{ +- if (dm->x_attr != NULL) { +- PyObject *v = PyDict_GetItemString(dm->x_attr, name); +- if (v != NULL) { +- Py_INCREF(v); +- return v; +- } +- } +- return Py_FindMethod(_librsync_deltamaker_methods, (PyObject *)dm, name); +-} +- +-static int +-_librsync_deltamaker_setattr(_librsync_DeltaMakerObject *dm, +- char *name, PyObject *v) +-{ +- if (dm->x_attr == NULL) { +- dm->x_attr = PyDict_New(); +- if (dm->x_attr == NULL) return -1; +- } +- if (v == NULL) { +- int rv = PyDict_DelItemString(dm->x_attr, name); +- if (rv < 0) +- PyErr_SetString(PyExc_AttributeError, +- "delete non-existing deltamaker attribute"); +- return rv; +- } +- else return PyDict_SetItemString(dm->x_attr, name, v); +-} +- + static PyTypeObject _librsync_DeltaMakerType = { +- PyObject_HEAD_INIT(NULL) +- 0, ++ PyVarObject_HEAD_INIT(NULL, 0) + "deltamaker", + sizeof(_librsync_DeltaMakerObject), + 0, + _librsync_deltamaker_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ +- (getattrfunc)_librsync_deltamaker_getattr, /*tp_getattr*/ +- (setattrfunc)_librsync_deltamaker_setattr, /*tp_setattr*/ ++ 0, /*tp_getattr*/ ++ 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ ++ 0, /*tp_call*/ ++ 0, /*tp_str*/ ++ PyObject_GenericGetAttr, /*tp_getattro*/ ++ PyObject_GenericSetAttr, /*tp_setattro*/ ++ 0, /*tp_as_buffer*/ ++ Py_TPFLAGS_DEFAULT, /*tp_flags*/ ++ 0, /*tp_doc*/ ++ 0, /*tp_traverse*/ ++ 0, /*tp_clear*/ ++ 0, /*tp_richcompare*/ ++ 0, /*tp_weaklistoffset*/ ++ 0, /*tp_iter*/ ++ 0, /*tp_iternext*/ ++ _librsync_deltamaker_methods, /*tp_methods*/ + }; + + + /* --------------- PatchMaker Object for incremental patching */ + + +-staticforward PyTypeObject _librsync_PatchMakerType; ++static PyTypeObject _librsync_PatchMakerType; + + typedef struct { + PyObject_HEAD +- PyObject *x_attr; + rs_job_t *patch_job; + PyObject *basis_file; ++ FILE *cfile; + } _librsync_PatchMakerObject; + + /* Call with the basis file */ +@@ -331,23 +317,31 @@ _librsync_new_patchmaker(PyObject* self, + { + _librsync_PatchMakerObject* pm; + PyObject *python_file; +- FILE *cfile; ++ int fd; + + if (!PyArg_ParseTuple(args, "O:new_patchmaker", &python_file)) +- return NULL; +- if (!PyFile_Check(python_file)) { +- PyErr_SetString(PyExc_TypeError, "Need true file object"); +- return NULL; ++ return NULL; ++ fd = PyObject_AsFileDescriptor(python_file); ++ if (fd == -1) { ++ PyErr_SetString(PyExc_TypeError, "Need true file object"); ++ return NULL; ++ } ++ /* get our own private copy of the file, so we can close it later. */ ++ fd = dup(fd); ++ if (fd == -1) { ++ char buf[256]; ++ strerror_r(errno, buf, sizeof(buf)); ++ PyErr_SetString(PyExc_TypeError, buf); ++ return NULL; + } + Py_INCREF(python_file); +- ++ + pm = PyObject_New(_librsync_PatchMakerObject, &_librsync_PatchMakerType); + if (pm == NULL) return NULL; +- pm->x_attr = NULL; + + pm->basis_file = python_file; +- cfile = PyFile_AsFile(python_file); +- pm->patch_job = rs_patch_begin(rs_file_copy_cb, cfile); ++ pm->cfile = fdopen(fd, "rb"); ++ pm->patch_job = rs_patch_begin(rs_file_copy_cb, pm->cfile); + + return (PyObject*)pm; + } +@@ -358,6 +352,9 @@ _librsync_patchmaker_dealloc(PyObject* s + _librsync_PatchMakerObject *pm = (_librsync_PatchMakerObject *)self; + Py_DECREF(pm->basis_file); + rs_job_free(pm->patch_job); ++ if (pm->cfile) { ++ fclose(pm->cfile); ++ } + PyObject_Del(self); + } + +@@ -374,8 +371,12 @@ _librsync_patchmaker_cycle(_librsync_Pat + rs_buffers_t buf; + rs_result result; + ++#if PY_MAJOR_VERSION >= 3 ++ if (!PyArg_ParseTuple(args, "y#:cycle", &inbuf, &inbuf_length)) ++#else + if (!PyArg_ParseTuple(args, "s#:cycle", &inbuf, &inbuf_length)) +- return NULL; ++#endif ++ return NULL; + + buf.next_in = inbuf; + buf.avail_in = (size_t)inbuf_length; +@@ -385,13 +386,17 @@ _librsync_patchmaker_cycle(_librsync_Pat + + result = rs_job_iter(self->patch_job, &buf); + if (result != RS_DONE && result != RS_BLOCKED) { +- _librsync_seterror(result, "patch cycle"); +- return NULL; ++ _librsync_seterror(result, "patch cycle"); ++ return NULL; + } + ++#if PY_MAJOR_VERSION >= 3 ++ return Py_BuildValue("(ily#)", (result == RS_DONE), ++#else + return Py_BuildValue("(ils#)", (result == RS_DONE), +- (long)inbuf_length - (long)buf.avail_in, +- outbuf, RS_JOB_BLOCKSIZE - (long)buf.avail_out); ++#endif ++ (long)inbuf_length - (long)buf.avail_in, ++ outbuf, RS_JOB_BLOCKSIZE - (long)buf.avail_out); + } + + static PyMethodDef _librsync_patchmaker_methods[] = { +@@ -399,58 +404,50 @@ static PyMethodDef _librsync_patchmaker_ + {NULL, NULL, 0, NULL} /* sentinel */ + }; + +-static PyObject * +-_librsync_patchmaker_getattr(_librsync_PatchMakerObject *pm, char *name) +-{ +- if (pm->x_attr != NULL) { +- PyObject *v = PyDict_GetItemString(pm->x_attr, name); +- if (v != NULL) { +- Py_INCREF(v); +- return v; +- } +- } +- return Py_FindMethod(_librsync_patchmaker_methods, (PyObject *)pm, name); +-} +- +-static int +-_librsync_patchmaker_setattr(_librsync_PatchMakerObject *pm, +- char *name, PyObject *v) +-{ +- if (pm->x_attr == NULL) { +- pm->x_attr = PyDict_New(); +- if (pm->x_attr == NULL) return -1; +- } +- if (v == NULL) { +- int rv = PyDict_DelItemString(pm->x_attr, name); +- if (rv < 0) +- PyErr_SetString(PyExc_AttributeError, +- "delete non-existing patchmaker attribute"); +- return rv; +- } +- else return PyDict_SetItemString(pm->x_attr, name, v); +-} +- + static PyTypeObject _librsync_PatchMakerType = { +- PyObject_HEAD_INIT(NULL) +- 0, ++ PyVarObject_HEAD_INIT(NULL, 0) + "patchmaker", + sizeof(_librsync_PatchMakerObject), + 0, + _librsync_patchmaker_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ +- (getattrfunc)_librsync_patchmaker_getattr, /*tp_getattr*/ +- (setattrfunc)_librsync_patchmaker_setattr, /*tp_setattr*/ ++ 0, /*tp_getattr*/ ++ 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ ++ 0, /*tp_call*/ ++ 0, /*tp_str*/ ++ PyObject_GenericGetAttr, /*tp_getattro*/ ++ PyObject_GenericSetAttr, /*tp_setattro*/ ++ 0, /*tp_as_buffer*/ ++ Py_TPFLAGS_DEFAULT, /*tp_flags*/ ++ 0, /*tp_doc*/ ++ 0, /*tp_traverse*/ ++ 0, /*tp_clear*/ ++ 0, /*tp_richcompare*/ ++ 0, /*tp_weaklistoffset*/ ++ 0, /*tp_iter*/ ++ 0, /*tp_iternext*/ ++ _librsync_patchmaker_methods, /*tp_methods*/ + }; + + + /* --------------- _librsync module definition */ + ++#if PY_MAJOR_VERSION >= 3 ++#define MOD_DEF(ob, name, doc, methods) \ ++ static struct PyModuleDef moduledef = { \ ++ PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \ ++ ob = PyModule_Create(&moduledef); ++#else ++#define MOD_DEF(ob, name, doc, methods) \ ++ ob = Py_InitModule3(name, methods, doc); ++#endif ++ + static PyMethodDef _librsyncMethods[] = { + {"new_sigmaker", _librsync_new_sigmaker, METH_VARARGS, + "Return a sigmaker object, for finding the signature of an object"}, +@@ -461,18 +458,37 @@ static PyMethodDef _librsyncMethods[] = + {NULL, NULL, 0, NULL} + }; + +-void init_librsync(void) ++static PyObject * ++moduleinit(void) + { + PyObject *m, *d; + +- _librsync_SigMakerType.ob_type = &PyType_Type; +- _librsync_DeltaMakerType.ob_type = &PyType_Type; +- m = Py_InitModule("_librsync", _librsyncMethods); ++ Py_TYPE(&_librsync_SigMakerType) = &PyType_Type; ++ Py_TYPE(&_librsync_DeltaMakerType) = &PyType_Type; ++ ++ MOD_DEF(m, "_librsync", "", _librsyncMethods) ++ if (m == NULL) ++ return NULL; ++ + d = PyModule_GetDict(m); + librsyncError = PyErr_NewException("_librsync.librsyncError", NULL, NULL); + PyDict_SetItemString(d, "librsyncError", librsyncError); + PyDict_SetItemString(d, "RS_JOB_BLOCKSIZE", +- Py_BuildValue("l", (long)RS_JOB_BLOCKSIZE)); ++ Py_BuildValue("l", (long)RS_JOB_BLOCKSIZE)); + PyDict_SetItemString(d, "RS_DEFAULT_BLOCK_LEN", +- Py_BuildValue("l", (long)RS_DEFAULT_BLOCK_LEN)); ++ Py_BuildValue("l", (long)RS_DEFAULT_BLOCK_LEN)); ++ ++ return m; ++} ++ ++#if PY_MAJOR_VERSION < 3 ++void init_librsync(void) ++{ ++ moduleinit(); ++} ++#else ++PyObject *PyInit__librsync(void) ++{ ++ return moduleinit(); + } ++#endif diff --git a/cross/rdiff-backup/patches/05_extend--no-compress-files.patch b/cross/rdiff-backup/patches/05_extend--no-compress-files.patch new file mode 100644 index 000000000000..8ecd6a1d30ae --- /dev/null +++ b/cross/rdiff-backup/patches/05_extend--no-compress-files.patch @@ -0,0 +1,11 @@ +--- rdiff_backup/Globals.py ++++ rdiff_backup/Globals.py +@@ -185,7 +185,7 @@ compression = 1 + # compiled version of the first. + no_compression_regexp_string = ("(?i).*\\.(gz|z|bz|bz2|tgz|zip|rpm|deb|" + "jpg|jpeg|gif|png|jp2|mp3|ogg|avi|wmv|mpeg|mpg|rm|mov|flac|shn|pgp|" +- "gpg|rz|lzh|zoo|lharc|rar|arj|asc)$") ++ "gpg|rz|lzh|zoo|lharc|rar|arj|asc|iso|vob|mdf)$") + no_compression_regexp = None + + # If true, filelists and directory statistics will be split on diff --git a/cross/rdiff-backup/patches/06_rdiff-backup-enodata-fix.patch b/cross/rdiff-backup/patches/06_rdiff-backup-enodata-fix.patch new file mode 100644 index 000000000000..811ea48944e7 --- /dev/null +++ b/cross/rdiff-backup/patches/06_rdiff-backup-enodata-fix.patch @@ -0,0 +1,11 @@ +--- rdiff_backup/eas_acls.py ++++ rdiff_backup/eas_acls.py +@@ -98,7 +98,7 @@ class ExtendedAttributes: + continue + else: raise + except IOError, exc: +- if exc[0] == errno.EOPNOTSUPP or exc[0] == errno.EPERM: ++ if exc[0] == errno.EOPNOTSUPP or exc[0] == errno.EPERM or exc[0] == errno.ENODATA: + return # if not supported, consider empty + elif exc[0] == errno.ENOENT: # path is bad + log.Log("Warning: unable to clear xattrs on %s: %s" % diff --git a/spk/rdiff-backup/Makefile b/spk/rdiff-backup/Makefile index d2347f22328c..73a338158f52 100644 --- a/spk/rdiff-backup/Makefile +++ b/spk/rdiff-backup/Makefile @@ -1,5 +1,5 @@ SPK_NAME = rdiff-backup -SPK_VERS = 1.2.8 +SPK_VERS = 1.3.3 SPK_REV = 1 SPK_ICON = src/rdiff-backup.png @@ -16,7 +16,7 @@ DISPLAY_NAME = rdiff-backup CHANGELOG = "Initial release" BETA = 1 -HOMEPAGE = http://www.nongnu.org/rdiff-backup/ +HOMEPAGE = https://rdiff-backup.net LICENSE = GNU GPL INSTALLER_SCRIPT = src/installer.sh diff --git a/spk/rdiff-backup/PLIST b/spk/rdiff-backup/PLIST index d2c9c50272d8..4cfaf73a12cf 100644 --- a/spk/rdiff-backup/PLIST +++ b/spk/rdiff-backup/PLIST @@ -1,2 +1 @@ rsc:share/wheelhouse -