StripAttach

A quick and dirty script to strip, save and compress attachments from a MIME message arriving to the standard input. The attachments are replaced with URL information and the processed message is then dumped to stdout. This makes a good use as a procmail filter to keep down mailbox sizes. Also can be a good starting base to achieve single attachment storage on large servers with many users.

#!/bin/bash
#
# stripattach - a quick and dirty script to strip, save and compress attachments
# from a MIME message arriving to the standard input. The attachments are replaced
# with URL information and the processed message is then dumped to stdout. This
# makes a good use as a procmail filter to keep down mailbox sizes. Also can be a good
# starting base to achieve single attachment storage on large servers with many users.
#
# Hacked together by Erno Rigo <mcree@tricon.hu> at 2005-10-05
#
# Licensed under the GPLv2
#
 
# directory to save attachments to:
savedir=`mktemp -d -p /home/mcree/public_html/attachments attach.XXXXXX`
chmod 0755 "$savedir"
 
# directory accessible via URL:
savedir_web="http://www.tricon.hu/~mcree/attachments/"`basename "$savedir"`
 
###############################################################################
# don't touch anything below this line (unless you know what you do)
###############################################################################
 
# sanity checks
for req in tac sgrep ripmime gzip expr mktemp dd; do
    if ! command -v $req 2>&1 1>/dev/null; then
	echo -e "\nthis script requires $req to operate properly!\n"
	exit 0
    fi
done
 
# read stdin to temporary workpad file
file=`mktemp`
cat > $file
 
boundaries=`cat $file | grep '^--.*--$'`
 
echo -e "$boundaries" | while read boundary; do
 
    bnd=`echo "$boundary" | rev | cut -b 3- | rev`
 
    #echo "BND:";echo -e "$bnd"
 
    part=`mktemp`
 
    # search for attachments for this boundary
    lastend=0
    cat $file | sgrep -o "%s,%e,%l\n" 'inner("'$bnd'".."'$bnd--'") containing "Content-Disposition: attachment"' | tac | while read pos; do
	# extract attachments (in reverse order) belonging to this boundary
 
	#echo $pos
	posstart=`echo $pos | cut -f1 -d','`
	posend=`echo $pos | cut -f2 -d','`
	posend=`expr $posend + 1`
	poslen=`echo $pos | cut -f3 -d','`
 
	# save attachment
	attach=`mktemp`
	attachdir=`mktemp -d`
	dd if=$file of=$attach skip=$posstart count=$poslen bs=1 2>/dev/null
	ripmime -i $attach -d $attachdir
	gzip -9 $attachdir/*
	filename=`ls -1 $attachdir`
	cp "$attachdir/$filename" "$savedir"
	#cat $attach
	rm -rf $attachdir
	rm -f $attach
 
	# rip attachment from e-mail
	tmpfile=`mktemp`
	tmphead=`mktemp`
	tmptail=`mktemp`
	dd if=$file of=$tmphead count=$posstart bs=1 2>/dev/null
	dd if=$file of=$tmptail skip=$posend bs=1 2>/dev/null
 
	cat $tmphead >> $tmpfile
	echo -e "$bnd\nContent-Type: text/plain;\n\n attachment removed\n file saved as: $savedir/$filename\n file can be accessed as: $savedir_web/$filename\n\n$bnd--" >> $tmpfile
	cat $tmptail >> $tmpfile
 
	cp $tmpfile $file
 
	rm -f $tmpfile
	rm -f $tmphead
	rm -f $tmptail
 
    done 
 
    rm -f $part
 
done
 
cat $file
 
rm -f $file