<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>oriole.systems</title>
	<link href="https://oriole.systems/atom.xml" rel="self" />
	<link href="https://oriole.systems" />
	<updated>2026-02-06T00:00:00Z</updated>
	<id>https://oriole.systems/</id>
	<entry>
		<id>https://oriole.systems/posts/weltschmerz-1.9.0.html#2026-02-06T00:00:00Z</id>
		<updated>2026-02-06T00:00:00Z</updated>
		<title>New features in weltschmerz 1.9.0</title>
		<author><name>Wolfgang Müller</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/weltschmerz-1.9.0" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>New features in weltschmerz 1.9.0</h1>
		<address>Wolfgang Müller</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2026-02-06">Friday, February  6, 2026</time>
	</header>
	<section class="post">
		<p>It&#8217;s been a very long time since the last post on updates for <a href="weltschmerz">weltschmerz</a>,
my terminal emulator. The <a href="weltschmerz-1.5.0">last post</a>, reporting on version 1.5.0, was
published around four years ago. With today&#8217;s release of version 1.9.0, it&#8217;s finally time
to catch up!</p>
<h2 id="drag-drop">Drag &#38; drop</h2>
<p>Commit
<a href="https://git.oriole.systems/weltschmerz/commit/?id=2fdbf96d6ff9828c946197e17d803f45510c2aa4">2fdbf96</a>,
released with <a href="https://git.oriole.systems/weltschmerz/tag/?h=1.6.0">version 1.6.0</a>, makes
weltschmerz act as a drop target for both text and URIs, making it possible to drag and
drop files, links, and ordinary text from other applications into the terminal. If files
are dropped, weltschmerz normalizes them for use in the shell so that you don&#8217;t need to
worry about escaping spaces or such.</p>
<h2 id="freebsd-compatibility">FreeBSD compatibility</h2>
<p><a href="https://git.oriole.systems/weltschmerz/tag/?h=1.7.0">Version 1.7.0</a> was mainly
a compatibility release that targeted the <a href="https://www.freebsd.org/">FreeBSD</a>
operating system. Most changes were related to the Makefile, which now uses
more compatible invocations of
<a href="https://man.freebsd.org/cgi/man.cgi?install(1)">install(1)</a> and drops usage of
<code>$&#60;</code>, which FreeBSD make only allows for suffix-transformation rules and not
explicit rules like GNU make does. See commit
<a href="https://git.oriole.systems/weltschmerz/commit/?id=623985d13002e99e2780655016281f790a25473c">623985d</a>
and commit
<a href="https://git.oriole.systems/weltschmerz/commit/?id=9e23bc6039b1bec0b431ce681cb769c665c9d42a">9e23bc6</a>.</p>
<p>In addition, since commit
<a href="https://git.oriole.systems/weltschmerz/commit/?id=d6090f7488b43346bcdd354d15363e3620375f43">d6090f7</a>,
weltschmerz now also considers <code>&#47;compat&#47;linux&#47;proc</code> when trying to determine the current
working directory (and OSC 7 support has been turned off). These changes make weltschmerz
work flawlessly out of the box with FreeBSD.</p>
<h2 id="configurable-resize-hints">Configurable resize hints</h2>
<p>The release of <a href="https://git.oriole.systems/weltschmerz/tag/?h=1.8.0">version 1.8.0</a> added
another small feature: configurable resize hints. For the longest time, weltschmerz had
defaulted to allowing size changes only in increments of the cell size. This ensured that
there was no padding around the terminal and that the window was always perfectly sized
for its contents. This is especially advantageous when using floating windows.</p>
<p>However, when weltschmerz was then placed into a tiled context, instead of having padding
on the terminal side, there were visible gaps between the actual windows. Sadly, there is
no perfect solution for this, but I felt that this behaviour should at least be
configurable.</p>
<h2 id="removing-deprecated-functionality">Removing deprecated functionality</h2>
<p>Over the years I have also removed a bunch of deprecated functionality from weltschmerz.</p>
<h3 id="spawn_async">spawn_async</h3>
<p>With the release of 1.6.0 came a change that was completely inconsequential for users but
quite important for me because it had been a cause for annoyance for basically the entire
existence of the program: the deprecation of <code>spawn_sync</code>. This function is used when
weltschmerz needs to spawn a process; the shell, for example.</p>
<p>The problem: upstream had deprecated <code>spawn_sync</code>, but the Vala bindings for its
replacement, <code>spawn_async</code>, were broken. The <a href="https://gitlab.gnome.org/GNOME/vala/-/issues/721">cause of the
breakage</a> had been known since 2018, but
the
<a href="https://gitlab.gnome.org/GNOME/vala/-/commit/f058e9e828f494ebf8d60cabff7999f219048623">fix</a>
was only committed in early 2022. I noticed only quite a bit later and fixed it with
commit
<a href="https://git.oriole.systems/weltschmerz/commit/?h=1.8.0&amp;id=a2ab0abdbb2d98cc9f458c03213bc22cdc77d6db">a2ab0ab</a>
in November of 2022.</p>
<h3 id="switching-weltschmerz-to-termprops">Switching weltschmerz to termprops</h3>
<p>With VTE 0.78 came the deprecation of a bunch of helper functions in favour of a
<a href="https://gitlab.gnome.org/GNOME/vte/-/issues/2125">termprop-based system</a>. weltschmerz
specifically was using the <code>get_window_title</code> and <code>get_current_directory</code> functions, which
<a href="https://gitlab.gnome.org/GNOME/vte/-/issues/2733">have been subsumed</a> by the
<code>XTERM_TITLE</code> and <code>CURRENT_DIRECTORY_URI</code> termprops. <a href="https://git.oriole.systems/weltschmerz/tag/?h=1.9.0">Version
1.9.0</a> now uses the termprops
directly.</p>
<p>This would usually be uninteresting for the end user, but the migration away from
<code>get_window_title</code> actually also fixes a bug that caused weltschmerz to segfault. It seems
that the Vala bindings for the <code>vte.window_title</code> property are buggy and indicate that the
property is a non-nullable string when in reality <code>vte.window_title</code> is internally
translated to a call to <code>get_window_title</code>, which returns a nullable string. weltschmerz
assumed <code>vte.window_title</code> was correct and never checked for null.</p>
<p>This is not an issue unless you can force the window title to be null. My
<a href="https://ahti.space/~nortti">partner</a> found a clever way to do so: by passing an overlong
title to the OSC mechanism, a <a href="https://gitlab.gnome.org/GNOME/vte/-/blob/5613991f49465d02f25ad679a6bc2f0f805ac9cd/src/vteseq.cc#L7933">code
path</a>
in VTE is triggered that leaves the window title as null. Running the following in
versions previous to 1.9.0 would reliably crash weltschmerz:</p>
<pre><code>python -c &#39;print(f\&#39;\\033]0;{"."*1025}\\033\\\\\&#39;)&#39;
</code></pre>
<h2 id="makefile-and-meson.build-improvements">Makefile and meson.build improvements</h2>
<p>My partner also contributed
<a href="https://git.oriole.systems/weltschmerz/commit/?id=d96f9852b962558e8297bd8443c84457b85cf1f3">two</a>
<a href="https://git.oriole.systems/weltschmerz/commit/?id=9d3e7871df919438e594d6a1167a76bda4bfadc8">more</a>
improvements to the Makefile, which now standardizes on one way of doing
variable expansions and allows passing <code>CFLAGS</code> to the compiler. In addition, I
finally <a href="https://git.oriole.systems/weltschmerz/commit/?id=c850770b0c37586c9d677ab20faa1710b14f7c1e">made meson
use</a>
the <code>locale</code> keyword for <code>install_man</code> instead of installing the translated
manual pages manually.</p>
<h2 id="bold-is-bright-and-ipv6-addresses">&#8220;bold is bright&#8221; and IPv6 addresses</h2>
<p>A <a href="https://git.oriole.systems/weltschmerz/commit/?id=aa1f819a6ae9fcb15db0fbed80b01f8693735448">new
feature</a>
in 1.9.0 is the <code>bold-is-bright</code> setting, which controls whether bold characters are also
automatically drawn in bright colors, like some older terminal emulators do. This change
had been sitting around uncommitted for a very long time, and I finally decided to include
it.</p>
<p>And last but not least, my partner
<a href="https://git.oriole.systems/weltschmerz/commit/?id=daba1fdd7f13295169376cc01fc862a5098183a4">taught</a>
the URL matching mechanism about bare IPv6 addresses, which are now clickable.</p>
<hr/>
<p>That&#8217;s it for this update. See
<a href="https://git.oriole.systems/weltschmerz/tree/NEWS"><code>NEWS</code></a> for the full set of
changes, and
<a href="https://git.oriole.systems/weltschmerz/log/?qt=range&amp;q=1.5.0..1.9.0"><code>1.5.0..1.9.0</code></a>
for all relevant commits. Download weltschmerz on <a href="weltschmerz">its project page</a>.</p>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/hircine.html#2024-03-09T00:00:00Z</id>
		<updated>2024-03-09T00:00:00Z</updated>
		<title>hircine - A web-based comic organizer</title>
		<author><name>Wolfgang Müller</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/hircine" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>hircine - A web-based comic organizer</h1>
		<address>Wolfgang Müller</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2024-03-09">Saturday, March  9, 2024</time>
	</header>
	<section class="post">
		<h2 id="synopsis">Synopsis</h2>
<p>hircine is a web application built to organize large collections of comics and
manga. It imports image files from <em>ZIP</em> archives, supports a wide range of
metadata, comes with a powerful filtering system, and keeps its own object
store of processed image files for easy and fast access via the browser.</p>
<figure>
    <img class="round" width="90%" src="img/hircine-edit.jpg" alt="A picture of the edit interface of hircine"/>
    <figcaption>Editing a comic in hircine</figcaption>
</figure>
<p>Archives are never modified by the program, making it an ideal choice for the
astute collector. Comics may be read in the minimal built-in reader. Metadata
import via scrapers is also supported.</p>
<h2 id="resources">Resources</h2>
<ul>
<li><a href="https://hircine.oriole.systems">Homepage</a></li>
<li><a href="https://git.oriole.systems/hircine">Git repository</a></li>
</ul>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/weltschmerz-1.5.0.html#2021-11-27T00:00:00Z</id>
		<updated>2021-11-27T00:00:00Z</updated>
		<title>New features in weltschmerz 1.5.0</title>
		<author><name>Wolfgang Müller</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/weltschmerz-1.5.0" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>New features in weltschmerz 1.5.0</h1>
		<address>Wolfgang Müller</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2021-11-27">Saturday, November 27, 2021</time>
	</header>
	<section class="post">
		<p>Today, a bit more than 4 months since the last update for
<a href="weltschmerz">weltschmerz</a>, I&#8217;m happy to announce 1.5.0, bringing new and
exciting features to the terminal emulator. Just like with
<a href="weltschmerz-1.4.0">1.4.0</a> most of them were designed and implemented by
<a href="https://ahti.space/%7Enortti/">nortti</a>. Thanks a lot!</p>
<p>Head over to the <a href="weltschmerz">project page</a> to download the new version right
away, or read on to take a look at noteworthy changes.</p>
<h2 id="open-with-">Open with &#8230;</h2>
<figure>
    <img src="img/weltschmerz-open-with.png" alt="The 'Open     with ...' feature in weltschmerz 1.5.0"/>
    <figcaption>The 'Open with ...' feature in weltschmerz 1.5.0</figcaption>
</figure>
<p>The main new feature in weltschmerz 1.5.0, added in
<a href="https://git.oriole.systems/weltschmerz/commit/?id=a9706ec27edc0aef03f72daba28647aca1c42070">a9706ec</a>,
is the ability to add custom &#8216;Open with &#8230;&#8217; handlers for the URI context menu.
These are added to the new <code>open-with</code> section in the configuration file. For
example, the handlers in the picture above are defined like so:</p>
<pre><code>[open-with]
mpv = mpv --force-window=immediate --really-quiet %
ff-priv = firefox-bin --private-window %
</code></pre>
<p>Any occurrence of the <code>%</code> character will be replaced by the URI before
weltschmerz launches the given program.</p>
<h2 id="changes-to-osc-7-handling">Changes to OSC 7 handling</h2>
<p>To increase compatibility with systems and setups that do not understand or emit
OSC 7 escapes, weltschmerz now falls back to obtaining its current directory
from the <code>procfs</code> subsystem. Additionally, a new option &#8216;prefer-osc7&#8217; has been
introduced that controls whether OSC 7 should be preferred at all. See
<a href="https://git.oriole.systems/weltschmerz/commit/?id=71388f94c694a36b0ac360b34f09d7c16a51f803">71388f9</a>
and
<a href="https://git.oriole.systems/weltschmerz/commit/?id=6f0399481b215817960b5cf36ee03a658a2d9b89">6f03994</a>.</p>
<h2 id="small-bugfixes-and-more-internationalization">Small bugfixes and more internationalization</h2>
<p>When matching URLs, weltschmerz now ignores punctuation at the end. This should
make it easier to open up URLs in terminal-bound chat applications. Finally,
version 1.5.0 contains a full Finnish translation of the manual.</p>
<p>That&#8217;s it for this update. See
<a href="https://git.oriole.systems/weltschmerz/tree/NEWS"><code>NEWS</code></a> for the full set of
changes, and
<a href="https://git.oriole.systems/weltschmerz/log/?qt=range&amp;q=1.4.1..1.5.0"><code>1.4.1..1.5.0</code></a>
for all relevant commits.</p>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/ywalk-when-you-can-ride.html#2021-11-13T00:00:00Z</id>
		<updated>2021-11-13T00:00:00Z</updated>
		<title>Why walk when you can ride?</title>
		<author><name>Wolfgang Müller</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/ywalk-when-you-can-ride" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>Why walk when you can ride?</h1>
		<address>Wolfgang Müller</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2021-11-13">Saturday, November 13, 2021</time>
	</header>
	<section class="post">
		<p>Do you ever find yourself in the middle of nowhere, in the northern Ashlands of
Vvardenfell, and suddenly think: &#8220;Damn, what&#8217;s my fastest way to Tel Branora
from here?  I <em>still</em> have to deliver Mistress Therana&#8217;s skirt!"</p>
<figure>
    <img class="round" width="90%" src="img/morrowind-ashlands.jpg" alt="A screenshot of Morrowind in the dark and dusty Ashlands, with two Netch in the vicinity."/>
    <figcaption>Somewhere in the Ashlands of Vvardenfell.</figcaption>
</figure>
<p>Depending on the character you play, the answer to this question can vary
wildly. For one you could try to reach Khuul and rely on regular fast travel
services like the Silt Strider and the Guild Guide, but maybe you&#8217;re playing a
particularly stuck-up Telvanni and would like to avoid interacting with the
Imperial rats of the Mages Guild.  Valenvaryon or Falasmaryon is close, and
you have picked up all Propylon indices already, so that is a very good
alternative. Or maybe you&#8217;re feeling the need for some fresh sea air and would
like to sail all around Vvardenfell.</p>
<p>Morrowind&#8217;s fast travel system is extensive and complex, so figuring out the
fastest routes from any one location to another is not an easy task. Even worse,
some of the best travel options (the intervention spells that teleport you to
the next Temple or Imperial Shrine) are hard to know when to use optimally.</p>
<figure>
    <img class="round" width="90%" src="img/morrowind-routes.png" alt="A map of all travel routes on Vvardenfell"/>
    <figcaption>A map of all travel routes on Vvardenfell, courtesy of the
    <a href="https://en.uesp.net/wiki/Morrowind:Transport">UESP</a>.
    </figcaption>
</figure>
<p>Morrowind veterans probably have a very good idea of the intricacies of
Vvardenfell&#8217;s travel routes and can figure out the above problem in seconds, but
maybe you&#8217;ve just started the game and feel a bit overwhelmed, or you just
installed <a href="https://www.tamriel-rebuilt.org/">Tamriel Rebuilt</a> and have to
suddenly juggle a multitude of new routes.</p>
<p>The latter is true for me, so I ended up writing <strong>ywalk</strong>, a command-line tool
that figures out the fastest route between a set of places in Morrowind. It can
consider certain limitations (Telvanni disdain for the Mages Guild perhaps, or
having to escort yet another lost pilgrim<sup id="fnref1"><a href="#fn1" rel="footnote">1</a></sup> who can&#8217;t teleport) and give you
an optimized route.</p>
<p>Connections between places are parsed from a simple text file with tab-separated
values. A connection definition is simply the origin, the destination, the mode
of travel, and how long the journey takes in in-game hours:</p>
<pre><code>Origin       Destination     Mode            Time
Seyda Neen   Balmora         Silt Strider    3
Vivec        Hla Oad         Boat            5
Balmora      Seyda Neen      Silt Strider    3
Balmora      Vivec           Guild Guide     0
</code></pre>
<p>Since a very small number of routes are one-way only<sup id="fnref2"><a href="#fn2" rel="footnote">2</a></sup>, I decided to keep
things simple and require every route to be specified explicitly. As you can see
above, the route between Seyda Neen and Balmora is specified twice, once for
each direction.</p>
<p>To collect these routes, I used the indispensable <a href="https://en.uesp.net/wiki/Main_Page">Unofficial Elder Scrolls
Pages</a> and my own copy of the game running
on <a href="https://openmw.org">OpenMW</a>. I made each catalogued journey myself at least
once, just to be sure.</p>
<p><strong>ywalk</strong> ships with definitions for the entire fast-travel network for
the Game of the Year version of Morrowind (meaning the <em>Master Index</em> plugin is
enabled by default). For Tamriel Rebuilt it includes definitions that are active
with <em>TR_Travels</em>. For now, only places with fast-travel options are considered.
An exception to this rule are available player homes in Vvardenfell, for use
with the Recall option. If you are curious, check out
<a href="https://git.oriole.systems/ywalk/tree/data/goty.tsv">goty.tsv</a> and
<a href="https://git.oriole.systems/ywalk/tree/data/tr-travels.tsv">tr-travels.tsv</a>.</p>
<h2 id="installation">Installation</h2>
<p><strong>ywalk</strong> is written in Python and is supposed to be installed per user. The
data files and manual need to be installed separately because Python packaging
is a nightmare. For a full install as a user, get the sources from the
<a href="https://git.oriole.systems/ywalk">git repository</a> and run the following
commands:</p>
<pre><code>$ python setup.py install --user
$ make install
</code></pre>
<p>This will install <strong>ywalk</strong> to <code>~&#47;.local&#47;bin</code>, the data files to their canonical
path <code>~&#47;.local&#47;share&#47;ywalk</code>, and the manual to <code>~&#47;.local&#47;share&#47;man&#47;</code>.</p>
<h2 id="usage">Usage</h2>
<p><strong>ywalk</strong> offers a simple command-line interface. Invoke it with the list of
places you want to travel through or to, and it will print a route if it can. By
default it allows all modes of travel, but you can allow only specific modes
with <code>-m</code>, or restrict them with <code>-M</code>. For detailed usage information, see
<a href="https://git.oriole.systems/ywalk/about/ywalk.1">the manual</a>.</p>
<figure>
    <img class="round" width="90%" src="img/morrowind-khuul.jpg" alt="A screenshot of Morrowind in the port of Khuul."/>
    <figcaption>Can't wait to get out of this place.</figcaption>
</figure>
<p>Let&#8217;s see it in action! Consider a regular character that has no problem with
land-based transport and can use the Mages Guild relays, but has no way of
invoking Almsivi or Divine Intervention and never even heard of a Propylon
chamber. In that case, we&#8217;d head over to Khuul and then start our journey:</p>
<pre><code>$ ywalk -M almsivi,divine,propylon Khuul &#39;Tel Branora&#39;
Start in Khuul
 then take the Silt Strider to Ald&#39;ruhn (5 hours)
 then take the Guild Guide to Vivec
 then take the Boat to Tel Branora (5 hours)
Arrive in Tel Branora after 10 hours.
</code></pre>
<figure>
    <img class="round" width="90%" src="img/morrowind-propylon.jpg" alt="A screenshot of Morrowind in Falasmaryon's Propylon chamber."/>
    <figcaption>The homely hum of crystals.</figcaption>
</figure>
<p>Now for the stuck-up Telvanni that raided every single Dunmer stronghold and
completed their Propylon Index collection. We start in Falasmaryon in that case
and avoid Mages Guild relays like the Corprus disease:</p>
<pre><code>$ ywalk -M guide Falasmaryon &#39;Tel Branora&#39;
Start in Falasmaryon
 then travel by Propylon to Caldera
 then travel by Propylon to Telasero
 then invoke Almsivi Intervention to Molag Mar
 then take the Boat to Tel Branora (2 hours)
Arrive in Tel Branora after 2 hours.
</code></pre>
<figure>
    <img class="round" width="90%" src="img/morrowind-swamp.jpg" alt="A screenshot of Morrowind in the eastern swamp."/>
    <figcaption>On the way to Hla Oad.</figcaption>
</figure>
<p>And finally for our sailor, again from Khuul:</p>
<pre><code>$ ywalk -m boat Khuul &#39;Tel Branora&#39;
Start in Khuul
 then take the Boat to Gnaar Mok (7 hours)
 then take the Boat to Hla Oad (4 hours)
 then take the Boat to Vivec (5 hours)
 then take the Boat to Tel Branora (5 hours)
Arrive in Tel Branora after 21 hours.
</code></pre>
<figure>
    <img class="round" width="90%" src="img/morrowind-mora.jpg" alt="A screenshot of Morrowind in the port of Sadrith Mora."/>
    <figcaption>Arriving in Sadrith Mora.</figcaption>
</figure>
<p>Let&#8217;s say our character absolutely hates the swamp. We can make sure to avoid
Gnaar Mok with <code>-P</code>. This will lead to a journey around the eastern parts of
Vvardenfell:</p>
<pre><code>$ ywalk -m boat -P &#39;Gnaar Mok&#39; Khuul &#39;Tel Branora&#39;
Start in Khuul
 then take the Boat to Dagon Fel (8 hours)
 then take the Boat to Sadrith Mora (10 hours)
 then take the Boat to Tel Branora (8 hours)
Arrive in Tel Branora after 26 hours.
</code></pre>
<p>By default, <strong>ywalk</strong> optimizes for least travel time. It recommends using
teleportation over regular Silt Strider or boat services even though using the
latter would usually decrease the number of hops needed. If you&#8217;re interested
instead in a route with the least number of hops, you can change the weighting
method for the path-finding algorithm with <code>-w</code>.</p>
<figure>
    <img class="round" width="90%" src="img/morrowind-branora.jpg" alt="A screenshot of Morrowind looking at Tel Branora."/>
    <figcaption>Our destination, with a slight hint of rotting Kwama Eggs.</figcaption>
</figure>
<p>I hope you&#8217;ll have fun trying this out. Feel free to send any improvements
along!</p>
<div class="footnotes">
<hr/>
<ol>

<li id="fn1">
<p>Always better than a naked Nord, though. They probably all deserve it.&#160;<a href="#fnref1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn2">
<p>Vos to Sadrith Mora, for example. Curiously, Tamriel Rebuilt removes this
connection entirely.&#160;<a href="#fnref2" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/weltschmerz-1.4.0.html#2021-07-03T00:00:00Z</id>
		<updated>2021-07-03T00:00:00Z</updated>
		<title>New features in weltschmerz 1.4.0</title>
		<author><name>Wolfgang Müller</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/weltschmerz-1.4.0" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>New features in weltschmerz 1.4.0</h1>
		<address>Wolfgang Müller</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2021-07-03">Saturday, July  3, 2021</time>
	</header>
	<section class="post">
		<p>After more than a year of hibernation, the last two weeks have seen a greatly
increased amount of work dedicated to <a href="weltschmerz">weltschmerz</a>. The initial
impetus to pick up on development came after a whole bunch of contributions and
bug reports from a new user, <a href="https://ahti.space/~nortti/">nortti</a>. Thanks a lot
for those and for jump-starting further work on the project!</p>
<p>Read on to take a look at noteworthy changes and all the new features, or head
on over to the <a href="weltschmerz">project page</a> to get 1.4.0 right away.</p>
<h2 id="controlling-cursor-blinking">Controlling cursor blinking</h2>
<p>The first feature nortti
<a href="https://git.oriole.systems/weltschmerz/commit/?id=0774a46257bdc6daa1c6a1c3485d75bd07ef849c">proposed and implemented</a>
is the new <strong><code>cursor_blink</code></strong> setting. Modifying cursor blink behaviour was not
possible before; weltschmerz simply relied on GTK&#8217;s default setting of <code>SYSTEM</code>.
This falls back to whatever is set for
<a href="https://developer.gnome.org/gtk3/stable/GtkSettings.html#GtkSettings--gtk-cursor-blink"><code>gtk-cursor-blink</code></a>
which in almost all cases<sup id="fnref1"><a href="#fn1" rel="footnote">1</a></sup> will be <code>TRUE</code>.</p>
<p>Now users may enable or disable cursor blinking within weltschmerz. The default
value for <code>cursor_blink</code> is <code>SYSTEM</code> which means that there is nothing to do if
the current behaviour already works for you.</p>
<h2 id="open-terminal">Open terminal</h2>
<figure>
    <img src="img/weltschmerz-open-terminal.png" alt="The 'Open     terminal' feature in weltschmerz 1.4.0"/>
    <figcaption>The 'Open terminal' feature in weltschmerz 1.4.0</figcaption>
</figure>
<p>The
<a href="https://git.oriole.systems/weltschmerz/commit/?id=b70083a5f4404e2422ff0a0aadd023a661164fae">second contribution</a>
they made is the incredibly handy <strong>Open terminal</strong> feature. Similar to
<a href="new-features-in-weltschmerz#Open%20directory"><strong>Open directory</strong></a>,
this feature leverages <code>OSC 7</code> support<sup id="fnref2"><a href="#fn2" rel="footnote">2</a></sup> to open a new instance of weltschmerz in
the current directory. This is bound to <code>Ctrl+Shift+T</code> for quick and easy access.</p>
<h2 id="url-copying">URL copying</h2>
<p>Up until now, weltschmerz only populated the <code>CLIPBOARD</code> selection when copying
URLs to the clipboard via the <strong>Copy URL</strong> context menu entry. Since all other
copy operations set the <code>PRIMARY</code> selection as well,
<a href="https://git.oriole.systems/weltschmerz/commit/?id=b497a49d8bd2a345dd30a9f55dc4976560df157f">1.4.0 changes this</a>.
Now, <strong>Copy URL</strong> populates both <code>CLIPBOARD</code> and <code>PRIMARY</code>, making weltschmerz
behave like other GTK and QT apps<sup id="fnref3"><a href="#fn3" rel="footnote">3</a></sup>.</p>
<h2 id="a-handful-of-bugfixes">A handful of bugfixes</h2>
<p>weltschmerz now has a minimum size of 28 × 3 cells, reports its window geometry
correctly at all times, and always draws the scrollbar if the user or
distribution turns overlay scrolling off. The latter may seem inconsequential,
but the journey to the fix was a very long and arduous one.</p>
<p>I&#8217;ve written about these changes extensively in the relevant commit messages
<a href="https://git.oriole.systems/weltschmerz/commit/?id=ff708b2251ffdc209f23a2275c721532dff2fddb">here</a>,
<a href="https://git.oriole.systems/weltschmerz/commit/?id=89f8571cbcf48b7810c7027faf26ee5cf4b968b1">here</a>,
and
<a href="https://git.oriole.systems/weltschmerz/commit/?id=ff27c3da1266df519aa15d95cfc32ad9d0d7b5e5">here</a>.
Definitely check those out if you are a fan of weird issues and possibly even
weirder workarounds.</p>
<h2 id="internationalization">Internationalization</h2>
<p>Finally, I&#8217;m glad to announce that weltschmerz is now translatable! The 1.4.0
release comes with a German and a Finnish translation of the program, excluding
the manual (a bigger effort, and I did not want to drag 1.4.0 out even
further<sup id="fnref4"><a href="#fn4" rel="footnote">4</a></sup>).</p>
<p>This introduces <a href="https://www.gnu.org/software/gettext">gettext</a> as new
dependency. In almost all cases it should already be installed since it is the
de-facto standard for translations in GNOME and GNU-adjacent projects.</p>
<p>If your language is missing and you want to contribute, have a look at the
<a href="https://git.oriole.systems/weltschmerz/tree/TRANSLATE#n1"><code>TRANSLATE</code></a> file in the
project repository.</p>
<h2 id="closing-thanks">Closing &#38; Thanks</h2>
<p>That&#8217;s it for this release. Thanks a lot again to nortti for all their
contributions and for providing valuable feedback throughout the entire 1.4.0
development process!</p>
<p>See <a href="https://git.oriole.systems/weltschmerz/tree/NEWS"><code>NEWS</code></a> for the full set
of changes, and
<a href="https://git.oriole.systems/weltschmerz/log/?qt=range&amp;q=1.3.0..1.4.0"><code>1.3.0..1.4.0</code></a>
for all relevant commits.</p>
<div class="footnotes">
<hr/>
<ol>

<li id="fn1">
<p>I&#8217;d love to hear from you if your distribution disables blinking cursors
by default.&#160;<a href="#fnref1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn2">
<p>This particular escape is
<a href="https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/20">not yet fully specified</a>.&#160;<a href="#fnref2" rev="footnote">&#8617;</a></p>
</li>

<li id="fn3">
<p>See
<a href="https://specifications.freedesktop.org/clipboards-spec/clipboards-latest.txt">here</a>
for freedesktop&#8217;s consensus on how clipboards should work in X11.&#160;<a href="#fnref3" rev="footnote">&#8617;</a></p>
</li>

<li id="fn4">
<p>The newly released
<a href="https://git.oriole.systems/weltschmerz/tag/?h=1.4.1">version 1.4.1</a>
now contains a full translation of the manual
<a href="https://git.oriole.systems/weltschmerz/about/weltschmerz.de.1">into German</a>.&#160;<a href="#fnref4" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/zunzuncito.html#2021-06-12T00:00:00Z</id>
		<updated>2021-06-12T00:00:00Z</updated>
		<title>Introducing zunzuncito, a microblog</title>
		<author><name>Wolfgang Müller</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/zunzuncito" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>Introducing zunzuncito, a microblog</h1>
		<address>Wolfgang Müller</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2021-06-12">Saturday, June 12, 2021</time>
	</header>
	<section class="post">
		<p>Writing things is hard. So hard, in fact, that the dearth of posts here is not
for lack of ideas or things to talk about, but instead for limits on how I want
to spend my time. There are plenty of things I&#8217;d love to write longer posts
about, but doing that takes at least three to four days if not an entire week.
True, this is partly down to obsessing over documenting everything and my need
to get every detail right, but in a sense I also cherish that part of me, so I
don&#8217;t want to outright suppress it.</p>
<p>Clearly not everything needs that kind of treatment, however. Some things can be
said with brevity and perhaps do not deserve an in-depth look at that particular
moment. But since I&#8217;ve long taken this site as a space to write longer-form and
truly developed articles, breaking with that notion here seems unwise and
inconsistent - this place is just not built for short posts. Still, I have long
felt the need for a platform that is meant for that kind of content.</p>
<h2 id="platforms-aplenty-all-broken">Platforms aplenty, all broken</h2>
<p>Modern microblog platforms like Twitter seem to mostly take care of that need
for other people. I&#8217;ve tried a few times now to keep a Twitter presence going,
but never really felt a deep connection to it. Attention-grabbing design choices
always put me off of it after a few months. It wasn&#8217;t really a space I felt
comfortable in, I felt like I had to market myself to others.</p>
<p>Mastodon is the same by virtue of being designed like Twitter, a decision I
understand on a technical level<sup id="fnref1"><a href="#fn1" rel="footnote">1</a></sup> but one that I deeply dislike on an ethical
one. I do not think that Twitter&#8217;s problems<sup id="fnref2"><a href="#fn2" rel="footnote">2</a></sup> will be solved by federation
alone. There will need to be changes to the core experience and a rethink on how
social networks affect people. Neither is a space for me.</p>
<h2 id="a-humming-microblog">A humming microblog</h2>
<p>Instead, I decided to build my own. A place for all the smaller things
that I would still like to share with the world. A place that I have full
control over and can cultivate by myself.</p>
<p>Check zunzuncito out <a href="https://zunzuncito.oriole.systems">over here</a>. It&#8217;s
named<sup id="fnref3"><a href="#fn3" rel="footnote">3</a></sup> after the <a href="https://en.wikipedia.org/wiki/Bee_hummingbird">Bee
hummingbird</a>, the world&#8217;s
smallest bird.</p>
<p>zunzuncito runs on <a href="https://www.getzola.org/">Zola</a>, a static site engine.
Initially I wanted to use the tried and true combo of
<a href="https://kristaps.bsd.lv/lowdown/">lowdown</a> and
<a href="https://kristaps.bsd.lv/sblg/">sblg</a>, but there were some annoying limitations
like the lack of easy pagination. Make no mistake, however, using Zola still
results in a number of limitations that make this a bespoke solution at best.</p>
<p>I expect to be iterating on this design as I use it. If you want to follow
along, check out the <a href="https://git.oriole.systems/zunzuncito">git repository</a>.</p>
<div class="footnotes">
<hr/>
<ol>

<li id="fn1">
<p>It arguably also was the easiest thing to do and an obvious marketing
decision. The platform wouldn&#8217;t have grown the same had it provided a
completely different and new experience.&#160;<a href="#fnref1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn2">
<p>Really these are no longer <em>Twitter&#8217;s</em> problems, but rather problems on
the societal level, as people have internalized the sort of culture and
context shared on these types of platforms.&#160;<a href="#fnref2" rev="footnote">&#8617;</a></p>
</li>

<li id="fn3">
<p>Spanish <a href="https://es.wiktionary.org/wiki/zunz%C3%BAn">zunzún</a> (an
onomatopoeia) +
<a href="https://es.wiktionary.org/wiki/-cito#Etimolog%C3%ADa_2">-cito</a> (a diminutive
suffix)&#160;<a href="#fnref3" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/signify-cgit.html#2021-05-16T00:00:00Z</id>
		<updated>2021-05-16T00:00:00Z</updated>
		<title>Hosting signify signatures on cgit</title>
		<author><name>Wolfgang Müller</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/signify-cgit" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>Hosting signify signatures on cgit</h1>
		<address>Wolfgang Müller</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2021-05-16">Sunday, May 16, 2021</time>
	</header>
	<section class="post">
		<p>A seemingly overlooked<sup id="fnref1"><a href="#fn1" rel="footnote">1</a></sup> feature of <a href="https://git.zx2c4.com/cgit/about/">cgit</a>
is its ability to host detached signatures of the snapshots it generates. Add a
signature of a snapshot to the Git repository, and cgit will automatically
offer it right next to the corresponding snapshot:</p>
<figure>
    <img class="round" src="img/cgit-signatures.png" width="60%" alt="Detached signatures     linked alongside compressed tarballs"/>
    <figcaption>Detached signatures in their natural habitat</figcaption>
</figure>
<p>But how does cgit know which signature corresponds to which snapshot, and how
are signatures stored in the Git repository itself? Enter
<a href="https://git-scm.com/docs/git-notes"><code>git-notes(1)</code></a>, another feature that is
probably overlooked. Intended to facilitate adding additional notes to commit
messages without changing the commit itself, <code>git-notes(1)</code> lends itself well to
attaching textual data to any Git object such as a commit or a tag.</p>
<h2 id="duly-noted">Duly noted</h2>
<p>Internally, Git stores the contents of a note as a
<a href="https://git-scm.com/book/en/v2/Git-Internals-Git-Objects">blob</a>, meaning it is
saved to the object database and referred to by its hash. But Git must also
store which commit a note belongs to. For this it uses a
<a href="https://git-scm.com/book/en/v2/Git-Internals-Git-Objects#_tree_objects">tree</a>.
A tree is Git&#8217;s way of encoding a directory: it contains a list of paths, and
maps them to blobs (files) or other trees (subdirectories). We can look at those
trees using <a href="https://git-scm.com/docs/git-cat-file"><code>git-cat-file(1)</code></a>. For
example, the following is the tree for <a href="https://git.oriole.systems/quarg/commit/?id=7cd07362c4c13bfd01afa85a4666c491a020f330">this
commit</a>:</p>
<pre><code>$ git cat-file -p 6a81213f2e88a33835f2fb94015bda5dc04a397c
100644 blob 3feb78adc667d7bf4ad2cec4fb780b29ced25302    .gitignore
100644 blob 2149bd82c51e65c34d8aee87f96c4f1c1af8f6c1    LICENSE
100644 blob d397eaf5a75d0d30c4d9d2ffcd1007b44acc842a    quarg.1
040000 tree eee3c892c769bad3b7d883f0a162500406f67c3b    quarg
100644 blob 1a861ec51a39cbefa0f5027995c358af2224ebbb    setup.py
</code></pre>
<p>The tree object that links notes, however, uses the commit blob itself as a
&#8220;path&#8221;. In the following tree (for
<a href="https://git.oriole.systems/quarg/commit/?h=refs/notes/signatures/tar.gz&amp;id=f12709c0843a89b5be37fe499b9928a8c11cbcd9">this</a>
commit) the note blob is on the left side whilst the commit blob (&#8220;path&#8221;) is on
the right:</p>
<pre><code>$ git cat-file -p 3a5fd837cae7e478b9a230f6c301c93efda7c1e2
100644 blob 5c7ec832f83342aa460bb27b0b75e12695a98a53    43c9fb13e063cebfd08e741b67b9ec2317aed4b9
</code></pre>
<p>Let&#8217;s see which commit that is:</p>
<pre><code>$ git show -s --pretty=oneline 43c9fb13e063cebfd08e741b67b9ec2317aed4b9
43c9fb13e063cebfd08e741b67b9ec2317aed4b9 (tag: 0.1.2) Prepare for release of 0.1.2
</code></pre>
<p>The note tree is then linked in a normal <a href="https://git.oriole.systems/quarg/commit/?h=refs/notes/signatures/tar.gz&amp;id=f12709c0843a89b5be37fe499b9928a8c11cbcd9">commit
object</a>
that a special
<a href="https://git-scm.com/book/en/v2/Git-Internals-Git-References">ref</a> points to. By
default, that is <code>refs&#47;notes&#47;commits</code>. One may think of that ref as pointing to
a special branch holding all the information on notes &#8220;published&#8221; to that
branch.</p>
<p>Instead of that default location, cgit looks in <code>refs&#47;notes&#47;signatures&#47;&#60;format&#62;</code>
for any signatures. For example, signatures for a gzip-compressed tarball are
stored in <code>refs&#47;notes&#47;signatures&#47;tar.gz</code>. If cgit finds a signature attached to
a tag and can generate a matching tarball, it will automatically link the
contents of the note blob as a <code>.asc</code><sup id="fnref2"><a href="#fn2" rel="footnote">2</a></sup> file.</p>
<h2 id="snap-shot">Snap, shot!</h2>
<p>With the Git internals out of the way, let&#8217;s break down the process of hosting a
signature on cgit.</p>
<p>Before we get to the actual signing process, a quick but important detour. Since
we will be publishing signatures of the snapshot itself, we have to make sure
that its contents are stable. Furthermore, we have to be absolutely certain that
cgit is generating the same snapshot that we used when we made the signature.</p>
<p>We could of course tag a release, download the snapshot via cgit ourselves,
verify that it contains the correct files, and then sign it, but that seems
backwards; we just blindly trusted the cgit machinery to give us what we expect.
What if our cgit host had been compromised? We should make sure that we can
create the same snapshot locally.</p>
<p>Thankfully, this is a trivial thing to do. We can use
<a href="https://git-scm.com/docs/git-archive"><code>git-archive(1)</code></a> to create a stable
archive<sup id="fnref3"><a href="#fn3" rel="footnote">3</a></sup> from any tag. This is, in fact, also what cgit does internally. By
default, <code>git-archive(1)</code> does not prefix the files in the archive with the
project title and tag, so to make sure that we get a sane<sup id="fnref4"><a href="#fn4" rel="footnote">4</a></sup> tarball, we have to
pass the right prefix &#8211; just as cgit does:</p>
<pre><code>$ git archive --prefix=quarg-0.1.2&#47; -o quarg-0.1.2.tar.gz -- 0.1.2
</code></pre>
<p>The resulting file should be exactly what you get when you download a snapshot
for the same version from cgit.</p>
<h2 id="signed-sealed-delivered">Signed, Sealed, Delivered</h2>
<p>Now that we have the actual snapshot, we can get to signing it.</p>
<p>The example in <code>cgitrc(5)</code> uses the dreaded <code>gpg(1)</code> interface to generate a
signature, but since notes are just textual objects, we can use any utility that
generates a signature in text form. I will be using OpenBSD&#8217;s
<a href="https://www.openbsd.org/papers/bsdcan-signify.html">signify</a>, a tool I have
been recommending for a long time given its simplicity and ease of use<sup id="fnref5"><a href="#fn5" rel="footnote">5</a></sup>.</p>
<p>To make things more straightforward and give people who do not want to use
signify a way of verifying the integrity of the download, we do not sign the
snapshot itself, but its checksum. Conveniently, signify supports verifying the
signature and checksum in one invocation<sup id="fnref6"><a href="#fn6" rel="footnote">6</a></sup>.</p>
<p>Since signify expects BSD-style checksums from OpenBSD&#8217;s
<a href="https://man.openbsd.org/sha256"><code>sha256(1)</code></a>, we have to make sure to pass the
<code>--tag</code> option to its GNU counterpart,
<a href="https://manpages.debian.org/buster/coreutils/sha256sum.1.en.html"><code>sha256sum(1)</code></a>:</p>
<pre><code>$ sha256sum --tag quarg-0.1.2.tar.gz &#62; quarg-0.1.2.tar.gz.SHA256
</code></pre>
<p>Finally, the following invocation of signify cryptographically signs the
checksum file using our secret key and writes the signature to
<code>quarg-0.1.2.tar.gz.SHA256.sig</code>:</p>
<pre><code>$ signify -Ses release.sec -m quarg-0.1.2.tar.gz.SHA256
</code></pre>
<h2 id="final-assembly">Final assembly</h2>
<p>Now all that is left is to store the signature in Git&#8217;s object database using
<a href="https://git-scm.com/docs/git-hash-object"><code>git-hash-object(1)</code></a> and tell
<code>git-notes(1)</code> to link that blob to the <code>0.1.2</code> release tag:</p>
<pre><code>$ git notes --ref=signatures&#47;tar.gz add -C "$(git hash-object -w quarg-0.1.2.tar.gz.SHA256.sig)" 0.1.2
</code></pre>
<p>Let&#8217;s take a look at the signature we just stored:</p>
<pre><code>$ git notes --ref=signatures&#47;tar.gz show 0.1.2
untrusted comment: verify with release.pub
RWRyR8jRAxhmZ8C5e7Vxkaed4Tg5Po+Qg4J+0LvjfRRfzch1MqUL8nzkrtGEB8fLG1+DwRYkzYdcZ7qjcYSPx048lTSVpqjSAAc=
SHA256 (quarg-0.1.2.tar.gz) = 1b6610c2417f36b5b1df5208c3c641b8b2ac3283dae87f453801cdc8c4ffb80a
</code></pre>
<p>Looks good. Let&#8217;s verify it before publishing:</p>
<pre><code>$ git notes --ref=signatures&#47;tar.gz show 0.1.2 | signify -Cp release.pub -x -
Signature Verified
quarg-0.1.2.tar.gz: OK
</code></pre>
<p>Great, this is ready to be published. Git will not include <code>refs&#47;notes&#47;*</code> by
default when pushing, so to update the upstream repository with the new
signatures, we have to push the ref manually:</p>
<pre><code>$ git push origin refs&#47;notes&#47;signatures&#47;tar.gz
</code></pre>
<p>Similarly, a regular clone of the repository will not download any note objects
by default. If you want to have a look at the signatures for
<a href="https://git.oriole.systems/weltschmerz/">weltschmerz</a> or
<a href="https://git.oriole.systems/quarg/">quarg</a>, for example, you have to fetch them
manually like so:</p>
<pre><code>$ git fetch origin refs&#47;notes&#47;signatures&#47;tar.gz:refs&#47;notes&#47;signatures&#47;tar.gz
</code></pre>
<p>Git also supports showing notes in
<a href="https://git-scm.com/docs/git-log"><code>git-log(1)</code></a> directly, by use of the
<code>--notes</code> option. The following will display any signatures for the tar.gz
format inline after the commit message<sup id="fnref7"><a href="#fn7" rel="footnote">7</a></sup>:</p>
<pre><code>$ git log --notes=signatures&#47;tar.gz
</code></pre>
<h2 id="when-in-doubt-automate">When in doubt, automate</h2>
<p>Of course doing all of this every time one wants to carve a new release is a bit
tedious, so I ended up writing a <a href="https://git.oriole.systems/git-helpers/tree/git-sign-for-cgit">small helper script</a>.
For now it hardcodes the invocation of signify, but it should be easily
extensible to accommodate other tools.</p>
<div class="footnotes">
<hr/>
<ol>

<li id="fn1">
<p>It is mentioned briefly in <a href="https://git.zx2c4.com/cgit/tree/cgitrc.5.txt?id=892ba8c3cc0617d2087a2337d8c6e71524d7b49c#n777"><code>cgitrc(5)</code></a>
but I have yet to see it be deployed widely. Of course it might also be that
signatures are not valued that much anymore these days.&#160;<a href="#fnref1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn2">
<p>Whilst I&#8217;d prefer <code>.sig</code> for signify signatures specifically, this would
need patching in cgit. So for now I have to concede and accept that Firefox
calls it a &#8216;detached OpenPGP signature&#8217; even though it isn&#8217;t.&#160;<a href="#fnref2" rev="footnote">&#8617;</a></p>
</li>

<li id="fn3">
<p>An interesting side effect that I only
<a href="https://git.oriole.systems/site/commit/?id=0da8a6e3d85a98e38b1abc2499f7e7b3fe5d9534">recently</a>
noticed is that by signing tarballs generated by <code>git-archive(1)</code> one also
implicitly signs a commit. Read more
<a href="https://oriole.systems/posts/verify-with-signify#Verification%20of%20the%20corresponding%20commit">here</a>.&#160;<a href="#fnref3" rev="footnote">&#8617;</a></p>
</li>

<li id="fn4">
<p>The worst sin a tarball can commit is having all files saved at toplevel,
polluting the directory it is extracted into.&#160;<a href="#fnref4" rev="footnote">&#8617;</a></p>
</li>

<li id="fn5">
<p>A portable version is available
<a href="https://github.com/aperezdc/signify">here</a>.&#160;<a href="#fnref5" rev="footnote">&#8617;</a></p>
</li>

<li id="fn6">
<p>This is so that you can verify a whole set of files with just one
signature.&#160;<a href="#fnref6" rev="footnote">&#8617;</a></p>
</li>

<li id="fn7">
<p>Note that we do not have to type out the full ref here. <code>git-log(1)</code>
will make sure to <a href="https://git-scm.com/docs/git-log#Documentation/git-log.txt---notesltrefgt">form the full name</a>.
<code>git-notes</code> also supports these short forms.&#160;<a href="#fnref7" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/quarg.html#2021-05-07T00:00:00Z</id>
		<updated>2021-05-07T00:00:00Z</updated>
		<title>quarg - Searching Quassel</title>
		<author><name>Wolfgang Müller</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/quarg" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>quarg - Searching Quassel</h1>
		<address>Wolfgang Müller</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2021-05-07">Friday, May  7, 2021</time>
	</header>
	<section class="post">
		<h2 id="synopsis">Synopsis</h2>
<p>quarg is a command-line search tool for Quassel. It supports connecting to both
SQLite and PostgreSQL databases and has a wide range of search options. Mostly
born of frustration with Quassel&#8217;s built-in search, quarg aims to be a simple
and easily extensible search platform.</p>
<p>quarg is written in <a href="https://www.python.org/">Python</a>, enabling it to work on a
variety of operating systems. It has successfully been tested on Linux as well
as Windows machines.</p>
<h2 id="download">Download</h2>
<ul>
<li><a href="https://git.oriole.systems/quarg/snapshot/quarg-1.1.0.tar.gz">quarg-1.1.0.tar.gz</a>
(<a href="https://git.oriole.systems/quarg/snapshot/quarg-1.1.0.tar.gz.asc">signature</a>,
 <a href="verify-with-signify">verify?</a>,
 <a href="https://git.oriole.systems/quarg/refs">archive</a>)</li>
<li><a href="https://git.oriole.systems/quarg">Git repository</a></li>
</ul>
<h2 id="requirements">Requirements</h2>
<ul>
<li><a href="https://www.python.org/">Python</a> &#62;= 3.8 (with support for SQLite if using the SQLite backend)</li>
<li><a href="https://dateutil.readthedocs.io/en/stable/parser.html">dateutil</a> &#62;= 2.8.2</li>
<li><a href="https://www.sqlalchemy.org/">SQLAlchemy</a> &#62;= 2.0</li>
<li><a href="https://www.psycopg.org/">psycopg</a> (recommended if using the PostgreSQL backend)</li>
</ul>
<h2 id="usage-configuration">Usage &#38; Configuration</h2>
<p>See <a href="https://git.oriole.systems/quarg/about/quarg.1"><code>quarg(1)</code></a>.</p>
<h2 id="installation">Installation</h2>
<p>First, create a <a href="https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/">virtual
environment</a>
and activate it.</p>
<pre><code>python -m venv venv
source venv&#47;bin&#47;activate
</code></pre>
<p>Now you can install the downloaded tarball with pip:</p>
<pre><code>python -m pip install quarg-1.1.0.tar.gz
</code></pre>
<p>Remember to make sure you install psycopg if you intend to use the PostgreSQL
backend:</p>
<pre><code>python -m pip install psycopg
</code></pre>
<p>quarg should now be available in your shell:</p>
<pre><code>quarg -h
</code></pre>
<p>If you happen to use Gentoo, quarg is available in the <a href="https://gitweb.gentoo.org/repo/proj/guru.git/tree/net-irc/quarg">GURU
overlay</a>.</p>
<h2 id="contributing">Contributing</h2>
<p>I plan to set up a more public venue for proposing changes and reporting issues
with my software. For now, see the <a href="/">front page</a> for contact info. Feel free
to send patches with
<a href="https://git-scm.com/docs/git-send-email">git-send-email(1)</a> - see
<a href="https://git-scm.com/docs/MyFirstContribution#howto-git-send-email">here</a> and
<a href="https://git-send-email.io/">here</a> for an intro.</p>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/a-new-look.html#2020-06-13T00:00:00Z</id>
		<updated>2020-06-13T00:00:00Z</updated>
		<title>A New Look, Some Updates</title>
		<author><name>Wynn Wolf Arbor</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/a-new-look" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>A New Look, Some Updates</h1>
		<address>Wynn Wolf Arbor</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2020-06-13">Saturday, June 13, 2020</time>
	</header>
	<section class="post">
		<p>It has now been approximately <a href="beton-brut">one year</a> since the
initial publication of this site and its new design. Looking through the
<a href="https://git.oriole.systems/site/log/?qt=grep&amp;q=css%3A">commits</a> that
changed the CSS I can&#8217;t see any big changes; overall the core design
remained very stable. That is (or, rather, was) especially true for the
design of the <a href="/">landing page</a>. Why <em>was</em>? Well, as you might have
noticed, it now has a whole new look.</p>
<p>Gone is the previous brutalist, blocky, beautifully Oriole-yellow page,
replaced by a simple minimalist top-to-bottom list of articles. I even
decided to throw in a quick introduction as well. Whilst I still love
the old design very dearly (it was based on countless design iterations,
ideas, and experiments spanning about 6 months in total), it always
clashed with all other content on this site. That was, of course, in a
way intentional - the idea was to be as uncompromising as possible.  For
the time, it was the right thing to do. I was going through an extreme
amount of turmoil (both externally and internally), and finally had
something completely for myself with that design. It became a sort of
safe haven, a space where I did not have to care much about the needs of
others; a space in which I expressed myself without worry.</p>
<figure>
    <img class="round" src="img/old-landing-page.png" alt="The old landing page"/>
    <figcaption>oriole.system's old landing page</figcaption>
</figure>
<p>Over the last 5 months I have had lots of time to think and reflect, and
learned a lot about myself. The current design therefore reflects a
new-found confidence, and is more an example of easiness than of
uncompromising and extremely idiosyncratic design. Maybe some time in
the future I&#8217;ll be lucky enough to re-use parts of the old art style and
keep it around for something that is more in tune with its complicated
and personal history.</p>
<h2 id="git-http-backend1">git-http-backend(1)</h2>
<p>As <a href="the-long-journey-to-cgit#Future%20work">mentioned</a> in the
previous post, an outstanding item for
<a href="https://git.oriole.systems">git.oriole.systems</a> was support for the
&#8220;smart&#8221;<sup id="fnref1"><a href="#fn1" rel="footnote">1</a></sup> HTTP protocol as supplied by
<a href="https://git-scm.com/docs/git-http-backend">git-http-backend(1)</a>. This
is now implemented via a small
<a href="https://git.oriole.systems/pramantha/tree/www-apps/cgit/files/cgit-1.2.3-git-http-backend.patch?id=3e255c257f3a07f1515e20a4f45a6505eec49d40">patch</a>
for cgit: Whenever cgit is asked to handle a &#8220;cloneable&#8221; item, instead
of caching and serving it itself, it executes <code>git-http-backend(1)</code> and
lets that handle the rest. The advantage of this approach is that
there&#8217;s no additional configuration needed on the side of the web
server, barring the addition of the environment variables
<code>GIT_PROJECT_ROOT</code> and <code>GIT_HTTP_EXPORT_ALL</code> required for
<code>git-http-backend(1)</code> itself.</p>
<p>To my knowledge, it is not easily possible with Caddy 1 to set up the
complex<sup id="fnref2"><a href="#fn2" rel="footnote">2</a></sup> structure needed to run cgit and <code>git-http-backend(1)</code> at
the same URL. Caddy 2 brings much improved <a href="https://caddyserver.com/docs/caddyfile/matchers#path">path matching
support</a>, so I may
change this again once I have migrated everything. For now, this simple
setup suffices.</p>
<h2 id="testing-the-waters">Testing The Waters</h2>
<p>I&#8217;ve also been working on getting things ready for the inevitable
migration to Caddy 2. There&#8217;s still much to be done, and I don&#8217;t think
I&#8217;ll be ready for at least another month. Firstly I want to give Caddy 2
some more time before I use it as a stable service (2.1 is already in
<a href="https://github.com/caddyserver/caddy/releases/tag/v2.1.0-beta.1">beta</a>
and contains a lot of fixes). Secondly I have to make sure that every
single part of my infrastructure will continue to work with Caddy 2, and
that means a lot of testing.</p>
<p>Since I had been working on setting up cgit anyway, I decided to draft a
new Caddyfile that is compatible with Caddy 2. For the most part, it
went surprisingly well. I generally prefer the new syntax, and pretty
much all new features are integrated very cleanly. The documentation
could be improved in a few places, however. Most of the time there is a
clear lack of cross-references, and if you don&#8217;t know how a certain part
of the configuration is called, it is very hard to search for it.</p>
<p>There was one minor hitch to this effort. It seemed that no matter what
I did, I couldn&#8217;t get the <code>fastcgi</code> transport to work with slowcgi: the
<code>PATH_INFO</code> variable would just remain empty. After a few hours of
testing and digging, I could finally identify the root cause. Turns out
there was an ever-so-subtle bug in Caddy&#8217;s handling of the <code>split</code>
directive. I
<a href="https://github.com/caddyserver/caddy/issues/3490">reported</a> the issue
upstream and sent along a small <a href="https://github.com/caddyserver/caddy/pull/3491">pull
request</a> that was
promptly merged.</p>
<h2 id="dark-mode-and-">Dark mode and <code>prefers-color-scheme</code></h2>
<p>Finally, just yesterday I updated the whole site to respect the
<a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme"><code>prefers-color-scheme</code></a>
CSS media feature. Whoever prefers dark websites and has told their
operating system or browser<sup id="fnref3"><a href="#fn3" rel="footnote">3</a></sup> to use dark mode when available will
hopefully rejoice in not having their eyes burnt out when visiting my
site. This is arguably a small change, and inconsequential in the grand
scheme of things, but it was lots of fun to work on after the rather
more stressful crunch of getting cgit to work nicely.</p>
<figure>
    <img class="round" src="img/landing-page-dark.png" alt="The landing page in dark mode"/>
    <figcaption>The landing page in dark mode</figcaption>
</figure>
<p>I&#8217;m still playing around with the overall colour choice and composition,
so you may see more or less significant changes down the road. The main
focus will still be the default light design (as that is the one I
prefer), but dark mode will not just be an afterthought. Feedback on
this is very much welcome.</p>
<p>And by the way, if you are interested in how this site is put together,
check out its <a href="https://git.oriole.systems/site/">Git repository</a>.</p>
<div class="footnotes">
<hr/>
<ol>

<li id="fn1">
<p>I really wish it had a better name&#8230;&#160;<a href="#fnref1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn2">
<p>Read: it needs regular expressions, which means that now I have
one more problem.&#160;<a href="#fnref2" rev="footnote">&#8617;</a></p>
</li>

<li id="fn3">
<p>For Firefox, try setting <code>ui:systemUsesDarkTheme</code> to <code>1</code> in
<code>about:config</code>.<br/>
<strong>Note</strong>: As of <a href="https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_and_edit_CSS#view_media_rules_for_prefers-color-scheme">Firefox 87</a>
this is no
longer needed. You can now toggle between dark and light mode in the
developer tools.&#160;<a href="#fnref3" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/the-long-journey-to-cgit.html#2020-05-31T00:00:00Z</id>
		<updated>2020-05-31T00:00:00Z</updated>
		<title>The Long Journey to cgit</title>
		<author><name>Wynn Wolf Arbor</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/the-long-journey-to-cgit" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>The Long Journey to cgit</h1>
		<address>Wynn Wolf Arbor</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2020-05-31">Sunday, May 31, 2020</time>
	</header>
	<section class="post">
		<p>As more and more FOSS projects leave the confines of dusty arcane
mailing lists or thrice-cursed Bugzilla instances for the seemingly
green pastures of the likes of GitHub or GitLab, there has been an ever
greater need as a proactive user to engage and deal with these
platforms. And, to be perfectly frank, the general experience sucks!</p>
<p>Their search interfaces especially leave a lot of things to be desired.
Usually I end up capitulating after a minute, clone the whole repository
instead, and fire up <a href="https://github.com/BurntSushi/ripgrep"><code>rg(1)</code></a>.
Why struggle to perform a task in your browser if you have tools that
have been perfected for it right in your terminal?</p>
<figure>
    <img class="round" src="img/oh-no-github-search.png" alt="GitHub's search bar"/>
    <figcaption>The most dreaded place in all of GitHub.</figcaption>
</figure>
<p>Another aspect GitHub has been working on is its review interface. From
my personal experience, patch reviews have been perfected on mailing
lists like <code>git@vger.kernel.org</code>, where people discuss proposed patches
by replying to them with in-line comments. After this review phase, an
improved version of the patch is sent in, and another review phase
begins, until there are no more points to discuss, and the patch is
either accepted or deferred.</p>
<p>It took GitHub a very long time to achieve relative feature-parity with
patch reviews by mail. Now, the review interface exists and it works,
but it is very crowded and needlessly convoluted. Finding old versions
of a specific pull-request could be a lot nicer, as could be comparing
subsequent versions to the original. Just about the best feature of
having all this readily available in your browser is the ability to
easily reference other bug reports, leading to improved inter-project
communication. Of course a good mail archive frontend would solve this
problem for mailing lists too.</p>
<p>Regarding repository landing pages, I feel that a Git web interface
should show the state of the Git repository, not introduce me to a
project. Chances are I&#8217;ve discovered a project&#8217;s repository through its
website or project page, which hopefully already achieved the
introductory part.  Once I&#8217;ve found the repository, I&#8217;m ready to look at
the code or browse a few commits; I don&#8217;t want to waste time reading a
(possibly slightly different) project outline.</p>
<p>I want a system that augments my already existing CLI workflow in a
practical way - something that enhances the experience in certain ways,
and doesn&#8217;t completely recontextualize it. Which brings me to the
present state&#8230; and a question.</p>
<h2 id="the-status-quo">The status quo</h2>
<p>I have been hosting my Git repositories on my dedicated server for more
than half a decade now, using a very simple (but effective) system:</p>
<ol>
<li>Initialize a bare Git repository in a well-known directory</li>
<li>Tweak directory permissions (<code>0700</code> if it&#8217;s private)</li>
<li>Enable the default <code>post-update</code> hook that runs
<code>git-update-server-info(1)</code></li>
<li>Push my work to the server via <code>ssh(1)</code></li>
</ol>
<p>Together with any old web server that can serve static files and a few
symbolic links in the right places, this setup enables most (if not all)
of what I need from a Git hosting platform. I can push and pull my work
using <code>ssh(1)</code>, and the few public repositories I have are accessible
via pull-only HTTPS using Git&#8217;s &#8220;dumb protocol&#8221;.</p>
<p>I can even collaborate directly with other users on my server by
allowing specific people write access to the bare repositories. No <code>git</code>
user or group needed - just good old POSIX Access Control Lists. And for
people without a shell account on my server (the vast majority as it
turns out) there still was the possibility of using
<a href="https://git-scm.com/docs/git-send-email">git-send-email(1)</a> to
contribute, of course<sup id="fnref1"><a href="#fn1" rel="footnote">1</a></sup>.</p>
<h2 id="no-web-interface">No web interface?</h2>
<p>Over the last decade or so one thing has become very apparent:
fully-featured and well-integrated collaborative platforms for
development are there to stay, and users&#8217; expectations have risen with
them. Given these expectations, I&#8217;ve been asked more than a couple of
times recently why I do not have a Git web interface for my projects.
The answer&#8217;s always been the same, <strong>&#8220;why browse a repository with
anything other than CLI tooling?&#8221;</strong>, but the question stuck with me&#8230;</p>
<p>It was trivial to find out why I didn&#8217;t set up a web interface
initially, back when I set up the system I described above: I simply did
not need one. This was a deliberate decision as I had recently migrated
away from GitHub, which, back then, already contained most of the
interactive web components it has now. My projects did not see a great
deal of external activity, there were next to no bug reports, and most
of the projects were too small to warrant integration into GitHub&#8217;s
whole feature set. They were frequently starred<sup id="fnref2"><a href="#fn2" rel="footnote">2</a></sup>, but it did not seem
that activity would pick up any time soon.</p>
<p><em>A web interface therefore was not even part of the equation.</em></p>
<h2 id="yes-web-interface">Yes web interface!</h2>
<p>These days, the question is harder to answer as I admittedly very much
recognize the ease of use and comfort of using a web interface to give a
project only a cursory glance, link a patch on IRC, or do a quick and
dirty blame on some broken code. As repository size decreases,
explorability on decent web interfaces increases, and, for the smallest
projects, a good web frontend can arguably fully replace <code>git-clone(1)</code>.</p>
<p>So, do I need a web interface? <em>No, not really.</em> Do I want one? <em>I think
so.</em> Given a decent enough candidate, I am confident that it will provide
features other people find useful. Perhaps it will also boost visibility
of what I am working on, and give me a nice stage on which to present
projects still lacking their own post on this site. Plus, it is
something to keep me occupied for a few days as I go about setting it
up.</p>
<p>About I month back I set out to compile a full list of requirements:</p>
<ul>
<li>Self-hosted, without depending on popular containerized deployments</li>
<li>A minimal and well-designed user interface</li>
<li>No misguided social networking features (GitHub stars, I am looking at you)</li>
<li>Active development, good documentation</li>
<li>Easy integration with my preferred web server, <a href="https://caddyserver.com/">Caddy</a></li>
<li>Light on dependencies: no Ruby, no Perl, no PHP</li>
<li>Not strictly necessary, but a bonus: no JavaScript</li>
</ul>
<h2 id="searching-for-candidates">Searching for candidates</h2>
<p>The search was on. I quickly found a very helpful
<a href="https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#Web_Interfaces">list</a>
and started digging through it&#8230;</p>
<h3 id="klaus">klaus</h3>
<p>First up, <a href="https://github.com/jonashaag/klaus">klaus</a>. The
<a href="https://klausdemo.lophus.org/~jonashaag/klaus/">demo</a> looks promising enough,
except for the fact that one of the badges gets blocked by the
<code>X-Frame-Options</code> policy, but that is not relevant to the project
itself. It is built with Python, making hosting relatively easy with my
server setup, and also does not contain any features beyond simple
repository browsing.</p>
<p>My issues come with the overall design. I just&#8230; don&#8217;t like the way it
looks. Lots of the core elements are very blocky, positioned too close
together, and not contrasted enough.  The diffs themselves look good,
but the commit messages suffer from the same blocky and grey fate,
drowning in the big wall of text below.</p>
<p>The design of the summary page feels strange to me as well, with most of
the page taken over by the rendered <code>README</code> file and no quick way to
see the last few commits other than scrolling all the way down. All of
this would need a great deal of work to fix, more than I am willing to
commit to right now.</p>
<h3 id="sorcia">sorcia</h3>
<p><a href="https://git.mysticmode.org/r/sorcia">sorcia</a> is a relatively new
frontend written in Go. It&#8217;s still in alpha, and the &#8220;federation&#8221; part
seems to be missing entirely, but is very pleasing to look at and use
already. The <a href="https://sorcia.org/">homepage</a> has the following to say:</p>
<blockquote>
<p>Initially I&#8217;ve started building this project for myself as I&#8217;ve grown
kinda frustrated with the noisy interface that I&#8217;ve been noticing on
Github or other similar softwares. I started my career as a UI
designer and then moved on to web programming, so I thought I could
build and design something that would only have the necessary features
which I need in order to host and develop my projects.</p>
</blockquote>
<p>Sounds like what I am looking for. Sadly, a cursory look at the
installation guide reveals a bit of a snag. For now, sorcia seems to use
its own SSH server, and cannot be integrated to use an already running
one. Bummer.</p>
<p>Additionally, without JavaScript,
<a href="https://git.mysticmode.org/r/sorcia/tree/master/config/app.ini.sample">some</a>
<a href="https://git.mysticmode.org/r/sorcia/commit/master/96d462d33ee80853bb29bfddf6c910675708fa52">things</a>
are not as nice yet as they could be. Picking this as a long-time
solution right now is definitely a no-go. Maybe very well worth a look
in year or so - if the project is still around by then. That said, I
definitely appreciate the effort to create a nice user experience.</p>
<p><strong>Addendum (2021-02-01):</strong> Indeed sorcia seems to be dead.</p>
<h3 id="gogs-gitea">Gogs &#38; Gitea</h3>
<p>Now on to the big ones, the behemoths of self-hosted Git services: Gogs,
and its more or less recent fork Gitea. I&#8217;ll focus on the latter only,
seeing as the user experience is largely the same.</p>
<p>Gitea fulfills most of the requirements, with one huge caveat: The
interface and features set is meant to match GitHub&#8217;s or GitLab&#8217;s. I
will not only get a Git browser, but also an issue tracker, support for
pull requests, a full-fledged wiki system, an activity tab, and the
ability to watch repositories, star, and fork them.</p>
<figure>
    <img class="round" src="img/gitea-unnecessary.png" alt="The Gitea     navigation."/>
    <figcaption>The Gitea navigation with unnecessary functionality
    highlighted in red.</figcaption>
</figure>
<p>Gitea&#8217;s not meant to have one instance per user, it&#8217;s meant to have one
instance per company or community. And that community better be big!
This puts me in a weird position where I am forced to go all in, but get
nothing in return: If I were to consider enabling the issue tracker
properly, I would also have to open up registrations; that means
enabling authentication, allowing outbound mail, and fighting spam. All
for the end result of people not wanting to register with yet another
random instance on the internet.</p>
<p>On the other hand, if I disable<sup id="fnref3"><a href="#fn3" rel="footnote">3</a></sup> all the features I do not need, the
10% that remains of the whole of Gitea is not even that great. Barely
worth putting in the effort of going through its one thousand line
<a href="https://github.com/go-gitea/gitea/blob/670db99f4fa26c9e97ce7945b61d9a6f20558634/custom/conf/app.example.ini">sample configuration</a>
file.</p>
<h3 id="cgit">cgit</h3>
<p><a href="https://git.zx2c4.com/cgit/about/">cgit</a> is probably one of the oldest
web frontends for Git, next to <a href="https://git-scm.com/docs/gitweb">gitweb</a>
(which comes bundled with Git itself.) As such, it is one of the most
mature interfaces out there. Written entirely in C, the list of
dependencies is expectedly short: cgit pulls in a tagged release of Git
in the build stage, but other than that only depends<sup id="fnref4"><a href="#fn4" rel="footnote">4</a></sup> on zlib.</p>
<p>cgit is a Git web browser <strong>only</strong>, but has a bit of a different
approach compared to klaus and sorcia. While the latter two put more
emphasis on project presentation and present a fully-rendered <code>README</code>
file first and foremost, cgit focuses more on giving the user a
summarized view of their repository - showing a selection of the latest
active branches, tags, and commits.</p>
<figure>
    <img class="round" src="img/cgit-log.png" alt="The commit log in     cgit."/>
    <figcaption>The commit log on cgit's summary page.</figcaption>
</figure>
<p>In that regard, cgit might scare off users who are unfamiliar with git
internals, but for me this is a welcome change. I can quickly scan
through the summary view and find out what has been worked on recently,
all without having to click through to another page. Of course cgit also
supports markdown or manpage rendering, but it&#8217;s only a secondary
concern.</p>
<p>All in all, I liked cgit the most and set out to deploy it. But things
are never this easy&#8230;</p>
<h2 id="not-so-common-gateway-interface">Not-so Common Gateway Interface</h2>
<p>There is an item on my list of requirements that calls for easy
integration with Caddy, a web server I&#8217;ve been using for a couple of
years now. Nowadays, most web applications actually run an HTTP server
themselves and can easily be set up with Caddy acting as a reverse
proxy. cgit, however, as the subtle name might reveal, runs via
<a href="https://tools.ietf.org/html/rfc3875">CGI</a>, an ancient interface that
relies on the web server executing the application for every incoming
request.</p>
<p>This is a problem because Caddy does not natively support CGI. While
there exists an abandoned
<a href="https://github.com/jung-kurt/caddy-cgi">plugin</a> for Caddy 1, the
recently released Caddy 2.0 does not share the same plugin interface and
lacks CGI support completely. I deem it unlikely that it will ever get
it.</p>
<p>Thankfully, both versions support FastCGI, an attempt to overcome the
overhead of launching a process for every single request (most CGI
applications are actually scripts run by interpreters, so this overhead
can become quite noticable.) But how does one plug a CGI application
into a FastCGI interface?</p>
<p>The answer is to use a FastCGI wrapper, a long-running process that acts
as a bridge between the web server and the CGI application. Problem is
that there are not many good ones around that are still maintained. All
I could find after a few hours of search was a cursed Perl script, and
an implementation in C that was more than 8 years old. <strong>Yikes.</strong></p>
<h2 id="slowcgi8-to-the-rescue">slowcgi(8) to the rescue</h2>
<p>A look on the OpenBSD side of things, though, revealed something very
promising: <a href="https://man.openbsd.org/slowcgi.8"><code>slowcgi(8)</code></a>. The
OpenBSD project is never really vocal about any of its programs, so this
slipped through the cracks easily - even though it&#8217;s been a part of the
operating system since version 5.4, released seven years ago.</p>
<p>slowcgi clocks in at around 1300 lines of C, is actively
maintained, simple, secure by default<sup id="fnref5"><a href="#fn5" rel="footnote">5</a></sup>, and seemed very easy to port
to Linux. In fact, it&#8217;s been ported
<a href="https://github.com/adaugherity/slowcgi-portable">already</a> by someone
else, but that version hasn&#8217;t seen any updates in about a year now - so
I decided to roll my own thing (and will keep maintaining it for the
time being). Instead of pulling in
<a href="https://libbsd.freedesktop.org/wiki/">libbsd</a>, I decided to just copy
in the required parts of the OpenBSD source. In the future I might
migrate over to using Kristap&#8217;s excellent
<a href="https://github.com/kristapsdz/oconfigure">oconfigure</a>.</p>
<p>Once ported, slowcgi works right out of the box. By default it uses
a chroot to keep CGI applications jailed under a specific root
directory, and runs as a separate <code>www</code> user. A chroot for cgit is
technically not needed, but comes highly recommended. Even if it means
having to set up the entire chroot tree with cgit&#8217;s runtime
dependencies, defense in depth is important and makes the setup more
secure and safe in the long run.</p>
<h2 id="putting-everything-together">Putting everything together</h2>
<p>With slowcgi up and running, there&#8217;s only the matter of putting
together all the pieces: Caddy needs to be set up to talk to the
slowcgi instance controlling cgit, and the chroot needs to be set
up properly. At this stage, considerations for backwards compatibility
come into play also. Particularly, I did not want to have to move the
already existing repositories to a new location. Everything that worked
before should continue to work like before.</p>
<p>Since cgit will exist in a chroot, I cannot use symbolic links to any
paths outside of it. Putting cgit into the same directory tree as the
repositories seemed suboptimal also, as I want to keep the web interface
and the actual Git data fully independent of each other for more
flexibility in the future.</p>
<h3 id="the-general-framework">The general framework</h3>
<p>I found my solution in a feature called &#8220;bind mounts&#8221;. People who have
needed to <code>chroot(1)</code> into a Linux installation from a Live CD might be
familiar with this - to give the installation access to devices mapped
by the host running from the CD, the whole <code>&#47;dev</code> directory is bound
onto something like <code>&#47;mnt&#47;dev</code>. Thus, the same files are accessible
through multiple distinct mount points, with one of those contained
within the chroot.</p>
<p>This is the same concept I used in
<a href="https://git.oriole.systems/skein/about/skein.7"><code>skein(7)</code></a>, a small
framework facilitating a flexible and modular approach to multi-user
cgit hosting.  Given a simple directory structure, a helper script sets
up all necessary devices<sup id="fnref6"><a href="#fn6" rel="footnote">6</a></sup> and bind mounts for every user wanting to
give the cgit CGI application access to their repositories. If there is
a need to have multiple cgit hosts set up, this framework also allows
fine-grained control over which repositories show up on which host. This
way, users on my server who would like to opt in to having a cgit
frontend can freely determine how it is set up.</p>
<p>The following is part of the <code>skein(7)</code> framework, showing my home
directory in the cgit chroot. Symbolic links in each instance&#8217;s <code>repos&#47;</code>
directory point to the actual Git repositories under the <code>repos.avail</code>
bind mount.</p>
<pre><code>wolf
├── instances
│   └── git.oriole.systems
│       ├── config
│       ├── repos
│       │   ├── slowcgi.git@ -&#62; ..&#47;..&#47;..&#47;repos.avail&#47;slowcgi.git
│       │   └── [...]
│       └── site
│           ├── cgit.css
│           ├── custom.css
│           ├── favicon.svg
│           ├── logo.svg
│           └── robots.txt
└── repos.avail
</code></pre>
<p>As for cgit&#8217;s runtime dependencies&#8230; I&#8217;ve decided to keep these to an
absolute minimum and use only statically compiled binaries to reduce the
amount of work needed to maintain the chroot setup. Whilst this means
that cgit will <strong>not</strong> have access to a shell (or, for that matter, a
Python interpreter), a very decent chunk of its filter capabilities can
still be used in conjunction with the wonderful
<a href="https://kristaps.bsd.lv/lowdown/">lowdown</a> and
<a href="https://mandoc.bsd.lv/">mandoc</a> projects and a tiny custom C
<a href="https://git.oriole.systems/skein/tree/cgit-about-filter.c">program</a>
invoking them.</p>
<p>Finally, the directives needed for Caddy are as simple as:</p>
<pre><code>git.oriole.systems {
    import shared
    root &#47;srv&#47;cgit&#47;home&#47;wolf&#47;instances&#47;git.oriole.systems&#47;site&#47;

    fastcgi &#47; &#47;run&#47;slowcgi.cgit.sock {
        env SCRIPT_FILENAME &#47;bin&#47;cgit
        env CGIT_CONFIG &#47;home&#47;wolf&#47;instances&#47;git.oriole.systems&#47;config

        except &#47;cgit.css &#47;custom.css &#47;logo.svg &#47;favicon.svg &#47;robots.txt
    }
}
</code></pre>
<h3 id="configuring-cgit">Configuring cgit</h3>
<p>All that remains now is configuring cgit itself to work with this
framework. There&#8217;s not much to be done in that regard, it simply needs
to be pointed to my custom
<a href="https://git.oriole.systems/skein/tree/cgit-about-filter.c"><code>cgit-about-filter</code></a>
program, and the repository location within the chroot:</p>
<pre><code>about-filter=&#47;bin&#47;cgit-about-filter
scan-path=&#47;home&#47;wolf&#47;instances&#47;git.oriole.systems&#47;repos
</code></pre>
<p>For projects with a <code>README</code> file formatted in markdown, <code>lowdown(1)</code>
will take care of HTML conversion. Manuals are formatted by <code>mandoc(1)</code>.
Given the lack of a Python interpreter there is no syntax highlighting,
but I find excessive syntax highlighting unappealing anyway. A couple
more changes to cgit&#8217;s default <code>cgit.css</code>&#8230; and we&#8217;re done!</p>
<h2 id="git.oriole.systems">git.oriole.systems</h2>
<p>Finally, after about a week&#8217;s worth of research, experimentation, and
setup work, my new Git web interface is finally online under
<a href="https://git.oriole.systems">git.oriole.systems</a>! A great deal of
care has gone into setting it up <em>just right</em>, and I dearly hope this
will be useful for people, enjoyable to use, and interesting to just
browse around in.</p>
<h3 id="future-work">Future work</h3>
<p>A few things remain to be done in the next few weeks and months. For
one, I&#8217;ll have to look at changing my <code>Caddyfile</code> to be compatible with
the recent release of Caddy 2, before I fully switch over to it. That
means having to relearn most of what Caddy does, and may be a bit
time-consuming. Of course I&#8217;ll also have to remain backwards compatible
with all the things I have already set up.</p>
<p>There&#8217;s a few things to be done on the Git web interface front, too:
Right now I still serve Git repositories using the <a href="https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols#_dumb_http">&#8220;Dumb
HTTP&#8221;</a>
protocol. Integration with Git&#8217;s own
<a href="https://git-scm.com/docs/git-http-backend"><code>git-http-backend(1)</code></a> would
be a good addition. Furthermore, I have been planning for a very long
time to set up a <a href="https://public-inbox.org/">public inbox</a> for issue
tracking and bug reports. Once that is set up, I&#8217;ll have to link to the
proper addresses from within each Git repository.</p>
<p>All this will be part of a future post. For now, enjoy.</p>
<div class="footnotes">
<hr/>
<ol>

<li id="fn1">
<p>The chances of that happening are tremendously low, but
<a href="https://git-send-email.io/">hope</a> dies last, as they say.&#160;<a href="#fnref1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn2">
<p>To my eternal chagrin, the project with the highest amount of
stars was a hastily thrown-together shell script that fired up a
now-playing notification for mpd&#8230;&#160;<a href="#fnref2" rev="footnote">&#8617;</a></p>
</li>

<li id="fn3">
<p>Not even supported yet, but is
<a href="https://github.com/go-gitea/gitea/pull/8788">introduced</a> with the
upcoming <code>1.12.0</code>.&#160;<a href="#fnref3" rev="footnote">&#8617;</a></p>
</li>

<li id="fn4">
<p>The README <a href="https://git.zx2c4.com/cgit/tree/README#n52">mentions</a>
libcrypto and libssl, but as far as I can tell these are not needed.
Git switched to <a href="https://github.com/git/git/commit/e6b07da2780f349c29809bd75d3eca6ad3c35d19">its own</a>
SHA1 implementation a few years back, and libssl may only be
<a href="https://github.com/git/git/blob/56219baf1eae50134ee05eaa64e26e7f1207042c/INSTALL#L132">required</a>
for <code>git-imap-send(1)</code>.&#160;<a href="#fnref4" rev="footnote">&#8617;</a></p>
</li>

<li id="fn5">
<p>Sadly there&#8217;s no good way to do
<a href="https://man.openbsd.org/pledge.2"><code>pledge(2)</code></a> nicely on Linux, so those
parts are ignored. And no, I&#8217;m
<a href="https://github.com/kristapsdz/acme-client-portable/blob/master/Linux-seccomp.md">not</a>
<a href="https://learnbchs.org/pledge.html">going</a>
<a href="https://lwn.net/Articles/738694/">to</a> pivot to <code>seccomp(2)</code>.&#160;<a href="#fnref5" rev="footnote">&#8617;</a></p>
</li>

<li id="fn6">
<p>For now that is just &#47;dev&#47;null.&#160;<a href="#fnref6" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/new-features-in-weltschmerz.html#2020-04-13T00:00:00Z</id>
		<updated>2020-04-13T00:00:00Z</updated>
		<title>New features in weltschmerz 1.3.0</title>
		<author><name>Wynn Wolf Arbor</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/new-features-in-weltschmerz" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>New features in weltschmerz 1.3.0</h1>
		<address>Wynn Wolf Arbor</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2020-04-13">Monday, April 13, 2020</time>
	</header>
	<section class="post">
		<p>Over the past few weeks I have been working on bringing a few new
features to <a href="weltschmerz">weltschmerz</a>, my terminal emulator. One
of them is the addition of a major VTE feature that I had overlooked
when I first prototyped it: The support for <strong>OSC 8 hyperlinks</strong>.</p>
<p>The remaining two are smaller in nature, but hopefully just as useful:
The context menu has learned a couple of new tricks, namely <strong>copying a
selection as HTML</strong>, and the ability to <strong>open the current directory</strong>
in the desktop environment&#8217;s default file manager.</p>
<p>Additionally, I have overhauled and improved the configuration
management code to make future changes and additions easier. These
improvements include a small bug fix, but are otherwise invisible to the
end user.</p>
<p>Head on over to the <a href="weltschmerz">project page</a> to get the newest
version right away, or read on to take a closer look at each new
feature.</p>
<h2 id="hyperlink-support">Hyperlink support</h2>
<p>The motivation for this feature came when I <a href="https://developers.redhat.com/blog/2020/03/26/static-analysis-in-gcc-10/">read about</a>
the new <code>-fanalyzer</code> static analysis pass that will come with GCC 10.
The post mentions that in sufficiently capable terminals, new CWE
identifiers and the option names for warnings are clickable hyperlinks
pointing people to the right place in the documentation.</p>
<p>Since the post mentioned <em>gnome-terminal</em> as one such capable emulator,
I assumed that VTE had to have been updated with hyperlink support and
went to find out when that happened. It turned out that it had been
added <a href="https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda">way back when</a>
in 2017, I just never paid much attention to it.</p>
<p>Since VTE already had full support, I decided to add this feature to
weltschmerz as well. Now, if enabled, hyperlinks are clickable; they
open up in the application that GLib thinks is best for the given URI.
To make the user aware of what they will open, the terminal now renders
a tooltip with the URI when hovering over a hyperlink:</p>
<p><img src="img/weltschmerz-hyperlinks.png" alt="hyperlinks in weltschmerz"/></p>
<p>Given the relative infancy of this functionality, and a couple of
<a href="https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda#security">security concerns</a>,
this feature is disabled by default. If you want to try it out, it can
be enabled in weltschmerz&#8217;s config file like so:</p>
<pre><code class="language-ini">[misc]
allow-hyperlinks = true
</code></pre>
<h2 id="copy-as-html">Copy as HTML</h2>
<p>Whilst looking through VTE&#8217;s <a href="https://valadoc.org/vte-2.91/Vte.Terminal.html">Vala
documentation</a> to find
out more about hyperlinks, I stumbled across the <a href="https://valadoc.org/vte-2.91/Vte.Format.html">definition</a>
for the <em>Format</em> enum which controls in what format the selection is
copied to the clipboard. <code>TEXT</code> makes the clipboard contain the plain
text copy of the selection, and <code>HTML</code> formats the selection as HTML,
with mostly complete style and colour information, like this:</p>
<pre class="indent clear">
<b>diff --git a/NEWS b/NEWS</b>
<b>index a9b1359..4e1c329 100644</b>
<b>--- a/NEWS</b>
<b>+++ b/NEWS</b>
<font color="#5C4BC8">@@ -1,5 +1,11 @@</font>
 This file lists important changes to the weltschmerz terminal emulator.

<font color="#377945">+Changes in version 1.2.1, released on January 17, 2020:</font>
<font color="#377945">+</font>
<font color="#377945">+    --- MINOR BUGFIXES ---</font>
<font color="#377945">+ * weltschmerz.1: The manual page now contains updated contact and author</font>
<font color="#377945">+   information.</font>
<font color="#377945">+</font>
 Changes in version 1.2.0, released on December 30, 2019:

     --- MINOR NEW FEATURES ---
</pre>
<p>Adding support for this was straightforward. <strong>Copy as HTML</strong> is now
available as a context menu entry whenever there is an active selection.
The above is an excerpt of the output of <code>git-diff(1)</code> from one of the
release commits. Except for the font (which depends on your browser),
this is exactly how it looked in my terminal.</p>
<h2 id="open-directory">Open directory</h2>
<p>For the longest time I primarily used <a href="https://github.com/ranger/ranger">ranger</a>,
a terminal file manager, to traverse directories and open files quickly.
A few months back I decided to try out a few GUI-based ones and found that
<a href="https://docs.xfce.org/xfce/thunar/start">Thunar</a> does the job very
well. So well, in fact, that I rarely use ranger anymore these days. I
find that for regular day-to-day browsing, I am much faster with the
mouse and quick drag-and-drop actions are now essential to me.</p>
<p>I still spend most of my time in a terminal, however, and whilst it is
very easy to open a terminal from within Thunar, it used to be not so
easy to open an instance of Thunar (or whichever file manager you
prefer) from within weltschmerz.</p>
<p><img src="img/weltschmerz-open-directory.png" alt="Open directory context menu entry in weltschmerz"/></p>
<p>Now, with the new <strong>Open directory</strong> context menu entry (or by hitting
<code>Ctrl+Shift+O</code>), weltschmerz opens the current directory in the desktop
manager&#8217;s default file manager. Note that VTE relies on <strong>OSC 7</strong> to
determine which directory an application is in.</p>
<p>The shell I use, <a href="https://fishshell.com/">fish</a>, emits the correct
escape sequence <a href="https://github.com/fish-shell/fish-shell/blob/8029f15f1fd4f77b0105fcf7421a5cdf551e2fec/share/functions/__fish_config_interactive.fish#L269">automatically</a>
whenever it enters a new directory, but other shells will most likely
<strong>not</strong> do this by default. In that case, the menu entry will be greyed
out. However, for other shells, it should simply be sufficient to put the
proper escape sequence into <code>PS1</code> or something comparable to
<code>PROMPT_COMMAND</code> in bash. Note that it has to contain a URI (and not
a regular path).</p>
<p>Consider something like the following (though note that <code>hostname</code> and <code>path</code>
should be URL-encoded):</p>
<pre><code class="language-sh">printf &#39;\e]7;file:&#47;&#47;%s%s\a&#39; "$hostname" "$path"
</code></pre>
<h2 id="closing">Closing</h2>
<p>That&#8217;s it for this release. I hope these new features will be useful (or
at least interesting) to people. Until next time!</p>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/debug-ncmpcpp-taglib.html#2020-01-11T00:00:00Z</id>
		<updated>2020-01-11T00:00:00Z</updated>
		<title>Debugging adventures: ncmpcpp and taglib</title>
		<author><name>Wynn Wolf Arbor</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/debug-ncmpcpp-taglib" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>Debugging adventures: ncmpcpp and taglib</h1>
		<address>Wynn Wolf Arbor</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2020-01-11">Saturday, January 11, 2020</time>
	</header>
	<section class="post">
		<p>I have a pretty extensive music library which I manage with
<a href="https://www.musicpd.org/">mpd(1)</a> and
<a href="https://github.com/ncmpcpp/ncmpcpp">ncmpcpp(1)</a>. Whilst I would love to
find a standalone tag editor that is easily usable from the command line
(or alternatively a nicely designed GUI one), ncmpcpp&#8217;s built-in tag
editor has always been enough for my needs.</p>
<p>About two weeks ago I was in the process of adding a new album to my
collection. This always includes a quick glance at the tags and some
cleanup. This time, however, after I saved my changes, the following
happened:</p>
<p><img src="img/ncmpcpp-double-tag.png" alt="ncmpcpp displaying duplicate entries"/></p>
<p>Every time I saved my changes, another duplicate entry would be added to each
tag. I had not updated <code>ncmpcpp(1)</code> in a while and was initially confused as to
why it failed suddenly. I left it, removed all tags using <code>metaflac(1)</code>, and
tagged the album manually. At the time I could not really be bothered to fix
it, but I still wanted to investigate it at a later point, so I added an entry
to my to-do list.</p>
<h2 id="diving-in">Diving in</h2>
<p>Today I decided to look into this finally. First stop: the <code>ncmpcpp(1)</code>
source code. I already knew that it used <code>taglib</code> to access and modify
Vorbis comments, so I quickly found the <a href="https://github.com/ncmpcpp/ncmpcpp/blob/31ee76e8eee0cdc953f85d6c9369fb0aca010889/src/tags.cpp#L173-L199">part of the
code</a>
that was responsible for saving changes:</p>
<pre><code class="language-cpp">void writeXiphComments(const MPD::MutableSong &#38;s, TagLib::Ogg::XiphComment *tag)
{
    auto writeXiph = [&#38;](const TagLib::String &#38;type, const TagLib::StringList &#38;list) {
        tag-&#62;removeField(type);
        for (auto it = list.begin(); it != list.end(); ++it)
            tag-&#62;addField(type, *it, false);
    };
    &#47;&#47; remove field previously used as album artist
    tag-&#62;removeField("ALBUM ARTIST");
    &#47;&#47; remove field TRACK, some taggers use it as TRACKNUMBER
    tag-&#62;removeField("TRACK");
    &#47;&#47; remove field DISC, some taggers use it as DISCNUMBER
    tag-&#62;removeField("DISC");
    &#47;&#47; remove field DESCRIPTION, it&#39;s displayed as COMMENT
    tag-&#62;removeField("DESCRIPTION");
    writeXiph("TITLE", tagList(s, &#38;MPD::Song::getTitle));
    &#47;&#47; [...]
}
</code></pre>
<p>Here, <code>ncmpcpp(1)</code> calls <code>removeField(type)</code> before adding a tag, which
looked fine. Maybe the list contains more than one entry? Stepping
through this code in <code>gdb(1)</code> revealed that <code>addField</code> was only called
once per tag, meaning it was only added once. At this point I remembered
that I was pretty sure <code>ncmpcpp(1)</code> had not been updated in a while, so
I refocused on <code>taglib</code> instead: Maybe <code>removeField</code> stopped working for
some reason.</p>
<h2 id="unorthodox-packaging-decisions">Unorthodox packaging decisions</h2>
<p>A quick query against the Gentoo package database revealed that I was
using <code>taglib-1.11.1_p20190920-r1</code> which looked very suspicious already.
The latest stable version on the <a href="https://taglib.org/">website</a> is
<code>1.11.1</code> from <strong>October 24, 2016</strong>.</p>
<pre><code class="language-sh">nabokov ~$ eix taglib
[I] media-libs&#47;taglib (1.11.1_p20190920-r1@11&#47;01&#47;20)
</code></pre>
<p>So what is going on here? <code>taglib</code> is still under active development,
but there has not been a stable release for about four years. Gentoo
instead decided to
<a href="https://gitweb.gentoo.org/repo/gentoo.git/tree/media-libs/taglib/taglib-1.11.1_p20190920-r1.ebuild#n7">package</a>
the <a href="https://github.com/taglib/taglib/commit/54508df30bc888c4d2359576ceb0cc8f2fa8dbdf">latest
commit</a>
(at time of writing) as a &#8220;stable&#8221; version. For projects that have some
kind of stability guarantee regarding their API, this is a very
dangerous and strange choice on the part of the packagers; quite
frankly, it is inviting random breakage.</p>
<h2 id="exploring-taglib">Exploring taglib</h2>
<p>Digging around in <code>taglib</code>&#8217;s <a href="https://github.com/taglib/taglib">github
repo</a> revealed that <code>removeField</code> had
been <a href="https://github.com/taglib/taglib/issues/651">marked</a> deprecated
internally in mid-2015 because of an apparent linking error when using
<code>String::null</code>. Let&#8217;s have a look at the prototype of <code>removeField</code> from
<a href="https://github.com/taglib/taglib/blob/84e3582332eb593497912d055f15827a57815478/taglib/ogg/xiphcomment.h#L188">back then</a>:</p>
<pre><code class="language-cpp">void removeField(const String &#38;key, const String &#38;value = String::null);
</code></pre>
<p>This method removes a tag entry of a specific type and optionally
matches it against a given value. For example, <code>removeField("TITLE")</code>
removes all <code>TITLE</code> tags, and <code>removeField("TITLE",
"Garbagemx36")</code> only removes <code>TITLE</code> entries if they match
&#8220;Garbagemx36&#8221;.</p>
<p>The <a href="https://github.com/taglib/taglib/issues/651">issue</a> mentions that
changing the default parameter for <code>value</code> to an empty string would
change the behaviour of the method. Suddenly, <code>removeField("TITLE")</code>
would only remove <code>TITLE</code> entries if they matched the empty string -
leaving everything else intact.</p>
<p>Sounds like we found our culprit. But didn&#8217;t the issue say that they
would not make this change? What gives?</p>
<h2 id="enter-gdb">Enter GDB</h2>
<p>At this point I started doubting the correctness of five year old issue
comments, and decided to have a look at things myself. Thankfully,
Gentoo makes it very easy to add debugging information to packages and
have the source code installed alongside binaries and library files. A
single addition to <code>&#47;etc&#47;portage&#47;package.env</code> later and I was debugging
<code>removeField</code> in <code>gdb(1)</code>.</p>
<p>Stepping ahead to <a href="https://github.com/taglib/taglib/blob/84e3582332eb593497912d055f15827a57815478/taglib/ogg/xiphcomment.cpp#L267">where the method
checks</a>
whether <code>value</code> is null or not, I printed its contents:</p>
<pre><code>(gdb) p value
$1 = (const TagLib::String &#38;) @0x7fffffffc240: {
  _vptr.String = 0x7ffff5be83b8 &#60;vtable for TagLib::String+16&#62;, static null = {
    _vptr.String = 0x7ffff5be83b8 &#60;vtable for TagLib::String+16&#62;, 
    static null = &#60;same as static member of an already seen type&#62;, 
    static WCharByteOrder = TagLib::String::UTF16LE, d = 0x5555559a95c0}, 
  static WCharByteOrder = TagLib::String::UTF16LE, d = 0x555555b9f700}
</code></pre>
<p>Ah, like any good project, <code>taglib</code> is using a custom string type. Let&#8217;s convert it to a C
string:</p>
<pre><code>(gdb) print value.toCString(false)
$5 = 0x555555b9f740 ""
</code></pre>
<p>And there it was. <code>taglib</code> indeed was using an empty string (and not
<code>null</code>) as the default for <code>value</code> in <code>removeField</code>.</p>
<h2 id="closing-blame">Closing Blame</h2>
<p>One question remained: Why was this changed after all? It seemed pretty
clear back then that the developers did not want to break the API.
Perhaps there was a different bug at work here?</p>
<p>As I had learnt earlier, the default value for a parameter is found in
the header file, so I used <code>git-blame(1)</code> to find commits that introduced
changes to the prototype. Surprisingly, what I found was a very <a href="https://github.com/taglib/taglib/commit/c05fa78406fd8ce7382a11c1f63a17c4bfbe83fa#diff-b48915d5a31d8a598dc1f3e92810bbd1L189">recent
change</a>
from September that added actual deprecation warnings&#8230; and
quietly changed <code>String::null</code> to <code>String()</code>. I was not able to find a
reason for this; to my knowledge, no commit or issue mentions this
change.</p>
<p>So in the end, whilst wanting to keep up API promises, the behaviour of
an already deprecated method was changed in what can only be called the
&#8220;development branch&#8221; of the project, and it hit me because Gentoo
decided that it was a good idea to use work-in-progress code as a stable
candidate for a package.</p>
<p>Around the time I discovered this, someone else had already opened an
<a href="https://github.com/ncmpcpp/ncmpcpp/issues/371">issue</a> on GitHub. I
shared my findings and later opened a <a href="https://github.com/ncmpcpp/ncmpcpp/pull/373">pull
request</a>. I am pondering
bringing this to the package maintainer&#8217;s attention, but am not
confident it will result in any positive change.</p>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/that-living-parameter.html#2019-09-09T00:00:00Z</id>
		<updated>2019-09-09T00:00:00Z</updated>
		<title>That Living Parameter</title>
		<author><name>Wynn Wolf Arbor</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/that-living-parameter" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>That Living Parameter</h1>
		<address>Wynn Wolf Arbor</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2019-09-09">Monday, September  9, 2019</time>
	</header>
	<section class="post">
		<p>casually oversized radiator<br/>
annoying alkaline rug<br/>
produce only defiance  </p>
<p>senior sycamore tree<br/>
bright ladybug sanctuary<br/>
simply nimble antennea  </p>
<p>mystified prowling turtle<br/>
hypnotic eel footage<br/>
most spirited obedience  </p>
<p>unlawful tuesday outfit<br/>
discard kitten quilt<br/>
illusive bobcat fabric  </p>
<p>semisoft nectar hug<br/>
grumbly moonbeam radiance<br/>
frosty celestial dandelion  </p>
<p>unwanted external gender<br/>
maximize underuse coerce<br/>
timid imperfect finale  </p>
<p>efficient waking exorcism<br/>
cursive twilight venture<br/>
that unshaven hamster  </p>
<p>education stream unguided<br/>
glacial student seminar<br/>
penalize math stuffing  </p>
<p>dismiss raisin donut<br/>
gulp poking anchovy<br/>
that living parameter  </p>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/beton-brut.html#2019-07-21T00:00:00Z</id>
		<updated>2019-07-21T00:00:00Z</updated>
		<title>Béton Brut</title>
		<author><name>Wynn Wolf Arbor</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/beton-brut" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>Béton Brut</h1>
		<address>Wynn Wolf Arbor</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2019-07-21">Sunday, July 21, 2019</time>
	</header>
	<section class="post">
		<p>It is hard to believe that it took me well over half a year to finally
come to the point where I can publish this website on my new domain and
leave the old one behind. There&#8217;s a few reasons it took this long, and
for once, surprisingly, they are not at all software-related. It was a
journey through uncertainty, insecurity, and compulsive hesitancy, which
is why this post will mostly be a reflective one.</p>
<h2 id="legacy-woes">Legacy Woes</h2>
<p>Last year in November I had a bunch of free time on my hands, and I very
innocently decided to work on a new site design. Back then I only really
wanted to change a few things, since a full makeover seemed a bit too
daunting. Still, after throwing around a bunch of ideas in my head, it
seemed more clear that I would have to abandon the bulk of what I
already had. Mainly this was because the old site was built on a
considerable amount of legacy code: I was using AsciiDoc, which I had
fallen out of favour with, and most of the site was being held together
by an unwieldy Makefile and a couple of hacky shell scripts.</p>
<p>So whilst it was easy enough to add new content, changing the design or
even merely attempting to tweak core concepts was impossible without a
bigger rewrite.</p>
<p>Another concern was my growing disdain for a few of the things that I
had published. Ideally I thought it&#8217;d be best to rewrite the bits that I
didn&#8217;t like and keep the rest, but I couldn&#8217;t find a sufficient amount
of motivation. I ended up neglecting to write any new posts on the site,
and knowing I had stuff online that I kind of despised made me feel
depressed every time I thought about it. I felt that the site could no
longer reasonably present the kind of person I was. I felt that I was
lying.</p>
<h2 id="honest-design">Honest Design</h2>
<p>Around the same time I stumbled upon <a href="https://brutalistwebsites.com/">Brutalist
Websites</a> (since defunct, and only
reasonably browsable by removing the prominent overlay), which curated a
collection of <em>brutalist</em> websites.</p>
<p><img src="img/brutalist-websites.png" alt="Brutalist Websites"/></p>
<p>There was always a certain - perhaps morbid - fascination I had with
Brutalism and its idea of <em>béton brut</em>, raw concrete. The German word
for this concept, <em>Sichtbeton</em>, takes a more experiential approach; it
is simply concrete that is unobstructedly visible. There&#8217;s no attempt to
hide the underpinning, instead it is displayed with a certain kind of
pride. Core to the whole concept is a notion of honesty, of being
utterly clear about what a thing is made of.</p>
<p>So when I felt that I was lying about what kind of person I was, it
seemed only fitting to create something new in that sort of style, and
to take to heart the idea of being more honest to the outside world and
myself.</p>
<h2 id="the-foundation">The Foundation</h2>
<p>Not only did that mean creating a new design, it also meant starting
from scratch and looking for a new engine to build the whole website. I
quickly decided to use <a href="https://kristaps.bsd.lv/sblg/">sblg</a> to generate
HTML files from templates, and
<a href="https://kristaps.bsd.lv/lowdown/">lowdown</a> to convert markdown files to
XML content that sblg understands.</p>
<p>The whole project would live in only a couple of directories, tied
together with a much simpler and cleaner Makefile this time. Compared to
AsciiDoc, site generation was blazingly fast and very robust. It only
took me about a day or two to fully tweak everything the way I wanted it
to behave.</p>
<h2 id="small-steps">Small Steps</h2>
<p>What ended up taking 90% of the rest of the time was the design. With
the idea of being fully honest came a problem: I started questioning
certain decisions because of what they might reveal about myself, what
they might look like from an outside perspective. I noticed that, for a
very long time, I had been genuinely insecure about releasing anything
that was in any way personal to me.</p>
<p>For instance, the idea very early on was to have one single page
containing everything I published; be it a piece of software, a poem, or
some sort of essay. This resulted in a lot of internal conflict as I
often considered my poetry to be &#8220;pretentious&#8221; and inherently less
impactful than a software project. Suddenly I was wanting to have two
sites, one for the &#8220;real&#8221; and technical projects, and one for the more
personal. In turn that would mean that I was actively censoring my
output by categorizing it away to a more obscure part of the site.</p>
<p>Another problem was an almost compulsive need to tweak the most
insignificant parts of the design towards a sense of perfection and
coherence that was frankly unattainable. Because of a lot of internal
turmoil, it became impossible to do any further work I would feel
positive of.</p>
<p>In the end the solution was to take considerable time off personal
projects and reflect on and try to dismantle those problems and
insecurities. I learned that it is very helpful to talk to trustworthy
friends about this, and to find a comfortable space in which to
experiment with being more immediately public with projects, ideas, or
thoughts - even if you think they are unrefined and not ready. This is
especially helpful if one tends to feel vulnerable after having
published or when considering to publish. Initially it is perfectly fine
to create a &#8220;mock public&#8221; space that no one can see, but which can be
made more public as time goes on (a locked Twitter or Fediverse profile,
for example).  The idea is to build confidence in the act of publishing
itself, and to take away the vulnerability and fear.</p>
<h2 id="horizon">Horizon</h2>
<p>Building this sort of confidence in publishing personal content is
time-consuming and not always easy. You may feel the intense urge to
undo a publication or to re-read it until it sounds drab and uninspired.
In those cases, maybe ask a friend for feedback, but most importantly:
take a step back and take some time off. It may read wholly differently
tomorrow.</p>
<p>As for technical work, if you, like me, feel sometimes that what you do
is unimportant, unrecognized, or invisible, it might help to start a
document in which you collect even the smallest things that have some
sort of impact day to day. Julia Evan&#8217;s idea of a <a href="https://jvns.ca/blog/brag-documents/">brag
document</a> is a helpful resource. I
tend to be overly humble myself and want to highlight the following excerpt,
which helped me understand something no one had explained to me before:</p>
<blockquote>
<p>One thing I want to emphasize, for people who don&#8217;t like to brag, is –
<strong>you don&#8217;t have to try to make your work sound better than it is</strong>. Just
make it sound <strong>exactly as good as it is</strong>!</p>
</blockquote>
<p>Like <em>béton brut</em>, be uncompromisingly honest about your work. Don&#8217;t
make it sound better than it is, but most importantly, learn that it
has value and that there is no shame in showing it.</p>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/weltschmerz.html#2019-07-12T00:00:00Z</id>
		<updated>2019-07-12T00:00:00Z</updated>
		<title>weltschmerz - A terminal emulator in Vala</title>
		<author><name>Wolfgang Müller</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/weltschmerz" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>weltschmerz - A terminal emulator in Vala</h1>
		<address>Wolfgang Müller</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2019-07-12">Friday, July 12, 2019</time>
	</header>
	<section class="post">
		<h2 id="synopsis">Synopsis</h2>
<p>weltschmerz is a small and simple terminal emulator built upon the Virtual
Terminal Emulator widget. It&#8217;s written in Vala, supports clickable URLs and
hyperlinks, can reload its configuration whilst running, and has basic search
functionality.</p>
<p><img src="img/weltschmerz.png" alt="weltschmerz in action"/></p>
<p>As a VTE app, weltschmerz supports practically every contemporary
terminal emulator feature. It is built to be a stable and practical
terminal emulator for daily use.</p>
<h2 id="download">Download</h2>
<ul>
<li><a href="https://git.oriole.systems/weltschmerz/snapshot/weltschmerz-1.9.0.tar.gz">weltschmerz-1.9.0.tar.gz</a>
(<a href="https://git.oriole.systems/weltschmerz/snapshot/weltschmerz-1.9.0.tar.gz.asc">signature</a>,
 <a href="verify-with-signify">verify?</a>,
 <a href="https://git.oriole.systems/weltschmerz/refs">archive</a>,
 <a href="https://git.oriole.systems/weltschmerz/tree/NEWS">changelog</a>)</li>
<li><a href="https://git.oriole.systems/weltschmerz">Git repository</a></li>
</ul>
<h2 id="packages">Packages</h2>
<ul>
<li><a href="https://gitweb.gentoo.org/repo/proj/guru.git/tree/x11-terms/weltschmerz">Gentoo Linux</a> (through <a href="https://wiki.gentoo.org/wiki/Project:GURU">GURU</a>)</li>
</ul>
<h2 id="requirements">Requirements</h2>
<ul>
<li><a href="https://wiki.gnome.org/Apps/Terminal/VTE">VTE</a> &#62;= 2.91 (must be built with support for Vala)</li>
<li><a href="https://wiki.gnome.org/Projects/Vala">Vala</a> &#62;= 0.42</li>
<li><a href="https://www.gtk.org/">GTK+</a> &#62;= 3.24</li>
<li><a href="https://www.gnu.org/software/gettext">gettext</a></li>
</ul>
<h2 id="usage-configuration">Usage &#38; Configuration</h2>
<p>See <a href="https://git.oriole.systems/weltschmerz/about/weltschmerz.1"><code>weltschmerz(1)</code></a>.</p>
<h2 id="build">Build</h2>
<p>weltschmerz can be built with any POSIX-conformant make or with
<a href="https://mesonbuild.com">Meson</a>. The latter may be interesting to
distribution packagers or people already comfortable with this
particular build system.</p>
<p><strong>Note:</strong> if your Vala compiler executable is not named <code>valac</code>, you
need to export the environment variable <code>VALAC</code> containing the correct
name before you can build weltschmerz:</p>
<pre><code>export VALAC=&#39;valac-0.42&#39;
</code></pre>
<h3 id="makefile">Makefile</h3>
<p>Run the following to build and install weltschmerz to the default
location (<code>&#47;usr&#47;local</code>):</p>
<pre><code>make install
</code></pre>
<p>The Makefile honors the environment variables <code>PREFIX</code>, <code>DESTDIR</code>,
<code>BINDIR</code>, and <code>MANDIR</code>. For instance, if you want to install weltschmerz
to a local directory, call make like so:</p>
<pre><code>PREFIX=~&#47;software&#47;weltschmerz make install
</code></pre>
<h3 id="meson">Meson</h3>
<p>Create the build directory and configure the Meson build like so:</p>
<pre><code>meson setup build
</code></pre>
<p>The build can be configured extensively; for more information, see <code>meson(1)</code>.
If you want to install weltschmerz locally for use with <a href="https://www.gnu.org/software/stow/">GNU
Stow</a>, for example, pass
<code>--prefix=~&#47;.local&#47;stow&#47;weltschmerz</code>.</p>
<p>Once the build is set up, install weltschmerz:</p>
<pre><code>meson install -C build
</code></pre>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/verify-with-signify.html#2019-01-01T00:00:00Z</id>
		<updated>2019-01-01T00:00:00Z</updated>
		<title>Verifying snapshots with signify</title>
		<author><name>Wolfgang Müller</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/verify-with-signify" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>Verifying snapshots with signify</h1>
		<address>Wolfgang Müller</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2019-01-01">Tuesday, January  1, 2019</time>
	</header>
	<section class="post">
		<p>I use the <a href="https://github.com/aperezdc/signify/">signify</a> tool to
cryptographically sign all software downloads you will find on this
site and on <a href="https://git.oriole.systems">git.oriole.systems</a>.</p>
<p>Whilst you technically don&#8217;t need <code>signify</code> to verify the <em>integrity</em> of
downloaded files, I strongly recommend using it to also verify the
<em>signature</em>.  A portable version of the tool is available
<a href="https://github.com/aperezdc/signify">here</a>.</p>
<h3 id="using-my-personal-overlay">Using my personal overlay</h3>
<p>If you happen to use Gentoo, feel free to use my <a href="https://git.oriole.systems/pramantha">personal
overlay</a>. You only need to enable the
<code>verify-sig</code> USE flag to verify the downloaded tarballs.</p>
<h3 id="obtaining-the-signature-and-checksum">Obtaining the signature and checksum</h3>
<p>Whether or not you decide to use <code>signify</code> to verify downloaded files, you need
to obtain the detached signature linked on the respective project page or git
repository<sup id="fnref1"><a href="#fn1" rel="footnote">1</a></sup>. It contains the signature as well as the checksum.</p>
<h3 id="obtaining-the-public-key">Obtaining the public key</h3>
<p>To fully verify a download with <code>signify</code>, first obtain <a href="/release.pub">my public
key</a>.  I keep a copy of the same key on DNS, feel free to
verify it therewith:</p>
<pre><code>$ drill TXT releasekey.oriole.systems
</code></pre>
<p>Another copy of the key exists on the <a href="https://libera.chat">Libera Chat</a> IRC
servers, in my taxonomy data:</p>
<pre><code>&#47;msg NickServ taxonomy wolf
</code></pre>
<p>You may want to keep the public key saved on your system for future
verifications.</p>
<h3 id="verification-with-signify">Verification with signify</h3>
<p>Once you have downloaded my public key, run the following to verify your
download:</p>
<pre><code>$ signify -C -p release.pub -x &#60;snapshot&#62;.asc
Signature Verified
&#60;snapshot&#62;: OK
</code></pre>
<h3 id="verification-with-sha256sum">Verification with sha256sum</h3>
<p>Alternatively, if you don&#8217;t want to install <code>signify</code>, you can use
the <code>sha256sum</code> tool to only verify the integrity of the download:</p>
<pre><code>$ tail -n1 &#60;snapshot&#62;.asc | sha256sum -c
&#60;snapshot&#62;: OK
</code></pre>
<h3 id="verification-of-the-corresponding-commit">Verification of the corresponding commit</h3>
<p>Every tarball hosted here contains its corresponding commit ID in the global
extended pax header<sup id="fnref2"><a href="#fn2" rel="footnote">2</a></sup>. Therefore, if a tarball is signed, it may be used to verify
a commit and all of its ancestors.</p>
<p>To do so, place the tarball in the cloned git repository first. If you already
have the detached signature, you may verify the tarball normally like shown
above. Otherwise, you can fetch the signatures directly from the repository:</p>
<pre><code>$ git fetch origin refs&#47;notes&#47;signatures&#47;tar.gz:refs&#47;notes&#47;signatures&#47;tar.gz
</code></pre>
<p>Now you can verify the tarball like so:</p>
<pre><code>$ git notes --ref=signatures&#47;tar.gz show &#60;version&#62; | signify -Cp release.pub -x -
Signature Verified
&#60;snapshot&#62;: OK
</code></pre>
<p>Once verified, you can extract the commit using
<a href="https://git-scm.com/docs/git-get-tar-commit-id"><code>git-get-tar-commit-id(1)</code></a> and
show it:</p>
<pre><code>$ gzip -d -c &#60;snapshot&#62; | git get-tar-commit-id | xargs git show
</code></pre>
<div class="footnotes">
<hr/>
<ol>

<li id="fn1">
<p>If you are interested in how this is put together, check out <a href="signify-cgit">this</a> post.&#160;<a href="#fnref1" rev="footnote">&#8617;</a></p>
</li>

<li id="fn2">
<p><a href="https://git-scm.com/docs/git-archive#_description"><code>git-archive(1)</code></a> puts
it there.&#160;<a href="#fnref2" rev="footnote">&#8617;</a></p>
</li>

</ol>
</div>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/transcript.html#2018-12-30T00:00:00Z</id>
		<updated>2018-12-30T00:00:00Z</updated>
		<title>A Transcript</title>
		<author><name>Wynn Wolf Arbor</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/transcript" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>A Transcript</h1>
		<address>Wynn Wolf Arbor</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2018-12-30">Sunday, December 30, 2018</time>
	</header>
	<section class="post">
		<p>though one thing still disturbs me greatly<br/>
and I don&#8217;t know whether I am alone in this<br/>
but it is most obvious at night, in the dark<br/>
or in the haze, the fog;<br/>
that I am not fully there - that there is<br/>
in another space, another self, not me<br/>
but indistinguishable from me,<br/>
yet wholly alien.  </p>
<p>it is irksome to know this, and<br/>
whilst I have come to learn how to cope,<br/>
it never fully leaves me, this thought<br/>
that I am fake.  </p>
<p>it seems an impossible situation, to be<br/>
and not to be at the same time, and to<br/>
hide and show as necessary, just so;<br/>
yes, the necessity of it is still of<br/>
great difficulty. I am not sure<br/>
whether to continue or not, to be,<br/>
to not be, at the same time.  </p>
<p>since, in the past, it worked and<br/>
sometimes made it easy.<br/>
yet, it is not honest, and I fear<br/>
being eaten up from the inside<br/>
by this self, and for it<br/>
to take over.  </p>
<p>then, nothing will be true<br/>
but everything will go on as if<br/>
it were.  </p>
<p>and so I leave this query with<br/>
utmost confusion and no real<br/>
hope of assurance<br/>
that my self be saved and the other<br/>
to be discarded.  </p>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/concrete.html#2017-03-08T00:00:00Z</id>
		<updated>2017-03-08T00:00:00Z</updated>
		<title>Concrete</title>
		<author><name>Wynn Wolf Arbor</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/concrete" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>Concrete</h1>
		<address>Wynn Wolf Arbor</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2017-03-08">Wednesday, March  8, 2017</time>
	</header>
	<section class="post">
		<p>Concrete. Drab, lifeless surfaces, complete in their sterility. Dust
from abrasion dancing around in the few shafts of light like
poisoned spores, carrying death across the hallway. Lying against
the blood-stained wall, this should be his last moment in life. Born
in concrete, deep below the earth, away from sunshine, green grass,
sunflowers, singing birds; Killed in concrete just the same, smashed
against the wall, shot into the lungs and shoulders, bleeding out far
away from light or happiness.</p>
<p>The others were all already gone. Strewn about, lying atop of each
other, dead eyes, pale skin. Grey and feeble, like the concrete all
around. Pools of blood under the bodies, a dark coagulated red. Life
forgotten now seeping into the devouring pores of the cement floor.</p>
<p>&#8220;I&#8217;ll end up like them, eaten up, rotting here where there is
no sunshine. I&#8217;ll end up in the belly of the concrete monstrosity, my
skeleton grinning sheepishly at the unlucky dwellers who find this vault
expecting riches, but getting only death; death grimacing back, and the
concrete, silent as ever, watching, waiting.&#8221;</p>
<p>A putrid smell lay in the room, ironlike, miasmatic, and
dusty. Thankfully only a few more breaths left. Complete silence,
except for the ghastly wheezing of ruptured lungs. A last reminder of
life dwindling between the uncaring walls. Nobody listening except the
elongated and lobeless concrete ears, the rough surfaces like petrified
skin.</p>
<p>Darkness slowly crept in; first at the edges, concealing the unnatural
smiles of mutilated faces. Faces of friends, family, faces of enemies,
of bullies. Everyone&#8217;s face. Nobody&#8217;s face.</p>
<p>He drew his last breath. The darkness crept more towards the center,
towards that one fixpoint; towards the concrete wall he had been staring
at all this time. His enemy. Mankind&#8217;s enemy. And yet it was just a
wall. Something so simple had become the name for all the horrors in the
world, and it was staring back. Endlessly it was staring back, loudly
accusing in complete silence.</p>
<p>It resounded in the corpse-filled room, mangled vocal chords in an
undead chorus.</p>
<p>It resounded in his dying, confused mind.</p>
<p>Concrete.</p>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/the-cat.html#2016-08-04T10:49:20Z</id>
		<updated>2016-08-04T10:49:20Z</updated>
		<title>The Cat</title>
		<author><name>Wynn Wolf Arbor</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/the-cat" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>The Cat</h1>
		<address>Wynn Wolf Arbor</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2016-08-04T10:49:20Z">Thursday, August  4, 2016</time>
	</header>
	<section class="post">
		<p>One should live in a house like a cat, finding repose on almost every
surface. To the cat, the whole house is a shelter. Every table, every
sofa, every chair, every bed, indeed every floor is an invitation to
find some rest. Do we not find cats, again and again, in the most
unusual and unexpected places? We find them there, lying and sleeping
with a kind of lightness and peace as if they themselves had designed
that space specifically for them. We find them there snugly in a ball,
breathing softly to themselves and relaxing their claws.</p>
<p>Now, in this instance, they need them not. In this instance the whole
world around them, usually a cat&#8217;s plaything and center of attention,
ceases to exist almost, as if they, in their peaceful huddledness,
transcended life and entered the realm of daydreaming. A human realm,
not an animal one. Of which things do they dream? Do they dream of the
mouse that eluded them in the existential battle for life and retreated
back to its hole, its own shelter? Do they maybe dream of the fields in
which they were kings and queens, unchallenged monarchs of old?</p>
<p>Truly there is something kingly about cats; a certain evolutionary
dignity. How is it that they live content with beings displaying even
greater hubris? Or maybe they just want to learn? How innocent, though,
in their pursuit of this. How unburdened, how free. Whom do they see
when they look at us? What do they feel when we talk to them?</p>
<p>Can it be that it is only instinct that drives them? They exhibit such
humanness, they exhibit an animal soul. It is a purer soul, a more
simple one, but it is a soul. What do they feel when we gently stroke
their fur with our hands? Do they feel the same kind of love? How is it
to live a cat&#8217;s life?</p>
<p>I said earlier that cats lie down to repose anywhere. Like a human,
however, they have their favourite spots. Always these spots have a
distinctly human element. It is the small opening under our beds that
we so cherished as a child, dreaming of and building at the same time
a warm and safe den ourselves. It is next to our spot on the sofa, as
if we radiated a familiarity and comfort there even in our absence.
It is in the bags we use for our shopping, the suitcases we use for
travelling.</p>
<p>It is on our discarded clothes on the table, floor, chair or bed, as
if they wanted to absorb the fragrances of our lives and thus come
closer to our person. It is our smell that is home to them, our &#8216;&#8216;having
lived&#8217;&#8217; in something, on something, that is so dear to them. Maybe
they want to feel the pain that was inflicted upon us, or the joy and
happiness that was diffused through the clothes as we wore them. They
are not all without us, and while we are gone they are emptier inside
for the loss, seeking refuge, seeking a nest, seeking shelter from the
rain in the touched and transformed things we left behind. We are their
mothers and fathers to them, we are their family. This bond transcends
species, it is therefore something inherent in life. It is a soulful
longing for nearness, a longing for exchange of life, and what makes
life what it is.</p>
<p>My cats cannot comprehend what I have written here, but I believe
fully that they feel the same way. The cat hair on my clothes is their
attempt at sharing this warmness, this closeness. And when the cat
lies down close to me and purrs with all the excellence of beauty and
reverberation, then I feel loved in the universe and want to share that
love. Maybe in this simplicity we should look for love and give it back
with all our heart. Maybe in this simplicity we have found the core of
us and the dignified true expression of the animal, and of nature.</p>
	</section>
</article></div>
		</content>
	</entry>
	<entry>
		<id>https://oriole.systems/posts/old-days.html#2016-06-03T02:44:44Z</id>
		<updated>2016-06-03T02:44:44Z</updated>
		<title>Old Days</title>
		<author><name>Wynn Wolf Arbor</name></author>
		<link rel="alternate" type="text/html" href="https://oriole.systems/posts/old-days" />
		<content type="xhtml">
			<div xmlns="http://www.w3.org/1999/xhtml">
<article>
	<header class="post">
		<h1>Old Days</h1>
		<address>Wynn Wolf Arbor</address>
		<a href=".." title="Back to frontpage">↖</a>
		<time datetime="2016-06-03T02:44:44Z">Friday, June  3, 2016</time>
	</header>
	<section class="post">
		<p>In the lowland of the taiga;<br/>
And vast forests boreal<br/>
Midst wapiti and wild reindeer,<br/>
Lynx, stoat, squirrel, snowshoe, brown bear,<br/>
Lives a hermit in remembrance<br/>
Of old days and the explosion.  </p>
<p>Green the firs, bicoloured birches<br/>
Waving proudly in light wind;<br/>
Poplars shedding crimson catkins.<br/>
And the hermit, longing, silent<br/>
Standing lonely on the brink<br/>
Of tundra, opens weary eyes and sees.  </p>
<p>Oak trees bending, whipping back;<br/>
Barks then tinged by hellish fire,<br/>
Songbirds in a sky of black.<br/>
The mushroom cloud, the ball of red:<br/>
People fleeing, hoping, dying,<br/>
To the church walls shadows burnt.  </p>
<p>In the seas the water boiling,<br/>
Blistering from the reflection<br/>
Of the short-lived man-made sun.<br/>
Uriel in heaven crying,<br/>
Mourning loss of the creation<br/>
That, in war, unmade itself.  </p>
<p>No more seasons, only winter;<br/>
Everlasting winter, with grey soot<br/>
Like snowflakes falling gently<br/>
Down to blackened soil; a Hell<br/>
on Earth, forever dead and frozen.<br/>
Upon mankind a shadow cast.  </p>
<p>So the hermit with his gas mask,<br/>
Breathing filters and asbestos<br/>
Makes his way, past sickly tree stumps,<br/>
Past the rotten flesh, past poison<br/>
Past the hollow shells of old<br/>
Through miasma to catharsis;  </p>
<p>Through the lowland of the taiga;<br/>
In vast graveyards boreal<br/>
Midst wapiti and dead reindeer,<br/>
Lynx, stoat, squirrel, snowshoe, brown bear,<br/>
Through miasma past the tombstones<br/>
Past the unmarked grave and carcass.  </p>
<p>Face turned west another fire,<br/>
Older still than the creation;<br/>
Shimmering subtly, orange, crimson<br/>
Through the clouds and casting rays<br/>
Upon the rolling hills afar,<br/>
Lights like ghostly sirens calling.  </p>
<p>And the harp, resurging music,<br/>
Calming shadows, living beings,<br/>
Forests, meadows, nature, beauty!<br/>
From that subtle light display<br/>
Made the hermit so resentful<br/>
And envious of death&#8217;s embrace.  </p>
<p>Far away inside a bunker<br/>
Beneath the old charred earth forgotten<br/>
Lies dormant in a silo still<br/>
The array of rockets primed;<br/>
Awaiting silent, patient, stoic<br/>
An end, and the explosion.  </p>
	</section>
</article></div>
		</content>
	</entry>

</feed>


