The intersection of technology and liberal arts

That Federico Viticci has quite an eye.

This week’s episode of Connected started with the boys talking about Stephen Hackett’s reversion to his Genius days at the Macstock conference. On Saturday, he did a RAM upgrade and replaced a hard drive with an SSD in Father John’s iMac. On Sunday, he did a RAM upgrade on Rosemary Orchard’s new Mac mini. While teasing Stephen for his good deeds, Federico said the photo of the latter upgrade (linked in the show notes) reminded him of a Renaissance painting. I was stunned. I knew he had to be talking about my photo, because that was exactly the effect I was going for.

Here’s the photo.

Macstock tableau

I took the picture specifically because the scene reminded me of The Last Supper. The foreshortening of the table draws your eye down to where the action is and is similar to the Last Supper’s ceiling. The people watching Stephen are like the apostles.

I disagree with Federico’s comment about the golden spiral, though.1 I was going for triangular construction, just like da Vinci. Note the three heads of the gentlemen standing at the other end of the table. The near edge and long sides of the table also suggest a triangle. The best triangle would have been the head and folded arms of David Sparks, but he turned bit too far sideways before I could snap the photo.

You might think I’d end with a comment about the relationship between the golden spiral and the Fibonacci sequence, which the boys were fumbling around with, but the internet is loaded with articles about that. I assume you know how to Google.


  1. And Ed Cormany will be hearing from my lawyers regarding his defacing of my masterpiece. 


File extensions and colors

For the past couple of months, I’ve been testing out iCloud Drive as a replacement for Dropbox. This was inspired by my growing tendency to work on my iPad Pro and the improvements to the Files app. While Dropbox has long been the standard way for iOS text editors to sync files, that environment is clearly shifting and strong integration with Files (where Dropbox will always have second-class status compared to iCloud Drive) is the way of the future. But Files still presents obstacles to the way I work; luckily I have a way around one of those obstacles, thanks to David Sparks.

I write my reports in LaTeX and generate PDFs to send to my clients. In the process of creating the PDF, LaTeX and its helper programs also create several other files. For example, if my LaTeX source code is test.tex, after compilation the folder will include test.aux, test.fls, test.out, test.fdb_latexmk, and test.log in addition to test.tex and test.pdf. All these files with the same base name but different extensions is no problem when working in the Finder on a Mac because I can see the extensions. But Files doesn’t show extensions.

Files with different extensions

The little icons help distiguish the PDF from the rest, but the files that Files sees as text tend to look the same, as do the file with extensions it doesn’t understand at all. So if I need to look through the log file to figure out an error, I’m likely to open the wrong one.1

I was complaining about this to David Sparks during a break at this weekend’s MacStock conference. He asked the very reasonable question “Isn’t there a setting that will let you see the extensions?” As far as I’ve been able to tell, the only way to see a file’s extension is to long-press on it

Files popup

and select the Info from the popup.

Files info window

This three-step process—long-press for popup, tap Info, dismiss Info window—is not something I want to keep doing.

“What about assigning colors to the different extensions?” said David.

“Oooh,” said I.

As a general rule, I don’t think much of tags as an organizational strategy. I’m much more comfortable with folders and subfolders. But in this case, they’re a great workaround because I’d only need a few, colors are already provided by default, and I’d be using them only in my work project folders.

So when I got home that night, I went to Hazel and made up some rules. I have individual folders for each work project, but they’re all inside a folder called projects. So all my new rules are assigned to that folder.

Hazel rules for project files

The first rule makes sure the color-tagging rules are applied to all the subfolders.

Hazel rule for project subfolders

The other rules assign colors based on the file extension.

Hazel rule for TeX files

You’ll note that I have a rule for coloring Python source files. Obviously, LaTeX doesn’t generate a test.py file, but when I write a program to do analysis for a report, I often give the program and report the same base names. I suppose I could force myself out of this habit, but why should I have to?

The Hazel rules run on my Mac, of course, but the changes they make propagate across iCloud. Now I can distinguish at a glance the LaTeX source, the Python source, and the LaTeX log files.

Color-coded files in Files app

I can’t remember the last time I looked at an .aux, .out, or any of the other files, so I didn’t bother making rules for them. I can do that later if needed.

This workaround doesn’t let Apple off the hook. The extension is part of a file’s name, and we should be able to see it directly from within Files, just as we can in the Finder. It’s not like there isn’t room for the extension, especially in list view. My guess is that this is not something we’ll be seeing in iOS/iPadOS 13, so the workaround is likely to be useful for quite while. Thanks again, David!


  1. I should mention here that while I’m editing and reviewing my report on my iPad, I’m compiling it on one of my Macs via an SSH connection. Sometimes I make this connection through Prompt and sometimes through the Terminal feature of Textastic


Zoom out

This vulnerability in the Macintosh client for the Zoom audio/video conferencing system has gotten a lot of attention since it was published yesterday. In a nutshell:

  1. Safari forces users to click a button to confirm they want an app launched.1 This would mean an extra click for Zoom users.
  2. To get around this terrible imposition on their users, Zoom installed a webserver on their computers without telling them. A webserver that remains present and running, even when the Zoom app is not running. Even if you uninstall the Zoom app.
  3. There is a set of commands you can run to kill the webserver and prevent its relaunch, even if you still want/need to use Zoom. The commands are near the end of the Medium post by Jonathan Leitschuh, who discovered all this. Ironically, the commands sometimes don’t appear in Safari on the Mac, apparently because of some incompatibility between the Safari and the GitHub embedding code used in the post.

I don’t pretend to follow all of Leitschuh’s explanation of the vulnerability, but I do understand the commands for the fix. I thought I’d talk about what they do. Also, there’s a cut-and-paste solution getting some traction on Twitter that I want to talk about.

First, here’s what Zoom says about the installation of the webserver:

Second, when Zoom is installed on a Mac device by the user, a limited-functionality web server that can only respond to requests from the local machine is also installed on the device. This is a workaround to a change introduced in Safari 12 that requires a user to confirm that they want to start the Zoom client prior to joining every meeting. The local web server enables users to avoid this extra click before joining every meeting. We feel that this is a legitimate solution to a poor user experience problem, enabling our users to have faster, one-click-to-join meetings. We are not alone among video conferencing providers in implementing this solution.

There’s no question that Mac users have a tendency to complain about changes Apple makes to the Mac’s OS and first-party software (I may have even done some complaining myself). But generally speaking, we think Apple’s focus on security is a good thing, and we certainly don’t want apps installing servers on our computers without telling us about it. Even if it means the “poor user experience” of (horrors!) an extra click when we want to use video. Note that Zoom doesn’t discuss the poor user experience of finding your computer’s camera turned on when you visit a malicious website.

Assuming you want to keep Zoom on your computer, the first step in Leitschuh’s fix is to make sure Zoom’s “Turn off my video when joining a meeting” setting is clicked on:

Zoom video settings

Let us bask for a moment in the warm glow of a user interface that asks you to turn something on in order to turn something off. And remember, Zoom is very concerned about poor user experiences.

With that bit of GUI work done, we have to move to the command line to rid ourselves of the unwanted webserver. These steps will be needed even if you deleted the Zoom app.

The unwanted webserver uses port 19421. We can find which process is using that port through the lsof command:

lsof -i :19421

lsof means “list open files,” and it’s using the expansive Unix definition of a file, which is basically anything that can read or write a stream of bytes. An internet address that’s listening for input, which our webserver uses, fits within that definition. The -i option to lsof allows us to specify as much of an internet address as necessary. We could, for example, give the protocol (TCP) and host (localhost) along with the port, but in this case only the port number (which has to come after a colon) is necessary.

The output is a table of processes that fit the specification

COMMAND     PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ZoomOpene 59742 drang   7u  IPv4 0x31175d99fb28ad5b      0t0  TCP localhost:19421 (LISTEN)

The header line tells us what’s in the columns below. In this case, there’s only one entry. You can see from the COMMAND that it’s related to Zoom (the full name of the command is trucated to fit) and from the USER that it’s running as me. The key item is the PID, or process identification number. That’s the ID of the webserver we want to stop.

Stopping a process in Unix means using the kill command. Despite its name, kill normally just sends a signal to the given process to “please finish up what you’re doing and then stop, if you don’t mind.” But you can give it an option to be more forceful. The -9 option is aggressive; the process can’t ignore it and shuts down immediately. So our next command is

kill -9 <PID>

where <PID> is number we got from the lsof output.

This tweet from Mateusz Stawecki uses a Unix pipeline to get the PID from the lsof command and feed it to the kill command.

Stawecki tweet

Given that the point of this exercise is to enhance the security of our computers, it’s hard to justify copying and pasting a command from Twitter. But Stawecki’s command does work. Let’s see why.

Ignoring for a moment everything that comes after the first semicolon, the pipeline is

lsof -i TCP:19421 | awk 'NR > 1 {print $2}' | xargs kill -9

As we’ve seen, the TCP part of the lsof command is an unnecessary but harmless addition. The output of lsof is fed to the awk command, which skips over the header line (NR > 1) and outputs the second field (print $2) of the next line. As we’ve seen, this second field is the PID of the process we want to kill. The xargs command takes the PID and turns it into an argument for the kill command.

There’s an easier way to do this, eliminating the awk command entirely. lsof has a “terse” option, -t, which reduces the output to just the PID(s) of the matching process(es). So we can cut Stawecki’s pipeline down to just two steps:

lsof -ti :19421 | xargs kill -9

And since there’s only one matching process, we could reduce the command even further:

kill -9 $(lsof -ti :19421)

The $(command) construct says “run this command and put its output here.” Because I like building up my commands step by step, I prefer the xargs solution, but either will work.

Now we’ve killed the web server, but we need to do more to prevent it from coming back. Zoom put a folder named .zoomus in your home directory, and inside that folder is an app called ZoomOpener. This is the app that launches the web server.

ZoomOpener app

We get rid of the app and its enclosing folder through

rm -r ~/.zoomus

Leitschuh’s article and Stawecki’s pipeline both use rm -rf, but the force (-f) option is unnecessary. The Unix rm command is powerful and a little scary, especially when combined with the recursive (-r) option. You may prefer to use the Finder to throw the .zoomus folder into the Trash and empty it. If so, you’ll have make the folder visible (files and folders that start with a period are invisible by default). This is done by pressing ⇧⌘. (that’s Command-Shift-Period). Press it again to go back to the usual Finder view.

With the ZoomOpener app deleted, we must be finished, right? Wrong. The Zoom app will recreate the folder and the ZoomOpener app the next time you launch it unless you do this:

touch ~/.zoomus

The touch command is meant to update an existing file’s access and modification dates without changing its contents, but if the file you give it as an argument doesn’t exist, it will create it. For reasons I don’t quite understand, putting a file named .zoomus in your home directory prevents the Zoom app from creating a .zoomus folder and installing ZoomOpener in it.

If you go back to Stawecki’s tweet, you’ll see that he has the rm and touch commands in there after the pipeline. Again, I don’t blame you for being leery of using his commands, but they do work and won’t ruin your system.

Of course, the real question is why should you trust me? Or anyone? You may want to read Ken Thompson’sReflections on Trusting Trust.”


  1. Thanks to Jeff Johnson for clearing up my initial confusion about the confirmation. Jeff makes StopTheNews, an app that handles Apple News URLs and is the sort of app that gets launched from a URL and requires a confirmation. Pretty sure Jeff hasn’t added a web server to get around that. 


Quadratic PCalc

When in the course of human events it becomes necessary for a person to dissolve the computational bands which have connected him with an app and to assume among the powers of the earth, the separate and equal station to which the Laws of Mathematics and of Polynomials entitle him, a decent respect to the opinions of other users of the app requires that he should declare the causes which impel him to the separation.

A few months ago, I explained why I wrote my own combinations function for PCalc. Today I declare my independence from its quadratic formula function.

We all know the quadratic formula. It works on equations that look like this,

[ax^2 + bx + c = 0]

and provides the two solutions:

[x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}]

It’s the ± that gives us two solutions. One of the solutions uses the minus and the other uses the plus.

PCalc comes with a quadratic solver function. You can find it in the Special section of functions, and it has a very long and explicit name.

PCalc built-in quadratic formula

What the name is telling you is to put the a term in the X register, the b term in the Y register, and the c term in the memory (or the M0 memory if you have multiple memories turned on). Then the two solutions, [x_1] and [x_2], will come out in the X and Y registers.

This solution has the advantage of being usable to every PCalc user. It works whether you have multiple memories on or not. More important, it works whether you’re in algebraic or RPN mode. It’s also presented in a form that should be familiar to anyone who knows what the quadratic formula is. PCalc’s developer, James Thomson, was careful to set it up with universal applicability.

But I don’t care about universal applicability. I care about what seems natural to me, and the placement of the a, b, and c terms has never seemed right to me. So I wrote my own quadratic solver function that fits with the way I think.

First, there’s no need for three inputs. Any quadratic can be put in the form

[x^2 + bx + c = 0]

without any loss of generality by dividing through by the leading coefficient. This means the inputs to the function can fit in the X and Y registers—no need to use one of PCalc’s memory registers.1

Second, I prefer to enter the b term in the Y register and the c term in the X register. In RPN mode, I enter them onto the stack in what I consider their natural order: b first and then c. Even if I were in algebraic mode—which I never am—it would seem more natural to me to enter b first, press the x~y key to put it in the Y register, and then enter the c term.

So with that design of the inputs, the PCalc function for the quadratic formula looks like this (the long screenshot was stitched together with PicSew):

Quadratic formula in PCalc

If you don’t want to enter the steps yourself, you can download it.

Note that if the equation has complex roots, my function will throw an error. This is consistent with PCalc’s built-in quadratic function and with how it handles the square roots of negative numbers. PCalc is a real calculator.

To solve a quadratic, I just enter b and c in that order and call the function. Here’s the input and output for the equation

[x^2 + x - 6 = 0]

Quadratic input and output

I hold that for the kinds of work I do with quadratic equations, the superiority of my quadratic solver function is self-evident.


  1. You may think that dividing through by the leading coefficient is extra work. Not really. Most of the quadratics I deal with already have a leading coefficient of one, so I seldom need to divide. And even when I do, the two divisions can be done quickly with RPN stack manipulation. It’s harder for me to remember which term goes into memory than it is to do two divisions.