From 1f689fd039533801842ae241671f2437ddbe0044 Mon Sep 17 00:00:00 2001 From: Steph Enders Date: Thu, 7 Mar 2024 15:17:29 -0500 Subject: Copy old files and update build.sh to generate it all! This is a huge messy commit but :) sue me. I'm not at work I can do git badly for once! --- posts/venturing-back-into-c.html | 153 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 posts/venturing-back-into-c.html (limited to 'posts/venturing-back-into-c.html') diff --git a/posts/venturing-back-into-c.html b/posts/venturing-back-into-c.html new file mode 100644 index 0000000..16e3047 --- /dev/null +++ b/posts/venturing-back-into-c.html @@ -0,0 +1,153 @@ + +--post-date: 2019-02-17 +--type: blog +
+

Venturing back into C

+

For the past two weeks or so I have been diving back into C + programming. I've found it to be a very fun and refreshing experience + coming off of a slog of Java 11 updates at work. I've found comfort + in its simplicity and frustrations in my "I can do this without an + IDE" mindset.

+

I started C programming in College during a 8 AM course of which all I + can remember is that it was at 8 AM. I loved programming in C, dealing + with memory, pointers, no strings, structs, no strings, linking, no + strings. It was a really interesting difference from the web and Java + programming I had done previously. Obviously the lack of the + "string" type made things interesting and initially a challenge + for me back then. In my most recent endevour I found char * to be perfectly suitable for every case I came + across. It was usually a separate library that was failing me, not a + fixed char array. This was mostly due to the types of programs I was + writting in college were text adventures where all of what I did was + using strings. And my lack of understanding of what was actually + happening in C was really what was causing all the issues.

+

The Project

+

I started working on an application I had been meaning to develop + called reminder.d. This daemon + would monitor for reminder notifications I would send via a CLI. It queue + them up based on some time set to send the notification. I ended up + writing both the CLI and the daemon in this past week, both in C.

+

The Beginning

+

This project started with an outline (as a README) which I think was + the reason this ended up as an actually successful project. I had been + thinking about this for a long time, and had begun using a calendar to + keep track of long term reminders/dates etc. First, I outlined the + architecture "how would I actually do want to send myself + remidners". Since half my day is spent infront of a computer, with a + terminal open or at least two keystrokes away, a CLI would do the trick. + Then how do I actually send myself notifications... writing them down. So + I can use the CLI to write to a file and have a daemon pick up the + changes and notify me once it hits the desired time posted.

+

The CLI

+

The CLI remindme took in messages and appened them to a file. + This file would be monitored by the daemon later on. Each reminder + consisted of three parts:

+ After a notification is written the daemon will pick up the + notification and notify if the time set is now/past. +

The Daemon

+

The Daemon reminder-daemon opened and tailed a file at + /usr/local/etc/reminder.d/$USER.list. It would tail the file + monitoring any incoming lines parsing them into reminders. The syntax of + the reminder is FLAG EPOCHSEC MESSAGE . + Tokenizing on spaces it was then added to a linked-list sorted by time. + Every second it checks the file for any new lines, adding reminders as + they come in, then check the head of the list. If the reminder at the + head is ready to be notified the daemon pops it off the list and sends + the notification. After a notification is sent successfully the daemon + modifies that line in file updating its FLAG + to 'd'. This is so when the daemon starts back up it skips the + reminder. Notifications are sent via libnotify: Reminder - $DATETIME with the message body. They are also + set to last until dismissed manually, this way if were to walk away, once + I sat down I'd see the stale reminder waiting.

+

Future Plans for Reminder.d

+

Having a system to create and send myself notifications is incredibly + useful but having them limit to just the computer I sent them on makes + them a very limited. I have been using them at work for the last few days + and its nice to be able to tell myself to remeber to email a person after + lunch. But I would like to be able to tell myself things later in the + day. I have planned since the beginning to have a remote server I can + sync the reminders through. In addition having an application running on + my phone that also gets and sets reminders.

+

Remote syncing would change entirely how I deal with reminders in the + file.

+
+
+ struct remnode { 
+   long fileptr; 
+   struct reminder* reminder; 
+   struct remnode* next; 
+ }; 
+      
+

Is currently the struct I use to keep track of the reminders. + fileptr is the line of the file where the + reminder is, so I can fseek back to the + location and overwrite its flag. I cannot currently think of a way to + keep the files perfectly identical without introducing countless + edgecases. What I do think might work is providing some form of UUID. + When a remote pull tells the systems daemon that a notification has been + cleared it can mark it by ID. Right now the fileptr is effectively its + ID, but that will not work anymore. A composite key of the daemons own id + (generated at install?) with a new ID of each incoming message would help + ensure uniqueness across ID generations across multiple systems.

+

What I've learned

+

First off, I probably could've done this in bash. With + date notify-send git awk cron and a few other + useful commands I could very easily keep track of file changes and push + notifications at a certain time. But seeing as I scrap together bash + scripts all the time I though C would make things more fun.

+

Writing manpages was the probably the most fun I had working on the + project. They have a simple elegance to them, similar to C. That being + said you could FEEL the age of the language. Every single decision is + there to make things simple to parse. Even compared to modern markup the + explicit direct nature of the language made it so easy to learn. Every + tag served a specific purpose and each objective I had had a flag to do + it.

+

+.TH REMINDME 1 
+.SH NAME
+ remindme \- Send yourself reminders at a specific time on one or more devices
+.SH SYNOPSIS
+.B remindme
+[\fB\-t\fR \fITIME\fR]
+[\fB\-\-at \fITIME\fR]
+[\fB\-i\fR \fIPERIOD\fR]
+[\fB\-\-in\fR \fIPERIOD\fR]
+        
+      
+

Libnotify was insanely easy to work with, from a programming + perspective.

+

+  NotifyNotification *notif = notify_notification_new(title, rem->message, "info");
+  notify_notification_set_app_name(notif, APP_NAME);
+  notify_notification_set_timeout(notif, NOTIFY_EXPIRES_NEVER);
+
+  GError* error = NULL;
+  gboolean shown = notify_notification_show(notif, &error);
+        
+      
+

In closing

+

Overall, this was an extremely fun first week of engineering. I look + forward to what I am able to do syncing and sending notifications on + android.

+

For the zero people reading, grab a beer and outline your project. + Full through. Think about the how, then write it down. Don't worry + about getting in the weeds of how to write a manfile, thats what is fun + about programming. I thought I botched my debian/sid environment + uninstalling and reinstalling a notification daemon. Infact I think its + caused me to take a stance on the whole systemd thing. Either way, start + a private repo (they're free now) write a README and a LICENSE file + and iterate on the README until you realize "oh shit this is + something I can do". Then do it. This project still needs some work, + but for an MVP, its actually done. And now I can dive in the deep end of + trying to actually make it easy to setup on a fresh PC. Or dive into + modern android development and server syncing...

+
+ -- cgit v1.2.3-54-g00ecf