Friday, September 08, 2023
Welcome back!
Hello! Long time, no entries.
This isn't the longest time I've been absent here at the ol' blog (the longest stretch has been 4½ months back in late 2012), but things around Chez Boca have been interesting for the past three and a half months. The biggest thing is a medical issue that Bunny has been going through. It's not life threatening, but it is life changing for the both of us, and the doctors are still trying to figure out what happened in late April that caused the issue. I've also been forced to deal with the medical-industrial complex and the bureaucracy surrounding it (Bunny used to deal with the medical-industrial complex, having been a former Fed herself and can stomach the bureaucracy) and while I have plenty to say about it, I'll refrain least I work myself up.
Another issue has been that my primary development system (a Linux system) has been offline for the past few months. July 3rd we had a small power outtage. It normally wouldn't be a big deal as the UPS kept the system up until I could shut it down cleanly, but when power was restored, the computer just refused to turn on. And given the situation with Bunn—
A week later and I can resume writing this entry. As I was writing, the situation with Bunny was such that I didn't feel up to mucking with the computer. It was just last week that I felt up to getting a replacement power supply. I ordered it from Amazon and it arrived the next day, not in a box, but wrapped in foam and packing tape stuffed inside an opaque plastic bag. I was not surprised in the least that the fan inside the power supply was broken. Not bad enough that a bit of cyanoacrylate glue (aka “Super Glue”) wouldn't fix it, but still, the fact that I had to do that wasn't a good sign (“Why don't you just return it?” asked Bunny? “Because I'm desperate enough to get my system up and running.”)
It was enough to get the system up and running, and as I was typing out this entry the new power supply went “POP” and that was the end of that.
Sigh.
I opted to return it for a replacement. It arrived yesterday, wrapped in foam and packing tape stuffed inside an opaque plastic bag, but this time the fan was fine, and it's now been running for over 24 hours without incident.
Saturday, September 09, 2023
How common is it for people to not know their own email address?
I'm still receiving all sorts of email from other Sean Conners to my sean.conner@gmail.com
address,
and I'm seriously wondering how?
Do these people not know their email address?
Currently:
- I own a condo in Austin, Texas;
- I have a doctor's appointment in Lake Wales, FL;
- I've subscribed to receive information about a blood-clotting prescription I have;
- and I still have a young child in elementary school.
I was able to call and stop the emails about the condo, doctor's appointment and medication, but for some reason, the administrators of the school in Tenneesee can't remove my email address unless they get permission from the parent of the actual child, and they won't tell me the name of the parent who thinks I need their child's school notices.
Sigh.
To make matters worse, in one case, the doctor's appointment case, the name of the patient wasn't even “Sean Conner!”
What?
How? Just … how?
Wednesday, September 13, 2023
Dear Walmart … seriously? That's what you keep under lock and key?
You keep alcohol wipes under lock and key?
Are they that valuable?
You do realize that we repealed the 18th Amendment, right?
Sigh.
Thursday, September 14, 2023
Stirring and shaking may be boring, but the future this brings will effect you in the future
This all works fine for the purposes of the telephone system. I mean, at least for a long time, it did. But have you noticed what's up with email lately? It seems that, given an open communications system, people will inevitably develop something called a "cryptocurrency" and badly want to make sure that you get in on something called an "ICO." The general term for this phenomenon is "spam," and the fact that it is only one letter away from "scam" is meaningful as the line between mere unsolicited advertising and outright crime is often razor thin.
In the email system, this problem has been elegantly solved by a system of ad-hoc, inconsistent, often-wrong heuristic classifiers glued to a trainwreck of different cryptographic attestation and policy metadata schemes that still haven't solved the problem. It is, perhaps, no surprise that the phone system is taking a generally similar approach.
The whole STIR/SHAKEN thing first crossed my path a few years ago at The Enterprise. At the time, I wasn't sure what the difficulty was in stopping spam/robo calls and that the Oligarchic Cell Phone Companies were complicit with said calls because it made them money. The actual story, covered in the above article, is much more complicated and nuanced than my own cynical take on it (worth reading, even if it's a bit long). By the time I left The Enterprise, we were starting to support it with our offering (which was “Caller Name ID”—that is, given a phone number, map that back to a name), along with a process that was attempting to classify the originating side of the call as legit or not if the call wasn't attested (that was being done at another department within The Enterprise). If you use a certain Oligarchic Cell Phone Company, and see the name “Potential SPAM” as the caller name, you were using code I worked on.
Tuesday, September 19, 2023
How long until I receive some really damaging information about another Sean Conner out there?
Yet another email for Sean Conner. This time, I own a 2015 Acura RDX with XXXXXX miles (XXXXXXX kilometers for those Imperially challenged) on the odometer and Tennessee license plate XXXXXXX, having just received service from Budget Brakes in XXXXXXXXX, Tennessee. That's only 875 miles (1,410 km) from Chez Boca (and for reference, the closest Budget Brakes to me is in Pensacola, Florida, 630 miles (1010 km) away).
I'm … just speechless … that this keeps happening!
Don't people know their own email address?
Do companies just assume customers have firstnamelastname@gmail.com
?
Why does this keep happening?
Friday, September 22, 2023
Failures in customer facing user interfaces
I was at a local fast food establishment getting lunch when I found myself behind a gentleman attempting to work the self-serve soda fountain. It had a touch screen where you navigated down a series of menus to your selection of tasty beverage to be dispensed from the single nozzle below the screen. The gentleman just didn't know how to use the device. He would select a soft drink category, the screen would then show a bunch of selections with round buttons on the screen, with one button being slightly above the rest, and larger. He would press other buttons, each one would jump up slightly and enlarge, the previous one would jump down and shrink, but the gentleman never clued in that the one button that was larger was “selected” and that he should then place his cup below the nozzle and press the physical dispense button.
This went on for several minutes before he turned to me and lamented that the machine wasn't working. I then pointed out to him how the machine worked. He thanked me, got his preferred drink dispensed into his cup and left.
I'm not sure what to make of this. Obviously, the makers of the soda dispensing machine thought about the UI but the fact that the gentleman in front of me couldn't figure it out shows that it wasn't entirely intuitive as the makers wanted it to be. I, knowing how the computer sausage is made, and having used various UIs over the decades, knew how to navigate the machine despite not knowing Spanish (the currently selected language with no obvious way that I saw to change it).
It's not an easy problem to solve. I have had problems using the self-checkout lanes at the grocery store when an item I have doesn't have a bar code on it, like fresh produce, or the bar code that is on the item doesn't scan for some reason. The interface itself may make it obvious that one can search for the item, but what to type? I recently had issues with a green pepper, and the solution was to look up “pepper” and select “green pepper” from the list, not to search for “green pepper.”
User studies? What are those?
I'm not optimistic that this will improve over time.
Discussions about this entry
Monday, September 25, 2023
The scene that always plays out at Chez Boca
“You know today is the day you get your hair cut.”
“You didn't have to go to all the trouble of setting up an appointment for me.”
“It was my pleasure.”
“But it hasn't been that long since my last haircut.”
“It's been over two months.”
“Yes, it hasn't been that long.”
“We're going now.”
“Do I have to? Hey! Ouch! Stop pulling my ear! Ow! Ow! Ow! Ow! Okay! I'll come.”
“Don't forget your keys.”
“You mean I have to drive as well?”
And with that, Bunny and I went to my hair cut appointment.
An unexpected nostalgic hit at the local barber surgeon shop
Bunny and I arrive at barber shop to await my doom haircut.
At the back of the shop I see something I haven't seen in years—nay, decades!
A video arcade machine!
I approach the cabinet and it's clear it's not an original machine at all, but a modern recreation with dozens of games available to play. Not as cool as an original machine, but still, a cool thing to find in a commercial establishment in 2023! The last time I saw a video arcade machine in a commercial, non-arcade setting was … the mid to late 80s?
While awaiting my turn in the chair, I managed to play a few games like Galaga, Qix, and Burger Time. Thirty-five years later and I still can't play these games. But it seems no one can play these games (or perhaps, the cabinet itself was only very recently installed) as I was able to get the top score on the games I played.
I'm not sure if it's just nostalgia, but I swear there were more diverse video games back in the 80s than today. Not only did you have the swarming alien invaders genre, but the the maze genre (Pacman), side scrollers (like Jungle King, platformer genre (like Donkey Kong or the above Burger Time), vertical scroller genre (like Spy Hunter or Crazy Climber), or the isometric genre (like Marble Madness or Zaxxon), and don't forget the vector games and the very crisp graphics. I'm probably forgetting a few other genres. These days, it seems it's all first-person shooters.
My time with the games was cut short as it was my turn in the barber chair.
Afterwards, as I was showing my barber how to play Qix (I don't think he was born yet when Qix came out), Bunny asked if she should get one for me for Christmas. I told her no, because it was just too addictive to have at home.
Changing the historical record of my blog
Twenty-one years ago I was worried about loosing the historical presentation of my blog both because it was template driven, and through the use of CSS. Changes that effect everything at once certainly appeared quite Orwellian to me, although I might be in a very small minority in worring about this.
And yet, since then, I've tweaked the CSS quite a bit since I wrote that. I figure I'm not changing the content, so it's okay. right?
It was over a year ago when I noticed that a lot of my earlier entries had the initial paragraph shifted over to the left,
due to a change in the template file I made around 2003.
The old template had an initial <P>
tag so I didn't have to type it,
and the new one removed said tag.
That left maybe a thousand posts
(give or take)
that needed fixing.
I started doing the job manually at first,
then gave up at the sheer number of posts to fix.
Again,
it was not changing the content but fixing the presentation.
And it bothered me that there were posts that weren't formatted correctly.
About a week or two ago, I realized that the markup I used for foreign words:
<span lang="de" title="My hovercraft is full of eels">Mein Luftkissenfahrzeug ist voller Aale</span>
is probably not sematically sound HTML. I even wrote about that issue twenty years ago, and now realize it should be:
<i lang="de" title="My hovercraft is full of eels">Mein Luftkissenfahrzeug ist voller Aale</i>
Around the same time,
I read up on the “proper” use of <BLOCKQUOTE>
and that the attribution should appear outside the blockquote,
not inside as I've been doing for years,
even though I was doing The Right Thing™ when I first started blogging,
but changed for some reason I long forgot.
And then several days ago,
I noticed the sample BASIC code was incorrect and it was bugging me—the keyword THEN
would always show up as THENNOT
.
How that happened is a topic for another post,
but in the meantime,
I decided to fix the issue without mentioning it.
The change didn't change the intended meaning of the post,
it was fixing incorrect output,
not saying we were always at war with Eastasia.
After that,
I decided to go back and fix the “formatting” issues in the blog.
I have code that will read entries and parse the HTML I use into into an AST
(or should it be a DOM,
even though I'm using Lua, not Javascript?)
which I use to generate the Gopher and Gemini versions.
To fix the initial paragraph issue,
all I needed to do was identify the entries that didn't start with a <P>
tag and just prefix the raw text with said tag.
To update the HTML for foreign words,
it was enough to identify entries with <SPAN LANG="
language">
and with some sed
magic,
switch it to read <I LANG="
language">
(and fix the corresponding closing tags).
It's just fixing the semantics of the HTML,
not changing the past,
right?
The fix for the <BLOCKQUOTE>
issue wasn't quite so easy—I still had over 700 entries that needed to be fixed,
so I ended up writing code that would spit out the parsed HTML back into HTML.
It would have been easy to output it as:
<p>I've been following the various Linux <abbr title="Initial Public Offerin g">IPO</abbr>s and today I see that <a class="external" href="http://www.val inux.com/">VA Linux Systems</a> had their <a class="external" href="http://d ailynews.yahoo.com/h/nm/19991209/bs/markets_valinux_1.html">IPO today.</a>. Briefly, it IPOed (can you verb a TLA? Can you verb the word “verb?” Whate ver … ) at US$30 and opened at US$299. Inbloodysane.</p><p><a class="extern al" href="http://www.andover.net/">Andover.Net</a> wasn't nearly as inbloody sane.</p>
one long line—the browsers don't care, but I do if I ever have to go back and edit this. Instead, I want the output to still be editable:
<p>I've been following the various Linux <abbr title="Initial Public Offering">IPO</abbr>s and today I see that <a class="external" href="http://www.valinux.com/">VA Linux Systems</a> had their <a class="external" href="http://dailynews.yahoo.com/h/nm/19991209/bs/markets_valinux_1.html">IPO today.</a>. Briefly, it IPOed (can you verb a TLA? Can you verb the word “verb?” Whatever … ) at US$30 and opened at US$299. Inbloodysane.</p> <p><a class="external" href="http://www.andover.net/">Andover.Net</a> wasn't nearly as inbloodysane.</p>
That meant handling not only <P>
but all the block level tags in HTML,
<BLOCKQUOTE>
,
<TABLE>
,
<DL>
(which I use for emails and screenplay dialog),
<UL>
,
<OL>
,
and <PRE>
.
Now that I have that working,
I can identify the citation paragraphs for blockquotes,
and move them to the appropriate location.
I'm about to do that, yet I'm still a bit hesitent. Yes, it's just fixing the semantic presentation, but now that I have the code to read and write HTML, future mass changes are easy to do.
I'm probably thinking too much on this.
I think.
Tuesday, September 26, 2023
To err is human—to really mess up takes a computer
I ran the code to fix the BLOCKQUOTE
issue and as it turns out,
there were 54 entries that needed further fixing due to the fix I just applied.
I wanted the HTML files to still be editable,
and as such,
I wrapped the contents of the block-level elements to fit within 80 columns,
and the function I used did not take into account where it was safe to break on an HTML tag.
So for future reference,
I'll have to write a customize word-wrapping function to take into account HTML.
As it was,
I fixed all 54 entries by hand;
some were trivial,
some required going into the backups.
Ah, the wonders of automation. A human can mess up, a computer can mess up a lot. Quickly.
The other thing I learned is that the entity '
is not defined for HTML 4
(it is for HTML 5,
and XML).
This is important because I'm still using HTML 4 for my blog.
Why not HTML 5?
Because I'm not fond of the “living standard”
(read: changes whenever,
meaning an ever-constant churn of updating HTML to maintain the standard du jour)
and the
step-by-step parsing rules instead of a concise syntax.
It also doesn't help that whenever I see WHATWG,
I read it as “What working group?”
Wednesday, September 27, 2023
A classic blunder, like getting involved in a land war in Asia
The first time I included some BASIC code,
I typed in the sample directly from a magazine
(like we used to do back in the 1980s).
The second
(and most recent) time I included BASIC code,
it was extracted from a disk image downloaded from the Intarwebs
(using code I wrote)
and then decoded into ASCII,
using code I wrote,
based off a text file I also found on the Intarwebs.
I didn't notice when I posted the code because it was
a wall of text 32 characters wide
(the width of the text screen on a Color Computer).
It was only months later when I finally noticed all the THENNOT
s littering the code.
There was nothing wrong with the actual file, but I did locate the bug in my code:
char const *const c_tokens[] = { "FOR", "GO", /* ... */ "SUB", "THEN" "NOT", "STEP", "OFF", /* ... */ "DSKO$", "DOS" };
If you look close,
you'll see there's a missing comma after the THEN
token,
and in C,
two literal strings separated by whitespace are concatenated into a single string.
Thus,
all the THENNOT
s I was seeing.
And a bunch of incorrect code because most of the BASIC keywords were then off-by-one
(a classic mistake of C programming).
Friday, September 29, 2023
YAML config file? Pain? Try Lua
Several articles about using YAML for configuration have been making the rounds, yet rarely do I see Lua being mentioned as an alternative for configuration files.
Yes, it's a language, but it started out life as a configuration format. It's also small for a language, easy to embed, and easy to sandbox for the paranoid. Here's an example:
lua_State *gL; bool config_read(char const *conf) { int rc; assert(conf != NULL); /*--------------------------------------------------- ; Create the Lua state, which includes NO predefined ; functions or values. This is literally an empty ; slate. ;----------------------------------------------------*/ gL = luaL_newstate(); if (gL == NULL) { fprintf(stderr,"cannot create Lua state"); return false; } /*----------------------------------------------------- ; For the truly paranoid about sandboxing, enable the ; following code, which removes the string library, ; which some people find problematic to leave un-sand- ; boxed. But in my opinion, if you are worried about ; such attacks in a configuration file, you have bigger ; security issues to worry about than this. ;------------------------------------------------------*/ #ifdef PARANOID lua_pushliteral(gL,"x"); lua_pushnil(gL); lua_setmetatable(gL,-2); lua_pop(gL,1); #endif /*----------------------------------------------------- ; Lua 5.2+ can restrict scripts to being text only, ; to avoid a potential problem with loading pre-compiled ; Lua scripts that may have malformed Lua VM code that ; could possibly lead to an exploit, but again, if you ; have to worry about that, you have bigger security ; issues to worry about. But in any case, here I'm ; restricting the file to "text" only. ;------------------------------------------------------*/ rc = luaL_loadfilex(gL,conf,"t"); if (rc != LUA_OK) { fprintf(stderr,"Lua error: (%d) %s",rc,lua_tostring(gL,-1)); return false; } rc = lua_pcall(gL,0,0,0); if (rc != LUA_OK) { fprintf(stderr,"Lua error: (%d) %s",rc,lua_tostring(gL,-1)); return false; } /*-------------------------------------------- ; the Lua state gL contains our configuration, ; we can now query it for values ;---------------------------------------------*/ /* ... */ return true; }
Yes, it's all too possible for someone to write:
(function() while true do end end)()
in the configuration and block the process with 100% CPU utilization, but as I stated in the code example, if that's a worry, you have bigger security issues to worry about.
Another nice benefit of using Lua is string management. If you are only using Lua for the configuration file, and once read, don't execute any more Lua code, then there's no need to duplicate the strings for your codebase—just keep using the strings directly from Lua. As long as you close the Lua state at the end of the program, they'll be cleaned up for you. And speaking of strings, you'll also have Lua's “long strings:”
long_string = [[ This is a long Lua string that can span several lines. Escapes like '\n' don't work in this, but then again, you don't really need the '\n' here because they're part of the string. ]] long_string_2 = [=[ And if you want to embed a literal ']]' in a long string, you can, no problems here. ]=]
I use Lua for the configuration file for my blogging engine (to see how I pull the configuration from Lua) which looks like:
name = "A Blog Grows in Cyberspace" description = "A place where I talk about stuff in cyperspace." class = "blog, rants, random stuff, programming" basedir = "." webdir = "htdocs" lockfile = ".modblog.lock" url = "http://www.example.com/blog/" adtag = "programming" conversion = "html" prehook = "./prehook_script" posthook = "./posthook_script" author = { name = "Joe Blog" , email = "joe@example.com", } templates = { { template = "html", output = webdir .. "/index.html", items = "7d", reverse = true, posthook = "posthook_template_script" }, { template = "atom", output = webdir .. "/index.atom", items = 15, reverse = true, }, }
But if you think it'll be too complicated to instruct devops as to when to use a comma and not, you can always include semicolons at the end of each line:
name = "A Blog Grows in Cyberspace"; description = "A place where I talk about stuff in cyperspace."; class = "blog, rants, random stuff, programming"; basedir = "."; webdir = "htdocs"; lockfile = ".modblog.lock"; url = "http://www.example.com/blog/"; adtag = "programming"; conversion = "html"; prehook = "./prehook_script"; posthook = "./posthook_script"; author = { name = "Joe Blog"; email = "joe@example.com"; }; templates = { { template = "html"; output = webdir .. "/index.html"; items = "7d"; reverse = true; posthook = "posthook_template_script"; }; { template = "atom"; output = webdir .. "/index.atom"; items = 15; reverse = true; }; };
to simplify the configuration instructions (“just add a semicolon to the end of each line … ”). One other benefit—comments. That's one of the biggest complaints about using JSON as a configuration file format—a lack of comments.
Also, you don't even have to mention you are using Lua as a configuration file—most likely, no one will really notice anyway. I used Lua to configure “Project: Sippy-Cup” and “Project: Cleese” at The Enterprise and no one said anything about the format. It was also used for “Project: Bradenburg” (written by another team member) and there were no issues with that either.