<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-22035590</id><updated>2012-02-16T07:31:22.416-05:00</updated><category term='Qt'/><category term='PlayBook'/><category term='Sysadmin'/><category term='BlackBerry'/><category term='Programming'/><title type='text'>H.E.C. Geek</title><subtitle type='html'>Household Enterprise Computing Geek</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-22035590.post-1855491526980229155</id><published>2011-10-24T00:49:00.000-04:00</published><updated>2011-10-24T02:11:20.214-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PlayBook'/><category scheme='http://www.blogger.com/atom/ns#' term='Qt'/><category scheme='http://www.blogger.com/atom/ns#' term='BlackBerry'/><title type='text'>Qt for the BlackBerry PlayBook</title><content type='html'>At the keynote to the &lt;a href="http://www.blackberrydevcon.com/americas"&gt;BlackBerry Developer Conference&lt;/a&gt; last week, two very interesting things were announced.&amp;nbsp; First, the &lt;a href="http://developer.blackberry.com/native/"&gt;BlackBerry PlayBook Native SDK&lt;/a&gt; is &lt;b&gt;finally&lt;/b&gt; in public release (it had previously been in a semi-closed beta).&amp;nbsp; Second, RIM unveiled the &lt;a href="http://blackberry.github.com/"&gt;Native Open Source Components Initiative&lt;/a&gt; on GitHub.&amp;nbsp; This GitHub site includes ports of many open source libraries to the PlayBook, including the &lt;a href="http://qt.nokia.com/"&gt;Qt Framework&lt;/a&gt;!&amp;nbsp; The only real downside here is that all they've done so far is to push out the code.&amp;nbsp; No how-to documentation has been provided.&amp;nbsp; Therefore, I'm going to attempt to give a walkthrough for setting yourself up to use their Qt port for PlayBook development.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Before we begin, I'm going to make the following assumptions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;You are using Linux (MacOSX is probably similar, Windows probably has more differences)&lt;/li&gt;&lt;li&gt;You have a Git client installed&lt;/li&gt;&lt;li&gt;You have installed the Native SDK in: /opt/RIM/bbndk &lt;/li&gt;&lt;li&gt;You have already requested and installed code signing keys &lt;/li&gt;&lt;li&gt;You have generated a debug token, and saved it in your home directory as "debugToken.bar"&lt;/li&gt;&lt;li&gt;You have an actual PlayBook, on an IP address your computer can connect to, that is in development mode with the above debug token installed.&lt;/li&gt;&lt;/ul&gt;(I'm sorry if those are a lot of assumptions, but RIM's own documentation covers all of those steps and I'd rather not get sidetracked.)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Downloading and Building Qt&lt;/h3&gt;First, put the following line at the bottom of your &lt;i&gt;.bashrc&lt;/i&gt; file:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;source &lt;span style="color: #40015a;"&gt;/opt/RIM/bbndk/bbndk-env.sh&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size: xx-small;"&gt;(Seriously, just do it.  If you don't, then I don't want to hear all sorts of complaining about how various commands can't be found during the build processes to follow.  If you insist on not putting that in your &lt;i&gt;.bashrc&lt;/i&gt;, then make sure you run it in every single new shell window you open before doing anything I'm about to discuss.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now, time to download and build Qt:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #ffffff; color: black;"&gt;~&lt;span style="color: #40015a;"&gt;/pbdev&lt;/span&gt;&lt;span style="color: #797997;"&gt;$&lt;/span&gt; git clone https&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;span style="color: #40015a;"&gt;/&lt;/span&gt;&lt;span style="color: #40015a;"&gt;/github.com/blackberry/Qt.git&lt;/span&gt;&lt;br /&gt;Cloning into Qt&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;remote&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Counting objects&lt;span style="color: #808030;"&gt;:&lt;/span&gt; &lt;span style="color: #008c00;"&gt;46226&lt;/span&gt;, &lt;span style="color: maroon; font-weight: bold;"&gt;done&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;remote&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Compressing objects&lt;span style="color: #808030;"&gt;:&lt;/span&gt; &lt;span style="color: #008c00;"&gt;100&lt;/span&gt;% &lt;span style="color: purple;"&gt;(&lt;/span&gt;&lt;span style="color: #008c00;"&gt;29220&lt;/span&gt;&lt;span style="color: #40015a;"&gt;/29220&lt;/span&gt;&lt;span style="color: purple;"&gt;)&lt;/span&gt;, &lt;span style="color: maroon; font-weight: bold;"&gt;done&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;remote&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Total &lt;span style="color: #008c00;"&gt;46226&lt;/span&gt; &lt;span style="color: purple;"&gt;(&lt;/span&gt;delta &lt;span style="color: #008c00;"&gt;14755&lt;/span&gt;&lt;span style="color: purple;"&gt;)&lt;/span&gt;, reused &lt;span style="color: #008c00;"&gt;45939&lt;/span&gt; &lt;span style="color: purple;"&gt;(&lt;/span&gt;delta &lt;span style="color: #008c00;"&gt;14468&lt;/span&gt;&lt;span style="color: purple;"&gt;)&lt;/span&gt;&lt;br /&gt;Receiving objects&lt;span style="color: #808030;"&gt;:&lt;/span&gt; &lt;span style="color: #008c00;"&gt;100&lt;/span&gt;% &lt;span style="color: purple;"&gt;(&lt;/span&gt;&lt;span style="color: #008c00;"&gt;46226&lt;/span&gt;&lt;span style="color: #40015a;"&gt;/46226&lt;/span&gt;&lt;span style="color: purple;"&gt;)&lt;/span&gt;, &lt;span style="color: #008c00;"&gt;158&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: #008c00;"&gt;41&lt;/span&gt; MiB &lt;span style="color: #e34adc;"&gt;|&lt;/span&gt; &lt;span style="color: #008c00;"&gt;832&lt;/span&gt; &lt;span style="color: #40015a;"&gt;KiB/s&lt;/span&gt;, &lt;span style="color: maroon; font-weight: bold;"&gt;done&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;Resolving deltas&lt;span style="color: #808030;"&gt;:&lt;/span&gt; &lt;span style="color: #008c00;"&gt;100&lt;/span&gt;% &lt;span style="color: purple;"&gt;(&lt;/span&gt;&lt;span style="color: #008c00;"&gt;14755&lt;/span&gt;&lt;span style="color: #40015a;"&gt;/14755&lt;/span&gt;&lt;span style="color: purple;"&gt;)&lt;/span&gt;, &lt;span style="color: maroon; font-weight: bold;"&gt;done&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;~&lt;span style="color: #40015a;"&gt;/pbdev&lt;/span&gt;&lt;span style="color: #797997;"&gt;$&lt;/span&gt; &lt;span style="color: #bb7977; font-weight: bold;"&gt;cd&lt;/span&gt; Qt&lt;br /&gt;~&lt;span style="color: #40015a;"&gt;/pbdev/Qt&lt;/span&gt;&lt;span style="color: #797997;"&gt;$&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: #40015a;"&gt;/configure-qsk&lt;/span&gt; arm v7le&lt;br /&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;Qt is now configured &lt;span style="color: maroon; font-weight: bold;"&gt;for&lt;/span&gt; building&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt; Just run &lt;span style="color: #0000e6;"&gt;'gmake'&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;Once everything is built, you must run &lt;span style="color: #0000e6;"&gt;'gmake install'&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;Qt will be installed into &lt;span style="color: #40015a;"&gt;/home/octo/pbdev/Qt/stage/nto/armle-v7/usr/lib/qt4&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To reconfigure, run &lt;span style="color: #0000e6;"&gt;'gmake confclean'&lt;/span&gt; and &lt;span style="color: #0000e6;"&gt;'configure'&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;~&lt;span style="color: #40015a;"&gt;/pbdev/Qt&lt;/span&gt;&lt;span style="color: #797997;"&gt;$&lt;/span&gt; make&lt;br /&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;~&lt;span style="color: #40015a;"&gt;/pbdev/Qt&lt;/span&gt;&lt;span style="color: #797997;"&gt;$&lt;/span&gt; make install&lt;br /&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br/&gt;&lt;h3&gt;Your first Qt app&lt;/h3&gt;Yes, now I'm going to show you how to build/package/install a simple "hello world" application.  Once you get past this point, its mostly normal Qt development.&lt;br /&gt;&lt;br /&gt;This example application consists of the following files, which I'll describe in detail below:&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;File&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;main.cpp&lt;/td&gt;&lt;td&gt;source code for the application&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;helloworld.pro&lt;/td&gt;&lt;td&gt;qmake project file&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;blackberry-tablet.xml&lt;/td&gt;&lt;td&gt;bar descriptor file&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;icon.png&lt;/td&gt;&lt;td&gt;80x80px icon&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;splashscreen.png&lt;/td&gt;&lt;td&gt;1024x600px splashscreen image&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;h4&gt;main.cpp&lt;/h4&gt;&lt;div style="border: 1px solid;"&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: #004a43;"&gt;#&lt;/span&gt;&lt;span style="color: #004a43;"&gt;include &lt;/span&gt;&lt;span style="color: maroon;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #40015a;"&gt;QApplication&lt;/span&gt;&lt;span style="color: maroon;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #004a43;"&gt;#&lt;/span&gt;&lt;span style="color: #004a43;"&gt;include &lt;/span&gt;&lt;span style="color: maroon;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #40015a;"&gt;QPushButton&lt;/span&gt;&lt;span style="color: maroon;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #004a43;"&gt;#&lt;/span&gt;&lt;span style="color: #004a43;"&gt;include &lt;/span&gt;&lt;span style="color: maroon;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #40015a;"&gt;QWidget&lt;/span&gt;&lt;span style="color: maroon;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;int&lt;/span&gt; &lt;span style="color: #400000;"&gt;main&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;int&lt;/span&gt; argc&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;char&lt;/span&gt; &lt;span style="color: #808030;"&gt;*&lt;/span&gt;argv&lt;span style="color: #808030;"&gt;[&lt;/span&gt;&lt;span style="color: #808030;"&gt;]&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;{&lt;/span&gt;&lt;br /&gt;    QCoreApplication&lt;span style="color: purple;"&gt;::&lt;/span&gt;addLibraryPath&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;app/native/lib&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    QApplication app&lt;span style="color: #808030;"&gt;(&lt;/span&gt;argc&lt;span style="color: #808030;"&gt;,&lt;/span&gt; argv&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    QWidget window&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    window&lt;span style="color: #808030;"&gt;.&lt;/span&gt;resize&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #008c00;"&gt;1024&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #008c00;"&gt;600&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    QPushButton quit&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;Quit&lt;/span&gt;&lt;span style="color: maroon;"&gt;"&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;window&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    quit&lt;span style="color: #808030;"&gt;.&lt;/span&gt;setGeometry&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #008c00;"&gt;422&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #008c00;"&gt;100&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #008c00;"&gt;180&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #008c00;"&gt;40&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    QObject&lt;span style="color: purple;"&gt;::&lt;/span&gt;&lt;span style="color: #400000;"&gt;connect&lt;/span&gt;&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;quit&lt;span style="color: #808030;"&gt;,&lt;/span&gt; SIGNAL&lt;span style="color: #808030;"&gt;(&lt;/span&gt;clicked&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;,&lt;/span&gt; &lt;span style="color: #808030;"&gt;&amp;amp;&lt;/span&gt;app&lt;span style="color: #808030;"&gt;,&lt;/span&gt; SLOT&lt;span style="color: #808030;"&gt;(&lt;/span&gt;quit&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    window&lt;span style="color: #808030;"&gt;.&lt;/span&gt;show&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: maroon; font-weight: bold;"&gt;return&lt;/span&gt; app&lt;span style="color: #808030;"&gt;.&lt;/span&gt;exec&lt;span style="color: #808030;"&gt;(&lt;/span&gt;&lt;span style="color: #808030;"&gt;)&lt;/span&gt;&lt;span style="color: purple;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: purple;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This is a pretty basic Qt sample application so far.  The only unique part is the first line, where we are explicitly telling QCoreApplication to add a library path.&amp;nbsp; This is necessary to enable the application to find the &lt;a href="http://labs.qt.nokia.com/category/labs/lighthouse/"&gt;QPA plugin&lt;/a&gt; that RIM provides as part of their Qt port.&amp;nbsp; What is important to note is that the path is relative to the directory the app will be executed from on the device.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;helloworld.pro&lt;/h4&gt;&lt;div style="border: 1px solid;"&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: #797997;"&gt;QMAKE_LFLAGS &lt;/span&gt;&lt;span style="color: #808030;"&gt;+=&lt;/span&gt;&lt;span style="color: #007997;"&gt; '-Wl,-rpath,&lt;/span&gt;&lt;span style="color: #606060;"&gt;\'&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;app&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;native&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;lib&lt;/span&gt;&lt;span style="color: #606060;"&gt;\'&lt;/span&gt;&lt;span style="color: #007997;"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #797997;"&gt;LIBS &lt;/span&gt;&lt;span style="color: #808030;"&gt;+=&lt;/span&gt;&lt;span style="color: #007997;"&gt; -lbbsupport&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #797997;"&gt;SOURCES &lt;/span&gt;&lt;span style="color: #808030;"&gt;+=&lt;/span&gt;&lt;span style="color: #007997;"&gt; main&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;cpp&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #797997;"&gt;package.target &lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #007997;"&gt; &lt;/span&gt;&lt;span style="color: #606060;"&gt;$$&lt;/span&gt;&lt;span style="color: #007997;"&gt;{TARGET}&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;bar&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #797997;"&gt;package.depends &lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #007997;"&gt; &lt;/span&gt;&lt;span style="color: #606060;"&gt;$$&lt;/span&gt;&lt;span style="color: #007997;"&gt;TARGET&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #797997;"&gt;package.commands &lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #007997;"&gt; blackberry-nativepackager &lt;/span&gt;&lt;span style="color: #606060;"&gt;\&lt;/span&gt;&lt;span style="color: #007997;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007997;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-devMode -debugToken &lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;~&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;debugToken&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;bar &lt;/span&gt;&lt;span style="color: #606060;"&gt;\&lt;/span&gt;&lt;span style="color: #007997;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007997;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-package &lt;/span&gt;&lt;span style="color: #606060;"&gt;$$&lt;/span&gt;&lt;span style="color: #007997;"&gt;{TARGET}&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;bar -arg -platform -arg blackberry &lt;/span&gt;&lt;span style="color: #606060;"&gt;\&lt;/span&gt;&lt;span style="color: #007997;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007997;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;blackberry-tablet&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;xml &lt;/span&gt;&lt;span style="color: #606060;"&gt;$$&lt;/span&gt;&lt;span style="color: #007997;"&gt;TARGET &lt;/span&gt;&lt;span style="color: #606060;"&gt;\&lt;/span&gt;&lt;span style="color: #007997;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007997;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-e icon&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;png res&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;icon&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;png &lt;/span&gt;&lt;span style="color: #606060;"&gt;\&lt;/span&gt;&lt;span style="color: #007997;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007997;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-e splashscreen&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;png res&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;splashscreen&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;png &lt;/span&gt;&lt;span style="color: #606060;"&gt;\&lt;/span&gt;&lt;span style="color: #007997;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007997;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-e &lt;/span&gt;&lt;span style="color: #606060;"&gt;$$&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #808030;"&gt;QT_INSTALL_LIBS&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libQtCore&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;4 lib&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libQtCore&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;4 &lt;/span&gt;&lt;span style="color: #606060;"&gt;\&lt;/span&gt;&lt;span style="color: #007997;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007997;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-e &lt;/span&gt;&lt;span style="color: #606060;"&gt;$$&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #808030;"&gt;QT_INSTALL_LIBS&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libQtGui&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;4 lib&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libQtGui&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;4 &lt;/span&gt;&lt;span style="color: #606060;"&gt;\&lt;/span&gt;&lt;span style="color: #007997;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007997;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-e &lt;/span&gt;&lt;span style="color: #606060;"&gt;$$&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #808030;"&gt;QT_INSTALL_LIBS&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libQtOpenGL&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;4 lib&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libQtOpenGL&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;4 &lt;/span&gt;&lt;span style="color: #606060;"&gt;\&lt;/span&gt;&lt;span style="color: #007997;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007997;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-e &lt;/span&gt;&lt;span style="color: #606060;"&gt;$$&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #808030;"&gt;QT_INSTALL_LIBS&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libQtNetwork&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;4 lib&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libQtNetwork&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;4 &lt;/span&gt;&lt;span style="color: #606060;"&gt;\&lt;/span&gt;&lt;span style="color: #007997;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007997;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-e &lt;/span&gt;&lt;span style="color: #606060;"&gt;$$&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #808030;"&gt;QT_INSTALL_LIBS&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libbbsupport&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;4 lib&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libbbsupport&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;4 &lt;/span&gt;&lt;span style="color: #606060;"&gt;\&lt;/span&gt;&lt;span style="color: #007997;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #007997;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-e &lt;/span&gt;&lt;span style="color: #606060;"&gt;$$&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #808030;"&gt;QT_INSTALL_PLUGINS&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;platforms&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libblackberry&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so lib&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;platforms&lt;/span&gt;&lt;span style="color: #808030;"&gt;/&lt;/span&gt;&lt;span style="color: #007997;"&gt;libblackberry&lt;/span&gt;&lt;span style="color: #808030;"&gt;.&lt;/span&gt;&lt;span style="color: #007997;"&gt;so&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #797997;"&gt;QMAKE_EXTRA_TARGETS &lt;/span&gt;&lt;span style="color: #808030;"&gt;+=&lt;/span&gt;&lt;span style="color: #007997;"&gt; package&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;This file does a lot of important things:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Configures the linker to hard-code the path, relative to the directory the app will be executed from, where the Qt libraries will be installed&lt;/li&gt;&lt;li&gt;Includes the "bbsupport" library, which allows the app to interface with the device in a Qt-friendly way&lt;/li&gt;&lt;li&gt;Adds a special make target ("make helloworld.bar") that builds a BAR file with the following characteristics:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Development-mode build, using a debug token&lt;/li&gt;&lt;li&gt;Passes command-line arguments to use the "blackberry" QPA plugin&lt;/li&gt;&lt;li&gt;Bundles all the resources and libraries our app may need&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;blackberry-tablet.xml&lt;/h3&gt;&lt;div style="border: 1px solid;"&gt;&lt;pre style="background: #ffffff; color: black;"&gt;&lt;span style="color: #004a43;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;xml&lt;/span&gt;&lt;span style="color: #004a43;"&gt; &lt;/span&gt;&lt;span style="color: #074726;"&gt;version&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #7d0045;"&gt;1.0&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #004a43;"&gt; &lt;/span&gt;&lt;span style="color: #074726;"&gt;encoding&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;utf-8&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #004a43;"&gt; &lt;/span&gt;&lt;span style="color: #074726;"&gt;standalone&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0f4d75;"&gt;no&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #004a43;"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;qnx&lt;/span&gt; &lt;span style="color: #666616;"&gt;xmlns&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #666616;"&gt;http&lt;/span&gt;&lt;span style="color: purple;"&gt;:&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;//&lt;/span&gt;&lt;span style="color: #5555dd;"&gt;www.qnx.com&lt;/span&gt;&lt;span style="color: #40015a;"&gt;/schemas/application/1.0&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;id&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;org.demo.helloworld&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;id&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;filename&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;helloworld&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;filename&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;name&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;Hello PlayBook&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;name&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;versionNumber&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;1.0.0&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;versionNumber&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;description&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;Hello World Example Application&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;description&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;copyright&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;2011&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;copyright&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;initialWindow&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;systemChrome&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;none&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;systemChrome&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;transparent&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;false&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;transparent&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;autoOrients&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;true&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;autoOrients&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;aspectRatio&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;landscape&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;aspectRatio&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;initialWindow&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;publisher&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;Logicprobe.org&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;publisher&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;permission&lt;/span&gt; &lt;span style="color: #274796;"&gt;system&lt;/span&gt;&lt;span style="color: #808030;"&gt;=&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;true&lt;/span&gt;&lt;span style="color: #0000e6;"&gt;"&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;run_native&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;permission&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;category&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;core.games&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;category&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;icon&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;image&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;res/icon.png&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;image&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;icon&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #a65700;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;splashscreen&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;res/splashscreen.png&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;splashscreen&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #a65700;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #5f5035;"&gt;qnx&lt;/span&gt;&lt;span style="color: #a65700;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;The descriptor file is pretty standard for the PlayBook, and described in far greater detail within RIM's own documentation.The graphics are not provided here, but you can use any appropriately sized PNGs of your choosing.  If you omit the splash screen, remember to remove it from the descriptor file as well.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Building and installing&lt;/h4&gt;&lt;div style="border: 1px solid;"&gt;&lt;pre style="background: #ffffff; color: black;"&gt;~&lt;span style="color: #40015a;"&gt;/pbdev/helloworld&lt;/span&gt;&lt;span style="color: #797997;"&gt;$&lt;/span&gt; &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: #40015a;"&gt;/Qt/stage/nto/armle-v7/usr/lib/qt4/bin/qmake&lt;/span&gt;&lt;br /&gt;~&lt;span style="color: #40015a;"&gt;/pbdev/helloworld&lt;/span&gt;&lt;span style="color: #797997;"&gt;$&lt;/span&gt; make&lt;br /&gt;qcc  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;qcc  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;~&lt;span style="color: #40015a;"&gt;/pbdev/helloworld&lt;/span&gt;&lt;span style="color: #797997;"&gt;$&lt;/span&gt; make helloworld&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;bar&lt;br /&gt;blackberry-nativepackager  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;  &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;Info&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Package created&lt;span style="color: #808030;"&gt;:&lt;/span&gt; helloworld&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;bar&lt;br /&gt;~&lt;span style="color: #40015a;"&gt;/pbdev/helloworld&lt;/span&gt;&lt;span style="color: #797997;"&gt;$&lt;/span&gt; blackberry-deploy -installApp -device &lt;span style="color: #008c00;"&gt;192&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: #008c00;"&gt;168&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: #008c00;"&gt;1&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: #008c00;"&gt;42&lt;/span&gt; -password foobar helloworld&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;bar&lt;br /&gt;Info&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Sending request&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Install&lt;br /&gt;Info&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Action&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Install&lt;br /&gt;Info&lt;span style="color: #808030;"&gt;:&lt;/span&gt; File size&lt;span style="color: #808030;"&gt;:&lt;/span&gt; &lt;span style="color: #008c00;"&gt;6646238&lt;/span&gt;&lt;br /&gt;Info&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Installing &lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;Info&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Processing &lt;span style="color: #008c00;"&gt;6646238&lt;/span&gt; bytes&lt;br /&gt;Info&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Progress &lt;span style="color: #008c00;"&gt;0&lt;/span&gt;%&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;Info&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Progress &lt;span style="color: #008c00;"&gt;21&lt;/span&gt;%&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;Info&lt;span style="color: #808030;"&gt;:&lt;/span&gt; Progress &lt;span style="color: #008c00;"&gt;97&lt;/span&gt;%&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;br /&gt;actual_dname&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;org&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;demo&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;helloworld&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;testDev__helloworld32c52fe1&lt;br /&gt;actual_id&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;testDev__helloworld32c52fe1&lt;br /&gt;actual_version&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;span style="color: #008c00;"&gt;1&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;span style="color: maroon; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span style="color: #008c00;"&gt;0&lt;/span&gt;&lt;br /&gt;result&lt;span style="color: #808030;"&gt;:&lt;/span&gt;&lt;span style="color: #808030;"&gt;:&lt;/span&gt;success&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;And that's all there is to it!  If the size of the BAR file bothers you, try experimenting around to see if you can get away with including a smaller subset of the Qt libraries or building Qt with fewer features.  However, the bulk of that size is from QtCore and QtGui.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-1855491526980229155?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/1855491526980229155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=1855491526980229155' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/1855491526980229155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/1855491526980229155'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2011/10/qt-for-blackberry-playbook.html' title='Qt for the BlackBerry PlayBook'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-2283683524152805993</id><published>2011-10-02T15:20:00.001-04:00</published><updated>2011-10-04T21:36:05.246-04:00</updated><title type='text'>The mythical $800 hammer</title><content type='html'>I'm currently at the cusp of a major job transition.&amp;nbsp; For many years, my career has revolved around the world of Gov't contracts.&amp;nbsp; This began with a brief but meaningful stint as a federal employee, and has continued as a long journey through the world of Gov't contracting.&amp;nbsp; I've had a lot of personal reservations about this world, mainly in terms of the dynamics of the business models it supports.&amp;nbsp; With all the doom and gloom currently overshadowing the federal budget, and the industry downsizing and reorganization that is likely to follow, I think its time for me to move on.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For the last few years, I've spent a lot of my personal time on a major BlackBerry &lt;a href="http://www.logicmail.org/"&gt;software project&lt;/a&gt;.&amp;nbsp; At many points, this personal project has provided far more interesting technical challenges and professional growth opportunities than what I was actually being paid to work on.&amp;nbsp; Soon I'll be flipping it all around, and doing mobile software development as my actual day job.&amp;nbsp; I'm curious to see how it will go, and especially how I'll sink or swim in the faster-paced world of non-gov't software development.&lt;br /&gt;&lt;br /&gt;That all being said, I'd like to offer some slightly tongue-in-cheek commentary on why everything the Gov't buys is so expensive:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Where does the $800 Hammer come from?&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;First you need to have a DARPA program to fund research into advanced nail insertion technology (ANIT)&lt;/li&gt;&lt;li&gt; Then you have some Federally-Funded Research and Development Center (FFRDC) do an involved trade study that concludes that a simple hammer is preferable to the DARPA-developed ANIT prototype.&lt;/li&gt;&lt;li&gt; A program executive office (PEO) now hosts an industry day presentation on the US Army's Tactical Hammer Needs to the tool-making industries&lt;/li&gt;&lt;li&gt; The PEO now publishes a Request For Information (RFI) to solicit information from industry on steel hardening and handle-forming capabilities that could be used for the hammers&lt;/li&gt;&lt;li&gt; Finally a Request for Proposal (RFP) is published, along with a detailed performance spec, requirements list, and statement of work&lt;/li&gt;&lt;ul&gt;&lt;li&gt;There are a limited number of hammers desired, with options for buying more later&lt;/li&gt;&lt;li&gt;They also have to conform to various Military standards that no tool you'd buy at Home Depot would ever have to conform to&lt;/li&gt;&lt;li&gt;They need to be made in the US in a facility that holds the proper security clearances&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;The PEO finally selects one of the submitted proposals, awarding the contract&lt;/li&gt;&lt;ul&gt;&lt;li&gt;One of the loosing contractors decides to file a formal protest, and drags the process out longer&lt;/li&gt;&lt;li&gt;Eventually a settlement is made, and the selected prime contractor takes them on as a subcontractor for handle-to-head integration tasks&lt;/li&gt;&lt;/ul&gt;&lt;li&gt; After several rounds of requirements engineering, systems engineering, and product R&amp;amp;D, along with approvals at preliminary and critical design reviews (PDR/CDR), the government gives the go-ahead to enter Low-Rate Initial Production (LRIP)&lt;/li&gt;&lt;li&gt;Testing eventually finds issues in the initial batch.  Some design changes are made, costs are passed along, and eventually the hammer enters full-rate production (FRP)&lt;/li&gt;&lt;li&gt; Following training and deployment, the MK42 Tactical Nail Insertion Device (code-name "Hammer") is deployed into the field&lt;/li&gt;&lt;li&gt;Meanwhile, nails are getting tougher, and follow-on program for the MK49 Objective Nail Banger is announced&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-2283683524152805993?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/2283683524152805993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=2283683524152805993' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/2283683524152805993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/2283683524152805993'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2011/10/mythical-800-hammer.html' title='The mythical $800 hammer'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-4341604246694412529</id><published>2008-03-07T11:14:00.000-05:00</published><updated>2011-10-24T02:11:20.221-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>C# WTF: Abuse of events</title><content type='html'>Someone actually noticed my last post, so I'm going to start putting more of that stuff on here.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Getting a property through events:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Common uses:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Pretending to decouple classes for no apparent reason.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;\red0\green128\blue0;}??\fs20     \cf3 public\cf0  \cf3 delegate\cf0  \cf3 int\cf0  \cf4 GetSomeValueDelegate\cf0 ();\par ??\par ??    \cf3 class\cf0  \cf4 Foo\par ??\cf0     \{\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 GetSomeValueDelegate\cf0  GetSomeValue;\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  DoStuff()\par ??        \{\par ??            \cf5 /* . . . */\par ??\cf0             \cf3 if\cf0  (\cf3 this\cf0 .GetSomeValue != \cf3 null\cf0  &amp;amp;&amp;amp; \cf3 this\cf0 .GetSomeValue &amp;gt; 4)\par ??            \{\par ??                OtherStuff();\par ??            \}\par ??            \cf5 /* . . . */\par ??\cf0         \}\par ??    \}\par ??\par ??    \cf3 class\cf0  \cf4 Bar\par ??\cf0     \{\par ??        \cf3 private\cf0  \cf4 Foo\cf0  foo;\par ??        \cf3 private\cf0  \cf3 int\cf0  someValue;\par ??\par ??        \cf3 public\cf0  Bar()\par ??        \{\par ??            foo = \cf3 new\cf0  \cf4 Foo\cf0 ();\par ??            foo.GetSomeValue += \cf3 new\cf0  \cf4 GetSomeValueDelegate\cf0 (\cf3 this\cf0 .HandleGetSomeValue);\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  Run()\par ??        \{\par ??            foo.DoStuff();\par ??        \}\par ??\par ??        \cf3 private\cf0  \cf3 int\cf0  HandleGetSomeValue()\par ??        \{\par ??            \cf3 return\cf0  \cf3 this\cf0 .someValue;\par ??        \}\par ??    \}\par ??}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;delegate&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;GetSomeValueDelegate&lt;/span&gt;();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Foo&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;event&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;GetSomeValueDelegate&lt;/span&gt; GetSomeValue;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; DoStuff()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;/* . . . */&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (&lt;span style="color: blue;"&gt;this&lt;/span&gt;.GetSomeValue != &lt;span style="color: blue;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.GetSomeValue &amp;gt; 4)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; OtherStuff();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;/* . . . */&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Bar&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Foo&lt;/span&gt; foo;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; someValue;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; Bar()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foo = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Foo&lt;/span&gt;();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foo.GetSomeValue += &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;GetSomeValueDelegate&lt;/span&gt;(&lt;span style="color: blue;"&gt;this&lt;/span&gt;.HandleGetSomeValue);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Run()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foo.DoStuff();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; HandleGetSomeValue()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.someValue;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Common variants:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Having the event return a reference to the Bar instance that manages Foo.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Having the event return a property of singleton that is accessible from both classes.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Externalizing logic through events&lt;/span&gt;&lt;br /&gt;Common uses:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Decoupling a class from its internal logic.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;\red43\green145\blue175;}??\fs20     \cf3 public\cf0  \cf3 delegate\cf0  \cf3 void\cf0  \cf4 ResultsEventHandler\cf0 (\cf3 string\cf0 [] results);\par ??\par ??    \cf3 class\cf0  \cf4 Foo\par ??\cf0     \{\par ??        \cf3 public\cf0  \cf3 event\cf0  \cf4 ResultsEventHandler\cf0  ResultsEvent;\par ??\par ??        \cf3 private\cf0  \cf3 string\cf0 [] resultsData;\par ??\par ??        \cf3 public\cf0  \cf3 string\cf0 [] Results\par ??        \{\par ??            \cf3 get\cf0  \{ \cf3 return\cf0  \cf3 this\cf0 .resultsData; \}\par ??            \cf3 set\cf0  \{ \cf3 this\cf0 .resultsData = \cf3 value\cf0 ; \}\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  DoStuff()\par ??        \{\par ??            \cf3 string\cf0 [] results = PerformOperation();\par ??            \cf3 if\cf0  (ResultsEvent != \cf3 null\cf0 )\par ??            \{\par ??                ResultsEvent(results);\par ??            \}\par ??        \}\par ??    \}\par ??\par ??    \cf3 class\cf0  \cf4 FooManager\par ??\cf0     \{\par ??        \cf3 private\cf0  \cf4 Foo\cf0  foo;\par ??        \cf3 private\cf0  Bar bar;\par ??\par ??        \cf3 public\cf0  FooManager()\par ??        \{\par ??            foo = \cf3 new\cf0  \cf4 Foo\cf0 ();\par ??            bar = \cf3 new\cf0  Bar();\par ??            foo.ResultsEvent += \cf3 new\cf0  \cf4 ResultsEventHandler\cf0 (\cf3 this\cf0 .OnResultsEvent);\par ??        \}\par ??\par ??        \cf3 public\cf0  \cf3 void\cf0  DoStuff()\par ??        \{\par ??            foo.DoStuff();\par ??            ProcessResults(foo.Results);\par ??        \}\par ??\par ??        \cf3 private\cf0  \cf3 void\cf0  OnResultsEvent(\cf3 string\cf0 [] results)\par ??        \{\par ??            foo.Results = results;\par ??            bar.Data = results;\par ??        \}\par ??    \}\par ??}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;delegate&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ResultsEventHandler&lt;/span&gt;(&lt;span style="color: blue;"&gt;string&lt;/span&gt;[] results);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Foo&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;event&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ResultsEventHandler&lt;/span&gt; ResultsEvent;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt;[] resultsData;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt;[] Results&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;get&lt;/span&gt; { &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;this&lt;/span&gt;.resultsData; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;set&lt;/span&gt; { &lt;span style="color: blue;"&gt;this&lt;/span&gt;.resultsData = &lt;span style="color: blue;"&gt;value&lt;/span&gt;; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; DoStuff()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;string&lt;/span&gt;[] results = PerformOperation();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (ResultsEvent != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ResultsEvent(results);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;FooManager&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Foo&lt;/span&gt; foo;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; Bar bar;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; FooManager()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foo = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;Foo&lt;/span&gt;();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; bar = &lt;span style="color: blue;"&gt;new&lt;/span&gt; Bar();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foo.ResultsEvent += &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af;"&gt;ResultsEventHandler&lt;/span&gt;(&lt;span style="color: blue;"&gt;this&lt;/span&gt;.OnResultsEvent);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; DoStuff()&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foo.DoStuff();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ProcessResults(foo.Results);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; OnResultsEvent(&lt;span style="color: blue;"&gt;string&lt;/span&gt;[] results)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; foo.Results = results;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; bar.Data = results;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-4341604246694412529?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/4341604246694412529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=4341604246694412529' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/4341604246694412529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/4341604246694412529'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2008/03/c-wtf-abuse-of-events.html' title='C# WTF: Abuse of events'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-1690478094420894684</id><published>2008-01-03T10:31:00.000-05:00</published><updated>2011-10-24T02:11:20.208-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>C# WTF: Abuse of exception handlers</title><content type='html'>I've started collecting assorted examples of bad code, and will start periodically posting them.  Everything seen here was first seen in real code (and fixed, when possible).  Just remember, these are examples of what you shouldn't ever do! :-)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Type checking by InvalidCastException:&lt;/span&gt;&lt;br&gt;&lt;br /&gt;Common uses:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Checking the type of an object in a collection when the developer does not know about the "&lt;span style="font-weight:bold;"&gt;is&lt;/span&gt;" operator or its equivalents.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red43\green145\blue175;\red0\green0\blue255;\red0\green128\blue0;\red163\green21\blue21;}??\fs20             \cf3 Selection\cf0  selItems = \cf3 UtilServices\cf0 .GetInstance().GetSelectedItems();\par ??            \cf4 if\cf0  (selItems != \cf4 null\cf0 )\par ??            \{\par ??                \cf4 try\par ??\cf0                 \{\par ??                    \cf4 foreach\cf0  (\cf4 object\cf0  item \cf4 in\cf0  selItems)\par ??                    \{\par ??                        \cf5 // Cast to a Foo Item.\par ??\cf0                         \cf3 FooItem\cf0  fooItem = (\cf3 FooItem\cf0 )item;\par ??                    \}\par ??                    ProcessSuccess();\par ??                \}\par ??                \cf4 catch\cf0  (System.\cf3 Exception\cf0  ex)\par ??                \{\par ??                    \cf5 // If an exception is thrown, the items are not FooItems\par ??\cf0                     \cf3 Logger\cf0 .Error(\cf6 "Exception: "\cf0  + ex.Message);\par ??                    ProcessFailure();\par ??                \}\par ??            \}\par ??}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;Selection&lt;/span&gt; selItems = &lt;span style="color: #2b91af;"&gt;UtilServices&lt;/span&gt;.GetInstance().GetSelectedItems();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; (selItems != &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;try&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue;"&gt;object&lt;/span&gt; item &lt;span style="color: blue;"&gt;in&lt;/span&gt; selItems)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// Cast to a Foo Item.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;FooItem&lt;/span&gt; fooItem = (&lt;span style="color: #2b91af;"&gt;FooItem&lt;/span&gt;)item;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ProcessSuccess();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;catch&lt;/span&gt; (System.&lt;span style="color: #2b91af;"&gt;Exception&lt;/span&gt; ex)&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// If an exception is thrown, the items are not FooItems&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Logger&lt;/span&gt;.Error(&lt;span style="color: #a31515;"&gt;"Exception: "&lt;/span&gt; + ex.Message);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ProcessFailure();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Null checking by Exception handler:&lt;/span&gt;&lt;br&gt;&lt;br /&gt;Common uses:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Not being bothered by the hassle of all those "&lt;span style="font-weight:bold;"&gt;if&lt;/span&gt;" statements.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Consolas;}}{\colortbl;??\red0\green0\blue0;\red255\green255\blue255;\red0\green0\blue255;}??\fs20             \cf3 try\par ??\cf0             \{\par ??                foo = bar.GetSomeData();\par ??                thing = foo.ThingValue;\par ??            \}\par ??            \cf3 catch\par ??\cf0             \{\par ??                foo = bar.GetOtherData();\par ??                thing = foo.ThingValue;\par ??            \}\par ??}&lt;br /&gt;--&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;try&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foo = bar.GetSomeData();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; thing = foo.ThingValue;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: blue;"&gt;catch&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;{&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foo = bar.GetOtherData();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; thing = foo.ThingValue;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;}&lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-1690478094420894684?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/1690478094420894684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=1690478094420894684' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/1690478094420894684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/1690478094420894684'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2008/01/c-wtf-abuse-of-exception-handlers.html' title='C# WTF: Abuse of exception handlers'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-5791562554051357058</id><published>2007-04-12T08:07:00.000-04:00</published><updated>2011-10-24T02:11:20.227-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Converting from a DIB to a System.Drawing.Bitmap</title><content type='html'>Yes, I even do some .NET programming in C# these days.  Don't worry, its just at my day job.  In any case, since everyone and their brother, cousin, and best friend seems to have a blog with random .NET tidbits, I figured I'd add one here too.  (Speaking of which...  Please, people, your blogs aren't so important that you need to fill 75% of it with links to other people's blog postings, lest your "special" readers never know about them.  It makes Googling painful at times.)&lt;br /&gt;&lt;br /&gt;In any case, I found myself inside some code that got an image (in native Windows "DIB" format, as an object that was of type "byte[]") and needed to convert it into a System.Drawing.Bitmap.  The code actually did this already, by extracting the image size from the DIB header, creating a new Bitmap, then proceeding to iterate over every single pixel to directly set it in the Bitmap.  Obviously that was way too slow, and a better solution was needed.&lt;br /&gt;&lt;br /&gt;I then searched the web far and wide, not really finding anything useful.  Sure, there were a lot of hints, but no real solutions.  Bitmap itself actually has no easy way to be created from a byte array.  What it does have, strangely enough, is the ability to be created from a pointer to unmanaged memory and some hints:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;public Bitmap (&lt;br /&gt; int width,&lt;br /&gt; int height,&lt;br /&gt; int stride,&lt;br /&gt; PixelFormat format,&lt;br /&gt; IntPtr scan0&lt;br /&gt;)&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Since I had my data in a byte[], not as a chunk referenced by an IntPtr, the first step was to remedy the situation.  Here is how you do it, as weird as it may look:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;GCHandle handle = GCHandle.Alloc(dib, GCHandleType.Pinned);&lt;br /&gt;IntPtr handlePtr = handle.AddrOfPinnedObject();&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;(When you are done using the handle, don't forget to call "handle.Free()".)&lt;br /&gt;&lt;br /&gt;Now all I had to do was offset the IntPtr by 40 (size of the DIB header), add in the information the existing code already extracted from the header, and create a new bitmap.  Here's the final result:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;using System.Drawing;&lt;br /&gt;using System.Drawing.Imaging;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;...&lt;br /&gt;GCHandle handle = GCHandle.Alloc(dib, GCHandleType.Pinned);&lt;br /&gt;IntPtr handlePtr = handle.AddrOfPinnedObject();&lt;br /&gt;IntPtr scan0 = new IntPtr(handlePtr.ToInt32() + 40);&lt;br /&gt;Bitmap bitmap =&lt;br /&gt;    new Bitmap(width, height, width * 3, PixelFormat.Format24bppRgb, scan0);&lt;br /&gt;handle.Free();&lt;br /&gt;...&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;It may look ugly, and very icky, but it does work.  In fact, this allowed me to take an operation that took two whole seconds of wall-clock time and make it instantaneous.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-5791562554051357058?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/5791562554051357058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=5791562554051357058' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/5791562554051357058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/5791562554051357058'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2007/04/converting-from-dib-to.html' title='Converting from a DIB to a System.Drawing.Bitmap'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-116285802589320447</id><published>2006-11-06T18:57:00.000-05:00</published><updated>2011-10-24T02:11:20.203-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Frameworks, oh my!</title><content type='html'>Earlier this evening, I was having a little chat with my good friend and development wizard &lt;a href="http://codealchemy.blogspot.com/"&gt;Chris&lt;/a&gt;.  I was chatting with him about a recent frustration with the world of certain "Frameworks".&lt;br /&gt;&lt;br /&gt;As I proceed forward in a software engineering class project involving an application built on &lt;a href="http://java.sun.com/javaee/javaserverfaces/"&gt;JavaServer Faces&lt;/a&gt; running on top of &lt;a href="https://glassfish.dev.java.net/"&gt;GlassFish&lt;/a&gt;, I found myself reminded on &lt;a href="http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12"&gt;this rant&lt;/a&gt; someone sent me a link to recently.  While I ultimately have a far more balanced view, I do find his rambling somewhat amusing.&lt;br /&gt;&lt;br /&gt;So anyways, here's my rant:&lt;br /&gt;&lt;br /&gt;After a group meeting for my class, it looks like the most sensible way to design our web pages for this web app is essentially a templated composite view, so we can have standard headers, sidebars, etc, without having to code them on each page.&lt;br /&gt;&lt;br /&gt;As such, I start looking up how to do them properly in the context of JSF (JavaServer Faces), which conventionally uses JSP (JavaServer Pages) for its page description system.&lt;br /&gt;&lt;br /&gt;Then I start reading that you can do it this way, or that way, but that those ways all have problems for this reason or that reason.&lt;br /&gt;&lt;br /&gt;In fact, most conventional documents on how to use JSF ignore the problem completely.&lt;br /&gt;&lt;br /&gt;But when they discount all the obvious ways, they then recommend this alternate page composition system called "Facelets".&lt;br /&gt;&lt;br /&gt;So I start reading up on Facelets, and it says how they use XHTML instead of JSP, because JSP is bad for this reason or that reason, especially with JSF, and talk all about how Facelets and JSF go wonderfully together.&lt;br /&gt;&lt;br /&gt;As such, I look into what it'll take to have Facelets integrate cleanly with my chosen IDE (NetBeans), which I chose because it integrates so well with the other ways I was trying to do things.&lt;br /&gt;&lt;br /&gt;I discover a NetBeans plugin that'll let me to Facelets, and provide all that tag-completion on the XHTML files that I was getting in the JSP files.  Only problem is that its at version 0.3.&lt;br /&gt;&lt;br /&gt;I install it anyways, and finally figure it all out.&lt;br /&gt;&lt;br /&gt;In the end, Facelets has turned out to actually be a very nice solution, and I'm really happy with it.&lt;br /&gt;&lt;br /&gt;(and since JSF supports plugable page composition systems, it integrates cleanly and correctly too)&lt;br /&gt;&lt;br /&gt;But, given that JSF seemed to start from the basis of "we see all these other frameworks out there designed to fix/improve-upon what JSP provides", I wonder why I didn't start with reading about Facelets.&lt;br /&gt;&lt;br /&gt;(and in general, I'm actually quite pleased with the whole JSF approach)&lt;br /&gt;&lt;br /&gt;I just wish Facelets got more coverage in my JSF-bible-type book (published last month, co-authored by one of the spec leads).  All it got was a few examples in the short chapter on plugable page rendering libraries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-116285802589320447?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/116285802589320447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=116285802589320447' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/116285802589320447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/116285802589320447'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2006/11/frameworks-oh-my.html' title='Frameworks, oh my!'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-116222515349490149</id><published>2006-10-30T10:21:00.000-05:00</published><updated>2011-10-24T02:11:20.196-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>The Java Preferences API vs. MacOS 10.4</title><content type='html'>While it may not be obvious from all my sysadmin-style tinkering discussed in this blog, I am also a software developer.  Lately I've been working on a Java GUI program that has to save and load a complex tree of settings.  While the project is nearing its completion, I've decided to occasionally spend some time trying to find and fix various issues and performance bottlenecks.  This is the story of one of those bottlenecks...&lt;br /&gt;&lt;br /&gt;A common way to save and load application preferences in Java, is to use the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/prefs/Preferences.html"&gt;Preferences&lt;/a&gt; API.  This API uses a different back-end implementation on each operating system, but essentially provides a tree view for storing preferences.  Its implementation is also intended to make the backing-store somewhat transparent, so you just have to set your preferences.  There is no need to perform a "save" operation afterwards.&lt;br /&gt;&lt;br /&gt;Now first of all, I did want to make saving an explicit operation in my application.  So while I maintained my own configuration tree, writing it to nodes in the Java Preferences tree was a user-triggered operation.  Originally I also wrote out the Preferences tree to a file on disk, which was loaded in place of Java's Preferences store.  However, upon realizing that was a needless waste of resources, I removed the external configuration file.&lt;br /&gt;&lt;br /&gt;One major part of my application involves configuring a number of "thingies," where each "thingie" has a potentially large number of individual parameters directly under its configuration node.  A problem I noticed was that as I increased the number of "thingies" in the configuration, save and load became dramatically slower.  However, here's the really interesting part.  It only really became slower on MacOSX!  On my Linux test machine, the performance impact wasn't even noticeable!&lt;br /&gt;&lt;br /&gt;Thanks to the wonderful profiler in &lt;a href="http://www.netbeans.org/"&gt;NetBeans&lt;/a&gt;, I was able to track down this issue to functions under &lt;span style="font-style:italic;"&gt;"java.util.prefs.AbstractPreferences"&lt;/span&gt;, or more particularly &lt;span style="font-style:italic;"&gt;"java.util.prefs.MacOSXPreferences"&lt;/span&gt;.  Apparently the MacOSX implementation of the node() and various put() methods can be quite slow.  If you have enough of them, it really adds up.&lt;br /&gt;&lt;br /&gt;So how did I fix it?  Well, something a bit less elegant than how I was doing things before.  You see, the save and load methods for "thingie" configurations really just involved converting items between a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Map.html"&gt;Map&lt;/a&gt; and Preferences nodes.  Since the Map really just managed access to an object which contained a collection of simple types (String, Integer, etc.), I got an idea.  Why not just serialize the Map directly, and store it as a byte array in a Preferences node?  Sure, it may seem like a bit of an inelegant solution, but it worked!  Not only did it work, but it resulted in a MASSIVE performance increase.&lt;br /&gt;&lt;br /&gt;So how much of a performance improvement does this make?  Reading the program's configuration used to take 2195ms, according to the profiler.  It now only takes 956ms.  However, writing used to take 7314ms.  Now that number is down to 645ms!&lt;br /&gt;&lt;br /&gt;So, what did we learn?&lt;br /&gt;1. Java performance characteristics can vary wildly across operating systems.&lt;br /&gt;2. Object serialization to a byte array node in the Java Preferences system can be significantly faster than creating an elegant structure within the Java Preferences API to store a lengthy configuration, especially on MacOSX.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-116222515349490149?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/116222515349490149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=116222515349490149' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/116222515349490149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/116222515349490149'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2006/10/java-preferences-api-vs-macos-104.html' title='The Java Preferences API vs. MacOS 10.4'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-115715419176430378</id><published>2006-09-01T19:30:00.000-04:00</published><updated>2011-10-24T02:10:51.913-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sysadmin'/><title type='text'>Yet Another IPv6 Setup</title><content type='html'>Last weekend I got the bright idea to give IPv6 another attempt on my network.  I had previously tried it a while back, tunneling straight from my Cisco router.  However, I had an older Cisco router that could only do IPv6 on a "testing" build of IOS.  Being sick and tired of potential "issues" with this build, I wound up just ditching IPv6 for the time being.  At the time I had a single static IP, and I did not have any other &lt;span style="font-style: italic;"&gt;good&lt;/span&gt; configuration options.&lt;br /&gt;&lt;br /&gt;These days I have a connection with multiple static IPs, so I have more options available to myself now.  My current network config is also rather interesting, so allow me to illustrate:&lt;br /&gt;{Internet} ----&gt;(Cisco 4500 rtr)----&gt;(FreeBSD firewall)====&gt;{Multiple internal subnets}&lt;br /&gt;&lt;br /&gt;Basically I've banished all NAT to that Cisco, which does the common port-translating NAT for most machines on my network.  However, it also does 1:1 (bi-directional) NAT for my firewall and server machines.  The advantage of 1:1 NAT is that you &lt;span style="font-style: italic;"&gt;only&lt;/span&gt; translate the network address, and nothing else.  As such, you can use it for a lot more than just the usual restrictive TCP and UDP setup you have with port-translating NAT.  Of course 1:1 NAT does just translate network addresses, so you need to configure your firewall as if your machines did have public addresses.&lt;br /&gt;&lt;br /&gt;So coming out of the Cisco router, I have my private address range (with some public IPs mapped to some of the private IPs).  Just behind it, the FreeBSD firewall takes the next step.  First, it filters out any traffic I don't want going into my network (obviously).  Second, it takes this private address range and subnets it further.  (the internal side of the box is a VLAN trunk to my switches)  Yes, I have multiple subnets internally.  This lets me separate different types of traffic for the purposes of flexibility and/or security.&lt;br /&gt;&lt;br /&gt;Basically, I wanted to connect my various internal networks to the IPv6 Internet, by way of this FreeBSD firewall.  (FYI, the system is running FreeBSD 6.0-RELEASE at the time of this writing, and is named "Tritanium")  To accomplish this, I had two main options at my disposal:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Use a "tunnel broker" service (i.e. &lt;a href="http://tunnelbroker.net/"&gt;Hurricane Electric&lt;/a&gt;, &lt;a href="http://www.hexago.com/"&gt;Hexago&lt;/a&gt;, or &lt;a href="http://www.sixxs.net"&gt;Sixxs&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Use a 6to4 tunnel (&lt;a href="ftp://ftp.rfc-editor.org/in-notes/rfc3056.txt"&gt;RFC3056&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;The last time around, I used a tunnel broker.  However, this method depends on having an active account with an external service.  While that does work, it is a bit of an annoyance it would be nice to do without.&lt;br /&gt;As such, I decided to attempt 6to4 this time around.  The 6to4 method works by directly mapping your public IPv4 address into an IPv6 /48 subnet.  Then your border router essentially tunnels IPv6 packets directly inside IPv4 packets (as IP protocol 41).  What's really cool about this is that you don't need any external services or configurations.  If you go to an IPv6 site, and ping your local 6to4 address, you will see the inbound packets while sniffing your external interface.  So, with all that being set, time to get on to an account of my experiences:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 1: Figure out your IPv6 address&lt;/span&gt;&lt;br /&gt;This is probably the easiest step of the entire adventure.  You just take your public IPv4 address (yes, it does have to be a public routable address), convert it to hexadecimal, and tack it onto the end of the 6to4 prefix (2002).  For the sake of this writeup, lets assume our public address is "12.34.56.78".  In hex, that translates to "0C22384E".  So that translates into the following 6to4 subnet:&lt;br /&gt;2002:c22:384e::/48&lt;br /&gt;&lt;br /&gt;(IPv6 lets you omit leading zeros and abbreviate the end of the address, in case you were wondering.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 2: Configure the 6to4 tunnel&lt;/span&gt;&lt;br /&gt;This was probably one of the most frustrating steps, despite the fact that it looks like it &lt;span style="font-style: italic;"&gt;should&lt;/span&gt; be the easiest.  I blame my configuration more than anything else, though.  You see, while the external interface on Tritanium maps directly to a public IP address, it actually has a private IP address itself.&lt;br /&gt;&lt;br /&gt;In short, you have to configure FreeBSD's &lt;a href="http://www.freebsd.org/cgi/man.cgi?query=stf&amp;apropos=0&amp;amp;sektion=0&amp;manpath=FreeBSD+6.0-RELEASE&amp;amp;format=html"&gt;stf(4)&lt;/a&gt; interface with your 6to4 address, and then setup routing.  However, I had a bit of a problem.  You see, for this to work in both directions, two things had to happen.  First, Tritanium had to have something telling it that it did indeed have a relationship with its public IP.  Second, certain sanity checks (that prevent you from using stf with private IPs) had to be bypassed.&lt;br /&gt;&lt;br /&gt;The first step was easy.  I just created an alias on Tritanium's external interface with its public IP address, and a /32 netmask:&lt;br /&gt;# ifconfig fxp1 inet 12.34.56.78 netmask 0xffffffff alias&lt;br /&gt;&lt;br /&gt;The second step turned out to be a lot more involved.  What's going to happen is that Tritanium will be receiving incoming 6to4 packets where the IPv4 address (1:1 translated to a private IP by the Cisco router) will not match the IPv6 address (based on our public IP) contained within.  Let's just say that it does not work out of the box.  Upon reading the stf man page, it does however tell us that the: "Ingress filter can be turned off by IFF_LINK2 bit".  (this is the "link2" flag you can pass to ifconfig when setting up an interface)&lt;br /&gt;&lt;br /&gt;Glossing over what was an entire night of frustration and debugging, let's just say that LINK2 doesn't really do much of anything.  The stf interface driver has a lot of sanity checks, some failing with my configuration, and the "ingress filter" block of code that LINK2 disables isn't one of those checks.&lt;br /&gt;&lt;br /&gt;The fix I ultimately came up with involved fixing the source code (if_stf.c) to make the LINK2 flag disable the sanity checks that were failing on my setup.  The result of my fix can be summed up in &lt;a href="http://hyperion.logicprobe.org/%7Eocto/stuff/if_stf.patch"&gt;this&lt;/a&gt; patch.  (yes, it is against 6.0-RELEASE, but it shouldn't be hard to adapt to a newer version)&lt;br /&gt;&lt;br /&gt;Once that file was patched, and the kernel module reloaded, the next step was pretty simple:&lt;br /&gt;# ifconfig stf0 create&lt;br /&gt;# ifconfig stf0 inet6 2002:c22:384e::1 prefixlen 16 link2&lt;br /&gt;&lt;br /&gt;The third step involves setting up routing.  For this, we need to create a route to a public 6to4 router.  I took the easy way with this one, as there is a public "anycast" address for your nearest 6to4 router.  That address is 192.88.99.1 (in IPv4), or 2002:c058:6301:: (in 6to4 IPv6).  So I set my default IPv6 route to that:&lt;br /&gt;# route add -inet6 default 2002:c058:6301::&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3: Internal subnets and routing&lt;/span&gt;&lt;br /&gt;First I set IPv6 addresses on my internal interfaces, using subnets of the /48 that I got with 6to4:&lt;br /&gt;# ifconfig vlan1 inet6 2002:c22:384e:1::1 prefixlen 64&lt;br /&gt;# ifconfig vlan2 inet6 2002:c22:384e:2::1 prefixlen 64&lt;br /&gt;# ifconfig vlan3 inet6 2002:c22:384e:3::1 prefixlen 64&lt;br /&gt;# ifconfig vlan4 inet6 2002:c22:384e:4::1 prefixlen 64&lt;br /&gt;&lt;br /&gt;Then I enabled IPv6 forwarding:&lt;br /&gt;sysctl net.inet6.ip6.forwarding=1&lt;br /&gt;&lt;br /&gt;Finally, I enabled &lt;a href="http://www.freebsd.org/cgi/man.cgi?query=rtadvd&amp;apropos=0&amp;amp;sektion=0&amp;manpath=FreeBSD+6.0-RELEASE&amp;amp;format=html"&gt;rtadvd(8)&lt;/a&gt; in my rc.conf, and also told it which interfaces to run on (a subset of the ones above), and then started it:&lt;br /&gt;# /etc/rc.d/rtadvd start&lt;br /&gt;&lt;br /&gt;In case you were wondering, "rtadvd" is the router advertisement daemon.  Using it, all my internal IPv6-enabled systems will automatically learn their IPv6 network addresses and routers.  Pretty cool, eh?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 4: The firewall&lt;/span&gt;&lt;br /&gt;While the IPv6 Internet is probably not yet anywhere near as hazardous as the IPv4 internet, chances are that you still want some level of protection.  Since I used to use OpenBSD for my firewalls in the past, I had become accustomed to using &lt;a href="http://www.freebsd.org/cgi/man.cgi?query=pf&amp;apropos=0&amp;amp;sektion=0&amp;manpath=FreeBSD+6.0-RELEASE&amp;amp;format=html"&gt;pf(4)&lt;/a&gt;.  Unfortunately, I discovered that pf has a very annoying problem with my configuration.  Just having pf enabled (even with all rules flushed) seemed to inhibit IPv6 packet forwarding!  It was actually kinda strange how it behaved.  I could talk normally on the IPv6 Internet from Tritanium directly.  However, only ICMP worked correctly from my internal machines.  Outbound TCP and UDP packets were never forwarded across Tritanium, while inbound ones worked just fine.&lt;br /&gt;&lt;br /&gt;What's the solution?  Use &lt;a href="http://www.freebsd.org/cgi/man.cgi?query=ipfw&amp;apropos=0&amp;amp;sektion=0&amp;manpath=FreeBSD+6.0-RELEASE&amp;amp;format=html"&gt;ipfw(8)&lt;/a&gt; instead of pf, and your problem will be solved.  Just make sure you configure the IPv4 side of ipfw so that IP protocol 41 packets are permitted unscathed.  (my version wouldn't let me specifically allow proto 41, for some strange reason, so I just permitted all IP packets that I hadn't explicitly blocked with some other rules elsewhere in my configuration.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 5: And there was much rejoicing!&lt;/span&gt;&lt;br /&gt;I'm now connected to the IPv6 internet, after a week's worth of evening tinkering.  Yippee!&lt;br /&gt;I may eventually put all my configurations into rc.conf (I had some difficulties when I first tried, and gave up soon afterwards), but right now most of this stuff is just running out of rc.local on the machine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-115715419176430378?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/115715419176430378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=115715419176430378' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/115715419176430378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/115715419176430378'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2006/09/yet-another-ipv6-setup.html' title='Yet Another IPv6 Setup'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-115560904606552748</id><published>2006-08-14T22:15:00.000-04:00</published><updated>2011-10-24T02:10:51.908-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sysadmin'/><title type='text'>Solaris Live Upgrade (on an SVM mirror set)</title><content type='html'>Many of you have probably heard of Sun's live upgrade feature by now.  Live upgrade essentially lets you upgrade your system from one Solaris version to another with minimal downtime.  If done right, the only downtime you need to suffer is the time required for rebooting your server.&lt;br /&gt;&lt;br /&gt;Live Upgrade works like this:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Create a "boot environment" (BE) representing your current system&lt;/li&gt;&lt;li&gt;Create an "alternate boot environment" (ABE) which is a clone of your BE&lt;/li&gt;&lt;li&gt;Run a Solaris upgrate against the ABE&lt;/li&gt;&lt;li&gt;Switch the active "boot environment" to the ABE&lt;/li&gt;&lt;li&gt;Reboot&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Seems simple enough, right?  Well, on the surface it does seem simple.  There's just one problem.  You need an empty partition to use as the ABE!  You know what really annoyed me though?  Most of the LU examples and docs I've read seem to involve using some random extra scrap of a partition for the ABE.  Well, as you can probably guess, the ABE becomes your system boot partition at the end of this process.  Do you really want some random scrap partition to be your system partition for the long term?  I certainly didn't.&lt;br /&gt;&lt;br /&gt;This whole procedure is also easier if you separate your system partitions from your data ones.  Yes, I know this is normally a good practice.  However, I've grown to just use a huge "/" and smaller "/var" on most of my machines these days.  It's just easier, and I still have "/home" on an external file server.&lt;br /&gt;&lt;br /&gt;So what was I to do?  The Solaris 10 6/06 DVD set was here, and I wanted to upgrade.  (my server was running the original Solaris 10 release)  I needed something large to make my ABE on, but also needed it to be somewhere I was comfortable using as my long-term boot drive.  I also wanted to avoid involving anything beyond that server itself.  Then it occured to me...  the "system disk" of my server was actually an SVM mirror set!&lt;br /&gt;&lt;br /&gt;In short form, here was my plan of action:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Make a backup&lt;/span&gt; (thankfully this machine has a DDS3 drive installed in it)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Remove the second disk from the mirror and unconfigure its meta devices&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Run live upgrade, using that second disk as the ABE&lt;/li&gt;&lt;li&gt;Switch the default BE to the one on the second disk&lt;/li&gt;&lt;li&gt;Boot off the second disk, into the new version of Solaris&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;Make sure the server is still working correctly&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Unconfigure the mirror devices in SVM&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Recreate the meta devices on the second disk, mirrors containing them, run metaroot, etc.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Reboot again&lt;/li&gt;&lt;li&gt;Add the first drive back into the mirrors&lt;/li&gt;&lt;/ul&gt;Seems simple enough, right? ;-)  When all is said and done, the goal was to have the same drive configuration before.  The only differences would be that my mirror components would be reversed, and I'd be running a newer version of Solaris.&lt;br /&gt;&lt;br /&gt;While I should now show a complete walkthrough of what I did,  a full post-mortem reconstruction would be rather tedious.  Besides, if you're familar with SVM and can read through Sun's LU docs, following my strategy should be straightforward and simple.  (yes, it does work)  Just remember to install the recommended patches before using LU, or it'll fail.&lt;br /&gt;&lt;br /&gt;Also, I strongly recommend mounting the upgraded ABE before that first reboot.  You should then check the "/var/sadm/system/data/upgrade_cleanup" file for any changes of interest that it made.  I failed to do this myself, and wound up having sendmail misconfigured for several hours.  On the bright side, it does make backup copies of any configuration files that it changes.&lt;br /&gt;&lt;br /&gt;Good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-115560904606552748?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/115560904606552748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=115560904606552748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/115560904606552748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/115560904606552748'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2006/08/solaris-live-upgrade-on-svm-mirror-set.html' title='Solaris Live Upgrade (on an SVM mirror set)'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-115560729092445382</id><published>2006-08-14T21:41:00.000-04:00</published><updated>2011-10-24T02:10:51.904-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sysadmin'/><title type='text'>Fun with Solaris 10 6/06 and ZFS</title><content type='html'>The 6/06 release of Solaris 10 finally incorporated ZFS as part of the operating system.  This is quite exciting, because now we can start using ZFS without having to run a Solaris Express or OpenSolaris distribution.  As such, I was itching to try it out.  I started by ordering the "Solaris Enterprise System" DVD stack from Sun.  Sure, I could have downloaded it, but its nicer to have a whole set of media already there for me.&lt;br /&gt;&lt;br /&gt;Now I needed a test system...  So I dug out my older Ultra 60 workstation, hooked up a DVD drive, and a few hours later I was good to go.  Thus far, the only real change I noticed from the original Solaris 10 release was a newer and nicer looking login screen.&lt;br /&gt;&lt;br /&gt;Time to hook up a boatload of hard drives!  I had an expansion box from my now-since-decomissioned CLARiiON FC RAID monster, good to go with 10x36GB 10krpm FC hard drives.  All I needed to do was connect them, reformat them with a normal block size (they were formated for 520 bytes instead of the normal 512, thanks to the CLARiiON controller), and I'd be good to go.  Unfortunately, all I had to connect them to was a QLogic QLA2100 FC HBA.  The QLA2100 isn't supported past Solaris 8, or so they'd lead you to believe.  Thankfully you just have to get the Solaris driver, unpack it from the package stream QLogic provides, modify the package to not complain about your Solaris version, and install it.  As expected, it then worked just fine.&lt;br /&gt;&lt;br /&gt;To fix the block size on the drives, I got the "scu" utility from &lt;a href="http://home.comcast.net/%7ESCSIguy/SCSI_FAQ/RMiller_Tools/scu.html"&gt;here&lt;/a&gt;, and then followed the instructions on &lt;a href="http://www.doki-doki.net/%7Elamune/computers/blocksize/index.html"&gt;this&lt;/a&gt; page.  All pretty straightforward, but it did take about an hour per drive.  It doesn't really do much I/O to to the drive from your system, though, so doing all the drives at once does speed things up.&lt;br /&gt;&lt;br /&gt;Finally, I went through "format" on each drive to fix the annoying "bad magic" messages.  Now I had 10 drives off the end of an FC link, all set and good to go!&lt;br /&gt;&lt;br /&gt;Setting up ZFS was really easy.  If you haven't done so yet, I strongly recommend going &lt;a href="http://www.opensolaris.org/os/community/zfs/"&gt;here&lt;/a&gt; to review their documentation and screencasts.  The specific commands are really easy to figure out, but that site shows them to you.  Essentially, with ZFS, you make a pool out of mirrors, RAID-Z sets, or individual disks.  You can then chop up the pool however you see fit.&lt;br /&gt;&lt;br /&gt;In any case, I tried a few configurations and ran some benchmarks.  Keep in mind that testing with "dd" and a large block size will ALWAYS yield better results than you'll ever see on a real benchmark program.  (I think I got up to 80MB/s with "dd" at some point)  Also, running multiple benchmark programs or "dd" sessions in parallel may also yield higher throughput.  FYI, I was connecting to all 10 drives over a single 100MB/s FC link.  So on with the results!&lt;br /&gt;&lt;br /&gt;One 10-drive RAID-Z set&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ bonnie++ -d . -s 2G&lt;br /&gt;Version  1.03       ------Sequential Output------ --Sequential Input- --Random-&lt;br /&gt;                  -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--&lt;br /&gt;Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP&lt;br /&gt;proxima          2G 14685  91 35308  48 23733  49 13301  92 52396  50 512.1  13&lt;br /&gt;                  ------Sequential Create------ --------Random Create--------&lt;br /&gt;                  -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--&lt;br /&gt;            files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP&lt;br /&gt;               16  4798  99 +++++ +++  7455  99  5230  99 +++++ +++  7350  97&lt;br /&gt;proxima,2G,14685,91,35308,48,23733,49,13301,92,52396,50,512.1,13,16,4798,99,+++++,+++,7455,99,5230,99,+++++,+++,7350,97&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;One 5-drive RAID-Z set&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ bonnie++ -d . -s 2G&lt;br /&gt;Version  1.03       ------Sequential Output------ --Sequential Input- --Random-&lt;br /&gt;                   -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--&lt;br /&gt;Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP&lt;br /&gt;proxima          2G 15241  94 32991  44 24989  45 13676  93 58862  52 550.2  10&lt;br /&gt;                   ------Sequential Create------ --------Random Create--------&lt;br /&gt;                   -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--&lt;br /&gt;             files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP&lt;br /&gt;                16  4821  97 +++++ +++  7509  99  5190  98 +++++ +++  7849  99&lt;br /&gt;proxima,2G,15241,94,32991,44,24989,45,13676,93,58862,52,550.2,10,16,4821,97,+++++,+++,7509,99,5190,98,+++++,+++,7849,99&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Two 5-drive RAID-Z sets&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ bonnie++ -d . -s 2G&lt;br /&gt;Version  1.03       ------Sequential Output------ --Sequential Input- --Random-&lt;br /&gt;                   -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--&lt;br /&gt;Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP&lt;br /&gt;proxima          2G 15051  92 30531  41 26045  47 14018  93 57507  56 864.6  12&lt;br /&gt;                   ------Sequential Create------ --------Random Create--------&lt;br /&gt;                   -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--&lt;br /&gt;             files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP&lt;br /&gt;                16  4908  99 +++++ +++  6800  95  4868  99 +++++ +++  5847  81&lt;br /&gt;proxima,2G,15051,92,30531,41,26045,47,14018,93,57507,56,864.6,12,16,4908,99,+++++,+++,6800,95,4868,99,+++++,+++,5847,81&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-115560729092445382?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/115560729092445382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=115560729092445382' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/115560729092445382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/115560729092445382'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2006/08/fun-with-solaris-10-606-and-zfs.html' title='Fun with Solaris 10 6/06 and ZFS'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-113958236919513053</id><published>2006-02-10T09:21:00.000-05:00</published><updated>2006-02-10T09:39:29.203-05:00</updated><title type='text'>Air Travel and Mobile Computing</title><content type='html'>Almost since their inception, laptop computers have been an increasingly popular implement of the air traveler.  You see them used both in airports and on airplanes, by more and more people.  However, airports and airplanes today do not provide a friendlier environment for laptop users than they did years ago.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Problem #1: Electrical power&lt;/span&gt;&lt;br /&gt;Regardless of what the makers of DC-DC converter bricks may tell you, most airplanes are not equipped with DC power outlets for passengers.  Occasionally you might find them in first class, and I once saw them in coach on a short Orlando-Atlanta flight, but normally they are simply not available.  As such, the only solution is having laptops with good battery life, and topping them off at airports in-between flights.&lt;br /&gt;&lt;br /&gt;Airports, however, aren't that great either.  Outlets in sitting areas tend to be very scarce, and often squatted by other laptop users or people who don't even realize they're in the way.  I frequently find myself scouring the entire food court, or the entire gate waiting area, only seeing one or two outlets.  Even then, I'm lucky to get access to them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Problem #2: Internet access&lt;/span&gt;&lt;br /&gt;Access while on airplanes is something we presently don't expect, and thus can live without.  After all, for most domestic trips, the airlines don't want to keep you on the same one for more than 2 hours anyways.  Sure, there is talk about installing access, but you all know how that's going to be done.  It'll be prohibitively expensive, and/or only offered to first class, and will wind up being practically unavailable to your average laptop-toting passenger.  (Remember the sky phones?)&lt;br /&gt;&lt;br /&gt;Airports, however, have been installing Wi-Fi access points all over the place.  Except, they do it in a way that makes it nearly useless.  First, they all insist on charging for access.  This is a problem because even though it is usually cheap, it is still hard to justify $5.95-9.95 for a 10 minute E-Mail check between flights.  (thankfully I can use GPRS on my cell phone instead)  If you are a frequent traveller, they do have monthly access plans.  Of course every airport's Wi-Fi installation is managed by a different organization, and thus these plans are worthless unless you fly the "exact same trip" with long layovers on a regular basis.  In essense, airport internet access is implemented in such a way that it is practically useless to most travelers on a 1-hour layover.  (Well, at least until there are popular programs that can tunnel IP over DNS and ICMP, which are the only things their proxies seem to let out onto the global internet.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-113958236919513053?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/113958236919513053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=113958236919513053' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113958236919513053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113958236919513053'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2006/02/air-travel-and-mobile-computing.html' title='Air Travel and Mobile Computing'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-113923383486983985</id><published>2006-02-06T08:42:00.000-05:00</published><updated>2006-02-06T08:50:34.870-05:00</updated><title type='text'>New blog!</title><content type='html'>My blog on LiveJournal was more like a collage of personal ramblings and reflections, and the blogs there from various friends of mine were also like that.  As such, I've decided to separate out the technical content.  Below you'll see a bunch of technical posts that I've copied over here.  In the future, I hope to put all my technical postings on this site instead.&lt;br /&gt;&lt;br /&gt;Why am I doing this?  Well, the reasons are two-fold.  First, most technical postings on LJ would get lost in the noise of personal-life ramblings from everyone on everyone else's friends pages.  Second, I'd rather post these in a forum open to people that really have no need nor desire to know about any of my own personal-life ramblings.&lt;br /&gt;&lt;br /&gt;I'd also like to have a personal tech blog to complement my efforts on this website:&lt;br /&gt;&lt;a href="http://www.hecomputing.org/"&gt;Household Enterprise Computing&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As well as my tinkerings with this excessive collection of operational computer hardware:&lt;br /&gt;&lt;a href="http://www.logicprobe.org/systems/"&gt;Logicprobe Systems List&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;(or any of the many less-operational boxes that I didn't bother to list there)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If anyone still wants to know exactly what I consider "Household Enterprise Computing" to be, &lt;a href="http://www.hecomputing.org/?page_id=6"&gt;here&lt;/a&gt; is a good writeup that I did a while ago.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-113923383486983985?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/113923383486983985/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=113923383486983985' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923383486983985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923383486983985'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2006/02/new-blog.html' title='New blog!'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-113923292285342874</id><published>2005-12-18T22:55:00.000-05:00</published><updated>2011-10-24T02:10:51.898-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sysadmin'/><title type='text'>The Objective Rack - Mark IV</title><content type='html'>Behold, the &lt;a href="http://www.logicprobe.org/gallery/v/octo/objrack4/"&gt;The Objective Rack - Mark IV&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;This whole rack-rebuild project took most of Saturday. Thankfully everything of mine came up ok afterwards. Unfortunately a friend's server (that I've started hosting as of last weekend) didn't come up so easily. After a whole night of frantic tinkering attempts, I backed up all the data I could salvage and we reinstalled it this morning.&lt;br /&gt;&lt;br /&gt;This is but the latest in a continual cycle I go through....&lt;br /&gt;1) Build rack all nice and neat&lt;br /&gt;2) Use new setup for a while&lt;br /&gt;3) Gradually decide to change things over time (add new machines, remove old machines, etc.)&lt;br /&gt;4) Decide that the once-elegant rack has become a mess of tangled wires and ad-hoc mounting&lt;br /&gt;5) Tear it down and repeat from step 1.&lt;br /&gt;&lt;br /&gt;As I said, this is the 4th iteration of my attempts at building a rack of computer equipment for my personal use. Here's the history in chronological order:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.logicprobe.org/%7Eocto/myroom/apt/rack.jpg"&gt;Mark I&lt;/a&gt; - Moved to an apartment in Florida, bought the rack in the process, got everything all setup. Many of my systems weren't rackmount, so I used a lot of rack-mount shelves.&lt;br /&gt;&lt;a href="http://www.logicprobe.org/gallery/v/octo/album06/"&gt;Mark II&lt;/a&gt; - Upgraded a lot of equipment, had a lot of new stuff to mount (including an E4000 and a big RAID box), and took the desktops out of the rack. First use of the term "objective rack".&lt;br /&gt;Mark III - Moved from the apartment to a house, finally had the proper mounting kit for the E4000, needed to get everything setup again.&lt;br /&gt;&lt;a href="http://www.logicprobe.org/gallery/v/octo/objrack4/"&gt;Mark IV&lt;/a&gt; - Retired some of the more power-hungry equipment (E4000 and big RAID box), changed a lot of systems around, had some new equipment and cable-guide stuff to integrate.&lt;br /&gt;&lt;br /&gt;Prior to the rack, I went through a series of wire-shelf-based setups.  These began my sophomore year of college with &lt;a href="http://www.logicprobe.org/%7Eocto/myroom/octos_equipment.jpg"&gt;this setup&lt;/a&gt;, and continued with a new iteration every academic year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-113923292285342874?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/113923292285342874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=113923292285342874' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923292285342874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923292285342874'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2005/12/objective-rack-mark-iv.html' title='The Objective Rack - Mark IV'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-113923285726620646</id><published>2005-12-06T23:16:00.000-05:00</published><updated>2011-10-24T02:10:51.893-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sysadmin'/><title type='text'>Fun with LDAP and Kerberos</title><content type='html'>Several weeks ago I decided that I want my firewall to no longer be a Solaris machine, and that I wanted a dedicated authentication/utility server. The goal was to decouple my internal utility services (authentication, DNS, NTP, etc.) from my main servers. So I dug up a cheap 1U server, put FreeBSD on it, made it my firewall/internal-router/external-DNS/et&lt;div style="text-align: left;"&gt;&lt;wbr&gt;c. box, and took my Netra T1 out of production.&lt;br /&gt;&lt;br /&gt;Since the Netra T1 was to be the new auth server, I began last week by blowing away its prior installation and giving it a fresh load of Solaris 10. (note: always remember to make the small dedicated partition for the SVM metadb replicas *before* installing Solaris) I then got my internal DNS migrated to it, as well as NTP.&lt;br /&gt;&lt;br /&gt;For a while, I was running good 'ole NIS to do my distributed user accounts. Of course its an old protocol, and everyone says to upgrade, but it "just f**ing works", and I can configure it in my sleep on just about any *nix. Of course the whole point of this auth server was to try something new. Originally I knew I wanted to take a shot at LDAP again, as I've tried (and failed) before, going back to NIS. As I approached this past weekend, and did some reading, I decided to take a bigger chunk and try LDAP with Kerberos.&lt;br /&gt;&lt;br /&gt;So on Saturday I brought the Netra out to the LEAP Installfest, and started getting OpenLDAP and the Kerberos that comes with Solaris (SEAM) all installed and configured. By Sunday afternoon, I was still tinkering, and things still weren't yet working right. I figured out how to migrate my NIS accounts into LDAP, knew how to make users in Kerberos, but client authentication just wasn't working right. (it sort-of worked to my FreeBSD server, and didn't work with my Solaris one) I spend way too much time staring at PAM debuging output, and continued to be baffled.&lt;br /&gt;&lt;br /&gt;So I said f*ck it, pulled out OpenLDAP, and went and installed "Sun Java System Directory Server 5.2". (which used to be called SunONE *something*, which used to be called iPlanet *something*, which used to be Netscape *something*) The name sounds fancy, but it really is just an LDAP server with some graphical (and the usual command-line) admin tools.&lt;br /&gt;&lt;br /&gt;After tinkering all night, it was almost working. In the morning I figured out the magic extra LDAP user parameter to finally get authentication working. So by sometime Monday morning, I could do name lookups and authentication against the SJSDS LDAP server from both my Solaris and FreeBSD servers. However, while I had SSL configured on the LDAP server, it wasn't reaching down to the clients.&lt;br /&gt;&lt;br /&gt;I spent all of last night attacking the SSL issue... You see, LDAP isn't really a good authentication protocol (which is different from an authorization/lookup protocol, which it is decent at). Without SSL, you have 2 authentication types... simple (your client sends your password IN CLEAR TEXT over the wire to the LDAP server), and CRAM-MD5/DIGEST-MD5 (the password isn't in the clear on the wire, but it is IN CLEAR TEXT in the LDAP database itself. (thus breaking my desire for password-hash compatability with the data I imported from NIS) In any case, but the end of the night, I got simple authentication with SSL working. Thus, no cleartext passwords anywhere.&lt;br /&gt;&lt;br /&gt;Then tonight I got brave again... You see, the Sun JSDS docs do have a good writeup on integrating Kerberos. But when I initially tried it, the ns-slapd process (the LDAP server itself) kept core-dumping. Apparently, this was a known issue according to the release notes, and there was even a fix (which worked!). So as of the middle of this evening, I actually succeeded in getting LDAP+Kerberos fully functional across all my remote-access systems. I even figured out how to convince PAM on my Solaris server to use SSL LDAP authentication for users that don't yet have a Kerberos principal. (couldn't figure out how to tweak PAM to do that seemlessly on FreeBSD, though.) Now that Kerberos is working, its only a matter of time before I find myself fully taking advantage of what it has to offer.&lt;br /&gt;&lt;br /&gt;In any case, I think I've conquered LDAP+Kerberos. Next step is to eventually get around to figuring out exactly what I did, and producing a detailed technical writeup to help others in the future. (sure, the web is full of such writeups, but they're all partial and I needed to piece together hints from all of them to get things working.)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-113923285726620646?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/113923285726620646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=113923285726620646' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923285726620646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923285726620646'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2005/12/fun-with-ldap-and-kerberos.html' title='Fun with LDAP and Kerberos'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-113923279136813187</id><published>2005-10-31T16:05:00.000-05:00</published><updated>2011-10-24T02:10:51.876-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sysadmin'/><title type='text'>Reflections on uber-geekness...</title><content type='html'>As extreme and weird as we may seem in our computer-related projects, the truth is that we're often doing the same things as normal users. Its just that we find much more sophisticated ways of accomplishing them...&lt;br /&gt;&lt;br /&gt;Normal people use laptops to get computing anywhere in the house.&lt;br /&gt;Ubergeeks deploy a server infrastructure with a hot-desktable thin-client solution.&lt;br /&gt;&lt;br /&gt;Normal people check e-mail through their ISP or something like gmail/hotmail/etc.&lt;br /&gt;Ubergeeks run their own e-mail server with IMAP+SSL, SMTP AUTH, and server-side mail filtering.&lt;br /&gt;&lt;br /&gt;Normal people use their desktop PC when they need to run a Windows application.&lt;br /&gt;Ubergeeks install Windows 2000 Server on a SunPCi card in their Sun enterprise server and install Citrix Metaframe Presentation Server to provide multi-user Windows application access authenticated through Samba, and still refuse to play Snood.&lt;br /&gt;&lt;br /&gt;Normal people listen to MP3s with WinAmp or iTunes off their desktop's hard drive.&lt;br /&gt;Ubergeeks mount an NFS export from their RAID file server and play the MP3s in XMMS.&lt;br /&gt;&lt;br /&gt;Normal people watch movies off their DVD player or their cable services.&lt;br /&gt;Ubergeeks construct network-booted machines running MythTV to stream movies off their RAID file server.&lt;br /&gt;&lt;br /&gt;Normal people buy telephones at Walmart and use them to talk to their friends.&lt;br /&gt;Ubergeeks run Cat5e across their houses, and deploy an IP Telephony solution through an Asterisk box.&lt;br /&gt;&lt;br /&gt;Normal people think a "router" is an $80 Linksys box you buy at CompUSA that lets them connect multiple PCs to the internet.&lt;br /&gt;Ubergeeks think a "router" is a multi-service rackmount Cisco device with ethernet, T1, and frame-relay interfaces, capable of supporting OSPF and BGP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-113923279136813187?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/113923279136813187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=113923279136813187' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923279136813187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923279136813187'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2005/10/reflections-on-uber-geekness.html' title='Reflections on uber-geekness...'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-113923274437341275</id><published>2005-10-28T09:13:00.000-04:00</published><updated>2011-10-24T02:10:51.872-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Sysadmin'/><title type='text'>A necessary evil...</title><content type='html'>Yup, I'm talking about Windows here. As much as I normally avoid it, the need to use it does occasionally crop up. It could be when the g/f wants to go to some ActiveX game-tracking ESPN site, someone actually *needs* to use MS Office (the real thing), or when I want to run some embedded development software written for low-end Windows tinkerers.&lt;br /&gt;&lt;br /&gt;Of course your usual Windows desktop is useless for this, give how my computing setup is presently designed. Outside of my personal desktop in my computer room, all my "around the house" computers basically consist of &lt;a href="http://www.sun.com/software/media/flash/tour_sunray/"&gt;SunRay&lt;/a&gt; thin clients. (which provide an X-based desktop running Gnome served off a Solaris machine) Even with VNC (which is slow and crappy) or "Remote Desktop" from a normal Windows machine running your average desktop version of Windows, I'd still run into problems once more than one person wanted to use the thing at a time.&lt;br /&gt;&lt;br /&gt;So, what I need is a mult-user remote-desktop-capable Windows machine...&lt;br /&gt;&lt;br /&gt;For the hardware, I've got a SunPCi II card currently sitting in my &lt;a href="http://sunsolve.sun.com/handbook_pub/Systems/SunBlade1000/SunBlade1000.html"&gt;Sun Blade 1000&lt;/a&gt; workstation.  This is a machine I plan to turn into a server soon to replace the &lt;a href="http://sunsolve.sun.com/handbook_pub/Systems/E420R/E420R.html"&gt;Sun E420R&lt;/a&gt; which I've been using as an interim server since I decided that my &lt;a href="http://sunsolve.sun.com/handbook_pub/Systems/E4000/E4000.html"&gt;Sun E4000&lt;/a&gt; used too much power. In any case, I've been using the SB1000 for tinker purposes lately, so it was perfect to test out some things on. Now the SunPCi II was basically a 600MHz Celeron with 192MB of RAM on a PCI card inside the Sun. I've since upgraded it to a 743MHz Pentium III (1GHz P3 with a 100MHz FSB... darn clock multiplier locks). I also need to add RAM.&lt;br /&gt;&lt;br /&gt;For the software, I basically had two choices... Windows 2000 Server or Windows 2003 Server. Since the SunPCi II software only supports Win2k Server, my decision was made there. So I got that installed and running. Unfortunately, to my dismay, the "Terminal Services" in Win2k server (remote desktop backend) only supported 8-bit color, and might not work as well as desired for the serial ports. Thankfully, there was an alternative... (I know WinXP Pro would have worked, but it would have failed my multi-user requirement if both users wanted to be using at the same time.) I dug out this wonderful product called Citrix Metaframe XP Presentation Server. (3rd party remote desktop up the wazoo) Not only did it work with serial ports, but I even got login music (which I promptly disabled).&lt;br /&gt;&lt;br /&gt;Now there was just one piece of the puzzle left... authentication. So I went ahead, and once and for all figured out how to get Windows domain-style logins running through my Samba server. Now all my normal "Logicprobe accounts" can also be used to log into this Windows machine.&lt;br /&gt;&lt;br /&gt;(I'll have to set this all up again when I rebuild that SB1000 into a server, but at least I've done a test run of everything and know it will work.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-113923274437341275?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/113923274437341275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=113923274437341275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923274437341275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923274437341275'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2005/10/necessary-evil.html' title='A necessary evil...'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22035590.post-113923259811663266</id><published>2005-10-27T00:04:00.000-04:00</published><updated>2006-02-06T15:57:23.753-05:00</updated><title type='text'>Ahh, the joys of geeking out...</title><content type='html'>On Saturday I was visiting a friend of mine who recently bought a house over in the Winter Springs area. While there, I ran across a CD he had of a game from Sierra called Alien Legacy. I remember playing this game from hours on end, and it took me back.&lt;br /&gt;&lt;br /&gt;So the next day, when at home, I decided to get out my bad-ass gaming box. This thing has specs that'll make you drool. The box is a loaded 486DX-33MHz with a whopping 16MB of RAM (probably worth about $800 retail), a fantastic Number Nine #9GFX VESA Local Bus (VLB) graphics card, Sound Blaster 16 sound card, and an Adaptec ISA SCSI card. That's right... Both the CD-ROM drive and hard drive are SCSI. I even wound up upgrading from the 400MB drive I was using to an enormous 2 "gigabyte" hard disk. And for the heck of it, I also decided to order a VLB SCSI card to replace the ISA one I had. This thing's definitely a screamer, and no idea how I got my hands on it :-)&lt;br /&gt;Needless to say, Alien Legacy ran really well on it.&lt;br /&gt;&lt;br /&gt;Oh, wait...  It's 2005, not 1993...  That machine's probably someone's old junk collection that they'd pay me to take away. :-D&lt;br /&gt;&lt;br /&gt;Well, in reality, its a machine I decided to build a couple years ago with the goal of being the uber-dream-machine from 1993'ish, to run those old games really well. At this point, the only other upgrade I'd even consider would be for a 408DX2-66, simply because TIE Fighter can get jerky at times.&lt;br /&gt;&lt;br /&gt;In any case, I also chose a fitting name for this machine...  &lt;a href="http://en.wikipedia.org/wiki/Phlogiston"&gt;Phologiston&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22035590-113923259811663266?l=hecgeek.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hecgeek.blogspot.com/feeds/113923259811663266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22035590&amp;postID=113923259811663266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923259811663266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22035590/posts/default/113923259811663266'/><link rel='alternate' type='text/html' href='http://hecgeek.blogspot.com/2005/10/ahh-joys-of-geeking-out.html' title='Ahh, the joys of geeking out...'/><author><name>octo</name><uri>http://www.blogger.com/profile/14640499079957252690</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-hgeweQtSSl8/Toiw6EIWq6I/AAAAAAAAAFc/R2tNitM6e0Y/s220/10948_548825113086_17503746_32236866_4313840_n.jpg'/></author><thr:total>0</thr:total></entry></feed>
