#!/bin/sh # # mime_helper -- help MH display MIME attachments # # Steven Winikoff # 2009/04/17 # 2018/01/13 -- rewrite for nmh-1.7 # # This is intended to be invoked from .mh_profile, with entries similar to # this one: # # mhshow-show-application: %pmime_helper %F %s "%{name}" # # where the % escapes are interpreted as follows (see mhshow(1) for # details): # # %F exclusive execution, insert filename containing content, and # stdin is terminal not content # # %s Insert content subtype # # for example, here are some sample values of these strings: # # %F = /home/smw/Mail/mhshowk4vGey.pdf # %s = pdf # # %F = /home/smw/Mail/mhshowyME4Gs.docx # %s = vnd.openxmlformats-officedocument.wordprocessingml.document # # %F = /home/smw/Mail/mhshowxQPJe6.xlsx # %s = vnd.openxmlformats-officedocument.spreadsheetml.sheet # # %F = /home/smw/Mail/mhshowpW8QGd # %s = vnd.ms-powerpoint # # %F = /home/smw/Mail/mhshowwRBwpH.jpeg # %s = jpeg # # %F = /home/smw/Mail/mhshowTs8Yaf.gif # %s = gif # # %F = /home/smw/Mail/mhshowtXWO8m.png # %s = png # # %F = /home/smw/Mail/mhshowuQrPmF # %s = octet-stream # [ file reports # "Composite Document File V2 Document, Little Endian, Os: # Windows, Version 5.1, Code page: 1252, Title: PLAYLIST # APRIL 18 ,2009, Author: lou, Template: Normal, Last Saved # By: lou, Revision Number: 10, Name of Creating Application: # Microsoft Word 8.0, Total Editing Time: 04:07:00, Create # Time/Date: Thu Apr 16 16:35:00 2009, Last Saved Time/Date: # Thu Apr 16 23:52:00 2009, Number of Pages: 1, Number of # Words: 923, Number of Characters: 5264, Security: 0" # ] # # note that this script (intentionally) leaves unpacked attachments # in /tmp/attachments on the machine where the attachment is opened; # these should be cleaned either manually or via cron (eg from # /local/misc/daily_cleaner) # #-------------------------------------------------------------------------- # basic setup: trace=0 ruler="+------------------------------------------" ruler="${ruler}-----------------------------------" attach_dir="/tmp/attachments" user="${USER-smw}" scp_options="-p -r -B -o ForwardAgent=no -o ForwardX11=no" decoder="${SMW}/bin/rfc2047decoder" MH_top=`mhpath +` #-------------------------------------------------------------------------- # shell function to try to guess a file's type based on the output # of file(1); this is needed only when we don't receive a useful # subtype from the message -- and nobody will be surprised to learn # that this usually happens with Microsoft software :-/ guess_file_type() { echo echo "$1" | cut -d/ -f2 } #-------------------------------------------------------------------------- # are we connected locally or remotely? ("yes" :-) this_host=`hostname` desktop="${ORIGINATING_HOST}" [ -z "${desktop}" -o "${desktop}" = ${this_host} ] && desktop="${REMOTEHOST}" local=0 [ -z "${desktop}" -o "${desktop}" = ${this_host} ] && local=1 #-------------------------------------------------------------------------- # grab command line parameters: case "$1" in -i*) #-- special case: invoked directly by mhread for an HTML message, # bypassing mhshow entirely; in this case, the first argument will # always be either -il or -ia (and in either case, should be passed # on to view_html_message), and the last argument will always be # the full path of the message to be viewed imgs="${1}" # -il or -ia for i in $@; do sourcefile="${i}"; done # last cmd line argument subtype="html" filename="`echo ${sourcefile} | sed s%${MH_top}/%%\;s%/%_%g`" file_output="text/html" ;; *) sourcefile="$1" # mhshow %F subtype="$2" # mhshow %s filename="$3" # mhshow "%{name}" file_output=`file --brief --mime-type "$1"` ;; esac #-------------------------------------------------------------------------- # strip out all \ characters in the content filename, along with leading # and trailing ' characters; also consolidate any remaining runs of # ' characters into one single ': filename="`echo \"${filename}\" | tr -d '\134' | \ sed -r 's/^'"'"'*//;s/'"'"'*$//;s/'"'"'+/'"'"'/g'`" #-------------------------------------------------------------------------- # decode the content filename if appropriate: prefix=`echo "${filename}" | cut -c1-2` if [ "${prefix}" = "=?" ] then #-- yes, this filename was encoded in RFC 2047 format; decode it: charset=`echo "${filename}" | cut -d'?' -f2 | tr A-Z a-z` filename=`echo "${filename}" | ${decoder}` #-- and translate to utf-8 if it isn't already: if [ "${charset}" != "utf-8" ] then filename=`echo "${filename}" | iconv -f "${charset}" -t utf-8` fi fi #-------------------------------------------------------------------------- # strip out any leading and trailing spaces: filename="`echo \"${filename}\" | sed 's/^ *//;s/ *$//'`" #-------------------------------------------------------------------------- # figure out what type of file we have, and by extension (pun unintended, # for a change :-), which application we need to open it: case "${subtype}" in x-awk) subtype="`guess_file_type \"${file_output}\"`" ;; octet-stream) subtype="`guess_file_type \"${file_output}\"`" ;; download) subtype="`guess_file_type \"${file_output}\"`" ;; unknown) subtype="`guess_file_type \"${file_output}\"`" ;; esac subtype=`echo "${subtype}" | tr A-Z a-z` case "${subtype}" in *htm*) app="view_html_message ${imgs}" ;; *bmp*) app="/usr/bin/xviewer -n" ;; *gif*) app="/usr/bin/xviewer -n" ;; *jpeg*) app="/usr/bin/xviewer -n" ;; *jpg*) app="/usr/bin/xviewer -n" ;; *jpeg*) app="/usr/bin/xviewer -n" ;; *png*) app="/usr/bin/xviewer -n" ;; *tiff*) app="/usr/bin/xviewer -n" ;; *m4a*) app="/usr/bin/vlc" ;; *mov*) app="/usr/bin/vlc" ;; *mp*4*) app="/usr/bin/vlc" ;; *mp3*) app="/usr/bin/vlc" ;; *mpeg*) app="/usr/bin/vlc" ;; *quicktime*) app="/usr/bin/vlc" ;; *wav*) app="/usr/bin/vlc" ;; *wmv*) app="/usr/bin/vlc" ;; *pdf*) app="/usr/bin/atril" ;; # was evince, xreader *.ps*) app="/usr/bin/atril" ;; # was gv -media=letter *tnef*) app="unpack_losemail_dat" ;; # was tnef -f *zip*) app="file-roller" ;; *composite*) app="soffice" ;; *csv*) app="soffice" ;; *doc*) app="soffice" ;; *excel*) app="soffice" ;; *icrosoft*) app="soffice" ;; *powerpoint*) app="soffice" ;; *openxml*) app="soffice" ;; *pps*) app="soffice" ;; *ppt*) app="soffice" ;; *rtf*) app="soffice" ;; *vnd.ms*) app="soffice" ;; *vsd*) app="soffice" ;; *word*) app="soffice" ;; *xls*) app="soffice" ;; *calendar*) app="calendar_extract" ;; *vCalendar*) app="calendar_extract" ;; *ics) app="calendar_extract" ;; *txt) app="more" ;; *plain) app="more" ;; *) app="UNKNOWN" ;; esac #-------------------------------------------------------------------------- # trace what's going on: if [ ${trace} -gt 0 ] then echo echo "** \$1 (%F) = [${sourcefile}]" echo "** \$2 (%s) = [${subtype}]" echo "** \$3 (%name) = [${filename}]" echo "** \`file\` = ${file_output}" echo "** subtype = [${subtype}]" echo "** app = ${app}" echo echo "(see mhshow(1), mhlist(1) and ~/.mh_profile)" fi [ ${trace} -gt 1 ] && exit 0 #-------------------------------------------------------------------------- # bail out if we can't recognize this file type: if [ "${app}" = "UNKNOWN" ] then echo "${ruler}" echo "| unrecognized attachment type; details are as follows:" echo "|" echo "| \$1 (%F) = [$1]" echo "| \$2 (%s) = [$2]" echo "| \$3 (%name) = [$3]" echo "| subtype = [${subtype}]" echo "|" echo "| file reports: ${file_output}" echo "|" echo "| edit $0 to recognize this file type in future" echo "${ruler}" exit 2 fi #-------------------------------------------------------------------------- # finally, open the file: # # text and calendar attachments are viewed in the foreground on the # local machine, but all other file types are opened in the background; # this allows nmh to continue on its way without having to wait for the # user to close the application if [ "${subtype}" = "txt" -o "${subtype}" = "plain" ] then ${app} "${sourcefile}" echo elif [ "${app}" = "calendar_extract" ] then echo "${ruler}" ${app} < "${sourcefile}" else #-- we need the basename of the file to copy into the attachments # directory; we also want to add an extension, but only if the # basename doesn't already include one: base="${filename}" [ -z "${base}" ] && base="`basename \"${sourcefile}\"`" nosuffix=`echo "${base}" | sed 's/\..*//'` [ "${base}" = "${nosuffix}" ] && base="${base}.${subtype}" #-- construct the full pathname to which the attachment will be copied: target="${attach_dir}/${base}" #-- are we displaying this attachment locally? if [ ${local} -gt 0 ] then #-- yes, we're on the local desktop machine; the required helper # application can run directly: echo echo "${ruler}" echo "| copying ${sourcefile}" echo "| to ${target}" cp -p "${sourcefile}" "${target}" echo "|" echo "| opening ${target}" echo "| with ${app}" echo "${ruler}" ${app} "${target}" > /dev/null 2>&1 & else #-- we're in an ssh session from a remote desktop machine, so first # we have to copy the file to the remote desktop, then start the # application there via ssh: echo echo "${ruler}" echo "| copying ${sourcefile}" echo "| to ${desktop}:${target}" scp ${scp_options} "${sourcefile}" \ ${user}@${desktop}:"\"${target}\"" echo "|" echo "| opening ${target} remotely" echo "| with ${app}" echo "${ruler}" ssh -nY -l ${user} ${desktop} \ "setenv DISPLAY :0;${app} \"${target}\"" > /dev/null 2>&1 & fi fi