Event loops libraries are optimized for the case of programs with huge number of sockets, timers, etc. It’s great, big programs needs performances, but what about small programs? What is a “small application”? It’s hard to say, but I’d define it as a program that needs less than, say, 50 sockets at runtime. Something like that. The definition is fuzzy on purpose. A server is probably not a “small…
TL;DR during the c2k24 OpenBSD hackathon I worked on Game of Trees and in particular in getting SHA256 working. It is working fine, except for the network protocol (and gotd) where more work is still needed. Git, since several years now, has been working making the hashing function customizable per-repository. It's not a trivial task since git revolves around SHA1 for almost everything, and so…
Let’s say, just for a moment, that you’re mad enough to write a web application in C. (I’m probably beyond salvation at this point, but I like C, it’s my favourite programming language, and I like to hack on fun things in my limited spare time.) At some point you have to output the HTML somehow, and I guess the code will look like printf("<!doctype>\n"); printf("<html>\n"); printf("..."); which is…
This is mostly an announce more than a in-depth post. I think I wrote all I wanted to say about the 2.0 release in a previous entry when I "released" a first alpha. gmid 2.0 first alpha Then I got distracted by many other things and time flew. The only complain is that I haven't managed to write as much as I wanted in these last six months on the blog. However, today I just released gmid 2.0. It's…
This post is a follow-up on the previous announcement of gmid 2.0 dropping CGI script support. I felt that I had to explain more accurately why I decided to drop that feature and what are the options available and what I can try to do before finalizing the release. One of my favourites talk is "Simple Made Easy" by Rich Hickey. "Simple Made Easy", a talk by Rich Hickey Without going too much into…
It took quite some time. Last September I was thinking I would have 2.0 ready for December, and here we are. Better late than never I guess. This time I decided to do a round of public testing before releasing 2.0 itself. I decided to call this an "alpha" rather than a first RC to better convey the idea that I'm still open to change (even in incompatible ways) the new feature set before the…
I haven't posted in a long time here, this is actually the first entry of the 2023... woops! Truth to be told, there are various things I'd like to write about but not enough time, so I thought to copy the big guys and write a "Status Update" post myself. It's more like sending a message in a bottle though. So, lots of stuff, right? Let's go! OpenSMTPD-portable Last month I started to help in the…
Edit 2022-10-28: b32decode was slightly improved in its interface, it's a bit easier to use now: the ‘s’ parameter can be const and there's no need to pass an explicit length. For reasons behind the scope of this entry, I had to decode some data encoded in base32. After an embarrassing moment where i used EVP_DecodeBlock from libcrypto because apparently I can’t read (it’s a base64, not 32,…
TL;DR plass(1) is a NIH pass(1), but I like it more! Many many moons ago, so many that I don’t remember the details, I was trying to hack something with pass(1) and got really fed up with it. It was my second password manager, with keepassxc being the first, and I really loved the idea behind it but I started to hate the interface. I remember that I found the output of the various pass commands…
2024/02/29 edit: fixed the sample config file: unix_socket_name changed to listen on socket. The latest release of the Game of Trees control version systems includes a brand-new repository web interface: gotwebd. It was written by tracey@ and it's going to replace the "old" CGI script, also written by him. My gotwebd instance Game of Trees (got) website Disclaimer: I've contributed a bit to got…
A couple of weeks ago bcallah@ imported QBE into the OpenBSD ports tree and, since then, I was looking forward to play with it. When a friend of mine studying for a course on declarative programming in F# told me they wrote a little interpreter i forced^W convinced him to write a compiler for brainfuck in F# that outputs QBE, and I'm following him in Haskell. (heph, now you have to write a blog…
I'm interested in how full text search (FTS from here onwards) works. FTS is the action of searching a collection of documents for some arbitrary text. I've been using elasticsearch and I remember playing a bit with solr, but nothing beats trying to write something from scratch to understand how things works. Here I'm doing a walkthrough of what I wrote, which is incredibly naive of course, and…
2024/02/29 edit: fixed a few typos and links, improved the markup. This is a partial and inaccurate translation of a post with the same title I published the other day on my Italian capsule. Moved by curiosity I wrote a small music player. The ideas was to see if it was possible to decode the audio files in a tightly sandboxed process. TL;DR: it was an error. I ended up writing a thing I like, now…
Telescope The 0.7 release is named after “Via Paolo Fabbri 43”, a song by Francesco Guccini. It's a song about: una canzone piena di cose e di scherzi, e l'ironia è soprattutto su di me, sui miei “se fossi, se facessi” che a volte forse sono solo scuse per non essere e non fare. La canzone vuole essere un invito a essere di più e a fare di più. (in English) a song full of things and jokes, and the…
I’d like to announce ‘com.omarpolo/gemini’: a new clojure library to make Gemini requests. com.omarpolo/gemini: A Clojure library to make Gemini requests It’s also available on clojars, so go download it! :D background I needed something to ping antenna when I publish things on this blog. The site is assembled using some clojure scripts (not the most idiomatic clojure you’d read, but it works) and…
The first commit in gmid git repository was the 2 October of the last year, with the 1.0 being tagged a couple of days later 2020-10-07. I wanted to publish this on some days ago, exactly one year after the first release, but I couldn’t make it in time. gmid has been my introduction to Gemini. I think I’ve wrote about it before, but the first time I’ve used a Gemini client (I think it was amfora,…
The first part “Inspecting zip files” The code for the whole series; see ‘zipview.c’ for this post in particular. Edit 2021/08/21: Stefan Sperling (thanks!) noticed an error in the ‘next’ function. After that I found that a wrong check in ‘next’ caused an invalid memory access. The ‘next‘ and ‘ls’ functions were corrected. Now that we know how to navigate inside a zip file let’s see how to extract…
Part two: “Extracting files from zips” The code for the whole series; see ‘zipls.c’ for this post in particular. Edit 2021/08/20: some edits to improve the code and the commentary. Edit 2021/08/21: stricter while condition for ‘ls’ and added links to the code Disclaimer: before today I didn’t knew anything about how zip files are structured, so take everything here with a huge grain of salt. The…
As part of the regression suite for a project I’m working on, I designed a simple scripting language (which is not even Turing-complete by the way) to create specific situations and test how the program respond. I’ve almost finished the interpreter for it, so it’s the time to start writing tests. How do you edit a file if you don’t have a proper major mode available? You write one! A major mode is…
Taking ’bout 9P: intro The Topen request at first looks weird. Here’s its signature size[4] Topen tag[2] fid[4] mode[1] It’s strange, isn’t it? For comparison, here’s the C signature for the open(2) system call: int open(const char *path, int flags, ...); Where is the path in the Topen call? The description for the Topen request says: The open request asks the file server to check permissions and…
These days I’m hacking on 9P. In case you don’t know, 9P is a protocol for a network file system that was developed as part of the plan9 operating system. Now, to make it clear, I’ve never — sigh! — used 9P nor plan9 before. I’m just starting to explore the 9P protocol, hacking something together (for a secret project), and writing some notes here on my blog. If you find some errors please be kind…
Two years ago I decided to switch to a light-theme and I was really happy with that. Maybe it’s just me, but black text on white background is perfectly readable, and it didn’t give me problems or eye tiredness, not even when it’s 1 am and I’m still hacking together something. Fast forward two years, and I’m still happily using only light themes. Sometimes, I get some comments like “you’ve burnt…
On UNIX when you type C-z (hold control and press ‘z’) at your terminal the program you have opened, let’s say ed(1), will be suspended and put into the background. Later, with ‘fg’ it can be bring back into foreground. But how it works? When the tty driver sees that you’ve typed control-z it’ll send a SIGTSTP signal to the process in the foreground. Then, the shell should do its part and handle…
Early today, this hot Saturday morning, I tagged a new version of gmid. As always, this release is dubbed after a song, this time it’s one of my favourites by Dream Theater: “Space-dye Vest”. It has nothing to do with space other than the title, but it’s a really good song. It’s also one of their saddest songs, you have been warned. This 1.7 brings in a lot of new stuff, improvements and bugfixes.…
I just switched my mailserver from a setup with a single UNIX user to a slightly more complex one with virtual users. I don’t know how other admins manages their virtual users, but in this entry I’m going to discuss the method I’m using. This is *not* a tutorial on how to install and configure OpenSMTPD or Dovecot or anything else, as I don’t feel like I’m the most qualified to do so. Instead, if…
Some time ago I wrote a text/gemini parser for Clojure. More than a real parser was a hack, an extremely verbose one, just to play with this transducer thing. Well, I got tired of that and rewrote it as a standalone library that is now available on clojars. com.omarpolo/gemtext on Clojars. There’s still a transducer at the heart of the library, but it’s a more reasonable one this time. It allows…
It took me a while to release this 1.6 version compared to the previous ones, but we’re finally here! The headlines for this version are an improved CGI implementation and performance, but you’ll find the full changelog at the end of this entry. libevent is now a dependency of gmid: the new event-loop should be faster than the old poll(2)-based one. Thanks to a clear design and…
Last week I spent a couple of days at my relative house. The only thing I took with me was a raspberry, plugged to the TV. The raspberry was running void linux, with only a small selection of software installed on it (Emacs, git, a C toolchain and nothing more, neither X11), and it was refreshing! Most of the time the system was offline so I could focus on writing code, with only some occasional…
I just recalled how cool macros are. I was helping to convert a manuscript for a book from LibreOffice to LaTeX, and to speed the conversion we used pandoc. The problem was that pandoc added a lot of noise to the generated code. Take for instance this bit: \hypertarget{foo-bar-baz}{% \subsubsection[foo bar baz]{\texorpdfstring{\protect\hypertarget{anchor-92}{}{}Foo Bar Baz}{Foo Bar…
Debugging for something unrelated, I noticed that on linux gmid’ server process would crash upon SIGHUP. I never noticed it before because (unfortunately) ‘ulimit -c 0’ seems to be the default on various systems (i.e. no core files) and I started testing on-the-fly reconfiguration only recently. What was particularly strange was that I got not logging whatsoever. I have a compile-time switch for…
EDIT 2021/02/05: typos Some daemons are able to restart themselves. I mean, a real in-place restart, not a naïve external stop+re-exec. Why would you care if a daemon is able to restart in place or not? Well, it depends. For some daemons is almost a necessary feature (think of sshd, would you be happy if when you restart the daemon it would shut down every ongoing connections? I wouldn’t), in…
These last twenty days were pretty productive on the gmid front: I ended up doing way more things that I had planned for this v1.5 release. The headlines are the automatic sandboxing on OpenBSD, FreeBSD and linux and the introduction of the configuration file, but you’ll find the whole change log at the end of this entry. On OpenBSD pledge and unveil were already in place, but their usage has been…
I had the opportunity to implement a sandbox and I'd like to write about the differences between the various sandboxing techniques available on three different operating systems: FreeBSD, Linux and OpenBSD. The scope of this entry is sandboxing gmid. gmid is a single-threaded server for the Gemini protocol; it serves static files and optionally executes CGI scripts. gmid Before, the daemon was a…
If it’s still not clear, I love writing parsers. A parser is a program that given a stream of characters builds a data structure: it’s able to give meaning to a stream of bytes! What can be more exiting to do than writing parsers? Some time ago, I tried to use transducers to parse text/gemini files but, given my ignorance with how transducers works, the resulting code is more verbose than it…
In one of the recent posts, the one were I was discussing the IRI implementation in gmid, I said that I wasn’t happy with the UTF-8 parser. IRIs are not hard! Since then, I improved the valid_multibyte_utf8 function at least two times, and I’m happy with the current result, but I thought to document here the various “generations” of that function. The purpose of valid_multibyte_utf8 is to tell if…
I’m enjoying writing literate programming-esque posts. I have written two of them in the last months, and I’ll definitely write more in the future. The joy of elisp: an example Parsing Gemtext with Clojure I’m new to the idea of literate programming, so I hope you’ll excuse my lack of knowledge on the matter. Those two posts were written by taking the sources of an already written program and…
I like text/gemini. I like writing in this format. At first, it was a bit limitating, like, I want *bold*, /italic/, _underline_, ~striked~, [inline links](…), , ! (?) etc. But I as started writing (by the way, every post in the last 3 months was written in text/gemini) I found myself pretty accustomed to it. I really like the idea of one link-per-line. I also…
I’m starting to enjoy Emacs Lisp (elisp) more and more. I’m not exactly sure why (well, I have a soft spot for LISP, regardless of its incarnation), because I think Common LISP, Clojure or Scheme are better programming languages overall, but in these last months I ended up writing more elisp than anything else. The point is, I think, that elisp is incredibly fun. I’ve never seen a LISP machine in…
In the last days I finally decided to update the URI handling in gmid, and I also took the opportunity to support IRI (Internationalized Resource Identifiers). The following is the design and implementation of IRIs in gmid. The status quo gmid had a very primitive URI handling. It had a couple of routines to advance the URI buffer until the start of the path, to override the “?” with a NUL byte…
2020/12/12 edit: typos. Today I chatted with a friend about screen recording. He had a problem with a the record script he was using, and this made me thinking about how I record the screen. I find useful to share some little screen records, to showcase something I'm doing with friends usually. Some time ago I quickly wrote a small record script: #!/bin/ksh if ! s=$(slop -f "%x %y %w %h"); then…
Snippets are small templates that can be “expanded”, and are generally used to avoid typing scaffolding. Since they are a common features available on various editors and IDEs, I have confidence the reader has seen them at some point. Yasnippet is an Emacs package to manage and expand snippets; actually, yasnippet is probably THE Emacs package for snippets. Yasnippet repository (the full setup is…
I had this piece of data (("12345" (("Content-Disposition" "form-data" (("name" . "code")))))) and I wanted to extract the cons with “name” and “code”. Armed with my ‘a’s and ‘d’s I wrote (interactively, one letter at a time) (caaddr (caadar thing)) then I though “two function call is too much” (caaddaadar thing) but ‘caaddaadar’ doesn’t exists. Life sucks even more now. --- P.S.: yeah, I was…
I’ve just tagged the version 1.3 of gmid, a dead simple zero configuration gemini server, which brings in CGI scripts supports. gmid project page gmid presentation This gave me the opportunity to play around with CGI scripts, and I had a blast! I’m currently hosting 3 scripts, written in three different scripting languages, because why not? Hello World Hello World This was the first script I ran…
I’m not really happy with the management of windows in Emacs. Certain commands/modes spawn buffers that completely destroys the layout, or there are modes that likes to mess with your layout (org mode and magit in particular — although these at least revert the changes they made). I’ve taken various precautions to minimise the friction (I have an hydra for other-window, avy and ace-window), but…
These days I’m building a gemini server called gmid. Original name, uh? (I hope I’m not stealing the name from someone else) gmid is a simple, zeroconf gemini server for static content. At the moment it doesn’t even handle virtual hosts, but it’s working fine for my use-case (serving a statically-generated blog). gmid repo github mirror I had a lot of fun writing it, so I thought to write a post,…
EDIT April 2021: I have revisited this parser and published it as a library. The version presented here is not only overly-complex, but also overly-verbose. Parsing text/gemini with Clojure revisited I've written various parsers in the past. From simplistic stuff in Korn shell, to hand written recursive descendant parsers in Go and or C, to yacc-based parsers in C. I even played with Alex and…
I've finally decided to invest some time and mess aronud with gemini! This post is just an "hello world gemini", to announce that, from now on, this blog will be available also with the gemini protocol. Project Gemini Website I thought for a while on how to make the content available on both HTTP and gemini. Automatically translating markdown (what I used until now) to gemtext is NOT something I…
Like I said in the previous entry I don't like to write howtos: the information tend to rot away if not carefully updated, and I don't have all that stamina. Anyway, I felt like writing this, and so here we are. Previous entry: Automatic USB Tethering on OpenBSD Due to events that are outside the scope of this entry, I moved my computer in a place where I cannot comfortably attach a jack to it. (I…
2024/02/29 edit: update the samples to use dhcpleasectl These days, for various reason, I'm using USB tethering very often. Enabling it it's not difficult at all, it as simple as doas dhcpleasectl urndis0 But it's tedious. Especially if you need to do it multiple times per day. I needed something to save me from filling my shell history of dhclient urndis0. Enter hotplugd(8)! hotplugd is a daemon…
2020/10/07 edit: I finally started to understand how interpolation in hydra works, so I’ve updated the code. (also converted to gemtext and some minor text changes) Without a specific motivation, I wanted to try some Emacs music players. I briefly tried bongo, to finally set on EMMS, the Emacs Multi Media System. One thing that I really appreciate about EMMS is how minimal it is: there is only one…