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 USB stick (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 USB stick 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:
(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 USB stick 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 USB stick.
#!/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.