@@ -33,69 +33,65 @@ mwmaildir="${MAILDIR:-$HOME/mail}"
# Regex to confirm valid email address
mwemailre=".\+@.\+\\..\+"
mwshare="$prefix/share/mutt-wizard"
if [ -n "$XDG_CONFIG_HOME" ]; then
mwmbsyncrc="$mwconfigdir/isync/mbsyncrc"
else
mwmbsyncrc="$HOME/.mbsyncrc"
fi
mwsharerc="$mwshare/mutt-wizard.muttrc"
mwcachedir="${XDG_CACHE_HOME:-$HOME/.cache}/mutt-wizard"
mwmuttrc="$mwmuttdir/muttrc"
mwmbsyncrc="$mwconfigdir/isync/mbsyncrc"
mwmsmtprc="$mwconfigdir/msmtp/config"
mwsharerc="$mwshare/mutt-wizard.muttrc"
mwcachedir="${XDG_CACHE_HOME:-$HOME/.cache}/mutt-wizard"
mwssltype="IMAPS"
mbsyncbin="$prefix/bin/mbsync -c $mwmbsyncrc"
msmtpbin="$prefix/bin/msmtp"
take mwaddrmwtype(){
_ mwaddrmwtype(){
mwacc="$mwaddr" # let the user always just deal with his email
mwaccmutt="${mwaddr//[.@]/_}" # but mutt would not show it with an @ or .
mwacccachedir=$mwcachedir/${mwaddr//[.@]/_} # @ cannot stay because of mutt, . could
mwaccmaildir="$mwmaildir/$mwaccmutt" # folder name as shown by mutt and opens with gf in vim
mwaccmuttrc="$mwaccmuttdir/$idnum-$mwacc.mwonofftype.$mwtype.muttrc"
mwaccmuttrc="$mwaccmuttdir/$mw idnum-$mwacc.mwonofftype.$mwtype.muttrc"
mwpass=mutt-wizard-$mwaddr
[ -n "$idnum" ] && mwaccmuttrc="$mwaccmuttdir/$idnum-$mwacc.mwonofftype.$mwtype.muttrc"
[ -n "$mw idnum" ] && mwaccmuttrc="$mwaccmuttdir/$mw idnum-$mwacc.mwonofftype.$mwtype.muttrc"
}
for x in "/etc/ssl/certs/ca-certificates.crt" "/etc/pki/tls/certs/ca-bundle.crt" "/etc/ssl/ca-bundle.pem" "/etc/pki/tls/cacert.pem" "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem" "/etc/ssl/cert.pem" "/usr/local/share/ca-certificates/"
for mwcrt in "/etc/ssl/certs/ca-certificates.crt" "/etc/pki/tls/certs/ca-bundle.crt" "/etc/ssl/ca-bundle.pem" "/etc/pki/tls/cacert.pem" "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem" "/etc/ssl/cert.pem" "/usr/local/share/ca-certificates/"
do
[ -f "$x" ] && sslcert="$x " && break
[ -f "$mwcrt" ] && mwsslcert="$mwcrt " && break
done || { echo "CA Certificate not found. Please install one or link it to /etc/ssl/certs/ca-certificates.crt" && exit 1 ;}
getaccounts() {
accounts="$(find "$mwaccmuttdir" -type f | grep -o "[0 -9]-.*.muttrc" | sed "s/-/: /;s/\.muttrc//" | sort -n)"
_mw getaccounts() {
mw accounts="$(find "$mwaccmuttdir" -type f | grep -o "[1 -9]-.*.muttrc" | sed "s/-/: /;s/\.muttrc//" | sort -n)"
}
mwlist() {
getaccounts && [ -n "$accounts" ] && echo "${accounts//.mwonofftype./ }"
_ mwlist() {
_mw getaccounts && [ -n "$mw accounts" ] && echo "${mw accounts//.mwonofftype./ }"
}
mwadd() {
asktype && askinfo && tryconnect && finalize || mwdelete
_ mwadd() {
_mw asktype && _mw askinfo && _mw tryconnect && _mw finalize || _ mwdelete
}
getprofiles() {
unset msmtp_ header msmtp_ profile mutt_ profile mbsync_ profile
_mw getprofiles() {
unset mwm smtpheader mwm smtpprofile mwm uttprofile mwm bsyncprofile
printf "Creating profiles for \`%s\`..." "$mwaddr"
msmtp_ header="defaults
mw msmtpheader="defaults
auth on
tls on
tls_trust_file $sslcert
tls_trust_file $mw sslcert
logfile ${XDG_LOG_HOME:-$HOME}/msmtp.log
"
msmtp_ profile="account $mwacc
mw msmtpprofile="account $mwacc
host $mwsmtp
port $mwsport
from $mwaddr
user $mwlogin
passwordeval \"pass $mwpass\"
$starttlsoff
$mw starttlsoff
"
mbsync_ profile="IMAPStore $mwacc-remote
mw mbsyncprofile="IMAPStore $mwacc-remote
Host $mwimap
Port $mwiport
User $mwlogin
PassCmd \"pass $mwpass\"
SSLType $mwssltype
CertificateFile $sslcert
CertificateFile $mw sslcert
MaildirStore $mwacc-local
Subfolders Verbatim
@@ -115,7 +111,7 @@ MaxMessages 0
"
if [ "$mwtype" = "offline" ]; then
mutt_ profile="# vim: filetype=neomuttrc
mw muttprofile="# vim: filetype=neomuttrc
# muttrc file for account $mwaddr
set realname = \"$mwname\"
set from = \"$mwaddr\"
@@ -129,7 +125,7 @@ macro index gm \"<shell-escape>mailsync $mwacc<enter>\" \"sync mail $mwaddr\"
unmailboxes *
"
else
mutt_ profile="# vim: filetype=neomuttrc
mw muttprofile="# vim: filetype=neomuttrc
# muttrc file for account $mwaddr
set realname = \"$mwname\"
set from = \"$mwaddr\"
@@ -152,7 +148,7 @@ fi
printf "DONE.\\n"
}
askinfo() {
_mw askinfo() {
if [ -z "$mwaddr" ]; then
printf "Type the \033[31memail address\033[0m\\n\t\033[36m"
read -r mwaddr
@@ -186,7 +182,7 @@ EOF
gmail.com) printf "\033[31mGmail: \"less secure\" must be enabled before you continue.\\nDo it now, if you have not done it already:\\nhttps://support.google.com/accounts/answer/6010255\\n\033[0m" ;;
protonmail.ch|protonmail.com|pm.me) printf "\033[31mProtonmail: Users must install and configure Protonmail Bridge for the sync to work:\\nhttps://protonmail.com/bridge/\\n\033[0m" && ssltype="None" ;;
esac
[ "$mwsport" = 465 ] && starttlsoff="tls_starttls off"
[ "$mwsport" = 465 ] && mw starttlsoff="tls_starttls off"
fi
if [ -z "$mwname" ]; then
printf "Name to associate to email.\\n\t"
@@ -201,37 +197,37 @@ EOF
# if the user has a pass entry he could provide it via mwpass
if [ -z "$mwpass" ]; then
mwpass=mutt-wizard-$mwaddr
getpass
_mw getpass
fi
unset idnum
take mwaddrmwtype
getprofiles
mkdir -p "$mwmuttdir" "$mwaccmuttdir" "$mwconfigdir/ msmtp" "${mwmbsyncrc%/*}"
unset mw idnum
_ mwaddrmwtype
_mw getprofiles
mkdir -p "$mwmuttdir" "$mwaccmuttdir" "${ mwmsmtprc%/*} " "${mwmbsyncrc%/*}"
if [ ! -f "$mwmsmtprc" ]; then
echo "$msmtp_ header" > "$mwmsmtprc"
echo "$mwm smtpheader" > "$mwmsmtprc"
else
sed -i "/account $mwacc/,/^\(\s*$\|account\)/d" "$mwmsmtprc"
fi
echo "$msmtp_ profile" >> "$mwmsmtprc"
echo "$mwm smtpprofile" >> "$mwmsmtprc"
case "$mwservice" in
protonmail.ch|protonmail.com|pm.me) protonfinger || return 1 ;;
esac
[ -f "$mwmbsyncrc" ] && sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
echo "$mbsync_ profile" >> "$mwmbsyncrc"
echo "$mwm bsyncprofile" >> "$mwmbsyncrc"
#mwaccmuttrc
mwaccmuttrc="$mwaccmuttdir/$(find "$mwaccmuttdir" -type f | grep -m 1 -o "[0 -9]-$mwacc.mwonofftype.$mwtype.muttrc")"
mwaccmuttrc="$mwaccmuttdir/$(find "$mwaccmuttdir" -type f | grep -m 1 -o "[1 -9]-$mwacc.mwonofftype.$mwtype.muttrc")"
if [[ ! -f "$mwaccmuttrc" ]]; then
# new idnum = first one missing
getaccounts
for x in $(seq 1 9); do echo "$accounts" | grep "$x:" >/dev/null 2>&1 || { export idnum="$x"; break ;}; done
mwaccmuttrc="$mwaccmuttdir/$idnum-$mwacc.mwonofftype.$mwtype.muttrc"
# new mw idnum = first one missing
_mw getaccounts
for mw x in $(seq 1 9); do echo "$mw accounts" | grep "$mw x:" >/dev/null 2>&1 || { export mw idnum="$mw x"; break ;}; done
mwaccmuttrc="$mwaccmuttdir/$mw idnum-$mwacc.mwonofftype.$mwtype.muttrc"
else
idnum=${mwaccmuttrc%%-*}
idnum=${idnum##*/}
mw idnum=${mwaccmuttrc%%-*}
mw idnum=${mw idnum##*/}
fi
echo "$mutt_ profile" > "$mwaccmuttrc"
echo "$mwm uttprofile" > "$mwaccmuttrc"
[ ! -f "$mwmuttrc" ] && echo "# vim: filetype=neomuttrc" > "$mwmuttrc" && echo "muttrc created."
! grep "source.*mutt-wizard.mutt rc" "$mwmuttrc" >/dev/null && echo "source $mwsharerc # mw-autogenerated" >> "$mwmuttrc"
! grep "source $mwshare rc" "$mwmuttrc" >/dev/null && echo "source $mwsharerc # mw-autogenerated" >> "$mwmuttrc"
if [ "$mwtype" = "offline" ]; then
! grep "^macro .* gM .*" "$mwmuttrc" >/dev/null && echo "macro index gM '<shell-escape>mailsync -Va<enter>' \"sync all mail\" # mw-autogenerated" >> "$mwmuttrc"
fi
@@ -239,18 +235,18 @@ EOF
return 0
}
protonfinger() {
_mw protonfinger() {
printf "Getting Protonmail bridge fingerprint...\\n"
fingerprint="$($msmtpbin --serverinfo --host=127.0.0.1 --port=1025 --tls --tls-certcheck=off)" || return 1
sed -i "s/account $mwacc/&\ntls_trust_file\ntls_fingerprint $fingerprint/" "$mwmsmtprc"
mw fingerprint="$($msmtpbin --serverinfo --host=127.0.0.1 --port=1025 --tls --tls-certcheck=off)" || return 1
sed -i "s/account $mwacc/&\ntls_trust_file\ntls_fingerprint $mw fingerprint/" "$mwmsmtprc"
}
getpass() {
_mw getpass() {
while : ; do pass rm -f "$mwpass" >/dev/null 2>&1
pass insert "$mwpass" && break; done ;}
tryconnect() {
_mw tryconnect() {
if [ ! -d "$mwaccmaildir" ]; then
mwaccmaildirWasThere="NO" # we need to remove again for "online"
mkdir -p "$mwaccmaildir"
@@ -259,18 +255,18 @@ tryconnect() {
mailboxes="$($mbsyncbin -l $mwacc | sed 's/\//./')" >/dev/null 2>&1
fi
if [ -n "$mailboxes" ]; then
spoolfile=$(echo "$mailboxes" | grep -i -m 1 inbox | sed -ne 's/.*/+\0/p')
[ -z "$spoolfile" ] && return 1
mw spoolfile=$(echo "$mailboxes" | grep -i -m 1 inbox | sed -ne 's/.*/+\0/p')
[ -z "$mw spoolfile" ] && return 1
#make directories
printf "\033[32mMailboxes detected.\033[0m\\n"
echo "$mailboxes" | xargs -I {} mkdir -p "$mwaccmaildir/{}/"{cur,new,tmp}
record=$(echo "$mailboxes" | grep -i -m 1 sent | sed -ne 's/.*/+\0/p')
[ -z "$record" ] && mkdir -p "$mwaccmaildir/Sent/"{cur,new,tmp} && record="Sent"
[ -z "$mw record" ] && mkdir -p "$mwaccmaildir/Sent/"{cur,new,tmp} && record="Sent"
postponed=$(echo "$mailboxes" | grep -i -m 1 draft | sed -ne 's/.*/+\0/p')
[ -z "$postponed" ] && mkdir -p "$mwaccmaildir/Drafts/"{cur,new,tmp} && postponed="Drafts"
[ -z "$mw postponed" ] && mkdir -p "$mwaccmaildir/Drafts/"{cur,new,tmp} && postponed="Drafts"
trash=$(echo "$mailboxes" | grep -i -m 1 trash | sed -ne 's/.*/+\0/p')
[ -z "$trash" ] && mkdir -p "$mwaccmaildir/Trash/"{cur,new,tmp} && trash="Trash"
[ -z "$mw trash" ] && mkdir -p "$mwaccmaildir/Trash/"{cur,new,tmp} && trash="Trash"
return 0
else
@@ -280,9 +276,9 @@ tryconnect() {
}
finalize() { # new mwaccmuttrc
boxes="$(find "$mwaccmaildir/" -name cur | sed "s,$mwaccmaildir/,,g;s,/cur,,")"
if [[ "$boxes" =~ ^[[:space:]]*$ ]]; then
_mw finalize() { # new mwaccmuttrc
mw boxes="$(find "$mwaccmaildir/" -name cur | sed "s,$mwaccmaildir/,,g;s,/cur,,")"
if [[ "$mw boxes" =~ ^[[:space:]]*$ ]]; then
printf "\033[31mNo local mailboxes have been detected for %s.\033[0m\\nThis means that mbsync has not been successfully run.\\nRun mbsync, and if it has an error, be sure to check your password and server settings manually if needbe.\\n" "$mwacc"
return
fi
@@ -290,93 +286,97 @@ finalize() { # new mwaccmuttrc
muttsync=$(printf '<sync-mailbox><enter-command>source %s<enter><change-folder>!<enter>;<check-stats>' $mwaccmuttrc)
cat >> "$mwaccmuttrc" <<EOF
set spoolfile = "$spoolfile"
set record = "$record"
set postponed = "$postponed"
set trash = "$trash"
set spoolfile = "$mw spoolfile"
set record = "$mw record"
set postponed = "$mw postponed"
set trash = "$mw trash"
folder-hook \$folder '$muttsync'
macro index,pager i$idnum '$muttsync' "switch to $email "
macro index,pager i$mwidnum '$muttsync' "switch to $mwacc "
mailboxes =$mwaccmutt ===================== $(echo "$boxes" | sed -e "s/ //g;s/.*/\"=\0\"/g" | tr "\n" " ")
mailboxes =$mwaccmutt ===================== $(echo "$mw boxes" | sed -e "s/ //g;s/.*/\"=\0\"/g" | tr "\n" " ")
EOF
for eqbox in $ boxes; do
box=${eq box##*/}
box=${box##*.}
boxi=${box::2}
boxi=${boxi,,}
for mwabox in $mw boxes; do
mwbox=${mwa box##*/}
mw box=${mw box##*.}
mw boxi=${mw box::2}
mw boxi=${mw boxi,,}
cat >> $mwaccmuttrc <<EOF
macro index,pager i$boxi "<change-folder>=$eqbox<enter>" "go to $ box"
macro index,pager M$boxi "<save-message>=$eqbox<enter>" "move mail to $ box"
macro index,pager C$boxi "<copy-message>=$eqbox<enter>" "copy mail to $ box"
macro index,pager i$mwboxi "<change-folder>=$mwabox<enter>" "go to $mw box"
macro index,pager M$mwboxi "<save-message>=$mwabox<enter>" "move mail to $mw box"
macro index,pager C$mwboxi "<copy-message>=$mwabox<enter>" "copy mail to $mw box"
EOF
done
if [ "$mwtype" = "offline" ]; then
notmuchauto
_mw notmuchauto
printf "All done.\\n\033[33mYou can now run \`\033[32mmailsync [%s]\033[33m\` to sync your mail.\033[0m\\n" "$mwacc"
else
mkdir -p "$mwacccachedir"
sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
[ "$mwaccmaildirWasThere" = "NO" ] && rm -rf "$mwaccmaildir/ "
[ "$mwaccmaildirWasThere" = "NO" ] && rm -rf "$mwaccmaildir"
fi
return 0
}
confirm() {
printf "[y/N]: Do you want to %s?\\n\t" "$@" && read -r input && ! echo "$input" | grep -i "^y$\|^yes$" >/dev/null && printf "That doesn't seem like a yes to me.\\n\\n" && return 1
_mw confirm() {
printf "[y/N]: Do you want to %s?\\n\t" "$@" && read -r mw input && ! echo "$mw input" | grep -i "^y$\|^yes$" >/dev/null && printf "That doesn't seem like a yes to me.\\n\\n" && return 1
return 0 ;
}
mwpick() {
_ mwpick() {
printf "Select an accounts to %s:\\n" "$1"
mwlist
read -r idnum
[ -z "$idnum" ] && return 1
mwaddr="$(echo "$accounts" | grep "$idnum:" | sed "s/\.mwonofftype\./ /" | awk '{print $2}')"
mwtype="$(echo "$accounts" | grep "$idnum:" | sed "s/\.mwonofftype\./ /" | awk '{print $3}')"
takemwaddrmwtype
_mwlist
[ -z "$mwpick" ] && read -r mwpick
mwidnum="$mwpick"
[ -z "$mwidnum" ] && return 1
mwaddr="$(echo "$mwaccounts" | grep "$mwidnum:" | sed "s/\.mwonofftype\./ /" | awk '{print $2}')"
mwtype="$(echo "$mwaccounts" | grep "$mwidnum:" | sed "s/\.mwonofftype\./ /" | awk '{print $3}')"
_mwaddrmwtype
[ -z "$mwacc" ] && printf "Invalid response." && return 1
return 0 ;
}
mwdelete() {
sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
rm -rf "$mwacccachedir"
rm -rf "$mwaccmuttdir/"[1-9]"-$mwacc.mwonofftype.$mwtype.muttrc"
sed -i "/[0-9]-$mwacc.mwonofftype.$mwtype.muttrc/d" "$mwmuttrc"
sed -i "/account $mwacc/,/^\(\s*$\|account\)/d" "$mwmsmtprc"
_mwdelete() {
rm -f "$mwaccmuttrc"
sed -i "/$mwaccmuttrc/d" "$mwmuttrc"
if [ "$mwtype" = "offline" ]; then
sed -i "/IMAPStore $mwacc-remote$/,/# End profile/d" "$mwmbsyncrc"
sed -i "/account $mwacc/,/^\(\s*$\|account\)/d" "$mwmsmtprc"
else
rm -rf "$mwacccachedir"
fi
}
mwcron() {
_ mwcron() {
! pgrep cron >/dev/null && echo "No cron manager running. Install/enable one and then select this option again." && return 1
if crontab -l | grep mailsync >/dev/null; then
echo "Active mail sync cronjob detected. Do you want to remove it?"
printf "\033[36m\t"
read -r rmyn
[ -z "$mwcronremove" ] && read -r mwcronremove
printf "\033[0m"
echo "$rmyn " | grep -i "^y\(es\)*$" >/dev/null && crontab -l | sed '/mailsync/d' | crontab - >/dev/null && echo "Mail sync turned off."
echo "$mwcronremove " | grep -i "^y\(es\)*$" >/dev/null && crontab -l | sed '/mailsync/d' | crontab - >/dev/null && echo "Mail sync turned off."
else
echo "How many minutes between each mail sync?"
printf "\033[36m\t"
read -r minnum
[ -z $mwcronminutes ] && read -r mwcronminutes
printf "\033[0m"
while ! echo "$minnum" | grep "^[0 -9]\+$" >/dev/null; do
while ! echo "$mwcronminutes" | grep "^[1 -9]\+$" >/dev/null; do
printf "That doesn't look like a number. How many minutes between each mail sync?\\n\033[36m\t"
read -r minnum
read -r mwcronminutes
printf "\033[0m"
done
(crontab -l; echo "*/$minnum * * * * export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus; export DISPLAY=:0; $(type mailsync | cut -d' ' -f3)") | crontab - &&
echo "Cronjob added. Mail will sync every $minnum minutes. Be sure you have your cron manager running."
(crontab -l; echo "*/$mwcronminutes * * * * export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus; export DISPLAY=:0; $(type mailsync | cut -d' ' -f3)") | crontab - &&
echo "Cronjob added. Mail will sync every $mwcronminutes minutes. Be sure you have your cron manager running."
fi
}
asktype() {
_mw asktype() {
if [ -z "$mwtype" ]; then
while : ; do
printf "[yes/no]: Local mail via mbsync? No: Mutt remotes (slower)\\n\t"
read -r offnot
case "$offnot " in
read -r mwoffline
case "$mwoffline " in
[Yy][Ee][Ss]) mwtype="offline" && break ;;
[Nn][Oo]) mwtype="online" && break ;;
*) echo "Write out either yes or no completely. Try again or press ctrl-c to quit." ;;
@@ -385,18 +385,18 @@ asktype() {
fi
}
mwpurge() {
confirm "delete all account data" || exit
rm -rf "$mwmbsyncrc" "$mwaccmuttdir" "$mwconfigdir/msmtp" "${mwmbsyncrc%/*}" "$mwcachedir"
pgrep cron >/dev/null && crontab -l | sed '/mailsync/d' | crontab - >/dev/null
_mwpurge() {
_mwconfirm "delete all account data" || exit
rm -rf "$mwaccmuttdir" "${mwmsmtprc%/*}" "${mwmbsyncrc%/*}" "$mwcachedir"
sed -i "/\# mw-autogenerated/d" "$mwmuttrc"
pgrep cron >/dev/null && crontab -l | sed '/mailsync/d' | crontab - >/dev/null
echo "All configs and account settings have been purged."
}
notmuchauto() {
_mw notmuchauto() {
[ -z "$NOTMUCH_CONFIG" ] && NOTMUCH_CONFIG="$HOME/.notmuch-config"
[ -f "$NOTMUCH_CONFIG" ] && return 0
nmbasic="[database]
mw nmbasic="[database]
path=$mwmaildir
[user]
name=$mwname
@@ -411,19 +411,19 @@ synchronize_flags=true
[crypto]
gpg_path=$GPG"
mkdir -p "${NOTMUCH_CONFIG%/*}"
echo "$nmbasic" > "$NOTMUCH_CONFIG"
echo "$mw nmbasic" > "$NOTMUCH_CONFIG"
}
trap 'echo -e "\033[0m\n"; exit' STOP INT ABRT KILL
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
case "$1" in
ls) mwlist ;;
add) mwadd ;;
pass) mwpick "change the password of" && getpass ;;
delete) mwpick delete && confirm "delete the \`$mwacc\` profile" && mwdelete ;;
purge) mwpurge ;;
cron) mwcron ;;
ls) _ mwlist ;;
add) _ mwadd ;;
pass) _ mwpick "change the password of" && _mw getpass ;;
delete) _ mwpick delete && _mw confirm "delete the \`$mwacc\` profile" && _ mwdelete ;;
purge) _ mwpurge ;;
cron) _ mwcron ;;
*) cat << EOF
mw: mutt-wizard, auto-configure email accounts for mutt
including downloadable mail with \`isync\`.