Hooks to be used to receive/send emails.
Author: brian (git@myr.sh)
Date: Tue Dec 26 19:50:58 2023 -0300
Added example receive script
diff --git a/receive-example.domain b/receive-example.domain
new file mode 100755
index 0000000..5559fd4
--- /dev/null
+++ b/receive-example.domain
@@ -0,0 +1,261 @@
+#!/bin/sh
+
+escapehtml() {
+ sed -e 's/&/\&/g' -e 's/</\</g' -e 's/>/\>/g'
+}
+
+# update index page
+index() {
+ cat <<- EOF
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>dovel</title>
+ <link rel=icon href=/assets/favicon.ico>
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
+ <meta name="color-scheme" content="light dark"/>
+ <style>body{max-width:600px;padding:0 15px;margin:40px auto;font-family:sans-serif;}a{color:#888}small{float:right;}</style>
+ <link rel="manifest" href="/assets/manifest.json">
+ <link rel="apple-touch-icon" sizes="200x200" href="/logo.png">
+ </head>
+ <body>
+ <center>
+ <pre>
+ _________ ______
+ ______ /________ _________ /
+ _ __ /_ __ \_ | / / _ \_ /
+ / /_/ / / /_/ /_ |/ // __/ /
+ \__,_/ \____/_____/ \___//_/
+ </pre>
+ </center>
+ <a href=compose.html>compose</a> 
+ <a href=logout.html>logout</a>
+ EOF
+
+ ls -ogdt --time-style long-iso "$HOME/mail"/* | while read -r g x s d t f
+ do
+ f="$(basename "$f" | cut -d ' ' -f -1)"
+ cat <<- EOF
+ <p>
+ <a href="$f/index.html">$f</a>
+ <small>$t $d</small>
+ </p>
+ EOF
+ done
+ cat <<- EOF
+ </body>
+ </html>
+ EOF
+}
+
+# update inbox page
+inbox() {
+ cat <<- EOF
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>dovel</title>
+ <link rel=icon href=/assets/favicon.ico>
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
+ <meta name="color-scheme" content="light dark"/>
+ <style>body{max-width:600px;padding:0 15px;margin:40px auto;font-family:sans-serif}a{color:#888}small{float:right}</style>
+ <link rel="manifest" href="/assets/manifest.json">
+ <link rel="apple-touch-icon" sizes="200x200" href="/logo.png">
+ </head>
+ <body>
+ <h1>$to</h1>
+ <a href=/index.html>go back</a>
+ EOF
+
+ ls -ogdt --time-style long-iso "$HOME/mail/$to"/* | while read -r g x s d t f
+ do
+ f="$(basename "$f")"
+ qty="$(ls -1 "$HOME/mail/$to/$f" | wc -l)"
+ cat <<- EOF
+ <p>
+ <a href="$f/index.html">$f</a>
+ <small>$t $d</small><br>
+ <i>$qty emails</i>
+ </p>
+ EOF
+ done
+ cat <<- EOF
+ </body>
+ </html>
+ EOF
+}
+
+# update emails page
+emails() {
+ cat <<- EOF
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <title>dovel</title>
+ <link rel=icon href=/assets/favicon.ico>
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
+ <meta name="color-scheme" content="light dark"/>
+ <style>body{max-width:600px;padding:0 15px;margin:40px auto;font-family:sans-serif}a{color:#888}small{float:right}</style>
+ <link rel="manifest" href="/assets/manifest.json">
+ <link rel="apple-touch-icon" sizes="200x200" href="/logo.png">
+ </head>
+ <body>
+ <h1>$subj</h1>
+ <a href="/$to/index.html">go back</a><br><br>
+ EOF
+
+ # print each email
+ # TODO: read text part
+ # TODO: decode quoted-pritable or base64
+ ls -1rt "$HOME/mail/$to/$subj"/*.mbox | while read -r f
+ do
+ {
+ # print headers
+ read -r foo from date
+ cat <<- EOF
+ <details>
+ <summary>
+ From: $from <i style="float:right">$date</i>
+ </summary>
+ <pre>
+ EOF
+
+ while read -r k v
+ do
+ printf "$k $v\n"
+ case "$k" in
+ "Content-Type:") ctype="${v%%;*}" ;;
+ "boundary="*) boundary="${k#*\"}" ;;
+ "Content-Disposition:")
+ cdisp="${v%%;*}"
+
+ if echo "$v" | grep -qv "filename="
+ then
+ read -r v
+ printf -- "$k $v\n"
+ fn="${v#*filename=}"
+ fi
+ fn="${v#*filename=}"
+ fn="$(echo "$fn" | tr -d '"')"
+ ;;
+ "Content-Transfer-Encoding:") cenc="$v" ;;
+ "") break ;;
+ esac
+ done
+
+ cat <<- EOF
+ <br>
+ </pre>
+ </details>
+ <br>
+ EOF
+
+ case "$ctype" in
+ "multipart"*)
+ boundary="${boundary%\"}"
+ printf "<pre>\n"
+ while read -r line
+ do
+ case "$line" in
+ --"$boundary")
+ read -r key pctype char
+ read -r key pcenc
+ read -r blank
+ ;;
+ --"$boundary"--) break ;;
+ *)
+ # now write only text/plain part
+ if [ "$pctype" = "text/plain;" ]
+ then
+ printf -- "$line\n"
+ fi
+ ;;
+ esac
+ done
+ printf "</pre>\n"
+ ;;
+ *)
+ # not multipart so body xor attachments
+ if [ "$cdisp" = "attachment" ]
+ then
+ cat <<- EOF
+ <a href="data:$ctype;base64,
+ EOF
+
+ if [ "$cenc" = "base64" ]
+ then
+ cat
+ else
+ base64
+ fi
+ printf -- "\" download=\"$fn\">$fn</a><br>"
+
+ else
+ printf "<pre>\n"
+ if [ "$cenc" = "base64" ]
+ then
+ base64 -d
+ else
+ cat
+ fi
+ printf "</pre>\n<br>\n"
+ fi
+ ;;
+ esac
+ } < "$f"
+ done
+
+ # finish
+ cat <<- EOF
+ </body>
+ </html>
+ EOF
+}
+
+save() {
+ echo "parsing email"
+
+ # first line is From email date:
+ read -r foo from date
+
+ # read headers
+ while read -r k v
+ do
+ case "$k" in
+ "To:") to="$v" ;;
+ "Subject:") subj="$v" ;;
+ "Message-ID:") eid="$v" ;;
+ "") break ;;
+ esac
+ done
+
+ # adjust fields
+ to="$(printf "$to" | cut -d ' ' -f -1 | tr -d '<>')"
+ eid="${eid:-$(date -Iseconds)}"
+
+ # now the rest is a body
+ cat > /dev/null
+
+ # move temp file
+ mkdir -p "$HOME/mail/$to/$subj"
+ mv "$tmp" "$HOME/mail/$to/$subj/$eid.mbox"
+
+ # create html pages
+ echo "building index page"
+ mkdir -p "$out/$to/$subj"
+ index > "$out/index.html"
+
+ echo "building inbox page"
+ inbox > "$out/$to/index.html"
+
+ echo "building emails page"
+ emails > "$out/$to/$subj/index.html"
+}
+
+# copy to temp file
+echo "[INFO] receive-example.domain started"
+out="$HOME/www/mail"
+tmp="$(mktemp)"
+tee "$tmp" | save
+echo "[INFO] script finished"
+