summaryrefslogtreecommitdiff
path: root/bin/mailsync-dsync
diff options
context:
space:
mode:
Diffstat (limited to 'bin/mailsync-dsync')
-rwxr-xr-xbin/mailsync-dsync132
1 files changed, 132 insertions, 0 deletions
diff --git a/bin/mailsync-dsync b/bin/mailsync-dsync
new file mode 100755
index 0000000..5fe80a7
--- /dev/null
+++ b/bin/mailsync-dsync
@@ -0,0 +1,132 @@
+#!/bin/sh
+# Copyright © 2015-2016 Jonas Smedegaard <dr@jones.dk>
+# Description: Synchronize mail using Dovecot tool dsync
+#
+# This program 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 3, or (at your option)
+# any later version.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Depends: dovecot-core
+# Recommends: moreutils
+#
+# FIXME
+# * Generailze account resolving (avoid hardcoded accounts)
+#
+# TODO
+# * Gracefully serialize (with warning) if parallel not available
+# * Add option to not parallelize (and not warn if parallel missing)
+# * Add global lock
+# * Handle "region" derived from profile:
+# + Avoid parallelize same-region profiles
+# + Lock each region separately
+# * Parse configfile for profiles
+
+set -e
+
+PRG=$(basename "$0")
+
+showhelp() {
+ cat <<EOF
+Usage: $PRG [--tomuch] [--] PROFILE [PROFILE...]
+Synchronize one or more Dovecot Maildir profiles
+
+ --toomuch Don't update notmuch database after syncronization
+ --debug Enable debugging output
+ --alive Monitor SSH connection that server is alive
+ --reset Clear state tracking to force full sync
+ -h, --help This help text
+
+Examples:
+ $PRG jones hb
+ $PRG --toomuch jones
+EOF
+}
+
+exit1() {
+ response="${1:+Error: }${1:-Internal error!}"
+ echo >&2 "$response"
+ exit 1
+}
+
+# parse cmdline options
+TEMP="`getopt -s sh -o h -l help,toomuch,debug,alive,reset -n "$PRG" -- "$@"`" || exit1 "Internal getopt error."
+eval set -- "$TEMP"
+while true ; do
+ case "$1" in
+ -h|--help) showhelp; exit;;
+ --toomuch) toomuch=yes; shift;;
+ --debug) debug=yes; shift;;
+ --alive) alive=yes; shift;;
+ --reset) reset=yes; shift;;
+ --) shift; break;;
+ *) exit1 "Internal error resolving options.";;
+ esac
+done
+
+[ $# -gt 0 ] || set -- jones debian bb hb lxp5
+
+_nice() {
+# ionice -c 3 chrt --idle 0 /bin/sh -c "$@"
+ "$@"
+}
+
+_dsync() {
+ profile="$1"
+ case "$profile" in
+ jones) host=mail.jones.dk;;
+ debian) host=jonas-debian@mail.jones.dk;;
+ bb) host=mail.bitbase.dk;;
+ hb) host=mail.homebase.dk;;
+# db) host=db.letsgo.dk;;
+# lb) host=lb.letsgo.dk;;
+ lxp5) host=lxp5.free-owl.de;;
+ *) exit1 "Wrong account \"$account\"";;
+ esac
+ for algo in ed25519 ecdsa dsa rsa; do
+ key="$HOME/.ssh/id_${algo}_mail_$profile"
+ if [ -f "$key" ] && [ -f "$key.pub" ]; then
+ break
+ fi
+ key=
+ done
+ cachedir="$HOME/.cache/mydsync"
+ statefile="$cachedir/$profile"
+ [ -z "$reset" ] || rm -f "$statefile" "$statefile"~
+ if [ -s "$statefile" ]; then
+ cp -f "$statefile" "$statefile"~
+ else
+ touch "$statefile"
+ fi
+ state="$(cat "$statefile")"
+ if [ -z "$state" ] && [ -f "$statefile"~ ]; then
+ state="$(cat "$statefile"~)"
+ fi
+ mkdir -p "$cachedir"
+ [ -n "$key" ] || exit1 "ssh key missing for $profile"
+ _nice doveadm ${debug:+-D} \
+ -o mail_location=maildir:~/Maildir/"$profile" \
+ sync -s "$state" -x spam -x Junk -x Trash \
+ ssh -i "$key" -o BatchMode=yes \
+ ${alive:+-o ServerAliveInterval=10 -o ServerAliveCountMax=5} \
+ "$host" doveadm dsync-server \
+ > "$statefile"
+}
+
+case $# in
+ 0)
+ exit1 "Internal error: no arguments to process";;
+ 1)
+ _dsync "$1";;
+ *)
+ parallel -i sh -c "$0 --toomuch ${debug:+--debug} ${alive:+--alive} ${reset:+--reset} {}" -- "$@";;
+esac
+[ -n "$toomuch" ] || _nice notmuch new