ASCII Art Diagrams

I’ve used and I like it. has some different features, and although it seems like it has some capabilities that textik doesn’t have (like adjusting some of the objects), I like better.

Once I’ve got my basic diagram done in textik, I use vim to further adjust it and move things around. I paste the diagrams into Confluence or other documentation.

Record a screencast with audio on linux

Here’s how I recorded my screen, with audio from the microphone, from my Ubuntu 20.04 machine:

sleep 10 && ffmpeg -video_size 1920x1080 -framerate 25 -f x11grab -i :0.0+0,0 -f pulse -ac 2 -i default ~/Videos/screencast.mp4


Simulate dropped or latent packets in Linux

I’m documenting this more for my own reference than anything, partly because I’ve used ‘tc’ off and on over the years.


    tc qdisc add dev tun0 root netem loss 30%
    tc qdisc show dev tun0
    tc qdisc change dev tun0 root netem loss 0.1%

    When finished:

    tc qdisc del dev tun0 root
  • organize photos with exiftool

    I organize images in a custom hierarchy of directories. Lately, I’ve been using Google Photos and its shared albums to share photos with family. When I download the photos from the album that others have contributed, I want to organize those photos based on who contributed them. Google photos doesn’t make that easy.

    Fortunately, cameras embed their make and model into each picture that they take, and since nearly everyone uses a different model of smartphone or camera, it is easy to separate out the images.

    Windows Explorer allows me to add the model of the camera for an image in the details view. Then I can sort on the model, and break out the photos into a separate subdirectory for each contributor.

    On Linux, I haven’t found an easy way to do the same thing — i.e. Gnome’s file manager, Nautilus, is anemic in comparison, as are other Linux alternatives.

    Recently, I found exiftool, and it solves the problem for me, at a command-line level (it works on Windows, MacOS, Linux, BSD, and others).

    Test adding the model of camera to image (e.g. Canon EOS Rebel XIV)

    exiftool -p -v1 '-testname<$model %f.%e' *.jpg

    Do it for real:

    exiftool -p -v1 '-filename<$model %f.%e' *.jpg

    The final task is to remove the model name from the image. E.g.

    rename 's/Canon EOS Rebel XIV //' *.jpg

    Exiftool can do so much more, including organize images into subdirectories. This examples organizes images in the current directory into year-month-date directories:

    exiftool -preserve -d "%Y-%m-%d" "-directory<filemodifydate" "-directory<createdate" "-directory<datetimeoriginal" .

    XAR self contained executables via squashfs

    From the world of interesting and cool approaches to solving software deployment issues:

    Statically linked binaries that minimize dependency management difficulties work well for C++ executables, but languages like Python, JavaScript, and even Lua present a different challenge: How do you place source code and data (such as SSL certificates or shared libraries) inside a single executable? What do you do about the dependencies the tool might have on modules installed on the host operating system?

    XARs are slightly modified squashfs files… that mount themselves when executed and unmount after an idle timeout. They could almost be thought of as a self-executing container without the virtualization. By using the squashfs format, we not only distribute data in a … compressed format…, but we also decompress on demand only the portions we need. Thanks to this architecture, XARs have nearly zero overhead in production and can be used just as native scripts or executables would be.

    Show which git branches have been merged and can be deleted

    At work, we generate quite a few feature branches, which get tested, and then merge into “develop”. The feature branches don’t get cleaned up frequently. Here’s a series of shell commands I cobbled together to show the most recent person to commit to the branch, and which branches have been merged into develop.

    git checkout develop
    git pull -r
    (for branch in $(git branch -r --merged | grep -vP "release|develop|master") ; do git log -1 --pretty=format:'%an' $branch | cat ; echo " $branch" ; done) | sort | sed -e 's#origin/##'

    The output looks something like this:

    Jane Doe feature/something
    Jane Doe feature/another-thing
    Jane Doe feature/yet-another-something
    Zane Ears feature/howdy

    And they can be deleted as follows:

    git push origin --delete feature/something

    Add a camera via WPS to a LEDE/OpenWRT router

    I have some WiFi cameras that can be added to a router via WPS. Here’s how I got it to work with one of my LEDE routers. On the other one, somehow, I broke its ability to do WiFi completely, so this can be dangerous — I had to re-install LEDE. YMMV.

    OpenWRT/LEDE Instructions:

    First, backup the router config — always a good idea!


    opkg update
    opkg remove wpad-mini
    opkg install wpad hostapd-utils
    opkg upgrade dnsmasq
    cp /etc/config/wireless /etc/config/wireless.orig
    vi /etc/config/wireless and change wps_pushbutton to '1' -- but only for one interface.

    Check to see if WiFi is working. If not, use the ethernet port connected to a laptop to log back in, and update the firmware that isn’t broken. There may be a better way, but that’s worked for me.

    Put the router into WPS mode (note: this times out after a while):

    hostapd_cli wps_pbc

    Other instructions say to run this (YMMV):

    hostapd_cli -i wlan1 wps_pbc

    Within a minute or so, push the WPS mode button on the camera.

    Yubikey 4 GPG key generation (Ubuntu)

    Install supporting software

    sudo apt-add-repository ppa:yubico/stable
    sudo apt-get update
    sudo apt-get install scdaemon -y
    sudo apt-get install python-setuptools python-crypto python-pyscard python-pyside pyside-tools libykpers-1-1 pcscd -y
    sudo apt-get install yubioath-desktop yubikey-personalization yubikey-personalization-gui yubikey-manager  -y

    Insert Yubikey and Generate key

    gpg --card-edit
    gpg/card> admin
    gpg/card> generate
    gpg/card> quit

    export and backup the public keys, because the Yubikey only stores the private portion of the key

    gpg --armor --export $KEYID >

    Require touching the Yubikey button to authenticate, sign, or encrypt:

    ykman openpgp touch aut on 
    ykman openpgp touch sig on 
    ykman openpgp touch enc on 

    Change the pin

    gpg --card-edit
    gpg/card> admin
    gpg/card> passwd
    gpg/card> quit

    Change yubikey information

    gpg --card-edit
    gpg/card> name
    gpg/card> lang
    gpg/card> quit


    LEDE awesomeness

    I’ve had what I thought was a great WiFi router for the past 3 years. The vendor continues to provide firmware updates, which is admirable.

    Having heard of the awesome improvements that are being made by folks in the LEDE fork of OpenWRT (in the area of eliminating bufferbloat), I thought it was time for an upgrade. So I purchased an Archer C7 version 2 router, and today, I installed LEDE. Installation was a breeze. Configuring LEDE isn’t as easy as most consumer WiFi routers, but the payoff has been good.

    My downstream 2GHz WiFi cameras and networking gear seem to be staying online better, and streaming live video works better as well. I’m not sure if my family notices much of a difference, but I do. I appreciate the folks who have brought me better networking.

    UPnP, SSDP, mDNS, LLMNR, etc. on the home network

    Sometime in the distant past, I was aware of Universal Plug and Play (UPnP), but I didn’t know much about it. It’s a technology that allows devices in the home to talk to each other without prior configuration — it allows auto-discovery and configuration of printers and media servers, among other things.

    The auto-discovery happens via SSDP (Simple Service Discovery Protocol). A device joins a network and announces “I’m here!”, and then other device can choose to respond. Even if the device gets a different IP address, it can still be uniquely identified by its unique identifier (UUID).

    Here’s more information about UPnP and related protocols that run on the home network:


    UPnP protocol (no authentication):

    • Discovery (SSDP)
    • Description – HTTPU and HTTPMU
    • Control
    • Event notification
    • Presentation

    UPnP has well defined device profiles for:

    • Audio & Video — DLNA, and
    • Routers:

      • Internet Gateway Device Protocol

      • Retrieve external IP addr

      • Enumerate port mappings
      • Add/Remove port mappings & port forwarding: firewall-hole-punching
    • Devices Profile for Web Services (DPWS)

    Other protocols that help on the home network:

    • LLMNR: Link-local Multicast Name Resolution — implemented by Microsoft in Windows.
    • mDNS (multicast DNS) runs on port 5353. Uses .local hostnames.
    • DNS-SD: DNS service discovery. Can use DNS or mDNS.

    Apple’s Bonjour uses mDNS and DNS-SD. Linux’s Avahi uses IPv4LL, mDNS, and DNS-SD. Linux’s systemd has “systemd-resolve”, a command-linetool to resolve hostnames on a network via DNS, mDNS, and LMMNR.