Skip to content

Posts from the ‘Technology’ Category

26
Oct

Original Inspiration for the iPhone Maps Application

I am 100% sure that this Dilbert comic from 1990 was Steve Jobs’ original inspiration for creating the iPhone with its famous Maps application:

Dilbert from May 10, 1990

You knew that Dilbert was over 21 years old, right? (I didn’t. :)

21
Oct

How to Launch a Privileged Process on OS X

For security reasons, Apple recommends that GUI applications should never run with the privileges of the root user. GUI applications normally load several types of plugins and input managers automatically. If a malicious plugin was installed then it could cause security problems when the privileged application was launched.

In addition, system services that run with the privileges of the root user (such as launch daemons) need to avoid using certain technology frameworks provided by Apple. These frameworks are not safe to use in a service that runs with the privileges of the root user.

If you need your GUI application to do something that requires root privileges, Apple recommends you split your application into two parts. First, create a GUI that runs as a normal user. Then when you need to do something with root privileges, you launch a separate helper process or tool. Splitting your application avoids security holes while keeping things very easy for your users.

Two Steps

Launching a privileged process is done in two steps:

1) Request authorization. The operating system will ask the user for permission to run a privileged process. The user will need to enter an administrator’s username and password.

#import <Security/Security.h>

OSStatus PreauthorizePrivilegedProcess(AuthorizationRef *authRef) {
    AuthorizationItem item = { kAuthorizationRightExecute, 0, NULL, 0 };
    AuthorizationRights rights = { 1, &item };
    AuthorizationFlags flags = kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize;
    return AuthorizationCreate(&rights, kAuthorizationEmptyEnvironment, flags, authRef);
}

2) Launch the process. If the user authenticates correctly, you can use the authorization reference created above to launch the helper process.

OSStatus LaunchPreauthorizedProcess(AuthorizationRef *authRef, NSString *path) {
    OSStatus status = AuthorizationExecuteWithPrivileges(*authRef, [path UTF8String], kAuthorizationFlagDefaults, NULL, NULL);
    AuthorizationFree(*authRef, kAuthorizationFlagDestroyRights);
    return status;
}

Please note that the authorization reference created in the first function is released in the second function. If you want to launch several privileged processes in a short amount of time, you can comment out this line and and release the reference on your own afterwards.

Some of Apple’s sample code (and other examples) has an extra step where they copy the authorization reference. This is only necessary if you have a previously created authorization reference that you want to add elevated privileges to.

Just One Step

If you don’t need to update your GUI between these two steps, then both actions can be combined into one step.

#import <Security/Security.h>

OSStatus LaunchPrivilegedProcess(NSString *path) {
    AuthorizationRef authRef;
    OSStatus status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authRef);
    if (status == errAuthorizationSuccess) {
        status = AuthorizationExecuteWithPrivileges(authRef, [path UTF8String], kAuthorizationFlagDefaults, NULL, NULL);
        AuthorizationFree(authRef, kAuthorizationFlagDestroyRights);
    }
    return status;
}

I consider this code to be in the public domain. Please feel free to copy and paste. And let me know if you find any problems or have suggestions.

4
Aug

How To Type Curly Quotes In Mac OS X

Mac OS X has an easy way to type “curly” quotes and apostrophes instead of "straight" versions. I used both versions in that sentence to show the difference. Here is a bigger version to make the distinction more visible:

Many people think “curly” quotes look better than "straight" ones.

You can use the following keyboard shortcuts to type a single or double curly quote:

  1. Single quote open (‘) — option ]
  2. Single quote close (’) — shift option ]
  3. Double quote open (“) — option [
  4. Double quote close (”) — shift option [

However, I think it makes more sense to use [ and ] for open and close versions instead of the shift key. I found myself constant typing “mismatched‘ quotes. I also wanted to use the shift key for double quotes since that’s how the normal keyboard button works.

  1. Single quote open (‘) — option [
  2. Single quote close (’) — option ]
  3. Double quote open (“) — option shift [
  4. Double quote close (”) — option shift ]

Since OS X supports custom key bindings, I looked for a way to fix this. The trick is to create a file called DefaultKeyBinding.dict in the KeyBindings folder inside your Library folder. You can use this file to override the default key bindings for most applications.

Here are my changes. Please feel free to copy the settings below and save them to your own computer. You may need to create the KeyBindings folder if it isn’t already there.

/*
 Updates Apple's default keybindings for curly quotes.
 See http://www.danandcheryl.com/2010/08/how-to-type-curly-quotes-in-mac-os-x

 Save this file here:
 /Users/<name>/Library/KeyBindings/DefaultKeyBinding.dict
*/
{
    "~[" = ("insertText:", "‘");
    "~]" = ("insertText:", "’");
    "~{" = ("insertText:", "“");
    "~}" = ("insertText:", "”");
}
28
Jun

How to Check the System Idle Time Using Cocoa

UPDATE: Aleksandar Sabo wrote a brief explanation of how this code works.

There is sample code on the Internet for programmatically checking the system idle time using IOKit and Cocoa (see here, for example). However, most of the examples seem overly long (see Paul Graham’s Succinctness is Power). The code below works in Tiger/10.4 and later and is about as concise as I can make it while still handling errors properly.

#include <IOKit/IOKitLib.h>

/**
 Returns the number of seconds the machine has been idle or -1 if an error occurs.
 The code is compatible with Tiger/10.4 and later (but not iOS).
 */
int64_t SystemIdleTime(void) {
    int64_t idlesecs = -1;
    io_iterator_t iter = 0;
    if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iter) == KERN_SUCCESS) {
        io_registry_entry_t entry = IOIteratorNext(iter);
        if (entry) {
            CFMutableDictionaryRef dict = NULL;
            if (IORegistryEntryCreateCFProperties(entry, &dict, kCFAllocatorDefault, 0) == KERN_SUCCESS) {
                CFNumberRef obj = CFDictionaryGetValue(dict, CFSTR("HIDIdleTime"));
                if (obj) {
                    int64_t nanoseconds = 0;
                    if (CFNumberGetValue(obj, kCFNumberSInt64Type, &nanoseconds)) {
                        idlesecs = (nanoseconds >> 30); // Divide by 10^9 to convert from nanoseconds to seconds.
                    }
                }
                CFRelease(dict);
            }
            IOObjectRelease(entry);
        }
        IOObjectRelease(iter);
    }
    return idlesecs;
}    

I consider this code to be in the public domain. Please feel free to copy and paste. And let me know if you find any problems or have suggestions.

18
May

How to Print a PDF File Using Cocoa

UPDATE 2014-03-13: @robwithhair created a command-line tool for printing PDF files based on this code which shows some additional options.

Mac OS X is well known for its great support for PDF files. You can create a PDF file from anything you can print. I thought that using Apple’s PDFKit framework would make it easy to program a way to print an existing PDF file. That turned out not to be the case.

Sending a file to a printer using the lp command is easy. However, this approach does not work for PDF files formatted for landscape printing. You can specify landscape orientation, but I wanted a way to detect the orientation automatically.

PDFKit has a PDFView object that has a printWithInfo:autoRotate: method. However, adding a PDFDocument to a PDFView and telling it to print doesn’t work. I eventually stumbled onto the fact that PDFDocumenthas a secret method that makes printing easy. So here is the code:

#import <Quartz/Quartz.h>

- (void)printPDF:(NSURL *)fileURL {

    // Create the print settings.
    NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
    [printInfo setTopMargin:0.0];
    [printInfo setBottomMargin:0.0];
    [printInfo setLeftMargin:0.0];
    [printInfo setRightMargin:0.0];
    [printInfo setHorizontalPagination:NSFitPagination];
    [printInfo setVerticalPagination:NSFitPagination];

    // Create the document reference.
    PDFDocument *pdfDocument = [[[PDFDocument alloc] initWithURL:fileURL] autorelease];

    // Invoke private method.
    // NOTE: Use NSInvocation because one argument is a BOOL type. Alternately, you could declare the method in a category and just call it.
    BOOL autoRotate = YES;
    NSMethodSignature *signature = [PDFDocument instanceMethodSignatureForSelector:@selector(getPrintOperationForPrintInfo:autoRotate:)];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    [invocation setSelector:@selector(getPrintOperationForPrintInfo:autoRotate:)];
    [invocation setArgument:&printInfo atIndex:2];
    [invocation setArgument:&autoRotate atIndex:3];
    [invocation invokeWithTarget:pdfDocument];

    // Grab the returned print operation.
    NSPrintOperation *op = nil;
    [invocation getReturnValue:&op];

    // Run the print operation without showing any dialogs.
    [op setShowsPrintPanel:NO];
    [op setShowsProgressPanel:NO];
    [op runOperation];
}

I consider this code to be in the public domain. Please feel free to copy and paste. And let me know if you find any problems or have suggestions.

21
Dec

The New and Improved Mozy for Mac 1.6

Of course, it can’t really be both new and improved. Logically, it has to be one or the other. It’s just that I’m excited about the 1.6 release of Mozy’s Mac client. It was finished last week and the response has been very positive.

It seems that with #Mozy for #Mac 1.6 it’s finally reliable. Awesome! — @donut2d

Latest Mozy update (1.6) on Mac OS X is a major improvement – it actually works, and doesn’t suck out all of your RAM. — @mmetcalfe

Our last few releases, while making improvements in many areas, seemed to have lingering and subtle problems. With the 1.6 version, we hope to have finally put them behind us.

We turned on auto-update today. If Mozy hasn’t updated itself yet, please feel free to grab the latest version of MozyHome (or MozyPro) and let us know what you think.

Official List of Changes

You can see the official list at the pages linked above. Mozy only makes the list of changes available for the current release, so I’ve copied them here for the future. You can see the changes in Mozy for Mac 1.4 and Mozy for Mac 1.5 too.

Enhancements

  • Removed dependency on Spotlight since Spotlight queries are unreliable under certain circumstances
  • Changes to backup selections are now saved automatically
  • Reduced memory usage
  • Decrease size of SupportFiles.zip file
  • Improved the performance of the Configuration window
  • Improved support for Snow Leopard and fixed issues caused by Snow Leopard’s 64-bit architecture
  • Improved interaction between Mozy’s preferences and Snow Leopard; Mozy’s preferences no longer require System Preferences to be re-started
  • Improved the use of temporary files
  • Improved reports in Admin Console for Pro users
  • Improved support of our external drive feature by addressing edge cases that can cause stability issues
  • Improved feedback when setting a preference to an invalid value
  • Improved error handling when an auto-update fails to download successfully
  • Added support for nine non-English languages
  • Added the ability to delete a Backup Set using the keyboard
  • Added the ability to undo and redo configuration changes
  • Added the ability to sort Backup Sets by file count or total size
  • Added history information to main Configuration window
  • Added “Install updates automatically” checkbox to dialog which prompts user to upgrade
  • Added ability to manually check for an update
  • Added ability to back up network drives using the NFS protocol for Pro users

Bug Fixes

  • Fixed issues which caused the “Show status in menu bar” preference to not work properly
  • Fixed the link in the Readme file for downloading the software
  • Fixed a computer name display issue in the Setup Assistant
  • Fixed an issue causing the Configuration window to crash when browsing a folder with lots of files
  • Fixed an issue which caused the file exclusion warning to not show up properly
  • Fixed an issue which caused network connection errors
  • Fixed an issue which caused several duplicate warning dialogs to appear
  • Fixed an issue which prevented the use of certain non-Roman characters in a password
  • Fixed an issue which caused a file to be accidentally excluded
  • Fixed an issue which caused the Backup Set Editor to display the wrong file size
  • Fixed an issue which caused files to be re-uploaded unnecessarily
  • Fixed an issue which caused files in Trash to be backed up

Languages

One of the two major changes in this release is support for nine languages in addition to American English:

  1. German
  2. Greek
  3. British English
  4. Castillian Spanish
  5. French
  6. Italian
  7. Dutch
  8. Portuguese
  9. Slovenian

If you have chosen one of those languages in System Preferences, Mozy will use it automatically. No assembly required. If you find spots where the translation doesn’t make sense, please let us know.

File Scanning

The other major change — the one I’m most excited about — is the new file scanning engine. This is how Mozy finds all your files and decides which ones to back up.

In the past, we’ve depended on Spotlight, Apple’s file scanning feature in OS X, for about half of our scanning. Backup Sets that searched for files of a certain type used Spotlight. Backup Sets that matched a folder (and selections made in the Files & Folders tab) scanned the hard drive directly. We kept finding that Spotlight returned inconsistent results in some cases. So we decided to stop using it.

While we were making the change, we simplified how things work and made everything but the initial scan much, much faster. Mozy now uses far less memory, even when backing up millions of files. There are still some improvements we want to make, but the new file scanning engine makes Mozy feel rock solid.

Conclusion

If you’ve gotten this far, thanks for reading. Please feel free to drop me a note (dan at mozy dot com) with any comments or suggestions. Oh, and Mozy for Mac 1.6 has two new easter eggs. :-)

If you’re new to Mozy, you can try our 2GB-for-free, no-strings-attached version here.

9
Dec

How to Optimize WordPress, Part 2

My last post on how to optimize WordPress covered some general optimization techniques to speed up a website. Reducing HTTP requests, removing wasteful plugins and decreasing file sizes helped quite a bit. Now it’s time to try out page caching.

If you remember, the five things that normally occur for each page are:

  1. Initialize PHP
  2. Query the database
  3. Create the page
  4. Send the page
  5. Send additional files

Page caching plugins, like Hyper Cache and W3 Total Cache, eliminate steps two and three, except when creating a page the first time. WP Super Cache also cuts out step one.

All of the plugins were fairly easy to install. And I discovered during my tests that WP Super Cache, at least at Nearly Free Speech.NET, works just fine with safe mode on.

This graph shows the time it took to load my home page with each of the caching plugins enabled. I have circled the point where I first turned on page caching.

Graph showing response times with various caching plugs

Hyper Cache and WP Super Cache both performed well. W3 Total Cache seemed to struggle. It does more than page caching, like reformatting files to save space, but clearly slowed things down.

WP Super Cache has a few advantages over Hyper Cache:

  1. It supports browser caching better
  2. It doesn’t need to load PHP
  3. It checks for security problems and suggests fixes

So I am now a happy WP Super Cache user.

UPDATE Dec 2009:

After a few days, I started having issues with WP Super Cache and switched back to Hyper Cache. You can see how the irregularities went away. I’ve been using Hyper Cache for almost a week now, and things have remained stable.

Graph of WP Super Cache irregularities that were solved by changing back to Hyper Cache

After being contacted by the author of the W3 Total Cache plugin, I’ve agreed to give it another try. I turned off all the settings except for “disk enhanced” page caching. I’ll update the article again in a few days.

UPDATE Jan 2010:

After looking into things a bit more, my results are still showing Hyper Cache to be faster than W3 Total Cache. However, when I test using the curl command line tool from home, it seems that both plugins are about the same speed. My web hosting company uses a network-level reverse proxy and a few other caching tricks that eliminate the need for some of the features provided by these types of plugins. I’m not sure what’s going on here, but will be sticking with Hyper Cache for now since it appears to work better with my particular situation.

I do like that W3 Total Cache handles page compression properly. I could not get page compression to work with Hyper Cache and had to turn it off. I’d recommend you try all three plugins and measure which works best for you.

UPDATE Apr 2010:

I’ve been having some troubles with Hyper Cache recently. Page redirects were working properly in Firefox, but not in Safari. I tried a new caching plugin I hadn’t heard of before: Quick Cache. Redirects are now working in both browsers. After a week of using Quick Cache, it’s performance is very good. I’ve decided to stick with it.

27
Nov

How to Optimize WordPress

Having lived with WordPress for 8 months, I decided to see if I could improve the performance of my website. There are lots of things to fix.

For each page of my website, WordPress normally does the following:

  1. Initialize PHP, which is the programming language WordPress is written in.
  2. Read information out of the database.
  3. Translate the information into HTML.
  4. Send the HTML to the web browser.
  5. Send additional files needed to view the page.

One major cause of WordPress slowness is #2. Reading all that information can take several seconds per page. I installed a plugin called DB Cache Reloaded to help figure out what was going on. If you view the source of my home page, you’ll see something like the following:

<!– 1.549 seconds, 30 uncached queries, 0 cached queries, 10.76MB memory used –>

This tells me that there are 30 database queries just to show my home page. That’s a lot of slowness. You can also see how many seconds it took to generate the page, which is how long #2 plus #3 took.

The DB Cache Reloaded plugin works by remembering the result of each database query and, in the future, using the previous result instead of re-reading it from the database. With this turned on, about 2/3rds of the database queries are avoided.

<!– 1.236 seconds, 10 uncached queries, 20 cached queries, 10.76MB memory used –>

I also discovered that the KB Robots plugin makes a database query for every page on my site. Wasteful. Since my robots.txt file is simple, I removed the plugin and just created the file myself. One less query.

To speed up #3, I explored the idea of using a plugin to cache whole HTML pages. The most popular seem to be WP Super Cache, Hyper Cache and W3 Total Cache. Since none of them work WP Super Cache does not work when PHP is running in safe mode, I’m going to try them another time. But the performance improvement should be big because, these plugins allow me to skip #2 and #3. WP Super Cache will also skip #1.

Another point of improvement is reducing the number of things a browser has to download in order to show my site (#4). Most browsers will first download the page itself. Then if additional files are needed, such as pictures, style sheets or scripts, it will download them two at a time. When there are a lot of extra files, the overhead of downloading them can add up quickly. A caching plugin will not help out here.

Though I really liked my original WordPress theme, called Panorama, it uses a lot of extra files. They aren’t very big, but when downloaded two at a time they slow things down quite a bit.

Using a web page analyizer, I investigated how much work a browser has to do to download the files needed to display my website. The following table highlights the differences between my old theme and my new one, Titan, which uses about half the number of files (10 vs 22).

Panorama     Titan
HTML11
HTML Images52
CSS Images82
Scripts53
CSS imports32
Frames00
HTTP Requests2210
Size (KB)266240
DB Queries3032


Eliminating those small files (or combining several into one) makes a measurable difference. On the day I was testing, the average time to download my page dropped from four seconds down to two.

However, notice that the number of database queries is higher now. I believe this is because of all the options the Titan theme makes available. There were originally 35 queries, but Titan includes analytics, a box in the sidebar, and a category listing in the footer. So by using the theme options instead of separate plugins for each of those things, I was able to save 3 queries. And despite the small increase in database queries, my site still feels much faster.

One last thing I tried is removing some widgets from my sidebar. I put in a new archives section, using years instead of months, that I maintain manually. I will have to update it once each year, but it reduced the size of the page slightly and eliminated a database query. Lots of small and simple improvements can really add up.

Each of my remaining sidebar sections — Popular, Recent and Random — take about a fifth of the total time to create the page (#3). Taking them out would speed things up. But I like having them to help people find other articles to read they might find interesting.

The last point to mention is the plugin I use to find related posts. I really like having these suggestions for further reading. However, most of these types of plugins are really slow because they calculate “relatedness” each time a page is loaded. Wasteful.

I’ve found one that pre-calculates related pages every time an article is created or edited, but it is based on tags rather than the full article content. And I haven’t been tagging things. I tried some auto-tagging plugins, but could not find one that seemed to work well. So until I can get around to tagging all my articles, I’ll have to wait on that.

Overall, I am pleased with the results so far. I’m going back to tag my articles so that I can try out the new related posts plugin. Then I’m going to see about turning off PHP’s safe mode and turning on page caching.

UPDATE: I’ve written a Part 2 about my experience with caching plugins. You can read it here.

2
Oct

How to Neglect a Product to Death

My friend and former co-worker Matt Ryan recently commented on the impending death of Novell Forge. A message on the Novell Forge site confirms that Novell will be shutting things down soon. I can corroborate some of Matt’s story as I was on the Forge team for about a year during its heyday.

But what really interests me about the situation are the implied instructions on how to neglect a successful product into a slow death that can be blamed on the product itself.

  1. Avoid rewarding or recognizing any of the people involved. Even better, reward someone else.
  2. Do not feed its success. Withhold funding, staffing and career growth opportunities.
  3. Provide poor support. Delay fixing problems.
  4. Set unrealistic goals and expectations. Blame the product or team for failure.
  5. Find excuses to kill the project. Focus on the negative in all meetings with executives.

This was a particular worry at Mozy when it was acquired by EMC. They promised that EMC did not want to be the lumbering elephant that accidentally squashed its shiny new purchase. And it was true. But we worried about accidental squashing anyway.

It has been two years, and I have seen projects and executives come and go. Though I do not believe it was intentional, at times it felt like Mozy was being neglected. But the core of Mozy has remained strong and continues to grow.

Based on my experience, here is what to do to keep a successful product moving forward:

  1. Execute anyway. Deliver a quality product in the face of neglect.

There is precious little a neglected production team can do other than produce. I heard something once I have always remembered: nothing succeeds like success. It is much harder to produce in the face of neglect, but it is also nearly impossible to ignore or argue with.

Mozy is clearly not perfect, but despite occasional neglect it continues to provides a valuable, profitable service. Working with smart people helps. Working for smart people helps. Working with people you like helps. Working on something you care about helps. Working with cool technology helps. But over time, delivering a useful, profitable product is what matters.