add fallback (grep) solution, pretty obsolete
authorJohannes Weißl <jargon@molb.org>
Mon, 26 Apr 2010 22:17:49 +0000 (00:17 +0200)
committerJohannes Weißl <jargon@molb.org>
Mon, 26 Apr 2010 22:17:49 +0000 (00:17 +0200)
This was the first version, maybe it is useful to someone...

muttjump_fallback [new file with mode: 0755]

diff --git a/muttjump_fallback b/muttjump_fallback
new file mode 100755 (executable)
index 0000000..6e8b6e0
--- /dev/null
@@ -0,0 +1,106 @@
+#!/bin/bash
+# written by Johannes Weißl
+
+# muttjump_fallback
+#
+# This is a fallback solution for muttjump which doesn't use any mail
+# indexer to find the original mail (which is of course way slower in
+# most cases).
+#
+# This requires two folder-hooks in .muttrc:
+#
+# # hack: set my_cwd to current folder path, abusing $record
+# # todo: better solution?
+# folder-hook . 'set my_backup_record=$record ; set record=^ ; set my_cwd=$record ; set record=$my_backup_record'
+
+# # set macro for jumping to original message
+# # needs to be set for every folder after my_cwd (see above) has been set
+# # todo: better solution?
+# folder-hook . 'macro generic ,J "<enter-command>push <pipe-message>\"muttjump_fallback $my_cwd $folder\"<enter><enter>" "jump to original message"'
+
+# program paths
+MUTT=${MUTT:-mutt}
+
+function die () {
+    echo -e >&2 "$0: $1"
+    exit 1
+}
+
+# Check command-line arguments and STDIN
+if tty -s || [ $# -gt 2 ] || [ $# -lt 1 ] ; then
+    cat >&2 <<END
+Usage: $0 virtual-maildir [folder] < msg
+
+This script calls mutt, jumping to the message given in stdin.
+It uses grep to search for the messages in "virtual-maildir" (a maildir
+containing only symbolic links), and finds out the target through readlink.
+If "virtual-maildir" contains shortcuts like '=', "folder" can be given for
+expansion.
+END
+    exit 1
+fi
+
+# check if mutt is installed
+if ! type -p $MUTT >/dev/null ; then
+    die "$MUTT is not in PATH, set MUTT variable"
+fi
+
+# search for Message-ID in STDIN
+tmpfile=$(mktemp)
+msgid_line=$(tee "$tmpfile" | grep -i '^Message-ID: ' | head -n1)
+msgid=$(echo "$msgid_line" | sed -n 's/^[^:]*: \(.*\)/\1/p')
+msgsize=$(wc -c "$tmpfile")
+rm -f "$tmpfile"
+
+if [ -z "$msgid" ] ; then
+    die "could not find Message-ID header in standard input"
+fi
+msgid_clean=$(echo "$msgid" | sed 's/^<\(.*\)>$/\1/')
+
+maildir=$1
+
+# If $folder is given as second argument, replace "+" or "=" in $maildir
+if [ $# -gt 1 ] ; then
+    folder=$2
+    maildir=$(echo "$maildir" | sed "s@^[+=]@$folder/@")
+fi
+
+if [ ! -d "$maildir/cur" ] ; then
+    die "directory \"$maildir\" doesn't exist or is no Maildir"
+fi
+
+# grep for Message-ID in the current Maildir
+# TODO: This is definitely not what we want, but there seems to be no way
+# to pass the filename of the currently selected mail to an external
+# program, as this is dependent on the folder format.
+num_files=$(ls -1 "$maildir"/cur/ | wc -l)
+if [ $num_files -ge 100 ] ; then
+    echo "Grepping through $num_files messages, this could take a while!"
+fi
+msgfile=$(grep -HlFx "$msgid_line" "$maildir"/cur/* | head -n1)
+if [ -z "$msgfile" ] ; then
+    die "could not find Message-ID in maildir:
+  grep -HlFx \"Message-ID: $msgid\" \"$maildir\"/cur/*"
+fi
+
+# find out original message-file of linked message
+orig_msgfile=$(readlink "$msgfile")
+if [ -z "$orig_msgfile" ] ; then
+    die "message \"$msgfile\" is no link to another message, aborting!"
+fi
+
+# get containing maildir of $orig_msgfile
+orig_maildir=$(dirname $(dirname "$orig_msgfile"))
+if [ ! -d "$orig_maildir/cur" ] ; then
+    die "directory \"$orig_maildir\" doesn't exist or is no Maildir"
+fi
+
+# Close message-stdin and open terminal-stdin instead.
+# mutt behaves different if STDIN is no terminal
+# TODO: Find cleaner solution (e.g. mutt command-line argument?)
+exec 0<&-
+term="/dev/$(ps -p$$ --no-heading | awk '{print $2}')"
+exec < $term
+
+# start mutt, open original folder and jump to the original message
+$MUTT -e "push <change-folder>$orig_maildir<enter><search>\"~i $msgid\"<enter>"

Benjamin Mako Hill || Want to submit a patch?