<?xml version="1.0" encoding="utf-8"?>

<feed xmlns="http://www.w3.org/2005/Atom">
	<title>ayekat.ch</title>
	<id>ayekat.ch/blog</id>
	<link rel="self"
	      type="application/atom+xml"
	      href="http://ayekat.ch/atom.xml" />
	<author>
		<name>ayekat</name>
		<email>takeya@bluewin.ch</email>
	</author>
	<updated>2026-04-22T01:37:04+0200</updated>

	<entry>
		<title>karuiwm</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/karuiwm"
		      id="karuiwm" />
		<id>karuiwm</id>
		<updated>2021-12-24T11:33:00+0100</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;Today, &lt;a href=&quot;https://gitlab.com/ayekat/karuiwm/-/merge_requests/14&quot;&gt;merge request 14&lt;/a&gt; was accepted into karuiwm&#x27;s master branch,
and karuiwm can now finally be used without having to embed user preferences
into the binary at compile-time via a &lt;a href=&quot;https://gitlab.com/ayekat/PKGBUILDs/-/blob/aa20a92cdc0cb02dda16f696873e4256d0867528/config.h&quot;&gt;configuration header&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But what even &lt;em&gt;is&lt;/em&gt; karuiwm, you&#x27;re asking?&lt;/p&gt;
&lt;p&gt;Let me reach back a bit.&lt;/p&gt;
&lt;h2 id=&quot;dwm&quot;&gt;dwm&lt;/h2&gt;
&lt;p&gt;In the year 2013&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;, &lt;small class=&quot;sidenote&quot;&gt;Yes,
I am aware that 2013 is 8 years ago and this seems excessive. Bear with me, this
is relevant.&lt;/small&gt; ayekat was a user of suckless&#x27; &lt;a href=&quot;http://dwm.suckless.org/&quot;&gt;dwm&lt;/a&gt;, a dynamically
tiling window manager that is&amp;mdash;among other things&amp;mdash;known for not
loading any configuration at runtime. Instead, things like key bindings, window
border colours and other user preferences are all declared in a C source header
file, &lt;code&gt;config.h&lt;/code&gt;, that is then included in dwm&#x27;s source code at compile-time.&lt;/p&gt;
&lt;p&gt;This requires the user to have some basic understanding of the source code
itself, but that sounds scarier than it really is: The configuration file is
mostly just a bunch of variable declarations whose syntax is relatively easy to
grasp, and an example configuration file is provided to showcase how you can
invoke specific functions within dwm.&lt;/p&gt;
&lt;p&gt;For more advanced tweaking, though, you have to patch parts of dwm&#x27;s source code
itself. This is even actively encouraged (and people&#x27;s patches are also
&lt;a href=&quot;http://dwm.suckless.org/patches/&quot;&gt;gathered on dwm&#x27;s website itself&lt;/a&gt;). Overall, dwm users quickly get
to know its codebase and how to extend it the way they like. There&#x27;s probably a
reason why many of today&#x27;s existing tiling window managers can be traced back to
dwm in some form or another.&lt;/p&gt;
&lt;p&gt;One notable property of dwm is that it doesn&#x27;t group windows together to
workspaces (or &quot;desktops&quot;). Instead, it provides &lt;em&gt;tags&lt;/em&gt; that you can assign to
its windows. So as a user, rather than switching around between workspaces, you
instead decide which subset of tags to select (=&amp;nbsp;which windows to show).
This allows selecting windows a lot more flexibly, and overall, this is quite
powerful if you grasp the concept.&lt;/p&gt;
&lt;p&gt;Of course, ayekat didn&#x27;t grasp the concept.&lt;/p&gt;
&lt;p&gt;Instead, ayekat spent considerable time and energy into patching dwm and
defining key bindings such that only one tag at a time could be active, and a
window could be tagged with only one tag at a time, and one could switch between
&quot;adjacent&quot; tags (left/right) and optionally grab a window and pull it from one
&quot;tag&quot; to another, and&amp;mdash; &amp;hellip; yeah, well, it was basically workspaces.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;dwm workspaces&quot; src=&quot;/files/img/dwm_statusbar_workspaces.png&quot; /&gt;
&lt;small class=&quot;sidethought&quot;&gt;dwm statusbar showing &quot;basically workspaces&quot;.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;At some later point, I abused dwm&#x27;s tags system further to get a special
&quot;scratchpad&quot; tag, with one window assigned that I could easily toggle on and off
with a key binding, overlaying the windows in the current workspace (note that a
&lt;a href=&quot;http://dwm.suckless.org/patches/scratchpad/&quot;&gt;scratchpad patch&lt;/a&gt; did not exist back then). All in all, I lived
a pretty happy life with &quot;workspaces&quot; in dwm.&lt;/p&gt;
&lt;p&gt;That is, until one day I saw &lt;a href=&quot;https://florv.ch/&quot;&gt;florv&lt;/a&gt; use an XMonad module called
&lt;a href=&quot;https://hackage.haskell.org/package/xmonad-contrib-0.16/docs/XMonad-Actions-GridSelect.html&quot;&gt;GridSelect&lt;/a&gt;, which looked something like this:&lt;/p&gt;
&lt;div class=&quot;fullwidth&quot;&gt;
&lt;img src=&quot;/files/img/gridselect.png&quot; alt=&quot;XMonad GridSelect&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;My brain somehow misinterpreted this as some sort of visualisation of a
two-dimensional map of workspaces where one could move around and create
workspaces dynamically, and I was intrigued (especially given my own limited
&lt;del&gt;tags&lt;/del&gt;&lt;ins&gt;workspaces&lt;/ins&gt;). And I wanted that as well.&lt;/p&gt;
&lt;p&gt;The two-dimensionally arranged, dynamically created workspaces, I mean. Not
GridSelect.&lt;/p&gt;
&lt;p&gt;Now it probably doesn&#x27;t come as a surprise to anyone that dwm&#x27;s code isn&#x27;t
exactly designed with workspaces in mind. And it &lt;em&gt;definitely&lt;/em&gt; isn&#x27;t designed
with dynamically allocated workspaces arranged in two dimensions in mind.&lt;/p&gt;
&lt;p&gt;To patch this into dwm, I would have needed to change its codebase to a point
where one could not really consider it &quot;dwm&quot; anymore. Maintaining patches for
such a thing would&#x27;ve been a nightmare; at this point, it would be easier and
less painful to just write my own window manager. But who in their right mind
would do that?&lt;/p&gt;
&lt;h2 id=&quot;stwm&quot;&gt;stwm&lt;/h2&gt;
&lt;p&gt;In 2013&amp;mdash;the same year, but a little later&amp;mdash;ayekat decided to write
the &lt;a href=&quot;https://gitlab.com/ayekat/karuiwm/-/commit/a4fa45789dee9ffbac8475927622b53b595a90ff&quot;&gt;Simple Tiling Window Manager&lt;/a&gt;. It didn&#x27;t do much, but it did
tile. And it did manage windows. Not any windows, mind you, but at least its
own, empty windows.&lt;/p&gt;
&lt;p&gt;The goal was pretty straighforward: Write a window manager in the vein of dwm
(and largely inspired by its codebase, because I didn&#x27;t know C and Xlib very
well back then), with the features I wanted directly baked into it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Workspaces.&lt;/li&gt;
&lt;li&gt;Workspaces arranged in two dimensions!&lt;/li&gt;
&lt;li&gt;A pretty-looking map to switch around between those workspaces.&lt;/li&gt;
&lt;li&gt;A Scratchpad.&lt;/li&gt;
&lt;li&gt;Workspaces!!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And so I spent Winter 2013 on writing my second-ever major C program, a window
manager. Around the end of the year, it was then feature-complete enough for me
to &lt;a href=&quot;https://github.com/ayekat/dotfiles/commit/83d83e04befd848c41bdf7a520cde3b7fbcab6d5&quot;&gt;switch from dwm to stwm&lt;/a&gt;. To be honest, I&#x27;m still quite
impressed by my past self, because this took less than two months overall.
There&#x27;s probably a reason why I failed all my maths courses in that
semester&amp;hellip;&lt;/p&gt;
&lt;p&gt;Here&#x27;s a screenshot showcasing the scratchpad and the desktops arranged in two
dimensions (inside a &lt;a href=&quot;https://en.wikipedia.org/wiki/Xephyr&quot;&gt;Xephyr&lt;/a&gt; window):&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;karuiwm demo&quot; src=&quot;/files/img/karuiwm_demo.png&quot; /&gt;
&lt;small class=&quot;sidethought&quot;&gt;Yes, this is from today. While skimming through my
old screenshots, I noticed that the looks of my setup haven&#x27;t really changed at
all since back then, so I might as well just take a screenshot right now. Please
kindly ignore the 8 years gap.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;At some point (actually barely a week after I had started using it), I decided
that &quot;simple tiling window manager&quot; wasn&#x27;t a particularly uniquely identifying
name, so &lt;a href=&quot;https://gitlab.com/ayekat/karuiwm/-/commit/61c817459e7ff0c3a412ed723a05d0b4ba842567&quot;&gt;I went with &quot;karuiwm&quot; instead&lt;/a&gt;. The attentive reader may
of course have noticed that &quot;karui&quot; (かるい, 軽い) means &quot;lightweight&quot; in
Japanese, so this makes this the &quot;lightweight window manager&quot;, which&amp;hellip;
&lt;small class=&quot;sidethought&quot;&gt;&lt;em&gt;meh&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Nevermind.&lt;/p&gt;
&lt;h2 id=&quot;karuiwm-and-the-weight-of-legacy-dwm&quot;&gt;karuiwm and The Weight of &lt;del&gt;Legacy&lt;/del&gt;&amp;thinsp;&lt;ins&gt;dwm&lt;/ins&gt;&lt;/h2&gt;
&lt;p&gt;karuiwm is not a &lt;em&gt;fork&lt;/em&gt; of dwm; it was&amp;mdash;and the Git commit history will
confirm that&amp;mdash;implemented from scratch. But it certainly wasn&#x27;t a
clean-room implementation in any sense of that word.&lt;/p&gt;
&lt;p&gt;Much of the structure and many of the function and variable names even to this
day will remind readers of dwm. There&#x27;s monitors and clients; there&#x27;s &lt;code&gt;mfact&lt;/code&gt;
and &lt;code&gt;nmaster&lt;/code&gt;; one can &lt;code&gt;step()&lt;/code&gt; through clients and &lt;code&gt;shift()&lt;/code&gt; and &lt;code&gt;zoom()&lt;/code&gt; them
in the layout; and one can &lt;code&gt;quit()&lt;/code&gt; karuiwm.&lt;/p&gt;
&lt;p&gt;More importantly, though, karuiwm adopted the approach of not reading any
configuration files at runtime, but instead requiring the user to write a
&lt;code&gt;config.h&lt;/code&gt; file very much like in &lt;code&gt;dwm&lt;/code&gt; (with a very similar structure, to some
extent probably even compatible).&lt;/p&gt;
&lt;p&gt;While that worked fine in the beginning, at some point I decided that I would
want to package all software installed on my system for better system files
tracking&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small class=&quot;sidenote&quot;&gt;That was an
odyssey in its own right; see &lt;a href=&quot;/blog/not-a-bug-fixing&quot;&gt;the Tale told here&lt;/a&gt;.&lt;/small&gt;, and I
realised that sometimes I want configuration for different machines to be
&lt;em&gt;different&lt;/em&gt;. But how do you do that if the configuration must be baked into the
software when being built?&lt;/p&gt;
&lt;p&gt;In karuiwm&#x27;s case, I built one package for each system.&lt;/p&gt;
&lt;p&gt;That wasn&#x27;t terribly elegant, of course. &lt;a href=&quot;https://gitlab.com/ayekat/PKGBUILDs/-/commit/e0e5c6dd9dbd718506d713f0e56dbe61ce960afb#9b9baac1eb9b72790eef5540a1685306fc43fd6c&quot;&gt;Here&lt;/a&gt;&#x27;s for
instance what the &lt;span style=&quot;font-variant: small-caps;&quot;&gt;pkgbuild&lt;/span&gt; file
looked like when I added a third system to my fleet. And while the target
userbase was originally just myself, vanity probably still got the better part
of me, and I wanted it to be useful for &lt;em&gt;others&lt;/em&gt; as well. Or maybe I simply got
tired of having to reply to curious friends that, yes, this &lt;em&gt;was&lt;/em&gt; a window
manager, but, no, it currently &lt;em&gt;wasn&#x27;t&lt;/em&gt; meant for them to use. Or maybe my inner
pedant woke up and stated loudly enough that this was, in fact, not terribly
elegant.&lt;/p&gt;
&lt;p&gt;Whatever the reason, I decided to work on adding &quot;configuration file reading&quot; as
a feature. But given the lack of any abstraction layers and the abundance of
spaghetti in my code at that point, this meant that it would first take a bit of
untangling and refactoring.&lt;/p&gt;
&lt;p&gt;Or maybe just rewrite the thing from scratch&amp;hellip;?&lt;/p&gt;
&lt;h2 id=&quot;life-engineering-lesson&quot;&gt;&lt;del&gt;life&lt;/del&gt;&amp;thinsp;&lt;ins&gt;engineering&lt;/ins&gt; lesson&lt;/h2&gt;
&lt;p&gt;That was around the end of 2014. You may have noticed that 2014 was &lt;em&gt;seven years
ago&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Here&#x27;s the most important lesson I took from this project: If anyone ever
suggests to &lt;strong&gt;&quot;just rewrite it from scratch&quot;&lt;/strong&gt; because refactoring the code
would be too tedious and unfunny, please&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Slap them.&lt;/em&gt;&lt;small class=&quot;sidethought&quot;&gt;&lt;a href=&quot;https://gitlab.com/ayekat/karuiwm/-/commit/8b4efba89194f9f564bd861a64260ecbef736df5&quot;&gt;2014 ayekat&lt;/a&gt;? *&lt;em&gt;Slap!&lt;/em&gt;*&lt;br /&gt;&lt;a href=&quot;https://gitlab.com/ayekat/karuiwm/-/commit/140459fba8085c7e4ed1523af96b6fca848f3819&quot;&gt;2017
ayekat&lt;/a&gt;? *&lt;em&gt;Slap!&lt;/em&gt;*&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;I wasted almost exactly 4 years of my life on this before it finally dawned on
me that this was doomed to fail everytime: With new code, it doesn&#x27;t really
matter which components you implement at what point. You can easily leave out
(or even remove) some critical feature with the promise of adding it back
sometime later when &quot;it&#x27;s all cleaned up a bit&quot;, because who cares? You aren&#x27;t
sitting on that branch that you just sawed off. Nobody is.&lt;/p&gt;
&lt;p&gt;But with code that is actually in production, it &lt;em&gt;counts&lt;/em&gt;. If you break some
critical functionality, you better fix it quickly, because otherwise it&#x27;ll hurt.
It&#x27;s ugly and painful, and it isn&#x27;t as fun as spitting out hundreds and
thousands of lines of new code, but it forces you to stick to the existing
feature set, and it prevents you from &quot;giving up&quot;. In return, because you
usually only make small changes incrementally, it&#x27;s easy to leave the codebase
and then come back half a year later to continue working on it. There are no
&quot;fantasy features&quot; where you don&#x27;t remember anymore what exactly the goal was;
every feature is actually &lt;em&gt;in use&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;And it worked! It took me another 3 years to refactor the code, but it worked.
Yes, 3 years is still a long time, but in my defense, Life somehow continued to
happen as well, and besides, you should have seen&lt;span
class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small class=&quot;sidenote&quot;&gt;Actually, just see for
yourself: The &lt;a href=&quot;https://gitlab.com/ayekat/karuiwm/-/tree/55f3a56db1042bbffabf384d27657e6aa04ea7bb&quot;&gt;codebase in 2018&lt;/a&gt; before I started
refactoring.&lt;/small&gt; the initial spaghetti.&lt;/p&gt;
&lt;p&gt;Also, it wouldn&#x27;t be a true product of mine without at least some amount of
overengineering:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Everything a user can do is exposed as an &lt;em&gt;action&lt;/em&gt;. An action has a uniquely
   identifying name and a list of arguments it accepts; for example:&lt;ul&gt;
&lt;li&gt;&lt;code&gt;focus_step_window&lt;/code&gt; changes the window focus to the previous or next
  window in the layout, and it takes one argument (an integer);&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scratchpad_toggle&lt;/code&gt; toggles the visibility of the scratchpad, and takes
  zero arguments;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;key_bind&lt;/code&gt; binds a key to an action, and it takes three arguments (a
  keymap name, a key combination, and a string describing the action
  invocation).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;To allow users to invoke actions, karuiwm exposes an RPC mechanism via Unix
   socket, and reads line-based &quot;commands&quot; that invoke an action.&lt;/li&gt;
&lt;li&gt;When karuiwm starts up, it invokes a script that connects back to the RPC
   socket and invokes actions like &lt;code&gt;key_bind&lt;/code&gt; and &lt;code&gt;window_set_border_colour&lt;/code&gt;.
   That script is of course user-defined.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ultimately, karuiwm doesn&#x27;t actually do any specific &quot;configuration&quot; loading at
all. It simply sets up the RPC interface, and then hands off the configuration
to an external script.&lt;/p&gt;
&lt;h2 id=&quot;outlook&quot;&gt;outlook&lt;/h2&gt;
&lt;p&gt;With the runtime configuration in place, I now no longer need to feel (too) bad
whenever someone requests to try out the window manager; it is now at an
acceptable pain level, I think&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small
class=&quot;sidenote&quot;&gt;I mean, there&#x27;s no documentation, there&#x27;s glitchy bugs
everywhere, and things still change all the time and probably break your
configuration before you&#x27;ve finished writing it. But I feel comfortable enough
with inflicting that amount of pain to you.&lt;/small&gt;.&lt;/p&gt;
&lt;p&gt;That being said, after 8 years of dog-feeding myself, I&#x27;ve started to notice
some limitations. They aren&#x27;t major, but&amp;hellip; let&#x27;s say that I shouldn&#x27;t have
to be annoyed even by only minor things in a tool that I&#x27;ve written myself, for
myself.&lt;/p&gt;
&lt;p&gt;So here&#x27;s what&#x27;s planned for the near and far future:&lt;/p&gt;
&lt;h3 id=&quot;mouse-follows-focus&quot;&gt;mouse follows focus&lt;/h3&gt;
&lt;p&gt;When using key bindings to switch focus between windows, I often end up with the
mouse pointer not being in the focused window. When using multiple monitors, the
distance between the mouse pointer and the focused window can become
significant; sometimes I have to move it around by potentially several thousand
pixels to get it into the window I&#x27;m currently working in, which&amp;mdash;as much
as I love the ThinkPad TrackPoint&amp;mdash;is a bit painful with the ThinkPad
TrackPoint&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small class=&quot;sidenote&quot;&gt;Or &lt;a href=&quot;https://xkcd.com/243/&quot;&gt;however
you call that thing&lt;/a&gt;&lt;/small&gt;.&lt;/p&gt;
&lt;p&gt;In those situations, I often wish I had a &quot;mouse-follows-focus&quot; feature, where
the mouse would automatically be warped into the currently focused window upon
focus change.&lt;/p&gt;
&lt;p&gt;I still need to determine how exactly the coordinates should be set, of course.
Remembering the last coordinates and restoring those might work in some cases,
but what happens if the mouse was moved out of the window manually the last time
the window had (lost) focus? Or what about windows that have changed their
dimensions in the meantime (and the saved coordinates now lie outside the
window)?&lt;/p&gt;
&lt;h3 id=&quot;modules&quot;&gt;modules&lt;/h3&gt;
&lt;p&gt;Many of the features may not be needed by all users, so it would be nice to just
load the parts one really needs, but also allow users to easily extend karuiwm&#x27;s
functionality however they like, without having to get their code into karuiwm
directly.&lt;/p&gt;
&lt;p&gt;Here, I&#x27;m thinking about a modules system, by dynamically loading shared objects
and then establishing some API that those modules could use to announce
themselves to karuiwm and expose additional functionality (actions, layouts,
&amp;hellip;); a bit similar to&amp;mdash;but hopefully a lot cleaner than&amp;mdash;what
I&#x27;m doing in &lt;a href=&quot;https://gitlab.com/ayekat/karuibar-modules&quot;&gt;karuibar&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The challenge probably lies in keeping the API simple enough to avoid getting
tangled up in compatibility issues, while still being versatile enough to allow
users to easily write useful modules.&lt;/p&gt;
&lt;p&gt;In an initial step (also as a sort of dog-feeding), I&#x27;m planning to split off
much of the current functionality into modules, e.g. the scratchpad, the
workspace map (including, ironically (given the history of karuiwm), the fact
that workspaces are arranged in 2 dimensions), or even just the RPC socket
handling itself.&lt;/p&gt;
&lt;h3 id=&quot;proper-statusbar-support&quot;&gt;proper statusbar support&lt;/h3&gt;
&lt;p&gt;Right now, karuiwm displays a dummy statusbar with &lt;code&gt;override_redirect&lt;/code&gt; that only
shows some minimal information about the currently viewed workspace (a logo of
the applied layout and the workspace&#x27;s name). The rest of the statusbar is empty
and unused; I currently just overlay &lt;a href=&quot;https://gitlab.com/ayekat/karuibar&quot;&gt;karuibar&lt;/a&gt; in that empty area,
though karuibar doesn&#x27;t interact with the window manager at all.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;karuiwm statusbar&quot; src=&quot;/files/img/karuiwm_limited_statusbar.png&quot; /&gt;
&lt;small class=&quot;sidethought&quot;&gt;The part to the right is hidden underneath
karuibar.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;The goal here is to stop shipping a statusbar with karuiwm altogether, and
instead pass all necessary WM-related information to karuibar. For that,
karuibar needs to be extended to at least:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Be able to distinguish between a focused and an unfocused monitor; and&lt;/li&gt;
&lt;li&gt;Allow an external component to independently update one slot in the bar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the karuiwm end, I&#x27;m probably going to create a module that prepares
information to be forwarded and shown in karuibar. Potentially it could be
abstracted away in a way that one could also use other statusbar
implementations (most importantly, I should start handling the &lt;a href=&quot;https://specifications.freedesktop.org/wm-spec/1.3/ar01s05.html#idm45578527822832&quot;&gt;&lt;code&gt;_NET_WM_STRUT&lt;/code&gt;
property&lt;/a&gt;, to support all kinds of statusbar implementations).&lt;/p&gt;
&lt;h3 id=&quot;dummy-windows&quot;&gt;dummy windows&lt;/h3&gt;
&lt;p&gt;karuiwm manages one single workspace set, no matter how many monitors are
attached. So monitors are &quot;sharing&quot; a set of workspaces between them.&lt;/p&gt;
&lt;p&gt;Consequently, it may happen that one monitor tries to view a workspace that is
already visible on another monitor. But X cannot show the content of one window
in multiple locations&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;,&lt;small
class=&quot;sidenote&quot;&gt;At least not without a compositor involved, I think&lt;/small&gt; so
I need to handle this &quot;conflict&quot; case.&lt;/p&gt;
&lt;p&gt;The current approach is fairly straightforward: Simply swap the views between
the monitors, and we&#x27;re done. But that occasionally causes some confusion.
Imagine the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;On monitor A, show the &lt;code&gt;dev&lt;/code&gt; workspace; on monitor B, show the &lt;code&gt;chat&lt;/code&gt;
   workspace.&lt;/li&gt;
&lt;li&gt;On monitor A, switch to the &lt;code&gt;chat&lt;/code&gt; workspace, then notice the mistake, and
   switch to the &lt;code&gt;mails&lt;/code&gt; workspace. Later, switch back to the &lt;code&gt;dev&lt;/code&gt; workspace.&lt;/li&gt;
&lt;li&gt;Now try to look at the chat (expected on monitor B), but instead see &lt;em&gt;mails&lt;/em&gt;
   there.&lt;/li&gt;
&lt;li&gt;Confused ayekat.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here, I would prefer monitor B to simply stay at the &lt;code&gt;chat&lt;/code&gt; workspace. But now I
need a solution for what happens if multiple monitors try to view the same
workspace (and thus the same windows).&lt;/p&gt;
&lt;p&gt;The new idea here is to let the unfocused monitor stay on its workspace, but
because the windows are also shown on the other (focused) monitor, have the
unfocused monitor simply show some &quot;dummy&quot; windows in their stead, i.e. empty
windows that only contain the name of each client window that &lt;em&gt;would&lt;/em&gt; be shown
there.
&lt;small class=&quot;sidethought&quot;&gt;As far as I know, there&#x27;s a project called &lt;span
style=&quot;font-variant: small-caps;&quot;&gt;&lt;a href=&quot;https://common-lisp.net/project/clfswm/&quot;&gt;clfswm&lt;/a&gt;&lt;/span&gt; that implements
something like this.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;As soon as the other monitor moves away, &quot;reclaim&quot; the client window content
again, and everything is fine. No confused ayekat.&lt;/p&gt;
&lt;p&gt;Whether I&#x27;ll implement this by switching between dummy windows and client
windows, or whether I&#x27;ll start reparenting windows (such that there&#x27;s always a
dummy window, but sometimes it simply doesn&#x27;t have the client window mapped)
remains to be defined.&lt;/p&gt;
&lt;h3 id=&quot;wayland&quot;&gt;Wayland&lt;/h3&gt;
&lt;p&gt;I guess one of the major issues of working on something for almost a decade is
that the technology landscape around you changes so much that by the time you&#x27;re
finally done, it has already become obsolete.&lt;/p&gt;
&lt;p&gt;X still isn&#x27;t quite dead, fortunately&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small
class=&quot;sidenote&quot;&gt;I mean, mostly just fortunate for karuiwm.&lt;/small&gt;, but I
should still consider preparing for a transition to Wayland in some not-too-far
future.&lt;/p&gt;
&lt;p&gt;To do so, I will first need to split all the X-specific parts away from the
generic window management part in karuiwm. Ideally, it will become its own
module that provides some generic &quot;compositor interface&quot; to karuiwm, and then I
could provide a second module exposing the same interface towards karuiwm,
but implementing window management (or rather, &lt;em&gt;compositing&lt;/em&gt;) for Wayland.&lt;/p&gt;
&lt;p&gt;It probably isn&#x27;t as simple as I make it sound here, but one can dream&amp;hellip;&lt;/p&gt;
&lt;h2 id=&quot;but-so-is-it-usable-now&quot;&gt;but, so, is it usable now?&lt;/h2&gt;
&lt;p&gt;For playing around? Sure!&lt;/p&gt;
&lt;p&gt;For production use? &lt;em&gt;Hell no.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As noted somewhere above&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small
class=&quot;sidenote&quot;&gt;At this point, I wouldn&#x27;t even be mad if you somehow missed it
in this wall of text.&lt;/small&gt;, documentation is still severly lacking, there are
some awkward glitches and occasional crashes, and overall a lot of behavioural
changes are still expected, especially in the context of the RPC.&lt;/p&gt;
&lt;p&gt;I mainly wrote this article because I felt excited about the fact that I have
finally completed something that had kept me busy for the past 7 years, and how
a project that&#x27;s been going for over 8 years at this point is finally starting
to take some serious shape, and I somehow wanted to get my excitement out into
the World.&lt;/p&gt;
&lt;p&gt;That being said, a first release is now becoming more and more realistic, and I
expect version &lt;span style=&quot;font-variant-numeric: lining-nums&quot;&gt;0.1&lt;/span&gt; to
drop sometime in 2022. Then again, there was a time in late 2019 where I thought
I&#x27;d be done by Summer 2020, so&amp;hellip;&lt;/p&gt;
&lt;p&gt;Let&#x27;s just not stress ourselves to much.&lt;/p&gt;
&lt;div class=&quot;fullwidth&quot;&gt;
&lt;img src=&quot;/files/img/relax.jpg&quot; alt=&quot;relaxed sanny&quot; /&gt;
&lt;/div&gt;		</summary>
	</entry>

	<entry>
		<title>Freenode</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/freenode"
		      id="freenode" />
		<id>freenode</id>
		<updated>2021-05-29T14:13:00+0200</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;Farewell!&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;13:58 ayekat│ info
13:58 -NickServ(NickServ@services.)- Information on ayekat (account ayekat):
13:58 -NickServ(NickServ@services.)- Registered : Aug 20 08:22:44 2010 (10y 40w 5d ago)
13:58 -NickServ(NickServ@services.)- Last addr  : ~ayekat@███████████
13:58 -NickServ(NickServ@services.)- Last seen  : now
13:58 -NickServ(NickServ@services.)- Logins from: ayekat
13:58 -NickServ(NickServ@services.)- Nicks      : ayekat
13:58 -NickServ(NickServ@services.)- Email      : ████████@█████████ (hidden)
13:58 -NickServ(NickServ@services.)- Flags      : HideMail
13:58 -NickServ(NickServ@services.)- *** End of Info ***
14:00 ayekat│ drop ayekat █████████████████
14:00 -NickServ(NickServ@services.)- This is a friendly reminder that you are about to destroy the account ayekat.
14:00 -NickServ(NickServ@services.)- To avoid accidental use of this command, this operation has to be confirmed. Please confirm by 
          replying with /msg NickServ DROP ayekat ██████████ ████████:████████
14:00 ayekat│ drop ayekat █████████████████ ████████:████████
14:00 -NickServ(NickServ@services.)- The account ayekat has been dropped.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can now find me on &lt;a href=&quot;https://libera.chat/&quot;&gt;Libera.Chat&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you can&#x27;t find me, occasionally I&#x27;ll take on the name of this lovely fellow:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;slimefoot&quot; src=&quot;/files/img/slimefoot.jpg&quot; /&gt;&lt;small class=&quot;sidethought&quot;&gt;&lt;em&gt;Artist: Alex
Konstad&lt;br /&gt;
Image &amp;copy; 2018 Wizards of the Coast&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;In case you&#x27;ve been living under a rock, search the Web for &quot;freenode
libera.chat&quot;.&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>Not-a-bug fixing</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/not-a-bug-fixing"
		      id="not-a-bug-fixing" />
		<id>not-a-bug-fixing</id>
		<updated>2019-03-14T15:00:00+0100</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;As far as system maintenance is concerned, I guess I have some minor case of
obsessive compulsive disorder. I very much dislike having &lt;a href=&quot;https://github.com/ayekat/dotfiles/issues/7&quot;&gt;random applications
dropping files in my home directory&lt;/a&gt;, and I am equally
displeased whenever I find software packages on my system that I don&#x27;t need.
While I consider it a waste of time and bandwidth to download and perform
updates for such packages, what causes me more unease is the mere fact that the
system does not appear &lt;em&gt;clean&lt;/em&gt; to me. It is clutter that serves no purpose.&lt;/p&gt;
&lt;p&gt;So whenever I see a package that I do not recognise, my very first reaction is
typically&lt;/p&gt;
&lt;h3 id=&quot;why-is-this-package-installed&quot;&gt;&lt;em&gt;Why is this package installed?&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;In theory, this is very easily determined:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Was the package installed explicitly? Then I should know myself why I
  installed it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Was the package installed as a dependency? Then I should look at its reverse
  dependencies, recursively, until I hit the &quot;topmost&quot; package (i.e. the one
  that was installed explicitly); then see above.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In practice, however, there are a couple of obstacles.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;First&lt;/em&gt;, I don&#x27;t always remember why I installed a given package. Sometimes I
need it for some one-time task and then forget to remove it afterwards. And a
few months later, I&#x27;ve forgotten about it entirely.&lt;/p&gt;
&lt;p&gt;To avoid that sort of situations, I&#x27;ve started writing &lt;em&gt;meta-packages&lt;/em&gt; for the
various tasks. A meta-package has a name, a description of the task, and a list
of package dependencies required for that task. Rather than directly installing
the required tools explicitly, I install the meta-package and let &lt;em&gt;that&lt;/em&gt; pull in
all the wanted packages as dependencies.&lt;/p&gt;
&lt;p&gt;After shifting to using meta-packages for almost everything on my system, I felt
rather clever and happy, as I had found a way to exploit the package manager&#x27;s
dependency system to encode all the information I wanted.&lt;/p&gt;
&lt;p&gt;I didn&#x27;t feel clever for very long, though. Because&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Second&lt;/em&gt;,&lt;/p&gt;
&lt;h3 id=&quot;why-are-the-dependencies-broken&quot;&gt;&lt;em&gt;Why are the dependencies broken?&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;My distribution of choice is currently &lt;a href=&quot;https://archlinux.org/&quot;&gt;Arch Linux&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Arch Linux uses the package manager &lt;em&gt;pacman&lt;/em&gt;. Pacman defines so-called &lt;em&gt;package
groups&lt;/em&gt;, which on a technical level behave like tags or topics, i.e. they have
no influence on how packages depend on, conflict with, or in any other way
relate to each other. However, rather oddly, pacman allows installing and
removing groups with the same syntax as used for packages. This explains why
some pacman users (and even developers) occasionally mistake groups for
meta-packages.&lt;/p&gt;
&lt;p&gt;Arch Linux itself doesn&#x27;t really help resolving this confusion either, as it
doesn&#x27;t use groups very consistently. In many cases, they are like tags;
packages are assigned to groups like &lt;a href=&quot;https://www.archlinux.org/groups/x86_64/vim-plugins/&quot;&gt;&lt;code&gt;vim-plugins&lt;/code&gt;&lt;/a&gt; or
&lt;a href=&quot;https://www.archlinux.org/groups/x86_64/xorg/&quot;&gt;&lt;code&gt;xorg&lt;/code&gt;&lt;/a&gt;, which aren&#x27;t intended to be installed all at once. But there
are also groups like &lt;a href=&quot;https://www.archlinux.org/groups/x86_64/lxqt/&quot;&gt;&lt;code&gt;lxqt&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://www.archlinux.org/groups/x86_64/mate/&quot;&gt;&lt;code&gt;mate&lt;/code&gt;&lt;/a&gt;, which may very well
be installed in their entirety; however, simply replacing them by meta-packages
would cause issues for users who wish to remove some of the packages.&lt;/p&gt;
&lt;p&gt;Furthermore, there are groups like &lt;a href=&quot;https://www.archlinux.org/groups/x86_64/base-devel/&quot;&gt;&lt;code&gt;base-devel&lt;/code&gt;&lt;/a&gt;, a set of
packages that are assumed to be present on a build system, and thus never
explicitly listed among buildtime dependencies for Arch Linux packages; it makes
little sense to install packages from this group only partially (at least if one
installs packages within the context of &lt;code&gt;base-devel&lt;/code&gt;), so replacing it by a
meta-package would very much be feasible.&lt;/p&gt;
&lt;p&gt;Given the confusing nature of groups, for a user it would be easiest to simply
ignore their existence entirely (except for &lt;code&gt;base-devel&lt;/code&gt;: turn that into a
meta-package, and be done with it).&lt;/p&gt;
&lt;p&gt;It &lt;em&gt;would&lt;/em&gt; be easiest.&lt;/p&gt;
&lt;p&gt;Because Arch Linux has managed to add to the confusion about groups by adding a
group whose &lt;em&gt;own&lt;/em&gt; purpose is entirely undefined: &lt;a href=&quot;https://www.archlinux.org/groups/x86_64/base/&quot;&gt;&lt;code&gt;base&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Depending on whom you ask, the reply you get will be different. Some developers
argue that all packages in &lt;code&gt;base&lt;/code&gt; are supposed to be installed on all Arch Linux
systems, and will intentionally &lt;em&gt;not&lt;/em&gt; declare some dependencies when they are in
&lt;code&gt;base&lt;/code&gt;. There are other developers who take a more moderate stance and argue
that only &lt;em&gt;some&lt;/em&gt; packages should be expected on an Arch Linux installation
(&lt;code&gt;glibc&lt;/code&gt; or &lt;code&gt;filesystem&lt;/code&gt; come to mind), while others should be uninstallable
without issues; essentially they agree with the other ones, but argue that the
current &lt;code&gt;base&lt;/code&gt; is too large&amp;mdash;unfortunately, nobody is clear where exactly
they draw the line.&lt;/p&gt;
&lt;p&gt;And last, there are the pedantic people like me who argue that &lt;code&gt;base&lt;/code&gt; should be
considered a set of &quot;recommended packages&quot; at most, and packages in there should
be removable in any way the user wishes, i.e. &lt;em&gt;none&lt;/em&gt; of the packages should be
implicitly assumed to be installed.&lt;/p&gt;
&lt;p&gt;But all those opinions don&#x27;t matter, because this is a case of a metaphorical
chain breaking at its weakest link: even just &lt;em&gt;one&lt;/em&gt; maintainer intentionally not
declaring dependencies on &lt;code&gt;base&lt;/code&gt; packages is enough to &quot;compromise&quot; the entire
system: users now have to &lt;em&gt;globally&lt;/em&gt; assume that things may break if &lt;code&gt;base&lt;/code&gt; is
not fully installed.&lt;/p&gt;
&lt;p&gt;Essentially, the user is forced to have installed a bunch of packages that they
will never need.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Arch Linux is a general-purpose distribution. Upon installation, only a
command-line environment is provided: rather than tearing out unneeded and
unwanted packages, the user is offered the ability to build a custom system
[&amp;hellip;]&lt;/p&gt;
&lt;p&gt;&lt;footer&gt;&lt;cite&gt;&lt;a href=&quot;https://wiki.archlinux.org/index.php/Arch_Linux#Versatility&quot;&gt;Arch Linux: &lt;em&gt;Versatility&lt;/em&gt;&lt;/a&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The lack of policy also means that users cannot submit any bug reports for such
packages: if there is no document that properly describes the &lt;code&gt;base&lt;/code&gt; group, any
interpretation of it is a valid one, no matter how absurd. In fact, if I were to
only submit packages to the &lt;a href=&quot;https://wiki.archlinux.org/index.php/Arch_User_Repository&quot;&gt;Arch User Repository&lt;/a&gt; where I state &lt;em&gt;all&lt;/em&gt; the
&lt;code&gt;base&lt;/code&gt; packages as dependencies, no matter if required or not, my packages might
get removed by an AUR overseer at some point, but the reasoning would probably
be something in the vein of &quot;absurd&quot; or &quot;silly&quot;, but nobody would be able to
refer me to a document stating that my interpretation of the &lt;code&gt;base&lt;/code&gt; group was
technically wrong.&lt;/p&gt;
&lt;p&gt;But there was a time when I didn&#x27;t know that. In autumn 2017, when setting up a
new system, I managed to crash the &lt;code&gt;locale-gen&lt;/code&gt; command by not having &lt;code&gt;sed&lt;/code&gt;
installed. The &lt;code&gt;glibc&lt;/code&gt; package (which provides the &lt;code&gt;locale-gen&lt;/code&gt; command) doesn&#x27;t
mention &lt;code&gt;sed&lt;/code&gt; at all, neither as a mandatory nor optional dependency. So I did
what every optimistic, enthusiastic, &lt;em&gt;naive&lt;/em&gt; Arch Linux user would do: open a
bug report. &lt;a href=&quot;https://bugs.archlinux.org/task/55635&quot;&gt;This one&lt;/a&gt;. And &lt;a href=&quot;https://lists.archlinux.org/pipermail/arch-dev-public/2017-September/028978.html&quot;&gt;this&lt;/a&gt; is what followed on the
developers-only mailing list.&lt;/p&gt;
&lt;p&gt;&amp;hellip; and there went my enthusiasm.&lt;/p&gt;
&lt;h2 id=&quot;persona-non-grata&quot;&gt;&lt;em&gt;persona non grata&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;Based on that reaction in particular and what I had otherwise seen of the Arch
Linux bug tracker overseers&#x27; behaviour on the forums and mailing lists, I got
the feeling that they would now be specifically careful not to resolve any of
&lt;em&gt;my&lt;/em&gt; present or future requests. As far as the bug tracker was concerned, I was
now practically dead.&lt;/p&gt;
&lt;p&gt;Not that this would change much; the majority of issues I had previously
reported (or voted for) had also been either rejected or simply ignored, despite
having patches or trivial solutions attached. It appeared to me that my
perception of what is considered a &quot;bug&quot; differed quite a bit from the Arch
Linux maintainers&#x27; one. I concluded that I couldn&#x27;t really trust my own
judgement on that matter anymore: if something appeared like a bug to me, is it
really a bug? &lt;em&gt;Should I bother reporting it?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I decided &lt;em&gt;no&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It wasn&#x27;t worth the hassle.&lt;/p&gt;
&lt;h3 id=&quot;i-can-fix-this-shit-myself&quot;&gt;I can fix this shit myself&lt;/h3&gt;
&lt;p&gt;Building packages for pacman is not rocket science. The packaging tooling isn&#x27;t
exactly powerful, but it is also rather simple, and it gets the job done without
getting in my way&amp;mdash;so actually quite fitting for a distribution that Arch
Linux claims to be. And having used this distribution for more than seven years
and packaged quite a few things, I decided that I was capable enough of taking
over some of &lt;em&gt;their&lt;/em&gt; packages as well.&lt;/p&gt;
&lt;p&gt;While I didn&#x27;t feel comfortable tackling a package as fundamental as &lt;code&gt;glibc&lt;/code&gt;
right away, I felt confident enough to at least adopt &lt;code&gt;debootstrap&lt;/code&gt;
(&lt;a href=&quot;https://bugs.archlinux.org/task/48908&quot;&gt;FS#48908&lt;/a&gt;), &lt;code&gt;lighttpd&lt;/code&gt; (&lt;a href=&quot;https://bugs.archlinux.org/task/45902&quot;&gt;FS#45902&lt;/a&gt;,
&lt;a href=&quot;https://bugs.archlinux.org/task/51931&quot;&gt;FS#51931&lt;/a&gt;) and &lt;code&gt;pass&lt;/code&gt; (&lt;a href=&quot;https://bugs.archlinux.org/task/55059&quot;&gt;FS#55059&lt;/a&gt;,
&lt;a href=&quot;https://bugs.archlinux.org/task/55504&quot;&gt;FS#55504&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;I started by setting up a personal package repository on a publicly accessible
server, &lt;a href=&quot;http://archlinux.zuepfe.net/&quot;&gt;&lt;code&gt;archlinux.zuepfe.net&lt;/code&gt;&lt;/a&gt;, and configured my systems to add that
repository to their pacman package sources. Then I wrote a convenience script
that would allow me to more easily push packages to that repository, &lt;code&gt;zr&lt;/code&gt; (for
&lt;em&gt;Züpfe Repositories&lt;/em&gt;), and added my custom variants of abovementioned packages
to my custom repository. Up to this point, things were rather smooth.&lt;/p&gt;
&lt;p&gt;But then I started realising that this was going to be &lt;em&gt;a lot of work&lt;/em&gt;&amp;mdash;at
least for a regular user. I had no way of knowing when a library soname bump
related rebuild was due, or when some bug was reported for the &quot;real&quot; version of
the packages that would force me to react someway. I would also need to
subscribe to upstream channels to get all the relevant information required as a
packager for software I was not necessarily very familiar with.&lt;/p&gt;
&lt;p&gt;A lot of duplicated efforts, ultimately. And all that for merely changing some
metadata&amp;hellip;?&lt;/p&gt;
&lt;p&gt;That sounded a bit backwards.&lt;/p&gt;
&lt;h3 id=&quot;lets-just-repackage&quot;&gt;Let&#x27;s &lt;em&gt;just&lt;/em&gt; repackage&lt;/h3&gt;
&lt;p&gt;Pacman packages are pretty simple. They are Xzipped tarballs containing the
following three files at the top level:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.BUILDINFO&lt;/code&gt;: a list of packages installed on the build system as this package
  was built;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.MTREE&lt;/code&gt;: a Gzipped list of files contained in the package, following the
  &lt;a href=&quot;http://jlk.fjfi.cvut.cz/arch/manpages/man/core/man-pages/mtree.5.en&quot;&gt;&lt;code&gt;mtree(5)&lt;/code&gt;&lt;/a&gt; format;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.PKGINFO&lt;/code&gt;: all package metadata (except what is listed in &lt;code&gt;.BUILDINFO&lt;/code&gt; and
  &lt;code&gt;.MTREE&lt;/code&gt;), i.e. name, version, description, dependencies, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The tarball may also optionally contain a &lt;code&gt;.CHANGELOG&lt;/code&gt; file and a &lt;code&gt;.INSTALL&lt;/code&gt;
file that defines actions to be triggered upon installing, upgrading or removing
the package. Everything else in the tarball is the files that are part of the
package, with a directory structure reflecting how they will be installed to the
system.&lt;/p&gt;
&lt;p&gt;That&#x27;s all, no magic. Theoretically, we can easily modify a package directly:
just unpack the tarball, then modify the metadata or add/rename/patch/remove a
file. Sounds crazy? &lt;em&gt;Then let&#x27;s do it.&lt;/em&gt; Rather than maintaining our own version
of the package and building the software from scratch, we just use the work
that&#x27;s already been done by the package maintainer. This is about as low-effort
as it can get.&lt;/p&gt;
&lt;p&gt;And thus, &lt;a href=&quot;https://bbs.archlinux.org/viewtopic.php?id=234936&quot;&gt;&lt;code&gt;repkg&lt;/code&gt;&lt;/a&gt; was born.&lt;/p&gt;
&lt;p&gt;And &lt;a href=&quot;https://gitlab.com/ayekat/PKGBUILDs#zuepfe-repkg&quot;&gt;this&lt;/a&gt; is the list of packages that I currently modify with it. I
can now get sane packages, and the Arch Linux maintainers can keep their bugs
without having a pedantic who complains. &lt;em&gt;That&#x27;s&lt;/em&gt; a win-win.&lt;/p&gt;
&lt;h2 id=&quot;future&quot;&gt;future&lt;/h2&gt;
&lt;p&gt;It&#x27;s now been 1.5 years since that &quot;bug tracker incidence&quot;, and the &lt;code&gt;base&lt;/code&gt; group
still hasn&#x27;t changed. I&#x27;ve seen 3 discussions among the developers come and go
again without any notable progress. In the most recent iteration, people still
seemed to have different ideas of what the purpose of the &lt;code&gt;base&lt;/code&gt; group should
be, so the one concrete proposal of a new (slimmed down) list of packages in
&lt;code&gt;base&lt;/code&gt; seemed just halfhearted at best. I don&#x27;t expect this issue to be resolved
anytime soon.&lt;/p&gt;
&lt;p&gt;Then again, even if the Arch developers suddenly changed their minds and decided
to fix all the things &lt;em&gt;I&lt;/em&gt; consider issues, I&#x27;d still keep using &lt;code&gt;repkg&lt;/code&gt; to
modify packages to my needs, because &lt;em&gt;it&#x27;s just so damn convenient&lt;/em&gt;. Not only
can I now easily fix all the cases of &quot;that&#x27;s not a packaging bug&quot;, but also fix
upstream issues, and otherwise adapt packages to my personal needs&amp;mdash;and I
wouldn&#x27;t want to miss that.&lt;/p&gt;
&lt;p&gt;As far as &lt;code&gt;repkg&lt;/code&gt; is concerned, I&#x27;ve written a wrapper script, &lt;code&gt;remakepkg&lt;/code&gt;, that
handles the downloading of packages and makes the command line invocation more
convenient. But I&#x27;ve noticed that it becomes a bit tedious after a while:&lt;/p&gt;
&lt;p&gt;First, it is currently hardwired to the current checkout of the package
database, so it can&#x27;t repackage a package from a newer, remote database &quot;ahead
of time&quot;, i.e. I first have to attempt a &lt;code&gt;pacman -Syu&lt;/code&gt;, have &lt;code&gt;diffrepo&lt;/code&gt; detect
that the repositories are out of sync, then repackage and push the offending
package to my repository, and try again.&lt;/p&gt;
&lt;p&gt;Second, I&#x27;d like it all to happen more automatically. The repackaging rules are
not bound to a specific package version; they can apply to &lt;em&gt;any&lt;/em&gt; version of the
package (as long as the relevant parts don&#x27;t change), so it could also just run
fully automated, rather than having to invoke it manually each time.&lt;/p&gt;
&lt;p&gt;Third, it doesn&#x27;t scale particularly well: it works fine for one or two dozens
of packages, but if I crank up things to the hundreds (e.g. because I want to
fix something more fundamentally that affects a great number of packages),
running &lt;code&gt;remakepkg&lt;/code&gt; for each one separately isn&#x27;t terribly convenient.&lt;/p&gt;
&lt;p&gt;But this is all assuming that I&#x27;ll keep using this distribution. After 9 years,
I&#x27;ve started to see quite a few cracks. And for a distribution that I would have
otherwise considered as &quot;not getting in my way&quot;, I must admit I&#x27;ve now spent a
considerable time working around its flaws.&lt;/p&gt;
&lt;p&gt;It&#x27;s still &lt;em&gt;good enough&lt;/em&gt;, though, so&amp;hellip;&lt;small
class=&quot;sidethought&quot;&gt;&lt;em&gt;&amp;hellip; meh&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>Hierarchaeology</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/hierarchaeology"
		      id="hierarchaeology" />
		<id>hierarchaeology</id>
		<updated>2017-10-30T22:22:00+0100</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;&lt;em&gt;(and other halfway forgotten things)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Back in the old days of Unix, things used to be a little different. While this
may sound like I&#x27;m another one of those who like to dwell in the &quot;good old
times&quot;, that is not really the case. I have only encountered Unix (through
Linux) in the late 00&#x27;s of the ongoing century, so the best I can do is an
archaeological approach&amp;mdash;which incidentally makes it all the more
interesting.&lt;/p&gt;
&lt;p&gt;A few random things I&#x27;ve found (and a few myths and backronyms that I&#x27;ve found
to be rather wrong):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/etc&lt;/code&gt; really just means &lt;em&gt;et cetera&lt;/em&gt;. The notion of &quot;configuration files&quot;
  didn&#x27;t exist back then (one would have to recompile a program to change an
  aspect of its behaviour); this directory simply contained &lt;a href=&quot;https://unix.stackexchange.com/a/56172/92369&quot;&gt;files that didn&#x27;t
  fit elsewhere&lt;/a&gt;. Hell, even &lt;code&gt;init&lt;/code&gt; used to be in here.
  Configuration files were not specifically &lt;em&gt;only&lt;/em&gt; in this location (there was
  no specification for them), and it was only when other things got gradually
  moved out and the only remaining thing seemed to be configuration files, that
  this directory began to be seen as the &quot;configuration directory&quot;. Note,
  though, that even today, it is not exclusively configuration files in here.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/sbin&lt;/code&gt; &lt;a href=&quot;https://lists.fedoraproject.org/pipermail/devel/2011-October/158845.html&quot;&gt;originally&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt; just meant &lt;em&gt;static
  binaries&lt;/em&gt;&lt;/a&gt;&lt;small class=&quot;sidenote&quot;&gt;This is no longer the case
  on Linux (probably never has been), and quite probably &lt;a href=&quot;https://www.reddit.com/r/BSD/comments/2szofc/eli5_why_is_separating_binaries_into_bin_sbin/cnudxzs/&quot;&gt;neither on
  BSD&lt;/a&gt;.&lt;/small&gt;, as in: &lt;em&gt;Binaries that do not rely on an
  external library and are thus ideal for being used in a limited environment&lt;/em&gt;
  (e.g. early boot). This made them useful for low-level system
  plumbing&amp;mdash;this aspect somehow morphed into the perception that &lt;code&gt;sbin&lt;/code&gt;
  contains &quot;system administrator tools&quot;, and nowadays, it is &quot;hidden&quot; from
  normal users by not having it in &lt;code&gt;$PATH&lt;/code&gt; (and &lt;em&gt;that&lt;/em&gt; separation causes issues
  more often than it solves any).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/usr&lt;/code&gt; &lt;a href=&quot;http://lists.busybox.net/pipermail/busybox/2010-December/074114.html&quot;&gt;originally just meant &lt;em&gt;user&lt;/em&gt;&lt;/a&gt;. It was the mountpoint of a
  separate disk, and user data was moved here to keep the root filesystem from
  overfilling. Likewise, other files like manuals (&lt;code&gt;man&lt;/code&gt;), source files (&lt;code&gt;src&lt;/code&gt;),
  and &quot;non-essential&quot; binaries (&lt;code&gt;bin&lt;/code&gt;) and libraries (&lt;code&gt;lib&lt;/code&gt;) were moved into
  their equivalent under &lt;code&gt;/usr&lt;/code&gt; for the same reason. This left the &quot;first disk&quot;
  with the root filesystem only with the tools to bootstrap the system and mount
  &lt;code&gt;/usr&lt;/code&gt;. Note that these days, this is handled by the initial RAM disk, so the
  separation is pretty pointless.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When &lt;code&gt;/usr&lt;/code&gt; started filling up as well, user-personal data was moved to a
  third disk, mounted under &lt;code&gt;/home&lt;/code&gt;. Ironically, this left the original &quot;user
  directory&quot; as a location for non-user, system-wide data.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When GNU/Linux entered the scene (roughly 20 years later), that layout had
already become &lt;a href=&quot;https://en.wikipedia.org/wiki/Unix_filesystem#Conventional_directory_layout&quot;&gt;semi-formalised&lt;/a&gt;. As a result, we now find
ourselves in this legacy-loaded mess.&lt;/p&gt;
&lt;p&gt;But hey, at least it is somewhat standardised! And there is a slow-but-steady
effort to improve the hierarchy: currently, the various &lt;code&gt;bin&lt;/code&gt; and &lt;code&gt;lib&lt;/code&gt;
directories are being &lt;a href=&quot;https://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/&quot;&gt;merged&lt;/a&gt; together (although, on
some distributions the arbitrary split between &lt;code&gt;sbin&lt;/code&gt; and &lt;code&gt;bin&lt;/code&gt; is still
retained).&lt;/p&gt;
&lt;p&gt;Other old trivia that is not hierarchy- but still filesystem-related:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prepending dots to a filename to make that file &quot;hidden&quot; &lt;a href=&quot;https://plus.google.com/u/0/+RobPikeTheHuman/posts/R58WgWwN9jp&quot;&gt;was an
  accident&lt;/a&gt;. Back in the starting days of Unix, &lt;code&gt;ls&lt;/code&gt; used to
  show all entries in a directory. &lt;em&gt;All&lt;/em&gt; of them, even &lt;code&gt;.&lt;/code&gt; and &lt;code&gt;..&lt;/code&gt; for the
  current and parent directory. This was of course a bit redundant (every
  directory contains them), so the authors decided to add code to &lt;code&gt;ls&lt;/code&gt; to hide
  those entries by default. But instead of ignoring &lt;code&gt;.&lt;/code&gt; and &lt;code&gt;..&lt;/code&gt;, they took a
  shortcut: &lt;code&gt;ls&lt;/code&gt; should simply ignore &lt;em&gt;each entry that would start with a
  dot&lt;/em&gt;.&lt;br /&gt;
  Elegant, heh?&lt;small class=&quot;sidethought&quot;&gt;Actually, the originally intended
  behaviour eventually got implemented as &lt;code&gt;ls -A&lt;/code&gt;.&lt;/small&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The list is admittedly a bit short. I will extend this over time whenever I
stumble over another trivia that I find interesting.&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>Sketches</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/sketches"
		      id="sketches" />
		<id>sketches</id>
		<updated>2017-04-23T17:11:00+0200</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;After about 3 years of being offline, I have finally found some time to hack
together a webcomic-panel like structure on this website to re-publish my stick
figure drawings. I used to refer to them as &lt;em&gt;sannies&lt;/em&gt;, but I find the name a bit
silly, so&amp;hellip; &lt;a href=&quot;/sketches&quot;&gt;&lt;em&gt;sketches&lt;/em&gt;&lt;/a&gt; it is!&lt;/p&gt;
&lt;p&gt;For those of you who don&#x27;t know what this is all about: I used to draw stick
figures during the classes in high school (and early EPFL) as &quot;memory
aids&quot;&amp;mdash;hence the name &lt;em&gt;sannies&lt;/em&gt; (&lt;em&gt;&lt;strong&gt;S&lt;/strong&gt;ketches &lt;strong&gt;A&lt;/strong&gt;s &lt;strong&gt;N&lt;/strong&gt;otes&lt;/em&gt;).
Over the years, I have started to scribble down all kinds of other things,
though; I got some positive feedback, and I thought &quot;why not?&quot;&lt;/p&gt;
&lt;p&gt;So besides the early &quot;&lt;a href=&quot;/sketches/0&quot;&gt;course topic&lt;/a&gt;&quot; ones and snapshots of
&lt;a href=&quot;/sketches/19&quot;&gt;awkward&lt;/a&gt; and &lt;a href=&quot;/sketches/23&quot;&gt;interesting&lt;/a&gt; classroom scenes
(sometimes depictions of my &lt;a href=&quot;/sketches/27&quot;&gt;frustration&lt;/a&gt;), the portfolio now
contains a somewhat extensive collection of &quot;&lt;a href=&quot;/sketches/14&quot;&gt;capture the
mood&lt;/a&gt;&quot;-like drawings:&lt;/p&gt;
&lt;div class=&quot;fullwidth&quot;&gt;
&lt;img class=&quot;bordered&quot; alt=&quot;SuperRTL&quot; src=&quot;/sketches/20.jpg&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;And there should be most of it&amp;mdash;the rather embarassing ones (for historical
accuracy) as well as the countless depictions of our main class
teacher. She might have had a little rough job with the bunch of us&amp;mdash;me
included&amp;hellip; but hey, despite my abyssmal french skills back then, I&#x27;ve made
it to Lausanne! Have I redeemed myself?&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;bordered&quot; alt=&quot;A.S.&quot; src=&quot;/sketches/36.jpg&quot;&gt;&lt;small class=&quot;sidethought&quot;&gt;She was awesome.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;I haven&#x27;t yet finished the series on poor old &lt;a href=&quot;/sketches/61&quot;&gt;Dr.
Goldstein&lt;/a&gt;, although there are two more drawings
that I haven&#x27;t scanned in yet&amp;mdash;there&#x27;s more to come! Unfortunately,
academic institutions don&#x27;t value free time as much as I&#x27;d love them to, so
that&#x27;s going to be another thing to do this summer.&lt;/p&gt;
&lt;p&gt;As a final remark, if I may: my main motivation for this was actually just to
properly explain the origin of my online avatar picture:&lt;/p&gt;
&lt;h2 id=&quot;the-camera-man&quot;&gt;the camera man&lt;/h2&gt;
&lt;p&gt;&lt;img class=&quot;bordered&quot; alt=&quot;camera man&quot; src=&quot;/files/img/cameraman_full.jpg&quot; /&gt;&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>Epoch</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/epoch"
		      id="epoch" />
		<id>epoch</id>
		<updated>2017-03-29T16:50:00+0200</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;I always wondered why we would anchor the counting of our years to an event
mostly relevant to only one World religion: the &quot;international and secular&quot; year
0 really just denotes the year in which the Christian religion&#x27;s prophet is
believed to have been born. This might explain why &lt;a href=&quot;https://en.wikipedia.org/wiki/Calendar#Calendars_in_use&quot;&gt;some parts of the
globe&lt;/a&gt; have not adopted
that calendar yet&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small class=&quot;sidenote&quot;&gt;Or
rather simply that &lt;em&gt;Status Quo&lt;/em&gt; has repeatedly shown itself to be the strongest
force opposing any kind of improvements.&lt;/small&gt;. And who would blame them.&lt;/p&gt;
&lt;p&gt;But then the question is, what makes a good secular calendar?&lt;/p&gt;
&lt;p&gt;The Unix-phile person in me would welcome a system that is not too complicated
to use and implement&amp;mdash;I&#x27;d say the current Gregorian calendar is not all too
bad in that respect. So the following suggestion by a friend of mine (who
incidentally happens to be a Finn) got my full approval:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Year 0 denotes the beginning of the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Unix_time&quot;&gt;Unix epoch&lt;/a&gt;, i.e.
&lt;a href=&quot;https://en.wikipedia.org/wiki/Anno_Domini&quot;&gt;AD&lt;/a&gt; 1970.
&lt;footer&gt;&lt;cite&gt;T. Tuuva&lt;/cite&gt;&lt;/footer&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Seems simple. Relocate year 0, and keep things the same otherwise.&lt;/p&gt;
&lt;p&gt;Of course this would blatantly ignore the fact that not all cultures use 365-day
or 12-month cycles to mark a &quot;year&quot;, or 7-day cycles to mark a week&lt;span
class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small class=&quot;sidenote&quot;&gt;Although from a quick glance
I could not find any other week lengths.&lt;/small&gt;, but those are rooted in very
ancient religions or astrology, and are thus not necessarily limited to just one
geographic region.&lt;/p&gt;
&lt;p&gt;Either way, we need to &quot;rethink&quot; a few things, of course:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In the Unix epoch, the Christian epoch starts in &amp;minus;1970. Converting a
  year number from that &quot;Old Calendar&quot; is thus of course simply done by
  subtracting 1970.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Since negatively numbered years are not very user-friendly, those years should
  be referred to as &lt;em&gt;Before Unix&lt;/em&gt;, or &lt;strong&gt;BU&lt;/strong&gt; for short. To explicitly refer to
  a positive year number, we might adapt something like &lt;em&gt;Anno Unix&lt;/em&gt; (&lt;strong&gt;AU&lt;/strong&gt;).
  It&#x27;s perhaps silly, I don&#x27;t know&amp;mdash;we&#x27;ll see.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A few randomly selected major events in history (to &quot;reorient&quot;): Cæsar was
  murdered on the ides of March, in 2014 BU. The Middle Ages started around the
  14&lt;sup&gt;th&lt;/sup&gt; century BU and ended around the 5&lt;sup&gt;th&lt;/sup&gt; century BU.
  &lt;em&gt;Sgt. Pepper&lt;/em&gt; was released in the year 3 BU, &lt;em&gt;Star Wars&lt;/em&gt; screened in AU 7. The
  Berlin Wall fell in 19, and 9/11 happened in 31. And (hopefully not last or
  least) we&#x27;ll run into the &lt;a href=&quot;https://en.wikipedia.org/wiki/Year_2038_problem&quot;&gt;Year 68
  problem&lt;/a&gt; in&amp;hellip; well, 68.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Many of us might be young enough to witness the second century.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To force myself to get into the habit of using that new system, I decided to
concretise this idea a bit more and configure my computer to display and use
dates in this system; the obvious first place for that was the standard C
library. Since we do not touch the internal time system (it already &lt;em&gt;is&lt;/em&gt; in the
Unix epoch), we only need to adapt the external representation of the date,
namely what &lt;a href=&quot;https://linux.die.net/man/3/strftime&quot;&gt;&lt;code&gt;strftime()&lt;/code&gt;&lt;/a&gt; returns.&lt;/p&gt;
&lt;p&gt;Unfortunately, &lt;code&gt;strftime()&lt;/code&gt; acts on a &lt;code&gt;struct tm&lt;/code&gt;, which starts counting the
years in 70 BU (AD 1900), so &lt;code&gt;strftime()&lt;/code&gt; does some transforming on its own
already, which does not exactly simplify things.&lt;/p&gt;
&lt;p&gt;Moreover, there are several format specifiers for the year (e.g. &lt;code&gt;%Y&lt;/code&gt; and &lt;code&gt;%y&lt;/code&gt;
for the year itself, &lt;code&gt;%C&lt;/code&gt; for the century, and &lt;code&gt;%G&lt;/code&gt; and &lt;code&gt;%g&lt;/code&gt; for the
ISO-week-based year&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small
class=&quot;sidenote&quot;&gt;E.g. if december 31 is a sunday in 48, it is part of week 1 in
the next year&lt;/small&gt;) + a few &quot;composite&quot; specifiers like &lt;code&gt;%D&lt;/code&gt; (&lt;code&gt;%m/%d/%y&lt;/code&gt;) and
&lt;code&gt;%F&lt;/code&gt; (&lt;code&gt;%Y-%m-%d&lt;/code&gt;). To make matters more complicated, there are also format
&lt;em&gt;modifiers&lt;/em&gt; like &lt;code&gt;%E&lt;/code&gt; and &lt;code&gt;%O&lt;/code&gt; (although I have not yet looked into those).&lt;/p&gt;
&lt;p&gt;So&amp;hellip;&lt;/p&gt;
&lt;h2 id=&quot;quickndirty&quot;&gt;quick&#x27;n&#x27;dirty&lt;/h2&gt;
&lt;p&gt;For a quick test-&quot;baptising&quot;, rather than trying to modify the abovementioned
format specifiers correctly, I decided to simply add a new specifier, &lt;code&gt;%f&lt;/code&gt; (note
that this diff applies to glibc 2.25&amp;mdash;it may need to be adapted for other
releases):&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gh&quot;&gt;diff --git a/time/strftime_l.c b/time/strftime_l.c&lt;/span&gt;
&lt;span class=&quot;gh&quot;&gt;index eb3efb8129..18b339d926 100644&lt;/span&gt;
&lt;span class=&quot;gd&quot;&gt;--- a/time/strftime_l.c&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+++ b/time/strftime_l.c&lt;/span&gt;
&lt;span class=&quot;gu&quot;&gt;@@ -1013,6 +1013,9 @@ __strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;     cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;     break;

&lt;span class=&quot;gi&quot;&gt;+   case L_(&amp;#39;f&amp;#39;):&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+     DO_NUMBER(1, tp-&amp;gt;tm_year - 70);&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;   case L_(&amp;#39;F&amp;#39;):
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;     if (modifier != 0)
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;       goto bad_format;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, to enjoy my transition to the new epoch, I modified my &lt;a href=&quot;https://github.com/ayekat/karuibar&quot;&gt;status
bar&lt;/a&gt; to use &lt;code&gt;%f-%m-%d&lt;/code&gt; for the date display:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;karuibar time module in epoch&quot; src=&quot;/files/img/karuibar-epoch.png&quot; /&gt;&lt;small
class=&quot;sidethought&quot;&gt;Should&#x27;ve waited another 6 minutes&amp;hellip; just for the sake
of it.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Of course, applications do not use &lt;code&gt;%f&lt;/code&gt;, so this approach is a dead end. But
it&#x27;s a start.&lt;/p&gt;
&lt;h2 id=&quot;slownproperly&quot;&gt;slow&#x27;n&#x27;properly&lt;/h2&gt;
&lt;p&gt;I initially feared that changing the code for &lt;code&gt;%Y&lt;/code&gt;, &lt;code&gt;%y&lt;/code&gt; and all the other
specifiers would degrade to a gorefest, but the code turned out to be remarkably
clean. In comparison, the code I &lt;em&gt;then&lt;/em&gt; introduced was a little less clean. But
for testing purposes, I considered it &quot;well enough&quot;:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;--- a/time/strftime_l.c&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+++ b/time/strftime_l.c&lt;/span&gt;
&lt;span class=&quot;gu&quot;&gt;@@ -880,7 +880,7 @@ __strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;           }

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;         {
&lt;span class=&quot;gd&quot;&gt;-           int year = tp-&amp;gt;tm_year + TM_YEAR_BASE;&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+           int year = tp-&amp;gt;tm_year - 70;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;           DO_NUMBER (1, year / 100 - (year % 100 &amp;lt; 0));
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;         }

&lt;span class=&quot;gu&quot;&gt;@@ -1212,10 +1212,10 @@ __strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;           switch (*f)
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;             {
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;             case L_(&amp;#39;g&amp;#39;):
&lt;span class=&quot;gd&quot;&gt;-               DO_NUMBER (2, (year % 100 + 100) % 100);&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+               DO_NUMBER (2, ((year - 1970) % 100 + 100) % 100);&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;             case L_(&amp;#39;G&amp;#39;):
&lt;span class=&quot;gd&quot;&gt;-               DO_NUMBER (1, year);&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+               DO_NUMBER (1, year - 1970);&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;             default:
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;               DO_NUMBER (2, days / 7 + 1);
&lt;span class=&quot;gu&quot;&gt;@@ -1257,7 +1257,7 @@ __strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;         if (modifier == L_(&amp;#39;O&amp;#39;))
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;           goto bad_format;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;         else
&lt;span class=&quot;gd&quot;&gt;-           DO_NUMBER (1, tp-&amp;gt;tm_year + TM_YEAR_BASE);&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+           DO_NUMBER (1, tp-&amp;gt;tm_year - 70);&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;       case L_(&amp;#39;y&amp;#39;):
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;         if (modifier == L_(&amp;#39;E&amp;#39;))
&lt;span class=&quot;gu&quot;&gt;@@ -1276,7 +1276,7 @@ __strftime_internal (CHAR_T *s, size_t maxsize, const CHAR_T *format,&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;# endif
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;#endif
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;           }
&lt;span class=&quot;gd&quot;&gt;-         DO_NUMBER (2, (tp-&amp;gt;tm_year % 100 + 100) % 100);&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+         DO_NUMBER (2, ((tp-&amp;gt;tm_year - 70) % 100 + 100) % 100);&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;       case L_(&amp;#39;Z&amp;#39;):
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;         if (change_case)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And indeed, after installing the patched glibc and rebooting the machine, the
system started displaying dates with the new epoch format. Here&#x27;s an example
output of systemd:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ systemctl --user status
● testbox
    State: running
     Jobs: 0 queued
   Failed: 0 units
    Since: Tue 47-03-28 15:47:49 CEST; 1h 4min ago
   CGroup: /user.slice/user-1000.slice/user@1000.service
           └─init.scope
             ├─306 /usr/lib/systemd/systemd --user
             └─315 (sd-pam)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So everything seemed neat and rainbow-y&amp;hellip;&lt;/p&gt;
&lt;h2 id=&quot;except-for-coreutils&quot;&gt;&amp;hellip; except for coreutils&lt;/h2&gt;
&lt;p&gt;For some reason, &lt;code&gt;date&lt;/code&gt;, &lt;code&gt;ls&lt;/code&gt; and all the other programs provided by coreutils
were still stuck in the Gregorian calendar. And indeed, after taking a closer
look, it turned out that coreutils maintains its &lt;em&gt;own&lt;/em&gt; version of &lt;code&gt;strftime()&lt;/code&gt;
(and quite probably a few other (g)libc components).&lt;/p&gt;
&lt;p&gt;Yay! More patching!&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gd&quot;&gt;--- a/lib/strftime.c&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+++ b/lib/strftime.c&lt;/span&gt;
&lt;span class=&quot;gu&quot;&gt;@@ -906,9 +906,9 @@&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;            }

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;          {
&lt;span class=&quot;gd&quot;&gt;-            int century = tp-&amp;gt;tm_year / 100 + TM_YEAR_BASE / 100;&lt;/span&gt;
&lt;span class=&quot;gd&quot;&gt;-            century -= tp-&amp;gt;tm_year % 100 &amp;lt; 0 &amp;amp;&amp;amp; 0 &amp;lt; century;&lt;/span&gt;
&lt;span class=&quot;gd&quot;&gt;-            DO_SIGNED_NUMBER (2, tp-&amp;gt;tm_year &amp;lt; - TM_YEAR_BASE, century);&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+            int century = (tp-&amp;gt;tm_year - 70) / 100;&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+            century -= (tp-&amp;gt;tm_year - 70) % 100 &amp;lt; 0 &amp;amp;&amp;amp; 0 &amp;lt; century;&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+            DO_SIGNED_NUMBER (2, tp-&amp;gt;tm_year - 70 &amp;lt; 0, century);&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;          }

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;        case L_(&amp;#39;x&amp;#39;):
&lt;span class=&quot;gu&quot;&gt;@@ -1275,18 +1275,17 @@&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;              {
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;              case L_(&amp;#39;g&amp;#39;):
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;                {
&lt;span class=&quot;gd&quot;&gt;-                  int yy = (tp-&amp;gt;tm_year % 100 + year_adjust) % 100;&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+                  int yy = ((tp-&amp;gt;tm_year - 70) % 100 + year_adjust) % 100;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;                  DO_NUMBER (2, (0 &amp;lt;= yy
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;                                 ? yy
&lt;span class=&quot;gd&quot;&gt;-                                 : tp-&amp;gt;tm_year &amp;lt; -TM_YEAR_BASE - year_adjust&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+                                 : tp-&amp;gt;tm_year - 70 &amp;lt; -year_adjust&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;                                 ? -yy
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;                                 : yy + 100));
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;                }

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;              case L_(&amp;#39;G&amp;#39;):
&lt;span class=&quot;gd&quot;&gt;-                DO_SIGNED_NUMBER (4, tp-&amp;gt;tm_year &amp;lt; -TM_YEAR_BASE - year_adjust,&lt;/span&gt;
&lt;span class=&quot;gd&quot;&gt;-                                  (tp-&amp;gt;tm_year + (unsigned int) TM_YEAR_BASE&lt;/span&gt;
&lt;span class=&quot;gd&quot;&gt;-                                   + year_adjust));&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+                DO_SIGNED_NUMBER (4, tp-&amp;gt;tm_year - 70 &amp;lt; -year_adjust,&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+                                  (tp-&amp;gt;tm_year - 70 + year_adjust));&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;              default:
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;                DO_NUMBER (2, days / 7 + 1);
&lt;span class=&quot;gu&quot;&gt;@@ -1326,8 +1325,7 @@&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;          if (modifier == L_(&amp;#39;O&amp;#39;))
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;            goto bad_format;

&lt;span class=&quot;gd&quot;&gt;-          DO_SIGNED_NUMBER (4, tp-&amp;gt;tm_year &amp;lt; -TM_YEAR_BASE,&lt;/span&gt;
&lt;span class=&quot;gd&quot;&gt;-                            tp-&amp;gt;tm_year + (unsigned int) TM_YEAR_BASE);&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+          DO_SIGNED_NUMBER (4, tp-&amp;gt;tm_year -70 &amp;lt; 0, tp-&amp;gt;tm_year - 70);&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;        case L_(&amp;#39;y&amp;#39;):
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;          if (modifier == L_(&amp;#39;E&amp;#39;))
&lt;span class=&quot;gu&quot;&gt;@@ -1346,9 +1344,9 @@&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;            }

&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;          {
&lt;span class=&quot;gd&quot;&gt;-            int yy = tp-&amp;gt;tm_year % 100;&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+            int yy = (tp-&amp;gt;tm_year - 70) % 100;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;            if (yy &amp;lt; 0)
&lt;span class=&quot;gd&quot;&gt;-              yy = tp-&amp;gt;tm_year &amp;lt; - TM_YEAR_BASE ? -yy : yy + 100;&lt;/span&gt;
&lt;span class=&quot;gi&quot;&gt;+              yy = tp-&amp;gt;tm_year - 70 &amp;lt; 0 ? -yy : yy + 100;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;            DO_NUMBER (2, yy);
&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;          }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that seems &lt;em&gt;almost&lt;/em&gt; fine. Notice how for the &lt;code&gt;%Y&lt;/code&gt; modifier, coreutils
actually pads the year number with zeroes to have it use at least 4 digits, in
&lt;em&gt;any&lt;/em&gt; case? So we get &lt;code&gt;0047&lt;/code&gt; instead of just &lt;code&gt;47&lt;/code&gt;, for instance.&lt;/p&gt;
&lt;p&gt;However, I sense that fixing this would cause a great disturbance in the Force.
As if millions of badly written scripts suddenly errored out in terror and were
suddenly terminated.&lt;/p&gt;
&lt;p&gt;Alright, we done here?&lt;/p&gt;
&lt;h2 id=&quot;a-rabbit-hole&quot;&gt;a rabbit hole&lt;/h2&gt;
&lt;p&gt;What about the &lt;em&gt;in&lt;/em&gt;put? For instance, how would coreutils&#x27; &lt;code&gt;date&lt;/code&gt; interpret
dates passed with the &lt;code&gt;--date&lt;/code&gt; option?&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ date --date=&amp;#39;2017-03-28&amp;#39;
Tue 28 Mar 00:00:00 CEST 0047
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Well, that doesn&#x27;t look terribly right&amp;mdash;that&#x27;ll require patching,
too&amp;hellip;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;At this point, I stopped.&lt;/p&gt;
&lt;p&gt;The problem is, patching &lt;code&gt;strftime()&lt;/code&gt; is comparatively trivial (as we&#x27;ve seen
above) and solves the &lt;em&gt;out&lt;/em&gt;put problem. Most applications&amp;mdash;independently of
the language they are written in&amp;mdash;somehow make use of libc&#x27;s &lt;code&gt;strftime()&lt;/code&gt;
at some point either directly or through bindings, so there isn&#x27;t really much of
duplication of code here (except for coreutils, because).&lt;/p&gt;
&lt;p&gt;But &lt;em&gt;reading&lt;/em&gt; date and time values and converting them to an internal
representation is a different thing: there are quite possibly countless
different implementations for that, in all sorts of programs and languages, and
they most likely all assume that we&#x27;re in the Gregorian calendar. The fact that
&lt;code&gt;struct tm&lt;/code&gt; puts its year 0 to 70 BU (AD 1900) doesn&#x27;t exactly simplify things
(although, if we think about it, that&#x27;s a different problem&lt;span
class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small class=&quot;sidenote&quot;&gt;But still a
problem.&lt;/small&gt;).&lt;/p&gt;
&lt;p&gt;That&#x27;s a rabbit hole that I don&#x27;t really want to step into.&lt;/p&gt;
&lt;h2 id=&quot;final-thoughts&quot;&gt;final thoughts&lt;/h2&gt;
&lt;p&gt;The idea still seems tempting: switch to a different time epoch and get rid of
the religious baggage. But as long as our everyday live keeps using the
Gregorian calendar (and for us geeks in particular, as long as the &lt;em&gt;computer&lt;/em&gt;
keeps using the Gregorian calendar), it&#x27;s rather difficult to get into the &quot;Unix
mode&quot;.&lt;/p&gt;
&lt;p&gt;And while my naive approach of simply adding a new format specifier (&lt;code&gt;%f&lt;/code&gt;,
remember?) to &lt;code&gt;strftime()&lt;/code&gt; seems a little lazy, the alternative would be a
matter of &quot;all or nothing&quot;, with &quot;all&quot; being pretty much impossible for a single
person, and &quot;nothing&quot; being downright frustrating. &quot;Some&quot; is a dangerous middle
ground where things will break sooner or later anyway.&lt;/p&gt;
&lt;p&gt;Another aspect we haven&#x27;t looked into yet is the way we treat leap years.
Because the years in the Unix calendar basically have the same length as the
ones in the Gregorian calendar, the same &lt;font color=&quot;#3A3&quot;&gt;4&lt;/font&gt;/&lt;font
color=&quot;#D22&quot;&gt;100&lt;/font&gt;/&lt;font color=&quot;#3A3&quot;&gt;400&lt;/font&gt; rule can be applied here,
too. But the leap years have been established using the Gregorian calendar; in
the Unix calendar, they would be in 2, 6, 10, 14&amp;hellip; with the first
&quot;non-leap-year&quot; in AU 130 (AD 2100). We have to convert our dates to the
Gregorian calendar before determining whether they are leap years or
not&amp;mdash;and frankly that isn&#x27;t very convenient. But we&#x27;d need more adoption
for changing &lt;em&gt;that&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;We&#x27;d need more people.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;erratum&quot;&gt;erratum&lt;/h2&gt;
&lt;p&gt;Actually, the Gregorian calendar &lt;a href=&quot;https://en.wikipedia.org/wiki/Year_zero&quot;&gt;starts counting years at AD
1&lt;/a&gt;. The year preceding AD 1 is 1 BC.
Consequently, we have Gaius Julius Caesar who died in 44 BC, which is actually
201&lt;strong&gt;3&lt;/strong&gt; and not 2014 BU.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;astronomical&lt;/em&gt; calendar (and ISO-8601) do have a year 0 that corresponds to
1 BC (so the year numbers for everything before AD 1 are off by 1), even though
it&#x27;s not used very often in historical contexts.&lt;/p&gt;
&lt;p&gt;Speaking of standards&amp;mdash;&lt;a href=&quot;https://tools.ietf.org/html/rfc3339&quot;&gt;RFC 3339&lt;/a&gt; also
states that year numbers are expected to be 4-digit numbers. So coreutils
padding the year number as seen is actually standard-conform behaviour. The
standard also explicitly states that years are expected to lie between AD 0000
and AD 9999&amp;mdash;it does not mention negative years or years above 10,000 at
all, so at least I can rest assured that the RFC will be adapted someday (and
perhaps the Unix epoch can establish itself until then and profit from the era
of the date notation instability).&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>Shadows</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/shadows"
		      id="shadows" />
		<id>shadows</id>
		<updated>2017-03-08T00:10:00+0100</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;&lt;small class=&quot;sidethought&quot;&gt;I apologise for the 4.1&amp;thinsp;MiB and their
potential effect on your quota. Although&amp;hellip; something something modern
websites deal with it&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Cleaning up my photographs from the past year, I came across a few things I
considered worthy to be shared. The first thing is probably this video showing
the effects of sunlight shining on a bird window sticker through leaves moving
in the wind:&lt;/p&gt;
&lt;div class=&quot;fullwidth&quot;&gt;
&lt;video src=&quot;/files/vid/bird.webm&quot; poster=&quot;/files/img/bird.jpg&quot; controls&gt;
trees + wind + window = moving shadows!
&lt;/video&gt;
&lt;/div&gt;

&lt;p&gt;&amp;hellip; and yes, this is the original speed at which it was recorded. If you
don&#x27;t believe me, feel free to play the video again a few times. After all, make
use of the 4.1&amp;thinsp;MiB I just made you download for seeing this page.&lt;/p&gt;
&lt;p&gt;And just for the pinch of &lt;em&gt;technical&#x27;ism&lt;/em&gt; in this blog:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg -i DSC_0203.MOV -c:v libvpx -crf 5 -b:v 2M -an bird.webm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;VP8/VP9 experts, awake and cringe! Or &lt;a href=&quot;/about&quot;&gt;contact me&lt;/a&gt; and tell me all the
things that are wrong with that line.&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>日本語 in LaTeX</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/nihongo-latex"
		      id="nihongo-latex" />
		<id>nihongo-latex</id>
		<updated>2017-03-03T01:00:00+0100</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;Seldom is it a pleasant experience to discover that you are wrong and need to
adapt. But unpleasant experiences make life&amp;hellip; well, Life. In a good way;
let&#x27;s say, &lt;em&gt;spices that give some perspective on the sweet things&lt;/em&gt;, to make a
somewhat pityful attempt at poetry. Or &lt;em&gt;WebKit security issues that make us
abandon old and unmaintained web browser&lt;/em&gt;&amp;mdash;ah yes, there, I think I&#x27;m
slowly getting the hang of this. What would Life be without stories to tell of
past disasters, both little and great&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small
class=&quot;sidenote&quot;&gt;Let us live through the little ones and tell stories of the
great ones! Or so.&lt;br /&gt;&amp;hellip; OK, I&#x27;ll stop.&lt;/small&gt;.&lt;/p&gt;
&lt;p&gt;The other day in particular, I found myself defending my use of &lt;code&gt;pdflatex&lt;/code&gt; to a
&lt;a href=&quot;http://florv.ch/&quot;&gt;much wiser person&lt;/a&gt;, stating that
&lt;code&gt;\usepackage[utf8]{inputenc}&lt;/code&gt; would indeed allow UTF-8-encoded characters in in
@LaTeX@ documents to be treated correctly. That was until I was gently told that
&lt;code&gt;inputenc&lt;/code&gt; is really only a hack: try to use something marginally exotic, and
&lt;code&gt;pdflatex&lt;/code&gt; will show you the metaphoric door.&lt;/p&gt;
&lt;p&gt;I got shown that door without much seeking:&lt;/p&gt;
&lt;div class=&quot;hiragana-table&quot;&gt;&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;ん&lt;/td&gt;&lt;td&gt;わ&lt;/td&gt;&lt;td&gt;ら&lt;/td&gt;&lt;td&gt;や&lt;/td&gt;&lt;td&gt;ま&lt;/td&gt;&lt;td&gt;は&lt;/td&gt;&lt;td&gt;な&lt;/td&gt;&lt;td&gt;た&lt;/td&gt;&lt;td&gt;さ&lt;/td&gt;&lt;td&gt;か&lt;/td&gt;&lt;td&gt;あ&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;　&lt;/td&gt;&lt;td&gt;　&lt;/td&gt;&lt;td&gt;り&lt;/td&gt;&lt;td&gt;　&lt;/td&gt;&lt;td&gt;み&lt;/td&gt;&lt;td&gt;ひ&lt;/td&gt;&lt;td&gt;に&lt;/td&gt;&lt;td&gt;ち&lt;/td&gt;&lt;td&gt;し&lt;/td&gt;&lt;td&gt;き&lt;/td&gt;&lt;td&gt;い&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;　&lt;/td&gt;&lt;td&gt;　&lt;/td&gt;&lt;td&gt;る&lt;/td&gt;&lt;td&gt;ゆ&lt;/td&gt;&lt;td&gt;む&lt;/td&gt;&lt;td&gt;ふ&lt;/td&gt;&lt;td&gt;ぬ&lt;/td&gt;&lt;td&gt;つ&lt;/td&gt;&lt;td&gt;す&lt;/td&gt;&lt;td&gt;く&lt;/td&gt;&lt;td&gt;う&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;　&lt;/td&gt;&lt;td&gt;　&lt;/td&gt;&lt;td&gt;れ&lt;/td&gt;&lt;td&gt;　&lt;/td&gt;&lt;td&gt;め&lt;/td&gt;&lt;td&gt;へ&lt;/td&gt;&lt;td&gt;ね&lt;/td&gt;&lt;td&gt;て&lt;/td&gt;&lt;td&gt;せ&lt;/td&gt;&lt;td&gt;け&lt;/td&gt;&lt;td&gt;え&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;　&lt;/td&gt;&lt;td&gt;を&lt;/td&gt;&lt;td&gt;ろ&lt;/td&gt;&lt;td&gt;よ&lt;/td&gt;&lt;td&gt;も&lt;/td&gt;&lt;td&gt;ほ&lt;/td&gt;&lt;td&gt;の&lt;/td&gt;&lt;td&gt;と&lt;/td&gt;&lt;td&gt;そ&lt;/td&gt;&lt;td&gt;こ&lt;/td&gt;&lt;td&gt;お&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ever since I have managed to make Japanese input work again with
&lt;a href=&quot;https://en.wikipedia.org/wiki/Input_method&quot;&gt;IBus&lt;/a&gt;, I seem to constantly seek
excuses to type it everywhere. And yes, &lt;code&gt;pdflatex&lt;/code&gt; did not cope with it.&lt;/p&gt;
&lt;p&gt;So I have tinkered around on my playground-@LaTeX@ file, hunting it through
various incarnations (while letting it produce the same blank page over and
over), incidentally switching to &lt;code&gt;xelatex&lt;/code&gt;&amp;mdash;until it finally decided to
give a glimpse at what &lt;em&gt;Hiragana&lt;/em&gt;, &lt;em&gt;Katakana&lt;/em&gt; and &lt;em&gt;Kanji&lt;/em&gt; might actually look
like if typeset by Knuth: &lt;small class=&quot;sidethought&quot;&gt;And behold!, the
&lt;a href=&quot;/files/src/japanese.tex&quot;&gt;Source&lt;/a&gt;.&lt;/small&gt;&lt;/p&gt;
&lt;div class=&quot;fullwidth&quot;&gt;
&lt;img class=&quot;bordered&quot; src=&quot;/files/img/japanese-latex.png&quot; alt=&quot;Japanese LaTeX&quot; /&gt;
&lt;/div&gt;

&lt;h2 id=&quot;publishing&quot;&gt;publishing&lt;/h2&gt;
&lt;p&gt;Of course, the vanity in person that I am, I wanted to share this, so I had to
adapt a few things in &lt;code&gt;ayekat.ch&lt;/code&gt;, too:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Specify the &lt;a href=&quot;https://en.wikipedia.org/wiki/Ming_(typefaces)&quot;&gt;&lt;em&gt;Minchō&lt;/em&gt;&lt;/a&gt; font
  typefaces &lt;code&gt;&quot;IPAMincho&quot;&lt;/code&gt; and &lt;code&gt;&quot;Sazanami Mincho&quot;&lt;/code&gt; in the site&#x27;s CSS, to have the
  Japanese fonts be more in line with the rest of the site&#x27;s serif
  font&amp;mdash;not sure what this actually looks like on a system that does not
  have these fonts installed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add a &quot;token substitution&quot; system to my markup handler, so that I can simply
  type &lt;code&gt;&amp;#x40;LaTeX&amp;#x40;&lt;/code&gt; to conveniently get the stylised @LaTeX@
  logo printed. To do so, I had to Spaghetti-code some workarounds in order to
  get rid of those pesky HTML tags in the site&#x27;s title;&lt;small
  class=&quot;sidethought&quot;&gt;&amp;hellip; yes, I would like some &lt;em&gt;Bolognese&lt;/em&gt; sauce and
  &lt;em&gt;Parmigiano&lt;/em&gt; cheese with that Spaghetti code, thank you very much.&lt;/small&gt;
  precisely speaking, I use an additional, &quot;stripped&quot; variable + a little
  condition checking for when to print which title variant.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Put in a hack to have the &lt;code&gt;text/x-tex&lt;/code&gt; MIME type be recognised as being
  encoded with UTF-8 (as python doesn&#x27;t detect that properly, apparently)&lt;small
  class=&quot;sidethought&quot;&gt;&amp;hellip; yes, yes, I would &lt;em&gt;really&lt;/em&gt; love some sauce and
  cheese!&lt;/small&gt;, so the web browsers would properly show the @LaTeX@ source
  file for abovementioned outcome.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Coding at its finest, eh?&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>/var/log/computers</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/var-log-computers"
		      id="var-log-computers" />
		<id>var-log-computers</id>
		<updated>2017-02-23T22:29:00+0100</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;With a bit of nostalgia, after going through the history of &lt;em&gt;waltz&lt;/em&gt; for the new
incarnation of the &lt;a href=&quot;/about&quot;&gt;about page&lt;/a&gt;, I thought I could also go through my
history of desktop hardware. However, this turned out to be rather difficult, as
I did not really keep track of my computers as a child and teenager.
Consequently, this undertaking turned mostly into me digging through pictures on
the web and comparing them with my ever-dwindling memories of what I had
previously owned and used.&lt;/p&gt;
&lt;p&gt;Nevertheless, I decided to devote this (mini-)article to my first-ever personal
computer:&lt;/p&gt;
&lt;h2 id=&quot;compaq-presario-7222&quot;&gt;Compaq Presario 7222&lt;/h2&gt;
&lt;p&gt;Around &#x27;99 (when &lt;a href=&quot;https://en.wikipedia.org/wiki/Compaq&quot;&gt;&lt;em&gt;Compaq&lt;/em&gt;&lt;/a&gt; still used to
dominate the personal computer market), my father acquired a shiny new tower
(&lt;em&gt;Compaq&lt;/em&gt;, too), running &lt;em&gt;Windows 98&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;And I was given this gem:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/files/img/compaq-presario-7222.jpeg&quot; alt=&quot;Compaq Presario
7222&quot;&gt;&lt;small class=&quot;sidethought&quot;&gt;Image taken from &lt;a href=&quot;http://www.recycledgoods.com/compaq-presario-7222-p1-100mhz-intel-pentium-desktop-computer.html&quot;&gt;&lt;em&gt;Recycled
Goods&lt;/em&gt;&lt;/a&gt;.&lt;br
/&gt;Please imagine a bulky CRT screen placed on top of it.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;According to the data I could find about it&lt;span
class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small
class=&quot;sidenote&quot;&gt;&lt;a href=&quot;http://www.sysopt.com/showthread.php?57159-Presario-7222&quot;&gt;SysOpt&lt;/a&gt;,
&lt;a href=&quot;https://www.kahlon.com/rm1318_Compaq_Presario_7222.html&quot;&gt;Kahlon&lt;/a&gt;&lt;/small&gt;, the
CPU was an &lt;em&gt;Intel Pentium 1&lt;/em&gt; (that would be x586, I believe) with a whooping
100&amp;thinsp;MHz, 8&amp;thinsp;MB of main memory, 1.2&amp;thinsp;GB of storage (not sure
if the hard drive was 5.25 or 3.5 inches) and support for various phone
technologies that I have never got to know before they became extinct in the
personal PC sector. According to the data, it also had a sound card, even though
I tend to associate this PC with &quot;no sound&quot;&amp;mdash;mostly because I never had any
audible warnings when enemies attacked me in &lt;em&gt;Age of Empires&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Attached to it was a bulky CRT screen (the same dirty white), and&amp;mdash;drum
roll, please&amp;mdash;my favourite keyboard of all time (in the same dirty white):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/files/img/compaq-keyboard-split-spacebar.jpeg&quot; alt=&quot;Compaq
Split-Spacebar Keyboard&quot; /&gt;&lt;small class=&quot;sidethought&quot;&gt;Notice the split spacebar?
&lt;em&gt;The Split Spacebar??&lt;/em&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=LhG8Ry-L3IQ&quot;&gt;SPACEPAR!?!&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Yes, the split spacebar. I think my love story with this computer was also
partly grounded in this keyboard. The left space key was actually a &lt;em&gt;back&lt;/em&gt;space,
which meant that I could comfortably erase my typing errors without having to
move my fingers around too much&amp;mdash;which in turn drove me to learn
touch-typing (at the age of 11, I think, without even knowing how a computer
really works).&lt;/p&gt;
&lt;p&gt;I have kept that keyboard for as long as my computers used to provide a PS/2
port&amp;mdash;which was roughly until 2007.&lt;/p&gt;
&lt;p&gt;The machine itself was running &lt;em&gt;Windows 95&lt;/em&gt;, and during my childhood, it served
two purposes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Playing &lt;em&gt;Age of Empires&lt;/em&gt;&amp;mdash;without sound.&lt;/li&gt;
&lt;li&gt;Writing documents and stories&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small
  class=&quot;sidenote&quot;&gt;Because I wanted to become the next
  J.&amp;thinsp;K.&amp;thinsp;Rowling. Or &lt;a href=&quot;https://en.wikipedia.org/wiki/Ephraim_Kishon&quot;&gt;Ephraim
  Kishon&lt;/a&gt;. I don&#x27;t know.&lt;/small&gt;
  with &lt;em&gt;Microsoft Office 97 Word&lt;/em&gt;&amp;mdash;without sound.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And things had to be done in precisely that order. If any application was
launched &lt;em&gt;before&lt;/em&gt; running AoE, AoE would simply hang. But it was enough, and I
had a happy childhood&amp;mdash;and who needs Internet, anyway?&lt;/p&gt;
&lt;p&gt;Did I mention I had no sound?&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>Tufte CSS</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/tufte-css"
		      id="tufte-css" />
		<id>tufte-css</id>
		<updated>2017-01-31T16:56:00+0100</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;Vanity has caught me again. Inspired by Dave Liepmann&#x27;s &lt;a href=&quot;https://edwardtufte.github.io/tufte-css/&quot;&gt;&lt;em&gt;Tufte
CSS&lt;/em&gt;&lt;/a&gt;, a hommage to &lt;a href=&quot;https://en.wikipedia.org/wiki/Edward_tufte&quot;&gt;Edward
Tufte&lt;/a&gt;&#x27;s work on data visualisation
and his effort to translate it to the Web, I have mostly tried to integrate
those nifty sidenotes&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small
class=&quot;sidenote&quot;&gt;Websites usually have more freedom in the horizontal space, and
the concept of a &lt;q&gt;footnote&lt;/q&gt; or a &lt;q&gt;bottom of page&lt;/q&gt; really has no
meaning here. Also they look &lt;em&gt;cool&lt;/em&gt;, don&#x27;t they?&lt;/small&gt; into my blog, but also
wanted to solve the issue of text lines generally being too long, while other
content (code, graphics) was generally too narrow. And since this required some
tinkering in the CSS, I considered my days off from work over this prolonged
weekend as a perfect opportunity to spice up my blog&#x27;s design with this small
change.&lt;/p&gt;
&lt;p&gt;And indeed, getting the sidenotes into the &lt;em&gt;blog&lt;/em&gt; turned out to be rather easy.
But to keep things consistent, I considered it a necessity to apply this
main&amp;ndash;side area separation to &lt;em&gt;all&lt;/em&gt; the parts of this website. Which of
course meant I had to tinker around a little more in the Python CGI codebase.&lt;/p&gt;
&lt;p&gt;Oh boy.&lt;/p&gt;
&lt;p&gt;In 2015, I might &lt;a href=&quot;/blog/dynamic-waltz&quot;&gt;have been proud&lt;/a&gt; about what I had done.
But looking at that code today meant an unsettling amount of head-shaking and
fist-rising, occasionally accompanied by a whispered &lt;em&gt;&quot;What the hell&quot;&lt;/em&gt;. The code
&lt;em&gt;had&lt;/em&gt; been split up, yet I failed to see any kind of logic of how it was done
so. It seemed to me like I had simply split code away from a file once it had
crossed some magical &lt;q&gt;too many lines&lt;/q&gt; limit. Or something, I don&#x27;t really
know&amp;mdash;there was a single 116-lines long script called &lt;code&gt;scaffold.py&lt;/code&gt; that
handled the HTTP request parsing and the overall HTML document structure
build-up + HTTP response generation (latter in a very ugly way). I could
recognise a half-hearted attempt to split the &lt;em&gt;view&lt;/em&gt; generation from the
&lt;em&gt;logic&lt;/em&gt;, which unfortunately got somehow swallowed up by later code extensions
for previously unforeseen features. Starting to fix something at one place
caused a string of bugs to pop up at a completely different place, and the
&lt;q&gt;small change&lt;/q&gt; subsequently ate up my entire weekend.&lt;/p&gt;
&lt;p&gt;Although&amp;mdash;honestly&amp;mdash;I can&#x27;t say that it was completely devoid of
&lt;em&gt;fun&lt;/em&gt;. I mean, it&#x27;s vanity tinkering&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small
class=&quot;sidenote&quot;&gt;The kind of tinkering that only affects parts of your IT
infrastructure that revolve around your appearance to the outside
world&amp;mdash;after all, we&#x27;re talking about a personal &lt;em&gt;website&lt;/em&gt;.&lt;/small&gt;, after
all. And the result is pretty neat, I think:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The main content now takes 60% of the entire &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; width to the left,
  while the sidenote area takes 36% of the width to the right. The sidenotes are
  simply &lt;code&gt;&amp;lt;small&amp;gt;&lt;/code&gt; elements, styled with CSS to float to the right. To be
  honest, it isn&#x27;t terribly comfortable writing the markup for that in a blog
  article, but then again, it&#x27;s probably fine this way, as I would otherwise
  abuse them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The main page directly leads to the blog view. There is no point in showing a
  visitor an almost empty page with three links&amp;mdash;that&#x27;s just
  pseudo-&lt;q&gt;artistic&lt;/q&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The gallery&#x27;s CSS has been fixed to scale the image such that it uses the
  entire available screen space (similar to CSS&#x27;s &lt;code&gt;background-size: cover&lt;/code&gt;
  property&amp;mdash;except that it&#x27;s not a background).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The principal font has been changed to the more elegant and open &lt;a href=&quot;https://en.wikipedia.org/wiki/Linux_Libertine&quot;&gt;Linux
  Libertine&lt;/a&gt;, with
  &lt;a href=&quot;https://en.wikipedia.org/wiki/Georgia_(typeface)&quot;&gt;Georgia&lt;/a&gt; as a fallback
  font.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Looking at the diff of the commit that introduced the change, it feels like git
futilely tried to make sense of the mess, only to resort to follow my
example&lt;span class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small class=&quot;sidenote&quot;&gt;You know, the
head-shaking, fist-rising and curse-whispering.&lt;/small&gt;: In the &lt;code&gt;cgi&lt;/code&gt; directory,
the diff (with roughly 360 lines removed and 450 lines added) shows 9 unchanged
non-whitespace lines, of which &lt;em&gt;all&lt;/em&gt; are keywords like &lt;code&gt;try:&lt;/code&gt; or &lt;code&gt;else:&lt;/code&gt;, or
&lt;code&gt;import os&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;showing-off&quot;&gt;showing off&lt;/h2&gt;
&lt;p&gt;&lt;small class=&quot;sidethought&quot;&gt;I consider text lines at around 35 ems to be the most
comfortable to read, while code should at least have a width of 80 characters.
By the way, this is a side&lt;em&gt;thought&lt;/em&gt;, i.e. a sidenote without a specific numbered
anchor in the text. Cool, eh?&lt;/small&gt; As noted above, the goal of this layout is
also to solve the old issue of text lines generally being too long, while other
elements like code blocks tend to become pretty useless if jammed into too
little space.  This can now easily be achieved by assigning the &lt;code&gt;fullwidth&lt;/code&gt;
class to any element in an article, and it will take up the entire 100% of the
width. This is often useful for showing a graphics that requires a high enough
resolution, or just for showing an image with added emphasis, like the photo of
this lovely cat:&lt;/p&gt;
&lt;div class=&quot;fullwidth&quot;&gt;
&lt;img src=&quot;/photos/cats/20140104_135845.jpg&quot; alt=&quot;lea&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;Of course it is not mandatory to display a picture in full-width&amp;mdash;
displaying a &lt;q&gt;regular&lt;/q&gt; picture accompanied with a caption text to the side
is now possible, too:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;bbq&quot; src=&quot;/photos/bbq/20150513_205818.jpg&quot; /&gt;&lt;small class=&quot;sidethought&quot;&gt;Shot from one
of our &lt;a href=&quot;/photos/bbq&quot;&gt;barbecue evenings&lt;/a&gt; at the EPFL &lt;em&gt;(model: Nikon D5100, focal
length: 35mm, exposure: 15s, aperture: f1.8, flash: no, ISO: 100&lt;/em&gt;)&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Another element that is best viewed in full width is a &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; code block (note
that this is a diversion from &lt;em&gt;Tufte CSS&lt;/em&gt;, where code is kept within the
boundary of normal text&amp;mdash;I just thought that this doesn&#x27;t make any sense);
as an example, the CSS part that allowed me to properly center and zoom the
picture in this website&#x27;s &lt;a href=&quot;/photos&quot;&gt;gallery&lt;/a&gt; view:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;article&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.9&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;rem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;/* gallery navigation takes 2.9 rems */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;article&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;-webkit-&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;zoom-in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;zoom-in&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;overflow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;hidden&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;article&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;/* http://stackoverflow.com/a/19414020/3673974 */&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;absolute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;-100&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;-100&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;-100&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;-100&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;margin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;auto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;min-height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;min-width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Lastly (and obviously) I learned a few things about the spacing around
em-dashes (there is none), the proper use of markup tags introduced with HTML 5
(&lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;, etc.), or just how to properly organise my code such
that it doesn&#x27;t end up as this pile of mess I had encountered on Friday evening.&lt;/p&gt;
&lt;p&gt;And to explain my absence over the past 14 months: I had initially intended to
write an article about how to set up an &lt;a href=&quot;http://pcengines.ch/alix2d3.htm&quot;&gt;ALIX
2d3&lt;/a&gt; with Debian for using as a home network
router (similar to my &lt;a href=&quot;/blog/qemu-networkd-nftables&quot;&gt;&lt;em&gt;QEMU/network/nftables&lt;/em&gt;&lt;/a&gt;
guides), but the thing grew and grew and was never really finished, yet it did a
remarkably good job at keeping me from writing any other new articles&lt;span
class=&quot;ref-sidenote&quot;&gt;&lt;/span&gt;&lt;small class=&quot;sidenote&quot;&gt;&lt;em&gt;&quot;If you work on a blog
article, you might as well work on me!&quot;&lt;/em&gt;&lt;/small&gt;, until I concluded that the
information might be better kept in my private little wiki that I have started
to build up recently.&lt;/p&gt;
&lt;p&gt;But that&#x27;s for a different story.&lt;/p&gt;
&lt;p&gt;As for the future: I have noticed that I prefer writing code over writing
&lt;em&gt;about&lt;/em&gt; code, so perhaps the focus of my blog will lie a little more on
non-technical stuff (like politics&amp;mdash;the world currently is quite a mess,
honestly), or the more high-level, organisational aspects of technology (like
&lt;em&gt;&quot;When will applications stop littering my home directory with dotfiles and adhere
to the &lt;a href=&quot;https://specifications.freedesktop.org/basedir-spec/latest/&quot;&gt;XDG base directory
specifications&lt;/a&gt;?&quot;&lt;/em&gt;)&amp;mdash;I
have no idea how it will work out, but we&#x27;ll (hopefully) see in the next few
weeks.&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>Waiter! There&#x27;s a VLA in my C!</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/vla"
		      id="vla" />
		<id>vla</id>
		<updated>2015-11-15T16:50:00+0100</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;Real world ayekat has chosen to pass on some of his knowledge to the
microtechnics and electricity people on his daily living site. Mostly this
consists of annoying some poor students with elaborated in-depth facts about the
beauty of Unix and the C programming language.&lt;/p&gt;
&lt;p&gt;While it might sound like a rather doable job, one never ceases to learn new
things. Or as for this matter: one never ceases to encounter the ugly sides in
the things one so loves and cherishes.&lt;/p&gt;
&lt;p&gt;In my case it was a simple sequence of code that I thought would never compile
&amp;mdash; and the moment it did, I feared I would not be on good terms with it:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scanf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;-Wall&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-Wextra&lt;/code&gt;! &lt;code&gt;-pedantic&lt;/code&gt;! &lt;code&gt;man gcc&lt;/code&gt;! &lt;code&gt;-W&lt;/code&gt;&lt;em&gt;HowCanThisNotThrowAWarning&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&quot;variable-length-arrays&quot;&gt;Variable Length Arrays&lt;/h2&gt;
&lt;p&gt;What is happening? Obviously the array is allocated at runtime, yet it doesn&#x27;t
seem to require a manual &lt;code&gt;free&lt;/code&gt; afterwards. And indeed, a quick test program
confirmed my assumption: it is allocated on the stack.&lt;/p&gt;
&lt;p&gt;That doesn&#x27;t seem to be that much of black magick. After all, &lt;code&gt;alloca&lt;/code&gt; &amp;mdash;
while non-standard &amp;mdash; is also used to allocate memory on the stack, and
apparently it is just C99 notation for&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scanf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;%d&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alloca&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So why do I react so allergic to those VLAs?&lt;/p&gt;
&lt;p&gt;First, I &lt;em&gt;do&lt;/em&gt; program in C99, but I tend to put all variable declarations at the
top of the functions. That may be a relic from the C89 times, but for me, this
also makes it easier to comprehend what is happening on the stack; I don&#x27;t like
random variable declarations popping up in the middle of the code (and to all
people arguing about keeping variable declarations as local as possible:
they are local to the function &amp;mdash; if you argue with &quot;but for longer
functions&quot;, modularise your bloody code).&lt;/p&gt;
&lt;p&gt;VLAs mess around with my mental picture of what&#x27;s happening, because a variable
declaration depends on executed code (the &lt;code&gt;alloca&lt;/code&gt; way makes it clearer, while
keeping the same functionality).&lt;/p&gt;
&lt;p&gt;As for a technical reason: again, it is allocated on the &lt;em&gt;stack&lt;/em&gt;, and the stack
has a limited size, and all you can do is sit there and watch and pray&amp;hellip;
and subsequently enter Damnation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;RETURN VALUE&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The alloca() function returns a pointer to the beginning of the allocated
space. If the allocation causes stack overflow, program behavior is
undefined.
&lt;footer&gt;&lt;cite&gt;&lt;a href=&quot;https://www.mankier.com/3/alloca&quot;&gt;&lt;code&gt;alloca(3)&lt;/code&gt;&lt;/a&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Undefined&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Try entering &lt;code&gt;192837465647382910&lt;/code&gt; to the above program and watch the World burn.
This is no longer some non-standard, unsafe technique &amp;mdash; it is now some
&lt;em&gt;standard&lt;/em&gt;, unsafe technique. And to make matters worse, the abovementioned
students use a two-dimensional VLA to store &lt;em&gt;image data&lt;/em&gt; on the stack.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;What&lt;/em&gt; could possibly go wrong&amp;hellip;&lt;/p&gt;
&lt;h2 id=&quot;the-rabbit-hole&quot;&gt;The Rabbit Hole&lt;/h2&gt;
&lt;p&gt;As stated above, the students use two-dimensional arrays. So while messing
around with those VLAs, I stumbled over another peculiarity in the C language.&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;do_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;do_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now let&#x27;s see what interesting things &lt;code&gt;gcc&lt;/code&gt; has to say about this:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;warning: passing argument 3 of ‘do_something’ from incompatible pointer type [-Wincompatible-pointer-types]
  do_something(w, h, array);
                     ^
note: expected ‘int **’ but argument is of type ‘int (*)[(sizetype)(a)]’
 void do_something(int width, int height, int **array);
      ^
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So apparently a 2D array is &lt;em&gt;not&lt;/em&gt; the same thing as &lt;code&gt;**&lt;/code&gt;, fine &amp;mdash; but what
in the name of the Seven Hells is an &lt;code&gt;int (*)[(sizetype)(a)]&lt;/code&gt;?&lt;/p&gt;
&lt;h2 id=&quot;multi-dimensional-arrays&quot;&gt;Multi-Dimensional Arrays&lt;/h2&gt;
&lt;p&gt;This might seem pretty logic, but I&#x27;ve nevertheless managed to write programs in
C for about 8 years without paying proper attention to the subtle differences
between pointers and arrays; I knew that if they were statically allocated, the
program would handle them differently for &lt;code&gt;sizeof&lt;/code&gt;, yet I failed to grasp the
&lt;em&gt;exact&lt;/em&gt; reason for that &amp;mdash; and subsequently also what so radically
separates &lt;em&gt;multi-dimensional&lt;/em&gt; arrays from pointers.&lt;/p&gt;
&lt;p&gt;Yet, if we look at how they are stored in memory, it makes perfect sense: a 2D
array is not simply a 1D array of 1D arrays, but rather like one big 1D array
that has been cut into &lt;em&gt;n&lt;/em&gt; pieces. We can&#x27;t just put classical &quot;double-pointers&quot;
there (think about pointer arithmetics violently blowing up and cities burning
and people dying and the air stinking and everything being really, really bad).&lt;/p&gt;
&lt;p&gt;So how can we reference a 2D array?&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// OK&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt;                    &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// ... or no, wait - no, actually: BOOM!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Not like this.&lt;/p&gt;
&lt;p&gt;Let us have another look at that bizarre &lt;code&gt;int (*)[(sizetype)(a)]&lt;/code&gt;. It resembles
a function pointer, yet that would make no sense. And it isn&#x27;t, anyway.&lt;/p&gt;
&lt;p&gt;It is simply a notation. The &lt;code&gt;(*)&lt;/code&gt; indicates that it is a pointer to something,
and the brackets to the right indicate that the &quot;something&quot; is an array of size
&lt;code&gt;a&lt;/code&gt;. Consequently, a 2D array is like a 1D array of some &quot;units&quot;, where each
unit has a size of &lt;code&gt;a&lt;/code&gt;. And &lt;code&gt;sizetype&lt;/code&gt; is simply &lt;code&gt;gcc&lt;/code&gt;&#x27;s way of telling us that
it expects a type that can be used to indicate a size &amp;mdash; might be an &lt;code&gt;int&lt;/code&gt;,
a &lt;code&gt;size_t&lt;/code&gt;, or something alike.&lt;/p&gt;
&lt;p&gt;So we would need to write this instead:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// yay!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;a[3][4]&lt;/code&gt; is a array of three 4-element units. &lt;code&gt;(*p)[4]&lt;/code&gt; is a pointer to the
first element in an array of 4-element units (&lt;em&gt;not&lt;/em&gt; an array of arrays) and the
notation suddenly starts to make &quot;sense&quot;, or whatever you would call that for
some weird C notation.&lt;/p&gt;
&lt;p&gt;Equally, a function would need to be declared like this:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;do_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// or with some &amp;quot;sugar&amp;quot;:&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;do_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// or with even MORE &amp;quot;sugar&amp;quot;:&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;do_something&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Science! &lt;small class=&quot;sidethought&quot;&gt;
Source: &lt;a href=&quot;http://www.comeaucomputing.com/techtalk/c99/#variablelengtharrays&quot;&gt;&lt;em&gt;Tech Talk About C99 &amp;mdash; What Are Variable Length
Arrays?&lt;/em&gt;&lt;/a&gt;
&lt;/small&gt;&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>Anarcho DHCP</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/anarcho-dhcp"
		      id="anarcho-dhcp" />
		<id>anarcho-dhcp</id>
		<updated>2015-11-09T14:37:00+0100</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;There is a non-negligible amount of things that you learn by mistake. And if you
know me, I make a lot of mistakes. Ergo, I learn a lot of things &amp;mdash; even if
they mostly have no useful purpose.&lt;/p&gt;
&lt;p&gt;Yet, this is useful: Even if you have assigned an IP address to your &lt;em&gt;WiFi&lt;/em&gt;
interface that is different from the subnet you&#x27;ve joined, if dnsmasq is
running, you might still give a DHCP lease to any other device that enters the
network.&lt;/p&gt;
&lt;p&gt;I already knew that from &lt;em&gt;wired&lt;/em&gt; networks, yet I hadn&#x27;t thought that the same
&quot;accident&quot; could happen in &lt;em&gt;wireless&lt;/em&gt; networks. Not until I heard my lovely
girlfriend&#x27;s voice say something like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I don&#x27;t have internet!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Instead of the usual &lt;code&gt;192.168.2.0/24&lt;/code&gt;, she had been assigned an address in the
&lt;code&gt;172.16.12.0/24&lt;/code&gt; subnet &amp;mdash; which happens to be my laptop&#x27;s subnet for
sharing internet over WiFi/&lt;code&gt;hostapd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, &lt;code&gt;hostapd&lt;/code&gt; hadn&#x27;t been running on my laptop, and she was connected to
the right AP anyway. Yet somehow my laptop&#x27;s &lt;code&gt;dnsmasq&lt;/code&gt; must have got the DHCP
discover message anyway, and answered to it faster than the router.&lt;/p&gt;
&lt;p&gt;From that, I assumed that no matter if you&#x27;re on a wired or wireless connection,
rogue DHCP servers may be a problem. When I stated my discovery &lt;a href=&quot;/blog/bash&quot;&gt;among my
collegues&lt;/a&gt;, the reaction I got was something along the way of &quot;&lt;em&gt;of
course &amp;mdash; and it&#x27;s not the first time your computer does that &amp;mdash; fix
your fucking networking!&lt;/em&gt;&quot;, followed by:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;flor&amp;gt; ayekat: si j&amp;#39;étais l&amp;#39;opérateur réseau je ban ton compte directement si tu
      fais ça
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Interestingly, even if the AP runs a DHCP server on it&#x27;s own, it broadcasts the
DHCP discover packet. This might seem weird at the first glance, but then again
&lt;code&gt;hostapd&lt;/code&gt; and &lt;code&gt;dnsmasq&lt;/code&gt; are two different processes (that may as well run on two
different devices), and things still work as expected if all is set up
correctly.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If&lt;/em&gt; things are set up correctly.&lt;/p&gt;
&lt;p&gt;For my part, I have decided not to put any IP addresses on my ethernet and WiFi
interfaces that may be subject to accidental DHCP lease offers by dnsmasq, put a
static address on my ethernet interface (for emergencies), and assign IP
addresses manually to an interface if necessary &amp;mdash; after all, it doesn&#x27;t
happen each day that I share my internet connection.&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>QEMU/networkd/nftables</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/qemu-networkd-nftables"
		      id="qemu-networkd-nftables" />
		<id>qemu-networkd-nftables</id>
		<updated>2015-11-07T11:35:00+0100</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;Remember &lt;a href=&quot;/blog/qemu-networkd&quot;&gt;this post&lt;/a&gt; when I was all enthusiastic about
using a local server with QEMU and some apparently simple network setup using
systemd-networkd? Remember when you were like &lt;em&gt;Oh!, I&#x27;ve gotta try this out! But
wait &amp;mdash; what about forwarding ports?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There was supposed to be a fourth section going something like &quot;&lt;strong&gt;nftables&lt;/strong&gt;
&amp;mdash; Now, let&#x27;s add some port-forwarding!&quot;. Later, it became something like
&quot;Oh, it&#x27;s a little more complicated &amp;mdash; let&#x27;s just complete it once I&#x27;ve got
all the informations!&quot;. It then became &quot;God, this is awfully fucked up&quot;, before
finally becoming &quot;Oh, it&#x27;s actually pretty logic - I&#x27;m just really dumb.&quot;&lt;/p&gt;
&lt;p&gt;Well, welcome to that follow-up.&lt;/p&gt;
&lt;h2 id=&quot;systemd-networkd&quot;&gt;systemd-networkd&lt;/h2&gt;
&lt;p&gt;As stated, I decided to use nftables for port-forwarding. Yet packets didn&#x27;t
seem to even &lt;em&gt;enter&lt;/em&gt; my prerouting chain, which was rather unfortunate, as it is
there where things like &quot;this packet will get redirected to this host&quot; should
happen.&lt;/p&gt;
&lt;p&gt;After asking on &lt;code&gt;#netfilter&lt;/code&gt; and getting friendly troubleshooting advice (and
involuntary invoking a pro-systemd vs. anti-systemd debate when I stated that
the &lt;code&gt;IPMasquerade&lt;/code&gt; option in my systemd-networkd setup might perhaps have had
some bad influence on the matter), I decided to tear my network and its
configuration down and restart from scratch (while people on &lt;code&gt;#netfilter&lt;/code&gt; were
ripping each other&#x27;s head off about the purpose of systemd-networkd and its
apparent non-conformity to some RFC).&lt;/p&gt;
&lt;p&gt;When everything was back up, my setup looked almost the same, except for the
missing &lt;code&gt;IPMasquerade&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# /etc/systemd/network/qemu0.netdev&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[NetDev]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;qemu0&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;bridge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# /etc/systemd/network/qemu0.network&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[Match]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;qemu0&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[Network]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;172.16.10.1/24&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;IPForward&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;nftables-masquerade&quot;&gt;nftables: masquerade&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://netfilter.org/projects/nftables/&quot;&gt;nftables&lt;/a&gt; is an effort to replace the
existing netfilter/iptables framework. Although it is not production-ready, I
decided to bleed and replace my existing iptables setup with nftables, since in
the long run, learning the Ins and Outs of a filtering system that has a
hard-to-parse syntax and that will soon get replaced didn&#x27;t seem very lucrative
to me.&lt;/p&gt;
&lt;p&gt;Hence, the masquerading takes place in &lt;code&gt;/etc/nftables.conf&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;ch&quot;&gt;#!/usr/sbin/nft -f&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prerouting&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prerouting&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;priority&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;postrouting&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;postrouting&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;priority&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;saddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;172.16.10.1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;oifname&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;wlp3s0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;enp0s25&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;masquerade&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Looks sane enough, and works.&lt;/p&gt;
&lt;h2 id=&quot;nftables-port-forwarding&quot;&gt;nftables: port-forwarding&lt;/h2&gt;
&lt;p&gt;Packet filtering is a topic that could fill a new article on its own &amp;mdash; I
usually stick to this mental picture (I may stand corrected):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Packet enters pre-routing chain, where we may alter it before it enters
  routing&lt;/li&gt;
&lt;li&gt;if Packet is for the system itself:&lt;ul&gt;
&lt;li&gt;Packet enters input chain, where we decide whether we let it in&lt;/li&gt;
&lt;li&gt;Packet ends/starts here&lt;/li&gt;
&lt;li&gt;Packet enters output chain, where we decide whether we let it out&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;else if Packet is for a different system:&lt;ul&gt;
&lt;li&gt;Packet enters forward chain, where we can influence the routing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Packet enters post-routing chain, where we may alter it before it leaves the
  system&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Alright! So let&#x27;s add some classic rule: one that forwards connections to the
host&#x27;s port 2222 to the guest&#x27;s port 22:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;ch&quot;&gt;#!/usr/sbin/nft -f&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prerouting&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prerouting&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;priority&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tcp&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dport&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2222&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dnat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;172.16.10.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;postrouting&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nat&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hook&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;postrouting&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;priority&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;saddr&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;172.16.10.1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;oifname&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;wlp3s0&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;enp0s25&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;masquerade&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-troubleshooting&quot;&gt;The Troubleshooting&lt;/h2&gt;
&lt;p&gt;Although everything looks fine, we&#x27;ve got the above-stated problem: Packets
don&#x27;t enter nftables&#x27; &lt;code&gt;prerouting&lt;/code&gt; chain. Packets not entering the &lt;code&gt;prerouting&lt;/code&gt;
chain apparently ate an entire Friday afternoon away from me.&lt;/p&gt;
&lt;p&gt;Let&#x27;s prevent that for you:&lt;/p&gt;
&lt;p&gt;As already stated in &lt;a href=&quot;/blog/qemu-networkd&quot;&gt;the original article&lt;/a&gt;,
systemd-networkd provides the options &lt;code&gt;IPForward&lt;/code&gt; and &lt;code&gt;IPMasquerade&lt;/code&gt;. The tricky
thing about &lt;code&gt;IPForward&lt;/code&gt; is that if you don&#x27;t specify it, it will set the sysctl
option &lt;code&gt;net.ipv4.conf.&amp;lt;interface&amp;gt;.forwarding&lt;/code&gt; to 0 &amp;mdash; regardless of whether
you set &lt;code&gt;net.ipv4.ip_forward&lt;/code&gt; to 1 in &lt;code&gt;/etc/sysctl.d/99-ip_forward.conf&lt;/code&gt;.
&lt;a href=&quot;https://bbs.archlinux.org/viewtopic.php?id=204195&quot;&gt;But we already knew &lt;em&gt;that&lt;/em&gt;.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The other tricky thing is that &lt;a href=&quot;/blog/qemu-networkd&quot;&gt;this&lt;/a&gt; is actually wrong:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Also, &lt;code&gt;IPMasquerade&lt;/code&gt; replaces iptables/nftables rules for masquerading in this
simple case.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is incorrect because systemd will &lt;em&gt;not&lt;/em&gt; handle IP masquerading on its own,
but use iptables. It&#x27;s actually good, because it doesn&#x27;t reinvent the wheel, but
delegate the filtering to an appropriate tool: the firewall. It also makes sense
that if we remove the option, no iptables rules for masquerading will be added.&lt;/p&gt;
&lt;p&gt;Yet&amp;thinsp;&amp;hellip; in my &lt;em&gt;nf&lt;/em&gt;tables setup, while packets seemed to enter the
&lt;code&gt;postrouting&lt;/code&gt; chain, they refused to do the same for &lt;code&gt;prerouting&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;At this point, I reread all documentation I could find on creating a NAT with
port forwarding for nftables, before stumbling over
&lt;a href=&quot;http://wiki.nftables.org/wiki-nftables/index.php/Performing_Network_Address_Translation_%28NAT%29#Incompatibilities&quot;&gt;this&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You cannot use iptables and nft to perform NAT at the same time. So make sure
that the &lt;em&gt;iptable_nat&lt;/em&gt; module is unloaded:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;rmmod iptable_nat
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/blockquote&gt;
&lt;p&gt;Friday evening. Weekend. It&#x27;s all fine.&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>QEMU/networkd</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/qemu-networkd"
		      id="qemu-networkd" />
		<id>qemu-networkd</id>
		<updated>2015-11-06T17:45:00+0100</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;As I start to get more and more into touch with &quot;the industry&quot;, I realise that
it&#x27;s pretty much impossible to just walk in with your laptop and start hacking
straight away. Mostly, you&#x27;ll end up in an environment where they&#x27;re working
with some &quot;solution&quot; X, where X isn&#x27;t just any ordinary application, but some
intrusive monster that will change at least 50% of the configuration that
handles the fundamental behaviour of your system.&lt;/p&gt;
&lt;p&gt;That is rarely nice.&lt;/p&gt;
&lt;p&gt;Luckily, things can be virtualised, and shit doesn&#x27;t need to be accepted like
that. But setting up a proper virtualisation solution (that is not server-grade,
like Xen) is a little less trivial. There is VirtualBox, but it&#x27;s almost become
one of those intrusive techs on its own, and not very configuration friendly. It doesn&#x27;t play nice with KVM either. And it&#x27;s been
&lt;a href=&quot;https://en.wikipedia.org/wiki/Sun_acquisition_by_Oracle&quot;&gt;oracled&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But fortunately, there is &lt;a href=&quot;http://wiki.qemu.org/Main_Page&quot;&gt;QEMU&lt;/a&gt;, which is
purely CLI-based, and it integrates with KVM, which is nice. It needs some
scripting, though, since no one in their right mind would type a QEMU command
manually. But that is usually trivially done in an evening full of cursing and
cups of tea.&lt;/p&gt;
&lt;p&gt;But then, alas! Networking!&lt;/p&gt;
&lt;h2 id=&quot;systemd-networkd&quot;&gt;systemd-networkd&lt;/h2&gt;
&lt;p&gt;systemd is quite a controversial piece of software. Basically it was written
to replace formerly existing init/rc solutions. Then, it also replaced login.
And docker. And incorporated udev. And dbus. And an HTTP server. That also
serves QR code. For login.&lt;/p&gt;
&lt;p&gt;Then, it added network handling. Which is cool. Because network handling is
usually a pain in the ass. ifupdown, netcfg/netctl, NetworkManager, Wicd and
alike have not just emerged for no reason &amp;mdash; but they may not be available
on all platforms, or be rather GUI-centric. And mostly they feel more like an
overlay to the underlying network commands (&lt;code&gt;ip&lt;/code&gt;, &lt;code&gt;dhcpcd&lt;/code&gt;), than actual network
managers.&lt;/p&gt;
&lt;p&gt;At this point, systemd-networkd does quite a good job at handling the network,
has a text-based configuration similar to ifupdown, and integrates rather well
with the system (I mean&amp;thinsp;&amp;hellip; it&#x27;s basically &lt;em&gt;part&lt;/em&gt; of the system).
The documentation for systemd-networkd &amp;mdash; and for systemd in general
&amp;mdash; is respectable, and it will work on most systems, given that all
noteworthy distributions apart from Gentoo have switched to systemd.&lt;/p&gt;
&lt;p&gt;And of course, it can set up bridges:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# /etc/systemd/network/qemu0.netdev&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[NetDev]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;qemu0&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Kind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;bridge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# /etc/systemd/network/qemu0.network&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[Match]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;qemu0&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;[Network]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;172.16.10.1/24&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;IPForward&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;yes&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;IPMasquerade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In order to allow QEMU to use &lt;code&gt;qemu0&lt;/code&gt; as the bridge, we will need to add an
entry into &lt;code&gt;/etc/qemu/bridge.conf&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;allow qemu0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The caveat &amp;mdash; and also the cool thing &amp;mdash; is on the last two lines in
the &lt;code&gt;.network&lt;/code&gt; file: sysctl&#x27;s IP packet forwarding settings
(&lt;code&gt;net.ipv4.ip_forward&lt;/code&gt;) are ignored and instead handled by systemd-network via
&lt;code&gt;net.ipv4.conf.&amp;lt;interface&amp;gt;.forwarding&lt;/code&gt;.  &lt;a href=&quot;https://bbs.archlinux.org/viewtopic.php?id=204195&quot;&gt;Took me some time figuring this
out.&lt;/a&gt; This also allows you to
remove that weird &lt;code&gt;/etc/sysctl.d/99-ip_forward.conf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Also, &lt;code&gt;IPMasquerade&lt;/code&gt; replaces iptables/nftables rules for masquerading in this simple case.&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl start systemd-networkd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;dnsmasq&quot;&gt;dnsmasq&lt;/h2&gt;
&lt;p&gt;The VM will be hooked up to the bridge generated above, and you&#x27;ll need to serve
it an IP address:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# /etc/dnsmasq.conf&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;dhcp-range&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;172.12.10.1,172.16.10.5,12h&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;dhcp-host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;52:54:00:12:34:56,172.16.10.2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We know the host&#x27;s IP address on the &lt;code&gt;qemu0&lt;/code&gt; interface, so we choose an
appropriate IP address range for DHCP; and we can anticipate the IP address it
will get, since we know the guest&#x27;s network interface MAC address (see below).&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl start dnsmasq
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;qemu&quot;&gt;QEMU&lt;/h2&gt;
&lt;p&gt;QEMU is really nice. If you&#x27;re used to point-and-click and it-just-werks, you
might have a tough time, but if you know what you want, it&#x27;s your best friend on
a desktop:&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;qemu-system-x86_64 -enable-kvm -cpu host -smp 4 \
                   -m 4096 \
                   -net nic,model=virtio,macaddr=52:54:00:12:34:56 \
                   -net bridge,br=qemu0 \
                   -drive file=disk.raw,if=virtio,format=raw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;-enable-kvm -cpu host -smp 4&lt;/code&gt; will use KVM (you know, to make the performance
bearable), use the host&#x27;s CPU model, and assign it 4 cores.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-m 4096&lt;/code&gt; will assign the VM 4&amp;thinsp;GiB of memory.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-net nic,model=virtio,macaddr=52:54:00:12:34:56&lt;/code&gt; will create a new Network
Interface Card through the &lt;a href=&quot;http://www.linux-kvm.org/page/Virtio&quot;&gt;virtio&lt;/a&gt;
interface and 52:54:00:12:34:56 as MAC address.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-net bridge,br=qemu0&lt;/code&gt; will attach said network interface to the network bridge
created above.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-drive file=disk.raw,if=virtio,format=raw&lt;/code&gt; will attach the raw disk image
&lt;code&gt;disk.raw&lt;/code&gt; as a virtual disk device through the virtio interface.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;You may want to script this.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;With the abovementioned configuration, you should now be able to request an IP
address via DHCP from the host, which will act as a gateway with NAT to the
guest inside the VM.&lt;/p&gt;
&lt;p&gt;Passing &lt;code&gt;-nographic -vnc :0&lt;/code&gt; to QEMU will make the VM run without graphical
output and a VNC attached to display :0. With an SSH server on the guest, you
now basically have a server, in a local network, on your machine.&lt;/p&gt;
&lt;p&gt;Yay!&lt;/p&gt;		</summary>
	</entry>

	<entry>
		<title>Dynamic Waltz</title>
		<link type="text/html"
		      href="http://ayekat.ch/blog/dynamic-waltz"
		      id="dynamic-waltz" />
		<id>dynamic-waltz</id>
		<updated>2015-09-05T23:13:00+0200</updated>
		<author>
			<name>ayekat</name>
			<email>takeya@bluewin.ch</email>
		</author>
		<summary type="html">
&lt;p&gt;After my PHP-driven, bloated-as-hell nightmare of an insecure website succumbed
to the evolution of sanity and died a long-awaited death, the choices laid out
before me were:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;to use a web development framework for &lt;em&gt;dynamically&lt;/em&gt; generated websites:
   generally I tend to suffer from the NIH syndrome and I tend to dislike
   frameworks for imposing some arbitrary software design on me (albeit
   sometimes well-done).  I also started to dislike the idea of having to launch
   a server-side process just for the sake of serving a single page.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;to use a web development framework for &lt;em&gt;statically&lt;/em&gt; generated websites:
   comment sections would either &lt;em&gt;still&lt;/em&gt; need to pass through some dynamic part
   (which renders the whole &quot;let&#x27;s go static!&quot; approach pointless) or be handled
   by some third party service like &lt;a href=&quot;http://disqus.org/&quot;&gt;disqus&lt;/a&gt; (which pretty
   much goes against my no-pointless-javascript-in-the-Web attitude &amp;mdash; I
   guess iframes have somehow gone out of fashion these days).&lt;br /&gt;
   Also, frameworks.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the end I came to a &quot;Fuck it All&quot; conclusion, abandoned website building for
good, and turned the ayekat.ch web experience into what resembles the current
&lt;a href=&quot;/about&quot;&gt;&lt;em&gt;about&lt;/em&gt;&lt;/a&gt; section. The time for expressing my narcism in pretty CSS
designs (and re-designs every 6 months) was spent on more useful things, and
life has gone on surprisingly well for the past year.&lt;/p&gt;
&lt;p&gt;However, after an attack of insanity, I decided to make a pretty website again.
Also I stumbled over&lt;/p&gt;
&lt;h2 id=&quot;python&quot;&gt;python&lt;/h2&gt;
&lt;p&gt;&amp;hellip; yes, I can already hear you whimper&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;oh no, here it goes again&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There truly &lt;em&gt;is&lt;/em&gt; some sort of hype around this language, and I kept away from it
for the mere reason that most people advocating it used arguments comparing it
with C. I may also just have hanged around in the &lt;a href=&quot;http://boards.4chan.org/g&quot;&gt;wrong part of the
web&lt;/a&gt;, though.&lt;/p&gt;
&lt;p&gt;Anyway, I started using it, and I concluded that&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;the language is very nice. It is definitively better than PHP (but that isn&#x27;t
  a huge accomplishment), but also trumps shell scripts when the task becomes a
  little more complex than a naive automation. It allows you to do many things
  without much fighting with the syntax, and provides lots of functionality
  straight out of the box without any need for installing additional OS
  packages; &lt;em&gt;however&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;its module system is pretty archaic. It looks like it might have worked well
  in the past, but now it seems more like some mechanisms that were hacked
  together to make the whole thing work. Also, all imports seem to be resolved
  at the working directory of the top level file, which pretty much throws
  modularity out of the window: using &lt;code&gt;if __name__ == &#x27;__main__&#x27;&lt;/code&gt; checks (which
  I find pretty handy for developing a certain component) becomes utterly
  useless if used in a module; also, at any given time a module down the line
  may break if it tries to import a file that happens to have the same name as a
  file in your own project.&lt;br /&gt;
  &amp;hellip; although, I have to admit that C&#x27;s &lt;code&gt;#include&lt;/code&gt; statements are not the
  pinnacle of intelligence either (and &lt;code&gt;&quot;&lt;/code&gt; and &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; may not always behave very
  intuitively).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But we are not forced to modularise our code (in the sense of python) for a
simple website, are we? Yet the nagging question remained: static or dynamic?
Rationality pulled me towards static website building (why would I need a
comment section, anyway? the last comment I got was an XSS attempt anyway), so&lt;/p&gt;
&lt;div class=&quot;codehilite&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ sloccount cgi

SLOC    Directory       SLOC-by-Language (Sorted)
366     cgi             python=366
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;CGI.&lt;/p&gt;
&lt;p&gt;Because. Fuck. It. I had fun. It&#x27;s my personal emotional link to the good old
days when the Web was not shit yet. It compiles markdown to HTML, handles
requests for static files (images, CSS, PDFs) and defines the HTTP header on its
own. If it wasn&#x27;t a launched process for each request, I&#x27;d be almost proud.&lt;/p&gt;
&lt;p&gt;Then again, it&#x27;s a bloody &lt;em&gt;website&lt;/em&gt;. Why are we even talking?&lt;/p&gt;
&lt;h2 id=&quot;waltz&quot;&gt;waltz&lt;/h2&gt;
&lt;p&gt;Named after both a dance and an actor coming from a particular country to the
East of mine, I am on a new server. We all are. &quot;We&quot; is a small group of people
who have all been very excited by the delightful, frequent and unannounced
server downtimes and I/O issues at our former host
&lt;a href=&quot;http://filemedia.de&quot;&gt;filemedia.de&lt;/a&gt;, such that we collectively decided to try
out something less exciting by default.&lt;/p&gt;
&lt;p&gt;Age, I guess. It&#x27;s not good for the heart.&lt;/p&gt;
&lt;p&gt;Since I&#x27;m not known for blogging (or if, then not for blogging particularly
well), the direction this blog will take is yet unclear. Perhaps I&#x27;ll tell you a
lot about exciting technical things I&#x27;ve recently discovered.  Perhaps I will
also just post failed attempts at poetry. Or jokes. I might tell you about the
weather in Switzerland, and how the political and economical relationship to the
European Union looks like to a totally uninformed cave dweller. I might just
post photographs of cats because I happen to have taken a shitton of them. Or
maybe just remain dead. Perhaps I&#x27;ll discover that, statistically, this place is
more dead than &lt;em&gt;Sun&lt;/em&gt;&#x27;s open source projects after &lt;a href=&quot;https://en.wikipedia.org/wiki/Sun_acquisition_by_Oracle&quot;&gt;Oracle
happened&lt;/a&gt;, and just
archive and remove the published nonsense. Some older posts may appear, perhaps
the future event prediction timeline based on dystopical books (and how the
World has changed ever since I posted that back in 2009), if I happen to find it
somewhere. Or maybe I&#x27;ll make a new one.&lt;/p&gt;
&lt;p&gt;Until then, I wish you a very nice rest of the summer.&lt;/p&gt;		</summary>
	</entry>
</feed>
