Eurodisney with Noah

Went with noah to see that Euro Disney thing and he seems to really enjoyed it. I am not a big fan of Eurodisney personally but the kid was so enjoying it. Last time i was there was like 11 years ago, things got way more expensive now  as well.

FFAP and Ruby in Emacs

If you want to use FFAP (find-file-at-point) in ruby-mode you can add this to your .emacs

(defvar ruby-program-name "ruby")
(defun ruby-module-path(module)
    (shell-command-to-string 
     (concat 
      ruby-program-name " -e " 
      "\"ret='()';$LOAD_PATH.each{|p| " 
      "x=p+'/'+ARGV[0].gsub('.rb', '')+'.rb';" 
      "ret=File.expand_path(x)" 
      "if(File.exist?(x))};printf ret\" " 
      module)))
 
(eval-after-load "ffap"
  '(push '(ruby-mode . ruby-module-path) ffap-alist))

When you do ffap (i bind it to C-x f) near a require ‘PP’ for example it will find it in your ruby path.

Ruby XMLRPC over a Self Certified SSL with a warning

If you use the XMLRPC client in ruby over a self certified SSL you have this warning :

warning: peer certificate won’t be verified in this SSL session

You can get override that warning cleanly (i have seen some people who just comment the message in the standard library) like that :

require 'xmlrpc/client'

require 'net/https'
require 'openssl'
require 'pp'module SELF_SSL
  class Net_HTTP < Net::HTTP
    def initialize(*args)
      super
      @ssl_context = OpenSSL::SSL::SSLContext.new
      @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
    end
  end

class XMLRPC_Client < XMLRPC::Client
    def initialize(*args)
      super
      @http = SELF_SSL::Net_HTTP.new( @host, @port,
                    @proxy_host,@proxy_port )
      @http.use_ssl = @use_ssl if @use_ssl
      @http.read_timeout = @timeout
      @http.open_timeout = @timeout
    end

end

end

if __FILE__ == $0

f = SELF_SSL::XMLRPC_Client.new2("https://url")
 puts f.call("method", 'arg')
end

Yum Force Exclude List

While talking with my fellow colleague Darren Birkett about what seems a design limitation
of yum to not be able to force listing the excludes from yum. I had a
shoot to make a yum plugin to force listing the excludes.

Here is how it works :

root@centos5:~> grep exclude /etc/yum.conf
exclude=rpm*
root@centos5:~> yum install rpm-devel
Loading “installonlyn” plugin
Loading “changelog” plugin
Loading “chmouel” plugin
Loading “priorities” plugin
Setting up Install Process
Setting up repositories
Reading repository metadata in from local files
Excluding Packages in global exclude list
Finished
0 packages excluded due to repository priority protections
Parsing package install arguments
Nothing to do

rpm* is excluded, but if we use the environment variable FORCE_EXCLUDE
it will force it.

 root@centos5:~> FORCE_EXCLUDE=true yum install rpm-devel
Loading “installonlyn” plugin
Loading “changelog” plugin
Loading “chmouel” plugin
Loading “priorities” plugin
Setting up Install Process
Setting up repositories
Reading repository metadata in from local files
0 packages excluded due to repository priority protections
Parsing package install arguments
Resolving Dependencies
–> Populating transaction set with selected packages. Please wait.
—> Downloading header for rpm-devel to pack into transaction set.
rpm-devel-4.4.2-47.el5.i3 100% |=========================| 17 kB 00:00
—> Package rpm-devel.i386 0:4.4.2-47.el5 set to be updated
–> Running transaction check
[.....]

It will allow you to list the excluded rpm as well :

 root@centos5:~> FORCE_EXCLUDE=true yum list|grep rpm
rpm.i386 4.4.2-47.el5 installed
rpm-libs.i386 4.4.2-47.el5 installed
rpm-python.i386 4.4.2-47.el5 installed
redhat-rpm-config.noarch 8.0.45-22.el5.centos base
rpm-build.i386 4.4.2-47.el5 base
rpm-devel.i386 4.4.2-47.el5 base
root@centos5:~> yum list|grep rpm
rpm.i386 4.4.2-47.el5 installed
rpm-libs.i386 4.4.2-47.el5 installed
rpm-python.i386 4.4.2-47.el5 installed
redhat-rpm-config.noarch 8.0.45-22.el5.centos base

See the README.txt in the rpm file to see how to use/install it.

You can download the rpm here and the src.rpm here

Moving from Australia and going back to Paris.

Finally after three years (almost i arrived on 29 September 2004 here) i am following all my french friends (except Aurelien whos staying here) and i am moving back to France. It is a heartbreak since this is one (if not the one) of the best country i ever lived. I made a lot of good friends in Sydney and for the last 3 month in Melbourne. Well anyway i am sorta looking forward to come back to France to be near my kid and see all my friends there.

And as always on my way back to France i am going to travel a bit in South America until december, i have made a website which show all places i am going to which i would update on the go.

The website is here :

http://whereis.chmouel.com/

It is probably only interesting to my mum but it as well give me some good understanding of all thoses new Ajax technology and others MVC Framework (via Django).

For all my french friends i hope to see you soon in Paris!

Emacs config

To anyone interested my extensive Emacs configuration is available here :

http://code.google.com/p/chmouel/source

And here is the usual screen shot :

Emacs Screen Shot

Netapp sue Sun

This is fun, theses two CEO of theses big companies are dog fighting each others :

Dave post:

http://blogs.netapp.com/dave/2007/09/netapp-sues-sun.html

Johanthan answer:

http://blogs.sun.com/jonathan/entry/on_patent_trolling

but the real (fake) truth about that post is here :

http://fakeschwartz.blogspot.com/2007/09/bring-it-cowboy.html

I tend to believe more NetAPP in this case, just because i don’t know how many time i have sweared on that bloody ps -aux that does not work on solaris.

Generating md5 encrypted password for chpasswd

If you want to generate properly encrypted password to feed to chpasswd, the most easier and proper way is to do that from command line :

echo "encryptedpassword"|openssl passwd -1 -stdin

If you want to generate in pure python you can do it like that :

    def md5crypt(password, salt, magic='$1$'):
        import md5
        m = md5.new()
        m.update(password + magic + salt)

        # /* Then just as many characters of the MD5(pw,salt,pw) */
        mixin = md5.md5(password + salt + password).digest()
        for i in range(0, len(password)):
            m.update(mixin[i % 16])

        # /* Then something really weird… */
        # Also really broken, as far as I can tell.  -m
        i = len(password)
        while i:
            if i & 1:
                m.update(’x00′)
            else:
                m.update(password[0])
            i >>= 1

        final = m.digest()
        # /* and now, just to make sure things don’t run too fast */
        for i in range(1000):
            m2 = md5.md5()
            if i & 1:
                m2.update(password)
            else:
                m2.update(final)
            if i % 3:
                m2.update(salt)
            if i % 7:
                m2.update(password)

            if i & 1:
                m2.update(final)
            else:
                m2.update(password)

            final = m2.digest()

        # This is the bit that uses to64() in the original code.
        itoa64 = ‘./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz’
        rearranged = ”
        for a, b, c in ((0, 6, 12), (1, 7, 13), (2, 8, 14), (3, 9, 15), (4, 10, 5)):
            v = ord(final[a]) < < 16 | ord(final[b]) << 8 | ord(final[c])
            for i in range(4):
                rearranged += itoa64[v & 0x3f]; v >>= 6

        v = ord(final[11])
        for i in range(2):
            rearranged += itoa64[v & 0x3f]; v >>= 6

        return magic + salt + ‘$’ + rearranged

You need to feed it up with a salt, like this :

    def generate_salt(count):
        import random, string
        char = string.ascii_letters + string.digits + string.punctuation.replace(':', '')
        return string.join(map(lambda x,v=char: random.choice(v), range(count)), '')

Automatic best resolution with xrandr

If you like me you have a big screen with your laptop and wants to automate when your X session start to get the best resolution, you can use that script :

#!/bin/bash

function get_resolutions() {
xrandr|while read -a line;do
RES="${line[1]}x${line[3]} "
[[ ${RES} != [0-9]* ]] && continue
echo ${RES}
done
}

_BEST_RES=0
BEST_RES=
for res in $(get_resolutions);do
_res=${res/x/}
[[ $_res -ge ${_BEST_RES} ]] && {
BEST_RES=${res}
_BEST_RES=${_res}
}
done
xrandr -s ${BEST_RES}

Automate SSH known_hosts cleanup

If you like me, you have to do a lot of installs[1] of the same test machine with the same IP and have to ssh it you will notice this annoying message :

IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
54:9d:c0:37:3a:80:48:6c:82:ec:d1:84:93:61:24.
Please contact your system administrator.
Add correct host key in /home/cboudjnah/.ssh/known_hosts
to get rid of this message.
Offending key in /home/cboudjnah/.ssh/known_hosts:595
Password authentication is disabled to avoid
 man-in-the-middle attacks.
Keyboard-interactive authentication is disabled to avoid
man-in-the-middle attacks.
Agent forwarding is disabled to avoid man-in-the-middle attacks.

I have automated the cleanup by a script :

#!/bin/bash
H=$1

[[ -z ${H} ]] && { echo "Need a host as argument"; exit 1 ;}
LINE=$(ssh -o StrictHostKeyChecking=yes $1 ‘exit’ 2>&1 | sed -n ‘/Offending key/ { s/.*://;s/r//;p }’)
[[ -z ${LINE} ]] && { echo "Nothing to clean";  exit; }
sed -i -n "$LINE!p" ~/.ssh/known_hosts

[1] Like having to tests bunch of FAI.