<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>elliot.science</title>
      <link>/</link>
      <description>personal notes</description>
      <generator>Zola</generator>
      <language>en_gb</language>
      <atom:link href="/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Wed, 27 May 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>OpenWrt, bringing joy and freedom to the router</title>
          <pubDate>Wed, 27 May 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>/post/openwrt-mx42/</link>
          <guid>/post/openwrt-mx42/</guid>
          <description xml:base="/post/openwrt-mx42/">&lt;h3 id=&quot;preface&quot;&gt;Preface&lt;&#x2F;h3&gt;
&lt;p&gt;The router is the single point of failure in any network, yet we are forced to rely on usually cheap, insecure black box proprietary firmware provided by hardware vendors and ISPs. These devices are often riddled with telemetry, tracking, and unnecessary services that compromise user privacy.&lt;&#x2F;p&gt;
&lt;p&gt;Software and hardware should be free and transparent, restrictive ideologies create closed gardens, slowing progress, security by obscurity and inevitably end up invading peoples privacy. Computers are supposed be a new world you can do anything in, but are being restricted more and more. By flashing &lt;strong&gt;OpenWrt&lt;&#x2F;strong&gt; on my Linksys SPNMX42 (it’s a rebranded MX4200v2), I reclaimed a large part of this back and improved the general browsing experience for my household. I replaced tracking with privacy-first solutions &lt;strong&gt;Stubby&lt;&#x2F;strong&gt; and &lt;strong&gt;adblock-lean&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-hardware&quot;&gt;The Hardware&lt;&#x2F;h3&gt;
&lt;p&gt;The Linksys SPNMX42 is simply the Linksys MX4200v2 rebranded. Linksys provide a mediocre web interface with a few nice features, but also bloatware and poor navigation. The router comes with 1024MB of ram what is plent enough for adblock, stubby, WireGuard VPN&lt;&#x2F;p&gt;
&lt;p&gt;The chip on the system is a Qualcomm IPQ8174 (Hawkeye) which is a Quad-core ARM Cortex-A53 processor @ 1.4GHz&lt;&#x2F;p&gt;
&lt;p&gt;Tri-Band Wi-Fi 6 (802.11ax)&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2.4 GHz:&lt;&#x2F;strong&gt; 2×2 (QCN5024 + Skyworks SKY85340-11)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;5 GHz (Low-Band):&lt;&#x2F;strong&gt; 2×2 (QCN5054 + Skyworks SKY85755-11)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;5 GHz (High-Band):&lt;&#x2F;strong&gt; 4×4 (QCN5054 + Skyworks SKY85755-11)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Accessing Recovery Mode:&lt;&#x2F;strong&gt; Linksys allows manual firmware uploads, though the option is usually hidden until you scroll to the footer and select ‘CA’. In my case, my ISP blocked manual uploads entirely. I managed to work around this by applying a validated firmware update to roll the device back, which subsequently enabled the OpenWrt factory image upload.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Flashing:&lt;&#x2F;strong&gt; Upload the &lt;code&gt;openwrt-25.12.4-qualcommax-ipq807x-linksys_mx4200v2-squashfs-factory.bin&lt;&#x2F;code&gt; to the stock firmware’s recovery page. &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;firmware-selector.openwrt.org&#x2F;&quot;&gt;OpenWrt firmware selector&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LuCI:&lt;&#x2F;strong&gt; Once flashed, connect to the router at &lt;code&gt;192.168.1.1&lt;&#x2F;code&gt; (default) and log in via the LuCI web interface.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Configuration&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;dns-privacy-with-stubby-and-mullvad&quot;&gt;DNS Privacy with Stubby and Mullvad&lt;&#x2F;h4&gt;
&lt;p&gt;DNS queries are traditionally sent in cleartext, allowing ISPs and third parties to profile your browsing habits. To rectify this, I utilise Stubby, a lightweight DNS-over-TLS (DoT) client, combined with Mullvad’s DNS servers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;apk&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;apk&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; add stubby&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Edit the Stubby configuration file (&lt;code&gt;&#x2F;etc&#x2F;stubby&#x2F;stubby.yml&lt;&#x2F;code&gt;) to point to Mullvad’s encrypted DNS resolvers.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;resolution_type&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; GETDNS_RESOLUTION_STUB&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;round_robin_upstreams&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;appdata_dir&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; &amp;quot;&#x2F;var&#x2F;lib&#x2F;stubby&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;tls_authentication&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; GETDNS_AUTHENTICATION_REQUIRED&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;tls_query_padding_blocksize&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 128&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;edns_client_subnet_private&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;idle_timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 9000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;listen_addresses&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83C092;&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; 127.0.0.1@5453&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83C092;&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; 0::1@5453&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;dns_transport_list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83C092;&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; GETDNS_TRANSPORT_TLS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;upstream_recursive_servers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83C092;&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; address_data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 194.242.2.2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;    tls_auth_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; &amp;quot;dns.mullvad.net&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #83C092;&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; address_data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 194.242.2.3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;    tls_auth_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; &amp;quot;dns.mullvad.net&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;blocking-ads-and-trackers-with-adblock-lean&quot;&gt;Blocking Ads and Trackers with Adblock-lean&lt;&#x2F;h4&gt;
&lt;p&gt;Advertising networks often serve as vectors for malware and tracking scripts.&lt;&#x2F;p&gt;
&lt;p&gt;adblock-lean is a low maintenance (almost set and forget), powerful and ultra-efficient adblocking solution for OpenWrt that does not mandate any external dependencies or introduce unnecessary bloat.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;apk&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; add adblock-lean&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;By pointing &lt;code&gt;dnsforwarder&lt;&#x2F;code&gt; to &lt;code&gt;dnsmasq&lt;&#x2F;code&gt;, adblock-lean hijacks DNS lookups for known malicious and advertising domains, returning a null IP address. This prevents client devices from ever attempting to load the ad server, saving bandwidth and improving page load times.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Conclusion&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The combination of encrypted DNS via Stubby and network-wide ad blocking provides an improvement in both security and performance.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Building a Lightweight WireGuard Manager for Mullvad</title>
          <pubDate>Sat, 21 Mar 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>/post/mullvad-python/</link>
          <guid>/post/mullvad-python/</guid>
          <description xml:base="/post/mullvad-python/">&lt;h3 id=&quot;preface&quot;&gt;Preface&lt;&#x2F;h3&gt;
&lt;p&gt;This script was designed to provide a lightweight, scriptable alternative to the official mullvad client. The script only requires python3, wireguard-tools (for wg and wg-quick) and then doas&#x2F;sudo (required for system operations). Most systems come with python3 and sudo usually, only requiring WireGuard to be installed.&lt;&#x2F;p&gt;
&lt;p&gt;This was originally singular monolithic script written in bash, but quite quickly went past what you should in bash. The original was made as an alternative for no UI and no OpenVPN, since this time Mullvad has offically dropped OpenVPN in their official client, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mullvad.net&#x2F;en&#x2F;blog&#x2F;removing-openvpn-from-the-mullvad-vpn-app&quot;&gt;link to article.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;server-configuration&quot;&gt;Server Configuration&lt;&#x2F;h3&gt;
&lt;p&gt;The setup script, &lt;code&gt;mullvad-setup.py&lt;&#x2F;code&gt;, automates the process of fetching the relay list, generating keys, and writing configuration files to &lt;code&gt;&#x2F;etc&#x2F;wireguard&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The script fetches the latest server list from the Mullvad API:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;API_RELAYS_URL&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;quot;https:&#x2F;&#x2F;api.mullvad.net&#x2F;public&#x2F;relays&#x2F;wireguard&#x2F;v1&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; fetch_relays&lt;&#x2F;span&gt;&lt;span&gt;():&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;Fetches the list of WireGuard relays.&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;{CYAN}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;[+] Fetching server list from Mullvad...&lt;&#x2F;span&gt;&lt;span&gt;{NC}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;        with&lt;&#x2F;span&gt;&lt;span&gt; urllib&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;request&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;urlopen&lt;&#x2F;span&gt;&lt;span&gt;(API_RELAYS_URL)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; response:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;loads&lt;&#x2F;span&gt;&lt;span&gt;(response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;read&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;decode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;#39;utf-8&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    except&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; Exception&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; e:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;        error_exit&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;Unable to fetch relay list: &lt;&#x2F;span&gt;&lt;span&gt;{e}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It then iterates through the returned JSON to generate individual configuration files for each relay, assigning the user’s specific IP address and DNS settings:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; write_configs&lt;&#x2F;span&gt;&lt;span&gt;(relays_data:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; dict&lt;&#x2F;span&gt;&lt;span&gt;, private_key:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;, address:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;):&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;Generates configuration files for all relays.&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #859289;font-style: italic;&quot;&gt;    # ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    config_content&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;[Interface]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;PrivateKey = &lt;&#x2F;span&gt;&lt;span&gt;{private_key}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;Address = &lt;&#x2F;span&gt;&lt;span&gt;{address}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;DNS = &lt;&#x2F;span&gt;&lt;span&gt;{DNS_SERVER}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;[Peer]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;PublicKey = &lt;&#x2F;span&gt;&lt;span&gt;{pubkey}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;Endpoint = &lt;&#x2F;span&gt;&lt;span&gt;{ipv4}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;:51820&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;AllowedIPs = 0.0.0.0&#x2F;0, ::&#x2F;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;manager-script&quot;&gt;Manager Script&lt;&#x2F;h3&gt;
&lt;p&gt;The core manager (&lt;code&gt;src&#x2F;mullvad.py&lt;&#x2F;code&gt;) acts as a wrapper around &lt;code&gt;wg-quick&lt;&#x2F;code&gt; and the Mullvad verification API. It automatically handles privilege escalation via &lt;code&gt;doas&lt;&#x2F;code&gt; or &lt;code&gt;sudo&lt;&#x2F;code&gt; when required.&lt;&#x2F;p&gt;
&lt;p&gt;The connection logic verifies the server exists in the local cache before attempting to bring up the interface:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; connect&lt;&#x2F;span&gt;&lt;span&gt;(target_server:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt;) -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; bool&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;Connects to the specified server.&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    servers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; get_server_list&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; servers&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; and&lt;&#x2F;span&gt;&lt;span&gt; target_server&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; not in&lt;&#x2F;span&gt;&lt;span&gt; servers:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;{RED}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;Error: Server &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;{target_server}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;#39; not found in server list.&lt;&#x2F;span&gt;&lt;span&gt;{NC}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83C092;&quot;&gt; False&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #859289;font-style: italic;&quot;&gt;    # ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; run_command&lt;&#x2F;span&gt;&lt;span&gt;([&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;wg-quick&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;quot;up&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, config_path])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;verification&quot;&gt;Verification&lt;&#x2F;h4&gt;
&lt;p&gt;The tool includes a verification command that checks the connection against Mullvad’s API to ensure the tunnel is active:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;def&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; verify&lt;&#x2F;span&gt;&lt;span&gt;() -&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;Checks connection status via Mullvad API.&amp;quot;&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    try&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; urllib&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;request&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;urlopen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;#39;https:&#x2F;&#x2F;am.i.mullvad.net&#x2F;json&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;, timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; json&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;loads&lt;&#x2F;span&gt;&lt;span&gt;(response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;read&lt;&#x2F;span&gt;&lt;span&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;decode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;#39;utf-8&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        mullvad_exit_ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; data&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;#39;mullvad_exit_ip&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83C092;&quot;&gt; False&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #859289;font-style: italic;&quot;&gt;        # ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; mullvad_exit_ip:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;            print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;{GREEN}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;Connection Verified!&lt;&#x2F;span&gt;&lt;span&gt;{NC}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;            return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    except&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; Exception&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt; as&lt;&#x2F;span&gt;&lt;span&gt; e:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;        print&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;{RED}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;Verification failed: &lt;&#x2F;span&gt;&lt;span&gt;{e}{NC}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;        return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;usage&quot;&gt;Usage&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #859289;font-style: italic;&quot;&gt;# List available servers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;mullvad&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #859289;font-style: italic;&quot;&gt;# Connect to a specific server&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;mullvad&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; connect se-sto-wg-011&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #859289;font-style: italic;&quot;&gt;# Connect to a random server in a specific region (e.g., Sweden)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;mullvad&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; random se&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #859289;font-style: italic;&quot;&gt;# Verify the connection&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;mullvad&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; verify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;&lt;&#x2F;div&gt;
&lt;p&gt;&lt;strong&gt;Transition to Official Client&lt;&#x2F;strong&gt;: I have since transitioned from this custom Python script to the official Mullvad client. While the custom script served its purpose, the official client offers significant advantages for a production Gentoo environment.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Comparison Summary&lt;&#x2F;strong&gt;:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: left&quot;&gt;Feature&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Custom Python Script&lt;&#x2F;th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Official Mullvad Client&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Setup &amp;amp; Config&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;mullvad-setup.py&lt;&#x2F;code&gt; fetches list; generates &lt;code&gt;&#x2F;etc&#x2F;wireguard&#x2F;*.conf&lt;&#x2F;code&gt;.&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;mullvad-vpn&lt;&#x2F;code&gt; handles config generation and updates automatically.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Connection Handling&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Wrapper around &lt;code&gt;wg-quick&lt;&#x2F;code&gt; (&lt;code&gt;wg-quick up&#x2F;down&lt;&#x2F;code&gt;).&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Dedicated daemon handling interface bring-up&#x2F;down. With the upcoming addition of Mullvad’s transition to gotatun.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Firewalling&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Relies on system firewall (iptables&#x2F;nftables) configured separately.&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Built-in firewall rules to prevent traffic leaks before tunnel is active.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Kill Switch&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;None (requires external script).&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Native “Disconnect Killswitch” feature.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Relay Selection&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Manual or simple &lt;code&gt;random&lt;&#x2F;code&gt; command based on cached list.&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Robust selection logic (country, city, ISP, exit country, etc.).&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Verification&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Checks IP via &lt;code&gt;am.i.mullvad.net&#x2F;json&lt;&#x2F;code&gt; (manual).&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Built-in verification tool &lt;code&gt;mullvad status&lt;&#x2F;code&gt;.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;Maintenance&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Requires manual script updates and config cache refreshing.&lt;&#x2F;td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Managed via &lt;code&gt;portage&lt;&#x2F;code&gt; (Gentoo ebuilds) with dependency tracking.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;&#x2F;strong&gt;: The shift to the official client eliminates the need to maintain the Python script and the setup utility. It also ensures that security patches and relay updates are handled by the package manager, rather than relying on a local cache file. The native firewall integration provides better protection against accidental leaks during connection drops, which was a limitation of the &lt;code&gt;wg-quick&lt;&#x2F;code&gt; based approach.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Rename by Timestamp</title>
          <pubDate>Wed, 10 Sep 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>/post/rename-by-timestamp/</link>
          <guid>/post/rename-by-timestamp/</guid>
          <description xml:base="/post/rename-by-timestamp/">&lt;h3 id=&quot;preface&quot;&gt;Preface&lt;&#x2F;h3&gt;
&lt;p&gt;A lightweight C utility to batch-rename files based on their modification timestamp. It addresses the common workflow issue of disorganized downloads or exported media by enforcing a consistent &lt;code&gt;YYYY-MM-DD_HH-MM-SS&lt;&#x2F;code&gt; naming convention. The tool is designed to be non-destructive, skipping files that already match the expected timestamp format.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;timestamp-detection-logic&quot;&gt;Timestamp Detection Logic&lt;&#x2F;h3&gt;
&lt;p&gt;To prevent unnecessary operations or data loss, the utility includes a strict validation check before renaming. It inspects the first 19 characters of a filename to ensure they conform exactly to the target date-time format.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; is_timestamp_formatted&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; char&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;filename) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;strlen&lt;&#x2F;span&gt;&lt;span&gt;(filename)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;  for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 4&lt;&#x2F;span&gt;&lt;span&gt;; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;is_digit&lt;&#x2F;span&gt;&lt;span&gt;(filename[i]))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; (filename[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;#39;-&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; filename[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;#39;-&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; filename[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;#39;_&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; ||&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      filename[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;13&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;#39;-&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; filename[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;16&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;#39;-&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;  for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 5&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;+=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 3&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;is_digit&lt;&#x2F;span&gt;&lt;span&gt;(filename[i])&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; || !&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;is_digit&lt;&#x2F;span&gt;&lt;span&gt;(filename[i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt; return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If a file passes this check, the program compares the embedded timestamp against the actual &lt;code&gt;st_mtime&lt;&#x2F;code&gt; retrieved via &lt;code&gt;stat()&lt;&#x2F;code&gt;. If they match, the file is safely skipped.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;path-resolution-extensions&quot;&gt;Path Resolution &amp;amp; Extensions&lt;&#x2F;h3&gt;
&lt;p&gt;The utility carefully handles directory prefixes and file extensions. It isolates the base filename using &lt;code&gt;strrchr()&lt;&#x2F;code&gt; to locate the final &lt;code&gt;&#x2F;&lt;&#x2F;code&gt;. It then checks for an existing extension using &lt;code&gt;strrchr(filename, &#x27;.&#x27;)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The new path is constructed dynamically to preserve the directory structure:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;char&lt;&#x2F;span&gt;&lt;span&gt; new_path[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;512&lt;&#x2F;span&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (last_slash) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;    int&lt;&#x2F;span&gt;&lt;span&gt; dir_len &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; last_slash &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; filepath &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (dir_len &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;        snprintf&lt;&#x2F;span&gt;&lt;span&gt;(new_path,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; sizeof&lt;&#x2F;span&gt;&lt;span&gt;(new_path),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;%.*s%s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, dir_len, filepath, new_filename);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;        snprintf&lt;&#x2F;span&gt;&lt;span&gt;(new_path,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; sizeof&lt;&#x2F;span&gt;&lt;span&gt;(new_path),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, new_filename);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    snprintf&lt;&#x2F;span&gt;&lt;span&gt;(new_path,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; sizeof&lt;&#x2F;span&gt;&lt;span&gt;(new_path),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;%s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;, new_filename);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This ensures that files located in subdirectories retain their original parent paths while only the base name is altered.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;wildcard-support-via-globbing&quot;&gt;Wildcard Support via Globbing&lt;&#x2F;h3&gt;
&lt;p&gt;Unlike basic wrappers that only accept single paths, this utility leverages the POSIX &lt;code&gt;glob()&lt;&#x2F;code&gt; library. This allows seamless integration with shell expansion rules. The code detects wildcards (&lt;code&gt;*&lt;&#x2F;code&gt;, &lt;code&gt;?&lt;&#x2F;code&gt;, &lt;code&gt;[&lt;&#x2F;code&gt;) in the input argument and processes them as pattern sets.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; has_wildcard &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; strpbrk&lt;&#x2F;span&gt;&lt;span&gt;(pattern,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;quot;*?[&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; (has_wildcard) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;    glob_t&lt;&#x2F;span&gt;&lt;span&gt; g;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;glob&lt;&#x2F;span&gt;&lt;span&gt;(pattern, GLOB_TILDE,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; NULL&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;g)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;size_t&lt;&#x2F;span&gt;&lt;span&gt; j &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; j &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; g&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83C092;&quot;&gt;gl_pathc&lt;&#x2F;span&gt;&lt;span&gt;; j&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;            struct&lt;&#x2F;span&gt;&lt;span&gt; stat st;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;stat&lt;&#x2F;span&gt;&lt;span&gt;(g&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83C092;&quot;&gt;gl_pathv&lt;&#x2F;span&gt;&lt;span&gt;[j],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;st)&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; S_ISREG&lt;&#x2F;span&gt;&lt;span&gt;(st&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83C092;&quot;&gt;st_mode&lt;&#x2F;span&gt;&lt;span&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;                process_file&lt;&#x2F;span&gt;&lt;span&gt;(g&lt;&#x2F;span&gt;&lt;span style=&quot;color: #859289;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #83C092;&quot;&gt;gl_pathv&lt;&#x2F;span&gt;&lt;span&gt;[j]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;        globfree&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;g);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Directories are explicitly filtered out using &lt;code&gt;S_ISDIR()&lt;&#x2F;code&gt; checks before any system calls are made, ensuring the utility only operates on regular files.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;compilation-usage&quot;&gt;Compilation &amp;amp; Usage&lt;&#x2F;h3&gt;
&lt;p&gt;Built strictly with C99 standards and compiled with strict warning flags (&lt;code&gt;-Wall -Wextra -pedantic&lt;&#x2F;code&gt;), the utility is highly portable across POSIX-compliant systems.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #859289;font-style: italic;&quot;&gt;# Build&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #859289;font-style: italic;&quot;&gt;# Run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;.&#x2F;bin&#x2F;rename-by-timestamp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;.jpg&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;.txt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Makefile provides a clean &lt;code&gt;install&lt;&#x2F;code&gt; target that copies the binary to &lt;code&gt;&#x2F;usr&#x2F;local&#x2F;bin&lt;&#x2F;code&gt;, making it available system-wide.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Data Sorting Visualiser in SDL2</title>
          <pubDate>Thu, 21 Aug 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>/post/sdl2-data-visualiser/</link>
          <guid>/post/sdl2-data-visualiser/</guid>
          <description xml:base="/post/sdl2-data-visualiser/">&lt;h1 id=&quot;data-sorting-visualiser&quot;&gt;Data Sorting Visualiser&lt;&#x2F;h1&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;sorting-example&quot;&gt;&lt;img src=&quot;&#x2F;post&#x2F;sdl2-data-visualiser&#x2F;output.gif&quot; alt=&quot;sorting example&quot; &#x2F;&gt;&lt;&#x2F;h2&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h2&gt;
&lt;p&gt;A visual tool that demonstrates sorting algorithms using SDL2. This program shows the step-by-step process of various sorting algorithms as they sort a randomly generated array of bars.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;features&quot;&gt;Features&lt;&#x2F;h3&gt;
&lt;p&gt;The source code and build instructions are located on my &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;elliowo&#x2F;sdl2-data-sorting-visualiser&quot;&gt;Codeberg&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multiple Algorithms&lt;&#x2F;strong&gt;: Bubble, Insertion, Selection, Quick, Merge, Heap, Shell, Radix, and Bucket sorts&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Interactive Controls&lt;&#x2F;strong&gt;: Pause&#x2F;resume sorting, reset the array, and set algorithms&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Real-time Visualisation&lt;&#x2F;strong&gt;: Highlights comparisons and swaps dynamically&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Algorithm Comparison&lt;&#x2F;strong&gt;: Visualise algorithmic behaviour and progression&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;core-architecture&quot;&gt;Core Architecture&lt;&#x2F;h3&gt;
&lt;p&gt;The application is built around a single-threaded SDL2 event loop. The main loop continuously polls events and redraws the state. To prevent the UI from freezing during sorting, the sorting algorithms are invoked directly within the loop but are designed to be non-blocking through a callback-based rendering system.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;SDL_Event e;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; running &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;while&lt;&#x2F;span&gt;&lt;span&gt; (running) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    while&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;SDL_PollEvent&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;e)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #859289;font-style: italic;&quot;&gt;        &#x2F;&#x2F; Event handling...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; (sorting_in_progress &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt; sort_func) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;        sort_func&lt;&#x2F;span&gt;&lt;span&gt;(arr, n, swap_callback);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        sorting_in_progress &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;        recalc_max&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    render_bars&lt;&#x2F;span&gt;&lt;span&gt;(renderer, arr, n);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    SDL_Delay&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;rendering-pipeline&quot;&gt;Rendering Pipeline&lt;&#x2F;h3&gt;
&lt;p&gt;Bars are drawn relative to the maximum value in the current array to ensure full vertical utilization of the viewport. The renderer clears the screen each frame and iterates through the array, calculating bar height based on a normalized ratio.&lt;&#x2F;p&gt;
&lt;p&gt;Highlighting is handled dynamically. When a comparison or swap occurs, specific indices are marked. The renderer checks these indices to override the default white color with red, providing immediate visual feedback of the algorithm’s focus.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; render_bars&lt;&#x2F;span&gt;&lt;span&gt;(SDL_Renderer &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;renderer,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;arr,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; n) { &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    SDL_SetRenderDrawColor&lt;&#x2F;span&gt;&lt;span&gt;(renderer,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    SDL_RenderClear&lt;&#x2F;span&gt;&lt;span&gt;(renderer);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; n; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;        int&lt;&#x2F;span&gt;&lt;span&gt; bar_height &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;)((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;double&lt;&#x2F;span&gt;&lt;span&gt;)arr[i]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt; max_val &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; (WINDOW_HEIGHT &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt;));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        SDL_Rect bar &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .x &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt; bar_width,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .y &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; WINDOW_HEIGHT &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; bar_height,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .w &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; bar_width,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            .h &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; bar_height&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; (i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; highlight1 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;||&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;==&lt;&#x2F;span&gt;&lt;span&gt; highlight2) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;            SDL_SetRenderDrawColor&lt;&#x2F;span&gt;&lt;span&gt;(renderer,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;            SDL_SetRenderDrawColor&lt;&#x2F;span&gt;&lt;span&gt;(renderer,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 255&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;        SDL_RenderFillRect&lt;&#x2F;span&gt;&lt;span&gt;(renderer,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;bar);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    SDL_RenderPresent&lt;&#x2F;span&gt;&lt;span&gt;(renderer);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;abstraction-layer-function-pointers&quot;&gt;Abstraction Layer: Function Pointers&lt;&#x2F;h3&gt;
&lt;p&gt;A critical design choice is the decoupling of sorting logic from the rendering pipeline. Each sorting algorithm accepts a function pointer to a &lt;code&gt;swap_callback&lt;&#x2F;code&gt;. This allows the algorithm to purely focus on array manipulation while the main loop handles all SDL2 state updates.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; bubble_sort&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt;arr,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; n,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; void&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;*&lt;&#x2F;span&gt;&lt;span&gt;swap_callback)(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;    for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;        for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; j &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;; j &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; n &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt; i &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;; j&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;            if&lt;&#x2F;span&gt;&lt;span&gt; (arr[j]&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; arr[j &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;                swap_callback&lt;&#x2F;span&gt;&lt;span&gt;(j, j &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;                swap&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;arr[j],&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; &amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;arr[j &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;+&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;swap_callback&lt;&#x2F;code&gt; acts as the synchronization bridge between C memory operations and SDL2’s graphics context:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;void&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; swap_callback&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; i,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; int&lt;&#x2F;span&gt;&lt;span&gt; j) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    highlight1 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; i;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    highlight2 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; j;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    render_bars&lt;&#x2F;span&gt;&lt;span&gt;(renderer, arr, n);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    highlight1 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; highlight2 &lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;= -&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    SDL_Delay&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;algorithm-specific-implementation-details&quot;&gt;Algorithm-Specific Implementation Details&lt;&#x2F;h3&gt;
&lt;p&gt;While most comparison-based sorts (Bubble, Insertion, Selection) follow standard iterative patterns, divide-and-conquer algorithms required slight adaptations to remain compatible with the synchronous callback model.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;QuickSort&lt;&#x2F;strong&gt;: The recursive helper partitions the array around a pivot. Each swap during partitioning triggers the visual callback. The recursion continues until the sub-array is empty.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;MergeSort&lt;&#x2F;strong&gt;: Temporary arrays (&lt;code&gt;L&lt;&#x2F;code&gt; and &lt;code&gt;R&lt;&#x2F;code&gt;) are allocated for merging. The callback is invoked during the merge phase to reflect element placement, though note that MergeSort is fundamentally not a swap-based sort, so the visualization represents element movement rather than direct swaps.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;RadixSort &amp;amp; CountingSort&lt;&#x2F;strong&gt;: These non-comparison sorts operate on digit extraction or frequency mapping. Because they rearrange elements in bulk passes rather than pairwise comparisons, the visual feedback is less granular, appearing as bulk transitions between states.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;memory-management&quot;&gt;Memory Management&lt;&#x2F;h3&gt;
&lt;p&gt;The visualiser dynamically manages memory for algorithms that require auxiliary storage. &lt;code&gt;MergeSort&lt;&#x2F;code&gt; allocates temporary arrays on the heap for each merge operation, while &lt;code&gt;BucketSort&lt;&#x2F;code&gt; pre-allocates an array of pointers. Proper &lt;code&gt;free()&lt;&#x2F;code&gt; calls are integrated into the algorithm loops to prevent memory leaks during repeated array resets.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>How I do my Computing</title>
          <pubDate>Tue, 21 May 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>/post/dotfiles/</link>
          <guid>/post/dotfiles/</guid>
          <description xml:base="/post/dotfiles/">&lt;h1 id=&quot;preface&quot;&gt;Preface&lt;&#x2F;h1&gt;
&lt;p&gt;We all have a dream inside us of living indefinitely in the tty, but we live in Orwell’s society of Xorg and
Wayland display servers. I personally suffer in this society in Hyprland and Wayland. My build of Hyprland and
dotfiles can be found on my &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;elliowo&#x2F;dotfiles&quot;&gt;Codeberg&lt;&#x2F;a&gt;, additionally my Emacs and Gentoo configurations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;my-system-s&quot;&gt;My system(s)&lt;&#x2F;h2&gt;
&lt;p&gt;I use a few systems that replicate the same environment, to do so I use Syncthing and SSH. My main system is a custom build with specs below and a Thinkpad T480&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Operating System: All my system run Gentoo Linux&lt;&#x2F;li&gt;
&lt;li&gt;CPU: AMD Ryzen 5 5600X (12) @ 3.700GHz&lt;&#x2F;li&gt;
&lt;li&gt;GPU: AMD Radeon RX 7800 XT&lt;&#x2F;li&gt;
&lt;li&gt;Memory: 32017MiB&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;post&#x2F;dotfiles&#x2F;hyprland.png&quot; alt=&quot;terminal on desktop&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;software&quot;&gt;Software&lt;&#x2F;h3&gt;
&lt;p&gt;I want to be able to use my system whether I am connected to the internet or not. Software has too many calls to home
and loses an incredible amount of functionality when it is not able. My preference on software is that and Free, Libre or
Open Source in that order. I am willing to put in work or lose comfort features for this, so how I compute may seem
obscene to you.&lt;&#x2F;p&gt;
&lt;p&gt;I have preferences on the tools that are used to create the software I used. Software should be preferably compiled
and in a software such as C, C++, Rust and Zig this is because I have experience in these languages and can get my
hands dirty, if needed. I am also a big fan of tty applications despite using emacs&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Packages&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;shell - bash with &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;starship.rs&#x2F;&quot;&gt;starship&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;window manager - &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hyprland.org&#x2F;&quot;&gt;hyprland&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;terminal - &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ghostty.org&#x2F;&quot;&gt;ghostty&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;vpn - &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mullvad.net&#x2F;en&#x2F;download&#x2F;vpn&quot;&gt;mullvad&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;launcher - &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;dnkl&#x2F;fuzzel&quot;&gt;fuzzel&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;file manager - &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yazi-rs.github.io&#x2F;&quot;&gt;yazi&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;image viewer - &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;artemsen&#x2F;swayimg&quot;&gt;swayimg&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;bar - &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Alexays&#x2F;Waybar&quot;&gt;waybar&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;media player - &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mpv.io&#x2F;&quot;&gt;mpv&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;lockscreen - &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;JosefNemec&#x2F;hyprlock&quot;&gt;hyprlock&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;web browser - &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;zen-browser.app&#x2F;&quot;&gt;zen&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;text editor - &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;emacs&#x2F;&quot;&gt;emacs&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;status bar - waybar (json&#x2F;config)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Requires &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.nerdfonts.com&#x2F;&quot;&gt;nerdfonts&lt;&#x2F;a&gt; to view icons.\&lt;&#x2F;p&gt;
&lt;h4 id=&quot;emacs&quot;&gt;Emacs&lt;&#x2F;h4&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&quot;Emacs is a great Operating System, but is just missing a good text editor&quot;&lt;&#x2F;p&gt;
&lt;p&gt;I love Emacs and Lisp, like many of it’s users I try to spend most my time in it. My biggest problem is the speed
of LSP, but everything else outweighs it. &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;elliowo&#x2F;dotfiles&#x2F;tree&#x2F;main&#x2F;emacs&quot;&gt;Here is my Emacs configuration :) &lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;post&#x2F;dotfiles&#x2F;orwell.png&quot; alt=&quot;emacs reading george orwell 1984&quot; &#x2F;&gt;&lt;br &#x2F;&gt;
&lt;img src=&quot;&#x2F;post&#x2F;dotfiles&#x2F;emacs.png&quot; alt=&quot;emacs writing code&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;society is made for w3m and nano&lt;&#x2F;p&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;&lt;&#x2F;div&gt;
&lt;p&gt;2023-08-12: my old xorg, dwm, suckless desktop&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;post&#x2F;dotfiles&#x2F;tty.jpg&quot; alt=&quot;old suckless desktop&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>My Linux cheat sheet</title>
          <pubDate>Sat, 13 Jan 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>/post/usefulcommands/</link>
          <guid>/post/usefulcommands/</guid>
          <description xml:base="/post/usefulcommands/">&lt;h1 id=&quot;preface&quot;&gt;Preface&lt;&#x2F;h1&gt;
&lt;p&gt;This is going to be generally for use on Gentoo Linux, but is able to be used on different distributions, when not specific&lt;&#x2F;p&gt;
&lt;h2 id=&quot;general-linux&quot;&gt;General Linux&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;transferring-drive&quot;&gt;Transferring drive&lt;&#x2F;h3&gt;
&lt;p&gt;Moving to a new system is straightforward with &lt;code&gt;rsync&lt;&#x2F;code&gt;. Ensure partitions are created beforehand.
I recommend the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;wiki.gentoo.org&#x2F;wiki&#x2F;Handbook:AMD64&#x2F;Installation&#x2F;Disks&quot;&gt;Gentoo Handbook&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Transfer command&lt;&#x2F;strong&gt; (this excludes runtime directories):&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;rsync&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; -aAXv &#x2F;source&#x2F;directory &#x2F;destination&#x2F;directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;breakdown:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;a - archive mode&lt;&#x2F;li&gt;
&lt;li&gt;A - preserve ACLs&lt;&#x2F;li&gt;
&lt;li&gt;X - preserve extended attributes&lt;&#x2F;li&gt;
&lt;li&gt;v - verbose&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;after-clone&quot;&gt;After clone&lt;&#x2F;h3&gt;
&lt;p&gt;You will have to do a few thing to get the system working, which is normal during Arch and Gentoo
installs.&lt;&#x2F;p&gt;
&lt;p&gt;To get the system to boot you will want to get your &#x2F;etc&#x2F;fstab correct, this file contains the mount points
of the partitions you created earlier. To get the drive names and partitions do &lt;code&gt;fdisk -l&lt;&#x2F;code&gt;, you want to
use these retrospectively to to your fstab. I also recommend using &lt;code&gt;noatime&lt;&#x2F;code&gt; on drives to get a bit more
speed out of them. Mine are below.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;&#x2F;dev&#x2F;nvme0n1p1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;          &#x2F;boot           vfat            noauto,noatime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;  1 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;&#x2F;dev&#x2F;nvme0n1p3&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;          &#x2F;               ext4            noatime&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;         0 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;&#x2F;dev&#x2F;nvme0n1p2&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;          none            swap            sw&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt;              0 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once you have done this you should just need your bootloader setup. I personally would delete the old grub from
the &#x2F;boot directory and then run when using UEFI&lt;&#x2F;p&gt;
&lt;p&gt;UEFI&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;mount&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &#x2F;boot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;grub-install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; --target=x86_64-efi --efi-directory=&#x2F;boot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;grub-mkconfig&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; -o &#x2F;boot&#x2F;grub&#x2F;grub.cfg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;LEGACY BIOS&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;grub-install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &#x2F;dev&#x2F;sda&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;whatever&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; partition boot is&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;grub-mkconfig&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; -o &#x2F;boot&#x2F;grub&#x2F;grub.cfg&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;gentoo-specific&quot;&gt;Gentoo specific&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;managing-emerge&quot;&gt;Managing emerge&lt;&#x2F;h3&gt;
&lt;p&gt;To check where most current installed packages are from:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;emerge&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; -pve world&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; perl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; -ne&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; &amp;#39;print &amp;quot;$1\n&amp;quot; if m!\] (.*?)&#x2F;!&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; sort&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; uniq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; -c&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; sort&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; -rn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; head&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; -n&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 30&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;76&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; dev-libs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;73&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; virtual&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    71&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; dev-python&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    51&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; media-libs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    48&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; x11-libs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    47&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; dev-perl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    42&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; sys-apps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    39&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; app-text&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    34&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; dev-ruby&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    31&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; dev-util&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    29&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; sys-devel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    29&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; acct-group&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    20&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; dev-qt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    19&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; sys-libs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    18&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; dev-lang&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    17&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; app-arch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    16&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; net-libs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    14&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; app-eselect&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    13&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; x11-apps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    12&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; app-crypt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; x11-misc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; media-fonts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;    10&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; app-alternatives&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;     9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; net-misc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;     9&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; acct-user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;     8&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; app-misc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;     7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; media-video&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;     7&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; app-admin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;     6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; media-gfx&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;     6&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; games-util&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</description>
      </item>
      <item>
          <title>about</title>
          <pubDate>Wed, 21 Jun 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>/about/</link>
          <guid>/about/</guid>
          <description xml:base="/about/">&lt;h3 id=&quot;hello&quot;&gt;Hello&lt;&#x2F;h3&gt;
&lt;p&gt;Hello, my name is Elliot. I am developer based in the South of England. I have experience in a variety of programming languages, but ones
I use regularly are Rust, Shell and C. Additional experience in C++, C#, Python and Javascript.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;elliowo&quot;&gt;Codeberg&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;projects&quot;&gt;Projects&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;elliowo&#x2F;unknown_os&quot;&gt;unknown_os&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;
Minimal  x86_64 kernel written in Rust: A personal project focused on gaining practical experience in system-level programming, memory management, drivers and emulating CPUs with kvm and qemu. &lt;a href=&quot;..&#x2F;post&#x2F;unknown-os&#x2F;&quot;&gt;More details&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;elliowo&#x2F;sdl2-data-sorting-visualiser&quot;&gt;sdl2-data-sorting-visualiser&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; – Created a real-time, interactive visualiser for data sorting algorithms (e.g., Bubble Sort, Quicksort) using C and the SDL2 library. &lt;a href=&quot;..&#x2F;post&#x2F;sdl2-data-visualiser&#x2F;&quot;&gt;More details&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;elliowo&#x2F;coral-ui&quot;&gt;coral-ui&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; – Rust&#x2F;JavaScript Web UI for Local Large Language Models: using Axum, Tokio, and JavaScript. Features include real-time streaming responses, session management, syntax highlighting, and markdown rendering.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codeberg.org&#x2F;elliowo&#x2F;mullvad-wg&quot;&gt;mullvad-wg&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;
A personal wireguard script for using Mullvad on Gentoo Linux using OpenRC. Reduced dependencies from default application. Uses  &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Duncaen&#x2F;OpenDoas&quot;&gt;OpenDoas&lt;&#x2F;a&gt; instead of sudo. &lt;a href=&quot;..&#x2F;post&#x2F;mullvad-wg-doas&#x2F;&quot;&gt;More details&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>From Hugo to Zola</title>
          <pubDate>Wed, 21 Jun 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>/post/hugo-to-zola/</link>
          <guid>/post/hugo-to-zola/</guid>
          <description xml:base="/post/hugo-to-zola/">&lt;h3 id=&quot;preface&quot;&gt;Preface&lt;&#x2F;h3&gt;
&lt;p&gt;I was looking to redesign my website and decided to look around beforehand, looking at websites,
themes and tools. Whilst looking at Hugo, the framework I used for my website and wanted to see if
there was an alternative written in Rust. Hugo is written in Go, a language I have had a little
experience with and have mixed feelings on, I found Zola.&lt;&#x2F;p&gt;
&lt;p&gt;I realised that Zola aligns with what I desire from a static-site generator and was even made because
of it. &lt;code&gt;This tool and the template engine it is using were born from an intense dislike of the  (insane) Golang template engine and therefore of Hugo that I was using before for 6+ sites.&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;new-website&quot;&gt;new website :)&lt;&#x2F;h4&gt;
&lt;p&gt;The website that inspired me to redesign my website. Due to my searching habits, I end up on a lot of
independent websites (following links or searching topics), I discovered this &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;eli.thegreenplace.net&#x2F;&quot;&gt;wonderful blog&lt;&#x2F;a&gt;. I liked the
tidiness and the content, it just made the important parts of website clear and simple. When reading
the Zola page I was looking at themes and &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kyoheiu&#x2F;emily_zola_theme&quot;&gt;Kyoheiu&lt;&#x2F;a&gt; had made one that reminded me of the wonderful
blog, once I had installed Zola I installed it and started building off it to meet my vision. I hope you like
it.&lt;&#x2F;p&gt;
&lt;p&gt;Never have I appreciated a file format as much as I was when moving content from my previous website to
current. I did have to do some slight tweaks to the markdown to fix formatting between both themes.&lt;&#x2F;p&gt;
&lt;p&gt;The new website has come with some features that the old one lacked. Main features are RSS, MathJax and
syntax highlighting!&lt;&#x2F;p&gt;
&lt;p&gt;Euler’s identity:&lt;&#x2F;p&gt;
&lt;h5 id=&quot;e-i-pi-1-0&quot;&gt;$e^{i\pi }+1=0$&lt;&#x2F;h5&gt;
&lt;p&gt;“Hello World!” example in C:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;#include&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt; &amp;lt;stdio.h&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt;int&lt;&#x2F;span&gt;&lt;span&gt; argc,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #7FBBB3;&quot;&gt; char&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E69875;&quot;&gt;**&lt;&#x2F;span&gt;&lt;span&gt; argv){&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A7C080;&quot;&gt;  puts&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #DBBC7F;&quot;&gt;&amp;quot;Hello, world!&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E67E80;&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D699B6;&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The unfortunate part of the new design is it doesn’t match the rest of my system, using the nord
theme, it instead uses the everforest theme.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;post&#x2F;hugo-to-zola&#x2F;newZola.png&quot; alt=&quot;new website&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;old-website&quot;&gt;old website :(&lt;&#x2F;h4&gt;
&lt;p&gt;The poorly abandoned and maintained website, open image in new tab for better view.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;post&#x2F;hugo-to-zola&#x2F;oldHugo.png&quot; alt=&quot;old website&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Running Mullvad VPN on Gentoo with OpenRC with OpenDoas</title>
          <pubDate>Sat, 08 Apr 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>/post/mullvad-bash/</link>
          <guid>/post/mullvad-bash/</guid>
          <description xml:base="/post/mullvad-bash/">&lt;h3 id=&quot;preface&quot;&gt;Preface&lt;&#x2F;h3&gt;
&lt;p&gt;This is a post about my fork of &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;phvr&#x2F;mullvad-wg&quot;&gt;phvr’s&lt;&#x2F;a&gt; Mullvad script for Gentoo and OpenRC, replacing sudo with
OpenDoas, with some additional features. Also details how to use it.&lt;&#x2F;p&gt;
&lt;p&gt;I have been using exclusively Linux for a few years now and started using VPN’s around a bit before
using Linux. I have used a few VPN’s and Mullvad was the most appealing provider to me but when I
moved from Arch to Gentoo. I had issues using it due to it not being in the default Gentoo overlay and
it’s lack of support for OpenRC. I looked around for some solutions and discovered &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;phvr&#x2F;mullvad-wg&quot;&gt;phvr’s&lt;&#x2F;a&gt; Mullvad
script for Gentoo.&lt;&#x2F;p&gt;
&lt;p&gt;I have used this for the past year and it is a great script, but I have found it is missing some features
that would be nice. This is why I have created a fork of it with some of the features I would like and
some broken bits due to Mullvad changing their naming system.&lt;&#x2F;p&gt;
&lt;p&gt;Requires less resources due to no UI and OpenVPN :)&lt;&#x2F;p&gt;
&lt;h4 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h4&gt;
&lt;p&gt;To add the overlay that contains it for portage:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ eselect repository add elliowo-overlay git https:&#x2F;&#x2F;github.com&#x2F;elliowo&#x2F;elliowo-overlay.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ emerge --sync&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ emerge mullvad-wg-doas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ mullvad help&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From source:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ git clone https:&#x2F;&#x2F;github.com&#x2F;elliowo&#x2F;mullvad-wg-doas.git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ cd mullvad-wg-doas&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ chmod +x mullvad&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ .&#x2F;mullvad help&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;usage&quot;&gt;Usage&lt;&#x2F;h4&gt;
&lt;h5 id=&quot;configuring-the-servers&quot;&gt;Configuring the servers&lt;&#x2F;h5&gt;
&lt;p&gt;To initialise the script to pull in all available servers and their wireguard configs, this will prompt your account number.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad update servers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To rename the files to work with the script consistently:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad update rename&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To set a default server, is not required. You can get servers with &lt;code&gt;mullvad list&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad update default&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;connecting-to-a-server&quot;&gt;Connecting to a server&lt;&#x2F;h5&gt;
&lt;p&gt;To connect to a random server&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad random&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;To connect to a default server, or can specify it.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad connect&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that this needs to be set with &lt;code&gt;mullvad update default&lt;&#x2F;code&gt;, before using the above command.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;enabling-disabling-kill-switch&quot;&gt;Enabling&#x2F;Disabling kill-switch&lt;&#x2F;h5&gt;
&lt;p&gt;Enable a kill-switch&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad kill-switch on &amp;lt;server&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Disable a kill-switch&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad kill-switch off &amp;lt;server&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is possible to choose multiple servers. To enable a kill-switch for all servers run&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad kill-switch &amp;lt;on|off&amp;gt; all&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;status-of-current-connection&quot;&gt;Status of current connection&lt;&#x2F;h5&gt;
&lt;p&gt;To get more detailed information about your connection, run&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;or&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad verify&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;to verify using the am.i.mullvad.net API&lt;&#x2F;p&gt;
&lt;h5 id=&quot;choosing-start-up-server&quot;&gt;Choosing start-up server&lt;&#x2F;h5&gt;
&lt;p&gt;It is possible to choose a server that will auto connect on boot.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad start-up &amp;lt;on|off&amp;gt; &amp;lt;server&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Show the currently selected startup server:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mullvad start-up show&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For this to work you need the ‘local’ service enabled:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #D3C6AA; background-color: #2D353B;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# rc-update add local default&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h5 id=&quot;more-information&quot;&gt;More information&lt;&#x2F;h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;elliowo&#x2F;mullvad-wg-doas&quot;&gt;repository&lt;&#x2F;a&gt; - Repository on github&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;phvr&#x2F;mullvad-wg&quot;&gt;phvr script&lt;&#x2F;a&gt; - Script this is based on.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mullvad.net&#x2F;en&#x2F;guides&#x2F;wireguard-and-mullvad-vpn&#x2F;&quot;&gt;Running WireGuard with Mullvad on Linux&lt;&#x2F;a&gt; - Mullvad’s official guide.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.wireguard.com&#x2F;&quot;&gt;WireGuard&lt;&#x2F;a&gt; - Official WireGuard website.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Duncaen&#x2F;OpenDoas&quot;&gt;OpenDoas&lt;&#x2F;a&gt; - OpenDoas GitHub.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Writing a kernel in Rust</title>
          <pubDate>Sun, 12 Feb 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>/post/unknown-os/</link>
          <guid>/post/unknown-os/</guid>
          <description xml:base="/post/unknown-os/">&lt;h3 id=&quot;preface&quot;&gt;Preface&lt;&#x2F;h3&gt;
&lt;p&gt;Somewhere in-between self-hatred and boredom I came up with the idea of writing a
kernel. I don’t know if it came from interest or ego, but I decided to go through with it. With
kernels there is a few languages that are applicable to this, mainly Assembly, C, C++
and Rust.&lt;&#x2F;p&gt;
&lt;p&gt;I have never written a kernel module, let alone start a kernel from scratch. So I chose the sane choice
of the language with the least online resources. The project will require a ton of reading anyway, will just add to
suffering, transfering c to rust and learning nuiances of Rust.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;post&#x2F;unknown-os&#x2F;helloWorld.gif&quot; alt=&quot;typing out hello world in kernel&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Features&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;BIOS&lt;&#x2F;li&gt;
&lt;li&gt;VGA text mode&lt;&#x2F;li&gt;
&lt;li&gt;CPU exceptions&lt;&#x2F;li&gt;
&lt;li&gt;double faults&lt;&#x2F;li&gt;
&lt;li&gt;hardware interrupts&lt;&#x2F;li&gt;
&lt;li&gt;paging&lt;&#x2F;li&gt;
&lt;li&gt;heap allocation&lt;&#x2F;li&gt;
&lt;li&gt;keyboard support using PS&#x2F;2&lt;&#x2F;li&gt;
&lt;li&gt;testing&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h4 id=&quot;what-i-ve-learnt&quot;&gt;What I’ve learnt&lt;&#x2F;h4&gt;
&lt;p&gt;During this project I have discovered a lot about computers that I did not understand. This was mostly
gaps in knowledge that have been filled in through learning the underlying technology or things I had
a rough understanding from school computer architecture lessons.&lt;&#x2F;p&gt;
&lt;p&gt;One thing that has blown my mind is discovering that computers aren’t 64 bit. When I discovered this
I wasn’t surprised, but had never thought about it. 64 bit only supports 48 bit addresses.&lt;&#x2F;p&gt;
&lt;p&gt;I have not discovered whether it was out of self-hatred or ego, but self-hatred did come from the
project and damage to my ego. My confidence did bounce back twice as much, unfortunately.&lt;&#x2F;p&gt;
&lt;h5 id=&quot;a-lesson-in-drunk-programming&quot;&gt;A lesson in drunk programming&lt;&#x2F;h5&gt;
&lt;p&gt;This was a bit of a drunk project for me I done most of the programming and research after coming back
from the pub. This had comeback in a worse form than a hangover. After a quite heavy&#x2F;healthy night
of 10 pints of Guinness, I lost count and shots. I woke up with a sore head, but later realised was the least of
my worries. I discovered that I had implemented paging (memory management) after coming home. I was definitely over
the drinking limit of having access to a text editor, compiler and shell. I made some beautiful code I
still do not understand to this day, I made some war-crimes of code that I spent the entire next day trying to fix.&lt;&#x2F;p&gt;
&lt;p&gt;There was also a poorly written note files that night trying to explain to future sober me that 64 bit is only actually 48 bit addresses :)&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-future-of-the-project&quot;&gt;The future of the project&lt;&#x2F;h4&gt;
&lt;p&gt;I called this operating system unknown_os due to me not knowing where I would take it at first, I now
have more of an idea and future things I want to add. Also, I would not call this an operating system
in it’s current state as it is just a kernel. I have thought about making it POSIX compliant, but am
unsure because will be restrained by standards. The power of TempleOS, inspires me and think there is
true genius in it’s design and development. I don’t know whether it is a shame or a beauty what happened.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Features I would like&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;shell, allows for a lot&lt;&#x2F;li&gt;
&lt;li&gt;filesystem, probably something like ext2 or fat&lt;&#x2F;li&gt;
&lt;li&gt;chess&lt;&#x2F;li&gt;
&lt;li&gt;tetris&lt;&#x2F;li&gt;
&lt;li&gt;support for other language(maybe)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>GPU Fan Replacement</title>
          <pubDate>Mon, 25 Apr 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>/post/gpu-fan-replacement/</link>
          <guid>/post/gpu-fan-replacement/</guid>
          <description xml:base="/post/gpu-fan-replacement/">&lt;h3 id=&quot;preface&quot;&gt;Preface&lt;&#x2F;h3&gt;
&lt;p&gt;My XFX Radeon R9 390 is a 275W Volcanic Islands card that has seen better days. It still meets my requirements, but I noticed the GPU fans failed to start until 70°C. The fan curve by this temperature was set to 4400 RPM. Diagnostics revealed a known XFX fan controller fault: the tachometer signal on the failed side was stuck reporting 3000 RPM despite the fan spinning at 5000+ RPM under manual PWM control. I ordered replacement fans from AliExpress to avoid the wait times for XFX support.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;disassembly-maintenance&quot;&gt;Disassembly &amp;amp; Maintenance&lt;&#x2F;h3&gt;
&lt;p&gt;Opening the card voids the warranty, though mine had already expired. I took the opportunity to clean the heatsink fins and replace the thermal paste.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;post&#x2F;gpu-fan-replacement&#x2F;gpuSecondImage.jpg&quot; alt=&quot;Graphics card taken apart&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;post&#x2F;gpu-fan-replacement&#x2F;gpuThirdImage.jpg&quot; alt=&quot;Replacing the fan on the heatsink&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reassembly&quot;&gt;Reassembly&lt;&#x2F;h3&gt;
&lt;p&gt;I reattached the new fans with the original screws, securing the cables to the heatsink with zip ties. Once the headers were connected to the controller, I reseated the shroud and verified the fans were ramping up correctly based on the GPU core temperature.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;post&#x2F;gpu-fan-replacement&#x2F;gpuFinal.jpg&quot; alt=&quot;Graphics card put together&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h3&gt;
&lt;p&gt;After replacing the fans my idle fan spin issue was fixed, but was still sitting at half the 3000 RPM, but once reaching higher RPM it matched software. I don’t mind this as I tend to lower RPM for noise. Replacing the fans reduced idle temperatures to around 34°C and lowered power consumption. Before the fan had been fixed the idle was between 40-50°C and was extremely loud. The card is significantly quieter now. Not long after, I acquired an RX 6660 XT, allowing the R9 390 to be repurposed in a secondary machine for a home-server, rather than being scrapped.&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
