<?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-21102333</id><updated>2011-08-31T13:23:16.669-07:00</updated><category term='Hibernate'/><category term='Hardware'/><category term='Windows'/><category term='Java'/><category term='news'/><category term='OpenWrt'/><category term='patterns'/><category term='QuickBooks'/><category term='Linux'/><category term='book review'/><title type='text'>Joe's Bit Bucket</title><subtitle type='html'>Rants, raves, comments and tips about computer hardware and software -- from a software developer's point of view.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>42</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-21102333.post-5457444455497901258</id><published>2009-09-22T11:43:00.002-07:00</published><updated>2009-09-29T14:36:09.027-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><title type='text'>Moved</title><content type='html'>Hello fans of Joe's Bit Bucket. This site has recently moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. See you there!&lt;br /&gt;&lt;br /&gt;Latest stories at &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://nerdboys.com/2009/09/28/case-mod-how-to-for-the-alix-single-board-computer/"&gt;Case Mod How-To for the Alix Single Board Computer&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-5457444455497901258?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/5457444455497901258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=5457444455497901258' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/5457444455497901258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/5457444455497901258'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2009/09/moved.html' title='Moved'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-6623097195097168225</id><published>2009-05-11T13:13:00.003-07:00</published><updated>2009-12-04T13:46:07.753-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Linux T-Shirts</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2009/05/11/linux-t-shirts/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;When I'm not at the office, I live in T-shirts. As such, I go through a lot of t-shirts and I have to replenish my supply regularly. But what's a good geek supposed to do when he can't find one he likes at his local mall? That's right, he makes his own!&lt;br /&gt;&lt;br /&gt;I recently used &lt;a href="http://www.zazzle.com/"&gt;zazzle.com&lt;/a&gt; to make some cool Linux T-Shirts for my own use. When me friends saw me wearing them, they wanted to buy them too. So, I released my Linux T-shirts to the public. Check out my Linux T-shirts at &lt;a href="http://www.zazzle.com/cyboc2000"&gt;my Zazzle store&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You'll notice that many of my Linux T-shirts feature &lt;a href="http://en.wikipedia.org/wiki/Tux"&gt;Tux the penguin&lt;/a&gt;, the mascot of Linux. Tux was designed by &lt;a href="http://www.isc.tamu.edu/%7Elewing/linux/"&gt;Larry Ewing&lt;/a&gt;, using &lt;a href="http://www.gimp.org/"&gt;The GIMP&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you decide to take a whirl at making your own shirts, please be respectful of others' intellectual property and either make your own graphics, use graphics that are in public domain or get the permission of the creator. For example, according to Larry Ewing's website, he grants you permission to use the Tux logo as long as you acknowledge both him and the GIMP.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-6623097195097168225?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/6623097195097168225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=6623097195097168225' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/6623097195097168225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/6623097195097168225'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2009/05/linux-t-shirts.html' title='Linux T-Shirts'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-7050473957945469465</id><published>2008-11-24T06:47:00.002-08:00</published><updated>2009-12-04T13:44:26.291-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Stupid sed Tricks</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2008/11/24/stupid-sed-tricks/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Here are some handy sed one-liners I've come across recently. Maybe someone else will find them handy.&lt;br /&gt;&lt;br /&gt;Wrap each line with quotes (quotation marks) - version 1:&lt;br /&gt;&lt;pre class="code-hs"&gt;sed 's/^[^$]*$/"&amp;amp;"/'&lt;/pre&gt;&lt;br /&gt;Wrap each line with quotes (quotation marks) - version 2:&lt;br /&gt;&lt;pre class="code-hs"&gt;sed 's/.*/"&amp;amp;"/'&lt;/pre&gt;&lt;br /&gt;Replace space with escaped space:&lt;br /&gt;&lt;pre class="code-hs"&gt;sed 's/ /\\ /g'&lt;/pre&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-7050473957945469465?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/7050473957945469465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=7050473957945469465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/7050473957945469465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/7050473957945469465'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2008/11/stupid-sed-tricks.html' title='Stupid sed Tricks'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-8402007058192917065</id><published>2008-11-14T15:17:00.005-08:00</published><updated>2009-12-04T13:42:57.760-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>How to Find Out Who is Logged On at a Windows Computer</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2008/11/14/how-to-find-out-who-is-logged-on-at-a-windows-computer/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Sometimes it's handy to find out who is logged on at a remote Windows computer. For example, before rebooting a critical server after hours, you might want to make sure your boss isn't logged in at his computer.&lt;br /&gt;&lt;br /&gt;In Linux, this is easy. You simply login to the remote computer with &lt;span style="font-family:courier new;"&gt;ssh&lt;/span&gt; (or &lt;span style="font-family:courier new;"&gt;telnet&lt;/span&gt;...yikes) and run the &lt;span style="font-family:courier new;"&gt;who&lt;/span&gt; command. For example:&lt;br /&gt;&lt;pre class="code-hs"&gt;&lt;br /&gt;me@bosscomputer:~$ who&lt;br /&gt;boss   tty7         2008-10-16 07:57 (:0)&lt;br /&gt;me   pts/0        2008-11-14 15:25 (mycomputer)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In Windows, I found two ways of doing this. Both ways work with Windows XP and Windows 2003 (and perhaps other versions too).&lt;br /&gt;&lt;br /&gt;The first way uses the &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb897545.aspx"&gt;psloggedon&lt;/a&gt; command, which is part of the &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896649.aspx"&gt;pstools&lt;/a&gt; suite created by Mark Russinovich. For example:&lt;br /&gt;&lt;pre class="code-hs"&gt;&lt;br /&gt;C:\tools\pstools&gt;psloggedon.exe \\bosscomputer&lt;br /&gt;&lt;br /&gt;loggedon v1.33 - See who's logged on&lt;br /&gt;Copyright ⌐ 2000-2006 Mark Russinovich&lt;br /&gt;Sysinternals - www.sysinternals.com&lt;br /&gt;&lt;br /&gt;Users logged on locally:&lt;br /&gt;11/14/2008 9:35:31 AM    MYDOMAIN\BOSS&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the example above, we see that my boss is currently logged into BOSSCOMPUTER and he logged in at 11/14/2008 9:35:31 AM.&lt;br /&gt;&lt;br /&gt;Often, you'll see error messages like these in the output, which you can ignore:&lt;br /&gt;&lt;pre class="code-hs"&gt;&lt;br /&gt;Error: could not retrieve logon time&lt;br /&gt;NT AUTHORITY\LOCAL SERVICE&lt;br /&gt;Error: could not retrieve logon time&lt;br /&gt;NT AUTHORITY\NETWORK SERVICE&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The neat thing about &lt;span style="font-family:courier new;"&gt;psloggedon&lt;/span&gt; is that it tells you not only about a logon from a user sitting in front of the computer but it can also tell you about remote logons to the computer via protocols like Remote Desktop Protocol (RDP). Here is an example of invoking &lt;span style="font-family:courier new;"&gt;psloggedon&lt;/span&gt; on a computer running Citrix Server (like Terminal Services):&lt;br /&gt;&lt;pre class="code-hs"&gt;&lt;br /&gt;C:\tools\pstools&gt;psloggedon.exe \\citrixbox&lt;br /&gt;&lt;br /&gt;loggedon v1.33 - See who's logged on&lt;br /&gt;Copyright ⌐ 2000-2006 Mark Russinovich&lt;br /&gt;Sysinternals - www.sysinternals.com&lt;br /&gt;&lt;br /&gt;Users logged on locally:&lt;br /&gt;11/14/2008 9:27:15 AM    MYDOMAIN\john&lt;br /&gt;11/14/2008 6:44:56 AM    MYDOMAIN\mary&lt;br /&gt;11/14/2008 6:29:42 AM    MYDOMAIN\steve&lt;br /&gt;11/14/2008 6:34:21 AM    MYDOMAIN\martha&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;All of the users in the above example were logged in remotely (despite the misleading word "locally" in the output).&lt;br /&gt;&lt;br /&gt;If you only care about logins from a user sitting in front of the computer, you can use another method: &lt;a href="http://social.technet.microsoft.com/Forums/en-US/winservercore/thread/ab6c7e6e-4ad4-4237-bab3-0349cd76c094"&gt;wmic.exe&lt;/a&gt;. For example&lt;br /&gt;&lt;pre class="code-hs"&gt;&lt;br /&gt;C:\tools\pstools&gt;wmic /node:"bosscomputer" ComputerSystem GET UserName&lt;br /&gt;UserName&lt;br /&gt;MYDOMAIN\boss&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the above example, you can see that my boss is logged in at BOSSCOMPUTER. When using the &lt;span style="font-family:courier new;"&gt;wmic&lt;/span&gt; command, I recommend you get in the habit of wrapping the computer name in quotation marks. If you don't, and the name contains a hyphen, you'll see the error "Invalid Global Switch".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If this tip helped you, please leave me a comment or send me an email!&lt;/span&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-8402007058192917065?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/8402007058192917065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=8402007058192917065' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/8402007058192917065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/8402007058192917065'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2008/11/how-to-find-out-who-is-logged-on-at.html' title='How to Find Out Who is Logged On at a Windows Computer'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-4226171778602872495</id><published>2008-11-14T09:14:00.005-08:00</published><updated>2009-12-04T13:41:29.393-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>How to Find Uptime in Windows</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2008/11/14/how-to-find-uptime-in-windows/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Sometimes it's useful to find out the uptime for a Windows computer. For example, if you are rebooting a whole bunch of Windows computers and you aren't careful about keeping track of which ones you have just rebooted, you can check the uptime.&lt;br /&gt;&lt;br /&gt;In Linux, it's easy to find out how long a computer has been up and running. You just runtime the good ol' &lt;span style="font-family:courier new;"&gt;uptime&lt;/span&gt; command. For example:&lt;br /&gt;&lt;pre class="code-hs"&gt;me@mycomputer:~$ uptime&lt;br /&gt;09:17:32 up 23 days, 19:13,  3 users,  load average: 0.36, 0.54, 0.49&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In Windows, it's almost as easy but not quite as intuitive. The following command should work on Windows XP, Windows 2003 and perhaps other versions: &lt;span style="font-family:courier new;"&gt;net statistics server&lt;/span&gt;. You could also use the shorthand version of that command: &lt;span style="font-family:courier new;"&gt;net stats srv&lt;/span&gt;. For example:&lt;br /&gt;&lt;pre class="code-hs"&gt;&lt;br /&gt;c:\temp&gt;net stats srv&lt;br /&gt;Server Statistics for \\MYCOMPUTER&lt;br /&gt;&lt;br /&gt;Statistics since 11/13/2008 1:40 PM&lt;br /&gt;&lt;br /&gt;Sessions accepted                  1&lt;br /&gt;Sessions timed-out                 1&lt;br /&gt;Sessions errored-out               1&lt;br /&gt;&lt;br /&gt;Kilobytes sent                     3734&lt;br /&gt;Kilobytes received                 491&lt;br /&gt;&lt;br /&gt;Mean response time (msec)          0&lt;br /&gt;&lt;br /&gt;System errors                      0&lt;br /&gt;Permission violations              0&lt;br /&gt;Password violations                0&lt;br /&gt;&lt;br /&gt;Files accessed                     82&lt;br /&gt;Communication devices accessed     0&lt;br /&gt;Print jobs spooled                 0&lt;br /&gt;&lt;br /&gt;Times buffers exhausted&lt;br /&gt;&lt;br /&gt;Big buffers                      0&lt;br /&gt;Request buffers                  0&lt;br /&gt;&lt;br /&gt;The command completed successfully.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The line that starts with "Statistics since", shows when the computer came up. That's not quite the same as uptime but it's close enough. Microsoft just makes you do the math (like they always do).&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;FOLLOW UP&lt;/span&gt;:&lt;br /&gt;I found an even easier way getting uptime in Windows. You can use &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb897550.aspx"&gt;psinfo&lt;/a&gt;, which is part of the &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896649.aspx"&gt;pstools&lt;/a&gt; suite of tools created by Mark Russinovich. For example:&lt;br /&gt;&lt;pre class="code-hs"&gt;&lt;br /&gt;C:\tools\pstools&gt;psinfo \\somecomputer Uptime&lt;br /&gt;&lt;br /&gt;PsInfo v1.75 - Local and remote system information viewer&lt;br /&gt;Copyright (C) 2001-2007 Mark Russinovich&lt;br /&gt;Sysinternals - www.sysinternals.com&lt;br /&gt;&lt;br /&gt;System information for \\somecomputer:&lt;br /&gt;Uptime:                    0 days 4 hours 7 minutes 57 seconds&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If this tip helped you, please leave me a comment or send me an email!&lt;/span&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-4226171778602872495?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/4226171778602872495/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=4226171778602872495' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/4226171778602872495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/4226171778602872495'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2008/11/how-to-find-uptime-in-windows.html' title='How to Find Uptime in Windows'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-2078611550718965885</id><published>2008-10-27T15:22:00.006-07:00</published><updated>2009-12-04T13:39:56.285-08:00</updated><title type='text'>How to Create a Tar File That Excludes Hidden Files and Folders</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2008/10/27/how-to-create-a-tar-file-that-excludes-hidden-files-and-folders/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Today I wanted to create a tar file that excludes hidden files and folders: ones that start with a dot (i.e. '.').&lt;br /&gt;&lt;br /&gt;Like a good boy, I read the fine man page (RTFM - sometimes the F is replaced with a ruder word than "fine") but I couldn't get it to work after several different variations of the exclude pattern. It seems that the exclude pattern that tar expects doesn't follow any of the &lt;a href="http://en.wikipedia.org/wiki/Regular_expression"&gt;regular expression&lt;/a&gt; (a.k.a. regex) syntaxes that &lt;span style="font-style: italic;"&gt;I'm&lt;/span&gt; familiar with. Someone enlighten me here if you know what it expects.&lt;br /&gt;&lt;br /&gt;Anyway, after lots of unsuccessful googling, I finally found a relevant &lt;a href="http://www.linuxquestions.org/questions/slackware-14/excluding-hidden-directories-when-using-tar-393653/#post2031708"&gt;post&lt;/a&gt;. Here's an example of the magical incantation to do this trick (it seems to work in my brief testing using &lt;span style="font-weight: bold;"&gt;Ubuntu&lt;/span&gt; Linux):&lt;br /&gt;&lt;pre class="code-hs"&gt;tar -cf test.tar foo/ -exclude '.*'&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If this tip helped you, please leave me a comment or send me an email!&lt;/span&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-2078611550718965885?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/2078611550718965885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=2078611550718965885' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/2078611550718965885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/2078611550718965885'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2008/10/how-to-create-tar-file-that-excludes.html' title='How to Create a Tar File That Excludes Hidden Files and Folders'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-3002098021851101845</id><published>2008-10-22T11:35:00.006-07:00</published><updated>2009-12-04T13:37:32.876-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>How to Use sudo tar in a Script Without Password Prompt</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2008/10/22/how-to-use-sudo-tar-in-a-script-without-password-prompt/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;If you are rolling your own backup shell script on your Ubuntu Linux box, chances are you might want to use &lt;span style="font-family:courier new;"&gt;tar&lt;/span&gt; or perhaps &lt;span style="font-family:courier new;"&gt;rsync&lt;/span&gt; somewhere in that script. For this example, let's say you've chosen to use &lt;span style="font-family:courier new;"&gt;tar&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;At some point, you will probably want to use &lt;span style="font-family:courier new;"&gt;cron&lt;/span&gt; or some other mechanism to automate your backup. Furthermore, if you want to coordinate the backup of several computers from one central computer, you will probably end up running the backup by making an &lt;span style="font-family:courier new;"&gt;ssh&lt;/span&gt; connection from the central computer to each backup target computer. In that case, the user that is running the backup will probably not be &lt;span style="font-family:courier new;"&gt;root&lt;/span&gt; (unless you allow root logins on your ssh servers) and may therefore have limited privileges.&lt;br /&gt;&lt;br /&gt;If that's the case, the user will not be able to backup some files with &lt;span style="font-family:courier new;"&gt;tar&lt;/span&gt; unless you use &lt;span style="font-family:courier new;"&gt;sudo tar&lt;/span&gt;. The problem with this is that &lt;span style="font-family:courier new;"&gt;sudo&lt;/span&gt; will prompt you for a password. If you want to prevent this prompt so that you can totally automate the backup over ssh, you'll need to do two things.&lt;br /&gt;&lt;br /&gt;First, you'll need to use ssh private key authentication where the private key has no password. There are lots of &lt;a href="http://www.mustnofee.com/tutorials/37-tutorials/87-setting-up-no-password-ssh"&gt;tutorials&lt;/a&gt; for how to do this. If you're nervous about using  a no-password private key, you could use a key ring mechanism instead. That's beyond the scope of this article so just google it.&lt;br /&gt;&lt;br /&gt;Second (and this is the main point of this article) you'll need to add a &lt;span style="font-family:courier new;"&gt;NOPASSWD&lt;/span&gt; line for &lt;span style="font-family:courier new;"&gt;tar&lt;/span&gt; in your &lt;span style="font-family:courier new;"&gt;sudoers&lt;/span&gt; file. Using &lt;span style="font-family:courier new;"&gt;visudo&lt;/span&gt;, add the following line to your &lt;span style="font-family:courier new;"&gt;sudoers&lt;/span&gt; file (replace &lt;span style="font-family:courier new;"&gt;mybackupusername&lt;/span&gt; with the name of your backup user):&lt;br /&gt;&lt;pre class="code-hs"&gt;mybackupusername ALL = NOPASSWD: /bin/tar&lt;/pre&gt;That line tells &lt;span style="font-family:courier new;"&gt;sudo&lt;/span&gt; that the backup user can run &lt;span style="font-family:courier new;"&gt;sudo tar&lt;/span&gt; without prompting for a password. If you're paranoid, you can fine-tune that line so it only allows certain options (switches) for &lt;span style="font-family:courier new;"&gt;tar&lt;/span&gt; (you might want to prevent the -x switch). For example:&lt;br /&gt;&lt;pre class="code-hs"&gt;mybackupusername ALL = NOPASSWD: /bin/tar -czf * -C *&lt;/pre&gt;Here's another, slightly different example:&lt;br /&gt;&lt;pre class="code-hs"&gt;mybackupusername ALL = NOPASSWD: /bin/tar -c*&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;If this tip helped you, please leave me a comment or send me an email!&lt;/span&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-3002098021851101845?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/3002098021851101845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=3002098021851101845' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/3002098021851101845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/3002098021851101845'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2008/10/how-to-use-sudo-tar-in-script-without.html' title='How to Use sudo tar in a Script Without Password Prompt'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-8434878362604350193</id><published>2008-09-19T13:28:00.004-07:00</published><updated>2009-12-04T13:35:42.616-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Windows DFS Brain Damage</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2008/09/19/windows-dfs-brain-damage/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;So we just started using Windows' &lt;a href="http://www.microsoft.com/windowsserver2003/technologies/storage/dfs/default.mspx"&gt;Distributed File System&lt;/a&gt; (or DFS for short). More specifically, we have been using the DFS Namespaces portion of DFS, which basically allows you to have one virtual share point to one or more underlying physical shares on any arbitrary physical server.&lt;br /&gt;&lt;br /&gt;In theory, this level of indirection makes maintenance easier because on the client side you can map a drive letter to the virtual share, allowing you to change the physical share behind the scenes without any configuration changes on the client. For example, you could have a virtual share called &lt;span style="font-family:courier new;"&gt;\\myADDomain\corp\files&lt;/span&gt; that is configured to point to the physical share &lt;span style="font-family:courier new;"&gt;\\myFileServer\files&lt;/span&gt;. On the client, you can map a drive letter (e.g. Z:) to &lt;span style="font-family:courier new;"&gt;\\myADDomain\corp\files&lt;/span&gt;. Behind the scenes, that gets translated to &lt;span style="font-family:courier new;"&gt;\\myFileServer\files&lt;/span&gt; when the client uses the drive letter.&lt;br /&gt;&lt;br /&gt;Today a user got the following error when logging into his Windows XP Pro machine: "An error occurred while reconnecting Z: to \\myADDomain\corp\files. Microsoft Windows Network: The system cannot find the file specified. The connection has not been restored."&lt;br /&gt;&lt;br /&gt;My first instinct was to reboot the client, as suggested in many DFS troubleshooting tips. So, I tried rebooting but upon logging in, the user got the new error: "Z:\ refers to a location that is unavailable."&lt;br /&gt;&lt;br /&gt;Sigh...&lt;br /&gt;&lt;br /&gt;In DFS jargon,&lt;span style="font-family:courier new;"&gt; \\myADDomain\corp&lt;/span&gt; is called a DFS root and the &lt;span style="font-family:courier new;"&gt;files&lt;/span&gt; portion of &lt;span style="font-family:courier new;"&gt;\\myADDomain\corp\files&lt;/span&gt; is called a link. To make things more complicated, the DFS root points to these things called Root Targets, for example, &lt;span style="font-family:courier new;"&gt;\\myDC1\corp&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;\\myDC2\corp&lt;/span&gt;. Essentially, there are two levels of indirection here. &lt;span style="font-family:courier new;"&gt;\\myADDomain\corp&lt;/span&gt; points &lt;span style="font-family:courier new;"&gt;\\myDC1\corp&lt;/span&gt; (and &lt;span style="font-family:courier new;"&gt;\\myDC2\corp&lt;/span&gt;) and &lt;span style="font-family:courier new;"&gt;\\myDC1\corp\files&lt;/span&gt; (and &lt;span style="font-family:courier new;"&gt;\\myDC2\corp\files&lt;/span&gt;) points to &lt;span style="font-family:courier new;"&gt;\\myFileServer\files&lt;/span&gt;. I told you it was complicated.&lt;br /&gt;&lt;br /&gt;The temporary workaround in this case was to map Z: drive directly to &lt;span style="font-family:courier new;"&gt;\\myFileServer\files&lt;/span&gt;. Of course, this renders DFS useless so I had to find a permanent fix. Below are the steps I followed:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Opened the DFS (Distributed File System) admininstrative tool on &lt;span style="font-family:courier new;"&gt;myDC1&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Noticed that &lt;span style="font-family:courier new;"&gt;\\corp.myADDomain.com\CORP&lt;/span&gt; (alias &lt;span style="font-family:courier new;"&gt;\\myADDomain\corp&lt;/span&gt;) DFS root was pointing to 2 root targets: &lt;span style="font-family:courier new;"&gt;\\myDC1\corp&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;\\myDC2\corp&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Right-clicked on each root target and clicked Check Status. Each one got a green check mark after the status check. This is good.&lt;/li&gt;&lt;li&gt;Noticed that the DFS root had the following DFS link: &lt;span style="font-family:courier new;"&gt;files&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Right-clicked on the link and clicked Check Status. It got a red X after the status check. This is BAD.&lt;/li&gt;&lt;li&gt;I then ran the DFS admin tool on &lt;span style="font-family:courier new;"&gt;myDC2&lt;/span&gt;. When I checked the status of root targets and link on this computer, ALL got green checkmarks. This is good.&lt;/li&gt;&lt;li&gt;On both &lt;span style="font-family:courier new;"&gt;myDC1&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;myDC2&lt;/span&gt;, I ran Windows Explorer and opened the folder that maps to the CORP share. For example, the root target &lt;span style="font-family:courier new;"&gt;\\myDC1\CORP&lt;/span&gt; maps to &lt;span style="font-family:courier new;"&gt;C:\dfsroot&lt;/span&gt; on &lt;span style="font-family:courier new;"&gt;myDC1&lt;/span&gt;. Similarly, the root target &lt;span style="font-family:courier new;"&gt;\\myDC2\CORP&lt;/span&gt; maps to &lt;span style="font-family:courier new;"&gt;C:\dfsroot&lt;/span&gt; on &lt;span style="font-family:courier new;"&gt;myDC2&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;In the &lt;span style="font-family:courier new;"&gt;C:\dfsroot&lt;/span&gt; folder on &lt;span style="font-family:courier new;"&gt;myDC1&lt;/span&gt;, the only child folder I saw was a hidden one called &lt;span style="font-family:courier new;"&gt;DO_NOT_REMOVE_NtFrs_PreInstall_Directory&lt;/span&gt;. However, on &lt;span style="font-family:courier new;"&gt;myDC2&lt;/span&gt;, the folder had the &lt;span style="font-family:courier new;"&gt;files&lt;/span&gt; child folder in addition to the funky hidden one.&lt;/li&gt;&lt;li&gt;AFAIK, you cannot manually recreate the missing child folder on &lt;span style="font-family:courier new;"&gt;myDC1&lt;/span&gt; with Explorer because they it does not seem to be a real folder (right click to see the properties and you will see what I mean). In other words, it is a "magical" pseudo-folder.&lt;/li&gt;&lt;li&gt;Instead, in the DFS admin tool on &lt;span style="font-family:courier new;"&gt;myDC1&lt;/span&gt;, I right clicked on the &lt;span style="font-family:courier new;"&gt;\\myDC1\corp&lt;/span&gt; root target and clicked Remove Target.&lt;/li&gt;&lt;li&gt;Then I recreated the &lt;span style="font-family:courier new;"&gt;\\myDC1\corp&lt;/span&gt; root target by right clicking the DFS root (&lt;span style="font-family:courier new;"&gt;\\corp.myADDomain.com\CORP&lt;/span&gt;) and clicking New Root Target. For the server name I entered &lt;span style="font-family:courier new;"&gt;myDC1&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Then, magically, the files child folder in &lt;span style="font-family:courier new;"&gt;C:\dfsroot&lt;/span&gt; on &lt;span style="font-family:courier new;"&gt;myDC1&lt;/span&gt; reappeared!&lt;/li&gt;&lt;li&gt;After that, the user logged out, logged in and Z: drive got mapped correctly. Woot!&lt;/li&gt;&lt;/ol&gt;How did myDC1 get into the bad state in the first place? I don't know. Go ask Microsoft...&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;FOLLOW UP (November 14, 2008)&lt;/span&gt;: This has happened two more times since writing this article. It seems to happen whenever we reboot one of the domain controllers that is hosting a Root Target. I'm not sure how to prevent the problem but at least the workaround described above always fixes it. Sigh...&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If this tip helped you, please leave me a comment or send me an email!&lt;/span&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-8434878362604350193?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/8434878362604350193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=8434878362604350193' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/8434878362604350193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/8434878362604350193'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2008/09/windows-dfs-brain-damage.html' title='Windows DFS Brain Damage'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-6959879827606222341</id><published>2008-03-18T13:14:00.003-07:00</published><updated>2009-12-04T13:33:34.975-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>How To See the Members of a Group in Linux</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2008/03/18/how-to-see-the-members-of-a-group-in-linux/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;As far as I know, there is no standard Linux command to find out the users that are members of a given group.  Intuitively, you would think there would be a command like &lt;span style="font-family: courier new;"&gt;members&lt;/span&gt; that takes the group name as a parameter. Unfortunately, it seems that no such command exists. In lieu of this command, you can simply &lt;span style="font-family:courier new;"&gt;grep&lt;/span&gt; the file &lt;span style="font-family:courier new;"&gt;/etc/group&lt;/span&gt; like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;grep "^thegroupname:" /etc/group&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Obviously, you need to replace &lt;span style="font-family: courier new;"&gt;thegroupname&lt;/span&gt; with the group you are searching for.  The character '^' means "beginning of line". The character ':' is the field separator between the group name and the group password in the group file.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If this tip helped you, please leave me a comment or send me an email!&lt;/span&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-6959879827606222341?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/6959879827606222341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=6959879827606222341' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/6959879827606222341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/6959879827606222341'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2008/03/how-to-see-members-of-group-in-linux.html' title='How To See the Members of a Group in Linux'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-4545241521998192396</id><published>2008-03-14T06:41:00.003-07:00</published><updated>2009-12-04T13:31:44.263-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>How to Find Out Which Version of Linux You Are Running</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2008/03/14/how-to-find-out-which-version-of-linux-you-are-running/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;This is a brief howto for finding out which version of Linux you are running.  I say "brief" because this is certainly not comprehensive. There are a few ways to skin this cat, depending on which Linux distribution you are running. I will only cover Debian and Ubuntu. Similar techniques may work on other distros (especially Debian derivatives) but your mileage may vary.&lt;br /&gt;&lt;br /&gt;But first, why should you even care which version you are running? There are many reasons why you should care, but perhaps the best reason is that it comes in handy when you are troubleshooting errors.  For example, if you are a Linux newbie and you post an error message on a forum asking for help troubleshooting it, you can bet that the first response will include the question: "Which version of Linux are you running?".  Knowing the version can sometimes also come in handy when you are installing new packages when the package is dependent on a certain version of Linux.&lt;br /&gt;&lt;br /&gt;Note that the question "Which version of Linux are you running?" is actually sort of ambiguous. Sometimes you want to know the version of the Linux &lt;span style="font-style: italic;"&gt;kernel&lt;/span&gt; and other times you want to know the version of the Linux &lt;span style="font-style: italic;"&gt;distribution&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;To get the version of the Linux kernel, you use the &lt;span style="font-family:courier new;"&gt;uname&lt;/span&gt; command, which I believe should be available on all distributions. For example:&lt;br /&gt;&lt;pre class="code-hs"&gt;me@mycomputer:~$ uname -r&lt;br /&gt;2.6.18-5-686&lt;/pre&gt;&lt;br /&gt;In the above example, we see that the kernel version is 2.6.18-5-686. You can also use the &lt;span style="font-family:courier new;"&gt;-a&lt;/span&gt; option to get even more information:&lt;br /&gt;&lt;pre class="code-hs"&gt;me@mycomputer:~$ uname -a&lt;br /&gt;Linux mycomputer 2.6.18-5-686 #1 SMP Fri Jun 1 00:47:00 UTC 2007 i686 GNU/Linux&lt;/pre&gt;&lt;br /&gt;To find out the version of the Linux distribution, there are a few ways, depending on the distro. In Ubuntu, version information is stored in the files &lt;span style="font-family:courier new;"&gt;/etc/issue&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;/etc/lsb-release&lt;/span&gt;. You can simply &lt;span style="font-family:courier new;"&gt;cat&lt;/span&gt; these files to see the information. Here is what I found on an Ubuntu 7.10 box:&lt;br /&gt;&lt;pre class="code-hs"&gt;me@mycomputer:~$ cat /etc/issue&lt;br /&gt;Ubuntu 7.10 \n \l&lt;/pre&gt;&lt;pre class="code-hs"&gt;me@mycomputer:~$ cat /etc/lsb-release&lt;br /&gt;DISTRIB_ID=Ubuntu&lt;br /&gt;DISTRIB_RELEASE=7.10&lt;br /&gt;DISTRIB_CODENAME=gutsy&lt;br /&gt;DISTRIB_DESCRIPTION="Ubuntu 7.10"&lt;/pre&gt;&lt;br /&gt;On Debian and Debian derivatives (e.g. Ubuntu), version information is stored in the file &lt;span style="font-family:courier new;"&gt;/etc/debian_version&lt;/span&gt;. Here is what the file contained on a Debian 4.0 box:&lt;br /&gt;&lt;pre class="code-hs"&gt;me@mycomputer:~$  cat /etc/debian_version&lt;br /&gt;4.0&lt;/pre&gt;&lt;br /&gt;And here is what the file contained on an Ubuntu 7.10 box:&lt;br /&gt;&lt;pre class="code-hs"&gt;me@mycomputer:~$  cat /etc/debian_version&lt;br /&gt;lenny/sid&lt;/pre&gt;&lt;br /&gt;I did some googling and found that some other distros follow this &lt;span style="font-family:courier new;"&gt;/etc/*version&lt;/span&gt; convention. For example, apparently Red Hat stores version infomation in &lt;span style="font-family:courier new;"&gt;/etc/redhat-version&lt;/span&gt;. I don't have a Red Hat system lying around (I haven't had one since they split into Red Hat and Fedora) so I couldn't try it. Therefore, I'll just take it as a matter of faith that this is true. On other distros, chances are that you'll have a &lt;span style="font-family:courier new;"&gt;*version&lt;/span&gt; file in your &lt;span style="font-family:courier new;"&gt;etc&lt;/span&gt; directory.&lt;br /&gt;&lt;br /&gt;Finally, another way you can find out the distro version is with the &lt;span style="font-family:courier new;"&gt;lsb_release&lt;/span&gt; command. Here is the output from an Ubuntu 7.10 box:&lt;br /&gt;&lt;pre class="code-hs"&gt;me@mycomputer:~$  lsb_release -a&lt;br /&gt;No LSB modules are available.&lt;br /&gt;Distributor ID: Ubuntu&lt;br /&gt;Description:    Ubuntu 7.10&lt;br /&gt;Release:        7.10&lt;br /&gt;Codename:       gutsy&lt;/pre&gt;&lt;br /&gt;And here is the output from a Debian 4.0 box:&lt;br /&gt;&lt;pre class="code-hs"&gt;me@mycomputer:~$  lsb_release -a&lt;br /&gt;No LSB modules are available.&lt;br /&gt;Distributor ID: Debian&lt;br /&gt;Description:    Debian GNU/Linux 4.0r1 (etch)&lt;br /&gt;Release:        4.0r1&lt;br /&gt;Codename:       etch&lt;/pre&gt;&lt;br /&gt;I'm not sure if that command is available on all distros or just Debian and its derivatives. For other distros, I leave that as an exercise to the reader. If the command is not installed on your Debian or Debian derivative box, you can install it with: &lt;span style="font-family:courier new;"&gt;apt-get install lsb-release&lt;/span&gt;. Note that you might need to &lt;span style="font-family:courier new;"&gt;su&lt;/span&gt; or &lt;span style="font-family:courier new;"&gt;sudo&lt;/span&gt; before installing it. Note also that the package name has a hyphen ("-") whereas the command has an underscore ("_"). That difference got me the first time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If this tip helped you, please leave me a comment or send me an email!&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-4545241521998192396?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/4545241521998192396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=4545241521998192396' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/4545241521998192396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/4545241521998192396'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2008/03/how-to-find-out-which-version-of-linux.html' title='How to Find Out Which Version of Linux You Are Running'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-2419959708480489691</id><published>2008-02-12T06:10:00.001-08:00</published><updated>2009-12-04T13:29:12.133-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Bart's Boot CD with Broadcom NetXtreme 57XX Gigabit Controller</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2008/02/12/barts-boot-cd-with-broadcom-netxtreme-57xx-gigabit-controller/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Are you having problems getting &lt;a href="http://www.nu2.nu/bootcd/"&gt;Bart's Boot CD&lt;/a&gt; to recognize the Broadcom NetXtreme 57xx Gigabit Controller network interface card?&lt;br /&gt;&lt;br /&gt;I work with some Dell computers (models: Optiplex SX280, Optiplex GX620, Precision 690 and Precision 370) that have this NIC and the current version of Bart's Boot CD is unable to recognize it.  The automatic NIC detection fails with a message to the effect of "could not find any device, you can try manually selecting a driver" (sorry, I can't remember the exact error).&lt;br /&gt;&lt;br /&gt;Naturally, I looked on Bart's site to see if there was a new driver cab file that would fix this problem.  There I found &lt;a href="http://www.nu2.nu/download.php?sFile=b57.cab"&gt;b57.cab&lt;/a&gt;, which had the description "Broadcom NetXtreme Gigabit Ethernet NDIS2 Driver v7.03 (031002)".  That seemed like it would be the right one so I put it on my boot disk and tried it. Again, auto-detection failed.&lt;br /&gt;&lt;br /&gt;I tried manually loading the driver in &lt;code&gt;b57.cab&lt;/code&gt; but I got  "Error 7306: The driver failed to initialize." I tried manually loading some of the other drivers on the disk but I got "Error 7321: Network-card drivers failed to load."&lt;br /&gt;&lt;br /&gt;The good news is that I figured out how to fix this issue, after doing some research.  Essentially, I made a custom version of &lt;code&gt;b57.cab&lt;/code&gt;. Read on for more details.  Note that you could apply these techniques for making custom versions of any of Bart's network driver cabs.&lt;br /&gt;&lt;br /&gt;First, let me explain how (I think) the auto-detection works. Each of the network driver cabs includes a file called &lt;code&gt;ndis.pci&lt;/code&gt;. Here are the contents of &lt;code&gt;ndis.pci&lt;/code&gt; from the latest released version of &lt;code&gt;b57.cab&lt;/code&gt; (ver 1.6):&lt;br /&gt;&lt;pre class="code-hs"&gt;ret="B57"&lt;br /&gt;ven=14E4 "Broadcom"&lt;br /&gt;dev=1645 "NetXtreme Gigabit Ethernet (BCM5701)"&lt;br /&gt;1644 "NetXtreme Gigabit Etherent (BCM5700/5401)"&lt;br /&gt;16A7 "NetXtreme Gigabit Ethernet (BCM5703X)"&lt;br /&gt;165D "NetXtreme Gigabit Ethernet (BCM5705M 10/100/1000)"&lt;br /&gt;165E "NetXtreme Gigabit Ethernet (BCM5705M 10/100/1000)"&lt;br /&gt;166D "NetXtreme Gigabit Ethernet (BCM5705MFE 10/100)"&lt;br /&gt;16A6 "NetXtreme Gigabit Ethernet (BCM5702 10/100/1000)"&lt;br /&gt;164D "NetXtreme Gigabit Ethernet (BCM5702FE 10/100)"&lt;br /&gt;1648 "NetXtreme Gigabit Ethernet (BCM5704C 10/100/1000)"&lt;br /&gt;1696 "NetXtreme Gigabit Ethernet (BCM5782 10/100/1000)"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;"Ven" stands for "vendor id", which identifies the manufacturer of the card. "dev" stands for "device ID", which identifies the model or chip set of the card. Operating systems use the &lt;a href="http://en.wikipedia.org/wiki/PCI_Configuration_Space"&gt;vendor and device IDs&lt;/a&gt; to implement &lt;a href="http://en.wikipedia.org/wiki/Plug-and-play"&gt;plug-and-play&lt;/a&gt; for PCI devices.  When plug and play works, the operating system can automatically load the correct drivers for a device.&lt;br /&gt;&lt;br /&gt;In this case, the manufacturer is Broadcom (vendor id 14E4) and all of the listed devices seem to be NetXtreme 57xx Gigabit devices of some sort. So why did autodetection fail? A clue is to look at the revision history of &lt;code&gt;b57.cab&lt;/code&gt;. For example, look at this note: "v1.2 Updated by Oivind Pettersen from IBM, added dev=1644". Hmm, perhaps I need to add a new device ID to the list but how do I know which one to add?&lt;br /&gt;&lt;br /&gt;To answer that question, I loaded Windows on a Dell Precision 690 and started poking around in Control Panel. I found the information I needed by drilling down to &lt;code&gt;Control Panel | System | Hardware | Device Manager | Network Adapters | Broadcom NetXtreme 57XX Gigabit Controller | Details&lt;/code&gt;. There I found the string "PCI\VEN_14E4&amp;amp;DEV_1600&amp;amp;SUBSYS_01C01028&amp;amp;REV_02\4&amp;amp;F667E4F&amp;amp;0&amp;amp;00E0".&lt;br /&gt;&lt;br /&gt;In that string, you can clearly see the vendor id, 14E4, and the device id, 1600. If you examine the device id list above, you'll note that 1600 is missing. Therefore, I added it. Similarly, for the Dell Optiplex SX280 and GX620, I had to add the device id 1677. I can't remember what the device id was for the Precision 370 but it was either one of the old ones of one of the two new ones.&lt;br /&gt;&lt;br /&gt;After making the changes, my new &lt;code&gt;ndis.pci&lt;/code&gt; file looked like this:&lt;br /&gt;&lt;pre class="code-hs"&gt;ret="B57"&lt;br /&gt;ven=14E4 "Broadcom"&lt;br /&gt;dev=1600 "NetXtreme Gigabit Ethernet (BCM57xx)"&lt;br /&gt;1645 "NetXtreme Gigabit Ethernet (BCM5701)"&lt;br /&gt;1644 "NetXtreme Gigabit Etherent (BCM5700/5401)"&lt;br /&gt;16A7 "NetXtreme Gigabit Ethernet (BCM5703X)"&lt;br /&gt;165D "NetXtreme Gigabit Ethernet (BCM5705M 10/100/1000)"&lt;br /&gt;165E "NetXtreme Gigabit Ethernet (BCM5705M 10/100/1000)"&lt;br /&gt;166D "NetXtreme Gigabit Ethernet (BCM5705MFE 10/100)"&lt;br /&gt;1677 "NetXtreme Gigabit Ethernet (BCM57xx)"&lt;br /&gt;16A6 "NetXtreme Gigabit Ethernet (BCM5702 10/100/1000)"&lt;br /&gt;164D "NetXtreme Gigabit Ethernet (BCM5702FE 10/100)"&lt;br /&gt;1648 "NetXtreme Gigabit Ethernet (BCM5704C 10/100/1000)"&lt;br /&gt;1696 "NetXtreme Gigabit Ethernet (BCM5782 10/100/1000)"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;After changing &lt;code&gt;ndis.pci&lt;/code&gt;, I rebuilt &lt;code&gt;b57.cab&lt;/code&gt; with &lt;a href="http://www.larshederer.homepage.t-online.de/cabpack.htm"&gt;CabPack&lt;/a&gt; (any cab building software would suffice).&lt;br /&gt;&lt;br /&gt;To get the new cab into your boot disk, you need to do the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Put the cab in the folder &lt;code&gt;bart\bcd\cabs\drivers\ndis&lt;/code&gt;&lt;/li&gt;&lt;li&gt;cd to the folder &lt;code&gt;bart\bcd&lt;/code&gt;&lt;/li&gt;&lt;li&gt;build the boot sector: bcd -bab&lt;/li&gt;&lt;li&gt;create the ISO file:  bcd -b corpmb&lt;/li&gt;&lt;li&gt;burn the ISO file to CD using Nero or other burning software&lt;/li&gt;&lt;/ol&gt;After building a new boot disk I tried it.  This time, the card was automatically detected and the system tried to load the DOS network driver in &lt;code&gt;b57.cab&lt;/code&gt;. Unfortunately, I got "Error 7306: The driver failed to initialize."&lt;br /&gt;&lt;br /&gt;What else could be wrong? Perhaps I had an old version of the DOS driver? Sure enough, I found a newer version of the NetXtreme 57xx DOS NDIS2 &lt;a href="http://www.broadcom.com/support/ethernet_nic/netxtreme_desktop.php"&gt;drivers&lt;/a&gt; on Broadcom's website. The version number was 10.4.6 (I think the lastest version on Bart's site was 7.03).&lt;br /&gt;&lt;br /&gt;To upgrade the driver, I simply replaced the &lt;code&gt;B57.dos&lt;/code&gt; in &lt;code&gt;b57.cab&lt;/code&gt; with the &lt;code&gt;B57.dos&lt;/code&gt; included in the download from Broadcom. Then I followed the previously mentioned steps to rebuild the boot disk. This time, auto-detection worked AND the driver loaded correctly! Woot!&lt;br /&gt;&lt;br /&gt;Using these steps, anyone should be able to quickly build a custom &lt;code&gt;b57.cab&lt;/code&gt;. However, if you're technically challenged (or just plain lazy), you can try sending me a polite email request for the cab. If I'm in a good mood, I might just respond to your request.&lt;br /&gt;&lt;br /&gt;Note that you could also use these steps to upgrade the cab files for other network drivers. Just keep these tips in mind:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;If auto-detection fails, you first must find the cab file that contains an &lt;code&gt;ndis.pci&lt;/code&gt; with your card's vendor id. If you find the vendor id, you will need to add a device id to &lt;code&gt;ndis.pci&lt;/code&gt;. If you don't find the vendor id in any of the cabs, you'll need to make a brand new cab file. I don't have any specific instructions on that but you should be able to figure it out from my notes above.&lt;/li&gt;&lt;li&gt;If you get "Error 7321: Network-card drivers failed to load", you probably have the wrong DOS driver for your card. For example, you tried to use a Broadcom driver for an Intel card. Try a different driver.&lt;/li&gt;&lt;li&gt;If you get "Error 7306: The driver failed to initialize", you probably have the right driver but it's too old. Try a newer version of that driver.&lt;/li&gt;&lt;/ol&gt;&lt;b&gt;If this tip helped you, please leave me a comment!&lt;/b&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-2419959708480489691?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/2419959708480489691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=2419959708480489691' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/2419959708480489691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/2419959708480489691'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2008/02/barts-boot-cd-with-broadcom-netxtreme.html' title='Bart&apos;s Boot CD with Broadcom NetXtreme 57XX Gigabit Controller'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-7212187169784968850</id><published>2008-02-08T13:20:00.001-08:00</published><updated>2009-12-04T13:26:44.026-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='book review'/><title type='text'>Book Review: Head First HTML with CSS &amp; XHTML</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2008/02/08/book-review-head-first-html-with-css-xhtml/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://headfirstlabs.com/Images/hfhtml_cover.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://headfirstlabs.com/Images/hfhtml_cover.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;First and foremost, I am a persistence layer software developer. I don't do much UI work and what little UI work I do usually involves rich client UIs. I rarely do any web UI work.&lt;br /&gt;&lt;br /&gt;Having said that, I think it's important to know at least a little bit about web UI technologies, even if you are a back-end developer. Why? Well, at the very least, you will be able to understand the vocabulary of the UI guys you work with.  Furthermore, you never know when you might have to look for a new job and there's a good chance they'll want you to know about some of that web UI stuff.&lt;br /&gt;&lt;br /&gt;With that in mind, I recently picked up a copy of &lt;a href="http://headfirstlabs.com/books/hfhtml/index.php"&gt;Head First HTML with CSS &amp;amp; XHTML&lt;/a&gt; to see if I could learn a thing or two. I just finished the book and I wanted to share my thoughts on it. Please read on.&lt;br /&gt;&lt;br /&gt;There are a lot of HTML books out there so you might be wondering why I got this particular HTML book . One reason is that it got a rating of 4.7 out of 5 stars from 193 reviewers on &lt;a href="http://www.amazon.com/Head-First-HTML-CSS-XHTML/dp/059610197X"&gt;Amazon.com&lt;/a&gt;. That's a pretty good score! Another reason is because I've skimmed some of the other books in the &lt;a href="http://headfirstlabs.com/books.php"&gt;Head First series&lt;/a&gt; and I think they are pretty darn fun to read.&lt;br /&gt;&lt;br /&gt;So what do I think of this book? It's fantastic! It's fun to read, engaging, informative and full of humor. It has numerous interesting activities and exercises to reinforce learning. It has lots of diagrams, photos and colors. I has plenty of jokes. And, on top of all that, the authors seem to really know their stuff. &lt;br /&gt;&lt;br /&gt;If you read this book, you &lt;i&gt;will&lt;/i&gt; learn the fundamentals of HTML, XHTML and CSS. You will learn it quickly and you won't feel like you're being tortured. Most importantly, you will have fun.&lt;br /&gt;&lt;br /&gt;No book is perfect however. My biggest quibble is the horrible index. I had a hard time finding anything and I had to keep on adding my own items to the index with a pencil. You CANNOT expect to use this book as a reference. It should be viewed strictly as a tutorial.&lt;br /&gt;&lt;br /&gt;Also, by no means is this book a comprehensive resource on CSS. For example, it didn't even talk about the &lt;code&gt;min-width&lt;/code&gt; property for setting the minimum width of your page. Lots of sites use this feature. I can't believe the authors didn't mention it in their chapter on layouts.&lt;br /&gt;&lt;br /&gt;The authors also spend quite a bit of time modularizing headers, footers and sidebars but they neglect to mention that it won't help you that much if you are have a purely static HTML website, where you would have to go through much pain to make any changes to them (how much fun would it be to make the same change in 100 pages?).  I feel the authors should have at mentioned this problem and recommended that you investigate server-side-includes, PHP, JSP or ASP as a solution to this problem.&lt;br /&gt;&lt;br /&gt;Contrary to what the book's cover says, I don't think you'll "launch your web career in one chapter". However, this book is definitely an excellent starting point for anyone who is new to these technologies.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Pros:&lt;/b&gt; Extremely fun to read. Teaches most of the fundamentals. Teaches standards compliance.&lt;br /&gt;&lt;b&gt;Cons:&lt;/b&gt; Horrible index.&lt;br /&gt;&lt;b&gt;Rating:&lt;/b&gt; 4.5/5&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-7212187169784968850?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/7212187169784968850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=7212187169784968850' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/7212187169784968850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/7212187169784968850'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2008/02/book-review-head-first-html-with-css.html' title='Book Review: Head First HTML with CSS &amp; XHTML'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-2572526298341526073</id><published>2008-02-07T16:20:00.001-08:00</published><updated>2009-12-04T13:24:00.493-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>How to Copy a File and Get a Progress Bar, in Linux</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2008/02/07/how-to-copy-a-file-and-get-a-progress-bar-in-linux/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Today I had to copy a really big file (in this case, a Ghost image) from a Linux box to a Windows box, using Samba. My first instinct was to use the cp command. The problem with cp is that it does not show you any sort of progress (I couldn't find any relevant option in the &lt;a href="http://www.linuxcommand.org/man_pages/cp1.html"&gt;cp man page&lt;/a&gt;). What I wanted was a progress bar display like the one &lt;a href="http://www.gnu.org/software/wget/"&gt;wget&lt;/a&gt; displays.&lt;br /&gt;&lt;br /&gt;I did some googling and found a few decent candidates:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://chris-lamb.co.uk/2008/01/24/can-you-get-cp-to-give-a-progress-bar-like-wget/"&gt;Lamby's "can you get cp to give a progress bar like wget?" bash script (cp_p)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://packages.debian.org/stable/utils/mc"&gt;Midnight Commander (mc)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://packages.debian.org/stable/utils/lfm"&gt;Last File Manager (lfm)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ubuntuforums.org/showthread.php?t=316707"&gt;Pabix's "cp with progress bar" bash script (gcp)&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ivarch.com/programs/pv.shtml"&gt;Pipe Viewer (pv)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;While all of them might work, the only one I tried was pv and I loved it. It did exactly what I wanted. The result was sort of like "cp with a progress bar".&lt;br /&gt;&lt;br /&gt;Under Debian Linux (sarge version) pv was easy enough to install: apt-get install pv.&lt;br /&gt;&lt;br /&gt;After reading the &lt;a href="http://www.ivarch.com/programs/quickref/pv.shtml"&gt;pv man page&lt;/a&gt;, I was still a little unclear on exactly how to use it to copy files (yes, I guess I'm dumb). However, after a little bit of experimentation, I figured it out:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;me@mycomputer:/home/ghost$ pv bigfile &amp;gt; /mnt/ghost_on_windows_box/bigfile&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The source file is bigfile, in the current directory. The target file is bigfile, on a share called /mnt/ghost_on_windows_box. Obviously, the share is a SMB share on a Windows box. On the Linux box, I mounted that share with the CIFS file system (via an entry in /etc/fstab).&lt;br /&gt;&lt;br /&gt;Here is what the output looked like, at three different stages:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;205MB 0:00:17 [8.03MB/s] [=======&amp;gt;                           ] 25% ETA 0:00:49&lt;br /&gt;436MB 0:00:31 [40.7MB/s] [=================&amp;gt;                 ] 54% ETA 0:00:25&lt;br /&gt;801MB 0:00:44 [  18MB/s] [=================================&amp;gt;] 100% ETA 0:00:00&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Just confirm that the copy worked, I ran md5sum on both the source file and the target file. It indeed worked.&lt;br /&gt;&lt;br /&gt;One minor problem I noticed, however, is that it took several seconds to get my command prompt back after pv showed the copy was 100% complete.  After some investigation, it seems that it wasn't pv's fault. Rather, it had something to do with Samba. I'm not even sure if it was the Linux  Samba client's fault or the Windows SMB server's fault.&lt;br /&gt;&lt;br /&gt;I confirmed that it was not a pv problem by copying the file to a local folder on the Linux box. In that case, pv returned control to the shell immediately after the progress bar went to 100%.&lt;br /&gt;&lt;br /&gt;As a workaround for this Samba copying problem, I added an extra command to the original command:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;me@mycomputer:/home/ghost$ pv bigfile &amp;gt; /mnt/ghost_on_windows_box/bigfile; echo ***DONE***&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, several seconds (or even a minute or so) after the progress bar reaches 100%, I get the message ***DONE*** in the console. Then I know it is really done.&lt;br /&gt;&lt;br /&gt;For my needs, pv works great.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;If this tip helped you, please leave me a comment!&lt;/b&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-2572526298341526073?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/2572526298341526073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=2572526298341526073' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/2572526298341526073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/2572526298341526073'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2008/02/how-to-copy-file-and-get-progress-bar.html' title='How to Copy a File and Get a Progress Bar, in Linux'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-7302303958989164079</id><published>2007-06-08T13:50:00.001-07:00</published><updated>2009-12-03T13:56:43.055-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='Hibernate'/><title type='text'>State Pattern Persistence with Hibernate</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2007/06/08/state-pattern-persistence-with-hibernate/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;In my software development job, I do a lot of persistence layer implementation, especially using the &lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt; O/R mapper. I work closely with a clever domain layer programmer who tends to use a lot of design patterns, perhaps because he likes the woman of the cover of &lt;a href="http://www.oreilly.com/catalog/hfdesignpat/"&gt;Head First Design Patterns&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Sometimes, these design patterns create a bit of a challenge for me in the persistence layer, especially since I always tell my domain layer programmer that I can persist things transparently, without having to muck up his code with persistence layer artifacts.&lt;br /&gt;&lt;br /&gt;A case in point is the &lt;a href="http://en.wikipedia.org/wiki/State_pattern"&gt;State pattern&lt;/a&gt;. I have now persisted 5 different sets of states so it's no longer a challenge. However, it took me a little while to figure how to do it. Naturally, I started by checking out &lt;a href="http://forum.hibernate.org/"&gt;Hibernate's forums&lt;/a&gt; but much to my chagrin, I found several people asking the same question but no one offering an answer. Therefore, I will provide an answer in this blog post. Read on!&lt;br /&gt;&lt;br /&gt;Imagine you have a Customer class, which is playing the "context" role in the design pattern. The customer has a simple state machine with two states: active and inactive. I've implemented State pattern persistence in two ways: without an enumeration and with an enumeration. First, here is a sample implementation of the pattern in the domain layer, without using an enumeration:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;public interface CustomerState&lt;br /&gt;{&lt;br /&gt;  /**&lt;br /&gt;   * Checks whether the CustomerState is 'Active'.&lt;br /&gt;   * @return true if the CustomerState is 'Active'.&lt;br /&gt;   */&lt;br /&gt;  boolean isActive();&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Checks whether the CustomerState is 'Inactive'.&lt;br /&gt;   * @return true if the CustomerState is 'Inactive'.&lt;br /&gt;   */&lt;br /&gt;  boolean isInactive();&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Activates the specified Customer.&lt;br /&gt;   * @param customer the Customer being activated.&lt;br /&gt;   */&lt;br /&gt;  void activate(Customer customer);&lt;br /&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Deactivates the specified Customer.&lt;br /&gt;   * @param customer the Customer being deactivated.&lt;br /&gt;   */&lt;br /&gt;  void deactivate(Customer customer);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;/**&lt;br /&gt;* All concrete subclasses of this class are stateless (they have no instance&lt;br /&gt;* variables). Therefore, we have overridden equals and hashCode (see below)&lt;br /&gt;* because any instance of a particular subclass should be considered equal to&lt;br /&gt;* any other instance of that sublcass.&lt;br /&gt;*/&lt;br /&gt;public abstract class AbstractCustomerState implements CustomerState&lt;br /&gt;{&lt;br /&gt; public static final CustomerState ACTIVE = new CustomerStateActive();&lt;br /&gt; public static final CustomerState INACTIVE = new CustomerStateInactive();&lt;br /&gt;&lt;br /&gt; public boolean isActive()&lt;br /&gt; {&lt;br /&gt;   return false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean isInactive()&lt;br /&gt; {&lt;br /&gt;   return false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void activate(Customer customer)&lt;br /&gt; {&lt;br /&gt;   throw new UnsupportedOperationException();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void deactivate(Customer customer)&lt;br /&gt; {&lt;br /&gt;   throw new UnsupportedOperationException();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Returns true if the Object's class name matches this Object's class name.&lt;br /&gt;  */&lt;br /&gt; public final boolean equals(Object obj)&lt;br /&gt; {&lt;br /&gt;   if (this == obj)&lt;br /&gt;   {&lt;br /&gt;     return true;&lt;br /&gt;   }&lt;br /&gt;   if (obj == null)&lt;br /&gt;   {&lt;br /&gt;     return false;&lt;br /&gt;   }&lt;br /&gt;   return getClass().getName().equals(obj.getClass().getName());&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Returns the hashCode of the Object's Class name because all instances of&lt;br /&gt;  * this Class are equal.&lt;br /&gt;  */&lt;br /&gt; public final int hashCode()&lt;br /&gt; {&lt;br /&gt;   return getClass().getName().hashCode();&lt;br /&gt; } &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;public class CustomerStateActive extends AbstractCustomerState&lt;br /&gt;{&lt;br /&gt; public boolean isActive()&lt;br /&gt; {&lt;br /&gt;   return true;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void deactivate(Customer customer)&lt;br /&gt; {&lt;br /&gt;   // do some checks to make sure it's okay to deactivate this customer&lt;br /&gt;   // ...&lt;br /&gt;&lt;br /&gt;   // set the state&lt;br /&gt;   ((AbstractCustomer) customer).setState(AbstractCustomerState.INACTIVE);&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;public class CustomerStateInactive extends AbstractCustomerState&lt;br /&gt;{&lt;br /&gt; public boolean isInactive()&lt;br /&gt; {&lt;br /&gt;   return true;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void activate(Customer customer)&lt;br /&gt; {&lt;br /&gt;   // do some checks to make sure it's okay to activate this customer&lt;br /&gt;   // ...&lt;br /&gt;&lt;br /&gt;   // set the state&lt;br /&gt;   ((AbstractCustomer) customer).setState(AbstractCustomerState.ACTIVE);&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Notice in my example that I have made the states stateless. Yes, I realized that a &lt;i&gt;stateless&lt;/i&gt; state seems like an oxymoron but it's true; the above state classes do not have any instance variables. Since they are stateless, any instance of a state is equal to any other instance of that same state. That's why I overrode the equals() and hashCode() methods. Since the states are stateless, I also created constants for each state (ACTIVE and INACTIVE) in the abstract base class so that we don't have to keep on instantiating them all over the place.&lt;br /&gt;&lt;br /&gt;Anyway, the code above is what the domain layer developer would hand over to me. Then it would be my job to persist it. The first task is to make a Hibernate UserType implementation:&lt;br /&gt;&lt;pre class="code-hs"&gt;public class CustomerStateUserType implements UserType&lt;br /&gt;{&lt;br /&gt; public static final int ACTIVE_STATE_DB_VALUE = 1;&lt;br /&gt; public static final int INACTIVE_STATE_DB_VALUE = 2;&lt;br /&gt;&lt;br /&gt; public int[] sqlTypes()&lt;br /&gt; {&lt;br /&gt;   return new int[] {Types.INTEGER};&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Class returnedClass()&lt;br /&gt; {&lt;br /&gt;   return CustomerState.class;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean isMutable()&lt;br /&gt; {&lt;br /&gt;   // CustomerStates are stateless, therefore they are clearly immutable&lt;br /&gt;   return false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object deepCopy(Object value) throws HibernateException&lt;br /&gt; {&lt;br /&gt;   // CustomerStates are immutable&lt;br /&gt;   return value;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Serializable disassemble(Object value) throws HibernateException&lt;br /&gt; {&lt;br /&gt;   // CustomerStates are immutable&lt;br /&gt;   return (Serializable) value;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object assemble(Serializable cached, Object owner)&lt;br /&gt;   throws HibernateException&lt;br /&gt; {&lt;br /&gt;   // CustomerStates are immutable&lt;br /&gt;   return cached;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object replace(Object original, Object target, Object owner)&lt;br /&gt;   throws HibernateException&lt;br /&gt; {&lt;br /&gt;   // CustomerStates are immutable&lt;br /&gt;   return original;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean equals(Object x, Object y)&lt;br /&gt;   throws HibernateException&lt;br /&gt; {&lt;br /&gt;   if (x == y)&lt;br /&gt;   {&lt;br /&gt;     return true;&lt;br /&gt;   }&lt;br /&gt;   if (x == null || y == null)&lt;br /&gt;   {&lt;br /&gt;     return false;&lt;br /&gt;   }&lt;br /&gt;   return x.equals(y);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public int hashCode(Object x) throws HibernateException&lt;br /&gt; {&lt;br /&gt;   return x.hashCode();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object nullSafeGet(ResultSet rs, String[] names, Object owner)&lt;br /&gt;   throws HibernateException, SQLException&lt;br /&gt; {&lt;br /&gt;   final int stateValue = rs.getInt(names[0]);&lt;br /&gt;   if (rs.wasNull())&lt;br /&gt;   {&lt;br /&gt;     return null;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   CustomerState state = null;&lt;br /&gt;   switch (stateValue)&lt;br /&gt;   {&lt;br /&gt;     case ACTIVE_STATE_DB_VALUE:&lt;br /&gt;       state = AbstractCustomerState.ACTIVE;&lt;br /&gt;       break;&lt;br /&gt;     case INACTIVE_STATE_DB_VALUE:&lt;br /&gt;       state = AbstractCustomerState.INACTIVE;&lt;br /&gt;       break;&lt;br /&gt;     default:&lt;br /&gt;       throw new RuntimeException("Unknown CustomerState value ["&lt;br /&gt;         + stateValue + "]");&lt;br /&gt;   }&lt;br /&gt;   return state;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void nullSafeSet(PreparedStatement st, Object value, int index)&lt;br /&gt;   throws HibernateException, SQLException&lt;br /&gt; {&lt;br /&gt;   if (value == null)&lt;br /&gt;   {&lt;br /&gt;     st.setNull(index, Types.INTEGER);&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;     if (value.equals(AbstractCustomerState.ACTIVE))&lt;br /&gt;     {&lt;br /&gt;       st.setInt(index, ACTIVE_STATE_DB_VALUE);&lt;br /&gt;     }&lt;br /&gt;     else if (value.equals(AbstractCustomerState.INACTIVE))&lt;br /&gt;     {&lt;br /&gt;       st.setInt(index, INACTIVE_STATE_DB_VALUE);&lt;br /&gt;     }&lt;br /&gt;     else&lt;br /&gt;     {&lt;br /&gt;       throw new RuntimeException("Unknown CustomerState [" + value + "]");&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;As you can see, most of the interesting code is in nullSafeGet() and nullSafeSet(), which map the states to an integer column in the database. Next, you need to map it:&lt;br /&gt;&lt;pre class="code-hs"&gt;&amp;lt;hibernate-mapping&amp;gt;&lt;br /&gt;&amp;lt;class name="Customer" table="customer"&amp;gt;&lt;br /&gt; &amp;lt;property name="state" column="state" type="CustomerStateUserType"&lt;br /&gt;   access="field"/&amp;gt;&lt;br /&gt; &amp;lt;!- ...other properties -&amp;gt;&lt;br /&gt;&amp;lt;/class&amp;gt;&lt;br /&gt;&amp;lt;/hibernate-mapping&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Pretty easy, huh? The only problem with this implementation is that if the domain layer developer subsequently adds another state, I have to modify my UserType to account for the new state. If the domain layer developer forgets to tell me about the new state, it could be awhile before the error is discovered. Of course, one way around this is to make nullSafeGet and nullSafeSet map each state to the state's class name. For example:&lt;br /&gt;&lt;pre class="code-hs"&gt;public class CustomerStateUserType implements UserType&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; public int[] sqlTypes()&lt;br /&gt; {&lt;br /&gt;   return new int[] {Types.VARCHAR};&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; //...other methods&lt;br /&gt;&lt;br /&gt; public Object nullSafeGet(ResultSet rs, String[] names, Object owner)&lt;br /&gt;   throws HibernateException, SQLException&lt;br /&gt; {&lt;br /&gt;   final String stateValue = rs.getString(names[0]);&lt;br /&gt;   if (rs.wasNull())&lt;br /&gt;   {&lt;br /&gt;     return null;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   CustomerState state = null;&lt;br /&gt;&lt;br /&gt;   try&lt;br /&gt;   {&lt;br /&gt;     state = (CustomerState) Class.forName(stateValue).newInstance();&lt;br /&gt;   }&lt;br /&gt;   catch (Exception e)&lt;br /&gt;   {&lt;br /&gt;     throw new RuntimeException("Can't instantiate instance of ["&lt;br /&gt;       + stateValue + "]", e);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   if (!(state instanceof CustomerState))&lt;br /&gt;   {&lt;br /&gt;     throw new RuntimeException("Unknown CustomerState value ["&lt;br /&gt;       + stateValue + "]");&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return state;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void nullSafeSet(PreparedStatement st, Object value, int index)&lt;br /&gt;   throws HibernateException, SQLException&lt;br /&gt; {&lt;br /&gt;   if (value == null)&lt;br /&gt;   {&lt;br /&gt;     st.setNull(index, Types.VARCHAR);&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;     if (value instanceof AbstractCustomerState)&lt;br /&gt;     {&lt;br /&gt;       st.setString(index, value.getClass().getName());&lt;br /&gt;     }&lt;br /&gt;     else&lt;br /&gt;     {&lt;br /&gt;       throw new RuntimeException("Unknown CustomerState ["&lt;br /&gt;         + value + "]");&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Of course, the problem with storing the class name in the database column is that it takes up more space than an integer; consider the relative cost of storing a million records with an integer state value versus a value like "com.mycompany.someapp.domain.customer.CustomerStateActive".&lt;br /&gt;&lt;br /&gt;The second style of implementing this pattern involves using an enumeration, specifically Apache's Jakarta-commons Enum class (of course, you could probably use Java 1.5's new enum feature too). Here are the relevant domain layer classes:&lt;br /&gt;&lt;pre class="code-hs"&gt;import org.apache.commons.lang.enums.Enum;&lt;br /&gt;&lt;br /&gt;public abstract class AbstractCustomerState extends Enum implements CustomerState&lt;br /&gt;{&lt;br /&gt; public static final CustomerState ACTIVE = new CustomerStateActive();&lt;br /&gt; public static final CustomerState INACTIVE = new CustomerStateInactive();&lt;br /&gt;&lt;br /&gt; protected AbstractCustomerState(String name)&lt;br /&gt; {&lt;br /&gt;   super(name);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Overrides superclass method to allow enums to be subclasses, yet still be&lt;br /&gt;  * part of the same enumeration. This is what allows an enum to play the role&lt;br /&gt;  * of a State in the State design pattern. The Javadoc comments for Enum call&lt;br /&gt;  * this type of Enum a "Functional Enum".&lt;br /&gt;  * @see org.apache.commons.lang.enums.Enum#getEnumClass()&lt;br /&gt;  * @see org.apache.commons.lang.enums.Enum&lt;br /&gt;  */&lt;br /&gt; public final Class getEnumClass()&lt;br /&gt; {&lt;br /&gt;   return AbstractCustomerState.class;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static AbstractCustomerState getEnum(String name)&lt;br /&gt; {&lt;br /&gt;   return (AbstractCustomerState) getEnum(&lt;br /&gt;     AbstractCustomerState.class, name);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static Map getEnumMap()&lt;br /&gt; {&lt;br /&gt;   return getEnumMap(AbstractCustomerState.class);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static List getEnumList()&lt;br /&gt; {&lt;br /&gt;   return getEnumList(AbstractCustomerState.class);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static Iterator iterator()&lt;br /&gt; {&lt;br /&gt;   return iterator(AbstractCustomerState.class);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; //*start of CustomerState methods*&lt;br /&gt; public boolean isActive()&lt;br /&gt; {&lt;br /&gt;   return false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean isInactive()&lt;br /&gt; {&lt;br /&gt;   return false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void activate(Customer customer)&lt;br /&gt; {&lt;br /&gt;   throw new UnsupportedOperationException();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void deactivate(Customer customer)&lt;br /&gt; {&lt;br /&gt;   throw new UnsupportedOperationException();&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;public class CustomerStateActive extends AbstractCustomerState&lt;br /&gt;{&lt;br /&gt; CustomerStateActive()&lt;br /&gt; {&lt;br /&gt;   super("ACTIVE");&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean isActive()&lt;br /&gt; {&lt;br /&gt;   return true;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void deactivate(Customer customer)&lt;br /&gt; {&lt;br /&gt;   // do some checks to make sure it's okay to deactivate this customer&lt;br /&gt;   // ...&lt;br /&gt;&lt;br /&gt;   // set the state&lt;br /&gt;   ((AbstractCustomer) customer).setState(AbstractCustomerState.INACTIVE);&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;public class CustomerStateInactive extends AbstractCustomerState&lt;br /&gt;{&lt;br /&gt; CustomerStateInactive()&lt;br /&gt; {&lt;br /&gt;   super("INACTIVE");&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean isInactive()&lt;br /&gt; {&lt;br /&gt;   return true;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void activate(Customer customer)&lt;br /&gt; {&lt;br /&gt;   // do some checks to make sure it's okay to activate this customer&lt;br /&gt;   // ...&lt;br /&gt;&lt;br /&gt;   // set the state&lt;br /&gt;   ((AbstractCustomer) customer).setState(AbstractCustomerState.ACTIVE);&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;There is a tradeoff with this implementation. Notice the extra code at the top of AbstractCustomerState? I must override several methods of the Enum class, as per the "Functional Enums" section of Enum's JavaDocs. For the UserType, I started by making an abstract base class for all enumerations:&lt;br /&gt;&lt;pre class="code-hs"&gt;/**&lt;br /&gt;* Maps a org.apache.commons.lang.enums.Enum to a Hibernate type. This&lt;br /&gt;* allows you to persist Enum instances. This class was adapted from an&lt;br /&gt;* example posted in &lt;a href="http://www.hibernate.org/172.html"&gt;this forum&lt;br /&gt;* thread &lt;/a&gt; and an example on page 210 of "Hibernate in Action" (first&lt;br /&gt;* edition).&lt;br /&gt;*/&lt;br /&gt;public abstract class EnumUserType implements UserType&lt;br /&gt;{&lt;br /&gt; private Class enumClass;&lt;br /&gt;&lt;br /&gt; public EnumUserType(Class enumClass)&lt;br /&gt; {&lt;br /&gt;   this.enumClass = enumClass;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public int[] sqlTypes()&lt;br /&gt; {&lt;br /&gt;   return new int[] {&lt;br /&gt;     Types.VARCHAR&lt;br /&gt;   };&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Class returnedClass()&lt;br /&gt; {&lt;br /&gt;   return enumClass;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean equals(Object x, Object y) throws HibernateException&lt;br /&gt; {&lt;br /&gt;   if (x == y)&lt;br /&gt;   {&lt;br /&gt;     return true;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   if (x == null || y == null)&lt;br /&gt;   {&lt;br /&gt;     return false;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return Hibernate.STRING.isEqual(x, y);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object nullSafeGet(ResultSet rs, String[] names, Object owner)&lt;br /&gt;   throws HibernateException, SQLException&lt;br /&gt; {&lt;br /&gt;   String value = rs.getString(names[0]);&lt;br /&gt;   return rs.wasNull() ? null : EnumUtils.getEnum(enumClass, value);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void nullSafeSet(PreparedStatement st, Object value, int index)&lt;br /&gt;   throws HibernateException, SQLException&lt;br /&gt; {&lt;br /&gt;   // make sure the received value is of the right type&lt;br /&gt;   if ((value != null) &amp;&amp;amp; !returnedClass().isAssignableFrom(value.getClass()))&lt;br /&gt;   {&lt;br /&gt;     throw new IllegalArgumentException("Received value is not a["&lt;br /&gt;       + returnedClass().getName() + "] but [" + value.getClass() + "]");&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   if (value != null)&lt;br /&gt;   {&lt;br /&gt;     Enum enum = (Enum) value;&lt;br /&gt;      &lt;br /&gt;     // convert the enum into its persistence format&lt;br /&gt;     String enumName = enum.getName();&lt;br /&gt;&lt;br /&gt;     // set the value into the resultset&lt;br /&gt;     st.setString(index, enumName);&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;     st.setNull(index, Types.VARCHAR);&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object deepCopy(Object value) throws HibernateException&lt;br /&gt; {&lt;br /&gt;   // Enums are immutable - nothing to be done to deeply clone it&lt;br /&gt;   return value;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public boolean isMutable()&lt;br /&gt; {&lt;br /&gt;   // Enums are immutable&lt;br /&gt;   return false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public int hashCode(Object object) throws HibernateException&lt;br /&gt; {&lt;br /&gt;   return object.hashCode();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Serializable disassemble(Object value)&lt;br /&gt;   throws HibernateException&lt;br /&gt; {&lt;br /&gt;   return (Serializable) value;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object assemble(Serializable cached, Object owner)&lt;br /&gt;   throws HibernateException&lt;br /&gt; {&lt;br /&gt;   return cached;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Object replace(Object original, Object target, Object owner)&lt;br /&gt;   throws HibernateException&lt;br /&gt; {&lt;br /&gt;   return original;&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Then, I extended that base class to create a CustomerStateUserType.&lt;br /&gt;&lt;pre class="code-hs"&gt;public class CustomerStateUserType extends EnumUserType&lt;br /&gt;{&lt;br /&gt; public CustomerStateUserType()&lt;br /&gt; {&lt;br /&gt;   super(AbstractCustomerState.class);&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Notice that the derived UserType is a piece of cake to make.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;If this tip helped you, please leave me a comment!&lt;/b&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-7302303958989164079?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/7302303958989164079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=7302303958989164079' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/7302303958989164079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/7302303958989164079'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2007/06/state-pattern-persistence-with.html' title='State Pattern Persistence with Hibernate'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-9205222015078432047</id><published>2007-06-04T06:53:00.001-07:00</published><updated>2009-12-03T13:53:30.486-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenWrt'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Stupid Cron Tricks</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2007/06/04/stupid-cron-tricks/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Have you ever wanted to make &lt;span style="font-family:courier new;"&gt;cron&lt;/span&gt; run a scheduled task on some weird interval like every 29 days? I was faced with that problem just the other day.&lt;br /&gt;&lt;br /&gt;I was starting to get annoyed with &lt;a href="http://www.dyndns.com/"&gt;DynDNS&lt;/a&gt;'s nag emails, asking me to either log in and "touch" my WRT54GL router's host record every 30 days or to upgrade to a paid service that does not require a periodic touch.&lt;br /&gt;&lt;br /&gt;Of course, you can create a &lt;span style="font-family:courier new;"&gt;cron&lt;/span&gt; job that calls programs like &lt;span style="font-family:courier new;"&gt;ez-ipupdate&lt;/span&gt; to automate this periodic touching. The problem is, even though &lt;span style="font-family:courier new;"&gt;cron&lt;/span&gt; is quite flexible, it does not support intervals of 29 days.&lt;br /&gt;&lt;br /&gt;Why 29 days? If you touch the record any earlier than 28 days since the previous touch, DynDNS may flag you for abuse and disable your host record (in practice, I have been able to touch the record a handful of times within 28 days without being flagged, but why take a chance?). On the other hand, if you don't touch the host record within 30 days, you get a nag email (and if you don't touch it within 35 days, the record is deleted by DynDNS altogether). So, I figured that 29 days would be a safe value to use.&lt;br /&gt;&lt;br /&gt;I thought I had solved the problem with the technique I described in &lt;a href="http://joesbitbucket.blogspot.com/2007/01/how-to-force-ez-ipupdate-to-touch.html"&gt;this article&lt;/a&gt;. It &lt;span style="font-style: italic;"&gt;did&lt;/span&gt; automatically touch the record during within the 28 to 35 day window but since it was based on a &lt;span style="font-style: italic;"&gt;monthly&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;cron&lt;/span&gt; job, I still got nag emails during 31-day months because 31 is greater than the 30 day nag email threshold.&lt;br /&gt;&lt;br /&gt;So how did I solve the problem the second time around? I based my solution on Stephan Sokolow's &lt;a href="http://leary.csoft.net/%7Essokolow/wordpress/archives/2007/03/04/crontab-timing-tricks/"&gt;Crontab Timing Tricks&lt;/a&gt; article, but with a few minor changes. Here is the script that does most of the work:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;#!/bin/sh&lt;br /&gt;#&lt;br /&gt;# Runs ez-ipupdate periodically (every $INTERVAL days).&lt;br /&gt;# To automate this, call this script from a daily cron job.&lt;br /&gt;&lt;br /&gt;let INTERVAL=29&lt;br /&gt;let upSeconds=`cat /proc/uptime | cut -f1 -d.`&lt;br /&gt;let days=$((${upSeconds}/86400))&lt;br /&gt;&lt;br /&gt;echo `date`&lt;br /&gt;echo interval = ${INTERVAL}&lt;br /&gt;echo uptime in days = ${days}&lt;br /&gt;&lt;br /&gt;if [ $days -lt $INTERVAL ]; then&lt;br /&gt;  echo uptime less than interval, so no touch needed&lt;br /&gt;elif [ $(( $days % $INTERVAL )) -ne 0 ]; then&lt;br /&gt;  echo uptime is not a multiple of interval, so no touch needed&lt;br /&gt;else&lt;br /&gt;  echo uptime is a multiple of interval, a touch is needed&lt;br /&gt;  echo doing touch&lt;br /&gt;  rm -f /tmp/ez-ipupdate.cache&lt;br /&gt;  /usr/sbin/ez-ipupdate -c /etc/ez-ipupdate.conf&lt;br /&gt;fi&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see, &lt;span style="font-family:courier new;"&gt;ez-ipupdate&lt;/span&gt; is only called every 29 days, based on the system uptime.&lt;br /&gt;&lt;br /&gt;Next, I created a &lt;span style="font-family:courier new;"&gt;cron&lt;/span&gt; job to automatically call the script daily:&lt;br /&gt;&lt;pre class="code-hs"&gt;1 0 * * * /usr/sbin/periodic-ez-ipupdate &amp;gt; /tmp/periodic-ez-ipupdate-cron.log 2&amp;gt;&amp;amp;1&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ya, It's pretty cheesy but it works.&lt;br /&gt;&lt;br /&gt;One caveat with my solution is that if the router is rebooted sooner than 29 days since the last reboot, my &lt;span style="font-family:courier new;"&gt;periodic-ez-ipupdate&lt;/span&gt; script will not be called. That's okay though because the stock configuration of &lt;span style="font-family:courier new;"&gt;ez-ipupdate&lt;/span&gt; in OpenWrt White Russian RC6 automatically calls &lt;span style="font-family:courier new;"&gt;ez-ipupdate&lt;/span&gt; upon reboot. Note, however, if you frequently reboot your router, you will be flagged for abuse for sending too many unnecessary updates to DynDNS. Fortunately, I go several months between reboots of my router.&lt;br /&gt;&lt;br /&gt;An obvious solution to the reboot problem would be to store the date of the last touch in a file and compare that to the current system date to see if 29 days had passed. The is a great solution if your router has a hard drive. However, the WRT54GL only has flash memory, which has a &lt;a href="http://www.kingston.com/ukroot/flash/flashendurance.asp"&gt;finite number of write cycles&lt;/a&gt;. Many manufacturers will tell you that you have at least 10,000 write cycles. But I have read that some chips can give you as little as 1,000 write cycles, so why take a chance? That's why I used the uptime-based solution.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;If this tip helped you, please leave me a comment!&lt;/b&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-9205222015078432047?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/9205222015078432047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=9205222015078432047' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/9205222015078432047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/9205222015078432047'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2007/06/stupid-cron-tricks.html' title='Stupid Cron Tricks'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-5935224645774506582</id><published>2007-03-08T10:31:00.001-08:00</published><updated>2009-12-03T13:51:11.738-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenWrt'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>A Virtual Visit from Paul Wouters</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2007/03/08/a-virtual-visit-from-paul-wouters/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Soon after posting yesterday's blog entry, &lt;a href="http://joesbitbucket.blogspot.com/2007/03/how-to-vpn-between-rv082-or-rv042-and.html"&gt;How To: VPN Between RV082 (or RV042) and WRT54GL (or WRT54G)&lt;/a&gt;, I received a comment from &lt;a href="http://www.xtdnet.nl/paul/"&gt;Paul Wouters&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;Use dpdaction=restart&lt;br /&gt;&lt;br /&gt;btw yout ike/ipsec lifetimes are insanely short. you should not do that. leave them default, and the shortest one of the other device will be used.&lt;/blockquote&gt;Paul, if you're reading this, thanks for the tips!&lt;br /&gt;&lt;br /&gt;I wasn't sure how I could have missed that useful &lt;code&gt;dpdaction=restart&lt;/code&gt; setting so I went back and checked the &lt;a href="http://www.die.net/doc/linux/man/man5/ipsec.conf.5.html"&gt;ipsec.conf man page&lt;/a&gt; this morning. Sure enough, the &lt;code&gt;dpdaction=restart&lt;/code&gt; setting was missing from the man page. That's why I missed it! See! I did RTFM!&lt;br /&gt;&lt;br /&gt;Anyway, I did &lt;a href="http://www.google.ca/search?q=dpdaction+restart&amp;hl=en&amp;amp;start=0&amp;sa=N"&gt;some googling&lt;/a&gt; to find out more about &lt;code&gt;dpdaction=restart&lt;/code&gt; and I came across this &lt;a href="http://lists.openswan.org/pipermail/users/2005-November/007203.html"&gt;Openswan mailing list message&lt;/a&gt;, authored by none other than Paul Wouters:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;On Thu, 10 Nov 2005, Duncan Reed wrote:&lt;br /&gt;&lt;br /&gt;&gt; I was interested in seeing how the new(ish) dpdaction=restart option&lt;br /&gt;&gt; differed from clear and hold. Looking through the ipsec.conf man and&lt;br /&gt;&gt; other docs they don't appear to have been updated yet.&lt;br /&gt;&gt;&lt;br /&gt;&gt; How does restart differ from hold? And in what situations would I use&lt;br /&gt;&gt; restart instead of the other options.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;clear&lt;/b&gt;: tear down the broken tunnel. Allow cleartext pckets to the destination&lt;br /&gt;&lt;b&gt;hold&lt;/b&gt;: tear down the broken tunnel. Disallow cleartext packets, wait for the remote to re-estbalished a new IPsec SA (responder)&lt;br /&gt;&lt;b&gt;restart&lt;/b&gt;: tear down the broken tunnel. Disallow cleartext packets, attempt to restart the IPsec tunnel (initiator)&lt;br /&gt;&lt;br /&gt;clear is mostly used for roadwarriors. You likely won't be talking to that remote IP again, as the roadwarrior might show up elsewhere.&lt;br /&gt;&lt;br /&gt;hold is for a connection, usually with a remote subnet defined, that vanished but is on dynamic IP. you cannot restart it, but you also want to prevent&lt;br /&gt;sending cleartext packets for the defined remote subnet.&lt;br /&gt;&lt;br /&gt;restart is for a connection to a remote static ip, which you can initiate yourself.&lt;br /&gt;&lt;br /&gt;Compare it to rekey=no. If you have right=%any, you need to have rekey=no, and you cannot use dpdaction=restart. If this was a single roadwarrior, you clear, if it was for a subnet, you want to hold it.&lt;br /&gt;&lt;br /&gt;Paul&lt;/blockquote&gt;&lt;br /&gt;I love finding out about undocumented settings! Hehe!&lt;br /&gt;&lt;br /&gt;Now, as for my "insanely short" values for &lt;code&gt;keylife&lt;/code&gt; and &lt;code&gt;ikelifetime&lt;/code&gt;, where did I come up with those? Well, when I was trying to connect the RV082 to the WRT54G, I figured that if I had any problems with bad settings, the RV082 side would be the pickiest. So, I tried to stick mostly to the RV082's default values. RV082's default value for &lt;code&gt;Phase1 SA Life Time&lt;/code&gt; is 28800 seconds (8 hours) and the default value for &lt;code&gt;Phase2 SA Life Time&lt;/code&gt; is 3600 seconds (1 hour).&lt;br /&gt;&lt;br /&gt;My mistake was in my mapping of the RV082's settings names to the OpenSwan settings names. I &lt;i&gt;incorrectly&lt;/i&gt; mapped &lt;code&gt;Phase1 SA Life Time&lt;/code&gt; to &lt;code&gt;keylife&lt;/code&gt; and  &lt;code&gt;Phase2 SA Life Time&lt;/code&gt; to &lt;code&gt;ikelifetime&lt;/code&gt;. The correct mapping is &lt;code&gt;Phase1 SA Life Time&lt;/code&gt; to &lt;code&gt;ikelifetime&lt;/code&gt; and  &lt;code&gt;Phase2 SA Life Time&lt;/code&gt; to &lt;code&gt;keylife&lt;/code&gt;.  How did I found that out? From another Paul Wouters &lt;a href="http://lists.openswan.org/pipermail/users/2005-September/006657.html"&gt;mailing list message&lt;/a&gt;, of course:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;On Tue, 27 Sep 2005, Agent Smith wrote:&lt;br /&gt;&lt;br /&gt;&gt; ike_life is set by the keyword ikelifetime which is&lt;br /&gt;&gt; phase 1 timeout (maximum supported is 8 hr.)&lt;br /&gt;&gt;&lt;br /&gt;&gt; ipsec_life is set by keylife keyword and that is phase&lt;br /&gt;&gt; 2 timeout.&lt;br /&gt;&gt;&lt;br /&gt;&gt; phase 2 timeout is typically less then phase 1&lt;br /&gt;&gt; timeout.&lt;br /&gt;&gt;&lt;br /&gt;&gt; correct?&lt;br /&gt;&lt;br /&gt;Yes&lt;br /&gt;&lt;br /&gt;Paul&lt;/blockquote&gt;So what values should you use for &lt;code&gt;ikelifetime&lt;/code&gt; (phase1) and &lt;code&gt;keylife&lt;/code&gt; (phase2)? I emailed this question to Paul and here is his answer:&lt;br /&gt;&lt;blockquote&gt;The RFC leaves it open. Some people prefer phase 2 to last longer then phase1, some vise versa. I believe &lt;span style="font-style: italic;"&gt;using phase2 that is bigger then phase1 is good&lt;/span&gt;, since a phase 1 rekey failure won't immediately blow your tunnel out of the water, since phase2 is still valid for a few more hours.&lt;/blockquote&gt;Based on Paul's advice, I assume the Openswan default values are appropriate. That is, &lt;code&gt;ikelifetime=1&lt;/code&gt; and &lt;code&gt;keylife=8&lt;/code&gt;. Note that the default values on the RV082/RV042 appear to be the exact opposite of this, so you should probably reverse the values on the RV082/RV042.&lt;br /&gt;&lt;br /&gt;BTW, I found out that Paul has authored a book about Openswan called &lt;a href="http://www.packtpub.com/openswan/book"&gt;Openswan: Building and Integrating Virtual Private Networks&lt;/a&gt;. I recall seeing this book at the bookstore when I was attempting to create my VPN. At the time I thought "Great book. I should get it". However, I didn't get it because I didn't feel like begging my boss to buy me yet another book. I probably should have got it...&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-5935224645774506582?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/5935224645774506582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=5935224645774506582' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/5935224645774506582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/5935224645774506582'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2007/03/virtual-visit-from-paul-wouters.html' title='A Virtual Visit from Paul Wouters'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-5004958474261254941</id><published>2007-03-07T09:35:00.001-08:00</published><updated>2009-12-03T13:48:41.943-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenWrt'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>How To:  VPN Between RV082 (or RV042) and WRT54GL (or WRT54G)</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2007/03/07/how-to-vpn-between-rv082-or-rv042-and-wrt54gl-or-wrt54g/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Using the &lt;a href="http://beast:8080/JSPWiki/Wiki.jsp?page=OpenWrt"&gt;OpenWrt&lt;/a&gt; Linux distribution, you can configure a LinkSys WRT54G (also WRT54GS and WRT54GL) router as an IPSec VPN endpoint. This IPSec VPN functionality is provided by an &lt;a href="http://www.openswan.org/"&gt;Openswan&lt;/a&gt; package that was built specifically for OpenWrt.&lt;br /&gt;&lt;br /&gt;In this How To, I will show you how to create a VPN between a LinkSys WRT54GL and a LinkSys RV082 (RV042 could be used also).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;As usual, if the post helps you, please have the common courtesy to leave me a thank you comment!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Openswan vs Freeswan - What's the difference?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Openswan is a &lt;a href="http://wiki.openswan.org/index.php/Openswan/FreeSWAN"&gt;fork&lt;/a&gt; of the Freeswan project. Apparently, &lt;a href="http://www.openswan.org/docs/feature_comparison.php"&gt;Openswan has more features that Freeswan&lt;/a&gt;. Anyway, it's moot because only Openswan has been ported to OpenWrt. Note that much of the Freeswan documentation, tips and how-tos also apply to Openswan.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Software and Hardware Versions&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I used the following hardware and software versions for the OpenWrt end of the VPN tunnel: &lt;ul&gt;&lt;li&gt;LinkSys WRT54GL v1.1 (serial number starts with CL7B). &lt;/li&gt;&lt;li&gt;OpenWrt firmware version: White Russian RC6 &lt;/li&gt;&lt;li&gt;Openswan 2.4.4-1 &lt;/li&gt;&lt;/ul&gt; &lt;p&gt; On the other end of the VPN tunnel, I used: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;LinkSys RV082 &lt;/li&gt;&lt;li&gt;Stock firmware version: 1.3.3.5 &lt;/li&gt;&lt;li&gt;From skimming the GPL source code for that firmware version, it appears that it uses Freeswan (perhaps version 1.99) for its VPN server. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Network Diagram&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This how-to was created in a "lab" environment. To simulate the internet we used private IP addresses. Here is the network diagram:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/__68CJkmINgk/Re753D43hcI/AAAAAAAAAAM/ZSBWHmXHTw0/s1600-h/Openswan_VPN_in_lab.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/__68CJkmINgk/Re753D43hcI/AAAAAAAAAAM/ZSBWHmXHTw0/s400/Openswan_VPN_in_lab.JPG" alt="" id="BLOGGER_PHOTO_ID_5039239757406111170" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt; &lt;i&gt;From the point of view of the WRT54G&lt;/i&gt;, the WRT54G side of the tunnel is called the &lt;b&gt;local side&lt;/b&gt; or the &lt;b&gt;left side&lt;/b&gt; and the RV082 side of the tunnel is called the &lt;b&gt;remote side&lt;/b&gt; or the &lt;b&gt;right side&lt;/b&gt;.  &lt;/p&gt;&lt;p&gt; Here are the relevant IP addresses, as shown in the above network diagram:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Left WAN interface ("left") = 192.168.3.2&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Left LAN subnet ("leftsubnet") = 192.168.2.0/24&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Left LAN interface ("leftsourceip") = 192.168.2.1&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Right WAN interface ("right") = 192.168.3.1&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Right LAN subnet ("rightsubnet") = 192.168.1.0/24&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Right LAN interface ("rightsourceip") = 192.168.1.1&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 1: Configure the RV082 Side of the VPN&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Login to the RV082 Web Admin Site &lt;/li&gt;&lt;li&gt;Browse the VPN page. &lt;/li&gt;&lt;li&gt;Click the &lt;code&gt;Add New Tunnel&lt;/code&gt; button. The following "Mode Choose" screen will appear. Click the &lt;code&gt;Add Now&lt;/code&gt; near the top (i.e. in the Gateway to Gateway section). &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/__68CJkmINgk/Re77Nz43hdI/AAAAAAAAAAU/ydyU8lph9wQ/s1600-h/ModeChoose.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/__68CJkmINgk/Re77Nz43hdI/AAAAAAAAAAU/ydyU8lph9wQ/s400/ModeChoose.jpg" alt="" id="BLOGGER_PHOTO_ID_5039241247759762898" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Enter the settings as shown on the following two screenshots, then press &lt;code&gt;Save Settings&lt;/code&gt;: &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/__68CJkmINgk/Re78Cz43heI/AAAAAAAAAAc/SP-ZbvVRuzo/s1600-h/RV082_VPN_Settings1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/__68CJkmINgk/Re78Cz43heI/AAAAAAAAAAc/SP-ZbvVRuzo/s400/RV082_VPN_Settings1.jpg" alt="" id="BLOGGER_PHOTO_ID_5039242158292829666" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/__68CJkmINgk/Re7_QD43hfI/AAAAAAAAAAk/cBsV5uW6UdQ/s1600-h/RV082_VPN_Settings2.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/__68CJkmINgk/Re7_QD43hfI/AAAAAAAAAAk/cBsV5uW6UdQ/s400/RV082_VPN_Settings2.jpg" alt="" id="BLOGGER_PHOTO_ID_5039245684460979698" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Step 2: Configure the WRT54G Side of the VPN&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Install OpenWrt White Russian RC6, if you haven't done so already. &lt;/li&gt;&lt;li&gt;If necessary, update OpenWrt's package list: &lt;tt&gt;ipkg update &lt;/tt&gt;&lt;/li&gt;&lt;li&gt;Install the openswan package: &lt;code&gt;ipkg install openswan&lt;/code&gt;. ipkg should automatically detect and install openswan dependencies like kmod-openswan.&lt;/li&gt;&lt;li&gt;Create the file &lt;code&gt;/etc/ipsec.secrets&lt;/code&gt;, which will hold your preshared key. Here are the contents of my file (note that you can configure keys for specific tunnels or all tunnels):&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre class="code-hs"&gt;# PSK for tunnel from specific ip to specific ip&lt;br /&gt;#192.168.3.2 192.168.3.1: PSK "abc123"&lt;br /&gt;&lt;br /&gt;# PSK for tunnel from any ip to any ip&lt;br /&gt;: PSK "abc123"&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Edit the file &lt;code&gt;/etc/ipsec.conf&lt;/code&gt;. Here are the contents of my file:&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;version 2.0     # conforms to second version of ipsec.conf specification&lt;br /&gt;&lt;br /&gt;# basic configuration&lt;br /&gt;config setup&lt;br /&gt;    plutodebug="none"&lt;br /&gt;    klipsdebug="none"&lt;br /&gt;    nat_traversal=no&lt;br /&gt;    interfaces=%defaultroute&lt;br /&gt;&lt;br /&gt;# Add connections here&lt;br /&gt;conn TestVPN&lt;br /&gt;    authby=secret&lt;br /&gt;    keyexchange=ike&lt;br /&gt;    ikelifetime=480m&lt;br /&gt;    keylife=60m&lt;br /&gt;    pfs=yes&lt;br /&gt;    left=192.168.3.2&lt;br /&gt;    leftsubnet=192.168.2.0/24&lt;br /&gt;    leftnexthop=%defaultroute&lt;br /&gt;    right=192.168.3.1&lt;br /&gt;    rightsubnet=192.168.1.0/24&lt;br /&gt;    auto=start&lt;br /&gt;    leftsourceip=192.168.2.1&lt;br /&gt;&lt;br /&gt;#Disable Opportunistic Encryption&lt;br /&gt;include /etc/ipsec.d/examples/no_oe.conf&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Edit &lt;code&gt;/etc/firewall.user&lt;/code&gt;. Here is what I &lt;i&gt;appended&lt;/i&gt; to the end of the file:&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;### IPSec VPN&lt;br /&gt;# allow IPSEC&lt;br /&gt;iptables -A input_rule -p esp -s 192.168.3.1              -j ACCEPT&lt;br /&gt;# allow ISAKMP&lt;br /&gt;iptables -A input_rule -p udp -s 192.168.3.1 -dport 500  -j ACCEPT&lt;br /&gt;# allow NAT-T&lt;br /&gt;iptables -A input_rule -p udp -s 192.168.3.1 -dport 4500 -j ACCEPT&lt;br /&gt;# disable NAT for communications with remote LAN&lt;br /&gt;iptables -t nat -A postrouting_rule -d 192.168.1.0/24     -j ACCEPT&lt;br /&gt;# Allow any traffic between tunnel LANs&lt;br /&gt;iptables -A forwarding_rule -i $LAN -o ipsec0 -j ACCEPT&lt;br /&gt;iptables -A forwarding_rule -i ipsec0 -o $LAN -j ACCEPT&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Step 3: Start up the Tunnel&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If you are starting the tunnel for the first time, you can start it by either rebooting the WRT54G, or by executing: &lt;code&gt;/etc/init.d/S60ipsec -start&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Step 4: Verify the Tunnel is Up&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;There are numerous ways to verify that the tunnel is up and working:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;RV082 System Log - You should see a message like this: &lt;code&gt;Tunnel Negotiation Info - Quick Mode Phase 2 SA Established, IPSec Tunnel Connected&lt;/code&gt;&lt;/li&gt;&lt;li&gt;RV082 VPN connection status (in the web admin tool) - The button in the "tunnel test" column should have the caption "Disconnect" and the "status" column should say "connected". For example:&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/__68CJkmINgk/Re8FNT43hgI/AAAAAAAAAAs/LuH68q5swJA/s1600-h/VpnConnectionStatus.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/__68CJkmINgk/Re8FNT43hgI/AAAAAAAAAAs/LuH68q5swJA/s400/VpnConnectionStatus.jpg" alt="" id="BLOGGER_PHOTO_ID_5039252234286106114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ssh to the WRT54G and run the command &lt;code&gt;ipsec auto -status&lt;/code&gt;. The output should look something like this:&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;000 #2: "TestVPN":500 STATE_QUICK_I2 (sent QI2, IPsec SA established); EVENT_SA_REPLACE in 2514s; newest IPSEC; eroute owner&lt;br /&gt;000 #2: "TestVPN" esp.82fdd248@192.168.3.1 esp.96ea10e4@192.168.3.2 tun.1002@192.168.3.1 tun.1001@192.168.3.2&lt;br /&gt;000 #1: "TestVPN":500 STATE_MAIN_I4 (ISAKMP SA established); EVENT_SA_REPLACE in 27519s; newest ISAKMP; lastdpd=0s(seq in:0 out:0)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What you want to see are the phrases are "ISAKMP SA established" and "IPSec SA established", with the relevant connection name (in this case, "TestVPN"). Note that &lt;code&gt;ipsec auto -status&lt;/code&gt; will tell you only what states have been achieved, rather than the current state. Since determining the current state is rather more difficult to do, current state information is not available from Linux FreeS/WAN. If you are actively bringing a connection up, the status report's last states for that connection likely reflect its current state. Beware, though, of the case where a connection was correctly brought up but is now downed: Linux FreeS/WAN will not notice this until it attempts to rekey. Meanwhile, the last known state indicates that the connection has been established.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ssh to the WRT54G and run the command &lt;code&gt;logread&lt;/code&gt;. The output should look something like this:&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #1: initiating Main Mode&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #1: received Vendor ID&lt;br /&gt;payload [Dead Peer Detection]&lt;br /&gt;Jan  1 00:05:13 (none) daemon.err ipsec__plutorun: 104 "TestVPN" #1:&lt;br /&gt;STATE_MAIN_I1: initiate&lt;br /&gt;Jan  1 00:05:13 (none) daemon.err ipsec__plutorun: ...could not start conn&lt;br /&gt;"TestVPN"&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #1: transition from&lt;br /&gt;state STATE_MAIN_I1 to state STATE_MAIN_I2&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #1: STATE_MAIN_I2: sent&lt;br /&gt;MI2, expecting MR2&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #1: I did not send a&lt;br /&gt;certificate because I do not have one.&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #1: transition from&lt;br /&gt;state STATE_MAIN_I2 to state STATE_MAIN_I3&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #1: STATE_MAIN_I3: sent&lt;br /&gt;MI3, expecting MR3&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #1: Main mode peer ID is&lt;br /&gt;ID_IPV4_ADDR: '192.168.3.1'&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #1: transition from&lt;br /&gt;state STATE_MAIN_I3 to state STATE_MAIN_I4&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #1: STATE_MAIN_I4:&lt;br /&gt;ISAKMP SA established {auth=OAKLEY_PRESHARED_KEY cipher=oakley_3des_cbc_192&lt;br /&gt;prf=oakley_md5 group=modp1024}&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #1: Dead Peer Detection&lt;br /&gt;(RFC 3706): enabled&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #2: initiating Quick&lt;br /&gt;Mode PSK+ENCRYPT+TUNNEL+PFS+UP {using isakmp#1}&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #2: Dead Peer Detection&lt;br /&gt;(RFC 3706): enabled&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #2: transition from&lt;br /&gt;state STATE_QUICK_I1 to state STATE_QUICK_I2&lt;br /&gt;Jan  1 00:05:13 (none) kern.warn pluto[1646]: "TestVPN" #2: STATE_QUICK_I2: sent&lt;br /&gt;QI2, IPsec SA established {ESP=&gt;0x82fdd26a &lt;0x454556ce xfrm="3DES_0-HMAC_MD5" natd="none" dpd=""&gt;&lt;/pre&gt;&lt;br /&gt;Again, what you want to see are the phrases are "ISAKMP SA established" and "IPSec SA established".&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ping the RV082's LAN address from the WRT54G.&lt;/li&gt;&lt;li&gt;Ping the WRT54G's LAN address from the RV082.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Troubleshooting&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If the connection does not come up:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Check the VPN Log on the RV082. There might be some useful error messages.&lt;/li&gt;&lt;li&gt;Check the dmesg log on the WRT54G (ssh to the WRT54G and run the command &lt;code&gt;dmesg&lt;/code&gt;). For more verbose messages, try changing the plutodebug and klipsdebug settings in /etc/ipsec.conf from "none" to "all" or another supported log level. &lt;b&gt;HOWEVER&lt;/b&gt;, please make sure to change both settings back to "none" when you have finished debugging otherwise the VPN performance will suffer a lot! You have been warned!&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;How to Get the VPN to Reconnect Automatically&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If the WAN link between the two VPN endpoints goes down, the VPN link will go down too. To get the VPN to reconnect when the WAN link comes up again, you have two options:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Enable the "Keep-Alive" setting on the "advanced" section of the VPN tunnel configuration on the RV082:&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/__68CJkmINgk/Re8Hfz43hhI/AAAAAAAAAA0/9g9R3vhosy0/s1600-h/RV082-Keepalive.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/__68CJkmINgk/Re8Hfz43hhI/AAAAAAAAAA0/9g9R3vhosy0/s400/RV082-Keepalive.jpg" alt="" id="BLOGGER_PHOTO_ID_5039254751136941586" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note that this keep-alive setting does not seem to work if the WAN link is down for more than about 4 minutes. After that, you will probably have to manually reconnect the tunnel.&lt;ul&gt;&lt;li&gt;Enable the "dead peer detection" settings on the WRT54G in the file &lt;code&gt;/etc/ipsec.conf&lt;/code&gt;. The relevant settings are &lt;code&gt;dpddelay&lt;/code&gt;, &lt;code&gt;dpdtimeout&lt;/code&gt; and &lt;code&gt;dpdaction&lt;/code&gt;. Please see the &lt;a href="http://www.die.net/doc/linux/man/man5/ipsec.conf.5.html"&gt;Openswan ipsec.conf man page&lt;/a&gt; for a description of each setting. According to the man page, those settings should have default values, however, they didn't seem to work so I added them manually to &lt;code&gt;ipsec.conf&lt;/code&gt;. Here are the settings I used:&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;dpddelay=10&lt;br /&gt;dpdtimeout=30&lt;br /&gt;dpdaction=hold&lt;/pre&gt;&lt;br /&gt;Note that the RV082 also has dead peer detection (DPD) but it does not seem to work like &lt;a href="http://www.openswan.org/docs/local/README.DPD"&gt;DPD on the WRT54G&lt;/a&gt;. Here is a description of the RV082's DPD feature:&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;Dead Peer Detection (DPD): When DPD is enabled, the RV082 will send the periodic HELLO/ACK messages to prove the tunnel liveliness when both peers of VPN tunnel provide DPD mechanism. Once a dead peer detected, the RV082 will disconnect the tunnel so the connection can be re-established. The Interval is the number of seconds between DPD messages. The default is DPD enabled, and default Interval is 10 seconds.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;As you can see, RV082 DPD only seems to remove the dead connection. It does not seem to try to reconnect. That's what the RV082's keep-alive feature is for, as described here:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;Keep-Alive: This mechanism helps to keep up the connection of IPSec tunnels. Whenever a connection is dropped and detected, it will be re-established immediately.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;The WRT54G's DPD feature seems to do both jobs: disconnect the dead connect and reconnect.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I have found that a combination of the above strategies works well for keeping connections up. That is:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Enable DPD on RV082&lt;/li&gt;&lt;li&gt;Enable keep-alive on RV082&lt;/li&gt;&lt;li&gt;Enable DPD on WRT54G&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;If those strategies don't work, you can also try pinging each VPN endpoint periodically. This is a "roll your own" keep-alive solution.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;How to Manually Reconnect the Tunnel&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;If the tunnel does not automatically reconnect after a WAN link goes down and comes back up, you can manually reconnect it from either side of the tunnel:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;To reconnect from the WRT54G side, ssh to the WRT54G and run &lt;code&gt;/etc/init.d/S60ipsec restart&lt;/code&gt;. (Alternatively, you can reboot the WRT54G but this will bring down &lt;i&gt;all&lt;/i&gt; WAN connectivity for a few seconds.)&lt;/li&gt;&lt;li&gt;To reconnect from the RV082 side, press the tunnel's Connect button on the VPN Summary page in the web admin tool. (Alternatively, you can reboot the RV082 but this will bring down &lt;i&gt;all&lt;/i&gt; WAN connectivity for a few seconds.)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Split DNS on WRT Side of the Tunnel&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Let's say you have an internal DNS server on the RV side of the tunnel and you want all DNS lookups for the internal domain to be delegated to that DNS server but still have the WRT handle other (i.e. internet host) DNS lookups. The solution for this problem is to use a feature called &lt;i&gt;split dns&lt;/i&gt;.  Split DNS allows a DNS server to delegate lookups to another DNS server for certain domains.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;To enable this feature, you need to add a "server" setting to the file &lt;code&gt;/etc/dnsmasq.conf&lt;/code&gt; on the WRT (and, of course, you would need to restart dnsmasq). For example:&lt;/p&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;server=/internal.mydomain.com/192.168.1.145&lt;/pre&gt;&lt;br /&gt;&lt;code&gt;internal.mydomain.com&lt;/code&gt; is the domain that you want to split requests for to the internal DNS server across the VPN. 192.168.1.145 is the address of that DNS server.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Joining a Domain on WRT Side of the Tunnel&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Let's say you have an active directory domain controller on the RV side of the tunnel and you have a computer on the WRT side that you want to join to the domain.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;To join a domain across the VPN, you need to add a "srv-host" setting to the file /etc/dnsmasq.conf (and, of course, you would need to restart dnsmasq). For example:&lt;/p&gt;&lt;br /&gt;&lt;pre class="code-hs"&gt;srv-host=_ldap._tcp.dc._msdcs.internal.mydomain.com&lt;br /&gt;,mydomaincontroller.internal.mydomain.com,389,0,100&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;In this example, &lt;code&gt;mydomaincontroller.internal.mydomain.com&lt;/code&gt; is the name of the domain controller and &lt;code&gt;internal.mydomain.com&lt;/code&gt; is the domain. I'm not sure if this only works with active directory or if it also works with NT4 domains. I leave that as an exercise to the reader.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Links&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Following are some useful how-to and informational links about installing and running Openswan on a WRT54G. Note that &lt;i&gt;none&lt;/i&gt; of these links provide a &lt;i&gt;comprehensive&lt;/i&gt; how-to. I had to piece together information from all of these links to create this page.&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.openswan.org/"&gt;Openswan&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.mikemcarthur.net/article.php?story=20050408164917958"&gt;The VPN Follies (Part 1) - Terminating VPN Connections with Linux and other Stuff - Introduction&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.mikemcarthur.net/article.php?story=20050620172738374"&gt;VPN Follies Part 2 - Linux 2.4, OpenSWAN, and WRT54G&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://wiki.openwrt.org/IPSec?highlight=%28openswan%29#head-f82d76b0ef953ec148ffb5fc252f8551105601bb"&gt;IPSec on OpenWrt&lt;/a&gt; - from the &lt;a href="http://wiki.openwrt.org/"&gt;OpenWrt Wiki&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.die.net/doc/linux/man/man5/ipsec.conf.5.html"&gt;Openswan &lt;span class="searchword"&gt;ipsec.conf&lt;/span&gt; man page&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.die.net/doc/linux/man/man5/ipsec.secrets.5.html"&gt;Openswan ipsec.secrets man page&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.die.net/doc/linux/man/man5/resolv.conf.5.html"&gt;resolv.conf man page&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://thekelleys.org.uk/dnsmasq/docs/setup.html"&gt;dnsmasq setup&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://wiki.openswan.org/"&gt;Openswan wiki&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://wiki.openswan.org/index.php/Openswan/FAQ#a54"&gt;Can I use Network Neighborhood (Samba, NetBIOS) over IPsec?&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch35_:_Configuring_Linux_VPNs"&gt;Configuring Linux VPNs&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Addendum&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For some corrections and further information about this how-to, please see the following:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://joesbitbucket.blogspot.com/2007/03/virtual-visit-from-paul-wouters.html"&gt;A Virtual Visit from Paul Wouters&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-5004958474261254941?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/5004958474261254941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=5004958474261254941' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/5004958474261254941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/5004958474261254941'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2007/03/how-to-vpn-between-rv082-or-rv042-and.html' title='How To:  VPN Between RV082 (or RV042) and WRT54GL (or WRT54G)'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-69693686343340472</id><published>2007-01-10T13:17:00.001-08:00</published><updated>2009-12-03T13:44:59.878-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>How to Hide the Outlook Envelope Icon When You Get Spam</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2007/01/10/how-to-hide-the-outlook-envelope-icon-when-you-get-spam/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;In Outlook 2003, I have enabled the setting "show an envelope icon in the notification area".  With this setting enabled, whenever I get a new email, an envelope is displayed in the Windows system tray. I like this feature because it is less obtrusive and distracting than the methods of new email notification (e.g. Desktop Alerts, playing a sound, etc).&lt;br /&gt;&lt;br /&gt;The only problem with this setting is that, by default, the envelope icon gets displayed even when the new email is spam (i.e junk email).  This is a big problem for me because probably 90% of my email is spam and I actually lose a few minutes every day by switching to Outlook whenever the envelope icon appears, only to discover that the new mail is spam. It is so annoying!&lt;br /&gt;&lt;br /&gt;With prior versions of Outlook, this was a tricky problem to solve. My solution back then was to hack out a VBA script and hook it into Outlook with a rule. My code was based off this &lt;a href="http://www.outlookcode.com/d/code/clearenvicon.htm"&gt;example&lt;/a&gt;. It was a pain in the butt to create and install and sometimes it failed with non-descriptive error messages that said something like "rule failed".&lt;br /&gt;&lt;br /&gt;When I installed Outlook 2003 the other day, I noticed an email folder called "Junk E-Mail". When I saw that, it gave me hope for a better solution. So, I started reading about this new folder in Outlook 2003's help file. I read and I read and I read. To my chagrin, I found no relationship between the Junk E-Mail folder and the envelope icon in the help file.&lt;br /&gt;&lt;br /&gt;Undaunted, I thought I would try an experiment anyway because I thought there might be something magical about this new folder. After all, it can't be deleted like user-created folders.&lt;br /&gt;&lt;br /&gt;Before I tell you about my experiment, I'll give you some background information. At our office, we run Exchange 2003. However, we front this with a Spam Assassin server running on a Linux box. All incoming mail first goes through the Spam Assassin server, which detects spam and marks it by appending a special string (e.g. **THIS IS FRIGGING SPAM**) to the subject line before forwarding it on to Exchange.&lt;br /&gt;&lt;br /&gt;For my experiment, I created the following Outlook rule, using the rules wizard thingy:&lt;br /&gt;&lt;blockquote&gt;Apply this rule after the message arrives&lt;br /&gt;with **THIS IS FRIGGING SPAM** in the subject&lt;br /&gt;move it to the SPAM folder&lt;br /&gt;except if from {anyone in my office}&lt;br /&gt;or except if from {my wife}&lt;br /&gt;or except if from {etc, etc, etc}&lt;br /&gt;stop processing more rules&lt;/blockquote&gt;&lt;br /&gt;The SPAM folder shown in the above rule is a folder I had created. When spam arrived, it was correctly moved to the SPAM folder but the envelope icon still appeared, which is NOT what I wanted.&lt;br /&gt;&lt;br /&gt;Next, I edited the rule, changing the SPAM folder to the magical "Junk E-mail" folder. Voila! It worked! The next time I got a new spam message, the envelope icon did NOT appear.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;If this tip helped you, please leave me a comment!&lt;/b&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-69693686343340472?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/69693686343340472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=69693686343340472' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/69693686343340472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/69693686343340472'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2007/01/how-to-hide-outlook-envelope-icon-when.html' title='How to Hide the Outlook Envelope Icon When You Get Spam'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-6021645852448515953</id><published>2007-01-08T12:12:00.002-08:00</published><updated>2009-12-03T13:43:11.149-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenWrt'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>How to Force ez-ipupdate to Touch Dyndns Record Every Month</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2007/01/08/how-to-force-ez-ipupdate-to-touch-dyndns-record-every-month/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Like most home internet users, I have a dynamic IP address and I use &lt;a href="https://www.dyndns.com/"&gt;Dyndns&lt;/a&gt; to map it to a static host name so that I can remotely access my router (and computers behind it) without having to know its current IP address.&lt;br /&gt;&lt;br /&gt;My router is a LinkSys WRT54G, which is running the &lt;a href="http://openwrt.org/"&gt;OpenWrt&lt;/a&gt; custom firmware. OpenWrt comes with a package called &lt;a href="http://ez-ipupdate.com/"&gt;ez-ipupdate&lt;/a&gt;, which can be configured to automatically update your Dyndns host record whenever the router's address changes. For detailed instructions, see the &lt;a href="http://wiki.openwrt.org/DDNSHowTo"&gt;DDNSHowTo&lt;/a&gt; page in the OpenWrt wiki.&lt;br /&gt;&lt;br /&gt;The instructions in OpenWrt's wiki are pretty good but they don't deal with the situation where the time between address changes is greater than 30 days. This is a problem if you are using Dyndns's &lt;span style="font-style: italic;"&gt;free&lt;/span&gt; &lt;a href="http://www.dyndns.com/services/dns/dyndns/"&gt;Dynamic DNS service&lt;/a&gt;. The &lt;a href="http://www.dyndns.com/services/dns/dyndns/faq.html#q15"&gt;Dynamic DNS service FAQ&lt;/a&gt; states the you must periodically "touch" the host record, even if the address hasn't changed, or your host record will be deleted. Here is the policy as at the time of writing this blog post:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;A Dynamic DNS hostname only needs to be updated when your IP address has changed. Any updates more frequently than this - from the same IP address - will be considered abusive by the update system and may result in your hostname becoming blocked. Any script which runs periodically should check to make sure that the IP has actually changed before making an update, or the host will become blocked. An exception to this is for users with mostly static IP addresses; you may update 24-35 days after your previous update with the same IP address to "touch" the record and prevent it from expiring. Users will receive an e-mail notification if a host has been unchanged for 30 days, hosts are deleted after 35 days without being updated unless you've purchased upgrade credit(s).&lt;/blockquote&gt;&lt;br /&gt;Here is an example of the e-mail notification (i.e. "nag" email) that you get when you haven't touched the host record in 30 days:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;A hostname you have registered with Dynamic Network Services at DynDNS, SomeDynamicHostName.dyndns.org, with current IP address 192.168.1.1, will expire in the next 5 days. This expiration is due to an automatic timeout; your host has not been updated for 30 days, and hosts are removed after not being updated for 35 days.  This is our policy to prevent a stagnant DNS system.&lt;br /&gt;Users with static IP addresses can use the Static DNS system, which does not have this timeout.&lt;br /&gt;&lt;br /&gt;You can "touch" your hostname and prevent it from being deleted simply by performing a manual, or forced, update.  The system will not consider this&lt;br /&gt;single update abusive.    If you wish to allow your hostname to expire,&lt;br /&gt;simply do nothing.  You will receive a    notification when this occurs.&lt;br /&gt;&lt;br /&gt;You can also purchase an account upgrade credit at https://www.dyndns.com/+upgrades/add.html - users with any credits on their account are exempt from this expiration policy.&lt;br /&gt;&lt;br /&gt;https://www.dyndns.com/+dyndns/SomeDynamicHostName.dyndns.org is a direct URL to a page where you can manually update your hostname.  Simply submit the form (by clicking the "Modify Host" button), and your hostname will not expire unless it is left without updates for another 35 days.&lt;br /&gt;&lt;br /&gt;Please DO NOT contact the support department and ask to have your host updated.  Following the instructions above is the ONLY way to keep your host from being removed by our automated system.&lt;br /&gt;&lt;br /&gt;If you do not use your account any longer, please delete it using the tools at &lt;https:&gt;.  We regret seeing you go.&lt;br /&gt;&lt;br /&gt;Replies to this e-mail address will be discarded.  Please contact the support department at support@dyndns.com if you have questions, queries, or comments.&lt;br /&gt;&lt;br /&gt;Sincerely,&lt;br /&gt;The DynDNS Team&lt;/https:&gt;&lt;/blockquote&gt;&lt;br /&gt;To prevent the deletion of my host record, I created a cron job that touches the host record on the first day of each month. To create a cron job in OpenWrt, you must put a job definition in the file &lt;span style="font-family:courier new;"&gt;/etc/crontabs/root&lt;/span&gt;. Here is my job definition (must be all on one line):&lt;br /&gt;&lt;pre style="font-family: courier new;"&gt;&lt;blockquote&gt;1 0 1 * * rm -f /tmp/ez-ipupdate.cache&lt;br /&gt;; /usr/sbin/ez-ipupdate -c /etc/ez-ipupdate.conf&lt;br /&gt;&gt; /tmp/ez-ipupdate-cron.log 2&gt;&amp;1&lt;/blockquote&gt;&lt;/pre&gt;Note that without the first command, &lt;span style="font-family:courier new;"&gt;rm -f /tmp/ez-ipupdate.cache&lt;/span&gt;, ez-ipupdate will not touch the record at dyndns.org and will instead show the message "no update needed at this time". So, the first command it critical to force a "touch" of the record. Without the first command, the log file /tmp/ez-ipupdate-cron.log would show the following, which is NOT what we want:&lt;br /&gt;&lt;blockquote&gt;ez-ipupdate Version 3.0.11b8&lt;br /&gt;Copyright (C) 1998-2001 Angus Mackay&lt;br /&gt;no update needed at this time&lt;/blockquote&gt;With the first command, you should see this in the log file, which IS what we want:&lt;br /&gt;&lt;blockquote&gt;ez-ipupdate Version 3.0.11b8&lt;br /&gt;Copyright (C) 1998-2001 Angus Mackay&lt;br /&gt;connected to members.dyndns.org (63.208.196.95) on port 80&lt;br /&gt;members.dyndns.org says that your IP address has not changed since the last update&lt;/blockquote&gt;Even though it says "your IP address has not changed" it has still "touched" the record, which is what we want.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If this tip helped you, please leave me a comment!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update&lt;/span&gt;: Here is &lt;a href="http://joesbitbucket.blogspot.com/2007/06/stupid-cron-tricks.html"&gt;a better solution&lt;/a&gt;.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-6021645852448515953?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/6021645852448515953/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=6021645852448515953' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/6021645852448515953'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/6021645852448515953'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2007/01/how-to-force-ez-ipupdate-to-touch.html' title='How to Force ez-ipupdate to Touch Dyndns Record Every Month'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-9154368464008945874</id><published>2006-12-20T06:56:00.001-08:00</published><updated>2009-12-02T14:47:38.455-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Just the File Size Please</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/12/20/just-the-file-size-please/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Yesterday I wrote a custom log file rotator script in bash for one of my embedded Linux boxes (yes, I know about logrotate but this was a special situation that required a custom script).&lt;br /&gt;&lt;br /&gt;One of the building blocks I needed for this script was a function that could return the size of a file. The &lt;span style="font-family:courier new;"&gt;wc&lt;/span&gt; command seemed appropriate for this:&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;span style="font-family:courier new;"&gt;me@mycomputer:~$ wc -help&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Usage: wc [OPTION]... [FILE]...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Print newline, word, and byte counts for each FILE, and a total line if&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;more than one FILE is specified.  With no FILE, or when FILE is -,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;read standard input.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; -c, -bytes            print the byte counts&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; -m, -chars            print the character counts&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; -l, -lines            print the newline counts&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; -L, -max-line-length  print the length of the longest line&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; -w, -words            print the word counts&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     -help     display this help and exit&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     -version  output version information and exit&lt;/span&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;Yep, the &lt;span style="font-family:courier new;"&gt;-c&lt;/span&gt; option was the one that I wanted. Here is an example of retrieving the size of the file called &lt;span style="font-family:courier new;"&gt;foo&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;span style="font-family:courier new;"&gt;me@mycomputer:~$ wc -c foo&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1071 foo&lt;/span&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;The size of the file is 1071 bytes. But what's with the extra "foo" string? I didn't want that. I justed wanted the 1071. What's a boy to do? &lt;a href="http://en.wikipedia.org/wiki/Awk#AWK_versions_and_implementations"&gt;awk&lt;/a&gt; to the rescue. Awk is a general purpose programming language that is designed for processing text files and streams. For example, you can use it to parse data fields from text that is piped in from another command. Here is how I used &lt;span style="font-family:courier new;"&gt;awk&lt;/span&gt; to parse just the file size from the output of &lt;span style="font-family:courier new;"&gt;wc&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;span style="font-family:courier new;"&gt;me@mycomputer:~$ wc -c foo | awk '{print $1}'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1071&lt;/span&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;I hope this helps someone else. If you have a better way of getting just the file size, please leave a comment.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;b&gt;UPDATE&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here is an easier (and better performing?) way of getting just the file size:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;stat -c%s filename&lt;/span&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-9154368464008945874?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/9154368464008945874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=9154368464008945874' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/9154368464008945874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/9154368464008945874'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/12/just-file-size-please.html' title='Just the File Size Please'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-8413175379387659497</id><published>2006-12-19T06:32:00.001-08:00</published><updated>2009-12-02T14:44:50.406-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenWrt'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Accessing Windows Shares Across a VPN</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/12/19/accessing-windows-shares-across-a-vpn/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Just for laughs, I recently created a point-to-point VPN (a.k.a. gateway-to-gateway VPN) between my home and the office. At the office, the VPN endpoint is a LinkSys RV042, which, as far as I can tell, runs Freeswan VPN software. At home, the VPN endpoint is a LinkSys WRT54GL, which I hacked to run the OpenWrt linux distribution and OpenSwan VPN software. A future post will detail exactly how I did this but the purpose of this post is to discuss how I got my Windows file shares to work across the VPN.&lt;br /&gt;&lt;br /&gt;When I first setup the VPN, I initially joined my home Windows XP Pro computer to the Active Directory domain at the office. That made it easy to share files back and forth. However, I didn't like that other domain admins could have full access to my home computer. Therefore, I unjoined my home computer and reverted it back to workgroup mode.&lt;br /&gt;&lt;br /&gt;After reverting back to workgroup mode, I could still access shares on office computers. Upon accessing a share on my office computer, I would be prompted to enter a username and password. I this case, I entered my domain username and password. I can't remember if I put in the short username (e.g. myusername) or the fully qualified username (e.g. mydomainname\myusername) but the point is that it worked.&lt;br /&gt;&lt;br /&gt;On the other hand, I couldn't access any home shares from the office. Upon attempting access, I would either get an "access denied" error or a "credentials supplied conflict with an existing set of credentials" error.&lt;br /&gt;&lt;br /&gt;The problem is, when you access a workgroup share from a domain computer, Windows assumes you want to login with your domain username and password and it doesn't prompt you to enter your workgroup username and password. Since my domain username and password are different from my workgroup username and password, I couldn't be authenticated and access was denied.&lt;br /&gt;&lt;br /&gt;The solution was to set up a username and password on my home computer that was identical to my domain username and password. This solution works fine but the only problem is that the new user appears on the Windows XP Welcome Screen. Thankfully, there is a way to hide users from the Welcome Screen:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Open the Registry Editor (i.e. run regedit).&lt;/li&gt;&lt;li&gt;Navigate to the following registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList&lt;/li&gt;&lt;li&gt;Create a DWORD value where the name is the username of the user you want to hide from the Welcome Screen. For example, "myusername".&lt;/li&gt;&lt;li&gt;Set the value of the new registry entry to 0 (it should default to this value automatically).&lt;/li&gt;&lt;li&gt;Close the Registry Editor.&lt;/li&gt;&lt;li&gt;You might have to reboot but I didn't have to.&lt;/li&gt;&lt;/ol&gt;You might be wondering how I accessed computers at the remote end of the VPN using Windows Explorer. Well, there are a few options. One way is to enable NetBios over TCP. If you do that, you should be able to automically see the computer names in "My Network Places". I didn't use that method but if you want to try it, see &lt;a href="http://wiki.openswan.org/index.php/Openswan/FAQ#a54"&gt;Can I use Network Neighborhood (Samba, NetBIOS) over IPsec?&lt;/a&gt; in the &lt;a href="http://wiki.openswan.org/index.php/Openswan/FAQ"&gt;Openswan FAQ&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Another method is to register computers at both ends of the VPN with a DNS server at the office. If you do that, you should be able to enter "\\somecomputer" into Windows Explorer's location bar to see a list of shares on a remote computer. I tried that and it worked great. In my case, I found dnsmasq's "split DNS" feature to be particularly useful. For now, I'll leave it as an exercise to the reader to find out more about this feature but for a hint, read about the "server" setting for the file "dnsmasq.conf" in the &lt;a href="http://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html"&gt;dnsmasq manpage&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Finally, you can also access the remote computers by IP address. In this case, enter "\\&lt;span style="font-style: italic;"&gt;someaddress&lt;/span&gt;" (e.g. \\192.168.1.10) into Windows Explorer's location bar.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-8413175379387659497?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/8413175379387659497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=8413175379387659497' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/8413175379387659497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/8413175379387659497'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/12/accessing-windows-shares-across-vpn.html' title='Accessing Windows Shares Across a VPN'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-3392694947471846225</id><published>2006-12-15T14:30:00.001-08:00</published><updated>2009-12-02T14:42:32.037-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Arp Tip</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/12/15/arp-tip/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;I finally used Windows' &lt;span style="font-family:courier new;"&gt;arp&lt;/span&gt; command for something useful.&lt;br /&gt;&lt;br /&gt;Last week I was configuring numerous brand new LinkSys routers for various branch offices. After successfully configuring the first one, I plugged in the second and tried to connect to it's web admin page. Unfortunately, my connection attempt kept on timing out. After a couple of minutes of pulling my hair out, I remembered something I had learned about in school a few years ago: &lt;a href="http://en.wikipedia.org/wiki/Address_Resolution_Protocol"&gt;Address Resolution Protocol&lt;/a&gt; or ARP for short.&lt;br /&gt;&lt;br /&gt;ARP is a protocol for determining a host's hardware address given its network address. In the common case of TCP/IP-over-ethernet networks, the hardware address is known as the &lt;a href="http://en.wikipedia.org/wiki/MAC_address"&gt;MAC address&lt;/a&gt; and the network address is known as the &lt;a href="http://en.wikipedia.org/wiki/Ip_address"&gt;IP address&lt;/a&gt;. This protocol is important because a host's hardware address must be known before you can communicate with it over a network.&lt;br /&gt;&lt;br /&gt;If you're familiar with LinkSys routers, you'll know that they all have the default IP address of 192.168.1.1. On the other hand, every networked device (including LinkSys routers) has (or should have) a unique MAC address. For example, I had two routers with MAC addresses of 00-00-24-c5-94-f4 and 00-00-24-c6-66-84 respectively.&lt;br /&gt;&lt;br /&gt;When I plugged the first one in and tried to connect to http://192.168.1.1, Windows silently used ARP to translate the IP address 192.168.1.1 into the MAC address 00-00-24-c5-94-f4. This worked without a hitch and I was able to configure the router.&lt;br /&gt;&lt;br /&gt;The problem arose when I plugged in the second router. Apparently, Windows (and perhaps other operating systems) caches the IP-address-to-MAC-address for a period of time. When I tried to connect to  http://192.168.1.1, Windows looked that IP address in its arp cache and found the MAC address of 00-00-24-c5-94-f4. However, the MAC address it really needed to use was 00-00-24-c6-66-84.&lt;br /&gt;&lt;br /&gt;How long does Windows cache these arp mappings and how do you delete the cache? The &lt;a href="http://technet2.microsoft.com/WindowsServer/en/library/cae0e239-267b-45df-88a8-f6f1303830471033.mspx?mfr=true"&gt;answers&lt;/a&gt; can be found on Microsoft's TechNet. According to TechNet:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Dynamic ARP cache entries - These entries are added and deleted automatically during normal use of TCP/IP sessions with remote computers. Dynamic entries age and expire from the cache if not reused within 2 minutes. If a dynamic entry is reused within 2 minutes, it may remain in the cache and age up to a maximum cache life of 10 minutes before being removed or requiring cache renewal by using the ARP broadcast process.&lt;/blockquote&gt;To view the current contents of the ARP cache, go to a command prompt and run &lt;span style="font-family:courier new;"&gt;arp -a&lt;/span&gt;. To delete the entire cache, run &lt;span style="font-family:courier new;"&gt;arp -d&lt;/span&gt;. To delete only a particular mapping, run &lt;span style="font-family:courier new;"&gt;arp -d &lt;ip&gt;&lt;/ip&gt;&lt;/span&gt; (for example, &lt;span style="font-family:courier new;"&gt;arp -d 192.168.1.1&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;Here is an example session to show you what I'm talking about. Note that ping fails (i.e. times out) if you have an incorrect IP-address-to-MAC-address mapping:&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\&amp;gt; arp -a&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Interface: 192.168.1.25 on Interface 0x9000006&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Internet Address      Physical Address      Type&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;192.168.1.1            00-00-24-c5-94-f4     dynamic&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\&amp;gt; ping 192.168.1.1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Pinging 192.168.1.1 with 32 bytes of data:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Reply from 192.168.1.1: bytes=32 time&amp;lt; 10ms TTL=64&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Reply from 192.168.1.1: bytes=32 time&amp;lt; 10ms TTL=64&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Reply from 192.168.1.1: bytes=32 time&amp;lt; 10ms TTL=64&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Reply from 192.168.1.1: bytes=32 time&amp;lt; 10ms TTL=64&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Ping statistics for 192.168.1.1:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Approximate round trip times in milli-seconds:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  Minimum = 0ms, Maximum =  0ms, Average =  0ms&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-family: courier new;"&gt;(AT THIS POINT, I PLUGGED IN THE OTHER ROUTER)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\&amp;gt; ping 192.168.1.1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Pinging 192.168.1.1 with 32 bytes of data:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Request timed out.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Request timed out.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Request timed out.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Request timed out.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Ping statistics for 192.168.1.1:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Approximate round trip times in milli-seconds:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  Minimum = 0ms, Maximum =  0ms, Average =  0ms&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\&amp;gt; arp -a&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Interface: 192.168.1.25 on Interface 0x9000006&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Internet Address      Physical Address      Type&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;192.168.1.1            00-00-24-c5-94-f4     dynamic&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\&amp;gt; arp -d 192.168.1.1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\&amp;gt; ping 192.168.1.1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Pinging 192.168.1.1 with 32 bytes of data:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Reply from 192.168.1.1: bytes=32 time=1ms TTL=64&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Reply from 192.168.1.1: bytes=32 time&amp;lt; 10ms TTL=64&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Reply from 192.168.1.1: bytes=32 time&amp;lt; 10ms TTL=64&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Reply from 192.168.1.1: bytes=32 time&amp;lt; 10ms TTL=64&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Ping statistics for 192.168.1.1:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Approximate round trip times in milli-seconds:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;  Minimum = 0ms, Maximum =  1ms, Average =  0ms&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\&amp;gt; arp -a&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Interface: 192.168.1.25 on Interface 0x9000006&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Internet Address      Physical Address      Type&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;192.168.1.1            00-00-24-c6-66-84     dynamic&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;C:\&amp;gt;&lt;/span&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-3392694947471846225?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/3392694947471846225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=3392694947471846225' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/3392694947471846225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/3392694947471846225'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/12/arp-tip.html' title='Arp Tip'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-4804296303204735817</id><published>2006-11-24T13:07:00.001-08:00</published><updated>2009-12-02T14:39:34.032-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>How to Clear syslog Log Files in Linux</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/11/24/how-to-clear-syslog-log-files-in-linux/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Many Linux distributions are preconfigured to automatically and periodically rotate &lt;span style="font-family:courier new;"&gt;syslog&lt;/span&gt; log files by means of &lt;span style="font-family:courier new;"&gt;cron&lt;/span&gt; jobs that call &lt;span style="font-family:courier new;"&gt;logrotate&lt;/span&gt; or a similar log rotation script. However, if you want to clear a log file manually, you can simply use the greater than sign followed by the log file name. For example, to manually clear the file &lt;span style="font-family:courier new;"&gt;kern.log&lt;/span&gt;, you can run this command:&lt;br /&gt;&lt;blockquote&gt;me@mycomputer:&gt; /var/log/kern.log&lt;/blockquote&gt;&lt;br /&gt;The beauty of this is that the cleared out file still retains its original permissions and ownership.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-4804296303204735817?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/4804296303204735817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=4804296303204735817' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/4804296303204735817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/4804296303204735817'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/11/how-to-clear-syslog-log-files-in-linux.html' title='How to Clear syslog Log Files in Linux'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-8129298630601032917</id><published>2006-11-17T06:09:00.000-08:00</published><updated>2007-03-07T12:05:05.803-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenWrt'/><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>VPN Between RV082 (or RV042) and WRT54GL (or WRT54G)</title><content type='html'>Great news! I have managed to get a site-to-site (a.k.a. gateway-to-gateway) VPN working between a LinkSys RV082 and a LinkSys WRT54GL running OpenWrt! It should also be possible to use similar hardware like the RV042, RV016, WRT54G, WRT54GS, etc.&lt;br /&gt;&lt;br /&gt;The full how-to is &lt;a href="http://joesbitbucket.blogspot.com/2007/03/how-to-vpn-between-rv082-or-rv042-and.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-8129298630601032917?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/8129298630601032917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=8129298630601032917' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/8129298630601032917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/8129298630601032917'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/11/vpn-between-rv082-or-rv042-and-wrt54gl.html' title='VPN Between RV082 (or RV042) and WRT54GL (or WRT54G)'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-2944964027231135756</id><published>2006-10-19T12:33:00.001-07:00</published><updated>2009-12-02T14:37:30.851-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Displaying Masqueraded Connections</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/10/19/displaying-masqueraded-connections/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;I often use Linux's &lt;span style="font-family:courier new;"&gt;netstat&lt;/span&gt; command to do things like figuring out which ports are listening on a computer and what are the active connections on a computer. It's very handy for troubleshooting networking problems.&lt;br /&gt;&lt;br /&gt;Today I wanted to figure out what sites a certain user on my network was connecting to and how much traffic the user was using. I connected to the router with SSH and ran &lt;span style="font-family:courier new;"&gt;netstat&lt;/span&gt; with no options. I was surprised to see only my SSH connection. Then I remembered that the user in question gets onto the internet with a masqueraded address. Well, duh!&lt;br /&gt;&lt;br /&gt;I figured &lt;span style="font-family:courier new;"&gt;netstat&lt;/span&gt; was still the command that I needed to use but that I just needed to pass some option. So, I looked at the man page for &lt;span style="font-family:courier new;"&gt;netstat&lt;/span&gt; and sure enough I found the &lt;span style="font-family:courier new;"&gt;-M&lt;/span&gt; option, whose description is "Display a list of masqueraded connections."&lt;br /&gt;&lt;br /&gt;I tried &lt;span style="font-family:courier new;"&gt;netstat -M&lt;/span&gt; and got the following error message: "netstat: no support for `ip_masquerade' on this system."&lt;br /&gt;&lt;br /&gt;That sucks! After some googling, I found out that &lt;span style="font-family:courier new;"&gt;netstat -M&lt;/span&gt; only works on pre-2.4 kernels. On 2.4 and later kernels, you need to use this: &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;blockquote&gt;cat /proc/net/ip_conntrack&lt;/blockquote&gt;&lt;/span&gt;The format of ip_conntrack is kind of cryptic but if you look at it for a few moments, you can figure it out. You can also use &lt;span style="font-family:courier new;"&gt;grep&lt;/span&gt; to filter out the stuff you don't need. For example, to see only the connections involving a particular address, say 192.168.1.10, you can do this: &lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;blockquote&gt;cat /proc/net/ip_conntrack | grep 192.168.1.10&lt;/blockquote&gt;&lt;/span&gt;Apparently, there is a command out there that can nicely format the contents of ip_conntrack. It's called &lt;a href="http://cv.intellos.net/"&gt;conntrack viewer&lt;/a&gt;. Unfortunately, I couldn't connect to that site today. Perhaps the link is dead.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-2944964027231135756?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/2944964027231135756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=2944964027231135756' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/2944964027231135756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/2944964027231135756'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/10/displaying-masqueraded-connections.html' title='Displaying Masqueraded Connections'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-5440916516650241598</id><published>2006-10-11T13:23:00.001-07:00</published><updated>2009-12-02T14:35:30.496-08:00</updated><title type='text'>How to Kill Outlook Before Backing Up Your PST file</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/10/11/how-to-kill-outlook-before-backing-up-your-pst-file/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;I use &lt;a href="http://www.educ.umu.se/%7Ecobian/cobianbackup.htm"&gt;Cobian Backup&lt;/a&gt; to automatically backup my Outlook mail file (i.e. PST file) as well as other types of files. There is a catch with backing up PST files with Cobian Backup: Outlook cannot be running. If Outlook is running, Cobian will not backup the PST file because it will be locked by Outlook.&lt;br /&gt;&lt;br /&gt;Luckily, Cobian has a feature called "events", which can be used to run arbitrary tasks before and/or after a backup job. I use this feature to kill Outlook before running my backup job, which removes the file lock and allows Cobian to backup the PST file.&lt;br /&gt;&lt;br /&gt;If you want to use this feature to kill Outlook, the first step is to create a batch file that can kill Outlook from the command line. I called my batch file "kill_outlook.bat". Here are the contents:&lt;br /&gt;&lt;blockquote&gt;taskkill /f /im outlook.exe&lt;/blockquote&gt;The &lt;i&gt;taskkill&lt;/i&gt; command is available on Windows XP Pro and, I believe, also Windows XP Home and Windows Server 2003. On Windows 2000, instead of &lt;i&gt;taskkill&lt;/i&gt;, you need to use &lt;i&gt;kill&lt;/i&gt;, which is not included on the Windows 2000 install disk. To get &lt;i&gt;kill&lt;/i&gt;, you must install the &lt;a href="http://www.microsoft.com/windows2000/downloads/servicepacks/sp4/supporttools.mspx"&gt;Windows 2000 Support Tools&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;After you make the batch file and test it, you need to configure a "before backup" event in Cobian. Open your backup job configuration and go to the Events tab. Under the "Before Backup" box, press the "Add" button and click "Execute and wait" on the popup menu. In the file browser dialog that appears, browse to and select the batch file you just created. Then click OK. Finally, click OK on the job properties dialog and you are done!&lt;br /&gt;&lt;br /&gt;Good luck!&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-5440916516650241598?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/5440916516650241598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=5440916516650241598' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/5440916516650241598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/5440916516650241598'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/10/how-to-kill-outlook-before-backing-up.html' title='How to Kill Outlook Before Backing Up Your PST file'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-3309358120998842558</id><published>2006-10-11T06:11:00.001-07:00</published><updated>2009-12-02T14:32:41.506-08:00</updated><title type='text'>Linux traceroute vs Windows tracert</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/10/11/linux-traceroute-vs-windows-tracert/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Anyone who has used Linux &lt;i&gt;traceroute&lt;/i&gt; and Windows &lt;i&gt;tracert&lt;/i&gt; knows that the two programs have very different command line options. But did you know that there is a fundamental difference in the way that these two programs work?&lt;br /&gt;&lt;br /&gt;According to &lt;a href="http://www.faqs.org/rfcs/rfc1393.html"&gt;RFC1393&lt;/a&gt;, traceroute implementations are supposed to use the ICMP protocol. Indeed, the windows implementation does use ICMP. However, by default, the Linux implementation uses UDP, unless you apply the "-I" option, in which case it will use ICMP.&lt;br /&gt;&lt;br /&gt;I googled to find out why Linux traceroute uses UDP by default but I couldn't find any definitive reasons. In practice, I've found that there is no real performance benefit; both the UDP flavour and the ICMP flavour seem to take about the same amount of time to do their work.&lt;br /&gt;&lt;br /&gt;I guess the real advantage of being able to choose between the UDP and ICMP flavours is that if a firewall along the route is configured to block ICMP, you can try UDP. Similarly, if a firewall blocks UDP you can try ICMP.&lt;br /&gt;&lt;br /&gt;If want to allow someone to traceroute &lt;span style="font-style: italic;"&gt;your&lt;/span&gt; internet host, you need to configure your firewall to allow it. For ICMP, you must accept (i.e. iptables -j ACCEPT) ICMP packets of type 0 (Echo Reply), 8 (Echo) and 30 (Traceroute).&lt;br /&gt;&lt;br /&gt;The UDP firewall configuration is slightly different. For UDP, you must &lt;i&gt;not&lt;/i&gt; drop (i.e. iptables -j DROP) UDP packets in the destination port range of 33434 to 33600. Note that you do &lt;i&gt;not&lt;/i&gt; have open these ports (i.e. iptables -j ACCEPT). It is sufficient to simply reject (i.e. iptables -j REJECT) on these ports. Just don't use "iptables -j DROP", which will cause the UDP flavour of traceroute to fail. Note that there is &lt;i&gt;no&lt;/i&gt; traceroute service for these ports (i.e. you don't have to run any sort of traceroute server/daemon); indeed, for traceroute's "-p" option, the man page says:&lt;br /&gt;&lt;blockquote&gt;Set the base UDP port number used in probes (default is 33434). Traceroute hopes that nothing is listening on UDP ports base to base + nhops - 1 at the destination host (so an ICMP PORT_UNREACHABLE message will be returned to terminate the route tracing). If something is listening on a port in the default range, this option can be used to pick an unused port range.&lt;/blockquote&gt;&lt;br /&gt;Good luck and happy tracerouting!&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-3309358120998842558?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/3309358120998842558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=3309358120998842558' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/3309358120998842558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/3309358120998842558'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/10/linux-traceroute-vs-windows-tracert.html' title='Linux traceroute vs Windows tracert'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-1177390413736733706</id><published>2006-10-06T12:50:00.001-07:00</published><updated>2009-12-02T14:30:48.510-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>How to Sort Files By Modification Time in ls</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/10/06/how-to-sort-files-by-modification-time-in-ls/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;To sort files by modification time when using &lt;span style="font-family: courier new;"&gt;ls&lt;/span&gt;, use the &lt;span style="font-family: courier new;"&gt;-t&lt;/span&gt; option. For example, to sort in descending order:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;[me@mycomputer usr]$ ls -lt&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;total 224&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x   88 root root 65536 Sep  1 17:39 lib&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x   14 root root  4096 Sep  1 16:00 local&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    2 root root 12288 Jul 26 04:04 sbin&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x  174 root root  4096 Jul 25 19:01 share&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    2 root root 40960 Jan 25  2006 bin&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    7 root root  4096 Jan 16  2006 libexec&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    3 root root  4096 Oct 16  2005 java&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x   61 root root 12288 Mar 13  2005 include&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    4 root root  4096 Mar 13  2005 src&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;lrwxrwxrwx    1 root root    10 Mar 13  2005 tmp -&gt; ../var/tmp&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    6 root root  4096 Feb 27  2005 kerberos&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    2 root root  4096 Feb 22  2005 etc&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    2 root root  4096 Feb 22  2005 games&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    7 root root  4096 Feb 21  2005 X11R6&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To sort in descending order,  add the &lt;span style="font-family: courier new;"&gt;-r&lt;/span&gt; option:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;[me@mycomputer usr]$ ls -ltr&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;total 224&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    7 root root  4096 Feb 21  2005 X11R6&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    2 root root  4096 Feb 22  2005 games&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    2 root root  4096 Feb 22  2005 etc&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    6 root root  4096 Feb 27  2005 kerberos&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;lrwxrwxrwx    1 root root    10 Mar 13  2005 tmp -&gt; ../var/tmp&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    4 root root  4096 Mar 13  2005 src&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x   61 root root 12288 Mar 13  2005 include&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    3 root root  4096 Oct 16  2005 java&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    7 root root  4096 Jan 16  2006 libexec&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    2 root root 40960 Jan 25  2006 bin&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x  174 root root  4096 Jul 25 19:01 share&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x    2 root root 12288 Jul 26 04:04 sbin&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x   14 root root  4096 Sep  1 16:00 local&lt;/span&gt;&lt;br /&gt; &lt;span style="font-family: courier new;"&gt;drwxr-xr-x   88 root root 65536 Sep  1 17:39 lib&lt;/span&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-1177390413736733706?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/1177390413736733706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=1177390413736733706' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/1177390413736733706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/1177390413736733706'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/10/how-to-sort-files-by-modification-time.html' title='How to Sort Files By Modification Time in ls'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-6012748058457723990</id><published>2006-10-06T12:36:00.001-07:00</published><updated>2009-12-02T14:28:34.548-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>How to Add a User to a Group in Linux</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/10/06/how-to-add-a-user-to-a-group-in-linux/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Today I had to add an existing user to an existing group in Linux. It's been so long since the last time I did it that I had actually forgotten how to do it. Well, good ol' man pages to the rescue. Here's how to do it:&lt;br /&gt;&lt;blockquote&gt;adduser &lt;span style="font-style: italic;"&gt;user&lt;/span&gt; &lt;span style="font-style: italic;"&gt;group&lt;/span&gt;&lt;/blockquote&gt;If you want to verify that it worked, use grep:&lt;br /&gt;&lt;blockquote&gt;grep &lt;span style="font-style: italic;"&gt;group&lt;/span&gt; /etc/group&lt;/blockquote&gt;In grep's output, you should see the user's name. For example:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;group&lt;/span&gt;:!:50:tom,dick,harry,&lt;span style="font-style: italic;"&gt;user&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;Enjoy!&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-6012748058457723990?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/6012748058457723990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=6012748058457723990' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/6012748058457723990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/6012748058457723990'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/10/add-user-to-group-in-linux.html' title='How to Add a User to a Group in Linux'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-115990442674662958</id><published>2006-10-03T11:54:00.001-07:00</published><updated>2009-12-02T14:25:54.959-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenWrt'/><title type='text'>Disabling Password Authentication on Dropbear SSH Server in OpenWrt Running on WRT54G</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/10/03/disabling-password-authentication-on-dropbear-ssh-server-in-openwrt-running-on-wrt54g/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;I have a LinkSys WRT54G router which runs &lt;a href="http://openwrt.org/"&gt;OpenWrt&lt;/a&gt; (version White Russian RC5). For console access to the router, I  have enabled the Dropbear SSH server, which works well.&lt;br /&gt;&lt;br /&gt;Recently, I opened up the SSH port to allow remote access to the console. To secure this as best I could, I disabled password authentication and enabled public key authentication, by following the instructions in the &lt;a href="http://wiki.openwrt.org/DropbearPublicKeyAuthenticationHowto"&gt;Dropbear Public Key Authentication Howto&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;After doing disabling password authentication, I thought to myself "What if I lose my private key?" The answer is "I'm probably screwed", because there is no serial port on the WRT54G for local access. (Actually, there are some &lt;a href="http://wiki.openwrt.org/OpenWrtDocs/Customizing/Hardware/Serial_Console"&gt;hardware mods&lt;/a&gt; you can do to add a serial port but I'm not that handy or brave).&lt;br /&gt;&lt;br /&gt;So I thought to myself "Would't it be great if you could configure Dropbear to disallow password authentication for remote connections but allow it for local connections?"&lt;br /&gt;&lt;br /&gt;I thought, perhaps, that Dropbear might have an option for this. Here are the command-line options for Dropbear 0.48:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-b bannerfile&lt;/span&gt; = Display the contents of bannerfile before user login (default: none)&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-d dsskeyfile&lt;/span&gt; = Use dsskeyfile for the dss host key (default: /etc/dropbear/dropbear_dss_host_key)&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-r rsakeyfile&lt;/span&gt; = Use rsakeyfile for the rsa host key (default: /etc/dropbear/dropbear_rsa_host_key)&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-F&lt;/span&gt; = Don't fork into background&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-E&lt;/span&gt; = Log to stderr rather than syslog&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-m&lt;/span&gt; = Don't display the motd on login&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-w&lt;/span&gt; = Disallow root logins&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-s&lt;/span&gt; = Disable password logins&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-g&lt;/span&gt; = Disable password logins for root&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-j&lt;/span&gt; = Disable local port forwarding&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-k&lt;/span&gt; = Disable remote port forwarding&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-a&lt;/span&gt; = Allow connections to forwarded ports from any host&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-p port&lt;/span&gt; = Listen on specified tcp port, up to 10 can be specified (default 22 if none specified)&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;-i&lt;/span&gt; = Start for inetd&lt;/li&gt;&lt;/ul&gt;As shown above, the &lt;i&gt;-s&lt;/i&gt; option can be used to disallow password authentication (thereby forcing public key authentication). However, I can't see an option that would do &lt;i&gt;exactly&lt;/i&gt; what I wanted (i.e. disable password authentication for remote connections but still allow password authentication for local connections).&lt;br /&gt;&lt;br /&gt;After thinking about the problem for a few minutes, I realized that I could solve the problem by starting &lt;i&gt;two&lt;/i&gt; instances of the Dropbear daemon. The only thing you have to do is make a small change to /etc/init.d/S50dropbear.&lt;br /&gt;&lt;br /&gt;Here is the last line from the stock version of that file in White Russian RC5:&lt;br /&gt;&lt;pre&gt;/usr/sbin/dropbear&lt;br /&gt;&lt;/pre&gt;What we want to do is change that file so that we start a second instance of dropbear that disallows password authentication. Here is the last line, plus a new line that starts the second instance:&lt;br /&gt;&lt;pre&gt;# failsafe for local access - port 22, pw auth allowed&lt;br /&gt;/usr/sbin/dropbear&lt;br /&gt;&lt;br /&gt;# secure for remote access - port 50022, pw auth not allowed&lt;br /&gt;/usr/sbin/dropbear -s -p 50022&lt;br /&gt;&lt;/pre&gt;The line new line &lt;i&gt;/usr/sbin/dropbear -s -p 50022&lt;/i&gt; starts a second instance of dropbear that disallows password authentication. Note that it starts the second instance on port 50022 instead of the default port 22; you can use another unused port number instead, if you so desire.&lt;br /&gt;&lt;br /&gt;After making those changes you will have to reboot the router.&lt;br /&gt;&lt;br /&gt;Next, you have to allow remote access to port 50022 and disallow remote access to port 22. If you are running the WRT54G on a LAN, behind an internet-facing router, just port forward from some port on the internet-facing router to port 50022 on the WRT54G. Do NOT port forward to port 22.&lt;br /&gt;&lt;br /&gt;If you are running WRT54G as your internet-facing router, open port 50022 on the firewall on the WAN side. Do NOT open port 22 on the WAN side (by default, it should already be open on the LAN side).&lt;br /&gt;&lt;br /&gt;The only downside I can see with my "second instance strategy" is slightly higher memory usage. Hopefully, in later releases of OpenWrt, you'll be able to use the web admin interface (webif) to disable/enable password authentication so that you can run just one instance of Dropbear.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-115990442674662958?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/115990442674662958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=115990442674662958' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115990442674662958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115990442674662958'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/10/disabling-password-authentication-on.html' title='Disabling Password Authentication on Dropbear SSH Server in OpenWrt Running on WRT54G'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-115973661852397064</id><published>2006-10-01T13:52:00.001-07:00</published><updated>2009-12-02T14:23:05.636-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='QuickBooks'/><title type='text'>QuickBooks Help - Page Cannot Be Displayed</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/10/01/quickbooks-help-page-cannot-be-displayed/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;I installed QuickBooks Pro 2006 yesterday. When I tried to access the help files, I got the error: "Page Cannot Be Displayed".&lt;br /&gt;&lt;br /&gt;I found lots of suggested solutions in Google. I tried many of them one-by-one and they did not work. Then I started trying them in combination. Finally, it worked. However, I'm not sure &lt;span style="font-style: italic;"&gt;which&lt;/span&gt; combination did the trick. If you are having the same problem, please try the various tips on the page &lt;a href="http://www.nik.com.au/archives/2005/04/06/chm-help-files-error-the-page-cannot-be-displayed/"&gt;CHM help files error: The page cannot be displayed.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I think this tip is important:&lt;br /&gt;&lt;blockquote&gt;regsvr32 hhctrl.ocx&lt;/blockquote&gt;But you &lt;span style="font-style: italic;"&gt;might &lt;/span&gt;have to create the MaxAllowedZone registry key first (see above link).&lt;br /&gt;&lt;br /&gt;Again, I'm not sure exactly which combination did the trick. Just keep trying all of the suggestions on that page (perhaps in various orders) until it is fixed. Then post a comment back here, describing what worked for you.&lt;br /&gt;&lt;br /&gt;BTW, Intuit's knowledge base sucks shit! It should have the solution for this problem, which seems to be a common one, judging from the number of posts about it in the QuickBooks forums.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-115973661852397064?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/115973661852397064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=115973661852397064' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115973661852397064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115973661852397064'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/10/quickbooks-help-page-cannot-be.html' title='QuickBooks Help - Page Cannot Be Displayed'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-115966172564157966</id><published>2006-09-30T17:03:00.002-07:00</published><updated>2009-12-02T14:20:39.568-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='QuickBooks'/><title type='text'>QuickBooks Pro 2006 - Shitty Out of Box Experience</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/09/30/quickbooks-pro-2006-shitty-out-of-box-experience/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;I just installed QuickBooks Pro 2006. The installation went okay but when I tried to start QuickBooks for the first time, I ran into problems. The splash screen came on for about a half a second and then the program closed. I tried it again and then same thing happened.&lt;br /&gt;&lt;br /&gt;I figured if Intuit was a typical software company, they would have put some error message into a log file. Sure enough, I found a log file at "C:\Program Files\Intuit\QuickBooks Pro\QBWIN.log". Inside the log I found several "missing module" messages:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt; =================== COMRegAll ===================&lt;br /&gt;Sat Sep 30 16:42:37 2006&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Missing module: 'C:\WINDOWS\system32\mfco42d.dll'&lt;br /&gt;Missing module: 'C:\WINDOWS\system32\msvcirtd.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\addinmgr2.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qfill.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbwps.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\COMObjectFactory.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\GraphSeriesCol.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\cominifile.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\ViewSrcColumns.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBCtrCustHighlights.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBCtrUnpaidBills.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBCtrVendPayHist.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbcscbvw.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\CtrViewGraph.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\ctrviewtable.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbctripmds.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\ctrviewhtml.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\customercontact.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\openbalbycustjob.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Intuit\QuickBooks Pro\excelpayrolldatasource.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbctraddin.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbctrcustinvsummary.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbctrcustpaysummary.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbctropenpobycust.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbctropenpovendor.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbctrprofitloss.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbctrqview.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBCtrTenLstProfCust.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBCtrTenMostProfCust.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBCtrUnbillTimeCost.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\storageclasses.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\TenLeastProfitJob.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\TenMostProfitJob.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\vendorcontact.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbctrcashpos.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\ComEvtBroadcaster.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\Qbctrspacer.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\Qbctrtitle.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBInstanceFinder.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\viewsource.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBCtrItemProfit.DLL'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBCtrTenMostProfSvcs.DLL'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBCtrTenLstProfSvcs.DLL'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\OverdueBalance.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Intuit\QuickBooks Pro\CookieMonster.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\AXLBridge.exe'&lt;br /&gt;Missing module: 'C:\Program Files\Intuit\QuickBooks Pro\QBXLAdin.DLL'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\CtrViewToolTip.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\tcmaddin.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBCtrTRDS.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\CoLocator2.DLL'&lt;br /&gt;Missing module: 'C:\Program Files\Intuit\QuickBooks Pro\ECredit.DLL'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\bbfdepcalc.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBDTView.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBDTRatios.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBXMLRP2.DLL'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\sdksubscription.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\qbsdkcomutil.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\sdkparse.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBUpdate\QBUServiceMgr.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBUpdate\QBUpdate.exe'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBUpdate\QBMsgMgr.exe'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBUpdate\QBMsgRequestMgr.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBUpdate\QBOneStepUpdate.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\QBUpdate\QBUpdateCtrl.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\AnswerWorks 4.0\AWAPI4.DLL'&lt;br /&gt;Missing module: 'C:\Program Files\Intuit\QuickBooks Pro\components\HR\bin\HROrganizer.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Intuit\QuickBooks Pro\components\HR\bin\wrapper.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\QuickBooks\ctGrid.ocx'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\CashFlow\1.0\CashFlowProjector.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Common Files\Intuit\QuickBooks\\Intuit\LoanManager\1.0\LoanManager.dll'&lt;br /&gt;Missing module: 'C:\Program Files\Intuit\QuickBooks Pro\dbctrs8.dll'&lt;br /&gt;=================================================&lt;br /&gt;&lt;/blockquote&gt;Looking at the messages, I noticed an obvious error with a part of the path that was duplicated: "Intuit\QuickBooks\\Intuit\QuickBooks". I googled for a solution and didn't find one. Then I checked Intuit's so-called "knowledge base" and still did not find a solution.&lt;br /&gt;&lt;br /&gt;That's when I noticed the batch file "C:\Program Files\Intuit\QuickBooks Pro\reboot.bat". I opened the file and noticed the comment "Post-reboot registration commands, for QuickBooks 2003" at the top of the file. Then I noticed a whole bunch of calls to "regsvr32". For example:&lt;br /&gt;&lt;blockquote&gt;C:\WINDOWS\system32\regsvr32 /s "C:\Program Files\Common Files\Intuit\QuickBooks\addinmgr2.dll"&lt;/blockquote&gt;Obviously, that batch file was supposed to run automatically the first time I rebooted after installing QuickBooks. Now I know what you're thinking but let me assure you that I DID reboot after installation. QuickBooks just effed up and didn't run the batch file.&lt;br /&gt;&lt;br /&gt;Anyway, I manually ran the batch file and it fixed the problem. I was able to run QuickBooks.&lt;br /&gt;&lt;br /&gt;If you have the same problem and this blog post helps you, please leave a comment.&lt;br /&gt;&lt;br /&gt;Cheers!&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-115966172564157966?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/115966172564157966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=115966172564157966' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115966172564157966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115966172564157966'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/09/quickbooks-pro-2006-shitty-out-of-box.html' title='QuickBooks Pro 2006 - Shitty Out of Box Experience'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-115937513184157991</id><published>2006-09-27T09:30:00.002-07:00</published><updated>2009-12-02T14:17:34.246-08:00</updated><title type='text'>Norton GoBack...To the Stone Age</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/09/27/norton-goback-to-the-stone-age/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;My boss came to me yesterday with her notebook and said "My notebook has been &lt;i&gt;really&lt;/i&gt; slow for the last week or so. Can you please fix it?"&lt;br /&gt;&lt;br /&gt;Of course I can! I started by turning on her notebook and noticed that it started up very slowly. Then, after logging in, I noticed that there was constant hard drive activity, even when the notebook was left idle for 30 minutes.&lt;br /&gt;&lt;br /&gt;I ran msconfig and noticed that there were several &lt;span style="font-style: italic;"&gt;stupid&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;unnecessary &lt;/span&gt;"services" configured to startup automatically at boot time. For example:&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;iPodService and iTunesHelper - Apparently, these just make iTunes easier to launch and/or make iTunes launch faster. Whoop-de-doo...&lt;/li&gt;   &lt;li&gt;vzfw - A Sony Vaio program which takes up about 35-40 MB of memory and which apparently &lt;a href="http://forum.notebookreview.com/showthread.php?t=40682"&gt;searches your hard drive for multimedia files&lt;/a&gt; to serve up to other users on the LAN - as useless a "service" as I have ever seen.&lt;/li&gt;   &lt;li&gt;the winzip "quick launch" thingy&lt;/li&gt;   &lt;li&gt;the quicktime "quick launch" thingy&lt;/li&gt;   &lt;li&gt;ati2evxx - The ATI External Event Utility, which apparently just provides hot keys for changing video setting. Who needs that shit? Is it really that hard to right-click on the desktop, click properties and then click settings?&lt;/li&gt; &lt;/ul&gt; I set all of the above "services" (and a few other stupid ones) to start up manually, or not at all. As a result, the computer booted much faster and used much less memory. However, I still noticed constant HD drive activity. That's when I noticed that &lt;a href="http://www.symantec.com/home_homeoffice/products/overview.jsp?pcid=sp&amp;amp;pvid=ngb40"&gt;Norton GoBack 4.0&lt;/a&gt; was recently installed on the computer.&lt;br /&gt;&lt;br /&gt;Here is what GoBack is supposed to do:&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;Reverses system crashes, failed software installations, user errors, and more&lt;/li&gt;   &lt;li&gt;Rolls PCs back minutes, hours, or even days before onset of a problem&lt;/li&gt;   &lt;li&gt;Lets you try software safely, with a fast uninstall if you don’t like it&lt;/li&gt;   &lt;li&gt;Recovers accidentally deleted or modified files&lt;/li&gt;   &lt;li&gt;Prevents unauthorized users from rolling back a hard drive&lt;/li&gt;   &lt;li&gt;Automatically schedules hard drive restorations to a set configuration&lt;/li&gt; &lt;/ul&gt; In other words, GoBack is for idiots who are too lazy to perform regular backups. It's not that hard to do, People, really.&lt;br /&gt;&lt;br /&gt;When I googled &lt;i&gt;"norton GoBack" "constant hard drive"&lt;/i&gt;, I found someone with &lt;a href="http://bluezhift.proliphus.com/2006/01/29/fear-norton-goback/"&gt;a similar story&lt;/a&gt;. After he removed GoBack, the constant hard drive activity went away.&lt;br /&gt;&lt;br /&gt;So, I removed GoBack too. And guess what? That fixed the problem.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-115937513184157991?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/115937513184157991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=115937513184157991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115937513184157991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115937513184157991'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/09/norton-gobackto-stone-age_27.html' title='Norton GoBack...To the Stone Age'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-115773668980542072</id><published>2006-09-08T10:31:00.001-07:00</published><updated>2009-12-01T14:11:23.355-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Network Statistics in Linux</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/09/08/network-statistics-in-linux/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;&lt;ul&gt; &lt;li&gt;To display statistics for each networking protocol, on systems using a full shell: &lt;tt&gt;netstat -s&lt;/tt&gt; &lt;/li&gt;&lt;li&gt;To display statistics for each networking protocol, on systems using the stripped down "Busybox" shell (e.g. OpenWrt): &lt;tt&gt;more /proc/net/snmp&lt;/tt&gt; &lt;/li&gt; &lt;/ul&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-115773668980542072?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/115773668980542072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=115773668980542072' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115773668980542072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115773668980542072'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/09/network-statistics-in-linux.html' title='Network Statistics in Linux'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-115651907681506452</id><published>2006-08-25T06:15:00.002-07:00</published><updated>2009-12-01T14:07:12.073-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Windows Automatic Updates - Stop Nagging Me, Biatch!</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/08/25/windows-automatic-updates-stop-nagging-me-biatch/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Don't you hate it when you install a security patch with Windows Automatic Updates and afterwards Windows keeps nagging you to restart? Here's what the nag dialog box says:&lt;br /&gt;&lt;blockquote&gt;Updating your computer is almost complete. You must restart your computer for the updates to take effect. Do you want to restart your computer now?&lt;br /&gt;&lt;/blockquote&gt;Your choices are: Restart Now and Restart Later. Unfortunately, by default, "later" means only 10 minutes later, which can be annoying when you're trying to get some work done, especially since the dialog box steals input focus from whatever window you were working with.&lt;br /&gt;&lt;br /&gt;If you run Windows XP Pro, you can &lt;a href="http://www.codinghorror.com/blog/archives/000294.html"&gt;use the Group Policy Editor to stop the nagging&lt;/a&gt;. If you run Windows 2000, like me, you can do a registry hack to reduce the frequency of the nagging or to stop it altogether. Here are the registry settings:&lt;br /&gt;&lt;blockquote&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU]&lt;br /&gt;"RebootRelaunchTimeout"=dword:0000003c&lt;br /&gt;"RebootRelaunchTimeoutEnabled"=dword:00000001&lt;/blockquote&gt;RebootRelaunchTimeout is the number of minutes between nags. I entered 3c (hexadecimal), which is 60 minutes (decimal). If you set RebootRelaunchTimeoutEnabled to 0, can you disable the nags altogether, which I do NOT recommend; eventually (sooner rather than later), you should restart your machine so that the security updates can take effect.&lt;br /&gt;&lt;br /&gt;One important point: these registry settings don't take effect until you either restart your computer or restart the Automatic Update service (Control Panel...Administrative Tools...Services...Automatic Updates...click the service restart button).&lt;br /&gt;&lt;br /&gt;For a full explanation of these two registration settings and some related ones, refer to &lt;a href="http://technet2.microsoft.com/WindowsServer/en/library/75ee9da8-0ffd-400c-b722-aeafdb68ceb31033.mspx?mfr=true"&gt;this article&lt;/a&gt;.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-115651907681506452?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/115651907681506452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=115651907681506452' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115651907681506452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115651907681506452'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/08/windows-automatic-updates-stop-nagging.html' title='Windows Automatic Updates - Stop Nagging Me, Biatch!'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-115628035500053761</id><published>2006-08-22T13:35:00.001-07:00</published><updated>2009-12-01T13:56:48.343-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>How to Inject Dependencies Into Domain Objects When Using the Spring Framework 1.x and Hibernate</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/08/22/how-to-inject-dependencies-into-domain-objects-when-using-the-spring-framework-1-x-and-hibernate/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;!--&lt;br /&gt;Yesterday I read &lt;a href="http://chris-richardson.blog-city.com/migrating_to_spring_2_part_3__injecting_dependencies_into_en.htm"&gt;an interesting post&lt;/a&gt; on &lt;a href="http://chris-richardson.blog-city.com/"&gt;Chris Richardson's blog&lt;/a&gt; about how to inject dependencies into domain objects when using the Spring Framework and Hibernate. This is a great feature because it allows you the option to create richer domain models and avoid the &lt;a href="http://www.martinfowler.com/bliki/AnemicDomainModel.html"&gt;anemic domain model&lt;/a&gt; anti-pattern, which was coined by Martin Fowler and discussed at great lengths in Eric Evans' book &lt;a href="http://domaindrivendesign.org/books/index.html"&gt;Domain Driven Design&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Unfortunately, this AspectJ-based solution discussed by Chris Richardson will not be officially supported until Spring Framework 2 is released (which should be soon). There are some other solutions (e.g. DependencyInjectionInterceptorFactoryBean, ServiceLocator lookups, passing dependencies as as parameters to service methods, etc) but, as Chris points out, these all have some undesirable drawbacks.&lt;br /&gt;&lt;br /&gt;Today I thought of a another solution, which might be sufficient (if a bit kludgy) until Spring Framework 2 is released. The genesis for this solution was my realization that the service dependencies for a given domain object class could probably use the same reference for &lt;i&gt;all instances&lt;/i&gt; of that class. In other words, it seemed to me that it might make sense to store the dependency in a static variable of the class instead of an instance variable. If I use a static variable, I can set the dependency before Hibernate starts instantiating any instances of the domain object class.&lt;br /&gt;&lt;br /&gt;Fortunately, Spring provides the MethodInvokingFactoryBean, which can be used to call any arbitrary static method upon starting up the application context. Using this mechanism, I can configure the service in the application context and transparently set the dependency for this in the domain object class. Furthermore, if I type the static variable with the service's interface instead of the implementation, I can easily replace the implementation with a stub or mock during unit testing.&lt;br /&gt;&lt;br /&gt;Using Chris Richardson's "PendingOrder" example, here is how my cheesy solution might work. First the code:&lt;br /&gt;&lt;pre class="code-hs"&gt;public interface RestaurantRepository &lt;br /&gt;{&lt;br /&gt;  //...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class RestaurantRepositoryImpl implements RestaurantRepository &lt;br /&gt;{&lt;br /&gt;  //...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class PendingOrder &lt;br /&gt;{&lt;br /&gt;  private static RestaurantRepository restaurantRepository;&lt;br /&gt;&lt;br /&gt;  public static void setRestaurantRepository(RestaurantRepository rr) &lt;br /&gt;  {&lt;br /&gt;    restaurantRepository = rr;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public int updateDeliveryInfo (&lt;br /&gt;    Address deliveryAddress,&lt;br /&gt;    Date deliveryTime,&lt;br /&gt;    boolean force) &lt;br /&gt;  {&lt;br /&gt;    // the RestaurantRepository dependency is used here&lt;br /&gt;  }&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Now, the configuration:&lt;br /&gt;&lt;pre class="code-hs"&gt;&amp;lt;bean id="restaurantRepository" class="somepackage.RestaurantRepositoryImpl"&amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="pendingOrderRestaurantRepositoryInjector"&lt;br /&gt;  class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"&amp;gt;&lt;br /&gt;  &amp;lt;property name="staticMethod"&amp;gt;&lt;br /&gt;    &amp;lt;value&amp;gt;somepackage.PendingOrder.setRestaurantRepository&amp;lt;/value&amp;gt;&lt;br /&gt;  &amp;lt;/property&amp;gt;&lt;br /&gt;  &amp;lt;property name="arguments"&amp;gt;&lt;br /&gt;    &amp;lt;list&amp;gt;&lt;br /&gt;      &amp;lt;ref bean="restaurantRepository"/&amp;gt;&lt;br /&gt;    &amp;lt;/list&amp;gt;&lt;br /&gt;  &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/pre&gt;Yes, it's cheesy but I think it will work fine until I switch to using the AspectJ-based solution when Spring Framework 2 is released.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-115628035500053761?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/115628035500053761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=115628035500053761' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115628035500053761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115628035500053761'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/08/how-to-inject-dependencies-into-domain.html' title='How to Inject Dependencies Into Domain Objects When Using the Spring Framework 1.x and Hibernate'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-115386631150796338</id><published>2006-07-25T06:21:00.001-07:00</published><updated>2009-12-01T13:51:31.168-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OpenWrt'/><title type='text'>Tinyproxy on WRT54GS</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/07/25/tinyproxy-on-wrt54gs/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;I installed &lt;a href="http://tinyproxy.sourceforge.net/"&gt;Tinyproxy&lt;/a&gt; 1.6.3 on my LinkSys WRT54GS router today. Following are some installation notes and comments about Tinyproxy.&lt;br /&gt;&lt;br /&gt;My router currently runs the White Russian RC5 release of the &lt;a href="http://openwrt.org/"&gt;OpenWrt&lt;/a&gt; Linux distribution. Tinyproxy is not yet an officially supported &lt;a href="http://wiki.openwrt.org/OpenWrtDocs/Packages"&gt;OpenWrt package&lt;/a&gt;. Rather, it is part of the "backports" package repository. To install Tinyproxy, I first had to add the backports repository to my repository list by adding the following line to my &lt;span style="font-family:courier new;"&gt;/etc/ipkg.conf&lt;/span&gt; file:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;blockquote&gt;src backports http://downloads.openwrt.org/backports/rc5&lt;/blockquote&gt;&lt;/span&gt;After adding that line, I ran &lt;span style="font-family:courier new;"&gt;ipkg update&lt;/span&gt; to add the backport packages to my list of packages. To confirm that Tinyproxy was in the list, I ran &lt;span style="font-family:courier new;"&gt;ipkg list&lt;/span&gt; and looked for tinyproxy in the output. Finally, to install Tinyproxy, I ran &lt;span style="font-family:courier new;"&gt;ipkg install tinyproxy&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The installer put a tinyproxy init script in &lt;span style="font-family:courier new;"&gt;/etc/init.d&lt;/span&gt;. You can either run Tinyproxy manually with &lt;span style="font-family:courier new;"&gt;/etc/init.d/tinyproxy start&lt;/span&gt; or you can run it automatically by renaming it something like &lt;span style="font-family:courier new;"&gt;S50tinyproxy&lt;/span&gt; and rebooting.&lt;br /&gt;&lt;br /&gt;Once I got Tinyproxy running, I pointed my browser at it and started surfing. One thing I noticed right away is that Tinyproxy was SLOW for sites with lots of graphics. For example, on average it took about 30 seconds to load http://tsn.ca.&lt;br /&gt;&lt;br /&gt;Of course, the question was "Is Tinyproxy slow because of the hardware (WRT54GS) or the software (Tinyproxy)?"&lt;br /&gt;&lt;br /&gt;To answer this question, I ran both &lt;a href="http://www.squid-cache.org/"&gt;Squid&lt;/a&gt; and Tinyproxy on a P3-350 with 256 MB of RAM, running CentOS 4. On average, Squid took about 9 seconds to load http://tsn.ca and Tinyproxy took about 10 seconds. Therefore, I concluded that Tinyproxy's slow performance on the WRT54GS was due to the hardware.&lt;br /&gt;&lt;br /&gt;For websites with mostly text, Tinyproxy's performance on the WRT54GS was certainly acceptable. For example, search results from Google appeared almost instantly.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-115386631150796338?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/115386631150796338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=115386631150796338' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115386631150796338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115386631150796338'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/07/tinyproxy-on-wrt54gs.html' title='Tinyproxy on WRT54GS'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-115378445104698199</id><published>2006-07-24T06:56:00.001-07:00</published><updated>2009-12-01T13:41:52.095-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>Toshiba A100-SK4 - First Impressions</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/07/24/toshiba-a100-sk4-first-impressions/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;After months of begging, I finally bought my wife a notebook computer. It's a Toshiba A100-SK4 (manufacturer's part number: PSAA8C-SK400E). Here are the specs:&lt;br /&gt;&lt;ul&gt; &lt;li&gt;Processor: Intel Centrino Solo T1350&lt;/li&gt;&lt;li&gt;Processor Speed: 1.86GHz&lt;/li&gt;&lt;li&gt;Screen Size: 15.4" (wide screen)&lt;/li&gt;&lt;li&gt;Screen Type: WXGA TFT With TruBrite&lt;/li&gt;&lt;li&gt;RAM: 1GB DDR&lt;/li&gt;&lt;li&gt;Hard Drive: 80GB&lt;/li&gt;&lt;li&gt;Optical Drive: DVD Super-Multi Drive&lt;/li&gt;&lt;li&gt;Graphics: 128MB (Shared) Intel GMA 950&lt;/li&gt;&lt;li&gt;Average Battery Life: Up to 3.5 Hours&lt;/li&gt;&lt;li&gt;Battery Type:     6-Cell Lithium-Ion&lt;/li&gt;&lt;li&gt;Cache:     32KB L1, 2MB L2&lt;/li&gt;&lt;li&gt;Fax/Modem: 56K V.92&lt;/li&gt;&lt;li&gt;I/O Ports: 4 x USB 2.0, 1 x S-Video Out, 1 x RGB&lt;/li&gt;&lt;li&gt;Network Cards: 10/100 Ethernet LAN, Wireless 802.11bg&lt;/li&gt;&lt;li&gt;PC Card Slots: 1 Type II, CardBus, Express Card&lt;/li&gt;&lt;li&gt;Pointing Device: Touchpad&lt;/li&gt;&lt;li&gt;Preloaded Operating System: Microsoft Windows XP Home (yuck)&lt;/li&gt;&lt;li&gt;Product Weight: 2.8 kg&lt;/li&gt;&lt;li&gt;Product Dimensions: 36.00(W) x 3.68(H) x 26.70(D) cm&lt;/li&gt;&lt;li&gt;Speakers: Built-In Stereo Speakers&lt;/li&gt;&lt;li&gt;System Bus: 533MHz&lt;/li&gt; &lt;/ul&gt; So far, I like this notebook. Granted, I haven't used it for more than checking my email, surfing the web and watching a DVD movie.&lt;br /&gt;&lt;br /&gt;Here are some good things I have noticed:&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;It boots very quickly. I haven't timed the boot yet but I can assure you that you won't be disappointed. If I'm feeling bored this week, maybe I'll time the boot.&lt;/li&gt;   &lt;li&gt;The wireless reception is excellent. I get a strong signal all over our two-storey house and also outside on the sundeck.&lt;/li&gt;   &lt;li&gt;The screen is bright and supports a pretty wide range of viewing angles in both the x-axis and the y-axis.&lt;/li&gt;   &lt;li&gt;The speakers sound pretty good with the "surround sound" feature activated. I turned this feature on while watching the movie Sea Biscuit and I was quite impressed.&lt;/li&gt; &lt;/ul&gt; Something I don't like about this notebook is its &lt;span style="font-style: italic;"&gt;extremely&lt;/span&gt; loud DVD drive. The first time I watched a DVD on it, I was distracted by the noise. It sounded like a jet engine!&lt;br /&gt;&lt;br /&gt;I did some research and found out that the notebook comes with a small utility called the Acoustic Silencer, which is supposed to mitigate this noise. When activated, the Acoustic Silencer limits the spin rate of the DVD drive to reduce vibratiion, which is supposed to reduce the noise. Toshiba recommends that you activate the Acoustic Silencer before running a movie DVD or a music CD. I tried it a couple of nights ago and it worked! It noticeably reduced the drive noise and as a result, I wasn't distracted by it when I watched a movie. Of course, I think the Acoustic Silencer is a probably kludge to cover up a shitty-ass drive but if it works, I guess we can't complain, can we?&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-115378445104698199?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/115378445104698199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=115378445104698199' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115378445104698199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/115378445104698199'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/07/toshiba-a100-sk4-first-impressions.html' title='Toshiba A100-SK4 - First Impressions'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-113899294913872756</id><published>2006-02-03T10:46:00.001-08:00</published><updated>2009-11-30T13:51:56.386-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>Soekris net4801 pictures</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/02/03/soekris-net4801-pictures/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;Alright, here are some pictures of my new Soekris net4801.&lt;br /&gt;&lt;br /&gt;Here's the adapter. As you can see, it's the kind that doesn't take up 50 slots on your power bar.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5060/1277/1600/net4801_4.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/5060/1277/320/net4801_4.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's the back of the unit, showing the various connectors. Note that this unit has a USB port.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5060/1277/1600/net4801_2.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/5060/1277/320/net4801_2.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's the front of the unit, showing the status lights. By the way, I read somewhere that you can use the error light for your own purposes. Pretty cool.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5060/1277/1600/net4801_3.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/5060/1277/320/net4801_3.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's a good view of the board.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5060/1277/1600/net4801_1.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/5060/1277/320/net4801_1.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Finally, here's the 2.5" hard drive mounting bracket.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5060/1277/1600/net4801_5.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/5060/1277/320/net4801_5.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-113899294913872756?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/113899294913872756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=113899294913872756' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/113899294913872756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/113899294913872756'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/02/soekris-net4801-pictures.html' title='Soekris net4801 pictures'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-113881163919249558</id><published>2006-02-01T08:31:00.001-08:00</published><updated>2009-11-18T14:38:34.011-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>Soekris net4801</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/02/01/soekris-net4801/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;Oh yeah, baby! I just got a &lt;a href="http://www.soekris.com/net4801.htm"&gt;Soekris net4801&lt;/a&gt; and I'm going to turn it into a multi-WAN router. I'm currently installing and configuring &lt;a href="http://voyage.hk/software/voyage.html"&gt;Voyage Linux&lt;/a&gt; on it. I'll post some photos and details soon.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-113881163919249558?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/113881163919249558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=113881163919249558' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/113881163919249558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/113881163919249558'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/02/soekris-net4801.html' title='Soekris net4801'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-113771644810923784</id><published>2006-01-19T16:01:00.001-08:00</published><updated>2009-11-18T14:35:25.151-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>Multi-WAN Router / Firewall: Soekris VS WRAP</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/01/19/multi-wan-router-firewall-soekris-vs-wrap/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;!--&lt;br /&gt;After much investigation, it looks like building my own firmware for the LinkSys RV082 will take too long. I will pursue it at a later date but for now I will build my own.&lt;br /&gt;&lt;br /&gt;The requirements are:&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;Low cost&lt;/li&gt;   &lt;li&gt;Small form factor&lt;/li&gt;   &lt;li&gt;Quiet&lt;/li&gt;   &lt;li&gt;Low heat&lt;/li&gt;   &lt;li&gt;A minimum of three ethernet ports&lt;/li&gt;   &lt;li&gt;Serial port console access&lt;/li&gt;   &lt;li&gt;Powerful enough to be able to route and filter at least 10 Mbps of traffic.&lt;/li&gt;   &lt;li&gt;Linux, FreeBSD and/or OpenBSD compatible&lt;/li&gt;   &lt;li&gt;Loading operating system from Compact Flash&lt;/li&gt; &lt;/ul&gt;&lt;br /&gt;Nice to haves:&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;PXE boot&lt;/li&gt;   &lt;li&gt;USB port&lt;/li&gt;   &lt;li&gt;IDE port&lt;/li&gt; &lt;/ul&gt; So far, the contenders are:&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;&lt;a href="http://www.soekris.com/net4801.htm"&gt;Soekris Engineering net4801&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;&lt;a href="http://www.pcengines.ch/wrap.htm"&gt;&lt;span style=";font-family:Trebuchet MS,Arial,Sans Serif;font-size:100%;"  &gt;WRAP.1E-2&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt; &lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Both are powered by the same CPU (&lt;span style=";font-family:Trebuchet MS,Arial,Sans Serif;font-size:100%;"  &gt;Geode SC1100&lt;/span&gt;),  have three ethernet ports and 128 MB RAM. Both can run Linux, FreeBSD and OpenBSD.&lt;br /&gt;&lt;br /&gt;Both options require separate purchase of a compact flash card. The recommended size is 256 MB, which costs CA$28. For CA$87, we could get a 1 GB card, which would leave room for lots of extra apps and online documentation - extremely nice but not required.&lt;br /&gt;&lt;br /&gt;The Soekris would cost about US$255 for the board, case and power supply. The WRAP would cost about $175 for the board, case and power supply.&lt;br /&gt;&lt;br /&gt;The Soekris has extra features that the WRAP does not have; the Soekris has an IDE connector for an optional 2.5" hard drive as well a USB port. These are not required but they are very nice to have.&lt;br /&gt;&lt;br /&gt;The user manuals for both devices are pretty sparse (about 12 pages each). On the internet, I have found detailed operating system installation HOW-TOs for both computers; however, there are more HOW-TOs for the Soekris and they are better written.&lt;br /&gt;&lt;br /&gt;Either option would work but the Soekris is more flexible because of the option to add a 2.5" hard drive and a USB device. Also, I think the documentation for the Soekris is slightly better.&lt;br /&gt;&lt;br /&gt;For now, I am leaning towards the Soekris.&lt;br /&gt;--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-113771644810923784?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/113771644810923784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=113771644810923784' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/113771644810923784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/113771644810923784'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/01/multi-wan-router-firewall-soekris-vs.html' title='Multi-WAN Router / Firewall: Soekris VS WRAP'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21102333.post-113751896193923481</id><published>2006-01-17T08:59:00.002-08:00</published><updated>2009-11-18T14:31:55.997-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><title type='text'>Under the Hood of the LinkSys RV082 VPN Router</title><content type='html'>This story has moved to &lt;a href="http://nerdboys.com/"&gt;NerdBoys.com&lt;/a&gt;. Please read this story at its new &lt;a href="http://nerdboys.com/2006/01/17/under-the-hood-of-the-linksys-rv082-vpn-router/"&gt;location&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;!--I have just acquired a LinkSys RV082 VPN router and I want to put custom firmware on it. I love the custom firmwares for the LinkSys WRT54G (e.g. OpenWrt, DD-WRT) but they don't run on the RV082. After much searching on the internet, I found a project which might eventually lead to custom firmware. The project is &lt;a href="http://openixp.phj.hu/" target="_blank" class="postlink"&gt;OpenIXP&lt;/a&gt;. Currently, it's targetted at the LinkSys WRV54G but the goal stated on the homepage is "to produce an Linux based open environment for the Intel IXP4xx processors". The project leader also has some &lt;a href="http://www.phj.hu/wrv54g/" target="_blank" class="postlink"&gt;great background information on his other site&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Anyway, I was talking to the project leader and he said that in order to port OpenIXP to the RV082 (and possibly RV042?) the first step is to open up the box and figure out what hardware it has. So, I did that. Below is a summary of how I opened the box and what I found inside.&lt;br /&gt;&lt;br /&gt;To open the box, start by using a small knife or similar device to gently pry back the back panel (the dark grey plastic panel that has the power plug). Next, you have to remove the top part of the metal case. It has four L-shaped clips on both sides which hook into the bottom part of the metal case. Starting from the back, use a knife to gently pry out each clip. Once you have pried out all eight clips, you should be able to remove the top part of the case by flipping it upwards from the back (like opening a door, where the front plastic panel is like the door hinge).&lt;br /&gt;&lt;br /&gt;Once I got inside, here are the main chips I found:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Intel FWIXP425BD - The CPU. Intel describes it as "IXP425 network processor, 533 MHz". Another marking on the chip is "L4450377".&lt;/li&gt;&lt;li&gt;Infineon ADM6999 - Infineon describes this as "a high performance, low cost, highly integrated (Controller, PHY and Memory) 9-port 10/100 Mbps TX/FX switch with 8-ports supporting 10/100Mbps TX/FX + 1 MII/GPSI/7 wire Ethernet switch controller port." My guess is that this switch manages the 8 LAN ports. &lt;a href="http://www.infineon.com/cgi-bin/ifx/portal/ep/channelView.do?channelId=-65140&amp;channelPage=/ep/channel/productOverview.jsp&amp;amp;pageTypeId=17099" target="_blank" class="postlink"&gt;More info&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Infineon ADM6996L - Infineon describes this as "a high performance, low cost, highly integrated (Controller, PHY and Memory) six-port 10/100 Mbps TX/FX switch with 5-ports supporting 10/100Mbps TX/FX + 1 10/100 MAC port Ethernet switch controller". My guess is that this switch manages the 2 WAN ports. &lt;a href="http://www.infineon.com/cgi-bin/ifx/portal/ep/channelView.do?channelId=-65139&amp;channelPage=/ep/channel/productOverview.jsp&amp;amp;pageTypeId=17099" target="_blank" class="postlink"&gt;More info&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;2 x Mira P2V28S40BTP - I'm pretty sure this is the RAM. Interestingly, it appears that there are two spots on the board to solder on two more RAM chips!&lt;/li&gt;&lt;li&gt;Intel TE28F128 -  I believe this is a 16 MB flash chip.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Here are the unused interface connectors I found:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;JP2 - 2 rows of 5 pins - 10 pins total. The pins do not have solder pads, rather, they are holes. Only pins 4, 6, 8 and 10 appear to be "connected" to the board (I can see traces coming from these pins). My guess is that this might be a serial port or a USB port.&lt;/li&gt;&lt;li&gt;JP4 - identical to JP2 except that none of the pins appear to be connected to the board.&lt;/li&gt;&lt;li&gt;JP5 - 2 rows of 20 pins - 40 pins total, with solder pads. No idea what this is for. For looking at the tracing coming out of it I think this is some sort of "multi" interface. I see several 4 pins groupings, a 7 pin grouping and a 2 pin grouping. Perhaps the serial port is over here and not at JP2 after all?&lt;/li&gt;&lt;li&gt;JP3 - 2 rows of 10 pins - 20 pins total, with solder pads. My guess is this is a JTAG interface.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;The LED assemblies are cool. The LED's are mounted in a plastic grid that has cells where the LED's are plugged in. There are many empty cells so I wonder if you could plug in more LED's? That would be cool.&lt;br /&gt;&lt;br /&gt;Anyway, below are some photos of the RV082 (thanks to my photo-taking homeboy, JNG).  Click on the photo to zoom in.&lt;br /&gt;&lt;br /&gt;The first photo shows an exploded view of the back panel, the front panel and the top of the case&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5060/1277/1600/IMG_0438.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/5060/1277/400/IMG_0438.jpg" alt="" border="0" /&gt;&lt;/a&gt;The next photo shows the L-shaped teeth on the top of the case. These teeth connect the top and bottom of the case.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5060/1277/1600/IMG_0441.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/5060/1277/400/IMG_0441.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The next photo shows the board and all the chips on it. A &lt;a href="http://members.shaw.ca/cyboc/IMG_0445.JPG"&gt;higher resolution version of this  photo&lt;/a&gt; is available too (please do not link to it because it's on my home ISP account and they may get pissed off if it generates too much traffic).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5060/1277/1600/IMG_0445.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/5060/1277/400/IMG_0445.jpg" alt="" border="0" /&gt;&lt;/a&gt;The next photo shows the LEDs and ethernet ports that live behind the front panel. Notice the empty slots in the LED grid? I wonder if I could plug in more LED's into that grid?&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5060/1277/1600/IMG_0450.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/5060/1277/400/IMG_0450.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Anyway, I'm a long way from having custom firmware for this baby. Any help would be appreciated.--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21102333-113751896193923481?l=joesbitbucket.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joesbitbucket.blogspot.com/feeds/113751896193923481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21102333&amp;postID=113751896193923481' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/113751896193923481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21102333/posts/default/113751896193923481'/><link rel='alternate' type='text/html' href='http://joesbitbucket.blogspot.com/2006/01/under-hood-of-linksys-rv082-vpn-router.html' title='Under the Hood of the LinkSys RV082 VPN Router'/><author><name>Joe</name><uri>http://www.blogger.com/profile/03602182138078986641</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://bp1.blogger.com/__68CJkmINgk/RmyT18Vg2eI/AAAAAAAAAEo/R61cl1Q2ZTg/s400/JoeBloggerProfile.jpg'/></author><thr:total>6</thr:total></entry></feed>
