I'm currently without internet connection to my own computer, and I've been working out ways to make send and receiving e-mail as seamless as possible. I thought I'd document my procedure, with scripts, for those who find themselves in the same predicament.
Thankfully, although the machines I'm using to connect to the net are Windows machines, I do have access to a Linux box that is connected to the net with an ssh account I can log in to. Here is my setup for e-mail:
Sending
I'm still using KMail for composing and sending e-mail. I've set up a 'sendmail' item for sending, but pointed it at my own python script, which, instead of attempting to send the e-mail, saves it as a file on a folder in my MP3 player (or complains if I've forgotten to plug it in). Here is the script:
#!/usr/bin/python
# Dump stdin in a file with unique name
from datetime import datetime
import operator
import sys
import os
import random
from copy import deepcopy
import itertools
DUMPDIR = '/media/sda1/mail/outgoing'
def mk_filename():
"Creates a unique filename"
return (reduce(operator.add,
[chr(random.randint(ord('A'), ord('Z'))) for i in xrange(0,10)]) \
+ '.' + datetime.isoformat(datetime.now())).replace(':','_')
def dump_file(recips):
if len(recips) == 0:
print "No recipients found."
sys.exit(1)
fname = mk_filename()
fn = os.path.join(DUMPDIR, fname + ".msg")
fp = open(fn, 'w')
for line in sys.stdin:
fp.write(line)
fp.close()
fn2 = os.path.join(DUMPDIR, fname + ".recips")
fp2 = open(fn2, 'w')
fp2.write(' '.join(recips))
fp2.close()
def prompt_for_continue():
prompt = "Cannot find directory %s for saving mail. " \
"Create directory or mount device and press 'Continue', " \
"or cancel." % (DUMPDIR,)
exit_status = os.system('kdialog --warningcontinuecancel "%s"' % prompt)
return exit_status == 0
def check_dir_and_dump(recips):
if not os.path.isdir(DUMPDIR):
if prompt_for_continue():
check_dir_and_dump()
else:
sys.stderr.write("Cancelled.")
sys.exit(1)
else:
dump_file(recips)
# For BCC, have to read recipients from command line,
# and then for simplicity create separate files for each, with a
# 'To' header added
def get_recipients():
recipients = deepcopy(sys.argv)
recipients = recipients[1:] # name of this shell script
cont = True
i = 0
while (cont):
if i >= len(recipients):
cont = False
else:
if recipients[i] == '-i':
recipients.pop(i)
else:
if recipients[i] == '-f':
recipients.pop(i)
recipients.pop(i)
else:
i += 1
return recipients
check_dir_and_dump(get_recipients())
os.system('sync')
Then, on the machine that is connected it to the internet, which I'll use perhaps once a day, I transfer the files from my MP3 player to my Linux box on the net via ftp. I also log in via ssh, using PuTTy, and run a script with sends all the emails in the 'outgoing' folder, deleting them if successful. To send these e-mails, I use 'msmtp', which can easily be downloaded, compiled and installed locally:
./configure --prefix=~/local && make && make install
(Needs ~/local to exist, probably, and needs ~/local/bin on your path to use the installed binary.)
Then, the script to send all the e-mails is just something like:
#!/bin/bash
cd $HOME
for TMP in ~/lp/mail/outgoing/*.msg;
do
echo $TMP
RECIPFILE=${TMP%%.msg}.recips
RECIPS=$(cat $RECIPFILE);
msmtp $RECIPS < $TMP || exit 1;
rm $TMP $RECIPFILE
done
(once you've created a config file for msmtp).
Receiving
Currently, I check my e-mail using Fastmail's web interface, and at that point deal with all the spam, and delete other e-mail that there is no point transfering, and answer some e-mails. What needs to be transfered goes into my 'received' folder, and you can then use Fastmail's 'Archive' feature to take all the e-mails in a folder and download them as a zip file. This zip file is saved back onto my MP3 player in a specific folder, and taken back to my computer.
Once on my computer, I have another script which imports all the e-mail in that folder into KMail, removing them from the MP3 player.
#!/bin/bash
# Attempt to import all files on removable device into KMail
INCOMING_DIR=/media/sda1/mail/incoming
EXTRACT_DIR=/home/luke/download/mail
die_loudly() {
# kdialog --error "$1"
echo "$1"
echo
exit 1
}
ps ax | egrep 'kontact|kmail' > /dev/null || { die_loudly "KMail isn't running, can't import messages" ; }
if [ \! -d "$INCOMING_DIR" ]
then
die_loudly "$INCOMING_DIR cannot be found"
fi
if [ \! -d "$EXTRACT_DIR" ]
then
die_loudly "$EXTRACT_DIR cannot be found"
fi
mv $INCOMING_DIR/*.zip $EXTRACT_DIR || die_loudly "Can't move files from device"
cd $EXTRACT_DIR
unzip -o *.zip
for FILE in *.eml
do
echo dcop kmail KMailIface dcopAddMessage "inbox" \"file://$PWD/$FILE\" ""
retval=`dcop kmail KMailIface dcopAddMessage "inbox" "file://$PWD/$FILE" ""`
if [ $? -ne 0 ]
then
die_loudly "Failed to import $FILE"
fi
if [ $retval -ne 1 ]
then
die_loudly "Failed to import $FILE"
fi
rm "$FILE"
done
rm $EXTRACT_DIR/*.zip
I normally run this from a console (Yakuake, to be precise, which is only ever 'F12' away), so I can see any error messages. Otherwise I'd change the 'die_loudly' function to use kdialog.
This is of course quite a bit of a faff, but it's doable. The methods and scripts are robust against forgetting to do it some days. If I wasn't using Windows boxes for connecting to the net, or if it was always the same box and I was allowed to install any software on, things would be better. As it is, 'PuTTy', which is a single, small executable, is the only thing I have to carry around with me. Also, if for whatever reason I'm reduced to only the web interface of Fastmail, I'm OK -- the Linux box isn't periodically retrieving my mails by POP or anything like that, and I only need it for sending e-mails I've prepared on my own machine.
UPDATED: Fixed scripts to handle BCC and other recipients that are passed only on the sendmail commandline.