diff options
Diffstat (limited to 'bin/mailsync-dsync')
-rwxr-xr-x | bin/mailsync-dsync | 132 |
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 |