Friday, December 25, 2009

Linux on the Real User's Desktop: Aventail VPN

Previously, I promised to outline some of the steps I had to take to make Linux a reality on the desktop of someone who used their PC for more than just watching YouTube videos of a cat jumping into and out of a box. In this installment, I'm going to cover the most of obscure of my hurdles: the Aventail VPN client.

I realize that this topic is targeted to an extremely small audience. My main reason for covering this is because it's not very well documented. In fact, the tarball I got from the corporate office had no documentation at all. Furthermore, my searches around the Internet turned up next to nothing on the subject -- most posts I found stated that it just wasn't possible. This is simply not true, and as proof, I've been using it for a couple weeks on multiple machines.

One little issue here: normally I would link to the installation tarball I've used. I'm even more inclined to do so since many corporate IT departments will issue a canned "we will not support Linux" response to any requests for the Linux client. Moreover, I've been unable to find many sources for it. At this point, I am uncertain of the legality in re-posting the tarball that I've used, so I'm holding out on doing so until I can find out one way or the other. In the meantime, I can promise you that Aventail includes this client as part of their standard distribution, so your corporate IT department does have it. Keep pestering them, and chances are that someone will send it to you just to shut you up. (But if you do happen to get it this way, be warned that you are completely on your own.)

If this fails, I have found a few links that might be of use. The first is, so far as I can tell, a direct link to the same version I've used, so I suggest trying that first. The rest are sites that list various versions of the Aventail Connect client, but I've not tried to download/install from them, so your mileage may vary:




I'm using version 8.90 because that's the version that was provided by our corporate IT department and is guaranteed to work with our hardware. I'm aware that 9.x and 10.x versions are available, but I've not used them. I would presume that the setup wouldn't be very different for these versions, and a quick scouring of various forums seems to support that thought.

When installing under Ubuntu, understand that the install and startup scripts are not written for your default shell. (Yes, this means we'll be doing a little work from the command prompt. But don't worry ... it's quite painless.)

First thing, copy the tarball into a working directory and decompress it. (I'll assume you can copy a file into another directory.) Once copied, open your terminal window, decompress, substituting the filename for whatever you might have.

tar -xvf AventailConnect-Linux.tar

Now that we've done the hard part, you'll need to make a quick tweak to the installation script. Remember, it's not written for bash, the default Ubuntu shell. When dealing with quick and dirty text editing, I prefer vim. If memory serves, vim isn't installed during the default Ubuntu setup, so we'll have to add that real quick. It's easy enough to install:

sudo apt-get install vim

The next thing we need to do is get the install script set up to work under Ubuntu. Let's open it for editing:

sudo vim install.sh

For the uninitiated, vim opens files in a view-only mode. To begin editing, you'll have to press the letter i to enter insert mode. From there, we make one tiny change. Edit the first line:

#!/bin/sh

to read:

#!/bin/bash

When you're done making changes, press [esc] to return to view mode, then enter the following:

:wq

The colon enters command mode. The w tells vim to write your changes to disk, and the q exits the editor.

Now we can run the installation script:

sudo ./install.sh

One little note: in one instance (I've done this quite a few times), I had to use sudo bash ./install.sh -- and I don't know why or what caused it. If the script won't run, saying there's an error with a function on line 22 or something around there, try this same tip and see if it works for you. The last few times I tried the install, I didn't need to do this, but I'm including it just in case.

Once the install script finishes, you'll have to make the same shell change to the startup script. Aventail installs to /usr/local/Aventail, so switch to that directory.

cd /usr/local/Aventail

Once there, let's open the file for editing:

sudo vim startct.sh

Change the first line from:

#!/bin/sh

to:

#!/bin/bash

Then save and exit with:

:wq

Next, we need to make sure that the startup script can be run without root privileges, so let's change that now:

sudo chmod 777 /usr/local/Aventail/startct.sh

If all went well, you should now be ready to connect to your corporate network. From the command prompt, simply type:

/usr/local/Aventail/startct.sh

The startup script will prompt you for the appliance host/IP address. Note that under Windows clients, this is usually automatically provided in the form of a configuration file, so you may not know it. If you don't know this address, contact your IT department. Alternatively, if you have access to a Windows-based install, the address can be found in the networking section as one of the connections. Right click, select properties, and check the connection info.

Enter the IP or hostname of your Aventail gateway, then follow the remainder of the prompts as you would under a Windows connection.

That's it! You're in!

When you're finished with your work and want to disconnect from your corporate network, enter the following at your command prompt:

/usr/local/Aventail/stopct

Hopefully you have as much success as I did. If you have anything to add, or noticed any errors with this, I'm very interested in your comments. There's a glaring lack of documentation on this particular topic, and I have no problem at all with helping fill this void.

Wednesday, December 23, 2009

Linux on the Real User's Desktop (part 1)

Alright, let's stop messing around: I'm a computer geek. I hate to admit it, because I especially hate the hassle of trying to get these incredibly complex machines to do what should be relatively simple tasks. Be that as it may, I am what I am, as Popeye would say.

I've tinkered over the years with the idea of using a Linux OS on my own home (and work) desktop, but end up switching back to Windows after a couple days because there are just too many essential functions that I can't quite make happen under Linux. For a vast majority of users, who only use their computers for web surfing, e-mail, web-based games, Facebook, and document editing, Linux is a very viable solution. For a "real" user, though -- what some would call a Windows power user -- the reality is that there are just certain shortcomings.

This time around, I've been using Ubuntu on the netbook for about three weeks, and the desktop for a little over a week, and I'm happy to say that for the most part, things are looking pretty good from the usability department. If I can get everything done that I need, I will have avoided the $200 upgrade fee to get Windows 7 Ultimate installed on my main desktop, and a few hundred more by not installing Windows 7 Home on a couple other computers.

So I figured I would document the few hurdles I've had to overcome to make Linux happen, and maybe if there's someone else out there who can gain from my experience, then I've done a bit to give back to the community.

In the next few posts on the topic, I'll go into a little detail on what needed to be done to get certain requirements met. This one, however, is a little overview of what those requirements are, and some general tips on configuration. I know this is a long post, but there's a lot of ground to cover here!

First, the what and the why:

Aventail VPN [view instructional link]
Our company uses Aventail exclusively for VPN access. It is extremely secure, and has also been the number one thorn in my side under Linux. Without it, I can't remote into the office PC, which instantly disqualifies Linux on my home desktop.

Source Code Editor/IDE
Remember, I'm a developer, so I need robust tools that can handle multiple languages in a rapid development environment.

Graphics Design/Editing
Again, this ties into my work as a developer. Part of that development includes graphical user interfaces. Additionally, I do a little photography, so I'll need to import and edit those photos as well.

iTunes/MobileMe
This one is something I'm going to have to live without, because as of this writing, it's just not possible. I have an iPhone, and in order to do all the really useful stuff, I need iTunes/MobileMe to work on the desktop and sync with the iPhone. A later post on this topic will deal with my workarounds.

Multimedia Friendly Apps
I have an extensive music and movie collection, plus I currently use Windows Media Center on a home theater PC to record and play back television (and also use an XBox 360 as a Windows Media Extender). Additionally, I do a small amount of music composition using tools like FruityLoops, so I'll need to replicate all this functionality.

Access to Windows Shares
There are other machines in the house that will be running Windows for a great many years (hey, I can't make everyone in the house switch), so I need to be able to perform integrated backups from a central machine.

Document Printing/Scanning
This is one of those things that a lot of people take for granted when they're getting set up, but it's worth special mention. Printers can be tricky under Linux because many manufacturers don't release specialized Linux drivers. Additionally, multi-function devices (like my Canon MP470 printer/scanner) don't have native scanner drivers either.

I'm sure there are more things that I'm forgetting, but this covers the bare essentials. Remember that any solution to these obstacles has to be free. The whole point in this experiment is to get things done without spending any more money. We spend enough on the hardware, and in this economy, every dollar saved is a pretty big deal.

A couple tips that are worth special mention. Bear in mind that my flavor of choice was Ubuntu Karmic Koala (v9.10), so my nuances might vary significantly from yours.

Server vs. Desktop vs. Netbook Remix
I can only strongly recommend the desktop variety. Server comes without any GUI installed at all, which means you have to download and configure one later if you don't want to do everything via the command-line (which kind of defeats the purpose of a desktop OS). Additionally, I suspect that very few of my readers have any real need to have a machine configured as a server by default. (Fear not -- if you require server daemons and applications like Apache, MySQL, or PHP, those can be installed and configured later quite easily.)

Conversely, Netbook Remix, while geared toward the lower-powered machines, lacks functionality in a great many areas. The desktop version can (and does) run just fine on most popular netbooks. In fact, I use it on my Gateway netbook, which is far from the most powerful workhorse in the category.

Installation method
The distro comes in .ISO format, which is ready to be burned to a CD as a bootable disc. I'm not really a fan of burning CDs any more than is absolutely necessary, so I chose to install from a USB flash drive. This has a couple advantages. First, I can use it to install to my netbook PC (which has no CD drive at all anyway), and makes for a far faster installation experience.

There are step-by-step instructions for building a bootable USB installation, but I prefer to use a free utility called UNetbootin to automate the process, which really makes the setup a snap. You could technically get away with a 1GB drive, but the install utility recommends 2GB. It's worth noting that this will erase the contents of your USB drive.

Installation destination
You aren't convinced. You need to make sure your existing Windows installation -- and all your precious data -- remains intact. No problem! During the install, you can choose to resize your primary partition, leaving all your Windows stuff in it's own little isolated world while creating your new Linux sandbox. Make sure you install side-by-side, and you will have what's called a "Dual Boot" configuration; you can switch between the two operating systems at any time just by rebooting your PC. Additionally, you can access all the data on your Windows partition through Linux.

Caution: be very careful with this step that you do not accidentally choose the wrong option and erase the contents of your disk. Make absolutely certain that you have the side-by-side configuration chosen. It's also a good idea to back up all your important documents before doing this.

One last note: be sure you run a full disk scan prior to installation. Open a command prompt window and type: chkdsk /f /r

You'll have to reboot for the scan to begin. Go watch a movie. This takes a while. When it's done, reboot again to make sure everything is tip top.

Desktop Environment
By default, Ubuntu comes with GNOME. (By the way, I typically hear this pronounced: guh-NOME.) GNOME should be suitable for most users, though there is a popular alternative called KDE. Some users claim that transitioning from Windows to Linux feels more natural when using KDE, though I've discovered that it has some unique little quirks that tend to sour the computing experience.

Sound issues were one of the big ones for me; things that "just worked" under GNOME refused to play any sounds at all under KDE. I do prefer the way KDE looks and feels, as well as its advanced configuration options, but when it's time to get down to the nitty gritty, I want things to function properly with no tinkering required. And so do you. Stick with GNOME until you're comfortable monkeying around under the hood.

If you're ready to take the KDE leap, you can install from the Synaptic Package Manager by searching for "kubuntu-desktop" which will install all dependencies automatically and allow you to switch your default desktop manager. Alternatively, you can forgo GNOME entirely by downloading the Kubuntu installation .ISO file instead of the standard Ubuntu.

Web Browser
Ubuntu comes with Firefox by default, which I'm eternally grateful for, but I'm one of the few who use Google Chrome as my primary browser. It just feels lighter and snappier. Thankfully, Google has recently released a beta version for Linux, which installs in a snap, so you can use either (or a host of alternative browsers). The upside to Chrome is that it has built-in support for most web-based technologies that typically require plug-ins to be downloaded and installed, which makes for a much more "automatic" experience.

...whew!

That's more than enough for now. I'll follow up a little later with a few of those pesky requirements that I listed above. If I keep this up, I'm going to need to start a whole new blog just for this topic, since I'm straying so far away from the code development that I set out to do here!

Saturday, September 26, 2009

Linksys Switch Issue

After a great deal of re-wiring, re-fitting old cabling with new RJ-45 connectors, reconfiguration of routers and network interfaces, I finally found the culprit. Frustratingly enough, it's one that would have saved me about 3 hours of climbing stairs, re-routing wires, and stripping CAT5.

If you're using a Linksys 5 or 8 port switch, and you have one of the ports daisy-chained to another switch, you can NOT use the port adjacent to the uplink port. According to Cisco, those two ports (Uplink/port 4 or Uplink/port 7) are wired together.

So, in my case:

[Cable Modem] -> [Router] -> [Switch 1] -> [Switch 2/3/4/5]

The router connects to my primary desktop, my VOIP device, and Switch 1.

Switch 1 distributes to other areas of the house, where I have additional switches installed to allow for more than a single device. (My home theater configuration, for example, included a PC, an XBOX 360, and a DirecTV tuner which is internet-ready for video on demand and remote scheduling. All are connected to Switch 2, which gets its feed from port 1 on Switch 1.)

Point of the story: I had unwittingly connected a device to port 4 on Switch 1, which killed the uplink connection back to the router. Any device connected to a numbered port on Switch 1 then found itself without any internet connectivity.

All is now well at home, and I can focus on getting the servers re-configured to free up another machine for the garage. Uh oh... I'm going to need a bigger switch. :)

Hopefully this little tidbit saves someone a bunch of time and headaches.

Reminder to self: Don't Over-Engineer It!

My boss has recently called me out on a problem I've developed in recent weeks. I have an affinity for elegant, tight, well-refined code. The problem is, to achieve that result, one often spends FAR too long in the engineering stage. Sometimes quick and dirty code really is the best approach, even if it's ugly as sin and makes other devs wince when they see it.

Sure, there are things that I will still avoid like the plague, and there are things that I will continue to do even though they aren't technically necessary. I won't put all my code in the global scope and let it run in crazy freestyle spaghetti form. I will make sure that anything appearing more than twice gets the distinction of being in its own function. But there are a few projects on my plate that really shouldn't take more than an hour or two to see completion status, and for some ridiculous reason, I find myself spending a couple days on them.

I know it frustrates the hell out of people, especially when they're used to seeing me "just get shit done."

So, again, a personal goal: know when to worry about elegance, and when to pump out the code like your fingers have teh diarrhea.

Tuesday, July 28, 2009

ZoneAlarm

Don't do it. I know it has it's place, but mine ain't one of 'em, and if you're reading this, odds are, yours ain't either.

I honestly don't have a friggin' clue as to the drugs I was on when I clicked "install" in the first place.



[iPhone post]

Saturday, May 30, 2009

iConvert


I've made no bones over the years about not being excessively fond of Microsoft solutions. They have some great products -- Office, SQL Server, and Media Center being just a few -- but for the majority of my needs (okay, geeky wants), most of their products are simply lacking. Or worse.

By this point, we all know how much I love my iPhone. I purchased it after my intense bouts of frustration over a couple years of using PalmOS and Windows Mobile devices. Apple hit it out of the park with the iPhone. Period.

Today, I further fell in love with Apple. I have all my music sitting on a network share attached to my primary desktop PC, and wanted to hear it over my home theater setup instead. Add to that, a recently downloaded iPhone app, which I'll cover in a moment.

So I installed iTunes on my HTPC, pointed it to the network share, and waited a few moments while iTunes indexed my library. I then fired up the aforementioned iPhone app, simply called "Remote" which asked me to select a library. I did, and was shown a little 4-digit code to key into iTunes. Once I did that, I had access to my full music library. I chose a song, and the house started rocking. I slid the little slider on my phone, and the volume magically dropped. Fast forward, rewind, play, pause, access to my pre-built playlists as well as the Genius...

It Just Friggin' Works. Every time I try something new, it's like happy magic invading my electronic devices.

My next computer purchase will most assuredly be a Mac. Period.


[iPhone post]

Tuesday, May 19, 2009

Sometimes I Could Just explode()

Every once in a while, a fella in a hurry to get somewhere drives a little faster than his brain can handle, and said fella ends up veering off the road and into a ditch somewhere. That's sort of what happened to me this morning.

I have a function that pulls debugging information and spits it out to a div element, and I wanted that div to have a limited scrollback buffer defined by lines rather than characters. Since a line break is used to end each log entry, I figured a simple .split("<br>") would do the handiwork of creating an array of log items that I could then reverse sort, trim, and spit back out into the div (so my newest items appeared at the top).

Oh, nay nay.

Unbeknownst to me, there's something funny about that self-closing line break, however, that split() didn't like. In fact, it just so happens that HTML tags in general require a bit of attention. I eventually discovered that this was all I needed:

.split(/<\s*br\s*\/?\s*>/gi)

This expression works on variations of <br>, including my <br />, and is not case sensitive, so it works equally well in Firefox as it does IE, which tends to force HTML tags to uppercase in the DOM. (This is important since I'm setting the innerHTML attribute of the div.)

However, I wasn't aware of any of this stuff when I ran into my little problem. So I struck out to create a mimic of PHP's explode() function, except as a prototype extension to string objects. This is the result:


// Javascript prototype that mimics PHP's explode function
String.prototype.explode = function(delimiter, limit) {
// Make 'limit' an optional parameter with a default of 0 (unlimited)
if (typeof limit == 'undefined') limit = 0;

// Create an empty array, the temp buffer, and a copy of the source string
var elements = [];
var temp_el = '';
var temp_str = new String(this);

// Loop through the local copy, removing each slice and pushing it to the array
// Note that we check here to see if we've reached our array element limit
while ((temp_str.indexOf(delimiter) > 0) && ((limit == 0) || (elements.length < limit))) {
temp_el = temp_str.substr(0, temp_str.indexOf(delimiter));
temp_str = temp_str.substr(temp_str.indexOf(delimiter) + delimiter.length, temp_str.length - temp_str.indexOf(delimiter) + 1);
elements.push(temp_el);
}

// If we have any remaining characters, and we haven't yet reached our
// element limit, push the remaining string to another element in the array
if ((temp_str.length > 0) && (elements.length < limit)) elements.push(temp_str);

// Return the array
return elements;
}


Interestingly enough, however, this failed to handle my HTML tags, just as split() failed, presumably for the same reasons. So my time perfecting this little gem ended up being all for naught, since I had to research why this function wouldn't handle the HTML tags either. What a colossal waste of time.

The function itself works, and quite well, from what I can tell based on my limited testing, so if you want it, you're more than welcome to it.

Be warned, however, that split() really is the only way to go. I'm only sharing it for its intrinsic humorous and edutainment value.

Monday, May 11, 2009

Portable database calls in PHP

It's been a while since I've posted real code, so I thought I'd share a little snippet from a PHP database class that has been my bread and butter for a couple years now.

It started out simple enough, just a nice little wrapper for some of the more repetitious database calls.  It has been growing in recent months, however, as I found myself wishing for expanded functionality.

One of the most recent additions to that wishlist is that I want a class property set after every database query that holds either the number of rows returned or affected, depending on the type of query passed to the class function.  What complicates this is that I've been writing the class to handle multiple types of databases.  I didn't want to have a bunch of switch() statements to cover mysql_num_rows(), mssql_num_rows(), mysql_affected_rows(), and so forth.  So this is my answer.

First, a class property is set by the user defining the type of database transport: mssql, mysql, &c.  The format of this is important, in that it must match one of the database vendor groups that PHP recognizes.  Simple enough.  (This could be an enumerated list of constant values, I suppose, but I'll worry about that another day.)

Now here's where things get fun.  Inside our class query function, we do the following:

Make sure the property is lower case, and keep it local, just for cleaner-looking code.

$transport = strtolower($this->transport);

Also set our default row count to something that represents an error value (we'll set it to a real value once we complete a valid database call).

$this->rowcount = -1;

Now we define the function used for the query.  This will translate to mysql_query() or mssql_query() and so on, depending on the value of the $transport variable.

$query_string = $transport.'_query($this->query_string)';

Finally, we can make the query call and get the result set.  This is the real magic, and shortens a rather long list of case statements into one simple call.  Note that to get anything back from  eval(), we have to explicitly make it pass a return value.  That's why we're wrapping the call inside a return() statement.

$result = eval('return('.$query_string.');');

We follow the same sort of logic to build an associative array containing the entire result set.  This saves us the trouble of doing it in our application, keeping it all neatly contained in this function.

$row_fetch = $transport.'_fetch_assoc($result)';
while($row = eval('return('.$row_fetch.');')) {
    $recordset[] = $row;
}

To get the number of records either returned or affected, we need to determine whether this was a SELECT statement, or if it was an UPDATE, INSERT, DELETE, &c.  We're forced to do this because there are two different functions that handle this counting function, depending on the type of SQL transaction.  So, we'll just see if it's a SELECT statement, and if it isn't, assume that we need to make an x_affected_rows() call.  All we need is the first word, and hope that the user didn't do anything really silly with the query.

$query_type = explode(" ", strtoupper(trim($this->query_string)), 1);
switch($query_type[0]) {
    case 'SELECT':
        $count_string = $transport.'_num_rows($this->db_handle)';
        break;
    default:
        $count_string = $transport).'_affected_rows($this->db_handle)';
        break;
}
$this->rowcount = eval('return('.$count_string.');');

That's pretty much it.  Now we have the recordset if one was returned from the query, as well as the number of rows affected by the query.  We can pass the recordset back in a return() call, or return null if none exists, and the user can take action based on either the recordset or the record count.

Best of all, it's pretty portable.  PostgreSQL, MySQL, MSSQL, Sybase, and on down the line.  So long as the transport property is properly defined, we can use this just about anywhere.  In my experience, other database types are rare enough that I don't need to worry about them, so I'm not going to bother with any special conditions for them.

I am aware that eval() isn't the most popular way of handling things, and it does come with a performance cost and security risk, but in the applications I'm working with, neither are really an issue, as the performance requirements are rather low, and the userbase is limited in experience and located on an isolated intranet.  If you're going to use this code, I would strongly suggest that you take measures to ensure that any SQL query passed to the class function meets your security requirements.

Test 2

Test.


-- Post From My iPhone

One Less Excuse

Since a lot of my time is spent on the road or away from home, I figure I might as well find ways to make more productive use of my time. Until I can devise a practical way to write code on the iPhone, my guess is putting ideas and commentary into electronic form is the next best thing.

So, I'm testing out an app called BlogPress to let me do just that. Sure, I could edit in a web browser, but that lacks a lot of extra functionality, and doesn't do a very good job (if any, in some cases) of saving and editing drafts.

I'll let you all know how it goes.


-- Post From My iPhone

Sunday, May 3, 2009

Was 5 Years Long Enough?

Somewhere in the ballpark of five years ago, I wrote that Linux was five years away from being a viable, mainstream, desktop operating system. I distinctly remember fighting with various driver issues at the time, from wireless NICs to display adapters, as well as being frustrated that the method of distribution and installation for even the most popular applications was inconsistent, obscure, and at times impossible.

For a life-long computer geek like myself to be overwhelmed with its complexity said a lot.

Mind you, this has nothing to do with server environments. I have been running my web, e-mail, and what-have-you servers on Linux machines for the better part of ten years now, and you'd be hard pressed to get me to switch to a Microsoft-based solution for them.

Regardless, I've not given up on Linux-based operating systems for the desktop. In fact, I just recently installed the latest Ubuntu distribution (9.04) in a virtual machine on my primary home office computer, and have spent the past week playing around with some of the newer features that I missed in the 8.x round of updates. (My current server runs 7.10.)

I decided today to take the plunge, reformatting my home theater PC (which is underutilized because the options for a home theater PC running Windows XP .. well .. suck). I had been running into driver conflict issues anyway, causing Windows lock-ups, and I wanted to begin using this PC again for software development while sitting in my cozy recliner. There's nothing quite like software development in a recliner pointed squarely at a 50" plasma, I'm here to tell you.

The installation went well enough, and with the exception of a driver issue with my ATI card, everything has gone smooth as silk. (ATI, I discovered long ago, is horrible when it comes to drivers under ANY operating system, so I can't fault the Ubuntu team for this). All of my semi-obscure hardware seems to work flawlessly, all the basic stuff flies right out of the box, and I'm pleasantly surprised to find that just about any application I've wanted to install can now be easily located in the Synaptic Package Manager.

Synaptic was the one thing Linux really needed to make a good case for itself. Locating and installing any given application or utility is infinitely more simple than ever before, and I would dare say is even easier than on a Windows box.

The selection of mature applications for Linux has grown exponentially in recent years, and with the exception of off-the-shelf game titles, can do anything your heart desires with a lot fewer headaches than in Windows. (For the brave, there are options available to get most Windows entertainment titles running as well, for a price, of course.)

Overall, I'd say the time for Linux has finally arrived. It's fast, stable, reliable, and is only as complicated as you choose to make it. I'll be taking more time to be critical in the coming weeks, but the way things stand now, I would have no reservations at all installing this on my mother's PC.

Saturday, January 31, 2009

The iPhone In the Corporate Environment

Since I last harassed you with my text, I've made a major change to my e-life: I purchased an iPhone.

Yes, for most of you, this comes as a shock on the order of the Detroit Lions winning the Super Bowl, but I have indeed gone over to the "other side." And I have to tell you, with a few minor nuisance items, I couldn't be happier.

The items I'm referring to, however, have been little short of showstoppers, I must admit. Again, we're stuck with Lotus Notes as our collaboration solution at work, and it's been the biggest thorn in the side of anyone who wants to use anything other than a Crapberry for their mobile device. To make matters worse, corporate has completely locked out remote access to e-mail through anything other than the Dingleberry Enterprise Server. This presents a challenge of a pretty fair magnitude: how do I keep my contacts, calendar, and e-mail synced between the desktop and the mobile device?

To be honest, it's been a royal pain in the ass. I'm still playing around with a few options -- and trying to keep myself limited to free/low-cost solutions limits those options a bit more -- but I'm starting to get comfortable with the awkward way I have to do things.

Contacts: mobileMe.
I don't even bother with keeping those in sync with Notes. To be honest, I prefer not to, because many of my contacts on my phone are personal, and I don't want them in a database on my work machine. These get replicated to my Vista machine at home via mobileMe, and that's just fine.

E-mail: auto-forward
This is where things get a little stupid. I set up a rule in Lotus Notes to automatically forward a copy of ANY incoming e-mail to my mobileMe account (which is a true push e-mail solution). I've found that my corporate e-mail arrives on my iPhone at the same time as it does on the Crackberry devices my co-workers use, so I'm not missing anything. My problem is that if I want to reply to message, it goes out through the mobileMe address rather than my corporate e-mail address. Additionally, it does not get forwarded to my corporate account, so I have no record of sent e-mails on my desktop. I don't want this, but without corporate opening up a port to the outside world, it's the only option I've found so far. It ain't pretty, but it works, and I'm still in touch with the goings-on in the office even when I'm not there.

Calendar: gCal
If you've been following the trend, you can probably speculate that my troubles here are the worst. This isn't so much the fault of Lotus Notes as it is the iPhone (and, more specifically, Apple), because the system calendar is not available to third-party applications for modification. My current solution is another e-mail forward: any Notes calendar item gets forwarded to my gMail account. (It appears as a *.ics iCal attachment, which gMail and gCal properly recognize.) The bad part about this is that I have yet to find a way to get gMail to automatically import these calendar files as gCal events, so I have to manually open gMail to accept and confirm these events. However, once they are there, I can have gCal send out my meeting reminders as SMS messages, so I still get notifications 15 minutes before the metting starts (and don't miss any more meetings).

The above solution would actually work well for any standard phone, not necessarily a smart phone, but it's a really ratty way around a problem that shouldn't exist.

There is a product called CompanionLink that will sync Notes events with gCal, but I'm opting not to spend the money on it just yet, as I believe there may be a way to get this to happen seamlessly for free.

The crux of the matter is that we are far enough along in the development of mobile devices that there really should be a standard for these things. The Blu-Ray vs. HD-DVD war didn't last a fraction of this long, retarded, silent war, so why are we still putzing around with proprietary synchronization methods? Mobile phones need to sync with collaboration software. Period. Make it happen, people.