Everything In Between

The brutally honest, first-person account of Meitar Moscovitz’s life.

Archive for the ‘Apple/Macintosh’ Category

HowTo: Use Rules to Automatically Manage Email in Apple Mail

5 comments

After recently moving to San Francisco, I joined the San Francisco Freecyclers’ Network. Freecycle is a really cool set of local groups who prefer to give away items to people who want them instead of throwing them away into the trash. The group uses email to connect people who offer items and those who want them. In order to stay sane, a simple, conventional format for writing an email’s subject line lets you quickly figure out what’s on offer and where.

Thanks to this simple text convention in subject lines, I could trivially automate the process of sorting through the approximately 100 emails a day that the email list generates in order to single out only the emails that interest me. Here’s how I did it.

Define Your Goals

Before setting out on any task, it behooves you to take a moment and think about what it is you’re trying to accomplish. For me, with the San Francisco Freecycling Network (SFFN) email list, I wanted to achieve the following goals:

  • Keep my inbox clear of email from the SFFN list unless a message was particularly interesting.
  • Browse the SFFN messages when I wanted to look at them without having to go to the web site.
  • Highlight particularly interesting messages in my inbox visually and play a special sound to alert me that such email has been found in case Mail was running in the background (since free stuff gets taken fast!).

I defined “particularly interesting” messages as ones that offered items of need for my recent move. With this in mind, I set out to create email rules that accomplished each goal in turn.

Step 1: Create a mailbox to store the appropriate messages

I began by creating a new mailbox to store all the SFFN messages I was getting. This alternate mailbox would be the mailbox I would shunt all SFFN email to so as to keep my inbox clear of it. I called the mailbox simply “SFFN”.

Do this:

  1. From the Mailbox menu, select New Mailbox…. The New Mailbox sheet appears.
  2. Select any location (“On My Mac” is fine, as is the account that receives the mailing list messages), and give it a name.
  3. Click OK.

Step 2: Create an email rule to move all appropriate messages to the new mailbox

With the new mailbox created, I now needed to get all the appropriate messages in there and out of my inbox.

Apple Mail’s email rules work by looking at each incoming message and matching it against a set of conditions that you provide. If the message being evaluated matches the conditions you specify, such as “from the San Francisco Freecycler’s Network mailing list”, then an associated action is automatically performed. Every email you get is evaluated against every rule you have unless a rule moves the message to another mailbox or until you trigger the “stop evaluating rules” action.

Since moving an email message to a new mailbox ends the process of evaluating rules and moving messages to the SFFN mailbox I just created is the goal of the rule I’m creating, I decided to name the rule “END – SFFN”.

Do this:

  1. From the Mail menu, select Preferences…. The Mail Preferences window opens.
  2. Click the Rules button. The Rules pane appears.
  3. Click the Add Rule button. The Add Rule sheet appears:
    1. Enter a meaningful description (I chose “END – SFFN”) in the Description: field.
    2. Provide the conditions you want to match. Since all SFFN emails must be addressed to the mailing list, I simply provided the email address of the mailing list (sffn@yahoogroups.com) as the condition for the To header.
    3. Provide the actions you want Mail to perform. I simply wanted to move the matched messages to the SFFN mailbox.
  4. Click OK.

For me, the above configuration looked like this:

end-sffn-mail-rule

Step 3: Create an email rule to highlight a message of particular interest

At this point, any and all email I receive from the San Francisco Freecyclers’ Network is being moved to the SFFN mailbox I created for it. This is nice because it keeps my inbox clear, but it’s still not very helpful since I still have to go trudging through the SFFN mailbox in order to find anything that might be interesting to me. The whole point of this exercise is to reduce the amount of time I spend actively looking for interesting things and let my computer do that work for me. So the next step is to tell Mail what I’m looking for so it can show the interesting messages to me.

Now, as it happens I’m in need of a wireless router. Since “router” is an appropriately unique word, I’m going to tell Mail to look for that word in a subject line. However, since I only want Mail to tell me when a router is available and not when other people like me are looking for routers, I’ll also tell Mail to look for the keyword “OFFER” in the subject line. (And this is why the Freecycle guidelines tell users to format their subject lines in a conventional way.)

Finally, since I don’t want to have to go digging for the interesting email message and since my inbox is already going to be kept clear by the previous rule, I’ll simply have Mail highlight the message in a bright green color and leave the message in my inbox without moving it to the SFFN mailbox I created earlier.

Do this:

  1. From the Rules pane in Mail’s preferences, click Add Rule.
  2. Enter a meaningful description in the Description: field. (Since I’m looking for a router, I called it “SFFN – Search for OFFERed ‘router’”.)
  3. Provide the conditions you wish to match. For me, this meant email sent to the Freecycler’s mailing list with the two words “OFFER” and “router” in the subject line.
  4. Specify the actions you wish Mail to perform. I wanted Mail simply to color the message green and to leave the email go to the inbox (where it was originally destined for), so I chose “Stop evaluating rules”. (I also decided I’d want Mail to play a special sound to alert me that it had found something interesting. This is optional, of course.)
  5. Click OK.

When I was done creating my rule, the above configuration looked like this:

Screenshot of Mail.app rule to highlight incoming Freecycling emails offering a router.

I can now repeat this step as many times as desired to tell Mail to highlight other messages that may be of particular interest for some other reason. For instance, say instead of looking for a wireless router, I wanted to look for a toaster. I would simply need to click on “Duplicate Rule” and replace all instances of “router” with “toaster”.

Step 4: Place email rules in appropriate order

Since Mail will repeatedly check incoming email against all the active rules, we need to be sure to place the rules in the correct order. You can think of each email rule as part of large Rube Goldberg machine, each message getting funneled through some piece of the logic at each successive rule. That’s why I began the name of the first rule I created with “END,” so that I’d know it should be placed after the rest of the SFFN-related email rules.

I decided that I wanted Mail to look for anything related to cameras and, of course, to toasters. This gave me a total of 4 rules (three to search for items of interest, and one to keep my inbox clear). Since the three highlighting rules all perform the same action, it doesn’t really matter which order they go in, but it is important that all of them appear before the rule to move messages to the SFFN mailbox.

To order rules, simply click-and-drag them into the order you wish Mail to evaluate them in. When I was done, my Rules pane looked like this:

Screenshot of the Mail.app Rules pane with sorted rules.

Conclusion

Mail rules are an extremely powerful feature that most email clients have, but that too few people use. They can save you enormous amounts of time and increase your productivity by automating simple yet time-consuming tasks.

The conventional, standardized subject lines that the Freecycle mailing list uses simplifies the logic required to have your computer automatically process your messages for you. This is a useful observation because it can be applied to other areas of your life where using simple conventions can help to organize otherwise overwhelming information tasks into manageable batches. Although this particular example uses stock, simple commands, you can get as fancy as you like by having an action trigger an AppleScript.

Now, hopefully, finding some additional housewares and a wireless router for my new San Francisco apartment will be as easy as checking (but not manually sorting!) my own email!

Written by Meitar

July 27th, 2009 at 4:07 pm

One Minute Mac Tip: Create an encrypted disk image to store confidential files

2 comments

Nary a day goes by when I don’t use my computer for some extremely personal stuff. I would consider it a Very Bad Thing if some of this information (my bank account details or private SSH keys, for instance) fell out of my control.

Everyone has sensitive files that they keep on their computer and, fortunately for Mac OS X Users, Apple has made it ridiculously easy to create a cryptographically secure containers for such files. You can think of a container like this, which is just a standard Mac OS X disk image (.dmg) file, like a vault that you open, put stuff you want to keep safe inside, and then close again.

Here’s how you go about making and using one.

Create the container, an encrypted disk image

  1. First, open up your copy of Disk Utility.app, which is located in your computer’s /Applications/Utilities folder. (As an aside, this program is a bit like a swiss army knife for handling disk operations in Mac OS X. You should definitely find out what else it can do).
  2. Next, select the File → New → Blank Disk Image… option. This will cause the New Blank Image window to appear.
  3. Fill in the typical details such as the disk image file’s name and where you want to save it to. In addition, you’ll be presented with a number of options such as Volume Name, Volume Size, and Image Format. The defaults are usually adequate except for Volume Name, which you should customize so that when you mount the disk image the disk label is meaningful for you, and the Image Format, which I recommend you switch to “sparse disk image.”

    Sparse disk images can start small and grow automatically as you write more files into them. If what you want to keep secure in this manner are very large files, say gigantic high resolution PhotoShop documents, then you might consider the sparse bundle disk image format instead.

    Also, obviously, set the Encryption to a value other than “None.”

    Here’s an example screenshot from my Mac:

    Screenshot of the New Blank Image window showing meaningful values entered, Encryption field set to 128-bit, and Image Format field set to sparse disk image.

    Screenshot of the New Blank Image window showing meaningful values entered, Encryption field set to 128-bit, and Image Format field set to sparse disk image.

  4. Press the “Create” button and you’ll be presented with a standard password selection dialogue. This is the password you’ll use to mount the disk image and is analogous to the idea of setting the combination on your vault’s lock. It’s critical that the password you choose is a good one. Ideally, your password is a totally random string that may include any printable character. Since that’s hard to remember, you can have the Mac OS X keychain manage your passwords for you.

Encrypt some files by writing them to the disk image

Now that you have an encrypted disk image, a secure container for your sensitive data, you can make use of it just as you might any other disk image on Mac OS X. For instance, say I have a top secret file called “My Killer Business Plan.pages” and I don’t want anyone to get at it. All I need to do is copy the file into my encrypted disk image, as the following screenshot shows:

Copying "My Killer Business Plan.pages" to the encrypted disk image encrypts the file, too.

It should go without saying that you want to delete the original, unencrypted copy of the file you’re copying into the encrypted disk image, but I’ll say that anyway. Don’t leave unprotected copies of your files lying around. Also, be certain to unmount (eject) the disk image when you’re done using it because the only thing the password protects is opening the disk image, not the files contained within it.

External references

Here are some additional places where this technique is discussed. Check out these additional articles about this topic elsewhere for more information and other perspectives:

Written by Meitar

October 13th, 2008 at 1:33 am

Extract list of all Apple WikiServer wiki titles into CSV format

one comment

An interesting request came in today from a coworker. She wanted to create a spreadsheet that contained all of our intranet’s wiki pages (which uses the Apple WikiServer), presumably because Apple doesn’t provide an easy way to “list all pages” in the wiki itself. Along with the page title, she also wanted to extract its internal ID, its URL, and the time the page was created as well as the time it was last modified.

I spent about an hour looking into this this afternoon and it turns out that much of this information is readily available on the filesystem in the Apple WikiServer’s data store. I whipped up the following shell script to extract this information in CSV format, exactly as requested.

I’m posting this script here in case someone else wants similar “export a list of WikiServer pages to a comma-separated values (CSV) file” functionality but isn’t sure how to go about getting it. To use this, just edit the line that reads http://my-server.example.com/groups/wiki/ so that it refers to the wiki base URI of your own server.

Update: The latest version of this script is now available at its Github-hosted repository. You should probably use that instead of the script below.

#!/bin/sh -
#
# Script to extract data from an Apple WikiServer's data store by querying the
# filesystem itself. Creates a 'wikipages.csv' file that's readable by any
# spreadsheeting application, such as Numbers.app or Microsoft Excel.app.
#
# USAGE:   To use this script, change to the WikiServer's pages directory, then
#          just run this script. A file named wikipages.csv will be created in
#          your current directory. For instance:
#
#              cd /Library/Collaboration/Groups/mygroup/wiki  # dir to work in
#              wikipages2csv.sh                               # run the script
#              cp wikipages.csv ~/Desktop                     # save output
#
# WARNING: Since the WikiServer's files are only accessible as root, this script
#          must be run as root to function. Additionally, this is not extremely
#          well tested, so use at your own risk.
#
# Author:  Meitar Moscovitz
# Date:    Mon Sep 22 15:03:54 EST 2008

##### CONFIGURE HERE ########

# The prefix to append to generated links. NO SPACES!
WS_URI_PREFIX=http://my-server.example.com/groups/wiki/

##### END CONFIGURATION #####
# DO NOT EDIT PAST THIS LINE
#############################

WS_CSV_OUTFILE=wikipages.csv
WS_PAGE_IDS_FILE=`mktemp ws-ids.tmp.XXXXXX`

function extractPlistValueByKey () {
    head -n \
      $(expr 1 + `grep -n "<key>$1</key>" page.plist | cut -d ':' -f 1`) page.plist | \
        tail -n 1 | cut -d '>' -f 2 | cut -d '<' -f 1
}

function linkifyWikiServerTitle () {
    echo $1 | sed -e 's/ /_/g' -e 's/&amp;/_/g' -e 's/&gt;/_/g' -e 's/&lt;/_/g' -e 's/\?//g'
}

function formatISO8601date () {
    echo $1 | sed -e 's/T/ /' -e 's/Z$//'
}

function csvQuote () {
    echo $1 | grep -q ',' >/dev/null
    if [ $? -eq 0 ]; then
        echo '"'$1'"'
    else
        echo $1
    fi
}

ls -d [^w]*.page | \
  sed -e 's/^\([a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]\)\.page$/\1/' > $WS_PAGE_IDS_FILE

echo "Title,ID,Date Created,Last Modified,URI" > $WS_CSV_OUTFILE
while read id; do
    cd $id.page
    title=$(extractPlistValueByKey title)
    created_date="$(formatISO8601date $(extractPlistValueByKey createdDate))"
    modified_date="$(formatISO8601date $(extractPlistValueByKey modifiedDate))"
    link=$WS_URI_PREFIX"$id"/`linkifyWikiServerTitle "$title"`.html
    cd ..
    echo `csvQuote "$title"`,$id,$created_date,$modified_date,`csvQuote "$link"` >> $WS_CSV_OUTFILE
done < $WS_PAGE_IDS_FILE
rm $WS_PAGE_IDS_FILE

For those new to the Wiki Server, this introduction to the Apple WikiServer for web developers may be of interest.

Written by Meitar

September 22nd, 2008 at 12:35 am

Scrum-style Burn Down Chart in iWork ‘08 Numbers.app

3 comments

Ever since I was introduced to the Scrum methodology of software development, I’ve enjoyed my work so much more than before. Most of that enjoyment is due to a sense of visibility, of knowing what’s going on.

I find working without an accurate awareness of the situation at large very disorienting, and software and web development are notorious for being circumstances that change rapidly. That’s why one of my favorite things about Scrum is the burn down chart. This is nothing more complex than a simple graph that depicts how much work you bit off and how far along trying to chew it you actually are. The benefit, of course, is that it’s pretty obvious pretty quickly if you’ve bit off more than you can chew. ;)

So up ’til now, my team and I have been doing this all on paper. There’s a certain tactile appreciation I have for doing this sort of thing on paper, but of course there are disadvantages, too. For instance, you can’t easily archive the information. You can’t easily share it with remote contractors. You can’t automatically mine this valuable data with software tools. You get the picture.

There are a few cool plugins to some tools like Trac that do all this, but at first blush most of these tools seem to require that you move all of your Scrum’s planning into the digital world. That is, you can’t just do the burn down chart, you have to do all your estimation (MoSCoW desirability, sizing, estimating ideal hours) through some tool. That’s a big step, and I wanted something simpler.

So naturally, I came up with a spreadsheet in Numbers.app as my solution. I mean, how much simpler can you get? Sure, it’s not exactly “well integrated” with other tools, but your non-tech-savvy boss will probably love it, and AppleScript can be used to automate data extraction. Here’s what it looks like:

An example Scrum-style burn down chart in Apple's iWork '08 Numbers spreadsheeting application, complete with an actual chart.

An example Scrum-style burn down chart in Apple's iWork '08 Numbers spreadsheeting application, complete with an actual chart.

(Click the screenshot to get a full-size view.)

As you can see, the Numbers sheet is a simple table and a line chart. I’ve embedded instructions for how to use the chart into the example itself, which I’ll quote here:

This is a sample Scrum-style iteration burn down chart for software development created by Meitar Moscovitz. It can be used to plot a team’s progress throughout a development cycle (aka. “iteration” or “sprint”). This sample chart depicts a 3-week iteration (15 working days) with a 150-point target goal.

The X-axis represents time, and is thus labelled Time in Days, while the Y-axis represents the work to be completed, and is labelled Points.

The green line shows the team’s ideal velocity based upon the total number of points—termed the Remaining Initial Value—scheduled for completion in the graphed iteration.

The blue line shows the team’s actual velocity (or “completed work”), which is entered by the team leader (aka. Scrum Master) after each day in the Done column.

To use this chart: duplicate this sheet, enter your iteration’s total points in the Initial Value row of the Remaining column, and delete the values in the Done column except its initial value of 0. To add more days, copy and paste more rows into the table. Optionally, give the sheet and its contents new titles. ;)

Feel free to download the Example Burn Down Chart.numbers file and use it yourself. If you do use it, please leave a comment and let me know how you’re going. Thanks, and enjoy!

(Mike Cohn of Mountain Goat Software has got a similar spreadsheet for Excel you can download.)

Written by Meitar

September 6th, 2008 at 6:46 am

One Minute Mac Tip: Remove .DS_Store files from ZIP Archives

5 comments

The Mac OS X Finder has some nifty features, one of which is an exceptionally useful contextual menu item to create ZIP archives of folders. Unfortunately, the Finder also has some really, really annoying habits, one of which is to create a file named .DS_Store in each folder a user opens (when not in Column view). What this means is that if you create a ZIP archive on your Mac and then send it to someone who unzips it without the Finder (such as a Windows user using the Windows Explorer), the recipient will see a lot of litter in the form of useless and meaningless .DS_Store files.

If you’re not afraid of the Terminal, this can be avoided. Put the following lines in your ~/.profile (or similar):

alias rmds='find . -name ".DS_Store" -type f -print0 | xargs -0 rm'

What this does is creates a new command that you can use (rmds) which recursively finds and deletes any regular file named “.DS_Store” starting from the current directory. Thus, running this command in the folder you are about to create an archive out of will clean it first, and will prevent unnecessary confusion on the part of your archive file recipient.

Alternatively, another way to do this is to use the command-line zip program and an (admittedly more complicated) pipeline to remove the .DS_Store files after they have been added to the archive. To do that, use this series of commands:

zip -d ZIPfile.zip `unzip -l ZIPfile.zip | grep .DS_Store | awk '{print $4}'`

where, naturally, ZIPfile.zip is the ZIP archive you want to remove the .DS_Store files from. Creating an alias out of that command (and making it work for paths that contain spaces) is left as an exercise for the reader. ;)

As an aside, the alias, find and xargs commands are incredibly useful in their own right and can be used to do a lot of pretty amazing things. As always, man command will give you the nitty gritty.

Also as an aside, you can stop the Finder from creating .DS_Store files entirely when browsing network volumes (like Windows shares) with another command, documented in Apple’s Knowledge Base.

Written by Meitar

August 4th, 2008 at 1:07 am

One Minute Mac Tip: Securely erase files from the command line

leave a comment

Security provisions are one of those “things” that Mac users have been snooty about—for good reason—for decades. However, I’d dare say that, even though the UNIX architecture of the underpinnings of Mac OS X is much more secure than most other popular operating systems (cough, Windows, cough), much of the security benefits that Mac users have enjoyed are really security-by-obscurity, which is not very secure at all. With the added popularity of Mac OS X, lots of responsibility suddenly shifts from the vendor (Apple, Inc.) to the individual users (this means you) to keep your data secure.

Apple has been on point, however, providing good security utilities built right into the operating system and easily available to end users. Of most common use is probably “Secure Empty Trash” which securely deletes files that you put into the trash. The counterpart to this function available in the Finder is, too few Mac users know, the srm or secure remove command-line utility.

srm can be thought of as simply a version of rm that overwrites file data before unlinking it from the file system. It comes with a few more options than rm comes with all geared towards tweaking just how it overwrites files. My favorite is -m, which the manual page says:

overwrite the file with 7 US DoD compliant passes (0xF6, 0×00, 0xFF, random, 0×00, 0xFF, random)

I had the perfect occasion to use srm today: I was transporting my SSH private key from one laptop to another via a temporary drive. I wanted to securely remove all traces of the private key file from the temporary drive after installing it in the new computer. (See this SSH public key tutorial if you don’t know why this might be important.)

After copying the private key file over, removing it securely looks like this:

srm -m private_key_file

It’s that easy.

To be confident that your file is truly overwritten with garbage, you can use the -n option. This is one way to retain a file, but completely corrupt it. Observe:

Meitar:~ meitar$ cat testfile
Hello world.
Meitar:~ meitar$ srm -mn testfile
Meitar:~ meitar$ cat testfile
?
 ?)c?I
      P?Meitar:~ meitar$

That garbage you see after the second invocation of cat shows that the file really was trashed, that is, overwritten with garbage data. Now, a simple rm testfile can do the rest of the work.

As always, man srm will give you all the other juicy details.

Written by Meitar

July 31st, 2008 at 4:24 am

Mac OS X Server Tip: Enable user avatars for Apple WikiServer without enabling User Weblogs

2 comments

Today I had the opportunity to toy around with more of Apple’s WikiServer (aka “Teams Server) intranet-building suite of applications. I already gave the wiki feature a pretty thorough treatment, so this time I set my sights on a simple user-specific (as opposed to group-specific) feature.

In my office of approximately twenty-some-odd employees, we’ve just begun using the groups’ blog feature to replace all-staff emails for interesting items that are not business related. This has actually been a huge boon for several reasons, not least of which is the productivity boost we can enjoy thanks to moving from a push system (relatively annoying, if occasionally interesting emails) to a pull system (web browsing, RSS feeds, all generated from the Apple WikiServer group blog). Out of the box, only one feature was missing from the group blog: user profile pictures (“avatars”).

If you only turn on the group wikis and blogs features in Apple’s WikiServer, you’ll find that whenever someone posts a comment to a wiki page or a blog post, a generic profile picture will appear next to their comment. If you give that person’s user account a profile picture in Workgroup Manager, you’ll see that generic profile icon turn into a broken question mark. It turns out that this is because the user profile pictures are served by a completely different web service than the group’s wiki and blog is served so if that server isn’t running none of these images will be served up to the browser.

Fixing that is simple enough: simply turn on the appropriate server—the User Weblog server—by opening Server Admin, navigating to the Web Service settings, and enabling the “Blogs” service for users under your web site, then clicking save. For the default web site (*), all that checkbox technically does is remove the comment in the /etc/apache2/sites/0000_any_80_.conf file that reads:

#        Include /etc/apache2/httpd_users.conf

The /etc/apache2/httpd_users.conf file enables the use of your web site’s /users URL paths. In practice, this means that you’ve now allowed anyone with a user account in your Open Directory database to create a new hosted, personal weblog on your server. This may be what you want, but it wasn’t what I wanted—all I wanted was user profile pictures on the groups features.

As it happens, everything behind the /users URL is actually a completely different web server (really an instance of Twisted Python) that’s accessed via a ProxyPass directive. This turns out to be really handy, because it means we can intercept requests for these URLs and redirect them before they ever get to the Twisted “User Weblog” server.

By examining the source of the wiki page on which a user’s profile picture icon appears, we can see that the URL path to the user’s image is retrieved by accessing a URL that looks like /users/username/icon.jpg (where username is the user’s full Unix username). So, with the following lines of Apache RewriteRule magic, we can enable only the serving of these user profile avatars but not let users create their own personal blogs:

#### We are ONLY using the /etc/apache2/httpd_users.conf file to
#### enable per-user avatar icons sourced from our OpenDirectory
#### user database. So to avoid the messy instance where people
#### create their own blogs we will redirect anything except the
#### image icons themselves to a 403 Forbidden error page.
<IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{REQUEST_URI} ^/users
        RewriteRule !^/users/[A-Za-z]+/icon.jpg [F,L]
</IfModule>

The magic happens in the lines that begin with RewriteCond and RewriteRule. The RewriteCond rule examines the incoming URI and only continues processing if it begins with “/users”. That’s important because the next line, the RewriteRule returns a 403 Forbidden error for any and all requests that do not match a URI that starts out like /users/username/icon.jpg. In other words, without the RewriteCond directive, the entire web site would only be able to serve user profile pictures, and without the RewriteRule, all the URLs of the User Weblog server would be available (such as those to create new personal weblogs).

With both in place, however, I can get exactly what I want out of the Weblog Server. No more and no less.

Written by Meitar

July 25th, 2008 at 9:58 am

One minute Mac tip: Schedule off-hours downloads by enabling `at`, `batch` UNIX job scheduling commands

leave a comment

In a lot of places in the world, many people still have to pay for bandwidth costs. I’m one of those people who just can’t afford to download lots of stuff during peak hours when my bandwidth might quickly get shaped or, worse, I’ll get charged. Nevertheless, there are often plenty of legit reasons to initiate huge downloads.

In these cases, it makes sense to be smart about when I initiate these downloads. Being something of a UNIX-head myself, I wanted to use the age-old at command to download a Linux ISO during off-peak hours, which my ISP says starts at 2 AM. Much to my chagrin, I found that at doesn’t work by default on Mac OS X and, worse, the Leopard man page leads to a dead end (though it didn’t back in Tiger…).

Turns out that the system daemon that is responsible for checking up on at jobs has been wrapped with a launchd job. This makes enabling at on your system really easy:

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

Once you’ve done this, you can now use at as you normally have done. For instance, I could now schedule my downloads to happen during the off-peak hours:

Perseus:Fedora maymay$ at 2:15am tomorrow # now press return
curl -LO http://download.fedoraproject.org/pub/fedora/linux/releases/9/Fedora/x86_64/iso/Fedora-9-x86_64-DVD.iso
# now press CTRL-D.
job 1 at Tue Jul 15 02:15:00 2008
Perseus:Fedora maymay$ atq
1	Tue Jul 15 02:15:00 2008

This is also incredibly handy for scheduling just about any resource-intensive task that you don’t have to do right now. To take it one step further, you can even let the computer itself choose when to run these resource-heavy tasks by using the batch command, which will execute commands much like at but will check the system load average instead of the system clock to determine if it should start the job.

Note that with the com.apple.atrun job loaded /usr/libexec/atrun is started every 30 seconds (unless you change the StartInterval key in the plist file). Since the atrun command checks a file on disk (that it places in the /usr/lib/cron/jobs directory) to see if there is any work to do, this will probably prevent your disks from ever sleeping, which could be a major concern for battery life on portables. Also, obviously, your computer needs to be turned on and awake for the job to actually launch.

For more information, check out the result of typing man at and man launchctl at a Terminal prompt. There’s also a really good Google Tech Talk about Launchd that will teach you a lot more about job scheduling on Mac OS X.

Written by Meitar

July 14th, 2008 at 3:48 am

One minute Mac tip: Auto-complete, spellcheck, and search for definitions in Cocoa text fields

leave a comment

Without doubt, the most common use of computers today is to create written content of some kind. Blogs are an obvious example, but written content can take a number of forms. Writing manuscripts for publication is another example.

No matter what kind of writing you’re doing, using good tools to make your writing technically better is an incredibly handy thing. Letting the computers do the technical stuff—the stuff they’re good at—let’s you focus on the creative stuff: writing great content. Which is why, if you use a Mac, you’ll be happy to hear that any application’s text field let’s you do a number of really cool things (as long as it’s a Cocoa application, of course).

1. Auto-complete unfinished words

Try this out:

  1. Open TextEdit, from your /Applications directory. A new blank document will open.
  2. Type Hel and then press the ESC key. A drop-down menu will suddenly appear with an alphabetically sorted auto-complete list of suggestions, sourced from your computer’s current language dictionary. It looks like this: Mac OS X\'s native Cocoa framework allows for many applications to get \"auto-complete\" functionality for free.

This feature works with both Pages and, for those of you still using it for some reason (I know you’re out there), TextEdit, too. Also, if you’re a developer and a writer as well (like I am), you’ll be happy to hear that this feature also works with Xcode’s Code Sense feature, and suggests completions for variable, function, class, and method names in your code.

2. Spellcheck as you type

A Cocoa text input field also has a number of other tricks up its sleeve. For instance, in many applications you can elect to turn on the “Check spelling as you type” feature, which will cause words you misspell (words not in the computer’s dictionary) to appear with a dotted red underline. If you right-click on these words, the contextual menu that appears will offer spelling corrections.

However, sometimes we use words like those in slang or colloquial language that isn’t in a proper dictionary. These words will still appear to be “misspelled” when you type, so in these cases, we can tell Mac OS X to “Learn Spelling” (also from the contextual menu). When you select this option, you append that spelling to your personal dictionary. (This is really just a plain-text file located at ~/Library/Spelling/lang file, where lang is the language code you’re typing in. For Enlgish, this file is ~/Library/Spelling/en.)

3. Look up word definitions and search for text in Google or Spotlight

Last, but certainly not least, another neat thing you can do with text on your Mac is look them up with Dictionary.app. Simply highlight some selectable text on screen, right-click and select “Look up in Dictionary”. This will cause Dictionary.app to open and display the definition of the selected word.

Since Dictionary.app can also look up articles in Wikipedia, this is also a very quick way to go to a Wikipedia article without ever having to open up a Web browser.

Also, from the very same menu, you can open a Web browser. Simply select “Search in Google” to cause your default Web browser to launch a Google search for the highlighted text.

Written by Meitar

June 28th, 2008 at 5:19 am

One minute Mac tip: Create the illusion that Bonjour works over a VPN

3 comments

If you’re a Mac user who often uses VPN connections, you’ll notice one very disappointing thing about connecting to your corporate or personal network over such tunneled connections: typically, Bonjour-style addresses (such as “computer-name.local”) don’t work. This is because multicast DNS (or mDNS) doesn’t work over a tunnel. Though there are ways to get it functional, they are pretty complicated and require that you have a lot of esoteric networking knowledge.

However, if the services you typically access via Bonjour use static IP addresses, then there is one age-old networking technique you can use to simulate Bonjour-style naming conventions without actually using Bonjour. This, of course, is the /etc/hosts file.

The /etc/hosts is a simple, static, text-based mapping of computer names to IP addresses. It does exactly what Bonjour does except it doesn’t keep itself up to date when things change. Of course, if you’re using static IPs for the services you want access to, you can pretty safely assume that things aren’t going to be changing frequently anyway. Long-time sysadmins will laugh at this, but I say let them laugh. This is remarkably useful and very easy to implement.

Let’s assume I’m running a personal web server on my home network, and I can access my home network via a VPN. On my home network, my web server’s IP address is, say, 192.168.2.100, and I usually access it as http://server.local/. All I need to do is open a Terminal prompt and run the following commands as an administrative user:

sudo echo "192.168.2.100	server.local" >> /etc/hosts

That’s it. What this does is hard-wire the name server.local so that it always resolves to the IP address 192.168.2.100. Now, anytime anything on my computer tries to access server.local, it’ll always access 192.168.2.100 directly instead of ever needing to make an mDNS query on the network. The net effect is that we can trick our computer into thinking that Bonjour is working, even when it’s not—such as over a VPN connection.

Note that in default cases, hard-wiring an IP address like this completely prevents your computer from ever asking other computers (such as DNS servers) what the current IP address for this name is. That means if the IP address of the remote server changes, you won’t be notified, and things will just not work. So be mindful that you’ve made this change, and revert it as a first step in troubleshooting procedures.

By the way, Windows users can do the very same thing simply by editing their etc/hosts. They can find this file at C:\WINDOWS\system32\drivers\etc\hosts and can edit it with Notepad. They will also need to install Bonjour for Windows to get Bonjour working in the first place, of course.

Written by Meitar

June 26th, 2008 at 5:25 am