<?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-7119494240114103556</id><updated>2012-02-16T09:52:14.805-08:00</updated><category term='gain root'/><category term='Verizon Nokia 770'/><category term='Wordpress'/><category term='WIMP'/><title type='text'>thoughts by clayg</title><subtitle type='html'>Mostly just documentation of technical experiments and experience that I felt worthy of archiving on the interwebz.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>54</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-7663636757475726366</id><published>2010-08-02T08:20:00.000-07:00</published><updated>2010-08-02T08:20:14.932-07:00</updated><title type='text'>Commits to Redisco</title><content type='html'>So this is kinda cool, my first pull request on github was accepted:&lt;br /&gt;&lt;a href="http://github.com/iamteem/redisco/commit/83f8f92b7120691a8bbbaa433a1907b7ad991d77"&gt;test&lt;/a&gt;, &lt;a href="http://github.com/iamteem/redisco/commit/27d64e001e0972691012f0c7977a2d73eb16136a"&gt;fix&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://github.com/iamteem/redisco"&gt;Redisco&lt;/a&gt;, is a neat project:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Redisco allows you to store objects in &lt;a class="reference external" href="http://code.google.com/p/redis/"&gt;Redis&lt;/a&gt;. It is inspired by the Ruby library &lt;a class="reference external" href="http://github.com/soveran/ohm/"&gt;Ohm&lt;/a&gt; and its design and code are loosely based on Ohm and the Django ORM. It is built on top of &lt;a class="reference external" href="http://github.com/andymccurdy/redis-py/"&gt;redis-py&lt;/a&gt;. It includes container classes that allow easier access to Redis sets, lists, and sorted sets.&lt;/blockquote&gt;I'm excited about using redisco in a project I'm working on for work that has a django/jQuery front end and &lt;a href="http://ask.github.com/celery/index.html"&gt;celery&lt;/a&gt;/&lt;a href="http://code.google.com/p/redis/"&gt;redis-server&lt;/a&gt; back end.&amp;nbsp; Redisco itself is a pretty new project (initial commit &lt;a href="http://github.com/iamteem/redisco/commit/7941733e4854acf4472d8804db1cbdf91a01ded7"&gt;May 13, 2010&lt;/a&gt; ) but I think it serves and important niche, allowing a lower barrier of entry to projects that want to move away from a RDMS data-store and get their first taste of &lt;a href="http://en.wikipedia.org/wiki/NoSQL"&gt;NoSQL&lt;/a&gt;.&amp;nbsp; Plus, the author was quick to help me fix problems that were effecting ME.&lt;br /&gt;&lt;br /&gt;In fact, you can check it out right now - my bug fixes are already available on PyPI:&lt;br /&gt;&lt;pre&gt;$ pip install redisco&lt;br /&gt;Downloading/unpacking redisco&lt;br /&gt;  Downloading redisco-0.1.1.tar.gz&lt;br /&gt;  Running setup.py egg_info for package redisco&lt;br /&gt;Installing collected packages: redisco&lt;br /&gt;  Running setup.py install for redisco&lt;br /&gt;Successfully installed redisco&amp;nbsp; &lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-7663636757475726366?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/7663636757475726366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=7663636757475726366' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7663636757475726366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7663636757475726366'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2010/08/commits-to-redisco.html' title='Commits to Redisco'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-4524352686470750419</id><published>2010-07-01T11:04:00.000-07:00</published><updated>2010-07-02T09:20:27.467-07:00</updated><title type='text'>Py3K - PEP 355</title><content type='html'>So, we still don't get object oriented path manipulation in Py3K&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:py"&gt;$ python3&lt;br /&gt;Python 3.1.1+ (r311:74480, Nov  2 2009, 14:49:22) &lt;br /&gt;[GCC 4.4.1] on linux2&lt;br /&gt;Type "help", "copyright", "credits" or "license" for more information.&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; import path&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;  File "&amp;lt;stdin&amp;gt;", line 1, in &amp;lt;module&amp;gt;&lt;br /&gt;ImportError: No module named path&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Is there still &lt;a href="http://mail.python.org/pipermail/python-dev/2006-September/069087.html"&gt;hope&lt;/a&gt;?&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;OK. Pronouncement: PEP 355 is dead. The authors (or the PEP editor)&lt;br /&gt;can update the PEP.&lt;br /&gt;&lt;br /&gt;I'm looking forward to a new PEP.&lt;br /&gt;&lt;br /&gt;--Guido&lt;/pre&gt;&lt;/blockquote&gt;&lt;a href="http://www.python.org/dev/peps/pep-0355/"&gt;PEP 355&lt;/a&gt; died out  years ago, but the &lt;a href="http://pypi.python.org/pypi/path.py/"&gt;reference  implementation&lt;/a&gt; still exists, and IMHO is still garbage.&amp;nbsp; Will there ever be another attempt at a stdlib &lt;a href="http://wiki.python.org/moin/PathClass"&gt;PathClass&lt;/a&gt;?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-4524352686470750419?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/4524352686470750419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=4524352686470750419' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4524352686470750419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4524352686470750419'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2010/07/py3k-pep-355.html' title='Py3K - PEP 355'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-3353793580343557439</id><published>2010-05-24T11:34:00.000-07:00</published><updated>2010-05-24T11:34:31.715-07:00</updated><title type='text'>Happy Daddy!</title><content type='html'>&lt;div style="margin: 0px auto 10px; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_enpkgyjJSRw/S_rFu1wn2nI/AAAAAAAAACs/ge8ZLVNYWQQ/s1600/IMG_0867.JPG"&gt;&lt;img alt="" border="0" src="http://3.bp.blogspot.com/_enpkgyjJSRw/S_rFu1wn2nI/AAAAAAAAACs/ge8ZLVNYWQQ/s400/IMG_0867.JPG" /&gt;&lt;/a&gt; &lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Twin#Monozygotic_twins"&gt;Monozygotic&lt;/a&gt; twin boys!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-3353793580343557439?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/3353793580343557439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=3353793580343557439' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/3353793580343557439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/3353793580343557439'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2010/05/happy-daddy.html' title='Happy Daddy!'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_enpkgyjJSRw/S_rFu1wn2nI/AAAAAAAAACs/ge8ZLVNYWQQ/s72-c/IMG_0867.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-1028261963883217273</id><published>2010-03-01T19:43:00.000-08:00</published><updated>2010-03-01T19:43:06.643-08:00</updated><title type='text'>How vain am I?</title><content type='html'>This vain:&lt;br /&gt;&lt;a href="http://code.djangoproject.com/ticket/5786"&gt;http://code.djangoproject.com/ticket/5786&lt;/a&gt;&lt;br /&gt;&lt;h3 id="comment:36"&gt;changed by jacob&amp;nbsp;&lt;/h3&gt;&lt;h3 id="comment:36"&gt;&lt;a class="anchor" href="http://code.djangoproject.com/ticket/5786#comment:36" title="Permalink to comment:36"&gt; &lt;/a&gt;&lt;/h3&gt;&lt;strong&gt;resolution&lt;/strong&gt; set to &lt;em&gt;fixed&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Thanks to alextreme, lbruno, and clayg.&lt;br /&gt;&lt;em&gt; &lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;Yeah, that's MY bug fix in your django 1.2 (currently in beta, &lt;a href="http://www.djangoproject.com/download/"&gt;get your official copy&lt;/a&gt; March 9th!)&lt;br /&gt;&lt;br /&gt;The really sad part is, it's not even really MY code change, not REALLY.&amp;nbsp; I just re-compiled some other guys patch as a top level diff and updated the tests... but I'm still TOTALLY jazzed about being the last submitter before the final commit.&amp;nbsp; Wait, is that vain?&amp;nbsp; Or just totally lame?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-1028261963883217273?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/1028261963883217273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=1028261963883217273' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1028261963883217273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1028261963883217273'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2010/03/how-vain-am-i.html' title='How vain am I?'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-4019843334445117129</id><published>2009-10-06T20:21:00.000-07:00</published><updated>2009-10-06T20:21:57.030-07:00</updated><title type='text'>Python over-riding options with ConfigParser and OptionParser</title><content type='html'>It looks like it may be woth looking into &lt;a href="http://code.google.com/p/argparse/"&gt;argparse&lt;/a&gt; (non-standard  library)&lt;br /&gt;&lt;br /&gt;"""&lt;br /&gt;The basic idea is that config information can be pulled  out of &lt;br /&gt;&lt;br /&gt;* Global config file&lt;br /&gt;* User local config file&lt;br /&gt;* environment  variables&lt;br /&gt;* command line&lt;br /&gt;&lt;br /&gt;Higher priority comes later in the list.&amp;nbsp;  &lt;br /&gt;"""&lt;br /&gt;&lt;br /&gt;But here's an implementation of cascading config file/command  line options with ConfigParser and OptionParser - without  subclassing.&lt;br /&gt;&lt;br /&gt;Basically you just...&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Set global defaults in at the  top of the module in the constants section&lt;/li&gt;&lt;li&gt;Use those to set defaults in the  config object&lt;/li&gt;&lt;li&gt;Read in the config file possibly over-riding defaults&lt;/li&gt;&lt;li&gt;Read  out the values in the config object to a dictionary&lt;/li&gt;&lt;li&gt;Use THOSE values to set  the command line defaults&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Then you can get any option you need out of the  command line options argument&lt;br /&gt;&lt;br /&gt;It's not very flexible, but it uses  standard libraries and should be fairly&amp;nbsp; obvious.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:python"&gt;#! /usr/bin/env python&lt;br /&gt;__doc__ = """&lt;br /&gt;example of cascading options with ConfigParser and OptionParser&lt;br /&gt;"""&lt;br /&gt;&lt;br /&gt;# imports&lt;br /&gt;import sys&lt;br /&gt;from ConfigParser import ConfigParser&lt;br /&gt;from optparse import OptionParser&lt;br /&gt;# constants&lt;br /&gt;default_option = 'default_value'&lt;br /&gt;default_toggle = True&lt;br /&gt;&lt;br /&gt;# classes&lt;br /&gt;# internal functions&lt;br /&gt;&lt;br /&gt;def main():&lt;br /&gt;    # create a config parser&lt;br /&gt;    # config parser objects store all options as strings&lt;br /&gt;    config = ConfigParser({'option':str(default_option),&lt;br /&gt;                           'toggle':str(default_toggle),&lt;br /&gt;                          })&lt;br /&gt;    config.read('example.cfg')&lt;br /&gt;    &lt;br /&gt;    # create command line option parser&lt;br /&gt;    parser = OptionParser("%prog [options]" + __doc__.rstrip())&lt;br /&gt;    &lt;br /&gt;    # configure command line options&lt;br /&gt;    parser.add_option("-o", "--option", action="store", dest="option", help="set option")&lt;br /&gt;    parser.add_option("-t", "--toggleOff", action="store_false", dest="toggle", help="set toggle off")&lt;br /&gt;    parser.add_option("-T", "--toggleOn", action="store_true", dest="toggle", help="set toggle on")&lt;br /&gt;    &lt;br /&gt;    # read config objects defaults section into a dictionary&lt;br /&gt;    config_options = config.defaults()&lt;br /&gt;    # config_options is dictionary of strings, over-ride toggle to bool&lt;br /&gt;    config_options['toggle'] = config.getboolean('DEFAULT', 'toggle')&lt;br /&gt;    # feed dictionary of defaults into parser object&lt;br /&gt;    parser.set_defaults(**config_options)&lt;br /&gt;&lt;br /&gt;    # parse command line options&lt;br /&gt;    (options, args) = parser.parse_args()&lt;br /&gt;&lt;br /&gt;    print "option: %s" % options.option&lt;br /&gt;    if options.toggle:&lt;br /&gt;        print "toggle is ON"&lt;br /&gt;    else:&lt;br /&gt;        print "toggle is OFF"&lt;br /&gt;&lt;br /&gt;    return 0;&lt;br /&gt;&lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;    status = main()&lt;br /&gt;    sys.exit(status)&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/7119494240114103556-4019843334445117129?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/4019843334445117129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=4019843334445117129' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4019843334445117129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4019843334445117129'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2009/10/python-over-riding-options-with.html' title='Python over-riding options with ConfigParser and OptionParser'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-3518721952315932728</id><published>2009-09-28T20:11:00.000-07:00</published><updated>2009-09-28T20:11:39.482-07:00</updated><title type='text'>vuze torrents get more peers</title><content type='html'>When I only had one or two torrents going at a time they seemed to download slower than my connection should have been able to support.&amp;nbsp; I was looking for ways to maximize my torrent download speed when I found the setting for "maximum number of connections" under options in &lt;a href="http://www.vuze.com/"&gt;Vuze&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Please note all the details here have only been tested to work to improve download speeds of freely distributable copyleft materials such as &lt;a href="http://www.ubuntu.com/getubuntu/downloadmirrors#bt"&gt;Ubuntu&lt;/a&gt; full DVD images.&lt;br /&gt;&lt;br /&gt;If you're like me, you've already covered the basics (I had "&lt;a href="http://wiki.vuze.com/index.php/Torrent_health"&gt;green smiles&lt;/a&gt;" and "&lt;a href="http://wiki.vuze.com/index.php/NAT"&gt;open nat&lt;/a&gt;") but if not, you may want to &lt;a href="http://forum.vuze.com/thread.jspa?threadID=78768"&gt;start with that&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My problem was that I was only connecting to 20-30 peers out of thounds of seeders and my down speed for a single torrent capped out around 150-170 kB/s.&amp;nbsp; I discovered that the max number of connections was set to 40, I don't remember changing it - hitting reset seemed to indicate that by default Vuze limits the max number of connections to 50:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&amp;nbsp;&lt;a href="http://farm3.static.flickr.com/2589/3964179501_98ec754a6a_o.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="226" src="http://farm3.static.flickr.com/2589/3964179501_98ec754a6a_o.gif" width="420" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;This number maps directly to the number of peers in your swarm.&amp;nbsp; And mine was set much lower than the recommend "&lt;a href="http://www.azureuswiki.com/index.php/Good_settings"&gt;Good Settings&lt;/a&gt;" - I went ahead and just disabled it for now:&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm3.static.flickr.com/2617/3964179437_c954eff621.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="237" src="http://farm3.static.flickr.com/2617/3964179437_c954eff621.jpg" width="420" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;And I was pretty happy with the results:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm3.static.flickr.com/2575/3964985172_8da731ec3b.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://farm3.static.flickr.com/2575/3964985172_8da731ec3b.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-3518721952315932728?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/3518721952315932728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=3518721952315932728' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/3518721952315932728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/3518721952315932728'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2009/09/vuze-torrents-get-more-peers.html' title='vuze torrents get more peers'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2617/3964179437_c954eff621_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-5124895037818669585</id><published>2009-09-18T19:16:00.000-07:00</published><updated>2009-09-18T20:23:08.187-07:00</updated><title type='text'>post code snippets in google blogger</title><content type='html'>Howdy folks, here's some code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: python"&gt;def myfunc(*args, **kwargs):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for arg in args:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print arg&lt;br /&gt;&amp;nbsp; &amp;nbsp; for k,v in kwargs.items():&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print k,v&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;First thing you need to do is make sure you're useing the Google Blogger's "Updated Editor".&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Log into Blogger, and from the Dashboard goto Settings.&lt;/li&gt;&lt;li&gt;On the Settings tab, down towards the bottom under "Global Settings"&lt;/li&gt;&lt;li&gt;"Select post editor" - "Updated editor"&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;The updated editor actually solved a lot of the "problems" I was having with pre formatted text getting messed up when I went back and forth between compose and edit html.&lt;br /&gt;&lt;br /&gt;But to post some really good looking source code you have to use &lt;a href="http://code.google.com/p/syntaxhighlighter/"&gt;SyntaxHighlighter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;SyntaxHighlighter is written in JavaScript, and there some css styling as well. To use SyntaxHighlighter on your google blogger page, you have to edit the template.&lt;br /&gt;&lt;br /&gt;Under the Layout tab, go to "Edit HTML"&lt;br /&gt;In the "Edit Template" box, scroll down toward the bottom.&lt;br /&gt;You want to add the .js/.css references just before the last closing head tag (&amp;lt;/head&amp;gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: html"&gt;&amp;lt;link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='Stylesheet' type='text/css'/&amp;gt;&lt;br /&gt;&amp;lt;link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='Stylesheet' type='text/css'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'/&amp;gt;&lt;br /&gt;&amp;lt;script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js ' type='text/javascript'/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif; text-align: left;"&gt;&lt;i&gt;SyntaxHighlighter makes it easy to copy the above snippet - just hover over the code, and click the "copy-to-clipboard" icon: &lt;a href="http://alexgorbatchev.com/pub/sh/current/styles/page_white_copy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://alexgorbatchev.com/pub/sh/current/styles/page_white_copy.png" /&gt;&lt;/a&gt;&lt;/i&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Then at the very bottom, you also want to set some global parameters just before the last closing body tag (&amp;lt;/body&amp;gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: html"&gt;&amp;lt;script language='javascript'&amp;gt;&lt;br /&gt;SyntaxHighlighter.config.bloggerMode = true;&lt;br /&gt;SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';&lt;br /&gt;SyntaxHighlighter.all();&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;You can then make highlighted code by wrapping your code snippet's in a &lt;br /&gt;&amp;lt;pre&amp;gt; tag with a specially formatted "class" attribute, like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: html"&gt;&amp;lt;pre class="brush:js"&amp;gt;&lt;br /&gt;alert("Hello world");&lt;br /&gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Result:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;alert("Hello world");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can add brushes for different languages by adding more JavaScript files to your Template. The author hosts the most recent version here:&lt;br /&gt;&lt;a href="http://alexgorbatchev.com/pub/sh/current/"&gt;http://alexgorbatchev.com/pub/sh/current/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;b&gt;N.B. Just because you put html inside a&amp;nbsp; &amp;lt;pre&amp;gt; tag doesn't magically make html parsers know you're try to post literal HTML code - you still have to escape valid HTML using &amp;amp;lt; and the like or it won't be rendered correctly.&amp;nbsp; Try something like &lt;a href="http://www.string-functions.com/htmlencode.aspx"&gt;this&lt;/a&gt;.&lt;/b&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I cobbled together the following steps from these sources: &lt;br /&gt;&lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter"&gt;SyntaxHighlighter Homepage&lt;/a&gt; &lt;br /&gt;&lt;a href="http://developertips.blogspot.com/2007/08/syntaxhighlighter-on-blogger.html"&gt;Using SyntaxHighlighter on BLOGGER&lt;/a&gt; &lt;br /&gt;&lt;a href="http://urenjoy.blogspot.com/2008/10/publish-source-code-in-blogger.html"&gt;Publish Source code in Blogger&lt;/a&gt; &lt;br /&gt;&lt;a href="http://alexgorbatchev.com/forums/comments.php?DiscussionID=82&amp;amp;page=1#Item_0"&gt;Syntax Highlighter NOT working in my googleblog&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-5124895037818669585?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/5124895037818669585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=5124895037818669585' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5124895037818669585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5124895037818669585'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2009/09/post-code-snippets-in-google-blogger.html' title='post code snippets in google blogger'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-2272244352283842436</id><published>2009-09-16T20:06:00.000-07:00</published><updated>2009-09-16T20:14:35.580-07:00</updated><title type='text'>Newegg Shipping Halo: ODST early</title><content type='html'>I pre-ordered from Newegg, and it arrived Monday Sept 14th.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/en/archive/9/9a/20090611232449%21Halo_3_ODST_Box_Art.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 454px; height: 640px;" src="http://upload.wikimedia.org/wikipedia/en/archive/9/9a/20090611232449%21Halo_3_ODST_Box_Art.png" alt="" border="0" /&gt;&lt;/a&gt;Play'd it through the first night on Heroic (6 hours).&lt;br /&gt;It was fun.&lt;br /&gt;No dual wielding.&lt;br /&gt;No battle rifle.&lt;br /&gt;You move surprisingly fast with a turret.&lt;br /&gt;No match-making for firefight (yet?).&lt;br /&gt;&lt;br /&gt;Halo: Mythic is a separate disk, with:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Matchmaking&lt;/li&gt;&lt;li&gt;Custom Games&lt;/li&gt;&lt;li&gt;Theater&lt;/li&gt;&lt;li&gt;Forge&lt;/li&gt;&lt;/ul&gt;...and ALL the multilayer maps.&lt;br /&gt;&lt;br /&gt;Heretic is Midship.&lt;br /&gt;Cathedral is like Epitaph, but VERY symmetrical.&lt;br /&gt;Longshore seems pretty cool.&lt;br /&gt;&lt;br /&gt;You play them off Mythic, you don't download them to your HD.  Your Halo3 saved content is available from with-in Mythic automatically.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-2272244352283842436?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/2272244352283842436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=2272244352283842436' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/2272244352283842436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/2272244352283842436'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2009/09/newegg-shipping-halo-odst-early.html' title='Newegg Shipping Halo: ODST early'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-887133295089674859</id><published>2009-08-14T20:07:00.000-07:00</published><updated>2009-08-14T22:47:18.055-07:00</updated><title type='text'>TypeError: dict objects are unhashable</title><content type='html'>My mom told me to update my blog.  Hi mom.&lt;br /&gt;&lt;br /&gt;I've been wanting to write this one for awhile anyway.&lt;br /&gt;&lt;br /&gt;In retrospect it was rather naive - but I wonder who hasn't at one time tried to create a set of dictionaries:&lt;br /&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;&lt;br /&gt;|&lt;/span&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;&gt;&gt;&lt;/span&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;&gt; parts = [&lt;br /&gt;|... {'id':1, 'desc':'widget', 'detail':'rear widget'},&lt;br /&gt;|... {'id':1, 'desc':'widget', 'detail':'front widget'},&lt;br /&gt;|... {'id':2, 'desc':'gear', 'size':4},&lt;br /&gt;|... {'id':3, 'desc':'cog', 'type':'green'},&lt;br /&gt;|... ]&lt;br /&gt;|&gt;&gt;&gt; myset = set(parts)&lt;br /&gt;|Traceback (most recent call last):&lt;br /&gt;|  File "&lt;stdin&gt;", line 1, in ?&lt;br /&gt;|TypeError: dict objects are unhashable&lt;br /&gt;&lt;/stdin&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;stdin&gt;What did I expect it to do?  I think the first time I tried this it seemed more reasonable.  I think my list of dictionaries actually contained exactly the same keys, with some exact duplicates and I needed to &lt;a href="http://www.urbandictionary.com/define.php?term=uniquify"&gt;uniquify&lt;/a&gt; the list.  I acctually ended up doing something like the example at the bottom...&lt;br /&gt;&lt;br /&gt;Dict objects are not hashable, read about &lt;a href="http://en.wikipedia.org/wiki/Hash_table"&gt;hash tables&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Set_data_structure"&gt;sets&lt;/a&gt; if it isn't obvious why it's important that objects in a set support a __hash__ method.&lt;br /&gt;&lt;br /&gt;A hash function is really simple idea:&lt;br /&gt;two &lt;span style="font-style: italic;"&gt;equal &lt;/span&gt;objects &lt;span style="font-weight: bold;"&gt;MUST &lt;/span&gt;return the same hash&lt;br /&gt;two &lt;span style="font-style: italic;"&gt;un-equal &lt;/span&gt;objects should &lt;span style="font-weight: bold;"&gt;RARELY &lt;/span&gt;return the same key&lt;br /&gt;&lt;br /&gt;But there's no really obvious reasonable way to implement hash on a dictionary of arbitrary keys and values.&lt;br /&gt;&lt;br /&gt;Here's a couple dumb ideas for adding a hash function to a dict:&lt;br /&gt;&lt;br /&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;&lt;br /&gt;|def __hash__(self):&lt;br /&gt;|    key = 0&lt;br /&gt;&lt;br /&gt;|def __hash__(self):&lt;br /&gt;|    id = 0&lt;br /&gt;|    for pair in sorted(self.items()):&lt;br /&gt;|        id += hash(pair)&lt;br /&gt;|    return hash(id)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And they "work" - at least in the sense that they remove the error:&lt;br /&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;&lt;br /&gt;|&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;&gt;&gt;&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;&gt; class Part(dict):&lt;br /&gt;|...     def __hash__(self):&lt;br /&gt;|...         return self['id']&lt;br /&gt;|...&lt;br /&gt;|&gt;&gt;&gt; myset = set([Part(x) for x in parts])&lt;br /&gt;|&gt;&gt;&gt; for part in myset:&lt;br /&gt;|...     print part&lt;br /&gt;|...&lt;br /&gt;|{'desc': 'widget', 'detail': 'rear widget', 'id': 1}&lt;br /&gt;|{'desc': 'gear', 'id': 2, 'size': 4}&lt;br /&gt;|{'type': 'green', 'id': 3, 'desc': 'cog'}&lt;br /&gt;|{'desc': 'widget', 'detail': 'front widget', 'id': 1}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And that's great, if my parts list contained EXACTLY equal dictionaries they would be removed - I could turn it back into a list an continue on with everything uniquified!  It might be worth nothing that the two parts with 'id' = 1 were not considered equal just because they returned the same hash.  When there is a &lt;a href="http://en.wikipedia.org/wiki/Hash_collision"&gt;hash collision&lt;/a&gt;, the inhereited __eq__() method recognized that 'rear widget' != 'left widget' and that the two parts were distinct.&lt;br /&gt;&lt;br /&gt;But what's really interesting what I've done by &lt;a href="http://pyref.infogami.com/__hash__"&gt;making a mutable object hashable&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;It can be used as a dictionary key with surprisingly bad results:&lt;br /&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;&lt;br /&gt;|&gt;&gt;&gt; part.__class__ # part is an instance of my Part class&lt;br /&gt;|&amp;amp;ltclass '__main__.Part'&gt;&lt;br /&gt;|&gt;&gt;&gt; part # a mutable object with a hash function&lt;br /&gt;|{'desc': 'widget', 'detail': 'front widget', 'id': 1}&lt;br /&gt;|&gt;&gt;&gt; mydict = {} # mydict is a plain dictionary&lt;br /&gt;|&gt;&gt;&gt; mydict[part] = 1 # i can use part as a key!&lt;br /&gt;|&gt;&gt;&gt; part['id'] = 2 # I then modify the key&lt;br /&gt;|&gt;&gt;&gt; mydict[part] # there is no value assigned to this new "modified" key&lt;br /&gt;|Traceback (most recent call last):&lt;br /&gt;|File "&lt;stdin&gt;", line 1, in ?&lt;br /&gt;|  KeyError: {'desc': 'widget', 'detail': 'front widget', 'id': 2}&lt;br /&gt;|&gt;&gt;&gt; mydict # or is there?&lt;br /&gt;|{{'desc': 'widget', 'detail': 'front widget', 'id': 2}: 1}&lt;br /&gt;&lt;/stdin&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;br /&gt;Here's a fairly reasonable attempt at making a custom class that is &lt;span style="font-weight: bold;"&gt;mostly&lt;/span&gt; mutable dictionary, but has a safe and reasonable hash function.  I'll also over-ridden __eq__ to ignore minor differences in the 'detail' between objects.&lt;br /&gt;&lt;br /&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;&gt;&gt;&gt; class Part(dict):&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...     def __init__(self, part_dict):&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...         if 'id' not in part_dict:&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...             raise TypeError("Parts must have an id")&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...         dict.__init__(self, part_dict)&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...     def __setitem__(self, key, value):&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...         if key == 'id':&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...             raise ValueError("Part id's can't change - create a new part")&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...         return dict.__setitem__(self, key, value)&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...     def __hash__(self):&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...         return self['id']&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...     def __eq__(self, other):&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...         a = self.copy()&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...         del a['detail']&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...         b = other.copy()&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...         del b['detail']&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...         return a == b&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;&gt;&gt;&gt; for part in set([Part(x) for x in parts]):&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...     print part&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;...&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;{'desc': 'widget', 'detail': 'rear widget', 'id': 1}&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;{'desc': 'gear', 'id': 2, 'size': 4}&lt;br /&gt;&lt;/span&gt;&lt;/stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;|&lt;/span&gt;&lt;stdin&gt;&lt;span style="white-space: pre; font-weight: bold;font-family:courier new;" &gt;{'type': 'green', 'id': 3, 'desc': 'cog'}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;So if parts is a list of build materials, and you wanted to know how many distinct parts it takes to build this thing... the above Part class might be the right track.  Aside from the ambiguity of added by over-riding "==" like that... dose anyone see any other problems with this?&lt;br /&gt;&lt;/stdin&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-887133295089674859?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/887133295089674859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=887133295089674859' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/887133295089674859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/887133295089674859'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2009/08/typeerror-dict-objects-are-unhashable.html' title='TypeError: dict objects are unhashable'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-4401013337915925227</id><published>2009-02-05T18:03:00.000-08:00</published><updated>2009-02-09T11:28:55.234-08:00</updated><title type='text'>pymssql and sqlalchemy</title><content type='html'>At the time of this writing the latest version of &lt;a href="http://www.sqlalchemy.org/"&gt;sqlalchemy&lt;/a&gt; (0.5.2) does not support the recent re-write of &lt;a href="http://pymssql.sourceforge.net/"&gt;pymssql&lt;/a&gt; (1.0.0), which was released last week.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 188px; height: 52px;" src="http://www.sqlalchemy.org/_img/sqla-logo6.gif" alt="" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;attempting to &lt;a href="http://www.sqlalchemy.org/docs/05/dbengine.html#create-engine-url-arguments"&gt;create a sqlalchemy engine object&lt;/a&gt; will result in an exception:&lt;p&gt;&lt;span style="font-family:courier new;"&gt;  File "/lib/python2.5/site-packages/SQLAlchemy-0.5.2-py2.5.egg/sqlalchemy/databases/mssql.py", line 1294, in create_connect_args&lt;br /&gt;self.dbapi._mssql.set_query_timeout(self.query_timeout)&lt;br /&gt;AttributeError: 'module' object has no attribute 'set_query_timeout'&lt;br /&gt;&gt;&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;According to the pymssql &lt;a href="http://pymssql.sourceforge.net/index.html"&gt;news&lt;/a&gt; page, the low level module in this major version release is not backwards compatible:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;BEWARE however, if you were using the lower level &lt;b&gt;_mssql module&lt;/b&gt;, it &lt;b&gt;changed in incompatible way&lt;/b&gt;. You will need to change your scripts, or continue to use pymssql 0.8.0. This is why major version number was incremented.&lt;/li&gt;&lt;/ul&gt;As a 'work-around' you can always install an older stable version of pymssql (0.8.0)&lt;p&gt;&lt;span style="font-family:courier new;"&gt;$easy_install pymssql==0.8.0&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-4401013337915925227?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/4401013337915925227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=4401013337915925227' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4401013337915925227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4401013337915925227'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2009/02/pymssql-and-sqlalchemy.html' title='pymssql and sqlalchemy'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-5063602075071262502</id><published>2009-01-06T23:00:00.000-08:00</published><updated>2009-01-06T23:13:08.586-08:00</updated><title type='text'>Quake Live Beta Invites Crash Test</title><content type='html'>I finally got my QuakeLive Closed Beta Account - and you may have too!&lt;br /&gt;&lt;br /&gt;The QuakeLive Beta is warming up!&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;on Monday we're going to be sending out our largest number of new beta invites ever - hopefully more than doubling our current active player base.&lt;/span&gt;&lt;/blockquote&gt;- QuakeLive News&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.quakelive.com/"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 101px;" src="http://farm4.static.flickr.com/3421/3176444654_f24aa44786_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;id is planning a big "crash test" on Wednesday afternoon - Jan 7th 2009.  Go check your email, and be ready for a three part sign-up and activation rig-o-mo-rag...&lt;br /&gt;&lt;br /&gt;id has asked us to "BRING THE HEAT"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-5063602075071262502?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/5063602075071262502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=5063602075071262502' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5063602075071262502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5063602075071262502'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2009/01/quake-live-beta-invites-crash-test.html' title='Quake Live Beta Invites Crash Test'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-6501596289631913702</id><published>2008-12-29T20:47:00.000-08:00</published><updated>2008-12-30T04:09:48.058-08:00</updated><title type='text'>Set PYTHONPATH</title><content type='html'>To set the enviornment variable &lt;a href="http://docs.python.org/using/cmdline.html#envvar-PYTHONPATH"&gt;PYTHONPATH&lt;/a&gt; in bash:&lt;br /&gt;export PYTHONPATH=/path/to/modules&lt;br /&gt;&lt;br /&gt;just setting PYTHONPATH=/path/to/modules won't work - you have to use export.  If you want a variable passed on to a child processes it has to show up when you type 'env'&lt;br /&gt;&lt;br /&gt;But since you used export - next time you start python, '/path/to/modules' will automatically be appended to the front of your sys.path&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3104/3149920792_eebfa3c85d_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 500px;" src="http://farm4.static.flickr.com/3104/3149920792_eebfa3c85d_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Obviously '/path/to/modules' should be the full path to whereever you're keeping your modules - something like /home/clayg/lib.  (relative path's will work, but not ~/ , probably best to avoid both)  You can separate multiple directories with a colon:&lt;br /&gt;&lt;br /&gt;export PYTHONPATH=/path/to/modules:/path/to/other/modules&lt;br /&gt;&lt;br /&gt;Setting python path is handy if, for example, you are using &lt;a href="http://peak.telecommunity.com/DevCenter/setuptools"&gt;setuptools&lt;/a&gt; or &lt;a href="http://docs.python.org/library/distutils.html"&gt;distutils&lt;/a&gt; to install python modules on a system which you do not have root privileges.&lt;br /&gt;&lt;br /&gt;Just download the source dist and find the directory with setup.py, then run:&lt;br /&gt;python setup.py build&lt;br /&gt;&lt;br /&gt;Then re-locate the folder with the __init__.py (usually ./build/lib/packagename) to your /path/to/modules folder.&lt;br /&gt;&lt;br /&gt;if you want your PYTHONPATH to stick around - you should add it to &lt;a href="http://thoughtsbyclayg.blogspot.com/2008/01/how-does-bash-work.html"&gt;.bashrc&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;import packagename should be good to go!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-6501596289631913702?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/6501596289631913702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=6501596289631913702' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/6501596289631913702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/6501596289631913702'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/12/set-pythonpath.html' title='Set PYTHONPATH'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-4927926766417450425</id><published>2008-12-04T03:20:00.000-08:00</published><updated>2009-04-23T07:03:51.138-07:00</updated><title type='text'>get dates from excel with python xlrd</title><content type='html'>a1_as_datetime = datetime.datetime(*xlrd.xldate_as_tuple(a1, 0))&lt;br /&gt;&lt;br /&gt;UPDATE: Please read the discussion of the second argument to xldate_as_tuple - "datemode" in the comments section of this post before using this example.  It is LIKELY that hard-coding the "datemode" option will not meet your long term needs.&lt;br /&gt;&lt;br /&gt;I had to piece this line together from two other articles, sorry don't remember which.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3207/3149135417_68b0d4aeb9_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 216px; height: 144px;" src="http://farm4.static.flickr.com/3207/3149135417_68b0d4aeb9_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Full Example:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&gt;&gt;&gt; import datetime, xlrd&lt;br /&gt;&gt;&gt;&gt; book = xlrd.open_workbook("myfile.xls")&lt;br /&gt;&gt;&gt;&gt; sh = book.sheet_by_index(0)&lt;br /&gt;&gt;&gt;&gt; a1 = sh.cell_value(rowx=0, colx=0)&lt;br /&gt;&gt;&gt;&gt; print "Cell A1 is ", a1&lt;br /&gt;Cell A1 is  39811.0&lt;br /&gt;&gt;&gt;&gt; a1_as_datetime = datetime.datetime(*xlrd.xldate_as_tuple(a1, book.datemode))&lt;br /&gt;&gt;&gt;&gt; print 'datetime: %s' % a1_as_datetime&lt;br /&gt;datetime: 2008-12-29 00:00:00&lt;br /&gt;&gt;&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This might make more sense if you're familiar with &lt;a href="http://www.lexicon.net/sjmachin/xlrd.html"&gt;xlrd&lt;/a&gt; -&lt;b&gt; A Python module for extracting data from MS Excel ™ spreadsheet files.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;If you &lt;span style="font-style: italic;"&gt;are &lt;/span&gt;familiar with xlrd, then the only part really worth discussing is &lt;a href="http://www.lexicon.net/sjmachin/xlrd.html#xlrd.xldate_as_tuple-function"&gt;xldate_as_tuple&lt;/a&gt;, which will convert the float that excel is using to store the date as something more useful, like a tuple:&lt;br /&gt;(2008, 12, 29, 0, 0, 0)&lt;br /&gt;&lt;br /&gt;Note that the first argument to the xldate_as_tuple function is the variable I defined as a1.  xldate_as_tuple will not accept a cell reference 'a1' or some such thing - you have to give it the float!&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://www.python.org/doc/2.5.2/lib/datetime-datetime.html"&gt;datetime&lt;/a&gt; module has a constructor for dates that requires at minimum three positional arguments:&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr valign="baseline"&gt;&lt;td&gt;&lt;nobr&gt;&lt;b&gt;&lt;tt id="l2h-634" class="class"&gt;datetime&lt;/tt&gt;&lt;/b&gt;(&lt;/nobr&gt;&lt;/td&gt;   &lt;td&gt;&lt;var&gt;year, month, day&lt;/var&gt;&lt;big&gt;[&lt;/big&gt;&lt;var&gt;,                             hour&lt;/var&gt;&lt;big&gt;[&lt;/big&gt;&lt;var&gt;, minute&lt;/var&gt;&lt;big&gt;[&lt;/big&gt;&lt;var&gt;,                             second&lt;/var&gt;&lt;big&gt;[&lt;/big&gt;&lt;var&gt;, microsecond&lt;/var&gt;&lt;big&gt;[&lt;/big&gt;&lt;var&gt;,                             tzinfo&lt;/var&gt;&lt;big&gt;]&lt;/big&gt;&lt;var&gt;&lt;/var&gt;&lt;big&gt;]&lt;/big&gt;&lt;var&gt;&lt;/var&gt;&lt;big&gt;]&lt;/big&gt;&lt;var&gt;&lt;/var&gt;&lt;big&gt;]&lt;/big&gt;&lt;var&gt;&lt;/var&gt;&lt;big&gt;]&lt;/big&gt;&lt;var&gt;&lt;/var&gt;)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;This would also work:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;a1_as_date = datetime.date(*xlrd.xldate_as_tuple(a1, 0)[:3])&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;You can pass the items of the tuple as positional arguments by prefacing the tuple with an &lt;a href="http://en.wikipedia.org/wiki/Asterisk"&gt;asterisk&lt;/a&gt; (wtg python!)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-4927926766417450425?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/4927926766417450425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=4927926766417450425' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4927926766417450425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4927926766417450425'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/12/get-dates-from-excel-with-python-xlrd.html' title='get dates from excel with python xlrd'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-7180066254650799275</id><published>2008-10-17T01:36:00.001-07:00</published><updated>2008-10-18T00:03:45.102-07:00</updated><title type='text'>Simple example of Threads in Python</title><content type='html'>The first time it was immediately obvious to me that there would be a significant gain from 'threading' a program I had written - was in the context of screen scraping.  I had a handful of HTTP GET requests from almost 20 pages that were being processed one... after... the... other.  I realized of course that if I would just start the next request before waiting on the last one to finish - the entire process would be over much more quickly.&lt;br /&gt;&lt;br /&gt;In this example the screen scraping 'worker' function is replaced with a simpler 'random wait' function:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#! /usr/bin/env python&lt;br /&gt;&lt;br /&gt;import sys&lt;br /&gt;import threading&lt;br /&gt;import time&lt;br /&gt;import random&lt;br /&gt;&lt;br /&gt;# The worker function does the processing&lt;br /&gt;def worker(arg):&lt;br /&gt; arg = random.randint(2,10)&lt;br /&gt; time.sleep(arg)&lt;br /&gt; return arg&lt;br /&gt;&lt;br /&gt;# The myThreadObj wraps the worker function in a thread&lt;br /&gt;class myThreadObj(threading.Thread):&lt;br /&gt; def __init__(self, arg):&lt;br /&gt;  threading.Thread.__init__(self)&lt;br /&gt;  self.arg = arg&lt;br /&gt;  self.value = 0&lt;br /&gt; def run(self):&lt;br /&gt;  self.value = worker(self.arg)&lt;br /&gt;  print 'Thread %d Ended.' % self.arg&lt;br /&gt;&lt;br /&gt;# my array of arguments to be processed by the worker function&lt;br /&gt;myArgs = range(5)&lt;br /&gt;&lt;br /&gt;# create a myThreadObj to process each argument&lt;br /&gt;myThreadList = []&lt;br /&gt;for i in myArgs:&lt;br /&gt; myThreadList.append(myThreadObj(i))&lt;br /&gt; # and start it immediately&lt;br /&gt; myThreadList[i].start()&lt;br /&gt;&lt;br /&gt;# wait for all threads to finish&lt;br /&gt;for each in myThreadList:&lt;br /&gt; each.join()&lt;br /&gt;&lt;br /&gt;print 'All threads have completed.'&lt;br /&gt;&lt;br /&gt;for i in myArgs:&lt;br /&gt; print "myThreadList[%d] = %d" % (i, myThreadList[i].value)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The myThreadObj wrapper should accept whatever arguments you normally pass to the worker, and when the worker is completed - it will store the returned value in 'self.value'&lt;br /&gt;&lt;br /&gt;The .join() function blocks until the .isAlive() method would return false. I process each thread iteratively to verify that all have completed.  It doesn't matter if .join() blocks for 8 seconds while it's waiting on the first thread, or if it gets to a thread that's already been completed for 6 seconds cause an earlier .join was waiting on a previous thread that took longer.   The point is that, by the time all of the .join() statements complete - ALL THREADS HAVE FINISHED.&lt;br /&gt;&lt;br /&gt;Once the threads are done we expect myThreadObj.value to contain the return value of the worker function.&lt;br /&gt;&lt;br /&gt;If your 'worker' function is something like an API call, or database query - anything with some built in lag from a system that's designed to serve multiple simultaneous requests - as long as you can queue them up - threading will provide a significant improvement.&lt;br /&gt;&lt;br /&gt;e.g.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;clayg@m-net:~$ cat nonthread.py&lt;br /&gt;#! /usr/bin/env python&lt;br /&gt;&lt;br /&gt;import sys&lt;br /&gt;import threading&lt;br /&gt;import time&lt;br /&gt;import random&lt;br /&gt;&lt;br /&gt;# The worker function does the processing&lt;br /&gt;def worker(arg):&lt;br /&gt;arg = random.randint(2,10)&lt;br /&gt;time.sleep(arg)&lt;br /&gt;return arg&lt;br /&gt;&lt;br /&gt;myArgs = range(5)&lt;br /&gt;&lt;br /&gt;for i in myArgs:&lt;br /&gt;print "myThreadList[%d] = %d" % (i, worker(i))&lt;br /&gt;clayg@m-net:~$ time ./nonthread.py ; echo ; time ./simplethread.py&lt;br /&gt;myThreadList[0] = 5&lt;br /&gt;myThreadList[1] = 5&lt;br /&gt;myThreadList[2] = 10&lt;br /&gt;myThreadList[3] = 2&lt;br /&gt;myThreadList[4] = 9&lt;br /&gt;&lt;br /&gt;real    0m31.073s&lt;br /&gt;user    0m0.045s&lt;br /&gt;sys     0m0.024s&lt;br /&gt;&lt;br /&gt;Thread 4 Ended.&lt;br /&gt;Thread 0 Ended.&lt;br /&gt;Thread 1 Ended.&lt;br /&gt;Thread 2 Ended.&lt;br /&gt;Thread 3 Ended.&lt;br /&gt;All threads have completed.&lt;br /&gt;myThreadList[0] = 5&lt;br /&gt;myThreadList[1] = 10&lt;br /&gt;myThreadList[2] = 10&lt;br /&gt;myThreadList[3] = 10&lt;br /&gt;myThreadList[4] = 2&lt;br /&gt;&lt;br /&gt;real    0m10.078s&lt;br /&gt;user    0m0.045s&lt;br /&gt;sys     0m0.030s&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/7119494240114103556-7180066254650799275?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/7180066254650799275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=7180066254650799275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7180066254650799275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7180066254650799275'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/10/simple-example-of-threads-in-python.html' title='Simple example of Threads in Python'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-7132353532318349236</id><published>2008-10-01T23:41:00.000-07:00</published><updated>2008-10-01T23:48:30.886-07:00</updated><title type='text'>Parsing a list of numbers in Python</title><content type='html'>I find that I often need to get a selection of numbers in a range as input.  I'm using Python more and more these days it seems, so I needed to port this classic function over.  I must have done this 4 weeks ago - I'd been meaning to put it up here.&lt;br /&gt;&lt;br /&gt;The valid input will be a comma separated list of integers, which could possibly contain a 'range' defined as "x-y" - where x and y are both integers.&lt;br /&gt;&lt;br /&gt;I tried not to make any special stipulation for the order of these integers, or even that the input string would not contain bad characters.&lt;br /&gt;&lt;br /&gt;Here it is:&lt;br /&gt;&lt;pre&gt;#! /usr/local/bin/python&lt;br /&gt;import sys&lt;br /&gt;import os&lt;br /&gt;&lt;br /&gt;# return a set of selected values when a string in the form:&lt;br /&gt;# 1-4,6&lt;br /&gt;# would return:&lt;br /&gt;# 1,2,3,4,6&lt;br /&gt;# as expected...&lt;br /&gt;&lt;br /&gt;def parseIntSet(nputstr=""):&lt;br /&gt;  selection = set()&lt;br /&gt;  invalid = set()&lt;br /&gt;  # tokens are comma seperated values&lt;br /&gt;  tokens = [x.strip() for x in nputstr.split(',')]&lt;br /&gt;  for i in tokens:&lt;br /&gt;     try:&lt;br /&gt;        # typically tokens are plain old integers&lt;br /&gt;        selection.add(int(i))&lt;br /&gt;     except:&lt;br /&gt;        # if not, then it might be a range&lt;br /&gt;        try:&lt;br /&gt;           token = [int(k.strip()) for k in i.split('-')]&lt;br /&gt;           if len(token) &gt; 1:&lt;br /&gt;              token.sort()&lt;br /&gt;              # we have items seperated by a dash&lt;br /&gt;              # try to build a valid range&lt;br /&gt;              first = token[0]&lt;br /&gt;              last = token[len(token)-1]&lt;br /&gt;              for x in range(first, last+1):&lt;br /&gt;                 selection.add(x)&lt;br /&gt;        except:&lt;br /&gt;           # not an int and not a range...&lt;br /&gt;           invalid.add(i)&lt;br /&gt;  # Report invalid tokens before returning valid selection&lt;br /&gt;  print "Invalid set: " + str(invalid)&lt;br /&gt;  return selection&lt;br /&gt;# end parseIntSet&lt;br /&gt;&lt;br /&gt;print 'Generate a list of selected items!'&lt;br /&gt;nputstr = raw_input('Enter a list of items: ')&lt;br /&gt;&lt;br /&gt;selection = parseIntSet(nputstr)&lt;br /&gt;print 'Your selection is: '&lt;br /&gt;print str(selection)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When trying to copy this from someone else I came across a similar function written in Ruby, in case you needed &lt;a href="http://lorenzod8n.wordpress.com/2007/12/04/parsing-a-list-of-numbers-in-ruby/"&gt;that &lt;/a&gt;instead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-7132353532318349236?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/7132353532318349236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=7132353532318349236' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7132353532318349236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7132353532318349236'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/10/parsing-list-of-numbers-in-python.html' title='Parsing a list of numbers in Python'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-5604753278514370082</id><published>2008-09-26T00:32:00.000-07:00</published><updated>2008-09-26T01:56:35.744-07:00</updated><title type='text'>olpc default no password</title><content type='html'>I received an &lt;a href="http://laptop.org/"&gt;OLPC &lt;/a&gt;in the mail today.  It's on loan from a family member who got it as a gift for her daughter.  I was told "It's not a &lt;span style="font-style: italic;"&gt;REAL &lt;/span&gt;computer! - can you fix it?"&lt;br /&gt;&lt;br /&gt;Yes, send it to me.&lt;br /&gt;&lt;br /&gt;Whatever it takes right?  I couldn't wait to tear into this &lt;a href="http://en.wikipedia.org/wiki/OLPC_XO-1"&gt;thing&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3116/2889652986_6e0cb1e353.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://farm4.static.flickr.com/3116/2889652986_6e0cb1e353.jpg" alt="" border="0" /&gt;&lt;/a&gt;SSH is up and running by default out the gate.  Just go to the "&lt;a href="http://farm4.static.flickr.com/3116/2889713990_77f53eeca2_o.jpg"&gt;Neighborhood View&lt;/a&gt;" and connect to your in home wireless AP and you can hit ssh right away:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[olpc@xo-14-7F-A0 ~]$ telnet 192.168.1.118 22&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;Trying 192.168.1.118...&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;Connected to 192.168.1.118.&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;Escape character is '^]'.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SSH-2.0-OpenSSH_4.5&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Which is cool, but there's a catch - you can't login.&lt;br /&gt;&lt;br /&gt;The default user is named 'olpc' - this user, as well as root DO NOT HAVE A DEFAULT PASSWORD.&lt;br /&gt;&lt;br /&gt;The password file is shadow'd:&lt;br /&gt;[olpc@xo-14-7F-A0 ~]$ egrep '^(root|olpc)' /etc/passwd&lt;br /&gt;root:x:0:0:root:/root:/bin/bash&lt;br /&gt;olpc:x:500:500::/home/olpc:/bin/bash&lt;br /&gt;&lt;br /&gt;But if you look at the hash in /etc/shadow you see olpc's "current password hash" is "!!" - which is not valid:&lt;br /&gt;[olpc@xo-14-7F-A0 ~]$ egrep '^(root|olpc)' /etc/shadow&lt;br /&gt;root::13880:0:99999:7:::&lt;br /&gt;olpc:!!:14148:0:99999:7:::&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;root's password is just plain empty&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;Which is handy on the local system:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[olpc@xo-14-7F-A0 ~]$ whoami&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;olpc&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;[olpc@xo-14-7F-A0 ~]$ su&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;bash-3.2# whoami&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;root&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But kind of awkward when you try to login via ssh:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;login as: olpc&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;olpc@192.168.1.118's password:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;Access denied&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The tricky part about that invalid "!!" hash is that it's neither a blank password nor a valid password.  The olpc user can't even change it's &lt;span style="font-weight: bold; font-style: italic;"&gt;OWN &lt;/span&gt;password because there is NO CURRENT VALID PASSWORD:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[olpc@xo-14-7F-A0 ~]$ passwd&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Changing password for user olpc.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Changing password for olpc.&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;(current) UNIX password:&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;passwd: Authentication token manipulation error&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;So we decide move on to root.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Root has an 'empty' password.  Which is valid - but it had me raise en eyebrow as well.&lt;br /&gt;&lt;br /&gt;login as: root&lt;br /&gt;root@192.168.1.118's password:&lt;br /&gt;Access denied&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3061/2889690166_aaef03a675_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://farm4.static.flickr.com/3061/2889690166_aaef03a675_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I was slightly forgiving after my investigation into the default configuration of &lt;a href="http://www.openssh.com/"&gt;OpenSSH&lt;/a&gt;.&lt;br /&gt;bash-3.2# egrep '#Permit(Root|Empty)' /etc/ssh/sshd_config&lt;br /&gt;#PermitRootLogin yes&lt;br /&gt;#PermitEmptyPasswords no&lt;br /&gt;&lt;br /&gt;Because these configuration lines are commented out, the ssh server goes with the standard OpenSSH settings.  Which will NEVER allow the super user to to authenticate directly over ssh, and furthermore would not allow ANY user with an empty password to authenticate &lt;span style="font-style: italic;"&gt;anyway&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:georgia;font-size:100%;"  &gt;To login to your OLPC XO Laptop via ssh you will need to:&lt;br /&gt;1) open a local terminal&lt;br /&gt;2) su to root&lt;br /&gt;3) set a valid password for the 'olpc' user&lt;br /&gt;4) connect to the laptop &lt;/span&gt;&lt;span style="font-weight: bold;font-family:georgia;font-size:100%;"  &gt;as the 'olpc' user&lt;/span&gt;&lt;span style="font-weight: bold;font-family:georgia;font-size:100%;"  &gt; via ssh using the new password you just created&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;e.g.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[olpc@xo-14-7F-A0 ~]$ whoami&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;olpc&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[olpc@xo-14-7F-A0 ~]$ su&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;bash-3.2# passwd olpc&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Changing password for user olpc.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;New UNIX password:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;BAD PASSWORD: it is too short&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Retype new UNIX password:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;passwd: all authentication tokens updated successfully.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;bash-3.2# exit&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;exit&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[olpc@xo-14-7F-A0 ~]$ ssh olpc@192.168.1.118&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;The authenticity of host '192.168.1.118 (192.168.1.118)' can't be established.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;RSA key fingerprint is d4:5a:b0:30:0d:eb:61:9c:df:c9:32:0e:ab:ff:51:9e.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Are you sure you want to continue connecting (yes/no)? yes&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Warning: Permanently added '192.168.1.118' (RSA) to the list of known hosts.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;olpc@192.168.1.118's password:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[olpc@xo-14-7F-A0 ~]$&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Stay tuned - More to come!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-5604753278514370082?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/5604753278514370082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=5604753278514370082' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5604753278514370082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5604753278514370082'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/09/olpc-default-no-password.html' title='olpc default no password'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3116/2889652986_6e0cb1e353_t.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-6159967934104338171</id><published>2008-09-13T00:40:00.000-07:00</published><updated>2008-09-18T13:44:39.763-07:00</updated><title type='text'>Display free memory in Linux / Ubuntu</title><content type='html'>Short Answer:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;free -m | awk 'NR==3 {print $4 " MB"}'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The command 'free' displays some formatted information from /proc/meminfo.&lt;br /&gt;The throw '-m' displays these numbers in &lt;span style="font-weight: bold;"&gt;rounded &lt;/span&gt;megabytes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;# free -m&lt;br /&gt;&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp total&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp used&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp free&amp;nbsp&amp;nbsp shared&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp buffers&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp cached&lt;br /&gt;Mem:&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp 4049&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp 3982&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp 67&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp 0&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp 16&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp 3530&lt;br /&gt;-/+ buffers/cache:&amp;nbsp&amp;nbsp 435&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp 3614&lt;br /&gt;Swap:&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp 6142&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp 53&amp;nbsp&amp;nbsp&amp;nbsp&amp;nbsp 6088&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;It's strange, cause I always figured the "first row, third column" - right under 'FREE' - would be the amount of free memory on a Linux system.  But that number was always low after I'd been running awhile.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3191/2852999138_0fa54b2f62_m.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://farm4.static.flickr.com/3191/2852999138_0fa54b2f62_m.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;And it turns out that it is NOT really what I was looking for.  A more accurate representation of the memory being &lt;span style="font-weight: bold;"&gt;used by your applications&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;available for new processes &lt;/span&gt;is displayed in the &lt;span style="font-weight: bold;"&gt;SECOND &lt;/span&gt;line.&lt;br /&gt;&lt;br /&gt;In addition to the memory that is actually being USED by the kernel and processes resident in memory - Linux also reserves memory to allocate to processes as '&lt;span style="font-weight: bold;"&gt;buffers&lt;/span&gt;' AND uses pretty much any left over memory to hold "&lt;span style="font-weight: bold;"&gt;cached&lt;/span&gt;" files.&lt;br /&gt;&lt;br /&gt;Looking only at the top line...&lt;br /&gt;total = all memory in the system (4GB on this server)&lt;br /&gt;used = all memory currently in use/reserved by running processes and the OS&lt;br /&gt;free = total - used&lt;br /&gt;shared = memory being shared by multiple processes (deprecated?)&lt;br /&gt;buffers = memory reserved by the OS to alloc as buffers when process need them (aka the '&lt;a href="http://belhob.wordpress.com/2007/10/21/dynamic-memory-allocation/"&gt;heap&lt;/a&gt;')&lt;br /&gt;cached = recently used files being stored in ram (THANK YOU LINUX!)&lt;br /&gt;&lt;br /&gt;Here's a simple example I &lt;a href="http://mail.nl.linux.org/linux-mm/2003-03/msg00077.html"&gt;found &lt;/a&gt;to show off the power of 'caching':&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;for i in 1 2 ; do free -o; time grep -r foo /usr/bin &gt;/dev/null 2&gt;/dev/null; done&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;So really the buffers would be allocated to a running process if it asked for them anyway, and the memory being used to cache copies of recently used files would be released immediately if it makes sense to allocate the RAM elsewhere.  So all that memory is '&lt;span style="font-style: italic;"&gt;available&lt;/span&gt;'.&lt;br /&gt;&lt;br /&gt;Using these definitions:&lt;br /&gt;&lt;br /&gt;When thinking about 'how much memory is really being &lt;span style="font-weight: bold;"&gt;used&lt;/span&gt;' - I want to calculate:&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;'used' - ('buffers' + 'cached')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When thinking about 'how much memory is really &lt;span style="font-weight: bold;"&gt;free&lt;/span&gt;' - I want to calculate:&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;'free' + ('buffers' + 'cached')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;With this in mind, the meaning of the second row header form the output of the Linux command "free" (&lt;a href="http://gentoo-wiki.com/FAQ_Linux_Memory_Management"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;-/+ buffers/cache:&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;) makes more sense...&lt;br /&gt;&lt;br /&gt;Free is doing some light lifting for us, using the formula's above to display:&lt;br /&gt;"minus buffers and cache" for the used column&lt;br /&gt;and&lt;br /&gt;"plus buffers and cache" for the free colum&lt;br /&gt;&lt;br /&gt;So when you run free on Linux - the amount of free memory is always displayed right there in the second row, third column.  Hence the 'Short Answer'...&lt;br /&gt;&lt;br /&gt; - Much respect to Mike Griffin who got me thinking about this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-6159967934104338171?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/6159967934104338171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=6159967934104338171' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/6159967934104338171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/6159967934104338171'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/09/display-free-memory-on-linux-ubuntu.html' title='Display free memory in Linux / Ubuntu'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3191/2852999138_0fa54b2f62_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-1344790242823900168</id><published>2008-09-04T00:15:00.000-07:00</published><updated>2008-09-04T14:26:24.636-07:00</updated><title type='text'>DD-WRT Xbox LIVE open NAT</title><content type='html'>When I first setup my DD-WRT router I had problems with Xbox LIVE reporting strict NAT and then moderate NAT.&lt;br /&gt;&lt;br /&gt;To achive "&lt;a href="http://www.xbox.com/en-US/support/connecttolive/xbox360/connectionmethods/troubleshootliveconnection-testnat.htm"&gt;open&lt;/a&gt;" NAT status on Xbox LIVE your best bet is ALWAYS &lt;a href="http://en.wikipedia.org/wiki/Universal_Plug_and_Play"&gt;UPnP&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Not DMZ.&lt;br /&gt;Not even setting up &lt;a href="http://support.microsoft.com/kb/908874"&gt;manual LIVE port forwarding&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Both of these methods fall apart if you have two Xboxs.  UPnP allows the Xbox(s) to decide the best ports to use, when they should be open and when to close them.&lt;br /&gt;&lt;br /&gt;By default the DD-WRT v24 firmware disables UPnP.&lt;br /&gt;&lt;br /&gt;To Enable UPnP on DD-WRT v24:&lt;br /&gt;&lt;span&gt;NAT / QoS -&gt; UPnP -&gt;&lt;br /&gt;&lt;/span&gt;UPnP Service: Enabled&lt;br /&gt;&lt;br /&gt;Click Apply.  You may need to reboot your xbox for changes to take effect.&lt;br /&gt;&lt;br /&gt;In order for UPnP to work as intended the client device (the xbox) must be using DHCP to obtain an IP address from the UPnP enabled router.  To verify your Xbox is using DHCP, as opposed to assigning itself a static ip - open the dashboard and navigate to:&lt;br /&gt;System -&gt; Network Settings -&gt; Edit Settings -&gt;&lt;br /&gt;Select "IP Settings"&lt;br /&gt;Verify "Automatic"&lt;br /&gt;&lt;br /&gt;To see what your Xbox thinks about your NAT try the "Live Connection Test"&lt;br /&gt;System -&gt; Network Settings -&gt; "Test Xbox LIVE Connection"&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://assets.xbox.com/en-us/support/_images/ILM-TestLiveEditSettings.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://assets.xbox.com/en-us/support/_images/ILM-TestLiveEditSettings.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-1344790242823900168?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/1344790242823900168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=1344790242823900168' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1344790242823900168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1344790242823900168'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/09/dd-wrt-xbox-live-open-nat.html' title='DD-WRT Xbox LIVE open NAT'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-1986819084216243673</id><published>2008-09-03T20:45:00.000-07:00</published><updated>2008-09-05T00:41:56.744-07:00</updated><title type='text'>Easy DD-WRT wireless bridge</title><content type='html'>So this is me connecting to a dd-wrt on the other side of the room - no wires&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3271/2827147808_beffee00f4_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 500px;" src="http://farm4.static.flickr.com/3271/2827147808_beffee00f4_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;First you have to be able to connect to both routers on different ip's on the same subnet via wired connection.&lt;br /&gt;&lt;br /&gt;primary gateway - 192.168.1.1&lt;br /&gt;remote client bridge - 192.168.1.2&lt;br /&gt;&lt;br /&gt;If you're all set up and rocking it with your primary gateway on 192.168.1.1 - but you need to add this new device which defaults to the same ip into the mix....&lt;br /&gt;Just log into your current device and change it's ip to .3 - then plug in the new router, navigate to it on .1 - change it .2 - go back to the original on .3 and put it back on .1&lt;br /&gt;&lt;br /&gt;You *may* want to go ahead and disable DHCP on the remote client bridge while your in there, but only if you're not going to immediately configure wireless.&lt;br /&gt;&lt;br /&gt;Remote client bridge (192.168.1.2) wireless setup:&lt;br /&gt;&lt;br /&gt;Step 1:&lt;br /&gt;Wireless -&gt; Basic Settings&lt;br /&gt;&lt;br /&gt;Wireless Mode: Client Bridge&lt;br /&gt;Wireless Network Name (SSID): &lt;enter&gt;&lt;ssid&gt;"SSID of primary gateway / wireless AP"&lt;br /&gt;&lt;br /&gt;click Apply&lt;br /&gt;&lt;br /&gt;Step 2:&lt;br /&gt;Wireless -&gt; Wireless Security&lt;br /&gt;configure wireless settings to match your primary gateway's wireless config&lt;br /&gt;&lt;br /&gt;Apply changes&lt;br /&gt;&lt;br /&gt;That's it, unplug your router and test the connection!&lt;br /&gt;&lt;br /&gt;I *highly* recommend you START with 64bit/10 digit hex WEP.  Go ahead and change your settings on the primary gateway / wireless AP if you have to.  Once you have that working by all means upgrade to a higher security state.  But, do your self a favor and start simple to make sure you have it working.&lt;/ssid&gt;&lt;/enter&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-1986819084216243673?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/1986819084216243673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=1986819084216243673' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1986819084216243673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1986819084216243673'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/09/easy-dd-wrt-wireless-bridge.html' title='Easy DD-WRT wireless bridge'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-2404176991344583425</id><published>2008-09-03T20:25:00.000-07:00</published><updated>2008-09-04T14:17:21.104-07:00</updated><title type='text'>DD-WRT applyuser.cgi hangs</title><content type='html'>What to do if you're running into the issue with the DD-WRT admin page hanging on the applyuser.cgi script when you try to save changes.&lt;br /&gt;&lt;br /&gt;SYMPTOM:&lt;br /&gt;when you click 'apply' you get directed to the address -&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;http://192.168.1.1/applyuser.cgi&lt;/span&gt; &lt;/blockquote&gt;Which is followed by a blank white screen.  Navigating back just proves your changes were not affected.&lt;br /&gt;&lt;br /&gt;SOLUTION:&lt;br /&gt;restart the browser - it's probably just a cookie with a hung up user session or something, but I couldn't find it.  Other suggestions would be very welcome...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-2404176991344583425?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/2404176991344583425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=2404176991344583425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/2404176991344583425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/2404176991344583425'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/09/dd-wrt-applyusercgi-hangs.html' title='DD-WRT applyuser.cgi hangs'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-1849461065135407042</id><published>2008-09-03T19:01:00.000-07:00</published><updated>2008-09-04T14:21:03.066-07:00</updated><title type='text'>HOW TO: DD-WRT on Asus WL-500G Premium V2</title><content type='html'>Our goal is simple:&lt;br /&gt;&lt;br /&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 500px;" src="http://farm4.static.flickr.com/3265/2826886292_44c518b0ee_o.jpg" alt="" border="0" /&gt;&lt;br /&gt;Put DD-WRT on an Asus WL-500G Premium V2&lt;br /&gt;&lt;br /&gt;Our process is straight forward&lt;br /&gt;&lt;ol&gt;&lt;li&gt;establish ip connectivity to router&lt;/li&gt;&lt;li&gt;download dd-wrt firmware&lt;br /&gt;&lt;/li&gt;&lt;li&gt;download Asus WL-500G Premium V2 utilitypack&lt;/li&gt;&lt;li&gt;reboot router in 'restore' mode&lt;/li&gt;&lt;li&gt;disable windows firewall (really?! Yes, I'm afraid so)&lt;/li&gt;&lt;li&gt;install/run Firmware Restoration utility&lt;/li&gt;&lt;li&gt;browse to new firmware and click upload&lt;br /&gt;&lt;/li&gt;&lt;li&gt;wait for router to reboot automatically&lt;/li&gt;&lt;li&gt;re-enable windows firewall&lt;/li&gt;&lt;/ol&gt;Step 1:&lt;br /&gt;My current router was already running on 192.168.1.1 - so I moved it to 192.168.1.2 left my pc on dhcp.  I suppose you could always configure a static ip 192.168.1.??? and a subnet of 255.255.255.0 - The point is you have to be able to ping the asus on 192.168.1.1 !&lt;br /&gt;&lt;br /&gt;Step 2:&lt;br /&gt;DD-WRT download section:&lt;br /&gt;&lt;a href="http://www.dd-wrt.com/dd-wrtv3/dd-wrt/downloads.html"&gt;http://www.dd-wrt.com/dd-wrtv3/dd-wrt/downloads.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;stable -&gt; dd-wrt.v24 SP1 -&gt; Consumer -&gt; ASUS -&gt; WL500g-Premium -&gt;&lt;br /&gt;&lt;a href="http://www.dd-wrt.com/dd-wrtv2/downloads/stable/dd-wrt.v24%20SP1/Consumer/Asus/WL500g-Premium/dd-wrt.v24_mega_generic.bin"&gt;dd-wrt.v24_mega_generic.bin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Step 3:&lt;br /&gt;GAWD ASUS SITE SUCKS!  I hate javascript sometimes...&lt;br /&gt;&lt;br /&gt;Asus download section:&lt;br /&gt;&lt;a href="http://support.asus.com/download/download.aspx"&gt;http://support.asus.com/download/download.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Product: Wireless&lt;br /&gt;Series: AP/Router&lt;br /&gt;Model: WL-500gP V2&lt;br /&gt;&lt;br /&gt;Direct &lt;a href="http://support.asus.com/download/download.aspx?SLanguage=en-us&amp;amp;model=WL-500gP%20V2"&gt;WL-500gP V2&lt;/a&gt; download section&lt;br /&gt;Direct &lt;a href="http://dlcdnet.asus.com/pub/ASUS/wireless/WL-500gPV2/UT_WL500gPv2_4008.zip"&gt;WL-500GP V2 Utility&lt;/a&gt; download&lt;br /&gt;&lt;br /&gt;*I also found it on the included CD, just run D:\Utility\setup.exe&lt;br /&gt;&lt;br /&gt;Step 4:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Unplug the router&lt;/li&gt;&lt;li&gt;Press and hold small black 'restore' button on back next to antenna&lt;/li&gt;&lt;li&gt;Plug in router and continue to hold 'restore'&lt;/li&gt;&lt;li&gt;Wait for the power 'icon' on the front to blink on/off once per second&lt;/li&gt;&lt;li&gt;Release 'restore' button - power icon should continue to blink&lt;/li&gt;&lt;/ul&gt;Success:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3056/2826831596_55bec49657_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://farm4.static.flickr.com/3056/2826831596_55bec49657_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;You should still be able to ping the router on 192.168.1.1 while it is in this mode.&lt;br /&gt;&lt;br /&gt;Step 5:&lt;br /&gt;&lt;br /&gt;Disable Windows Firewall&lt;br /&gt;&lt;br /&gt;You can skip this step for now, but you're going to have to do it eventually.  The ASUS firmware Restoration Utility will run, but won't upload while the windows firewall is active.&lt;br /&gt;&lt;br /&gt;Start -&gt; Control Panel -&gt; Windows Firewall -&gt; Off&lt;br /&gt;&lt;br /&gt;Step 6:&lt;br /&gt;&lt;br /&gt;Extract the UT_WL500gPv2_4008.zip that you downloaded earlier and run the setup.exe to install the Asus WL-500G Premium V2 utilitypack&lt;br /&gt;&lt;br /&gt;Run the Firmware Restoration Utility:&lt;br /&gt;Start -&gt; Program Files -&gt; ASUS Utility -&gt; WL-500gP V2 Wireless Router -&gt; Firmware Restoration&lt;br /&gt;&lt;br /&gt;Step 7:&lt;br /&gt;&lt;br /&gt;Click Browse and navigate out to:&lt;br /&gt;dd-wrt.v24_mega_generic.bin&lt;br /&gt;&lt;br /&gt;Click Upload...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3047/2826047205_2bfc090983.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://farm4.static.flickr.com/3047/2826047205_2bfc090983.jpg" alt="" border="0" /&gt;&lt;/a&gt;It kind of bugs me that it didn't ASK what ip I wanted to upload this firmware to, but I guess I think it 'knows'...&lt;br /&gt;&lt;br /&gt;While the progress bar is pushing around you may see some blinking on the router at first, but after awhile it just sits there:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3230/2826047241_7c3842b253_m.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://farm4.static.flickr.com/3230/2826047241_7c3842b253_m.jpg" alt="" border="0" /&gt;&lt;/a&gt;Should take about a minute for the progress bar to quit, and then you can click close.&lt;br /&gt;&lt;br /&gt;Step 8:&lt;br /&gt;&lt;br /&gt;Really, just sit there... for like 45-60 seconds.  I know, seems like forever.  Eventually the modem will reboot, and you'll get the 'AIR' light lit up and I noticed I could ping it again.  While you waiting don't forget Step 9!&lt;br /&gt;&lt;br /&gt;Step 9:&lt;br /&gt;&lt;br /&gt;Don't forget to turn back on windows firewall!!!&lt;br /&gt;&lt;br /&gt;DONE.  Navigate back to http://192.168.1.1/ and setup the user:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3112/2827005524_733bba962b_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 500px;" src="http://farm4.static.flickr.com/3112/2827005524_733bba962b_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You haven't really LIVED until you've ssh'd into your router:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;login as: root&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;DD-WRT v24 mega (c) 2008 NewMedia-NET GmbH&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Release: 07/27/08 (SVN revision: 10012:10013)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;root@192.168.1.1's password:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;==========================================================&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; ____  ___    __        ______ _____         ____  _  _&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; | _ \| _ \   \ \      / /  _ \_   _| __   _|___ \| || |&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; || | || ||____\ \ /\ / /| |_) || |   \ \ / / __) | || |_&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; ||_| ||_||_____\ V  V / |  _ &lt; | |    \ V / / __/|__   _|&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; |___/|___/      \_/\_/  |_| \_\|_|     \_/ |_____|  |_|&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                       DD-WRT v24&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                   http://www.dd-wrt.com&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;==========================================================&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;BusyBox v1.11.1 (2008-07-27 19:56:11 CEST) built-in shell (ash)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Enter 'help' for a list of built-in commands.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;root@DD-WRT:~# cat /proc/cpuinfo&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;system type             : Broadcom BCM5354 chip rev 2&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;processor               : 0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cpu model               : BCM3302 V2.9&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;BogoMIPS                : 239.20&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;wait instruction        : no&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;microsecond timers      : yes&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;tlb_entries             : 32&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;extra interrupt vector  : no&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;hardware watchpoint     : no&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;VCED exceptions         : not available&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;VCEI exceptions         : not available&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;root@DD-WRT:~#&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note the superuser username.  Instead of the username you created in the DD-WRT initial configuration page, you have to use 'root' as the login username - but still the same password.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-1849461065135407042?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/1849461065135407042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=1849461065135407042' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1849461065135407042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1849461065135407042'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/09/how-to-dd-wrt-on-asus-wl-500g-premium.html' title='HOW TO: DD-WRT on Asus WL-500G Premium V2'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3047/2826047205_2bfc090983_t.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-298192067128902701</id><published>2008-09-03T18:03:00.000-07:00</published><updated>2008-09-04T14:22:17.940-07:00</updated><title type='text'>ASUS WL-500g Premium V2 and DD-WRT</title><content type='html'>So I picked the &lt;a href="http://www.asus.com/products.aspx?l1=12&amp;amp;l2=43&amp;amp;l3=0&amp;amp;model=1121&amp;amp;modelmenu=1"&gt;ASUS WL-500g Premium&lt;/a&gt; because...&lt;br /&gt;&lt;ol&gt;&lt;li&gt;I knew it was supported by &lt;a href="http://www.dd-wrt.com/wiki/index.php/Supported_Devices"&gt;DD-WRT&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Lots of memory (32 MB)&lt;/li&gt;&lt;/ol&gt;I think I read &lt;a href="http://www.dd-wrt.com/phpBB2/viewtopic.php?t=73"&gt;somewhere&lt;/a&gt; that it was actually a pretty good piece of hardware for this kind of thing... but it doesn't matter - it looks cool:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;img src="http://farm4.static.flickr.com/3050/2826764848_e047423b88_o.jpg" alt="" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;Not going to be needing this:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://farm4.static.flickr.com/3088/2825926257_ed11f62336_o.jpg" alt="" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;ASUS WL-500g Premium V2 default IP:&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;192.168.1.1&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ASUS WL-500g Premium V2 default Login:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Username: admin&lt;br /&gt;Password: admin&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;So this is what we're trying to get rid of:&lt;br /&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3148/2825946181_1c6790c571_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://farm4.static.flickr.com/3148/2825946181_1c6790c571_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;OK, so now &lt;a href="http://thoughtsbyclayg.blogspot.com/2008/09/how-to-dd-wrt-on-asus-wl-500g-premium.html"&gt;how to&lt;/a&gt; get DD-WRT onto this thing...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-298192067128902701?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/298192067128902701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=298192067128902701' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/298192067128902701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/298192067128902701'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/09/asus-wl-500g-premium-v2-and-dd-wrt.html' title='ASUS WL-500g Premium V2 and DD-WRT'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-8360229452889302076</id><published>2008-09-03T17:38:00.000-07:00</published><updated>2008-09-04T14:24:45.877-07:00</updated><title type='text'>HOW TO: DD-WRT wireless bridge</title><content type='html'>Got my package from &lt;a href="http://www.newegg.com/"&gt;newegg&lt;/a&gt; today:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3050/2825857423_c77dbfa93f_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm4.static.flickr.com/3050/2825857423_c77dbfa93f_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;Two &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16833320030&amp;amp;Tpk=asus%2bwl-500g"&gt;ASUS WL-500g&lt;/a&gt; wireless routers.  I plan to load them with &lt;a href="http://www.dd-wrt.com/dd-wrtv3/index.php"&gt;DD-WRT&lt;/a&gt; and build a stable &lt;a href="http://en.wikipedia.org/wiki/Wireless_bridge"&gt;wireless bridge&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So I'd like to create a complete guide here, as I work - more updates to follow!&lt;br /&gt;&lt;br /&gt;Update:&lt;br /&gt;&lt;a href="http://thoughtsbyclayg.blogspot.com/2008/09/how-to-dd-wrt-on-asus-wl-500g-premium.html"&gt;HOW TO: DD-WRT on Asus WL-500G Premium V2&lt;/a&gt;&lt;br /&gt;&lt;a href="http://thoughtsbyclayg.blogspot.com/2008/09/easy-dd-wrt-wireless-bridge.html"&gt;Easy DD-WRT wireless bridge&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-8360229452889302076?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/8360229452889302076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=8360229452889302076' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/8360229452889302076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/8360229452889302076'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/09/how-to-dd-wrt-wireless-bridge.html' title='HOW TO: DD-WRT wireless bridge'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-2271478964060683032</id><published>2008-08-15T00:53:00.000-07:00</published><updated>2008-11-17T09:01:30.434-08:00</updated><title type='text'>Best Bash Script EVER - "Just In Case"</title><content type='html'>clayg@m-net:~$ cat bin/jic&lt;br /&gt;#!/bin/bash&lt;br /&gt;if [ $# -eq 0 ]&lt;br /&gt;then&lt;br /&gt;echo "usage: jic [filename]"&lt;br /&gt;exit 1&lt;br /&gt;fi&lt;br /&gt;if ! [ -e $1 ]&lt;br /&gt;then&lt;br /&gt;echo "$1 does not exist!"&lt;br /&gt;exit 1&lt;br /&gt;fi&lt;br /&gt;ext=$(date +%y%m%d.%H%M%S)&lt;br /&gt;jic=$1.$ext&lt;br /&gt;cp $1 $jic&lt;br /&gt;chmod -x $jic&lt;br /&gt;echo "SAVED: $jic"&lt;br /&gt;&lt;br /&gt;Credit goes to a sourpuss I used to work with by the name of Chuck Carson, who gave me the idea.  Where ever you are big guy - thanks.&lt;br /&gt;&lt;br /&gt;The script creates a backup copy of a file you are about to modify:&lt;br /&gt;# jic /etc/sysconfig/iptables&lt;br /&gt;would create a copy called /etc/sysconfig/iptables.YYMMDD.HHMMSS&lt;br /&gt;&lt;br /&gt;you know... &lt;span style="font-style: italic;"&gt;just in case&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Also handy for versioning revisions to scripts you're working on - never now when you're latest hack will turn out to be a total bust.&lt;br /&gt;&lt;br /&gt;Also - go get yourself a free shell account on &lt;a href="http://www.arbornet.org/"&gt;http://www.arbornet.org/&lt;/a&gt;&lt;/filename&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-2271478964060683032?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/2271478964060683032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=2271478964060683032' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/2271478964060683032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/2271478964060683032'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/08/best-bash-script-ever-just-in-case.html' title='Best Bash Script EVER - &quot;Just In Case&quot;'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-1794609587574817616</id><published>2008-07-13T17:25:00.000-07:00</published><updated>2008-07-25T01:05:42.839-07:00</updated><title type='text'>can linux tell me how many open memory slots i have</title><content type='html'>yes it can:&lt;br /&gt;sudo lshw&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="highlight"&gt;lshw&lt;/span&gt;&lt;/b&gt; is a small tool to extract detailed information on the hardware configuration of the machine. It can report exact memory configuration, firmware version, mainboard configuration, CPU version and speed, cache configuration, bus speed, etc.&lt;br /&gt;&lt;br /&gt;So if you're running linux and you need to know your graphics chip set, your motherboard manufacturer or model number... but you're too lazy to open the case and look ;)&lt;br /&gt;&lt;br /&gt;Try the Linux utility List Hardware.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-1794609587574817616?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/1794609587574817616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=1794609587574817616' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1794609587574817616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1794609587574817616'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/07/can-linux-tell-me-how-many-memory-slots.html' title='can linux tell me how many open memory slots i have'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-5018950654871642835</id><published>2008-06-20T01:00:00.000-07:00</published><updated>2008-07-24T00:26:12.195-07:00</updated><title type='text'>Use nmap to scan for ssh servers on subnet</title><content type='html'>Nmap ("Network Mapper") is a free and open source utility for network exploration or security auditing.  If you don't have it - get it:&lt;br /&gt;&lt;blockquote&gt;sudo apt-get install nmap&lt;/blockquote&gt;There's also a GUI called &lt;a href="http://nmap.org/download.html"&gt;Zenmap &lt;/a&gt;that I use sometimes.  But I'm trying to &lt;a href="http://nmap.org/book/man.html"&gt;learn&lt;/a&gt; my way around the powerful command line interface...&lt;br /&gt;&lt;br /&gt;Here's a simple example that will scan all computers on your 255.255.255.0 subnet and report any devices listening on port 22 - the default for SSH.  All of this along with the version of SSH that the server is running is output to a text file 'sshservers':&lt;br /&gt;&lt;blockquote&gt;nmap -p 22 --open -sV 10.0.0.0/24 &gt; sshservers&lt;/blockquote&gt;They say "necessity is the mother of invention" - See what happened was the DHCP server at worked assigned one of my machines a new ip and I wanted to try and track it down remotely.  The only thing I could really think of that I knew - was that it was running sshd and it was somewhere in on this one 'VLAN'.  To narrow down possible candidates I wanted to gather a list of all the machines on this one subnet listening on port 22.  Nmap is perfect for this kind of job!&lt;br /&gt;&lt;br /&gt;Lets break it down&lt;br /&gt;&lt;blockquote&gt;nmap : the executable name&lt;br /&gt;-p 22 : specifies the port to test&lt;br /&gt;--open : suppress  output for clients that are not listening&lt;br /&gt;-sV : display the version string reported by the scanned server&lt;br /&gt;10.0.0.0/24 : the target network, could have been 192.168.0.0/24&lt;br /&gt;(/24 specifies a subnet of 255.255.255.0, look up &lt;a href="http://www.akadia.com/services/ip_routing_on_subnets.html"&gt;slash notation&lt;/a&gt;)&lt;br /&gt;&gt; sshservers : redirects standard output to a file named 'sshservers'&lt;/blockquote&gt;Here was me:&lt;br /&gt;&lt;blockquote&gt;Interesting ports on [ipaddressremoved]:&lt;br /&gt;PORT   STATE SERVICE VERSION&lt;br /&gt;22/tcp open  ssh     OpenSSH 4.7p1 Debian 8ubuntu1.2 (protocol 2.0)&lt;br /&gt;MAC Address: [macaddressremoved] (Intel)&lt;br /&gt;Service Info: OS: Linux&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-5018950654871642835?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/5018950654871642835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=5018950654871642835' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5018950654871642835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5018950654871642835'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/06/use-nmap-to-scan-for-ssh-servers-on.html' title='Use nmap to scan for ssh servers on subnet'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-8099051441606304788</id><published>2008-06-06T00:36:00.000-07:00</published><updated>2008-06-06T01:23:43.531-07:00</updated><title type='text'>Rambling</title><content type='html'>I bought a domain - it's &lt;a href="http://clayg.info/"&gt;clayg.info&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://godaddy.com/"&gt;Godaddy &lt;/a&gt;said it was only $0.99 - but it ended up being $1.19 after some kind of ICANN tax.  I also got a &lt;a href="http://dyndns.org/"&gt;dyndns.org&lt;/a&gt; account that I'm going to use keep a pointer to my computer at home.  And I'm going to have a few cname records for static private ips around the office - 10.0.0.0 stuff.  I'd never even thought of it, but if you're on a network where you don't control the dns records - it IS surprisingly handy.&lt;br /&gt;&lt;br /&gt;I bought a used e machine that I'm going to clean up into a project server.  I want to install a few different things.  &lt;a href="http://www.freebsd.org/"&gt;FreeBSD&lt;/a&gt;, &lt;a href="http://www.apache.org/"&gt;Apache&lt;/a&gt;, &lt;a href="http://www.php.net/"&gt;PHP&lt;/a&gt;, &lt;a href="http://www.jboss.org/"&gt;JBoss&lt;/a&gt;, &lt;a href="http://www.mysql.com/"&gt;MySQL &lt;/a&gt;&amp;amp; &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt;.  I'll have it setup here at home and use the godaddy/dyndns address like my own little web host.&lt;br /&gt;&lt;br /&gt;I got that Ubuntu and Windows XP &lt;a href="http://synergy2.sourceforge.net/security.html"&gt;secure&lt;/a&gt; &lt;a href="http://synergy2.sourceforge.net/"&gt;synergy&lt;/a&gt; tunneled through ssh setup working.  But I didn't take very good notes.  The highlights were definitely:&lt;br /&gt;a) use &lt;a href="http://www.itefix.no/phpws/index.php?module=pagemaster&amp;amp;PAGE_user_op=view_page&amp;amp;PAGE_id=12&amp;amp;MMN_position=149:149"&gt;CopSSH &lt;/a&gt;for the ssh server on the windows box&lt;br /&gt;b) start the synergy client from /etc/gdm/PreSession/Default&lt;br /&gt;&lt;br /&gt;Just after the fi, and before the exit&lt;br /&gt;ssh -f -N -L 24800:[synergy server ip]:24800 [username]@[synergy server ip]&lt;br /&gt;synergyc -f localhost &gt; /dev/null &amp;amp;&lt;br /&gt;&lt;br /&gt;Obviously setting up ssh keys for passwordless authentication is key.  Generate the key on the client, and then append the public key to the ~/.ssh/authorized_key file on the server.&lt;br /&gt;&lt;br /&gt;The SWT project is coming along.  I've updated the engine to better support multiple 'views' in the right pane.  I'll post the source here when I get a chance.&lt;br /&gt;&lt;br /&gt;Oh and I'm a dad:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3053/2554988519_581ae5ae09_m.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://farm4.static.flickr.com/3053/2554988519_581ae5ae09_m.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-8099051441606304788?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/8099051441606304788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=8099051441606304788' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/8099051441606304788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/8099051441606304788'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/06/rambling.html' title='Rambling'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3053/2554988519_581ae5ae09_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-3754877646064751258</id><published>2008-04-07T01:38:00.000-07:00</published><updated>2008-04-07T02:50:08.895-07:00</updated><title type='text'>Deploy simple swt application in eclipse</title><content type='html'>Once you have your program running in Eclipse, at some point your going to want to share it.  It &lt;span style="font-weight: bold;"&gt;is&lt;/span&gt; easy to do - despite all the tutorials about Java Web Start and jnlp .xml files - you don't need a web server.  You can build an old fashioned platform specific .jar file very easily.&lt;br /&gt;&lt;br /&gt;This tutorial is for SWT v3.3 (and above?  I only test on Windows &amp;amp; Linux)&lt;br /&gt;&lt;br /&gt;Under your workspace/myprojectname folder create a folder called "build"&lt;br /&gt;under that make a folder for each OS you want to distribute, for example:&lt;br /&gt;/home/clayg/workspace/LeftTabs/build/LeftTabs-linux&lt;br /&gt;/home/clayg/workspace/LeftTabs/build/LeftTabs-winxp&lt;br /&gt;&lt;br /&gt;Get your hands on the latest SWT release for the OS you're building for:&lt;br /&gt;&lt;a href="http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.3.1.1-200710231652/swt-3.3.1.1-gtk-linux-x86.zip"&gt;Linux &lt;/a&gt;- swt-3.3.1.1-gtk-linux-x86.zip&lt;br /&gt;&lt;a href="http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.3.1.1-200710231652/swt-3.3.1.1-win32-win32-x86.zip"&gt;Windows&lt;/a&gt; - swt-3.3.1.1-win32-win32-x86.zip&lt;br /&gt;&lt;br /&gt;Once you extract that archive you'll see a file called "&lt;span style="font-weight: bold;"&gt;swt.jar&lt;/span&gt;" right in the root - that's your platform specific implementation of all the SWT classes your neat little app is using.  It has to go in the working directory of the .jar you're going to create for your application.&lt;br /&gt;&lt;br /&gt;So copy the swt.jar from the linux release into:&lt;br /&gt;/home/clayg/workspace/myprojectname/build/myprojectname-linux&lt;br /&gt;and copy the swt.jar from the windows release into:&lt;br /&gt;/home/clayg/workspace/myprojectname/build/myprojectname-winxp&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;(C:\Documents and Settings\clayg\workspace\myprojectname\build\myprojectname-[platform])&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then go into eclipse.  Open your project, we're going to create a manifest for your application's java archive.  The manifest tells the java runtime which class to execute and what classes it depends on (I'm pretty sure that's basically what it's doing?).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Right click&lt;/span&gt; on your project in the Package Explorer and select &lt;span style="font-weight: bold;"&gt;New -&gt; File&lt;/span&gt;.  Name it myprojectname-manifest.txt (LeftTabs-manifest.txt).  Fill it with the following goodness:&lt;br /&gt;&lt;br /&gt;Manifest-Version: 1.0&lt;br /&gt;Class-Path: swt.jar&lt;br /&gt;Main-Class: myprojectname&lt;br /&gt;[blank line]&lt;br /&gt;&lt;br /&gt;Replace myprojectname with the name of the class that contains your main method, which is hopefully also the name of the project, and also more than likely your one and only source file?  Replace [blank line] with you guessed - a blank line.  I tried it without the blank line, and you really do need it - LAME.&lt;br /&gt;&lt;br /&gt;Now &lt;span style="font-weight: bold;"&gt;right click&lt;/span&gt; on your project again, and this time selected &lt;span style="font-weight: bold;"&gt;Export&lt;/span&gt;.  In the wizard, under Java - pick "JAR File" and click &lt;span style="font-weight: bold;"&gt;Next&lt;/span&gt;.  Your project should already be selected, under "Select the export destination:" click &lt;span style="font-weight: bold;"&gt;Browse &lt;/span&gt;next to "JAR File"&lt;br /&gt;&lt;br /&gt;You want to create a file called myprojectname-[platform].jar under the folder:&lt;br /&gt;/home/clayg/workspace/myprojectname/build/myprojectname-[platform]&lt;br /&gt;so the first time I did this for the linux platform, I ended up with&lt;br /&gt;/home/clayg/workspace/LeftTabs/build/LeftTabs-linux/LeftTabs-linux.jar&lt;br /&gt;the second time, when I did this again for windows, I got:&lt;br /&gt;/home/clayg/workspace/LeftTabs/build/LeftTabs-winxp/LeftTabs-winxp.jar&lt;br /&gt;&lt;br /&gt;Click &lt;span style="font-weight: bold;"&gt;Next&lt;/span&gt;, make sure "Export class files with warnings" is selected, click &lt;span style="font-weight: bold;"&gt;Next &lt;/span&gt;again.&lt;br /&gt;&lt;br /&gt;Now choose "&lt;span style="font-weight: bold;"&gt;Use existing manifest from workspace&lt;/span&gt;" and click &lt;span style="font-weight: bold;"&gt;Browse&lt;/span&gt;.  Select the myprojectname-manifest.txt, click &lt;span style="font-weight: bold;"&gt;OK&lt;/span&gt;.  Now just hit &lt;span style="font-weight: bold;"&gt;Finish &lt;/span&gt;to build your application.&lt;br /&gt;&lt;br /&gt;You need the whole myprojectname-[platform] directory to run your app.&lt;br /&gt;In windows:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;double click the &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;myprojectname-winxp&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;.jar file&lt;/span&gt;&lt;br /&gt;In linux open a console in the myprojectname-linux folder, and run:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;$java -jar myprojectname-linux.jar&lt;/span&gt;&lt;br /&gt;from the command prompt&lt;br /&gt;&lt;br /&gt;In the process of building my LeftTabs application for windows, I discovered a bug that didn't show up when I was building it under Linux.  I believe the end result is actually a more elegant solution.&lt;br /&gt;&lt;br /&gt;Line 374:&lt;br /&gt;text.addListener(SWT.FocusOut, new Listener()&lt;br /&gt;{ ...&lt;br /&gt;&lt;br /&gt;became:&lt;br /&gt;text.addListener(SWT.Deactivate, new Listener()&lt;br /&gt;{ ...&lt;br /&gt;&lt;br /&gt;The purpose of this Listener was to trigger the Modify Event for the view Widget which would tell the main application that the data in the view should be written back to the selected item in the tree.  I &lt;span style="font-weight: bold; font-style: italic;"&gt;was &lt;/span&gt;doing this when Text item in the view LOST FOCUS.  But apparently in windows this happens after the new item is selected in the Tree - which caused the data in the tree to loose sync with the data in the view.&lt;br /&gt;&lt;br /&gt;Anyway, &lt;a href="http://www.google.com/translate_t?langpair=es%7Cen&amp;amp;q=Vivir%20es%20aprender"&gt;vivir es aprender&lt;/a&gt;, I didn't know an event SWT.Deactivate existed.  Works great.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-3754877646064751258?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/3754877646064751258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=3754877646064751258' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/3754877646064751258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/3754877646064751258'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/04/deploy-simple-swt-application-in.html' title='Deploy simple swt application in eclipse'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-8144294100821381515</id><published>2008-04-02T00:22:00.000-07:00</published><updated>2008-04-10T00:35:04.800-07:00</updated><title type='text'>SWT Java - Left Hand Tabs - with Drag and Drop custom treeItem.setData()</title><content type='html'>I'm a month behind my planned development because I had to build the foundation of my application before I could even start.&lt;br /&gt;&lt;br /&gt;Here's hoping someone else gets a head start.&lt;br /&gt;&lt;br /&gt;LeftTabs.java is a simple expandable application based on the SWT Java framework that has a "list" of "items" on the left, and on the right a "view" that will display their data.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm4.static.flickr.com/3154/2383513562_960742333b_o.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm4.static.flickr.com/3154/2383513562_960742333b_o.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The list is implemented by a tree.  You can assign your own custom data type to each treeItem.  You can create new items with a right-click pop-up menu.  You can delete or drag and drop any item in the tree.  Your custom data associated with the treeItem will be meticulously preserved.  You can update the data in the view on the right and the changes will be synced back to your custom data type in the selected treeItem - automatically.&lt;br /&gt;&lt;br /&gt;It's not all that surprising that more templates like this aren't available.  It was rather difficult to but together.  But there was lots of resources that went into making this possible.  Many elements in this code are based on examples taken from: &lt;a href="http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/CatalogSWT-JFace-Eclipse.htm"&gt;www.java2s.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="padding: 5px; overflow: scroll; display: block; margin-left: 10px; background-color: rgb(238, 238, 238); height: 400px;font-size:85%;" &gt;&lt;br /&gt;/*&lt;br /&gt; * Basic template for app with left hand tabs&lt;br /&gt; * and custom pane on right&lt;br /&gt; * by clay.dot.gerrard.at.gmail.dot.com&lt;br /&gt; */&lt;br /&gt;import java.io.ByteArrayInputStream;&lt;br /&gt;import java.io.ByteArrayOutputStream;&lt;br /&gt;import java.io.DataInputStream;&lt;br /&gt;import java.io.DataOutputStream;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;&lt;br /&gt;import org.eclipse.swt.SWT;&lt;br /&gt;import org.eclipse.swt.widgets.Composite;&lt;br /&gt;import org.eclipse.swt.widgets.Display;&lt;br /&gt;import org.eclipse.swt.widgets.Event;&lt;br /&gt;import org.eclipse.swt.widgets.Listener;&lt;br /&gt;import org.eclipse.swt.widgets.Menu;&lt;br /&gt;import org.eclipse.swt.widgets.MenuItem;&lt;br /&gt;import org.eclipse.swt.widgets.Shell;&lt;br /&gt;import org.eclipse.swt.widgets.Text;&lt;br /&gt;import org.eclipse.swt.widgets.Tree;&lt;br /&gt;import org.eclipse.swt.widgets.TreeItem;&lt;br /&gt;import org.eclipse.swt.graphics.Point;&lt;br /&gt;import org.eclipse.swt.graphics.Rectangle;&lt;br /&gt;import org.eclipse.swt.widgets.MessageBox;&lt;br /&gt;import org.eclipse.swt.dnd.*;&lt;br /&gt;import org.eclipse.swt.layout.*;&lt;br /&gt;&lt;br /&gt;public class LeftTabs {&lt;br /&gt; &lt;br /&gt; // left hand "tab" tree&lt;br /&gt; static Tree tree;&lt;br /&gt; // right hand viewer&lt;br /&gt; static CompositePane view;&lt;br /&gt; // temporary TreeItem used to hold data during Drag &amp; Drop&lt;br /&gt; static TreeItem sourceTreeItem;&lt;br /&gt; //  keep track of number of treeItems created&lt;br /&gt; static int count = 1;&lt;br /&gt;&lt;br /&gt;  public static void main(String[] args) {&lt;br /&gt;    // setup the display &amp; shell &amp; layout&lt;br /&gt; final Display display = new Display();&lt;br /&gt;    final Shell shell = new Shell(display);&lt;br /&gt;    FillLayout fillLayout = new FillLayout();&lt;br /&gt;    // columns&lt;br /&gt;    fillLayout.type = SWT.HORIZONTAL;&lt;br /&gt;    // break 'em up a little&lt;br /&gt;    fillLayout.spacing = 3;&lt;br /&gt;    fillLayout.marginHeight = 3;&lt;br /&gt;    shell.setLayout(fillLayout);&lt;br /&gt;  &lt;br /&gt;    // And here's the tree&lt;br /&gt;    tree = new Tree(shell, SWT.BORDER);   &lt;br /&gt;    // filled with some data&lt;br /&gt;    for (int i = 1; i &lt;= 3; i++) {&lt;br /&gt;      TreeItemData myData = new TreeItemData();&lt;br /&gt;      myData.Name = "Item" + i;&lt;br /&gt;      myData.field1 = myData.Name + " Data";&lt;br /&gt;      TreeItem item = new TreeItem(tree, SWT.NONE);&lt;br /&gt;      count++;&lt;br /&gt;      item.setText(myData.Name);&lt;br /&gt;      item.setData(myData);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    // And here's the right hand pane&lt;br /&gt;    view = new CompositePane(shell);&lt;br /&gt;    &lt;br /&gt;    // right click menu on the tree&lt;br /&gt;    tree.addListener(SWT.MenuDetect, new Listener() {&lt;br /&gt;        public void handleEvent(Event event) {&lt;br /&gt;          Menu menu = new Menu(shell, SWT.POP_UP);&lt;br /&gt;          // NEW ITEM&lt;br /&gt;          MenuItem item_new = new MenuItem(menu, SWT.PUSH);&lt;br /&gt;          item_new.setText("New Item");&lt;br /&gt;          // when click "New Item", add an item to tree&lt;br /&gt;          item_new.addListener(SWT.Selection, new Listener() {&lt;br /&gt;            public void handleEvent(Event e) {&lt;br /&gt;             TreeItem[] selection = tree.getSelection();&lt;br /&gt;             int index;&lt;br /&gt;             if (selection.length != 0)&lt;br /&gt;              index = tree.indexOf(selection[0]) + 1;&lt;br /&gt;             else&lt;br /&gt;              index = 0;&lt;br /&gt;             TreeItem item = new TreeItem(tree, SWT.NONE, index);&lt;br /&gt;             TreeItemData myData = new TreeItemData();&lt;br /&gt;             myData.Name = "Item" + count++;&lt;br /&gt;             myData.field1 = myData.Name + " Data";&lt;br /&gt;             item.setText(myData.Name);&lt;br /&gt;                item.setData(myData);&lt;br /&gt;                view.setData((TreeItemData) item.getData());&lt;br /&gt;                tree.setSelection(item);&lt;br /&gt;            }&lt;br /&gt;          }); // end item_new event&lt;br /&gt;          &lt;br /&gt;          // DELETE ITEM&lt;br /&gt;          MenuItem item_delete = new MenuItem(menu, SWT.PUSH);&lt;br /&gt;          item_delete.setText("Delete Item");&lt;br /&gt;          // when click "Delete Item", delete selected item&lt;br /&gt;          item_delete.addListener(SWT.Selection, new Listener() {&lt;br /&gt;           public void handleEvent(Event e) {&lt;br /&gt;            TreeItem[] selection = tree.getSelection();&lt;br /&gt;            int index = tree.indexOf(selection[0]);&lt;br /&gt;            for (int i=0; i &lt; selection.length; i++){&lt;br /&gt;             selection[i].dispose();&lt;br /&gt;            }&lt;br /&gt;            // item deleted need new selection&lt;br /&gt;            TreeItem[] items = tree.getItems();&lt;br /&gt;            if (items.length != 0) {&lt;br /&gt;             if (index &gt; items.length-1) {&lt;br /&gt;              // it would be better to select an item closer to the deleted item?&lt;br /&gt;              view.setData((TreeItemData) items[items.length-1].getData());&lt;br /&gt;              tree.setSelection(items[items.length-1]);&lt;br /&gt;             } else {&lt;br /&gt;              view.setData((TreeItemData) items[index].getData());&lt;br /&gt;                 tree.setSelection(items[index]);&lt;br /&gt;             }&lt;br /&gt;            }&lt;br /&gt;           }&lt;br /&gt;          }); // end item_delete&lt;br /&gt;          &lt;br /&gt;          menu.setLocation(event.x, event.y);&lt;br /&gt;          menu.setVisible(true);&lt;br /&gt;          while (!menu.isDisposed() &amp;&amp; menu.isVisible()) {&lt;br /&gt;            if (!display.readAndDispatch())&lt;br /&gt;              display.sleep();&lt;br /&gt;          }&lt;br /&gt;          menu.dispose();&lt;br /&gt;        }&lt;br /&gt;      });  // end right click menu&lt;br /&gt;        &lt;br /&gt;    // when a new treeItem is selected, update the view&lt;br /&gt;    tree.addListener(SWT.Selection, new Listener() {&lt;br /&gt;        public void handleEvent(Event event) &lt;br /&gt;        {&lt;br /&gt;         view.setData((TreeItemData) event.item.getData());&lt;br /&gt;        }&lt;br /&gt;      });  // end update view with tree item data&lt;br /&gt;    &lt;br /&gt;    // when the tree looses focus make sure things are in order&lt;br /&gt;    tree.addListener(SWT.FocusOut, new Listener() {&lt;br /&gt;     public void handleEvent(Event event) {&lt;br /&gt;      TreeItem[] selection = tree.getSelection();&lt;br /&gt;      // no item selected - view data is ambigous, possible data loss&lt;br /&gt;      if (selection.length == 0) {&lt;br /&gt;       MessageBox messageBox = new MessageBox(shell, SWT.ICON_ERROR);&lt;br /&gt;             messageBox.setText("Possible Loss of Data.");&lt;br /&gt;             messageBox.setMessage("Think about what you did to cause the view data and the tree selection to get out of sync, and decide how you want your program to behave!");&lt;br /&gt;             messageBox.open();&lt;br /&gt;             //*/&lt;br /&gt;             TreeItem[] items = tree.getItems();&lt;br /&gt;       if (items.length != 0) {&lt;br /&gt;        view.setData((TreeItemData) items[0].getData());&lt;br /&gt;        tree.setSelection(items[0]);&lt;br /&gt;       } else {&lt;br /&gt;        // no items in view?!  you can't delete the last item...&lt;br /&gt;        TreeItemData myData = new TreeItemData();&lt;br /&gt;        myData.Name = "Item" + count++;&lt;br /&gt;        myData.field1 = myData.Name + " Data";&lt;br /&gt;        TreeItem item = new TreeItem(tree, SWT.NONE);&lt;br /&gt;        item.setText(myData.Name);&lt;br /&gt;        item.setData(myData);&lt;br /&gt;        view.setData((TreeItemData) item.getData());&lt;br /&gt;        tree.setSelection(item);&lt;br /&gt;       }&lt;br /&gt;       //*/&lt;br /&gt;      } &lt;br /&gt;        }&lt;br /&gt;    }); // end tree loose focus&lt;br /&gt;    &lt;br /&gt;    // setup DragSource&lt;br /&gt;    DragSource source = new DragSource(tree, DND.DROP_COPY);&lt;br /&gt;    source.setTransfer(new Transfer[] { TreeItemDataTransfer.getInstance() });&lt;br /&gt;    &lt;br /&gt;    source.addDragListener(new DragSourceAdapter() {&lt;br /&gt;     public void dragStart(DragSourceEvent event) {&lt;br /&gt;      TreeItem[] selection = tree.getSelection();&lt;br /&gt;      if (selection.length &gt; 0 &amp;&amp; selection[0].getData() != null) {&lt;br /&gt;       event.doit = true;&lt;br /&gt;       sourceTreeItem = selection[0];&lt;br /&gt;      } else {&lt;br /&gt;       event.doit = false;&lt;br /&gt;      }&lt;br /&gt;     } // end dargStart&lt;br /&gt;     &lt;br /&gt;     public void dragSetData(DragSourceEvent event) {&lt;br /&gt;      if (TreeItemDataTransfer.getInstance().isSupportedType(event.dataType))&lt;br /&gt;       event.data = sourceTreeItem.getData();&lt;br /&gt;     } // end dargSetData&lt;br /&gt;     &lt;br /&gt;     public void dragFinished(DragSourceEvent event) {&lt;br /&gt;      if (event.doit) {&lt;br /&gt;       sourceTreeItem.dispose();&lt;br /&gt;      }&lt;br /&gt;      sourceTreeItem = null;&lt;br /&gt;     } // end dragFinished&lt;br /&gt;    }); // end DragSource&lt;br /&gt;&lt;br /&gt;    // setup DropTarget&lt;br /&gt;    DropTarget target = new DropTarget(tree, DND.DROP_COPY);&lt;br /&gt;    target.setTransfer(new Transfer[] {TreeItemDataTransfer.getInstance() });&lt;br /&gt;    &lt;br /&gt;    target.addDropListener(new DropTargetAdapter() {&lt;br /&gt;     public void dragEnter(DropTargetEvent event) {&lt;br /&gt;      event.detail = DND.DROP_COPY;&lt;br /&gt;     } // end dragEnter&lt;br /&gt;     &lt;br /&gt;     public void dragOver(DropTargetEvent event) {&lt;br /&gt;      event.feedback = DND.FEEDBACK_SCROLL;&lt;br /&gt;      // if the drop target is a specific item in the tree&lt;br /&gt;      if (event.item != null) {&lt;br /&gt;       TreeItem item = (TreeItem) event.item;&lt;br /&gt;       Point pt = display.map(null, tree, event.x, event.y);&lt;br /&gt;       Rectangle bounds = item.getBounds();&lt;br /&gt;       // give visual cue of drop location to user&lt;br /&gt;       if (pt.y &lt; bounds.y + bounds.height/2) {&lt;br /&gt;        event.feedback |= DND.FEEDBACK_INSERT_BEFORE;&lt;br /&gt;       } else {&lt;br /&gt;        event.feedback |= DND.FEEDBACK_INSERT_AFTER;&lt;br /&gt;       }&lt;br /&gt;      } else {&lt;br /&gt;       // set event.item to last item in list &amp; set feedback to after&lt;br /&gt;      }&lt;br /&gt;     } // end dragOver&lt;br /&gt;     &lt;br /&gt;     public void drop(DropTargetEvent event) {&lt;br /&gt;      try {&lt;br /&gt;       if (event.data == null) {&lt;br /&gt;        event.detail = DND.DROP_NONE;&lt;br /&gt;        return;&lt;br /&gt;       }&lt;br /&gt;       &lt;br /&gt;       TreeItem newItem;&lt;br /&gt;       // if the dropTarget is a specific item in the tree&lt;br /&gt;       if (event.item != null) {&lt;br /&gt;        TreeItem selection  = (TreeItem) event.item;&lt;br /&gt;           Point pt = display.map(null, tree, event.x, event.y);&lt;br /&gt;           Rectangle bounds = selection.getBounds();&lt;br /&gt;           //TreeItem[] items = tree.getItems();&lt;br /&gt;           // find index of selection&lt;br /&gt;           int index = tree.indexOf(selection);&lt;br /&gt;           // insert newItem at index&lt;br /&gt;           if (pt.y &lt; bounds.y + bounds.height/2) {&lt;br /&gt;            // insert before&lt;br /&gt;            newItem = new TreeItem(tree, SWT.NONE, index);&lt;br /&gt;           } else {&lt;br /&gt;            // insert after&lt;br /&gt;            newItem = new TreeItem(tree, SWT.NONE, index+1);&lt;br /&gt;           }&lt;br /&gt;       } else {&lt;br /&gt;        // no specific item selected, drop at the end&lt;br /&gt;        newItem = new TreeItem(tree, SWT.NONE);&lt;br /&gt;       }&lt;br /&gt;              &lt;br /&gt;       TreeItemData myType = (TreeItemData) event.data;&lt;br /&gt;       newItem.setText(myType.Name);&lt;br /&gt;       newItem.setData(myType);&lt;br /&gt;       // set selection otherwise view data gets out of sync&lt;br /&gt;       tree.setSelection(newItem);&lt;br /&gt;      } catch (RuntimeException e) {&lt;br /&gt;       e.printStackTrace();&lt;br /&gt;      }&lt;br /&gt;     } // end drop&lt;br /&gt;    }); // end DropTarget&lt;br /&gt;    &lt;br /&gt;    // write view data back to tree - see CompositePane.Update()&lt;br /&gt;    tree.addListener(SWT.Arm, new Listener() {&lt;br /&gt;     public void handleEvent(Event event) {&lt;br /&gt;      tree.getSelection()[0].setData((TreeItemData) view.getData());&lt;br /&gt;     }&lt;br /&gt;    }); &lt;br /&gt;    &lt;br /&gt;    // wrap it up&lt;br /&gt;    shell.open();&lt;br /&gt;    while (!shell.isDisposed()) {&lt;br /&gt;      if (!display.readAndDispatch())&lt;br /&gt;        display.sleep();&lt;br /&gt;    }&lt;br /&gt;    display.dispose();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}  // class LeftTabs&lt;br /&gt;&lt;br /&gt;class TreeItemData {&lt;br /&gt; // all the data to be held by each treeItem&lt;br /&gt; String Name;&lt;br /&gt; String field1;&lt;br /&gt;} // new members must be explicitly handled in nativeToJava &amp; javaToNative&lt;br /&gt;&lt;br /&gt;// Transfer class for handling DND of TreeItemData&lt;br /&gt;class TreeItemDataTransfer extends ByteArrayTransfer {&lt;br /&gt; private static final String TreeItemData_TRANSFER_NAME = "TreeItemData_TRANSFER";&lt;br /&gt; private static final int TreeItemData_TRANSFER_ID = registerType (TreeItemData_TRANSFER_NAME);&lt;br /&gt; private static TreeItemDataTransfer instance = new TreeItemDataTransfer();&lt;br /&gt; &lt;br /&gt; public static TreeItemDataTransfer getInstance() {&lt;br /&gt;  return instance;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; protected String[] getTypeNames() {&lt;br /&gt;  return new String[] { TreeItemData_TRANSFER_NAME };&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; protected int[] getTypeIds() {&lt;br /&gt;  return new int[] {TreeItemData_TRANSFER_ID};&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void javaToNative (Object object, TransferData transferData) {&lt;br /&gt;  if (object == null || !(object instanceof TreeItemData))&lt;br /&gt;   return;&lt;br /&gt;  &lt;br /&gt;  TreeItemData myType = (TreeItemData) object;&lt;br /&gt;  &lt;br /&gt;  if (isSupportedType(transferData)) {&lt;br /&gt;   try {&lt;br /&gt;    ByteArrayOutputStream stream = new ByteArrayOutputStream();&lt;br /&gt;    DataOutputStream out = new DataOutputStream(stream);&lt;br /&gt;    // write out each member in your custom dataType&lt;br /&gt;    out.writeUTF(myType.Name);&lt;br /&gt;    out.writeUTF(myType.field1);&lt;br /&gt;    out.close();&lt;br /&gt;    &lt;br /&gt;    super.javaToNative(stream.toByteArray(), transferData);&lt;br /&gt;   } catch (IOException e) {&lt;br /&gt;    e.printStackTrace();&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; } // end javaToNative&lt;br /&gt; &lt;br /&gt; public Object nativeToJava (TransferData transferData) {&lt;br /&gt;  if (isSupportedType(transferData)) {&lt;br /&gt;   byte[] buffer = (byte[]) super.nativeToJava(transferData);&lt;br /&gt;   if (buffer == null)&lt;br /&gt;    return null;&lt;br /&gt;   &lt;br /&gt;   TreeItemData myType = new TreeItemData();&lt;br /&gt;   &lt;br /&gt;   try {&lt;br /&gt;    ByteArrayInputStream stream = new ByteArrayInputStream(buffer);&lt;br /&gt;    DataInputStream in = new DataInputStream(stream);&lt;br /&gt;    // read in each member in your custom dataType&lt;br /&gt;    myType.Name = in.readUTF();&lt;br /&gt;    myType.field1 = in.readUTF();&lt;br /&gt;    in.close();&lt;br /&gt;   } catch (IOException e) {&lt;br /&gt;    e.printStackTrace();&lt;br /&gt;    return null;&lt;br /&gt;   }&lt;br /&gt;   return myType;&lt;br /&gt;  } else {&lt;br /&gt;   return null;&lt;br /&gt;  }&lt;br /&gt; } // end nativetoJava&lt;br /&gt;                  &lt;br /&gt;} // end TreeItemDataTransfer&lt;br /&gt;&lt;br /&gt;// Composite widget for defining the right hand "view"&lt;br /&gt;class CompositePane extends Composite {&lt;br /&gt;&lt;br /&gt; // local TreeItemData, to keep track of changes&lt;br /&gt; static TreeItemData viewData;&lt;br /&gt; &lt;br /&gt; // declarations of pane view widgets&lt;br /&gt; static Text text;&lt;br /&gt; &lt;br /&gt; public CompositePane (Composite c) {&lt;br /&gt;  // setup layout of the pane&lt;br /&gt;  super(c, SWT.NONE);&lt;br /&gt;  this.setLayout(new FillLayout());&lt;br /&gt;        &lt;br /&gt;        // put widgets in the pane&lt;br /&gt;        text = new Text(this, SWT.BORDER | SWT.MULTI | SWT.WRAP);&lt;br /&gt;        &lt;br /&gt;        // add a loose focus listener to EVERY *EDITABLE* widget&lt;br /&gt;        text.addListener(SWT.Deactivate, new Listener()&lt;br /&gt;        {&lt;br /&gt;         public void handleEvent(Event event)&lt;br /&gt;         {&lt;br /&gt;          // sync changes in view back to dataum&lt;br /&gt;          Update();&lt;br /&gt;         }&lt;br /&gt;        });        &lt;br /&gt; }  // CompositePane constructor&lt;br /&gt; &lt;br /&gt; public void setData (TreeItemData n)&lt;br /&gt; {&lt;br /&gt;  viewData = n;&lt;br /&gt;  // populate the pane's elements with the viewData&lt;br /&gt;  text.setText(viewData.field1);&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; // update viewData, then notify listener that it should sync to the tree&lt;br /&gt; public void Update() {&lt;br /&gt;  viewData.field1 = text.getText();&lt;br /&gt;  this.notifyListeners(SWT.Modify, new Event());&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public TreeItemData getData()&lt;br /&gt; {&lt;br /&gt;  return viewData;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;} // class CompositePane&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;I'm not happy with my options for displaying code in google blogger, and more than a little &lt;span style="font-weight: bold;"&gt;disappointed &lt;/span&gt;in this temporary solution.  Expect a blog post to come out of that.  I'm also trying to work on a secure crossplatform Snergy config that's giving me trouble so it may be worth a post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-8144294100821381515?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/8144294100821381515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=8144294100821381515' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/8144294100821381515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/8144294100821381515'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/04/swt-java-left-hand-tabs-with-drag-and.html' title='SWT Java - Left Hand Tabs - with Drag and Drop custom treeItem.setData()'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-335510103059076386</id><published>2008-02-16T00:14:00.000-08:00</published><updated>2008-09-04T15:42:38.998-07:00</updated><title type='text'>how to delete last command from bash history</title><content type='html'>If you have ever typed something into a command prompt that you wished you hadn't - you may find it useful to know that you can delete it from ~/.bash_history very easily.&lt;br /&gt;&lt;br /&gt;The command:&lt;br /&gt;&lt;dl compact="compact"&gt;&lt;dt&gt;&lt;b&gt;history -d&lt;/b&gt; &lt;i&gt;offset&lt;/i&gt;&lt;/dt&gt;&lt;/dl&gt;will delete the history entry at position &lt;i&gt;offset&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;# history&lt;br /&gt;1  cd&lt;br /&gt;2  history&lt;br /&gt;3  ls -alhF&lt;br /&gt;4  history&lt;br /&gt;5  wget username:password@private.ftp.com/secret/file.tar.gz&lt;br /&gt;6  history&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;so to delete the wget command (which contains a password) - just use:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;history -d 5&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;# history -d 5&lt;br /&gt;# history&lt;br /&gt;1  cd&lt;br /&gt;2  history&lt;br /&gt;3  ls -alhF&lt;br /&gt;4  history&lt;br /&gt;5  history&lt;br /&gt;6  history -d 5&lt;br /&gt;7  history&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But suppose you KNOW you're about to enter a command you don't want to go into history.  It'd be nice if you could just tack a little "hideme" modifer onto the front or tail of your command and be done with it.  Unfortunately from what I've been able to google there is no such feature built into history or bash.&lt;br /&gt;&lt;br /&gt;Naturally I made one.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;TMP=$(history | tail -1 | awk '{print $1}') &amp;amp;&amp;amp; history -d $TMP &amp;amp;&amp;amp; \&lt;br /&gt;paste_in_shell_and_replace_this_with_whatever_you_want_to_hide&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;And naturally someone smarter than me came along and found a better way to do it - THANKFULLY they posted a comment here to help us out (thanks Mitch!):&lt;br /&gt;&lt;br /&gt;history -d $((HISTCMD-1)) &lt;span style="font-size:85%;"&gt;&amp;amp;&amp;amp; \&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;paste_in_shell_and_replace_this_with_whatever_you_want_to_hide&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Rather than holding down backspace, you may find it useful to know that in bash Ctrl-W will delete from the cursor to the beginning of the previous word.&lt;br /&gt;&lt;br /&gt;What I don't get, is that according man bash HISTCMD should be the CURRENT history number:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;     HISTCMD&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    The history number, or index in the history list, of the current command.&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and yet in ALL my tests $HISTCMD is the "index in the history list, of the current command" &lt;span style="font-weight: bold;"&gt;+1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But it can still lead to two two useful aliases:&lt;br /&gt;&lt;br /&gt;alias hideme='history -d $((HISTCMD-1))'&lt;br /&gt;alias hideprev='history -d $((HISTCMD-2)) &amp;amp;&amp;amp; history -d $((HISTCMD-1))'&lt;br /&gt;&lt;br /&gt;Dig the sneaky:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;# history&lt;br /&gt;1  cd&lt;br /&gt;2  history&lt;br /&gt;3  ls -alhF&lt;br /&gt;4  history&lt;br /&gt;5  history&lt;br /&gt;6  history -d 5&lt;br /&gt;7  history&lt;br /&gt;8  vi .bashrc&lt;br /&gt;9  history&lt;br /&gt;# &lt;span style="font-weight: bold;"&gt;echo password &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&amp;amp;&amp;amp; hideme&lt;br /&gt;password&lt;br /&gt;# echo password&lt;br /&gt;password&lt;br /&gt;# hideprev&lt;br /&gt;&lt;/span&gt;# history&lt;br /&gt;1  cd&lt;br /&gt;2  history&lt;br /&gt;3  ls -alhF&lt;br /&gt;4  history&lt;br /&gt;5  history&lt;br /&gt;6  history -d 5&lt;br /&gt;7  history&lt;br /&gt;8  vi .bashrc&lt;br /&gt;9  history&lt;br /&gt;10  history&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I know the blog's kinda been on Linux kick lately - some of that is coming from the new job - I'm using Linux more.  But, I've been working on a little project in Eclipse - Java/SWT - and I'm getting to a point where I may have some useful learnings to post coming out of that.  Or maybe not...&lt;br /&gt;&lt;br /&gt;Internet Tablet, and all my xbox's are running fine...&lt;br /&gt;&lt;br /&gt;I'd like to throw out some props to Ivie for sending me an email about one of my posts that she read.  I try to post stuff that I myself have trouble finding out there on the interwebz - so it's always nice to hear from someone that finds it useful - thanks Ivie!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-335510103059076386?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/335510103059076386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=335510103059076386' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/335510103059076386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/335510103059076386'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/02/how-to-delete-last-command-from-bash.html' title='how to delete last command from bash history'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-9051872434874516188</id><published>2008-01-26T23:10:00.000-08:00</published><updated>2008-01-30T01:23:11.424-08:00</updated><title type='text'>ubuntu disable hardware</title><content type='html'>I had a second sound card that kept getting picked up by apps under ubuntu as my primary audio device.  In windows I sometimes use the game port on this pci sound card, but in general I don't even care if Linux detects it.&lt;br /&gt;&lt;br /&gt;In ubuntu gnome, under &lt;span style="font-weight: bold;"&gt;System-&gt;Preferences-&gt;Sound&lt;/span&gt;&lt;br /&gt;I had something like this:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm3.static.flickr.com/2065/2222694272_2781468eaa_o.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm3.static.flickr.com/2065/2222694272_2781468eaa_o.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;In an unrelated effort, I had only recently discovered an important linux command - &lt;span style="font-weight: bold;"&gt;lsmod&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The command list modules will display information about all loaded kernel modules.  Kernel modules are dynamically loaded kernel functions, such as a device driver.&lt;br /&gt;&lt;br /&gt;When I looked through the list of loaded kernel modules on my system:&lt;br /&gt;&lt;blockquote&gt;lsmod | less&lt;/blockquote&gt;I found this:&lt;br /&gt;&lt;br /&gt;snd_ens1370           21536  0&lt;br /&gt;gameport                 16776  1 snd_ens1370&lt;br /&gt;snd_ak4531_codec  9856  1 snd_ens1370&lt;br /&gt;snd_pcm                  80388  5 snd_ens1370,snd_intel8x0,snd_ac97_codec&lt;br /&gt;&lt;br /&gt;There was no doubt in my mind - I needed to stop the kernel from loading the module &lt;span style="font-weight: bold;"&gt;snd_ens1370&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I had considered just deleting it all together:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;$ locate 1370&lt;br /&gt;/lib/modules/2.6.22-14-generic/kernel/sound/pci/snd-ens1370.ko&lt;br /&gt;/usr/src/linux-headers-2.6.22-14-generic/include/config/snd/ens1370.h&lt;br /&gt;/usr/share/alsa/cards/ENS1370.conf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But it turns out there is a more elegant way.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;To disable hardware in ubuntu - blacklist the module&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Take a look at, &lt;span style="font-weight: bold;"&gt;/etc/modprobe.d/blacklist&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;To disable my Ensoniq sound card in ubuntu - I added the following lines:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;# disable my PCI ensoniq sound card&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;blacklist snd_ens1370&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;then just reboot...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm3.static.flickr.com/2252/2221934021_3f778e7916_o.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm3.static.flickr.com/2252/2221934021_3f778e7916_o.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-9051872434874516188?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/9051872434874516188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=9051872434874516188' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/9051872434874516188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/9051872434874516188'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/01/ubuntu-disable-hardware.html' title='ubuntu disable hardware'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-425377000536983209</id><published>2008-01-16T00:02:00.000-08:00</published><updated>2008-01-30T12:11:25.602-08:00</updated><title type='text'>how does bash work</title><content type='html'>When evoked the Borne Again Shell can launch one of two different types of interactive shells, &lt;span style="font-weight: bold;"&gt;login &lt;/span&gt;&lt;span&gt;or &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;non-login&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;These descriptions are based on my experiences with a variety of Debian &amp;amp; Fedora based environments - each has their own peculiarities in their implementation of bash.  I'll do my best to be "generic"&lt;br /&gt;&lt;br /&gt;When you login via tty, ssh, or su --login - your $SHELL is launched for you.  This is called a "&lt;span style="font-weight: bold;"&gt;login&lt;/span&gt;" shell, and it will automatically source the following files:&lt;br /&gt;&lt;blockquote&gt;1) /etc/profile&lt;/blockquote&gt;then&lt;br /&gt;&lt;blockquote&gt;2) ~/.profile or ~/.bash_profile&lt;br /&gt;&lt;span style="font-style: italic;"&gt;(but generally not both, one will take "precedence")&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;When you launch /bin/bash &lt;span style="font-weight: bold;"&gt;by some other means&lt;/span&gt; (xterm, konsole, su, or even typing /bin/bash) it is considered &lt;span style="font-weight: bold;"&gt;non-login&lt;/span&gt; and it WILL source &lt;span style="font-weight: bold;"&gt;.bashrc&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;It is VERY common for ~/.profile (&lt;/span&gt;or ~/.bash_profile&lt;span style="font-weight: bold;"&gt;) to source ~/.bashrc&lt;/span&gt; by either:&lt;br /&gt;&lt;blockquote&gt;. ~/.bashrc&lt;/blockquote&gt;or&lt;br /&gt;&lt;blockquote&gt;source ~/.bashrc&lt;/blockquote&gt;You can use source either way - in both &lt;span style="font-weight: bold;"&gt;interactive&lt;/span&gt; and non-interactive shells.&lt;br /&gt;&lt;br /&gt;/etc/profile may source lots of other files.  Sometimes /etc/bashrc (or /etc/bash.bashrc) and sometimes even ~/.bashrc - so watch out!&lt;br /&gt;&lt;br /&gt;Your system may not have all these files - or they may have different names.  Try:&lt;br /&gt;&lt;blockquote&gt;ls -al /etc/ | grep bashrc&lt;br /&gt;ls -al /etc/ | grep profile&lt;br /&gt;ls -al ~ | grep bashrc&lt;br /&gt;ls -al ~ | grep profile&lt;/blockquote&gt;to get some different ideas.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;the command "su -" is short hand for "su --login root" or "switch user to root and launch a login shell"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;it is NOT "switch to super user and load environment variables" (even if that may be the case on some&lt;/span&gt; systems)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-425377000536983209?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/425377000536983209/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=425377000536983209' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/425377000536983209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/425377000536983209'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/01/how-does-bash-work.html' title='how does bash work'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-5230703160977783601</id><published>2008-01-05T08:07:00.001-08:00</published><updated>2008-06-26T09:18:00.024-07:00</updated><title type='text'>3RLOD Error 0020 X Clamp Replacement</title><content type='html'>And so, it was my turn:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm3.static.flickr.com/2195/2167599317_ba36291ee8_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm3.static.flickr.com/2195/2167599317_ba36291ee8_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;For a used 360, I'm actually pretty happy it lasted as long as it did.  Manufacture date was 2/06 - so there's nothing holding me back now.&lt;br /&gt;&lt;br /&gt;Funny thing, this is actually how my FIRST xbox got &lt;a href="http://www.team-xecuter.com/x3/tutorials/x3pin1015.htm"&gt;modded&lt;/a&gt;.  When it &lt;a href="http://www.llamma.com/xbox/Repairs/ComaConsole.htm"&gt;broke&lt;/a&gt;, it was out of warranty, so I had nothing keeping me from opening it up.  &lt;a href="http://xboxmediacenter.com/"&gt;XBMC &lt;/a&gt;is the best thing I ever did for my entertainment center.&lt;br /&gt;&lt;br /&gt;In this case the interwebz says I need an &lt;a href="http://forums.xbox-scene.com/index.php?showtopic=595746&amp;amp;mode=threaded&amp;amp;pid=4189020"&gt;X-Clamp Replacement&lt;/a&gt; - so you know... whatever.&lt;br /&gt;&lt;br /&gt;I went with &lt;a href="http://rbjtech.bulldoghome.com/pages/rbjtech_bulldoghome_com/XClampIII.htm"&gt;RBJ's MKIII method&lt;/a&gt;. Which is extremely well documented, so I didn't really take many pictures.  (Update: Last I checked RBJ had taken down his tutorial, which is too bad - I sent him a message.  &lt;a href="http://llamma.com/xbox360/repair/ring_of_light_x-clamp_fix.htm"&gt;Lamma&lt;/a&gt; has a good one up, which is essentially the same thing.  However, it should be noted I did NOT buy the kit he's selling - although I'm sure it's worth every penny - you can get the parts anywhere.  It's the &lt;span style="font-weight: bold;"&gt;work &lt;/span&gt;of removing the x-clamp, not the tools/equipment you use, that fixes your xbox.)&lt;br /&gt;&lt;br /&gt;I used the following hardware from Lowe's:&lt;br /&gt;2 packs - M5-.8x20mm - Oval Head Phillips - Sales # 138573 - $.92 each pack (Qty:2)&lt;br /&gt;2 packs - M5-.8x16mm - Oval Head Phillips - Sales # 138566 - $.68 each pack (Qty:2)&lt;br /&gt;5 packs - 5mm Flat Washers  - Part # 138319 - $.56 each pack (Qty:10)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm3.static.flickr.com/2030/2167629203_4db513ef61_o.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm3.static.flickr.com/2030/2167629203_4db513ef61_o.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I spent probably more time than I should have cleaning the old thermal paste off the chips &amp;amp; heat sinks.  Goo-Gone and 99% alcohol.  Then I used a razor to spread a very thin even layer of some generic thermal paste on the CPU and GPU.  I just used what I had lying around instead of the "artic silver" stuff everyone talks about.&lt;br /&gt;&lt;br /&gt;Drilling the holes in the case was surprisingly pretty easy - I used a 1/4" bit for a pilot hole, then opened it up to 3/8's.  Using the tape to hold the bolts in place while I got the board in place also went pretty smooth.&lt;br /&gt;&lt;br /&gt;I accidentally screwed the CPU head sink down backward on my first try putting things back together (heat tube AWAY from the GPU) - but once I got everything screwed down... It booted up on the first try - green lights all around.&lt;br /&gt;&lt;br /&gt;Been running great for 3 days - &lt;a href="http://forums.xbox-scene.com/index.php?showtopic=595746&amp;amp;pid=4191200&amp;amp;mode=threaded&amp;amp;show=&amp;amp;st=90&amp;amp;#entry4191200"&gt;posted success&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;BTW, I start the new job @ &lt;a href="http://www.rackspace.com/index.php"&gt;Rackspace &lt;/a&gt;on Monday.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-5230703160977783601?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/5230703160977783601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=5230703160977783601' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5230703160977783601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5230703160977783601'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2008/01/3rlod-error-0020-x-clamp-replacement.html' title='3RLOD Error 0020 X Clamp Replacement'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-7929254245891892233</id><published>2007-12-21T23:20:00.000-08:00</published><updated>2008-06-28T23:29:57.836-07:00</updated><title type='text'>Reset BIOS password on an IBM Thinkpad T23</title><content type='html'>I had really hoped I could reset the supervisor password on a spare IBM T23 laptop we had around the office by - disconnecting the CMOS battery or shorting a jumper. Anything besides the procedure described on &lt;a href="http://sodoityourself.com/hacking-ibm-thinkpad-bios-password/"&gt;sodoityourself.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But apparently there's no way to "reset it" you just have to build yourself a "testpoint" jig and read the encrypted data directly off the EEPROM connected to the main board.&lt;br /&gt;&lt;br /&gt;So I picked up a few parts from RadioShack and went to work.  BTW, The password turned out to be XPBIOS.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm3.static.flickr.com/2108/2127118820_85c758e90e_b.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm3.static.flickr.com/2108/2127118820_85c758e90e_b.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;But, I feel it's important to note, &lt;a href="http://www.allservice.ro/forum/viewtopic.php?t=776"&gt;I'm an idiot&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The image you see above here is NOT of a working cable.  It is in-fact the improperly constructed cable which was later rebuilt and used to successfully dump the contents of the actmel eeprom on the IBM Thinkpad.&lt;br /&gt;&lt;br /&gt;Apparently &lt;a href="http://sodoityourself.com/wp-content/uploads/2006/12/cable_simplified.jpg"&gt;there&lt;/a&gt; &lt;a href="http://sodoityourself.com/wp-content/uploads/2007/02/circuit.jpg"&gt;isn't&lt;/a&gt; &lt;a href="http://home.wanadoo.nl/electro1/avr/uartrx.gif"&gt;much&lt;/a&gt; &lt;a href="http://www.sksapps.com/wii/programmer1.jpg"&gt;standardization&lt;/a&gt; to &lt;a href="http://www.zytrax.com/images/rs232_db9.gif"&gt;diagramming&lt;/a&gt; a &lt;a href="http://spiff.rit.edu/richmond/ritobs/kiwi/kiwi_html_39dc6e35.jpg"&gt;serial&lt;/a&gt; connector.  It's hard to tell if the flat picture you're looking at is supposed to be a male or female connection.  And even worse - true circuit diagrams will often show the BACK of the connector - i.e. they draw it so you would be looking at where the "wires" are ACTUALLY connecting to the BACK of the connector.&lt;br /&gt;&lt;br /&gt;Crazy.&lt;br /&gt;&lt;br /&gt;Your only real hope is to know the pin numbers of an rs232 cable.  Thankfully, almost ALL diagrams will include pin numbers to specify the orientation of the connector and avoid this type of confusion.&lt;br /&gt;&lt;br /&gt;Well... that doesn't help you much if you don't know which pin is which on your cable.  So here is a picture of an rs232 / db9 / 9-pin serial cable - with both male and female connectors labeled pin 1, pin 5, pin 6, and pin 9.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm3.static.flickr.com/2012/2127786355_d81b859855_o.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 225px;" src="http://farm3.static.flickr.com/2012/2127786355_d81b859855_o.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Not even &lt;a href="http://en.wikipedia.org/wiki/RS-232"&gt;wiki &lt;/a&gt;has this kind of information...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-7929254245891892233?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/7929254245891892233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=7929254245891892233' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7929254245891892233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7929254245891892233'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/12/reset-bios-password-on-ibm-thinkpad-t23.html' title='Reset BIOS password on an IBM Thinkpad T23'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2108/2127118820_85c758e90e_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-7158509701401802288</id><published>2007-12-19T20:42:00.000-08:00</published><updated>2008-02-16T01:08:33.993-08:00</updated><title type='text'>Nokia 770 OS2007HE - Can't change Regional settings</title><content type='html'>Flashed my Nokia tablet with the new '07 OS "Hacker Edition" - it's been running strong all night.&lt;br /&gt;&lt;br /&gt;The first issue I came into was a problem changing the Regional settings and Device language from English (United Kingdom) to English (USA).  I would get an error:&lt;br /&gt;&lt;blockquote&gt;Device storage memory full.&lt;br /&gt;Delete some data to free memory.&lt;br /&gt;&lt;/blockquote&gt;Total rubbish, the memory was fine.  Not surprisingly all this little drop down does is change a setting in a config file.  Install xTerm, gainroot, find the file, edit the setting, reboot and now my date displays month/day/year - no problem.&lt;br /&gt;&lt;br /&gt;**UPDATE** Ivie found an even simpler solution documented on &lt;a href="http://lulugirl896.spaces.live.com/blog/cns%216FBB20725D020C7A%211515.entry"&gt;her blog&lt;/a&gt; - you may want to try that first.&lt;br /&gt;&lt;br /&gt;I found an updated version of xTerm that draws the screen quite a bit better, and supports color.  To install xTerm on a Nokia 770 0S2007HE go to &lt;a href="http://maemo-hackers.org/wiki/OssoXterm"&gt;maemo-hackers&lt;/a&gt; and click on the &lt;a href="http://maemo-hackers.org/osso-xterm.install"&gt;.install&lt;/a&gt; link for "bora"&lt;br /&gt;&lt;br /&gt;To gain root access on a Nokia 770 OS2007HE use the same old 2006 "becomeroot" package  - download it &lt;a href="http://www.mediafire.com/?41rrgttyrd0"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Then just open up xTerm, su gainroot and edit the following file:&lt;br /&gt;&lt;blockquote&gt;/etc/osso-af-init/locale&lt;/blockquote&gt;change the last two lines to:&lt;br /&gt;&lt;blockquote&gt;export LANG=en_US&lt;br /&gt;export LC_MESSAGES=en_US&lt;/blockquote&gt;that is... as long as you live here in the states.&lt;br /&gt;&lt;br /&gt;I'll probably have more updates as I run into more snags installing and reconfiguring all my packages.  To-Do list &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/06/goals.html"&gt;updated&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-7158509701401802288?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/7158509701401802288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=7158509701401802288' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7158509701401802288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7158509701401802288'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/12/nokia-770-os2007he-cant-change-regional.html' title='Nokia 770 OS2007HE - Can&apos;t change Regional settings'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-7897833626507589360</id><published>2007-12-13T07:00:00.001-08:00</published><updated>2007-12-13T07:28:41.086-08:00</updated><title type='text'>Configure Nokia 770 Internet Search Applet</title><content type='html'>&lt;div style="float: right; margin-left: 10px; margin-bottom: 10px;"&gt; &lt;a href="http://www.flickr.com/photos/9743135@N03/2108906084/" title="photo sharing"&gt;&lt;img src="http://farm3.static.flickr.com/2160/2108906084_3e210651aa_m.jpg" alt="" style="border: 2px solid rgb(0, 0, 0);" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="margin-top: 0px;font-size:0;" &gt;  &lt;a href="http://www.flickr.com/photos/9743135@N03/2108906084/"&gt;Configure Nokia 770 Internet Search Applet&lt;/a&gt;&lt;br /&gt;Originally uploaded by &lt;a href="http://www.flickr.com/people/9743135@N03/"&gt;clay.gerrard@sbcglobal.net&lt;/a&gt; &lt;/span&gt;&lt;/div&gt;Add additional search engines to your Nokia 770 Internet Search Applet by creating carefully crafted .xml documents in /usr/share/mis.  You can even make custom icons!&lt;br /&gt;&lt;br /&gt;To add IMDB, Amazon, eBay, NewEgg &amp;amp; Google Maps (for Nokia 770) download &lt;a href="http://www.mediafire.com/download.php?5cgy1ulngf9"&gt;internetsearch.zip&lt;/a&gt; from my media fire account, and add the extracted files to /usr/share/mis&lt;br /&gt;&lt;br /&gt;Extract the files into a folder on your Nokia 770's memory card (something like internetsearch).  Then you'll need to fire up xTerm and &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/gain-root-access-to-nokia-770.html"&gt;becomeroot&lt;/a&gt;.  Copy the files to /usr/share/mis  using a command similar to  this:&lt;br /&gt;&lt;blockquote&gt;cp /media/mmc1/internetsearch/* /usr/share/mis/&lt;/blockquote&gt;Reboot for changes to take effect.&lt;br /&gt;&lt;br /&gt;I've added my favorite search engines.  I particularly like the &lt;a href="http://www.internettablettalk.com/2006/01/19/google-maps-for-nokia-770/"&gt;Google Maps for Nokia 770&lt;/a&gt; - the trick to using this effectively is to "zoom in" to 150% using the buttons on top.  Then instead of "dragging" around the map - you click where you want to re-center.&lt;br /&gt;&lt;br /&gt;This is an update and repackage of work started by &lt;a href="http://www.internettablettalk.com/forums/member.php?u=9632"&gt;Moonshine&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;For more details about the format of these .xml files reference &lt;a href="http://www.internettablettalk.com/forums/showthread.php?s=2cbfd694c8705cb43d369f1177325540&amp;amp;t=3058"&gt;this post&lt;/a&gt; on internet tablet talk.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-7897833626507589360?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/7897833626507589360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=7897833626507589360' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7897833626507589360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7897833626507589360'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/12/configure-nokia-770-internet-search.html' title='Configure Nokia 770 Internet Search Applet'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2160/2108906084_3e210651aa_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-4302120256266101824</id><published>2007-11-30T13:04:00.000-08:00</published><updated>2007-12-12T18:16:12.813-08:00</updated><title type='text'>c0072746 - Can not expand Public Folders in Exchange 2003</title><content type='html'>FINALLY!!!  This has been bugging me for AGES!!!&lt;br /&gt;&lt;br /&gt;There is &lt;a href="http://technet.microsoft.com/en-us/library/aa996098.aspx"&gt;TONS &lt;/a&gt;of errors that may crop up when you try to expand public folders in the Exchange System Manager (ESM).  But I couldn't find much about MY error: c0072746&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Exchange System Manager&lt;br /&gt;An existing connection was forcibly closed by the remote host.&lt;br /&gt;&lt;br /&gt;Facility: Win32&lt;br /&gt;ID no: c0072746&lt;br /&gt;Exchange System Manager&lt;br /&gt;[OK]&lt;/blockquote&gt;I'm not really worried about the "error" - the public folders work FINE inside Outlook and OWA.  My real concern was that I couldn't administrate the public folders through ESM - setting permissions and the like.&lt;br /&gt;&lt;br /&gt;FINALLY I found a tool that will let me administrate them with out using ESM - &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=635BE792-D8AD-49E3-ADA4-E2422C0AB424&amp;amp;displaylang=en"&gt;PFDAVAdmin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Download it &lt;a href="http://www.microsoft.com/downloads/info.aspx?na=90&amp;amp;p=&amp;amp;SrcDisplayLang=en&amp;amp;SrcCategoryId=&amp;amp;SrcFamilyId=635be792-d8ad-49e3-ada4-e2422c0ab424&amp;amp;u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f2%2ff%2f0%2f2f0d72e2-a97a-49b6-879a-3b405cab017e%2fPFDAVAdmin.EXE"&gt;here&lt;/a&gt;&lt;br /&gt;Run the .exe to extract the contents to a folder called PFDAVAdmin&lt;br /&gt;Double click PFDAVAdmin.exe to start the GUI&lt;br /&gt;&lt;br /&gt;From here you can change permissions on all your public folders, and correct problems such as no owner being defined.  Once I fixed all the permissions errors, ESM was again able to administer the public folders - PRAISE JESUS!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-4302120256266101824?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/4302120256266101824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=4302120256266101824' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4302120256266101824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4302120256266101824'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/11/c0072746-can-not-expand-public-folders.html' title='c0072746 - Can not expand Public Folders in Exchange 2003'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-1685123065831584548</id><published>2007-11-26T17:38:00.000-08:00</published><updated>2007-11-26T17:56:18.565-08:00</updated><title type='text'>My Wordpress Site</title><content type='html'>&lt;a href="http://www.cciwholesale.com"&gt;www.cciwholesale.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Yup, so that's word press.  I made more than a few minor re-writes to some of the default theme and widget pages.  Enough changes that I feel justified in putting PHP experience on my resume. &lt;br /&gt;&lt;br /&gt;The inital installation was super easy, that famous "&lt;a href="http://codex.wordpress.org/Installing_WordPress"&gt;five minute install&lt;/a&gt;" was really amazing to experience.  &lt;a href="http://www.crystaltech.com/"&gt;CrystalTech&lt;/a&gt; even had a &lt;a href="https://www.webcontrolcenter.com/Knowledge_Base/frmKB.aspx?KBID=1001"&gt;tutorial&lt;/a&gt;.  They could have put this part closer to the top though:&lt;br /&gt;&lt;span id="lblArticle_Article"&gt;&lt;blockquote&gt;You may need to add the “index.php” file as a default start page for your site configuration. This can be achieved within the WebControlCenter within the IIS -&gt; Default Pages menu.&lt;/blockquote&gt;&lt;/span&gt;The only thing I feel I'm missing on a WIMP vs LAMP configuration is the URL re-write feature.&lt;br /&gt;&lt;br /&gt;http://www.cciwholesale.com/cci/about&lt;br /&gt;&lt;br /&gt;would have been a lot better than:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cciwholesale.com/cci/?page_id=2"&gt;http://www.cciwholesale.com/cci/?page_id=2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But apparently there's no good way for a web hosting company that runs an IIS server to give their users a good way to implement this feature.  If I'm wrong on that - I'd love to be &lt;a href="mailto:clayg@cciwholesale.com"&gt;corrected&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I got a new job working for &lt;a href="http://www.rackspace.com/index.php"&gt;RackSpace&lt;/a&gt; - they're a managed services hosting company, and the largest tech employer in San Antonio.  I am actually pretty excited - I won't start until after the holidays.  I'm going to be working with the managed services group, mainly setting up back-up policies on all their client's various hosted systems, filling restore requests, and generally troubleshooting any problems that come up.  It's all good.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-1685123065831584548?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/1685123065831584548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=1685123065831584548' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1685123065831584548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1685123065831584548'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/11/my-wordpress-site.html' title='My Wordpress Site'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-5068112335805082273</id><published>2007-10-04T20:12:00.000-07:00</published><updated>2007-11-30T23:56:30.514-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Wordpress'/><category scheme='http://www.blogger.com/atom/ns#' term='Verizon Nokia 770'/><category scheme='http://www.blogger.com/atom/ns#' term='gain root'/><category scheme='http://www.blogger.com/atom/ns#' term='WIMP'/><title type='text'>So now you're an expert with wordpress</title><content type='html'>A new project - just what the blog needs to get back on track.  It's been a while.  I welcome back my fictional readers.&lt;br /&gt;&lt;br /&gt;If you need to build a brochure site for your business (and let's be honest, if you don't already have one - you and me BOTH have put it off too long) - Wordpress may be for you.&lt;br /&gt;&lt;br /&gt;I assume two things.&lt;br /&gt;1) You have basically zero experience with PHP and mySQL&lt;br /&gt;2) You're tired of waiting on an extra hundred hours of spare free time to come along&lt;br /&gt;&lt;br /&gt;Technically I also assume you have a hosting company that you pay to store things on the web for you - which you currently only access via FTP.  If they are fairly decent - you probably also have tons of other functionality provided on your account at no extra charge that you aren't taking advantage of.  Because... we'll I do.&lt;br /&gt;&lt;br /&gt;My businesses use &lt;a href="http://www.crystaltech.com/"&gt;CrystalTech&lt;/a&gt; (where's the free month?) which is a very powerful &lt;a href="http://www.builderau.com.au/program/php/soa/Install-configure-and-integrate-PHP-and-MySQL-on-Windows/0,339028448,339271632,00.htm"&gt;WIMP&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Hopefully in the next few weeks I'll have something useful to say about the whole procedure of getting a WordPress site up and running, that I can post.  Hopefully, someone will get some benefit from it.  According to my &lt;a href="http://my6.statcounter.com/project/standard/keyword.php?project_id=2761352"&gt;stats&lt;/a&gt; - &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/gain-root-access-to-nokia-770.html"&gt;gain root&lt;/a&gt; and &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/wireless-internet-anywhere-nokia-770.html"&gt;Verizon Nokia 770&lt;/a&gt; have been a real "hit."&lt;br /&gt;&lt;br /&gt;If you guys are worried about my Nokia, it's ok, she's doing fine.  They're even starting to go back up on &lt;a href="http://cgi.ebay.com/Nokia-770-Internet-Tablet-Laptop-WiFi-Bluetooth-Web_W0QQitemZ150167663104QQihZ005QQcategoryZ38331QQtcZphotoQQcmdZViewItem"&gt;eBay&lt;/a&gt;.  To-do list &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/06/goals.html"&gt;updated&lt;/a&gt;.  For a few weeks I was sporting a laptop (which I ended up having to deploy) so the Nokia wasn't getting much attention.  I need to do that &lt;a href="http://linuxjunk.blogspot.com/2007/08/nokia-n770-internally-mounted-sd-card.html"&gt;Nokia 770 Memory upgrade&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Hacking the Verizon "red" UI on the KRZR turned out to be a chore.  I just wanted to make it green... The ringer even stopped working after a weekend at &lt;a href="http://www.aclfestival.com/lineup.aspx"&gt;ACL&lt;/a&gt;.  It's cool - it just needed to be cleaned &amp;amp; re-seated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-5068112335805082273?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/5068112335805082273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=5068112335805082273' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5068112335805082273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5068112335805082273'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/10/so-now-youre-expert-with-wordpress.html' title='So now you&apos;re an expert with wordpress'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-5434864805428588575</id><published>2007-07-30T18:37:00.001-07:00</published><updated>2008-12-11T14:16:18.192-08:00</updated><title type='text'>Unlimited Wireless Internet Anywhere - Nokia 770 &amp; Verizon EVDO DUN - $15/mo</title><content type='html'>Big NEWS.&lt;br /&gt;This weekend - I got a new phone.&lt;br /&gt;A white Verizon K1m:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_enpkgyjJSRw/Rq6TaU-qbYI/AAAAAAAAAAU/p1SZyKGHSHI/s1600-h/k1m.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_enpkgyjJSRw/Rq6TaU-qbYI/AAAAAAAAAAU/p1SZyKGHSHI/s320/k1m.jpg" alt="" id="BLOGGER_PHOTO_ID_5093170309120028034" border="0" /&gt;&lt;/a&gt;First I had to add unlimited Mobile Web to my account for $15 extra a month, and then I had to enable DUN (&lt;a href="http://www.howardforums.com/showthread.php?t=938352"&gt;tutorial&lt;/a&gt;) - but it was totally worth it:&lt;br /&gt;&lt;br /&gt;(Update: 938352 was THE thread for this hack, do a search for the thread number in hofo EVERYONE referenced it, but for some reason it's gone now.  Try &lt;a href="http://www.howardforums.com/showthread.php?t=1018585&amp;amp;highlight=verizon+dun"&gt;this one&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_enpkgyjJSRw/Rq6UJE-qbZI/AAAAAAAAAAc/2mQ69-KRGeE/s1600-h/shot-2007-07-29-12-24-14.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_enpkgyjJSRw/Rq6UJE-qbZI/AAAAAAAAAAc/2mQ69-KRGeE/s320/shot-2007-07-29-12-24-14.png" alt="" id="BLOGGER_PHOTO_ID_5093171112278912402" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Granted that &lt;a href="http://www.dslreports.com/mspeed"&gt;test &lt;/a&gt;was performed standing still in the middle of an empty parking lot.  But I'm getting 200 kbps pretty consistant, with bursts in the 300's and dips to the mid-100's.  More than enough to listen to web radio or check my email - if not at the same time.&lt;br /&gt;&lt;br /&gt;Wireless Internet Anywhere - it's like I'm in the future... or Japan.&lt;br /&gt;&lt;br /&gt;Lot's of updating on the &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/06/goals.html"&gt;to-do list&lt;/a&gt; - plus I want to make a few posts about some of my mods to the KRZR and my experiences with the Verizon red UI.  More to come soon!&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_enpkgyjJSRw/Rq6SuU-qbXI/AAAAAAAAAAM/8Q4uOBh_nJs/s1600-h/k1m.jpg"&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-5434864805428588575?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/5434864805428588575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=5434864805428588575' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5434864805428588575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5434864805428588575'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/07/wireless-internet-anywhere-nokia-770.html' title='Unlimited Wireless Internet Anywhere - Nokia 770 &amp; Verizon EVDO DUN - $15/mo'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_enpkgyjJSRw/Rq6TaU-qbYI/AAAAAAAAAAU/p1SZyKGHSHI/s72-c/k1m.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-4318149190572371141</id><published>2007-07-16T21:38:00.001-07:00</published><updated>2007-07-16T21:40:13.134-07:00</updated><title type='text'>Is there a microphone on the Nokia 770?</title><content type='html'>I always kinda wondered since I picked one up.  And having installed an audio recorder, I can now say with out a doubt - that the Nokia 770 does indeed have a built in mic.&lt;br /&gt;&lt;br /&gt;You can record your own voice notes by installing &lt;a href="https://garage.maemo.org/projects/maemo-recorder/"&gt;maemo-reocrder&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To-do list - &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/06/goals.html"&gt;updated&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-4318149190572371141?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/4318149190572371141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=4318149190572371141' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4318149190572371141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4318149190572371141'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/07/is-there-microphone-on-nokia-770.html' title='Is there a microphone on the Nokia 770?'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-4627200059658584800</id><published>2007-07-15T15:19:00.001-07:00</published><updated>2007-12-26T10:48:39.411-08:00</updated><title type='text'>mame emulator on nokia 770</title><content type='html'>&lt;div style="float: right; margin-left: 10px; margin-bottom: 10px;"&gt; &lt;a href="http://www.flickr.com/photos/9743135@N03/822642936/" title="photo sharing"&gt;&lt;img src="http://farm2.static.flickr.com/1196/822642936_d512db7c59_m.jpg" alt="" style="border: 2px solid rgb(0, 0, 0);" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="margin-top: 0px;font-size:0;" &gt;  &lt;a href="http://www.flickr.com/photos/9743135@N03/822642936/"&gt;mame emulator on nokia 770&lt;/a&gt; &lt;br /&gt; Originally uploaded by &lt;a href="http://www.flickr.com/people/9743135@N03/"&gt;clay.gerrard@sbcglobal.net&lt;/a&gt; &lt;/span&gt;&lt;/div&gt;xmaeme is really impressive - but not that playable.  There seems to be a hardware limitation that prevents the emulator engine from recognizing more than one button press at a time.  And with all the hardware keys to the left of the display, people are generally forced to rotate the device 90deg, so the buttons are on the bottom.  This way you can put both hands on the keys and still see.  The image on the display can be rotated clockwise to compensate and make the game appear right side up - however I found some roms would not load with this option enabled.&lt;br /&gt;&lt;br /&gt;From the xMaeme loader gui - when I checked "rotate clockwise" - many games would fail to load with the error message -  "unable to load ROM"&lt;br /&gt;&lt;br /&gt;Perhaps a role playing type game on the Nintendo emulator will be more fun.&lt;br /&gt;&lt;br /&gt;Nevertheless, here's the project homepage: &lt;a href="https://garage.maemo.org/projects/xmame/"&gt;https://garage.maemo.org/projects/xmame/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-4627200059658584800?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/4627200059658584800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=4627200059658584800' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4627200059658584800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4627200059658584800'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/07/mame-emulator-on-nokia-770.html' title='mame emulator on nokia 770'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1196/822642936_d512db7c59_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-7928789842049979158</id><published>2007-07-09T19:14:00.000-07:00</published><updated>2007-07-15T15:20:21.519-07:00</updated><title type='text'>Adding users and Shadow Password</title><content type='html'>So the Nokia 770 does have the "adduser" script.  I tried:&lt;br /&gt;&lt;blockquote&gt;    adduser clayg&lt;/blockquote&gt;&lt;br /&gt;Everything looked like a normal debian adduser script, full name, room number etc.  But it didn't work quite right.&lt;br /&gt;&lt;br /&gt;When I tried to log-in with my new user from putty it booted me right back out.  So I tried switching users from the console.&lt;br /&gt;&lt;blockquote&gt;    su clayg&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;It told me stright away /bin/bash doesn't exist.  Hince the whole "busybox" thing every time I log-in.  I'm not running the bourne-again shell!&lt;br /&gt;&lt;br /&gt;I headed to /etc/passwd to investigate and guess what - the password file on the Nokia 770 is NOT SHADOWED.&lt;br /&gt;&lt;br /&gt;To create the /etc/shadow file and remove the encrypted passwords from the world readable file /etc/passwd issue the command:&lt;br /&gt;&lt;blockquote&gt;    pwconv&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This command will create the file /etc/shadow (which is only readable by root) and use that to store all the user's encrypted passwords.&lt;br /&gt;&lt;br /&gt;Now, if you look at the last line in /etc/passwd you should see something like this:&lt;br /&gt;&lt;blockquote&gt;    clayg:x:1000:1000:Clay Gerrard,,,:/home/clayg:/bin/bash&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;It's the last bit that's causing problems.  The last field is the shell to invoke when the user logs in, and if you check under /bin - bash really isn't there...&lt;br /&gt;&lt;br /&gt;I referenced the entries for root and user as an example, and changed the last field from /bin/bash to /bin/sh&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm2.static.flickr.com/1060/765084527_177982c25a.jpg?v=0"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm2.static.flickr.com/1060/765084527_177982c25a.jpg?v=0" alt="" border="0" /&gt;&lt;/a&gt;I guess I could have just installed bash...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-7928789842049979158?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/7928789842049979158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=7928789842049979158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7928789842049979158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/7928789842049979158'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/07/adding-users-and-shadown-password.html' title='Adding users and Shadow Password'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-4053212779493761130</id><published>2007-07-09T15:38:00.001-07:00</published><updated>2007-07-09T16:53:00.543-07:00</updated><title type='text'>Weather Applet &amp; Video Converter</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm2.static.flickr.com/1061/764595336_c5fcc9764c.jpg?v=0"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm2.static.flickr.com/1061/764595336_c5fcc9764c.jpg?v=0" alt="" border="0" /&gt;&lt;/a&gt;&lt;a href="https://garage.maemo.org/projects/omweather/"&gt;https://garage.maemo.org/projects/omweather/&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;If you planning on watching video's on your Nokia 770 you're going to want this little java application to convert your standard mpg's and avi's to Nokia 770 compatible resolution and framerate:&lt;br /&gt;&lt;a href="https://garage.maemo.org/frs/?group_id=26"&gt;https://garage.maemo.org/frs/?group_id=26&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-4053212779493761130?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/4053212779493761130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=4053212779493761130' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4053212779493761130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4053212779493761130'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/07/weather-applet.html' title='Weather Applet &amp; Video Converter'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-5097945661523273766</id><published>2007-07-07T15:16:00.000-07:00</published><updated>2007-07-09T15:25:51.307-07:00</updated><title type='text'>SSH on Nokia 770 Internet Tablet</title><content type='html'>So my apartment complex has free wifi out by the pool.  Pretty nice.  Got the password from the lady at the front desk and logged right in.&lt;br /&gt;&lt;br /&gt;Now that I can &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/gain-root-access-to-nokia-770.html"&gt;becomeroot&lt;/a&gt;, I'm able to start doing some REAL work on this thing.  Like install a SSH Client &amp; Server.  I've never heard of the project before, but I ended up installing the &lt;a href="http://matt.ucc.asn.au/dropbear/dropbear.html"&gt;dropbear&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;First you should add the maemo-hackers repository to your application manager:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Open the Application Manager&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Click on the Application Manager Titlebar&lt;/li&gt;&lt;li&gt;Select Tools-&gt;Application Catalogue&lt;/li&gt;&lt;li&gt;Click NEW to add the maemo-hackers.org repository&lt;/li&gt;&lt;/ol&gt;The catalogue entry for the maemo-hackers.org repository should have the following settings:&lt;br /&gt;&lt;br /&gt;Web Address: http://maemo-hackers.org/apt&lt;br /&gt;Distribution: mistral&lt;br /&gt;Components: main&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm2.static.flickr.com/1352/749493293_9d54e38234.jpg?v=0"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm2.static.flickr.com/1352/749493293_9d54e38234.jpg?v=0" alt="" border="0" /&gt;&lt;/a&gt;Leave "Enabled" checked.  After you hit ok a few times it should prompt to refresh list of packages.  Do this and when you look at "all packages" you'll see quite a few more than you had before.  Go ahead and choose to install dropbear-client.&lt;br /&gt;&lt;br /&gt;Well isn't that fun - now you can use ssh to log-in to your favorite linux box... but the real trick is getting that ssh server running isn't it?  Well, that's a little harder because you have to have root privileges to install the dropbear-server - but we &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/gain-root-access-to-nokia-770.html"&gt;HAVE &lt;/a&gt;root privilege&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;INSTALL SSH SERVER ON NOKIA 770 INTERNET TABLET OS 2006&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Close out of the application manager. Start up xterm. Gain root access.&lt;br /&gt;&lt;br /&gt;enter the following command in xterm to install the dropbear-server&lt;br /&gt;&lt;blockquote&gt;   apt-get install dropbear-server&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;NOTE: you must have the maemo-hackers.org repository already added into your application catalog&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now run ifconfig to check your ip, open putty or some other ssh client on another machine somewhere - and dig the log-in:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm2.static.flickr.com/1308/749668575_86d747814d.jpg?v=0"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm2.static.flickr.com/1308/749668575_86d747814d.jpg?v=0" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;I also found this cool &lt;a href="https://garage.maemo.org/projects/thememaker"&gt;themeing app&lt;/a&gt;, it's java so you can run it just about anywhere.  You can reskin your Nokia by editing just one jpg and using the java app to compile the .deb - then if you don't like it, you just uninstall it!&lt;br /&gt;&lt;br /&gt;to-do list: &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/06/goals.html"&gt;updated&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;BTW, the default root password is rootme, and that ssh server is always on.  You may want to change that root password like - right away...&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-5097945661523273766?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/5097945661523273766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=5097945661523273766' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5097945661523273766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/5097945661523273766'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/07/ssh-on-nokia-770-internet-tablet.html' title='SSH on Nokia 770 Internet Tablet'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-4402701674275633869</id><published>2007-07-06T23:39:00.000-07:00</published><updated>2007-07-06T23:52:56.402-07:00</updated><title type='text'>Gain Root Access to Nokia 770</title><content type='html'>First you'll want to download the "becomeroot" package.  I found a copy on the &lt;a href="http://tinyurl.com/2vpb56"&gt;Polish Eko1 repository&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;After you nab a copy of &lt;a href="http://eko.one.pl/maemo/dists/mistral/user/binary-armel/becomeroot_0.1-2_armel.deb" title="becomeroot_0.1-2_armel.deb"&gt;becomeroot_0.1-2_armel.deb&lt;/a&gt;, you can install it by using the "install from file" option in the application manager.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm2.static.flickr.com/1111/745944094_78080be1e1.jpg?v=0"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm2.static.flickr.com/1111/745944094_78080be1e1.jpg?v=0" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;Then you can open up xTerm.  You did install &lt;a href="http://770.fs-security.com/xterm/files/osso-xterm_0.11_arm.deb"&gt;xTerm &lt;/a&gt;right?&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm2.static.flickr.com/1112/745092923_10a412d614.jpg?v=0"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://farm2.static.flickr.com/1112/745092923_10a412d614.jpg?v=0" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The command "sudo gainroot" will open a root shell.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-4402701674275633869?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/4402701674275633869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=4402701674275633869' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4402701674275633869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4402701674275633869'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/07/gain-root-access-to-nokia-770.html' title='Gain Root Access to Nokia 770'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-4035372076885159160</id><published>2007-07-06T08:15:00.001-07:00</published><updated>2007-07-06T08:15:09.059-07:00</updated><title type='text'>shot-2007-05-08-10-12-10</title><content type='html'>&lt;div style="float: right; margin-left: 10px; margin-bottom: 10px;"&gt; &lt;a href="http://www.flickr.com/photos/9743135@N03/738480663/" title="photo sharing"&gt;&lt;img src="http://farm2.static.flickr.com/1080/738480663_c6913fd874_m.jpg" alt="" style="border: solid 2px #000000;" /&gt;&lt;/a&gt; &lt;br /&gt; &lt;span style="font-size: 0.9em; margin-top: 0px;"&gt;  &lt;a href="http://www.flickr.com/photos/9743135@N03/738480663/"&gt;shot-2007-05-08-10-12-10&lt;/a&gt;  &lt;br /&gt;  Originally uploaded by &lt;a href="http://www.flickr.com/people/9743135@N03/"&gt;clay.gerrard@sbcglobal.net&lt;/a&gt; &lt;/span&gt;&lt;/div&gt;got xTerm up and running, it's definitely a debian based linux.  The media card is mounted at /media/mmc1&lt;br clear="all" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-4035372076885159160?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/4035372076885159160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=4035372076885159160' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4035372076885159160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4035372076885159160'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/07/shot-2007-05-08-10-12-10.html' title='shot-2007-05-08-10-12-10'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1080/738480663_c6913fd874_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-3370623323538207128</id><published>2007-07-06T08:04:00.000-07:00</published><updated>2007-07-06T14:44:10.026-07:00</updated><title type='text'>Nokia 770 CPU info &amp; Disk Info</title><content type='html'>cat /proc/cpuinfo&lt;br /&gt;&lt;br /&gt;Processor    : ARM926EJ-Sid(wb) rev 3 (v5l)&lt;br /&gt;BogoMIPS    : 125.76&lt;br /&gt;Features    : swp half thumb fastmult edsp java&lt;br /&gt;CPU implementer    : 0x41&lt;br /&gt;CPU architecture: 5TEJ&lt;br /&gt;CPU variant    : 0x0&lt;br /&gt;CPU part    : 0x926&lt;br /&gt;CPU revision    : 3&lt;br /&gt;Cache type    : write-back&lt;br /&gt;Cache clean    : cp15 c7 ops&lt;br /&gt;Cache lockdown    : format C&lt;br /&gt;Cache format    : Harvard&lt;br /&gt;I size        : 32768&lt;br /&gt;I assoc        : 4&lt;br /&gt;I line length    : 32&lt;br /&gt;I sets        : 256&lt;br /&gt;D size        : 16384&lt;br /&gt;D assoc        : 4&lt;br /&gt;D line length    : 32&lt;br /&gt;D sets        : 128&lt;br /&gt;&lt;br /&gt;Hardware    : Nokia 770&lt;br /&gt;Revision    : 17100016&lt;br /&gt;Serial        : 033302008b5f702f&lt;br /&gt;&lt;br /&gt;df -h&lt;br /&gt;&lt;br /&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10.5pt; line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;;"&gt;    Filesystem&lt;span style=""&gt;                &lt;/span&gt;Size&lt;span style=""&gt;      &lt;/span&gt;Used Available Use% Mounted on&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;span style="font-size: 10.5pt; line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;;"&gt;/dev/mtdblock4&lt;span style=""&gt;            &lt;/span&gt;2.0M&lt;span style=""&gt;      &lt;/span&gt;2.0M&lt;span style=""&gt;         &lt;/span&gt;0 100% /mnt/initfs&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: 10.5pt; line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;;"&gt;none&lt;span style=""&gt;                    &lt;/span&gt;512.0k&lt;span style=""&gt;     &lt;/span&gt;64.0k&lt;span style=""&gt;    &lt;/span&gt;448.0k&lt;span style=""&gt;  &lt;/span&gt;13% /mnt/initfs/tmp&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: 10.5pt; line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;;"&gt;/dev/mtdblock4&lt;span style=""&gt;          &lt;/span&gt;123.5M&lt;span style=""&gt;     &lt;/span&gt;62.3M&lt;span style=""&gt;     &lt;/span&gt;61.2M&lt;span style=""&gt;  &lt;/span&gt;50% /&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: 10.5pt; line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;;"&gt;none&lt;span style=""&gt;                    &lt;/span&gt;512.0k&lt;span style=""&gt;     &lt;/span&gt;64.0k&lt;span style=""&gt;    &lt;/span&gt;448.0k&lt;span style=""&gt;  &lt;/span&gt;13% /tmp&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: 10.5pt; line-height: 115%; font-family: &amp;quot;Courier New&amp;quot;;"&gt;none&lt;span style=""&gt;  &lt;/span&gt;&lt;span style=""&gt;                    &lt;/span&gt;1.0M&lt;span style=""&gt;     &lt;/span&gt;44.0k&lt;span style=""&gt;    &lt;/span&gt;980.0k&lt;span style=""&gt;   &lt;/span&gt;4% /dev&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;         &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;todo list - &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/06/goals.html"&gt;updated&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-3370623323538207128?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/3370623323538207128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=3370623323538207128' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/3370623323538207128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/3370623323538207128'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/07/nokia-770-cpu-info-disk-info.html' title='Nokia 770 CPU info &amp; Disk Info'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-8616497762848960532</id><published>2007-07-05T23:44:00.001-07:00</published><updated>2007-07-05T23:44:32.320-07:00</updated><title type='text'>shot-2007-05-08-00-29-31</title><content type='html'>&lt;div style="float: right; margin-left: 10px; margin-bottom: 10px;"&gt; &lt;a href="http://www.flickr.com/photos/9743135@N03/735278554/" title="photo sharing"&gt;&lt;img src="http://farm2.static.flickr.com/1109/735278554_05a5fd56aa_m.jpg" alt="" style="border: solid 2px #000000;" /&gt;&lt;/a&gt; &lt;br /&gt; &lt;span style="font-size: 0.9em; margin-top: 0px;"&gt;  &lt;a href="http://www.flickr.com/photos/9743135@N03/735278554/"&gt;shot-2007-05-08-00-29-31&lt;/a&gt;  &lt;br /&gt;  Originally uploaded by &lt;a href="http://www.flickr.com/people/9743135@N03/"&gt;clay.gerrard@sbcglobal.net&lt;/a&gt; &lt;/span&gt;&lt;/div&gt;I uploaded this to flickr from Bilbo, that's what i'm calling it... Bilbo.&lt;br clear="all" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-8616497762848960532?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/8616497762848960532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=8616497762848960532' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/8616497762848960532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/8616497762848960532'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/07/shot-2007-05-08-00-29-31.html' title='shot-2007-05-08-00-29-31'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1109/735278554_05a5fd56aa_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-4436023551102508516</id><published>2007-07-05T23:36:00.000-07:00</published><updated>2007-07-06T00:01:48.509-07:00</updated><title type='text'>Nokia 770 Internet Tablet back in hand!</title><content type='html'>Finally, after a week of waiting - I just got stock in today.&lt;br /&gt;&lt;br /&gt;Naturally, I've updated the to-do list: &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/06/goals.html"&gt;http://thoughtsbyclayg.blogspot.com/2007/06/goals.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Worth noting the screen shot app &lt;a href="http://inz.fi/blog/2007/06/21/screenshooting-made-easy-ish/"&gt;mh-shot-tool&lt;/a&gt; and this slightly cool &lt;a href="http://flickr.com/photos/9743135@N03/735278554/in/photostream/"&gt;screenshot&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-4436023551102508516?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/4436023551102508516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=4436023551102508516' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4436023551102508516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/4436023551102508516'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/07/nokia-770-internet-tablet-back-in-hand.html' title='Nokia 770 Internet Tablet back in hand!'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-3191199373964489316</id><published>2007-06-30T16:40:00.000-07:00</published><updated>2007-06-30T18:46:30.504-07:00</updated><title type='text'>Unclose last tab in Firefox , edubuntu and "stuff"</title><content type='html'>the keyboard shortcut &lt;span style="font-weight: bold;"&gt;ctrl-shift-t&lt;/span&gt; will "undo" the last tab close in FireFox 2.0 - oops!&lt;br /&gt;&lt;br /&gt;You wouldn't know this about me.  But I am a keyboard shortcut junky.&lt;br /&gt;&lt;br /&gt;thanks home dood...&lt;br /&gt;&lt;a href="http://grahams.livejournal.com/635284.html"&gt;http://grahams.livejournal.com/635284.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So, I'm rebuilding my sisters horribly virus infected PC this weekend.  It's already a decent machine, 2Ghz Intel, 512MB RAM, 60GB IDE HD, DVD-RW.  I'm going to back up all her data onto a seperate HD with a 40GB "stuff" partition.  And install a dual boot windows XP and &lt;a href="http://www.edubuntu.org/"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="color: rgb(255, 153, 0);"&gt;edu&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;buntu&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; on the other half.&lt;br /&gt;&lt;br /&gt;I wish Windows users would just INSIST on separate system and storage partitions on their personal computers.  Windows is too unstable, and it's to much work to back-up and restore their data (7GB of pictures, music and office documents on my sisters home computer).  For me, I just put in a second hard-drive, copied the "usual places" over and ran a few searches for misc jpg's and m4p's and the like... but most folks simply can not recover their data if it's on a system partition that has been deeply compromised by a Trojan.  Unless they have a "stuff" partition.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-3191199373964489316?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/3191199373964489316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=3191199373964489316' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/3191199373964489316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/3191199373964489316'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/06/unclose-last-tab-in-firefox-20-edubuntu.html' title='Unclose last tab in Firefox , edubuntu and &quot;stuff&quot;'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-6316955737769259658</id><published>2007-06-29T23:24:00.000-07:00</published><updated>2007-06-30T00:09:06.083-07:00</updated><title type='text'>Hello, Nikki</title><content type='html'>Tell everyone what it is you do...&lt;br /&gt;&lt;a href="http://www.gadgetell.com/wp-print.php?p=3788"&gt;&lt;span style="text-decoration: underline;"&gt;http://www.gadgetell.com/wp-print.php?p=3788&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Much like the reviewer, I was reluctant to let her go - but I had to sell her.  Nikki I barely knew thee.  =(&lt;br /&gt;&lt;br /&gt;One thing I learned from the sale, you can easily erase all of your stored web passwords on your Nokia 770 by booting up xterm (&lt;a href="http://770.fs-security.com/xterm/"&gt;http://770.fs-security.com/xterm/&lt;/a&gt;)  and removing the  hidden directory .opera in your home folder.&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote  style="font-weight: bold;font-family:trebuchet ms;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;cd&lt;/span&gt; ~&lt;br /&gt;rm -R .opera&lt;/blockquote&gt;Yeah it turns out the browser on this thing is good &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;ol&lt;/span&gt; opera.  I wonder if &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;firefox&lt;/span&gt; has been ported.  A &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;PDA&lt;/span&gt; that I can tweak like a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;linux&lt;/span&gt; box - just heavenly.&lt;br /&gt;&lt;br /&gt;But it's all good cause I got 8 more on the way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-6316955737769259658?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/6316955737769259658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=6316955737769259658' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/6316955737769259658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/6316955737769259658'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/06/hello-nikki.html' title='Hello, Nikki'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-315897730733934731</id><published>2007-06-29T06:59:00.000-07:00</published><updated>2007-12-19T21:02:14.824-08:00</updated><title type='text'>Nokia 770 To-Do List</title><content type='html'>&lt;p class="MsoNormal"&gt;So I'm going to set some goals for myself.  Here's a list of things I would very much like to do to/on/with my Nokia 770. My first Internet Tablet I had named Nikki, like Nokia - but with the hottness.  But I had to sell that little girl.  So now I have Bilbo, the baddass.  I'll update this post as I complete items on the list, and as much as possible link to tutorials of other's or my own.&lt;br /&gt;&lt;b style=""&gt;&lt;span style=";font-family:Arial;font-size:16;"  &gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style=";font-family:Arial;font-size:16;"  &gt;Things to do to/on/with my Nokia 770&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;install      screen capture tool (&lt;a href="http://inz.fi/blog/2007/06/21/screenshooting-made-easy-ish/"&gt;&lt;span style="text-decoration: underline;"&gt;.install&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/shot-2007-05-08-00-29-31.html"&gt;proof&lt;/a&gt;) - 7/6&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;Connect      to a couple wifi spots, learn the connection manager - 6/28&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;use      it in a real life coffee shop, enjoy the attention - done, and at the movie/music store and many restaurants&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;Install      DOOM and complete first level – incomplete&lt;/span&gt;&lt;/li&gt;&lt;ul&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;*(installed on 6/28, still      trying to get used to touch screen controls)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;Install      &lt;a href="http://770.fs-security.com/xterm/"&gt;xTerm &lt;/a&gt;and dig around the base linux file structure (&lt;a href="http://www.flickr.com/photos/9743135@N03/738480663/"&gt;screenshot&lt;/a&gt;)- 6/28&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;post      "cat /proc/cpuinfo" on the blog - &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/nokia-770-cpu-info-disk-info.html"&gt;complete  &lt;/a&gt;7/6&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;Find      a mellow organic green theme, barring that, build one (&lt;a href="http://flickr.com/photos/9743135@N03/734599691/"&gt;bg&lt;/a&gt;, &lt;a href="http://solid.gold.code.googlepages.com/sgc.green.1.0.deb"&gt;theme&lt;/a&gt;)- 7/6&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;Install      a SSH Server, use putty to login - 7/7  (&lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/ssh-on-nokia-770-internet-tablet.html"&gt;tutorial&lt;/a&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;scp      file from linux box to Nokia - DONE &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;login      as root - (&lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/gain-root-access-to-nokia-770.html"&gt;howto&lt;/a&gt;)7/7&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;create      new user - 7/9 &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/adding-users-and-shadown-password.html"&gt;complete&lt;/a&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;Install      a VNC Server, use tightVNC to control device from PC - incomplete&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;connect      it to some manner of bluetooth something - 7/27,  connected to  k1m&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;setup      Email Client (gmail, &lt;a href="http://tinyurl.com/28ddoe"&gt;http://tinyurl.com/28ddoe&lt;/a&gt;) -      6/28&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;copy      some mp3's from my PC via usb cable - 6/28&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;transfer      files to Nokia from my PC over bluetooth - complete 7/30&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;Install 1GB+ internal memory upgrade in this thing (may require kernel upgrade) - incomplete&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;get      a bluetooth keyboard hooked up with this rig - incomplete&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;flash      with latest firmware to restore to factory default - 12/19/07 (&lt;a href="http://thoughtsbyclayg.blogspot.com/"&gt;OS2007HE&lt;/a&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;install      decent weather applet - 7/9, &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/weather-applet.html"&gt;link&lt;/a&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;install      decent calender app - incomplete&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;chat      with my friends on their aim &amp;amp; yahoo accounts (gaim or googleTalk?) -      incomplete&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;Record      some sound of some such via some manor of mic of sorts - 7/16 &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/is-there-microphone-on-nokia-770.html"&gt;complete &lt;/a&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;make      an internet call - incomplete&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;establish      a vpn tunnel to at least one of the offices - incomplete&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;install      netcat - scan a few ports on some random unsecured hotspot - incomplete&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;install      UKTUBE, laugh at the people who just spent $500 on their iPhone –      incomplete&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;install      some sort of emulator, MAME or NES or Gameboy - &lt;a href="http://thoughtsbyclayg.blogspot.com/2007/07/mame-emulator-on-nokia-770.html"&gt;complete &lt;/a&gt;7/14&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;make post to this very blog, from my Nokia 770 - incomplete&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;p class="MsoNormal"&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style=";font-family:Arial;font-size:10;"  &gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-315897730733934731?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/315897730733934731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=315897730733934731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/315897730733934731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/315897730733934731'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/06/goals.html' title='Nokia 770 To-Do List'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7119494240114103556.post-1074959171168141366</id><published>2007-06-28T20:19:00.000-07:00</published><updated>2007-07-09T09:15:11.388-07:00</updated><title type='text'>Hacking the Nokia 770</title><content type='html'>I found a few of these bad boys for sale on the interwebz.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.nokiausa.com/EUROPE_NOKIA_COM_3/Find_and_Compare/770/770_main.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px;" src="http://www.nokiausa.com/EUROPE_NOKIA_COM_3/Find_and_Compare/770/770_main.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I have some &lt;a href="http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&amp;amp;item=150140520932"&gt;listed on ebay&lt;/a&gt;.&lt;a href="http://tinyurl.com/32rb9m"&gt;&lt;/a&gt;&lt;br /&gt;Another I'm going to play around with for a few days... I'll let you know how it goes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7119494240114103556-1074959171168141366?l=thoughtsbyclayg.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://thoughtsbyclayg.blogspot.com/feeds/1074959171168141366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7119494240114103556&amp;postID=1074959171168141366' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1074959171168141366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7119494240114103556/posts/default/1074959171168141366'/><link rel='alternate' type='text/html' href='http://thoughtsbyclayg.blogspot.com/2007/06/hacking-nokia-770.html' title='Hacking the Nokia 770'/><author><name>clayg</name><uri>http://www.blogger.com/profile/17201646652441277087</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
