You are not logged in.
Devuan has inspired me to do all my computing as simply as possible. Here's a little script I wrote so that I can send email from a script or terminal with virtually zero overhead (specifically, without having to install and configure an MTA such as exim or postfix). All you need is:
1. sudo apt-get install curl
2. put your smtp credentials at the top of the script
3. make this script executable and put it in your PATH (on my system, the script is called easymail)
I thought I'd share it here in case anyone else has use for it. If you see anything in it that could be improved, please let me know.
Cheers,
Bruno
#!/bin/sh
# Purpose: To send email as simply as possible (i.e., without needing to install an MTA
# such as exim or postfix). The script's only dependencies are curl and coreutils on Linux,
# curl and gcoreutils on OpenBSD.
#
# Note about regular vs. root user: Either one can use this script :)
#
# Note about CA ssl certificates on computer/phone:
# If they are missing, add --insecure to the curl command.
#
# Author: Bruno "GNUser" Dantas
# License: GPLv3
# Version: 3.0 (27Mar2019)
# Changelog:
# - working on Devuan ASCII and OpenBSD 6.4
# - body not mandatory
# - no bashisms
# smtp credentials
host='smtps://my.email.com'
port='993'
user='my-username'
password='secretPasswoRd'
main()
{
get_stdin
get_commandline_options "$@"
build_eml_file
wait_for_internet
send_eml_file
}
show_usage()
{
echo "Usage: easymail -d <destination> [-s <subject>] [-b <body>] [-a <attachment>]
Notes:
- destination: an email address (if multiple, precede each one with -d)
- subject: a string
- body: stdin, -b string, or -b file (note: -b flag takes precedence over stdin). examples:
1. echo 'some string' | easymail
2. easymail </path/to/some-text-file
3. easymail -b 'some string'
4. easymail -b /path/to/some-text-file
- attachment: a file (if multiple, precede each one with -a)
Example:
easymail -d somebody@somewhere.com -s 'Devuan' -b 'Devuan rocks!' -a fork.pdf"
}
attach()
{
# create an attachments file if one does not exist yet
[ -z $attachments_file ] && attachments_file=$(mktemp)
# now append the attachment to the attachments file
filename="$(basename "$1")"
echo "------7II5XTH4IPXG2QZOY8LJF98QQX4IR3
Content-Transfer-Encoding: base64
Content-Type: application/octet-stream;
name=\"$filename\"
Content-Disposition: attachment;
filename=\"$filename\";
" >>$attachments_file
if uname | grep -qi BSD; then
cat "$1" | b64encode poop | tail -n +2 >>$attachments_file
else # Linux
cat "$1" | base64 >>$attachments_file
fi
}
cleanup()
{
rm -f $eml_file $attachments_file
}
trap cleanup EXIT HUP TERM INT
get_stdin()
{
if uname | grep -qi BSD; then
body="$(gtimeout 1 dd bs=1 count=1 2>/dev/null && cat)"
else # Linux
body="$(timeout 1 dd bs=1 count=1 2>/dev/null && cat)"
fi
# dd has 1 sec to get 1 byte, which is plenty of time if there is data
# in stdin waiting to be read. If dd succeeds, it passes its byte to stdout
# and triggers cat, which has unlimited time to get remaining data.
# This seems complicated but is necessary: using just cat causes script to
# hang if there is no data in stdin.
}
get_commandline_options()
{
while [ "$#" -gt 0 ]; do
case "$1" in
-d)
curl_destination="${curl_destination}--mail-rcpt $2 "
header_destination="${header_destination}$2, "
shift 2
;;
-s)
subject="$2"
shift 2
;;
-b)
body="$2"
shift 2
;;
-a)
attach "$2"
shift 2
;;
-*)
echo "Invalid option: $1"
shift
;;
*)
shift
;;
esac
done
}
build_eml_file()
{
# create header
eml_file=$(mktemp)
echo "MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=\"----7II5XTH4IPXG2QZOY8LJF98QQX4IR3\"
Content-Transfer-Encoding: 8bit
Subject: $subject
From: Easymail <easymail@suckless.nix>
Date: $(date)
To: $header_destination
------7II5XTH4IPXG2QZOY8LJF98QQX4IR3
Content-Transfer-Encoding: 8bit
Content-Type: text/plain;
charset=UTF-8
" >$eml_file
# append body
if [ -f "$body" ]; then
cat "$body" >>$eml_file
else
echo "$body" >>$eml_file
fi
# append attachment(s) if applicable
if [ -f "$attachments_file" ]; then
cat "$attachments_file" >>$eml_file
fi
}
wait_for_internet()
{
while true; do
wget --spider --timeout=2 -o /dev/null duckduckgo.com && return 0
sleep 1
done
}
send_eml_file()
{
curl --url ${host}:${port} --ssl-reqd --upload-file $eml_file $curl_destination --user ${user}:${password} >/dev/null 2>&1
}
if [ "$#" -le 1 ]; then
show_usage
else
main "$@"
fi
Last edited by GNUser (2019-03-29 19:18:41)
Offline