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.

Why I love DATA

In a ruby script, there's a keyword __END__ that for a long time I thought just marked anything after it as a comment. So I used to use it to store snippets and notes about the script that weren't really needed inline. Then one day I stumbled across the DATA constant, and wondered what flaming magic it was.

DATA is in fact an IO object, that you can read from (or anything else you'd do with an IO object). It contains all the content after __END__ in that ruby script file*. (It only exists when the file contains __END__, and for the first file ruby invokes though. See footnote for more details.)

How can we use this, and why indeed do I love this fickle constant? I mostly use it for quick scripts where I need to process text data, rather than piping to STDIN.

Given a list of URLs that I want to open in my web browser and look at, I could do the following for instance:

DATA.each_line.map(&:chomp).each do |url|
  `open "#{url}"`
end

__END__
http://google.com/
http://yahoo.com/

which upon running (on a mac) would open all the URLs listed in DATA in my default web browser. (For bonus points, use Launchy for cross-platform compatibility.) Really handy & quick/simple when you've got 500+ URLs to open at once to go through. (I once had a job that required me to do this daily. Fun.)

Or given a bunch of CSV data that you just want one column for, you could reach for cut or awk in the terminal, but ruby has a really good CSV library which I trust and know how to use already. Why not just use that & DATA to pull out the field you want?

require "csv"

CSV.parse(DATA, headers: true).each do |row|
  puts row["kName"]
end

__END__
kId,kName,kURL
1,Google UK,http://google.co.uk
2,"Yahoo, UK",http://yahoo.co.uk
# >> Google UK
# >> Yahoo, UK

I find when the data I want to munge is already in my clipboard, and I can run ruby scripts directly from text editors without having to save a file, it saves having to write the data out to a file, have ruby read it back in, etc just to do something with the data. I can just write the script reading from DATA, paste the data in and run it. Which also lets me run it iteratively and build up a slightly more complex script that I don't want to keep. Then do what I need with the output and close the file without saving it.

* technically DATA is an IO handler to read __FILE__, which has been wound forward to the start of the first line after __END__ in the file. And it only exists for the first ruby file to be invoked by the interpreter.

cat > tmp/data.rb <<RUBY
p DATA.read
__END__
data.rb
RUBY

ruby tmp/data.rb
# => "data.rb\n"

cat > tmp/data-require.rb <<RUBY
require "./tmp/data"
RUBY

ruby tmp/data-require.rb
# => /Users/caius/tmp/data.rb:1:in `<top (required)>': uninitialized constant DATA (NameError)

And because it's a file handle pointing at the current file, you can rewind it and read the entire ruby script into itself…

$ ruby tmp/readself.rb 
DATA.rewind
print DATA.read

__END__
something goes here

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.

+[NSObject load] in MacRuby

If you've not heard of it, MacRuby is an implementation of Ruby 1.9 directly on top of Mac OS X core technologies such as the Objective-C runtime and garbage collector, the LLVM compiler infrastructure and the Foundation and ICU frameworks. Basically means you write in Ruby using Objective-C frameworks, and vice versa. It's pretty damn cool to be honest!

What is +[NSObject load]?

From the documentation:

Invoked whenever a class or category is added to the Objective-C runtime; implement this method to perform class-specific behavior upon loading.

This means when your class is loaded, and implements the load method, you get a load message sent to your class. Which means you can start doing stuff as soon as your class is loaded by the runtime.

The main place I've seen it used (and used it myself) is in SIMBL plugins. A SIMBL plugin is an NSBundle that contains code which is loaded (injected) into a running application shortly after said application is launched. It lets you extend (or "fix") cocoa applications with additional features. So you have this bundle of code, that gets loaded into a running application some point after it starts, and you want to run some code as the bundle is loaded - usually to kick off doing whatever you want to do in the plugin. This is where load becomes useful.

Here's a quick implementation that just logs to the console:

    @implementation MainController
    
    + (void) load
    {
        NSlog(@"MainController#load called");
    }

Now where does MacRuby come into this?

Well I came across a need to do the same in ruby, have some code triggered when the class is loaded into the runtime. Tried implementing Class.load but to no avail. Then remembered MacRuby is just ruby! And I can call any code from within my ruby class definition.

For continuity I still call it Class.load, but then call it as soon as I've defined it in the class. Eg:

class MainController
  def self.load
    NSLog "MainController#load called"
  end

  self.load
end

Of course, I'm not sure when the Objective-C method is called, it's probably after the entire class has been defined rather than as soon as load has been loaded into the runtime. So you might want to move the self.load call to just before the closing end.

iPad? iPerfect (…for me)

Google Groups is a pile of fail and hasn't posted my message in reply to a thread on Geekup so I'm blogging it instead.

On 27 Jan 2010, at 19:53, Steve Richardson wrote:
Thoughts?

I've been searching for a device to fit between my Macbook Pro and iPhone. I work all day on the MBP, and moving it to then watch video in another room or read twitter/news/mail whilst watching telly, etc is a pain.

The iPhone is a great little device on the move, but for trying to multitask at home it's a bit.. tedious. Even jailbroken and running multiple apps at once it's still limiting.

I'd been looking around at netbooks, but what put me off actually getting one was my previous experience with one. I know I'd want it to run OS X to keep in sync (easily) with my other Apple devices, but hackintoshing one was a bit too much hassle, plus the fact ones to hackintosh cost more than I really wanted to pay for something that wasn't quite what I thought I needed.

And then.. the iPad. I've been sort of keeping up with the rumours (mainly through Daring Fireball) and whilst I didn't get excited about it too much ahead of announcement1, having seen the official video of it it's pretty much guaranteed that I'm going to get one.

Yes, it's limited (App Store, closed device), but.. I don't care. Take the iPhone, it's good enough for doing things on it, even if someone else is in charge of the ecosystem and has a big finger saying yes or no. I (willingly) use iTunes, Mobile Me, all the things that are so wonderfully integrated in the world of Apple, so another device that consumes my media using channels I already know and use is just a massive win for me.

All I'm hoping now is that $499 doesn't equal £499. Hopefully it'll be £399, still a good £80 above direct exchange rate, but low enough that it's a no-brainer for me to get one.

…And I think this is the first Apple product that I've seen announced and actually known from the start why I'm going to get one, instead of just a knee-jerk "SHINY!!!! WANT!!!" reaction. Uh oh, does that make me an adult?

1 I miss getting really excited about apple announcements :(

Update

It just got even better. Was lamenting to a friend on IM that it'd be so much nicer once you can directly suck photos off a camera/SD card into it. Turns out there's an adapter for that. See "iPad Camera Connection Kit" at the bottom of http://www.apple.com/ipad/specs/ for details.

at(1) on OS X

I recently came across the at(1) command, and wondered why it wasn't executing jobs I gave it on my machine. Had a poke around the man pages, and discovered in atrun(8) that by default launchd(8) has the atrun entry disabled.

To enable it (and have at jobs fire) you simply need to run the following command once:

sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.atrun.plist

Personally I've taken to using this to sleep my machine after a custom amount of time, mainly because my alarm clock/sleep timer of choice (Awaken) can't handle playing Spotify for x minutes and then sleeping the machine. The following command puts the machine to sleep, which (quite effectively) silences spotify.

echo "osascript -e 'tell app \"Finder\" to sleep'" | at 1:00am

See the at(1) manpage for how to specify the time, but as I'm only ever scheduling it on the same day (usually 20 minutes or so in advance), just passing the time works fine.

Read Later in a keystroke

I use a wonderful service for saving text to be read later, instapaper.com. It's gotten more wonderful as time has gone on and other applications/service's have gained the ability to save links/articles/webpages there for me to pick up later.

For instance, I'm out and about checking twitter on my iPhone using tweetie and someone tweets a link. Rather than wait for it to load and having to read it then and there I can just hit "Read Later" and it's saved in my instapaper account for me to read as and when I choose to. Recently the legendary mac feed reader NetNewsWire gained this ability too.

There's a few ways to send a feed item to instapaper from within NNW. Firstly you can right-click and click "Send to Instapaper".

Send to Instapaper from contextual menu
View Original on Flickr

Secondly there's a menu item for it in the News menu, which also provides my chosen way of instapapering an item—the keyboard shortcut! ⌃P (control-P).

Send to Instapaper from News menu
View Original on Flickr

So, in NNW I'm happily sending stuff to instapaper with the handy ⌃P shortcut, but that doesn't exist in the third place I mark things to read later–Safari! Up until now I've been using the standard "Read Later" bookmarklet that instapaper.com provides, and it's got a spot on my Bookmarks Bar so I can easily click it.

That doesn't really help with the fact I'm hitting ⌃P in NNW, and it doesn't work in Safari. Quite often I noticed myself hitting the key combination in Safari and wondering for a split second why it wasn't sending the item to instapaper. Then the solution hit me!

In OS X you can setup (and/or override) menu items with custom key combinations! Why hadn't I remembered this before. Because the "Read Later" bookmark(let) is nested under the Bookmarks menu, it is a menu item! A quick trip into the Keyboards Prefpane in System Preferences and a new binding later and voilâ, "Read Later" in Safari is bound to ⌃P and I can use it in both Safari and NNW.

Filling in the form to bind the keyboard shortcut
View Original on Flickr

Filter through command

This is another old post that I'm republishing. Originally published 27th April 2007.

My text editor TextMate has a nice feature called "Filter through command" whereby you can filter the current document through a command.

Anyway, I've never used it before, but today I had a text file with 30 or so url's in, each on a new line, so I thought I'd test it out. I selected it to input the document & to not replace the output. I then entered the following command, which is a ruby command to take each line that isn't blank, and run the shell command open $url.

ruby -e 'a = ARGF.read.scan(/\S+/); a.each { |x| `open #{x}` }'

What this does is take ARGF (the document) and read it in line by line, but only the non-whitespace characters (so newlines, space, etc are ignored.) And it assigns it to an array called a. What I then do is for each item of a, we run it past the shell command open, which on OS X if you pass it a URL it just opens that URL in the default browser.

My browser is Safari, and its set to open new links in a new tab in the foremost window. So I ran the command, and hey presto, within a few seconds I had all the URL's loading in seperate tabs in Safari's foremost window!

The power of Unix (OS X) & TextMate (amongst other tools) just never ceases to amaze me.

Update

I just realised if you change the regex to scan for http://.* then it'll select all website URLs.

ruby -e 'a = ARGF.read.scan(/^http://.*$/); a.each { |url| `open #{url}` }'

Mac Tips you may not know

Here are some mac tips I know and consider "basic" mac knowledge, but no-one else seems to know.

(Alternative title Peter Cooper suggested, "A miscellany of input device co-ordinations to modulate the response of Apple's task preview and switching subsystem")