#!/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