Caius Theory

Now with even more cowbell…

Remove OS X Disk Password

I recently reinstalled a laptop and in doing so setup full disk encryption in a slightly strange fashion. The basic flow I followed was:

  1. Boot into Recovery mode (hold ⌘-R at boot)
  2. Erase the internal HD as HFS+ (Journaled, Encrypted) and set a disk password
  3. Install OS X onto the internal disk
  4. During setup, use Migration Assistant to copy clone containing previous install data from backup disk

This worked great in the end, once I'd recompiling various utilities I had installed. (Downside of moving from one CPU arch to another - can't just copy all compiled binaries over.)

However, I failed at step 2 above and entered "password" as my disk password since it was only intended to be temporary. Usually OS X's full disk encryption (FileVault 2) allows the machine users to unlock the disk, and not a standalone password. Due to the slightly odd way I setup the machine, I had the option of either using the disk password or my user account's password.

Having hunted around trying to find how to change or remove this disk password and leave only my users password, I finally stumbled across the magic incantations in an apple discussion thread asking How to disable "Disk Password" on boot?.

The magic incantations are as follows:

  1. List all the passwords that can currently unlock the drive

    Make sure there is a second password listed or removing the disk password will lock you out of the disk.

     $ sudo fdesetup list -extended
     ESCROW  UUID                                                    TYPE USER
             28376DDE-B6E1-48BE-A06F-4212067581D6    Disk Passphrase User
             4DBF8CEF-40F7-4F00-902F-A47AA643C656                 OS User caius
    
  2. Note the UUID of the "Disk Passphrase" entry, and remove that from the list

     sudo fdesetup remove -uuid 28376DDE-B6E1-48BE-A06F-4212067581D6
    
  3. List the passwords again to make sure the Disk Passphrase entry was removed

     $ sudo fdesetup list -extended
     ESCROW  UUID                                                    TYPE USER
             4DBF8CEF-40F7-4F00-902F-A47AA643C656                 OS User caius
    

Hey presto, only your user is left being able to unlock the disk.

Solve volume down button not working on iPhone 5

I noticed this morning that my volume down button (-) wasn't working on my iPhone 5 running iOS 7. Pushing the physical button in didn't change the volume. The volume up button increased the volume successfully still.

As is my normal first step debugging iPhone weirdness, I rebooted the phone by turning it off, leaving it off for a few seconds, then booting it back up with the power button. Once powered off and on in this way, the volume down key still didn't decrease the volume.

Fearing a physical button issue at this point, I turned to google for suggestions on what else to try. Running across this thread on Apple's discussion forums, I tried out the solution in there.

  1. Open "Settings"
  2. Scroll down and tap on "General"
  3. Tap on "Accessibility"
  4. Scroll down to the bottom and tap on "AssistiveTouch"
  5. Tap the toggle for AssistiveTouch to turn it on, and you should see a little icon appear on screen (white circle contained in a dark grey rounded square)
  6. Tap the AssistiveTouch icon (was in the top left corner on screen for me)
  7. Tap on "Device"
  8. Tap "Volume Down" a bunch of times and you should see the volume being turned down
  9. Tap outside the AssistiveTouch dialog to close it
  10. Try pushing the physical Volume Down button

In my case, following these steps made my physical volume down button start working again. Makes me wonder if the solution author on the apple discussion thread is right, in that this is a software issue and forcing a volume down action through the on-screen interface makes it remember that there's a physical button to respond to as well.

Either way, I can stop deafening myself whenever I receive a notification now!

Compile & run swift files directly

Turns out you can run a swift file without having to compile it into a binary somewhere and then run that binary. Makes swift behave a bit more like a scripting language like ruby or python when you need it to.

Using the xcrun binary, we can reach into the current Xcode /bin folder and run binaries within there. So xcrun swift lets you run the swift binary to compile files for instance. If you view the help with -h, there's a useful flag -i listed there:

-i    Immediate mode

Turns out immediate mode means "compile & run" in the same command, which is what we're after.

$ cat hello.swift
println("Hello World")

$ xcrun swift -i hello.swift
Hello World

Bingo. But what if we want to make hello.swift executable and call it directly without having to know it needs the swift binary to call it. Unix lets files define their shebang to say how the file needs to be executed, so lets go for that here too!

$ cat hello2.swift
#!/usr/bin/env xcrun swift -i
println("Hello World 2")

$ chmod +x hello2.swift
$ ./hello2.swift
Hello World 2

No more having to fire up Xcode for quick CLI tools, especially ones using the system frameworks!

Rename Google Drive folder on Mac

  1. Quit Google Drive app
  2. Rename ~/Google Drive/ to whatever you want
  3. Open Google Drive and wait for it to complain the folder is missing
  4. Click the menu item and click the warning item
  5. Click "Locate Folder.." button on the right in window that pops up
  6. Find your renamed folder and hit OK
  7. There is no step seven

Add to iCloud Reading List programmatically

One piece of a larger puzzle I'm trying to solve currently, was how to add a given URL to my Apple "Reading List" that is stored in iCloud and synced across all my OS X and iOS devices. More specifically, I wanted to add URLs to the list from my mac running Mavericks (10.9). I had a quick look at the Cocoa APIs and couldn't see anything in OS X to do this. (iOS has an API to do it from Cocoa-land it seems though.)

I figured Safari.app was the key to getting this done on OS X, given it has the ability itself to add the current page to the reading list, either via a keyboard command, a menu item, or a button in the address bar. One quick mental leap later, and I was wondering if the engineers at Apple had been nice enough to expose that via Applescript for me to take advantage of.

One quick stop in "Script Editor.app" later, and I had the Applescript dictionary open for Safari.app. Lo and behold, there is rather handily an Applescript command called "add reading list item", which does exactly what I want. It has a few different options you can call it with, depending on whether you want Safari to go populate the title & preview text, or if you want to specify it yourself at save-time.

As I want to be able to call this from multiple runtimes, I've chosen to save it as an executable, which leans on osascript to run the actual Applescript. And here it is:

#!/usr/bin/env osascript

on run argv
    if (count of argv) > 0
        tell app "Safari" to add reading list item (item 1 of argv as text)
    end if
end run

Save it as whatever you want (eg. add_to_reading_list), make it executable (chmod +x add_to_reading_list), and then run it with the URL you want saving as the first argument.

$ add_to_reading_list "http://caius.name/"
$ add_to_reading_list "http://google.com/"
# … etc …

(Adding support for specifying preview text and title is left as an exercise for the reader!)

Have fun reading later!

Mounting Harman Kardon Soundsticks on the wall

Having recently moved my Soundstick III's into the front room, I've been thinking of a way to wall mount them safely to free up table room. Googling eventually turned up just one person who has previously documented mounting his soundsticks on the wall, using 22mm plumbing clips (intended for 22mm central heating pipes).

A quick scrounge round the local Homebase this afternoon yielded a pack of similar clips, 5x 22mm push clips for £1.99. Having just fitted the speakers to the wall, they're nice and secure (providing no-one hangs on them, which they shouldn't do), fairly neat and simple to fit.

I've left the subwoofer on the floor under the table, and only mounted the "sticks" (tweeters) on the wall, one each side of the mirror over our dining table. I can then conveniently run the cables to the "sticks" behind the mirror and keep it looking neater.

I affixed the clips to the wall, one either side of the mirror with enough space for the speaker to sit without overlapping the mirror. Mostly just held the stick up and guessed at where to put the clip, but it looks ok.

Speaker clip without speaker in it

Then I bent the speaker stand backwards behind the stick (don't worry, it's on a hinge!) and threaded the cable through the middle of the ring to make it sit flusher against the wall.

Speaker ring bent behind the unit

And then it was just a case of easing the speaker ring into the clip, with the clip at the top of the ring (picture below if you can't visualise that easily). I think the rings are more like 24-25mm so it takes a bit of easing to get them in there. Once it's in there's no play in the clip for it to wiggle out though, even though it's plastic. I tried not to fatigue the clip arms too much wiggling it in there as well, so as to minimise the chance of it failing over time. (Something to check periodically!)

Close up of speaker unit in clip

Lastly, I just zip tied the cables together behind the mirror, and ran them down vertically from the middle to the floor and plugged them in. Sounds fantastic, and due to being plugged into an Airport Express, anything compatible can stream audio through them wirelessly. Fabulous darling!

(Click any image for a larger version)

Use Readline With Default Ruby on OS X

OS X Lion comes with ruby 1.8.7-p249 installed, although it's compiled against libedit rather than libreadline. Whilst libedit is a mostly-compatible replacement for libreadline, I find there's a couple of settings I'm used to that don't work in libedit. (Like history-beginning-search-backward.)

Luckily you can grab the source of ruby and compile just the readline extension, and move it into the right place for it to just work. Here's what's been working for me:

# Install readline using homebrew
brew install readline

# Download the ruby source and check out 1.8.7-p249
mkdir ~/tmp && cd ~/tmp
git clone git://github.com/ruby/ruby
cd ruby
git checkout v1_8_7_249
cd ext/readline
ruby extconf.rb --with-readline-dir=$(brew --prefix readline) --disable-libedit
make

Now you should have readline.bundle in the current directory, and it should be compiled against your homebrew-installed readline library, rather than libedit that comes with the system. We can quickly double-check that by using otool to check what the binary is linked against.

$ otool -L readline.bundle
readline.bundle:
    /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/libruby.1.dylib (compatibility version 1.8.0, current version 1.8.7)
    /usr/local/Cellar/readline/6.2.2/lib/libreadline.6.2.dylib (compatibility version 6.0.0, current version 6.2.0)
    /usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

And in the output you should see a line listing "libreadline", and no lines listing "libedit". Which that shows, we've compiled it properly then. Now the bundle is built we need to move it into the right place so it's loaded when ruby is invoked.

RL_PATH="/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin11.0"
# Back up the original bundle, just in cases
sudo mv "$RL_PATH/readline.bundle" "$RL_PATH/readline.bundle.libedit"
sudo mv readline.bundle "$RL_PATH/readline.bundle"

And that's it. You've got a proper compiled-against-readline installed ruby 1.8.7-p249 on 10.7 now.

One gotcha I ran into was needing to pass the same arguments to rvm when installing any other version of 1.8.7 on the same machine. Simple enough, just need to remember to do it though.

CC=gcc-4.2 rvm install 1.8.7-p357 -C --with-readline-dir=$(brew --prefix readline) --disable-libedit

Install GCC-4.2.1 (Apple build 5666.3) with Xcode 4.2

As of Xcode 4.2 Apple have stopped bundling GCC with it, shipping only the (mostly) compatible llvm-gcc binary instead. The suggested fix is to install GCC using the osx-gcc-installer project. However, I wanted to build and install it from source, which apple provides at http://opensource.apple.com/.

You should already have installed Xcode 4.2 from the app store, then basically the following steps are to grab the tarball from the 4.1 developer tools source, unpack & compile it, then install it into the right places.

Update 2016-07-03: I'd suggest just using homebrew to install this these days:

brew install homebrew/dupes/apple-gcc42

Instructions

# Grab and unpack the tarball
mkdir ~/tmp && cd ~/tmp
curl -O http://opensource.apple.com/tarballs/gcc/gcc-5666.3.tar.gz
tar zxf gcc-5666.3.tar.gz
cd gcc-5666.3

# Setup some stuff it requires
mkdir -p build/obj build/dst build/sym
# And then build it. You should go make a cup of tea or five whilst this runs.
gnumake install RC_OS=macos RC_ARCHS='i386 x86_64' TARGETS='i386 x86_64' \
  SRCROOT=`pwd` OBJROOT=`pwd`/build/obj DSTROOT=`pwd`/build/dst \
  SYMROOT=`pwd`/build/sym

# And finally install it
sudo ditto build/dst /

And now you should have gcc-4.2 in your $PATH, available to build all the things that llvm-gcc fails to compile.

App Store Hidden Preferences

See the Update at the end before you get excited :(

Having just installed 10.6.6 to use the Mac App Store, I was slightly annoyed that it fills my dock with apps as I install them. I'm a bit strange, in that I use a hidden preference to make the dock uneditable (it stops me accidentally dragging an app off.) But that means I can't drag off the Mac App Store installed apps either.

Had a quick look through /Applications/App Store.app/Contents/MacOS/App Store with strings (love that tool) and noted a few strings that looked interesting. (There's a full list in this gist.) There wasn't anything that explicitly stated it stopped it putting anything in the dock, but I did notice an option that stopped it showing install progress in the dock.

Yank up a terminal window, bash out the following…

defaults write com.apple.appstore FRDebugShowInstallProgress -bool NO

…head back to the MAS and install another (free) app, and hey presto, it's leaving my dock alone! Hopefully that's all I needed to continue using my Dock as I like. (Hidden, and left alone.)

Update 2011-01-06:

Seems my joy was short-lived. I'd re-downloaded an app I'd already purchased and it just showed download progress in the MAS app, not in the dock. Installing new applications still shows up in the dock (annoyingly.)

I've been having a poke through how it all hangs together, and if it's possible to actually block downloads from the Dock or not. It doesn't look like there's a hidden preference to hide new apps from downloading in the dock, you can just disable the progress bars in the dock with prefs. The MAS.app seems to be codenamed "Firenze", with the "hidden" prefs being prefixed with "FRDebug".

As I understand it, the App\ Store.app invokes a binary inside /System/Library/PrivateFrameworks/CommerceKit.framework called "storeagent" to do the actual downloading/talking to the dock. From looking at the class-dump of storeagent it communicates with the dock to place a new type of DockTile. Interesting sounding methods to (potentially?) swizzle are -[DownloadQueue sendDownloadListToDock] and -[DownloadQueue tellDockToAddDownload:].

I've given up for now, but I reckon it should be possible to create a bundle that swizzles the right methods in storeagent to stop it placing the downloads on the Dock.

Facebook iPhone app Contact Sync isn't automatic

There's an article on the guardian about private phone numbers being uploaded from facebook, and another over techeye.net on the same subject.

Firstly a quote from the techeye article:

Facebook doesn't warn users that they are uploading their phone's address book to Facebook.

And whilst the guardian article never says it happens automatically, it also doesn't lay it out that you have to explicitly enable that feature, and agree to the facebook app uploading the data.

I was pretty sure that facebook wouldn't be grabbing all your contact information without telling you, if they did at all, and that both articles were just pure scaremongering. So I fired up the facebook iPhone app, headed into my friends list on there, clicked sync and got the following screen:


View Original

Ok, so according to that text, they're just pulling down profile images and profile links from facebook and putting them in your address book against your contacts. Seems fairly harmless so far. So I toggled the top switch, to enable Contact Sync, and got the following screen:


View Original

Reading that, it's fairly obvious what data facebook are uploading (although a little ambiguous why), and it certainly isn't happening automatically. As it says, it uploads the "name, email address, phone number" from all your contacts to facebook, and pull down "your friends' profile photos and other info from Facebook".

So whilst facebook are collecting more data (albeit stored subject to their Privacy Policy), it's certainly NOT done automatically, and is very explicit about what is being uploaded at the point you enable it.