Building Mutt-KZ with GPGME support

1 Get the source from github

git clone git@github.com:karelzak/mutt-kz.git

2 Dependencies

$ sudo yum install slang-devel openssl-devel cyrus-sasl-devel tokyocabinet-devel

3 Compile

Configure, you'll need to resolve a bunch of dependencies

$ ./prepare --with-slang --with-regex --with-sasl --with-ssl --enable-locales-fix --enable-pop --enable-imap --enable-smtp --enable-hcache --enable-hcache --enable-gpgme --enable-exact-address

and make

$ make
...
$ ldd ./mutt
	linux-vdso.so.1 =>  (0x00007fffb8bfe000)
	libncursesw.so.5 => /lib64/libncursesw.so.5 (0x0000003d23800000)
	libtinfo.so.5 => /lib64/libtinfo.so.5 (0x0000003d39200000)
	libssl.so.10 => /lib64/libssl.so.10 (0x00000031ce400000)
	libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00000031cd000000)
	libz.so.1 => /lib64/libz.so.1 (0x0000003d21c00000)
	libsasl2.so.3 => /lib64/libsasl2.so.3 (0x0000003d3d800000)
	libtokyocabinet.so.9 => /lib64/libtokyocabinet.so.9 (0x0000003d23400000)
	libgpgme.so.11 => /lib64/libgpgme.so.11 (0x0000003d26000000)
	libc.so.6 => /lib64/libc.so.6 (0x0000003d20c00000)
	libdl.so.2 => /lib64/libdl.so.2 (0x0000003d21400000)
	libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00000031cdc00000)
	libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00000031cd400000)
	libcom_err.so.2 => /lib64/libcom_err.so.2 (0x0000003d29c00000)
	libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00000031ce000000)
	libresolv.so.2 => /lib64/libresolv.so.2 (0x0000003d23000000)
	libcrypt.so.1 => /lib64/libcrypt.so.1 (0x0000003d33c00000)
	libbz2.so.1 => /lib64/libbz2.so.1 (0x0000003d2e400000)
	librt.so.1 => /lib64/librt.so.1 (0x0000003d22000000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003d21000000)
	libm.so.6 => /lib64/libm.so.6 (0x0000003d21800000)
	libassuan.so.0 => /lib64/libassuan.so.0 (0x0000003d4d200000)
	libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x0000003d38e00000)
	/lib64/ld-linux-x86-64.so.2 (0x0000003d20800000)
	libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00000031cd800000)
	libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x0000003d2a800000)
	libfreebl3.so => /lib64/libfreebl3.so (0x0000003d2e800000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003d22c00000)
	libpcre.so.1 => /lib64/libpcre.so.1 (0x0000003d22800000)

Then copy mutt and pgpewrap into /opt (or another location).

4 Configuration to use with GMAIL

4.1 ~/.muttrc

Edit and configure to your needs. The password to IMAP/SMTP must be stored in cleartext in ~/.mutt/gmail_password .

set realname            =  "Julien Vehent"
set from                =  "Julien Vehent <jvehent@mozilla.com>"
set hostname            =  "mozilla.com"
set use_from            =  yes

set smtp_url            =  smtps://jvehent@mozilla.com@smtp.gmail.com:465
set imap_pass           =  `cat  ~/.mutt/gmail_password`
set smtp_pass           =  `cat ~/.mutt/gmail_password`
set imap_user           =  "jvehent@mozilla.com"
set ssl_force_tls       =  yes

# set the header we always want to see
set envelope_from       =  yes
set reverse_name        =  yes
ignore *
unignore Date: From: To: Cc: Reply-To: Subject: Mail-Followup-To:
hdr_order Date: From: To: Cc: Reply-To: Subject: Mail-Followup-To:
set editor      =  "vim +13 -c 'set noautoindent' -c 'set wrap' -c 'set spell'"
set edit_headers        =  no
set include             =  yes
set markers             =  no
set fast_reply          =  yes
set pager_index_lines   =  10
set pager_context       =  3
set meta_key            =  yes
set menu_scroll

set index_format        = "%4C %Z %{%b %d %H:%M:%S} %-20.20L [%5c] %s"
set alias_format        = "%2n %t %-20.20a: %r"
set attach_format       = "%2n %D%I%u%t %T%f %d (%s) (%m/%M, %e, %C)"
set compose_format      = "Compose %h [Approx. msg size: %l, Atts: %a] %v %>-"
set date_format     = "!%a %e.%h'%y at %k:%M:%S %Z"
set folder_format       = "[%N] %d (%10s) %f"
set message_format      = "From: <%a>, Sub: %s"
set pager_format        = "%Z %C/%m %d (%F) %s (%c/%l) %|-"
set pgp_entry_format= "%3n %t%f %4l/0x%k %-4a %2c %u %[%a %e.%h'%y at %k:%M:%S %Z]"
set status_format       = "_%r_ %h: %f, %l/%m (%P,%s) [ %?p?PP:%p ?%?t?Tag:%t ?%?d?DEL:%d ?]%?V?, %L/%M only    = %V? < %?F?go:%F ?%?n?new:%n ?> %v"
#

# include color theme
source ~/.mutt/colors-solarize


# sidebar
set sidebar_width       = 32
set sidebar_visible     = yes
#set sidebar_shortpath  = yes
#set sidebar_sort       = yes
# alt-n, alt-p to select next, prev folder
# alt-o to open selected folder
bind index,pager \ep  sidebar-prev
bind index,pager \en  sidebar-next
bind index,pager \eo  sidebar-open

# some custom bindings
bind index,pager \ej  next-unread
bind index backspace previous-page

set folder      = "imaps://jvehent@mozilla.com@imap.gmail.com"
set spoolfile   = "imaps://jvehent@mozilla.com@imap.gmail.com/INBOX"
set mbox        = +Inbox                           # Default mailbox.
set spoolfile   =  "+INBOX"
set record      =  "+INBOX"
set postponed   =  "+Drafts"
set nostrict_threads                      # Lets have some fuzzy threading.
set sort        = threads
set sort_browser= reverse-date
set sort_aux    = last-date-received
set beep_new
set quote_regexp        = "^( {0,4}[>|:#%]| {0,4}[a-z0-9]+[>|]+)+"
set postpone            = ask-no                       # Ask about postponing.
unset imap_passive
set imap_check_subscribed
set mail_check          = 30
set imap_keepalive      = 30
set timeout             = 10
set net_inc             = 5
set header_cache        =  "~/.mutt/imap-mozilla-cache"
set message_cachedir=  "~/.mutt/imap-mozilla-message"

## Safe deletion macros apply for all folders, EXCEPT the 'deleted' folder.
## "Y" is set to 'unsafe delete' (useful over slow imap links).
## Also note the slight difference between 'index' and 'pager' for thread
## delete. The "\ni" will cause mutt to briefly switch to pager mode and
## back to index, causing the thread to uncollapse. It's a trick but as
## a trick goes, it works really well (for me, at least) :)
# source http://www.paganini.net/index.cgi/mutt/mutt01_safe_delete.html
bind  index   y   delete-message
bind  pager   y   delete-message
folder-hook . 'macro index d  <copy-message>=Trash\ny<delete-message>  "Safe Delete"'
folder-hook . 'macro pager d  <copy-message>=Trash\ny<delete-message>  "Safe Delete"'
folder-hook . 'macro index \ed \ni<tag-thread><copy-message>=Trash\ny<delete-message> "Safe delete Thread"'
folder-hook . 'macro pager \ed <tag-thread><copy-message>=Trash\ny<delete-message>    "Safe delete Thread"'
## Really erase if we're using the 'deleted' mail folder.
folder-hook 'deleted' 'macro index d   <delete-message> "Delete Message"'
folder-hook 'deleted' 'macro index \ed <delete-thread>  "Delete Thread"'
folder-hook 'deleted' 'macro pager d   <delete-message> "Delete Message"'
folder-hook 'deleted' 'macro pager d   <delete-message> "Delete Message"'

# Move message to nightwatch folder
folder-hook . 'macro index n  <copy-message>=Nightwatch\ny<delete-message>  "Move to Nightwatch"'
folder-hook . 'macro pager n  <copy-message>=Nightwatch\ny<delete-message>  "Move to Nightwatch"'

# Move message to nightwatch folder
folder-hook . 'macro index o  <copy-message>=OpSec\ny<delete-message>  "Move to OpSec"'
folder-hook . 'macro pager o  <copy-message>=OpSec\ny<delete-message>  "Move to OpSec"'

# Move message to "everyone" folder
folder-hook . 'macro index e  <copy-message>=everyone\ny<delete-message>  "Move to everyone"'
folder-hook . 'macro pager e  <copy-message>=everyone\ny<delete-message>  "Move to everyone"'

# Move message to infra folder
folder-hook . 'macro index i  <copy-message>=infra\ny<delete-message>  "Move to infra"'
folder-hook . 'macro pager i  <copy-message>=infra\ny<delete-message>  "Move to infra"'

# Move message to mwos folder
folder-hook . 'macro index w  <copy-message>=mwos\ny<delete-message>  "Move to mwos"'
folder-hook . 'macro pager w  <copy-message>=mwos\ny<delete-message>  "Move to mwos"'

# Move message to TLS folder
folder-hook . 'macro index l  <copy-message>=TLS\ny<delete-message>  "Move to TLS"'
folder-hook . 'macro pager l  <copy-message>=TLS\ny<delete-message>  "Move to TLS"'

# Move message to infra/aws folder
folder-hook . 'macro index a  <copy-message>=infra/aws\ny<delete-message>  "Move to infra aws"'
folder-hook . 'macro pager a  <copy-message>=infra/aws\ny<delete-message>  "Move to infra aws"'

# Move message to services folder
folder-hook . 'macro index v  <copy-message>=services\ny<delete-message>  "Move to services"'

# Auto view rules
auto_view application/zip
auto_view application/x-gzip
auto_view application/x-gunzip 
auto_view application/pgp-signature
auto_view application/pgp
auto_view application/octet-stream 
auto_view application/x-zip-compressed
auto_view application/x-arj-compressed
auto_view application/x-tar-gz
auto_view application/ms-tnef
auto_view application/x-perl
auto_view application/x-sh
auto_view application/x-tcl
auto_view application/x-delphi-source
auto_view application/emacs-lisp
auto_view application/msword
auto_view text/x-patch
#auto_view text/html
auto_view text/x-vcard
auto_view text/x-script.elisp
auto_view text/x-lisp
auto_view text/x-diff
auto_view image/tiff

# crypto
set crypt_use_gpgme
# specify the uid to use when encrypting/signing
set pgp_sign_as                 = 0x3B763E8F
set pgp_decode_command          = "gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f"
set pgp_verify_command          = "gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify %s %f"
set pgp_decrypt_command         = "gpg --status-fd=2 %?p?--passphrase-fd 0? --no-verbose --quiet --batch --output - %f"
set pgp_sign_command            = "gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --detach-sign --textmode %?a?-u %a? %f"
set pgp_clearsign_command           = "gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0? --armor --textmode --clearsign %?a?-u %a? %f"
set pgp_encrypt_only_command    = "/opt/pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"
set pgp_encrypt_sign_command    = "/opt/pgpewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"
set pgp_import_command          = "gpg --no-verbose --import %f"
set pgp_export_command          = "gpg --no-verbose --export --armor %r"
set pgp_verify_key_command          = "gpg --verbose --batch --fingerprint --check-sigs %r"
set pgp_list_pubring_command    = "gpg --no-verbose --batch --quiet --with-colons --list-keys %r"
set pgp_list_secring_command    = "gpg --no-verbose --batch --quiet --with-colons --list-secret-keys %r"
set pgp_good_sign               = "^gpg: Good signature from"
set pgp_timeout                 = 3600
# automatically sign all outgoing messages
set crypt_autosign                  = no
# sign only replies to signed messages
set crypt_replysign             = yes
# automatically encrypt outgoing messages
set crypt_autoencrypt           = no
# encrypt only replies to signed messages
set crypt_replyencrypt          = no
# encrypt and sign replies to encrypted messages
set crypt_replysignencrypted    = yes
# automatically verify the sign of a message when opened
set crypt_verify_sig            = yes
set pgp_auto_decode                 = yes

# add a header to outbound mail with the location of my pgp key
my_hdr X-PGP-Key: fp="E608 92BB 9BD8 9A69 F759  A1A0 A3D6 5217 3B76 3E8F"\; id="0x3B763E8F"\; get=<hkp://pgp.mit.edu/pks/lookup?search=0xA3D652173B763E8F&op=get>\;

4.2 Styles

~/.mutt/colors-solarize

# vim: filetype=muttrc

# sidebar colors
color sidebar_new yellow default
color sidebar_flagged red default

#
#
# make sure that you are using mutt linked against slang, not ncurses, or
# suffer the consequences of weird color issues. use "mutt -v" to check this.

# custom body highlights -----------------------------------------------
# highlight my name and other personally relevant strings
#color body          color136        color234        "(ethan|schoonover)"
# custom index highlights ----------------------------------------------
# messages which mention my name in the body
color index         color136        color234        "~b \"(v|V)ehent\" !~N !~T !~F !~p !~P"
color index         white           color230        "~b \"(v|V)ehent\" ~N !~T !~F !~p !~P"
color index         color136        color37         "~b \"(v|V)ehent\" ~T !~F !~p !~P"
color index         color136        red             "~b \"(v|V)ehent\" ~F !~p !~P"
## messages which are in reference to my mails
#color index         J_magent        color234        "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" !~N !~T !~F !~p !~P"
#color index         J_magent        color230        "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~N !~T !~F !~p !~P"
#color index         J_magent        color37         "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~T !~F !~p !~P"
#color index         J_magent        color160        "~x \"(mithrandir|aragorn)\\.aperiodic\\.net|thorin\\.hillmgt\\.com\" ~F !~p !~P"

# for background in 16 color terminal, valid background colors include:
# base03, bg, black, any of the non brights

# basic colors ---------------------------------------------------------
color normal        color241        color234        
color error         color160        color234        
color tilde         color235        color234        
color message       color37         color234        
color markers       color160        color254        
color attachment    color254        color234        
color search        color61         color234        
#color status        J_black         J_status        
color status        color241        color235        
color indicator     color234        color136        
color tree          color136        color234                                    # arrow in threads

# basic monocolor screen
mono  bold          bold
mono  underline     underline
mono  indicator     reverse
mono  error         bold

# index ----------------------------------------------------------------

#color index         color160        color234        "~D(!~p|~p)"               # deleted
#color index         color235        color234        ~F                         # flagged
#color index         color166        color234        ~=                         # duplicate messages
#color index         color240        color234        "~A!~N!~T!~p!~Q!~F!~D!~P"  # the rest
#color index         J_base          color234        "~A~N!~T!~p!~Q!~F!~D"      # the rest, new
color index         color160        color234        "~A"                        # all messages
color index         color166        color234        "~E"                        # expired messages
color index         color33         color234        "~N"                        # new messages
color index         color33         color234        "~O"                        # old messages
color index         color61         color234        "~Q"                        # messages that have been replied to
color index         white           color234        "~R"                        # read messages
color index         color33         color234        "~U"                        # unread messages
color index         color33         color234        "~U~$"                      # unread, unreferenced messages
color index         color241        color234        "~v"                        # messages part of a collapsed thread
color index         color241        color234        "~P"                        # messages from me
color index         color37         color234        "~p!~F"                     # messages to me
color index         color37         color234        "~N~p!~F"                   # new messages to me
color index         color37         color234        "~U~p!~F"                   # unread messages to me
color index         color240        color234        "~R~p!~F"                   # messages to me
color index         color160        color234        "~F"                        # flagged messages
color index         color160        color234        "~F~p"                      # flagged messages to me
color index         color160        color234        "~N~F"                      # new flagged messages
color index         color160        color234        "~N~F~p"                    # new flagged messages to me
color index         color160        color234        "~U~F~p"                    # new flagged messages to me
color index         color235        color160        "~D"                        # deleted messages
color index         color245        color234        "~v~(!~N)"                  # collapsed thread with no unread
color index         color136        color234        "~v~(~N)"                   # collapsed thread with some unread
color index         color64         color234        "~N~v~(~N)"                 # collapsed thread with unread parent
# statusbg used to indicated flagged when foreground color shows other status
# for collapsed thread
color index         color160        color235        "~v~(~F)!~N"                # collapsed thread with flagged, no unread
color index         color136        color235        "~v~(~F~N)"                 # collapsed thread with some unread & flagged
color index         color64         color235        "~N~v~(~F~N)"               # collapsed thread with unread parent & flagged
color index         color64         color235        "~N~v~(~F)"                 # collapsed thread with unread parent, no unread inside, but some flagged
color index         color37         color235        "~v~(~p)"                   # collapsed thread with unread parent, no unread inside, some to me directly
color index         color136        color160        "~v~(~D)"                   # thread with deleted (doesn't differentiate between all or partial)
#color index         color136        color234        "~(~N)"                    # messages in threads with some unread
#color index         color64         color234        "~S"                       # superseded messages
#color index         color160        color234        "~T"                       # tagged messages
#color index         color166        color160        "~="                       # duplicated messages

# message headers ------------------------------------------------------

#color header        color240        color234        "^"
color hdrdefault    color240        color234        
color header        color241        color234        "^(From)"
color header        color33         color234        "^(Subject)"

# body -----------------------------------------------------------------

color quoted        color33         color234        
color quoted1       color37         color234        
color quoted2       color136        color234        
color quoted3       color160        color234        
color quoted4       color166        color234        

color signature     color240        color234        
color bold          color235        color234        
color underline     color235        color234        
color normal        color244        color234        
#
color body          color245        color234        "[;:][-o][)/(|]"    # emoticons
color body          color245        color234        "[;:][)(|]"         # emoticons
color body          color245        color234        "[*]?((N)?ACK|CU|LOL|SCNR|BRB|BTW|CWYL|\
                                                     |FWIW|vbg|GD&R|HTH|HTHBE|IMHO|IMNSHO|\
                                                     |IRL|RTFM|ROTFL|ROFL|YMMV)[*]?"
color body          color245        color234        "[ ][*][^*]*[*][ ]?" # more emoticon?
color body          color245        color234        "[ ]?[*][^*]*[*][ ]" # more emoticon?

## pgp

color body          color160        color234        "(BAD signature)"
color body          color37         color234        "(Good signature)"
color body          color234        color234        "^gpg: Good signature .*"
color body          color241        color234        "^gpg: "
color body          color241        color160        "^gpg: BAD signature from.*"
mono  body          bold                            "^gpg: Good signature"
mono  body          bold                            "^gpg: BAD signature from.*"

# yes, an insance URL regex
color body          color160        color234        "([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*'();:&=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*'()$,;:@&=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*'():@&=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*'();/?:@&=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*'():@&=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*'();/?:@&=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n<>\"]"
# and a heavy handed email regex
#color body          J_magent        color234        "((@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]),)*@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\.[0-9]?[0-9]?[0-9]\\]):)?[0-9a-z_.+%$-]+@(([0-9a-z-]+\\.)*[0-9a-z-]+\\.?|#[0-9]+|\\[[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\.[0-2]?[0-9]?[0-9]\\])"

# Various smilies and the like
#color body          color230        color234        "<[Gg]>"                            # <g>
#color body          color230        color234        "<[Bb][Gg]>"                        # <bg>
#color body          color136        color234        " [;:]-*[})>{(<|]"                  # :-) etc...
# *bold*
#color body          color33         color234        "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
#mono  body          bold                            "(^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$)"
# _underline_
#color body          color33         color234        "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
#mono  body          underline                       "(^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)"
# /italic/  (Sometimes gets directory names)
#color body         color33         color234        "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"
#mono body          underline                       "(^|[[:space:][:punct:]])/[^/]+/([[:space:][:punct:]]|$)"

# Border lines.
#color body          color33         color234        "( *[-+=#*~_]){6,}"

#folder-hook .                  "color status        J_black         J_status        "
#folder-hook gmail/inbox        "color status        J_black         color136        "
#folder-hook gmail/important    "color status        J_black         color136        "
en/ressources/astuces/mutt-kz_gpgme.txt · Last modified: 2015/07/24 20:56 by julien
CC Attribution-Noncommercial-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0