Using msmtp with the GNOME keyring

Using msmtp with gnome keyring

If you use mutt to manage your mail, you are probably using msmtp to manage your mail delivery.

Probably you don’t like the fact that you have you store your SMTP password unencrypted in your $HOME/.msmtprc file.

Fear no more! Satoru Satoh has added support for the GNOME keyring, and, thanks to Martin Lambers, that’s already in the CVS tree.

So, if you want to use it, follow this easy steps:

    $ cvs -d:pserver:anonymous@msmtp.cvs.sourceforge.net:/cvsroot/msmtp login
    $ cvs -z3 -d:pserver:anonymous@msmtp.cvs.sourceforge.net:/cvsroot/msmtp co -P msmtp 
    $ cd msmtp
    $ autoreconf -i
    $ ./configure --with-gnome-keyring --prefix=/usr/local/msmtp-cvs
    $ make
    $ sudo make install
    Check that it is properly compiled with keyring support with:
    $ ldd /usr/local/msmtp-cvs/bin/msmtp  | grep keyring
        libgnome-keyring.so.0 => /usr/lib/libgnome-keyring.so.0 (0xb7d2c000)

There’s a problem, though. Msmtp has no support for setting this password inside the gnome keyring.

To handle this, i have made this little python script that will help you to do so. Thanks to Satoh again for this post where he explains how the gnome keyring bindings for python work.

Here you have a sample session of this script:

    $ ./msmtp-keyring-manage-password.py -s --username=myuser --server=smtp.example.com
    Password for user 'myuser' in server 'smtp.example.com' ? 
    Confirmation, Password for user 'myuser' in server 'smtp.example.com' ?
 
    $ ./msmtp-keyring-manage-password.py -g --username=myuser --server=smtp.example.com
 
    Password for user 'myuser' in server 'smtp.example.com' : foo

And here you have the script. You can download it from github, to avoid problems with python and whitespace.

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
 
    import gnomekeyring as gk, sys, optparse, getpass
 
 
    def set_keyring_password_for_msmtp_user(user, password, server):
 
        # Does it already exist?
        if get_keyring_password_for_msmtp_user(user, server) is not None:
            error_msg = "SMTP password for user '%s' in server '%s' does already exists" %(user, server)
            return (False, error_msg)
 
        # get default keyring name. you can also specify it explicitly.
        keyring = gk.get_default_keyring_sync()
 
        # display name for password.
        display_name = 'SMTP password for %s at %s'%(user, server)
 
        # select type. if you want some kind of "network" password, it seems that
        # appropriate type is network_password because it has a schema already.
        type = gk.ITEM_NETWORK_PASSWORD
 
        usr_attrs = {'user':user, 'server':server, 'protocol':'smtp'}
 
        # Now it gets ready to add into the keyring. Do it.
        # Its id will be returned if success or an exception will be raised
        id = gk.item_create_sync(keyring, type, display_name, usr_attrs, password, False)
        return (True, "")
 
 
    def get_keyring_password_for_msmtp_user(user, server):
 
        try:
            results = gk.find_network_password_sync(user=user, server=server, protocol='smtp')
        except gk.NoMatchError:
            return None
 
        return results[0]["password"]
 
    def main():
        usage = "%prog [-s|-g] --username myuser --server myserver"
 
        parser = optparse.OptionParser(usage=usage)
 
        parser.add_option("-s", "--set-password", action="store_true", dest="setpass", help="Set password for msmtp acount")
        parser.add_option("-g", "--get-password", action="store_true", dest="getpass", help="Get password for msmstp account")
 
        parser.add_option("-u", "--username", action="store", dest="username", help="Username for msmtp account")
        parser.add_option("-e", "--server", action="store", dest="server", help="SMTP server for msmtp account")
 
        (opts, args) = parser.parse_args()
 
        if not opts.setpass and not opts.getpass:
            parser.print_help()
            print "You have to use -s or -g !!"
            return -1
 
        if not opts.username or not opts.server:
            parser.print_help()
            print "You have to use both --username and --server !!"
            return -1
        elif opts.getpass:
            passwd = get_keyring_password_for_msmtp_user(opts.username, opts.server)
            print "Password for user '%s' in server '%s' : %s" %(opts.username, opts.server, passwd)
        else: # setpass
            msg = "Password for user '%s' in server '%s' ? " %(opts.username, opts.server)
            passwd = getpass.getpass(msg)
            passwd_confirmation = getpass.getpass("Confirmation, " + msg)
            if passwd != passwd_confirmation:
                print "Password and password confirmation are different, exiting..."
                return -1
            status_ok, error_msg = set_keyring_password_for_msmtp_user(opts.username, passwd, opts.server)
            if not status_ok:
                print error_msg
                return -1
        return 0
 
 
    if __name__ == '__main__':
        sys.exit(main())

Hope this is useful to somebody!!

Using rtags ang gtags for coding Ruby

Boring intro

When I was a C and Java developer (not that long ago), I always used the GNU GLOBAL source code tag system gtags.

Despite it’s awful, impossible-to-find-in-google name, it’s a wonderful system to navigate around your code: find function definitions, where they are used, fast “grepping” of code, you name it.

And, most important, it’s emacs support is wonderful!!

You can check their tutorial. It’s a little bit scary at the beginning, but, really, you should try it.

I want to show you how i use gtags when coding Ruby. Hopefully it will be useful to somebody else.

First problem: gtags only supports C, C++, Java, PHP, YACC ¿¿?? “out of the box”.

Fortunately, it’s developers are very smart and have thought of a system where you can use any program that outputs a pretty established format out of the code you want to tag (anything that emits output like ctags -x does).

So, you can use, for example, Exuberant ctags, to parse your Ruby code and then use gtags to navigate it.

Exuberant ctags it great for parsing lot’s of languages, but not so good with Ruby. But don’t despair, there’s this guy who has wrote rtags, a parser designed to extract code tags from Ruby code. This is more Ruby-especific, so it usually gets much more information (for example, attr_accessor :foo , alias :foo :bar).

Also, with rtags, it’s possible to tag not only my_method, but also MyClass#my_method, so you can list, for example, every method in one class.

Problems: rtags is slow. Painfully slow, compared with ctags. But gtags is pretty smart, I told you. The first time you index your sources it’ll be slow. But, after changing and changing your code, it’ll just reindex the files that have changed since it’s last reindex.

Get the code

First, you should have installed gtags (apt-get install global)

Now, you need to get a rtags version that can output cros xref format:

I have patched rtags, so you can use it with gtags (I am not that smart, it was easy, since the rtags code is easily read).

I have placed it in github, in http://github.com/gaizka/rtags/tree/master.

If you don’t care about git, you can get the file at: http://github.com/gaizka/rtags/tree/master%2Fbin%2Frtags?raw=true

Once you have, place anywhere in your disk, chmod +x, and add that direcotry to your $PATH.

Update The rtags mantainer has merged my modifications into the official repo, so can install directly with gems:

    $ gem install rtags --version 0.97

Just make sure it’s versión 0.97 or higher.

Configure it

With the installation of gtags comes a sample configuration file that you have to use to extend, to use it with rtags. First copy the sample:

    cp /usr/share/doc/global/examples/gtags.conf $HOME/.globalrc

And then add this lines. Careful with it, this format is awful, and you cannot have any blank lines on it.

(You can get the whole file here: http://pastie.org/290127

    # We need to change some of the output that rtags dumps
    #
    # Module::Submodule is NOT found by global (don't know why)
    # Module:Submodule IS found
    # So we replace :: with :
    #
    # Also, dotnames are not allowed in tags
    # So, when rtag parses this
    #   class User ;  def self.validate ; end ; end
    # as:
    #   User.validate  line_no file_name line
    # global doesn't find it with: global -c User
    # So we need to replace any dots in the firts column with #
    #   User#validate line_no file_name line
    #
    # So we need to to this:
    # rtags -x %s | awk '{ sub(/^::/, "") ; sub(/::/, ":"); sub(/\\./, "#", $1); print}'
    #
    rtags:\
    	:tc=common:\
    	:suffixes=s,a,sa,asm,C,H,cpp,cxx,hxx,hpp,cc,c,h,y,rb:\
    	:extractmethod:\
    	:GTAGS=rtags -x %s | awk '{ sub(/^\:\:/, "") ; sub(/\:\:/, "\:"); sub(/\\./, "#", $1); print}':\
    	:GRTAGS=gtags-parser --langmap=java\:.rb -dtr  %s:\
    	:GSYMS=gtags-parser --langmap=java\:.rb -dts  %s:
    #

Last, you need to tell gtags that you want to use the rtags parser. To do so, yo need to set the environment variable:

    export GTAGSLABEL=rtags

Test it

OK, we now should be able to roll!

Let’s index, for example, activerecord. Go to your gems directory, and try it (you should adapt your paths accordingly):

 
    cd $HOME/gem_repository/gems/activerecord-2.0.2
    export GTAGSLABEL=rtags
    $ gtags -v
    [Fri Oct 03 19:54:48 CEST 2008] Gtags started.
     Using config file '/home/gaizka/.globalrc'.
    [Fri Oct 03 19:54:48 CEST 2008] Creating 'GTAGS'.
     [1] extracting tags of lib/active_record.rb
     [2] extracting tags of lib/active_record/attribute_methods.rb
     ...
     ...
     [174/174] extracting tags of test/serialization_test.rb
    [Fri Oct 03 19:55:43 CEST 2008] Done.

List methods starting with find_:

    $ global -x "^find_*" 
    find_all_ordered  337 test/associations/eager_test.rb def find_all_ordered
    find_by_sql       531 lib/active_record/base.rb def find_by_sql
    find_every       1230 lib/active_record/base.rb def find_every
    find_first         22 lib/active_record/associations/has_and_belongs_to_many_association.rb    def find_first
    ...

ActiveRecord errors:

    $ global -x "^ActiveRecord:Errors*"
    ActiveRecord:Errors   19 lib/active_record/validations.rb class Errors
    ActiveRecord:Errors#[]  119 lib/active_record/validations.rb alias :[]
    ActiveRecord:Errors#add   64 lib/active_record/validations.rb def add
    ActiveRecord:Errors#add_on_blank   79 lib/active_record/validations.rb def add_on_blank
    ActiveRecord:Errors#add_on_empty   70 lib/active_record/validations.rb def add_on_empty
    ...

Command line is great, but when you are editing, you are editing, so you shouldn’t have to drop to the console when you are using your $EDITOR.

Vim support

I just use vim for quick edits, so i cannot help you here. Just point you to gtags documentation: http://www.gnu.org/software/global/globaldoc.html#SEC26

Emacs support

If you’re using the one true editor, you’re lucky. Gtags support is great.

If you want to use gtags in all your ruby coding, then add this lines to your .emacs:

  (autoload 'gtags-mode "gtags" "" t)
 
  (add-hook 'ruby-mode-hook (lambda () 
    (gtags-mode 1)
    (setq gtags-symbol-regexp "[A-Za-z_:][A-Za-z0-9_#.:?]*")
    (define-key ruby-mode-map "\e." 'gtags-find-tag)
    (define-key ruby-mode-map "\e," 'gtags-find-with-grep)
    (define-key ruby-mode-map "\e:" 'gtags-find-symbol)
    (define-key ruby-mode-map "\e_" 'gtags-find-rtag)))

Now, open one of the files of activerecord.

    cd $HOME/gem_repository/gems/activerecord-2.0.2
    emacs lib/active_record.rb

We need to tell gtags where to look for it’s parsed files:

    M-x gtags-visit-rootdir

And point it to $HOME/gem_repository/gems/activerecord-2.0.2

After this, let’s look for tags starting with Time

    M-x gtags-find-tag <RETURN> rename <TAB><TAB>

You should get the completions:

    rename_column    rename_table

Choose, for example, rename_table and you should get a window with contents like:

    rename_table      110 abstract/schema_statements.rb def rename_table
    rename_table      419 mysql_adapter.rb def rename_table
    rename_table      584 postgresql_adapter.rb def rename_table
    rename_table      212 sqlite_adapter.rb def rename_table
    rename_table      373 sqlite_adapter.rb def rename_table

Choose the line you want to go to, and bingo!, you should be there.

You can search inside modules by “tabbing” into them.

    M-x gtags-find-tag ActiveRecord<TAB><TAB>:Callbacks<TAB><TAB>#create_with_callbacks

One think i haven’t managed to is to get rtags emit it’s format so you can find both ActiveRecord:Callbacks#create_with_callbacks and Callbacks#create_with_callbacks. I’ll try to do it, so stay tunned!

You CAN find both ActiveRecord:Callbacks#create_with_callbacks and just create_with_callbacks, though.

Finding not just functions/classes definitions

Finding function definitions is great. But sometimes you need to know where one method is called, for example.

You can then use one of the next functions:

  • gtags-find-rtag . This one finds function references. It does not that good with Ruby, usually it finds more lines than desired. Works great with C or Java, though.

  • gtags-find-with-grep. This one uses grep for finding occurences in the lines of the code.

  • gtags-find-symbol. This one finds where “symbols” (not Ruby symbols, more like “tokens”)are used.

For example, to look where NotImplementedError are raised, you can do:

    M-x gtags-find-symbol NotImplementedError
 
    NotImplementedError   34 database_statements.rb         raise NotImplementedError, "select_rows is an abstract method"
    NotImplementedError   39 database_statements.rb         raise NotImplementedError, "execute is an abstract method"
    ....

Or, where ALTER TABLE is used:

    M-x gtags-find-with-grep ALTER TABLE
 
    ALTER%20TABLE     122 schema_statements.rb         add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
    ALTER%20TABLE     131 schema_statements.rb         execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}"
    ....

Reparsing files

Ok, you have coded loads of new functionality, and you want it to get tagged. You don’t need to execute gtags again, it’s too slow. You need to call this (in the directory where GTAGS file is).

    $ global -u -v

And it will only parse modified files since last parse, so it is pretty fast (don’t forget to export GTAGSLABEL=rtags to tell it to use rtags).

The end

I hope this is useful to somebody. If you need any aclaration, don’t hesitate in leaving a comment, i’ll try to help you with it.

Thanks to all the great developers out there that release free-as-in-freedom software. ¡¡Thanks for making our coding sessions easier!!

Listing keys used in a memcached server

Maybe this is of no use to anybody, but it was useful to me while developing some caching code, so I hope it can be useful to someone else.

This is a script will list every key that’s being used in a memcached server.

I haven’t tried it in a production server, and you sholud be careful doing it. It looks that some of the commands are blocking and can affect the performance for the rest of the clients.

    #!/bin/bash
 
    # Script to see which keys are stored in a memcached server
    # Warning: stats command is blocking, so be careful if you want to use this in production
 
    SERVER=localhost
    PORT=11211
 
    stats=`echo -e "stats items \n quit" | nc $SERVER $PORT`
 
    keys=`echo "$stats" | egrep "STAT.*number" | cut -d ':' -f 2 | xargs echo`
 
    commands=""
    for key in $keys ; do 
        commands="stats cachedump $key 100 \n $commands"
    done
 
    echo -e "$commands quit " | nc $SERVER $PORT | grep ITEM

Hope that helps anybody.

Volviendo a escribir

Este blog nació con un objetivo concreto. Me iba de viaje unos meses, y quería que mis amigos y familiares estuviesen al tanto de por dónde estaba. La cosa salió bien: ellos se divertían leyendo, y yo me divertía escribiendo.

Claro que era fácil escribir sobre todo eso. Estás de vacaciones, viendo sitios muy diferentes a los de casa, todo lo que haces parece interesante… Ahora es diferente. De vuelta en casa, las cosas que uno hace son muy parecidas a las que hace todo el mundo. Así que, ¿por qué escribir sobre ello?

Porque todo el mundo tiene que tener un blog :)

Y, aparte de eso, porque es hora de, tras tanto tiempo utilizando software libre, es hora de devolver algo a la comunidad. Así que intentaré publicar cosas que puedan ser de utilidad a algún desarrollador/hacker despistado.

Espero que te sirva alguna cosa. Y si no, hay miles y miles de otras webs donde puedes gastar tu tiempo :)

Y ahora, que pasa con imaginateaqui.net ?

Creo que imaginateaqui.net va a ser mucho menos interesante para vosotros cuando “aqui” signifique Madrid, y no Laos, Vietnam o India.

En un par de semanas ordenare las fotos, pondre las fotos que he sacado con la camara digital desde hace cuatro meses y que todavia no he visto, y ordenare un poco la pagina. Pero no creo que escriba mucho mas.

Espero que hayais disfrutado estos meses con mis batallitas. Por lo menos, tanto como yo he disfrutado inventandolas :)

Muchas gracias a todos por vuestro apoyo, comentarios y correos.

Pero, sobre todo, muchas gracias por estar ahi.

Esto se acaba

En doce horas estare en el avion que me llevara de vuelta a casa.

Esta aventurilla de cuatro meses ya casi ha finalizado. Voy a echar de menos esta manera de vivir, pero tambien tengo muchas ganas de volver, hasy un monton de cosas que echo de menos. Cuatro meses han sido suficientes para un primer viaje :)

Una buena amiga de un buen amigo me escribio hace unos dias y me pregunto, entre otras cosas, como me habia cambiado este viaje. Si veia las cosas de otra manera, que cosas iba a hacer distintas a la vuelta. Para averiguarlo voy a necesitar de la gente que me conoce. Vosotros sois los que me encontrareis diferente. O no.

Imagion que habra cosas que ahora voy a ver de manera distinta; cosas que dejare de hacer y cosas nuevas que empezare a hacer. Pero no tengo ni idea de como va a ser.

Va a ser divertido irlo descubriendo.

En Agra, el Taj Mahal

El Taj Mahal es impresionante. No importa cuantas veces lo hayas visto en postales, verlo en directo es espectacular.

Estvue alli a las seis de la maniana, con lo que no habia “muchisimos” turistas. Y mientras esperaba en la cola me encontra con una ex-companiera de curro. Si es que India es muy pequenia

Un viaje en tren un poco estresante

En Rishikesh pase casi una semana. Luego cogi un tren nocturno hasta Delhi. El plan era comprar un billete para Agra, pero entre retrasos y demas la cosa se complico.

Y acabe comprando un billete “sin reserva”. Esto quiere decir que no tienes un sitio asignado en el tren, como pasa normalmente con los demas billetes. Te metes en un vagon especial y, se supone, i hay algun asiento libre puedes pagar la diferencia de precio y cambiarte.

Esto debe de ser la teoria. La practica es que se forma una muchedumbre alrededor de los vagones y cuando abren las puertas, se forma una batalla campal. Gente gritando, dando empujones, pasando a bebes de brazo en brazo hasta algun hueco, etc, etc. El canadiense con el que habia coincidido al sacar el billete y yo conseguimos sentarnos en el suelo, cerca del banio, asi que no estabamos tan mal. Pero nos falta la picardia (o el morro) de los locales. Porque una hora mas tarde eramos los unicos de pie, mientras que el resto estaba (mas o menos) confortablemente sentado en el suelo.

Pero solo fueron tres horas, y nos sirvio para ver un poco mas de India. Y para confirmar que los indios se suelen descontrolar en las aglomeraciones. Y que, mucho karma y reencarnaciones y demas, pero aqui la gente tiene muy mala leche, y generalmente solo miran por su propio bienestar. Al menos en este tipo de situaciones.

Sobre Rishikesh

Rishkesh es una ciudad muy “mistica”. Es un sitio popular para los peregrinos indios, que se desplazan a varios templos muy importantes cercanos al Himalaya. Ah, y se considera la capital mundial del yoga; parece ser que los Beatles vinieron por aqui en los 60 para practicarlo. Esta muy cerca del Himalaya, y aqui el agua del Ganges esta limpia y muy fresca.

Mi intencion era acercarme mas al Himalaya y hacer algun trekking por alli. Pero como todavia estamos en temporada de lluvias, habia habido corrimientos de tierras y algunas carreteras estaban cortadas. Asi que no quise arriesgarme a ir y quedarme atrapado por alli (aunque alguno seguro que lo agradeceria :).

Asiq ue me pase alli casi una semana. A falta de trekkings por montanias lejanas, me converti en un autentico peregrino y me subi cuatro veces a un templo que habia en un monte a 23 km.

El paisaje hasta alli era precioso. Al lado del Ganges (solo hasta la mitad, luego el camino empezaba a tirar hacia arriba). Lo unico un poco desagradable eran los taxis/jeeps que subian llevando a peregrinos mas vagos (o con cosas mas importantes que hacer que perder el tiempo andando) que yo. Aunque lo de tener un monton de taxis esperando para la vuelta se agradecia mucho (otros 23 km hubiesen sido demasiados).

A los largo del camino habia varias colonias de monos de un par de especies diferentes. Estan cerca de la carretera porque la gente suele tirarles comida. Era agradable ver los monos en el camino, hasta que un dia tuve un incidente con uno de ellos. Asi que el resto de los dias me ponia un poco nervioso cada vez que pasaba cerca de ellos.

Y es que iba yo andando tranquilamente, cuando uno de ellos me ataco. Generalmente pasaba cerca suyo, y tambien generalmente, se solian alejar. Pero esta vez vi uno que se me iba acercando, asi que me quede quieto. Seguia acercandose, asi que me di la vuelta y empece a retroceder. No se si esto le envalentono, o decidio lucirse delante de su novia asustando a un humano mucho mas grande que el, pero la cosa es que empezo a trotar hacia mi. Yo, claro, empece a correr cuesta abajo. Y asi estuvimos unos segundos que se me hicieron interminables: el mono persiguiendome, enseniando los dientes y chillando; y yo corriendo mas rapido y llamandole de todo. Hasta que se canso y se dio la vuelta. Yo no me canse tan rapido de correr y, por si acaso, segui huyendo un rato. Luego pare un coche para que me subiese un km hasta que no habia mas monos. Y segui andando.

Esta sesion de pateo/peregrinacion era por las manianas. Por las tardes estuve haciendo yoga con un profesor muy divertido al que no le entendiamos siempre. Pero la gente que controlaba esto del yoga decia que las clases eran muy buenas. La verdad es que me gustaron mucho. Para mi no deja de ser unos estiramientos mas un poco de ejercicio. Por supuesto que sirve para encontrar nuestra paz interior, relajarse y todo eso. Pero como otros muchos otros tipos de ejercicio. Intentare practicarlo a la vuelta.

De Jaisalmer a Rishikesh

Disfrute mucho del viaje de Jaisalmer a Rishikesh, aunque tampoco paso nada apasionante. Puede que fuese porque por primera vez cogi un tren durante el dia.

El viaje empezo con un tren nocturno de Jaisalmer a Jodhpur, desde las 23:00 hasta las 5:00 del dia siguietnte. Y luego termino con el trayecto Jodhpur-Haridwar, desde las 10:00 hasta las 9:00 del dia siguiente.

Escogi un vagon sin aire acondicionado. Esto, ademas de ser mucho mas barato, permite (o mas bien obliga) a ir con la ventana abierta, disfrutando mucho mas del viaje.
Tambien tiene inconvenientes, y es que si cruzas un desierto durante unas cuantas horas en pleno mediodia, aunque vayas en tren, hace mucho calor. !!Y no veas la de arena que entra!! A pesar de ello, fue un viaje muy tranquilo y agradable. Creo que me gusta mucho viajar en tren.