Linux shortcut to connect to Bluetooth speakers

We have a Bluetooth speaker in our office that we often use to play music through. My Linux machine, however, didn’t automatically connect to the Bluetooth speaker, and even after connecting it, I’d have to switch the output to be that speaker.

I ended up creating a shortcut on my menu bar that would connect to the Bluetooth speaker and set it as the default audio output, all in one click.

First, I went and set up the audio like I normally would, making sure to note the Mac address of the device: Continue reading Linux shortcut to connect to Bluetooth speakers

Heroku changing up dyno pricing

Heroku is trialling new pricing levels for their dynos. Here’s the verbatim text they gave:

Free – Experiment in your own dev or demo app with a web and a worker dyno for free. Sleeps after 1 hr of inactivity. Active up to 12 hours a day. No custom domains. 512 MB RAM.

Hobby – Run a small app 24×7 with the Heroku developer experience for $7/dyno/mo. Custom domains. Run a maximum of one dyno per Procfile entry. 512 MB RAM.

Standard 1X, 2X: Build production apps of any size or complexity. Run multiple dynos per Procfile entry to scale out. App metrics, faster builds and preboot. All Hobby features. 512MB or 1GB RAM. $25 or $50/dyno/mo.
​
Performance – Isolated dynos for your large-scale, high-performance apps. All Standard features. Compose your app with performance and standard dynos. 6GB RAM. $500/dyno/mo.

Continue reading Heroku changing up dyno pricing

Fun networking stories: connecting three machines away via SSH

We had a hardware unit that was Ethernet enabled. To configure and manage it, the vendor provided us with a Windows program that, given the unit’s IP, could establish a TCP connection to the unit’s port 3300 and do all of its fancy management things.

The only problem was, the hardware unit was a hundred miles away on a private subnet at a client’s building, and the only thing that could directly talk to it was Linux computer A that we installed alongside the unit. We had the foresight to install Hamachi on computer A, and my own Linux computer B here also had Hamachi. My clunker Windows laptop C that could actually run the software was hooked up directly to computer B via Ethernet.

So, computer C had the Windows program and could talk to computer B via direct Ethernet. Computer B could talk to computer A via the Internet using Hamachi. And computer A could talk to the hardware unit via its local VLAN.

C -> B -> A -> hardware unit

The transitive property of hooking-up-computers states that if C can talk to B and B can talk to A, then C can talk to A. But how?

Well, when you only have SSH, every problem looks like an SSH connection.

  1. Computer B connected to computer A and established an SSH tunnel. The SSH tunnel forwarded B’s localhost:5000 port to A’s hardwareunit.local:3300. computer-b$ ssh -L5000:hardwareunit.local:3300 computer-a.local
  2. Computer C connected to computer B and established an SSH tunnel. The tunnel forwarded C’s localhost:3300 to B’s localhost:5000. computer-c$ ssh -L 3300:localhost:5000 computer-b.local
  3. Windows program on C connected to C’s localhost:3300, which actually goes to B’s localhost:5000, which actually goes to the hardware unit’s port 3300 via A.

Yes, everything was passed along via two SSH connections in a row, but it worked quite well, and it will save us from driving down to the client in the rare case that we need to do this again.

Workaround for HipChat on Linux: “can’t find build id”, “HashElfTextSection”

The new version of HipChat added support for video and screen-sharing. It also introduced the new requirement of OpenGL 2.0. On my computer, HipChat would crash on startup with repeated messages of

can't find build id
HashElfTextSection
can't find build id
HashElfTextSection
can't find build id
HashElfTextSection
can't find build id
HashElfTextSection

I wasn’t going to try video chatting on my old netbook anyways, so there’s no reason I needed hardware support for rendering text and emoticons.

First, get your system’s OpenGL info by running `glxinfo | grep OpenGL` and find your version string:

Continue reading Workaround for HipChat on Linux: “can’t find build id”, “HashElfTextSection”

tuntuntun – Combine Multiple Internet Connections Into One

GitHub repo: https://github.com/erjiang/tuntuntun (proof of concept status)

I was trying to play Minecraft by tethering over a Sprint data connection but was having awful random latency and dropped packets. The Sprint hotspot seems to only allow a limited number of connections to utilize the bandwidth at a time – a download in Chrome would sometimes stall all other connections. This was a huge problem in Minecraft, as loading the world chunks would stall my movements, meaning that I could teleport somewhere and die to an enemy by the time the map finished loading.

I’ve been seeing the idea of channel bonding here and there for a while, and it always seems like a cool idea without any popular and free implementations. Most of the approaches, though, were restricted to assigning different connections to different network interfaces. Essentially, a connection to YouTube might go over one link, while a software download might go out another. This works OK if you’re trying to watch YouTube while downloading updates, and it works great for many-connection uses like BitTorrent but in this case, I wanted to create a single load-balanced connection. So, I created tuntuntun.

Somewhat like a VPN

tuntuntun diagram

This requires the help of an outside server to act as the proxy for all of the connections, because most current Internet protocols require connections to originate from one address. The idea is to establish a connection to the proxy using a custom protocol that allows data to be split between two links. Tuntuntun works by encapsulating IP traffic in UDP packets, and does this in userspace using tun interfaces. A tun interface is a virtual network interface that has a userspace program as the other end. This means that any packets sent to the tun are read by the userspace program, and anything that the userspace program writes to it becomes “real” packets in the kernel.

Continue reading tuntuntun – Combine Multiple Internet Connections Into One

Batch organize photos by date

I wanted to get a pile of jpegs organized by the year, and then the day. For example, IMG00001.JPG would go in 2013/06-04 based on its EXIF creation date. The handy exiftool can do this, via its own virtual “Directory” tag. The “Directory” tag is not an actual EXIF tag, but exiftool will move the photo if you write to it.

Here’s two snippets, one to copy photos to a new directory based on the date (-o dummy/ forces a copy):

exiftool -o dummy/ -d %Y/%m-%d "-directory<datetimeoriginal" /path/to/unorganized/photos/*.JPG

And one to move photos to a new directory based on the date:

exiftool -d %Y/%m-%d "-directory<datetimeoriginal" /path/to/unorganized/photos/*.JPG

This will automatically create directories called $PWD/year/day.

Fixing Minecraft on Ubuntu with OpenJDK

Minecraft! On Ubuntu! It actually runs great, once you actually get it to run, but there were two little things mere mortals can’t be reasonably expected to debug.

Can’t connect to minecraft.net

My Internet connection worked, minecraft.net was up, friends were able to connect just fine, but I couldn’t. Running it from the terminal via java -jar minecraft.jar showed the error message java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty.

Basically, Minecraft uses SSL to protect your login, but Java didn’t have the certificates needed to verify. The Minecraft launcher really should give a better error message, but this was really Ubuntu’s fault. You need the ca-certificates-java package installed, but on my Ubuntu install, it was broken. Try doing ls /etc/ssl/certs/java/cacerts. If it comes up missing, then you need copy it from a friend or a different Unix machine. You don’t want to copy security files from strangers…

Black screen

Looking in the terminal showed the error java.lang.UnsatisfiedLinkError: ...: libjawt.so: cannot open shared object file: No such file or directory. There’s no good reason why an OpenJDK install can’t find its own damn libraries, but you can manually set your LD_LIBRARY_PATH variable to contain it.

Try doing locate libjawt.so. You’ll want to set your LD_LIBRARY_PATH to include one of the directories it gives you (just the directory, not included the file). Depending on whether you have OpenJDK 6 or 7, you’ll do something like:

LD_LIBRARY_PATH=/usr/lib/jvm/java-7-openjdk-i386/jre/lib/i386/ java -jar minecraft.jar

Again, check the results of locate versus your OpenJDK version (if you’re not sure, run java -version).

Ubuntu works great with the MSP430 Launchpad

I got my MSP430 TI Launchpad more than a year ago simply because of the price. It was (and still is) $4.30 (with free shipping!) for a development board, two MSP430 microcontrollers, external crystal, and USB cable. Unfortunately, Windows was the only supported OS at launch time with a couple proprietary bundled IDEs. It still is the only officially supported OS, but setting up Ubuntu 11.10 and newer for the msp430 has become trivial:

sudo apt-get install gcc-msp430 gdb-msp430 mspdebug

To test your Launchpad, try compiling “blink” from https://github.com/mrothe/ti-launchpad.

The build process goes something like:

msp430-gcc -Os -mmcu=msp430x2012 -o main.elf main.c
msp430-objcopy -O ihex main.elf main.hex # generate hex file
mspdebug rf2500 "prog main.hex" # download to the launchpad

Do mind your O, o, and 0.

cd && ls

I’ve noticed that I have a habit of changing to a directory and then immediately listing it’s contents. Wouldn’t it be nice if I could do it in one command?

My goto for shell automation is usually shell scripting. Shell scripting is nice because I can use any language I want, and I don’t have to worry about losing everything if I switch shells or something. Shell scripting isn’t suitable for this, however, because writing cd in a shell script will just change the script’s working directory.

I notice that a lot of people like to use aliases for various little things like command abbreviations, but aliases can’t interpolate arguments. Without control over arguments, I can’t give cd the argument and then ls after that.

The final solution I wrote is a bash function in my .bashrc, and while it’s bash-specific, I doubt I’ll ever need to port it to another shell (and it shouldn’t be difficult to do either).

cl () { cd \$1 && ls; }

Now I just need to train my fingers to type “cl” instead.

WordPress permissions on NearlyFreeSpeech.net

“To perform the requested action, connection information is required.”

My earlier post on WordPress with NearlyFreeSpeech.net was too hastily written. There are more issues than WP not wanting to use the direct upgrader, and editing WordPress code is not the right way to solve it either.

Problem 1: WordPress doesn’t want to use the direct upgrader. You can force it to use the direct upgrader by adding define('FS_METHOD', 'direct'); to /wp-config.php.

Problem 2: WordPress may not have write access to certain directories. The wp-content directory, for example, would need to be chgrp to web and chmod to 775 in order for WordPress to update the things within. Of course, there is the option of just doing that on all of your WordPress files.

Problem 3: WordPress will create files that you cannot edit. Files created by PHP will be owned by user ‘web’ and the permissions will be 644. That means you (“me”) cannot edit these files over SSH since you are not the owner. You can’t even delete, chown, or chmod the files. You’ll either have to get PHP to delete them or ask NFSN support to chown them for you. A workaround is to umask(002); to your wp-config.php, which makes files created by PHP group-writable. They will still be owned by web by default, but at least you can do something about it.

Problem 4: The default temp directory may not be accessible by PHP. NFSN’s FAQ for installing WordPress has instructions about this and a variant is given here. First, make a directory called ‘tmp’ in your WordPress root and give PHP permissions to write to it (chgrp to web and chmod to 775). Then, add define('WP_TEMP_DIR', dirname(__FILE__).'/tmp'); to your wp-config.php file.