123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- #!/bin/bash
- # password previously encrypted:
- # openssl enc -aes-256-cbc -iter 99999 -a -pass file:/etc/machine-id -out "$passfile"
- sep="################################################"
- server="posteo.de"
- user=danter
- me="${0##*/}"
- tag=Zaphod
- passfile="$HOME/.local/share/$me.txt"
- countonly=0
- debug=0
- after=''
- while getopts "cda:" opt; do
- case $opt in
- c)
- countonly=1
- ;;
- d)
- debug=1
- ;;
- a)
- after="$OPTARG"
- ;;
- esac
- done
- debug() {
- [[ "$debug" != 1 ]] && return
- (($# > 1)) && printf "$@" || echo "$1"
- }
- remCR() {
- # removes carriage returns from output
- # works directly on $out
- out="${out//$'\r'/}"
- }
- mimedecode() {
- # only if Perl & its Encode module are available
- # https://superuser.com/a/972248
- x="$(perl -CS -MEncode -e "print decode('MIME-Header', '$out')" 2>/dev/null)"
- [ -n "$x" ] && out="$x" || out="$@"
- }
- # Start the session
- coproc SSL { openssl s_client -connect "$server":993 -crlf -quiet 2>/dev/null; } || exit 1
- # Make sure openssl is dead when exiting
- trap 'kill $SSL_PID 2>/dev/null' EXIT
- # LOGIN
- line="$tag login $user@$server"
- echo "$line $(openssl enc -aes-256-cbc -iter 99999 -a -pass file:/etc/machine-id -d -in "$passfile")" >&${SSL[1]}
- debug "$line super_secret_password"
- # Catch output loop. Remove the printf if you want it quiet
- while read -r out; do
- debug '%q\n' "$out"
- # This reply tells us the server is done and waiting for more input
- [[ "$out" == "$tag "* ]] && break
- done <&${SSL[0]}
- debug "$sep"
- # Now we're talking to the server
- echo "$tag lsub INBOX \"*\"" >&${SSL[1]}
- debug "$tag lsub INBOX \"*\""
- # Catch output loop. Remove the printf if you want it quiet
- subs=(); count=0
- while read -r out; do
- debug '%q\n' "$out"
- # This is the first stepof the info we're after
- [[ "$out" == '* LSUB '* ]] && {
- out="${out#*\".\" }"
- remCR # remove carriage return!
- subs[count++]="$out"
- continue
- }
- # Again, this reply tells us the server is done and waiting for more input
- [[ "$out" == "$tag "* ]] && break
- done <&${SSL[0]}
- debug "$sep"
- # Now we're talking to the server
- declare -A unseen=()
- for i in "${subs[@]}"; do
- # 1. select folder
- echo "$tag select $i" >&${SSL[1]}
- debug "$tag select $i"
- # Catch output loop.
- found=0
- while read -r out; do
- debug '%q\n' "$out"
- # no need to search _each_ folder for unseen messages!
- [[ "$out" == '* OK [UNSEEN '* ]] && found=1
- [[ "$out" == "$tag "* ]] && break
- done <&${SSL[0]}
- # 2. search for unseen mail
- if [[ "$found" == 1 ]]; then
- echo "$tag search (unseen)" >&${SSL[1]}
- debug "$tag search (unseen)"
-
- # Catch output loop.
- while read -r out; do
- debug '%q\n' "$out"
- # 3. if SEARCH is followed by a space there are unseen messages
- [[ "$out" == '* SEARCH '* ]] && {
- out="${out#*SEARCH }"
- remCR
- # 4. asssign to array
- unseen[$i]="$out"
- continue
- }
- [[ "$out" == "$tag "* ]] && break
- done <&${SSL[0]}
- fi
- done
- debug "$sep"
- final=""
- # now also get subject lines
- for folder in "${!unseen[@]}"; do
- # select folder
- echo "$tag select $folder" >&${SSL[1]}
- debug "$tag select $folder"
- while read -r out; do
- debug '%q\n' "$out"
- # This reply tells us the server is done and waiting for more input
- [[ "$out" == "$tag "* ]] && break
- done <&${SSL[0]}
- # make array from numerical mail ids
- arr=(${unseen[$folder]})
- # removes leading & trailing quotes from folder name, for final display only
- folder="${folder#\"}";folder="${folder#\'}";folder="${folder%\"}";folder="${folder%\'}"
- final="${final}\n$folder"
- if [[ "$countonly" == 1 ]]; then
- final="$final: ${#arr[@]} unread mail"
- (( ${#arr[@]} > 1 )) && final="${final}s" || final="$final"
- else
- for i in "${arr[@]}"; do
- echo "$tag fetch $i body.peek[header.fields (subject)]" >&${SSL[1]}
- debug "$tag fetch $i body.peek[header.fields (subject)]"
- # Catch output loop.
- while read -r out; do
- debug '%q\n' "$out"
- [[ "$out" == "Subject: "* ]] && {
- out="${out#Subject: }"
- remCR
- [[ "${out,,}" == '=?utf-8?'*'?=' ]] && mimedecode
- final="$final\n - $out"
- continue
- }
- [[ "$out" == "$tag "* ]] && break
- done <&${SSL[0]}
- done
- fi
- done
- final="${final#\\n}"
- final="${final%\\n}"
- # That's all we wanted. Logging out
- echo "$tag logout" >&${SSL[1]}
- debug "$tag logout"
- while read -r out; do
- debug '%q\n' "$out"
- [[ "$out" == "$tag "* ]] && break
- done <&${SSL[0]}
- # at this point the openssl coproc should quit.
- debug "$sep"
- if [[ "$final" != "" ]]; then
- [[ "$after" != "" ]] && final="$final$after"
- echo -e "$final"
- fi
|