FreeBSD 15.0 Beta 5 Released With Build Fixes For Google & Azure Clouds
FreeBSD 15.0-RC1 had been expected this weekend but instead a fifth beta release of FreeBSD 15.0 was deemed warranted… ⌘ Read more
@prologic@twtxt.net yeah I should probably update. Version 0.15.1@31958f89 2025-06-29T20:35:20+10:00 go1.23.1
Mesa Lands Fixes For HDR With Vulkan Drivers
Merged overnight to Mesa 26.0-devel and likely to be back-ported for the upcoming Mesa 23.3 release are a few fixes around high dynamic range (HDR) support within the common Vulkan windowing system integration (WSI) / display code… ⌘ Read more
Magika 1.0 Goes Stable As Google Rebuilds Its File Detection Tool In Rust
BrianFagioli writes: Google has released Magika 1.0, a stable version of its AI-based file type detection tool, and rebuilt the entire engine in Rust for speed and memory safety. The system now recognizes more than 200 file types, up from about 100, and is better at distinguishing look-alike formats such as JSON vs JSONL, TS … ⌘ Read more
Archinstall 3.0.13 Adds WiFi Connection Menu To Arch Linux Installer
Just days after the Archinstall 3.0.12 release for this text-based Arch Linux installer, Archinstall 3.0.13 is now available to deliver a new feature. That new feature is a text-based interface for being able to connect to a WiFi network within Archinstall… ⌘ Read more
Intel ANV Vulkan Driver Finally Exposes Pipeline Binary “VK_KHR_pipeline_binary”
Introduced back in August of 2024 with Vulkan 1.3.294 was VK_KHR_pipeline_binary as a pipeline binary extension to retrieve binary data associated with individual pipelines. The focus of this is to bypass the Vulkan pipeline caching mechanism and so applications can manage caches themselves. Finally today for Mesa 26.0-devel the Intel “ANV” open-source Vulkan driver has enabled this extension… ⌘ Read more
RadeonSI + ACO Brings Some Performance Gains For Radeon Workstation Graphics
Last week Mesa 26.0-devel enabled the ACO back-end by default within the RadeonSI Gallium3D driver for all supported Radeon graphics cards by this open-source Linux driver. This move was done in the name of better performance, faster shader compilation times, and ACO being all-around better than the AMDGPU LLVM back-end these days for both OpenGL and Vulkan use. It was also noted that RadeonSI has “slightly better” viewperf performance w … ⌘ Read more
For the innocent bystanders (because I know that I won’t change @bender@twtxt.net’s opinion):
curl -s gopher://uninformativ.de/0/phlog/2025/2025-11/2025-11-05--my-current-reasons-against-ai.txt
Fwupd 2.0.17 Released With More Hardware Support & Features
Days after the Linux Vendor Firmware Service celebrated 135 million firmware downloads, a new version of the Fwupd utility is now available for firmware updating systems and peripherals under Linux… ⌘ Read more
Won a bunch of games of Solitaire and then rearranged the cards for maximum negative points, to distract me from the horrors.
(Still ended up with >0 points on OS/2, because don’t ask me.)
https://www.uninformativ.de/desktop/2025%2D11%2D04%2D%2Dkatriawm%2Dsolitaire.png
I’m building a service that lets you:
create and manage disposable, brandable email aliases so you can track leaks, forward important messages, and keep your real inbox clean.
I’ve just finishing building it for the most part, and have cut a v0.1.0 release. It’s currently closed source (to be decided later) and now open to beta testers. cc @bender@twtxt.net 🙏 I fully intend to monetize and offer this as a paid service in teh coming weeks/months, but beta/invite-only testers and early adopters/users first 🤟
🥳 Just released Gatherly v0.3.0 🤟 – My instance is available at: https://gatherly.mills.io (free for anyone to use)
I experimented with a 2.4x7mm aluminium rivet I had on hand. As expected, it was quite a bit long. Using my pliers wrench, I was able to crush it down by quite some bit. I should have taken a photo right after the hand riveter for comparison. Now, it’s much smoother and the chance of cutting my hand open is reduced by quite a bit. But breaking the burr with a few file strokes is still necessary. I should get 2.4x4mm rivets and try with them. I reckon they would be more suited for my 0.5mm sheet metal.
With the pliers wrench again, I was able to also crush down the chopped off 3mm copper nail and form a second head. That was surprisingly easy. Now, I need to figure out how to efficiently make a head on the remaining copper nail shaft, so that I can use this again.
Both are rock solid, there’s absolutely no movement at all between the two sheet metal cutoffs.
For a very first attempt, I’m extremely happy how this tray turned out: https://lyse.isobeef.org/tmp/blechschachtel/ The photos look rougher than in person. The 0.5mm aluminium sheet was 300x200mm to begin with. Now, the accidental outside dimensions are 210x110mm. It took me about an hour to make. Tomorrow, I gotta build a simple folder, so I don’t have to hammer it anymore, but can simply bend it a little at a time.
Hey @itsericwoodward@itsericwoodward.com, I just wanna let you know that twtstrm/0.4.0 sends a broken User-Agent header. Instead of the URL, the nick is repeated.
Hmm: gopher://uninformativ.de/0/phlog/2025/2025-08/2025-08-18--permacomputing.txt
That’s fairly recent, but fully justified. I give up! :-D
I should have checked the CHANGELOG first. LOL.
@movq@www.uninformativ.de I noticed that:
gopher://uninformativ.de/0/phlog/2018/2018-06/2018-06-01.txt
Is the first non-justified, and it is when you started using Markdown. The last justified one was:
gopher://uninformativ.de/0/phlog/2018/2018-05/2018-05-27.txt
So, I might have found the mystery! :-D
@bender@twtxt.net The address is/was correct but probably got mangled by the Markdown renderer. Let’s try again in a code block:
gopher://uninformativ.de/0/phlog/2025/2025-09/2025-09-03--roophloch.txt
@movq@www.uninformativ.de getting:
3Invalid request. Error Error 0
On that address.
@bender@twtxt.net Yeah, the acronym is funny. 😅
Wandering through the woods for 8km … gopher://uninformativ.de/0/phlog/2025/2025-09/2025-09-03–roophloch.txt
This is soooo bloody cool, @movq@www.uninformativ.de! https://www.uninformativ.de/blog/postings/2025-08-30/0/POSTING-en.html
@dce@hashnix.club I switched over to following you on Gopher, because why not. 😅
What’s Missing from “Retro”: gopher://midnight.pub/0/posts/2679
@movq@www.uninformativ.de According to this screenshot, KDE still shows good old application icons: https://upload.wikimedia.org/wikipedia/commons/9/94/KDE_Plasma_5.21_Breeze_Twilight_screenshot.png
And GNOME used to have them, too: https://upload.wikimedia.org/wikipedia/commons/9/9f/Gnome-2-22_%284%29.png
I like the looks of your window manager. That’s using Wayland, right? The only thing on this screenshot to critique is all that wasted space of the windows not making use of the full screen!!!1 At least the file browser. 8-)
This drives me nuts when my workmates share their screens. I really don’t get it how people can work like that. You can’t even read the whole line in the IDE or log viewer with all the expanded side bars. And then there’s 200 pixels on the left and another 300 pixels on the right where the desktop wallpaper shows. Gnaa! There’s the other extreme end when somebody shares their ultra wide screen and I just have a “regularish” 16:10 monitor and don’t see shit, because it’s resized way too tiny to fit my width. Good times. :-D
Sorry for going off on a tangent here. :-) Back to your WM: It has the right mix of being subtle and still similar to motif. Probably close to the older Windowses. My memory doesn’t serve me well, but I think they actually got it fairly good in my opinion. Your purple active window title looks killer. It just fits so well. This brown one (https://www.uninformativ.de/blog/postings/2025-07-22/0/leafpads.png) gives me also classic vibes. Awww. We ran some similar brownish color scheme (don’t recall its name) on Win95 or Win98 for some time on the family computer. I remember other people visting us not liking these colors. :-D
@movq@www.uninformativ.de I fully agree with you on https://www.uninformativ.de/blog/postings/2025-07-22/0/POSTING-en.html!
Although, in the first screenshot, the window title background is much darker in the new version than the old one!1!1 :-P Kidding aside, the contrast in the old one is still better.
Also, note the missing underlines for the Alt hotkeys now. I just think that the underline in the old one is too thick.
I did a “lecture”/“workshop” about this at work today. 16-bit DOS, real mode. 💾 Pretty cool and the audience (devs and sysadmins) seemed quite interested. 🥳
- People used the Intel docs to figure out the instruction encodings.
- Then they wrote a little DOS program that exits with a return code and they used uhex in DOSBox to do that. Yes, we wrote a COM file manually, no Assembler involved. (Many of them had never used DOS before.)
- DEBUG from FreeDOS was used to single-step through the program, showing what it does.
- This gets tedious rather quickly, so we switched to SVED from SvarDOS for writing the rest of the program in Assembly language. nasm worked great for us.
- At the end, we switched to BIOS calls instead of DOS syscalls to demonstrate that the same binary COM file works on another OS. Also a good opportunity to talk about bootloaders a little bit.
- (I think they even understood the basics of segmentation in the end.)
The 8086 / 16-bit real-mode DOS is a great platform to explain a lot of the fundamentals without having to deal with OS semantics or executable file formats.
Now that was a lot of fun. 🥳 It’s very rare that we do something like this, sadly. I love doing this kind of low-level stuff.
Saw this on Mastodon:
https://racingbunny.com/@mookie/114718466149264471
18 rules of Software Engineering
- You will regret complexity when on-call
- Stop falling in love with your own code
- Everything is a trade-off. There’s no “best” 3. Every line of code you write is a liability 4. Document your decisions and designs
- Everyone hates code they didn’t write
- Don’t use unnecessary dependencies
- Coding standards prevent arguments
- Write meaningful commit messages
- Don’t ever stop learning new things
- Code reviews spread knowledge
- Always build for maintainability
- Ask for help when you’re stuck
- Fix root causes, not symptoms
- Software is never completed
- Estimates are not promises
- Ship early, iterate often
- Keep. It. Simple.
Solid list, even though 14 is up for debate in my opinion: Software can be completed. You have a use case / problem, you solve that problem, done. Your software is completed now. There might still be bugs and they should be fixed – but this doesn’t “add” to the program. Don’t use “software is never done” as an excuse to keep adding and adding stuff to your code.
Okay, here’s a thing I like about Rust: Returning things as Option and error handling. (Or the more complex Result, but it’s easier to explain with Option.)
fn mydiv(num: f64, denom: f64) -> Option<f64> {
// (Let’s ignore precision issues for a second.)
if denom == 0.0 {
return None;
} else {
return Some(num / denom);
}
}
fn main() {
// Explicit, verbose version:
let num: f64 = 123.0;
let denom: f64 = 456.0;
let wrapped_res = mydiv(num, denom);
if wrapped_res.is_some() {
println!("Unwrapped result: {}", wrapped_res.unwrap());
}
// Shorter version using "if let":
if let Some(res) = mydiv(123.0, 456.0) {
println!("Here’s a result: {}", res);
}
if let Some(res) = mydiv(123.0, 0.0) {
println!("Huh, we divided by zero? This never happens. {}", res);
}
}
You can’t divide by zero, so the function returns an “error” in that case. (Option isn’t really used for errors, IIUC, but the basic idea is the same for Result.)
Option is an enum. It can have the value Some or None. In the case of Some, you can attach additional data to the enum. In this case, we are attaching a floating point value.
The caller then has to decide: Is the value None or Some? Did the function succeed or not? If it is Some, the caller can do .unwrap() on this enum to get the inner value (the floating point value). If you do .unwrap() on a None value, the program will panic and die.
The if let version using destructuring is much shorter and, once you got used to it, actually quite nice.
Now the trick is that you must somehow handle these two cases. You must either call something like .unwrap() or do destructuring or something, otherwise you can’t access the attached value at all. As I understand it, it is impossible to just completely ignore error cases. And the compiler enforces it.
(In case of Result, the compiler would warn you if you ignore the return value entirely. So something like doing write() and then ignoring the return value would be caught as well.)
@aelaraji@aelaraji.com I use Alt+. all the time, it’s great. 👌
FWIW, another thing I often use is !! to recall the entire previous command line:
$ find -iname '*foo*'
./This is a foo file.txt
$ cat "$(!!)"
cat "$(find -iname '*foo*')"
This is just a test.
Yep!
Or:
$ ls -al subdir
ls: cannot open directory 'subdir': Permission denied
$ sudo !!
sudo ls -al subdir
total 0
drwx------ 2 root root 60 Jun 20 19:39 .
drwx------ 7 jess jess 360 Jun 20 19:39 ..
-rw-r--r-- 1 root root 0 Jun 20 19:39 nothing-to-see
@prologic@twtxt.net I’m trying to call some libc functions (because the Rust stdlib does not have an equivalent for getpeername(), for example, so I don’t have a choice), so I have to do some FFI stuff and deal with raw pointers and all that, which is very gnarly in Rust – because you’re not supposed to do this. Things like that are trivial in C or even Assembler, but I have not yet understood what Rust does under the hood. How and when does it allocate or free memory … is the pointer that I get even still valid by the time I do the libc call? Stuff like that.
I hope that I eventually learn this over time … but I get slapped in the face at every step. It’s very frustrating and I’m always this 🤏 close to giving up (only to try again a year later).
Oh, yeah, yeah, I guess I could “just” use some 3rd party library for this. socket2 gets mentioned a lot in this context. But I don’t want to. I literally need one getpeername() call during the lifetime of my program, I don’t even do the socket(), bind(), listen(), accept() dance, I already have a fully functional file descriptor. Using a library for that is total overkill and I’d rather do it myself. (And look at the version number: 0.5.10. The library is 6 years old but they’re still saying: “Nah, we’re not 1.0 yet, we reserve the right to make breaking changes with every new release.” So many Rust libs are still unstable …)
… and I could go on and on and on … 🤣
OpenBSD has the wonderful pledge() and unveil() syscalls:
https://www.youtube.com/watch?v=bXO6nelFt-E
Not only are they super useful (the program itself can drop privileges – like, it can initialize itself, read some files, whatever, and then tell the kernel that it will never do anything like that again; if it does, e.g. by being exploited through a bug, it gets killed by the kernel), but they are also extremely easy to use.
Imagine a server program with a connected socket in file descriptor 0. Before reading any data from the client, the program can do this:
unveil("/var/www/whatever", "r");
unveil(NULL, NULL);
pledge("stdio rpath", NULL);
Done. It’s now limited to reading files from that directory, communicating with the existing socket, stuff like that. But it cannot ever read any other files or exec() into something else.
I can’t wait for the day when we have something like this on Linux. There have been some attempts, but it’s not that easy. And it’s certainly not mainstream, yet.
I need to have a closer look at Linux’s Landlock soon (“soon”), but this is considerably more complicated than pledge()/unveil():
So I was using this function in Rust:
https://doc.rust-lang.org/std/path/struct.Path.html#method.display
Note the little 1.0.0 in the top right corner, which means that this function has been “stable since Rust version 1.0.0”. We’re at 1.87 now, so we’re good.
Then I compiled my program on OpenBSD with Rust 1.86, i.e. just one version behind, but well ahead of 1.0.0.
The compiler said that I was using an unstable library feature.
Turns out, that function internally uses this:
https://doc.rust-lang.org/std/ffi/struct.OsStr.html#method.display
And that is only available since Rust 1.87.
How was I supposed to know this? 🤨
Hmmm 🧐 Not what I thought was going on… No bug…
time="2025-06-14T15:24:25Z" level=info msg="updating feeds for 8 users"
time="2025-06-14T15:24:25Z" level=info msg="skipping 0 inactive users"
time="2025-06-14T15:24:25Z" level=info msg="skipping 0 subscribed feeds"
time="2025-06-14T15:24:25Z" level=info msg="updating 80 sources (stale feeds)"
SuSE Linux 6.4 and Arachne on DOS also work (with Windows 2000 as a call target):
This is my highlight, really, haven’t seen this in action in a loooooooong time:
I had a lot of fun with my modems these past few days:
https://www.uninformativ.de/blog/postings/2025-05-31/0/POSTING-en.html
Maybe you’ll enjoy this as well:
I still have one of my first modems, a Creatix LC 144 VF:
I think this was the modem that I used when I first connected to the internet, but I’m not sure.
I plugged it in again and it still works:
The firmware appears to be from 1994, which sounds about right. I don’t think we had internet access before that. We certainly did use local mailboxes, though. (Or BBS’s, as you might call them.)
I now want to actually use that modem again. For the moment, I can only use a phone to dial into it, I lack a second modem to actually establish a connection. Here’s a video:
Not spectacular, but the modem does answer after me entering ATA.
I bought another cheap old modem on eBay and am now waiting for it to arrive. Once it’s here, I want to simulate an actual dial-up session, hopefully from OS/2 or Windows 3.x.
prologic@JamessMacStudio
Sun May 25 21:44:41
~/tmp/neurog
(main) 130
$ go build ./cmd/ttt/... && ./ttt
Generation 27 | Fitness: 0.486111 | Nodes: 44 | Conns: 82
… experimenting with building and training a tic-tac-toe game, which evolves a. neural net that learn to paly the game against the best evolved champions 😅
This is one of my attempts: 
$ go build ./cmd/xor/... && ./xor
Generation 95 | Fitness: 0.999964 | Nodes: 9 | Conns: 19
Target reached!
Best network performance:
[0 0] → got=0 exp=0 (raw=0.000) ✅
[0 1] → got=1 exp=1 (raw=0.990) ✅
[1 0] → got=1 exp=1 (raw=0.716) ✅
[1 1] → got=0 exp=0 (raw=0.045) ✅
Overall accuracy: 100.0%
Wrote best.dot – render with `dot -Tpng best.dot -o best.png`
fit 1 $ spin (saw 0.1 * sign fxy) $ rect 0 1 - rect 0 0.99 >> add;#punctual #livecoding #creativecoding #videoart
The thing about upright bass is that you must play it on a regular basis. At least several times a week, ideally daily. It requires quite a bit of strength and it’s very easy to lose those muscles again – at least I don’t use them that much otherwise. 🤣 I’ve been through several cycles of “gain strength → lose strength → goto 0” now …
And on a similar note, cross-post from Mastodon:
What I love about HTML and HTTP is that it can degrade rather gracefully on old browsers.
My website isn’t spectacular but I don’t think it looks horrible, either. And it’s still usable just fine all the way down to WfW 3.11:
It’s not perfect, but it’s usable. And that makes me happy. Almost 30 years of compatibilty.
The biggest sacrifice is probably that I don’t enforce TLS and that HTTP 1.0 has no Host: header, so no vhosts (or rather, everything must come from the default vhost). (Yes, some old browsers send Host:, even though they predate HTTP 1.1. Netscape does, but not IBM WebExplorer, for example.)
(On the other hand, it might completely suck on modern mobile devices. Dunno, I barely use those. 🤪)
On my blog: 0M — Remixed Classrooms https://john.colagioia.net/blog/2025/05/04/30m-free-education.html #3#0#million #books #diversity #education
Can you automate the drawing with a script? On X11, you can:
#!/bin/sh
# Position the pointer at the center of the dot, then run this script.
sleep 1
start=$(xdotool getmouselocation --shell)
eval $start
r=400
steps=100
down=0
for step in $(seq $((steps + 1)) )
do
# pi = 4 * atan(1)
new_x=$(printf '%s + %s * c(%s / %s * 2 * (4 * a(1)))\n' $X $r $step $steps | bc -l)
new_y=$(printf '%s + %s * s(%s / %s * 2 * (4 * a(1)))\n' $Y $r $step $steps | bc -l)
xte "mousemove ${new_x%%.*} ${new_y%%.*}"
if ! (( down ))
then
xte 'mousedown 1'
down=1
fi
done
xte 'mouseup 1'
xte "mousemove $X $Y"

Interestingly, you can abuse the scoring system (not manually, only with a script). Since the mouse jumps to the locations along the circle, you can just use very few steps and still get a great score because every step you make is very accurate – but the result looks funny:

🥴
First draft of yarnd 0.16 release notes. 📝 – Probably needs some tweaking and fixing, but it’s sounding alright so far 👌 #yarnd
irc.mills.io running behind Caddy Layer 4. However I don't terminate TLS at the edge in this case.
@bender@twtxt.net Sure! 👍
{
...
# Layer 4 Reverse Proxy
layer4 {
# Gopher
0.0.0.0:70 {
route {
proxy <internal_ip>:70
}
}
# IRC (TLS)
0.0.0.0:6697 {
route {
proxy <internal_ip>:6697
}
}
}
}
@kat@yarn.girlonthemoon.xyz At the core, you need an ngircd.conf like this:
[Global]
Name = your.irc.server.com
Password = yourfancypassword
Listen = 0.0.0.0
Ports = 6667
AdminInfo1 = Well, me.
AdminInfo2 = Over here!
AdminEMail = forget.it@example.invalid
[Options]
Ident = no
PAM = no
[SSL]
CertFile = /etc/ssl/acme/your.irc.server.com.fullchain.pem
KeyFile = /etc/ssl/acme/private/your.irc.server.com.key
DHFile = /etc/ngircd/dhparam.pem
Ports = 6669
Start it and then you can connect on port 6667. (The SSL cert/key must be managed by an external tool, probably something like certbot or acme-client.)
I’m assuming OpenBSD here. Haven’t tried it on Linux lately, let alone Docker. 😅
@prologic@twtxt.net @bmallred@staystrong.run Ah, I just found this, didn’t see it before:
https://restic.net/#compatibility
So, yeah, they do use semver and, yes, they’re not at 1.0.0 yet, so things might break on the next restic update … but they “promise” to not break things too lightheartedly. Hm, well. 😅 Probably doesn’t make a big difference (they don’t say “don’t use this software until we reach 1.0.0”).
@prologic@twtxt.net @bmallred@staystrong.run So is restic considered stable by now? “Stable” as in “stable data format”, like a future version will still be able to retrieve my current backups. I mean, it’s at version “0.18”, but they don’t specify which versioning scheme they use.