Through the Looking-Glass
2010-10-12: Through the Looking-Glass
My radio speaks is binary!
2010-10-10: My radio speaks is binary!
Gigaminx: (present for my birthday)
2010-09-16: Gigaminx: (present for my birthday)
Trini on bike
2010-09-05: Trini on bike
2010-08-28: Valporquero
My new bike!
2010-08-22: My new bike!
Mario and Ana's wedding
2010-08-13: Mario and Ana's wedding
Canyoning in Guara
2010-08-07: Canyoning in Guara
Trini and Mari in Marbella
2010-08-05: Trini and Mari in Marbella
Trini and Chelo in Tabarca
2010-08-03: Trini and Chelo in Tabarca
Valid XHTML 1.1
Log in

Let's say you have a venti server and you would like to mirror its contents to another one. How to do it?

First, you will need to have another venti configured. Please look at the venti(8) manual page to know how to do it, or see my post on how to set up a venti server. Please note that, if you want to run both servers at the same time, and if they are in the same machine, they must listen to different port numbers.

There are several ways to copy the contents of a venti server into another:

  • venti-copy

    With venti-copy you can copy an entire tree of blocks from one venti server to another. Both servers must be running in order to copy the blocks.

    If you have the list of scores all the trees in the file scores.txt, you could use the following command to start copying:

    cat scores.txt | while read score ; do venti-copy $venti1 $venti2 $a ; done

    Advantages: you don't need to stop either server; arena partitions in each server can have different geometry

    Disadvantages: it is very slow, and you need to know a priori the list of VtRoot scores you want to copy.

  • venti-mirrorarenas

    This command can be used to copy every arena from one arena partition to another. Both servers should be stopped.

    Advantages: it is very fast, and there are several tests to check that the arena geometries are the same.

    Disadvantages: it only works if source and destination have exactly the same number of arenas of the same size; after finishing the copy, you must use venti-buildarenas in the destination server.

  • venti-rdarena and venti-wrarena

    venti-rdarena reads one arena from a venti server and writes it to standard output; venti-wrarena writes an arena from a file to a venti server.

    In order to mirror one venti server, you could read all its arenas with venti-rdarena, one by one, and then write them to another server with venti-wrarena. Both servers should be stopped.

    Advantages: it works even if source and destination have different number of arenas; it is faster than venti-copy.

    Disadvantages: it only works if source and destination have arenas of the same size; it is very slow if your venti servers have a lot of arenas (each invocation of these executables read all the arena map); after finishing the copy, you must use venti-buildarenas in the destination server.

  • Copy all the arenas by hand

    If you figure out the position in the arena partition of each arena, and its size, you can yust copy the arenas with dd. Both servers should be stopped.

    For example, if you formatted the arena partitions with the default arenasize and blocksize, then the arenas will have 512MB (536870912 bytes), and will be located in the position 794624 + 536870912*n. So, you could use the following loop to copy arenas $start to $end, from file $orig to $dest:

    for i in $( seq $start $end )
      echo "Copying arena $i from $start to $end..."
      skip=$(( 97 + $i * 65536 ))
      dd if="$orig" bs=8192 skip=$skip count=65536 seek=$skip of="$dest"

    Advantages: it is very fast.

    Disadvantages: it only works if source and destination have arenas of the same size; you have to make sure that the arenas are located exactly where you are reading and writting them; after finishing the copy, you must use venti-buildarenas in the destination server.

Sometimes we need to reduce the size of a PDF file, without altering its content and without having access to the source code.

In order to do that, we can use gs this way:

     gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen \
       -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf

-dPDFSETTINGS=/screen option is used to specify that we want the PDF optimized to be displayed on a screen, reducing its size while loosing images quality.

We can specify /ebook instead of /screen to have a slightly better image quality, but still reducing file size.

Since a few years ago, it is beginning to be very common to have hundreds of connection attempts to SSH port, trying common usernames and passwords.

This has several drawbacks: log files can be filled up, SSH service can be irresponsible and, what is worst, some of the attacks could be successful if one of your users has a weak password.

To prevent those attacks, you can use these simple iptables rules that forbid establishing more than 6 connections per minute from every IP:

iptables -N SSH_CHECK
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSH_CHECK
iptables -A SSH_CHECK -m recent --set --name SSH
iptables -A SSH_CHECK -m recent --update --seconds 60 --hitcount 6 --name SSH -j DROP
Labels: LaTeX how-to

In LaTeX there are 10 special characters:

# $ % & \ ^ _ { } ~

Most of them can be escaped prepending a simple backslash, but \, ^ and ~ need special treatment:

  • for backslash (\) use \textbackslash{}
  • for caret (^) use \^{} or \textasciicircum{}
  • and for tilde (~) use \~{} or \textasciitilde{}

In short:

To getYou must use
Labels: emacs how-to

If you want to make GNU Emacs fullscreen, there are three things you should do:

  • Disable tool bar
    This can be accomplished executing (inside Emacs) (tool-bar-mode -1)
  • Disable menu bar
    This can be done executing (menu-bar-mode -1)
  • Go to full screen mode
    You have to execute (set-frame-parameter nil 'fullscreen 'fullboth)

If you want to disable always tool bar and menu bar, like me, and you want to be able to go to full screen with a keystroke (F11, for example), add this to your .emacs:

;; F11 = Full Screen
(defun toggle-fullscreen (&optional f)
  (let ((current-value (frame-parameter nil 'fullscreen)))
    (set-frame-parameter nil 'fullscreen
      (if (equal 'fullboth current-value)
        (if (boundp 'old-fullscreen) old-fullscreen nil)
        (progn (setq old-fullscreen current-value)
(global-set-key [f11] 'toggle-fullscreen)

;; Disable tool-bar
(tool-bar-mode -1)

;; Disable Menu Bar
(menu-bar-mode -1)

If you want to have a file crypted, so that noone can see its contents unless they have the correct password, you can use "gpg" to cypher or decypher it. However, its use is a bit complicated.

So, I decided to write a small shell script, called "gpg-vi", which asks for a password, and lets you edit a file, symmetrically crypted using GnuPG with that password.

The script will not let anyone else in that machine to see the contents of the file, but warning: the script writes the contents of the file in plain in a file in /tmp, so that your user id, or root, can see that file until the edition is finished (or even later, because the contents may still be there in the disk after deleting the file).

Labels: SQL Perl how-to

(or, how to use History Tables in PostgreSQL)

If you would like to store somewhere the full history of all the insertions, updates and deletions in all your tables (to maintain a wiki-like database), there is no simple way to do it... but here you can find a way to do it, in an article written by Thomas Liske.

It works in PostgreSQL, creating a PL/Perl database trigger called log_history() which adds a line to a new table called history.<SCHEMA>_<TABLENAME> with a timestamp (hist_ts), the operation (hist_op) and all the columns, whenever a INSERT, UPDATE or DELETE is executed. This effectively stores all the history of the tables where the trigger is used.

Here you can view the log_history trigger, and a simple function to bind the trigger on all the tables in a schema, history_create_triggers. You can call this function for schema "public" with SELECT history_create_triggers('public');

These two functions are written in PL/Perl and PL/pgSQL, respectively, so you have to add those language to your PostgreSQL database, if you have not already done so, with CREATE LANGUAGE plperl; and CREATE LANGUAGE plpgsql;

Labels: funny Rubik how-to
  1. Solve the white edges. The resulting cube should look like this:
  2. Solve the white corners:
  3. Second layer. Turn the cube upside down, so that the white face is at the bottom. Then, place all the edges in their correct position, except the yellow ones, so that the first two layers are finished:
    U R U R' U' F' U' F U' L' U' L U F U F'
  4. Orient yellow edges:
    F U R U' R' F' F R U R' U' F'
  5. Position yellow corners:
    L U' R' U L' U' R U2
  6. Orient yellow corners:
    R U R' U R U2 R' U2 R' U' R U' R' U2 R U2
  7. Position yellow edges:
    R2 U F B' R2 F' B U R2 R2 U' F B' R2 F' B U' R2
Labels: LaTeX how-to

Sometimes, when writing LaTeX documents, we find out lines too long, the so-called "overfull" lines, because LaTeX does not correctly divides words. To fix this, there are three parameters we can change: \pretolerance, \tolerance and \emergencystretch.

\pretolerance is used to tell the processor when there is too much space between words, and an attempt should be made to hyphenate some of them; \tolerance is used to indicate when there is too much space even after breaking words.

If we want to avoid breaking words, and avoid having too long lines, we have to use a very high value for \pretoletance. An “infinite” tolerance is represented by the value 10000.

In order to change its value, we have to add the line: