summaryrefslogtreecommitdiff
path: root/bin/mailsync-dsync
blob: 5fe80a74ae33271e15e2f9c1d6b3f225939d5b50 (plain)
  1. #!/bin/sh
  2. # Copyright © 2015-2016 Jonas Smedegaard <dr@jones.dk>
  3. # Description: Synchronize mail using Dovecot tool dsync
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 3, or (at your option)
  8. # any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful, but
  11. # WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. # General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. #
  18. # Depends: dovecot-core
  19. # Recommends: moreutils
  20. #
  21. # FIXME
  22. # * Generailze account resolving (avoid hardcoded accounts)
  23. #
  24. # TODO
  25. # * Gracefully serialize (with warning) if parallel not available
  26. # * Add option to not parallelize (and not warn if parallel missing)
  27. # * Add global lock
  28. # * Handle "region" derived from profile:
  29. # + Avoid parallelize same-region profiles
  30. # + Lock each region separately
  31. # * Parse configfile for profiles
  32. set -e
  33. PRG=$(basename "$0")
  34. showhelp() {
  35. cat <<EOF
  36. Usage: $PRG [--tomuch] [--] PROFILE [PROFILE...]
  37. Synchronize one or more Dovecot Maildir profiles
  38. --toomuch Don't update notmuch database after syncronization
  39. --debug Enable debugging output
  40. --alive Monitor SSH connection that server is alive
  41. --reset Clear state tracking to force full sync
  42. -h, --help This help text
  43. Examples:
  44. $PRG jones hb
  45. $PRG --toomuch jones
  46. EOF
  47. }
  48. exit1() {
  49. response="${1:+Error: }${1:-Internal error!}"
  50. echo >&2 "$response"
  51. exit 1
  52. }
  53. # parse cmdline options
  54. TEMP="`getopt -s sh -o h -l help,toomuch,debug,alive,reset -n "$PRG" -- "$@"`" || exit1 "Internal getopt error."
  55. eval set -- "$TEMP"
  56. while true ; do
  57. case "$1" in
  58. -h|--help) showhelp; exit;;
  59. --toomuch) toomuch=yes; shift;;
  60. --debug) debug=yes; shift;;
  61. --alive) alive=yes; shift;;
  62. --reset) reset=yes; shift;;
  63. --) shift; break;;
  64. *) exit1 "Internal error resolving options.";;
  65. esac
  66. done
  67. [ $# -gt 0 ] || set -- jones debian bb hb lxp5
  68. _nice() {
  69. # ionice -c 3 chrt --idle 0 /bin/sh -c "$@"
  70. "$@"
  71. }
  72. _dsync() {
  73. profile="$1"
  74. case "$profile" in
  75. jones) host=mail.jones.dk;;
  76. debian) host=jonas-debian@mail.jones.dk;;
  77. bb) host=mail.bitbase.dk;;
  78. hb) host=mail.homebase.dk;;
  79. # db) host=db.letsgo.dk;;
  80. # lb) host=lb.letsgo.dk;;
  81. lxp5) host=lxp5.free-owl.de;;
  82. *) exit1 "Wrong account \"$account\"";;
  83. esac
  84. for algo in ed25519 ecdsa dsa rsa; do
  85. key="$HOME/.ssh/id_${algo}_mail_$profile"
  86. if [ -f "$key" ] && [ -f "$key.pub" ]; then
  87. break
  88. fi
  89. key=
  90. done
  91. cachedir="$HOME/.cache/mydsync"
  92. statefile="$cachedir/$profile"
  93. [ -z "$reset" ] || rm -f "$statefile" "$statefile"~
  94. if [ -s "$statefile" ]; then
  95. cp -f "$statefile" "$statefile"~
  96. else
  97. touch "$statefile"
  98. fi
  99. state="$(cat "$statefile")"
  100. if [ -z "$state" ] && [ -f "$statefile"~ ]; then
  101. state="$(cat "$statefile"~)"
  102. fi
  103. mkdir -p "$cachedir"
  104. [ -n "$key" ] || exit1 "ssh key missing for $profile"
  105. _nice doveadm ${debug:+-D} \
  106. -o mail_location=maildir:~/Maildir/"$profile" \
  107. sync -s "$state" -x spam -x Junk -x Trash \
  108. ssh -i "$key" -o BatchMode=yes \
  109. ${alive:+-o ServerAliveInterval=10 -o ServerAliveCountMax=5} \
  110. "$host" doveadm dsync-server \
  111. > "$statefile"
  112. }
  113. case $# in
  114. 0)
  115. exit1 "Internal error: no arguments to process";;
  116. 1)
  117. _dsync "$1";;
  118. *)
  119. parallel -i sh -c "$0 --toomuch ${debug:+--debug} ${alive:+--alive} ${reset:+--reset} {}" -- "$@";;
  120. esac
  121. [ -n "$toomuch" ] || _nice notmuch new