Recently I upgraded my system from Ubuntu 8.04 to 9.04. My typical upgrade just retains the home partition and reloads the rest from scratch. When it came time to install WSO2 WSF/C and WSF/Ruby, I hit some snags.

It seems that 9.04 may not install some of the required libraries by default as I don’t remember having any issue installing it on 8.04. This was installed on fresh Jaunty install with on Ruby Enterprise Edition installed. libmysqlclient15-dev and libsqlite3-dev were installed as part of the REE install. WSO2 WSF/C was installed by trial and error. I’d run the install script and find the missing library, install it and try again until it compiled without any error. You may not need all the libraries below, but they worked for me.

Anyway, in case you’re getting errors, try these aggregated tips:

First off, you probably already have it but you’ll need to install build-essential

sudo apt-get install build-essential

I also needed this since the libtoolize command was failing.

sudo apt-get install libtool

Next, these were the libraries that I needed to get everything installed.

sudo apt-get install libxml 
sudo apt-get install libiconv-dev 
sudo apt-get install libxml2-dev 
sudo apt-get install openssl 
sudo apt-get install libsqlite 
sudo apt-get install libssl-dev 
sudo apt-get install libaxis2c-dev 
sudo apt-get install libxslt-dev 
sudo apt-get install librampart-dev

Now, follow the install instructions packaged with the WSF/C and WSF/Ruby tarballs and everything should go smoothly.

if you’re getting ax_util errors when compiling WSF/C, try this:

export CFLAGS="-D_GNU_SOURCE" 

at this point it is working for me and will hopefully be working for you.

My upgrade to Ubuntu 9.04

April 24th, 2009

I’ve been using Ubuntu 8.10 for about 3 months now. This has been my first foray into using linux full time since I gave up on it becoming a desktop contender back in 2002 (Boy was I wrong!). After a few attempts at using the upgrade button and having it time out, I downloaded the ‘alternate’ cd and was successful in running the upgrade.

Everything was going along swimmingly until I rebooted. Once the splash screen went away, I was presented with a black screen with a no longer moving wheel cursor. The keyboard was unresponsive, but I could move the static cursor. It was then I remembered that this was the same behavior I had seen when I installed 8.10.

After searching for fixes, this is was did it for me:

  1. Boot into recover mode and drop into a root shell
  2. dpkg-reconfigure xserver-xorg
  3. edit /etc/X11/xorg.conf and add a line to the devices section: Driver “vesa”
  4. reboot and you should be presented with the login screen

At this point, I tried to use the hardware manager to use the NVidia drivers but it didn’t seem to work. I ended up downloading the v180 driver from NVidia’s site and using their installer.

So far, everything else is going great.

For reference, my system specs are as follows: . Dell Precision T3400 . 8 Gig of ram . Quad Core . NVidia NVS 290 . Dual 250Gb sata drives

Rails, and therefore ruby, are always amazing me. Just today, I was working on a site that had a job object. The job belonged to both a company and a project. Now, normally, given restful routing, you have something like this as your url

http://www.mycoolsite.com/projects/1/jobs/4/edit

or

http://www.mycoolsite.com/companies/2/jobs/4/edit

and this will load up the form for a job object. In my jobs controller, I have a method as such:

class JobsController < ApplicationController
  before_filter :get_dependencies

  def get_dependencies
    #requests will come in from either projects or companies
    @project = Project.find(params[:project_id]) unless params[:project_id].nil?
    @company = Company.find(params[:company_id]) unless params[:company_id].nil?
    @parent = @project || @company
  end
end

and depending on whether the request came in from a context of a company or a project, the @parent object will contain that object. The form can also determine if the the parent object is a company or a project and pre-fill that blank with the correct information. All of this is pretty standard. The part that I was stuck on was linking to these forms. Given these urls:

http://www.mycoolsite.com/companies/2/jobs
or
http://www.mycoolsite.com/projects/1/jobs

How can I link to the add or edit actions without having to do something un-dry like this:

- if @parent.is_a? Project
  =link_to 'Edit', edit_project_job_path(@parent, job)
- else
  =link_to 'Edit', edit_company_job_path(@parent, job)

Well, the solution is simple, clear & concise—Would you expect anything less from RoR? :)

link_to 'Edit', edit_polymorphic_path([@parent,job])

This will automatically determine the parent object and it’s associated restful path along with the current jobs restful path.

Recently I had to finally bite the bullet and get my Linux VM’s talking with MS SqlServer. After much trial and error and umpteen tutorial sites, I have finally figured out how to do this…..and the amazing thing is that is dead simple.

First off, all of this was executed as root:

yum install freetds-devel unixODBC-devel
This will install not only these packages, but the freetds and unixODBC ones as well and install the libraries ‘libtdsS.so’ and ‘libtdsodbc.so’ in the /usr/lib folder
vim /etc/freetds.conf
- in the global section change “tds version” to 8.0
vim /etc/odbcinst.ini
—add an entry for FreeTDS
[FreeTDS]
Description     = ODBC for SqlServer
Driver          = /usr/lib/libtdsodbc.so
Setup           = /usr/lib/libtdsS.so
FileUsage       = 1
once this has been done, you should be able to connection up to your SqlServer machine
tsql -S <server-ip> -U <username> -P <password>
you will now be in a shell and can test is by doing this
use <actual database name>
go
select * from <actual table name>
go
Normally, at this point, I install Ruby Enterprise Edition. I use this as my only ruby installation on the machine. I won’t go into how to install it because http://www.rubyenterpriseedition.com/ has great documentation already.

Next, download ruby-odbc from http://www.ch-werner.de/rubyodbc/

Once downloaded, do the following
tar zxvf ruby-odbc-0.xxxx #replace the xxxx with the current version
cd ruby-odbc-0.xxxx 
ruby extconf.rb
make
make install
Next, grab the gems you’ll need
gem install dbi
gem install dbd-odbc
gem install rails-sqlserver-2000-2005-adapter -s http://gems.github.com
That’s it! At this point you can make a new rails app and modify the database.yml file to look similar to this:
development:
  adapter: sqlserver
  mode: odbc
  dsn: Driver=FreeTDS;Server=10.x.x.x;Database=dbBoring;Uid=sa;Pwd=password1

There is an option to edit the file /etc/odbc.ini and define your dsn’s there, but that didn’t feel too dry to me so I define them only in the database.yml file.

Flex Builder 3 on the OSX

January 7th, 2009

After days of watching Flex Builder 3 crash as soon as I opened it, I figured out how to fix it. It seems that Flex Builder doesn’t like the 64 bit version of Java 1.6 that OSX now uses. I had thought this might be an issue so I used the Java Prefences pane to move Java 1.5 up as my default. It didn’t change a thing. I downloaded eclipse to see if it was a Flex Builder issue or an Eclipse issue. Turns out it’s and Eclipse issue.

The solution: You need to specify the exact JVM in the Info.plist file. You can find this file Flex Builder.app -> Contents -> Info.plist

Open that up in your favorite text editor and add a line like so:

 <key>Eclipse</key>
  <array>
      <string>-startup</string>
       <string>../../../startup.jar</string>
      <string>-vm</string><string>/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Commands/java</string>

It's 2009

January 2nd, 2009

It’s 2009 and it’s time for those pesky resolutions.

  1. Start blogging more. The Rails community has helped me out immensely and it’s time to start giving back.
  2. Port over all those legacy apps at work that need updating but don’t get them because it’s too painful to refactor the old code.
  3. Learn VIM….no REALLY learn VIM. I think my productivity would increase two-fold once I got good at it.
  4. This one’s no surprise – Lose weight. I’ve been carrying around an extra 30 lbs that needs to go away.
  5. Write my own blog software.

Meme(me)

September 22nd, 2008

From Rey Bango’s Blog

1. Take a picture of yourself right now.
2. Don't change your clothes, don't fix your hair... just take a picture.
3. Post that picture with NO editing.
4. Post these instructions with your picture.

I’‘ve got a problem. I work in an all windows shop, but I develop in rails. Normally, that’s not such a big deal, but every once in a while, you find a plugin or gem that only works in linux. Usually, I’d through together a virtual machine loaded with linux and develop that way. It’s kinda a pain though, having to set up samba shares and editing your code “remotely”.

Recently, I found a project called andLinux (andLinux.org). This is a modified linux kernel that runs inside of Windows. It ships with a basic set of tools, Konquerer, Kate, Konsole, .etc….oh, I did I mention it’s KDE based :) All of these programs can interact directly with the windows desktop. As a matter of fact, now I have a right-click option to edit xml files in Kate.

The really cool part though is how I can develop rails apps. After I installed andLinux, I compiled ruby. I installed Apache2, Mysql, Passenger Phusion (mod_rails) and Rails and a host of other gems. The andLinux distro is able to see your windows hard drives by default, so in my Apache config, I pointed directly to the mounted windows directory where my source files exist. In the linux terminal I can script/server and go back to Netbeans on windows and edit to my hearts content.

I used these two links to configure the server.

Compiling Ruby, Rubygems and Rails on Ubuntu

Setting up Ubuntu and Passenger

Audio Sanity Restored

August 26th, 2008

I own a 2008 Toyota Prius. It’s got a handy aux-in jack in the console. The first day I had it, I had my iPod plugged into through a Belkin power/aux out adapter. It was great. The iPod stayed charged and my music sounded great. Things were good.

Fast forward to August when I got my iPhone 3G (yay!). This was the answer to a lot of my problems. I’ve missed countless calls because my iPod has been turned up louder than my phone can ring. The iPhone would solve that by performing both functions. So, imagine my disappointment when I plugged in my iPod to my Belkin cord and I get a message stating that “Charging is not supported with the accessory”.....oh well, I’ll just listen to the music until it dies. Que ‘Der Kommisar’:

bumda bum bum bum bum…bumda bwah bwah bwah..eeeeeeeee…....bumda bum bum bum…bumda bwah bwah bwah bwah eeeeeeeee…..

What in the hell is that whining sound!? Come to find out, the iPhone 3g suffers from a ground loop isolation problem whereas the iPod didn’t. My next step was to buy a new adapter for the iPhone….Yikes! $49.99 for the Griffin Auto Pilot Aux….

I went straight to the car, plugged in the adapter popped the iPhone on it and was greeted by that annoying ‘weeeeeeeeeeeeeeeeeeeeeeeee!’

More research…..

I found this device: PAC SNI-1/3.5

It only took a couple of days to get here, but since I drive 100 mile round trip to work each day…it seemed like an excruciatingly long time. Interestingly, radio is still more irritating than listening to the incessant ‘weeeeeeeeeeeeeeeeeeeee’. Anyway, plugged it in tonight. Plugged the ipod into it and viola!, instant silence. As far as I can tell, the signal isn’t noticeably degraded. The highs still sound sharp and the bass isn’t muffled (any more than the stock Toyota speakers make it)

So, do your ears a favor and get this thing….it’s the best $14 I’ve spent in a long time.

It's been awhile

April 14th, 2008

It’s been awhile since I’ve written anything. I’ve been deep into sites using Ruby/Rails, but now I’ve started playing around with JRuby/Rails. As such, I want to write down the steps to connect to a sqlserver database from JRuby.

First, download the sqlserver.jar file from Microsoft. Place it in the lib directory of your JRuby installation.

Second, configure your database.yml file to read like so:

ActiveRecord::Base.establish_connection(
    :adapter=> 'jdbc',
    :url=> 'jdbc:sqlserver://MyDatabaseServer;databaseName=MyDataBaseName',
    :driver => 'com.microsoft.jdbc.sqlserver.SQLServerDriver',
    :username=>'xxxxxxxx',
    :password=>'xxxxxxxx'
    )

Thirdly…..there is not step three!

I still haven’t given up my subscriptions to my ColdFusion based mailing lists. Heck I’ve belonged to them sing 2000. It’s almost like leaving family. Alas I digress, a question came up asking how you would solve this problem in CF.

Say that I have a list of allowed nmbers: 32,48,64,72,144,160,200,288,320,400,512,576,640,720,800

If I give the user the option of selecting a number, and it happens to not be in this list, how might I go about automagically selecting the next lowest number? One exception being if the user selects a number lower than 32, in which case the code should return 32.

Examples: User selects 100, the code would return 72.

User selects 480, the code would return 400.

User selects 25, the code would return 32.

One of the simplest solutions presented was this:

<cfset input = 100 />
<cfset last = listFirst(numbers) />

<cfloop list="#numbers#" index="num">
  <cfif num GT input>
   <cfbreak />
 </cfif>
 <cfset last = num />
</cfloop>

#last#

I thought, how would I do this in ruby. Here’s what I came up with. Definitely more elegant than the above code:

# our test input
input = 25

# change the list to an array
nums = "32,48,64,72,144,160,200,288,320,400,512,576,640,720,800".split(",")

# find all the numbers which would be smaller
target = nums.find_all {|num| input >= num.to_i }

# take the last element of the found elements, or if nil return the first 
# element of the original array
puts target.last || nums.first

Using MS SQLServer with Rails

September 18th, 2007

Rails and Microsoft SQLServer don’t seem to be the best of friends, particularly when consider blob images. I’ve outlined the steps that I had to cruft support for better binary support in MS SQLServer. Now, not all of this is my doing. A lot of the code was lifted from a sqlserver thread in the Ruby on Rails mailing list.

First off, download the SQL Native Client from Microsoft. This new provider has better support for statements longer than 8k. (About Time!)

Next, modify ADO.rb so that the execute method reads like so:

  def execute
    # TODO: use Command and Parameter
    # TODO: substitute all ? by the parametes
    # if there are no params, avoid the expensive scan operation of bind
    if @params.length > 0
        sql = bind(self, @statement, @params)
    else
        sql = @statement
    end

    @res_handle = @handle.Execute(sql) 
    # TODO: SELECT and AutoCommit finishes the result-set
    #       what to do?
    if @db['AutoCommit'] == true and not SQL.query?(@statement) then
      @db.commit
    end

  rescue RuntimeError => err
    raise DBI::DatabaseError.new(err.message)
  end

There’s a relatively expensive scan operation in the bind operation that really chokes when binary content is sent to it.

In the sqlserver_adapter.rb file, modify the the following functions:

  def self.string_to_binary(value)
    '0x'+value.unpack('H*').to_s
  end

  def self.binary_to_string(value)
    if value.kind_of? Array
      value.map {|c| c.chr}.join
    else
      value
    end
  end

Also, modify the Base class inside sqlserver adapter like so:

module ActiveRecord
  class Base
    def self.sqlserver_connection(config) #:nodoc:
      require_library_or_gem 'dbi' unless self.class.const_defined?(:DBI)

      config = config.symbolize_keys

      mode        = config[:mode] ? config[:mode].to_s.upcase : 'ADO'
      username    = config[:username] ? config[:username].to_s : 'sa'
      password    = config[:password] ? config[:password].to_s : ''
      provider      = config[:provider] ? config[:provider].to_s : 'SQLOLEDB'
      autocommit  = config.key?(:autocommit) ? config[:autocommit] : true
      if mode == "ODBC" 
        raise ArgumentError, "Missing DSN. Argument ':dsn' must be set in order for this adapter to work." unless config.has_key?(:dsn)
        dsn       = config[:dsn]
        driver_url = "DBI:ODBC:#{dsn}" 
      else
        raise ArgumentError, "Missing Database. Argument ':database' must be set in order for this adapter to work." unless config.has_key?(:database)
        database  = config[:database]
        host      = config[:host] ? config[:host].to_s : 'localhost'
        driver_url = "DBI:ADO:Provider=#{provider};Data Source=#{host};Initial Catalog=#{database};User Id=#{username};Password=#{password};" 
      end
      conn      = DBI.connect(driver_url, username, password)
      conn["AutoCommit"] = autocommit
      ConnectionAdapters::SQLServerAdapter.new(conn, logger, [driver_url, username, password])
    end
  end # class Base

  def type_cast(value)
    return nil if value.nil? || value =~ /^\s*null\s*$/i
    case type
    when :datetime  then cast_to_datetime(value)
    when :timestamp then cast_to_time(value)
    when :time      then cast_to_time(value)
    when :date      then cast_to_datetime(value)
    when :boolean   then value == true or (value =~ /^t(rue)?$/i) == 0 or value.to_s == '1'
    else super
    end
  end
  def quote(value, column = nil)
    return value.quoted_id if value.respond_to?(:quoted_id)

    case value
      when String
        if column && column.type == :binary
            column.class.string_to_binary(value)
        else
            super
        end
      when TrueClass             then '1'
      when FalseClass            then '0'
      when Time, DateTime        then "'#{value.strftime("%Y%m%d %H:%M:%S")}'" 
      when Date                  then "'#{value.strftime("%Y%m%d")}'" 
      else                       super
    end
  end

Make sure to use SQLNCLI as your provider in your database.yml and you should be golden! I’ve tested this with files up to 12 meg. 50 meg files caused the interpreter to crash.

I’d recently created a document management application for my company. I used a third party ocr app that I called from the command line. I deployed it and everything worked great….until the user said, let’s try this big document (180 pages). Amazingly, 15 minutes later, the document had been ocr’d and the text had been stuffed in the database, but the users browser had timed out after about 3 minutes and showed a screen that intimated the document import had failed.

I wrote a script that I threw in the root of my rails app directory. The script uses the the environment files and activeRecord objects from the main app. I think I may have been able to trim down some of my require statements had I used script/runner, but I developed this script while working on a solution involving the win32-service gem.

load 'config/environment.rb'
require 'app/models/document'
require 'app/models/notifications'

loop do

  @document = Document.find(:first, :conditions=>'processed=0')

  if !@document.nil?
    begin
      cmd = "#{CONFIG[:ocr]} -k 6 -6 -y 2 -o %FILENAME.pdf2 -p -t #{File.dirname(@document.full_filename)} #{File.expand_path(@document.full_filename)}" 
      cmd.gsub!(/\//,"\\")
      output = `#{cmd} 2>&1`
      #try to delete the original and rename the searchable one.
      File.delete(File.expand_path(@document.full_filename))
      File.rename(File.expand_path(@document.full_filename)+(2.to_s),File.expand_path(@document.full_filename))
      f=File.open(File.dirname(@document.full_filename)+"\\"+@document.filename.gsub(/pdf$/,"txt"),"r")
      text = f.read
      f.close
      @document.text_data = text
      @document.processed = true
      @document.save
      Notifications.deliver_processed(@document.created_by, @document, output)
    rescue
      Notifications.deliver_error($!)
    end

  end

  sleep 5

end
So I started digging around for ways of offloading the ocr portion into a background process. There are a lot of different ways to do this…..if you run on a unix/linux system. I, unfortunately, deploy to windows machines. After trying several different paths, I remembered my old friend SRVANY.exe. This utility is available in the Windows NT Resource kit (downloadable from Microsoft).

The Resource kit contains a lot of files, but these two, instsrv.exe and srvany are what interest us right now. The format to install a service is as follows

resource_kit\instsrv.exe MyServiceName resource_kit\srvany.exe

Your path to the resource kit may vary. Once you run that command, you should get some output like so:

The service was successfully added!

Make sure that you go into the Control Panel and use
the Services applet to change the Account Name and
Password that this newly installed service will use
for its Security Context.

Now, open up regedit and navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

Locate your new service in the left panel. Highlight the name and right click and choose New -> Key and name it Parameters

so that it looks like this:

Now, in the right panel, right click and and choose New -> String Value. Name it “Application”. Repeat the first step 2 more times, but name these “AppDirectory” and “AppParameters”. Double click the “Application” key and type in the path to your ruby interpreter.

For AppDirectory, type in the working directory for your project, e.g. c:\sites\myRailsApp

For AppParameters, type in the name of the script relative to the working directory. e.g. lib\import.rb. Since my script was in the root of the working directory, I was able to use just the script name.

Ok, next step….wait, there is no next step. You’re done! Now you can change all of the service specific settings in the Service snap-in, stuff like service login, start mode, etc.

Have fun with this!

Okay, I’ve been running a sample app on GoDaddy for approximately a little over year now. It started out as a quick way for a group of friends to identify movies in a picture….It was one of those time wasting things you do on a Friday….or Monday or whenever I guess. Since then, I had posted that I was able to get a rails app up and running on GoDaddy and provided a link to the sample app and it’s received a fair amount of traffic, but people are still trying to get it to work for them.

So here it is…Hitchhikers Guide To GoDaddy Rails!

First off, let’s create a new rails app

c:\sites>rails GoDaddyTest

Switch to the GoDaddyTest directory. Let’s edit the Dispatch.cgi and Dispatch.fcgi files in the public directory so that they point to the right ruby interpreter. Edit the first line of both files to read like so:

#!/usr/local/bin/ruby

Edit the .htaccess file in the public directory next. Find the line that reads

RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

and change it to read

RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

This makes GoDaddy use FCGI to run your app. Believe me, you’ll never ever ever want to use CGI on GoDaddy to run a rails app. EVER!

Exit back out of your editor and freeze rails in your app. This is pretty important because GoDaddy is running a very old version of rails.

c:\sites\GoDaddyTest>rake rails:freeze:edge TAG=rel_1-2-3

Lots of scrolling text will fly past you and your rails will be frozen to your app.

For simplicity’s sake, we’re not going to implement a database in this sample app. It’s pretty straight forward if you need a database, edit the database.yml file like so:

production:
  adapter: mysql
  database: xxxxxxxx
  username: xxxxxxxx
  password: xxxxxxx
  port: 3306
  host: mysqlXXXX.secureserver.net

You can get your database host name from your GoDaddy control panel.

Back to our guide though….let’s create a controller now.

c:\sites\GoDaddyTest\ruby script\generate controller Say hello goodbye pardon

The ole’ say controller…..straight from every beginning rails tutorial :) At this point, you might want to run the local server and see that everything works as expected on your development machine.

Now to the meat of the post. Fire up your Firefox (you are using Firefox, right?) and log into the GoDaddy site. Navigate to your Hosting account page and verify that you have at least the Deluxe package and your on a Linux account. Rails will not work on the GoDaddy Windows servers.

From there, goto the CGI Admin app. Create a rails application directory. This only needs to be done once and you can put as many rails apps in that directory as you want to. Pick whatever name you want to like

Next we upload the site into a subdirectory of your rails app directory. In our example we’d upload into the ‘my_rails_apps’ directory. Start the ftp process and then go get a cup of coffee. Change the oil in your car. Get a haircut. By the time you get back, you should be able to watch the last file upload.

Now, go back to the CGI admin page and create a symbolic link. This creates a link in the root of your site so that people can access your site via url like http://www.mycoolsite.com/my_rails_app versus having to access it like http://www.mycoolsite.com/my_rails_app/my_rails_app

Go ahead….click that ‘Show Rails Applications’ link. If you’ve uploaded your app, it will automagically appear in the list. Select our application my_rails_apps/GoDaddyTest and give it a cool name like superbad. Now let’s try out the application. http://www.mydomain.com/superbad/ <—don’t forget the trailing slash!!

Success!!! Let’s break out the champagne! We’re going public! Now let’s check some of our actions. http://www.mydomain.com/superbad/say/hello

KAAAAAHHHHHHHHNNNNNNNNNNN!!!!!!! So put the champagne cork back in and let’s figure out what’s gone wrong. Actually, I know what’s gone wrong, but I’ll give you a few minutes to ponder it.

Okay, figured it out yet? Not yet? Don’t feel bad, having an average IQ isn’t the end of the world. It’s a permissions issue. Windows doesn’t like dealing with Unix permissions. Hopefully your ftp client allows you to change execute permissions. Navigate to the public directory of your rails app on the server. From our example, that would be /my_rails_apps/GoDaddyTest/public/. If you’re using FileZilla, which I am, you can set them pretty easy. Highlight dispatch.fcgi and right click.

Go ahead and set execute on all of the levels.

now, do the same for the dispatch.rb file, and if you’re particularly masochistic, do the same for dispatch.cgi. Back to the browser and check http://www.mydomain.com/superbad/say/hello

Woohoo! Uncork that champagne again, pat yourself on the back, pat the dog, pat Pat…..you’ve successfully deployed your application on one of the slowest Rails providers in the known universe.

After you play with it a while and decide that hey, my sites’ for senior citizens and this should be fast enough for them, experiment with setting up domain pointers so that you can access the site via http://www.myalternatedomain.com/say/hello

12 hours into the conference....

September 8th, 2007

Well, actually, if you count last night, I've been attending this conference for over 16 hours. The talks have ranged from the basic to the really really out there topics, but most have been informative. One thing that I've noticed is the involvement of Sun. As a matter of fact, I sat next to a Sun employee on the NetBeans team. He was interested enough in Ruby people that he took notes on my concerns with the MacOs version of NetBeans. Pretty cool, especially if they get addressed :)

Sun also gave away quite a bit of swag including a $2350. Sun server....unfortunately, I didn't win it.