diff --git a/src/awk/attach.awk b/src/awk/attach.awk new file mode 100644 index 0000000..1a1b81d --- /dev/null +++ b/src/awk/attach.awk @@ -0,0 +1,59 @@ +# This awk scripts adds an attachment to an email message +# +# Variables: +# fpath: path to file + +# Include data +function attach() { + cmd = "file --brief --mime-type '"fpath"'" + suc = cmd | getline ctype + close(cmd) + if (suc != 1) + exit 1 + print "Content-Type: "ctype end + print "Content-Transfer-Encoding: base64"end + filename = a[split(fpath, a, "/")] + gsub(/[^[:alnum:]\.\-\_\ ]/, "", filename) + print "Content-Disposition: attachment; filename=\""filename"\""end + print "MIME-Version: 1.0"end + print ""end + cmd = "base64 '"fpath"'" + while ((cmd | getline line) == 1) + print line end + close(cmd) +} + +# Compute fresh boundary string +function genboundary() { + return sprintf("===============%020d==", int(exp(20*log(10))*rand())) +} + +BEGIN { srand(); gsub(/'/, "'\\''", fpath); } +/^\r?$/ && !inbody { inbody = 1; end = $0 } +/^\r?$/ && !boundary { + nb = genboundary() + print "MIME-Version: 1.0"end + print "Content-Type: multipart/mixed; boundary=\""nb"\""end + print ""end + print "--"nb end + print "Content-Type: text/plain"end + print "Content-Transfer-Encoding: 7bit"end +} +/^Content-Type:/ && !inbody { + match($0, "boundary=\"[^\"]+\"") + boundary = RSTART ? substr($0, RSTART+10, RLENGTH-11) : "" +} +$0 ~ "^--"boundary"--" { + print "--"boundary end + attach() + print ""end +} +{ print } +END { + if (!nb) exit + print ""end + print "--"nb end + attach() + print ""end + print "--"nb"--"end +} diff --git a/src/sh/awk.sh b/src/sh/awk.sh index ff08e69..02455d4 100644 --- a/src/sh/awk.sh +++ b/src/sh/awk.sh @@ -27,5 +27,12 @@ EOF ) export AWK_PARTNR + AWK_ATTACH=$( + cat <<'EOF' +@@include awk/attach.awk +EOF + ) + export AWK_ATTACH + export AWK_LOADED=1 fi diff --git a/src/sh/send.sh b/src/sh/send.sh index 4918c45..4292cac 100644 --- a/src/sh/send.sh +++ b/src/sh/send.sh @@ -1,3 +1,22 @@ +# Add attachment +# This function updates the email file. Errors are suppressed silently, and the +# email will not be altered. +# +# @argument $1: email file +attatchto() { + f="$($FZF \ + --bind="$KEYS_ENTER:accept" \ + --bind="$KEYS_CANCEL:abort" \ + --bind="$KEYS_DOWN_HP:half-page-down" \ + --bind="$KEYS_UP_HP:half-page-up" \ + --walker=file \ + --walker-root="$HOME" || true)" + [ -r "$f" ] || return 0 + eml=$(mktemp) + awk -v fpath="$f" "$AWK_ATTACH" < "$1" > "$eml" || return 0 + mv "$eml" "$1" +} + # Send email # @argument $1: Path to email file # @argument $2: if set, don't prompt the user (optional) @@ -6,10 +25,11 @@ send() { # Prompt user undecided=1 while [ "$undecided" ]; do - case "$($CATEMAIL "$1" | multiprompt "Do you want to send this email?" "$YESSTRING\n$EDITSTRING\n$ABORTSTRING")" in + case "$($CATEMAIL "$1" | multiprompt "Do you want to send this email?" "$YESSTRING\n$EDITSTRING\n$ATTACHSTRING\n$ABORTSTRING")" in 0) undecided= ;; 1) $EDITOR "$1" ;; - 2) return ;; + 2) attatchto "$1" ;; + 3) return ;; esac done fi diff --git a/src/sh/theme.sh b/src/sh/theme.sh index 29641ac..68ee458 100644 --- a/src/sh/theme.sh +++ b/src/sh/theme.sh @@ -16,10 +16,11 @@ if [ ! "${THEME_LOADED:-}" ]; then NOSTRING="${NOSTRING:-$(printf '\033[31mNo\033[0m')}" ABORTSTRING="${ABORTSTRING:-$(printf '\033[31mAbort\033[0m')}" EDITSTRING="${EDITSTRING:-$(printf '\033[33mEdit email\033[0m')}" + ATTACHSTRING="${ATTACHSTRING:-$(printf '\033[35mAttach file\033[0m')}" export ANSICOLORDATE ANSICOLORCNTS ANSICOLORFROM ANSICOLORSUBJ ANSICOLORTAGS export COLDATE COLCNTS COLFROM COLSUBJ COLTAGS COLRESET - export YESSTRING NOSTRING ABORTSTRING EDITSTRING + export YESSTRING NOSTRING ABORTSTRING EDITSTRING ATTACHSTRING export THEME_LOADED=1 fi