Script to sync KiSS PVR with Linux PC using FTP

I thought it was a good idea to keep a copy of my PVR files on my Linux server. As the KiSS PVR (I own a KiSS DP-558) supports regular FTP, I assumed there would be an off-the-shelf script that would support this, but I could not find it. Then I decided to adapt an existing script myself...

FTP sync PERL script

The basic PERL script I used was from Peter Orvos (, found through comments on an interesting LinuxJournal article ( The requirements I had were that it would be able to run in the background (cron) every day or so, and detect changes on both sides and act accordingly. This lead to quite some changes in the script, but works perfectly for me right now!

The (modified) PERL script itself: ftpsync

A lot of changes were made to this script, for example using a file (.last) to indicate the last sync. Based on the mtime of this file it can determine which changes have taken place on both sides (PVR and server) and sync these changes.

File renaming script

Now the issue I encountered was the support for different characters for filenames in Windows and Linux (FYI: I use VideoRedo on my Windows PC to edit the VOB files. Great app that you can find here), so I decided to rename the files avoiding characters like ":", "'" and "?", using another PERL 'rename' script (I really cannot remember where I found it, but I did quite some modifications to it):
# Usage: rename perlexpr [files]
# Example: rename 's/new$/old/' mah*.new
#          Changes all the files prefixed with the text mah and suffixed with .new to be suffixed with .old instead
# Or:      find /tmp -name '*~' -print | rename 's/^(.+)~$/.#$1/'

($regexp = shift @ARGV) || die "Usage:  rename perlexpr [filenames]\n";

if (!@ARGV) {
   @ARGV = <STDIN>;

foreach $_ (@ARGV) {
   $old_name = $_;
   # WARN if string already appeared
   # Strip replacement from regexp, 0 will be operator, 1 source, 2 target and 3 options
   @parts = split('/',$regexp);
   # See if target appears in old name
   if ($old_name =~ m/$parts[2]/i) {
      die "ERROR: Target appears in original filename; cannot rename back!!! Stopping at $old_name\n";

   $_ = $old_name;
   # Run the regexp on $_ and generate new $_. Put error in $@
   eval $regexp;
   die $@ if $@;
   $new_name = $_;
   print "Renaming '$old_name' to '$new_name'\n" unless $old_name eq $new_name;
   rename($old_name, $new_name) unless $old_name eq $new_name;
This PERL script is used by Bash scripts that do the renaming for me (this one changes the ":" into "##"):
# First all the files, otherwise if the dirs change the files cannot be found anymore!
find /KiSS/pvr/ -type f -print | rename 's/\:/##/g'
find /KiSS/pvr/ -type d -print | rename 's/\:/##/g'

Cron script

Finally some pieces of the cron script that is called every night: This piece does the renaming:
if [ "$?" -ne 0 ]; then
  echo "ERROR: Renaming ## to : failed"
  exit 1
Note that it contains quite some error checking; I noticed that if the script is generating errors and you continue syncing, you may loose all your recorded programs, and if the script runs twice, you may loose it on both sides, happened to me quite a few times :-(

Note as well that I removed the redirecting of the stdouts to a log file, I assume you will be able to regenerate it.

The actual FTP script calling:

ftpsync -v -d -o 7200 -s -r "/pvr/" -l "/KiSS/pvr/"
#ftpsync -k -v -d -o 7200 -s -r "/pvr/" -l "/KiSS/pvr/"
Note the '-k' option being commented out: '-k' is for 'kidding', meaning that the script does not actually perform the FTP operations (and .last updating); very useful for debugging. Also the '-o' option with 7200: The KiSS uses GMT internally and my Linux server is now on GMT+2 hours (=7200 seconds)

Now the renaming of the 'strange' characters to more widely accepted characters for Windows access:

if [ "$?" -ne 0 ]; then
  echo "ERROR: Renaming : to ## failed"
  exit 1


I hope that other people that want to sync two computers with eachother (real mirroring, not like rsync) like this script as well!


Valid HTML 4.01!