:date: 2011-06-09 10:52 .. role:: strike .. index:: mutt, imap, elinks, tech, linux .. _`2011-mutt_imap_and_elinks`: Mutt, IMAP and elinks ===================== .. image:: /_images/images/gallery/2011/2011-placeholder/20110605-mutt_window.png :scale: 50 :alt: mutt :align: right I spent the last two nights  figuring out how I can set up more than one e-mail account in the `email client mutt `_. For you who ask why spending several hours of  reading manuals and trying different configurations while any other e-mail client would give access within five minutes: Stop reading this article. We do not share any common ground in this topic. By default mutt can be configured for just one e-mail account at a time. If you start it with a different configuration file - no problem. But this is for amateurs and can be achieved within 5 minutes (as mentioned above). What we want is everything at the same time; all at once; all under full control. Mutt ---- So *account-hooks* are the way to go in this scenario. In this example I configured two different accounts on the same IMAP server (on different ones it is easier). Since a couple of descriptions about `configuring gmail accounts `_ `can be found `_ on the Internet, I skip this part and will just point at unspecific IMAP serves. I also spared any password protection functions. .. code:: #.muttrc account1@IMAPserver1 (Email-address1) account2@IMAPserver1 (Email address2) IMAPSERVERADDRESS (address of the imap server) The basic configuration of each account has been stored in separate files in `~/.mutt/accounts`: .. code:: #~/.mutt/accounts/account1.imapserver1 # # Folders for account1@IMAPserver1 # set folder="imap://account1@IMAPserver1@IMAPSERVERADDRESS/" set spoolfile="imap://account1@IMAPserver1@IMAPSERVERADDRESS/" set hostname="IMAPserver1" set folder=imap://IMAPSERVERADDRESS/ set record=+Sent set from="Firstname Secondname" set postponed=+Skisser set realname="Firstname Secondname" .. code:: #~/.mutt/accounts/account2.imapserver1 # # Folders for account2@IMAPserver1 # set folder="imap://account2@IMAPserver1@IMAPSERVERADDRESS/" set spoolfile="imap://account2@IMAPserver1@IMAPSERVERADDRESS/" set hostname="IMAPserver1" set folder=imap://IMAPSERVERADDRESS/ set record=+Sent set from="Firstname Secondname" set postponed=+Skisser set realname="Firstname Secondname" Once this has been done the rest is a piece of cake. .. code:: bash #~/.muttrc # General changes # # # # # # # # # # set date_format = "%Y-%m-%d ,%H:%M:%S" # Mailboxes (the primary one last) mailboxes "imap://account2@IMAPserver@IMAPSERVERADDRESS" "imap://account2@IMAPserver@IMAPSERVERADDRESS" # # Account Hooks # # Reset all variables to start from a know state. account-hook . 'unset preconnect imap_user imap_pass imap_authenticators; set ssl_starttls=ask-yes' # account1@IMAPserver account-hook imap://account1@IMAPserver@IMAPSERVERADDRESS/ '\ set imap_user=account1@IMAPserver \ imap_pass=""' # account2@IMAPserver account-hook imap://account2@IMAPserver@IMAPSERVERADDRESS/ '\ set imap_user=account2@IMAPserver \ imap_pass=""' # # Folder Hooks # folder-hook 'imap://account2@IMAPserver@IMAPSERVERADDRESS' 'source ~/.mutt/accounts/account2.IMAPserver' folder-hook 'imap://account1@IMAPserver@IMAPSERVERADDRESS' 'source ~/.mutt/accounts/account1.IMAPserver' # Choose the first accounts that shall be used at startup source ~/.mutt/accounts/account1.IMAPserver # Other stuff set header_cache ="~/.mutt/cache/headers_$imap_user" set message_cachedir =~/.mutt/cache/bodies set certificate_file =~/.mutt/certificates set smtp_url = "smtp://account1@IMAPserver@SMTPSERVERADDRESS[:PORT]/" set smtp_pass = "" # Annoyances set move = no #Stop asking "more read message to mbox"! set imap_keepalive = 900 set mail_check = 0 # My Editor is VI set editor='vi + -c "set textwidth=72" ' set attribution = "På %d, skrev %n:" # Key Bindings/Macros bind index "^" imap-fetch-mail Limit """"" Instead of searching, you can limit (filter) the index list of mutt and display only the messages of a certain interest. Instead '/' use 'l' (lowercase L). Per default it searches for subject, author and sender e-mailaddresses.  If you are in your sent email folder, this does not help you when you want all mails to a certain recipient. I found the following additional parameters quite helpful: * *~s party* : messages with subject containing "party" * *~d * *~t_ paulm* : To: matches paulm (useful for sent-mail folders) * *~O* : old (i.e. unread but not new) messages. ~N is new unread. ~U is unread, i.e. both together. * *~p* : messages addressed to you (useful if your inbox is bombarded with mailing list or system report activity). * *~p* ~U : for messages to you you have not read yet. * *.* : matches everything. In effect, remove the limit. * *~h Content-Type:.*html* | ~h Content-Type:.*multipart : messages with HTML-attachments | all attachments More in the mutt-documentation, `section 4.2: patterns `_. Switching folders """"""""""""""""" After a while it is getting quite boring, almost annoying to manually switch between often used folders of a account. Switching between *Trash* and *Inbox* and *Send* can really annoy the shit out of you, if you have to to it too often. Instead you can assign key-bindings to perform the necessary actions for you when giving just one or two keystrokes: .. code:: #.muttrc macro index gi "=INBOX" "Go to inbox" macro index gs "=INBOX.Sent" "Go to Sent Mail" macro index gd "=INBOX.Drafts" "Go to drafts" macro index gt "=INBOX.Trash" "Go to Trash" On pressing *gs* (maybe you should press before) mutt switches into the folder for the send mails. Addresses is this folder on IMAP by *INBOX.Sent*. This might not be correct in your case, but you figure out the right folder address when you switch to the folder manually (hopefully for the last time) and then you will see the current address in the bottom line of mutt. ELinks (HTML-Emails) -------------------- For reading :strike:`crappy` HTML emails inside the interface of mutt, two changes are necessary. Using a *.mailcap* file you tell mutt to render all HTML mails as text and display them in *links* or any other console browser you like. If you do not have one already, create a `.mailcap` file in your home directory and put the following lines in it: .. code:: #.mailcap text/html; links %s; nametemplate=%s.html text/html; links -dump %s; nametemplate=%s.html; copiousoutput Now tell mutt to automatically render HTML emails by putting this into your *.muttrc* file: .. code:: #.muttrc auto_view text/html If you get a couple of mails with problems displaying special characters like å, ø, æ. etc, you might consider *W3M* for the mails instead of *links* (or *ELinks*). *Update:* I have replaced *links* with *ELinks* in `~/.mailcap`. Occasionally I get HTML-emails from systems, sending out logs and reports and marking errors with HTML color-tags. Reading them on the console costs much time when you have to try to spot the errors. Of course you could just search within *ELinks* after terms like "*Error*", but that is to obvious. * You need to configure *ELinks* to be able to send the current URL to the external browser. * You need to configure a short cut for this action within *ELinks*. So you do the following to configure *ELinks* * Within *ELinks* you go to *Setup -> Options Manager -> Document -> URI passing*. * There you add an option with a name like *Opera* or *Firefox*. * Edit this option and add the parameter for your Browser, e.g. : `opera -backgroundtab %c`. * Save this edit. * Within *ELinks* you got to *Setup -> Key-binding Manager -> Main Mapping -> Pass URI of current frame to external command*. * Add an option for a shortcut, e.g. *CTRL-o*. * Save this edit. When you now press *+o* within ELinks your configured browser will open (or just open an additional Tab) and display the HTML document. This will edit `~/.elinks/elinks.conf` and add the following lines (if configured with Opera): .. code:: bash #~/.elinks/elinks.conf set document.uri_passing.Opera = "opera -backgroundtab %c" bind "main" "Ctrl-O" = "frame-external-command" Mailcap ------- The small file `.mailcap` is your key to happy life. Mutt checks that file first to see if an attached file you want to open has been specified there and how to open it. Occasionally you stumble over some files or configurations that do not really work out. Another experience you might make is that mutt waits until the started application terminates until you can continue using it. So just opening a PDF out of mutt and at the same time checking another file or email does not really work out. Unless you fork a separate process for it. There are several ways of doing it, but I just implemented `a tiny script `_ which I found `here `_ to do that for me: And it works fine. So instead opening an attached jpg-image with `gthumb `_ like this: .. code:: #~/.mailcap image/jpg; gthumb %s I will do it like this instead: .. code:: # ~/.mailcap image/jpg; mutt_bgrun gthumb %s *mutt_bgrun* needs to be available within the *$PATH* otherwise it is not gonna be found. Encrypt Passwords ----------------- As known the passwords can be stored directly into the configuration file `~/.muttrc`. And as also known this should not be the way to do it, since simple access to this file would grant all access to the whole e-mail folder. One way to fix this *security-issue* is to store the passwords encrypted in a GPG file and *source* it directly into the configuration file. That way Mutt will ask when coming up for a password to decrypt the file. This will not be the password for the e-mail account, but the password for the pgp file. That way no password is stored in plain text on the local disk. * Create a text-file with the two parameters for defining the password in it: .. code:: # ~/.mutt/.muttrc.pw set imap_pass="password" set smtp_pass="password" * Encrypt the file with your *pgp/gpg* key: .. code:: bash $ gpg -r 'gpgid' -e ~/.mutt/muttrc.pw $ ls ~/.mutt/.muttrc.pw* /home/user/.mutt/.muttrc.pw /home/user/.muttrc.pw.gpg * Shred the plain-text file and delete it safely. .. code:: bash $ shred ~/.mutt/.muttrc.pw $ rm ~/.mutt/.muttrc.pw The remaining file `~/.mutt/.muttrc.pw.gpg` is a binary and encrypted file that contains the parameters necessary for including them into the source-file. That file now needs to be imported into the mutt configuration file `~/.mutt/.muttrc` .. code:: # ~/.mutt/.muttrc source "gpg -d ~/.mutt/.muttrc.pw.gpg \|" This will decrypt and import the encrypted file into the configuration file while reading it when Mutt fires up. The pipe at the end of the command is necessary for redirecting the output back to mutt. When you now fire up Mutt you are gonna be asked for your pass-phrase for the PGP/GPG file once. As long Mutt is running it will grant you access to the file and you can send and receive e-mails as usual. If you want to go even further search for information how to connect the *gpg-agent* to mutt. Sending E-Mails as attachment ----------------------------- Occasionally I have to send e-mails attached to another email. This happens when I need to send some diagnostic e-mails the some vendor for instance. This is no problem at all if you know how to do it (and if you think about it) #. Write your e-mail as usual. #. Instead of lowercase *'a'* you use the uppercase *'A'* this time for attaching. #. Mutt will open your mailbox and you tag the messages you want to attach with *'t'*. #. Leave the attachment-dialog with *'x'*. #. Send. Forwarding attachments ---------------------- When forwarding an e-mail, mutt tends to only forward the message part, but leave the attachments behind. This is actually considered to be the correct behavior, since you are forwarding usually exactly what is currently on the screen. There are other convenient ways, to include the whole email into the forward, not only the currently displayed part. #. Way: #. Type `v` to get to the attachments screen. #. Type `t` repeatedly to tag all the attachments, including the initial small text/plain attachment (that is the original message body). #. When they are all tagged, type `;f` (forward all tagged attachments). After you fill in the *To:* prompt, you will be able to edit the message body, and when you leave the editor, you will have the attachment list there to edit as you see fit. #. Way: If that does not work (I have not tried it on HTML messages), there is a slightly more elaborate procedure: #. Use `Esc-e` (resend-message), basically use the current message as a template for a new one. This calls up an editor on the current message, including headers. #. Change the *From* to your name, the *To* to your intended recipient, and edit the message body to your hearts content. When you are done, you are being sent to the Compose screen, where you can adjust the attachment list and send the message. Forwarding is pretty clearly not what Esc-E was intended for ... but it does the job and might be a handy trick to know. `Source `_ Attachments, piping ------------------- Since we are already talking about attachments here: you can just pipe them as anything else (like the email, e.g.) to any command you like. So you can extract compress files on the file and save on step * Key: | * Command for a tar file to extract: .. code:: Pipe to: tar -C ~/ -x URLS ---- For opening URLS just install `urlview`: .. code:: bash $ sudo apt-get install urlview Then just *CRTL+b* will open the URL in your browser (or all URLS available you choose the one) Spellchecking ------------- Let's just add some spellchecking to the mutt/vim editor. Somewhere in my `.muttrc` or in one of the source-ed files I add the following line: .. code:: bash #.muttrc set editor="vim -c 'set spell spelllang=nb,en,de' -c 1 -c 'set textwidth=72'" Here are three parameters set. For the spellchecking only the first one is relevant. Supported languages are set to *nb*, *en* and *de*. If the dictionaries for the languages are missing, VIM will ask to download them and store them under `~/.vim`. This since change only is in the `.muttrc` and not in the VIM configuration file, this will not apply to all the other files we might edit with VIM (like configuration files). Unknown or misspelled files are highlighted. In case we want to add a file to the spellchecking library/file, just put the cursor over the word, go in *command*-mode and type *zg*. This will put the word into the spellchecking-file, usually placed in `~/.vim/spell/.utf-8.add` (you might want to put those files under your sync solutions to keep them aligned across your systems). If you want to actually correct the word from the suggestions the command *z=* gives you a selection of suggestions.