Un naufragio personal

Ángel Ortega

HOWTO ssh persistence, redux


 Host *
 ControlMaster auto
 ControlPath ~/.ssh/%r@%h:%p
 ControlPersist 1h

HOWTO install Linux from grub with an USB pendrive

I had a fucked up installation where only GRUB2 survived. The machine CD drive is broken and the BIOS is so old that it doesn't allow booting from USB.

  1. Install an ISO onto an USB drive using pendrivelinux.com.
  2. Insert the USB into the fucked linux and switch it on.
  3. On the grub> prompt, type ls (hd and press the tab key to auto-expand until you find the USB drive (it's most probably (hd1,msdos1)).
  4. Type set root=(hd1,msdos1).
  5. Type chainloader +1.
  6. Type boot.

An algorithm to play random music

Are you playing your huge music library in random mode for hours or days and fed up of listening the same fucking songs all over again, while never hearing others? So do I.

Regardless of what Steve Jobs and other morons think, their music players are fucked up, specially their shuffle functions. Music players running in random mode should keep the last time a song was played into account.

This is the algorithm to select which song to play next:

  1. Sort all songs by the last time they were played, in ascending order (never played ones fall at the beginning of the list, recently played songs fall at the end).
  2. Pick a given set from the beginning of the list (like, say, the 10% of them).
  3. Pick one song from this set at random.
  4. Get the author of this song and test if another song by the same author was played recently (like, say, the 10% of the last played songs). If it is, jump back to previous step.
  5. store current time as its playing time, and play it.

This way, new songs added to the set have the higher chance of being played soon, as they are at the top. Songs played a long time ago will follow. And the song that have just played won't be heard for a long time.

Implement this in your music players, scumbags.

Update: I've improved the algorithm by adding a step that spreads the authors.

HOWTO check passwords without sending them on the clear

There is a simple method to check for a valid secret among two parts without sending it on the clear. This note explains how.

  1. The server accepts a connection from the client and builds a random token (a text string). This string is sent to the client.
  2. The client concatenates the random token to the password and feeds the resulting string to a cryptographically-secure hashing function like, for example, sha1. The client sends the hash to the server.
  3. The server does the same operation (concatenating the random token to the password and hashing it) and compares the resulting hash with the one the client sent.
  4. If they match, the password is accepted and the connection goes on, otherwise is dropped.

This algorithm is related to the "salt" in UNIX passwords and to the Diffie-Hellman algorithm.


The server will only accept connections from clients that know that the password is seeKriT.

A connection is started. The server creates a random token and sends it to the client:

 OK 42d4df05

The client takes that, concatenates the password and feeds it to the sha1 hash engine:

 sha1("42d4df05seeKriT") = b0f3bd621ba92f5c26261d36a8ffb9cb3b7b399d

That monstrosity is sent to the server:


The server then does the same concatenation + hashing:

 sha1("42d4df05seeKriT") = b0f3bd621ba92f5c26261d36a8ffb9cb3b7b399d

and tests for the result. As they are the same, it assumes the connection is valid and returns


or otherwise, if the hashes do not match, returns


and closes the connection.

Reformatting / indenting a Cascade Style Sheet file

If you need to compare two CSS files, the freestyle formatting can drive you crazy. You can use this little Perl script to reformat / reindent them. Or if you just want a tidier file.

  1. Formats a CSS file from STDIN
  2. Angel Ortega <angel@triptico.com>
  3. Public domain
 my $css = join('', <STDIN>);
 $css =~ s/\s+/ /g;
 my $in = 0;
 foreach my $c (split(/(\s*\{\s*)|(\s*\}\s*)/, $css)) {
 	if ($c =~ /\{/) {
 		print " {\n";
 		$in = 1;
 	elsif ($c =~ /\}/) {
 		print "}\n";
 		$in = 0;
 	else {
 		if ($in) {
 			foreach my $sc (split(/\s*;\s*/, $c)) {
 				print "\t$sc;\n";
 		else {
 			print $c;

I agree that, if comparing two CSS files is the aim, sorting the entries alphabetically would also be great; I left that as an exercise for the reader.

Distribution rights for Antichthon Universalis

It seems that Pavel has gotten permission from the source to reproduce Antichthon Universalis. He is searching for publishers like crazy, but I'm afraid they won't find the document as interesting as he does (provided that he can find anybody not on holidays these days).

He says he doesn't have the technical knowledge to do it; maybe I'll help him. Who knows, it's not impossible that I even become the editor...

There are still no words from the language teacher on the subject.

On my part, I've finished taking a look at the book itself. I'm almost sure it's a forgery like the Oera Linda, but funny to look at anyway.

More on Antichthon Universalis

Pavel has sent to me some scans of Antichthon Universalis, the recently found encrypted text, and it's a rather curious document. The drawings are certainly strange and hard to understand, but what I find more surprising is the scripting:

All text is equally separated, glyph by glyph, as if it was a Chinese or Japanese text. I'm not sure if it's meant to be read horizontally or vertically.

Pavel is in contact with an old friend of him that is a linguistic scholar and had just sent him the book to have a more experienced opinion on it. It's certainly not a known script; some letters resemble Alchemical symbols, others seem deformations of the Enochian alphabet.

I'm busy these days so I had not time to dive into it yet; as soon as I have more information, I'll publish it here.

New encrypted document found

My friend Pavel Kolsinki has told me about a newly found document, called Antichthon Universalis, written in a strange, unknown language or code, with glyphs similar to those in the Rohonc Codex or other traditional cryptos. It also contains some very bizarre illustrations about plants, animals and what look like very symbolic maps.

For what he tells me, I think it's more like a Codex Seraphinianus than a Voynich manuscript, but let's see. I'm looking forward to seeing some scannings he's about to send me.

Rubbish Rain vs The Incident

The soon to be released, 8bit-like, retro-looking game The Incident looks pretty similar to a game I wrote for the ZX Spectrum back in the 80's, Rubbish Rain (aka Scrollisis). It can be downloaded in Z80 format from my page of ZX Spectrum programs.

It features a character trying to survive and unending cascade of objects falling from the sky. It even includes the player trying to move up/fly by becoming a bubble.

A curious case of prior art (though I'm pretty sure these people do not know my game).

Esta copia de Office no es original

Lo dirás tú. Pero cuando ocurra, hay que

  1. Cerrar el MS Office 2007,
  2. Renombrar C:\WINDOWS\system32\OGAAddin.dll a OGAAddin2.dll.

A partir de ese momento, MS Office 2007 ya es original.

Otra opción es usar OpenOffice.org, pero será como cambiar a Leatherface por Hannibal Lecter.

Listing GCC Preprocessor defines

To see all preprocessor macros defined by GCC, type

 echo | gcc -E -dM -

Why the iPod interface is crap

  • You cannot delete songs from the device. So everytime that fucking song starts again, you can do nothing but hope never forgetting to delete it on next sync time.
  • When you browse your songs by artist, only those with an album tag will be shown. Delete all album tags but one for all songs of a given artist for enhanced hilarity.
  • There is no way to play randomly any set, only the full one. So, if you're in the mood to listen those music from the chillout genre, you better fuck yourself and enjoy them in alphabetical order (again).
  • It's too easy to let it playing alone, so next time you pick it from the table, the battery is probably gone.
  • There is no way to enhance their storage capacity with external memory cards or so. Yes, this is on purpose. And yes, this is not an interface issue but a design one. My ass.

Fuck you, Apple. Your interface is shit no matter what your fanboys say.

All this is for the touch wheel ones, never used one of these new touch thingies. Yes, I'm an old fart.

Note to Facebook web programmers

When you talk about Entering an URL, you are implying that it's a real URL, that is, a string prefixed by an URL schema (the http+colon+slash+slash funny gibberish). By fixing this in your 'Import blog' option in your Notes application you can save several minutes of time to insignificant morons like me.

Or may be this is just a problem in the spanish translation.

How to enter spanish quotes (« and ») under MS Windows

The crappy way: Alt-174 for « and Alt-175 for ».

The more definitive, but not at all not cumbersome way: download a thing called Microsoft Keyboard Layout Creator from http://www.microsoft.com/downloads/details.aspx?familyid=FB7B3DCD-D4C1-4943-9C74... and create your own keyboard layout, probably using a standard one as template. This program will prepare a .msi installer for you. After executing it go to Control Panel and set your layout as the default one.

You most probably want to set « to AltGr-Z and » to AltGr-X, as any Linux user know and love.

Or take my spanish keyboard layout: keybspao.msi with source keybspao.klc.

Update: If you use Windows Vista or 7, you'll need at least Microsoft Keyboard Layout Creator 1.4. My keyboard layout source file is still functional, but you need one of this installers instead:

Overriding mod_rewrite if a file exists

I use mod_rewrite intensively on this site, mainly to make the transition from the old static files layout to this new, dynamic one based on my Gruta CMS. Following the premise that URLs must be eternal, I've used mod_rewrite magic to make old URLs like


still be accesible, but be interally redirected to


Anyway, it may prove useful to only do this redirection if a file with that path and name does not already exist in the filesystem. This can be used, for example, to serve special, manually crafted HTML pages, statistics made by other software, or to 'freeze' a special page to avoid too much server load.

So these are the magic words:

 RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}      -f
 RewriteRule ^ %{DOCUMENT_ROOT}%{REQUEST_URI}    [L]

They must be entered before any other rewriting directives.

What they mean is, if a file exists (-f) with a path formed by the site's document root plus the requested uri, rewrite the query to it and stop rewriting ([L]).

File locking in Perl

File locking in Perl is done with the flock() function. It's portable among architectures, is advisory-only and locks full files.

It accepts two arguments: a file handle and an operation id. As expected, it allows only one writer or many simultaneous readers, with no wait. Locks are automatically released on closing. The usage is simple:

  1. Open the file (for reading or writing).
  2. Call flock() with the file handle, and a second argument of 1 (if reading) or 2 (if writing).
  3. Do whatever operations you do to the file.
  4. Close it.

And that's it. The magic numbers 1 and 2 can also be used as LOCK_* constants imported from the Flock module. The perldoc documentation is comprehensive, take a look at it.

Example reader:

 open F, 'index.db'; # open for reading
  1. lock file. If a writer has it locked, it will
  2. wait until released. Many readers will read the
  3. file simultaneously without blocking. flock F, 1;
 while (<F>) {
    # do things...
  1. lock is released close F;

And a writer:

 open F, '>index.db'; # open for writing
  1. lock file for writing. If there is another reader
  2. or writer using the lock, it will block until
  3. released. flock F, 2;
  1. file is now locked
  2. write stuff to the file...
  1. lock is released; any readers or writers waiting
  2. will unblock and go on with its business close F;

As these locking semantics are advisory-only, anyone can screw everything by writing without locking, so take care.

Showing an intermixed short log of a bunch of git repositories

I store all my git repositories under the same directory, unsurprisingly called ~/git. I needed a way to have a quick list of what I have done in all of them in a given time, so I wrote a script named (probably incorrectly) my-git-metachangelog.sh. This script iterates all subdirectories, finds all that are git repositories, takes a shortlog for all of them, and sorts by date. The fields shown are: date, time, project and the first line of the commit message.

By default, shows the short log for the last 6 months. It accepts an optional unique argument with the number of months to summarize.

This is an example of its output:

 2008-12-11 18:25:29 gruta: Changed all POD docum. in templates to head2.
 2008-12-11 17:04:37 gruta: New templates 'main_top' and 'main_bottom'.
 2008-12-11 10:57:19 grutatxt: The option 'no-pure-verbatim' has been docum.
 2008-12-11 10:25:26 grutatxt: Don't move to 'blockquote' if in 'pre' mode.
 2008-12-11 10:19:44 grutatxt: Strip bold form head2 documentation.
 2008-12-11 10:17:11 grutatxt: 'pod2grutatxt' creates 'NAME' (Closes: #1016).
 2008-12-11 10:08:07 grutatxt: Improved header generation in pod2grutatxt.
 2008-12-11 09:49:30 grutatxt: New '--no-pure-verbatim' mode (Closes: #1015).
 2008-12-10 14:24:06 mp-5.x: Updated TODO.
 2008-12-10 07:25:44 gruta: New field 'description' (Closes:  #1050).
 2008-12-09 20:20:52 mp-5.x: Small documentation tweaks.
 2008-12-09 13:47:48 gruta: More comments in templates.
 2008-12-07 19:58:33 mp-5.x: New syntax color for special doc. blocks.
 2008-12-07 08:42:38 mp-5.x: Version 5.1.1 RELEASED.

And the script:

 # my-git-metachangelog.sh
 # Angel Ortega <angel@triptico.com> - public domain
 [ -z "$MONTHS" ] && MONTHS=6
 for r in *
 	do ([ -d $r ] && cd $r &&
 		git rev-parse HEAD > /dev/null 2>&1 &&
 		git log --no-merges \
 		--since="$MONTHS months ago" \
 		--pretty="format:%ai $r: %s%n")
 	done | \
 grep -v '^$' | sed -e 's/+[0-9][0-9][0-9][0-9] //' | \
 sort -r | less

2010-12-08 update: Fixed to also work on bare repositories.

Calculated columns in PostgreSQL using triggers

Sometimes is useful to have columns that are automatically created using operations with other ones. Certainly this violates the Relational Model, but sometimes you don't have a choice if the database schema was given to you by a legacy system.

In my case, I found a living system with a table like this:

 	first_name VARCHAR,
 	family_name VARCHAR,

It's certainly aberrant; the full_name column is just a concatenation of the other two. For additional fun, it's the primary key.

PostgreSQL makes maintaining this monster easier by using triggers.

First, create the following function (this is in plpgsql, but it could be done in any programming language linked to the PostgreSQL engine):

 CREATE FUNCTION build_user_full_name_func () RETURNS trigger AS '
 	NEW.full_name = NEW.first_name || '' '' || NEW.family_name;
 ' LANGUAGE plpgsql;

What this function does should be obvious: update full_name concatenating the other two columns with a space in between.

The magic is done creating this trigger:

     ON users FOR EACH ROW
     EXECUTE PROCEDURE build_user_full_name_func ();

Whenever users is affected by an INSERT or UPDATE, the trigger is called, and full_name (re)built.

Disallow connections from an IP, in one line

If you are having an attack from an IP and want to ban it right now, use this ban_ip script:

 ban_ip() { iptables -A INPUT -s $1 -j DROP; }

Mouse cursor jumps like crazy under QEMU

Just set the following environment variable: