rdiff-backup: the easiest way to backup (and restore)

Today I finally managed to set up an incremental backup for my workstation. What do we need? Well, nothing more than rdiff-backup, an opensource command line tool with all the powers you need.

it just backups. and your last backup is always available 1:1 at the destination (no strange storage formats etc., just dirs and files). Diffs and metadata are stored separately. So if you want a
backup that does its job, is plain, is easy to restore, has no unneccessary features and “just works” than rdiff-backup is the right tool for you.

Here a small bash script I write to accomplish the mission:

#!/bin/bash  
P=/home/soenke  
DESTINATION=mydestionationserver.local  
INCLUDE="  
$P/Documents  
$P/.gnupg  
"  

echo "$INCLUDE" | rdiff-backup --include-filelist-stdin --exclude $P/ $P/ $DESTINATION::/home/soenke/backup  

In my case “mydestionationserver.local” is a local mediacenter server running Ubuntu and a SSH server. INCLUDE has one backup src per line. P is the prefix dir, in my case my homedir. As you can
see, I’m using a whitelist of dirs/files to be backupped. If you want your full homedir get saved, just use:

rdiff-backup /path/to/src <server>::<destination-dir>

Just check the examples to learn more.

PHP: SortingIterator

I just had the need for an Iterator that can sort itself by a user defined callback.

My special use case is that the DirectoryIterator of PHP does not sort the file list so it’s pretty random. But my program logic relies on files being sorted by filename.

So here’s the little class:

class SortingIterator implements IteratorAggregate
{

        private $iterator = null;

        public function __construct(Traversable $iterator, $callback)
        {
                if (!is_callable($callback)) {
                        throw new InvalidArgumentException('Given callback is not callable!');
                }

                $array = iterator_to_array($iterator);
                usort($array, $callback);
                $this->iterator = new ArrayIterator($array);
        }


        public function getIterator()
        {
                return $this->iterator;
        }
}

Basically it uses the functionality of the function “iterator_to_array()” to convert the iterator into an array and then let the array getting sorted by usort() and the user-defined callback.

Then the sorted array is wrapped into an ArrayIterator so it can be used with all Iterator functions, decorators and whatever again.

Usage example:

function mysort($a, $b)
{
        return $a->getPathname() > $b->getPathname();
}

$it = new SortingIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator('/home/soenke/muell')), 'mysort');

foreach ($it as $f) {
        echo $f->getPathname() . "\n";
}

Without sorting Iterator:

/home/soenke/tests/test/a.txt
/home/soenke/tests/test/b.txt
/home/soenke/tests/test/ä.txt
/home/soenke/tests/test/aaa.txt
/home/soenke/tests/test/abc.txt
/home/soenke/tests/test/az.txt

And with Sorting-Iterator:

soenke@turingmachine:~/tests$ php dirit.php
/home/soenke/tests/test/a.txt
/home/soenke/tests/test/aaa.txt
/home/soenke/tests/test/abc.txt
/home/soenke/tests/test/az.txt
/home/soenke/tests/test/b.txt
/home/soenke/tests/test/ä.txt