Monday, May 2, 2011

Enable tab completion for Mac OS X SSH client

I was befuddled recently when trying to get tab-completion for file and directory names working using the Mac OS X standard ssh client.  up-arrow didn't work either for scrolling through previous shell commands.

I asked a friend about this and he found this post which solved my issue.  If using 'bash' as the shell in the ssh session the tab and arrow keys functioned as expected.

What I did:

1) check /etc/passwd to see which shell I was using on the remote Linux system (cat /etc/passwd). It was /bin/sh
2) checked to see what /bin/sh was (ln -l /bin/sh). It was a link to 'dash'.
3) changed my entry in /etc/passwd to use /bin/bash (I used vi)
4) logged out/back in (not sure if that was required) and my tab and arrow keys worked as expected

 Update
I found that the proper way to do this is to use 'chsh' (change shell):

chsh -s /bin/bash <username>

Friday, April 29, 2011

RFC 3339 dates and iOS parsing

I am currently developing an iPad client for a Java-based Web app that uses JAX-RS for the Web interface (Jersey is the implementation of JAX-RS being used).

I ran into an interesting problem yesterday regarding the parsing of RFC 3339 dates (example - 2011-04-28T16:28:03.065-07:00) in iOS.  Apple nicely documents how to parse RFC 3339 dates, but leaves out one detail.

There is an issue with the timezone containing the colon ':' character. The character must be removed for the RFC 3339 date to be able to be parsed into an NSDate instance.  I spent some time until I found this as a comment in a date parsing class.  Removing the colon from the timezone portion (i.e. 2011-04-28T16:28:03.065-0700) allows NSDateFormatter to parse the textual representation of the date into an NSDate instance.

I also ran into a cute issue: sometimes the fractional seconds aren't included, most likely because the value is 0.  I had to use two NSDateFormatter instances, one using 'yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSZ' the other 'yyyy'-'MM'-'dd'T'HH':'mm':'ssZ' for the date without milliseconds.

Here is the final version of the code to parse RFC 3339 date text into an NSDate instance.

    NSMutableString* dateString = [rfc3339DateTimeString mutableCopy];
    NSRange range = [dateString rangeOfString:@":" options:NSBackwardsSearch];
    if (range.location != NSNotFound) {
        // remove the last ':'
        [dateString deleteCharactersInRange:range];
    }
   
    // Convert the RFC 3339 date time string to an NSDate.
    static NSDateFormatter* rfc3339DateFormatter1 = nil;
    static NSDateFormatter* rfc3339DateFormatter2 = nil;
    if (rfc3339DateFormatter1 == nil) {
        rfc3339DateFormatter1 = [[NSDateFormatter alloc] init];
        NSLocale* enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
        [rfc3339DateFormatter1 setLocale:enUSPOSIXLocale];
        [rfc3339DateFormatter1 setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSZ"];
        [rfc3339DateFormatter1 setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

        rfc3339DateFormatter2 = [[NSDateFormatter alloc] init];
        [rfc3339DateFormatter2 setLocale:enUSPOSIXLocale];
        [rfc3339DateFormatter2 setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"];
        [rfc3339DateFormatter2 setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

        [enUSPOSIXLocale release];
    }
   
    NSDate* date = [rfc3339DateFormatter1 dateFromString:dateString];
    if (date == nil) {
        date = [rfc3339DateFormatter2 dateFromString:dateString];
    }
   
    return date;

Tuesday, April 26, 2011

Upgrade of MySQL 5.1 to 5.5 on Mac OS X

I recently upgraded my existing MySQL 5.1 instance to 5.5 on my Mac (Mac OS X 10.6.7).  On my first try MySQL would not start after the upgrade.  I received the error '/usr/local/mysql/bin/mysqld: Table 'mysql.plugin' doesn't exist'.

After some Web searching I found that I had run into the same exact issues identified by this MySQL bug.  The last comment was the key to my being able to successfully upgrade MySQL: use the my.cnf template files distributed with the MySQL 5.5 version.

I've upgraded twice, just to make sure the solution worked.  Here is what I did:

1) shutdown the MySQL 5.1 instance: sudo /Library/StartupItems/MySQLCOM/MySQLCOM stop
2) rename the existing my.cnf file (one may not exist): sudo mv /etc/my.cnf /etc/my.cnf.51
3) download and install MySQL 5.5: I used the DMG distribution, running mysql-5.5.11-osx10.6-x86_64.pkg first, MySQLStartupItem.pkg second, MySQL.prefPane third.
4) copied the MySQL 5.5 my-large.cnf file into /etc: sudo cp /usr/local/mysql/support-files/my-large.cnf /etc/my.cnf
5) started MySQL 5.5: sudo /Library/StartupItems/MySQLCOM/MySQLCOM start
6) tested the installation: mysql -u root

MySQL Uninstall:
When I tried the second upgrade I had to uninstall MySQL 5.5.  To do this I did the following:

1) delete MySQL install directories: sudo rm -rf /usr/local/mysql
2) delete Mac receipt files: sudo rm -f /private/var/db/receipts/com.mysql*