<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Julius' Blog (en)</title>
  <link href="http://blog.plenz.com/en/atom.xml" rel="self" />
  <link href="http://blog.plenz.com/en/" />
  <updated>2012-02-22T23:18:56+01:00</updated>
  <id>http://blog.plenz.com</id>
  <author>
    <name>Julius Plenz</name>
    <email>blog@plenz.com</email>
  </author>
  
  <entry>
    <title type="html">&quot;Shouting in the Dark&quot;</title>
    <link href="http://blog.plenz.com/2012-02/shouting-in-the-dark.html" />
    <updated>2012-02-21T15:56:00+01:00</updated>
    <id>http://blog.plenz.com/2012-02/shouting-in-the-dark</id>
    <content type="html">&lt;p&gt;Al Jazeera's documentary about the Bahrain protests, &lt;em&gt;Shouting in the Dark&lt;/em&gt;,
&lt;a href=&quot;http://www.aljazeera.com/news/middleeast/2012/02/201222184931745785.html&quot;&gt;has received a prestigeous award&lt;/a&gt;.
The documentary is really worth watching.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/xaTKDMYOBOU&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;


&lt;p&gt;I found the insidious practices of the Bahraini prince &amp;ndash; and the Arab
league's suport &amp;ndash; extremely unnerving.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">C Programming Exam Fail</title>
    <link href="http://blog.plenz.com/2012-02/c-programming-exam-fail.html" />
    <updated>2012-02-17T15:26:00+01:00</updated>
    <id>http://blog.plenz.com/2012-02/c-programming-exam-fail</id>
    <content type="html">&lt;p&gt;I just wrote an exam for the course &lt;em&gt;Technische Informatik III&lt;/em&gt; which was about
operating systems and network communication. In the exercises throughout the
semster, we &lt;a href=&quot;http://git.plenz.com/ti3/&quot;&gt;had to program in C a lot&lt;/a&gt;. Naturally,
in the exam was one task about interpreting what a C program does.&lt;/p&gt;

&lt;p&gt;It was really simple: Listening on a UDP socket and print incoming packets
along with source address and port. The program looked somewhat like this (from
what I remember; also some things were done in a not so clever way on the exercise
sheet, and they had obfuscated the variable names to a non-descriptive
&lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, etc.):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/socket.h&amp;gt;
#include &amp;lt;netinet/in.h&amp;gt;
#include &amp;lt;arpa/inet.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;error.h&amp;gt;

int main(int argc, char *argv[])
{
    int sockfd;
    struct sockaddr_in listen, incoming;
    socklen_t incoming_len;

    char buf[1024];
    int len; /* of received data */

    /* listen on 0.0.0.0:5000 */
    listen.sin_family = AF_INET;
    listen.sin_addr.s_addr = INADDR_ANY;
    listen.sin_port = htons(5000);

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        perror(&quot;socket&quot;);

    if(bind(sockfd, (struct sockaddr *) &amp;amp;listen, sizeof(listen)) == -1)
        perror(&quot;bind&quot;);

    while(1) {
        len = recvfrom(sockfd, buf, 1024, 0, (struct sockaddr *) &amp;amp;incoming,
                        &amp;amp;incoming_len);
        buf[len] = '\0';
        printf(&quot;from %s:%d: \&quot;%s\&quot;\n&quot;, inet_ntoa(incoming.sin_addr),
                ntohs(incoming.sin_port), buf);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I lol'd so hard when I saw this. It's a classic off-by-one error. (Can
you spot it, too?)&lt;/p&gt;

&lt;p&gt;If you want to store &lt;em&gt;x&lt;/em&gt; bytes of data in a string, reserve &lt;em&gt;x+1&lt;/em&gt;
bytes for the NULL termination character. Here, if you send a message
that is exactly 1024 bytes long (or longer, as it'll get truncated),
&lt;code&gt;buf[len]&lt;/code&gt; will actually be the 1025&lt;sup&gt;th&lt;/sup&gt; byte. Which might
just be anything.&lt;/p&gt;

&lt;p&gt;And those guys want to teach network and filesystem programming
&amp;ndash; hilarious. :-D&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">minimizing Linux filesystem cache effects</title>
    <link href="http://blog.plenz.com/2012-02/minimizing-linux-filesystem-cache-effects.html" />
    <updated>2012-02-09T23:43:00+01:00</updated>
    <id>http://blog.plenz.com/2012-02/minimizing-linux-filesystem-cache-effects</id>
    <content type="html">&lt;p&gt;Last weekend I toyed around a bit and tried to write a &lt;a href=&quot;https://github.com/Feh/nocache&quot;&gt;shared object
library that can be used via &lt;code&gt;LD_PRELOAD&lt;/code&gt; to minimize the effect a
program has on the Linux filesystem
cache&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Basically the use case is that you have a productive system running,
and you don't want your backup script to fill the filesystem cache
with mostly useless information at night (files that were cached
should stay cached). I didn't test whether this
brings measurable improvements yet.&lt;/p&gt;

&lt;p&gt;The coding was really fun and provided me with yet another insight how
the simple concept of file descriptors in UNIX is just great. (GNU
software is tough, though: I got stuck once, and &lt;a href=&quot;http://stackoverflow.com/questions/9161116/intercepting-the-openat-system-call-for-gnu-tar&quot;&gt;found help on
Stackoverflow&lt;/a&gt;,
which I had never used before.)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">shredding</title>
    <link href="http://blog.plenz.com/2012-01/shredding.html" />
    <updated>2012-01-30T14:09:00+01:00</updated>
    <id>http://blog.plenz.com/2012-01/shredding</id>
    <content type="html">&lt;p&gt;I'm currently &lt;a href=&quot;http://man.cx/shred&quot;&gt;shred&lt;/a&gt;ding my old X41's hard drive, because
I want to sell it (if you are interested, contact me). I'm overwriting it with
zeros, ten passes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ shred -vfz -n 10 /dev/sda
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Luckily, the disk was fully encrypted all the time. So it's just a precaution.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/img/x41-shred.jpg&quot;&gt;&lt;img src=&quot;/img/x41-shred.thumb.jpg&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Ten Years of Vim</title>
    <link href="http://blog.plenz.com/2012-01/ten-years-of-vim.html" />
    <updated>2012-01-30T02:17:00+01:00</updated>
    <id>http://blog.plenz.com/2012-01/ten-years-of-vim</id>
    <content type="html">&lt;p&gt;About ten years ago, I began using &lt;a href=&quot;http://www.vim.org/&quot;&gt;Vim&lt;/a&gt;. Since
about eight years ago, I have been using Vim for every email, every
piece of code, literally &lt;em&gt;every&lt;/em&gt; text I write. Today,
I want to write a short text about how I came to use Vim and what I
like about it.&lt;/p&gt;

&lt;p&gt;I don't really remember when I first used Vim. It must have been
around the time when I was programming PHP a lot. I had access
to a &quot;real&quot; computer at home &amp;ndash; running Windows XP &amp;ndash; in
2002 for the first time; before that, I could only use older
Macintoshs. It's typical for first-time Vi users to stumble into
believing &amp;ndash; by hear-say, I guess &amp;ndash; that it is indeed a
&lt;em&gt;really&lt;/em&gt; superior editor, until &lt;em&gt;they try it out the first time and
can't even save&lt;/em&gt;, because they don't know how to. That were my
first experiences too, probably.&lt;/p&gt;

&lt;p&gt;Anyhow, at some point in time I ditched &lt;a href=&quot;http://www.zend.com/products/studio/&quot;&gt;PHP Zend
Studio&lt;/a&gt; for
&lt;a href=&quot;http://www.scintilla.org/SciTE.html&quot;&gt;SciTE&lt;/a&gt;. Later, I got to know Vim
(i.e., by reading a tutorial about it and actually understanding it)
and was instantly hooked. Probably, the guys over at
&lt;a href=&quot;http://www.html-q.net/&quot;&gt;#html.de&lt;/a&gt; talked me into it. Ironically, I
used Vim before I ever used a UNIX-like operating system.&lt;/p&gt;

&lt;p&gt;In my Vim learning curve, I identify seven important advances:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Understanding the Modes Concept.&lt;/em&gt; &amp;ndash; This, of course, is
something everybody needs to grok. It's fairly straight-forward,
once you think about it.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Understand the Visual Mode and Yank/Paste.&lt;/em&gt; &amp;ndash; Line-wise
selection already gives you more power than a regular editor when
moving code.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Understand Mappings and Macros.&lt;/em&gt; &amp;ndash; Even today I am amazed
how few people automate things. If it's one line, do it manually.
If it's three lines, carefully think about the task &lt;em&gt;while
recording a macro for it&lt;/em&gt;!&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Unterstanding Windows.&lt;/em&gt; &amp;ndash; Multiple files and stuff.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Consequently using [h], [j], [k], [l].&lt;/em&gt; &amp;ndash; This actually was
a much bigger step that you might think. I went to great lengths to
achive this: &lt;a href=&quot;http://git.plenz.com/configs/tree/.vimrc?id=8609adce1234194c5481e4e196684374bc80cbea#n127&quot;&gt;I configured the arrow mapping to &lt;code&gt;:echoerr&lt;/code&gt; a
message.&lt;/a&gt;
Today, I configure all programs to use Vim key bindings, especially
for horizontal and vertical navigation. It's the first thing to do.
I only use the arrow keys for Mplayer seeking.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Using Text Objects.&lt;/em&gt; &amp;ndash; See &lt;code&gt;:help text-objects&lt;/code&gt;, if you
don't know about them.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Switching to a US keyboard layout.&lt;/em&gt; &amp;ndash; Once you do this, all
the Vim commands begin to make sense. (I used a German layout
before.)&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Steps 1&amp;ndash;5 happened in the first two years. The text object only
came with more recent Vim development, and I'm not quite sure when I
adopted them. Learning the US layout was around 2006, maybe.&lt;/p&gt;

&lt;p&gt;When I switched to using Debian in 2004, using Vim for all tasks
already felt natural. Of course, at that point I finally came to
understand Vim not merely as a text editor, but as a &lt;em&gt;philosophy&lt;/em&gt;.
And that is what fascinates me to this day: The Vi way of editing text
is much more than a set of clever key bindings. It's a
&lt;a href=&quot;http://stevelosh.com/blog/2010/09/coming-home-to-vim/#a-language-of-text-editing&quot;&gt;language&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/vi-ned.jpg&quot; style=&quot;float:right;margin:0 0 .2em .5em&quot;
title=&quot;Oh, Ned! You are a Vi man after all!&quot; alt=&quot;Vi-vs.-Emacs fight&quot; /&gt;
In a way, I'm really professional at using Vim. If I think of the
tasks I do, I suspect there are very few superfluous keys I press
during editing. I have acquired a really good intuition of how to skip
to a particular line, to a particular function parameter or a certain
word in a sentence. (I use [H], [M], [L] for global on-screen
navigation a lot, and I heavily use the [f], [t], [F] and [T] jump
commands.) Just as you don't actually think about the letters you type
when you become a good typist, I don't think about what command keys I
press in Normal mode. I just press them, and the cursor magically
moves around to where my eyes rest. This is good.&lt;/p&gt;

&lt;p&gt;On the other hand, I am just using core Vim features, most of which
are already found in original Vi implementations. My really
&lt;a href=&quot;https://github.com/Feh/configs/commits/master/.vimrc&quot;&gt;conservative .vimrc change history&lt;/a&gt;
shows that I pretty much settled my editing habits. &amp;ndash; But: &lt;em&gt;I have
never used a third-party plugin before.&lt;/em&gt; Strange as it may sound, I
never felt the urge to do so.
&lt;a href=&quot;https://wincent.com/products/command-t&quot;&gt;Command-T&lt;/a&gt; certainly looks
like it could be of use; however, I usually start a new Vim instance
and go with the Z Shell completion, which I suspect to be superior in
more than one way, to find the file(s). &amp;ndash; Thus I must acknowledge
that there might be vast possibilities yet do discover. (Oh, and while
confessing, there's another big one: I have never used
Emacs. All I know about it is hear-say.)&lt;/p&gt;

&lt;p&gt;For keyboard enthusiasts, there are two quirks with Vim: It mainly
relies on Escape for mode switches, and the keys for many
combinations are aligned for QWERTY layouts. There's just no way
around it: while [c] and [d] are mnemonic for &lt;em&gt;cut&lt;/em&gt; and &lt;em&gt;delete&lt;/em&gt;, [h],
[j], [k], [l] simply aren't. There's no way justify their use when
switching to Dvorak, and that's why I didn't (switch). I also once
tried mapping [j][j] to Escape, or using the Caps Lock key as Escape
replacement; I can't really stick to using it. (I also stick to
calling &lt;code&gt;vim&lt;/code&gt; on the command line instead of a shorter alias. It is
the fourth most command I type, after &lt;code&gt;sudo&lt;/code&gt;, &lt;code&gt;git&lt;/code&gt;, and &lt;code&gt;man&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;For me, text editing is equal to using Vim. I feel like a four-year
old moving a mouse when I'm forced to use another editor on other
people's computers. And because text editing is really clumsy with
regular text editors, I no longer wonder why people don't really
bother to correct errors: the effort is just not worth it.&lt;/p&gt;

&lt;p&gt;If I had to sum up the difference between Vim and other editors in one
sentence, it is this: &lt;em&gt;While other editors are great for creating
text, Vim is also great at &lt;strong&gt;manipulating&lt;/strong&gt; text&lt;/em&gt;. And text
manipulation, for most programmers and authors, is what it's all about.&lt;/p&gt;

&lt;p&gt;:wq&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">vlock and suspend to ram</title>
    <link href="http://blog.plenz.com/2012-01/vlock-and-suspend-to-ram.html" />
    <updated>2012-01-20T19:43:00+01:00</updated>
    <id>http://blog.plenz.com/2012-01/vlock-and-suspend-to-ram</id>
    <content type="html">&lt;p&gt;I've had weird race conditions when using &lt;code&gt;vlock&lt;/code&gt; together with &lt;code&gt;s2ram&lt;/code&gt;. It
appears suspend to ram &lt;a href=&quot;http://lxr.free-electrons.com/source/kernel/power/console.c&quot;&gt;wants to switch
VTs&lt;/a&gt;, while
&lt;code&gt;vlock&lt;/code&gt; hooks into the switch requests and explicitly disables them. So some of
the time, the machine would not suspend, while at other times, &lt;code&gt;vlock&lt;/code&gt; wouldn't
be able to acquire the VT.&lt;/p&gt;

&lt;p&gt;To solve this, I wrote a simple &lt;code&gt;vlock&lt;/code&gt; plugin, which simply clears the lock
mechanism, writes &lt;code&gt;mem&lt;/code&gt; to &lt;code&gt;/sys/power/state&lt;/code&gt; and later reinstates the locking
mechanism. This plugin is called after &lt;code&gt;all&lt;/code&gt; and &lt;code&gt;new&lt;/code&gt;. Thus, the screen will
be locked properly before suspending.&lt;/p&gt;

&lt;p&gt;Here's my &lt;code&gt;suspend.c&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;

/* Include this header file to make sure the types of the dependencies
 * and hooks are correct. */
#include &quot;vlock_plugin.h&quot;
#include &quot;../src/console_switch.h&quot;

const char *succeeds[] = { &quot;all&quot;, &quot;new&quot;, NULL };
const char *depends[] =  { &quot;all&quot;, &quot;new&quot;, NULL };

bool vlock_start(void __attribute__ ((__unused__)) **ctx_ptr)
{
    int fd;

    unlock_console_switch();

    if((fd = open(&quot;/sys/power/state&quot;, O_WRONLY)) != -1) {
        if(write(fd, &quot;mem&quot;, 3) == -1)
            perror(&quot;suspend: write&quot;);
        close(fd);
    }

    lock_console_switch();

    return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Simply paste it to the &lt;code&gt;vlock&lt;/code&gt; modules folder, &lt;code&gt;make suspend.so&lt;/code&gt; and copy it to
&lt;code&gt;/usr/lib/vlock/modules&lt;/code&gt;. I now invoke it like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;env VLOCK_PLUGINS=&quot;all new suspend&quot; vlock
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Xorg, really?!</title>
    <link href="http://blog.plenz.com/2012-01/xorg-really.html" />
    <updated>2012-01-20T13:27:00+01:00</updated>
    <id>http://blog.plenz.com/2012-01/xorg-really</id>
    <content type="html">&lt;p&gt;Are you fucking kidding me? &lt;a href=&quot;http://gu1.aeroxteam.fr/2012/01/19/bypass-screensaver-locker-program-xorg-111-and-up/&quot;&gt;You reintroduce broken behaviour that possibly
has devastating security consequences and and make it &lt;strong&gt;the
default&lt;/strong&gt;?!&lt;/a&gt;
Yeah I agree the &quot;usual&quot; X server locking approach is not the best way to do it
&amp;ndash; but to knowingly smash the security of people's computers on a grand
scale... that's priceless.&lt;/p&gt;

&lt;p&gt;(My locking solution is &lt;code&gt;env USER=feh vlock -a -n&lt;/code&gt;, again.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;a href=&quot;http://who-t.blogspot.com/2012/01/xkb-breaking-grabs-cve-2012-0064.html&quot;&gt;Why it happened&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">zsh: complete words from tmux pane</title>
    <link href="http://blog.plenz.com/2012-01/zsh-complete-words-from-tmux-pane.html" />
    <updated>2012-01-19T20:53:00+01:00</updated>
    <id>http://blog.plenz.com/2012-01/zsh-complete-words-from-tmux-pane</id>
    <content type="html">&lt;p&gt;Today I wrote a rather cool Z-Shell completion function: It will
present all words that are found in the current tmux pane in a zsh
completion menu. That means you can actually complete words from the
&lt;em&gt;output&lt;/em&gt; of commands that you just executed. (In a way it's a little
bit like the &lt;a href=&quot;http://www.opensource.apple.com/source/zsh/zsh-53/zsh/Functions/Zle/keeper&quot;&gt;keeper
function&lt;/a&gt;,
without the overhead of remembering to call &lt;code&gt;keeper&lt;/code&gt; in the first place.)&lt;/p&gt;

&lt;p&gt;The code below defines two keybindings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ctrl-X t&lt;/strong&gt; to do a &lt;em&gt;prefix&lt;/em&gt; completion: only words from the pane
that share the same prefix will be presented&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl-X Ctrl-X&lt;/strong&gt; to do a &quot;find stuff like crazy&quot; completion. If you
see the output and just enter something from the middle of the word,
it'll just as well complete. For example, if you see &lt;code&gt;176.9.247.89&lt;/code&gt;
somewhere in the pane, try typing &lt;code&gt;.9&lt;/code&gt; and hitting Ctrl-X twice.
It'll complete to that IP address.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Here's the code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_tmux_pane_words() {
  local expl
  local -a w
  if [[ -z &quot;$TMUX_PANE&quot; ]]; then
    _message &quot;not running inside tmux!&quot;
    return 1
  fi
  w=( ${(u)=$(tmux capture-pane \; show-buffer \; delete-buffer)} )
  _wanted values expl 'words from current tmux pane' compadd -a w
}

zle -C tmux-pane-words-prefix   complete-word _generic
zle -C tmux-pane-words-anywhere complete-word _generic
bindkey '^Xt' tmux-pane-words-prefix
bindkey '^X^X' tmux-pane-words-anywhere
zstyle ':completion:tmux-pane-words-(prefix|anywhere):*' completer _tmux_pane_words
zstyle ':completion:tmux-pane-words-(prefix|anywhere):*' ignore-line current
zstyle ':completion:tmux-pane-words-anywhere:*' matcher-list 'b:=* m:{A-Za-z}={a-zA-Z}'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How does it work? &lt;code&gt;_tmux_pane_words&lt;/code&gt; will just capture the current
pane's contents (&lt;code&gt;capture-pane&lt;/code&gt;), print out the buffer that
contains it (&lt;code&gt;show-buffer&lt;/code&gt;) and then delete it again
(&lt;code&gt;delete-buffer&lt;/code&gt;). &amp;ndash; The rest of the magic happens via Zsh's
excellent completion mechanisms.&lt;/p&gt;

&lt;p&gt;See it in action (after typing &lt;code&gt;spm^X^X&lt;/code&gt;):&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/2012-01-19-205829_508x163_scrot.png&quot; /&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">trying pthreads</title>
    <link href="http://blog.plenz.com/2012-01/trying-pthreads.html" />
    <updated>2012-01-17T01:37:00+01:00</updated>
    <id>http://blog.plenz.com/2012-01/trying-pthreads</id>
    <content type="html">&lt;p&gt;Today I played around with POSIX threads a little. In an assignment,
we have to implement a very, very simple webserver that does
asynchronous I/O. Since it should perform well, I thought I'd not only
serialize I/O, but also parallelize it.&lt;/p&gt;

&lt;p&gt;So there's a boss that just accepts new inbound connections and
appends the fds to a queue:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;clientfd = accept(sockfd, (struct sockaddr *) &amp;amp;client, &amp;amp;client_len);
if(clientfd == -1)
    error(&quot;accept&quot;);
new_request(clientfd);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;new_request&lt;/code&gt; function in turn appends it to a queue (of size
&lt;code&gt;TODOS&lt;/code&gt; = 64), and emits a &lt;code&gt;cond_new&lt;/code&gt; signal for possibly waiting
workers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pthread_mutex_lock(&amp;amp;mutex);
while((todo_end + 1) % TODOS == todo_begin) {
    fprintf(stderr, &quot;[master] Queue is completely filled; waiting\n&quot;);
    pthread_cond_wait(&amp;amp;cond_ready, &amp;amp;mutex);
}
fprintf(stderr, &quot;[master] adding socket %d at position %d (begin=%d)\n&quot;,
    clientfd, todo_end, todo_begin);
todo[todo_end] = clientfd;
todo_end = (todo_end + 1) % TODOS;
pthread_cond_signal(&amp;amp;cond_new);
pthread_mutex_unlock(&amp;amp;mutex);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The workers (there being 8) will just emit a &lt;code&gt;cond_ready&lt;/code&gt;, possibly
wait until a &lt;code&gt;cond_new&lt;/code&gt; is signalled, and then extract the first
client fd from the queue. After that, a simple function involving some
reads and writes will handle the communication on that fd.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;pthread_mutex_lock(&amp;amp;mutex);
pthread_cond_signal(&amp;amp;cond_ready);
while(todo_end == todo_begin)
    pthread_cond_wait(&amp;amp;cond_new, &amp;amp;mutex);
clientfd = todo[todo_begin];
todo_begin = (todo_begin + 1) % TODOS;
pthread_mutex_unlock(&amp;amp;mutex);

// handle communication on clientfd
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Full source is here: &lt;a href=&quot;http://git.plenz.com/ti3/tree/ueb9/webserver.c&quot;&gt;webserver.c&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;Now this works pretty well and is fairly easy. I'm not very
experienced with threads, though, and run into problems when I do
massive parallel requests.&lt;/p&gt;

&lt;p&gt;If I run &lt;code&gt;ab&lt;/code&gt;, the Apache Benchmark tool with 10,000 requests, 1,000
concurrent, on the webserver it'll go up to 9000-something requests and
then lock up.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ab -n 10000 -c 1000 http://localhost:8080/index.html
...
Completed 8000 requests
Completed 9000 requests
apr_poll: The timeout specified has expired (70007)
Total of 9808 requests completed
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The webserver is blocked; its last line of output reads like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[master] Queue is completely filled; waiting
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If I attach strace while in this blocking state, I get this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ strace -fp `pidof ./webserver`
Process 21090 attached with 9 threads - interrupt to quit
[pid 21099] recvfrom(32,  &amp;lt;unfinished ...&amp;gt;
[pid 21098] recvfrom(23,  &amp;lt;unfinished ...&amp;gt;
[pid 21097] recvfrom(31,  &amp;lt;unfinished ...&amp;gt;
[pid 21095] recvfrom(35,  &amp;lt;unfinished ...&amp;gt;
[pid 21094] recvfrom(34,  &amp;lt;unfinished ...&amp;gt;
[pid 21093] recvfrom(33,  &amp;lt;unfinished ...&amp;gt;
[pid 21092] recvfrom(26,  &amp;lt;unfinished ...&amp;gt;
[pid 21091] recvfrom(24,  &amp;lt;unfinished ...&amp;gt;
[pid 21090] futex(0x6024e4, FUTEX_WAIT_PRIVATE, 55883, NULL
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So the children seem to be starving on unfinished &lt;code&gt;recv&lt;/code&gt; calls, while
the master thread waits for any children to work away the queue. (With
a queue size of 1024 and 200 workers I couldn't reproduce the
situation.)&lt;/p&gt;

&lt;p&gt;How can one counteract this? Specify a timeout? Spawn workers on
demand? Set the &lt;code&gt;listen()&lt;/code&gt; backlog argument to a low value? &amp;ndash; or
is it all Apache Benchmark's fault? *confused*&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">mutt sidebar patch improvements</title>
    <link href="http://blog.plenz.com/2012-01/mutt-sidebar-patch-improvements.html" />
    <updated>2012-01-08T19:32:00+01:00</updated>
    <id>http://blog.plenz.com/2012-01/mutt-sidebar-patch-improvements</id>
    <content type="html">&lt;p&gt;It is generally accepted as an almost universal truth that mutt sucks,
but is the MUA that sucks less than all others. While people use
either Vim or Emacs and fight about it, I hardly see any people fight
about whether mutt is good or bad. There is, to my knowledge, no
alternative worth mentioning.&lt;/p&gt;

&lt;p&gt;Mutt dates back well into the mid-nineties. As you might imagine, with
lots of contributors over the course of almost two decades, the
code quality is rather messy.&lt;/p&gt;

&lt;p&gt;When development had stalled for quite a while in the mid-2000's, a
&lt;a href=&quot;http://synflood.at/blog/index.php?/archives/337-Forking-mutt.html&quot;&gt;fork was attempted&lt;/a&gt;.
While mutt-ng was quite popular for a while, most changes were
incorporated back into mainline mutt at some point.
(Ironically, the latest article in the &lt;a href=&quot;http://mutt-ng.supersized.org/&quot;&gt;mutt-ng development
blog&lt;/a&gt; is from October 2006 and is
titled &quot;mutt-ng isn't dead!&quot;). The development of main mutt gained
some momentum again, triggered in large parts by the
contributions of late Rocco Rutte.&lt;/p&gt;

&lt;p&gt;I remember two big features that the original mutt authors just
wouldn't integrate into mainline: The headercache patch and the
sidebar patch. About the former I can't say anything, but lately I've
been fixing the Sidebar patch in various places. (We use mutt at work
and rely heavily on e-mail communication, so we'd like a bug-free user
agent, naturally.)&lt;/p&gt;

&lt;p&gt;When all the mutt forking went about five years ago, I didn't know
much about it. Retrospectively, I see the people did a hell of a job.
Long before mutt-ng was forked, &lt;a href=&quot;http://guckes.net/&quot;&gt;Sven&lt;/a&gt; told me he
and &lt;a href=&quot;http://michael-prokop.at/&quot;&gt;Mika&lt;/a&gt; met in Graz for several weeks to
sift and sort through the availbale patches, intending to do a &quot;super
patch&quot;.&lt;/p&gt;

&lt;p&gt;Mutt's code quality is arguably rather messy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There's a wild mix of 2-, 4- or 8-space indentation, often mixed
with spaces (or vice versa)&lt;/li&gt;
&lt;li&gt;The user interface is &lt;em&gt;completely&lt;/em&gt; tangled with application logic&lt;/li&gt;
&lt;li&gt;It uses curses directly. Go figure&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;On top of that, the Sidebar patch tries to make it even worse. Imagine
this: mutt draws a mail from position (line=x,char=0) to the end of
the line. Now the sidebar patch will introduce a left &quot;margin&quot;, such
that the sidebar can be drawn there. Thus, all code parts where a line
is started from the leftmost character has to be rewritten to check
if the sidebar is active and possibly start drawing at
(line=x,char=20).&lt;/p&gt;

&lt;p&gt;The sidebar code quality is a fringe case of bad code. Really, it
sucks. However, there's no real way to &quot;do it right&quot;, since original
mutt never planned for a sidebar.&lt;/p&gt;

&lt;p&gt;Who maintains the sidebar patch? &amp;ndash; Not sure. There's a version
at &lt;a href=&quot;http://thomer.com/mutt/&quot;&gt;thomer.com&lt;/a&gt;, but he says:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;July 20, 2006&lt;/strong&gt; I quit. Sadly, there seems to be no desire
to absorb the sidebar patch into the main source tree.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The most up-to-date version is found at
&lt;a href=&quot;http://www.lunar-linux.org/mutt-sidebar/&quot;&gt;Lunar Linux&lt;/a&gt;. Last update
is from mid-2009.&lt;/p&gt;

&lt;p&gt;Debian offers a &lt;code&gt;mutt-patched&lt;/code&gt;
&lt;a href=&quot;http://packages.debian.org/mutt-patched&quot;&gt;package&lt;/a&gt; that includes the
sidebar patch, albeit in a different version than usually found 'round
the net. In short, this patch is a mess, too.&lt;/p&gt;

&lt;p&gt;But since I made all the fixes, I decided to contact the
package's maintainer, Antonio Radici. He promptly responded and said
he'd happily fix all the issues, so I started by opening two
&lt;a href=&quot;http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=646941&quot;&gt;bug&lt;/a&gt;
&lt;a href=&quot;http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=646942&quot;&gt;reports&lt;/a&gt;.
Nothing has happened since.&lt;/p&gt;

&lt;p&gt;The patches run quite stable for my colleagues, so I think it's best
to release them. Maybe someone else can use them. Please note that I
have absolutely no interest in taking over any Sidebar patch
maintainance. ;-)&lt;/p&gt;

&lt;p&gt;For some of the patches I provide annotations. They all feature quite
descriptive commit messages, and apply cleanly on top of the
&lt;a href=&quot;http://anonscm.debian.org/gitweb/?p=pkg-mutt/mutt.git&quot;&gt;Debian mutt repository&lt;/a&gt;'s
master branch.&lt;/p&gt;

&lt;p&gt;The first four patches are not by me, they are just the corresponding
patches from the &lt;code&gt;debian/patches/&lt;/code&gt; directory applied to have a
starting point.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0001-applying-debian-patches-mutt-patched-multiple-fcc.patch&quot;&gt;0001-applying-debian-patches-mutt-patched-multiple-fcc.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0002-applying-debian-patches-mutt-patched-sidebar.patch&quot;&gt;0002-applying-debian-patches-mutt-patched-sidebar.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0003-applying-debian-patches-mutt-patched-sidebar-dotted.patch&quot;&gt;0003-applying-debian-patches-mutt-patched-sidebar-dotted.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0004-applying-debian-patches-mutt-patched-sidebar-sorted.patch&quot;&gt;0004-applying-debian-patches-mutt-patched-sidebar-sorted.patch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The first few patches fix rather trivial bugs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0005-Fix-sidebar-compilation-errors-on-IRIX-systems.patch&quot;&gt;0005-Fix-sidebar-compilation-errors-on-IRIX-systems.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0006-Fix-counting-of-flagged-mails-in-mboxes.patch&quot;&gt;0006-Fix-counting-of-flagged-mails-in-mboxes.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0007-Fix-various-sidebar-drawing-issues.patch&quot;&gt;0007-Fix-various-sidebar-drawing-issues.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0008-Fix-setting-CurrBuffy-when-invoking-mutt-via-f.patch&quot;&gt;0008-Fix-setting-CurrBuffy-when-invoking-mutt-via-f.patch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Now come the performance critical patches. They are the real reason I
was assigned the task to repair the sidebar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0009-cache-time-when-sidebar-last-counted-all-the-mails.patch&quot;&gt;0009-cache-time-when-sidebar-last-counted-all-the-mails.patch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;This patch fixes a &lt;em&gt;huge&lt;/em&gt; speed penalty. Previously, the sidebar would
count the mails (and thus read through the whole mbox) &lt;em&gt;every time
that mtime &gt; atime&lt;/em&gt;! This is just an incredible oversight by the
developer and must have burned hundreds of millions of CPU cycles.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;This introduces a member `sb_last_checked' to the BUFFY struct. It
will be set by `mh_buffy_update', `buffy_maildir_update' and
`buffy_mbox_update' when they count all the mails.

Mboxes only: `buffy_mbox_update' will not be run unless the
condition &quot;sb_last_checked &amp;gt; mtime of the file&quot; holds. This solves
a huge performance penalty you obtain with big mailboxes. The
`mx_open_mailbox' call with the M_PEEK flag will *reset* mtime and
atime to the values from before. Thus, you cannot rely on &quot;mtime &amp;gt;
atime&quot; to check whether or not to count new mail.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also, don't count mail if the sidebar is not active:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0010-only-count-mail-if-sidebar-is-active.patch&quot;&gt;0010-only-count-mail-if-sidebar-is-active.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0011-buffy-check-msg_unread-if-sidebar-is-active.patch&quot;&gt;0011-buffy-check-msg_unread-if-sidebar-is-active.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0012-fix-sidebar-and-buffy-updates.patch&quot;&gt;0012-fix-sidebar-and-buffy-updates.patch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Then, I removed a lot of cruft and simply stupid design. Just consider
one of the functions I removed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-static int quick_log10(int n)
-{
-        char string[32];
-        sprintf(string, &quot;%d&quot;, n);
-        return strlen(string);
-}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That is just insane.&lt;/p&gt;

&lt;p&gt;Now, customizing the sidebar format is simple, straight-forward and
mutt-like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sidebar_format

    Format string for the sidebar. The sequences `%N', `%F' and
    `%S' will be replaced by the number of new or flagged messages
    or the total size of the mailbox. `%B' will be replaced with
    the name of the mailbox. The `%!' sequence will be expanded to
    `!' if there is one flagged message; to `!!' if there are two
    flagged messages; and to `n!' for n flagged messages, n&amp;gt;2.
&lt;/code&gt;&lt;/pre&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0013-introduce-sidebar_format-option.patch&quot;&gt;0013-introduce-sidebar_format-option.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0014-introduce-sidebar_folderindent-option.patch&quot;&gt;0014-introduce-sidebar_folderindent-option.patch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;While investigating mutt's performance, one thing struck me: To decode
a mail (eg. from Base64), mutt will create a temporary file and print
the contents into it, later reading them back. This also happens &lt;strong&gt;for
evaluating filters that determine coloring&lt;/strong&gt;. For example,&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;color   index  black green  '~b Julius'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will highlight mail containg my name in the body in bright green (this
is tremendously useful). However, for displaying a message in the
index, it will be decoded to a temporary file and later read back.
This is just insane, and clearly a sign that the mutt authors wouldn't
bother with dynamic memory allocation.&lt;/p&gt;

&lt;p&gt;By chance I found a glib-only function &lt;code&gt;fmemopen()&lt;/code&gt;,
&lt;a href=&quot;http://linux.die.net/man/3/fmemopen&quot;&gt;&quot;fmemopen, open_memstream, open_wmemstream - open memory as stream&quot;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;From the commit message:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;When searching the header or body for strings and the
`thorough_search' option is set, a temp file was created, parsed,
and then unlinked again. This is now done in memory using glibc's
open_memstream() and fmemopen() if they are available.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes mutt respond much more rapidly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0015-keep-buffer-like-temp-file-in-memory.patch&quot;&gt;0015-keep-buffer-like-temp-file-in-memory.patch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Finally, there are some patches that fix various other issues, see
commit message for details.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0016-Bugfix-use-realpath-on-initial-folder.patch&quot;&gt;0016-Bugfix-use-realpath-on-initial-folder.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0017-Sidebar-Copy-numbers-before-leaving-mailbox.patch&quot;&gt;0017-Sidebar-Copy-numbers-before-leaving-mailbox.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0018-Fix-Buffy-Sidebar-and-mail_check_recent-issues.patch&quot;&gt;0018-Fix-Buffy-Sidebar-and-mail_check_recent-issues.patch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0019-Copy-number-of-flagged-messages-when-leaving-mbox.patch&quot;&gt;0019-Copy-number-of-flagged-messages-when-leaving-mbox.patch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;There you go. I appreciate any comments or further improvements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 1:&lt;/strong&gt; The original author contacted me. He told me he's written most of
the code in a single sitting late at night. ;-)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 2:&lt;/strong&gt; The 16&lt;sup&gt;th&lt;/sup&gt; patch will make mutt crash when you compile it with &lt;code&gt;-D_FORTIFY_SOURCE=2&lt;/code&gt;. There's a fix:
&lt;a href=&quot;http://plenz.com/tmp/mutt-sidebar-patches/0020-use-PATH_MAX-instead-of-_POSIX_PATH_MAX-when-realpat.patch&quot;&gt;0020-use-PATH_MAX-instead-of-_POSIX_PATH_MAX-when-realpat.patch&lt;/a&gt; (thanks, Jakob!)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">tmux session names</title>
    <link href="http://blog.plenz.com/2012-01/tmux-session-names.html" />
    <updated>2012-01-03T17:47:00+01:00</updated>
    <id>http://blog.plenz.com/2012-01/tmux-session-names</id>
    <content type="html">&lt;p&gt;Usually, I name my tmux sessions according to what project I'm working on. To
attach a specific session, I use a custom &lt;code&gt;tm&lt;/code&gt; function, with the appropriate
completion:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# 2011-10-19: tmux shortcut for creating/attaching named sessions
  tm() {
    [[ -z &quot;$1&quot; ]] &amp;amp;&amp;amp; { echo &quot;usage: tm &amp;lt;session&amp;gt;&quot; &amp;gt;&amp;amp;2; return 1; }
    tmux has -t $1 &amp;amp;&amp;amp; tmux attach -t $1 || tmux new -s $1
  }

# 2011-10-19
# stolen from completion function _tmux
  function __tmux-sessions() {
      local expl
      local -a sessions
      sessions=( ${${(f)&quot;$(command tmux list-sessions)&quot;}/:[ $'\t']##/:} )
      _describe -t sessions 'sessions' sessions &quot;$@&quot;
  }
  compdef __tmux-sessions tm
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It looks like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/tmux-session-completion.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A colleague use this, but with a modification. If &lt;code&gt;[[ -z &quot;$1&quot; ]]&lt;/code&gt;, he'll simply
do a &lt;code&gt;tmux attach&lt;/code&gt;, which will attach the last recently used session.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Happy New Year!</title>
    <link href="http://blog.plenz.com/2011-12/happy-new-year.html" />
    <updated>2011-12-31T17:05:00+01:00</updated>
    <id>http://blog.plenz.com/2011-12/happy-new-year</id>
    <content type="html">&lt;p&gt;I started this blog exactly one year ago. Over the course of this
year, I wrote 105 articles. That is not really much, and I want to
write more &amp;ndash; just about the stuff that's on my mind. So stay
tuned. ;-)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/blogstats-one-year.png&quot; alt=&quot;Usage statistics for
blog.plenz.com&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A Happy New Year to all my readers!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Old DVDs and mplayer</title>
    <link href="http://blog.plenz.com/2011-12/old-dvds-and-mplayer.html" />
    <updated>2011-12-29T22:37:00+01:00</updated>
    <id>http://blog.plenz.com/2011-12/old-dvds-and-mplayer</id>
    <content type="html">&lt;p&gt;I was just watching an old DVD of mine (from 2003), but was annoyed that the
video had &quot;hardcoded&quot; black bars at the top and the bottom and was in
interlaced format. A fast motion looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/img/mplayer-standard.png&quot;&gt;&lt;img
src=&quot;/img/mplayer-standard.thumb.png&quot; alt=&quot;In motion, no deinterlacing, boders&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But mplayer can do everything! You just need to know how. Here it is: Use the
&lt;code&gt;cropdetect&lt;/code&gt; video filter, skip to the actual video and let it run for a while
(it will detect the black areas that don't change). Then copy the output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mplayer -vf cropdetect dvd://
...
[CROP] Crop area: X: 5..717  Y: 57..421  (-vf crop=704:352:10:64).
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, play the movie in 4:3 aspect racio, and force cropping at the numbers you
just found out. Additionally, use the &lt;code&gt;yadif&lt;/code&gt; deinterlacer:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mplayer -aspect 4:3 -vf yadif,crop=704:352:10:64 dvd://
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the same scene (with heavy motion) looks much nicer:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/img/mplayer-improved.png&quot;&gt;&lt;img
src=&quot;/img/mplayer-improved.thumb.png&quot; alt=&quot;In motion, deinterlacing, boders cropped&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">sed and jekyll tags</title>
    <link href="http://blog.plenz.com/2011-12/sed-and-jekyll-tags.html" />
    <updated>2011-12-27T03:18:00+01:00</updated>
    <id>http://blog.plenz.com/2011-12/sed-and-jekyll-tags</id>
    <content type="html">&lt;p&gt;Did you know the &lt;code&gt;-s&lt;/code&gt; switch to &lt;code&gt;sed&lt;/code&gt;? I had the strange effect that
operating on several files produced different results between when I
called &lt;code&gt;sed&lt;/code&gt; repeatedly in a &lt;code&gt;for&lt;/code&gt; loop and passing all the files as
arguments just once. &amp;ndash; &lt;code&gt;-s&lt;/code&gt; tells &lt;code&gt;sed&lt;/code&gt; not to consider all
files to be one big stream, but to separate them from each other.&lt;/p&gt;

&lt;p&gt;Anyway, here's a script that searches &lt;a href=&quot;http://git.plenz.com/blog/tree/_posts&quot;&gt;all the
posts&lt;/a&gt; now and gives me
numbers on the tags I already used.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh

sed -s -n '
    /---/,/---/ {
        /tags:/ {
            s/^tags: \[//;
            s/\]$//;
            s/, */\n/g;
            p
        }
    }' ~/blog/_posts/*.markdown | sort | uniq -c | sort -n
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">28C3</title>
    <link href="http://blog.plenz.com/2011-12/28c3.html" />
    <updated>2011-12-27T02:23:00+01:00</updated>
    <id>http://blog.plenz.com/2011-12/28c3</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;https://events.ccc.de/congress/2011/wiki/Main_Page&quot;&gt;&lt;img
src=&quot;/img/28c3_banner_hochkant.png&quot; alt=&quot;28C3 propaganda sticker&quot;
style=&quot;float:left; margin-right:.5cm;&quot; /&gt;&lt;/a&gt;
I'll be at &lt;a href=&quot;https://events.ccc.de/congress/2011/wiki/Main_Page&quot;&gt;the 28th Chaos Communication
Congress&lt;/a&gt; the next few
days. If you are there, too, write me an email or &lt;a href=&quot;http://plenz.com/contact.html&quot;&gt;text
me&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I haven't throughly looked at the
&lt;a href=&quot;https://events.ccc.de/congress/2011/Fahrplan/&quot;&gt;Fahrplan&lt;/a&gt; yet. But there are
some classics there already, for example &lt;a href=&quot;https://events.ccc.de/congress/2011/Fahrplan/events/4930.en.html&quot;&gt;Dan
Kaminsky&lt;/a&gt;,
the Fnord News Show or a new &lt;a href=&quot;https://events.ccc.de/congress/2011/Fahrplan/events/4675.en.html&quot;&gt;Neusprech talk by
maha&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some other talks seem promising: &lt;a href=&quot;https://events.ccc.de/congress/2011/Fahrplan/events/4781.en.html&quot;&gt;Deceiving Authorship
Detection&lt;/a&gt;
will unveil two tools for detecting and &lt;em&gt;obfuscating&lt;/em&gt; authorship patterns; &lt;a href=&quot;https://events.ccc.de/congress/2011/Fahrplan/events/4710.en.html&quot;&gt;The
future of cryptology: which 3 letters algorithm(s) could be our
Titanic?&lt;/a&gt; also sounds cool.&lt;/p&gt;

&lt;p&gt;I was surprised to see a &lt;a href=&quot;https://events.ccc.de/congress/2011/Fahrplan/events/4587.en.html&quot;&gt;talk about
&quot;bup&quot;&lt;/a&gt;.
Usually, the Congress has a very un-techy focus. To outsiders this might sound
strange, but it's mainly about &lt;em&gt;ideas&lt;/em&gt;, not so much about technology of the
status quo. Talk topics normally include &quot;What if X happens?&quot; (where X is in:
internet lockdown, censorship, Aliens arrive, ...), &quot;How can we hack X?&quot; (X
being: CCTVs, mobile devices, our government, ...), &quot;How we hacked X&quot; (where X
might just be your occasional airport access control badges system).&lt;/p&gt;

&lt;p&gt;Anyway, I hope I'll have some time to play around with stuff I had on my mind
for some time now.&lt;/p&gt;

&lt;p&gt;Preparation for tomorrow's Keynote: &lt;a href=&quot;http://www.ted.com/talks/evgeny_morozov_is_the_internet_what_orwell_feared.html&quot;&gt;Evgeny Morozov's TED
talk&lt;/a&gt;.&lt;/p&gt;

&lt;br style=&quot;clear:both;&quot; /&gt;

</content>
  </entry>
  
  <entry>
    <title type="html">X220's UMTS card</title>
    <link href="http://blog.plenz.com/2011-12/x220s-umts-card.html" />
    <updated>2011-12-22T13:22:00+01:00</updated>
    <id>http://blog.plenz.com/2011-12/x220s-umts-card</id>
    <content type="html">&lt;p&gt;I've been toying around with the UMTS module in my X220 lately. I got
a pre-paid SIM from &lt;a href=&quot;http://blau.de&quot;&gt;blau.de&lt;/a&gt;, who offer 24h UMTS
flatrates for 2,40 EUR. (This is probably my use case: Being somewhere
without internet access for a day or two. This only happens so often,
so I don't want a &quot;real&quot; flat.)&lt;/p&gt;

&lt;p&gt;My UMTS card is manufactured by Sony Ericsson and connected via
internal USB:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ lsusb -v -s 004:003
    ...
    idVendor           0x0bdb Ericsson Business Mobile Networks BV
    idProduct          0x1911
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The installation is easy: Just insert the SIM card behind the battery
as &lt;a href=&quot;http://forums.lenovo.com/t5/image/serverpage/image-id/4121iF2F67FA086EE1A0D/image-size/original?v=mpbl-1&amp;amp;px=-1&quot;&gt;shown
here&lt;/a&gt;.
Add yourself to the &lt;code&gt;dialout&lt;/code&gt; group, log in again, and you're set.&lt;/p&gt;

&lt;p&gt;You can first connect to your device using &lt;code&gt;chat&lt;/code&gt; or &lt;code&gt;picocom&lt;/code&gt; (which
you can be terminated via C-a C-x). To ask if you can use the SIM
without PIN, send the &lt;code&gt;AT+CPIN?&lt;/code&gt; command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ picocom /dev/ttyACM0
...
AT+CPIN?
+CPIN: READY
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you're not ready to go, I would disable the PIN request using a regular phone. (I did.)&lt;/p&gt;

&lt;p&gt;Dialling out is easy. I set up two profiles in the &lt;code&gt;/etc/wvdial.conf&lt;/code&gt;
that allow me to switch between &quot;pay per megabyte&quot; and &quot;dayflat&quot;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[Dialer blau]
Modem = /dev/ttyACM0
Init1 = AT+CGDCONT=1,&quot;IP&quot;,&quot;internet.eplus.de&quot;
Stupid mode = 1
phone= *99#
Username = blau
Password = blau

[Dialer tagesflat]
Modem = /dev/ttyACM0
Init1 = AT+CGDCONT=1,&quot;IP&quot;,&quot;tagesflat.eplus.de&quot;
Stupid mode = 1
phone= *99#
Username = blau
Password = blau
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The rest happens automatically, once you invoke &lt;code&gt;wvdial blau&lt;/code&gt; or
&lt;code&gt;wvdial tagesflat&lt;/code&gt;. (Note you have to execute these with root
privileges because they want to modify pppd-related config files.)
Most probably you want the follow-up command &lt;code&gt;route add default dev
ppp0&lt;/code&gt; to route all traffic via the ppp0 interface.&lt;/p&gt;

&lt;p&gt;In a test run I got a downstream speed of 190KB/s (city perimeter).
Working over SSH is not painful at all.&lt;/p&gt;

&lt;p&gt;I also played around with &lt;a href=&quot;http://wammu.eu/gammu/&quot;&gt;gammu&lt;/a&gt; a little
bit.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gammu --identify
Device               : /dev/ttyACM0
Manufacturer         : Lenovo
Model                : unknown (F5521gw)
Firmware             : R2A07
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Wammu interface is nice, it can even receive SMS. But sending SMSes
failed so far:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ echo &quot;Das ist ein Test&quot; | gammu --debug textall --debug-file /tmp/gammu \
    sendsms TEXT +491785542342
...
1 &quot;AT+CMGS=28&quot;
2 &quot;&amp;gt; 079194710716000011000C919471584532240000FF10C4F01C949ED341E5B41B442DCFE9^Z&quot;
3 &quot;+CMS ERROR: 500&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;... which is somewhat of an &quot;generic error&quot;. Maybe sending SMS is not
supported at all. I'll look into that later.&lt;/p&gt;

&lt;p&gt;Also, I'll have a look whether my Card supports GPS information
retrieval. &lt;a href=&quot;http://www.thinkwiki.org/wiki/Ericsson_F3507g_Mobile_Broadband_Module&quot;&gt;Thinkwiki claims a similar model does
this&lt;/a&gt;.
Interesting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Actually, I forgot one thing. I keep the following two entries in my &lt;code&gt;/etc/wvdial.conf&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[Dialer on]
Modem = /dev/ttyACM0
Init1 = AT+CFUN=1

[Dialer off]
Modem = /dev/ttyACM0
Init1 = AT+CFUN=4
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The actual sequence is now: &lt;code&gt;wvdial on &amp;amp;&amp;amp; wvdial blau&lt;/code&gt;. The &lt;code&gt;AT+CFUN=1&lt;/code&gt; will
active the radio equipment, which is necessary. And, suddenly, also SMS delivery works! :-)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">New X220</title>
    <link href="http://blog.plenz.com/2011-12/new-x220.html" />
    <updated>2011-12-10T14:38:00+01:00</updated>
    <id>http://blog.plenz.com/2011-12/new-x220</id>
    <content type="html">&lt;p&gt;I got a brand new &lt;a href=&quot;http://www.thinkwiki.org/wiki/Category:X220&quot;&gt;Thinkpad
X220&lt;/a&gt; on thursday. I'm
not much into hardware, I think it should mainly work. I have a model
with 4 GB of RAM, an i7 at 2.7 GHz, UMTS preinstalled, SSD instead of
a HDD and an IPS panel. It's a really nifty thing.&lt;/p&gt;

&lt;p&gt;Paying the extra money for the SSD is totally worth it. &lt;em&gt;Everything&lt;/em&gt;
happens instantaneous. The bootup process is down to five seconds.
The IPS panel is really worth it, too. ThinkPads have long been
criticized for their bad displays &amp;ndash; with the new panel at full
brightness, my regular screen looks really dim and grey...&lt;/p&gt;

&lt;p&gt;The Debian netinstall works smoothly. I haven't come around to testing
all the stuff like the DisplayPort connectors, Bluetooth, UMTS, USB
3.0. But the usual stuff works out of the box.&lt;/p&gt;

&lt;p&gt;However, there are major problems with the power management of both
the graphics card and the whole system, the latter one being a
regression in the recent 3.0 and 3.1 kernel series regarding
&lt;a href=&quot;http://en.wikipedia.org/wiki/Active_State_Power_Management&quot;&gt;ASPM&lt;/a&gt;.
Currently I'm using the 3.1.0-1-amd64 kernel with the
&lt;code&gt;pcie_aspm=force&lt;/code&gt; boot parameter. I cannot really see a difference in
power consumtion when varying this parameter, though.&lt;/p&gt;

&lt;p&gt;A &lt;a href=&quot;http://www.phoronix.com/scan.php?page=article&amp;amp;item=intel_i915_power&amp;amp;num=1&quot;&gt;major thing&lt;/a&gt;,
however, is re-enabling the RC6 mode of the graphics chip. This alone
saves more than 4W when the computer is in an idle state. My
&lt;code&gt;/etc/modprobe.d/i915-kms.conf&lt;/code&gt; looks like this now:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;options i915 modeset=1
options i915 i915_enable_rc6=1
options i915 i915_enable_fbc=1
options i915 lvds_downclock=1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Suspend/resume works fine, no flickering effects. I use the following
command to find out the current power consumption:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;while sleep 1; do
    awk '{printf&quot;%.2f\n&quot;,$1/-1000}' &amp;lt; /sys/devices/platform/smapi/BAT0/power_now;
done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This requires the &lt;code&gt;tp_smapi&lt;/code&gt; kernel module to be loaded. With full
brightness (0) and while writing this blog article, the consumption is at
~12W; with medium brightness (8) it's ~8.5W; at the lowest brightness
(15) it's ~8W; With the display completely turned off, it's ~6.5W.
There are people who
&lt;a href=&quot;http://forums.linuxmint.com/viewtopic.php?f=191&amp;amp;t=85424#p498935&quot;&gt;claim&lt;/a&gt;
they only have an ~5.4 power consumption. If you have any other hints
on this or if you own an X220 yourself, I'd be interested in the details.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">demotivating maths</title>
    <link href="http://blog.plenz.com/2011-12/demotivating-maths.html" />
    <updated>2011-12-05T21:48:00+01:00</updated>
    <id>http://blog.plenz.com/2011-12/demotivating-maths</id>
    <content type="html">&lt;p&gt;Math is not easy. (&lt;a href=&quot;http://blog.plenz.com/2011-10/pictures-in-pictures.html&quot;&gt;See
also&lt;/a&gt;) I saw
&lt;a href=&quot;http://i.imgur.com/rfHbw.jpg&quot;&gt;this&lt;/a&gt; scroll by today:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/math_imgur2.jpg&quot; alt=&quot;37 = 2 * 18&quot; style=&quot;width:600px;&quot; /&gt;&lt;/p&gt;

</content>
  </entry>
  
  <entry>
    <title type="html">GUI simplicity vs. UNIX simplicity</title>
    <link href="http://blog.plenz.com/2011-11/gui-simplicity-vs-unix-simplicity.html" />
    <updated>2011-11-24T18:59:00+01:00</updated>
    <id>http://blog.plenz.com/2011-11/gui-simplicity-vs-unix-simplicity</id>
    <content type="html">&lt;p&gt;I &lt;a href=&quot;http://blog.plenz.com/2011-10/gnome-is-not-aqua.html&quot;&gt;ranted about the new Unity
interface&lt;/a&gt; some weeks
ago. On several occasions thereafter, I had to help people solve
problems they had using some sort of graphical user interface.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Example I:&lt;/em&gt; I was debugging a broken VPN connection. The connection
settings were managed by the KDE network manager, which is rather easy
to use. Internally, of course, the network manager just writes out
some temporary configuration files and starts the PPP daemon with a lot of
custom flags. That's all fine if it works &amp;ndash; but in this case it
didn't work. It just said: &quot;connection failed&quot;, no diagnostics given.
(The solution was to enable
&lt;a href=&quot;http://en.wikipedia.org/wiki/Microsoft_Point-to-Point_Encryption&quot;&gt;MPPE&lt;/a&gt;,
which itself was trivial: ticking the corresponding box. How did I
find this out? Tailing &lt;code&gt;/var/log/dmesg&lt;/code&gt; while connecting. It said
right there: MPPE not enabled, but server side requires it.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Example II:&lt;/em&gt; The gnome network manager somehow fucked up. Even now I
don't know why. It says &quot;connecting&quot;, and then nothing happens. No
diagnostics.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;UNIX is simple. It really is. There is a &lt;a href=&quot;http://catb.org/esr/writings/taoup/html/&quot;&gt;reasonable and
easy-to-follow philosophy behind
it&lt;/a&gt;. But UNIX requires the
user to know what he wants to do, and read error messages. &lt;em&gt;UNIX
simplicity is not the same as iPhone simplicity.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Eric S. Raymond wrote this &lt;a href=&quot;http://catb.org/esr/writings/taoup/html/ch01s06.html&quot;&gt;set of
rules&lt;/a&gt; that
should guide UNIX program design. In this context, two important
rules stick out (emphasis mine):&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Rule of Silence:&lt;/strong&gt; When a program has nothing
surprising to say, it should say nothing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule of Repair:&lt;/strong&gt; When you must fail, fail &lt;em&gt;noisily&lt;/em&gt;
and as soon as possible.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Although this is of course mostly aimed at text user interface
programs, you can get an important point here. Most GUIs adhere to
the Rule of Silence quite well &amp;ndash; in fact so well that they
seldom say anything &lt;em&gt;at all&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;Since many UNIX GUIs invoke text-interface programs under the hood, it
should be a necessity to be able to view &lt;em&gt;how&lt;/em&gt; those program failed.
Luckily, most TUI programs provide descriptive error messages. If they are
hidden in the GUI there are two effects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &quot;regular&quot; user sees that something fails, and&lt;/li&gt;
&lt;li&gt;the admin looking at the problem sees that something fails and pulls
out his hair trying to find out &lt;em&gt;what&lt;/em&gt; &amp;ndash; so that he can repair
it!&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I don't use GUI programs at all, except for a Browser
(Vimperator/Firefox), a PDF viewer (Zathura) and The GIMP. Mostly,
this is because of usability considerations. But also, I'm afraid to
use a computer where I cannot see what is happening. And that's
exactly the case with GUIs that do stuff that can fail: &lt;em&gt;I don't know
what they are doing and why they are failing!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I the end I always go the extra mile and read up on the PPP daemon,
for example. This wouldn't be necessary if GUIs had a switch to do
some really verbose logging. That would help tremendously. Plus a
button to display that log. Should be easy, shouldn't it?&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Rap am Freitag</title>
    <link href="http://blog.plenz.com/2011-11/rap-am-freitag.html" />
    <updated>2011-11-11T21:16:00+01:00</updated>
    <id>http://blog.plenz.com/2011-11/rap-am-freitag</id>
    <content type="html">&lt;p&gt;Bushido hat ja den Bambi bekommen. Alle regen sie sich auf. Verständlicherweise
&lt;a href=&quot;http://www.taz.de/Burda-liebt-Bushido-/!81729/&quot;&gt;heult die taz rum&lt;/a&gt;, und
entblödet sich auch nicht, möglichst krasse Zitate als explizit vom Burda-Verlag
als einen &quot;wertvollen Beitrag zum gegenseitigen Verständnis sozialer Gruppen mit
unterschiedlichen kulturellen Wurzeln&quot; zu bezeichnen. Arm, das ist arm.&lt;/p&gt;

&lt;p&gt;Selbst die Piratenpartei &lt;a href=&quot;http://www.piratenpartei.de/Pressemitteilung/bambi-f%C3%BCr-bushido-piraten-vermissen-grundlegende-werte-beim-burda-verlag&quot;&gt;kritisiert die
Preisvergabe&lt;/a&gt;.
Oh. Aber für Pressemitteilungen zu wesentlichen, medial besonders
wichtigen Kernthemen wie dem Bundestrojaner habt ihr Tage gebraucht?
&amp;ndash; Ja, nee, ist klar.&lt;/p&gt;

&lt;p&gt;Den Bambi &amp;ndash; ich habe übrigens heute das erste Mal bewusst von der
Institution &quot;Bambi-Verleihung&quot; gehört... &amp;ndash; den Bambi für Integration hat
Bushido aber natürlich verdient. Vielleicht sollte man mal aus einem
anderen Blickwinkel drauf schauen:&lt;/p&gt;

&lt;p&gt;Ein ehemaliger Randgruppen-Rapper, der sich so weit hocharbeitet, dass
er mit den Stars und Sternchen des deutschen Fernsehens koksen kann;
seinen eigenen Kinofilm und eine nette Villa in Dahlem hat; ganz
offensichtlich gut das Klischee des Ausländers bedienen kann, und
versteht, wie er polarisieren kann. Ein Rapper, der einen fetten
Major-Deal hat, und es nicht mehr nötig hat, gute Musik zu machen,
sondern einfach mit dem Mainstream schwimmen kann. (&quot;23&quot; gehört?
Puuuhh.) Einer, der offensichtlich gut genug in der schmierigen Welt
zwischen Entertainment und Aufmerksamkeit heischendem Journalismus
umherwandelt, um sich so einen Preis vergeben zu lassen. &amp;ndash;
Eindeutig gut integriert, würde ich mal sagen.&lt;/p&gt;

&lt;p&gt;Boah ist das lachhaft, wie alle auf ihm rumkloppen. &lt;a href=&quot;http://staiger.tumblr.com/post/12650284235/briefe-an-mama&quot;&gt;Staiger hat da
sehr gut drüber reflektiert mit einem fiktiven &quot;Brief an
Mama&quot;.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh ja, Rap: Savas'
&lt;a href=&quot;http://www.amazon.de/gp/product/B005QEHYLI/ref=as_li_tf_tl?ie=UTF8&amp;amp;tag=wwwkoolsavasd-21&amp;amp;linkCode=as2&amp;amp;camp=1638&amp;amp;creative=6742&amp;amp;creativeASIN=B005QEHYLI&quot;&gt;Aura&lt;/a&gt;
ist da. Ziemlich gutes Album &amp;ndash; und zum Glück ein nicht
&quot;integrierter&quot; Rapper, sondern fresh wie eh und je.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Don't believe the hype...?</title>
    <link href="http://blog.plenz.com/2011-11/dont-believe-the-hype.html" />
    <updated>2011-11-11T20:13:00+01:00</updated>
    <id>http://blog.plenz.com/2011-11/dont-believe-the-hype</id>
    <content type="html">&lt;p&gt;A while ago a link to the following chart from &lt;a href=&quot;http://popcon.debian.org/&quot;&gt;Debian
Popcon&lt;/a&gt; appeared
&lt;a href=&quot;http://news.ycombinator.com/&quot;&gt;HN&lt;/a&gt;, claiming that &quot;Git is exploding&quot;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://qa.debian.org/popcon-graph.php?packages=subversion+git+mercurial+bazaar&amp;show_installed=on&amp;show_vote=on&amp;want_legend=on&amp;want_ticks=on&amp;from_date&amp;to_date&amp;hlght_date&amp;date_fmt=%25Y-%25m&amp;beenhere=1&quot;&gt;&lt;img src=&quot;img/git-hn.png&quot; width=&quot;500&quot; style=&quot;border:0;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was pretty fascinated by the steep rise of Git's curve. Of course,
the statistics are not representative, but they resemble a good set of
somewhat typical Debian systems.&lt;/p&gt;

&lt;p&gt;Today, I somehow thought about the graph again &amp;ndash; and started
investigating. Take a look at this graph:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://qa.debian.org/popcon-graph.php?packages=git-core+git&amp;show_installed=on&amp;show_nofiles=on&amp;want_legend=on&amp;want_ticks=on&amp;from_date=2009-01-01&amp;to_date=2011-01-01&amp;hlght_date=&amp;date_fmt=%25Y-%25m&amp;beenhere=1&quot;&gt;&lt;img src=&quot;img/git-crit.png&quot; width=&quot;500&quot; style=&quot;border:0;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On April 1st, one of the Git package maintainers &lt;a href=&quot;http://anonscm.debian.org/gitweb/?p=users/jrnieder-guest/git.git;a=commitdiff;h=5aaa336bcafed93d643d263aa95301b833d7980e&quot;&gt;uploaded a commit
that changed Git's package name to &quot;git&quot; from
&quot;git-core&quot;&lt;/a&gt;.
In the graph above you can very well see the steep ascend of of the red
line (&quot;git installed&quot;), while at the same time a sudden drop of the
&quot;git no-files&quot; package occurs. Slowly, the purple &quot;git-core no-files&quot;
follows, indicating that APT replaced git-core with its dummy
package that only contains dependencies, no files.&lt;/p&gt;

&lt;p&gt;This doesn't explain why the red line's ascend is so steep; however,
there must be some relation the package's name change.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">touch screens</title>
    <link href="http://blog.plenz.com/2011-11/touch-screens.html" />
    <updated>2011-11-09T22:42:00+01:00</updated>
    <id>http://blog.plenz.com/2011-11/touch-screens</id>
    <content type="html">&lt;p&gt;I don't own a smart phone. Neither do I own an ebook reader. It's not
that I don't like the idea; I like it. It's just that the products
in that area still is in a very embryoinic state.&lt;/p&gt;

&lt;p&gt;Considering what an iPhone or the Kindle can do, that sound like a
pretty strange statement. But actually, it isn't. Let the technology
be really advanced &amp;ndash; if the user interface is no good, the
product is no good.&lt;/p&gt;

&lt;p&gt;And the current user interfaces are no good. As &lt;a href=&quot;http://worrydream.com/ABriefRantOnTheFutureOfInteractionDesign/&quot;&gt;this nice
article&lt;/a&gt;
points out really well, we are degraded to finger-swiping and tapping
motions at best. With my &lt;a href=&quot;http://blog.ashfame.com/wp-content/uploads/2008/07/nokia-5310-xpressmusic.jpg&quot;&gt;current
phone&lt;/a&gt;,
I can type an SMS without looking at the display; control the MP3
player without taking the phone out of my pocket; switch it to silent
without looking at it. &amp;ndash; The key point here is to &lt;em&gt;sense&lt;/em&gt;
things. Or, as the article concludes:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;With an entire body at your command, do you seriously think the
Future Of Interaction should be a single finger?&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Side show, but the same principle applies: Keyboard vs. Mouse. Can you
actually &lt;em&gt;feel&lt;/em&gt; the corner of windows, buttons, etc.? &amp;ndash; I can't.
But I can sure feel whether I pressed a key. I can type without
looking at &lt;a href=&quot;http://www.daskeyboard.com/&quot;&gt;my keyboard&lt;/a&gt;, but I wouldn't
even care to touch the mouse without looking at the screen.&lt;/p&gt;

&lt;p&gt;The day we have smartphones that not only have &quot;force feedback&quot; but
real, tangible, tactile buttons and the illusion of touching a
non-flat, non-homogeneous surface, I'll buy one. Same goes for the
Kindle as soon as I can feel the edge of the paper and roll it like it
was a few pages of printout or a paperback.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">rss rant</title>
    <link href="http://blog.plenz.com/2011-10/rss-rant.html" />
    <updated>2011-10-30T14:41:00+01:00</updated>
    <id>http://blog.plenz.com/2011-10/rss-rant</id>
    <content type="html">&lt;p&gt;Rant Saturday! &lt;a href=&quot;http://feliciaday.com/blog/rss-rant&quot;&gt;Very good rant about sites un-implementing RSS feeds.&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">gnome is not aqua</title>
    <link href="http://blog.plenz.com/2011-10/gnome-is-not-aqua.html" />
    <updated>2011-10-30T13:51:00+01:00</updated>
    <id>http://blog.plenz.com/2011-10/gnome-is-not-aqua</id>
    <content type="html">&lt;p&gt;Dear GNOME team,&lt;/p&gt;

&lt;p&gt;I'd like to point out a fact to you: You are not, and should not compete with,
&lt;a href=&quot;http://en.wikipedia.org/wiki/Aqua_GUI&quot;&gt;Apple's Aqua GUI&lt;/a&gt;. There are
several reasons for that, but let me tell my story first.&lt;/p&gt;

&lt;p&gt;I installed Ubuntu 11.10 on a friend's laptop yesterday. The new Unity user
interface is somewhat unusable, of course. (Side rant: Unlike you
might think, quite many people out there have actual monitors, not
just tiny eeePC displays. Some even have computers that are more than
a few months old and lack the required processing power for stupid
eye-candy.) &amp;ndash; First thing to do: Install &lt;code&gt;gnome-shell&lt;/code&gt; and
select &quot;GNOME classic&quot; at the login screen. Second thing: Disable
startup sound.&lt;/p&gt;

&lt;p&gt;Enter $DEVELOPER, saying: &quot;Oh, fuck this shit. Everybody wants these
drum sounds at startup. So we'll make it hard to disable it.&quot; Guess
how you can do it: &lt;a href=&quot;http://maketecheasier.com/disable-login-sound-in-ubuntu-oneiric-quick-tips/2011/09/15&quot;&gt;Edit a somewhat buried file with root
privileges&lt;/a&gt;.
Try explaining that to your parents over the phone.&lt;/p&gt;

&lt;p&gt;At one point I realize: There is no &quot;Settings&quot; menu any more. There
just isn't. There are vague comments in some blogs this thing is
missing, but I can't find where they put it. That's what qualifies as
a &lt;em&gt;regression&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The &quot;System Settings&quot; have moved, too, and &lt;a href=&quot;http://blog.sudobits.com/wp-content/uploads/2011/09/system-settings-ubuntu1110.jpg&quot;&gt;looks like its OS X
counterpart&lt;/a&gt;.
Now if there's one thing Apple is really good at, it's making people
feel comfortable (or even elitist!) thinking &lt;em&gt;inside the box&lt;/em&gt; &amp;ndash;
by ways of designing a bearable user interface that hides complicated
stuff. Mostly, though, this means you can &lt;em&gt;only&lt;/em&gt; do what some
(possibly narrow-minded) developer intended.&lt;/p&gt;

&lt;p&gt;However, You, the GNOME team, are not good at it. Part of it is the
simple fact that there just happen to &lt;em&gt;exist&lt;/em&gt; tons of configuration
options. If you hide them &amp;ndash; and by hiding I mean: making it
unaccessable without using the shell and/or editing special files
&amp;ndash; you are &lt;em&gt;crippling&lt;/em&gt; the user.&lt;/p&gt;

&lt;p&gt;So, please, stop &quot;making things better&quot;. Or, if you do, on your way
please don't destroy the perfectly running classig GUI in order to
&quot;improve&quot; it. You are not Apple. You will never be Apple. The Aqua
design sucks, too, but they never had a lot of configuration options
in the first place. The Gnome Shell had.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

&lt;p&gt;P.S.: I don't use Desktop Environments myself, so I might have got
some terminology wrong. But the fact alone I cannot find ways to
configure stuff in two hour's time should tell tales.&lt;/p&gt;

&lt;p&gt;P.P.S.: Bad decision: &lt;a href=&quot;http://petermoulding.com/sites/default/files/ubuntu_11.4_gnome_scroll_bar_overlay.png&quot;&gt;The scrollbars.&lt;/a&gt;
Try teaching a person over age 60 (or below five) to use the 5px-wide scrool bar to
make pop up an additional small scrollbar &lt;em&gt;outside&lt;/em&gt; the window that
actually enables scrolling the window contents. Again: not all people
have a scroll wheel in their mouse. At least provide an easy settings
dialog to disable this behaviour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I'm &lt;a href=&quot;http://bytebaker.com/2011/10/19/ubuntu-should-zig-to-apples-zag/&quot;&gt;not
alone&lt;/a&gt;,
even &lt;a href=&quot;http://esr.ibiblio.org/?p=3822&quot;&gt;esr&lt;/a&gt; made that point a while
ago.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">great stuff</title>
    <link href="http://blog.plenz.com/2011-10/great-stuff.html" />
    <updated>2011-10-25T21:21:00+02:00</updated>
    <id>http://blog.plenz.com/2011-10/great-stuff</id>
    <content type="html">&lt;p&gt;I took a look at &lt;a href=&quot;http://cheezpictureisunrelated.files.wordpress.com/2011/10/wtf-photos-videos-what-is-this-madness.gif&quot;&gt;this animated gif&lt;/a&gt; and couldn't really figure out what it was and how it happened. But now I know you can &lt;a href=&quot;http://www.instructables.com/id/Cobra-Weave-Exploding-Stick-Bomb/&quot;&gt;create&lt;/a&gt; such a cool thing &amp;ndash; called &lt;em&gt;Cobra Weave Exploding Stick Bomb&lt;/em&gt; -- on your own, or watch &lt;a href=&quot;http://www.viralviralvideos.com/2011/06/09/domino-style-stick-explosion-by-kinect-king-americas-got-talent/&quot;&gt;professionals do that&lt;/a&gt;. Amazing.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">twitter search</title>
    <link href="http://blog.plenz.com/2011-10/twitter-search.html" />
    <updated>2011-10-18T21:42:00+02:00</updated>
    <id>http://blog.plenz.com/2011-10/twitter-search</id>
    <content type="html">&lt;p&gt;I don't have a twitter account. But in certain cases, I follow people
or events using the Twitter web site or RSS feeds. Because, luckily,
Twitter provides usable RSS feeds, although I'm pretty sure they don't
advocate or event document it.&lt;/p&gt;

&lt;p&gt;Simply use a URL like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=USERNAME
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But, seriously, you'd want to allow people to search for stuff, right?
To become interested and later immersed in Twitter.&lt;/p&gt;

&lt;p&gt;So evey time I want to look up a hash tag, I go to &lt;code&gt;twitter.com&lt;/code&gt; and
duh &amp;ndash; there is no search form. You can only sign in or sign up.
&lt;strong&gt;No search form.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not even is there a &lt;em&gt;link&lt;/em&gt; to a search form. How hard would that be?
My workaround is to go to &lt;code&gt;twitter.com/a&lt;/code&gt; &amp;ndash; the timeline of
certain @a, of whom I don't know who he is, but &quot;a&quot; is comfortable
letter to type &amp;ndash; and there it is, at the top of the screen: a
search box.&lt;/p&gt;

&lt;p&gt;Seriously? &amp;ndash; Can it be that hard?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Three people approached me with different ideas/URL of how
to find the search form. The most mnmonically convenient seems to be
&lt;a href=&quot;http://search.twitter.com/&quot;&gt;search.twitter.com&lt;/a&gt;, though there is a
&lt;a href=&quot;http://mobile.twitter.com/searches&quot;&gt;javascript-free mobile version&lt;/a&gt;,
too. Consequently, I added a form to &lt;a href=&quot;http://q.plenz.com/&quot;&gt;my general-purpose search
page&lt;/a&gt;. (Thanks for the hints to: Skudo,
&lt;a href=&quot;http://www.neureich-bimbeshausen.de/&quot;&gt;Julian&lt;/a&gt; and
&lt;a href=&quot;http://chneukirchen.org/&quot;&gt;Chris&lt;/a&gt;.)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">spam ratio</title>
    <link href="http://blog.plenz.com/2011-10/spam-ratio.html" />
    <updated>2011-10-13T11:24:00+02:00</updated>
    <id>http://blog.plenz.com/2011-10/spam-ratio</id>
    <content type="html">&lt;p&gt;How much spam do you get? &amp;ndash; I have a feeling I get more than I
deserver. So I checked my spm ratio, i.e. the number of (recognized)
spam mails divided my the number of total mails (as far as the
procmail log spans, which is some 270,000 mails).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ echo $(fgrep -c 'Subject: *****SPAM*****' Mail/from) / \
    $(fgrep -c 'Subject: ' Mail/from) | bc
.952154
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now this is gross. Only less than five percent of the mail I receive
might be of interest to me. :-(&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">gc via cron on hosted git repos</title>
    <link href="http://blog.plenz.com/2011-10/gc-via-cron-on-hosted-git-repos.html" />
    <updated>2011-10-12T22:43:00+02:00</updated>
    <id>http://blog.plenz.com/2011-10/gc-via-cron-on-hosted-git-repos</id>
    <content type="html">&lt;p&gt;If you host Git repositories, you might want to implement a cron job
that automatically triggers garbage collection on the server side.
As a regular user you can't usually access the unreachable objects
anyway, so there's no point to keep them.&lt;/p&gt;

&lt;p&gt;However, when invoking &lt;code&gt;git gc&lt;/code&gt;, Git will pack loose objects together.
This has a huge advantage: When a user clones a whole repository, Git
will compress all objects within a single packfile and transfer it via
the Git protocol. If all the objects are already in one packfile,
there's no overhead in creating a temporary packfile. (If you just
want to get a subset of commits, it's easier for git to &quot;thin out&quot; the
existing packfile, too.)&lt;/p&gt;

&lt;p&gt;You can usually see if a computationally expensive temporary packfile
is created if there is a message like &lt;code&gt;remote: counting objects ...&lt;/code&gt;
that keeps on counting for a while. For some hosters, this takes quite
some time, because the server is under high load.&lt;/p&gt;

&lt;p&gt;I use the following script to trigger &lt;code&gt;git gc&lt;/code&gt; every night:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh

BASE=/var/git/repositories

su - git -c &quot;
cd $BASE
find . -name '*.git' -type d | while read repo; do
    cd $BASE/\$repo &amp;amp;&amp;amp; git gc &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
done
&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You might want to omit the &lt;code&gt;su&lt;/code&gt; part if you create a script that's
executable by the owner of your git repositories itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; If you don't use &lt;a href=&quot;http://hjemli.net/git/cgit/tree/cgitrc.5.txt#n36&quot;&gt;cgit's age
files&lt;/a&gt;, you'll have all your
repos displaying they were recently changed in the &quot;idle&quot; column. To work
around this, include the following command adter the &lt;code&gt;git gc&lt;/code&gt; call:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir -p info/web &amp;amp;&amp;amp;
git for-each-ref \
    --sort=-committerdate \
    --format='%(committerdate:iso8601)' \
    --count=1 'refs/heads/*' \
    &amp;gt; info/web/last-modified
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">svn 1.7</title>
    <link href="http://blog.plenz.com/2011-10/svn-17.html" />
    <updated>2011-10-12T02:21:00+02:00</updated>
    <id>http://blog.plenz.com/2011-10/svn-17</id>
    <content type="html">&lt;p&gt;I feel I have a pretty good understanding of Git. Before I came
accustomed to it around the end of 2009, however, I had never
extensively used version control.&lt;/p&gt;

&lt;p&gt;Sure, I used RCS for simple projects; I played around with CVS and
bought a book about it; in 2007 I became somewhat accustomed to
Mercurial, because the &lt;a href=&quot;http://suckless.org/&quot;&gt;suckless&lt;/a&gt; and
&lt;a href=&quot;http://grml.org/&quot;&gt;grml&lt;/a&gt; projects used them at the time.&lt;/p&gt;

&lt;p&gt;All the time I happened to use Subversion, also for coordinating the
work on the &lt;a href=&quot;https://www.opensourcepress.de/index.php?26&amp;amp;backPID=178&amp;amp;tt_products=198&quot;&gt;book about Z
shell&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;RCS was simple, but was not at all suitable for collaboration. I
thought CVS and Subversion were, alas I never really understood how
they worked. As in: why they worked, what was good practice, why you
just couldn't seem to run it locally (without client-server
architecture).&lt;/p&gt;

&lt;p&gt;I happened to just read the &lt;a href=&quot;http://subversion.apache.org/docs/release-notes/1.7.html&quot;&gt;release notes of the new subversion
1.7&lt;/a&gt;. And,
reading the notes, I realize it wasn't me not being attentive or being
plain stupid, it's just the interface as well as repository design
that was totally messed up. For example:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Subversion 1.7 features a new subcommand called svn patch which
can apply patch files in unidiff format (as produced by svn diff
and other diff tools) to a working copy.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I mean &amp;ndash; what?! This must be such a basic thing &amp;ndash;
receiving patches via a mailing list and trying to apply them, right?
But apparently, there was no need for that since 2000...?&lt;/p&gt;

&lt;p&gt;Or consider this great improvement of adding a &lt;code&gt;--diff&lt;/code&gt; switch:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;svn log can now print diffs&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Oh, right. Diffs. In an SCM. Right. Might be of some use.&lt;/p&gt;

&lt;p&gt;I'm glad I don't have to use plain SVN any more.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">pictures in pictures</title>
    <link href="http://blog.plenz.com/2011-10/pictures-in-pictures.html" />
    <updated>2011-10-06T22:07:00+02:00</updated>
    <id>http://blog.plenz.com/2011-10/pictures-in-pictures</id>
    <content type="html">&lt;p&gt;While browsing I saw &lt;a href=&quot;http://i.imgur.com/M631m.jpg&quot;&gt;this one&lt;/a&gt; today:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/math_imgur.jpg&quot; alt=&quot;MATH - When you absolutely, positively want to piss someone off&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you look closely, someone calculates the check to be worth $536.49,
which is of course wrong. (It's $0.002.) So I set out with the GIMP to
draw a riposte:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/zero.jpg&quot; title=&quot;ZERO - e^{i\pi}+\sum_{n=1}^\infty \frac{1}{2^n} is just a clever way to write it&quot; /&gt;&lt;/p&gt;

&lt;p&gt;By the way, these are called &lt;a href=&quot;http://www.dailydemotivators.com/&quot;&gt;demotivator pictures&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">mail server switchover</title>
    <link href="http://blog.plenz.com/2011-10/mail-server-switchover.html" />
    <updated>2011-10-03T21:43:00+02:00</updated>
    <id>http://blog.plenz.com/2011-10/mail-server-switchover</id>
    <content type="html">&lt;p&gt;Today I migrated the last big part of my old server: the mail system.
Since I and other people depend on this server for their day-to-day
mailing, I had to switch over without losing a single e-mail. This is
how I did it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step one:&lt;/strong&gt; Port the configuration, make the environment run on the
new server. Copy also user metadata like passwords and make sure the
overall structure is working (incoming SMTP works, POP3 access, etc.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step two:&lt;/strong&gt; Copy over all mails from the old server. The mails will be
synced later on again, so this can happen some minutes in advance. (I
actually lost a few days doing this, because I discovered unused
mailboxes with 995,000 mails, &amp;gt;99% of them being spam. I had to ask
the owner first, though, whether I could delete them.)&lt;/p&gt;

&lt;p&gt;Now comes the time-critical path. It took me an overall
70 seconds to do steps three to five.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step three:&lt;/strong&gt; Stop the daemons that receive mail or give the user
access to it. For example: &lt;code&gt;for s in postfix courier*; do
/etc/init.d/$s stop; done&lt;/code&gt; &amp;ndash; connecting to the host will now
give a &quot;connection refused&quot; error message. MTAs trying to deliver mail
will usually try again ten minutes later. (So no mail gets lost.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step four:&lt;/strong&gt; Sync the emails again. There might have arrived new
messages, or users have deleted some of their inbox. I used this
command: &lt;code&gt;rsync -avhP --delete vmail@eris.feh.name: .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step five:&lt;/strong&gt; Apply iptables rules to forward connections to the new
server. This is due to the fact that DNS information is slow to
spread. For a few days I don't care whether &lt;code&gt;mail.feh.name&lt;/code&gt; resolves
to 88.198.158.101 or to 176.9.247.89. Both will effectively talk to
the new server.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;iptables -t nat -A PREROUTING -p tcp -s ! 176.9.34.52 --dport 25 \
  -j DNAT --to-destination 176.9.34.52:25
iptables -t nat -A PREROUTING -p tcp -s ! 176.9.34.52 --dport 110 \
  -j DNAT --to-destination 176.9.34.52:110
iptables -t nat -A POSTROUTING -d 176.9.34.52 -j MASQUERADE
iptables -A FORWARD -p tcp -d 176.9.34.52 -j ACCEPT
iptables -A FORWARD -p tcp -s 176.9.34.52 -j ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So this establishes forwarding for SMTP and POP3. The old server will
simply act as a NATing gateway to the new server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step six:&lt;/strong&gt; Adjust the DNS. As said above, you can take your time for
this; but the information will eventually spread. To have an indicator of
how many connections still arrive at the old host, try &lt;code&gt;iptables -t
nat -L -vn&lt;/code&gt;, it'll print packet and byte counts for each rule in the
NAT table.&lt;/p&gt;

&lt;p&gt;Done! And just one minute of outage. *like*&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">git and the unix philosophy</title>
    <link href="http://blog.plenz.com/2011-10/git-and-the-unix-philosophy.html" />
    <updated>2011-10-03T18:56:00+02:00</updated>
    <id>http://blog.plenz.com/2011-10/git-and-the-unix-philosophy</id>
    <content type="html">&lt;p&gt;Good, but slightly older article: &lt;a href=&quot;http://teddziuba.com/2010/08/too-smart-for-git.html&quot;&gt;Too Smart for Git&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Git follows Linux's philosophy of refusing to protect you from yourself.
Much like Linux, Git will sit back and watch you fuck your shit right up,
and then laugh at you as you try to get your world back to a state where up
is up and down is down. As far as source control goes, not a lot of people
are used to this kind of free love.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;His conclusion holds true for many other programs also:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The problem isn't that Git is to hard, it's that smart developers are
impatient and have exactly zero tolerance for unexpected behavior in their
tools.&lt;/p&gt;&lt;/blockquote&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">dead code easter egg</title>
    <link href="http://blog.plenz.com/2011-10/dead-code-easter-egg.html" />
    <updated>2011-10-02T19:57:00+02:00</updated>
    <id>http://blog.plenz.com/2011-10/dead-code-easter-egg</id>
    <content type="html">&lt;p&gt;I was just researching on how the file format of the &lt;code&gt;xt_recent&lt;/code&gt; module works.
That's where I found this nice easter egg: &lt;a href=&quot;http://lxr.free-electrons.com/source/net/netfilter/xt_recent.c?a=powerpc#L499&quot;&gt;instead of writing down the size of
an IPv6
address plus one&lt;/a&gt;,
they simply used a dummy string &lt;code&gt;+b335:1d35:1e55:dead:c0de:1715:5afe:c0de&quot;&lt;/code&gt;, reading &quot;beesides less dead code it is safe code&quot;.
Hehe.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">migrating domains</title>
    <link href="http://blog.plenz.com/2011-09/migrating-domains.html" />
    <updated>2011-09-27T21:23:00+02:00</updated>
    <id>http://blog.plenz.com/2011-09/migrating-domains</id>
    <content type="html">&lt;p&gt;Today, I migrated all my domains to the new server. While at it, I set
up a mirror of my blog repository at
&lt;a href=&quot;http://git.plenz.com/blog/&quot;&gt;http://git.plenz.com/blog/&lt;/a&gt;. You could
view the pure markdown files there, or see how I messed around with
Jekyll stuff.&lt;/p&gt;

&lt;p&gt;The sync is called from a &lt;code&gt;post-receive&lt;/code&gt; hook with the command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;env GIT_SSH=`pwd`/hooks/blogpush git push -f git@git.plenz.com:blog master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;... where &lt;code&gt;blogpush&lt;/code&gt; is just a little wrapper to make SSH use the
public key that has access to the repository:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh
ssh -o ControlMaster=no -i /home/feh/blog.git/hooks/fehblog $@
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">gitolite and interpolated paths</title>
    <link href="http://blog.plenz.com/2011-09/gitolite-and-interpolated-paths.html" />
    <updated>2011-09-25T23:04:00+02:00</updated>
    <id>http://blog.plenz.com/2011-09/gitolite-and-interpolated-paths</id>
    <content type="html">&lt;p&gt;The Git daemon supports a feature called &lt;em&gt;Interpolated Path&lt;/em&gt;. For
example, my Git daemon is called like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git-daemon --user=git --group=git \
    --listen=0.0.0.0 --reuseaddr \
    --interpolated-path=/var/git/repositories/%IP%D \
    /var/git/repositories
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What it does is it translates the request for a git repository before
actually searching for it. When I do a &lt;code&gt;git clone
git://git.plenz.com/configs.git&lt;/code&gt; what actually happens is that the Git
daemon will deliver the repository at
&lt;code&gt;/var/git/repository/176.9.247.89/configs.git&lt;/code&gt;. That is especially
nice in environments where you share one git daemon for several
people/projects and have sufficient IP addresses.&lt;/p&gt;

&lt;p&gt;However, &lt;a href=&quot;https://github.com/sitaramc/gitolite&quot;&gt;Gitolite&lt;/a&gt; doesn't seem
to have a config option for this. Now what I did was patch Gitolite so
that it'll prepend the repository name with the IP of the network
interface the call came through.&lt;/p&gt;

&lt;p&gt;This information is available from the &lt;code&gt;SSH_CONNECTION&lt;/code&gt; environment variable.&lt;/p&gt;

&lt;p&gt;(The patch to &lt;code&gt;gl-compile-conf&lt;/code&gt; is needed so that Gitolite will create a
&lt;code&gt;projects.list&lt;/code&gt; per virtual host. That way, you can use different
configuration files for each CGit instance, according to your VHost.)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;diff --git a/src/gl-auth-command b/src/gl-auth-command
index 61b2f5a..a8d1976 100755
--- a/src/gl-auth-command
+++ b/src/gl-auth-command
@@ -124,6 +124,12 @@ unless ( $verb and ( $verb eq 'git-init' or $verb =~ $R_COMMANDS or $verb =~ $W_
     exit 0;
 }

+# prepend host's ip address
+# SSH_CONNECTION looks like this: 92.225.139.246 41714 176.9.34.52 22
+#                                 from-ip        port  to-ip       port
+my $connected_via = (split &quot; &quot; =&amp;gt; $ENV{&quot;SSH_CONNECTION&quot;})[2] // &quot;&quot;;
+$repo = $connected_via . &quot;/&quot; . $repo;
+
 # some final sanity checks
 die &quot;$repo ends with a slash; I don't like that\n&quot; if $repo =~ /\/$/;
 die &quot;$repo has two consecutive periods; I don't like that\n&quot; if $repo =~ /\.\./;
diff --git a/src/gl-compile-conf b/src/gl-compile-conf
index 2d4110f..6f8f0d7 100755
--- a/src/gl-compile-conf
+++ b/src/gl-compile-conf
@@ -577,6 +577,22 @@ unless ($GL_NO_DAEMON_NO_GITWEB) {
     }
     close $projlist_fh;
     rename &quot;$PROJECTS_LIST.$$&quot;, $PROJECTS_LIST;
+
+    # vhost stuff
+    my %vhost = ();
+    for my $proj (sort keys %projlist) {
+        my ($ip, $repo) = split '/' =&amp;gt; $proj =&amp;gt; 2;
+        $vhost{$ip} //= [];
+        push @{$vhost{$ip}} =&amp;gt; $repo;
+    }
+    for my $v (keys %vhost) {
+        my $v_file = &quot;$REPO_BASE/$v/projects.list&quot;;
+        my $v_fh = wrap_open( &quot;&amp;gt;&quot;, $v_file . &quot;.$$&quot;);
+        print $v_fh $_ . &quot;\n&quot; for @{$vhost{$v}};
+        close $v_fh;
+        rename $v_file . &quot;.$$&quot; =&amp;gt; $v_file;
+    }
 }

 # ----------------------------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With this patch applied, I can &lt;code&gt;git push git.plenz.com:config.git&lt;/code&gt;
and it will end up pushing to &lt;code&gt;176.9.247.89/configs.git&lt;/code&gt;, fully transparent
to the user.&lt;/p&gt;

&lt;p&gt;N.B.: This strictly is a &quot;works for me&quot; solution. It's not very clean
&amp;ndash; but I don't plan on properly implementing a config setting. As
I said, it works for me. ;-)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">cgit and setuid</title>
    <link href="http://blog.plenz.com/2011-09/cgit-and-setuid.html" />
    <updated>2011-09-25T22:26:00+02:00</updated>
    <id>http://blog.plenz.com/2011-09/cgit-and-setuid</id>
    <content type="html">&lt;p&gt;I'm still in the process of setting up my new server. Today, I
migrated the Git repositories. I wanted a more secure setup, that is I
don't want my web server to be able to read the repositories. (It
spawns CGit, which has to read them somehow.)&lt;/p&gt;

&lt;p&gt;So I created all repositories below &lt;code&gt;/var/git/repositories&lt;/code&gt;, such that
they are only readable by the system user &quot;git&quot;.&lt;/p&gt;

&lt;p&gt;However, that presents a problem to the CGit CGI: It cannot access the
repositories any more. My first approach was: Just &lt;code&gt;chown git.git
/usr/lib/cgi-bin/cgit.cgi&lt;/code&gt; and set the setuid bit on it.&lt;/p&gt;

&lt;p&gt;But, alas, that will only make the CGit binary run with &lt;em&gt;effective&lt;/em&gt;
user ID &quot;git&quot;. What's needed to actually access the files is a &lt;em&gt;real&lt;/em&gt;
user ID &quot;git&quot;.&lt;/p&gt;

&lt;p&gt;The only way to set the real user ID is to call &lt;code&gt;setuid()&lt;/code&gt; with
effective root privileges. So I created a wrapper that&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;searches for git's user ID&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setuid()&lt;/code&gt;s to that ID (real an effective)&lt;/li&gt;
&lt;li&gt;executes the actual CGit CGI&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;That's what I came up with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; #include &amp;lt;unistd.h&amp;gt;
 #include &amp;lt;sys/types.h&amp;gt;
 #include &amp;lt;pwd.h&amp;gt;
 #include &amp;lt;string.h&amp;gt;

int main(int argc, char *argv[])
{
    struct passwd *p;
    uid_t git_uid = 0;

    while((p = getpwent()) != NULL) {
        if(strcmp(p-&amp;gt;pw_name, &quot;git&quot;))
            continue;
        /* got user &quot;git&quot; */
        git_uid = p-&amp;gt;pw_uid;
    }

    endpwent();

    if(!git_uid)
        return 1;

    setuid(git_uid);
    execv(&quot;/usr/lib/cgi-bin/cgit.cgi&quot;, argv);

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Provide it with a Makefile... (beware, use &lt;em&gt;real&lt;/em&gt; tabs!)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;default:
        gcc -Wall -o cgit-as-git.cgi cgit-as-git.c

install:
        install -o root -g root -m 4755 cgit-as-git.cgi /usr/lib/cgi-bin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;... and change the Lighttpd configuration accordingly:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$HTTP[&quot;host&quot;] == &quot;git.plenz.com&quot; {
    setenv.add-environment += ( &quot;CGIT_CONFIG&quot; =&amp;gt; &quot;/etc/cgit/plenz.com.conf&quot; )
    alias.url = (
        &quot;/cgit.css&quot; =&amp;gt; &quot;/usr/share/cgit/cgit.css&quot;,
        &quot;/cgit.png&quot; =&amp;gt; &quot;/usr/share/cgit/cgit.png&quot;,
        &quot;/cgit.cgi&quot; =&amp;gt; &quot;/usr/lib/cgi-bin/cgit-as-git.cgi&quot;,
        &quot;/&quot;         =&amp;gt; &quot;/usr/lib/cgi-bin/cgit-as-git.cgi&quot;,
    )
    cgi.assign = ( &quot;.cgi&quot; =&amp;gt; &quot;&quot; )
    url.rewrite-once = (
        &quot;^/cgit\.(css|png)&quot; =&amp;gt; &quot;$0&quot;,
        &quot;^/.+&quot; =&amp;gt; &quot;/cgit.cgi$0&quot; 
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Done! Lighttpd can now call CGit as if it was a &quot;usual&quot; binary, but it
will get wrapped and get the real and effective user ID of the
system's user &quot;git&quot;.&lt;/p&gt;

&lt;p&gt;N.B.: If you want to use the wrapper as well, you might want to change
the (hard coded) user name &quot;git&quot; and the binary (see &lt;code&gt;execv&lt;/code&gt; call).&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">software design</title>
    <link href="http://blog.plenz.com/2011-09/software-design.html" />
    <updated>2011-09-21T01:26:00+02:00</updated>
    <id>http://blog.plenz.com/2011-09/software-design</id>
    <content type="html">&lt;p&gt;I'm in the process of setting up a new server. I struggled for some
minutes now with the follwing strange behaviour: Lighttpd is very
picky (and not at all verbose) about &lt;em&gt;when&lt;/em&gt; you use
&lt;code&gt;alias.url&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As an actual example, look at these two blocks:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$HTTP[&quot;host&quot;] == &quot;HOST&quot; {
  alias.url += (&quot;/munin&quot; =&amp;gt; &quot;/var/www/munin&quot;)
}

$SERVER[&quot;socket&quot;] == &quot;:443&quot; {
  $HTTP[&quot;host&quot;] == &quot;HOST&quot; {
    alias.url += (&quot;/wiki&quot; =&amp;gt; &quot;/usr/share/dokuwiki&quot;,)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now I, the innocent user, would expect the following to happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Munin is available via HTTP and HTTPS via &lt;code&gt;/munin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The Wiki is available only via HTTPS at &lt;code&gt;/wiki&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;But, alas, nope. It's quite different. The wiki is available alright
if called &lt;em&gt;before&lt;/em&gt; the munin part, and vice versa. The other one will be a 404,
though. To make things work I actually have to &lt;em&gt;double&lt;/em&gt; the alias part for
munin &amp;ndash; once outside the part that matches for SSL and once inside.&lt;/p&gt;

&lt;p&gt;Oh, and don't confuse &lt;code&gt;==&lt;/code&gt; and &lt;code&gt;=~&lt;/code&gt; &amp;ndash; even
if both match, the exact match wins. (Meaning you cannot put the line
in a condition like &lt;code&gt;=~ &quot;:(443|80)&quot;&lt;/code&gt;.) So there's no real
cascading or so. Bad design in my opinion, but &lt;a href=&quot;http://redmine.lighttpd.net/issues/show/1427&quot;&gt;it
seems&lt;/a&gt; to be
&lt;a href=&quot;http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=445459&quot;&gt;intentional&lt;/a&gt;. WTF?&lt;/p&gt;

&lt;p&gt;Correct solution:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$HTTP[&quot;host&quot;] == &quot;HOST&quot; {
  alias.url += (&quot;/munin&quot; =&amp;gt; &quot;/var/www/munin&quot;)
}

$SERVER[&quot;socket&quot;] == &quot;:443&quot; {
  $HTTP[&quot;host&quot;] == &quot;HOST&quot; {
    alias.url += (&quot;/munin&quot; =&amp;gt; &quot;/var/www/munin&quot;)
  }
}

$SERVER[&quot;socket&quot;] == &quot;:443&quot; {
  $HTTP[&quot;host&quot;] == &quot;HOST&quot; {
    alias.url += (&quot;/wiki&quot; =&amp;gt; &quot;/usr/share/dokuwiki&quot;,)
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Holy crap. Explain that to someone unfamiliar with how difficult it is
to implement data structures in C. &amp;ndash; They'd just call you
a moron for not implementing a more intuitive aproach. &amp;ndash; Wait, I
do, too!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Git User's Survey</title>
    <link href="http://blog.plenz.com/2011-09/git-users-survey.html" />
    <updated>2011-09-05T17:34:00+02:00</updated>
    <id>http://blog.plenz.com/2011-09/git-users-survey</id>
    <content type="html">&lt;p&gt;The &lt;a href=&quot;http://tinyurl.com/GitSurvey2011&quot;&gt;Git User's Survey&lt;/a&gt; is up from
now until the beginning of october. Take part!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">cryptome RSS feed suspended</title>
    <link href="http://blog.plenz.com/2011-09/cryptome-rss-feed-suspended.html" />
    <updated>2011-09-02T17:27:00+02:00</updated>
    <id>http://blog.plenz.com/2011-09/cryptome-rss-feed-suspended</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;http://cryptome.org/cryptome.xml&quot;&gt;Great&lt;/a&gt;. :-(&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;25 August 2011: Due to unceasing abuse by clouds (now the worst offenders),
bots, siphons, aggregators, search engines, and other data thieves the Cryptome
RSS feed has been suspended.&lt;/p&gt;&lt;/blockquote&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">debugging a zsh completion function</title>
    <link href="http://blog.plenz.com/2011-09/debugging-a-zsh-completion-function.html" />
    <updated>2011-09-01T23:27:00+02:00</updated>
    <id>http://blog.plenz.com/2011-09/debugging-a-zsh-completion-function</id>
    <content type="html">&lt;p&gt;There's a Perl module &lt;code&gt;threads::shared&lt;/code&gt;. However, it won't show up as a
completion match to the &lt;code&gt;perldoc&lt;/code&gt; command. Why is that?, a colleague
asked me. Now, that obviously is a quirk, so let's debug it.&lt;/p&gt;

&lt;p&gt;We start at &lt;code&gt;/usr/share/zsh/functions/Completion/Unix/_perldoc&lt;/code&gt;, where
we find this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_alternative \
    'modules:module: _perl_modules -tP' \
    'pods:base pod: _perl_basepods' \
    'files:module or .pod file:_files -g &quot;*.(pod|pm)(-.)&quot;' &amp;amp;&amp;amp;
    ret=0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, go on to &lt;code&gt;_perl_modules&lt;/code&gt;: It searches for paths where Perl would
store modules and their documentation (line 85):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;inc=( $( $perl -e 'print &quot;@INC&quot;' ) )
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then, they do some complicated globbing stuff on the directories (line
104), where a loop iterates over &lt;code&gt;$inc&lt;/code&gt; and stores each element in
&lt;code&gt;$libdir&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;new_pms=( $libdir/{[A-Z]*/***/,}*${~sufpat}~*blib* )
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There's the catch: This globbing expression will only recurse into
subdirectories that start with an &lt;em&gt;uppercase&lt;/em&gt; letter. Lowercase
modules on the highest level are okay, though. That's why &lt;code&gt;threads&lt;/code&gt;
appears (from &lt;code&gt;threads.pm&lt;/code&gt;), but &lt;code&gt;threads::shared&lt;/code&gt; doesn't (from
&lt;code&gt;threads/shared.pm&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The search for all modules that are missed this way will translate to
the following Z-Shell command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ print -l ${^=$(perl -e 'print &quot;@INC&quot;')}/[a-z]*/***/*.pm(.N)
/usr/lib/perl/5.10/threads/shared.pm
/usr/share/perl/5.10/encoding/warnings.pm
/usr/share/perl/5.10/warnings/register.pm
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">tmux line continuation patch</title>
    <link href="http://blog.plenz.com/2011-08/tmux-line-continuation-patch.html" />
    <updated>2011-08-25T19:58:00+02:00</updated>
    <id>http://blog.plenz.com/2011-08/tmux-line-continuation-patch</id>
    <content type="html">&lt;p&gt;Yay! My &lt;a href=&quot;http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/tmux/cfg.c.diff?r1=1.12;r2=1.13&quot;&gt;patch to tmux&lt;/a&gt;
was &lt;a href=&quot;http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/tmux/cfg.c?only_with_tag=HEAD&quot;&gt;accepted yesterday&lt;/a&gt;. With it, tmux now supports &lt;code&gt;\&lt;/code&gt; as a line continuation character.
Thus, you can put statements like this in your config:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bind P run-shell \
  &quot;tmux set-b $(tmux sa - | curl -F 'sprunge=&amp;lt;-' http://sprunge.us) &amp;amp;&amp;amp; \
  tmux display-message 'sprunge: upload sucessful!'&quot;
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">dist-upgrade gnah</title>
    <link href="http://blog.plenz.com/2011-08/dist-upgrade-gnah.html" />
    <updated>2011-08-24T09:07:00+02:00</updated>
    <id>http://blog.plenz.com/2011-08/dist-upgrade-gnah</id>
    <content type="html">&lt;p&gt;I'm not sure why, but AFAIR I've never done a &lt;code&gt;dist-upgrade&lt;/code&gt; that was
entirely successful. That is true to my Debian system at home as well
as to various other Ubuntu systems I've laid hands on.&lt;/p&gt;

&lt;p&gt;My Debian system was a mix of stable and testing packages, and somehow
&lt;code&gt;aptitude&lt;/code&gt; came to a point where it'd just not be able to resolve some
dependencies, meaning I could not install nor remove any new packages.
So I opted for a &lt;code&gt;dist-upgrade&lt;/code&gt; to Testing. Here's how it went, roughly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everything installs fine, until &lt;code&gt;aptitude&lt;/code&gt; tries installing &lt;code&gt;libc&lt;/code&gt;,
where the installation process will go into a deadlock. Error
message and solution is posted
&lt;a href=&quot;http://www.facepunch.com/threads/1116926-Error-when-trying-to-dist-upgrade&quot;&gt;here&lt;/a&gt;
(yes, you have to manually patch a Perl module). &lt;code&gt;linux-base&lt;/code&gt; has
the same problem.&lt;/li&gt;
&lt;li&gt;System is left in a half-upgraded state, but &lt;code&gt;aptitude&lt;/code&gt; won't do any
further upgrading. &lt;code&gt;apt-get dist-upgrade&lt;/code&gt; continues, though.&lt;/li&gt;
&lt;li&gt;Reboot because of new kernel.&lt;/li&gt;
&lt;li&gt;Sound is all gone. &lt;code&gt;pcspkr&lt;/code&gt; module is appearently now called
&lt;code&gt;snd_pcsp&lt;/code&gt; and is thus loaded, strangely overriding all other sound
drivers. I blacklist it manually, reboot.&lt;/li&gt;
&lt;li&gt;Seems to work. Now install the new package I did all the upgrading
for... right. There's still some 500 upgrades left to do! Ok, now...&lt;/li&gt;
&lt;li&gt;Upgrade aborts with a problem: &lt;code&gt;libcaca0&lt;/code&gt; wants to overwrite
a file which is also present in &lt;code&gt;libcucul0&lt;/code&gt;. Purging &lt;code&gt;libcucul0&lt;/code&gt;
will reinstall &lt;code&gt;libcaca0&lt;/code&gt;, which in turn will fail. Turn to manual
override and uninstall all packages &lt;code&gt;libcaca*&lt;/code&gt; and &lt;code&gt;libcucul*&lt;/code&gt; using
&lt;code&gt;dpkg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Upgrade runs through fine. I go to sleep.&lt;/li&gt;
&lt;li&gt;Today, I power up the computer. &lt;em&gt;Alt+Enter&lt;/em&gt; to start a
terminal &amp;ndash; duh, nothing happens. Start an &lt;code&gt;xterm&lt;/code&gt;. Inspect the
situation: &lt;code&gt;rxvt&lt;/code&gt; and &lt;code&gt;rxvt-unicode&lt;/code&gt; are missing. Well, thanks, so
here I go, &lt;code&gt;aptitude install rxvt&lt;/code&gt;. But guess what: &lt;code&gt;apt-get&lt;/code&gt;
uninstalled &lt;code&gt;aptitude&lt;/code&gt;! Yeah, great.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;apt-get install rxvt-unicode&lt;/code&gt;, finally a decent terminal. Fire up
mplayer. It's not installed any more. Like, what?!&lt;/li&gt;
&lt;li&gt;Install &lt;code&gt;mplayer&lt;/code&gt;, start it on a file. No sound. After various
tries, a pattern &lt;strike&gt;evolves&lt;/strike&gt;&lt;ins&gt;dissolves&lt;/ins&gt;:
Sometimes it just won't play (like muted), sometime's there's an
error message of various audio drivers. &lt;code&gt;aplay&lt;/code&gt; works just fine.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mplayer -ao alsa&lt;/code&gt; works. Put it into the config. Happy now with
music.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Now, what I ask myself: Manually patching a Perl module, manually
resolving dependencies and invoking &lt;code&gt;dpkg&lt;/code&gt;, being (momentarily)
deprived of the few programs I use on a daily basis ... how will this
packaging system ever be &lt;em&gt;remotely&lt;/em&gt; feasible for someone who's not an
expert of sorts and well-versed in debugging in a Unix wold?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Some crap program said it depended on DECnet
stuff. After a reboot, this caused the MAC addresses of &lt;em&gt;all&lt;/em&gt; my
interfaces (yes, both wireless and wired!) to be the same, i.e.:
&lt;strong&gt;aa:00:04:00:0a:04&lt;/strong&gt;. Solution is removing &lt;code&gt;libdnet*&lt;/code&gt;
and &lt;code&gt;dnet-common&lt;/code&gt;. &amp;ndash; You kidding me?!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">URL shortener</title>
    <link href="http://blog.plenz.com/2011-08/url-shortener.html" />
    <updated>2011-08-07T21:01:00+02:00</updated>
    <id>http://blog.plenz.com/2011-08/url-shortener</id>
    <content type="html">&lt;p&gt;The bit.ly service requires some sort of registration or an API
key for some time now. I used to use it in shell scripts to automate
shortening of links.&lt;/p&gt;

&lt;p&gt;Similar to the &lt;a href=&quot;http://blog.plenz.com/2011-07/sprunge-the-fine-pastebin-service.html&quot;&gt;sprunge pastebin service&lt;/a&gt;, there's come up a new,
easy-to-understand URL shortening service called &lt;a href=&quot;https://github.com/akrennmair/gnzkrz&quot;&gt;&lt;strong&gt;gnzkrz&lt;/strong&gt;&lt;/a&gt;
(short for German &quot;ganz kurz&quot;, &quot;very short&quot;). And with it's &lt;a href=&quot;https://github.com/akrennmair/gnzkrz/commit/e479171f94ea49f154c3d799ac086aa8638bb898&quot;&gt;latest
commit&lt;/a&gt;, it acquired a simple API. I use it as such:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh
URL=`xclip -o`
SHORT=`wget -qO- &quot;http://krzz.de/_api/save?url=$URL&quot;`
(echo -n $SHORT | xclip -i -display :0 -loops 0 ) &amp;amp;
/home/feh/bin/notify-wrapper &quot;krzz.de: switched URL in clipboard&quot; &quot;$SHORT&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now I simply bind a hotkey to call this program, and it will exchange
the URL from my X clipboard with a shortened version.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">statically linking dwm against X11 and XCB</title>
    <link href="http://blog.plenz.com/2011-08/statically-linking-dwm-against-x11-and-xcb.html" />
    <updated>2011-08-05T01:55:00+02:00</updated>
    <id>http://blog.plenz.com/2011-08/statically-linking-dwm-against-x11-and-xcb</id>
    <content type="html">&lt;p&gt;Today, virtually all binaries used on linux systems are dynamically
linked to several libraries. While it is commonly accepted statically
linking applications is &lt;em&gt;bad&lt;/em&gt; &amp;ndash; most notably in terms of
security concerns: fixing a library's bug means you won't have to
recompile all applications that are using that special library,
they'll simply load the version available at run-time &amp;ndash; there
are in fact good reasons to use static linking. (And for those who
claim statically linked binaries occupy much disk space: yeah, sure.
As if a few megs compared to a few hundred kilobytes make that much a
difference today, plus you don't have the overhead of looking up and
loading the libs in the first place.)&lt;/p&gt;

&lt;p&gt;As I mentioned in &lt;a href=&quot;http://blog.plenz.com/2011-07/switching-screen-for-tmux.html&quot;&gt;my post about tmux&lt;/a&gt; already, there's a
huge advantage to static linking: you can compile bleeding edge
software with bleeding edge library functions and still use them on
reasonably outdated systems (think: Debian stable).&lt;/p&gt;

&lt;p&gt;One division of rapidly evolving software I could never successfully link
statically was window managers like &lt;a href=&quot;http://dwm.suckless.org/&quot;&gt;dwm&lt;/a&gt; or &lt;a href=&quot;http://awesome.naquadah.org/&quot;&gt;awesome&lt;/a&gt;.
However, especially considering the XCB development and adoption over
the past few years, to me it makes perfect sense. I'll just distribute
a copy of the window manager I use to different systems and have a
guarantee it'll work there, no matter the libxcb version (or if it's
available at all).&lt;/p&gt;

&lt;p&gt;Usually, however, it's not possible to just pass a &lt;code&gt;-static&lt;/code&gt; or
&lt;code&gt;-Wl,-Bstatic&lt;/code&gt; flag to the compiler (in my case, gcc). It'll fail to
find several symbols that are located in libraries that don't have to
be explicitly linked in. Such an error message might look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/usr/lib/libXinerama.a(Xinerama.o): In function `find_display':
(.text+0x89): undefined reference to `XextCreateExtension'
/usr/lib/libXinerama.a(Xinerama.o): In function `XineramaQueryScreens':
(.text+0x255): undefined reference to `XMissingExtension'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To find the appropriate library, you &lt;a href=&quot;http://stackoverflow.com/questions/3932742/static-library-auto-discovery-and-linking&quot;&gt;may try to use pkg-config&lt;/a&gt;.
I use a different approach, however. I have a shell function defined
called &lt;code&gt;findsym&lt;/code&gt; (beware, Z-Shell specialties apply):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;findsym () {
  [[ -z $1 ]] &amp;amp;&amp;amp; return 1
  SYMBOL=$1
  LIBDIR=${2:-/usr/lib}
  for lib in $LIBDIR/*.a
  do
    nm $lib &amp;amp;&amp;gt; /dev/null | grep -q $SYMBOL &amp;amp;&amp;amp; \
      print &quot;symbol found in $lib\n -L$LIBDIR -l${${lib:t:r}#lib}&quot;
  done
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thus, I can simply go looking for the missing &lt;code&gt;XMissingExtension&lt;/code&gt;
symbol like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ findsym XMissingExtension
symbol found in /usr/lib/libXext.a
 -L/usr/lib -lXext
symbol found in /usr/lib/libXi.a
 -L/usr/lib -lXi
symbol found in /usr/lib/libXinerama.a
 -L/usr/lib -lXinerama
symbol found in /usr/lib/libXrandr.a
 -L/usr/lib -lXrandr
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, I use the readme file, some common sense or symple try'n'error to
find out which library I'd best link in, too. In this case, it's
adding a simple &lt;code&gt;-lXext&lt;/code&gt; to the &lt;code&gt;LDFLAGS&lt;/code&gt; part.&lt;/p&gt;

&lt;p&gt;Thus, I come up with the following diff to dwm's &lt;code&gt;config.mk&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;--- a/config.mk
+++ b/config.mk
@@ -16,7 +16,7 @@ XINERAMAFLAGS = -DXINERAMA

 # includes and libs
 INCS = -I. -I/usr/include -I${X11INC}
-LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${XINERAMALIBS}
+LIBS = -L/usr/lib -L${X11LIB} -static -lX11 ${XINERAMALIBS} -lxcb -lXau -lXext -lXdmcp -lpthread -ldl

 # flags
 CPPFLAGS = -DVERSION=\&quot;${VERSION}\&quot; ${XINERAMAFLAGS}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There's one important point here: libX11 will (to me, it seems,
inevitably) load another library, not sure why or which one. Thus, it
is vitally important to statically link in &lt;code&gt;libdl&lt;/code&gt;, the library that
dynamically loads another library. Otherwise, the follwing error
messages appear:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/usr/lib/libX11.a(CrGlCur.o): In function `open_library':
(.text+0x3b): undefined reference to `dlopen'
/usr/lib/libX11.a(CrGlCur.o): In function `fetch_symbol':
(.text+0x6b): undefined reference to `dlsym'
/usr/lib/libX11.a(CrGlCur.o): In function `fetch_symbol':
(.text+0x88): undefined reference to `dlsym'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With the above modification to &lt;code&gt;config.mk&lt;/code&gt;, dwm will compile and link
just fine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ file dwm
dwm: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
statically linked, for GNU/Linux 2.6.18, not stripped
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can reduce the binary's size by a few hundred kilobytes by
manually calling &lt;code&gt;strip(1)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The binary works very well for me. I'll try to use it on different
systems over the next few weeks and see what happens. If that works
out well, I'll also try to get lucky with awesome and zathura, as
these (and the libraries needed) are not installed on many systems,
either.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">switching screen for tmux</title>
    <link href="http://blog.plenz.com/2011-07/switching-screen-for-tmux.html" />
    <updated>2011-07-21T21:35:00+02:00</updated>
    <id>http://blog.plenz.com/2011-07/switching-screen-for-tmux</id>
    <content type="html">&lt;p&gt;I had invited &lt;a href=&quot;http://www.linuxtag.org/2011/de/presse/newsarchiv/entry/article/featured-nicholas-marriott-tmux.html&quot;&gt;Nicholas Marriott&lt;/a&gt; to LinuxTag 2011 in Berlin to
give a talk on &lt;code&gt;tmux&lt;/code&gt;. I was conviced I should drop screen for tmux,
but ... Yesterday would be the day I first installed the program, and
by now I'm actively using it.&lt;/p&gt;

&lt;p&gt;It was not without pressure, though. I had volunteered to give a talk on
tmux at work, and today was the date. See the &lt;a href=&quot;http://userpage.fu-berlin.de/~plenz/tmux.pdf&quot;&gt;quick'n'dirty slides
here&lt;/a&gt; (in German).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tmux&lt;/code&gt; needs a fairly recent &lt;code&gt;libevent&lt;/code&gt;. So if you want to run a recent
tmux version (1.5) on a Debian stable system, you should consider
linking it statically like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ./configure --enable-static
$ sed -i '/^LIBS =/s/$/ -lresolv/' Makefile
$ make CC='gcc -static'
$ cp tmux ~/bin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;sed&lt;/code&gt; call is needed to make the static linking work, otherwise
&lt;code&gt;gcc&lt;/code&gt; will fail to find the symbol &lt;code&gt;__b64_ntop&lt;/code&gt;, which is part of
&lt;code&gt;glibc&lt;/code&gt;'s &lt;code&gt;libresolv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First action to be taken is to make Ctrl-A the prefix. I mean,
seriously, why would you use Ctrl-B? It's for &quot;previous page&quot; or
&lt;a href=&quot;https://github.com/Feh/configs/blob/0d74e6114254b0d145589b98926e8600d6397629/.zsh/zshrc#L1220&quot;&gt;previous argument&lt;/a&gt;!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;unbind C-b
set -g prefix C-a
bind a send-prefix
bind C-a last-window
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next is the status bar. The syntax is pretty self-explanatory.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set -g status-bg yellow
set -g status-fg black
set -g status-interval 5

set -g status-left &quot;#[fg=red]#S %H:%M &quot;
set -g status-right &quot;#H: #(cut -d' ' -f1-3 /proc/loadavg)&quot;

set -w -g window-status-current-bg red
set -w -g window-status-current-fg yellow
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also, cycling through the windows becomes easier. The &lt;code&gt;-r&lt;/code&gt; switch to
&lt;code&gt;bind&lt;/code&gt; allows half a second time (set via &lt;code&gt;repeat-time&lt;/code&gt;) to perform
the next keystroke without pressing the prefix again. So
&lt;code&gt;&amp;lt;prefix&amp;gt;&amp;lt;space&amp;gt;&amp;lt;space&amp;gt;&amp;lt;space&amp;gt;&lt;/code&gt; will move you three windows ahead:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# repeated space/backspace toggles windows forward/backwards
bind -r Space next-window
bind -r C-Space next-window
bind -r C-h previous-window
bind -r C-? previous-window
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This feature is very handy for resizing or switching panes repeatedly.
(Read more about sessions/windows/panes in the docs...)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bind -r h select-pane -L
bind -r j select-pane -D
bind -r k select-pane -U
bind -r l select-pane -R
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Having multiple panes in one window is easy enough. Splitting panes,
however, is sort of counter-intuitive: A horizontal split (&lt;code&gt;split-window
-h&lt;/code&gt;) will divide the current pane into two panes that are horizontally
next to each other &amp;ndash; i.e., a &lt;em&gt;horizontal&lt;/em&gt; split will introduce a
&lt;em&gt;vertical&lt;/em&gt; split line between to panes. &lt;a href=&quot;http://blog.hawkhost.com/2010/06/28/tmux-the-terminal-multiplexer/&quot;&gt;This resource&lt;/a&gt; has
a nice idea to make splitting more idiomatic:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bind | split-window -h
bind - split-window -v
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For a great feature, check out &lt;code&gt;link-window&lt;/code&gt;. If you do name your
sessions and windows in a predictable way so that you can match them
via &lt;code&gt;fnmatch(3)&lt;/code&gt;, you'll be able to do cool things like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bind M link-window -s comm:mutt*
bind I link-window -s comm:irssi*
bind K unlink-window
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So with Prefix-M you'll quickly bring up the mutt instance of your
communication's session, and will detach that single window with
Prefix-K again. That's especially handy for things like Mail and IRC
client, music player, Todo Lists ...&lt;/p&gt;

&lt;p&gt;Side note: Sadly, it's not possible without some tricks to link a
&lt;em&gt;window&lt;/em&gt; from another session to a &lt;em&gt;pane&lt;/em&gt; (sub-window) in the current
session. (Think a ten-line-high IRC client at the bottom of your
current window.) The &lt;a href=&quot;http://tmux.svn.sourceforge.net/viewvc/tmux/trunk/FAQ&quot;&gt;FAQ&lt;/a&gt; says &quot;[fixing this] is a big todo item
but quite invasive&quot;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Sprunge, the fine pastebin service</title>
    <link href="http://blog.plenz.com/2011-07/sprunge-the-fine-pastebin-service.html" />
    <updated>2011-07-20T23:55:00+02:00</updated>
    <id>http://blog.plenz.com/2011-07/sprunge-the-fine-pastebin-service</id>
    <content type="html">&lt;p&gt;I have never understood why automatically pasting to a pastebin
service should be so hard as in &quot;I need a &lt;a href=&quot;http://wgetpaste.zlin.dk/&quot;&gt;huge script&lt;/a&gt; to
do the job!&quot;.&lt;/p&gt;

&lt;p&gt;Luckily, once in a while there are &lt;a href=&quot;http://github.com/rupa/&quot;&gt;smart people&lt;/a&gt; that build good
and simple applications. &lt;a href=&quot;http://sprunge.us/&quot;&gt;Enter &lt;em&gt;sprunge&lt;/em&gt;, the first truly sane
pastebin service&lt;/a&gt;. Need to know how it works? You'll find the
man page on their website (no, really). &amp;ndash; No listing of pastes. No
annotation, comments, amendments. No foobar. Paste away!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sprunge &amp;lt; ~/bin/sprunge 
 http://sprunge.us/OcPR

$ wget -qO- http://sprunge.us/OcPR
#!/bin/sh
exec curl -F 'sprunge=&amp;lt;-' http://sprunge.us
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Represent directory structures in LaTeX</title>
    <link href="http://blog.plenz.com/2011-07/represent-directory-structures-in-latex.html" />
    <updated>2011-07-18T12:13:00+02:00</updated>
    <id>http://blog.plenz.com/2011-07/represent-directory-structures-in-latex</id>
    <content type="html">&lt;p&gt;When writing the &lt;a href=&quot;http://gitbu.ch/&quot;&gt;git book&lt;/a&gt; we faced a problem: when
dealing with an example repository, how do you describe a directory
structure?&lt;/p&gt;

&lt;p&gt;Simply &quot;writing&quot; about it is the cheap apporach, although pretty
stupid: most readers (including me) would skip over the paragraph.
Later, they'd be confused when we'd refer to a specific property of
the repository layout.&lt;/p&gt;

&lt;p&gt;The intermediate approach was to simply paste the output of the &lt;code&gt;tree&lt;/code&gt;
unix command. That was hard to &quot;parse&quot; though, and didn't look well.&lt;/p&gt;

&lt;p&gt;It is clear that a graphic representation of the directory structure
is optimal. But: how? The easiest way would be to install some
graphical application that can represent tree-structures, such as
Nautilus. There are no upsides to this, but two minor downsides: it
looks crappy, and it requires you to install some hundred megabytes of
gnome-wtf-libs.&lt;/p&gt;

&lt;p&gt;The major downside is this: If you want to re-do the screenshot,
you'll need the same directory structure, the same setup, GNOME
styles, same selection to grab, ... there is no easy way to automate
this.&lt;/p&gt;

&lt;p&gt;Not wanting to settle for the cheap way, what were the goals our
solution had to meet?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;can be understood at one glance (important)&lt;/li&gt;
&lt;li&gt;can be automated and tracked in git (important)&lt;/li&gt;
&lt;li&gt;does not eat up much space on the page&lt;/li&gt;
&lt;li&gt;doesn't depend on colors&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;An alternative that came to my mind was to use &lt;a href=&quot;http://www.graphviz.org/&quot;&gt;GraphViz's&lt;/a&gt;
&lt;code&gt;neato&lt;/code&gt; tool. I wrote a Perl script to convert a directory structure
to a diagram. The code's too cruel to be released to the world. You
can imagine what it looks like by invoking:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;neato -Txlib &amp;lt;&amp;lt;EOF
graph G {
  n1 [shape=folder width=1 style=filled label=&quot;baz&quot; pos=&quot;0.00,0.00!&quot;];
  n2 [shape=box height=.2 width=1 labelloc=t label=&quot;file&quot; pos=&quot;0.00,-0.60!&quot;];
  n3 [shape=folder width=1 style=filled label=&quot;foo&quot; pos=&quot;0.00,-1.20!&quot;];
  n4 [shape=folder width=1 style=filled label=&quot;bar&quot; pos=&quot;1.20,-1.20!&quot;];
  n3 -- n4;
  n1 -- n2 -- n3;
}
EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, this output did not meet above criteria #3&amp;amp;4. It looked even
cheaper than simple &lt;code&gt;tree&lt;/code&gt; output.&lt;/p&gt;

&lt;p&gt;The solution we settled for was &lt;a href=&quot;http://www.ctan.org/tex-archive/macros/generic/dirtree&quot;&gt;dirtree.sty&lt;/a&gt;. It works like this:
You download the &lt;code&gt;dirtree.sty&lt;/code&gt; and &lt;code&gt;dirtree.tex&lt;/code&gt; file, place them
within your project and add a &lt;code&gt;\usepackage{dirtree}&lt;/code&gt;. In theory, you
can then include a &lt;code&gt;\dirtree{}&lt;/code&gt; declaration (see the docs for
details).&lt;/p&gt;

&lt;p&gt;For example, this code (note the percent sign on line #1)...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;\dirtree{ %
.1 .git/.
.2 HEAD.
.2 config.
.2 hooks/.
.2 index.
.2 info/.
.2 logs/.
.3 HEAD.
.3 refs/.
.2 objects/.
.3 info/.
.3 pack/.
.2 refs/.
.3 heads/.
.3 remotes/.
.3 tags/.
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will produce the following graphic:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/dirtree.sty-example.png&quot; style=&quot;width: 150px;&quot; alt=&quot;dirtree.sty example&quot; /&gt;&lt;/p&gt;

&lt;p&gt;However, since it's not part of the LaTeX standard distribution, you
cannot be sure about it's stability. It may use &quot;dangerous&quot; LaTeX
constructs, etc... certainly nothing you want to include &quot;as-is&quot; in a
book that'll eventually be printed. Also, the book will go through a
conversion process to be distributed as an Ebook. You wouldn't want
such a little LaTeX hack to be a show-stopper &amp;ndash; or, worse yet,
discover document corruption just after you got some thousand fresh
copies from the printing press.&lt;/p&gt;

&lt;p&gt;EPS/PDF files are stable, however. So what we did was this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Put the &lt;code&gt;\dirtree{}&lt;/code&gt; statements into separate files, including some
&lt;code&gt;\begin{document}&lt;/code&gt; stuff so that it will compile to a PDF file
containing just the diagram.&lt;/li&gt;
&lt;li&gt;Remove any whitespace. We use &lt;a href=&quot;http://pdfcrop.sourceforge.net/&quot;&gt;pdfcrop&lt;/a&gt; for that.&lt;/li&gt;
&lt;li&gt;Convert to EPS.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;In terms of Makefile statements, &lt;a href=&quot;http://haenel.co&quot;&gt;Valentin&lt;/a&gt; came up with
this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;files=objektmodell-programm-crop\
    svn-stdlayout-crop\
    svn-nonstdlayout-crop\
    svn-branches-crop\
    git-branches-crop\
    git-dir-crop

pdfs=$(addsuffix .pdf, $(files))
epss=$(addsuffix .eps, $(files))

all: $(pdfs) $(epss)

clean:
    -rm -v *.pdf *.eps *.aux *.log

%.pdf : %.tex
    pdflatex $&amp;lt;

%-crop.pdf : %.pdf
    pdfcrop $&amp;lt;

%-crop.eps : %-crop.pdf
    pdftops -eps $&amp;lt; $@
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now it's as simple as &lt;code&gt;make -C dir-listings &amp;amp;&amp;amp; git add dir-listings&lt;/code&gt;
(with an appropriate &lt;code&gt;.gitignore&lt;/code&gt; file) to record changes to diagrams
and recompile the PDF and EPS files. If you don't plan to keep the
compiled files in your repository, you can also add a dependency for
the subdirectory to your main Makefile.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">I failed the social web, again</title>
    <link href="http://blog.plenz.com/2011-07/i-failed-the-social-web-again.html" />
    <updated>2011-07-12T12:59:00+02:00</updated>
    <id>http://blog.plenz.com/2011-07/i-failed-the-social-web-again</id>
    <content type="html">&lt;p&gt;For some days now, &lt;a href=&quot;http://plus.google.com/&quot;&gt;G+&lt;/a&gt; has opened its doors to beta testers.
All the people &lt;a href=&quot;http://i.imgur.com/KChTH.gif&quot;&gt;want invitations&lt;/a&gt;, and Reddit realized for
a long time already that &lt;a href=&quot;http://i.imgur.com/6abzK.jpg&quot;&gt;Facebook will be the new MySpace&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, last tuesday or so I saw G+ at a friend's, who sent me an
invitation. Friday, I pondered the question of whether or not to sign
up for G+ &amp;ndash; literally for hours. (I have to admit, though, that
while lying on my bed and considering the arguments, I fell asleep for
a short period.)&lt;/p&gt;

&lt;p&gt;I had seen some of the freshly-made Google profiles of the avant-garde
&amp;ndash; that is, technophile persons whose blogs I enjoy from time to
time &amp;ndash; and was rather impressed of the quality content they
posted. So I decided to give it a try.&lt;/p&gt;

&lt;p&gt;Now this was a major step! G+ would be the first Google product I
would use that requires registration. So I went through the process
and was eager to try out G+. However, as I had heard already, getting
an invite doesn't mean you can use it right away, it might take a day
or two.&lt;/p&gt;

&lt;p&gt;To make a long story short: While waiting for this timespan to elapse,
I browsed through various circles. And what I saw struck me as a
Facebook for grown ups: People I don't know talking about stuff I
don't care about, in a way that might be appropriate in a bar
atmosphere, but not to be archived publicly until ... forever or
something.&lt;/p&gt;

&lt;p&gt;A day later I got a second invite, and I could continue to the G+
thing. However, the site that came up told me my browser was not
supported (it's FF 3.5). So, it seems I'm not avant-garde enough to
use G+.&lt;/p&gt;

&lt;p&gt;I just deleted my freshly created Google account. I mean, come on,
it's sunny outside and there's a pile of unread books waiting!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Southern Sudan's Secession</title>
    <link href="http://blog.plenz.com/2011-07/southern-sudans-secession.html" />
    <updated>2011-07-07T19:35:00+02:00</updated>
    <id>http://blog.plenz.com/2011-07/southern-sudans-secession</id>
    <content type="html">&lt;p&gt;I am closely following the secession of Southern Sudan. It is a very
intriguing situation &amp;ndash; the birth of a new state.&lt;/p&gt;

&lt;p&gt;Information is scarce about this topic. The &lt;a href=&quot;http://www.sudantribune.com/index.php&quot;&gt;Sudan Tribune&lt;/a&gt;
provides some insights, but most quality coverage is done by
Al&amp;nbsp;Jazeera &lt;a href=&quot;http://english.aljazeera.net/InDepth/spotlight/southernsudanindependence/&quot;&gt;here&lt;/a&gt;. Some facts to consider
(quoted from &lt;a href=&quot;http://english.aljazeera.net/indepth/spotlight/southernsudanindependence/2011/06/2011630102213823618.html&quot;&gt;here&lt;/a&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The political system is dominated by one party [the SPLM]&lt;/li&gt;
&lt;li&gt;Other opposition parties are extremely weak&lt;/li&gt;
&lt;li&gt;Parliamentary elections in April 2010 were marred by widespread
reports of intimidation and fraud&lt;/li&gt;
&lt;li&gt;Juba [the Capitol-to-be] produces more than three-quarters of
Sudan's 500,000 barrels per day of oil&lt;/li&gt;
&lt;li&gt;98 per cent of government revenue comes from the petroleum sector&lt;/li&gt;
&lt;li&gt;Southern Sudan has just 60 kilometres of paved roads, and
electricity is provided only intermittently by generators&lt;/li&gt;
&lt;li&gt;southern officials estimate that between 150,000 and 200,000 people
&amp;ndash; in a region of 20 million &amp;ndash; are on the army's payroll&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Eritrea, Libya and Iran have already stated they won't recognize
Southern Sudan as a state. Most western countries probably will, as
plans are persued to open embassies in Juba. (Juba has just been
getting a new international airport &amp;ndash; I wonder how much fuel
they keep on stock to operate it just with generator power?)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Perl: use feature;</title>
    <link href="http://blog.plenz.com/2011-07/perl-use-feature.html" />
    <updated>2011-07-02T14:38:00+02:00</updated>
    <id>http://blog.plenz.com/2011-07/perl-use-feature</id>
    <content type="html">&lt;p&gt;With it's 5.10 version, Perl learned some pretty interesting new
features. Some of them modify the syntactic interpretation of Perl
code, so to stay backwards-compatible, you have to manually enable
them. To do this, add a line like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;use feature qw(:5.10);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to your other &lt;code&gt;use&lt;/code&gt; declarations. (For one-liners, add the &lt;code&gt;-E&lt;/code&gt;
command line switch.) The documentation is available via &lt;code&gt;perldoc
feature&lt;/code&gt; or &lt;a href=&quot;http://search.cpan.org/~jesse/perl-5.14.1/lib/feature.pm&quot;&gt;online&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There's one pretty trivial change that nonetheless has bothered me for
a long time already. Why is there no function in Perl to print out
some strings, and then finish with a newline? I mean, almost every
sane programming language has this, and it helps writing clean code a
lot (no fiddling with &lt;code&gt;\n&lt;/code&gt; and so on). &amp;ndash; Now, they backported
the &lt;code&gt;say&lt;/code&gt; function from Perl 6, which does just that: &lt;a href=&quot;http://search.cpan.org/~jesse/perl-5.14.1/pod/perlfunc.pod#say&quot;&gt;add an omplicit
newline&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The new concept of state variables is nothing I need for now; however,
the feature they strangely call &lt;code&gt;switch&lt;/code&gt; (although the actual keywords
are &lt;code&gt;given&lt;/code&gt;/&lt;code&gt;when&lt;/code&gt;) is pretty nice: It's pretty much like what you'd
expect with a typical C construct like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;switch(var) {
    case 1:
        /* do something */
        break;
    ...

    default:
        /* do default thing */
        break;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Perl that's now:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;given($var) {
    when(condition1) {
        # do something
    }

    do_other_thing when condition2; # as one-liner

    default {
        # fallthrough case
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; The &lt;code&gt;statement when condition;&lt;/code&gt; one-liner doesn't work.
Don't know where I got that from.&lt;/p&gt;

&lt;p&gt;You can use simple strings (maps to &lt;code&gt;$_ eq &quot;string&quot;&lt;/code&gt;), regular
expressions (maps to &lt;code&gt;$_ =~ /regex/&lt;/code&gt;) or function references like
&lt;code&gt;\&amp;amp;myfunc&lt;/code&gt; (maps to &lt;code&gt;myfunc($_)&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The best improvement, however, are so-called &lt;em&gt;named captures&lt;/em&gt;.
(You don't have to enable those specifically.)
It allows regexes to contain pairs of parentheses that you can assign
a name to later extract the match. That means: no stupid and
mind-boggling re-numbering of &lt;code&gt;$2&lt;/code&gt; to &lt;code&gt;$3&lt;/code&gt; etc., just because you
added a set of brackets around something you want to extract from a
string. Consider this example regex:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;my $re = qr/
    (?&amp;lt;user&amp;gt;[^\@\s]+)
    \@
    (?&amp;lt;domain&amp;gt;[^\s&quot;&amp;gt;]+)
    /x;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can now access the user-part of the e-mail address via &lt;code&gt;$+{user}&lt;/code&gt;,
not necessarily via &lt;code&gt;$1&lt;/code&gt;. The immediate gain is obvious: if you add
parentheses around the whole expression (to capture the whole e-mail
address) the user part is still available via &lt;code&gt;$+{user}&lt;/code&gt;. The numbered
variable would be &lt;code&gt;$2&lt;/code&gt; now, though.&lt;/p&gt;

&lt;p&gt;Another side-effect is that you can test several regexes in a row now, and
later extract matching parts from all of these &amp;ndash; of course only
if you use distinct capture names. Hash entries in &lt;code&gt;%+&lt;/code&gt; will only be
updated upon a match (and won't be cleared AFAIK, at least in the
lexical scope).&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">ending the silence</title>
    <link href="http://blog.plenz.com/2011-06/ending-the-silence.html" />
    <updated>2011-06-13T18:14:00+02:00</updated>
    <id>http://blog.plenz.com/2011-06/ending-the-silence</id>
    <content type="html">&lt;p&gt;It has been a little more than three months since I last posted
something here in my blog. Considering that the first post ever in
this blog was from 1st of January this year, this pretty much looked
like a &quot;tried to blog, but gave it up again&quot; thing.&lt;/p&gt;

&lt;p&gt;I was really busy, however, and was simply not able to write a single
post. What really ate up all my time was my latest pet project,
writing a &lt;a href=&quot;http://gitbu.ch/&quot;&gt;German book about Git&lt;/a&gt;. Valentin (my co-author)
and I worked really hard throughout the past few weeks &amp;ndash; only
got up once in a while to get something to eat and stock up on Club
Mate. The book is being published at &lt;a href=&quot;https://www.opensourcepress.de/&quot;&gt;Open Source Press&lt;/a&gt; and will
be available from the end of June. Go buy it!&lt;/p&gt;

&lt;p&gt;Now, with a lot of free time on my hands, I can finally get back to my
studies (yes, really). Also, I will devote more time to this blog. :-)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">git: find absolute path to tracked file</title>
    <link href="http://blog.plenz.com/2011-03/git-find-absolute-path-to-tracked-file.html" />
    <updated>2011-03-08T03:22:00+01:00</updated>
    <id>http://blog.plenz.com/2011-03/git-find-absolute-path-to-tracked-file</id>
    <content type="html">&lt;p&gt;If you need to name a blob by name, you can't trust Git to honor the
current working directory. If you are in a subdir, &lt;code&gt;git show
HEAD^:file&lt;/code&gt; won't work unless you prepend the subdirectory name.&lt;/p&gt;

&lt;p&gt;But there's a sort of &lt;code&gt;basename&lt;/code&gt; for absolute paths within a Git repo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git ls-tree --name-only --full-name HEAD file
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This honors &lt;code&gt;$PWD&lt;/code&gt; and thus returns a pathname that's unique across
the repository. You can build a simple &quot;diff to previous version&quot;
script with this now:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh

test ! -z &quot;$1&quot; || exit 1
temp=${1%.*}.HEAD^1.$$.${1#*.}
fullpath=`git ls-tree --name-only --full-name HEAD^ $1`

test ! -z &quot;$1&quot; || exit 2

echo &quot;extracting '$fullpath' from HEAD^...&quot;
git show HEAD^:$fullpath &amp;gt; $temp
vim -fd $1 $temp
echo &quot;cleaning up...&quot;
rm $temp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can act as a simplified &lt;code&gt;mergetool&lt;/code&gt; when you just want to
&lt;em&gt;review&lt;/em&gt; changes made to some file.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">git: forget recorded resolution</title>
    <link href="http://blog.plenz.com/2011-03/git-forget-recorded-resolution.html" />
    <updated>2011-03-01T05:24:00+01:00</updated>
    <id>http://blog.plenz.com/2011-03/git-forget-recorded-resolution</id>
    <content type="html">&lt;p&gt;Git's &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-rerere.html&quot;&gt;rerere&lt;/a&gt; is immensely useful. However, if you erroneously
record a &lt;em&gt;wrong&lt;/em&gt; conflict resolution, it's not entirely clear how to
delete it again. The preimage file is stored under
&lt;code&gt;$GIT_DIR/rr-cache/some-sha1-sum/preimage&lt;/code&gt;, which is not a convenient
place to look for that one wrong resolution if you have hundreds of
them. ;-)&lt;/p&gt;

&lt;p&gt;However, &lt;code&gt;v1.6.6-9-gdea4562&lt;/code&gt; introduced rerere's &lt;code&gt;forget&lt;/code&gt; subcommand,
which was not documented until recently (&lt;code&gt;v1.7.1.1-2-g2c64034&lt;/code&gt;). So
when rerere replays a wrong resolution onto your file, simply use &lt;code&gt;git
rerere forget path/to/file&lt;/code&gt; to forget the wrong resolution.&lt;/p&gt;

&lt;p&gt;To (temporarily) replace the resolved version with the originial
version containing conflict markers, use &lt;code&gt;git checkout -m --
path/to/file&lt;/code&gt;. You can then issue a &lt;code&gt;git rerere&lt;/code&gt; to replay the
resolution again.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">vi mode in GNU readline</title>
    <link href="http://blog.plenz.com/2011-02/vi-mode-in-gnu-readline.html" />
    <updated>2011-02-28T11:56:00+01:00</updated>
    <id>http://blog.plenz.com/2011-02/vi-mode-in-gnu-readline</id>
    <content type="html">&lt;p&gt;I am stuck in a course about computer algebra systems. We are using
&lt;a href=&quot;http://www.singular.uni-kl.de/&quot;&gt;Singular&lt;/a&gt;. I searched for some minutes how to switch on the vi mode on
the Singular command line, but apparently, there is none.&lt;/p&gt;

&lt;p&gt;However, since Singular uses the GNU readline libs, you can simply &lt;a href=&quot;http://tiswww.case.edu/php/chet/readline/readline.html#SEC22&quot;&gt;switch to
vi mode&lt;/a&gt; with Ctrl-Meta-j. &amp;ndash; How convenient is that. I wonder if
there's a possibility to configure readline to switch to vi mode by default.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">criss-cross subtree merges</title>
    <link href="http://blog.plenz.com/2011-02/criss-cross-subtree-merges.html" />
    <updated>2011-02-19T19:55:00+01:00</updated>
    <id>http://blog.plenz.com/2011-02/criss-cross-subtree-merges</id>
    <content type="html">&lt;p&gt;Note to self: It is bad to rely on Git's magic of finding out whether
you can fast-forward when doing a merge. The more clever way is to
explicitly state what you want to do with aliases:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nfm = merge --no-ff     # no-ff-merge
ffm = merge --ff-only   #    ff-merge
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I stumbled upon this today when I played around with subtree merges.
Strangely, the results with the &lt;em&gt;strategy&lt;/em&gt; &lt;code&gt;subtree&lt;/code&gt; were not the same
as with &lt;code&gt;recursive&lt;/code&gt;'s &lt;code&gt;subtree=path&lt;/code&gt; option:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git merge -s recursive doc
$ git merge -Xsubtree=Documentation doc
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Turns out that &amp;ndash; in the special case I had created &amp;ndash; Git
could fast-forward the branch although it was a subtree merge,
effectively ignoring any strategy option. Duh. I had already read,
understood and tried all the tests related to merging before I had
figured &lt;em&gt;that&lt;/em&gt; out.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Zathura</title>
    <link href="http://blog.plenz.com/2011-02/zathura.html" />
    <updated>2011-02-15T18:38:00+01:00</updated>
    <id>http://blog.plenz.com/2011-02/zathura</id>
    <content type="html">&lt;p&gt;I like small, clean software, that focuses on keyboard usability.
&lt;a href=&quot;http://pwmt.org/&quot;&gt;PWMT&lt;/a&gt;, &quot;programs with movie titles&quot;, has a nice and fast(!) PDF
viewer called Zathura. The user interface looks just like Vimperator
(or Vimprobable, for that matter). I like!&lt;/p&gt;

&lt;p&gt;The config file syntax is not documented. (Only on the web site, which
is not available at the moment.) So you'll have to change the colors
within &lt;a href=&quot;git://pwmt.org/zathura.git&quot;&gt;the code&lt;/a&gt; itself. &lt;code&gt;libpoppler-glib-dev&lt;/code&gt; is required to
build Zathura.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">git tracking branch management</title>
    <link href="http://blog.plenz.com/2011-02/git-tracking-branch-management.html" />
    <updated>2011-02-10T16:33:00+01:00</updated>
    <id>http://blog.plenz.com/2011-02/git-tracking-branch-management</id>
    <content type="html">&lt;p&gt;There are different approaches 'round the net on how to deal with git
remote tracking branches in an effecient way. Some people have
written Ruby gems (&lt;em&gt;uggh&lt;/em&gt;) that introduce lots of not-so-intuitive git
subcommands to manage all kinds of tracking branches.&lt;/p&gt;

&lt;p&gt;In recent versions of Git however, I have no need for these scripts. I
can live with the following aliases:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;lu = log ..@{u}
ft = merge --ff-only @{u}
track = branch --set-upstream
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To track a branch, I enter &lt;code&gt;git track master origin/master&lt;/code&gt;, for
example. (By the way, if you create a new branch and want to push it
to a remote, use &lt;code&gt;push -u&lt;/code&gt; &amp;ndash; it will automatically set up your
current branch to track the remote branch you just created.)&lt;/p&gt;

&lt;p&gt;Then, my regular workflow looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git remote update     # fetch changes
$ git lu                # log ..upstream -- review changes
$ git ft                # ff tracking branch -- integrate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The key here is using &lt;code&gt;@{u}&lt;/code&gt;, which is a short form of &lt;code&gt;@{upstream}&lt;/code&gt;,
a reference to the upstream branch (that is, the branch your &lt;code&gt;HEAD&lt;/code&gt; is
tracking). This special notation first appeared in Git 1.7.0.&lt;/p&gt;

&lt;p&gt;If you're not sure about the current status of your branches and what
they are tracking, simply use &lt;code&gt;git branch -vv&lt;/code&gt;. You'll find the
tracking information in brackets just before the commit description.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Egypt's net censorship and DNS tunneling</title>
    <link href="http://blog.plenz.com/2011-02/egypts-net-censorship-and-dns-tunneling.html" />
    <updated>2011-02-03T18:19:00+01:00</updated>
    <id>http://blog.plenz.com/2011-02/egypts-net-censorship-and-dns-tunneling</id>
    <content type="html">&lt;p&gt;I got a call yesterday &amp;ndash; from Egypt. It was around noon local
time, i.e. shortly after Egypt's government &lt;a href=&quot;http://english.aljazeera.net/news/middleeast/2011/02/201122113055781707.html&quot;&gt;had restored regular
internet access&lt;/a&gt; (&lt;a href=&quot;http://bgpmon.net/blog/?p=480&quot;&gt;see also&lt;/a&gt;, &lt;a href=&quot;http://stat.ripe.net/egypt/&quot;&gt;more graphs&lt;/a&gt;). At the
time of the call, I didn't know that, though.&lt;/p&gt;

&lt;p&gt;The guy asked me whether I could help him set up &lt;a href=&quot;http://www.dnstunnel.de&quot;&gt;DNS tunneling&lt;/a&gt;.
Today, he called again and inquired how things were going. He told me
he wanted to have a backup internet connection if things would get
messy again.&lt;/p&gt;

&lt;p&gt;I think, however, that DNS tunneling wouldn't be able to bypass the
internet block. &lt;a href=&quot;http://www.pcmag.com/article2/0,2817,2376863,00.asp&quot;&gt;On the day of the shutdown&lt;/a&gt; (Jan 27th, shortly
before midnight UTC),&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&quot;Approximately 3,500 individual &lt;a href=&quot;http://en.wikipedia.org/wiki/Bgp&quot;&gt;BGP routes&lt;/a&gt; were withdrawn, leaving no
valid paths by which the rest of the world could continue to exchange
Internet traffic with Egypt's service providers, ... Virtually all
of Egypt's Internet addresses are now unreachable, worldwide.&quot;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;For a more technical analysis, see &lt;a href=&quot;http://bgpmon.net/blog/?p=450&quot;&gt;this BGPmon blog post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What this means is that Egypt was essentially split off the net. Thus,
even a DNS query from inside Egypt (which would be relayed to a server
in, say, Germany) could not be forwarded by the provider's DNS
servers. Neither could a DNS request from Germany reach a name server
located in Egypt. &lt;a href=&quot;http://countermeasures.trendmicro.eu/egypt-the-plague-of-darkness/&quot;&gt;This blog post&lt;/a&gt; claims that the providers
did shut down DNS access as well (which wouldn't matter much in that
situation, anyway).&lt;/p&gt;

&lt;p&gt;So, to evade this blockade (i.e., IP won't get routed) it takes more
than just trying to sneak data out using covert IP channels.&lt;/p&gt;

&lt;p&gt;There are other methods, of course. Protesters &lt;a href=&quot;http://english.aljazeera.net/news/middleeast/2011/02/201122113055781707.html&quot;&gt;set up a voice to
tweet converter&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&quot;Over the weekend we came up with the idea of a speak-to-tweet
service &amp;ndash; the ability for anyone to tweet using just a voice
connection,&quot; they said.&lt;/p&gt;

&lt;p&gt;Voice mail messages left at +16504194196; +390662207294 or
+97316199855 will instantly be converted into text messages,
referred to as tweets, and posted at Twitter with an identifying
&quot;hashtag&quot; of &lt;code&gt;#egypt&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;You could use other radio infrastructure as well to communicate with
other countries, which would then feed your data stream into the net.
That's not possible on a large scale and for the typical user,
however.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Firefox: Open in Browser</title>
    <link href="http://blog.plenz.com/2011-02/firefox-open-in-browser.html" />
    <updated>2011-02-01T23:49:00+01:00</updated>
    <id>http://blog.plenz.com/2011-02/firefox-open-in-browser</id>
    <content type="html">&lt;p&gt;It's been bothering me for years. There are a lot of file types that
are essentially plaintext, but are labeled differently to make the
browser's/mailer's decision easier which program is best to handle
this type of file. For example, &lt;code&gt;text/x-diff&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, how hard could it be to include a little checkbox &quot;display in
browser&quot; in the file download dialog? I mean, it's &lt;em&gt;text&lt;/em&gt; after all.
But, apparently, &lt;a href=&quot;https://bugs.launchpad.net/firefox/+bug/25830&quot;&gt;it is quite hard&lt;/a&gt;. Yes, that's no display
failure, that thing has been suggested at the end of 1999 and the bug
report pushed back and forth since then. Stupid morons.&lt;/p&gt;

&lt;p&gt;However, there's a nice &lt;a href=&quot;https://addons.mozilla.org/en-US/firefox/addon/open-in-browser/&quot;&gt;addon&lt;/a&gt; which does just this job.&lt;/p&gt;

&lt;p&gt;On a related note, since the last upgrade, opening context or dropdown
menus will take Firefox up to 30 seconds sometimes. No heavy CPU or
disk usage, the application just freezes.&lt;/p&gt;

&lt;p&gt;I hope I'll find some time during the next few weeks to migrate to
&lt;a href=&quot;http://www.uzbl.org/&quot;&gt;a&lt;/a&gt; &lt;a href=&quot;http://www.vimprobable.org/&quot;&gt;saner&lt;/a&gt; &lt;a href=&quot;http://surf.suckless.org/&quot;&gt;alternative&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Google: Fast search result retrieval</title>
    <link href="http://blog.plenz.com/2011-01/google-fast-search-result-retrieval.html" />
    <updated>2011-01-31T02:23:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/google-fast-search-result-retrieval</id>
    <content type="html">&lt;p&gt;This whole Google jQuery autosuggestion bothers the hell out of me. I
mean, why would you use several keystrokes and possibly the mouse to
find a page, continuously requesting suggestions in the background?&lt;/p&gt;

&lt;p&gt;Often I use Google to find a page I can pretty safely identify with
some simple keywords. For example, in an IRC conversation I want to
give someone a link to Al Jazeera's page about current events in
Egypt.&lt;/p&gt;

&lt;p&gt;Stupid way: 1. fire up browser, 2. enter search terms in address bar
(:tabopen in Vimperator), 3. wait for the kilobytes to trickle through
the line, 4. find your way around the page, 5. select link, 6. copy it
somehow, 7. switch back to IRC window, 8. paste URL. Estimated time
amount: ranging from anywhere between 10 seconds to 30 seconds.&lt;/p&gt;

&lt;p&gt;Clever way: write a shell script to extract &quot;I am feeling lucky&quot;
result.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/sh

test -z &quot;$1&quot; &amp;amp;&amp;amp; exit 1

URL=&quot;`curl -s -i -e 'http://www.google.com' -A 'Firefox 23' \
    -G -d hl=en -d btnI=lucky --data-urlencode q=\&quot;$1\&quot; \
    http://www.google.com/search | grep '^Location:' | \
    head -n 1 | cut -d' ' -f2 | tr -d '\r\n'`&quot;

echo -n &quot;$URL&quot; | (xclip -i -display :0 -loops 0 ) &amp;amp;
/home/feh/bin/notify-wrapper &quot;Google 1st result&quot; &quot;$URL&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Footnote: You need a more or less sensible User-Agent string (&lt;code&gt;-A&lt;/code&gt;) as
well as a request on &lt;strong&gt;www&lt;/strong&gt;.google.com, otherwise you won't be served a
result.)&lt;/p&gt;

&lt;p&gt;Then, bind a key to open a prompt in which you'll enter your search
term. For awesome, this is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;awful.key({ modkey }, &quot;g&quot;,
  function ()
    awful.prompt.run({ prompt = &quot;Google: &quot; },
      mypromptbox[mouse.screen].widget,
      function (s)
        awful.util.spawn(&quot;/home/feh/bin/glucky '&quot; .. s .. &quot;'&quot;)
      end,
      nil, nil)
  end
),
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;notify-wrapper&lt;/code&gt; script uses DBus's &lt;code&gt;notify-send&lt;/code&gt; to make a little
notification box appear as soon as the URL is retrieved (which is,
like, instantaneous).&lt;/p&gt;

&lt;p&gt;Clever way works like this now: 1. Press Mod1-g, 2. enter search term,
3. paste URL. Time you need to find a popular link: Time to type
search string + 1 second. Huge time saver.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Upgrading to Gitolite and CGit</title>
    <link href="http://blog.plenz.com/2011-01/upgrading-to-gitolite-and-cgit.html" />
    <updated>2011-01-31T00:42:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/upgrading-to-gitolite-and-cgit</id>
    <content type="html">&lt;p&gt;I finally found some time to update the git version used on my server.
It's running a 1.7.1 now, which is just &lt;em&gt;slightly&lt;/em&gt; better than the
previous 1.5 version. ;-)&lt;/p&gt;

&lt;p&gt;Debian package maintainers bother me again, though. The simply erase
the &lt;code&gt;git&lt;/code&gt; user and put a &lt;code&gt;gitdaemon&lt;/code&gt; user in it's place, without
asking for confirmation. Will probably happen with the next upgrade,
too...&lt;/p&gt;

&lt;p&gt;Now, having a recent git version enables me to set up &lt;a href=&quot;https://github.com/sitaramc/gitolite&quot;&gt;gitolite&lt;/a&gt;
instead of the old gitosis. Setup is easy, straight-forward and
described in many places.&lt;/p&gt;

&lt;p&gt;I used &lt;a href=&quot;http://idl0r.qasl.de/blog/index.php/2010/11/07/migrating-from-gitosis-to-gitolite&quot;&gt;this script&lt;/a&gt; to convert my existing &lt;code&gt;gitosis.conf&lt;/code&gt; to match
gitolite's syntax; I noticed a major hiccup though: &lt;a href=&quot;http://sitaramc.github.com/gitolite/doc/2-admin.html#gwd&quot;&gt;setting a
description automatically enables gitweb access&lt;/a&gt;. I had to read
the source to find this out, because I couldn't remember it from the
docs and it didn't once cross my mind that you could actually &lt;em&gt;want&lt;/em&gt;
the behaviour to be like that. &amp;ndash; As in, you could just describe
a project without wanting to make it public &amp;ndash; no?&lt;/p&gt;

&lt;p&gt;However, with gitolite, I can finally use &lt;a href=&quot;http://hjemli.net/git/cgit/&quot;&gt;CGit&lt;/a&gt; too (because only
gitolie produces a &lt;code&gt;repositories.list&lt;/code&gt; which is in the format that
CGit understands, ie. without description appended to the lines).&lt;/p&gt;

&lt;p&gt;So now the repository page is &lt;a href=&quot;http://git.plenz.com/&quot;&gt;all new and shiny&lt;/a&gt;. See, for
example, this &lt;a href=&quot;http://git.plenz.com/dwm/commit/&quot;&gt;side-by-side diff&lt;/a&gt;. Nice, and faster than Gitweb.&lt;/p&gt;

&lt;p&gt;Integrating CGit with Lighttpd was another two-hour
fiddle-try-fail-repeat session. I finally came up with this snippet:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$HTTP[&quot;host&quot;] =~ &quot;^git\.(plenz\.com|feh\.name)(:\d+)?$&quot; {
  alias.url = (
    &quot;/cgit.css&quot; =&amp;gt; &quot;/usr/share/cgit/cgit.css&quot;,
    &quot;/cgit.png&quot; =&amp;gt; &quot;/usr/share/cgit/cgit.png&quot;,
    &quot;/cgit.cgi&quot; =&amp;gt; &quot;/usr/lib/cgi-bin/cgit.cgi&quot;,
    &quot;/&quot;         =&amp;gt; &quot;/usr/lib/cgi-bin/cgit.cgi&quot;,
  )
  cgi.assign = ( &quot;.cgi&quot; =&amp;gt; &quot;&quot; )
  url.rewrite-once = (
    &quot;^/cgit\.(css|png)&quot; =&amp;gt; &quot;$0&quot;,
    &quot;^/.+&quot; =&amp;gt; &quot;/cgit.cgi$0&quot;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's important here that you noop-rewrite the CSS and PNG file to
make Lighty expand the alias. Also, rewriting to an absolute filepath
won't work; that's why the &lt;code&gt;cgit.cgi&lt;/code&gt; aliases have to appear twice.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">add -p for new files</title>
    <link href="http://blog.plenz.com/2011-01/add--p-for-new-files.html" />
    <updated>2011-01-30T22:19:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/add--p-for-new-files</id>
    <content type="html">&lt;p&gt;If you have a file that's unknown to git (ie., it appears in the
&quot;untracked&quot; section of &lt;code&gt;git status&lt;/code&gt;), and you want to add only part of
the file to the index, git won't allow it: &lt;code&gt;No changes.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Instead, mark the file for adding, but without adding any actual line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add -N file
$ git add -p file
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;-N&lt;/code&gt; is short for &lt;code&gt;--intent-to-add&lt;/code&gt; and does just that: Create an
index entry with an empty content field.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">dec2bin for the poor</title>
    <link href="http://blog.plenz.com/2011-01/dec2bin-for-the-poor.html" />
    <updated>2011-01-26T21:18:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/dec2bin-for-the-poor</id>
    <content type="html">&lt;p&gt;Convert &lt;code&gt;0x53&lt;/code&gt; to binary, quick! &amp;ndash; Now you start to think: In
which language could you implement a &lt;code&gt;dec2bin&lt;/code&gt; function within a few
seconds? Or just do it with pen and paper, old school?&lt;/p&gt;

&lt;p&gt;But wait, there's poor man's &lt;code&gt;dec2bin&lt;/code&gt;!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ echo -n &quot;\x53&quot; | xxd -b
0000000: 01010011
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;;-)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Strip whitespace on rebase</title>
    <link href="http://blog.plenz.com/2011-01/strip-whitespace-on-rebase.html" />
    <updated>2011-01-25T17:12:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/strip-whitespace-on-rebase</id>
    <content type="html">&lt;p&gt;Normally, I &lt;a href=&quot;https://github.com/Feh/configs/blob/master/.gitstuff/myhooks/pre-commit&quot;&gt;use&lt;/a&gt; the following line in Git's &lt;em&gt;pre-commit&lt;/em&gt; hook:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git diff --cached --check || exit 1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes a &lt;code&gt;git commit&lt;/code&gt; abort if there are any whitespace-related
errors. However, if you have code that already has whitespace issues,
you can simply pass an option to &lt;code&gt;git rebase&lt;/code&gt; to automatically correct
them:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git rebase --whitespace=fix reference
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;N.B.: Rebase just passes this argument to the &lt;code&gt;git apply&lt;/code&gt; command.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Which files are accessed?</title>
    <link href="http://blog.plenz.com/2011-01/which-files-are-accessed.html" />
    <updated>2011-01-24T01:40:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/which-files-are-accessed</id>
    <content type="html">&lt;p&gt;Often, if you need to know which files are accessed during the startup
of an application, you are stuck searching for them in the manpage.
Also, probably not all of them are documented there.&lt;/p&gt;

&lt;p&gt;I use strace to find these files:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;strace -efile /usr/bin/program 2&amp;gt;&amp;amp;1 1&amp;gt;/dev/null | grep ^open | cut -d\&quot; -f2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that unless you place the &lt;code&gt;grep&lt;/code&gt; expression in between this will
give you all syscalls that involve files, i.e. also simple checks
whether a file exists or has a certain permission set.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">ACPI interface in /proc deprecated</title>
    <link href="http://blog.plenz.com/2011-01/acpi-interface-in-proc-deprecated.html" />
    <updated>2011-01-16T21:53:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/acpi-interface-in-proc-deprecated</id>
    <content type="html">&lt;p&gt;With a new kernel, &lt;code&gt;/proc/acpi/battery/*&lt;/code&gt; was suddenly missing. Turns
out it the interface is &lt;a href=&quot;http://cateee.net/lkddb/web-lkddb/ACPI_PROCFS_POWER.html&quot;&gt;is deprecated&lt;/a&gt; but can be turned on with a
config option at compile time. The same information is available in a
different form in the &lt;code&gt;/sys&lt;/code&gt; filesystem.&lt;/p&gt;

&lt;p&gt;I didn't see that coming; almost all programs I use to check the
battery state fail. It had been announced, &lt;a href=&quot;http://www.mail-archive.com/debian-kernel@lists.debian.org/msg45954.html&quot;&gt;actually&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The correct way is for upstream to announce the change in
feature-removal-schedule.txt, which they did 2 years ago.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;That's roughly how the &lt;a href=&quot;http://en.wikiquote.org/wiki/The_Hitchhiker's_Guide_to_the_Galaxy#Chapter_3&quot;&gt;Vogon Hyperspace Planning Council&lt;/a&gt;
operates. Stubborn dev &lt;a href=&quot;http://www.mail-archive.com/debian-kernel@lists.debian.org/msg45943.html&quot;&gt;replies&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;If the tools are not able to use them, it is their bug. No bug in
the kernel.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;However, after &lt;a href=&quot;http://git.sysphere.org/vicious/commit/?id=7be560b7&quot;&gt;updating vicious&lt;/a&gt; and &lt;a href=&quot;https://github.com/Feh/configs/commit/6f8e064669cc42741fab22b1243b851c87a7564d&quot;&gt;adjusting some API
changes&lt;/a&gt;, everything works fine again.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Dubstep &amp;ndash; it's kinda like that</title>
    <link href="http://blog.plenz.com/2011-01/dubstep-its-kinda-like-that.html" />
    <updated>2011-01-16T21:11:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/dubstep-its-kinda-like-that</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;/img/dubstep_its_kinda_like_that.jpg&quot;
style=&quot;border:0;&quot;&gt;&lt;img
src=&quot;/img/dubstep_its_kinda_like_that.jpg&quot;
alt=&quot;Dubstep -- it's kinda like that&quot;
width=&quot;500&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Using OpenWRT (again)</title>
    <link href="http://blog.plenz.com/2011-01/using-openwrt-again.html" />
    <updated>2011-01-14T21:38:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/using-openwrt-again</id>
    <content type="html">&lt;p&gt;The old and cheap wifi router we used in our flat got buggy; it had
some 20% packet loss at times, and the LAN clients were not able to
make connections to each other (only WAN connections were possible).&lt;/p&gt;

&lt;p&gt;So I dug up my old WRT54G, reset the factory settings, and used that
one as access point. This worked for about one week; today, when I
came home, the internet connection would not work any more.&lt;/p&gt;

&lt;p&gt;Ping statistics from the router (delivered to the web interface)
showed that the internet connection was established. However, the
router would not forward internet traffic from the LAN.&lt;/p&gt;

&lt;p&gt;An hour ago I installed &lt;a href=&quot;http://openwrt.org/&quot;&gt;OpenWRT&lt;/a&gt;. I had been using it some years
ago and was astonished that &quot;White Russian&quot; is still the stable
release. Anyhow, there's a web interface now which is pretty nice.
(With a link &quot;Review settings&quot;, where you'll get a shell script that
will get executed once you hit &quot;apply&quot; &amp;ndash; nice if you want to
find out the commands!)&lt;/p&gt;

&lt;p&gt;There was some manual work to do, I leave this for search engines in
case someone else has these issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WPA2-PSK setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;WPA2 is &lt;em&gt;not natively supported&lt;/em&gt;. Although the nvram keys exist, the
wifi driver cannot use them properly. &lt;code&gt;iwconfig&lt;/code&gt; will display
&lt;code&gt;Encryption key:off&lt;/code&gt; regardless of what you configure.&lt;/p&gt;

&lt;p&gt;To make WPA2 work, install the &lt;code&gt;nas&lt;/code&gt; package (&lt;a href=&quot;http://wiki.openwrt.org/oldwiki/openwrtdocs/nas&quot;&gt;documentation&lt;/a&gt;). The
&lt;code&gt;/etc/init.d/S41wpa&lt;/code&gt; script actually manages WPA2 settings (and
retrieves the configuration keys from nvram):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# ipkg install nas
# /etc/init.d/S41wpa restart
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The relevant nvram keys for my wireless are:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;wl0_akm=psk psk2
wl0_crypto=tkip+aes
wl0_ssid=...
wl0_wpa_psk=...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;PubKey Authentication with DropBear&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Simple, once you know it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ scp ~/.ssh/id_dsa.pub root@192.168.1.1:/etc/dropbear/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;NTP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Keep up to date!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# nvram set ntp_server=time.fu-berlin.de
# nvram commit
# ipkg install ntpclient
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Interestingly, the signal strength and bandwidth throughput is better
with OpenWRT than using the LinkSys firmware. :-)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Automatic screenshot processing</title>
    <link href="http://blog.plenz.com/2011-01/automatic-screenshot-processing.html" />
    <updated>2011-01-11T21:31:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/automatic-screenshot-processing</id>
    <content type="html">&lt;p&gt;Cut out window borders and application bars from screenshots
automatically: note down some corner points (in Gimp), then use
ImageMagick:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;for f (*.png) { convert -crop 975x559+2+30 $f $f; }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Task done!&lt;/p&gt;

&lt;p&gt;NB: This command replaces file contents. So when not
sure about the numbers, append some extension to it and view the
results first. Or, simply kepp the images in a git controlled
directory. That way, a simple &lt;code&gt;git reset -- .&lt;/code&gt; will restore your
previous images if you added them in the first place.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Kamusi and jQuery</title>
    <link href="http://blog.plenz.com/2011-01/kamusi-and-jquery.html" />
    <updated>2011-01-10T23:10:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/kamusi-and-jquery</id>
    <content type="html">&lt;p&gt;So some years ago I was what what one would call a Web Designer, doing
CSS and XHTML 1.0 and that stuff. I got bored, however, and nowadays I
hate these websites that are so over-styled and have so much
JavaScript in there. I have been turning away from any web-related
stuff since the times writing valid XHTML 1.0 was still &quot;in&quot;.&lt;/p&gt;

&lt;p&gt;However... today I tried this whole &quot;Use JavaScript instead of regular
links and reloads&quot; stuff out. Friends of mine suggested using
&lt;a href=&quot;http://jquery.com/&quot; title=&quot;jQuery homepage&quot;&gt;jQuery&lt;/a&gt;, of which I grabbed the &quot;mini&quot; version. (There have been
some really clever code golfers at work to shrink the whole library
down to some 77K. In that format, it's barely human-readable, though.)&lt;/p&gt;

&lt;p&gt;jQuery is nice, because it doesn't have many JavaScript parts in it.
The &quot;usual&quot; stuff seems to work by simply combining elementary jQuery
functions, for which there's a &lt;a href=&quot;http://api.jquery.com/&quot;&gt;great API documentation&lt;/a&gt;, and
identifying HTML objects in a syntax similar to CSS.&lt;/p&gt;

&lt;p&gt;So without really understanding how and why it works, I created a
Web2.0-ish version of my &lt;a href=&quot;https://github.com/Feh/kamusi-cli/tree/cgi&quot;&gt;kamusi command line client&lt;/a&gt;. Kamusi is
the &lt;a href=&quot;http://en.wikipedia.org/wiki/Kiswahili&quot;&gt;Kiswahili&lt;/a&gt; word for
&lt;em&gt;dictionary&lt;/em&gt;, and the program I wrote is a text-based interface
written in Perl for the extensive database of words from
&lt;a href=&quot;http://kamusi.org/&quot;&gt;http://kamusi.org/&lt;/a&gt;. Their web search, however, is very slow and
irritating to use.&lt;/p&gt;

&lt;p&gt;My hack-away implementation of a cleaner, faster search using jQuery
and a custom CGI to retrieve the results can be found at
&lt;a href=&quot;http://k.plenz.com&quot;&gt;http://k.plenz.com&lt;/a&gt;. Some sample queries you might try: &lt;code&gt;-nia&lt;/code&gt;,
&lt;code&gt;bongo&lt;/code&gt; or &lt;code&gt;-pa&lt;/code&gt;. Source code is availabe &lt;a href=&quot;https://github.com/Feh/kamusi-cli/tree/cgi&quot;&gt;in the &quot;cgi&quot; branch on
Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This jQuery stuff is hard to debug, actually. (JavaScript in general
is, IMO.) However, the syntax is pretty straight-forward. I do
realize now why so many of these Web2.0 pages use this fading and
scrolling-in stuff so much (and &lt;a href=&quot;http://jqueryui.com/demos/autocomplete/&quot;&gt;autosuggest&lt;/a&gt;, as well!). It's just
plain easy and provides a feel of using a &quot;dynamic application&quot;.&lt;/p&gt;

&lt;p&gt;I can understand now why these Web Designers are so proud of
themselves.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Wikileaks mass mirroring project</title>
    <link href="http://blog.plenz.com/2011-01/wikileaks-mass-mirroring-project.html" />
    <updated>2011-01-09T22:26:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/wikileaks-mass-mirroring-project</id>
    <content type="html">&lt;p&gt;Since a day after Wikieleaks called for &lt;a href=&quot;http://cablegate.wikileaks.org/Mass-mirroring-Wikileaks.html&quot;&gt;mass mirroring support&lt;/a&gt;
I've been hosting a Wikileaks mirror at &lt;a href=&quot;http://wikileaks.feh.name&quot;&gt;http://wikileaks.feh.name&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you're curious how to allow to upload files via &lt;a href=&quot;http://samba.anu.edu.au/rsync/&quot;&gt;rsync&lt;/a&gt;, but
just to a certain directory with no possibility to access other system
parts, take a look at &lt;code&gt;rrsync&lt;/code&gt;, which should ship with rsync. On a
Debian system, simply do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# cp /usr/share/doc/rsync/scripts/rrsync.gz /usr/bin
# gunzip /usr/bin/rrsync.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, I have this line in &lt;code&gt;~wl/.ssh/authorized_keys&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;command=&quot;rrsync www&quot; ssh-rsa AAAAB3N[...]w== wwwsync@wikileaks.org
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So any rsync mirroring command issued will have a &lt;code&gt;$HOME/www/&lt;/code&gt;
prepended. Thus, the wikileaks upload script can only modify files
below a certain subdirectory. If you touch the file &lt;code&gt;rrsync.log&lt;/code&gt;, each
login will be logged as well.&lt;/p&gt;

&lt;p&gt;Now, there are &lt;a href=&quot;http://cablegate.wikileaks.org/Mirrors.html&quot;&gt;some 1400 sites&lt;/a&gt; mirroring the content now. How to
access a random mirror, then? The German &lt;em&gt;taz&lt;/em&gt; had a &lt;a href=&quot;http://bewegung.taz.de/aktionen/support-wikileaks/beschreibung&quot;&gt;call for
action&lt;/a&gt; page with a &lt;a href=&quot;http://www.taz.de/~thoralf/wikileaks.tar.bz2&quot;&gt;strange bash script&lt;/a&gt; which would always
link to the first mirror in the list.&lt;/p&gt;

&lt;p&gt;However, there are more clever approaches. &lt;a href=&quot;http://wikileaks.de&quot;&gt;http://wikileaks.de&lt;/a&gt;, for
example, uses &lt;a href=&quot;http://en.wikipedia.org/wiki/Round_robin_DNS&quot;&gt;round robin DNS&lt;/a&gt; to display the cablegate pages of a
randomly chosen host. However, there seem to be only five hosts
registered yet:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ( repeat 100 host wikileaks.de ) | cut -f3 | sort -n | uniq -c
    100 85.214.146.40
    100 87.230.26.252
    100 87.239.128.202
    100 88.198.21.150
    100 178.63.249.117
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I just registered my IP to show up there. &lt;a href=&quot;http://mirrors.wikileaks.de/&quot;&gt;You can,
too!&lt;/a&gt; (Be sure to click the &quot;commit
changes&quot; radio button when you receive the confirmation link!)&lt;/p&gt;

&lt;p&gt;Another possibility is to point your browser to
&lt;a href=&quot;http://r.whereiswikileaks.org/&quot;&gt;http://r.whereiswikileaks.org/&lt;/a&gt;, which emits a 302 HTTP header
(&quot;found&quot;) and adds a Location header to redirect you to a randomly
selected mirror:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ curl http://r.whereiswikileaks.org/ -s --head | grep Location:
Location: http://wikileaks.my-niap.org
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Some french guy made &lt;a href=&quot;http://wikileaks.siwhine.org/swn-stats/&quot;&gt;interesting pie charts&lt;/a&gt; about the
distribution of the 1400 mirrors. German mirrors are most common
(30% of all active), mirrors from the US, France, Germany and the
Netherlands combined make up more than three quarter of all active
mirrors. There are &lt;a href=&quot;http://labs.vis4.net/wikileaks/mirrors/&quot;&gt;other vizualizations&lt;/a&gt;, too.&lt;/p&gt;

&lt;p&gt;Finally, there's a site &lt;a href=&quot;http://wl.mattiasgeniar.be/&quot;&gt;grouping wikileaks mirrors by
netblock&lt;/a&gt;. Interestingly, more than 100 mirrors are within German
ISP Hetzner's netblock (whose position on Wikileaks hosting &lt;a href=&quot;http://www.netzpolitik.org/2010/keine-wikileaks-mirrors-bei-hetzner/&quot;&gt;had not
been clear entirely&lt;/a&gt; during the first few days).&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">X41 keyboard problem</title>
    <link href="http://blog.plenz.com/2011-01/x41-keyboard-problem.html" />
    <updated>2011-01-06T21:23:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/x41-keyboard-problem</id>
    <content type="html">&lt;p&gt;Today I fixed that annoying keyboard problem I &lt;a href=&quot;/2011-01/tuning-old-hardware-with-slow-hard-drive.html&quot;&gt;talked about
earlier&lt;/a&gt;. It was really simple: &lt;a href=&quot;http://www-307.ibm.com/pc/support/site.wss/MIGR-54595.html&quot;&gt;remove keyboard&lt;/a&gt;, clean
contacts, put it back in.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Tuning old hardware with slow hard drive</title>
    <link href="http://blog.plenz.com/2011-01/tuning-old-hardware-with-slow-hard-drive.html" />
    <updated>2011-01-05T23:54:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/tuning-old-hardware-with-slow-hard-drive</id>
    <content type="html">&lt;p&gt;My main work machine is a pretty old &lt;a href=&quot;http://www.thinkwiki.org/wiki/Category:X41&quot;&gt;X41&lt;/a&gt; with a 40GB hard disk
and 512MB of RAM. It is more than five years old and is not without
problems. (In recent months, I have to try several before switching it
on successfully &amp;ndash; in most cases, it just beeps twice and
displays &quot;Keyboard error, &amp;lt;F1&amp;gt; to configure&quot; and the keyboard
doesn't work.)&lt;/p&gt;

&lt;p&gt;However, there's a thing which annoys me a lot: bad performance.
I use a &lt;a href=&quot;http://awesome.naquadah.org/&quot; title=&quot;awesome window manager&quot;&gt;resource-friendly window manager&lt;/a&gt; with some &lt;code&gt;urxvt&lt;/code&gt;s
running. Apart from the memory-hog Firefox, I very seldom use any
graphical application (ie. any program using the GTK or Qt libraries).&lt;/p&gt;

&lt;p&gt;For some weeks now I've been trying &lt;a href=&quot;http://marc.info/?l=linux-kernel&amp;amp;m=128993691017646&quot;&gt;this cgroups hack&lt;/a&gt;, with
mixed results. In some cases, the performance is better, sometimes
it's not.&lt;/p&gt;

&lt;p&gt;How bad could the overall performance be, then? &amp;ndash; Unfortunately,
very bad. Which has, in part, to do with my slow hard disk. It does
uncached reading with 18MB/s in theory:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo hdparm -t /dev/sda
/dev/sda:
 Timing buffered disk reads:   56 MB in  3.08 seconds =  18.21 MB/sec
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In reality, it's rather some 16.5MB/s:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ dd if=/dev/zero of=./zero bs=1048576 count=256
256+0 records in
256+0 records out
268435456 bytes (268 MB) copied, 10.0246 s, 26.8 MB/s

$ time cat zero &amp;gt; /dev/null
cat zero &amp;gt; /dev/null  0.01s user 0.25s system 1% cpu 16.246 total
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, I have to live with this (SSD's are still very expensive!). The
main problem here is that the Kernel swaps out data that wasn't
accessed for a while (although, from a na&amp;iuml;ve perspective, there's
no ultimate need to do so since there's still free memory left).&lt;/p&gt;

&lt;p&gt;I actually notice that with two programs regularly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When I hadn't taken a look at Firefox for a few minutes, it might
take up to 10(!) seconds to redraw the window.&lt;/li&gt;
&lt;li&gt;When I hadn't opened an &lt;code&gt;urxvt&lt;/code&gt; for some time, opening a new one
might take up to 5 seconds; initializing the shell another two.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Now I always thought this was the Linux Kernel being stupid. However I
discovered a switch today. From the &lt;a href=&quot;http://www.kernel.org/doc/Documentation/sysctl/vm.txt&quot;&gt;sysctl.vm documentation&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;swappiness

This control is used to define how aggressive the kernel will swap
memory pages.  Higher values will increase agressiveness, lower values
decrease the amount of swap.

The default value is 60.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Debian (like all other distros) seem to keep this default value. After
reading up on &lt;a href=&quot;http://www.pythian.com/news/1913/&quot;&gt;some&lt;/a&gt; &lt;a href=&quot;http://kerneltrap.org/node/3000&quot;&gt;articles&lt;/a&gt; I set &lt;code&gt;vm.swappiness=0&lt;/code&gt; in
&lt;code&gt;/etc/sysctl.conf&lt;/code&gt;. (You can do this interactively with &lt;code&gt;sysctl -w
vm.swappiness=0&lt;/code&gt; also. Interestingly, &lt;a href=&quot;https://help.ubuntu.com/community/SwapFaq#What%20is%20swappiness%20and%20how%20do%20I%20change%20it?&quot;&gt;Ubuntu recommends a value of
10&lt;/a&gt; for desktop systems.)&lt;/p&gt;

&lt;p&gt;For the past day or so, I have been monitoring the output of &lt;code&gt;vmstat
1&lt;/code&gt; every now and then (especially the swap in/out parameters &lt;code&gt;si&lt;/code&gt; and
&lt;code&gt;so&lt;/code&gt;). But even after the first hour one thing is evident: the
&lt;em&gt;interactive&lt;/em&gt; system performance is much, &lt;em&gt;much&lt;/em&gt; better. It feels like
a machine upgrade.&lt;/p&gt;

&lt;p&gt;Terminals open instantly (because the initialization parts of their
binary doesn't get swapped out, for example). Switching to Firefox is
instant. Switching tabs is fast. The system feels a lot more
responsive.&lt;/p&gt;

&lt;p&gt;Where's the drawback, then? If you could magically tune your system's
performance, why wouldn't you want do that?&lt;/p&gt;

&lt;p&gt;A case where this setup will give you a headache is when you actually
&lt;em&gt;do&lt;/em&gt; run out of memory. I easily accomplished that by opening Gimp on
a huge (blank) file. Now, working with Gimp is easy now; switching to
Firefox takes ages (heavy swapping). So there a not-so-agressive
swapping policy would be better if you switch between several
memory-hogging applications a lot.&lt;/p&gt;

&lt;p&gt;(Side note: When there's a lot of free memory left &amp;ndash; for example
after closing Gimp &amp;ndash; the kernel step by step swaps in certain
blocks again, a few every second so as to not disturb system
performance. I saw this going on for several minutes on a otherwise
completely idle system.)&lt;/p&gt;

&lt;p&gt;Conclusion: For the usage pattern I'm accustomed to, setting
&lt;code&gt;vm.swappiness=0&lt;/code&gt; actually is a huge performance improvement. But your
mileage may vary.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">First post with posting tool</title>
    <link href="http://blog.plenz.com/2011-01/first-post-with-posting-tool.html" />
    <updated>2011-01-04T01:29:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/first-post-with-posting-tool</id>
    <content type="html">&lt;p&gt;This is my first post with a &lt;a href=&quot;http://www.plenz.com/tmp/code/sh/blogpost&quot; title=&quot;Source code of the script&quot;&gt;custom shell script&lt;/a&gt;. It
automatically adds a YAML header on top of new posts, starts an editor
on it and later converts the title to a nice filename.&lt;/p&gt;

&lt;p&gt;Eventually, the script adds and commits the new post to the git repo
and pushes the result. &quot;Recovering&quot; is supported &amp;ndash; sort of. ;-)&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Excision Shambhala 2009 Mix</title>
    <link href="http://blog.plenz.com/2011-01/excision-shambhala-2009.html" />
    <updated>2011-01-03T23:05:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/excision-shambhala-2009</id>
    <content type="html">&lt;object height=&quot;225&quot; width=&quot;100%&quot;&gt; &lt;param name=&quot;movie&quot; value=&quot;http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Fplaylists%2F461827&amp;amp;show_comments=false&amp;amp;auto_play=false&amp;amp;show_playcount=true&amp;amp;show_artwork=false&amp;amp;color=66ff00&quot;&gt;&lt;/param&gt; &lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt; &lt;embed allowscriptaccess=&quot;always&quot; height=&quot;125&quot; src=&quot;http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Fplaylists%2F461827&amp;amp;show_comments=false&amp;amp;auto_play=false&amp;amp;show_playcount=true&amp;amp;show_artwork=false&amp;amp;color=66ff00&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;100%&quot;&gt;&lt;/embed&gt; &lt;/object&gt;


&lt;p&gt;   &lt;span&gt;&lt;a href=&quot;http://soundcloud.com/excision/sets/excision-shambhala-2009-mix&quot;&gt;Excision Shambhala 2009 Mix&lt;/a&gt; by &lt;a href=&quot;http://soundcloud.com/excision&quot;&gt;Excision&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Blog software</title>
    <link href="http://blog.plenz.com/2011-01/blog-software.html" />
    <updated>2011-01-03T18:41:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/blog-software</id>
    <content type="html">&lt;p&gt;Which blog software to take? &amp;ndash; Not a simple question to answer.&lt;/p&gt;

&lt;p&gt;I had my mind on &lt;a href=&quot;http://ikiwiki.info/&quot; title=&quot;The Ikiwiki Homepage&quot;&gt;Ikiwiki&lt;/a&gt;
for quite some time. I haven't got it working, though. After several
tries, I gave up. (The problem had in part something to do with an
outdated git version, which I cannot upgrade on the server without
going through quite some hassle.)&lt;/p&gt;

&lt;p&gt;I decided to use &lt;a href=&quot;https://github.com/mojombo/jekyll&quot;&gt;Jekyll&lt;/a&gt; now. As
with other &quot;static site generators&quot;, the documentation is pretty
rudimentary (and largely not very helpful). After some hours of
fiddling around, I finally found a way to integrate tags and a tag
cloud.
&lt;a href=&quot;http://ilkka.github.com/2010/11/21/jekyll-tag-cloud.html&quot;&gt;This blog post&lt;/a&gt;
has been very helpful, although I had to patch the file. Strangely,
also, Jekyll refused to load &lt;em&gt;any&lt;/em&gt; plugins when calling it like&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/var/lib/gems/1.8/bin/jekyll --no-auto &amp;lt;source&amp;gt; &amp;lt;destination&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To fix this, I set up git's &lt;code&gt;post-receive&lt;/code&gt; hook to &lt;code&gt;cd&lt;/code&gt; to that
directory first, and then call Jekyll with &lt;code&gt;.&lt;/code&gt; as source paramter.&lt;/p&gt;

&lt;p&gt;Time for a quick listing of pros and cons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pro&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write posts in &lt;code&gt;vim&lt;/code&gt; with Markdown syntax&lt;/li&gt;
&lt;li&gt;Store every modification in a git repo&lt;/li&gt;
&lt;li&gt;Publish with a simple &lt;code&gt;git push&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;strong&gt;contra&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Written in ruby (I'd have liked Perl much better)&lt;/li&gt;
&lt;li&gt;Lots of ruby/gem/rake/whatever stuff&lt;/li&gt;
&lt;li&gt;No extensive Documentation or User's Guide available&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The template mechanisms seem managable, though. As for security and
speed, the pages are generated &lt;em&gt;once&lt;/em&gt; (even for pagination stuff) and
are copied as simple static HTML pages to the web server. This is
nice.&lt;/p&gt;

&lt;p&gt;In the weeks to come I might publish the git repo of this blog where
&lt;a href=&quot;http://git.plenz.com/&quot;&gt;my other git repos are at&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title type="html">Starting a blog</title>
    <link href="http://blog.plenz.com/2011-01/first-post.html" />
    <updated>2011-01-01T23:42:00+01:00</updated>
    <id>http://blog.plenz.com/2011-01/first-post</id>
    <content type="html">&lt;p&gt;2011 is here. I will try to maintain a blog again. The last time I
gave up because I had nothing to write any more (I thought). I
discover, though, that a lot of people like to read what I write.&lt;/p&gt;

&lt;p&gt;So I have a blog again. I'll post random stuff here. Might just be
about UNIX tools; philosophy; math stuff; books I read; links I like.
English or German, -- maybe other languages in the future.&lt;/p&gt;

&lt;p&gt;Stay tuned. :-)&lt;/p&gt;
</content>
  </entry>
  
</feed>

