<?xml version="1.0" encoding="UTF-8" standalone="no"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0">

<channel>
	<title>Something Odd!</title>
	<atom:link href="https://odd.blog/feed/" rel="self" type="application/rss+xml"/>
	<link>https://odd.blog</link>
	<description></description>
	<lastBuildDate>Sun, 12 Apr 2026 18:07:34 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://odd.blog/files/2019/11/cropped-2017-12-02-IMG_4918-m-32x32.jpg</url>
	<title>Something Odd!</title>
	<link>https://odd.blog</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">70615218</site>	<itunes:explicit>no</itunes:explicit><itunes:image href="http://i9.tinypic.com/4y7cu1x.jpg"/><itunes:subtitle/><item>
		<title>Media Picker for Immich: Self-Hosted Photos in WordPress</title>
		<link>https://odd.blog/2026/04/12/media-picker-for-immich-self-hosted-photos-in-wordpress/</link>
					<comments>https://odd.blog/2026/04/12/media-picker-for-immich-self-hosted-photos-in-wordpress/#respond</comments>
		
		<dc:creator><![CDATA[Donncha]]></dc:creator>
		<pubDate>Sun, 12 Apr 2026 18:07:25 +0000</pubDate>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Immich]]></category>
		<category><![CDATA[WordPress plugin]]></category>
		<guid isPermaLink="false">https://odd.blog/?p=89592706</guid>

					<description><![CDATA[I&#8217;ve just released Media Picker for Immich on the WordPress.org plugin directory. It connects WordPress to a self-hosted Immich server so you can browse, search, and insert your photos and videos into posts without copying files around. Immich I run Immich at home. It&#8217;s where my photos now live. They&#8217;re organised, searchable, with facial recognition<a class="more-link" href="https://odd.blog/2026/04/12/media-picker-for-immich-self-hosted-photos-in-wordpress/">Continue reading <span class="screen-reader-text">"Media Picker for Immich: Self-Hosted Photos in WordPress"</span></a>

#Immich #WordPress #WordPressplugin]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;ve just released Media Picker for Immich on the WordPress.org plugin directory. It connects WordPress to a self-hosted <a href="https://immich.app/">Immich</a> server so you can browse, search, and insert your photos and videos into posts without copying files around.</p>



<h3 class="wp-block-heading">Immich</h3>



<p>I run Immich at home. It&#8217;s where my photos now live. They&#8217;re  organised, searchable, with facial recognition and AI search. My WordPress uploads directory is where photos used to go, and the two never talked to each other. This plugin fixes that.</p>



<h3 class="wp-block-heading">How it works</h3>



<p>Point the plugin at your Immich server and give it an API key. You can set a site-wide key or let each user configure their own to connect to their own Immich account.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="ec7f80" data-has-transparency="false" style="--dominant-color: #ec7f80;" fetchpriority="high" decoding="async" width="727" height="478" data-attachment-id="89592707" data-permalink="https://odd.blog/2026/04/12/media-picker-for-immich-self-hosted-photos-in-wordpress/immich-settings-page/" data-orig-file="https://odd.blog/files/2026/04/immich-settings-page.avif" data-orig-size="727,478" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="immich-settings-page" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/immich-settings-page.avif" src="https://odd.blog/files/2026/04/immich-settings-page.avif" alt="Screenshot 1: Settings → Immich:
Server address and blank site-wide API key, default cache settings" class="wp-image-89592707 not-transparent"/></figure>
</div>


<p>If the site-wide key is blank, each user adds their own key on their profile page. All Immich API calls happen server-side.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="ec807f" data-has-transparency="false" style="--dominant-color: #ec807f;" decoding="async" width="607" height="194" data-attachment-id="89592708" data-permalink="https://odd.blog/2026/04/12/media-picker-for-immich-self-hosted-photos-in-wordpress/immich-user-profile-settings/" data-orig-file="https://odd.blog/files/2026/04/immich-user-profile-settings.avif" data-orig-size="607,194" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="immich-user-profile-settings" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/immich-user-profile-settings.avif" src="https://odd.blog/files/2026/04/immich-user-profile-settings.avif" alt="Screenshot 2: User Profile page, Immich API Key field showing *******." class="wp-image-89592708 not-transparent"/></figure>
</div>


<h3 class="wp-block-heading">Two ways to add media</h3>



<p>Once configured, an Immich tab appears in two places.</p>



<p>The first is the Media Library grid. Switch to the Immich view and you can search, filter by person, and either Use or Copy assets into WordPress.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="9a7e82" data-has-transparency="false" style="--dominant-color: #9a7e82;" decoding="async" width="1385" height="717" data-attachment-id="89592710" data-permalink="https://odd.blog/2026/04/12/media-picker-for-immich-self-hosted-photos-in-wordpress/media-picker2-2/" data-orig-file="https://odd.blog/files/2026/04/media-picker2-1.avif" data-orig-size="1385,717" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="media-picker2" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/media-picker2-1.avif" src="https://odd.blog/files/2026/04/media-picker2-1.avif" alt="Screenshot 3: Media → Library, Immich view." class="wp-image-89592710 not-transparent" srcset="https://odd.blog/files/2026/04/media-picker2-1.avif 1385w, https://odd.blog/files/2026/04/media-picker2-1-1280x663.avif 1280w" sizes="(max-width: 1385px) 100vw, 1385px" /></figure>
</div>


<ul class="wp-block-list">
<li><strong>Use</strong> creates a virtual attachment. Nothing is copied; WordPress proxies the media from Immich on demand and caches it locally on first request. Your uploads directory stays lean.</li>



<li><strong>Copy</strong> downloads the original file into wp-content/uploads/ as a normal attachment.</li>
</ul>



<p>The same tab shows up in the &#8220;Select or Upload Media&#8221; dialog inside the post editor, so you can pull an Immich photo straight into a post without leaving the editor.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="b37c84" data-has-transparency="false" style="--dominant-color: #b37c84;" loading="lazy" decoding="async" width="1369" height="1115" data-attachment-id="89592711" data-permalink="https://odd.blog/2026/04/12/media-picker-for-immich-self-hosted-photos-in-wordpress/media-picker1/" data-orig-file="https://odd.blog/files/2026/04/media-picker1.avif" data-orig-size="1369,1115" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="media-picker1" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/media-picker1.avif" src="https://odd.blog/files/2026/04/media-picker1.avif" alt="Screenshot 4: Select or Upload Media dialog, Immich tab." class="wp-image-89592711 not-transparent" srcset="https://odd.blog/files/2026/04/media-picker1.avif 1369w, https://odd.blog/files/2026/04/media-picker1-1280x1043.avif 1280w" sizes="auto, (max-width: 1369px) 100vw, 1369px" /></figure>
</div>


<h3 class="wp-block-heading">A few details worth mentioning</h3>



<ul class="wp-block-list">
<li>Videos work too. Proxied videos stream with seek support.</li>



<li>Lightbox. Proxied Immich images in posts open a full-resolution lightbox on click.</li>



<li>Local cache. Proxied media is cached to wp-content/cache/immich/ after the first fetch. Optional cleanup with a configurable lifetime.</li>



<li>Your server stays private. Immich only needs to be reachable from WordPress — not from the public internet. Visitors never connect to Immich directly.</li>



<li>When images are copied over, virtually or otherwise, you can insert them into a post like any other image, which also includes adding them to galleries in posts.</li>
</ul>



<h3 class="wp-block-heading">Get it</h3>



<p>Install it from the <a href="https://wordpress.org/plugins/media-picker-for-immich/">WordPress plugin directory</a> or search for &#8220;media picker for Immich&#8221; in the plugins page in WordPress.</p>



<p>Feedback and bug reports are welcome. Development is done on GitHub <a href="https://github.com/donnchawp/media-picker-for-immich">here</a>.</p>

#Immich #WordPress #WordPressplugin]]></content:encoded>
					
					<wfw:commentRss>https://odd.blog/2026/04/12/media-picker-for-immich-self-hosted-photos-in-wordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">89592706</post-id>	</item>
		<item>
		<title>Trenchangle: Tower Defense on the C64</title>
		<link>https://odd.blog/2026/04/08/trenchangle-tower-defense-on-the-c64/</link>
					<comments>https://odd.blog/2026/04/08/trenchangle-tower-defense-on-the-c64/#comments</comments>
		
		<dc:creator><![CDATA[Donncha]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 08:59:33 +0000</pubDate>
				<category><![CDATA[C64]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Zzap!64]]></category>
		<guid isPermaLink="false">https://odd.blog/?p=89592652</guid>

					<description><![CDATA[I picked up Issue 31 of Zzap! 64 yesterday evening and had a quick look at the covermount disk. There&#8217;s a few really good-looking games there but one that caught my eye was Trenchangle, a tower defense game! I&#8217;m a sucker for the genre, but it took me several tries to even finish level one.<a class="more-link" href="https://odd.blog/2026/04/08/trenchangle-tower-defense-on-the-c64/">Continue reading <span class="screen-reader-text">"Trenchangle: Tower Defense on the C64"</span></a>

#C64 #Games #Zzap64]]></description>
										<content:encoded><![CDATA[
<p>I picked up Issue 31 of <a href="https://www.patreon.com/zzapmagazine">Zzap! 64</a> yesterday evening and had a quick look at the covermount disk. There&#8217;s a few really good-looking games there but one that caught my eye was <a href="https://drmortalwombat.itch.io/trenchangle">Trenchangle</a>, a tower defense game!</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://odd.blog/files/2026/04/Screenshot-2026-04-08-at-10.01.14.avif"><img data-dominant-color="82c16e" data-has-transparency="false" style="--dominant-color: #82c16e;" loading="lazy" decoding="async" width="719" height="545" data-attachment-id="89592661" data-permalink="https://odd.blog/2026/04/08/trenchangle-tower-defense-on-the-c64/screenshot-2026-04-08-at-10-01-14/" data-orig-file="https://odd.blog/files/2026/04/Screenshot-2026-04-08-at-10.01.14.avif" data-orig-size="719,545" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2026-04-08 at 10.01.14" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/Screenshot-2026-04-08-at-10.01.14.avif" src="https://odd.blog/files/2026/04/Screenshot-2026-04-08-at-10.01.14.avif" alt="Zzap!64 disk with cute disk art!" class="wp-image-89592661 not-transparent"/></a></figure>
</div>


<figure data-carousel-extra='{&quot;blog_id&quot;:2,&quot;permalink&quot;:&quot;https://odd.blog/2026/04/08/trenchangle-tower-defense-on-the-c64/&quot;}'  class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img data-dominant-color="138080" data-has-transparency="false" style="--dominant-color: #138080;" loading="lazy" decoding="async" width="384" height="272" data-attachment-id="89592653" data-permalink="https://odd.blog/2026/04/08/trenchangle-tower-defense-on-the-c64/cvjqdr/" data-orig-file="https://odd.blog/files/2026/04/cvJQdR.avif" data-orig-size="384,272" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="cvJQdR" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/cvJQdR.avif" data-id="89592653" src="https://odd.blog/files/2026/04/cvJQdR.avif" alt="Welcome screen" class="wp-image-89592653 not-transparent"/></figure>



<figure class="wp-block-image size-large"><img data-dominant-color="2c8180" data-has-transparency="false" style="--dominant-color: #2c8180;" loading="lazy" decoding="async" width="384" height="272" data-attachment-id="89592654" data-permalink="https://odd.blog/2026/04/08/trenchangle-tower-defense-on-the-c64/kf5pik/" data-orig-file="https://odd.blog/files/2026/04/Kf5PIK.avif" data-orig-size="384,272" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Kf5PIK" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/Kf5PIK.avif" data-id="89592654" src="https://odd.blog/files/2026/04/Kf5PIK.avif" alt="gameplay" class="wp-image-89592654 not-transparent"/></figure>
</figure>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://odd.blog/files/2026/04/Screenshot-2026-04-08-at-14.32.31.avif"><img data-dominant-color="c17d81" data-has-transparency="false" style="--dominant-color: #c17d81;" loading="lazy" decoding="async" width="910" height="665" data-attachment-id="89592687" data-permalink="https://odd.blog/2026/04/08/trenchangle-tower-defense-on-the-c64/screenshot-2026-04-08-at-14-32-31/" data-orig-file="https://odd.blog/files/2026/04/Screenshot-2026-04-08-at-14.32.31.avif" data-orig-size="910,665" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2026-04-08 at 14.32.31" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/Screenshot-2026-04-08-at-14.32.31.avif" src="https://odd.blog/files/2026/04/Screenshot-2026-04-08-at-14.32.31.avif" alt="" class="wp-image-89592687 not-transparent"/></a></figure>
</div>


<p>I&#8217;m a sucker for the genre, but it took me several tries to even finish level one. I should have added arrows to the arrow tower instead of expanding the tech tree available. Lesson learned.</p>



<p>The game doesn&#8217;t require a joystick, and it&#8217;s possibly easier to play in an emulator because you can use the cursor keys to navigate. I couldn&#8217;t see anywhere to redefine keys so that joystick might make it easier to play on a real machine.</p>



<p>Game progress can be saved and reset, which means I&#8217;ll definitely be coming back to this game for quick plays. It looks like it saves in a file called &#8220;GEOTSTATE&#8221;, which wasn&#8217;t there when I first opened the D64 file so it can be deleted.</p>



<p>There is a cracked and trained copy on CSDB, but this is a brand new C64 game. Support the developer and pay what you want on <a href="https://drmortalwombat.itch.io/trenchangle">their itch.io page</a>.</p>

#C64 #Games #Zzap64]]></content:encoded>
					
					<wfw:commentRss>https://odd.blog/2026/04/08/trenchangle-tower-defense-on-the-c64/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">89592652</post-id>	</item>
		<item>
		<title>My First DMCA Notice</title>
		<link>https://odd.blog/2026/04/07/my-first-dmca-notice/</link>
					<comments>https://odd.blog/2026/04/07/my-first-dmca-notice/#comments</comments>
		
		<dc:creator><![CDATA[Donncha]]></dc:creator>
		<pubDate>Tue, 07 Apr 2026 16:03:02 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[copyright]]></category>
		<category><![CDATA[Cyanogenmod]]></category>
		<category><![CDATA[dmca]]></category>
		<category><![CDATA[google]]></category>
		<guid isPermaLink="false">https://odd.blog/?p=89592630</guid>

					<description><![CDATA[Awww, well look at that. This ancient post about using Cyanogenmod on the Galaxy S2 has been reported for copyright infringement to Google. Along with dozens of porn sites. I didn&#8217;t know Cyanogenmod was just a hot topic! Anyway, I&#8217;m not going to do anything about it, but I just wanted to mark the occasion.

#Android #copyright #Cyanogenmod #dmca #google]]></description>
										<content:encoded><![CDATA[
<p>Awww, well look at that.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="ec7f80" data-has-transparency="false" style="--dominant-color: #ec7f80;" loading="lazy" decoding="async" width="543" height="261" data-attachment-id="89592631" data-permalink="https://odd.blog/2026/04/07/my-first-dmca-notice/screenshot-2026-04-07-at-16-56-54/" data-orig-file="https://odd.blog/files/2026/04/Screenshot-2026-04-07-at-16.56.54.avif" data-orig-size="543,261" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2026-04-07 at 16.56.54" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/Screenshot-2026-04-07-at-16.56.54.avif" src="https://odd.blog/files/2026/04/Screenshot-2026-04-07-at-16.56.54.avif" alt="DMCA notice with the following text:

 Google notice regarding copyright-related content

To the owner of https://odd.blog/,

Google has been notified that your site allegedly infringes upon the copyrights of others and violates applicable copyright laws in your region.

It is Google's policy to remove copyrighted content when the copyright holder or their authorised representative alleges that a use is infringing. Therefore, we are in the process of removing the reported content from Google search results for users globally." class="wp-image-89592631 not-transparent"/></figure>
</div>


<p>This ancient post about using <a href="https://odd.blog/2013/04/01/yes-the-cyanogenmod-10-1-upgrade-is-worth-it/">Cyanogenmod on the Galaxy S2</a> has been reported for copyright <a href="https://lumendatabase.org/notices/82220771">infringement</a> to Google. Along with dozens of porn sites. I didn&#8217;t know Cyanogenmod was just a hot topic!</p>



<p>Anyway, I&#8217;m not going to do anything about it, but I just wanted to mark the occasion.</p>

#Android #copyright #Cyanogenmod #dmca #google]]></content:encoded>
					
					<wfw:commentRss>https://odd.blog/2026/04/07/my-first-dmca-notice/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">89592630</post-id>	</item>
		<item>
		<title>DolphinDOS 2: Fixing a 35-Year-Old Bug That Never Was</title>
		<link>https://odd.blog/2026/04/03/dolphindos-2-fixing-a-35-year-old-bug-that-never-was/</link>
					<comments>https://odd.blog/2026/04/03/dolphindos-2-fixing-a-35-year-old-bug-that-never-was/#respond</comments>
		
		<dc:creator><![CDATA[Donncha]]></dc:creator>
		<pubDate>Fri, 03 Apr 2026 18:00:29 +0000</pubDate>
				<category><![CDATA[C64]]></category>
		<category><![CDATA[Commodore 64]]></category>
		<category><![CDATA[DolphinDOS2]]></category>
		<guid isPermaLink="false">https://odd.blog/?p=89592600</guid>

					<description><![CDATA[DolphinDOS 2 is a replacement ROM for the Commodore 64 and its 1541 floppy disk drive that dramatically speeds up disk access by using a parallel cable between the two machines. Instead of the glacial CBM serial bus, data transfers happen byte-at-a-time over an 8-bit parallel port, making loads roughly 25x faster. I&#8217;ve been maintaining<a class="more-link" href="https://odd.blog/2026/04/03/dolphindos-2-fixing-a-35-year-old-bug-that-never-was/">Continue reading <span class="screen-reader-text">"DolphinDOS 2: Fixing a 35-Year-Old Bug That Never Was"</span></a>

#C64 #Commodore64 #DolphinDOS2]]></description>
										<content:encoded><![CDATA[
<p><a href="https://e4aws.silverdr.com/projects/dolphindos2/">DolphinDOS 2</a> is a replacement ROM for the Commodore 64 and its 1541 floppy disk drive that dramatically speeds up disk access by using a parallel cable between the two machines. Instead of the glacial CBM serial bus, data transfers happen byte-at-a-time over an 8-bit parallel port, making loads roughly 25x faster. I&#8217;ve been maintaining a <a href="https://github.com/donnchawp/DolphinDOS2">custom version</a> for myself. It changes the keys used to list the contents of disks and load programmes to match the Action Replay that I&#8217;m more familiar with.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="9cb072" data-has-transparency="false" style="--dominant-color: #9cb072;" loading="lazy" decoding="async" width="832" height="783" data-attachment-id="89592603" data-permalink="https://odd.blog/2026/04/03/dolphindos-2-fixing-a-35-year-old-bug-that-never-was/screenshot-2026-04-03-at-17-13-52/" data-orig-file="https://odd.blog/files/2026/04/Screenshot-2026-04-03-at-17.13.52.avif" data-orig-size="832,783" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2026-04-03 at 17.13.52" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/Screenshot-2026-04-03-at-17.13.52.avif" src="https://odd.blog/files/2026/04/Screenshot-2026-04-03-at-17.13.52.avif" alt="A Commodore 64 boot up screen saying
&quot;COMMODORE 64 BASIC V2
DOLPHINDOS 2.0 38911 BASIC BYTES FREE

READY.
" class="wp-image-89592603 not-transparent"/></figure>
</div>


<p>It also works in <a href="https://vice-emu.sourceforge.io/">Vice</a>, <a href="https://ultimate64.com/">Ultimate64</a> and <a href="https://www.commodore.net/">Commodore 64 Ultimate</a>!</p>



<p>While I <a href="https://odd.blog/2019/05/14/new-c64-adventures/">blogged about buying a real Commodore 64</a> in 2019, I didn&#8217;t post about buying an <a href="https://ultimate64.com/Ultimate64">Ultimate 64</a> a few months later. The version I have is the non-Elite version but it&#8217;s quite a wonderful device. Unfortunately, life got in the way and the machine lay mostly unused for years. I must make a post about that little beauty one of these days. Anyway &#8230;</p>



<p>I just released version 1.2 of my DolphinDOS 2 project, and there&#8217;s a bug fix for a seemingly rare problem: a bug in the original DolphinDOS 2 ROM from the late 1980s that almost certainly never manifested on real hardware. It seems so rare I&#8217;ve never read of anyone complaining about it on any C64-related Facebook group until this <a href="https://github.com/donnchawp/DolphinDOS2/issues/5">bug report</a> surfaced. The parallel port would randomly be switched off when a C64 Ultimate was switched on!</p>



<p>It was never my intention to go diving into the assembly of this project. I just wanted to change some keys around, but I had Claude Code look at it, with the relevant sections of the C64 Programmer&#8217;s Guide at hand for reference. I honestly don&#8217;t have time to fix a rare bug like this, but Claude did. Here&#8217;s what it said about the bug. I would be interested in hearing what C64 developers who have looked at the RAM in a real 1541 have to say.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>The 1541 drive ROM uses four flag bytes at $6000–$6003 in drive RAM to control DolphinDOS features: R (read), F (fast format), V (verify), and P (parallel port). A value of $12 means disabled; anything else means enabled. The original ROM never initialises these flags at boot. It relies on whatever happens to be in RAM when the drive powers on.</p>



<p>On a real 1541 with SRAM, that RAM almost always powers up as zeroes — so $6003 is never $12, and the parallel port is always enabled. It just works accidentally.</p>



<p>On the C64 Ultimate, the emulated 1541 RAM isn&#8217;t zeroed so predictably. Sometimes $6003 powers up containing $12, and the parallel port silently disables itself. A user reported that their C64 Ultimate was randomly booting with the parallel port off. That&#8217;s something that would never happen on the original hardware.</p>
</blockquote>



<p>The fix was simple enough, set the important memory locations to zero, although it took a couple of tries before it worked.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>The fix adds a small init routine at the end of the 1541 ROM&#8217;s free space that zeroes $6000–$6003 and sets the track interleave at $6023 during the drive&#8217;s boot sequence. The tricky part was that the 1541 ROM has a checksum that the drive verifies on startup. If it doesn&#8217;t match, the drive refuses to boot. The new jump target was chosen so its address bytes sum to the same value as the original, keeping the checksum valid without needing a separate compensation byte.</p>
</blockquote>



<p>Claude Code did the analysis and wrote the patch. I pointed it at the disassembly and the bug report, and it identified the uninitialised RAM as the root cause, found free space in the ROM, worked out the checksum constraint, and produced a working fix. The reporter tested it on their C64 Ultimate and confirmed it resolved the issue. I tested it in Vice and on my Ultimate64.</p>



<p><a href="https://github.com/donnchawp/DolphinDOS2/releases/tag/1.2">Other changes in 1.2</a>:</p>



<ul class="wp-block-list">
<li>Tapping F1 now auto-runs after loading: previously F1 loaded the first program from disk but left you at the READY prompt. Now it executes RUN automatically.</li>



<li>Cursor colour changed from cyan to white matching the look of the Action Replay I&#8217;m used to.</li>



<li>kernal.asm is now compilable. I converted it to ACME assembler format, so you can modify and rebuild the C64 kernal ROM from source.</li>



<li>Install instructions updated for the latest Ultimate64 firmware (which seems to match the C64 Ultimate instructions I found online).</li>
</ul>



<p>The <a href="https://github.com/donnchawp/DolphinDOS2/releases/tag/1.2">release</a> is on GitHub. If you&#8217;re running DolphinDOS 2 on an Ultimate64 or C64 Ultimate, it&#8217;s worth updating.</p>



<p>You can also find the original kernal files <a href="https://rr.pokefinder.org/wiki/File:Kernal_ROM_all_rr.c64.org_2021-02.rar">here</a>, along with different versions of them. My 1541.rom is based on the c1541-20-6.rom found there. My kernal.rom is based on kernal-20-2.rom. There is a third revision of that kernal rom too. I asked Claude to tell me what was different between them:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>kernal-20-2 vs kernal-20-3: What&#8217;s different</strong></p>



<p>The code is functionally almost identical. The 911 byte differences break down into a few categories:</p>



<ol class="wp-block-list">
<li><strong>The version byte at $FF80</strong><br>v2: $03<br>v3: $00<br>Confusingly, the &#8220;revision 2&#8221; ROM has version byte $03 and &#8220;revision 3&#8221; has $00. The filenames may not reflect the actual revision order — kernal-20-3 might actually be an earlier or alternate build.<br></li>



<li><strong>Code insertion at $EF5C: STOP key check (+5 bytes)</strong><br>The biggest functional difference. At the start of the parallel LOAD path, v3 inserts: <br><code>EF5C JSR $FFE1 ; STOP - check RUN/STOP key<br>EF5F BNE $EF5C ; loop if not pressed<br>EF61 BEQ $EF2E ; if pressed, abort<br></code>v2 has no STOP key check here — it jumps straight into the transfer. This 3-instruction insertion (5 bytes) shifts all the code that follows by 5 bytes, which accounts for the majority of the single-byte differences (they&#8217;re all branch targets and jump addresses adjusted by +5 or +6 to compensate for the shift).<br></li>



<li><strong>Parallel handshake: SEI added at $F841 (+1 byte)</strong><br>v3 adds SEI (disable interrupts) at the entry to the parallel handshake routine. v2 doesn&#8217;t disable interrupts. This shifts the code in that block by 1 byte and cascades into further address adjustments.<br></li>



<li><strong>Parallel transfer timeout: timer-based vs loop-based ($F910–$F968)</strong><br>This is the most interesting technical difference. Both ROMs have a timeout when waiting for the drive to respond during parallel detection, but they implement it differently: <br>v2 (loop-based):<br><code>F92E LDX #$13 ; outer counter<br>F932 LDA $DD0D ; check CIA2 interrupt flags<br>F935 AND #$10 ; FLAG pin set?<br>F937 BNE $F948 ; yes → drive responded<br>F939 DEX ; no → count down<br>F93A BNE $F932<br>F93C DEC $A5 ; nested loop<br>F93E BNE $F932<br></code>Uses a nested DEX/DEC loop (~5000 iterations) as a timeout. <br><br>v3 (CIA timer-based):<br><code>F931 LDA #$FF<br>F933 STA $DC07 ; Timer B high byte = $FF<br>F936 LDA #$19<br>F938 STA $DC0F ; Start timer B, one-shot<br>F93B LDA $DD0D ; check FLAG pin<br>F93E AND #$10<br>F940 BNE $F950 ; drive responded<br>F942 LDA $DC06 ; read timer low byte<br>F945 CMP $DC06 ; compare with itself (has it changed?)<br>F948 BNE $F93B ; timer still running → keep waiting</code><br>Uses CIA1 Timer B for a hardware-timed timeout. More precise and CPU-independent.<br></li>



<li><strong>Parallel fallback path: error handling ($F88B)</strong><br>v2: JSR $EE85 → falls into standard IEC byte receive<br>v3: LDA #$00; JMP $EE16 → explicitly loads zero and jumps to a different IEC entry point<br></li>



<li><strong>Serial LOAD: error recovery ($EFF1)</strong><br>v2: JMP $EFCF — unconditional jump to byte receive<br>v3: BCS $EFD4 — conditional branch on carry, only retries if carry set<br></li>



<li><strong>Data table pointer at $F0F1</strong><br>v2: BIT $DD0D (2C 0D DD)<br>v3: STX $DC0C (8E 0C DC)<br>Different CIA register access — v3 writes to the serial port register rather than reading the interrupt flags. This changes how the timer/shift register state is managed after a transfer.<br></li>



<li><strong>Jump table entries ($F8B1–$F8C9)</strong><br>Several address entries in what appears to be a function pointer table are shifted by +6 bytes, consistent with the cumulative code insertion offsets.<br></li>
</ol>



<p>Summary</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong>Change</strong></td><td><strong>v2 (your base)</strong> </td><td><strong>v3</strong></td></tr><tr><td>STOP key during parallel LOAD</td><td>No check</td><td>Polls STOP key</td></tr><tr><td>Interrupt disable on handshake</td><td>No SEI </td><td>SEI at entry</td></tr><tr><td>Parallel detect timeout</td><td>Software loop</td><td>CIA Timer B</td></tr><tr><td>Error recovery on serial fallback</td><td>Unconditional retry</td><td>Conditional on carry</td></tr><tr><td>Version byte $FF80</td><td>$03</td><td>$00</td></tr></tbody></table></figure>



<p>v3 appears to be a more defensive build — it adds interrupt protection, hardware-timed timeouts, and a STOP key escape during parallel transfers. These are the kinds of changes you&#8217;d make after encountering real-world reliability issues on certain hardware configurations.</p>



<p>Whether v3 is &#8220;better&#8221; depends on context. The CIA timer approach is more robust, but the STOP key polling loop at $EF5C is a tight busy-wait that could introduce latency. For the Ultimate64&#8217;s emulated parallel port, which is inherently reliable, v2&#8217;s simpler approach is probably fine.</p>
</blockquote>



<p>Looks like version 2 of the 1541 kernal rom is fine for our use case.</p>



<p>I&#8217;m using Claude Code in my work at Automattic all the time. It&#8217;s been a huge help in getting through bug fixes and adding new features to the various projects I&#8217;m working on. I&#8217;ll be posting more about WordPress related goodness soon. Stay tuned.</p>



<p></p>

#C64 #Commodore64 #DolphinDOS2]]></content:encoded>
					
					<wfw:commentRss>https://odd.blog/2026/04/03/dolphindos-2-fixing-a-35-year-old-bug-that-never-was/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">89592600</post-id>	</item>
		<item>
		<title>The Venice of the North Rises Again</title>
		<link>https://odd.blog/2026/04/01/the-venice-of-the-north-rises-again/</link>
					<comments>https://odd.blog/2026/04/01/the-venice-of-the-north-rises-again/#comments</comments>
		
		<dc:creator><![CDATA[Donncha]]></dc:creator>
		<pubDate>Wed, 01 Apr 2026 17:05:35 +0000</pubDate>
				<category><![CDATA[Ireland]]></category>
		<category><![CDATA[AI art]]></category>
		<category><![CDATA[April Fools]]></category>
		<category><![CDATA[canals]]></category>
		<category><![CDATA[cork]]></category>
		<category><![CDATA[Cork City Council]]></category>
		<category><![CDATA[satire]]></category>
		<category><![CDATA[St Patrick Street]]></category>
		<category><![CDATA[Venice of the North]]></category>
		<category><![CDATA[Washington Street]]></category>
		<guid isPermaLink="false">https://odd.blog/?p=89592582</guid>

					<description><![CDATA[Well, I have to hand it to Cork City Council. After years of roadworks, diversions, temporary traffic lights, and that perpetual stretch of Patrick Street that looked like a minor archaeological dig, they&#8217;ve finally revealed the masterplan and it&#8217;s magnificent. They&#8217;ve ripped out the tarmac entirely and restored the old channels of the River Lee<a class="more-link" href="https://odd.blog/2026/04/01/the-venice-of-the-north-rises-again/">Continue reading <span class="screen-reader-text">"The Venice of the North Rises Again"</span></a>

#AIart #AprilFools #canals #cork #CorkCityCouncil #Ireland #satire #StPatrickStreet #VeniceoftheNorth #WashingtonStreet]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="86827d" data-has-transparency="false" style="--dominant-color: #86827d;" loading="lazy" decoding="async" width="1536" height="1024" data-attachment-id="89592583" data-permalink="https://odd.blog/2026/04/01/the-venice-of-the-north-rises-again/cork-st-patrick-street/" data-orig-file="https://odd.blog/files/2026/04/cork-st-patrick-street.avif" data-orig-size="1536,1024" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="cork-st-patrick-street" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/cork-st-patrick-street.avif" src="https://odd.blog/files/2026/04/cork-st-patrick-street.avif" alt="AI-manipulated photo of St. Patrick Street in Cork city with the road replaced by a canal filled with boats including motorboats and a small rowing boat, with pedestrians walking along the quayside past shops including Barter, with trees and street furniture lining the waterway." class="wp-image-89592583 not-transparent" srcset="https://odd.blog/files/2026/04/cork-st-patrick-street.avif 1536w, https://odd.blog/files/2026/04/cork-st-patrick-street-1280x853.avif 1280w" sizes="auto, (max-width: 1536px) 100vw, 1536px" /></figure>
</div>


<p></p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="647f84" data-has-transparency="false" style="--dominant-color: #647f84;" loading="lazy" decoding="async" width="1536" height="1024" data-attachment-id="89592585" data-permalink="https://odd.blog/2026/04/01/the-venice-of-the-north-rises-again/boats-on-washington-street-2/" data-orig-file="https://odd.blog/files/2026/04/boats-on-washington-street-1.avif" data-orig-size="1536,1024" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="boats-on-washington-street" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/04/boats-on-washington-street-1.avif" src="https://odd.blog/files/2026/04/boats-on-washington-street-1.avif" alt="AI-manipulated photo of Washington Street in Cork city with the road replaced by a canal carrying boats including a blue narrowboat named &quot;ORIEL&quot;, a white rowing boat, and a blue motor launch with passengers in life jackets, with shops including Kida Hair and Razors Barber visible on either side, a green construction crane in the background, and a South Main Street sign on the right." class="wp-image-89592585 not-transparent" srcset="https://odd.blog/files/2026/04/boats-on-washington-street-1.avif 1536w, https://odd.blog/files/2026/04/boats-on-washington-street-1-1280x853.avif 1280w" sizes="auto, (max-width: 1536px) 100vw, 1536px" /></figure>
</div>


<p>Well, I have to hand it to Cork City Council. After years of roadworks, diversions, temporary traffic lights, and that perpetual stretch of Patrick Street that looked like a minor archaeological dig, they&#8217;ve finally revealed the masterplan and it&#8217;s magnificent. They&#8217;ve ripped out the tarmac entirely and restored the old channels of the River Lee that ran beneath the city centre for the past 240 years. St. Patrick Street is now navigable by motorboat, and Washington Street has a functioning canal service complete with what appears to be a narrowboat called the Oriel running a shuttle to the courthouse.</p>



<p>Parking signs have been replaced by mooring cleats. The 220 bus route now terminates at a floating pontoon outside Penneys. I&#8217;m told that Eason&#8217;s is doing a roaring trade in waterproof editions, and a new Dublin Bikes-style scheme called &#8220;Cork Canoes&#8221; launches next week, but knowing the council, the docking stations won&#8217;t be ready for another while yet.</p>



<p>In fairness, they&#8217;ve finally earned the title. Cork: the Venice of the North. Truly, the real capital at last.</p>



<p><em>Happy April Fools&#8217; Day. These images were obviously generated using AI. Cork City Council has not, to my knowledge, flooded the city, but after some winters, nature has a good go at it herself.</em></p>

#AIart #AprilFools #canals #cork #CorkCityCouncil #Ireland #satire #StPatrickStreet #VeniceoftheNorth #WashingtonStreet]]></content:encoded>
					
					<wfw:commentRss>https://odd.blog/2026/04/01/the-venice-of-the-north-rises-again/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">89592582</post-id>	</item>
		<item>
		<title>Stopping Web Server Abuse with Fail2Ban</title>
		<link>https://odd.blog/2026/03/26/stopping-web-server-abuse-with-fail2ban/</link>
					<comments>https://odd.blog/2026/03/26/stopping-web-server-abuse-with-fail2ban/#comments</comments>
		
		<dc:creator><![CDATA[Donncha]]></dc:creator>
		<pubDate>Thu, 26 Mar 2026 16:15:17 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Apache2]]></category>
		<category><![CDATA[fail2ban]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://odd.blog/?p=89592564</guid>

					<description><![CDATA[At 4am yesterday morning I was awake. Luckily so, as I checked my email and saw a warning that my VPS had been running at 199% CPU for two hours. I went into my office and checked the logs. Someone had been hammering this site with HEAD requests since just after midnight with nearly 30,000<a class="more-link" href="https://odd.blog/2026/03/26/stopping-web-server-abuse-with-fail2ban/">Continue reading <span class="screen-reader-text">"Stopping Web Server Abuse with Fail2Ban"</span></a>

#Apache2 #fail2ban #WordPress]]></description>
										<content:encoded><![CDATA[
<p>At 4am yesterday morning I was awake. Luckily so, as I checked my email and saw a warning that my VPS had been running at 199% CPU for two hours. I went into my office and checked the logs. Someone had been hammering this site with HEAD requests since just after midnight with nearly 30,000 requests across different URLs in four hours.</p>



<p>If they&#8217;d hit the same page repeatedly, cached responses would have handled it. But by requesting thousands of distinct URLs, each request generated a fresh cache file, forcing PHP and the database to do real work every time. My small server was coping, but the load average was high.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="ee847b" data-has-transparency="false" style="--dominant-color: #ee847b;" loading="lazy" decoding="async" width="634" height="382" data-attachment-id="89592566" data-permalink="https://odd.blog/2026/03/26/stopping-web-server-abuse-with-fail2ban/screenshot-2026-03-25-at-04-02-48/" data-orig-file="https://odd.blog/files/2026/03/Screenshot-2026-03-25-at-04.02.48.avif" data-orig-size="634,382" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2026-03-25 at 04.02.48" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/03/Screenshot-2026-03-25-at-04.02.48.avif" src="https://odd.blog/files/2026/03/Screenshot-2026-03-25-at-04.02.48.avif" alt="" class="wp-image-89592566 not-transparent"/></figure>
</div>


<p>I blocked the offending IP in .htaccess immediately. That stopped requests from reaching PHP, but I wanted a proper defence, something that would catch this kind of abuse automatically next time.</p>



<p>I already had Fail2Ban installed. I&#8217;d just never configured it for web server attacks. Time to do that.</p>



<p><a href="https://github.com/fail2ban/fail2ban">Fail2Ban</a> works by watching log files for patterns, then banning IPs that match too often. I needed two files: a filter to match Apache access log lines, and a jail to define the thresholds.</p>



<p>First, the filter at /etc/fail2ban/filter.d/apache-ratelimit.conf:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
&#x5B;Definition]

# Matches any request line in Apache access log (combined/common format)
failregex = ^&amp;lt;HOST&gt; -.&quot;(GET|HEAD|POST|PUT|DELETE|OPTIONS) .

ignoreregex =
</pre></div>


<p>This matches every request in the log. </p>



<p>The jail decides what volume of requests counts as abuse. It lives at /etc/fail2ban/jail.d/apache-ratelimit.conf:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
&#x5B;apache-ratelimit]
enabled = true
filter = apache-ratelimit
logpath = /var/www/logs/access.log

# Triggers a ban after too many requests in a short window
maxretry = 500
findtime = 30

# Ban for 24 hours
bantime = 86400

# Use iptables to drop packets from banned IPs
banaction = iptables-multiport
port = http,https
protocol = tcp

# Allowlist trusted networks
ignoreip = 127.0.0.1
</pre></div>


<p>The logic: if a single IP makes more than 500 requests in 30 seconds then ban it for 24 hours. Adjust maxretry and findtime to suit your traffic patterns. Legitimate crawlers and real users won&#8217;t come close to these numbers, but an attacker blasting thousands<br>of requests will trip the threshold fast. These are not the numbers I&#8217;m using.</p>



<p>The ignoreip directive keeps trusted networks (monitoring services, your own IPs) from getting caught.</p>



<p>The changes to Fail2Ban are activated with the following command (as root):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
systemctl restart fail2ban
</pre></div>


<p>And I verified it was running by checking the status:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
fail2ban-client status apache-ratelimit
</pre></div>


<p>Within a couple of minutes, the offending IP appeared in the banned list. I checked the access log, and there was nothing more from that IP. The requests weren&#8217;t just being rejected by Apache; iptables was dropping the packets before they reached the web server at all.<br>That&#8217;s the key advantage over an .htaccess block: banned traffic never touches Apache.</p>



<p>A VPS with limited resources can&#8217;t absorb a flood of uncached requests. Caching helps with repeat visits to the same page, but an attacker who rotates URLs defeats that entirely. Fail2Ban shifts the defence from the application layer down to the network<br>layer, where it&#8217;s cheap to enforce.</p>



<p>If you run a small site on a VPS, configure fail2ban for your web server. It takes ten minutes and it works.</p>



<p>Anyway, I presume whoever did that attack is reading this post since they seem to like my blog so much. Why did you do it?</p>

#Apache2 #fail2ban #WordPress]]></content:encoded>
					
					<wfw:commentRss>https://odd.blog/2026/03/26/stopping-web-server-abuse-with-fail2ban/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">89592564</post-id>	</item>
		<item>
		<title>I’m Deleting Google Photos</title>
		<link>https://odd.blog/2026/03/13/im-deleting-google-photos/</link>
					<comments>https://odd.blog/2026/03/13/im-deleting-google-photos/#comments</comments>
		
		<dc:creator><![CDATA[Donncha]]></dc:creator>
		<pubDate>Fri, 13 Mar 2026 13:42:33 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[Google Photos]]></category>
		<category><![CDATA[Photos]]></category>
		<category><![CDATA[tech]]></category>
		<guid isPermaLink="false">https://odd.blog/?p=89592534</guid>

					<description><![CDATA[If you look at r/googlephotos on Reddit you&#8217;ll come across several posts from people who have had their accounts banned because of photos they have in their accounts. Most of the time it&#8217;s because of family photos of children. I have also seen posts from people who unwisely backed up their WhatsApp images folder, or<a class="more-link" href="https://odd.blog/2026/03/13/im-deleting-google-photos/">Continue reading <span class="screen-reader-text">"I&#8217;m Deleting Google Photos"</span></a>

#google #GooglePhotos #Photos #tech]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="e2877b" data-has-transparency="false" style="--dominant-color: #e2877b;" loading="lazy" decoding="async" width="320" height="69" data-attachment-id="89592536" data-permalink="https://odd.blog/2026/03/13/im-deleting-google-photos/screenshot-2026-03-13-at-12-59-52/" data-orig-file="https://odd.blog/files/2026/03/Screenshot-2026-03-13-at-12.59.52.avif" data-orig-size="320,69" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2026-03-13 at 12.59.52" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/03/Screenshot-2026-03-13-at-12.59.52.avif" src="https://odd.blog/files/2026/03/Screenshot-2026-03-13-at-12.59.52.avif" alt="popup dialog saying &quot;Moving 3290 to bin...&quot; with a progress meter" class="wp-image-89592536 not-transparent"/></figure>
</div>


<p>If you look at <a href="https://www.reddit.com/r/googlephotos/">r/googlephotos on Reddit</a> you&#8217;ll come across several posts from people who have had their accounts banned because of photos they have in their accounts. Most of the time it&#8217;s because of family photos of children. I have also seen posts from people who unwisely backed up their WhatsApp images folder, or backed up a drive without looking at what was on it first. Remember that researcher who lost their Google account because they had WWII Nazi documents in their Google Drive?</p>



<ul class="wp-block-list">
<li><a href="https://www.reddit.com/r/googlephotos/comments/1qu2mks/google_photos_disabled_my_entire_account_for_csam/">Google Photos disabled my entire account for “CSAM” — long‑term account with family photos. Has anyone else had this happen?</a></li>



<li><a href="https://www.reddit.com/r/googlephotos/comments/1rb5b81/google_just_banned_my_main_account_for_uploading/">Google just banned my main account for uploading a 10-year-old backup and is accusing me of CSAM.</a> (they got it back)</li>



<li><a href="https://www.reddit.com/r/googlephotos/comments/1qn9flz/google_permanently_disabled_my_6year_account_over/?share_id=BGHLAKtmhU--WVsqhb7IA&amp;utm_medium=android_app&amp;utm_name=androidcss&amp;utm_source=share&amp;utm_term=1">Google permanently disabled my 6-year account over an alleged Child sexual abuse material (CSAM) violation — lost my income, banking access, and 6,000+ memories. What options do I have now?</a> (they got it back)</li>
</ul>



<p>I have photos there going back to the year 2000, but I never regarded Google Photos as a backup service. It was a fabulous photo-sharing site, but I have barely used it since 2024 and now have my own self-hosted Immich server instead.</p>



<p>Last week I did a Google Takeout of everything, just in case, as it will also download any photos I saved from shared albums.</p>



<p>Today I went to the <a href="https://photos.google.com/quotamanagement/large">large photos and videos page</a> and deleted almost every item off that page.</p>



<p>Unfortunately, there isn&#8217;t a &#8220;delete everything from Google Photos&#8221; button. You&#8217;ll have to visit photos.google.com and select an image and then scroll down, and down and down&#8230; and then with shift pressed, click on the last image to delete. It then may take some time for Google to mark the images as deleted.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="db857d" data-has-transparency="false" style="--dominant-color: #db857d;" loading="lazy" decoding="async" width="349" height="305" data-attachment-id="89592537" data-permalink="https://odd.blog/2026/03/13/im-deleting-google-photos/screenshot-2026-03-13-at-13-17-10/" data-orig-file="https://odd.blog/files/2026/03/Screenshot-2026-03-13-at-13.17.10.avif" data-orig-size="349,305" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2026-03-13 at 13.17.10" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/03/Screenshot-2026-03-13-at-13.17.10.avif" src="https://odd.blog/files/2026/03/Screenshot-2026-03-13-at-13.17.10.avif" alt="" class="wp-image-89592537 not-transparent"/></figure>
</div>


<p>Honestly, I expect that the automatic CSAM detection they&#8217;re using has already scanned every single photo I&#8217;ve uploaded so I&#8217;m not worried about that. I&#8217;m not uploading anything else there either, but I&#8217;ve been meaning to move off Google Photos entirely for a long time.</p>



<p>It is really difficult to do. In my head I know that I have a Takeout backup of everything. I know that all the original photos are on my computer at home, and they&#8217;re on Immich now, but selecting photos of familiar smiling faces, of birthday parties, of holidays and festivals, and then clicking DELETE is hard.</p>



<p>They&#8217;re my photos. It was nice knowing you Google Photos.</p>



<p>If you want an alternative, self-host <a href="https://immich.app/">Immich</a> or use <a href="https://pixelunion.eu/">Pixel Union</a>, a hosted version of Immich where you get 16GB free before you have to pay for more storage. It&#8217;s also hosted in the EU, which is even better! I have an account there. I uploaded a few recent photos <a href="https://donncha.pixelunion.eu/share/LbWDl-TRSlYP-GGaLz8-w37n_0ZixN6d1QdZtYrt6Cw_dnblIRRtfETfPNKB12jznK0">in this album</a> for you to see what it looks like.</p>

#google #GooglePhotos #Photos #tech]]></content:encoded>
					
					<wfw:commentRss>https://odd.blog/2026/03/13/im-deleting-google-photos/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">89592534</post-id>	</item>
		<item>
		<title>The Enshittificator</title>
		<link>https://odd.blog/2026/03/02/the-enshittificator/</link>
					<comments>https://odd.blog/2026/03/02/the-enshittificator/#respond</comments>
		
		<dc:creator><![CDATA[Donncha]]></dc:creator>
		<pubDate>Mon, 02 Mar 2026 19:37:06 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[enshittification]]></category>
		<guid isPermaLink="false">https://odd.blog/?p=89592511</guid>

					<description><![CDATA[He comes from a family with a proud tradition of enshittification, making the world worse. Here is how platforms die: first, they are good to their users; then they abuse their users to make things better for their business customers; finally, they abuse those business customers to claw back all the value for themselves. Then,<a class="more-link" href="https://odd.blog/2026/03/02/the-enshittificator/">Continue reading <span class="screen-reader-text">"The Enshittificator"</span></a>

#enshittification]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed aligncenter is-type-video is-provider-vimeo wp-block-embed-vimeo wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="The Enshittificator" src="https://player.vimeo.com/video/1168468796?dnt=1&amp;app_id=122963" width="750" height="422" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share" referrerpolicy="strict-origin-when-cross-origin"></iframe>
</div></figure>



<p>He comes from a family with a proud tradition of enshittification, making the world worse.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Here is how platforms die: first, they are good to their users; then they abuse their users to make things better for their business customers; finally, they abuse those business customers to claw back all the value for themselves. Then, they die.</p>



<p>I call this enshittification, and it is a seemingly inevitable consequence arising from the combination of the ease of changing how a platform allocates value, combined with the nature of a &#8220;two sided market,&#8221; where a platform sits between buyers and sellers, holding each hostage to the other, raking off an ever-larger share of the value that passes between them.</p>



<p class="has-text-align-right"><a href="https://pluralistic.net/2023/01/21/potemkin-ai/">Cory Doctorow, 2023.</a></p>
</blockquote>



<p>You can also find it on <a href="https://www.youtube.com/watch?v=T4Upf_B9RLQ">YouTube</a>.</p>

#enshittification]]></content:encoded>
					
					<wfw:commentRss>https://odd.blog/2026/03/02/the-enshittificator/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">89592511</post-id>	</item>
		<item>
		<title>TIL there are people who can’t burp</title>
		<link>https://odd.blog/2026/02/26/til-there-are-people-who-cant-burp/</link>
					<comments>https://odd.blog/2026/02/26/til-there-are-people-who-cant-burp/#comments</comments>
		
		<dc:creator><![CDATA[Donncha]]></dc:creator>
		<pubDate>Thu, 26 Feb 2026 12:03:13 +0000</pubDate>
				<category><![CDATA[Health]]></category>
		<category><![CDATA[podcasts]]></category>
		<category><![CDATA[vox]]></category>
		<guid isPermaLink="false">https://odd.blog/?p=89592503</guid>

					<description><![CDATA[It never occurred to me that a person couldn&#8217;t burp, but it&#8217;s a rare condition that was only diagnosed in the last ten years. The host of Vox podcast Unexplainable, Sally Helms suffers from this condition and shared how it affected her life, and how a simple Botox injection to the upper esophageal sphincter in<a class="more-link" href="https://odd.blog/2026/02/26/til-there-are-people-who-cant-burp/">Continue reading <span class="screen-reader-text">"TIL there are people who can&#8217;t burp"</span></a>

#Health #podcasts #vox]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-rich is-provider-pocket-casts wp-block-embed-pocket-casts"><div class="wp-block-embed__wrapper">
<iframe title="Everyone does it. Why can’t I? - Unexplainable" src="https://pca.st/embed/g2zxc1o4" style="border: 0; border-radius: 8px; width: 100%; height: 200px;" allowfullscreen="true" frameborder="0"></iframe>
</div></figure>



<p>It never occurred to me that a person couldn&#8217;t burp, but it&#8217;s a rare condition that was only diagnosed in the last ten years. The host of Vox podcast Unexplainable, Sally Helms suffers from this condition and shared how it affected her life, and how a simple Botox injection to the upper esophageal sphincter in the throat, right behind the larynx, can cure it!</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="747687" data-has-transparency="false" style="--dominant-color: #747687;" loading="lazy" decoding="async" width="500" height="555" data-attachment-id="89592506" data-permalink="https://odd.blog/2026/02/26/til-there-are-people-who-cant-burp/its-true-v0-vu1qud1firkg1/" data-orig-file="https://odd.blog/files/2026/02/its-true-v0-vu1qud1firkg1.avif" data-orig-size="500,555" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="its-true-v0-vu1qud1firkg1" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/02/its-true-v0-vu1qud1firkg1.avif" src="https://odd.blog/files/2026/02/its-true-v0-vu1qud1firkg1.avif" alt="" class="wp-image-89592506 not-transparent"/></figure>
</div>


<p>Another sufferer is a sky diver, which caused serious problems for him when he flew into the sky and couldn&#8217;t burp.</p>



<p>The show has a <a href="https://docs.google.com/document/d/11XCj4T6PZv6RGv346xnI1IqypeYvzo3il4LMLQz7cpc/edit">transcript</a>, which is worth looking at, if only for the adorable and wholesome times when Sally discovered her burps. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>SALLY: Okay, so also often during this time, I would like get into this really weird position. Like I would, I would do the basically like backing out in the car thing, but I would put my arm on the wall and then I would like, turn my head around and like, dip my chin and crank my head. Um, my family was very supportive, but they were also confused. Like, I burped while I was hanging out with my sister and my dad.</p>



<p>SALLY:  Are you proud of me?</p>



<p>ELIZA: That was a real burp!&nbsp;</p>



<p>SALLY: I just did a little sputter burp, and you heard, do you, are you proud?&nbsp;</p>



<p>ELIZA: Oh my God. Yeah. But why did you have to do it in that weird contortion?&nbsp;</p>



<p>SALLY: I have to to make it come out.</p>



<p>ELIZA: Wow.</p>



<p><em>&lt;&lt;burp&gt;&gt;</em></p>



<p><em>&lt;&lt;laughter&gt;&gt;</em></p>



<p>MARK HELM (SALLY’S DAD): Good going, Sal!</p>



<p>ELIZA: That was such a weird one!</p>



<p>MARK: Did it come out?&nbsp;</p>



<p>SALLY: Yeah. Well…</p>
</blockquote>



<p>BTW, if you suffer from this condition, join the <a href="https://www.reddit.com/r/noburp/">r/noburp</a> Reddit.</p>

#Health #podcasts #vox]]></content:encoded>
					
					<wfw:commentRss>https://odd.blog/2026/02/26/til-there-are-people-who-cant-burp/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">89592503</post-id>	</item>
		<item>
		<title>From Screen to Tmux to Zellij</title>
		<link>https://odd.blog/2026/02/18/from-screen-to-tmux-to-zellij/</link>
					<comments>https://odd.blog/2026/02/18/from-screen-to-tmux-to-zellij/#comments</comments>
		
		<dc:creator><![CDATA[Donncha]]></dc:creator>
		<pubDate>Wed, 18 Feb 2026 18:17:52 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[2016]]></category>
		<category><![CDATA[canon-6d]]></category>
		<category><![CDATA[cork]]></category>
		<category><![CDATA[Ireland]]></category>
		<category><![CDATA[Screen]]></category>
		<category><![CDATA[terminal]]></category>
		<category><![CDATA[tmux]]></category>
		<category><![CDATA[Zellij]]></category>
		<guid isPermaLink="false">https://odd.blog/?p=89592476</guid>

					<description><![CDATA[I used GNU screen for years. I don&#8217;t think alternatives existed when I started using. It worked everywhere, and I only needed a few features. Eventually, curiosity pushed me to try tmux a few years ago but I didn&#8217;t see what advantage it had over the older software I knew already, so I went back<a class="more-link" href="https://odd.blog/2026/02/18/from-screen-to-tmux-to-zellij/">Continue reading <span class="screen-reader-text">"From Screen to Tmux to Zellij"</span></a>

#2016 #canon6d #cork #Ireland #Screen #terminal #tmux #Zellij]]></description>
										<content:encoded><![CDATA[
<p>I used <a href="https://www.gnu.org/software/screen/">GNU screen</a> for years. I don&#8217;t think alternatives existed when I started using. It worked everywhere, and I only needed a few features.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="7f807e" data-has-transparency="false" style="--dominant-color: #7f807e;" loading="lazy" decoding="async" width="1280" height="853" data-attachment-id="89592478" data-permalink="https://odd.blog/2026/02/18/from-screen-to-tmux-to-zellij/photo-by-donncha-o-caoimh-http-inphotos-org-3/" data-orig-file="https://odd.blog/files/2026/02/2016-04-16-IMG_0696-m-1.avif" data-orig-size="1280,853" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;8&quot;,&quot;credit&quot;:&quot;Donncha O Caoimh&quot;,&quot;camera&quot;:&quot;Canon EOS 6D&quot;,&quot;caption&quot;:&quot;Photo by: Donncha O Caoimh (http://inphotos.org)&quot;,&quot;created_timestamp&quot;:&quot;1460820594&quot;,&quot;copyright&quot;:&quot;Donncha O Caoimh (http://inphotos.org/)&quot;,&quot;focal_length&quot;:&quot;50&quot;,&quot;iso&quot;:&quot;100&quot;,&quot;shutter_speed&quot;:&quot;0.0025&quot;,&quot;title&quot;:&quot;Photo by: Donncha O Caoimh (http://inphotos.org)&quot;,&quot;orientation&quot;:&quot;0&quot;,&quot;exposure_bias&quot;:&quot;0/1&quot;,&quot;flash&quot;:&quot;16&quot;}" data-image-title="Photo by: Donncha O Caoimh (http://inphotos.org)" data-image-description="" data-image-caption="&lt;p&gt;Photo by: Donncha O Caoimh (http://inphotos.org)&lt;/p&gt;
" data-large-file="https://odd.blog/files/2026/02/2016-04-16-IMG_0696-m-1.avif" src="https://odd.blog/files/2026/02/2016-04-16-IMG_0696-m-1.avif" alt="The insides of an old PC thrown on the ground outside. Weathered." class="wp-image-89592478 not-transparent"/></figure>
</div>


<p></p>



<p>Eventually, curiosity pushed me to try <a href="https://github.com/tmux/tmux/wiki">tmux</a> a few years ago but I didn&#8217;t see what advantage it had over the older software I knew already, so I went back to screen. </p>



<p>So it went for several years, until in the last few days I decided to try tmux again, and I even configured it to use the same CTRL-a shortcut as screen and it worked well! I configured it to switch between tabs like in screen using the 1-0 keys. I could scroll back, just like in screen. It even had a session manager that let me choose which tab to use, although I&#8217;m annoyed I had to tap right arrow to expand the list first.</p>



<p>I announced on Slack that I was moving to tmux, and shortly after, someone casually asked, &#8220;if you are doing the switch now, have you tried <a href="https://zellij.dev">zellij</a>?&#8221;</p>



<p><strong>Life with screen</strong></p>



<p>My screen usage was almost aggressively simple:</p>



<ul class="wp-block-list">
<li>Ctrl-a c to create a new window</li>



<li>Ctrl-a 1–0 to jump between windows</li>



<li>Ctrl-a a to toggle to the last window</li>



<li>ESC and page up to view the scroll back.</li>
</ul>



<p>That was it, but I used it all the time. The first thing I did on connecting to a server was <code>screen -D -r</code> to connect to screen.</p>



<p>I wasn’t using splits. I wasn’t scripting layouts. Screen was effectively a tab manager for shells, and it did that job reliably for decades. It&#8217;s still running like that on my servers, for the moment.</p>



<p><strong>Moving to tmux</strong></p>



<p>The first pleasant surprise was that tmux doesn’t force you to relearn anything.</p>



<p>With a small config change, tmux can behave almost exactly like screen:</p>



<ul class="wp-block-list">
<li><code>Ctrl-a</code> prefix</li>



<li>number-based window switching</li>



<li>last-window toggle</li>



<li>better copy/paste</li>



<li>better session handling</li>
</ul>



<p>At that point, tmux felt like screen, <a href="https://github.com/tmux/tmux/commits/master/">but actively maintained</a>. Tmux felt like the natural evolution of screen. I only used it for a day or so, but then I tried Zellij.</p>



<p><strong>Discovering Zellij</strong></p>



<p>Zellij describes itself as a &#8220;Terminal Workspace with Batteries Included&#8221;. Zellij doesn’t feel like a screen or tmux replacement. It is quite different. Instead of a simple bar at the end of the screen showing the tabs, there&#8217;s a menu with keys. Tapping the key combination updates the menu, showing new options. At the top of the screen are the tabs you&#8217;ll use. Unlike screen and tmux, there&#8217;s no one single shortcut like CTRL-a or CTRL-b, there are multiple. There&#8217;s one for each mode: panes, tabs, search and session (plus a few more).</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="3d7f81" data-has-transparency="false" style="--dominant-color: #3d7f81;" loading="lazy" decoding="async" width="899" height="34" data-attachment-id="89592480" data-permalink="https://odd.blog/2026/02/18/from-screen-to-tmux-to-zellij/screenshot-2026-02-18-at-18-08-22/" data-orig-file="https://odd.blog/files/2026/02/Screenshot-2026-02-18-at-18.08.22.avif" data-orig-size="899,34" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2026-02-18 at 18.08.22" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/02/Screenshot-2026-02-18-at-18.08.22.avif" src="https://odd.blog/files/2026/02/Screenshot-2026-02-18-at-18.08.22.avif" alt="" class="wp-image-89592480 not-transparent"/></figure>
</div>

<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-dominant-color="4a7e82" data-has-transparency="false" style="--dominant-color: #4a7e82;" loading="lazy" decoding="async" width="621" height="28" data-attachment-id="89592481" data-permalink="https://odd.blog/2026/02/18/from-screen-to-tmux-to-zellij/screenshot-2026-02-18-at-18-08-33/" data-orig-file="https://odd.blog/files/2026/02/Screenshot-2026-02-18-at-18.08.33.avif" data-orig-size="621,28" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2026-02-18 at 18.08.33" data-image-description="" data-image-caption="" data-large-file="https://odd.blog/files/2026/02/Screenshot-2026-02-18-at-18.08.33.avif" src="https://odd.blog/files/2026/02/Screenshot-2026-02-18-at-18.08.33.avif" alt="" class="wp-image-89592481 not-transparent"/></figure>
</div>


<p></p>



<p>The biggest conceptual shift is this: tmux is tab-first. Zellij is pane-first.</p>



<p>In tmux, I naturally created lots of windows, like I did with screen. I split one or two, but Zellij takes that to the next level. </p>



<p>In Zellij, the expectation is:</p>



<ul class="wp-block-list">
<li>One tab = one <em>context</em></li>



<li>Panes = the work inside that context</li>
</ul>



<p>This sounds subtle, but it changes everything. You&#8217;re encouraged to create new panes in each tab before you make new tabs.</p>



<p><strong>Discoverability over memorization</strong></p>



<p>Zellij uses modes (pane mode, tab mode, scroll mode), and it shows you available keys on screen.</p>



<p>You don’t need a cheat sheet taped to your monitor. You look down, and the UI tells you what’s possible.</p>



<p>This is something tmux simply doesn’t try to do.</p>



<p><strong>Pane-centric workflows</strong></p>



<p>Zellij really shines when you stop creating tabs constantly and instead:</p>



<ul class="wp-block-list">
<li>edit code in one pane</li>



<li>run or build in another</li>



<li>tail logs in a third</li>



<li>fullscreen a pane temporarily when you need focus</li>
</ul>



<p>It feels closer to an IDE or a tiling window manager than a tabbed terminal.</p>



<p><strong>Modern assumptions</strong></p>



<p>Zellij assumes:</p>



<ul class="wp-block-list">
<li>a modern terminal</li>



<li>Unicode support</li>



<li>decent fonts</li>



<li>OSC 52 clipboard support</li>
</ul>



<p>That’s great locally. I&#8217;ll be interested to see how well it works on my VPS.</p>



<p><strong>The Terminal</strong></p>



<p>I use iTerm2 on a Mac and there were a few things to set up before I could use Zellij fully.</p>



<ul class="wp-block-list">
<li>In <strong>Preferences → Profiles → (your profile) → Terminal</strong> make sure that &#8220;Mouse Reporting&#8221; is checked. That lets you click panes to select them, scroll up a pane, and select text to copy it.</li>



<li>Zellij uses the ALT key, but if you use CMD on a Mac the operating system will intercept that. Instead use the Option key. In <strong>Preferences → Profiles → Keys</strong> set &#8220;Left option key&#8221; to &#8220;Esc+&#8221;. That may interfere with copying and pasting though. Now type Option-n to open a new pane!</li>



<li>I was seeing odd characters in the UI. Little &#8220;?&#8221; characters in boxes. I needed a new font: <code>brew install --cask font-jetbrains-mono-nerd-font</code><br>Then in <strong>Preferences → Profiles → Text</strong> set the font to &#8220;JetBrainsMono Nerd Font Mono&#8221; or whichever one you prefer. You may have to restart Zellij to see the change.</li>
</ul>



<p>This is barely touching the surface of what Zellij can do. If you use screen or tmux give it a go.</p>

#2016 #canon6d #cork #Ireland #Screen #terminal #tmux #Zellij]]></content:encoded>
					
					<wfw:commentRss>https://odd.blog/2026/02/18/from-screen-to-tmux-to-zellij/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">89592476</post-id>	</item>
	</channel>
</rss>