❌

Reading view

There are new articles available, click to refresh the page.

Fast MQTT logger (to syslog)

For almost 5 years I've been using the `mqtt-data-logger` [python script](https://github.com/RaymiiOrg/mqtt-data-logger) to log all MQTT communication. This script works, but is a bit limited in how it stores logs (files per time it's started) and it often can't keep up with the message rate (tens of thousands per second) of my mqtt brokers. So I've written a new tool in C++ to log all MQTT messages to syslog and optionally to the terminal. Then, via syslog, you can send it to where ever you like, be it a file or an ELK (Logstash/Elasticsearch/Kibana) stack. It even compiles without syslog support, if you only want to log to a file or the terminal. There's a docker image and a docker compose file, so you can easily deploy it wherever you have an MQTT broker running.

After 47 years, OpenVMS gets a package manager (VSP)!

As of the 18th of February, OpenVMS, known for its stability and high-availability, 47 years old and ported to 4 different CPU architecture, has a package manager! This article shows you how to use the package manager and talks about a few of its quirks. It's an early beta version, and you do notice that when using it. A small list of things I noticed, coming from a Linux (apt/yum/dnf) background: There seems to be no automatic dependency resolution and the dependencies it does list are incomplete. No update management yet, no removal of packages and no support for your own package repository, only the VSI official one. Service startup or login script changes are not done automatically. Packages with multiple installer files fail and require manual intervention. It does correctly identify the architectures, has search support and makes it way easier to install software. The time saved by downloading, manually copying and starting installation is huge, so even this early beta is a very welcome addition to OpenVMS.

Safely expose the Kubernetes Dashboard in Traefik k3s via a ServersTransport

I'm using the Headlamp dashboard for my [high-available local kubernetes cluster](/s/tutorials/High_Available_k3s_kubernetes_cluster_with_keepalived_galera_and_longhorn.html) because I find that to be faster, more clear and useful than the full blown Kubernetes Dashboard. In [my first article](/s/tutorials/My_First_Kubernetes_k3s_cluster_on_3_Orange_Pi_Zero_3s_including_k8s_dashboard_hello-node_and_failover.html#toc_4) I accessed the dashboard via a local port forward. This article documents how to expose the dashboard via an `Ingress` and some `Traefik` specific `annotations`. The dashboard helm chart sets up HTTPS internally, `Traefik` does not like that by default. Most of the time, all internal cluster communication is insecure (I'm not sure why, seems to be a bad idea). A few of the guides online suggest disabling HTTPS for the dashboard internally or, for the k3s specific case, disabling HTTPS validation entirely. Both of those are too broad for my use case, so I decided to figure out how to make `Traefik` talk to the `kubernetes-dashboard-kong-proxy` via `https`, without disabling certificate validation.

My First PCB: Relay AND gate

This is the result of my first attempt at learning KiCad during the Christmas break. I love the sound of a relay, so trying out [these relay logic gates](https://www.youtube.com/watch?v=_nXc439NTYk) from the Usagi video and the information [here on the MERCIA relay computer](https://web.archive.org/web/20250104211313/https://relaiscomputer.nl/index.php/elements) on a breadboard was fun, but a bit messy. No transistors or modern components, just relays, push buttons, resistors and LED's to show output. I've always wanted to make my own PCB. These simple relay logic gates are perfect to try out KiCad and actual PCB design, having never done that before. This short post shows you my first PCB, with all the beginner mistakes included.

My go-to C++ code for asynchronous work processing on a separate thread

You probably recognise this situation. You're working on your code and realise that the thing you're writing might take long, be blocking or is batch-wise. It might be resizing images, calling some API or processing hardware inputs or a stream of incoming messages. These tasks, if not handled efficiently, can halt your application, leaving it unresponsive. To avoid this, one solution is to offload these time-consuming operations to a separate thread, allowing the main application to continue executing without interruptions. In this article, I'll show you how you can implement asynchronous work processing in C++ using a worker thread. This example class is my go-to for this situation and is easily adapted to handle more complex use cases. It has a queue of work items and uses a `std::thread`, a `std::mutex` combined with a `std::condition_variable` to manage work asynchronously, processing items one by one.

The Adventure of the Missing Syscall: Error 38

Sherlock Holmes tackles a modern computing dilemma involving a missing system call. In this case, a frustrated developer attempts to port an embedded device running Yocto to a newer version, only to be met with `Error 38` due to a missing syscall. Holmes and Watson delve into the intricacies of kernel versions, glibc, and system calls to uncover the truth behind the missing `syscall_397` and provide a logical solution.

Logging all C++ destructors, poor mans run-time tracing

I recently faced a challenging issue with an application that wasn't shutting down correctly, either segfaulting or terminating without an active exception. Running the program via `valgrind` to check for memory leaks wasn't possible because the program couldn’t perform its cleanup if it didn't shut down correctly. This article covers adding runtime instrumentation provided by `gcc` to log destructors. This helped me figure out what was still left over from the closed-source framework in use preventing correct shutdowns or causing segfaults. It includes example code, setup instructions and insights into handling shutdown issues in large, multi-threaded codebases.

Compiling TETRIS from 1992 on OpenVMS x86 in 2024!

Since [DECWindows / CDE](/s/blog/OpenVMS_x86_E9.2-3_fixes_CDE_and_adds_Guest_Console.html) now works on OpenVMS x86 (from 9.2-3 onwards) there is much fun stuff to do. Back in 2021 I wrote an article on the [CDE desktop on Alpha / AXPbox](/s/blog/OpenVMS_CDE_Desktop_remote_x_axpbox.html) and also an article on how to run [CDE on modern linux, since it's still developed](/s/blog/The_Common_Desktop_Environment_CDE_is_still_developed_in_2021.html#toc_6). Both articles included a game, **GENERIC-TETRIS** from 1992, [written by Qiang Alex Zhao](https://web.archive.org/web/20240815073318/https://sites.cc.gatech.edu/gvu/people/qiang.a.zhao/Games.html). After getting the (remote) desktop working I wanted to compile and run Tetris to continue this lineage, from VAX, to Alpha, to Linux/CDE, to x86 VMS. I haven't got an Itanium to run it on, but if anyone has one left willing to send this way, feel free to contact me. This article includes the precompiled tetris binary for OpenVMS x86 and instructions to compile the source. The code required some minor modifications which I'll also cover, but that's not surprising for code that hasn't changed much since 1992 to be compiled in 2024. This article also shows you how to install curl on OpenVMS.

OpenVMS x86 E9.2-3 fixes CDE (DECWindows) and adds a Guest Console (no serial port required anymore)

I'm a big fan of OpenVMS. You can [read all my OpenVMS articles here](/s/tags/openvms.html). Since the [licensing changes](https://web.archive.org/web/20240814192656/https://vmssoftware.com/about/news/2024-03-25-community-license-update/) to the Hobbyist Program, I applied and was included in to the Ambassador Program. A new update of the X86 field test is released and this includes to major changes for hobbyists. One is a new feature, the Guest Console, which makes installing easier by no longer requiring a serial port and fiddling with Putty or your telnet client and the second is a fix to the C/C++ compiler which, (probably by accident), fixes CDE and DECWindows. The [Common Desktop Environment (CDE)](/s/blog/The_Common_Desktop_Environment_CDE_is_still_developed_in_2021.html) is still under development and can be installed on Linux quite easily. This post shows the two new features, the Guest Console and CDE working.

nameConstraints on your Self Signed Root CA in Kubernetes with cert-manager

If you have [set up a Self Signed Root CA](/s/tutorials/Self_signed_Root_CA_in_Kubernetes_with_k3s_cert-manager_and_traefik.html) for your local Kubernetes Cluster and have trusted the Root Certificate, you are at risk if the key is compromised. If the key is stolen, it can be used to create trusted certificates for everything. Luckily there is something we can do, using `nameConstraints` to limit the scope of the Root Certificate to, in our case, a single domain (`k3s.homelab.mydomain.org`). This means that if your key would be compromised, it would only be able to issue certificates for anything under that domain, not your bank for example.

Self-signed Root CA in Kubernetes with k3s, cert-manager and traefik. Bonus howto on regular certificates

Now that I'm learning Kubernetes for a few weeks, I'm finally at the point where I was 20 years ago with regular boring old tech, being able to [host multiple domains](/s/tutorials/Kubernetes_k3s_Ingress_for_different_domains_like_virtual_hosts.html), [password protection](/s/tutorials/Password_protect_web_services_in_Kubernetes_k3s_traefik_with_basic_auth.html) and [high available clusters](/s/tutorials/High_Available_k3s_kubernetes_cluster_with_keepalived_galera_and_longhorn.html). It seems we have to re-invent the wheel every time but in the end, it's just resume-driven development, the underlying stack costs more, is way more complex but for the user, nothing changes, they see the same website as always. [Not all change is progress](https://luddites.latenightlinux.com/). Enough of being a curmudgeon, time to continue with Kubernetes. In this episode of 'Remy discovers Kubernetes', I'm setting up `cert-manager`, **not with Lets Encrypt**, but with a self-signed certificate authority. I'll also show you how to set up a regular certificate, one you've for example bought somewhere. I'll also cover `nameConstraints` to make the risk of compromise of your trusted root ca lower.

OpenSSL get entire certificate chain from a domain or loop over entire chain in file

The `openssl x509` command can be used to get information from a certificate. If you supply a filename, the command will only use the topmost certificate in the file, not all certificates in the file, like in the case of a certificate chain. The `openssl s_client -connect` command can connect to a server and show all certificates served by that server. The command I'm providing in this snippet splits up all certificates found in a file or as the result of `openssl s_client` and allows `openssl x509` to loop over each one individually.

Password protect web services in Kubernetes (k3s/traefik) with basic auth

Now that I have a [high-available local kubernetes cluster](/s/tutorials/High_Available_k3s_kubernetes_cluster_with_keepalived_galera_and_longhorn.html) and am [experimenting with deploying apps](/s/snippets/Using_nodeSelector_to_deploy_a_Kubernetes_Helm_chart_only_on_x86_or_amd64_nodes_not_arm64.html), it's also time to look into securing those apps using certificates and passwords. In this case I'm going to set up password authentication, like a `.htaccess` file in `Apache2`, to protect the `Longhorn` dashboad, which by default requires no authentication. This means deploying an `Ingress`, a `Middleware` and a `Secret`.

Using nodeSelector to deploy a Kubernetes Helm chart only on x86/amd64 nodes, not arm64

My [k3s cluster](/s/tutorials/My_First_Kubernetes_k3s_cluster_on_3_Orange_Pi_Zero_3s_including_k8s_dashboard_hello-node_and_failover.html) runs on Orange Pi Zero 3 small board computers, with a 1.5 GHz Allwinner H618 Quad-Core Cortex-A53 ARM64 CPU. Nowadays most popular software has support for `aarch64` due to the popularity of boards like the Raspberry Pi and the Apple M1 series processors, but smaller projects or niche software often can only run on x86/amd64. If you write your own yaml files for deployment you can use a `nodeSelector` combined with the `kubernetes.io/arch=amd64`, but with a Helm Chart this is not that obvious. This small snippets shows you the correct syntax to force deploy a Helm Chart to only amd64 nodes in your cluster. This assumes you have a mixed cluster, I added a small virtual machine to it for testing.

Kubernetes (k3s) Ingress for different domains (virtual hosts)

Now that I have a [high-available local kubernetes cluster](/s/tutorials/High_Available_k3s_kubernetes_cluster_with_keepalived_galera_and_longhorn.html) it's time to learn not just managing the cluster but actually deploying some services on there. Most examples online use a `NodePort` or a `LoadBalancer` to expose a service on a port, but I want to have domains, like, `grafana.homelab.mydomain.org` instead of `192.0.2.50:3000`. Back in the old days this was called [Virtual Host](https://web.archive.org/web/20240515131604/https://httpd.apache.org/docs/2.4/vhosts/), using 1 IP for multiple domains. My k3s cluster uses `traefik` for its incoming traffic and by defining an `Ingress` we can route a domain to a service (like a `ClusterIP`). This page will show you how.

High Available k3s kubernetes cluster with keepalived, galera and longhorn

After my [first adventure with Kubernetes](/s/tutorials/My_First_Kubernetes_k3s_cluster_on_3_Orange_Pi_Zero_3s_including_k8s_dashboard_hello-node_and_failover.html), getting started with k3s on my small 3 node ARM cluster that [boots via PXE / NFS](/s/tutorials/Netboot_PXE_Armbian_on_an_Orange_Pi_Zero_3_from_SPI_with_NFS_root_filesystem.html), I noticed that there is only one k3s node that has the `control-plane,master` role. If that node fails you can no longer manager the cluster. Other nodes can fail and then the workloads (pods) will be restarted eventually after 5 minutes, but this node is special. Time to change that and make it a high available cluster. K3s [supports](https://web.archive.org/web/20240703112841/https://docs.k3s.io/datastore/ha) high-availability with embedded `etcd` and with external databases like `MySQL` and `postgres`. `etcd` will thrash your storage (SD cards) so I decided to go with a `MySQL` cluster using `Galera` for the database and `keepalived` for the High Available Cluster IP. This guide will show you how to configure the HA database and HA-IP and I'll also setup [longhorn](https://web.archive.org/web/20240707025724/https://longhorn.io/) for high-available block storage inside kubernetes. The end result is that I can pull the power from any two of the three nodes without the k3s cluster or workloads going down.

My First Kubernetes: k3s 'cluster' on 3 Orange Pi Zero 3's, including the dashboard, hello-node and failover

I've been working as an embedded C++ developer for over 5 years now so my sysadmin / devops skills are becoming a bit rusty. The odd bit of Ansible here and there but no new stuff. I figured it was time to expore Kubernetes, as it is what all the cool kids do these days. So I [got myself 3 new SBC's] (/s/tutorials/Netboot_PXE_Armbian_on_an_Orange_Pi_Zero_3_from_SPI_with_NFS_root_filesystem.html), the [Orange Pi Zero 3] (https://web.archive.org/web/20240623200133/http://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/details/Orange-Pi-Zero-3.html). I'll be using these to install and setup a basic Kubernetes cluster, getting the Dashboard working, installing a Hello World app and testing how the failover works.

Netboot (PXE) Armbian on an Orange Pi Zero 3 from SPI with NFS root filesystem

Because I wanted to experiment with Kubernetes I bought a few cheap SBC's and a Power over Ethernet switch to run `k3s`. Since Kubernetes is very resource intensive I wanted to try to boot the boards via the network without causing wear on the Micro SD card. The boards have built-in SPI flash from which it can boot `u-boot` and Armbian works quite well with a root filesystem over NFS. This guide will help you with netbooting an Orange Pi Zero 3 running Armbian.

Using a 1965 Dutch Rotary Phone via VoIP (T65) in 2024

Recently I was gifted a T65 rotary telephone. This was **the** standard telephone in The Netherlands in the seventies and eighties. I remember my parents having one as well. Because this phone does not use DTMF but pulse dialing it does not work with modern equipment, like the built in telephony / voip server on my FritzBox router. Using a hardware converter it is possible to convert pulse dialing to DTMF and to use your rotary phone again. This page covers two such devices, the DialGizmo and the GrandStream HT502 and a more homebrew approach.

Qt Property Macro (Q_PROPERTY with 95% less code)

Adding [properties to QObject based classes](https://web.archive.org/web/20240529180113/https://doc.qt.io/qt-6/properties.html) is cumbersome. Although [the property system](https://web.archive.org/web/20240529180113/https://doc.qt.io/qt-6/properties.html) and [Signals and Slots](https://web.archive.org/web/20240529180002/https://doc.qt.io/qt-6/signalsandslots.html) are great to use, especially with QML, it takes a lot of boilerplate code to add such properties to a class, at least 15 to 20 lines for each property. I've cobbled up a macro that saves you about 95% of lines when using a `Q_PROPERTY`. (22 lines to 1 line).

Qt 5.15 LTS on Windows without a Qt Account

I recently had to setup a Windows development environment with Qt 5.15. Qt 5.15 is still developed by the Qt company, but only released in binary form for paying customers. The [source code is released after 1 year](/s/blog/Qt_5.15_LTS_Docker_Image_for_Android_with_OpenSSL.html#toc_0). Via the Online Installer you can only install 5.15.2 and you must login with a Qt account. This guide shows you how to install the most recent Qt 5.15 (as of writing it's 5.15.13) and Qt Creator, **without** a Qt account. We're using `vcpkg` to compile Qt and a specific offline-enabled installer for Qt Creator.

Proxmox VE 7 Corosync QDevice in a Docker container

At home I have a 2 node Proxmox VE cluster consisting of 2 HP EliteDesk Mini machines, both running with 16 GB RAM and both an NVMe and SATA SSD with ZFS on root (256 GB). It's small enough (physically) and is just enough for my homelab needs specs wise. Proxmox VE has support for clustering. For a cluster (in any sense of the word), you need at least 3 nodes, otherwise there is no quorum. Corosync, the cluster software used by Proxmox, supports an external Quorum device. This is a small piece of software running on a third node which provides an extra vote for the quorum. In my case I wanted to run this on my NAS, since (physical) space is a premium. The NAS supports Docker, this guide explains how to run the QDevice for Proxmox VE 7 in a Docker container. There is a qdevice Docker image on the Docker hub but that guide does not work for Proxmox VE 7 and requires a lot of manual setup. Using my method involves a lot less steps, since you're basically running an extra debian VPS (a container with systemd and openssh).

Fixing the hiss on my Atgames Legends Pinball Micro including root access

The [Atgames Legends Pinball Micro](https://web.archive.org/web/20240123213954/https://www.atgames.us/products/legends-pinball-micro) is a small virtual pinball cabinet for around USD 350. I imported one to the Netherlands, Atgames does not ship here. The built in tables are okay and more are for sale via Atgames' webshop. Overall for the price it is a nice device. Build quality is okay, software lacks a bit of quality. One really annoying issue which severely impacts gameplay is a buzz / hiss sound. This post goes over my attempts to fix this hiss and the one that worked was a ground loop isolator.

Which Root Certificates should you trust? Find out with CertInfo

Which Root Certificates should you trust? Did you know that any certificate authority can issue a certificate for any website? There are protocols in place so that should not happen, but when (not if, when) they get hacked or coerced by their government, they can issue a certificate to intercept secure communication for any website. I've made an open source program, [CertInfo](https://github.com/raymiiOrg/certinfo) that analyzes your browser history and queries all visited domains for their certificates. It presents a list of used root certificates (meaning, a website you visited was ultimately signed by that root CA) and a list of unused root certificates (meaning, no website in your analyzed history was signed by that root CA).

YouLessQt, helps you align the YouLess to an analog electricity meter

The [YouLess](https://youless.nl/home.html) is a device that can help you monitor energy usage. It works on so called smart meters using a P1 port, it can monitor solar panels but it also works with regular old analog meters. I have an old style analog meter but I like gadgets and monitoring / reducing my energy usage just as much as the next guy so I bought one. It has an optical sensor that you paste (with tape) on your meter and that detects a little black bar on the rotor disc and using a rpm factor on your meter it calculates the electricity used. I has some trouble with the device when I set it up, it turned out to be aligned wrongly. It sometimes missed the black bar, so the numbers were incorrect. I wrote a little application using Qt and QML to show the raw light sensor values in a line graph to help me align the YouLess correctly. This post tells you more about the application, which of course is open source.

A docker image for Qt 5.15 LTS for Android, including OpenSSL and the KDE patch collection

Recently I got an email from Google regarding the API level of [Leaf Node Monitoring](https://leafnode.nl), my open source monitoring app for Windows, Linux and Android. The Play Store version must be updated to target API level 33. For Windows and Linux I'm building the app automatically in a CI environment but the Android build was still a manual process. Until now, because after a bunch of messing around with Android NDK versions, OpenSSL library paths and Qt compile flags I can automatically build Leaf Node Monitoring in my CI. I'm using Woodpecker CI and that requires every build step to be executed in a Docker image. There are a few Qt docker images floating around but they are all using the pre-built 5.15.2 version by extracting it from the Qt Online Installer. That version is quite old, 5.15.15 LTS was released [a few days ago for Commercial License Holders](http://web.archive.org/web/20230902132649/https://www.qt.io/blog/commercial-lts-qt-5.15.15-released) on August 31, so after 1 year it will become available as open source. My docker image builds Qt from source using the `5.15 KDE Qt Patch Collection` branch for Android and it includes OpenSSL. This is as far as I know the most up to date docker image for Qt 5.15, currently at 5.15.10 LTS.

Drawing a Circle in Qt QML three different ways

Qt has no `Circle` built in to QML as a basic type, as for example the `Rectangle` or the `Button` control. This post shows you how to get a `Circle` in QML, from the most basic method (a `Rectangle` with a `radius` of 180) to more advanced methods, using the `Canvas` JavaScript API (which allows us to draw a partially filled Circle, for a Pie Chart) and a `c++` control based on `QQuickPaintedItem`. I wanted to experiment with the `Canvas` QML control and the `QQuickPaintedItem` C++ interface to get a better understanding of Qt and QML drawing interfaces, this post reflects that journey including showing your grouped QML properties exposed from C++.

Site update, self-hosted search via pagefind

This is a static site, meaning that no server-side processing occurs. All HTML is generated out of a few folders full of markdown source and then uploaded to the cluster. Searching on this site was always provided by a text-box form that sent you to google with 'site:raymii.org' appended to it. Works fine, but it sends all data to Google. With my recent removal of all Google Ads on this site, as well as tracking via Google Analytics, sending searches via Google seems wrong.

I recently found the `pagefind` program which I now use on here, it is a self hosted static site search engine of sorts.

The sad state of Alpha emulators (for OpenVMS)

OpenVMS 7.3 was the last version for the VAX architecture. All later versions (like 8.4) are only available for the Alpha CPU architecture or Intel's Itanium platform. Since I don't want hardware running, which is suprisingly hard to get in The Netherlands, Alpha machines, I want to be able to run it in an emulator. simh is the best open source VAX emulator, but it does not support Alpha. My adventure with es40, the only open source Alpha emulator (development halted 10 years ago) ended prematurely since it crashes all the time. The only other available options are FreeAXP, Charon-AXP, vtAlpha and EmuVM AlphaVM. Only FreeAXP is available as a free (but not open source) download, Charon had a personal version but that is nowhere to be found nowdays, vtAlpha doesn't offer a trial or free version and EmuVM Alphaserver also stopped with their free version. In this article I'll go over my adventure with FreeAXP and EmuVM.

My 24 year old HP Jornada can do things your modern iPhone still can't do!

I like to tinker with old hardware. The [DEC](https://raymii.org/s/tags/dec.html) PDP-8 is my favorite [retro computer](/s/tags/pdp-8.html) and [Office 2003](/s/blog/Using_a_Windows_Mobile_2003_PDA_hp_ipaq_in_2022_including_whatsapp.html) is the best version ever released IMHO. One of my other favorite retro devices is the HP Jornada 720. A small `handheld PC` (smaller than a netbook) running Windows CE or in my case, Linux. It has a decent keyboard, CFL backlit screen, **32 MB of RAM(!)**, a compact Flash card for storage and a stylus for the resistive touchscreen. Oh and I got a 10Mbit PCMCIA network card, but wireless cards are also still available. It might be old, released in 1999, but can do one thing your modern iPhone can't.

Bare Metal Vi, boot into Vi without an OS!

This guide shows you how to run `Vi` without an operating system, bare metal. This is a follow up on my article from 2014 where I made a custom linux distro that would [Boot to Vim, VIM as PID 1](https://raymii.org/s/blog/Vim_as_PID_1_Boot_to_Vim.html). This time we go further, we boot into `Vi` without an operating system. This is made possible by [Cosmopolitan](https://justine.lol/cosmopolitan/index.html), a `libc` that outputs a POSIX-approved polyglot format that runs natively on Linux + Mac + Windows + FreeBSD + OpenBSD + NetBSD + BIOS with the best possible performance and the tiniest footprint imaginable.

OpenVMS 9.2 for x86, Installing HAProxy and troubleshooting UNIX file paths

This article shows you how to install HAProxy on OpenVMS 9.2 for x86. I've often used HAProxy in my career as a sysadmin and find it a very useful tool. HAProxy is an open source, fast, reliable load balancer for TCP and HTTP-based applications. This guide assumes you've set up your OpenVMS system via [my guide](https://raymii.org/s/blog/OpenVMS_9.2_for_x86_Getting_Started.html) and the [second part](https://raymii.org/s/blog/OpenVMS_9.2_for_x86_Getting_Started_part_2.html) of my guide, that will give you a fully licensed OpenVMS installation with networking and SSH access. Since I've used HAProxy so very often to set up high-available clusters and load balancers, I was surprised but happy to see it ported to OpenVMS. This guide shows the setup but also a few OpenVMS specific quirks, like file paths and troubleshooting error messages / logs.

OpenVMS 9.2 for x86, Getting Started part 3, the WebUI

OpenVMS on x86 is now available for hobbyists! Almost a year after [the official release](/s/blog/OpenVMS_9.2_for_x86_will_be_released_tomorrow.html). This is a part 3 of my getting started guide. Part 2 ended with a working network setup and SSH access. In part 3 we'll do something very exciting, installing the WebUI, a web based management interface for OpenVMS. I'll also share a few smaller tidbits, like how to use the interactive text editor via an `ssh` session and how to use `unzip`.

Site update, cookie consent popup (for a static site)

A small site update this time, just to let you know that I've added a cookie consent popup to this static site. If you reject all cookies, you should not see any advertisements and aren't tracked by Google Analytics. It's open source, cookieconsent by Orest Bida.

OpenVMS 9.2 for x86, Getting Started part 2, auto boot, licenses, PAKs, networking and SSH

OpenVMS on x86 is now available for hobbyists! Almost a year after [the official release](/s/blog/OpenVMS_9.2_for_x86_will_be_released_tomorrow.html). This is a part 2 of my getting started guide. [Part 1](https://raymii.org/s/blog/OpenVMS_9.2_for_x86_Getting_Started.html) ended with an installed system, this part continues with automatic startup, activating the license files (PAKs) and setting up networking including SSH access.

OpenVMS 9.2 for x86, Getting Started part 1, install guide with VirtualBox

OpenVMS on x86 is now available for hobbyists! Almost a year after [the official release](/s/blog/OpenVMS_9.2_for_x86_will_be_released_tomorrow.html). This is a part 1 of my getting started guide, showing you how to install OpenVMS on VirtualBox on Windows 10/11. More parts will follow, documenting license installation, network setup, ssh, application installation etc.

OpenVMS 9.2 for x86 is finally available for hobbyists!

OpenVMS x86 is now available for (most) hobbyists! Almost a year after [the official release](/s/blog/OpenVMS_9.2_for_x86_will_be_released_tomorrow.html) most hobbyists can now login to the [Service Portal](https://sp.vmssoftware.com) to download their copy of OpenVMS 9.2 for x86, `X86E921OE.ZIP` and the PAK (license) files (`x86community-20240401.zip`), valid until April 2024.

Named Booleans prevent C++ bugs and save you time

During a recent code review I found a hard to spot bug, a misplaced parenthesis in an `if` statement. I often employ a technique I call `named booleans`, which would have prevented this bug. It's a simple technique, instead of a long `if` statement, give every comparison a seperate boolean variable with a descriptive name and use those variables is the `if` statement. This post shows the bug in question, an example of my `named booleans` technique and another tip regarding naming magic numbers.

Johnnie 'QObject' Walker, replace a service locator pattern while you're at it

I've seen many C++ code bases where there was the concept of a service locator. An global static object that anyone can query to get a class. This is handy with old legacy spiderweb intertwined code that gets everything from everywhere, but not so useful when you're trying to unit test code, it is not visible from the header what dependencies you need. My preference goes to dependency injection, give all the dependencies to the class' constructor and use them that way. Makes it easy to mock and if you have many dependencies, it serves as a starting point to refactor in to a more clearly separated architecture. This article shows a piece of code that uses QObject, the Qt object base class, to replace a servicelocator. All QObjects can have a parent QObject, thus a tree is formed, which you can walk back up and search. This effectively replaces the servicelocator, since you can just request a certain type of QObject.

APT keeps complaining that the HTTPS certificate cannot be validated?

Recently a few of my Ubuntu 20.04 and Debian 11 servers failed to run an `apt update` because it insisted that the HTTPS certificate for a repository could not be validated, while `curl` on the same system had no issues connecting. Join me on a deep dive into certificate validation and troubleshooting `apt`, digging into the C++ source code for `apt` and `GnuTLS` and in the end, it turned out to be my own fault due to permission on a folder. However, the error messages were totally unhelpful resolving the mysterious validation problem. This article was written over the period of a few days, chronologically during troubleshooting.

Sparkling Network

This is an overview of all the servers in the Sparkling Network, mostly as an overview for myself, but it might be interesting for others. It also has a status overview of the nodes. Prices are monthly, excluding VAT.

Leaf Node Monitoring v2023.01 released, major performance improvements, new layout and new checks!

I'm pleased to announce the next version of Leaf Node Monitoring, the simple and easy to use open source site and server monitoring tool. Major new features include a responsive and adjustable layout, massive performance improvements and a new check type, allowing you to execute external processes, for example, the nagios/monitoring plugins. This post goes over everything that is new in this release.

Add moc includes to speed up Qt compilation

The Meta-Object Compiler, `moc`, handles Qt's C++ extensions and it is required for signals and slots and properties in Qt. `moc` reads C++ header files and if the `Q_OBJECT` macro is used, it generates an extra `.cpp` file named `moc_filename.cpp` containing extra (meta-object) code. This post has a bit of background information and a shell script to automatically include `moc_*.cpp` files in your code whenever `Q_OBJECT` is used. If you use `qmake`, this will probably speed up your build and if you use `cmake`, this will probably speed up incremental builds (when `CMAKE_AUTOMOC` is `on`).

Spinrite 6.0 on UEFI and an NVMe SSD drive

Spinrite is a hard drive recovery and maintenance utility written by Steve Gibson from GRC. It is marketed on the Security Now TWiT podcast which I often listen to. I have bought a copy of it and sometimes use it on solid state disks or SD cards. Spinrite 6.0 is written is assembly language and runs on top of MS-DOS or FreeDOS, using the BIOS. UEFI is not supported and neither are NVMe drives. This post will show you how to run Spinrite 6.0 on such a system anyway, using a modern linux live USB drive that can boot on UEFI only system and VirtualBox, exposing the NVMe disk as a SATA drive.

OpenSSL Command Generator

This is a simple page with a form which you can use to generate OpenSSL commands to, for example, create a CSR or a self signed certificate.

OpenSSL generate self signed certificate with SAN in one command (subject alternative name)

This small one liner lets you generate an OpenSSL self signed certificate with both a common name and a [Subject Alternative Name (SAN)](https://en.wikipedia.org/wiki/Subject_Alternative_Name). Most guides online require you to specify a separate config file but this guide uses a bash trick [(process substitution)](https://web.archive.org/web/20221014191420/https://superuser.com/questions/1059781/what-exactly-is-in-bash-and-in-zsh) to pass such a config file to OpenSSL via the command line. If you are using OpenSSL 1.1.1 or higher, there now finally is a built in command line option which I'll also cover.

Fade in / fade out in Qt/QML

This guide shows you how to add a fade in / fade out effect to a control in QML. There are a lot of built in animations in Qt/QML, but no fade in/fade out. Using a state machine and a `SequentialAnimation`, we can first animate the opacity, then set the visibility, achieving a fade in / fade out effect. Other ways like a `PropertyAnimation` are also available but are less expressive or configurable.

Responsive Qt/QML layout coming to Leaf Node Monitoring

[Leaf Node Monitoring](https://leafnode.nl) is my own open source (GPLv3), paid, network monitoring program for Windows, Linux & Android. Written in C++ & Qt 5. Perfect to run on your desktop and monitor your servers. Simple setup, auto-detects running services, runs checks concurrently and alerting. This post shows another upcoming feature in the next version, responsive layouting to more effectively use screen real estate.

OpenVMS 9.2 for x86 will be released tomorrow (2022-07-14), so exciting!

On July 8th, a few days ago, I saw the following post on the VMS Software Inc (VSI) blog, titled 'Release of OpenVMS V9.2 for x86 Scheduled for July 14, 2022'. That is tomorrow! I'm so excited, I can't wait to start playing around with it. This short post goes over the announcement and the status of the community license, and hopes to make you just as enthusiastic as I am for the coming release!

What's coming in the next version of Leaf Node Monitoring?

Leaf Node Monitoring is my own open source (GPLv3), paid, network monitoring program for Windows, Linux & Android. Written in C++ & Qt 5. Perfect to run on your desktop and monitor your servers. Simple setup, auto-detects running services, runs checks concurrently, open port scanning and alerting. I've recently released the first version, and this post goes over the features that will come in the next release.

Using a Windows Mobile 2003 PDA (HP iPAQ h4350) in 2022, including WhatsApp!

While cleaning out my collection of electronics, I found a PDA. Not the modern kind (voice assistant), but the old school precursor to the smartphone. It's a HP iPAQ h4350, it was a model used by the Dutch Railways. I picked it up in working condition years ago and was wondering, how does a mobile device from 2003 stack up to a modern smartphone? The first thing I did was run linux on it which worked surprisingly well, it however was noticeably slower than Windows Mobile. This post shows you how well the device still works in 2022, including using WhatsApp to chat. Almost all things I use my smartphone for, I can do with this PDA!

Qt/QML Property bindings break after a JavaScript assignment

Property bindings are one of the most powerful concepts in Qt/QML. Property bindings let you specify relationships between different object properties. When a properties dependencies change in value, the property is automatically updated according to the specified relationship. The QML engine monitors the properties dependencies (that is, the variables in the binding expression). When a change is detected, the QML engine re-evaluates the binding expression and applies the new result to the property. One little known caveat with property bindings is that they break after a static JavaScript assignment (`property = value`). This post shows you the different behaviors and how to use `Qt.binding()` to assign property bindings via JavaScript.

HTTP GET requests with Qt and in Qml (async)

With Qt it's very easy to work with (async) HTTP requests. This guide shows you how to do it with Qt core and in Qml. The two examples print the output of a HTTP GET request on screen after pressing a button. The Qml method uses JavaScript, so that's cheating a bit, the other method uses plain C++ with Qt's libraries for networking (`QNetworkAccessManager`) and signals and slots for the async part.

Selling my own GPL software part 3, prior art (existing GPL software for sale)

In my earlier posts I described the hurdles I faced with my plan to [sell my own](/s/blog/Selling_GPL_Software_part_1_lots_of_hurdles.html) GPL software and I described how to [embed the source code directly inside the app] (/s/articles/Embed_the_source_code_directly_in_your_Qt_app.html) (for mobile platforms). This post looks at a few other projects that sell GPL software and it's a bit of a progress update regarding my plans and software.

Price of a guest post on dragonflydigest.com?

I have a deep-seated hatred towards half-assed quick-moneygrabbing marketeers, but today they reached at an all-time low. This site is `raymii.org`, I received an email for a guest post on `dragonflydigest.com`. Not even remotely alike in spelling. I'm not called Justin, and I (sadly) don't maintain an excellent BSD distro. So dear telemarketers, every week I get emails like this, please put in a bit more effort. Normally I don't spend any time or effort, certainly not provide exposure, but this instance of Cunningham's Law does deserve a post, sadly.

Yocto boot2qt for the Seeed reTerminal (Qt 6)

In this guide we'll build a linux distribution for Seeed reTerminal, using the Yocto project and the `boot2qt` stack provided by Qt. This `boot2qt` image can be written to the internal eMMC and when booted up, the Seeed reTerminal runs a software stack that integrates nicely with Qt Creator (the Qt IDE), for example, one click deployment to the device. You can run your own Qt application on the reTerminal, full screen, it will boot right into it. This guide covers Qt 6.2. The guide also covers changing the default startup app to your own app, Qt Creator integration and rotating your Qt app, both Widgets and QML, the latter via Wayland and Weston.

Build a WeatherTerminal app for the Seeed reTerminal (with Qt 6 & QML)

In this guide I'll show you how to build a weather app for the Seeed reTerminal using Qt and QML. Imagine the reTerminal in your entrance hallway and with just a quick glance at the screen you'll know what the weather will be the next few hours, if you need an umbrella, if you'll have a headwind on your bicycle ride or if it's just going to be clear and sunny. This tutorial builds on the [reTerminal Yocto boot2qt distro](/s/tutorials/Yocto_boot2qt_for_the_Seeed_reTerminal_qt6.html) we've built in the previous article and uses Qt 6. Qt is a C++ framework, but this Weather app will use QML almost exclusively. I'm using just QML to make the guide more accessible and also because I'm used to doing everything in C++, so a sidestep to QML is fun for me as well.

Qt 5.15.3 Open Source released

Qt is a nice C++ framework with a GUI toolkit on top, actually, 2 toolkit, Widgets and Qml. Qt is available under the GPL and LPGL, open source licenses and a closed source license. [Back in 2020](https://lwn.net/Articles/817129/), the Qt company decided to [start a war](https://ev.kde.org/2020/04/06/changes-in-qt-and-the-kde-free-qt-foundation/) against their own users and contributors by withholding the 5.15 code, only releasing them under a closed license, making the offline installers available to paid customers and requiring a Qt account for the online installer. Due to [an agreement](https://www.qt.io/faq/3.2.-why-do-you-have-an-agreement-with-kde-about-your-licensing-what-kde-is-and-whats-the-history-of-qt-and-kde) with the [KDE project](https://kde.org/community/whatiskde/kdefreeqtfoundation/) they are obliged to release the code after one year under an open source license, and that time has come for 5.15.3. For most LTS releases, the Qt company writes a blog post, but this open source release only gets a [mailing list post](https://lists.qt-project.org/pipermail/development/2022-March/042262.html) (One day and 4 blog posts later, [no mention of 5.15.3 on their blog](https://archive.ph/IvMSn)). This short post is intended to give a bit more publicity to that release and to tell you about the KDE Qt 5.15 LTS patch collection. Even if I might not agree with the business practices, the framework is nice to work with.

I enforced the AGPL on my code, here's how it went

Five years ago I made a website that allowed you to put in a few domains and get an email when the SSL certificate was about to expire. No ads, no fuss, just an easy way for people to keep tabs on their sites without setting up their own monitoring like Nagios. As with all of my software, I released it under the AGPL due to it being web based software. Recently I found a company that hosted certificatemonitor, with some modifications (branding and a dutch tanslation), without any reference to its origin, no source code provided and no mention of the license. In this article I'll talk about what I did to enforce the license and how it went. TL;DR, not as expected. The company responded timely and friendly, but did a half assed attempt (added a link to my site with 'Inspired By Remy' as the text), then after my complaints, took down the entire site.

Raspberry Pi Compute Module 4 eMMC flashing issue (nRPI_BOOT)

I recently got my hands on a Raspberry Pi 4 Compute Module, 4 GB with 32 GB eMMC flash and a Compute Module 4 IO board. Due to the global chip shortage it's hard to find one in stock but I got lucky by checking [rpilocator.com] (https://rpilocator.com/) regularly (thanks to [Jeff Geerling] (https://www.jeffgeerling.com/blog/2022/its-dire-raspberry-pi-availability-tracker-launched) for that site. He's got amazing Raspberry Pi related content next to a bunch of high-quality Ansible playbooks, go give him a visit). The eMMC edition I have can only be flashed if you put a jumper on a pin on the I/O board (to put the cm4 in a special mode, `nRPI_BOOT`) and use a special tool, [usbboot](https://github.com/raspberrypi/usbboot). [Jeff has a great guide](https://web.archive.org/web/20220226203155/https://www.jeffgeerling.com/blog/2020/how-flash-raspberry-pi-os-compute-module-4-emmc-usbboot) on flashing the cm4 eMMC edition. My `cm4` however, was not showing up whenever I put it in this special flashing mode. This article goes over the troubleshooting I did and the eventual solution (hint: hardware problem).

Execute a script in a Yocto package on every image build

This is a small snippet showing a Yocto recipe that executes a script on every build of an image that includes that recipe. I use it to write the build hosts date/time to a file on the image, but you could do anything you want inside the script. It's not recommended to do this, for example, if you want to place a binary on your image you should version it correctly. Yocto can build from a git repo, no need to copy binaries. If you include the `buildinfo` class your image or the `os-release` recipe, build info is also written to your image.

Yocto boot2qt for the Raspberry Pi 4, both Qt 5.15 and 6.2

In this guide we'll build a linux distribution for Raspberry Pi 4, using the Yocto project and the `boot2qt` stack provided by Qt. This `boot2qt` image can be written to an SD card and when booted up, the Raspberry Pi runs a software stack that integrates nicely with Qt Creator (the Qt IDE), for example, one click deployment to the device. You can run your own Qt application on the Pi, full screen, it will boot right into it. This guide covers both Qt 5.15 and Qt 6.2. The 5.15 build process is a bit convoluted due to a few upstream issues. The guide also covers changing the default startup app to your own app and Qt Creator integration.

Embed the source code directly in your Qt app with qmake and qrc, for GPL compliance

In my earlier [post on selling GPL software](/s/blog/Selling_GPL_Software_part_1_lots_of_hurdles.html) I outlined a few points that make it hard to sell GPL software. One of them is the availability of the source code. You could put it online but then everyone has access without paying. Other options like putting it behind a login or sending a link after purchase require extra systems and saving more user information, lots of extra hassle for me and the users. One of my ideas for 'solving' this issue is by shipping the actual source code directly inside the application. This article shows you how to do that, by creating an archive of the current source code on every build with `qmake` and embedding that inside the application using `qrc`, including a button to save the archive locally to disk. It works on the desktop as well as Android, including the required permissions.

Log all Item properties and functions in Qml

This small snippet of Javascript logs all properties and functions of a Qml Item. This is useful when you're knees-deep in a dynamic control that has a model and you're wondering why your code does not work. Probably because you're not using the correct property name. Or at least, that is something I often have. Logging all properties or functions helps to figure out that issue.

Loop over all Repeater items or Delegate's in Qml

This small snippet shows how to loop over all Repeater items in Qml and also over all Delegate items in Qml. There are sublte differences between the two. I'm using this to update visual all items in a control, before syncing state to a networked backend, and if the backend actions fails, I undo the visual state change. The network backend could be slow, by keeping state locally and syncing in the background, the user can continue working.

Thank you, shotternail!

Recently I got a new Github Sponsor, a one-time donor. Often, these github profiles list a name, email address or some information to contact the person, even a last-resort ssh key with a comment, but this profile has nothing. They joined github 8 days ago, and I suspect it was just to do a donation to me. Because I have no other way of communicating, here is a public post to say thank you to [shotternail](http://web.archive.org/web/20220207192842/https://github.com/shotternail), whomever you are!

QML Touch Area visualization with QML_VISUAL_TOUCH_DEBUGGING

This guide shows you how to enable a red visual square around your `Mouseareas` and `MultiPointTouchArea` controls. It visualizes where you can click/touch and also shows any overlapping touch area's. It's helpful on full screen device interfaces like a coffee-machine or other HMI. The environment flag `QML_VISUAL_TOUCH_DEBUGGING` needs to be set, but this is not documented on the Qt Docs site, only on a cheat sheet from 2016 by ISC. If you google for the environment flag, the only pages you get are the Qt source code and that cheat sheet. I've found this flag to be very useful when debugging touch issues, like overlapping touch or when a touch area is too small to use. One of my co-workers found it when we had touch issues and since there is a lack of documentation, perfect for a small guide.

QML Drag and Drop including reordering the C++ model

This guide shows you how to implement drag and drop in Qml including how to reorder the backing C++ (`QAbstractListModel` derived) data model. Most QML Drag and Drop examples you find online, including the Qt official example, use a `ListModel` in the same Qml file which has the data, but no example I found actually reordered a C++ model. This example has a simple `MVVM (model-view-viewmodel)` C++ structure and a QML file with a drag and drop grid. The dragable example items come from the C++ model, which is derived from `QAbstractListModel`.

Selling my own GPL software, part 1: a lot of hurdles

For as long as I can remember I've got this dream of a passive income software project. At first I thought of it as a hosted service, probably something monitoring related, or high-available cloud hosting-ish. That's the kind of stuff a sysadmin dreams of.

Now that I'm a developer for a couple of years, exposed to a few different languages, design patterns and software architectures, that idea is still lingering around, but no longer focused on a hosted piece of software. The web is just too fast paced, bloated and way too much work compared to a piece of cross platform software.

In my spare time I've been chugging along on a piece of software, which I'm contemplating selling. In my case the commercial aspect is made more difficult because I also want to release the software with a GPL license.

This post describes the initial hurdles I'm encountering, next to just programming the software.

The yearly backup restore test

In my calendar there is a yearly recurring item named 'backup restore test'. This is an article on my backup scheme and the yearly restore test, covering all aspects, such as data validation, backup scheme, time and cost involved. I started doing personal restore tests each year around 2012, when I did them for my first job. At work back then, the restore test was monthly, for my own backups I decided that yearly was okay enough, since the backup scheme, software and provider do not change. I'm using Azure cold storage for my (locally encrypted) personal backups, since it's both cheap and supported by my local NAS. Have you done your backup restore test recently?

Responsive QML Layout (with scrollbars)

In this article I'll show you how to make a responsive layout in Qt / QML that automatically adjusts the amount of columns and rows based on the window dimensions, including scrollbars for when the content does not fit inside the window. This also works if you have a portrait and landscape orientation of your application, since the screen or window dimensions will be different across those two builds. I also explain how the dynamic resizing works with an explanation of property bindings in QML and as a bonus this works on mobile (Android/iOS) as well.

Qt/QML: Expose C++ classes to QML and why setContextProperty is not the best idea

In this article I'm going to discuss the different ways to expose a C++ class to QML. QML is a markup language (part of the QT framework) like HTML/CSS, with inline JavaScript that can interact with the C++ code of your (QT) application. There are multiple ways to expose a C++ class to QML, each with their own benefits and quirks. This guide will cover three integration methods, `qmlRegisterSingletonType<>`, `rootContext->setContextProperty()` and `qmlRegisterType<>`. We'll end off with a simple benchmark showing the difference in startup times between the first two.

Expose any Qt5 program via VNC

A few months ago I wrote about [Microsoft Teams running on a coffee machine. That was a fun work experiment where I got a VNC client running on the Linux-based coffee machines that we produce at work. In the comments on hackernews Jean-MichaΓ«l Celerier pointed me to the reverse, a way to expose any Qt application over VNC. This article shows you how I use this feature to work on our Qt 5 based coffee machine frontend as well as how you can use this on your machine, for example, to expose Dolphin, the KDE file manager, over VNC.

Rectangle{} debugging in QML, just like printf(), but for QT

Recently I've been using a debugging technique in QT/QML that I've decided to name `Rectangle{}` debugging, in the same vein as `printf()` debugging. QML is a markup language (part of the QT framework) like HTML/CSS, with inline Javascript that can interact with the C++ code of your (QT) application. QML has the concept of `anchors` for relative positioning of elements. Overall, `anchors` work quite well, but can get complex when inheretance and complicated layouts come into play. The `Rectangle{}` style of debugging places a semi-transparent rectangle with a border around your element so you can visualize the positioning and see what effect your changes have. This article shows an example where I recently applied this style of debugging at work in our coffee machine user interface, including some tips to do actual `printf()` style debugging (but with `Console.log`).

Relegendable keycaps for your macropad, the best thing ever for developer productivity

As you might know, I've got a weird keyboard. It is an Ergodox EZ, it's split up in two halves and for me it's the best thing ever to combat RSI. I've also got a weird mouse, a left handed vertical mouse, for the same reason. Even 15 minutes on a regular setup and my wrists and shoulders hurt. The next best thing is my standing desk and number three is having regular breaks with small exercises. One downside to the Ergodox is that you have less keys than on a regular keyboard. This is solved with layers, just like when holding SHIFT or CTRL, a key does something different. SHIFT is the layer for capital letters and symbols, with the Ergodox you can define your own layers. I however cannot get used to layers, not even after 7 years of using the Ergodox. Not a problem, I've got an extra keyboard in the middle, next to my mouse, with 8 or 9 keys just for my most often used shortcuts. It's called a macropad, one I've soldered myself and one I've bought on a well-known chinese webstore. One at work and one at home, both run QMK, firmware that allows me to program the macropad with my own shortcuts. Recently a video from Atomic Shrimp (awesome channel) showed off relegendable keycaps. Those are transparent keycaps with an insert for your own label. Before I had relegendable keycaps, I had regular keycaps for the macropad, for example, the `L` key sends `CTRL+ALT+L` to lock the desktop. Now, with these awesome keycaps, I have a dedicated `LOCK` key. This is such a big quality of life improvement, especially when using the CLion debugger shortcuts. This post covers my usage of the macropads, the re-legendable keycaps and shows you a few pictures of the macropads, both before and after.

Install NetBSD 9.2 on a DEC Alpha CPU with AXPBox

This is a guide on installing and running NetBSD 9.2 for the DEC Alpha CPU architecture on AXPbox, the open source Alpha Emulator. I recently wrote an article on how to install NetBSD in QEMU for Alpha and since I'm involved with the AXPbox project this article was just a matter of time. This guide shows you how to compile AXPbox and install NetBSD 9.2. It also shows you how to install packages without networking available and includes `openssl` and `sysbench` benchmarks, which we compare to NetBSD running inside QEMU.

Install NetBSD 9.2 on a DEC Alpha CPU in QEMU with X11

This is a guide on installing and running NetBSD 9.2 for the DEC Alpha CPU architecture in QEMU, including a GUI (X11 via VNC). It requires you to patch and compile QEMU yourself. It was never possible, until now, to run an actual operating system easily with QEMU Alpha, so this is amazing! It is very cool that Jason Thorpe is putting in so much effort on the QEMU side, as all but one patch is upstream already. Alpha emulation has always been a niche of a niche, so seeing this improve in QEMU is wonderful. OpenVMS does not boot yet since many more things are missing on the QEMU side, but who knows what the future might bring? Maybe even Windows NT for Alpha will boot on QEMU one day?

Remote desktop on NetBSD with Xnest (no VNC)

After I recently wrote about NetBSD on the DEC Alpha CPU in QEMU, I decided to play with NetBSD some more. One x86_64 virtual machine later, I'm starting to appreciate the beauty and simplicity. Great documentation, both online and via the manpages, low resource usage and boy oh boy does it feel fast. But, you're not here for my love letter, you want to have a remote desktop. In the earlier article, we set up VNC, both because it shows you how to install packages and because native X11 crashes. In this article, we are going to set up X11 forwarding via SSH, but with `Xnest` instead of VNC. `Xnest` allows you to have a full desktop / window manager inside a window. If you did a full install of NetBSD, then all you need is included on the system, no need to install any packages. This is an advantage if you are on an architecture that has no precompiled binary packages or if compiling from source takes too long.

Using IceWM and a Raspberry Pi as my main PC, sharing my theme, config and some tips and tricks.

KDE is my desktop environment of choice. KDE5 is rock-solid, configurable in any way possible and works great. It treats you like a responsible adult instead of a child like GNOME does these days, and after XFCE switched to GTK3, the RAM usage is on-par, more often than not a bare KDE install (Debian or Arch) uses around 300MB ram. This is with Baloo (search indexer) and Akonadi (PIM database backend) disabled. Great default behaviour, low resource usage and enourmous configurability, so why is this post then titled 'IceWM'? At home I'm using a small ARM device (Raspberry Pi 4 with an SSD) as my main computer, and there resources are limited. KDE runs fine, but you notice that it is a bit slower than on my work computer. IceWM on the other hand, uses less than 30 MB of RAM and even less CPU. The program that gives you a desktop background, icewmbg, uses double the RAM of IceWM itself! IceWM, next to Awesome, is one of my favorite window managers, very configurable and provides all I need. This PC doesn't have multiple screens, which would be a bit more of a hassle than with KDE. After switching, the machine feels a lot faster. It's the small details in which I notice it, like text input, a few seconds of lag here and there. This post shows my IceWM config including some options explained, my IceWM theme and a few tips and tricks to configure the rest of the desktop.

Firefox 89 Proton UI Tab Styling

Firefox 89 recently came out with a 'new' user interface (named proton). I'm not a fan of change because UX/UI people need to make it seem like their job is relevant. Also, the picture they show under the headline '17 billion clicks...' only scares the crap out of me, tracking every move a user makes in their browser seems to me to be a bad idea, but hey, lets see how long Mozilla can continue their war against their own users. Since the `about:config` flag to disable proton will probably be gone in a few releases I thought, why not try to get used to this new interface. It's so enormous and wide, lacking contrast. As you might have guessed, I cannot get used to the tab bar, so in this post I'll show you how to use the `userChrome.css` file to make the new tab bar look a bit more like the old tab bar.

Get started with the Nitrokey HSM or SmartCard-HSM

This is a guide to get started with the Nitrokey HSM (or SmartCard-HSM). It covers what a HSM is and what it can be used for. It also goes over software installation and initializing the device, including backups of the device and the keys. Finally we do some actual crypto operatons via pkcs11, OpenSSL, Apache and OpenSSH. We also cover usage in Thunderbird (S/MIME), Elementary Files (EF), a Web cluster with Apache and mod_nss and the decryption of the keys.

Execute a command and get both output and exit status in C++ (Windows & Linux)

Recently I had to parse some command line output inside a C++ program. Executing a command and getting just the exit status is easy using `std::system`, but also getting output is a bit harder and OS specific. By using `popen`, a POSIX `C` function we can get both the exit status as well as the output of a given command. On Windows I'm using `_popen`, so the code should be cross platform, except for the exit status on Windows is alway 0, that concept does not exist there. This article starts off with a stack overflow example to get just the output of a command and builds on that to a safer version (null-byte handling) that returns both the exit status as well as the command output. It also involves a lot of detail on `fread` vs `fgets` and how to handle binary data.

Exclude lines in less (or journalctl)

This is a small tip I want to give you when using a `less` based pager, for example in `journalctl` or when viewing a file interactively with `less` or `more`. You can exclude certain lines that match one or multiple words (or a regex) with a few keystrokes, once `less` is open. This is one of those tips you never knew you needed, but when you know it, you'll use it frequently. Like in my case today when searching through some logfiles to find out why my database stopped working.

All packages that were present in Ubuntu 18.04 but absent in Ubuntu 20.04

Otherwise titled `Figure out the differences between two apt repositories`. Recently I've had a few packages that I often use but were missing from Ubuntu 20.04 LTS. One is [ckermit](/s/blog/Ive_packaged_up_CKermit_as_a_snap_for_Ubuntu_20.04.html) and the other is [gnash](/s/blog/Ive_packaged_up_Gnash_as_a_Snap_for_modern_linux.html), both of which I 'converted' to a snap. (In air quotes because I just converted the 18.04 deb). This made me wonder if I could figure out a list of that are present in Ubuntu 18.04, but absent in Ubuntu 20.04. As `apt` and `dpkg` are standardized tools and and package formats, we can use a few shell tools to parse the package lists and compare them side by side. This post shows you how to do the comparison yourself and I discuss the removed packages a bit. Some are version increments (like `gcc-6` in Ubuntu 18.04 but `gcc-7`in Ubuntu 20.04), and some are packages that were combined into one instead of split up (like `ltsp` in Ubuntu 20.04 but a bunch of seperate `ltsp-$postfix` packages instead in Ubuntu 18.04). Many others are just replaced by newer versions (`python-ceph` vs `python3-ceph`). The list of differences is provided as a download, both ways.

I've packaged up CKermit as a snap, for Ubuntu 20.04

Last year I packaged up [gnash as a snap](/s/blog/Ive_packaged_up_Gnash_as_a_Snap_for_modern_linux.html) because it was missing from the Ubuntu 20.04 apt repositories. Recently I found out that `ckermit` is also not in Ubuntu 20.04, as far as I can tell because it wasn't in the Debian repositories when the Ubuntu 20.04 initial sync happened. Which is very inconvenient for an LTS release. I often use `ckermit` to connect to our hardware via a script, to automatically boot from NFS (via u-boot). I could do that manually via `screen` or `minicom`, but I have a `kermit` script that does it for me, which is very convenient. Since the snapping of `gnash` was so easy, I decided to do it for `ckermit` as well, since I now know how to convert deb packages to snaps. I also have a few colleagues who also use those kermit scripts and are going to update to 20.04 in the (near) future. The snap packaging is based on work by Phil Roche, he wrote about re-packaging older debian packages with an Ubuntu 18.04/16.04 base layer as a snap. My `ckermit` package is confined (no `--classic` needed), the source code for the snap is on my github and on any snap-enabled distro you can now 'snap install ckermit-raymii' to enjoy CKermit.

I've packaged up Gnash as a snap, for modern linux

I hate snaps just as much as the next guy but last week I did something unexpected. I packaged up Gnash as a snap. Gnash is a GNU flash media player, not updated since 2011, and thus removed from the Ubuntu 20.04 repositories. The snap packaging is based on work by phil roche, he wrote about re-packaging older debian packages with an Ubuntu 18.04/16.04 base layer as a snap. My gnash package is confined (no '--classic' needed), the source code for the snap is on my github and on any snap-enabled distro you can now 'snap install gnash-raymii' to enjoy Gnash again.

It compiles does not always mean that it works, a tale of virtual overridden fun in C++

In a [recent article on clang-tidy](/s/snippets/Run_one_specific_clang-tidy_check_on_your_codebase.html) I referenced the fact that we're doing a huge refactoring regarding `char` pointers, lifetime, ownership and `std::strings`. Todays post is another one related to that change, where even though everything compiled correctly, it didn't `work`. For a compiled language, that is not something you expect. Next to unit tests, a compiler error is your number one sign that you've made a mistake somewhere. In this case however, the code all compiled fine. The issue here was an older part of the code not using `override` combined with automated refactoring in CLion missing some parts of the code during a change. So, the issue in this case is entirely our own fault, it was spotted in the manual testing, but I'd rather had it not happen at all. In this post I'll describe the problem including some example code that illustrates what happened. My key point is that even though the code compiles, you should always test it, preferably automated with unit and integrations tests, otherwise manually with a runbook.

Run MS Teams on a coffee machine?!? (Or: Embedded Linux Framebuffer VNC client)

To fill some time [during compiling](https://xkcd.com/303/) I tried to get a VNC client running on a coffee machine, specifically to show MS Teams. At work I develop software for these coffee machines in C++, which allows me to do such fun stuff, because from a software point of view, it's just an ARM PC running linux with a framebuffer for graphics. I compiled a few framebuffer VNC clients, fired up an SSH tunnel and used `x11vnc` to share one specific window and after a few attempts, Teams was up and running on my 'new' second monitor. This post contains my little adventure in framebuffer VNC clients, but it's not a comprehensive guide as most of my other articles. Showing you how to set up an Openembedded server with a VariScite specific toolchain is way too much work to cross-compile a simple C program, but since that's my day job, why not use it for fun. It contains some tips for `x11vnc` and shows you two different framebuffer VNC clients, `fbvnc` and `directvnc`.

Run one specific clang-tidy check on your entire codebase

Recently I did a major refactor on a piece of code that involved thousands of lines of code which were in one way or another related to string handling. All of the code handled `char*` (C style character pointer arrays) and the concept of `const` or ownership was literally unknown in that part of the codebase. The refactored code uses `std::string`'s, but due to the legacy nature, a large number of methods returned `nullptr`'s instead of empty strings. I understand why this was done, but finding all those instances and the fact it only gives a runtime error was a bit of a bummer. Luckily `clang-tidy` is here to save the day. In my IDE, CLion, it gives a warning when you return a `nullptr`. It however does that only in the file you're currently editing, and since we're talking millions of files, I wasn't going to open them by hand. You can run `clang-tidy` easily on one file, and it's not hard to run it on an entire codebase as well, using the script `run-clang-tidy.py`, provided in their packages. This snippet shows you how to run one specific `clang-tidy` check, in my case, `bugprone-string-constructor`, on a (cmake and C++) codebase.

Three ways to print booleans as 'True' or 'False' in C++

In this article I'll show you three ways to print a textual representation of a boolean in C++. Normally a bool is printed as either a `0` or a `1` by `std::cout`, but more often than not, if you're printing a `bool`, it's better to see `true/false`. Imagine reading through lines and lines of boring, repeating log files, how easy is it to miss a `0` in a sea of `1`'s? I've been there many times, wishing for more verbose logs. I'll start with a simple `printf` with a ternary `if` e.g. `(a ? this : that)` and continue on to `std::boolalpha`. The latter one is more flexible and allows you to set different values to be printed, for localization, and can even be used to parse input streams. That means, the string `true false` results in two `booleans`, the first being, well, `true` and the latter, surprisingly, being `false`.

Disable (debug) logging in QT and QML

In QT you can use a few functions from the `qDebug.h` header like `qDebug()` and `qWarning()` to log information to the console. In QML you can use the likes of `console.log()`, `console.error()`. It's also very easy to implement your own logger (eg. `SyslogMessageHandler`) if you want something different, like logging to syslog and the console. In this post I'll show you how to disable both forms of logging in a release build, qml and qt have different ways to manage their output.

QT / QML Signals and Slots with C++

QT has an Observer mechanism built in, which they call '[Signals and Slots](https://web.archive.org/web/20210210180603/https://doc.qt.io/qt-5/signalsandslots.html)'. It allows objects to communicate with each other without having to have knowledge of either ones internals. By inheriting from `QObject` and defining a few `Q_PROPERTY` macro's, the QT Meta Object Compiler (`moc`) does all the hard work for you. Inside a C++ class this all works handy dandy and is reasonable easy to follow, but when using QML it requires a bit more work. This small example shows you how to bind QML and C++ together using signals and slots, in QT 5.12.

Limit specific process memory on desktop linux with cgroups and earlyoom

On my laptop I recently had trouble with out of memory issues when running `clion`, `firefox`, `thunderbird`, `teams` and a virtualbox VM. To combat this, I've setup cgroups to limit how much RAM specific applications can use and configured `earlyoom`, a very nifty tool that checks available memory and kills the process with the highest `oom_score` if available memory falls below 5%. Otherwise, my laptop would first grind to a halt (even without swap) and only after half an hour of seemingly being stuck would the OOM killer kick in. With `earlyoom` this hanging behavior is gone, although sometimes applications get killed when I don't expect it. I've given firefox, thunderbird and teams a cgroup with memory limit and clion and virtualbox use their own configuration to limit their RAM usage.This post details how to setup `cgroups` to limit memory of specific processes including automatically placing process inside a cgroup.

Reset the SYSTEM password on OpenVMS 8.4

This short post shows you how to reset the SYSTEM account password on a single OpenVMS 8.4 ALpha machine via the serial console. You need physical access to the machine and the procedure looks a lot like linux and appending `init=/bin/bash` to the GRUB commandline to boot into single user mode. It is tested on the AXPbox Alpha emulator, I forgot my password after not using it for a month.

The Common Desktop Environment (CDE) is still developed and modern in 2021

While playing around with the GUI on OpenVMS I was looking for CDE documentation and I found out CDE is still being developed and can be installed on modern linux. This quick post shows you how to install CDE on Debian 10 and includes a bit on compiling GENERIC TETRIS, the same program I installed on OpenVMS. Really cool to compile and run a game from 1992 on a retro/modern desktop environment.

OpenVMS CDE Desktop Remote X session GUI (on AXPbox)

Last year November, I posted on a new OpenVMS related project, AXPbox, the open source Alpha emulator, a fork of es40 by TomΓ‘Ε‘ Glozar. Last week I put together the first official release of AXPbox, one of the changes being in the network code, making it more stable, thus being able to run a remote X session. Meaning, you can run the CDE desktop and enjoy everything the OpenVMS GUI has to offer. This article shows you how to run the CDE GUI in a remote X session, including switching between the old Motif look and the new DECWindows and how to run Tetris.

AXPbox version 1.0.0 released! (Open source Alpha emulator)

Last year November, I posted on a new OpenVMS related project, AXPbox, the open source Alpha emulator, a fork of es40 by TomΓ‘Ε‘ Glozar. I got involved a bit in the project, submitting a few patches here and there, editing the Wiki and thus now have contributer rights on the github repository. After discussing a bit back and forth with TomΓ‘Ε‘, I put together the first official release of AXPbox, very exciting news. The release can be found here on github. This article has the release notes and a bunch of screenshots of OpenVMS inside AXPbox running GUI applications over the network.

Site updates, new font for better contrast and other small CSS fixes

New year, time for some site updates. This site is generated with my self-written open source static site generator named ingsoc (named after 1984) and this update is a collection of small improvements. A new font, internal code updates to the generator and a few CSS fixes here and there. This article goes over all of them including screenshots before and after!

Bash HTTP monitoring dashboard

This is a shell script that creates a webpage with the status of HTTP(s) sites. Parallel checking, thus very fast, only dependencies are curl and bash (version 4 or above). For all of you who want a simple script with a nice webpage to check a few websites. Perfect for a wall mounted monitoring display and a Raspberry Pi. Installation and configuration is easy to do inside the script. It scales well, both on the checking side as the information display page (dense on purpose). Failed checks appear right on top for you to act on. I had this script running at home for at least a year in that form, when I showed it to a friend he liked it, asked me to make it public, but before I did that I polished it up a bit.

C++ std::async with a concurrency limit (via semaphores)

std::async is an easy way to do multiple things concurrently, without the hurdle of manual thread management in C++. Like batch converting images, database calls, http requests, you name it. Create a few 'std::futures' and later on when they're ready, '.get()' 'm while they're still hot. A 'future' is an object which handles the synchronization and guarantees that the results of the invocation are ready. If you '.get()' it and it's not ready, it will block. Recently I had a use case for concurrency with a limit. I needed to do hundreds of HTTP calls to a JSON API. The concurrency limit was not for the hardware, but for the server on the other side. I didn't want to hammer it with requests. There is no standard way to limit the amount of concurrent jobs via 'std::async'. You can fire of a hundred jobs and it is up to the implementation to not fry the hardware. On linux/gcc it will probably use a thread pool so you're lucky, but you cant assume that. This article will show you a simple short solution to implement a concurrency limit together with std::async, by using a semaphore, implemented with modern (C++ 11) standard library features ('std::mutex', 'std::condition_variable' and such). It also has a C++ 17 version which replaces our custom CriticalSection class with the use of an 'std::scoped_lock' and 'BasicLockable'. We start off with a shorter example showing how to fire off a set number of jobs and wait until all of those are finished before continuing. That is very useful if you have a set number of jobs and want the implementation to handle all the thread work for you.

Lets talk about changelogs, or, how I loathe 'bugfixes and performance improvements'

This is a short personal rant to start the new year off. When you're a multi billion dollar company with more software developers than you'd ever need, how on earth is it possible that your public changelog in an app store is just 'bugfixes and performance improvements'? If that is all you're going to put there, then just leave it blank. Or be honest and put 'We can't be arsed to fill this in' there. For me as a technical user it's not actionable, and your non technical users are not going to read that page anyway.

Hacker News vs Lobste.rs in C++, an exercise in parsing json http api's and date/time/timezones

I recently wondered how many top posts on the Hacker News frontpage are also on Lobsters. At first I reached for my trusty Python, because when I need to do some JSON API parsing that's what I'll use. (Otherwise bash is my default goto for small things, except when json, networking or associative arrays are involved.) But, then, a thought came to my mind. Why not try it with reasonably modern C++. It's what I do at work, so why not a simple personal project. It would involve dependency management (json and a http library), parsing both API endpoints and, most importantly, doing stuff with time. Time, timezones and dates are hard. This article contains a bit of my learning process, compilation and usage instructions and an example run. Go look at the code and run the code yourself. Let me know if my timezone calculations are working outside of GMT+1.

C++ set up cpp-httplib with SSL support with cMake

For a small personal project that talks to a few JSON API's and does some data parsing I needed a header only C++ HTTP library. Header only because that is the simplest way to include it in my project, just copy and paste the file. I came across the project cpp-httplib, which fits my needs, does all the http methods, small, a few examples and it looks modern and has recent development commits. Setup and getting it working was easy, but as soon as I tried an https url, I got an exception ('https scheme is not supported.'). This guide shows you how to setup cpp-httplib for SSL support with cmake. It took me a bit longer than I wanted to set it up correctly, so why not save you the effort.

Semi-accurate live stream viewer count (hls/rtmp/restreamer) on the command line

Due to all the working-from-home in the past few months I had to setup a live stream. At first the stream went directly to YouTube, but after they've screwed up multiple times, we decided to not be dependent on them. Using restreamer, a piece of open source software to live stream both to your own server and to another (YouTube) at the same time, we have more control over the stream and are not surprised by YouTube doing stupid stuff unannounced. Restreamer provides a simple web player that works on all major platforms and streams to YouTube, but one thing it lacks is a live viewer count. That's a hard problem to solve correctly and accurately, in this article I'll show you how to do it semi-accurately via multiple ways, including live graphs. This article contains a rant on YouTube breaking stuff and the commands used to get a live viewer count.

Installing OpenVMS 8.4 Alpha inside AXPbox on Debian 10 / Ubuntu 20.04 with networking

In my previous article I announced the fork of the `es40` emulator to `AXPbox` by TomΓ‘Ε‘ including bug fixes and rework allowing it to install OpenVMS 8.4 without problems. Since then I've contributed a few patches and doc updates, now NetBSD boots as well (the patches for netbsd were from other es40 forks). I've also looked into getting networking setup, since that is a bit of a tedious process due to pcap and linux, pcap being used for network emulation. SIMH (among others, a great VAX emulator) suffers from the same problems with networking. This guide will show you how to install AXPbox and get OpenVMS 8.4 ready and running with networking inside AXPbox. It's a rather long guide with a lot of information and output.

std::accumulate in C++

I'm using codewars to practice my development skills. Today I found out about the std::accumulate method in C++ while doing an exercise there. I'm sharing it here because I never heard of it before. It is the numeric header, and it also accepts a custom binary function to apply instead of operator+. This snippet shows some examples including a lambda operator and the for loop you would use otherwise.

Get number of incoming connections on specific port with ss

Recently I had to write a few monitoring plugins, one of which was a count of incoming connections to a specific network port. In the past I would have used netstat and a combination of grep and wc filter out only specific ports and established connections, but nowdays netstat is replaced by ss on ubuntu. ss has options to filter directly on all sorts of stuff, like state, ports, protocol, making the command I use more readable and use less pipes.

Exciting OpenVMS Alpha Emulation news, es40 has been forked to Axpbox (and works!)

Back in 2018 I was playing around with OpenVMS a lot, as it continues on the legacy of the PDP-8 and PDP-11. OpenVMS 7.3 on the VAX emulated via SIMH runs perfectly, OpenVMS 8.4 for Alpha was kind of a disaster, or, the es40 emulator was. Real hardware is available via IslandCo, but shipping to the Netherlands is horribly expensive. The only options back then for emulation of Alpha were FreeAXP or AlphaVM, both paid, closed sourced products with watered down free versions. Nothing wrong with that, it enables us to play around, and now that OpenVMS is in the hands of VMS Software with an x86 port coming along we may hope for a bright future ahead for OpenVMS. VSI currently provides a hobbyist version, but it's a FreeAXP bundle for Windows only. Recently I got an email from TomΓ‘Ε‘ regarding his fork of the es40 emulator, axpbox. This short post is intended to give this emulator more visibility and exposure, since I find this to be amazingly cool and exciting. It lists the bugs fixed and new features, which allow OpenVMS 8.3 and 8.4 to install perfectly.

What does raymii.org cost to run?

Inspired by recent articles from Kev Quirk, Horst Gutmann and Jan-Lukas where they do a cost breakdown of their sites, I decided to do one as well. Kev is around USD 30, Horst is around USD 13 and Jan-Lukas is around 5 USD. Their breakdowns are interesting, from specific wordpress plugins to CDN or DNS costs. I don't have those, but I do have a multitude of small servers running this site, which add up to around USD 20, adding up two domain names gives me around USD 22 per month. It could be a lot cheaper, I only need one server for the gigantuous amounts of static HTML this site consists of, but I do have around 10.000 unique visitors each day, so having redundancy is nice. If I would go all cheap, this site would cost me no more than 2 USD a month including the domain name, but that would take the fun out of it. This article features a list of similar, how much does my site cost articles and a cost breakdown of this site.

Tiny Tiny RSS vs Miniflux

I'm an heavy user of RSS feeds, having over 1500 feeds I follow. Without a decent feed reader that setup wouldn't work. For over eight years now I've been an happy user of Tiny Tiny RSS, a web based feed reader. But, recently I found out about 'miniflux', also a web based RSS reader. In this article I'll compare the two for my use cases, mostly mobile usage. TD;DR, I've switched to Miniflux, due to it being more suited for mobile usage, less ajax heavy, easier to subscribe to feeds and a more pleasant reading layout.

Store multiple types in a single std::map in C++ with std::any, just like a python dict

In C++, everything has a type. When declaring a function you specify the return type and for each parameter you specify what type it is, just as for regular variables. Templates aside (those still have a type), you almost always know what type of data you're working with. There is the 'auto' keyword, which can save you a lot of typing and duplicate code, but fundamentally you're still working with types. Since C++ 17 you can use 'std::any' to store anything, without knowing the type. This is awesome for some tasks, and horrific for most use cases. In this article I'll show an example of a 'std::map' with 'std::any', that behaves like a python 'dict', it's able to store multiple different types in the same container.

CookieNumberPrinter, incremental / idle game style numbers in C++

To level up my software development skills, I'm programming a command line game in my spare time. It is a clone of the famous cookieclicker game by ortiel. A clone of a game is simple enough to get up and running fairly quickly, but also extensible enough when needed. How do you store huge score numbers when they don't fit in a long long? How do you write a game loop, how to use threads to handle user input? Saving a game (how to design a proper save format)? Also a great way to learn about project organization, software architecture and to try out design patterns. As the game is a clone of CookieCliker, which itself is an incremental game, I had to figure out how to work with large numbers. Since this is not a university math project, I allowed myself the luxury of using Boosts Multiprecision. The library handles the large numbers, including caluclation and operations with such a number. I did want to print the numbers in Idle Style, where large numbers are displayed with a suffix, like '1 million' instead of '1000000' and so on. This 'C++' class can be used to print Boost's 'cpp_dec_float' numbers in incremental style. It's just one header.

Get all SSH public keys from gitlab

This small snippet gets all the SSH keys from a gitlab instance. You need to be an administrator, then you can query all keys at once using the API. On the web frontend you can only see the keys per user, not all at once in an overview.

Local incremental backups of Google Photos on Ubuntu with gphotos-sync

'Google Photos' no longer syncs with 'Google Drive' or with their 'Backup and Sync' desktop software. There used to be a checkbox to get your 'Google Photos' pictures in 'Google Drive' but that has been disabled. I used that feature together with their 'Backup and Sync' tool to sync all the photos in 'Google Photos' to my local Windows computer. From there I use 'DigiKam' to manage the photos and backup them offline and offsite. Due to Google removing that feature, I had to go find another way to get the pictures out of 'Google Photos', which, after a few months of (automated) use, 'gphotos-sync' on Ubuntu seems to be the best, stable choice. In this guide I'll show you how to setup incremental backups from 'Google Photos' on Ubuntu. My 'DigiKam' database moved over without problems, and now I'm glad I don't have to use Windows for picture managemant anymore.

Get webcam resolution and info on Ubuntu and fix HD

With all the video calling nowdays due to working from home I decided to get a webcam. Since I mostly work at a workstation, I have no microphone or camera built in. A friend gave me a spare webcam, a generic non-brand. It says 'HD Camera' on the box, but by default it records in 640x480. Using a few tools on Ubuntu you can figure out what resolutions are supported for your device. It turned out to be Cheese, the webcam capture program I used, not supporting the 'mjpeg' format, just the 'yuyv' RAW format. Using another webcam program named Webcamoid solved it, that program was able to use mjpeg.

Ubuntu Snap auto updates broke my development setup and there is no way to turn them off

After updating-by-reinstall to Ubuntu 20.04, I installed CLion via snap since that seemed more convinient than manually downloading a java installation. CLion is the best thing since sliced bread, or I mean a C/C++ IDE by JetBrains. Ubuntu snap is a packaging system made by Canonical and pushed hard in Ubuntu. Today I found out the hard way that snap auto-updates and that there is no way to turn that off permanently. CLion was updated, which I noticed because the process was killed. The update broke several key plugins for my workflow and the theme was weird. In this article I'll discuss my disgust, I as the owner of the computer want to be in full control, not some developer that decides I need auto updates. I ended up removing snap completely, and my next install will not be Ubuntu due to this.

The Twitter Bitcoin hack can happen anywhere humans are involved

The recent twitter hack involved social engineering and access to the twitter backend. This opinion piece will show you that this sort of incident can happen everywhere as long as humans are involved. Everywhere there are manual actions or admin / backend panels, this can happen. Pay a support-slave enough and they'll delete an account 'by accident'. Or a rougue sysadmin that disables logging, does something horrible and enables logging again. I'll show you that there is no one size fits all solution. Or at least, not a single fix for all. Treating your employees well, educatingthem on risks and automating as much as possible will get you a long way.

Running gnash on Ubuntu 20.04 (in Docker with X11 forwarding)

As you might have noticed, I'm slowly updating servers and workstations to Ubuntu 20.04, and as always with major upgrades, things break or are removed. Earlier this week I fixed up pygopherd and today I'll get gnash running again. Gnash is not updated since 2011 and therefore, finally, removed from the Ubuntu 20.04 repositories. Compiling it from source proved to be a lot of effort due to gstreamer dependencies and after a few hours I thought, why not just spin up a Ubuntu 18.04 Docker container, install gnash and forward X11. That took just about 10 minutes and now I'm happily running gnash again. In this tutorial I'll show you how to setup gnash in a docker container with x11 forwarding and host networking.

Installing PyGopherd on Ubuntu 20.04

Ubuntu 20.04 dropped the Pygopherd package. There is no way to install it from the official repositories. In this guide I'll show you two ways to install the version from Ubuntu 18.04, which still works perfectly on 20.04. Either via just downloading the 2 deb packages, or via `apt pinning` from the previous (18.04) repository.

Generate QR code and write it to a PNG, scaled, in C++

The QR-Code-Generator library by Project Nayuki for C++ gives you an easy, fast and correct way to generate QR codes. However, you get just a data structure, showing that data is up to you. An example is provided to print the code to a terminal, but not to create and actual image file. For Java, there is an example provided which writes a PNG file, but not for C++. The author of the library also has another C++ library, Tiny-PNG-Out. It is correct up until 700 megapixel PNG files, which I hope your QR code never hits. I've written a class which bridges the two together, allowing you to both generate the QR code and write it to a PNG file, scaled up to be as readable as possible.

Github Actions, C++ with Boost and cmake, almost a 50% speedup with caching

For a personal project I use Github for source code hosting and Github Actions as an automated build and test tool. Github Actions compiles my cmake project and runs all the unit tests on every commit. It also saves a build artifact, the actual compiled program. By utilizing some dependency caching and make flags I sped up the build process by 43% by caching the apt install libboost1.65-dev and giving cmake a -j2 makeflag. This article shows my simple setup to compile a C++ project with cmake and Boost on Github Actions. After compilation, it runs all the tests and uploads the compiled binary for download. For my one man project it's overkill, but when collaborating or when builds take a long time on your own machine, it's great to have an automated build / test system.

I had to jailbreak my iPhone to change the default browser...

The title of this article says enough. To change the default browser on an iOS device you need to jailbreak your device (root it). It's 2020 and Apple does not allow you to switch Safari with Firefox. Recently a new jailbreak for iOS was released which support the lastest firmware, 13.5. I currently have an iPhone SE 2020 running 13.5, the jailbreak was a welcome addition to fix some small and some big annoyances with iOS. Like switching to Firefox as default browser. This post contains both a small rant on the state of iOS as wel as links to the jailbreak and applications used to switch the default browser.

Here be dragons, or, invalidated iterators

Recently I had a new 'first-time' moment. You know the ones, the, 'oh right', moments, after you put in a bit of research. Mine was, as you might expect from all the other recent content, related to C++. I learned, the hard way, that 'iterator-based for loops' don't like to be resized during the loop. Well, they don't really care, but some precautions are to be taken since the 'iterator' used in the loop might be invalidated. Or as the very helpfull error during the crash prints to the console, 'munmap_chunk(): invalid pointer' and your debugger points you to somewhere deep in 'new_allocator.h'. In this article I'll give a few examples, both using index based for loops and iterator based for loops, plus some more details on what's going on with iterator invalidation.

C++ async, threads and user input

For an unrelated piece of code, I recently spent a few days trying to figure out if there was a portable, modern C++ way to handle user input with a timeout. If there is no input after a few seconds, the program can continue doing other things. TL;DR, there is none, since stdin is blocking I/O. At the end of the article I'll also provide the code I ended up using, which uses two actual big-boy threads, one for input and one for 'other work'.

Personal Wireguard VPN on a Freedombox with Debian

This guide will show you how to set up a personal Wireguard VPN server on Debian or Ubuntu with Freedombox. Freedombox will be used to manage the VPN software, firewall and users. Wireguard is a relatively new VPN built in to the linux kernel. Freedombox is a long running project under the Debian umbrella providing a private server for non experts with focus on user freedom, ease of use and privacy. Combined, those two make a great pair. In the past I've written many articles on how to setup your own personal VPN server, but those all required manual setup and maintenance. With freedombox, the updates are automatic and the management is hidden away behind a convenient web interface.

Installing Freedombox on Armbian on the Olimex Pioneer

FreedomBox is a private server for non-experts: it lets you install and configure server applications with only a few clicks. It runs on cheap hardware of your choice, uses your internet connection and power, and is under your control. Last year the Pioneer became available, officially supported and sanctioned by the Freedombox Foundation. This is a home server you can buy from Olimex, comes in a nice metal case with a proper power supply, network cable, battery and SD card preloaded with Freedombox. Plug in and go. Perfect for users that don't want to tinker but do want their freedom and control. With the Pioneer, both the hardware and software are fully open source. In the default provided distribution for the Pioneer there are a few things I dislike. This guide covers the installation of Freedombox and Debian for the Olimex A20 Lime2 Pioneer with Armbian including reinstalling, Apache SSL certificate and LDAP issues.

nginx 1.15.2, ssl_preread_protocol, multiplex HTTPS and SSH on the same port

The NGINX blog recently had a nice article on a new feature of NGINX 1.15.2, $ssl_preread_protocol. This allows you to multiplex HTTPS and other SSL protocols on the same port, or as their blog states, 'to distinguish between SSL/TLS and other protocols when forwarding traffic using a TCP (stream) proxy'. This can be used to run SSH and HTTPS on the same port (or any other SSL protocol next to HTTPS). By running SSH and HTTPS on the same port, one can circumvent certain firewall restrictions. If the session looks like HTTPS, nginx will handle it, if it looks like something else, it will forward it to the configured other program. I used to use SSHL to get this functionality, but now it's built into the nginx webserver. This small guide will cover the installation of the latest version of nginx on Ubuntu (16.04) and configuring this multiplex feature.

Windows 10 updates with PowerShell

Recently I had issues updating one of my machines that runs Windows 10. Turns out the firewall was to restrictive. However, the information provided by the update dialog was just, 'Oh, updating failed, maybe try again'. Nothing useful, so I tried to figure out if it's possible to use Powershell for updating. Since Windows 10 build 1709 Microsoft provides a built in module, but that is not that user friendly. In this article I'll talk about using PSWindowsUpdate and the built in Microsoft WindowsUpdateProvider to update a Windows 10 machine via the commandline

Run CLion native on Android, ditch your desktop!

How often do you read articles that state that people have replaced their main computer with an iPad and are fully content? Now, how many of those articles just use a linux server (vps) somewhere with some native apps, but mostly SSH to that server? Well, what if I told you that you can run a full blown IDE, the best IDE for C++ there is, CLion by JetBrains, on Android? Including compiling, just native GCC, CMake, GDB and all the stuff you are used to? Just for fun I've installed CLion on an old Samsung Tab S2 I had lying around, using Ubuntu in a chroot. It works way better than I'd expected, with a Bluetooth keyboard and mouse it's almost as if your on a desktop. I wonder if you could run Android Studio and use the tablet to compile app's for itself. This article shows some photo's, including a mechanical keyboard, different window managers and had instructions to replicate this setup.

Tiny Tiny RSS + Readability == The best way to read RSS feeds

Back in 2012, I already wrote about Tiny Tiny RSS. We're now almost eight years later and I still use TT-RSS as my main RSS reader. I'm following almost a thousand feeds (944) and it is my main way of reading and discovering stuff online. All those personal blogs that post once half a year, mainline tech news sites and a bunch more sites. Back in 2012 I had 300 feeds, used the Android app. Nowdays, more feeds, still use the android app, used an iPhone app for a while and the server that it runs on has been migrated and upgraded a few times. I want to share my Tiny Tiny RSS setup with you, which uses the af_readability plugin. Combined with the Android app, I've got an ideal setup to read just content without distractions.

ScreensaverStopper, stop activating the screensaver by sending F24 often

ScreensaverStopper sends the F24 keystroke every 40 seconds. This way, Windows should not activate the screensaver. Useful if you do not have rights to disable the screensaver, but can run executables. Wwritten in C++, compiled with GCC 8.1 via MinGW/cMake. Filesize is around 14 KB, memory usage after a day of running around 600KB. License is GNU GPLv3.

and & or are valid in C++ (alternative tokens)

A post on lobste.rs on the C feature trigraphs triggered me to write this piece on the C++ feature, alternative tokens. I've recently suprised a co- worker by using an if statement with 'or' instead of '||', which works fine, but he never saw it before. It's in C++ since C++ 11, but MSVC requires a specific compiler flag ('/Za') or the 'iso646.h' header. This post has a few samples on the usage inclusing other alternative tokens like bitor, xor and or_eq.

Broken Corrupted Raspberry Pi SD Card

One of my Raspberry Pi's would not boot up after a reboot. The SD card was corrupted, sadly beyond repair. This article walks you through the steps I took to try to fix the SD card, including fsck, badblocks and other filesystem utilities. It also has tips to reduce the writing on the Raspberry Pi, this to save SD cards from some amount of wear and thus possible corruption.

Weight for Weight, a coding exercise that kept me busy

I'm using codewars to practice my development skills. The exercise I was working on the past couple of days was a level higher than the 'rank' codewars gives me, so a more difficult exercise. Using the sparse free time I have, this kata took a bit longer to complete, and had me thinking about the problem when I was not doing the exercise. If a problem fascinates me that way, I can't stop thinking about it until I've solved it. In this article I'll walk you through my work on this kata.

std::string to lowercase or uppercase in C++

I'm using codewars to practice my development skills. Today I learned a method to transform a std::string's casing, either to uppercase or lowercase. Researching it further, I also found out how to do unicode strings with boost. This article also includes a mini howto on installing Boost on Windows 10 via mingw for use with CLion.

C++ project setup with CMake & unit tests (google test)

This guide will show you how to setup a new C++ project with CMake and unit tests via Google's test framework. With this setup you can get started right away with test-driven-development in C++. It is also simple enough to look and figure out how to add gtest to your existing project and start doing TDD on your legacy (existing) codebase.

Get serial port data on the web with live updating

Recently I was asked to build a test setup to measure the accuracy of a few loadcells (weight sensors) in a frame. Someone other than me would execute the test and required access to the measured data, preferably live and without needing knowledge of ssh or linux. The weight sensors can be read with an openscale board from sparkfun via a serial connection which the board emulates over USB (via an FTDI chip), via that same serial connection you can also calibrate them or change settings like amount of decimals. As a quick solution I created a webpage that uses a small amount of javascript to live update the readings from the board. screen is used to capture the output of the serial connection to a file which the webpage displays and updates. In this article I'll talk about how I put various bits of software together to get the output of the serial connection onto a nice webpage with live updating.

Bash bits: find has a -delete flag

Bash Bits are small examples, tips and tutorials for the bash shell. This bash bit shows you that find has a -delete option. I recently found this out, before I would always use -exec rm {} ;. The delete flag is shorter, performs better and is easier to remember.

Only zero is false, everything else is true in C++

When using numbers in a boolean (implicit conversion), remember that only zero evaluates to false. Anything else, including negative numbers, will evaluate to true. This snippet talks about the rules for implicit conversion in C++ when using booleans. For seasoned programmers it's nothing new, but I found it interesting.

GNUplot tips for nice looking charts from a CSV file

Recently I had to do some testing which resulted in a lot of log data. Looking at a bunch of text is not the same as seeing things graphically, this particular logdata was perfect to put in a graph. My goto favorite tool for graphs and charts is gnuplot. Not only is it very extensible, it is also reproducable. Give me a configfile and command over 'do this, then this and then such and such' in Excel to get a consistent result. In this article I'll give tips for using gnuplot, which include parsing a CSV file, a second axis, environment variables, A4 PDF's and a ton of styling options for a nice looking chart.

connman operstate list

Recently I was debugging connection issues with a system that uses connman as it's network management software. In the log it was visible that the connection went away and came back, logged with 'operstate' $number $state. I couldn't easily find an overview of all the possible states, but since it's open source we can take a look at the code to find out. Publishing it here for future reference.

C++ template definitions in a .cpp file (instead of a header file)

In this snippet I'll show you how to place your C++ template definitions in a seperate .cpp file. I'd recommend you to just put template definitions in your header file, or a .hpp file, but if you really want to there is a trick to get them in a seperate .cpp file. The trick is to explicitly instanciate every template you're going to use at the end of the .cpp file. With many different templates and types this becomes cumbersome, but for certain usecases it could be useful.

C++ create and write to a CSV file with a variadic template

In this snippet I'll show you a variadic template to write to a file. In line with my other experiments to get a better grasp at templates, this example improves on my earlier attempt by using a variadic template, thus allowing you to provide an infinite number of columns to the csv file of any type that has the overloaded << operator.

C++ create and write to a CSV file

In this quick snippet I'll show you how to create and write to a csv file. It includes checking if the file is writable, and if it's not there, creates it with a different first row as header. It's a quick example, I've used it to log some test data. It can probably be improved.

Dark Reader, dark mode for any website

Recently I discovered a firefox extension that converts any website into a dark version. Works both on firefox for mobile and on the desktop (and all other major browsers), is open source, causes less strain on the eyes and improves battery life. Just as the earlier post on Blokada, I find this such a cool piece of software I wanted to share it with all my readers.

Cooking with C++ templates and stronger types

To gain a better understanding of C++ templates I'm playing around with them. Most of the online guides stop at the example of a simple template to, for example, get the max of two inputs, or cover just a bit more (like how to overload operators for your specific template classes to make << and + / - work). Combining templates with a stronger type to pass stuff around led me to a test kitchen. As in, some code with ingredients, amounts and an oven. One small thing kept it from working, after some feedback it turned out I was passing the wrong parameters to the template. Afterwards the error also made sense. This post covers both my learning and a small piece on stronger types.

C++ variadic template recursive example

In this article I'll show you how to use a variadic template in C++. Variadic templates allow you to have a template with a variable number of arguments, also called a parameter pack. Unpacking that pack is more difficult than it should be, so we use a recursive template to iterate over all the parameters one by one. I've also included an example in Python to compare to.

Retro PC Ads - 1975 Sphere 1

In this series of articles I'll cover old computer advertisements. We're starting off with the Sphere 1 from 1975, a computer built around the Motorola 6800.

Match dig 127.0.0.53 server with systemd-resolvd server

On systems that use systemd-resolved for DNS you will see the 127.0.0.53 IP address in dig output. dig is a tool to do DNS lookups, and for troubleshooting it's usefull to see which server is being queried. With systemd-resolved, you need to issue another command to view the actual server that is being queried, since systemd-resolvd also acts as a local caching server.

Site updates, new layout

This site is generated with my self-written open source static site generator named ingsoc (named after 1984). I've updated the layout of the website to be less cluttered, allowing you to get to the content much faster. Inspired by my recent gopher adventures I decided to do away with the 2 column layout (drop the sidebar with menu) and have a smaller header with essential links. On mobile this makes a huge difference in scrolling, on the desktop it looks less cluttered. This article details all the changes with side by side images showing differences.

Create a PDP-8 OS8 RK05 system disk from RX01 floppies with SIMH (and get text files in and out of the PDP-8)

This guide shows you how to build an RK05 bootable system disk with OS/8 on it for the PDP-8, in the SIMH emulator. We will use two RX01 floppies as the build source, copy over all the files and set up the LPT printer and the PTR/PIP paper tape punch/readers. As an added bonus the article also shows you how to get text files in and out of the PDP-8 sytem using the printer and papertape reader / puncher.

Bash Bits: Check if a program is installed

Bash Bits are small examples, tips and tutorials for Bash (Scripts). This bash bit shows you how to check if a piece of software is installed on a machine. It's a function you can use in your shell scripts.

OpenSSL test TLSv1.3 connection and ciphersuites with s_client

This guide shows you how to test a server's TLSv1.3 connection and use specific ciphersuites with the command line s_client client from the OpenSSL project. With OpenSSL 1.1.1 you can use TLSv1.3. This guide covers the installation of OpenSSL 1.1.1 on Ubuntu, testing the connection to a server and specific ciphersuites. It also covers the big differences between TLSv1.3 and lower.

Strong SSL Security on Apache2

This tutorial shows you how to set up strong SSL security on the Apache2 webserver. We do this by updating OpenSSL to the latest version to mitigate attacks like Heartbleed, disabling SSL Compression and EXPORT ciphers to mitigate attacks like FREAK, CRIME and LogJAM, disabling SSLv3 and below because of vulnerabilities in the protocol and we will set up a strong ciphersuite that enables Forward Secrecy when possible. We also enable HSTS and HPKP. This way we have a strong and future proof ssl configuration and we get an A+ on the Qually Labs SSL Test.

Strong SSL Security on lighttpd

This tutorial shows you how to set up strong SSL security on the lighttpd webserver. We do this by updating OpenSSL to the latest version to mitigate attacks like Heartbleed, disabling SSL Compression and EXPORT ciphers to mitigate attacks like FREAK, CRIME and LogJAM, disabling SSLv3 and below because of vulnerabilities in the protocol and we will set up a strong ciphersuite that enables Forward Secrecy when possible. We also enable HSTS and HPKP. This way we have a strong and future proof ssl configuration and we get an A+ on the Qually Labs SSL Test.

Strong SSL Security on nginx

This tutorial shows you how to set up strong SSL security on the nginx webserver. We do this by updating OpenSSL to the latest version to mitigate attacks like Heartbleed, disabling SSL Compression and EXPORT ciphers to mitigate attacks like FREAK, CRIME and LogJAM, disabling SSLv3 and below because of vulnerabilities in the protocol and we will set up a strong ciphersuite that enables Forward Secrecy when possible. We also enable HSTS and HPKP. This way we have a strong and future proof ssl configuration and we get an A+ on the Qually Labs SSL Test.

totext.py - Convert URL or RSS feed to text with readability

Love plaintext? This script downloads an URL, parses it with readability and returns the plaintext (as markdown). It supports RSS feeds (will convert every article in the feed) and saves every article. My usecase is twofold. One is to convert RSS feeds to a gopher site, the second is to get full text in my RSS reader. The script contains a few workarounds for so-called cookiewalls. It also pauses between RSS feed articles to not do excessive requests. The readability part is handled by Python, no external services are used.

Convert markdown inline links to reference style links with Pandoc

Markdown has two options to create a link. A link is the piece of text you click to go to another webpage. Actually, three ways, since you can just embed HTML code in Markdown. I write all the content for this site in Markdown files, which are then converted by my static site generator to HTML, text and a gopher version. I'm used to using the inline link style, which is where you paste the link right in the text. Since I've enabled the Gopher version of raymii.org, I noticed that there was no line wrapping. The HTML website all arranges that via CSS, but the text-only Gopher does not. Sometimes Gopher clients wrap text, but most don't. I'm re-wrapping all articles to make them fit, but the wrapping is way off with inline style markdown links. By converting them to reference style markdown links, the wrapping looks way better, and as an added bonus, reference style links give a better overview. There are a few scripts floating around to convert these links, but either Ruby or NodeJS. It turns out after a bit of research that Pandoc, the anything-to-anything text conversion tool, has an option to use reference style links. With this option, I converted all the articles here (almost 400) to the reference style Markdown links.

Building opkg .ipk packages by hand (for OpenEmbedded/Yocto/OpenWRT)

.ipk packages are used by a variety of embedded linux systems, like routers running OpenWRT and appliances running on OpenEmbedded (Yocto). The opkg command installs these packages and OpenEmbedded comes with a set of tools to build .ipk packages. Recently I had to create ipk packages in a scripted fashion for a few hundred systems, all unique per system. The .ipk packages includes a few software changes for debugging, a systemd service and one precompiled binary. The yocto build tools were not available on the machine where these packages would be made so I had to figure out how to make them by hand, which means, automatically. The packages are actually just compressed files containing a few control files and the data to be extracted on the filesystem. This article will walk you through the steps of creating these packages by hand.

Where is dropbearconvert on Ubuntu?

Dropbear is a lightweight SSH server and client implementation, often used on embedded systems and routers. If you use the dropbear SSH client (dbclient) and want to use a private key, it needs to be in the dropbear format and cannot have a passphrase. Dropbear provides a conversion utility to convert openssh style keys to dropbear style keys, dropbearconvert, but on Ubuntu it's not in your $PATH. This means you have to provide the full path to execute it, which is cumbersome. There is a bug in Ubuntu that has been reported in 2012, but in Ubuntu 18.04 (2019) it's still not fixed.

Disable motd news or (parts of) the dynamic motd on Ubuntu

On Ubuntu 18.04 and up, when you login via SSH you are greeted with some news via motd (message of the day) that includes advertisements and messages from Canonical (via motd.ubuntu.com). This small guide shows you how to disable news, (parts of) the dynamic motd or just revert back to a plain old /etc/motd file.

Site updates, raymii.org now also available on Gopher

I've made some new improvements to this website, you can now view raymii.org on Gopher! Building on the last site improvement, every article being available as plain text, it was easy to generate a gophermap file and bind it all together with pygopherd.

SpaceCat Launchpad v2, an awesome cool little macropad

On Reddit, Josh (from SpaceCat) did a valentines day action, 10% off your entire order. I'm eyeing a LaunchPad for a while now, both to have a small macro pad and to experiment with QMK (firmware). So I ordered the LaunchPad full kit, an assortment of Gateron key switches and a VIM keycap. This article goes over the quality, the build process and my current setup of the Launchpad.

Viewing PDF, .docx and .odt files in mutt (as text)

mutt is my email client at work. I like the simple interface, the speed and the ability to customize the workflow. Email is synced with offlineimap and sent via msmtp, addresses are in abook, and calcurse is the Calendar for meetings, no complicated setup there. One aspect I especially like is the ability to view attachments on the command line right from mutt itself. Some departments at work send emails with an attached PDF or .docx file that contains the actual message, instead of just putting the text in the email itself. Using pandoc and pdftotext in mutt, the text of the attachments is displayed as a regular mail, no interruptions in my workflow by opening an external program. This article explains how to set up your .muttrc and .mailcap to use pandoc and pdf2text to view attachments as text in mutt.

Get a JSON value with bash and sed

Recently I was asked to get one value from a json object using only shell tools. The json in question is from a dutch radio station and it lists the current song that is played. Using this together with a few shell commands and notify-send we can show the current song when it changes as a desktop notification. I'd rather use Python or jq if it has to be shell. In this case the co-worker asked to just use simple shell tools and no external dependencies.

My phone serves me 400+ ads and trackers per hour. Blokada, the best android adblocker, beats 'm all!

Recently I switched to a new phone. After a few years (!) my old phone stopped receiving calls making it time for a new one. The new phone has Android, which allowed me to install a system wide adblocker, Blokada. It works by posing itself as a local VPN, filtering advertisements, trackers and all kinds of nasty things that spy on you or bring in malware. It does not require root access on Android, it's open source and best of all, it works very well. In the first three days of usage it has blocked over 5000 ads and trackers, including 400 when I was asleep.

Split keyboards, a five year review including the ErgoDox EZ, Matias Ergo Pro and Kinesis Freestyle 2

A split keyboard is weird at first, but once you get used to it, you will never want anything else. The keyboard is made up from two halves allowing your arms and wrists to be in a natural (neutral, straight) position, instead of having an angle/twist in your wrist. I've been using split keyboards for about five years now. Over those years I've tried several different models from different manufacturers. In this article I'll talk about the three split keyboards I've used intensively and two I have only seen or tried shortly. We'll start with my current and favorite split keyboard, the ErgoDox EZ. The other two I've used are the Matias Ergo Pro and the Kinesis Freestyle 2. I discuss the UHK and Microsoft Natural Ergonomic Keyboard 4000 briefly.

SSH on Windows Server 2019 (including how to sudo)

On hackernews I saw a Microsoft blog post stating that Windows Server 2019 now includes OpenSSH. In this post I'll try out both the client and server on a Windows 2019 server, including how to login as a Active Directory Domain user and how to generate and place and SSH keypair. The bonus this time is how to elevate permissions via SSH on Windows, sudo but way more complicated. This guide is also applicable on Windows 10, build 1809 and up.

OpenSSL command line Root and Intermediate CA including OCSP, CRL and revocation

These are quick and dirty notes on generating a certificate authority (CA), intermediate certificate authorities and end certificates using the OpenSSL command line tools. It includes OCSP, CRL and CA Issuer information and specific issue and expiry dates. We'll set up our own root CA. We'll use the root CA to generate an example intermediate CA. We'll use the intermediate CA to sign end user certificates.

Ansible - Only do action if on specific distribution (Debian, Ubuntu, CentOS or RHEL) or distribution version (ubuntu precise, ubuntu trusty)

This ansible playbook example helps you execute actions only if you are on a certain distribution. You might have a mixed environment with CentOS and Debian, when using ansible to execute actions on different servers you don't need to run yum on debian, or apt on CentOS. Some package names are different and such, so this helps you with a when statement to select a specific distribution. As a bonus, you also get a when for specific distribution versions, like Ubuntu precise (12.04 LTS) or Ubuntu trusty (14.04 LTS).

Ansible - Only do something if another action changed

This Ansible tutorial shows you how execute actions only if another action has changed. For example, a playbook which downloads a remote key for package signing but only executes the apt-add command if the key has changed. Or a playbook which clones a git repository and only restarts a service if the git repository has changed.

Ansible - Add an apt-repository on Debian and Ubuntu

This is a guide that shows you how to add an apt repository to Debian and Ubuntu using Ansible. It includes both the old way, when the apt modules only worked on Ubuntu, and the new way, now that the apt-modules also support Debian, plus some other tricks.

Line total (up+down sum) in PHP Network Weathermap

With PHP Network Weathermap you can create a birds-eye view of network components from your monitoring system (like LibreNMS, Cacti or anything else with an RRD database). It can display simple maps with components and links between, showing up and down traffic, but also complex systems with custom components, like Nagios status, temperature or other information. For network and system administrators seeing the seperate in and out traffic of a link is fine, we can sum up two numbers. A co worker filling the role of service manager asked me if it was possible to sum up in and out and show that, including the scale (different colours depending on link usage). This co worker is not interested in the seperate up/down link speed but wants to know how much traffic a location is using in total. Using a clever workaround, you can display a line's total usage, including the scale. This article also gives some more tips on weathermap, colouring and scale.

Three new NitroKeys! Nitrokey Pro 2, Storage 2 and a FIDO-U2F Nitrokey

Last week I received several newsletters from Nitrokey. As you might know, I'm a fan of their (mostly open source) hardware security devices. Their newsletters introduced two new keys, the Nitrokey Pro 2 and the Nitrokey FIDO-U2F key. On their website I also saw the Nitrokey Storage Pro 2. This article is a summary of the newsletters and goes over the new features in the new hardware. It boils down to a new OpenPGP smartcard version (3.3, it was 2.1) in the Nitrokey Pro 2 and Storage 2. The FIDO-U2F device is an entirely new Nitrokey (with a button).

Use Ubuntu behind a Microsoft ForeFront TMG proxy with cntlm

Recently I had to deploy a few machines in a network where outgoing network access was forced through a Microsoft Forefront TMG proxy. For all the Windows clients this went automatically due to domain policies, for Linux this has to be set up manually. Defining the proxy in /etc/environment was not enough since NTML authentication is required, which is not supported by default. I found cntlm, a piece of software which acts as a local proxy, translating all requests to authenticated NTLM requests to your upstream proxy. This guide covers the (offline) installation, setup, getting the correct password hash and system-wide configuration. It should work on a desktop as well, but I did not test that.

Encrypt and decrypt files to public keys via the OpenSSL Command Line

This small tutorial will show you how to use the openssl command line to encrypt and decrypt a file using a public key. We will first generate a random key, encrypt that random key against the public key of the other person and use that random key to encrypt the actual file with using symmetric encryption.

Reddit Gold for Caldera Openlinux 1.2

Someone liked my Reddit post regarding a few old CD's I found of Caldera Openlinux 1.2, including source code and floppies so much they gilded it. I got some special internet points today.

Service checks in LibreNMS (http, all other Nagios plugins)

LibreNMS is becoming one of my favorite monitoring tools. Setup and getting started is easy and it has enough advanced options and tunables. I recently discovered that LibreNMS is able to check services as well. Services, in this context, means, executing Nagios plugins (like check_http, check_ping, etc). This allows you to check services that SNMP does not cover by default, like HTTP(s) health checks, certificate expiry, tcp port checks (e.g. rdp) and anything for which you can write a Nagios plugin yourself. The performance data, if available, is graphed automatically. Alerting is done with the regular LibreNMS alerts. This guide covers the setup of services (it's not enabled by default) and a few basic checks, like an http health check, certificate expiry and SSH monitoring.

tping - ping with a timestamp

tping is a bash alias I once got from an old co-worker. It's ping, but with a timestamp. Instead of looking at the increased icmp_seq number you now have a timestamp.

Linux on Microsoft Azure? Disable this built-in root-access backdoor (wa-linux-agent)

Are you running Linux on Microsoft Azure? Then by default anyone with access to your Azure portal can run commands as root in your VM, reset SSH keys, user passwords and SSH configuration. This article explains what the backdoor (wa-linux-agent) is, what it is meant to do, how it can be disabled and removed and what the implications are. OpenStack/QEMU also have an agent/backdoor which is covered in this article as well.

Python script to talk to LibreNMS API and get alerts and hosts

This script talks to the LibreNMS API to receive a list of down devices and alerts. The LibreNMS dashboard provides widgets for alerts and host statusses, but there is no easy way to access that output via the API. Using Python I was able to get certain information and output it as HTML or text using PrettyTable. It can be included in other systems or be used in a chain of monitoring customizations. z

Site updates for accessibility, text only pages and skip to main content

I've made some new improvements to this website. Raymii.org is generated using my self-written static site generator named ingsoc, the new features are focussed on accessibility. If you are using a screen reader or command-line browser this will benefit you. Or if you like to archive stuff offline. The two main improvements are a text-only version of every content page (article/tutorial etc) and a 'Skip to main content' link.

Send email with multiple inline images via bash with a loop

Recently I had a request from a user that whished to receive a scheduled email with two screenshots. The screenshots were automated via AutoIt on a network share, the user manually logged in every evening to check the pictures. With bash and postfix/sendmail we can automate this process, the user now doesn't have to login but can just check their email. There are a lot of snippets and guides to attach emails via the shell, but displaying multiple images inline as an HTML mail was something I had to figure out. You cannot embed the image in base64 HTML because Outlook doesn't show that, you must use the Content-ID style embed. Like UUENCODE, but more complicated. (The next step in this process with the user is to automate the reason why they have to check those screenshots every night, that is something for another article)

log_vcs - Ansible callback plugin that creates VCS (git) branches for every Ansible run

This Ansible callback plugin creates a VCS branch every time you run Ansible. If you ever need to go back to a certain state or environment, check out that branch and be sure nothing has changed. This is useful when you have multiple environments or multiple people deploying and continually develop your Ansible. When you often deploy to test / acceptance and less often to production, you can checkout the last branch that deployed to production if a hotfix or other maintenance is required, without having to search back in your commits and logs. I would recommend to develop infrastructure features in feature branches and have the master branch always deployable to production. However, reality learns that that is not always the case and this is a nice automatic way to have a fallback.

Windows 7 installer on a KVM Linux VPS (Windows on Digital Ocean)

For fun I wanted to install Windows 7 on a KVM Linux VPS (on [Digital Ocean) but it should work for any KVM or XEN-HVM VPS with console access). I was experimenting with Grub2 and ISO booting, since grub2 can natively boot a linux ISO. For Windows this is not possible, the installer needs to be extracted on a FAT32 partition from which you boot. On a normal system I would repartition the disk using a live CD, but on a VPS where an ISO cannot be booted this is troublesome. If I could boot from an ISO I would use that to install Windows, but where's the fun in that? I had to figure out how to shrink an EXT4 filesystem from a running Ubuntu VPS, which is possible, however very risky, with pivot_root. Next the partiton table can be converted to MBR, the partition can be resized, a FAT32 partiton and filesystem can be created, the Windows Installer files copied onto that, some Grub config and a reboot later, you're in the Windows 7 Installer.

Syslog configuration for remote logservers for syslog-ng and rsyslog, both client and server

Syslog is the protocol, format (and software) linux and most networking devices use to log messages. All kinds of messages, system, authentication, login and applications. There are multiple implementations of syslog, like syslog-ng and rsyslog. Syslog has the option to log to a remote server and to act as a remote logserver (that receives logs). With a remote logging server you can archive your logs and keep them secure (when a machine gets hacked, if root is compromised the logs on the machine are no longer trustworthy). This tutorial shows how to set up a syslog server with rsyslog and syslog-ng and shows how to setup servers as a syslog client (that log to a remote server) with syslog-ng and rsyslog.
❌