<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tequila Fish</title>
	<atom:link href="http://www.tequilafish.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tequilafish.com</link>
	<description>Ran-dumb ramblings of me...</description>
	<lastBuildDate>Thu, 26 Jan 2012 23:30:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Installing Bundler for Ruby in Ubuntu 10.04</title>
		<link>http://www.tequilafish.com/2012/01/26/installing_ruby_bundler_ubuntu_10-04/</link>
		<comments>http://www.tequilafish.com/2012/01/26/installing_ruby_bundler_ubuntu_10-04/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 23:20:34 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[10.04]]></category>
		<category><![CDATA[bundler]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.tequilafish.com/?p=573</guid>
		<description><![CDATA[When attempting to install Bundler for Ruby on Ubuntu 10.04, I got the following error: shell&#62; sudo gem install bundler ERROR: Error installing bundler: bundler requires RubyGems version >= 1.3.6 Running sudo gem -v I saw that I had 1.3.5. To get around this, simply install the available updater gem, then run it: shell&#62; sudo [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.tequilafish.com%2F2012%2F01%2F26%2Finstalling_ruby_bundler_ubuntu_10-04%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.tequilafish.com%2F2012%2F01%2F26%2Finstalling_ruby_bundler_ubuntu_10-04%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>When attempting to install <a href="http://gembundler.com/" title="Bundler" target="_blank">Bundler</a> for Ruby on Ubuntu 10.04, I got the following error:</p>
<p><code>shell&gt; sudo gem install bundler<br />
ERROR:  Error installing bundler:<br />
	bundler requires RubyGems version >= 1.3.6<br />
</code></p>
<p>Running <code>sudo gem -v</code> I saw that I had 1.3.5.  To get around this, simply install the available updater gem, then run it:</p>
<p><code>shell&gt; sudo gem install rubygems-update<br />
shell&gt; sudo /var/lib/gems/1.8/bin/update_rubygems<br />
</code></p>
<p>Now running <code>gem -v</code> I see that I have 1.8.15 and I am able to install bundler:</p>
<p><code>shell&gt; gem install bundler<br />
Fetching: bundler-1.0.21.gem (100%)<br />
Successfully installed bundler-1.0.21<br />
1 gem installed<br />
Installing ri documentation for bundler-1.0.21...<br />
Installing RDoc documentation for bundler-1.0.21...<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tequilafish.com/2012/01/26/installing_ruby_bundler_ubuntu_10-04/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unix: Delete all but N most recent files in a directory</title>
		<link>http://www.tequilafish.com/2011/06/26/unix-delete-all-but-n-most-recent-files-in-a-directory/</link>
		<comments>http://www.tequilafish.com/2011/06/26/unix-delete-all-but-n-most-recent-files-in-a-directory/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 06:21:43 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[tail]]></category>
		<category><![CDATA[unix]]></category>
		<category><![CDATA[xargs]]></category>

		<guid isPermaLink="false">http://www.tequilafish.com/?p=561</guid>
		<description><![CDATA[Here's a handy little command to delete every file in a directory except for the N most recent files. It is helpful for including in a log rotation or db backup script. find /path/to/files/ -maxdepth 1 -type -f -name '*' -print0 &#124; xargs -r0 ls -t &#124; tail -n +5 &#124; tr '\n' '\0' &#124; [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.tequilafish.com%2F2011%2F06%2F26%2Funix-delete-all-but-n-most-recent-files-in-a-directory%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.tequilafish.com%2F2011%2F06%2F26%2Funix-delete-all-but-n-most-recent-files-in-a-directory%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Here's a handy little command to delete every file in a directory except for the N most recent files.  It is helpful for including in a log rotation or db backup script.</p>
<p><code>find /path/to/files/ -maxdepth 1 -type -f -name '*' -print0 | xargs -r0 ls -t | tail -n +5 | tr '\n' '\0' | xargs -r0 rm</code></p>
<p>Breaking down and explaining each section of the command, we have:</p>
<p><code>find /path/to/files/ -maxdepth 1 -type -f -name '*' -print0</code></p>
<p>This will list all files in the specified directory.  The reason we use 'find' rather than 'ls' is because we need the full path of the files when later passing the argument list to the 'rm' command.  We specify a 'maxdepth' so we only search within the current directory.  We also specify a 'type' of 'f' so that we only find files and not other items like directories, sockets, or symbolic links.  It's probably best not to use '*' as your 'find' expression, as it could be dangerous if you accidentally point it to the wrong directory.  Use something like '*.sql.gz' or '*.log' or whatever suits you.  Also note that we are using '-print0'  so that the subsequent commands will be able to handle spaces and other special characters in filenames (see <a href="http://en.wikipedia.org/wiki/Xargs#The_separator_problem">http://en.wikipedia.org/wiki/Xargs#The_separator_problem</a>)</p>
<p><code>xargs -r0 ls -t</code></p>
<p>This will sort the list returned by the 'find' command in descending order by timestamp (newest to oldest).  The '-r' parameter instructs xargs not to run of no files are found by  the first 'find' command.  The '-0' parameter gets around the separator problem described in the previous step.</p>
<p><code>tail -n +5</code></p>
<p>This will filter the list to only show from the 5th line onward.  So if you want to keep the 10 most recent files, use +10 as your argument.</p>
<p><code>tr '\n' '\0'</code></p>
<p>This is similar to using '-print0' with the 'find' command above.  We need to clean up the output so that the subsequent xargs command can handle potential spaces in the filenames.  So we use the 'tr' command to translate newlines to the null character.</p>
<p><code>xargs -r0 rm</code></p>
<p>Finally, this command will delete the files returned by the combination of the previous commands.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tequilafish.com/2011/06/26/unix-delete-all-but-n-most-recent-files-in-a-directory/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL: Dynamic ORDER BY clause</title>
		<link>http://www.tequilafish.com/2010/08/18/mysql-dynamic-order-by-clause/</link>
		<comments>http://www.tequilafish.com/2010/08/18/mysql-dynamic-order-by-clause/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 02:03:22 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[asc]]></category>
		<category><![CDATA[desc]]></category>
		<category><![CDATA[order by]]></category>

		<guid isPermaLink="false">http://www.tequilafish.com/?p=541</guid>
		<description><![CDATA[When developing some discography software for a website, I came across the need to sort a list of releases differently depending on their release date. I wanted to sort future releases in ascending order (oldest to newest) and sort past releases in descending order (newest to oldest). This isn't an easy task, but after many [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.tequilafish.com%2F2010%2F08%2F18%2Fmysql-dynamic-order-by-clause%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.tequilafish.com%2F2010%2F08%2F18%2Fmysql-dynamic-order-by-clause%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>When developing some discography software for a website, I came across the need to sort a list of releases differently depending on their release date.  I wanted to sort future releases in ascending order (oldest to newest) and sort past releases in descending order (newest to oldest).  This isn't an easy task, but after many hours of trial and error, I finally figured it out with some MySQL trickery.</p>
<p>Given the following MySQL Database table named <tt>releases</tt>:</p>
<pre>
+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| title       | varchar(256)     | NO   |     | NULL    |                |
| releasedate | date             | NO   |     | NULL    |                |
+-------------+------------------+------+-----+---------+----------------+
</pre>
<p>I accomplished the dynamic <tt>ORDER BY</tt> clause by using the following query:</p>
<pre>
SELECT id,
       title,
       releasedate,
       UNIX_TIMESTAMP(releasedate) AS releasedate_unix,
       CASE WHEN releasedate > NOW() THEN 0 ELSE 1 END AS futureorpast
FROM releases
ORDER BY futureorpast ASC,
         CASE WHEN releasedate_unix > UNIX_TIMESTAMP(NOW()) THEN
            releasedate_unix
         ELSE
            (releasedate_unix * -1)
         END
</pre>
<p>Now for an explanation.  First, we need to "seperate" the results into two sets: future releases and past releases.  This is accomplished by calculating the <tt>futureorpast</tt> column upon which we can sort, so future releases are assigned a value of 0 while past releases are assigned a value of 1.  These are then sorted with future releases coming first, because obviously 0 comes before 1.</p>
<p>Next comes the tricky part: we want to sort future releases by <tt>ASC</tt> but past release by <tt>DESC</tt>.  This is unable to be accomplished using dynamic <tt>ASC</tt>/<tt>DESC</tt> in a <tt>CASE</tt> clause because you can only calculate <em>values</em> using <tt>CASE</tt>, not clauses.  The trick then is to convert the date column into a unix timestamp so that we have an integer, and then take the inverse of that integer on the values we want to sort in reverse.</p>
<p>Using this technique I was able to sort a subset of results in one direction and another subset of the same results in a different direction.  I'm not sure if this is the best way to accomplish this, so if anyone has other suggestions on how to accomplish this, I'd love to hear them!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tequilafish.com/2010/08/18/mysql-dynamic-order-by-clause/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to increase bash shell history length in OS X</title>
		<link>http://www.tequilafish.com/2010/08/11/how-to-increase-bash-shell-history-length-in-os-x/</link>
		<comments>http://www.tequilafish.com/2010/08/11/how-to-increase-bash-shell-history-length-in-os-x/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 04:52:28 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[histfilesize]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://www.tequilafish.com/?p=534</guid>
		<description><![CDATA[I do a lot of command line work on my OS X machine, so the history saves me a lot of time running repeat commands and also refreshing my memory on commands that I haven't run in a while. Unfortunately, the default history length in OS X is 500 commands. That seems like a lot, [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.tequilafish.com%2F2010%2F08%2F11%2Fhow-to-increase-bash-shell-history-length-in-os-x%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.tequilafish.com%2F2010%2F08%2F11%2Fhow-to-increase-bash-shell-history-length-in-os-x%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I do a lot of command line work on my OS X machine, so the history saves me a lot of time running repeat commands and also refreshing my memory on commands that I haven't run in a while.  Unfortunately, the default history length in OS X is 500 commands.  That seems like a lot, but when you're running 50+ commands a day it can push older commands off the list pretty quickly.  This is easily solved by setting the <tt>HISTFILESIZE</tt> in your <tt>.bash_profile</tt> file.</p>
<p>First, to find out what <tt>HISTFILESIZE</tt> is currently set at, run the following command from Terminal:</p>
<p><code>echo $HISTFILESIZE</code></p>
<p>To change this value, simply add the following line to your <tt>.bash_profile</tt> file (found in <tt>/Users/yourname/</tt>):</p>
<p><code>HISTFILESIZE=2000</code></p>
<p>This increases your bash history to 2000 items.  It will take effect next time you open a Terminal window.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tequilafish.com/2010/08/11/how-to-increase-bash-shell-history-length-in-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>eAccelerator and open_basedir: open_basedir restriction in effect. File() is not within the allowed path(s):</title>
		<link>http://www.tequilafish.com/2010/07/22/eaccelerator-and-open_basedir-open_basedir-restriction-in-effect-file-is-not-within-the-allowed-paths/</link>
		<comments>http://www.tequilafish.com/2010/07/22/eaccelerator-and-open_basedir-open_basedir-restriction-in-effect-file-is-not-within-the-allowed-paths/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 22:48:46 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[CentOS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.tequilafish.com/?p=417</guid>
		<description><![CDATA[After installing eAccelerator on a CentOS 5.5 server running PHP 5.2.10, a bunch of websites began failing with open_basedir errors like so: [Fri Jul 16 17:53:50 2010] [error] [client XX.XX.XXX.XXX] PHP Warning: require() [function.require]: open_basedir restriction in effect. File() is not within the allowed path(s): (/home/username/) in /home/username/public_html/wp-settings.php on line 19, referer: http://www.server.com/ After doing [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.tequilafish.com%2F2010%2F07%2F22%2Feaccelerator-and-open_basedir-open_basedir-restriction-in-effect-file-is-not-within-the-allowed-paths%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.tequilafish.com%2F2010%2F07%2F22%2Feaccelerator-and-open_basedir-open_basedir-restriction-in-effect-file-is-not-within-the-allowed-paths%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>After installing <a href="http://eaccelerator.net/">eAccelerator</a> on a CentOS 5.5 server running PHP 5.2.10, a bunch of websites began failing with open_basedir errors like so:</p>
<p><code>[Fri Jul 16 17:53:50 2010] [error] [client XX.XX.XXX.XXX] PHP Warning:  require() [<a href='function.require'>function.require</a>]: open_basedir restriction in effect. File() is not within the allowed path(s): (/home/username/) in /home/username/public_html/wp-settings.php on line 19, referer: http://www.server.com/</code></p>
<p>After doing some research it turns out that a default option that is compiled into eAccelerator is incompatible with open_basedir.  The fix is easy enough, simply re-compile with the <strong>--without-eaccelerator-use-inode</strong> option like so:</p>
<p><code>make clean<br />
phpize<br />
./configure --without-eaccelerator-use-inode<br />
make<br />
make install</code></p>
<p>After re-compiling and installing, make sure you clear out the existing eAccelerator files before restarting Apache:</p>
<p><code>rm -rf /var/cache/eaccelerator/*<br />
apachectl restart</code></p>
<p>eAccelerator states that the next version will have this compile option set by default.</p>
<p>Reference:</p>
<ul>
<li><a href="http://eaccelerator.net/ticket/414">http://eaccelerator.net/ticket/414</a></li>
<li><a href="http://eaccelerator.net/ticket/104">http://eaccelerator.net/ticket/104</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.tequilafish.com/2010/07/22/eaccelerator-and-open_basedir-open_basedir-restriction-in-effect-file-is-not-within-the-allowed-paths/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL: Global find &amp; replace</title>
		<link>http://www.tequilafish.com/2010/04/29/mysql-global-find-replace/</link>
		<comments>http://www.tequilafish.com/2010/04/29/mysql-global-find-replace/#comments</comments>
		<pubDate>Fri, 30 Apr 2010 02:25:05 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[replace]]></category>
		<category><![CDATA[update]]></category>

		<guid isPermaLink="false">http://www.tequilafish.com/?p=412</guid>
		<description><![CDATA[Global find &#038; replace is easy in MySQL: UPDATE table_name SET column_name = replace(column_name, "searchString", "replaceString");]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.tequilafish.com%2F2010%2F04%2F29%2Fmysql-global-find-replace%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.tequilafish.com%2F2010%2F04%2F29%2Fmysql-global-find-replace%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Global find &#038; replace is easy in MySQL:</p>
<p><code>UPDATE table_name SET column_name = replace(column_name, "searchString", "replaceString");</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tequilafish.com/2010/04/29/mysql-global-find-replace/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>OS X Snow Leopard Bugs: Audio gets reset to mute on reboot.</title>
		<link>http://www.tequilafish.com/2009/09/01/os-x-snow-leopard-bugs-audio-gets-reset-to-mute-on-reboot/</link>
		<comments>http://www.tequilafish.com/2009/09/01/os-x-snow-leopard-bugs-audio-gets-reset-to-mute-on-reboot/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 16:46:19 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://www.tequilafish.com/?p=402</guid>
		<description><![CDATA[While my upgrade to OS x 10.6 Snow Leopard has been mostly smooth, there are a few annoying bugs I've come across. This one has to do with audio - upon reboot, audio gets set to mute no matter what settings I had the volume on before. Not a big problem, but annoying none the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.tequilafish.com%2F2009%2F09%2F01%2Fos-x-snow-leopard-bugs-audio-gets-reset-to-mute-on-reboot%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.tequilafish.com%2F2009%2F09%2F01%2Fos-x-snow-leopard-bugs-audio-gets-reset-to-mute-on-reboot%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>While my upgrade to OS x 10.6 Snow Leopard has been mostly smooth, there are a few annoying bugs I've come across.  This one has to do with audio - upon reboot, audio gets set to mute no matter what settings I had the volume on before.  Not a big problem, but annoying none the less.  Here's how to fix it:</p>
<ol>
<li>In Finder, navigate to <strong>Macintosh HD &gt; Library &gt; Preferences &gt; Audio</strong></li>
<li>Delete the following files:
<ul>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>com.apple.audio.DeviceSettings.plist</strong></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>com.apple.audio.SystemSettings.plist</strong></li>
</ul>
</li>
<li>Open <strong>System Preferences &gt; Sound</strong></li>
<li>Set your sound to your preferred settings</li>
<li>Exit System Preferences and Reboot</li>
</ol>
<p>There you go!  After deleting those files, they will be re-created when you go into System Preferences and your audio will no longer be muted upon reboot.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tequilafish.com/2009/09/01/os-x-snow-leopard-bugs-audio-gets-reset-to-mute-on-reboot/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Windows XP: How to cancel a chkdsk or scandisk scheduled upon reboot</title>
		<link>http://www.tequilafish.com/2009/08/02/windows-xp-how-to-cancel-a-chkdsk-or-scandisk-scheduled-upon-reboot/</link>
		<comments>http://www.tequilafish.com/2009/08/02/windows-xp-how-to-cancel-a-chkdsk-or-scandisk-scheduled-upon-reboot/#comments</comments>
		<pubDate>Sun, 02 Aug 2009 16:38:31 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.tequilafish.com/?p=399</guid>
		<description><![CDATA[If you have a chkdsk or scandisk scheduled to run on a drive after your next reboot, normally you'd be able to cancel it by pressing any key 10 seconds before the scan starts. Unfortunately, my bluetooth keyboard/mouse combo didn't seem to work at this stage of bootup, so I was unable to cancel any [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.tequilafish.com%2F2009%2F08%2F02%2Fwindows-xp-how-to-cancel-a-chkdsk-or-scandisk-scheduled-upon-reboot%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.tequilafish.com%2F2009%2F08%2F02%2Fwindows-xp-how-to-cancel-a-chkdsk-or-scandisk-scheduled-upon-reboot%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>If you have a chkdsk or scandisk scheduled to run on a drive after your next reboot, normally you'd be able to cancel it by pressing any key 10 seconds before the scan starts.  Unfortunately, my bluetooth keyboard/mouse combo didn't seem to work at this stage of bootup, so I was unable to cancel any scan.  After some research I found out that the scheduled scan is simply a registry entry and that if you remove it, the scan wouldn't execute next time you reboot.  Here's how:</p>
<ol>
<li>Start &gt; Run &gt; regedt32</li>
<li>Navigate to <strong><tt>HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager</tt></strong></li>
<li>Open the <strong><tt>BootExecute</tt></strong> key</li>
<li>Remove the line that says: <strong><tt>autocheck autochk /r \??\E:</tt></strong> where "<tt>E:</tt>" is your drive letter</li>
<li>Exit Regedit and reboot, and no scan will execute</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.tequilafish.com/2009/08/02/windows-xp-how-to-cancel-a-chkdsk-or-scandisk-scheduled-upon-reboot/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Slicehost: Setting up a Tor relay on Fedora to help keep Iran connected #IranElection</title>
		<link>http://www.tequilafish.com/2009/06/21/slicehost-setting-up-a-tor-relay-on-fedora-to-help-keep-iran-connected-iranelection/</link>
		<comments>http://www.tequilafish.com/2009/06/21/slicehost-setting-up-a-tor-relay-on-fedora-to-help-keep-iran-connected-iranelection/#comments</comments>
		<pubDate>Sun, 21 Jun 2009 20:23:50 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Fedora]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Politics]]></category>
		<category><![CDATA[#iranelection]]></category>
		<category><![CDATA[bittorrent]]></category>
		<category><![CDATA[dcma]]></category>
		<category><![CDATA[iran]]></category>
		<category><![CDATA[relay]]></category>
		<category><![CDATA[slicehost]]></category>
		<category><![CDATA[tor]]></category>

		<guid isPermaLink="false">http://www.tequilafish.com/?p=319</guid>
		<description><![CDATA[As many of you know, most of the information from within Iran is coming from on-the-ground new-media and social networking sites such as Twitter, YouTube, and Facebook. This is happening despite crackdowns on communications networks by the Iranian government. The way this information is able to escape the firewalls of Iran is via proxies which [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.tequilafish.com%2F2009%2F06%2F21%2Fslicehost-setting-up-a-tor-relay-on-fedora-to-help-keep-iran-connected-iranelection%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.tequilafish.com%2F2009%2F06%2F21%2Fslicehost-setting-up-a-tor-relay-on-fedora-to-help-keep-iran-connected-iranelection%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>As many of you know, most of the information from within Iran is coming from on-the-ground new-media and social networking sites such as <a href="http://twitter.com/#search?q=%23iranelection">Twitter</a>, YouTube, and Facebook.  This is happening despite crackdowns on communications networks by the Iranian government.  The way this information is able to escape the firewalls of Iran is via proxies which relay and "hide" the destination of the communications so that it becomes difficult to block.  This allows those on the ground in Iran to communicate with the world instantly and effectively, without fear of government crackdown.  But it is a constant arms race.  As soon as a relay becomes known by the Iranian government it gets shut down.  The only way to keep the lines of communication open are to strengthen the distributed Tor network by adding more relays and bridges, making it more difficult for the Iranian government to block them all.</p>
<p>There have already been great write-ups on how you can contribute to the distributed proxy network <a href="http://www.torproject.org/">Tor</a>:<br />
<a href="http://anonygreen.wordpress.com/2009/06/18/how-to-setup-a-tor-relay-or-tor-bridge/">http://anonygreen.wordpress.com/2009/06/18/how-to-setup-a-tor-relay-or-tor-bridge/</a><br />
<a href="http://smokingfish.blogspot.com/2009/06/brief-introduction-to-tor-and-why-its.html">http://smokingfish.blogspot.com/2009/06/brief-introduction-to-tor-and-why-its.html</a></p>
<p>Please read over those documents for an overview.  I wanted to provide detailed instructions on how to get a Tor network set up quickly, easily, and cheaply for those of you who would like to contribute.  <strong style="color: #41A801;">You can provide invaluable assistance to the people of Iran for as little as 15 minutes of your time and $20/month</strong>.  </p>
<p><strong style="color: #41A801;">First off, this document assumes you have some system administration knowledge with Linux (Fedora) and are comfortable installing and configuring packages from the command line.</strong>  If that's you, you can have a Tor relay up and running in about 15 minutes.</p>
<p><strong>Key:</strong><br />
Shell commands are in <strong style="color: #9241AF;">purple</strong><br />
Config file settings are in <strong style="color: #3B6BBF;">blue</strong></p>
<ol>
<li>
<h2>Register at Slicehost</h2>
<p>Slicehost is a VPS provider that allows you to quickly build/deploy webservers very cheaply.  <a href="https://manage.slicehost.com/customers/new?flavor=1">Sign up here</a> and purchase the cheapest $20 slice to get started.  Pick <strong>Fedora 10</strong> as your Linux Distribution.  Do not pick Fedora 11, as it is incompatible with the current version of Tor.  Once you are registered, Slicehost will email you your IP and root password.  It can take a few minutes to build your new slice, so be patient.</li>
<li>
<h2>Slice Security</h2>
<p>Log in to your new slice.  Please note that this document covers the bare minimum of commands to get Tor up and running.  You should follow due diligence when it comes to securing your new slice, something which is outside the scope of this document.  Common practice security configurations are recommended.  <strong>Security is your own responsibility, and I will not be held liable for any security issues with your slice.</strong>  There are a few bare-minimum security things you should do to your slice:</p>
<p><strong>Change the root password:</strong><br />
<span style="color: #9241AF;">&nbsp;&nbsp;&nbsp;&nbsp;passwd root</span></p>
<p><strong>Create your own account &#038; set password:</strong><br />
<span style="color: #9241AF;">&nbsp;&nbsp;&nbsp;&nbsp;adduser yourusername<br />
&nbsp;&nbsp;&nbsp;&nbsp;passwd yourusername</span></p>
<p><strong>Disable root login to ssh</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #9241AF;">vim /etc/ssh/sshd_config</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;Change to this: <span style="color: #3B6BBF;">PermitRootLogin no</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #9241AF;">service sshd restart</span></p>
<p>These steps are the <strong>BARE MINIMUM</strong> you should do to secure your slice.
</li>
<li>
<h2>Update Your System</h2>
<p><span style="color: #9241AF;">yum -y update</span></li>
<li>
<h2>Install Prerequisites</h2>
<p><span style="color: #9241AF;">yum install wget vim-enhanced gcc make libevent libevent-devel openssl openssl-devel zlib zlib-devel rpm-build</span></li>
<li>
<h2>Download Tor &#038; Signature</h2>
<p><span style="color: #9241AF;"><br />
wget https://www.torproject.org/dist/rpm/tor-0.2.1.16.rc-tor.0.fc10.src.rpm<br />
wget https://www.torproject.org/dist/rpm/tor-0.2.1.16.rc-tor.0.fc10.src.rpm.asc<br />
</span></p>
</li>
<li>
<h2>Verify Packages</h2>
<p>Follow directions at <a href="http://www.torproject.org/verifying-signatures.html.en">http://www.torproject.org/verifying-signatures.html.en</a> to verify that you have an authentic RPM and not a fake.
</li>
<li>
<h2>Build &#038; Install Tor</h2>
<p><span style="color: #9241AF;"><br />
rpmbuild &#45;&#45;rebuild tor-0.2.1.16.rc-tor.0.fc10.src.rpm<br />
rpm -i rpmbuild/RPMS/x86_64/tor-0.2.1.16.rc-tor.0.fc10.x86_64.rpm<br />
</span>
</li>
<li>
<h2>Configure Tor</h2>
<p><span style="color: #9241AF;">vim /etc/tor/torrc</span></p>
<p>Change the following settings, substituting your own values for Nickname and Address:<br />
<span style="color: #3B6BBF;"><br />
DataDirectory /var/lib/tor<br />
ORPort 9001<br />
DirPort 9030<br />
Nickname YOUR_NICKNAME<br />
Address YOUR.IP.ADDRESS.XX<br />
</span><br />
Save &#038; Exit
</li>
<li>
<h2>Set Bandwidth Limits for Tor</h2>
<p>These settings are largely dependent on which slice you have purchased.  The ones you see below are for a 20GB slice, and they allow 2GB of transfer per day, so you should be well within the 20GB slice limit of 100GB/month.  If you have purchased a larger slice, these settings can be increased accordingly.  <strong style="color: #8F0808;">Be careful here, incorrect settings can push you over your monthly bandwidth limit very quickly!</strong>  I did over 12GB of transfer in a little over 8 hours before limiting bandwidth with these settings.</p>
<p><span style="color: #9241AF;">vim /etc/tor/torrc</span><br />
<span style="color: #3B6BBF;"><br />
RelayBandwidthRate 64 KBytes<br />
RelayBandwidthBurst 128 KBytes<br />
AccountingStart day 12:00<br />
AccountingMax 2 GB<br />
</span><br />
Save &#038; Exit.  The AccountingStart and AccountingMax settings will limit 2GB max transfer per day, resetting at 12:00 every day.  The RelayBandwidthRate and RelayBandwidthBurst settings throttle the bandwidth so that you don't reach AccountingMax after only a few hours.  Normally AccountingStart and AccountingMax would be enough to stay within your bandwidth limits, but I want my relay to be available all day rather than reaching AccountingMax and shutting down after a few hours.
</li>
<li>
<h2>Configure Your Firewall</h2>
<p><span style="color: #9241AF;">iptables-save > /etc/sysconfig/iptables.default<br />
iptables-save > /etc/sysconfig/iptables.test<br />
vim /etc/sysconfig/iptables.test<br />
</span><br />
Insert the following settings:<br />
<span style="color: #3B6BBF;"><br />
	# tor ORPort &#038; DirPort<br />
	-A INPUT -p tcp --dport 9001 -j ACCEPT<br />
	-A INPUT -p tcp --dport 9030 -j ACCEPT</span></p>
<p><span style="color: #3B6BBF;"><br />
	# tor Allow all outbound traffic<br />
	-A OUTPUT -j ACCEPT<br />
</span><br />
Save &#038; Exit.<br />
<span style="color: #9241AF;"><br />
iptables-restore < /etc/sysconfig/iptables.test<br />
iptables -L</span> (verify the rules are correct)<br />
<span style="color: #9241AF;">iptables-save > /etc/sysconfig/iptables</span><br />
</span></li>
<li>
<h2>Increase the number of open file descriptors</h2>
<p><span style="color: #9241AF;">vim /etc/security/limits.conf</span></p>
<p>Add this line:</p>
<p><span style="color: #3B6BBF;">_tor hard nofile 32768</span></p>
<p>Save &#038; Exit
</li>
<li>
<h2>Start up the Tor Service</h2>
<p><span style="color: #9241AF;">service tor start</span></li>
<p>If everything starts correctly, you should see output like this:<br />
<code>Starting tor: Jun 21 15:44:04.219 [notice] Tor v0.2.1.15-rc. This is experimental software. Do not rely on it for strong anonymity. (Running on Linux x86_64)<br />
Jun 21 15:44:04.219 [notice] Your ContactInfo config option is not set. Please consider setting it, so we can contact you if your server is misconfigured or something else goes wrong.<br />
Jun 21 15:44:04.223 [notice] Initialized libevent version 1.4.5-stable using method epoll. Good.<br />
Jun 21 15:44:04.223 [notice] Opening OR listener on 0.0.0.0:9001<br />
Jun 21 15:44:04.223 [notice] Opening Directory listener on 0.0.0.0:9030<br />
Jun 21 15:44:04.223 [notice] Opening Socks listener on 127.0.0.1:9050<br />
/usr/bin/torctl start: tor started  [  OK  ]</code></p>
<p>Also, you should view the tor.log and verify that you see the following (after 20-minutes):</p>
<p><span style="color: #9241AF;">cat /var/log/tor/tor.log</span></p>
<p><code>Jun 21 15:44:13.835 [notice] Tor has successfully opened a circuit. Looks like client functionality is working.<br />
Jun 21 15:44:13.835 [notice] Bootstrapped 100%: Done.<br />
Jun 21 15:44:13.835 [notice] Now checking whether ORPort XXX.XXX.XXX.XXX:9001 and DirPort XXX.XXX.XXX.XXX:9030 are reachable.. (this may take up to 20 minutes &#45;&#45; look for log messages indicating success)<br />
Jun 21 15:44:18.492 [notice] Self-testing indicates your DirPort is reachable from the outside. Excellent.<br />
Jun 21 15:44:18.492 [notice] Not advertising DirPort (Reason: AccountingMax enabled)<br />
Jun 21 15:44:26.804 [notice] Self-testing indicates your ORPort is reachable from the outside. Excellent. Publishing server descriptor.<br />
Jun 21 15:44:43.813 [notice] Performing bandwidth self&#45;test.. done.</code></p>
<p>If you see some errors or it doesn't start correctly, post in the comments and I'll see if I can help you out.  Here are some references to help you get it going:<br />
<a href="http://www.torproject.org/docs/tor-doc-unix.html.en#installing">http://www.torproject.org/docs/tor-doc-unix.html.en#installing</a><br />
<a href="http://www.torproject.org/docs/tor-doc-relay.html.en">http://www.torproject.org/docs/tor-doc-relay.html.en</a>
</ol>
<p>That's it!  You now have a fully functioning Tor Relay and are helping the Iranian people get news and information out to the rest of the world.  The cool thing about Slicehost is that you can easily upgrade your Slice with the click of a button to allow more bandwidth, RAM, and other resources.  They also have a Clone option so that once you have your initial Tor slice running, you can clone it multiple times so that you can have multiple Tor servers at a time.</p>
<p>More good reads on Tor and its effect in Iran:<br />
<a href="http://blog.torproject.org/blog/measuring-tor-and-iran">http://blog.torproject.org/blog/measuring-tor-and-iran</a><br />
<a href="http://p10.hostingprod.com/@spyblog.org.uk/blog/2009/06/tor-relays-and-exit-nodes-for-iran-and-for-the-rest-of-us.html">http://p10.hostingprod.com/@spyblog.org.uk/blog/2009/06/tor-relays-and-exit-nodes-for-iran-and-for-the-rest-of-us.html</a></p>
<h2>Update 1 - Preventing Abuse by BitTorrent Users</h2>
<p>A couple of days after setting up my Tor slice, I received a Digital Millennium Copyright Act (“DMCA”) notice that my relay was hosting copyrighted material and that I would be required to remove it or face having my Slice shut down.  Turns out that there are people out there using BitTorrent over the Tor network to transfer copyrighted material.  Philosophical debates about BitTorrent and copyright law aside, the whole reason why I am running Tor is to help those in Iran stay connected -- not to assist in the distribution of copyrighted material.  So, after a few minutes of research, I found out we can prevent Tor being used by BitTorrent by adjusting your <strong>ExitPolicy</strong>:</p>
<p><span style="color: #9241AF;">vim /etc/tor/torrc</span></p>
<p>Add the following:<span style="color: #3B6BBF;"><br />
  ExitPolicy reject *:1214<br />
  ExitPolicy reject *:4661-4666<br />
  ExitPolicy reject *:6346-6429<br />
  ExitPolicy reject *:6881-6999<br />
</span><br />
Save &amp; Exit<br />
Restart Tor: <span style="color: #9241AF;">service tor restart</span></p>
<p>You should also probably follow the advice at <a href="http://blog.torproject.org/blog/tips-running-exit-node-minimal-harassment">http://blog.torproject.org/blog/tips-running-exit-node-minimal-harassment</a></p>
<p>References:<br />
<a href="http://www.torproject.org/faq.html.en#ExitPolicies">http://www.torproject.org/faq.html.en#ExitPolicies</a> - Exit Policies in Tor<br />
<a href="https://www.torproject.org/eff/tor-dmca-response.html">https://www.torproject.org/eff/tor-dmca-response.html</a> - DCMA Response Template<br />
<a href="http://www.orient-lodge.com/node/3622?dsq=11687593">http://www.orient-lodge.com/node/3622?dsq=11687593</a> - A Slicehost user who also received a DCMA notice<br />
<a href="http://www.chrisbrunner.com/?p=119">http://www.chrisbrunner.com/?p=119</a> - Why You Shouldn’t Run BitTorrent Over Tor</p>
<h2>Update 2 - Slicehost Responds</h2>
<p>After making the adjustments above, I notified Slicehost of my changes and they have responded:<br />
<code>Thank you for your response.  We will go ahead and consider this matter resolved.  Thank you for your attention to this matter.</code><br />
Gotta give them credit for understanding that we're trying to help people in Iran -- not to pirate movies.  Thanks Slicehost!</p>
<h2>Update 3 - Upgraded to 0.2.1.16 &#038; Config Adjustments</h2>
<p>I received some configuration recommendations from Andrew Lewman of The Tor Project, and have updated the steps above accordingly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tequilafish.com/2009/06/21/slicehost-setting-up-a-tor-relay-on-fedora-to-help-keep-iran-connected-iranelection/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Dojo: How to get the ID of an element.</title>
		<link>http://www.tequilafish.com/2009/06/18/dojo-how-to-get-the-id-of-an-element/</link>
		<comments>http://www.tequilafish.com/2009/06/18/dojo-how-to-get-the-id-of-an-element/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 04:12:55 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Dojo]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[dojo javascript id]]></category>

		<guid isPermaLink="false">http://www.tequilafish.com/?p=312</guid>
		<description><![CDATA[To get the ID of an element using Dojo Framework, you need to use the dojo.attr function. Given the following HTML: &#60;img src=&#34;/path/to/imageA.jpg&#34; id=&#34;myImage1&#34; /&#62; &#60;img src=&#34;/path/to/imageB.jpg&#34; id=&#34;myImage2&#34; /&#62; &#60;img src=&#34;/path/to/imageC.jpg&#34; id=&#34;myImage3&#34; /&#62; You can get the IDs of each image in Dojo like so: dojo.query(&#34;img&#34;).forEach(function(currentNode) { &#160;&#160;&#160;&#160;var theElementId = dojo.attr(currentNode, &#34;id&#34;); &#160;&#160;&#160;&#160;console.log(&#34;id: &#34;, theElementId); [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.tequilafish.com%2F2009%2F06%2F18%2Fdojo-how-to-get-the-id-of-an-element%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.tequilafish.com%2F2009%2F06%2F18%2Fdojo-how-to-get-the-id-of-an-element%2F&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>To get the ID of an element using Dojo Framework, you need to use the <strong>dojo.attr</strong> function.</p>
<p>Given the following HTML:</p>
<p><code>&lt;img src=&quot;/path/to/imageA.jpg&quot; id=&quot;myImage1&quot; /&gt;<br />
&lt;img src=&quot;/path/to/imageB.jpg&quot; id=&quot;myImage2&quot; /&gt;<br />
&lt;img src=&quot;/path/to/imageC.jpg&quot; id=&quot;myImage3&quot; /&gt;</code></p>
<p>You can get the IDs of each image in Dojo like so:</p>
<p><code>dojo.query(&quot;img&quot;).forEach(function(currentNode) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;var theElementId = <strong>dojo.attr(currentNode, &quot;id&quot;)</strong>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;console.log(&quot;id: &quot;, theElementId); // debug<br />
});</code></p>
<p>If you have debugging on and something like Firebug, the console output would be like so:</p>
<p><code>id: myImage1<br />
id: myImage2<br />
id: myImage3</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tequilafish.com/2009/06/18/dojo-how-to-get-the-id-of-an-element/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

