#!/bin/sh
program=/home/m/michael/bin/rsync_host2dir

[ $# -eq 2 ] || {
	1>&2 echo "usage: $0 host directory"
	exit 1
}
[ -n "$1" ] || {
	1>&2 echo "host cannot be null: usage: $0 host directory"
	exit 1
}
[ -n "$2" ] || {
	1>&2 echo "directory cannot be null: usage: $0 host directory"
	exit 1
}
[ -d "$2" ] ||
2>> /dev/null mkdir -p "$2" # we check, and possibly also try again, later
if [ x$(id -u) = x0 ]; then
	[ -d "$2" ] || {
		mkdir -p "$2"
		[ -d "$2" ] || {
			1>&2 echo "$0: directory $2 doesn't exist, aborting"
			exit 1
		}
	}
else
	# make our directory absolute before cd /
	case x"$2" in
		x/*)
			# already absolute
			directory="$2"
		;;
		*)
			directory=$(pwd -P)/"$2" || exit
		;;
	esac
	set -- "$1" "$directory"; unset directory
	cd / &&
	{
		exec sudo su - root -c "LC_ALL=C SSH_AUTH_SOCK=$SSH_AUTH_SOCK ${SSH_OPTs+SSH_OPTs='$SSH_OPTs'} $program $1 $2" ||
		exit
	}
fi

host="$1"
directory="$2"
set --


# ssh -atx $SSH_OPTs "$host" 'hostname; id'; exit

backupmountpoints=$(
	ssh -ax $SSH_OPTs "$host" 'cd / && umask 077 && exec mount' |
	#/home/m/michael/src/backup/bin/device__mount_point__type__options
	perl -e '
		$^W=1;
		use strict;

		#data fields to gather from output of mount(8)
		my $match_mount=q:^(.+) on (.+) type (.+) \((.*?)\)\n*$:;
		#                  device
		#                          mount point
		#                                    type
		#                                           options
		my @mount=();

		while (<>){
			if (/$match_mount/) {
				my $device=$1;
				my $mount_point=$2;
				my $type=$3;
				my $options=$4;
				#skip filesystems we are not presently interested in
				(
					#must be one of these types ...
					$type =~
						/
							^	(?:
									ext[234] |
									reiserfs
								)
							$
						/ox
						||
					#or one of these type and ...
					$type =~
						/
							^	(?:
									ntfs |
									vfat |
									fat
								)
							$
						/ox
						&&
					#mounted readonly
					$options =~
						/
							(?:^|,)
								ro
							(?:,|$)
						/ox
				)	&&
					#and not one of these mount points
					$mount_point !~
					m!
						^
							(?:
								/+home/+r/+root/+tmp/+mnt |
								/+media |
								/+mnt |
								/+var/+local/+pub/+iso |
								/+var/+local/+tower |
								/+var/+local/+vtest |
								/+var/+tmp/+old-debian |
								/+var/+www/+old-debian.balug.org
							)
						(?:$|/)
					!ox
				or next;
				#push device mount_point type options on our array,
				#split out the options
				push @mount,[$device,$mount_point,$type,[split(/,/,$options)]]
			}
			else {
				print ("else\n");
				print STDERR ("$0: ",(m:^(.*?)\n*$:)," failed to match $match_mount\n");
			}
		}

		@mount=sort {
			#handle highest priorities (if present) first:
			#/boot, / (root), /usr, /var, /home
			for my $pri (
				q:/boot:,
				q:/:,
				q:/usr:,
				q:/var:,
				q:/home:
			) {
				if(@$a[1] eq $pri && @$b[1] ne $pri) { return -1; }
				if(@$b[1] eq $pri && @$a[1] ne $pri) { return 1; }
			}
			#everything else is higher and compares normally
			#print ("@$a[1] cmp @$b[1] ",@$a[1] cmp @$b[1],"\n");
			@$a[1] cmp @$b[1];
		}	@mount;

		my $mountpointsout=q::;
		for my $line (@mount) {
			#print join(q: :,(@{$line}[0..2]),join(q:,:,@{${$line}[3]})),"\n";
			#print(@{$line}[1],"\n"); # just the mount points
			if($mountpointsout ne q::){
				$mountpointsout .= q: :;
				$mountpointsout .= @{$line}[1];
			}else{
				$mountpointsout = @{$line}[1];
			};
		}
		print($mountpointsout);
	'
)

#echo "$backupmountpoints"

rsync \
	--ipv4 \
	--archive \
	--acls \
	--xattrs \
	--hard-links \
	--numeric-ids \
	--relative \
	--sparse \
	--rsh='ssh -aTx -o BatchMode=yes '"$SSH_OPTs" \
	--checksum \
	--partial \
	--one-file-system \
	--delete-excluded \
	--ignore-times \
	--compress-level=9 \
	--filter='-,/ /tmp/**' \
	--filter='-,/ /var/cache/apt/archives/**' \
	--filter='-,/ /var/local/pub/mirrored/cdimage.debian.org/**' \
	--quiet \
	"$host":"$backupmountpoints" "$directory"
#	--verbose
#	--bwlimit=KBPS
#	--inplace
#	--compress
#SSH_OPTs=-6
