Correcting Message Order with Courier

Recently I moved some local messages from my machine (previously downloaded with pop3) onto the server so I could use imap. I used Mail.app on Mac OS X 10.5.8 to do this.

For some reason, the messages in this example were uploaded in a way that caused them to be loaded in the wrong order on iOS 5.0.1. Since I run the mailserver myself, I took a look at the message files to see if I could deduce the cause of the issue. I noticed a series of messages on the mail server that looked like this:

1324697191.M91227P15574V000000000000CA00I0004B07D_556.hostname,S=5622:2,S
1324697192.M322096P15574V000000000000CA00I0004B07F_557.hostname,S=225691:2,RS
1324697196.M144018P15574V000000000000CA00I0004B081_558.hostname,S=7702:2,RS
1324697197.M715598P15574V000000000000CA00I0004B083_559.hostname,S=15741:2,S
1324697199.M327587P15574V000000000000CA00I0004B085_560.hostname,S=8744:2,RS

The received times of these messages, in the same order as listed above, are:

01/15/2010
01/09/2009
07/13/2010
02/21/2010
05/06/2010

It turns out that due to the messages in this example having a modification date that doesn’t match their receive timestamp the messages appear in the wrong order on an iOS device, where the mail application assumes the order of the messages it gets from the imap server is already sorted by date. This isn’t a problem with desktop mail clients — they simply fetch all the messages, sort them, and everything is fine. Several google searches on this subject yielded threads where people were trying to get their messages in the correct order and the suggested remedy was “sort them on the client side.”

To fix this, I wrote a perl script script to read the message headers, determine the receive time, and update the file name and modification date to match.

Use the script like this:

perl rename.pl cur/*

When you’re convinced it will do the right thing:

perl rename.pl cur/* --output-dir cur_renamed

After ensuring the rename was correct, I swapped the cur and cur_renamed directories, deleted the courierimapuiddb file, and restarted courier-imap. I also had to quit Mail.app on OS X and delete and read the mail account on the iOS device to get the messages to come in in the correct order.

Posted in General | Tagged , , | Leave a comment

Google Authenticator Backup Woes

TL;DR: Google Authenticator doesn’t backup on iOS; before erasing your old device, make sure to re-configure Google Authenticator on your new one.

I use the Google Authenticator app on iOS for 2-factor authentication into Google’s services. Recently, I was transitioning to a new phone after giving my existing one to my mom for Christmas. I did the standard backup -> restore plan which put most of my settings on my new device without issues. Fortunately, before I erased the old device, I made sure all my apps worked, including the authenticator.

Apparently, the data the authenticator app stores is not backed up for whatever reason, which means that instead of being able to generate the keys needed to access my accounts, the authenticator was prompting me to set up a new account. The smart folks over here recommend taking a screenshot of the QR code Google’s site gives you when you set up 2-factor authentication.

Questions:

To Google: Why doesn’t the authenticator back up its data? Seems this could be a nasty surprise for someone.
To Android users: Does this happen on Android as well?

Posted in General | Tagged , | Leave a comment

Cubic Spline Interpolation

Cubic spline interpolation is a simple way to obtain a smooth curve from a set of discrete points (knots). It has both C1 (first derivative) and C2 (second derivative) continuity, enabling it to produce a continuous piecewise function given a set of data points.

From the algorithm detailed here I have implemented a clamped cubic spline class in C++. It is templated on the type of X and Y, allowing for use of scalar or vector types. It requires only that X and Y define the operators +, -, *, and /, and that Y have a constructor that takes a single scalar argument, initializing all elements to the supplied value.

Usage is very simple. For example, to interpolate a 2D location over time, try this:

#import "glm.hpp"
#import <vector>

std::vector<float> times;
std::vector<glm::vec2> points;
times.push_back(0);
points.push_back(glm::vec2(0));
times.push_back(.5f);
points.push_back(glm::vec2(-303, -572));
times.push_back(1);
points.push_back(glm::vec2(-250, -980));

/* Create the spline interpolating the position over time */
Spline<float, glm::vec2> sp(times, points);

/* Compute the interpolated position at time 0.75f */
glm::vec2 value(sp[.75f]);

The code for the spline class is below:

Continue reading

Posted in Programming | Tagged , , , , | Leave a comment

Houses in Minecraft

So I’ve been playing Minecraft, focusing mainly on the creative aspect, although I play the new Beta client and run my own server locally so I get the features added post-classic. I’ve turned off monster spawning and set the difficulty to Peaceful, so I can focus on bringing creations to life instead of running from scary monsters in the night.

The first time I played with monsters, I found the sound of a zombie’s “murrrrrrrr” in a dark, endless cavern to be frightening enough that I never wanted to hear it again. /shivers.

I find the first-person building experience to be very satisfying to the OCD urge within me that wants to make everything right. As all blocks are destroyable (with the exception of Bedrock), any reality can be created given enough time. I’m fond of using the different kinds of blocks to vary the aesthetics — even if the blocks type is not practical.

My favorite activity is to visualize my buildings at night, as I find the lighting of torches, lava, and glowstone to create a very pleasing effect. I also make frequent use of glass to provide a sense of openness and to allow light to mix between areas.

Here’s some screenshots of a large house on top of a hill that I’ve been working on.

The master bedroom

The spacious master bedroom.

Continue reading

Posted in Programming | Tagged , , | 2 Comments

Time Machine Exclusions – Snow Leopard

A bit late, but here’s an update of the Time Machine exclusion list for Snow Leopard. Continue reading

Posted in Leopard | Tagged , | Leave a comment

NSCopying and Mutability

In the Cocoa frameworks, it is common to find mutable and immutable versions of classes that store data, such as strings, dictionaries, and arrays. Most of these classes also implement the NSCopying informal protocol, and those with mutable varients implement the NSMutableCopying protocol. These protocols specify methods for obtaining immutable and mutable copies of an object. These copying methods should be implemented such that the copy can return an instance of a subclass, to allow for subclasses to copy their specific instance variables.

There are situations, however, that can result in the inability of a subclass to do so. Consider NSURLRequest:

@interface NSURLRequest : NSObject <NSCoding, NSCopying, NSMutableCopying>

An immutable class, but one that implements NSMutableCopying, it responds directly to the -mutableCopyWithZone:(NSZone *)zone method that returns a mutable url request, an instance of NSMutableURLRequest. While this isn’t a problem in itself, it becomes an issue when this method is not re-implemented in NSMutableURLRequest.

– Nope: Implement the NSMutableCopying protocol only in your immutable class.

The implementation of -mutableCopyWithZone:(NSZone *)zone in the immutable class must certainly hard-code the name of the mutable class — it cannot be aware of any external subclasses of the mutable class. This means that asking for a mutable copy of the immutable class creates an instance of the known mutable subclass. Consider the following example:

@interface MyMutableURLRequest : NSMutableURLRequest {} @end

MyMutableURLRequest *request = [MyMutableURLRequest requestWithURL:url];
request = [request mutableCopy];

In this case, the object returned from -mutableCopy will be an instance of NSMutableURLRequest instead of the expected MyMutableURLRequest.

– Nope: Hardcode class names in -copyWithZone: and -mutableCopyWithZone:

Hardcoding class names serves to block subclassers from subclassing the copy methods without dirty hacks.

+ Yup: [Re]Implement the NSMutableCopying protocol in your mutable class.

By doing this, the class name doesn’t have to be hard-coded (in the mutable class), and so a subclasser can simply call [super mutableCopy] and then copy their specific instance variables.

+ Yup: Use [self class] in -copyWithZone: and -mutableCopyWithZone:

By using [self class], an object of the subclass type will be allocated.

Posted in Cocoa Yups and Nopes | Tagged , , , | 1 Comment

Readable If Statements

To kick of the Coding Yups and Nopes section, I’ll start with something simple. There are a set of things to do, and a set of things to avoid. For each thing, there are one or more reasons justifying its classification. These reasons are ordered by descending importance and increasing subjectivity.

– Nope:

if (condition) doWork();
else doOtherWork();
  • If you’re stepping through with a debugger (I used gdb), it is difficult to tell when stepping over the line if the statement is executed. To do so you must determine the value of condition, or determine if the function was called based on its side effects.
  • If you add an additional statement to the false case, it’s possible that braces may be forgotten, leading to incorrect operation.
  • Assuming the reason for putting both condition and statement on one line was to use less lines, the benefits of this are negated by the decreased readability of such a statement. By putting both condition and statement on one line, searching for a specific condition becomes more difficult.
  • Assuming other parts of your code are scoped and indented, this breaks that pattern.
if (condition) {
    doWork();
} else doOtherWork();
  • Similar to the above case. Basically this is inconsistent and has none of the advantages of either method.
if(condition){
    doWork();
}
  • This is a pure spacing issue. if is not a function, please do not call it as one. Also, that brace is squashed against that parentheses, give it some room! Skimping on spacing issues like this while writing makes it harder to read later.

+ Yup:

if (condition) {
    doWork();
} else {
    doOtherWork();
}
  • The perfect if-else statement. Well spaced, condition and statement on separate lines.
if (error) return;
if (error) break;
if (error) continue;
  • When used only for error/early exit conditions, these help to condense code so that the reader can quickly get to the meat of a function.
  • The statements and the condition are on one line because I do not consider the flow control statements return, break, and continue to contribute useful work, such that it should be scoped in braces and on its own line.
Posted in Coding Yups and Nopes | Tagged , , , , | Leave a comment

Window Resizing on Resolution Change

This post kicks off the “App Yups and Nopes” section in which I’ll post both good and bad things I see applications doing. This differs from the other Yups and Nopes sections in that it talkes specifically about observed application behavior. My intent is to show why a specific behavior is undesirable, then present a solution.

In this situation, I connect my laptop to a projector to watch a movie. My screen resolution changes to match that of the projector. I see applications with the following behaviors:

– Nope: Resize application windows to fit on screen, regardless of window or application visibility.

The goal of resizing an application window on screen resolution change is to make sure the window is placed so that the user is able to manipulate it (move and resize.) An application is only required to resize and reposition windows that are actually visible. If a window is offscreen or the application is hidden, the window size and position should not be modified. When an offscreen window or a window of a hidden application is modified in this way, useless computation results. If the window cannot be seen, what use is there in constraining its bounds?

+ Yup: Resize application windows as they are made visible, making only the smallest change necessary to satisfy visibility and interaction requirements.

A common trick I use before connecting an external monitor of smaller resolution is to hide all applications — for most applications this prevents their window state from being altered. In this way when I have finished using the projector, I can unhide these applications and continue using them with a window state identical to before the resolution change. This works great for applications that implement correct window resizing behavior. Most Cocoa applications do this correctly by default. Noted offenders are iTunes and iPhoto, both of which require me to pointlessly resize their windows after the resolution is restored.

Note also that only the height must be constrained to the visible screen height — windows are allowed to be wider than the screen. Furthermore, it is not necessary to reposition the window such that its entire contents are visible — windows can hang off the edge of the screen on the left and right sides. This, of course, becomes more complicated when multiple displays are attached as these restrictions change.

Posted in App Yups and Nopes | Leave a comment

Regression: Adobe CS4

So I was talking with my friends a while back, deep into one of my frequent rants about ineptitude in the software industry, when it struck me that I should start blogging this stuff. Also, my friends pointed out that the manner in which I deliver my criticism is particularly funny, and that I should post audio clips of this to accompany the rant.

I’ve decided to start a new section on this site devoted to these rants. The section is called “Regressions” and will contain my rants on various software issues that have been solved correctly before but, for some reason, are (still) present in some piece of software. These rants are a bit harsh: I’m trying to write it how I spit it when I get in the mood, and so if you find intense criticism and profanity offensive, I suggest you stop reading.

So, lets kick this bitch off with Adobe’s Creative Suite 4!

First, the installer is called “Setup.” On a Mac. See guys, on the Mac, we name things after what they really are. The correct name for this application is “Adobe CS4 Installer.” “Setup” is a) Windows-esque and b) useless for determining what this thing actually installs. Consider this regression #1.

Not only is the installer misnamed, but it’s in a folder with some other files. On the disk you see a folder with an icon that looks vaguely archive-like called “Adobe CS4 Master Collection.” I assumed this was the installer; what else would you put on the disk? Instead of the installer, however I see another Finder window open with 6 files: Bootstrapper.dmg, deployment, extensions, payloads, resources, Setup. What is all this crap? I just wanna install the apps dude, I don’t care about any of this junk.

After prompting for a password, the installer then proceeds to open a copy of the installer app running as root. This then makes another couple of child processes, which do something for a bit. Despite Apple’s consistent recommendation for and implementation of installers that use privilege-escalated tools only for the actual file copying portion, it seems that this part is too hard for Adobe, so they just launch the entire installer(s) as root. Nice job guys! Lets hope there’s no security flaws in your installer :) Regression #2.

I then get a dialog about some applications that need to be closed for installation. Photoshop of course is on there duh, so I close that. But what the fuck? Safari and Excel? What does that have to do with Adobe products? Presumably, Adobe thinks that because it can install its horrible PDF plugin for Safari and Office programs, you need to close these programs before you can install! Of course I don’t actually use these plugins because this is Mac OS X, where the graphics subsystem has had PDF support for 7 fucking years, and neither does anyone else who hasn’t been living under a rock. Regression #3.

Finally I get to the list of applications to install. I choose a custom install to see what there is and damn. That’s a LOT of crap to install. And fucking huge too! Acrobat 9 Pro is 1.2GB. How on earth you manage to make a PDF editor that big I have no idea, but clearly the folks at Adobe are good at it. Fortunately, Photoshop, which is about 2000 times more awesome and useful, is about half the size. Clearly Acrobat 9 has some absolutely AMAZING features that warrant this ridiculously huge installation size. Perhaps we should all aspire to make excessively large applications. Regression #4.

So I select some of these components and click install. The install finishes and I check my Applications folder to see the new apps. Wow. There’s a folder for each of the apps I wanted, of course, but there’s also a folder for some of the apps I didn’t want, containing an application container with nothing in it. Clearly along the packaging process Adobe thought that littering my hard drive with crap was acceptable. Regression #5.

You would think a big company like Adobe with a Mac userbase that is (or was) a significant portion of their customer base would be able to put more effort into their presentation, but perhaps to a big company these things are not such critical issues. With no serious competitor to Photoshop, customers are likely to overlook issues like these, if only because they have to.

[Note: Apologies if this seems a bit old -- I wrote it several months ago and completely forgot about it until today]

Posted in Regressions | 1 Comment

Units of mach_absolute_time()

As programmers on OS X are well aware, the units of mach_absolute_time() have been nanoseconds since 10.2, although this was only documented since 10.5. As the iPhone runs a slimmed down version of OS X, I thought it reasonable that the units would remain the same on the device.

[Update] As Justin points out below, this was never the case. A complete misread of the documentation on my part. I managed to work on only machines for which the units of mach_absolute_time() were nanoseconds.

So if you’re trying to get some timing from the iPhone using mach_absolute_time() and seeing times that indicate faster results on the iPhone, (not that this happened to me…), make sure to account for the difference in timebase.

Here’s the code for conversion between the mach_absolute_time() units and nanoseconds:

#include <mach/mach_time.h>

/* Get the timebase info */
mach_timebase_info_data_t info;
mach_timebase_info(&info);

uint64_t start = mach_absolute_time();

/* Do some code */

uint64_t duration = mach_absolute_time() - start;

/* Convert to nanoseconds */
duration *= info.numer;
duration /= info.denom;

/* Log the time */
NSLog(@"My amazing code took %lld nanoseconds!", duration);
Posted in Programming | 8 Comments