<?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>The Code Cave</title>
	<atom:link href="http://thecodecave.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://thecodecave.com</link>
	<description>Cold storage before my best ideas melt away...</description>
	<lastBuildDate>Wed, 01 Sep 2010 14:39:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
		<item>
		<title>Alternate version of &#8220;The Loop&#8221;</title>
		<link>http://thecodecave.com/2010/09/01/alternate-version-of-the-loop/</link>
		<comments>http://thecodecave.com/2010/09/01/alternate-version-of-the-loop/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 14:39:41 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://thecodecave.com/?p=846</guid>
		<description><![CDATA[OK So, most theme developers are aware of what the loop is&#8230; it displays your WordPress posts. The one interesting thing about the loop is that it bounces in and out of the php and straight html output.  So, most of the functions that are called do the echoes themselves.  But what if need the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2010%2F09%2F01%2Falternate-version-of-the-loop%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2010%2F09%2F01%2Falternate-version-of-the-loop%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>OK So, most theme developers are aware of what the loop is&#8230; it displays your WordPress posts.</p>
<p>The one interesting thing about the loop is that it bounces in and out of the php and straight html output.  So, most of the functions that are called do the echoes themselves.  But what if need the output in a variable, or want to code it so that the call is part of its own echo function? You simply cannot use the same functions.</p>
<p>Fortunately WordPress provides two versions  of each of these core functions.  For example there is the_content and get_the_content() also the_permalink() and get_permalink() (yes, that inconsistency has ALWAYS bothered me..)</p>
<p>Here is a version of  &#8221;The Loop&#8221; which calls all of the alternate versions of the functions:</p>
<blockquote><p>if (have_posts()) {</p>
<p style="padding-left: 30px;">while (have_posts()) {</p>
<p style="padding-left: 60px;">the_post();<br />
echo &#8216;&lt;div id=&#8221;post-&#8217; . the_ID() . &#8216;&#8221;&gt;&#8217;;<br />
echo &#8216;	&lt;div&gt;&lt;/div&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;	&lt;div&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;		&lt;div&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;			&lt;h2&gt;&lt;a href=&#8221;&#8216; . get_permalink() . &#8216;&#8221; rel=&#8221;bookmark&#8221; title=&#8221;Permanent Link to &#8216; . the_title_attribute(&#8216;echo=0&#8242;) . &#8216;&#8221;&gt;&#8217; . the_title(&#8216;echo=0&#8242;) . &#8216;&lt;/a&gt;&lt;/h2&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;			&lt;small&gt; &lt;!&#8211; by &#8216; . get_the_author() . &#8216; &#8211;&gt;&lt;/small&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;			&lt;div&gt;&#8217; . &#8220;\n&#8221;;<br />
$content = get_the_content();<br />
$content = apply_filters(&#8216;the_content&#8217;, $content);<br />
$content = str_replace(&#8216;]]&gt;&#8217;, &#8216;]]&amp;gt;&#8217;, $content);<br />
echo $content . &#8220;\n&#8221;;<br />
echo &#8216;			&lt;/div&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;		&lt;/div&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;	&lt;/div&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;	&lt;div&gt;&lt;/div&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;&lt;/div&gt;&#8217; . &#8220;\n&#8221;;</p>
<p style="padding-left: 30px;">}</p>
<p style="padding-left: 30px;">echo &#8216;&lt;div&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;	&lt;div&gt;&#8217; .  next_posts_link(&#8216;&amp;laquo; Older Entries&#8217;) . &#8216;&lt;/div&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;	&lt;div&gt;&#8217; . previous_posts_link(&#8216;Newer Entries &amp;raquo;&#8217;) . &#8216;&lt;/div&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;&lt;/div&gt;&#8217; . &#8220;\n&#8221;;</p>
<p>} else {</p>
<p style="padding-left: 30px;">echo &#8216;&lt;h2&gt;Not Found&lt;/h2&gt;&#8217; . &#8220;\n&#8221;;<br />
echo &#8216;&lt;p&gt;&#8217; . &#8220;Sorry, but you are looking for something that isn&#8217;t here.&#8221; . &#8216;&lt;/p&gt;&#8217; . &#8220;\n&#8221;;<br />
get_search_form();</p>
<p>}</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2010/09/01/alternate-version-of-the-loop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing SVN (Server &amp; Client) on CentOS</title>
		<link>http://thecodecave.com/2010/08/27/installing-svn-server-client-on-centos/</link>
		<comments>http://thecodecave.com/2010/08/27/installing-svn-server-client-on-centos/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 05:47:14 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Random thoughts]]></category>

		<guid isPermaLink="false">http://thecodecave.com/?p=837</guid>
		<description><![CDATA[The process is EXTREMELY simple. One line to install SVN, two to create the repository, and one to run the daemon: yum install subversion.i386 mkdir /svn svnadmin create /svn/my-repo/ svnserve -d Here&#8217;s what my results produced (The first line confirms I have subversion available in yum): [root@hosting ~]# yum list &#124; grep &#8216;subversion&#8217; subversion.i386 1.4.2-4.el5_3.1 [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2010%2F08%2F27%2Finstalling-svn-server-client-on-centos%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2010%2F08%2F27%2Finstalling-svn-server-client-on-centos%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>The process is EXTREMELY simple. One line to install SVN, two to create the repository, and one to run the daemon:</p>
<blockquote><p>yum install subversion.i386 mkdir /svn svnadmin create /svn/my-repo/ svnserve -d</p></blockquote>
<blockquote><p>Here&#8217;s what my results produced (The first line confirms I have subversion available in yum): [root@hosting ~]# yum list | grep &#8216;subversion&#8217; subversion.i386                          1.4.2-4.el5_3.1               base subversion-devel.i386                    1.4.2-4.el5_3.1               base subversion-javahl.i386                   1.4.2-4.el5_3.1               base subversion-perl.i386                     1.4.2-4.el5_3.1               base subversion-ruby.i386                     1.4.2-4.el5_3.1               base [root@hosting ~]# yum install subversion.i386 Loaded plugins: fastestmirror Determining fastest mirrors addons                                                                                                               |  951 B     00:00 base                                                                                                                 | 2.1 kB     00:00 extras                                                                                                               | 2.1 kB     00:00 updates                                                                                                              | 1.9 kB     00:00 wiredtree                                                                                                            |  951 B     00:00 Excluding Packages in global exclude list Finished Setting up Install Process Resolving Dependencies &#8211;&gt; Running transaction check &#8212;&gt; Package subversion.i386 0:1.4.2-4.el5_3.1 set to be updated &#8211;&gt; Processing Dependency: perl(URI) &gt;= 1.17 for package: subversion &#8211;&gt; Processing Dependency: neon &gt;= 0.25.5-6.el5 for package: subversion &#8211;&gt; Processing Dependency: libneon.so.25 for package: subversion &#8211;&gt; Processing Dependency: libapr-1.so.0 for package: subversion &#8211;&gt; Processing Dependency: libaprutil-1.so.0 for package: subversion &#8211;&gt; Running transaction check &#8212;&gt; Package apr.i386 0:1.2.7-11.el5_3.1 set to be updated &#8212;&gt; Package apr-util.i386 0:1.2.7-11.el5 set to be updated &#8211;&gt; Processing Dependency: libpq.so.4 for package: apr-util &#8212;&gt; Package neon.i386 0:0.25.5-10.el5_4.1 set to be updated &#8212;&gt; Package wt-URI.noarch 0:1.35-1 set to be updated &#8211;&gt; Processing Dependency: perl(Business::ISBN) for package: wt-URI &#8211;&gt; Running transaction check &#8212;&gt; Package postgresql-libs.i386 0:8.1.21-1.el5_5.1 set to be updated &#8212;&gt; Package wt-Business-ISBN.noarch 0:2.00_01-1 set to be updated &#8211;&gt; Processing Dependency: perl(Business::ISBN::Data) &gt;= 1.09 for package: wt-Business-ISBN &#8211;&gt; Running transaction check &#8212;&gt; Package wt-Business-ISBN-Data.noarch 0:1.13-1 set to be updated &#8211;&gt; Finished Dependency Resolution  Dependencies Resolved  ============================================================================================================================================ Package                                  Arch                      Version                              Repository                    Size ============================================================================================================================================ Installing: subversion                               i386                      1.4.2-4.el5_3.1                      base                         2.3 M Installing for dependencies: apr                                      i386                      1.2.7-11.el5_3.1                     base                         123 k apr-util                                 i386                      1.2.7-11.el5                         base                          80 k neon                                     i386                      0.25.5-10.el5_4.1                    base                         101 k postgresql-libs                          i386                      8.1.21-1.el5_5.1                     updates                      196 k wt-Business-ISBN                         noarch                    2.00_01-1                            wiredtree                    353 k wt-Business-ISBN-Data                    noarch                    1.13-1                               wiredtree                     12 k wt-URI                                   noarch                    1.35-1                               wiredtree                    146 k  Transaction Summary ============================================================================================================================================ Install       8 Package(s) Upgrade       0 Package(s)  Total download size: 3.3 M Is this ok [y/N]: y Downloading Packages: (1/8): wt-Business-ISBN-Data-1.13-1.noarch.rpm                                                                       |  12 kB     00:00 (2/8): apr-util-1.2.7-11.el5.i386.rpm                                                                                |  80 kB     00:00 (3/8): neon-0.25.5-10.el5_4.1.i386.rpm                                                                               | 101 kB     00:00 (4/8): apr-1.2.7-11.el5_3.1.i386.rpm                                                                                 | 123 kB     00:00 (5/8): wt-URI-1.35-1.noarch.rpm                                                                                      | 146 kB     00:00 (6/8): postgresql-libs-8.1.21-1.el5_5.1.i386.rpm                                                                     | 196 kB     00:00 (7/8): wt-Business-ISBN-2.00_01-1.noarch.rpm                                                                         | 353 kB     00:00 (8/8): subversion-1.4.2-4.el5_3.1.i386.rpm                                                                           | 2.3 MB     00:00 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; Total                                                                                                       1.6 MB/s | 3.3 MB     00:02 Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction Installing     : apr                                                                                                                  1/8 Installing     : neon                                                                                                                 2/8 Installing     : postgresql-libs                                                                                                      3/8 Installing     : wt-Business-ISBN-Data                                                                                                4/8 Installing     : apr-util                                                                                                             5/8 Installing     : wt-URI                                                                                                               6/8 Installing     : subversion                                                                                                           7/8 Installing     : wt-Business-ISBN                                                                                                     8/8  Installed: subversion.i386 0:1.4.2-4.el5_3.1  Dependency Installed: apr.i386 0:1.2.7-11.el5_3.1                     apr-util.i386 0:1.2.7-11.el5                neon.i386 0:0.25.5-10.el5_4.1 postgresql-libs.i386 0:8.1.21-1.el5_5.1         wt-Business-ISBN.noarch 0:2.00_01-1         wt-Business-ISBN-Data.noarch 0:1.13-1 wt-URI.noarch 0:1.35-1  Complete! [root@hosting ~]# mkdir /svn [root@hosting ~]# svnadmin create /svn/my-repo/ [root@hosting ~]# svnserve -d</p></blockquote>
<p>The last thing to do is to configure the password if you want one.</p>
<blockquote><p>vi /svn/my-repo/conf/svnserve.conf</p></blockquote>
<blockquote><p>vi /svn/my-repo/conf/passwd</p></blockquote>
<p>The details of those two files are beyond the scope of this post. Besides I&#8217;m sure you&#8217;ll want to triple check, as every one else does, that the svn password file is in plain text. Yes, that&#8217;s correct. Plain text.  That makes you think about all the svn repositories that you used secure passwords to access now doesn&#8217;t it?</p>
<blockquote></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2010/08/27/installing-svn-server-client-on-centos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Determining what versions of WordPress you are hosting</title>
		<link>http://thecodecave.com/2010/08/10/determining-what-versions-of-wordpress-you-are-hosting/</link>
		<comments>http://thecodecave.com/2010/08/10/determining-what-versions-of-wordpress-you-are-hosting/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 21:30:19 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[LINUX]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://thecodecave.com/?p=817</guid>
		<description><![CDATA[If you host lots of different sites for people, one of the things you might want to know is what versions of WordPress each site is running. WordPress stores the version number in a variable named $wp_version which is set in the file version.php. With that information in hand, you can write a bash command [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2010%2F08%2F10%2Fdetermining-what-versions-of-wordpress-you-are-hosting%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2010%2F08%2F10%2Fdetermining-what-versions-of-wordpress-you-are-hosting%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>If you host lots of different sites for people, one of the things you might want to know is what versions of WordPress each site is running.</p>
<p>WordPress stores the version number in a variable named $wp_version which is set in the file version.php.</p>
<p>With that information in hand, you can write a bash command that you run from your /home directory to display all of the WordPress versions you have on your server:</p>
<blockquote><p>find . -name version.php -type f|xargs grep ^\$wp_version</p></blockquote>
<p>This is one of the aliases I have in my .bashrc file.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2010/08/10/determining-what-versions-of-wordpress-you-are-hosting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Up Reporting Tools</title>
		<link>http://thecodecave.com/2010/08/09/building-up-reporting-tools/</link>
		<comments>http://thecodecave.com/2010/08/09/building-up-reporting-tools/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 02:23:11 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Random thoughts]]></category>

		<guid isPermaLink="false">http://thecodecave.com/?p=812</guid>
		<description><![CDATA[While working with Lee Newton over at b5media I was able to watch him build up some server tools over time that were invaluable to diagnosing exactly what was going on on the server. Now I find I need to make some of my own. Here&#8217;s how I am doing it. For now I am [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2010%2F08%2F09%2Fbuilding-up-reporting-tools%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2010%2F08%2F09%2Fbuilding-up-reporting-tools%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>While working with <a href="http://www.blogmeetsworld.com/">Lee Newton</a> over at b5media I was able to watch him build up some server tools over time that were invaluable to diagnosing exactly what was going on on the server.</p>
<p>Now I find I need to make some of my own.  Here&#8217;s how I am doing it.</p>
<p>For now I am going to concentrate on access logs.</p>
<p>Where these logs are varies server by server, but if you are running a standard cPanel setup, chances are you can find a directory named /usr/local/apache/domlogs with files in it named after your domain name. In this case I picked one of the sites I host: nakedpastor.com</p>
<p>So if I do a:</p>
<blockquote><p>cd /usr/local/apache/domlogs<br />
tail -10 nakedpastor.com
</p></blockquote>
<p>I will get the last 10 lines of the access log file</p>
<p>Here&#8217;s one example: </p>
<blockquote><p>24.555.555.27 &#8211; - [09/Aug/2010:20:13:45 -0400] &#8220;GET /wp-content/uploads/2010/08/IMG_0001.jpg HTTP/1.1&#8243; 304 &#8211; &#8220;http://www.nakedpastor.com/&#8221; &#8220;Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_3 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7E18 Safari/528.16&#8243;</p></blockquote>
<p>Someone on an iPhone is looking at a picture on the site (which David would get more Google Juice from if he had named it better).</p>
<p>The trick is going to be to break down that line into important bits of information that will help me diagnose how my server is being used.  For example, I might want to know if one IP address is flooding me.  I might want to know if I am getting a HUGE number of requests for one particular file or if I am serving a large number of errors.  If I ran this on a combined log file I, I would want to know if one domain was getting all of the traffic.  Top referrers might be a fun thing to look at too. There are lots of little bits of info in there that could be helpful. </p>
<p>My tool chest includes:</p>
<blockquote><p>tail &#8211;  request a certain number of lines from the END of the file as shown above. During testing I will use -15  to get the last 15 lines but when I make this live, I&#8217;ll want to look at the last several thousand at least.<br />
head &#8211; requests the number of lines at the top of a file. In this case it gives me the most pertinent results<br />
sort &#8211; Will put the most important results at the top<br />
cut &#8211; probably not helpful initially as the fields are not fixed width<br />
awk &#8211; Used to parse the lines into chunks so I can see what is important. <a href="http://www.cyberciti.biz/faq/bash-scripting-using-awk/">See also here</a><br />
grep &#8211; Used to search for text<br />
uniq &#8211;  Used with -c  uniq counts the number of occurrences of each variance<br />
| &#8211; The piping symbol used to send the results of one command right into the next.
</p></blockquote>
<p>Let&#8217;s go after something simple first. The IP address.  I want to take the last 100 lines of the error log, get the the ip address which will be the first word in the line, count how many times each ip address is used, sort it numerically by count and return the top 10.  In bash, that is pronounced as: </p>
<blockquote><p>tail -10000 /usr/local/apache/domlogs/nakedpastor.com | awk &#8216;{print $1}&#8217; | sort | uniq -c | sort -nr | head -10</p></blockquote>
<p>You can find examples of that line lots of places out there.  In fact I copied and pasted that from another site. Their line used a &#8220;tail -n&#8221; instead of &#8220;head&#8221;, but it did the same thing You may want to note that you have to call sort before you call uniq in order for unique to work right..</p>
<p>For the rest of the examples I&#8217;m going to use the awk command to break down the line into separate fields separated by quotes or spaces.  this line prints the number 7 because there are 7 fields separated by quotes:</p>
<blockquote><p>tail -5 nakedpastor.com|awk  -F &#8216;&#8221;&#8216; &#8216;{c=NF; print c}&#8217;
</p></blockquote>
<p>If I search for quotes and then search for space, I can get the result code</p>
<blockquote><p>tail -15 nakedpastor.com|awk  -F &#8216;&#8221;&#8216; &#8216;{print $3}&#8217;|awk &#8216;{print $1}&#8217;</p></blockquote>
<p>Or the requested page:</p>
<blockquote><p>tail -15 nakedpastor.com|awk  -F &#8216;&#8221;&#8216; &#8216;{print $2}&#8217;|awk &#8216;{print $2}&#8217;</p></blockquote>
<p>Or the referrer:</p>
<blockquote><p>tail -15 nakedpastor.com|awk  -F &#8216;&#8221;&#8216; &#8216;{print $4}&#8217;|awk &#8216;{print $1}&#8217;</p></blockquote>
<p>Or the agent:</p>
<blockquote><p>tail -15 nakedpastor.com|awk  -F &#8216;&#8221;&#8216; &#8216;{print $6}&#8217;|awk &#8216;{print $1}&#8217;</p></blockquote>
<p>So using these examples I can get the 20 most popular agent/OS combos:</p>
<blockquote><p> tail -1000 /usr/local/apache/domlogs/nakedpastor.com | awk  -F &#8216;&#8221;&#8216; &#8216;{print $6}&#8217;| sort | uniq -c | sort -nr | head -20</p></blockquote>
<p>So, there you have some tools to use the next time you want to see what is going on on your server.  Along with free -m and top you can get some neat info.</p>
<p>Just remember that you are getting snapshots.  When I looked a little bit ago. Knowmore.com&#8217;s bot took up 1390 of the 10000 lines I was looking at.  That&#8217;s over 10% of the traffic going to just that bot.  HOWEVER if I looked at 5000 lines, they didn&#8217;t appear at all. Looking at 100000 lines they only appeared 1394 times.  So, don&#8217;t just use one sample size. It can be misleading.</p>
<p>I will probably take these lines and combine them into some .bachrc functions along the line of what I&#8217;d discussed in my <a href="http://thecodecave.com/2010/06/21/three-helpful-additions-to-your-bashrc/">Three helpful additions to your .bashrc</a> post. </p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2010/08/09/building-up-reporting-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress Security &#8211; a plugin done right.</title>
		<link>http://thecodecave.com/2010/06/22/wordpress-security-a-plugin-done-right/</link>
		<comments>http://thecodecave.com/2010/06/22/wordpress-security-a-plugin-done-right/#comments</comments>
		<pubDate>Tue, 22 Jun 2010 16:49:24 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://thecodecave.com/?p=769</guid>
		<description><![CDATA[It&#8217;s rare that I open the source code for a random plugin and see every recommended security measure taken. When looking at Chris Boyd&#8216;s plugin GeoLocation Plugin, I kept digging deeper and deeper and found he&#8217;d consistently covered everything. This plugin is a text book example of how to write a secure plugin. Since he [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2010%2F06%2F22%2Fwordpress-security-a-plugin-done-right%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2010%2F06%2F22%2Fwordpress-security-a-plugin-done-right%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>It&#8217;s rare that I open the source code for a random plugin and see every recommended security measure taken.  When looking at <a href="http://twitter.com/chrisboyddotnet">Chris Boyd</a>&#8216;s plugin <a href="http://geo.chrisboyd.net/">GeoLocation Plugin</a>, I kept digging deeper and deeper and found he&#8217;d consistently covered everything.  This plugin is a text book example of how to write a secure plugin.</p>
<p>Since he has so many techniques in here, this post wrote itself in my head. It was irresistible.</p>
<p>I strongly recommend you <a href="http://wordpress.org/extend/plugins/geolocation/">download</a> the plugin and open geolocation.php to follow along</p>
<p>So, here are the security methods I saw him use, there may be more I didn&#8217;t catch, if so feel free to add them to the comments:</p>
<h3>Use nonces on all input forms</h3>
<p>Chances are your plugin will ask for information. A nonce is a security token that helps guarantee that you are getting real data from a real user.  In function geolocation_inner_custom_box() Chris calls</p>
<blockquote><p><tt>
<pre>
echo '&lt;input type="hidden" id="geolocation_nonce" name="geolocation_nonce"
	value="' .     wp_create_nonce(plugin_basename(__FILE__) ) . '" /&gt;';
</pre>
<p></tt></p></blockquote>
<p>to add the nonce to his input form and then to check this on the processing side in function geolocation_save_postdata he calls:</p>
<blockquote><p><tt>
<pre>
  // Check authorization, permissions, autosave, etc
  if (!wp_verify_nonce($_POST['geolocation_nonce'], plugin_basename(__FILE__)))
    return $post_id;
</pre>
<p></tt></p></blockquote>
<p>This is very simple code.  There&#8217;s almost no cost to adding nonces to form processing and you can use that exact code, just changing the name of the field.  This will block most bots from abusing your plugin.</p>
<h3>Verify the user&#8217;s permissions</h3>
<p>The user_can functions go hand in hand with the nonces and they work together to block the same kind of attacks.  If your plugin does something that just anyone off the street shouldn&#8217;t be able to do, verify that the user is allowed to do it. This check is just a little bit further into function geolocation_save_postdata:</p>
<blockquote><p><tt>
<pre>
  if('page' == $_POST['post_type'] ) {
    if(!current_user_can('edit_page', $post_id))
		return $post_id;
  } else {
    if(!current_user_can('edit_post', $post_id))
		return $post_id;
  }
</pre>
<p></tt></p></blockquote>
<p>This simple check to confirm that the user is allowed to edit a post before the geotagging information is added and ties the plugin directly into all of the security already built into WordPress. It is tremendously powerful.</p>
<h3>Configure default values</h3>
<p>In programming 101, you learn never to trust the computer to give you a clean value for an uninitialized variable. In web development, there are even more implications to this. Caching is one of those.  If you call get_option and WordPress does not have a value, it will access the database to see if there is a value set. Until a value is stored in the database, WordPress has to keep looking for it on every page load. Anything you can do that avoids accessing the database files and quite possibly the hard drives where the information is stored, will make your site run faster.  If a value is found, that value will be loaded from the cache automatically. Additionally, if you set your default values, you know what you are getting back.  Chris handles this in function default_settings():</p>
<blockquote><p><tt>
<pre>
function default_settings() {
	if(get_option('geolocation_map_width') == '0')
		update_option('geolocation_map_width', '450');

	if(get_option('geolocation_map_height') == '0')
		update_option('geolocation_map_height', '200');

	if(get_option('geolocation_default_zoom') == '0')
		update_option('geolocation_default_zoom', '16');

	if(get_option('geolocation_map_position') == '0')
		update_option('geolocation_map_position', 'after');
}
</pre>
<p></tt></p></blockquote>
<h3>Use the Settings API and let WordPress do all the work</h3>
<p>WordPress 2.7 added a wonderful set of tools called the Settings API. Most plugins do not take advantage of this complex tool set when they could.  Chris uses the register_setting API call in function register_settings to enumerate the type of data he wants in each field.</p>
<blockquote><p><tt>
<pre>
function register_settings() {
  register_setting( 'geolocation-settings-group',
		'geolocation_map_width', 'intval' );
  register_setting( 'geolocation-settings-group',
		'geolocation_map_height', 'intval' );
  register_setting( 'geolocation-settings-group',
		'geolocation_default_zoom', 'intval' );
  register_setting( 'geolocation-settings-group',
		'geolocation_map_position' );
  register_setting( 'geolocation-settings-group',
		'geolocation_wp_pin');
}
</pre>
<p></tt></p></blockquote>
<p>As you can see he specifies that certain values must be integers. Chris doesn&#8217;t take full advantage of the API in this plugin. In fact, I&#8217;m not convinced that simply calling register_setting on its own does anything. It is meant to be used with other calls.  Had he used them all WordPress could have handled all sorts of things for him automatically, including the nonce field and additional checks.</p>
<p>The settings API is POWERFUL but has a steep learning curve. Once you pass the learning curve your input form printing just becomes five lines:</p>
<blockquote><p><tt>
<pre>
&lt;form action="options.php" method="post"&gt;
	&lt;?php settings_fields('plugin_options'); ?&gt;
	&lt;?php do_settings_sections(__FILE__); ?&gt;
	&lt;input name="Submit" type="submit"
		value="&lt;?php esc_attr_e('Save Changes'); ?&gt;" /&gt;
&lt;/form&gt;
</pre>
<p></tt></p></blockquote>
<p>This topic is WAAAAAAY to big to cover here and I freely admit, I&#8217;m no expert on it. I recommend that you read more: <a href="http://planetozh.com/blog/2009/05/handling-plugins-options-in-wordpress-28-with-register_setting/">A quick &#038; dirty example</a> or <a href="http://www.presscoders.com/wordpress-settings-api-explained/">The Whole Shebang</a></p>
<h3>Verify your data</h3>
<p>The last two topics are related as the come from the same rule: ALL data that you get from ANY source must be verified.  This is where many plugins fail. The assumption is that &#8220;if it is in the database, it must be clean&#8221; or &#8220;it&#8217;s from an RSS feed, I know the data is good&#8221; or &#8220;The variable has INT in the name so it obviously contains an integer&#8221; or any of a thousand other gotyas.  The way to keep yourself safe from an assumption is to VERIFY.<br />
I want to highlight just two examples of this in Chris&#8217;s code.</p>
<p>First, in function display_location, he uses a cast to ensure the data he gets is what he wants from post meta:</p>
<blockquote><p><tt>
<pre>
$public = (bool)get_post_meta($post->ID, 'geo_public', true);
</pre>
<p></tt></p></blockquote>
<p>Second a function clean_coordinates uses regex to ensure the value he receives is what he wants:</p>
<blockquote><p><tt>
<pre>
$latitude = clean_coordinate($_POST['geolocation-latitude']);
[..]
function clean_coordinate($coordinate) {
	$pattern = '/^(\-)?(\d{1,3})\.(\d{1,15})/';
	preg_match($pattern, $coordinate, $matches);
	return $matches[0];
}
</pre>
<p></tt></p></blockquote>
<h3>Escape all variable data you display</h3>
<p>I won&#8217;t show specific examples of this as they are everywhere throughout the whole plugin, but this is one of the most important steps you can take to make your plugin secure.  It is also one of the areas that has has the most focus in the WordPress core over the years.  </p>
<p>If you are displaying a value that isn&#8217;t hard coded in your source, you need to first feed it through one of these functions (or something similar):</p>
<blockquote><p><tt>
<pre>
esc_attr()	Cleans HTML attributes for use on screen
esc_html()	Prepares complete blocks of HTML code
esc_js()	Special javascript handling of quotes and EOL characters
esc_sql()	Escapes data for use in a query
esc_url()	Returns a valid URL if possible
esc_url_raw()	Prepares an URL to be inserted in a database
</pre>
<p></tt></p></blockquote>
<p>This applies to values you are putting into javascript, urls you are displaying on the screen or using for includes, and data used to build image references.  All this information must be sanitized. Visit the codex for more information on <a href="http://codex.wordpress.org/Data_Validation">data validation</a>.</p>
<h3>Bonus Tip</h3>
<p>If you&#8217;ve made it this far in the post, you get one more tip for free. DON&#8217;T DO IT ALL YOURSELF.  I&#8217;d be willing to wager that this plugin was not &#8216;born&#8217; with all of these security techniques in place.  Though this plugin is attributed to Chris in the repository, he lists multiple authors for the plugin.  You don&#8217;t HAVE to do all of this by yourself. Once your plugin is done, ask people to review it.  I can pretty much guarantee that someone will find something. That&#8217;s just how it works.  But won&#8217;t you feel much better if your friend catches the problem before it is discovered because your plugin added an avenue of attack to every site it&#8217;s been installed on?  Someone will be glad to review it for you it.  That&#8217;s part of what is great about the WordPress community: people love to help.</p>
<h3>Summation</h3>
<p>Website security will forever be an on going battle. It is a big, complicated subject with nuances you can miss easily. However, WordPress has been around long enough to have build up quite a collection of tools you have at your disposal as a plugin author.  If use the tools WordPress provides, following Chris&#8217;s example outlined here, you can rest easy at night knowing you&#8217;ve done your job well.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2010/06/22/wordpress-security-a-plugin-done-right/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Three helpful additions to your .bashrc</title>
		<link>http://thecodecave.com/2010/06/21/three-helpful-additions-to-your-bashrc/</link>
		<comments>http://thecodecave.com/2010/06/21/three-helpful-additions-to-your-bashrc/#comments</comments>
		<pubDate>Tue, 22 Jun 2010 02:23:15 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[LINUX]]></category>

		<guid isPermaLink="false">http://thecodecave.com/?p=744</guid>
		<description><![CDATA[I just made a change to my .bashrc file and I thought I would share the tip. All of this is pretty basic stuff, but if you don&#8217;t customize your linux logins, this would be a good place to start. For Microsoft people who don&#8217;t know, .bashrc is in some ways like a combined config.sys [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2010%2F06%2F21%2Fthree-helpful-additions-to-your-bashrc%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2010%2F06%2F21%2Fthree-helpful-additions-to-your-bashrc%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>I just made a change to my .bashrc file and I thought I would share the tip.  All of this is pretty basic stuff, but if you don&#8217;t customize your linux logins, this would be a good place to start.</p>
<p>For Microsoft people who don&#8217;t know, .bashrc is in some ways like a combined config.sys and autoexec.bat file.  If you don&#8217;t know what an autoexec.bat file is, you totally missed the 80s dudes&#8230; </p>
<p>In a *nix environment, the rc at the end of a file name typically means that it is a &#8220;run control&#8221; file.  Run Control files execute when a program starts. In this case, the program is bash &#8211; the command line interpreter/shell. Other programs look for rc files too.  Because of this, you could have bunches of them in your home directory.  The . at the front of the file name indicates that they are hidden from a normal directory listing. This way they don&#8217;t clutter up your home.</p>
<p>I have lots of neat things in my .bashrc file that add functionality to my default CLI.  I&#8217;ll be sharing just three of those with you now.</p>
<p>The first is an alias: ebrc. When I type ebrc and press enter, I&#8217;m taken immediately into an editor with my .bashrc file open.  You can think of an alias as a single line shortcut.  It looks like this:</p>
<blockquote><p><tt>
<pre>
alias ebrc='vi ~/.bashrc'
</pre>
<p></tt></p></blockquote>
<p>As you can see, it just says &#8220;when I type &#8216;ebrc&#8217;, treat it like I really typed &#8216;vi ~/.bashrc&#8217;&#8221;.</p>
<p>The second thing I used tonight was the alias brc:</p>
<blockquote><p><tt>
<pre>
alias brc='. ~/.bashrc'
</pre>
<p></tt></p></blockquote>
<p>That executes the .bashrc file again, so that all of the changes I&#8217;d just made are loaded.</p>
<p>You might ask &#8220;Can&#8217;t you just type all that out? You&#8217;re not saving much time.&#8221; Go ahead.. ask. I&#8217;ll wait&#8230; </p>
<p>OK. The answer is Yes. So, it is important that you don&#8217;t go overboard on this stuff.  If you use aliases too much, you&#8217;ll lose your familiarity with *nix and the skills to do your work on any other server.  So proceed with caution. This stuff can be addictive and detrimental to your guru health.</p>
<p>Now with those two helper aliases in hand, I added the function I really wanted to include: &#8216;upskel&#8217;.  It takes a task I might otherwise put off and allows it to be completed in 7 keypresses.  This is the perfect use case for a .bashrc function.  </p>
<p>&#8216;upskel&#8217; takes the latest version of WordPress and places it into the cpanel skeleton directory that is used as the base for every new account created on my hosting service <a href="http://ehermitsinc.com">eHermits, Inc.</a>.  So, every time an update comes out for WordPress, I can spend 5 seconds to grab the latest and all new accounts I create will be safe and updated.</p>
<p>Unlike an alias, this is done through a function call. Functions allow the use of multiple lines and variables.  Here is the call I just added:</p>
<blockquote><p><tt>
<pre>
function upskel()
{
  cd /root/cpanel3-skel
  rm -R public_html
  rm latest.zip*
  wget http://wordpress.org/latest.zip
  unzip latest.zip
  mv wordpress public_html
}
</pre>
<p></tt></p></blockquote>
<p>Technically I probably could have done that as an alias but a function is much easier to read with multiple lines involved.</p>
<p>As a bonus, here is a function that takes a variable:</p>
<blockquote><p><tt>
<pre>
function  ewpc()
{
  cd /home/$1*/
  pwd
  sudo vi ./public_html/wp-config.php
}
</pre>
<p></tt></p></blockquote>
<p>Can you tell me what it does?</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2010/06/21/three-helpful-additions-to-your-bashrc/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>WordPress DB Hacks: Determining the ID of a category parents</title>
		<link>http://thecodecave.com/2010/06/03/wordpress-db-hacks-determining-the-id-of-a-category-parents/</link>
		<comments>http://thecodecave.com/2010/06/03/wordpress-db-hacks-determining-the-id-of-a-category-parents/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 18:52:31 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://thecodecave.com/?p=741</guid>
		<description><![CDATA[When manipulating WordPress databases for exports and merges, sometimes it is helpful to get a list of all of the parents for the categories your posts are in. For the import I am working on right now.  The category list is being flattened from 30 categories down to 5 categories. The blog has just over [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2010%2F06%2F03%2Fwordpress-db-hacks-determining-the-id-of-a-category-parents%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2010%2F06%2F03%2Fwordpress-db-hacks-determining-the-id-of-a-category-parents%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>When manipulating WordPress databases for exports and merges, sometimes it is helpful to get a list of all of the parents for the categories your posts are in.</p>
<p>For the import I am working on right now.  The category list is being flattened from 30 categories down to 5 categories. The blog has just over 75 thousand posts in it and doing the conversion manually would be a rather arduous process to say the least.</p>
<p>So, I came up with this little query to give me the parent category for each of the child categories on that site.</p>
<p>It&#8217;s fairly simple but I&#8217;ve had to write it several times now and thought maybe someone else might need it sometime too:</p>
<blockquote><p><tt>SELECT `tt1`.`term_taxonomy_id` as 'Child Tax ID', `t1`.`term_id` as 'Child Term ID', `t1`.`name` as 'Child Name', `tt2`.`term_taxonomy_id` as 'Parent Tax ID', t2.`term_id` as 'Parent Term ID', `t2`.`name` as 'Parent Name' FROM `wp_term_taxonomy` `tt1`, `wp_term_taxonomy` `tt2`, `wp_terms` `t1`, `wp_terms` `t2` where `tt1`.`term_id` = `t1`.`term_id` and `tt1`.`parent` = `t2`.`term_id` and `tt1`.`taxonomy` = 'category' and `tt2`.`term_id` = `t2`.`term_id` and `tt2`.taxonomy = 'category';</tt></p></blockquote>
<p>Now I can just grab it instead of rewriting it again next time.  After all, this is The Code Cave&#8230;</p>
<p>PS &#8211; If you just want to see the top level categories, here&#8217;s how:</p>
<blockquote><p><tt>SELECT `tt1`.`term_taxonomy_id`, `t1`.`term_id`, `t1`.`name` FROM `wp_term_taxonomy` `tt1`, `wp_terms` `t1`where `tt1`.`term_id` = `t1`.`term_id` and `tt1`.`taxonomy` = 'category' and `tt1`.`parent`=0</tt></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2010/06/03/wordpress-db-hacks-determining-the-id-of-a-category-parents/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why does Facebook keep telling me my email address is broken</title>
		<link>http://thecodecave.com/2010/06/03/why-does-facebook-keep-telling-me-my-email-address-is-broken/</link>
		<comments>http://thecodecave.com/2010/06/03/why-does-facebook-keep-telling-me-my-email-address-is-broken/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 15:16:10 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Tips, Techniques and Technologies]]></category>

		<guid isPermaLink="false">http://thecodecave.com/?p=737</guid>
		<description><![CDATA[Periodically I would get messages from Twitter and Facebook telling me that my email address is invalid. I would just hit reconfirm and it would work fine for a while. When a client came to me and said he was getting the same messages, it became important to dig into it. What did I find? [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2010%2F06%2F03%2Fwhy-does-facebook-keep-telling-me-my-email-address-is-broken%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2010%2F06%2F03%2Fwhy-does-facebook-keep-telling-me-my-email-address-is-broken%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Periodically I would get messages from Twitter and Facebook telling me that my email address is invalid. I would just hit reconfirm and it would work fine for a while.</p>
<p>When a client came to me and said he was getting the same messages, it became important to dig into it. What did I find? The Spam Cop is to blame.</p>
<p><span id="more-737"></span></p>
<p><strong>What is an RBL and how does it block mail?</strong></p>
<p>In earlier articles, I wrote my own spam blocking program because I wanted to be in control of how spam was caught. I no longer use that method, but if you read those articles, you will know that a common way of blocking spam is by asking different services &#8220;Does the ip address associated with this email send out spam?&#8221;. If the answer is yes, you can mark the email as spam, delete it or reject it.</p>
<p>One of the services that can answer the &#8220;Is this a spammer&#8217;s ip address&#8221; question is SpamCop.net. They are an automated service that has a bunch of email addresses out there waiting for people to send them spam. This method of setting a trap address for people to send email to generates what is called a &#8220;<strong>R</strong>eal-time <strong>B</strong>lack-hole <strong>L</strong>ist&#8221; SpamCop is one of the most relied on black list out there.  The problem is that it includes both Twitter and Facebook ip addresses on the list.</p>
<p><strong>Do Facebook and Twitter send out spam?</strong></p>
<p>According to SpamCop&#8217;s position, the answer is yes and they know it:</p>
<blockquote><p>FaceBook servers are sending ordinary spam, so they should be on our list like any other spam source.</p>
<p>Reports are being send to spamcop[at]facebook.com. We&#8217;ve sent them over 30,000 reports.</p>
<p>I can&#8217;t help but think they should be aware of the problem.</p>
<p>- Don D&#8217;Minion &#8211; SpamCop Admin -</p>
<p>http://forum.spamcop.net/forums/lofiversion/index.php/t10783.html</p></blockquote>
<p>In short, SpamCop isn&#8217;t budging and Facebook isn&#8217;t budging so the sys admins have to.</p>
<p><strong>How do I fix this? </strong></p>
<p>I see two paths: one: don&#8217;t use SpamCop as a black list; two:<strong> </strong>whitelist the ips that are being blocked.</p>
<p>Your method of implementing those steps may be different than mine, but if you use WHM and Exim on your servers, the process is simple. Open WHM and type in &#8220;exim&#8221; in the Find box and then choose &#8220;Exim Configuration Editor&#8221;.  From that screen, in the RBLs section, you COULD uncheck &#8220;RBL: bl.spamcop.net&#8221; and hit save.</p>
<p>I decided that keeping SpamCop was important. So I logged into my server by SSH and made a list of all of the IPs that were blocked for Twitter and for Facebook using these two commands:</p>
<blockquote><p>[root@hosting ~]#  exigrep facebook /var/log/exim_mainlog*|grep spamcop|cut -f2 -d?|cut -f1 -d&#8217;&#8221;&#8216;|sort|uniq<br />
109.194.143.178<br />
115.113.120.132<br />
123.192.73.157<br />
123.238.17.88<br />
123.24.235.138<br />
124.124.46.13<br />
125.251.222.122<br />
173.9.236.229<br />
178.95.9.11<br />
186.69.26.122<br />
188.162.175.80<br />
190.121.131.98<br />
195.205.21.51<br />
195.93.160.116<br />
200.85.38.222<br />
203.115.75.158<br />
217.123.229.190<br />
217.20.167.105<br />
220.130.11.134<br />
41.177.21.237<br />
62.162.52.152<br />
69.63.178.160<br />
69.63.178.161<br />
69.63.178.162<br />
69.63.178.163<br />
69.63.178.164<br />
69.63.178.165<br />
69.63.178.166<br />
69.63.178.167<br />
69.63.178.168<br />
69.63.178.169<br />
69.63.178.170<br />
69.63.178.171<br />
69.63.178.172<br />
69.63.178.173<br />
69.63.178.174<br />
69.63.178.175<br />
69.63.178.176<br />
69.63.178.177<br />
69.63.178.178<br />
69.63.178.179<br />
69.63.178.180<br />
69.63.178.181<br />
69.63.178.182<br />
69.63.178.183<br />
69.63.178.184<br />
69.63.178.185<br />
69.63.178.186<br />
69.63.178.187<br />
69.63.178.188<br />
69.63.178.189<br />
69.63.178.190<br />
69.63.178.191<br />
77.247.234.66<br />
77.46.179.115<br />
78.188.203.15<br />
79.177.115.97<br />
82.207.120.217<br />
82.246.8.181<br />
85.71.36.197<br />
87.251.142.12<br />
89.211.57.250<br />
93.125.10.223<br />
93.87.96.245<br />
93.88.184.11<br />
94.233.12.74<br />
95.133.172.164<br />
97.77.191.218<br />
98.249.208.39<br />
[root@hosting ~]#  exigrep twitter /var/log/exim_mainlog*|grep spamcop|cut -f2 -d?|cut -f1 -d&#8217;&#8221;&#8216;|sort|uniq<br />
128.121.146.141<br />
128.121.146.142<br />
128.121.146.143<br />
128.121.146.144<br />
128.121.146.151<br />
128.121.146.152<br />
128.121.146.153<br />
[root@hosting ~]#</p></blockquote>
<p>Now that I had a list of all ip addresses ever blocked for Facebook and Twitter I went back to that Exim configuration screen and at the end of the RBLS section under &#8220;Whitelist: IPs that should not be checked against RBLs&#8221; I clicked edit and pasted those IP addresses in. I then restarted my Exim mail server right from the option built into WHM.</p>
<p>If you would like, you can use the addresses I&#8217;ve included here in this list. There may be new ips to add each month, so you might also want to generate your own list to make sure it is current.</p>
<p>Also, it would be nice if we could white list blocks of IP addresses. I know exim supports that but I&#8217;m not certain if WHM&#8217;s interface does. I want to try it sometime. then to whitelist all of the twitter addresses, you could just put &#8220;128.121.146.0/20&#8243; or something similar. If you try that and it works, let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2010/06/03/why-does-facebook-keep-telling-me-my-email-address-is-broken/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using find to copy specific files on linux</title>
		<link>http://thecodecave.com/2010/06/02/how-do-you-copy-specific-files-in-a-directory-tree/</link>
		<comments>http://thecodecave.com/2010/06/02/how-do-you-copy-specific-files-in-a-directory-tree/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 02:19:04 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[LINUX]]></category>

		<guid isPermaLink="false">http://thecodecave.com/?p=733</guid>
		<description><![CDATA[I was faced with a weird copy command I wanted to do today; so I thought I would share. How do you copy files in a directory tree to another directory? I wanted to copy all of the mp3 files in a directory tree over to one specific target directory. Initially I thought the command [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2010%2F06%2F02%2Fhow-do-you-copy-specific-files-in-a-directory-tree%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2010%2F06%2F02%2Fhow-do-you-copy-specific-files-in-a-directory-tree%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>I was faced with a weird copy command I wanted to do today; so I thought I would share.</p>
<p><strong>How do you copy files in a directory tree to another directory?</strong></p>
<p>I wanted to copy all of the mp3 files in a directory tree over to one specific target directory.</p>
<p>Initially I thought the command</p>
<blockquote><p>cp -r *.mp3 /target/directory/</p></blockquote>
<p>would work, but even though it specifies the &#8211;recursive option, it does not iterate the subdirectory looking for the mp3 files.</p>
<p>So I resorted to my every faithful companion: find -exec. It seems like this is one of the most useful tools in linux. In this case, here is the command line I used:</p>
<blockquote><p>find . -type f -name &#8216;*.mp3&#8242; -exec cp {} /targetdirectory/ \;</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2010/06/02/how-do-you-copy-specific-files-in-a-directory-tree/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to: Find files edited in the last day</title>
		<link>http://thecodecave.com/2010/02/15/how-to-find-files-edited-in-the-last-day/</link>
		<comments>http://thecodecave.com/2010/02/15/how-to-find-files-edited-in-the-last-day/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 08:11:56 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[LINUX]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/?p=720</guid>
		<description><![CDATA[The process is straight forwarded. There are several methods: find . -mtime -1 \! -type d -exec ls -l {} \; Or more simply find . -type f -mtime -1 In my case, I wanted to do more. First since I was searching an SVN repository, I wasted to exclude all of the extra files [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2010%2F02%2F15%2Fhow-to-find-files-edited-in-the-last-day%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2010%2F02%2F15%2Fhow-to-find-files-edited-in-the-last-day%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>The process is straight forwarded. There are several methods:<br />
<tt>
<pre>
find . -mtime -1 \! -type d -exec ls -l {} \;
</pre>
<p></tt></p>
<p>Or more simply<br />
<tt>
<pre>
find . -type f -mtime -1
</pre>
<p></tt></p>
<p>In my case, I wanted to do more. First since I was searching an SVN repository, I wasted to exclude all of the extra files that are touched by SVN. Additionally, the goal was to show which files contained a print_r function.</p>
<p>Here&#8217;s what I came up with:</p>
<p><tt>
<pre>
find . -path '*/.svn/*' -prune -o -type f -mtime -1 \
-exec echo '{}' \; -exec grep print_r {} \;
</pre>
<p></tt></p>
<p>Hope that helps!</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2010/02/15/how-to-find-files-edited-in-the-last-day/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why is AVG blocking legitimate sites?</title>
		<link>http://thecodecave.com/2009/10/15/why-is-avg-blocking-legitimate-sites/</link>
		<comments>http://thecodecave.com/2009/10/15/why-is-avg-blocking-legitimate-sites/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 18:05:15 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Tips, Techniques and Technologies]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/why-is-avg-blocking-legitimate-sites/</guid>
		<description><![CDATA[AVG is a “free” antivirus software package that has become fairly popular lately. The b5media tech team has been asked many times in the last 24 hours about why AVG is blocking legitimate sites. There is a FAQ on AVG’s site about this, but it is incomplete and, in my opinion, inaccurate*. People are asking [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F10%2F15%2Fwhy-is-avg-blocking-legitimate-sites%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F10%2F15%2Fwhy-is-avg-blocking-legitimate-sites%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>AVG is a “free” antivirus software package that has become fairly popular lately. The <a href="http://b5media.com">b5media</a> tech team has been asked many times in the last 24 hours about why AVG is blocking legitimate sites. There is a FAQ on AVG’s site about this, but it is incomplete and, in my opinion, inaccurate*. People are asking the questions in the AVG forum, but responses have just been long paragraphs explaining how they’ve asked the question in the wrong forum and links to the FAQ. I’ll attempt to better address the question here.</p>
<p>The <a href="http://free.avg.com/ww-en/faq.num-1700#faq_1700">FAQ</a> says:</p>
<blockquote><p>There are several possibilities how a clean and legitimate website may become infected:</p>
<ul>
<li>Website was exploited by some hacktoolkit which searches for vulnerable websites, and automatically infects them. </li>
<li>Infection was inserted on the machine that is used to create/upload websites, which means that the author&#8217;s/administrator&#8217;s computer is infected.</li>
<li>An attacker gained direct access to the website administration thanks to a weak or stolen access password. </li>
</ul>
<p>We recommend to contact the administrator of such website.</p>
</blockquote>
<p>This may have largely been true 5 years ago, but it isn’t now. Yes, breaches in security happen and always will. However, the most common vector for malware to get on today’s sites is through ads.&#160; These ads aren’t even ever seen by the webserver you are visiting**.&#160; </p>
<p>The <a href="http://free.avg.com/ww-en/faq.num-1700#faq_1700">FAQ</a> would be accurate if they added:</p>
<ul>
<li>The website is currently displaying an ad/image hosted on a site that AVG has deemed dangerous.</li>
</ul>
<p>The unprinted bullet point is:</p>
<ul>
<li>We mess up. We are humans. We are not perfect and neither are the tools we use. Sometimes we will say a site is infected when it isn’t. Sometimes we will say something is malware, that really is, but it is so common place that blocking it will make so many sites unusable that we will have to back down. When this happens, we will try to “fix” the issue as quickly as possible.</li>
</ul>
<p>This ad vector is something that all websites are fighting right now. It’s difficult because servers can be spotless and tight, but tools like AVG and the Google toolbar will see one of these ads (that we have nothing to do with) and will list that site as infected.&#160; If a bad ad is served when Google scans for infection, then the site is completely dropped from the Google index. NOT GOOD. Then the admin has to go and figure out which ad is bad and from that which ad manager let something slip through that they should have blocked.***</p>
<p>So, what is the current issue? Well, on October 14, 2009 AVG reclassified an ad/cookie used on a large majority of websites out there as dangerous. That&#8217;s why AVG is blocking familiar sites such as <a href="http://nytimes.com">http://nytimes.com</a>, <a href="http://imageshack.us">http://imageshack.us</a>, <a href="http://yahoo.co.uk">http://yahoo.co.uk</a>, <a href="http://babelfish.yahoo.com">http://babelfish.yahoo.com</a>, <a href="http://problogger.com">http://problogger.com</a> as well as other b5media entities like <a href="http://everyjoe.com">http://everyjoe.com</a> <a href="http://splendicity.com">http://splendicity.com</a> and <a href="http://blisstree.com">http://blisstree.com</a></p>
<p>Everything seems to point to ads.YieldManager.com as what is being blocked. Yieldmanager.com has an Alexa rating of <a href="http://www.alexa.com/siteinfo/yieldmanager.com">198</a>. Think what you want of Alexa, 198 means they are BIG. You probably know the name as they have been on most sites you&#8217;ve visit for years.&#160; YieldManager is run by <a href="http://en.wikipedia.org/wiki/Right_Media">Right Media</a>, which, since 2007, has been controlled by Yahoo. This is why the ip addresses, that come up in the AVG LinkScanner alerts, all point to Yahoo.</p>
<p>In short, AVG will either change this decision or lose market share. It won&#8217;t take long for them to make up their mind.</p>
<p>UPDATE: Around 9am the <a href="http://forums.avg.com/gb-en/avg-free-forum?sec=thread&amp;act=show&amp;id=23081&amp;type=0">forum</a> included a <a href="http://forums.avg.com/gb-en/avg-free-forum?sec=thread&amp;act=show&amp;id=23413#post_23413">post</a> stating “UPDATE&#8230;. It&#8217;s now been ascertained that it was actually a false positive. Please update the AVG on your system.”</p>
<p>Forum users report that AVG has changed their <a href="http://forums.avg.com/gb-en/avg-free-forum?sec=thread&amp;act=show&amp;id=23245#post_23245">statement</a> from:</p>
<blockquote><p>Let us inform you that this is not a false detection. Our LinkScanner     <br />technology detects a real threat, which is Geo-IP and also browser      <br />specific targeted, therefore it is detected only at www.yahoo.co.uk      <br />(IP: ) in Mozilla Firefox web browser only.</p>
</blockquote>
<p>Over <a href="http://forums.avg.com/gb-en/avg-free-forum?sec=thread&amp;act=show&amp;id=23451#post_23451">to</a>:</p>
<blockquote><p>Unfortunately, the previous AVG Link scanner database might have     <br />detected the mentioned web page as threat. However, after thorough      <br />analysis we can confirm that it was a false alarm. We have released a      <br />new Link scanner update that removes the false positive detection on      <br />this web page. Please update your AVG and check if your are able to      <br />open the web page properly.</p>
</blockquote>
<p>As you can also see from that thread, some people received an update this morning, but still are having problems on popular sites.&#160; My only suggestion is that you update AVG a few more times and hope that they allow you to surf your favorite sites.</p>
<p>&#160;</p>
<p>&#160;</p>
<p>&#160;</p>
<p>* Yes, I’ve submitted feedback about this.</p>
<p>** The way most ads work is a webpage will include instructions for your computer to say “Hey, you big sexy ad server, give me an ad to display.” when the page is loaded.&#160; At that point, the big sexy ad server says “Very well then. Go to ads.example.com and get the ad.”.&#160; Your computer then visits ads.example.com which can return any number of different ads. Some will be perfect nice ads. Some may be nasty infectious ads. Others will work on one browser, and throw errors on another.&#160; The site has no control over this. Really, neither does the big, sexy ad server (though it should run its own periodic checks) since the ad that appears at ads.example.com was probably legit when the ad was purchased. The ads that appear are only as reliably legit as the checks in place at that third party ad server. </p>
<p>*** That said, it is kinda interesting to look at all the sites out there listed as infected. For example go <a href="http://www.google.com/safebrowsing/diagnostic?site=benderblog.com/">here</a> to see an infected site and then bounce up from there into any of the 3 networks that site is hosted on. That will lead you to thousands of other infected listings.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/10/15/why-is-avg-blocking-legitimate-sites/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Brain Storming on Blocking Bad-ads</title>
		<link>http://thecodecave.com/2009/09/06/brain-storming-on-blocking-bad-ads/</link>
		<comments>http://thecodecave.com/2009/09/06/brain-storming-on-blocking-bad-ads/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 18:11:27 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Random thoughts]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/brain-storming-on-blocking-bad-ads/</guid>
		<description><![CDATA[I’m just jotting down some notes about using the Google Safe Browsing API to prevent a site from serving malicious/bad ads. Problem Defined Ads are put on a site via javascript by calls as simple as “getad(‘adposition1’)”. JavaScript is executed via the client’s browser after the page is served. Those calls don’t touch any of [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F09%2F06%2Fbrain-storming-on-blocking-bad-ads%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F09%2F06%2Fbrain-storming-on-blocking-bad-ads%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>I’m just jotting down some notes about using the Google Safe Browsing API to prevent a site from serving malicious/bad ads.</p>
<h1>Problem Defined</h1>
<ul>
<li>Ads are put on a site via javascript by calls as simple as “getad(‘adposition1’)”. JavaScript is executed via the client’s browser after the page is served. </li>
<li>Those calls don’t touch any of our servers, they go from the client to the Google/Glam/Whatever Ad Server. So we don’t see the ads before they appear on the customer screens. </li>
<li>The ads being served may be malicious
<ul>
<li>Any ad that is served can link to a site that has been infected. We will want to block this. </li>
<li>Any ad that is served can “take over” the page and redirect the page to a site that may or may not have malware. We want to block ALL take over attempts. </li>
<li>There may be other types of ads that we wish to block.&#160; Potentially we might wish to block specific ads on specific sites (i.e. a sexual connotations in ads on pre-teen audience sites). This may be beyond the initial scope and/or incur unwanted execution expenses. </li>
</ul>
</li>
<li>Serving a malicious ad can get a site listed as “infected” even though your server has had nothing to do with ANY of the ad content.
<ul>
<li><a title="http://www.google.com/safebrowsing/diagnostic?site=http://malware.testing.google.test/testing/malware/" href="http://www.google.com/safebrowsing/diagnostic?site=http://malware.testing.google.test/testing/malware/">http://www.google.com/safebrowsing/diagnostic?site=http://malware.testing.google.test/testing/malware/</a> </li>
<li><a title="http://www.google.com/safebrowsing/diagnostic?site=Folkalley.com" href="http://www.google.com/safebrowsing/diagnostic?site=Folkalley.com">http://www.google.com/safebrowsing/diagnostic?site=Folkalley.com</a> </li>
<li><a title="http://www.google.com/interstitial?url=http://malware.testing.google.test/testing/malware/" href="http://www.google.com/interstitial?url=http://malware.testing.google.test/testing/malware/">http://www.google.com/interstitial?url=http://malware.testing.google.test/testing/malware/</a></li>
</ul>
</li>
</ul>
<h1>Obstacles</h1>
<ul>
<li>Any extra calls WILL slow the page load process. </li>
<li>Each page load MUST call the ad serving script again </li>
<li>If an ad can be identified as bad, some other type of content must be served in that position to ensure page integrity. </li>
<li>The request for ad content HAS to come from the customer side because many ads are geo-specific and the customer’s IP determines what ad shows at what time. </li>
<li>You don’t want to set up a system where the site itself can submit a site as “bad” as anyone could sniff that info and seed our black list with bad data. </li>
<li>The results of the first getad() call could result in more javascript which must, in turn, be processed by the browser to produce the final ad. Potentially, several layers of JS could exist before the real ad is served. (e.g. 2 layers of indirection before ad: Google Ad Manager JS —serves—&gt; Glam Ad embeded JS call —serves—&gt; JS call to 3rd Party Ad Server —serves—&gt; Ad). This pattern is real and happens often. </li>
</ul>
<h1>Possible solutions</h1>
<ul>
<li>Status Quo: As problem sites are reported to us, determine which ad is bad, report it to the ad server &amp; hope they fix it before google sees it and lists the site as a dangerous site in it’s tool bar and in chrome.
<ul>
<li>Unless you are “lucky” you don’t get the badad. </li>
<li>Once you get the badad, it is hard to determine the initial JS that caused the problem </li>
</ul>
</li>
<li>Embed everything JS with its own iframe
<ul>
<li>Will block take overs</li>
<li>May or may not prevent Google from listing the site, probably not.</li>
<li>Will break ads that are contextual based</li>
</ul>
</li>
<li>Check the ad entirely on the client side via a black list: GSB API (<a title="http://code.google.com/apis/safebrowsing/" href="http://code.google.com/apis/safebrowsing/">http://code.google.com/apis/safebrowsing/</a>) or PhishTank (<a title="http://data.phishtank.com/data/online-valid.xml" href="http://data.phishtank.com/data/online-valid.xml">http://data.phishtank.com/data/online-valid.xml</a>)
<ul>
<li>This Good/Bad check could be done with a single call with the API call </li>
<li>Calls to external servers are dependent upon the health/bandwidth of that server </li>
<li>This could also be done via downloading the black list and checking off of that: <a title="http://code.google.com/p/jgooglesafebrowsing/wiki/Quick_Start_Guide" href="http://code.google.com/p/jgooglesafebrowsing/wiki/Quick_Start_Guide">http://code.google.com/p/jgooglesafebrowsing/wiki/Quick_Start_Guide</a> </li>
<li>Blacklist downloading would cost time and would have to be updated periodically. </li>
</ul>
</li>
<li>Implement a hybrid solution where a call is done to our servers to see if the an ad is good or bad.&#160; (Server side base code: <a title="http://lampsecurity.org/php-google-safe-browsing-api" href="http://lampsecurity.org/php-google-safe-browsing-api">http://lampsecurity.org/php-google-safe-browsing-api</a> )
<ul>
<li>Ad call is processed in JS eval (Will have to be checked for nested JS calls) </li>
<li>MD5 of ad is sent to the server. The results are Good/Bad/Unknown.&#160; (Pass the url?)</li>
<li>If the result is Good, ad is served and process exits </li>
<li>If the result is Bad, either go to step 1, or serve place holder/known good ad &amp; exit. </li>
<li>If the result is Unknown, send the JS to the server for verification. The server processes the code and returns a Good/Bad result. </li>
<li>If the result is Good, ad is served and process exits </li>
<li>If the result is Bad, either go to step 1, or serve place holder/known good ad &amp; exit </li>
</ul>
</li>
<li>Other solutions? </li>
</ul>
<h1>Reading</h1>
<ul>
<li>All your IFrames Point to us: <a title="http://googleonlinesecurity.blogspot.com/2008/02/all-your-iframe-are-point-to-us.html" href="http://googleonlinesecurity.blogspot.com/2008/02/all-your-iframe-are-point-to-us.html">http://googleonlinesecurity.blogspot.com/2008/02/all-your-iframe-are-point-to-us.html</a>&#160;<a title="http://research.google.com/archive/provos-2008a.pdf" href="http://research.google.com/archive/provos-2008a.pdf">http://research.google.com/archive/provos-2008a.pdf</a></li>
<li>The Ghost In The Browser <a title="http://www.provos.org/index.php?/archives/17-The-Ghost-In-The-Browser.html" href="http://www.provos.org/index.php?/archives/17-The-Ghost-In-The-Browser.html">http://www.provos.org/index.php?/archives/17-The-Ghost-In-The-Browser.html</a>&#160;<a title="http://www.usenix.org/events/hotbots07/tech/full_papers/provos/provos.pdf" href="http://www.usenix.org/events/hotbots07/tech/full_papers/provos/provos.pdf">http://www.usenix.org/events/hotbots07/tech/full_papers/provos/provos.pdf</a></li>
<li>Ask the Google Malware Team: <a title="http://moderator.appspot.com/#15/e=a77ea&amp;t=a9521" href="http://moderator.appspot.com/#15/e=a77ea&amp;t=a9521">http://moderator.appspot.com/#15/e=a77ea&amp;t=a9521</a></li>
<li>Cybercrime 2.0: When the Cloud Turns Dark <a title="http://queue.acm.org/detail.cfm?id=1517412" href="http://queue.acm.org/detail.cfm?id=1517412">http://queue.acm.org/detail.cfm?id=1517412</a></li>
<li>Google Online security <a title="http://googleonlinesecurity.blogspot.com/" href="http://googleonlinesecurity.blogspot.com/">http://googleonlinesecurity.blogspot.com/</a></li>
</ul>
<p>Anyway, I had this going through my head and wanted to get this all written out. So I can have a place to check back on this tomorrow…</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/09/06/brain-storming-on-blocking-bad-ads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting the error &#8216;cannot move &#8211; to a subdirectory of itself&#8217;?</title>
		<link>http://thecodecave.com/2009/08/19/getting-the-error-cannot-move-to-a-subdirectory-of-itself/</link>
		<comments>http://thecodecave.com/2009/08/19/getting-the-error-cannot-move-to-a-subdirectory-of-itself/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 22:28:32 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[LINUX]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/?p=666</guid>
		<description><![CDATA[This error message always bothered me because it makes no sense when I get it. Here&#8217;s my scenario&#8230; I have a directory that is used as the base for all new accounts I sell on my servers. The path is; /root/cpanel3-skel. I always put WordPress in that directory and I want to keep the latest [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F08%2F19%2Fgetting-the-error-cannot-move-to-a-subdirectory-of-itself%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F08%2F19%2Fgetting-the-error-cannot-move-to-a-subdirectory-of-itself%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>This error message always bothered me because it makes no sense when I get it.</p>
<p>Here&#8217;s my scenario&#8230;  I have a directory that is used as the base for all new accounts I sell on my servers.  The path is; /root/cpanel3-skel.  I always put WordPress in that directory and I want to keep the latest version of WP in that directory</p>
<blockquote><p>
[root@wiredtree ~]# rm -r wordpress latest.*<br />
rm: cannot remove `wordpress&#8217;: No such file or directory<br />
rm: cannot remove `latest.*&#8217;: No such file or directory<br />
[root@wiredtree ~]# wget -q http://wordpress.org/latest.zip<br />
[root@wiredtree ~]# unzip -q latest.zip<br />
[root@wiredtree ~]# mv -f wordpress/* /root/cpanel3-skel/public_html/<br />
mv: cannot move `wordpress/wp-admin&#8217; to a subdirectory of itself, `/root/cpanel3-skel/public_html/wp-admin&#8217;<br />
mv: cannot move `wordpress/wp-content&#8217; to a subdirectory of itself, `/root/cpanel3-skel/public_html/wp-content&#8217;<br />
mv: cannot move `wordpress/wp-includes&#8217; to a subdirectory of itself, `/root/cpanel3-skel/public_html/wp-includes&#8217;
</p></blockquote>
<p>WHAAAAT? Obviously it is not a subdirectory of itself&#8230;</p>
<p>Something strange is going on&#8230;  We get a little more information if we try to do a move from one device to another.  Take a look at this error message:</p>
<blockquote><p>
[root@wiredtree tmp]# mv -f wordpress/* /root/cpanel3-skel/public_html/<br />
mv: inter-device move failed: `wordpress/wp-admin&#8217; to `/root/cpanel3-skel/public_html/wp-admin&#8217;; unable to remove target: Is a directory<br />
mv: inter-device move failed: `wordpress/wp-content&#8217; to `/root/cpanel3-skel/public_html/wp-content&#8217;; unable to remove target: Is a directory<br />
mv: inter-device move failed: `wordpress/wp-includes&#8217; to `/root/cpanel3-skel/public_html/wp-includes&#8217;; unable to remove target: Is a directory
</p></blockquote>
<p>This reveals the true source of the error message.  In &#8220;mv &#8211;help&#8221;, the explanation of &#8220;-f&#8221; is too simplified and says only:  </p>
<blockquote><p>-f, &#8211;force                  do not prompt before overwriting
</p></blockquote>
<p>In &#8220;cp &#8211;h&#8221; we closer,but not exact, explanation of the real process, and one that better matches the inter-device error message:</p>
<blockquote><p>  -f, &#8211;force                  if an existing destination file cannot be opened, remove it and try again</p></blockquote>
<p>The final bit of information is in an Ubunto bug <a href="https://bugs.launchpad.net/ubuntu/+source/coreutils/+bug/71174">71174</a> &#8220;Misleading error message with mv and existing directories&#8221; where they change the error message to be &#8220;mv: cannot move `a&#8217; to `b/a&#8217;: Directory not empty&#8221;.</p>
<p>So there you have it.  <strong>You get that error message because the -f command tries first to remove the directory and can&#8217;t because it contains one or more files.</strong> You don&#8217;t get this message if the subdirectories are empty. The remove works fine on an empty directory but fails if there are files. The Linux core can&#8217;t correctly handle this exception and throws up what is probably the last error message in a switch/case statement &#8220;cannot move &#8211; to a subdirectory of itself&#8221;.</p>
<p>So what do you do about it? Well you can either empty the destination directory first, or you can copy the files and then delete the source directory. I chose the latter option and run this from the root folder:</p>
<blockquote><p>
rm -r wordpress latest.*<br />
wget -q http://wordpress.org/latest.zip<br />
unzip -q latest.zip<br />
cp -rf wordpress/* cpanel3-skel/public_html/<br />
rm -r wordpress latest.*
</p></blockquote>
<p>Cool?  Hope that helps someone&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/08/19/getting-the-error-cannot-move-to-a-subdirectory-of-itself/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to batch resize images from the Linux CLI</title>
		<link>http://thecodecave.com/2009/08/18/how-to-batch-resize-images-from-the-linux-cli/</link>
		<comments>http://thecodecave.com/2009/08/18/how-to-batch-resize-images-from-the-linux-cli/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 20:26:09 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Random thoughts]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/how-to-batch-resize-images-from-the-linux-cli/</guid>
		<description><![CDATA[You might find this little command useful, it allows you to create thumbnails for all the files in a particular directory: find . -maxdepth 1 -name *.jpg -print -exec convert &#34;{}&#34; -resize 80&#215;60 &#34;thumbs/{}&#34; \; &#160; This should work on any server with ImageMagick installed and in the path. &#160; Enjoy!]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F08%2F18%2Fhow-to-batch-resize-images-from-the-linux-cli%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F08%2F18%2Fhow-to-batch-resize-images-from-the-linux-cli%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>You might find this little command useful, it allows you to create thumbnails for all the files in a particular directory: </p>
<blockquote><p>find . -maxdepth 1 -name *.jpg -print -exec convert &quot;{}&quot; -resize 80&#215;60 &quot;thumbs/{}&quot; \; </p>
</blockquote>
<p>&#160;</p>
<p>This should work on any server with ImageMagick installed and in the path. </p>
<p>&#160;</p>
<p><a href="http://www.thecodecave.com/wp-content/uploads/2009/08/ImageMagickLogo.jpg"><img title="ImageMagickLogo" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="ImageMagickLogo" src="http://www.thecodecave.com/wp-content/uploads/2009/08/ImageMagickLogo_thumb.jpg" width="237" border="0" /></a><a href="http://www.thecodecave.com/wp-content/uploads/2009/08/ImageMagickLogo1.jpg"><img title="ImageMagickLogo" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="139" alt="ImageMagickLogo" src="http://www.thecodecave.com/wp-content/uploads/2009/08/ImageMagickLogo_thumb1.jpg" width="135" border="0" /></a> </p>
<p>  <br clear="all" />
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/08/18/how-to-batch-resize-images-from-the-linux-cli/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jeremy Wright sets sail to uncharted waters</title>
		<link>http://thecodecave.com/2009/07/27/jeremy-wright-sets-sail-to-uncharted-waters/</link>
		<comments>http://thecodecave.com/2009/07/27/jeremy-wright-sets-sail-to-uncharted-waters/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 18:42:47 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Announcements]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/?p=653</guid>
		<description><![CDATA[Jeremy Wright publicly announced today that he has has left the helm of b5media. My family owes a lot to Jeremy Wright. With Aaron Brazell, Jeremy brought me into b5media, full time in this world of new media. I&#8217;d not have made many of the friends I have today or traveled to some of the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F07%2F27%2Fjeremy-wright-sets-sail-to-uncharted-waters%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F07%2F27%2Fjeremy-wright-sets-sail-to-uncharted-waters%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Jeremy Wright publicly <a href="http://bit.ly/21VJyQ">announced</a> today that he has has left the helm of <a href="http://b5media.com">b5media</a>.</p>
<p>My family owes a lot to <a href="http://ensight.org">Jeremy Wright</a>.  With <a href="http://technosailor.com">Aaron Brazell</a>, Jeremy brought me into <a href="http://b5media.com">b5media</a>, full time in this world of new media. </p>
<p>I&#8217;d not have made many of the friends I have today or traveled to some of the places I&#8217;ve been, without Jeremy and his dream for b5.  He&#8217;s a good friend and a good man.  </p>
<p>Times have not always been easy, but Jeremy has had the courage to make the difficult decisions that allowed my family and many others to still put food on the table. This is only due to Jeremy&#8217;s leadership and the strength of those at b5&#8242;s helm. Other companies in our market space have not been fortunate enough to have the same caliber of leadership.</p>
<p>Thank you for all the hard work over the years Jeremy, from all of us.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/07/27/jeremy-wright-sets-sail-to-uncharted-waters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How do you get the current directory name in PHP?</title>
		<link>http://thecodecave.com/2009/07/01/how-do-you-get-the-current-directory-name-in-php/</link>
		<comments>http://thecodecave.com/2009/07/01/how-do-you-get-the-current-directory-name-in-php/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 04:00:05 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[directory name]]></category>
		<category><![CDATA[getcwd]]></category>
		<category><![CDATA[working directory]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/?p=644</guid>
		<description><![CDATA[I ran into a situation where I wanted to get the name of the directory I was in, in PHP. To be clear, I didn&#8217;t want the full path, just the directory/folder name To be clear, if I was working in the directory: /home/username/public_html/addonname I wanted to have addonname returned. I worked out two solutions. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F07%2F01%2Fhow-do-you-get-the-current-directory-name-in-php%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F07%2F01%2Fhow-do-you-get-the-current-directory-name-in-php%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>I ran into a situation where I wanted to get the <em>name</em> of the directory I was in, in PHP. To be clear, I didn&#8217;t want the full path, just the directory/folder name</p>
<p>To be clear, if I was working in the directory:<br />
<em>/home/username/public_html/addonname</em></p>
<p>I wanted to have <em>addonname</em> returned.</p>
<p>I worked out two solutions.</p>
<p>The first solution used the <a href="http://us3.php.net/manual/en/function.getcwd.php">getcwd()</a> function which returns the full directory path as shown above but to use the basename function to get the part I needed.  It worked so&#8230; &#8220;<em>echo basename(getcwd());</em>&#8221; returns &#8220;addonname&#8221; in this scenario.</p>
<p>That would meet my needs perfectly. I believe that matches my requirements in spirit, but was not literally correct.  That statement returned the current working directory, but not the directory where the file was located.  In fact, PHP 4 and PHP 5 differ when getcwd() is called from the command line.  If you are in the &#8216;/&#8217; directory and execute &#8220;<em>php /test/talktome.php</em>&#8220;, a php 4 getcwd() in that file will return the path &#8220;/test&#8221; while PHP 5 will correctly return &#8216;/&#8217;.</p>
<p>To resolve this, this next call works even better:<br />
&#8220;<em>echo basename(dirname(__FILE__));</em>&#8221;</p>
<p>Does anyone want to do some speed tests to see which is faster after 10,000 calls? Let us know your results.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/07/01/how-do-you-get-the-current-directory-name-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mafia Wars: Cuba &#8211; New BETA Screenshots</title>
		<link>http://thecodecave.com/2009/06/05/mafia-wars-cuba-new-beta-sreenshots/</link>
		<comments>http://thecodecave.com/2009/06/05/mafia-wars-cuba-new-beta-sreenshots/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 06:12:42 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Things that catch my eye]]></category>
		<category><![CDATA[beta]]></category>
		<category><![CDATA[Mafia Wars]]></category>
		<category><![CDATA[Mafia Wars: Cuba]]></category>
		<category><![CDATA[Screenshots]]></category>
		<category><![CDATA[Zynga]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/?p=627</guid>
		<description><![CDATA[A few weeks ago, I&#8217;d been asked to beta test the new levels for the popular Zynga Mafia Wars game. Mafia Wars is arguably the most popular and successful of the social media games developed by the recently Venture Capital funded company Zynga. To date, the 1.5 year old, profitable, VC backed Zynga has raised [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F06%2F05%2Fmafia-wars-cuba-new-beta-sreenshots%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F06%2F05%2Fmafia-wars-cuba-new-beta-sreenshots%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>A few weeks ago, I&#8217;d been asked to beta test the new levels for the popular Zynga Mafia Wars game.  Mafia Wars is arguably the most popular and successful of the social media games developed by the recently <a href="http://news.cnet.com/8301-1023_3-9997270-93.html">Venture Capital funded company Zynga</a>. To date, the 1.5 year old, profitable, VC backed Zynga has raised <a href="http://vator.tv/pitch/show/zynga">39 Million dollars in funding</a>.  As Mafia Wars is widely popular, there is bound to be great interest in this new Zynga release. </p>
<p>The story starts as I was about to crash for the night and made the mistake of turning on a computer screen.  Imagine my surprise when I noticed a &#8220;Fly to Cuba&#8221; button on the top of my Facebook Mafia Wars page.  In this beta release, there are new jobs hidden till you complete the next level and there are loads of new help topics and weapon descriptions and loot items revealed.   I&#8217;ve made certain to record as much as I can tonight and you can look forward to finding more information in The Code Cave about this new Mafia Wars module.  </p>
<blockquote><p>
My Mafia Wars links:<br />
<a href="http://bit.ly/FriendBrian">Be My Friend on Facebook</a><br />
<a href="http://bit.ly/JoinBriansMafia">Join My Mafia</a><br />
<a href="http://bit.ly/PromoteBrian">Promote me, [LSM] Capt. Queeg, if it will help you</a><br />
<a href="http://bit.ly/GiveToBrian">Send me Black Mail Photos!</a> I need 130 more
</p></blockquote>
<p>However, as I am likely to pass out on the keyboard at any moment, for today, you&#8217;ll have to be content with these tall images of the Mafia Wars: Cuba Home page and its first Jobs page. Enjoy:</p>
<div id="attachment_626" class="wp-caption aligncenter" style="width: 274px"><a href="http://www.thecodecave.com/wp-content/uploads/2009/06/mwc.png"><img src="http://www.thecodecave.com/wp-content/uploads/2009/06/mwc-264x300.png" alt="This is the initial page for Mafia Wars: Cuba. Notice the Shared Mafia Wars Resources." title="Mafia Wars: Cuba - Main page" width="264" height="300" class="size-medium wp-image-626" /></a><p class="wp-caption-text">This is the initial page for Mafia Wars: Cuba. Notice the Shared Mafia Wars Resources.</p></div>
<div id="attachment_625" class="wp-caption aligncenter" style="width: 275px"><a href="http://www.thecodecave.com/wp-content/uploads/2009/06/el_sodado.png"><img src="http://www.thecodecave.com/wp-content/uploads/2009/06/el_sodado-265x300.png" alt="Mafia Wars: Cuba - Jobs -  El Soldado - The Soldier" title="El Soldado" width="265" height="300" class="size-medium wp-image-625" /></a><p class="wp-caption-text">Mafia Wars: Cuba - Jobs -  El Soldado - The Soldier</p></div>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/06/05/mafia-wars-cuba-new-beta-sreenshots/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
		<item>
		<title>WordPress/WordPress mu Merge Definitively Confirmed</title>
		<link>http://thecodecave.com/2009/06/04/wordpresswordpress-mu-merge-definitively-confirmed/</link>
		<comments>http://thecodecave.com/2009/06/04/wordpresswordpress-mu-merge-definitively-confirmed/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 15:56:43 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Random thoughts]]></category>
		<category><![CDATA[Donncha]]></category>
		<category><![CDATA[Lorelle]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[WordCamp SF]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress mu]]></category>
		<category><![CDATA[wp-hackers]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/wordpresswordpress-mu-merge-definitively-confirmed/</guid>
		<description><![CDATA[There&#8217;s been rumor and confusion over the last week about whether WordPress and WordPress mu were merging as Matt seemed to imply at WordCamp SF. The announcement was so shocking that the true meaning was uncertain. For example, the avid WordPress evangelist Lorelle was left with the impression that WordPress.org would become a community site. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F06%2F04%2Fwordpresswordpress-mu-merge-definitively-confirmed%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F06%2F04%2Fwordpresswordpress-mu-merge-definitively-confirmed%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>There&#8217;s been rumor and confusion over the last week about whether WordPress and WordPress mu were merging as Matt seemed to imply at WordCamp SF.  The announcement was so shocking that the true meaning was uncertain. For example, the avid WordPress evangelist Lorelle was left with the impression that WordPress.org would become a community site.  Thankfully, Donncha, WordPress mu&#8217;s lead, gave the conclusive word on the subject <a href="http://ocaoimh.ie/2009/06/04/wordpress-mu-merge-gpl-and-support/">this morning</a>: </p>
<blockquote><p>
Basically, the thin layer of code that allows WordPress MU to host multiple WordPress blogs will be merged into WordPress. I expect the WordPress MU project itself will come to an end because it won’t be needed any more (which saddens me), but on the other hand many more people will be working on that very same MU code which means more features and more bugfixes and faster too.</p></blockquote>
<p>Donncha, I would view this with the honor it does you.  It is not much of a stretch to say that with your work on mu, you&#8217;ve made a lasting contribution to the shape of world and how people get information and will relate to each other over the upcoming years. More and more and more sites are run on mu, while the whole buddy press/bbpress/mu paradigm is taking off and will change the shape of the web. The adoption of the mu&#8217;s features into the WP core is a signal of what is to come and it will be an exciting ride!</p>
<p>Congrats guy!</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/06/04/wordpresswordpress-mu-merge-definitively-confirmed/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress 2.8 Beta 1 Released</title>
		<link>http://thecodecave.com/2009/05/17/now-on-wordpress-2-8-beta-1/</link>
		<comments>http://thecodecave.com/2009/05/17/now-on-wordpress-2-8-beta-1/#comments</comments>
		<pubDate>Sun, 17 May 2009 16:38:09 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/?p=617</guid>
		<description><![CDATA[While I was rolling around near comatose yesterday WordPress 2.8 beta 1 hit the streets. We plan to do a thorough review of this project on Thursday at the Ohio WordPress meetup here in Akron, Ohio. So, I figured it would would be a good time to run it officially here in The Code Cave. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F05%2F17%2Fnow-on-wordpress-2-8-beta-1%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F05%2F17%2Fnow-on-wordpress-2-8-beta-1%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>While I was rolling around near comatose yesterday <a href="http://wordpress.org/development/2009/05/wordpress-2-8-beta-1/">WordPress 2.8 beta 1 </a>hit the streets.  We plan to do a thorough review of this project on Thursday at the Ohio WordPress meetup here in Akron, Ohio. So, I figured it would would be a good time to run it officially here in The Code Cave.</p>
<p>The upgrade process is as simple as always. Unzip the file, copy it over the existing files, go to wp-admin upgrade and click continue.  When the official release comes out, I plan upgrading my wp-upgrade script as I still think it is useful. Even though WordPress itself has upgrade abilities within it, the full file backup and database backup that my script does, still provides added benefit.  So, I&#8217;ll keep it around a while longer.</p>
<p>As for WordPress 2.8, you don&#8217;t need to fear about learning a totally new system from scratch. There are a number of nice changes and tweaks, but the basic interface remains the same.  There are a lot of changes for plugin developers and the like, but the everyday users will see some things like the new widget drop zone that makes it easy to make a widget inactive without loosing its settings.  I&#8217;ll be testing over the next few weeks to see what I&#8217;d consider note worthy for a release post. I used to even do a line by line comparison, but I don&#8217;t know if I&#8217;ll don&#8217;t be returning to that. For now you can read about the changes <a href="http://wordpress.org/wordpress-2.8-beta1.zip">here</a>. </p>
<p>If there is any part of this upgrade that you definitely think we should cover at the Ohio WordPress Meetup, please let me know so that I don&#8217;t miss it!</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/05/17/now-on-wordpress-2-8-beta-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>2 for 1 Deal for Facebook Mafia Wars</title>
		<link>http://thecodecave.com/2009/05/05/2for1_deal_mafia_wars/</link>
		<comments>http://thecodecave.com/2009/05/05/2for1_deal_mafia_wars/#comments</comments>
		<pubDate>Tue, 05 May 2009 23:46:25 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Things that catch my eye]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Mafia Wars]]></category>
		<category><![CDATA[trade]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/?p=610</guid>
		<description><![CDATA[Send me 1 item on my wish list and put a message on my wall asking for any two items from this list and I&#8217;ll send them back to you. Make sure to provide a link to your profile or your profile name or I&#8217;ll not be able to find you. First Come: First Serve. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F05%2F05%2F2for1_deal_mafia_wars%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F05%2F05%2F2for1_deal_mafia_wars%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Send me 1 item on <a href="http://apps.facebook.com/inthemafia/remote/html_server.php?xw_controller=stats&#038;xw_action=view&#038;user=694300976">my wish list</a> and put a message on my wall asking for any two items from this list and I&#8217;ll send them back to you. Make sure to provide a link to your profile or your profile name or I&#8217;ll not be able to find you.  First Come: First Serve. So you might want to have a backup choice or two.  I&#8217;ll adjust this page as I run out of stuff.</p>
<p>Of course if you want to do this you&#8217;ll need to:<br />
<a href="http://bit.ly/FriendBrianOnFB">Add me as a Facebook Friend</a><br />
<a href="http://bit.ly/JoinBriansMafia  ">Join My Mafia</a><br />
<a href="http://bit.ly/PromoteBrian">Promote me</a> (I&#8217;ll give you at least a 13% bonus depending upon your level if you <a href="http://apps.facebook.com/inthemafia/remote/html_server.php?xw_time=1241567011&#038;xw_exp_sig=b18c207ae6c441515be823bb9d752355&#038;xw_controller=group&#038;xw_action=promote&#038;slot=bagman&#038;uid=694300976">Promote me as your Bagman</a>)</p>
<p>After less than 2 months of playing, I am a Level 160 Boss Mogul with master on every level up to underboss. I have 11 out of 14 achievements. I currently earn 111mil every 51 minutes. I&#8217;ve been leveling up 3 to 4 times every day, though I might hit 5 levels today.  With >1000 mafia members, I&#8217;m really raking in the experience points just by other ppl using me in fights.  So I should reach the max bagman bonus for you pretty quickly.</p>
<p>Here is what I am offering:</p>
<p>Ten of Diamonds<br />
Monkey Sculpture<br />
White Poker Chip</p>
<p>Ebony Cigar<br />
Sky Cigar<br />
Rose Cigar<br />
Ivory Cigar<br />
Turquoise Cigar<br />
Gold Cigar</p>
<p>Eight of Spades<br />
Nine of Spades<br />
Ten of Spades<br />
Jack of Spades<br />
Queen of Spades</p>
<p>Topaz Ring<br />
Opal Ring<br />
Amethyst Ring<br />
Sapphire Ring</p>
<p>Solid Tie<br />
Striped Tie<br />
Checked Tie<br />
Geometric Tie<br />
Dot Tie<br />
Knitted Tie</p>
<p>Warhol Painting<br />
Van Gogh Painting<br />
Dali Painting<br />
Monet Painting<br />
Rembrandt Painting</p>
<p>Silver Cufflinks<br />
Gold Cufflinks<br />
Amber Cufflinks<br />
Jasper Cufflinks<br />
Agate Cufflinks<br />
Onyx Cufflinks<br />
Pearl Cufflinks</p>
<p>Mill Reef<br />
Sea Bird<br />
Arkle<br />
Golden Miller<br />
St Simon<br />
Ormonde<br />
Eclipse</p>
<p>9mm Semi-Automatic<br />
.22 Pistol<br />
Butterfly Knife<br />
Brass Knuckles<br />
.45 Revolver<br />
Firebomb<br />
Automatic Rifle<br />
Semi-Automatic Shotgun<br />
C4<br />
Tactical Shotgun<br />
.50 Caliber Rifle<br />
RPG Launcher<br />
Grenade Launcher</p>
<p>Stab-Proof Vest<br />
Lucky Shamrock Medallion</p>
<p>Armored Truck<br />
Prop plane</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/05/05/2for1_deal_mafia_wars/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>SxSW Wow!!!</title>
		<link>http://thecodecave.com/2009/03/02/sxsw-wow/</link>
		<comments>http://thecodecave.com/2009/03/02/sxsw-wow/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 07:39:11 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Random thoughts]]></category>
		<category><![CDATA[Blog World and New Media Expo]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[sham wow]]></category>
		<category><![CDATA[sxsw]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/?p=576</guid>
		<description><![CDATA[A New Look You may notice that there are a few things different around here! I am approaching the three year anniversary of The Code Cave and have decided to spice things up a bit. The site is now sporting a new theme on a new web host, its own VSP. And I&#8217;ve got a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F03%2F02%2Fsxsw-wow%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F03%2F02%2Fsxsw-wow%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<h2>A New Look</h2>
<p>You may notice that there are a few things different around here!  I am approaching the three year anniversary of The Code Cave and have decided to spice things up a bit.  The site is now sporting a new theme on a new web host, its own VSP. And I&#8217;ve got a number of posts lined up to be published.  The first of which is this one. My entry into the <a href="http://www.blogworldexpo.com">Blog World and New Media Expo</a> Free <a href="http://www.blogworldexpo.com/blog/2009/02/27/blog-world-to-give-away-free-badge-to-sxsw-interactive/">Ticket to South By South West Interactive contest</a>.</p>
<h2>Sham WOW!</h2>
<p>Now, I have to admit I was inspired by an infomercial that you simply can&#8217;t get around seeing these days.  It&#8217;s <a href="http://en.wikipedia.org/wiki/Vince_Offer">Vince Offer</a>&#8216;s  Sham Wow product:</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/QwRISkyV_B8&#038;hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/QwRISkyV_B8&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>Now if you haven&#8217;t seen that, surely you&#8217;ve seen the &#8220;Slappin your troubles away&#8221; <a href="http://www.youtube.com/watch?v=rUbWjIKxrrs">Slap Chop</a>. The excitment Vince shows for his favorite past time, of selling products everyone could use, is infectious. </p>
<p>I&#8217;m not the first to be inspired by his exuberance. Rhett and Link have given the commercial their full treatment and created this video:<br />
<object width="480" height="295"><param name="movie" value="http://www.youtube.com/v/ZsQcyhBsSjI&#038;hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/ZsQcyhBsSjI&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"></embed></object></p>
<h2>And now&#8230; SxSW WOW!</h2>
<p>My reaction ( major hat tip to http://twitter.com/markjaquith ) to <a href="http://www.blogworld.com">Blog World and New Media Expo</a> giving away a free ticket to SxSWi was simply WOW! and stare at the screen for screen for a while waiting for my brain to turn back on and finish processing every thing it had been ignoring from my eyes for the last 5 minutes.  SxSW wow!  And that was it! the vision was born within minutes of reading the article.</p>
<p>I shot some even fancier footage from my motorcycle showing the excitement of the 20 hour drive down to Texas, if that&#8217;s how I went (And yes, I would live stream the whole way). And had some other ideas to include, but the priorities fell to 1. Get the site transferred to the new host. 2. Make the site pretty enough to host the video 3. Get the blasted thing DONE!  </p>
<p>So without any more ado, whatever that is, I present you with &#8220;SxSW WOW!&#8221; (uploaded at March 01, 2009, 10:43 PM PST):<br />
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/lGd2eSaCgYk&#038;hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/lGd2eSaCgYk&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>I do need to thank my loving wife Denise Layman (aka <a href="http://twitter.com/Sorka">Sorka</a>) of <a href="http://www.amazon.com/Learn-Knit-Circle-Looms-1405/dp/1590121589/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1235978877&#038;sr=1-1">knitting fame</a> at <a href="http://knitchat.com">KnitChat.com</a> for all of her help filming with MS Movie Maker tips  as I&#8217;d never used it before.  Thanks Love!</p>
<p><a href="http://www.thecodecave.com/mov/sxswwow.avi">Download hi res</a> 600mb </p>
<h2>Mentioned in the Video</h2>
<p><a href="http://www.webernetting.com/">Tim Bourquin</a> founder of New Media Expo &#8211; <a href="http://vids.myspace.com/index.cfm?fuseaction=vids.individual&#038;videoid=36727508&#038;searchid=88d05325-026d-473f-b97d-6e91f75576dd ">who seems like a really nice guy</a> And as far as I know he&#8217;s never consumed 20 times his weight in ANY type of liquid<br />
<a href="http://twitter.com/blogworld">Rick Calvert</a> &#8211; Co-Founder of <a href="http://blogworldexpo.com">Blog World Expo</a> who I know is a really nice guy<br />
<a href="http://twitter.com/genuine">Jim Turner</a> &#8211; aka Genuine, who is an excellent write of no little fame. I noticed that he happened to be the author of the contest post! And as far as twitter is concerned, yes, I&#8217;m pretty sure he is following <a href="http://twitter.com/brianlayman">me</a>!</p>
<h2>Sham WOW! Script</h2>
<p>Since I had this file on my desktop I figured I&#8217;d share my script with you.  Here are the original and new lines I used from the commercial:<br />
<em>O: Hi It&#8217;s vince with Sham Wow!</em><br />
<strong>N: Hi it&#8217;s Brian and I&#8217;ve got a SxSW Wow! from Blog World Expo!</strong></p>
<p><em>O: I&#8217;ll be saying wow, everytime I use this ticket.</em><br />
<strong>N: You&#8217;ll be saying wow, every time you use this towel.</strong></p>
<p><em>O: It&#8217;s like a shammy it&#8217;s like a towel it&#8217;s like a sponge.</em><br />
<strong>N: It&#8217;s like a party, It&#8217;s like a confererence, I&#8217;ll be like a sponge, YAY ME!</strong></p>
<p><em>O: Sham wow holds 20 times its weight in liquid.</em><br />
<strong>N: SxSW attendees absorb 20 times their weight in liquid! Just ask Tim Bourquin</strong></p>
<p><em>O: Look at this it just does the work<br />
	Why do you want to work twice as hard</em><br />
<strong>N: Look at this, I&#8217;m doing work!<br />
	Why would I want to be working at home?</strong></p>
<p><em>O: Made in germany. You know the germans always make good stuff</em><br />
<strong>NOT USED: This is a gift from blog world expo, you know Calvert always makes good stuff&#8230;<br />
REPLACED: Every SxSW Wow! comes pre-Rick rolled by (Rick) Calvert himselfs</strong></p>
<p><em>O: Here&#8217;s some cola, wine coffee cola pet stains<br />
	Not only is your damage on top but<br />
	There&#8217;s your mildew. that is gonna smell you see that?</em><br />
<strong>N: Here&#8230; here is my anxiety of how to get to SxSW. My sweat, my tears, my embarrassing stains,<br />
	Not only is it on top<br />
	But it&#8217;s down deep man</strong></p>
<p><em>O: Were gonna do this in real time<br />
	Put it on the spill, turn it over<br />
	without even putting any pressure 50% of the cola right here. Following me camera guy<br />
	The other 50% the color starts ta come up.</em><br />
<strong>N: I&#8217;m gonna stream this live<br />
	I put my SxSW Wow! on top and roll it<br />
	No Pressure man, No pressure and suddenly 50% of my worries are gone!<br />
	All that remains is the fun of getting there. You followin me (Jim) Turner, you followin me?</strong></p>
<p><em>O: No other towel is gonna do that<br />
	It works like a vacuum.</em><br />
<strong>N: And look at that<br />
	It works like a Valium.<br />
	No other ticket is gonna do that!<br />
	SxSW Wow!</strong></p>
<p><em>O: See what I&#8217;m telling you.<br />
	Sham wow &#8211; you&#8217;ll be saying wow every time</em><br />
<strong>N: See what I&#8217;m telling you.<br />
	SxSW Wow! &#8211; I&#8217;ll be saying Wow! all the time!</strong></p>
<p><strong>THANKS BLOG WORLD EXPO!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/03/02/sxsw-wow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.thecodecave.com/mov/sxswwow.avi" length="629093888" type="video/x-msvideo" />
		</item>
		<item>
		<title>MySQL Founder Resigns from Sun over Quality of MySQL 5.1</title>
		<link>http://thecodecave.com/2009/02/05/mysql-founder-resigns-from-sun-over-quality-of-mysql-51/</link>
		<comments>http://thecodecave.com/2009/02/05/mysql-founder-resigns-from-sun-over-quality-of-mysql-51/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 00:48:12 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[b5media]]></category>
		<category><![CDATA[Michael Widenius]]></category>
		<category><![CDATA[Monty]]></category>
		<category><![CDATA[Sun Microsystems]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/?p=571</guid>
		<description><![CDATA[I first laid eyes on Michael Widenius, the original and principle author of the MySQL database software at the 2008 MySQL Conference in San Jose.&#160; Michael, who is more commonly known simply as “Monty”, had recently had his pride and joy, the MySQL AB company purchased by Sun Microsystems. I’d say that just about every [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F02%2F05%2Fmysql-founder-resigns-from-sun-over-quality-of-mysql-51%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F02%2F05%2Fmysql-founder-resigns-from-sun-over-quality-of-mysql-51%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://www.thecodecave.com/images/monty.jpg"><img title="A picture of MySQL founder Michael &quot;Monty&quot; Widenius" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin-left: 0px; margin-right: 0px; border-right-width: 0px" height="224" alt="A picture of MySQL founder Michael &quot;Monty&quot; Widenius" src="http://www.thecodecave.com/images/monty.jpg" width="170" align="left" border="0" /></a>  </p>
<p>I first laid eyes on <a href="http://en.wikipedia.org/wiki/Michael_Widenius">Michael Widenius</a>, the original and principle author of the MySQL database software at the 2008 MySQL Conference in San Jose.&#160; Michael, who is more commonly known simply as “Monty”, had recently had his pride and joy, the <a href="http://en.wikipedia.org/wiki/MySQL_AB">MySQL AB</a> company purchased by <a href="http://www.sun.com/">Sun Microsystems</a>. I’d say that just about every attendee was extremely nervous about <a href="http://www.scribd.com/doc/2575733/The-future-of-MySQL-The-Project">the future of MySQL</a>, and every (new) Sun employee was eager to say “Oh, the purchase was great thing!”. There certainly was a Sun head hunter at every corner ready to hand out an application form (and a pair of boxer shorts or two).<br />
<br clear="all" /><br />
<a href="http://www.thecodecave.com/images/MySQL_Boxer_shorts.JPG"><img title="MySQL_Boxer_shorts" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin-left: 0px; margin-right: 0px; border-right-width: 0px" height="184" alt="MySQL_Boxer_shorts" src="http://www.thecodecave.com/images/MySQL_Boxer_shorts.JPG" width="244" align="right" border="0" /></a>I left the conference having learned a lot of the techniques <a href="http://www.blogmeetsworld.com/">Lee Newton</a> would be soon applying to the <a href="http://www.b5media.com">b5media</a> database architecture. But far as the Sun purchase was concerned… I felt a little less safe. It was worrying that something that important was not quite as secure as it once was.&#160; There was no indication something bad was about to happen, but the way things were, it was sure to be painful if something did.</p>
<p>So now not a year later, <a href="http://monty-says.blogspot.com/2009/02/time-to-move-on.html">Monty announced today that he has quit</a> because Sun released MySQL 5.1 without first resolving significant flaws despite Monty’s strenuous objections. Monty previously released a <a href="http://monty-says.blogspot.com/2008/11/oops-we-did-it-again-mysql-51-released.html">detailed list</a> describing some of the “many known and unknown fatal bugs in the new features that are still not addressed.” My take from the article is that we should consider MySQL 5.1 should be considered a 5.0 maintenance release with pre-release beta features included.</p>
<p>Obviously Monty had spoken up to the higher ups at Sun prior to the release, but as he explained this had little affect.&#160; I think that the open source world collided heavily with the corporate reality of “Cost, Schedule, Features, or Quality – Choose 3”. In the open source communities, the choice is simple, the schedule rarely if ever enters the mix. In this corporate battle, it obviously was one of the three chosen. Monty had been seen this coming early on and had been very vocal even back in April 2008 (<a href="http://www.scribd.com/doc/2575733/The-future-of-MySQL-The-Project">see page 19</a>) calling for Sun to “<strong>Create a release policy and independent release policy board that can’t be manipulated by people in charge of server development (to not allow anyone to sacrifice quality to reach personal goals)</strong>” Whoa… “To reach Personal Goals” &#8211; even then it sounded to me like he had someone in particular in mind. Additionally, from another comment later in the keynote: “<strong>Sun is more opensource/free software friendly than MySQL AB has been lately and is driving MySQL in the right direction</strong>” it seems obvious that there was a power struggle going on. After all MySQL AB was co-founded by Michael and he should have had significant influence over the company’s philosophies. I don’t know the rest of this particular sub-plot, but I’m certain there is more to be told.</p>
<p>In any case, in light of MySQL 5.1’s quality issues at time of general availability Michael <a href="http://monty-says.blogspot.com/2009/02/time-to-move-on.html">tells us</a> he immediately quit&#160; but was talked into giving three months months to Sun for reconciliation and putting things right. That stretched into seven months, but the end result was the same. Michael announced today that he’s resigned and will be creating his own version of MySQL called <a href="http://askmonty.org/wiki/index.php/Main_Page">MySQL-Maria</a> which will will incorporate all MySQL updates but include rewrites and additional code to improve stability. It will be primarily developed by a new company he is forming named <a href="http://askmonty.org/">Monty Program Ab</a> which will be “a true open source company”. I’m still not sure what that means, but I guess I could <a href="http://zak.greant.com/hacking-business-models">read up on it</a> in more detail, if I wanted to.</p>
<p>So, what does this mean? Is it a good thing? I guess it is good that someone is out there fixing known bugs in MySQL, but won’t that happen anyway with an open source project? It’s great to see another company formed to further the open source movement, but can a MySQL standards war be beneficial?&#160; Given the adoption rate of new MySQL releases, does it even matter that 5.1 was released? It’s not as if ISPs will install it anytime before 2010 by which time there will be patches. </p>
<p>In the end, from the clues I’ve seen I suspect this episode occurred due to a personal, philosophical dispute that Monty didn’t win. Regardless, I wish him success with his new project and thank him for providing a tool that I use ever day: <a href="http://mysql.com">MySQL</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/02/05/mysql-founder-resigns-from-sun-over-quality-of-mysql-51/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A bed time story for posterity: Part 1</title>
		<link>http://thecodecave.com/2009/01/12/a-bed-time-story-for-posterity-part-1/</link>
		<comments>http://thecodecave.com/2009/01/12/a-bed-time-story-for-posterity-part-1/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 03:06:07 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[My Journal]]></category>
		<category><![CDATA[bed time stories]]></category>
		<category><![CDATA[children books]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/?p=562</guid>
		<description><![CDATA[I figured I&#8217;d record me reading a story to the kids&#8230; because&#8230; well you never know&#8230; And I did sign the life insurance policy today.. BTW &#8211; an antimacassar is that little thing that always falls off the back of the lazy boy every time you sit on it.. http://en.wikipedia.org/wiki/Antimacassar]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F01%2F12%2Fa-bed-time-story-for-posterity-part-1%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F01%2F12%2Fa-bed-time-story-for-posterity-part-1%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>I figured I&#8217;d record me reading a story to the kids&#8230; because&#8230; well you never know&#8230;</p>
<p>And I did sign the life insurance policy today.. <img src='http://thecodecave.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="425" height="319" id="qikPlayer" align="middle"><param name="allowScriptAccess" value="sameDomain" /><param name="allowFullScreen" value="true" /><param name="movie" value="http://qik.com/swfs/qikPlayer4.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#333333" /><param name="FlashVars" value="rssURL=http://qik.com/video/e19dbcda32374b9b8e798151f1b43317.rss&#038;autoPlay=false"><embed src="http://qik.com/swfs/qikPlayer4.swf" quality="high" bgcolor="#333333" width="425" height="319" name="qikPlayer" align="middle" allowScriptAccess="sameDomain" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" FlashVars="rssURL=http://qik.com/video/e19dbcda32374b9b8e798151f1b43317.rss&#038;autoPlay=false"/></object></p>
<p>BTW &#8211; an antimacassar is that little thing that always falls off the back of the lazy boy every time you sit on it.. <a href="http://en.wikipedia.org/wiki/Antimacassar">http://en.wikipedia.org/wiki/Antimacassar</a></p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/01/12/a-bed-time-story-for-posterity-part-1/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WordPress Quick Tip: Fixing the number of comments per post</title>
		<link>http://thecodecave.com/2009/01/07/fixing-wp-comments-per-post/</link>
		<comments>http://thecodecave.com/2009/01/07/fixing-wp-comments-per-post/#comments</comments>
		<pubDate>Wed, 07 Jan 2009 20:01:05 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress PHP MySQL]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/wordpress-quick-tip-fixing-the-number-of-comments-per-post/</guid>
		<description><![CDATA[For various reasons, sometimes the number of comments shown under the title of the post may not match the number of actual comments displayed under the post. Here is a simple SQL statement that will resolve the issue: update `wp_posts` set comment_count = (select count(*) from wp_comments WHERE `comment_post_ID` = `ID` and comment_approved = '1') [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F01%2F07%2Ffixing-wp-comments-per-post%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F01%2F07%2Ffixing-wp-comments-per-post%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>For various reasons, sometimes the number of comments shown under the title of the post may not match the number of actual comments displayed under the post.</p>
<p>Here is a simple SQL statement that will resolve the issue:<br />
<tt>
<pre>update `wp_posts` set comment_count = (select count(*) from wp_comments
WHERE `comment_post_ID` = `ID` and comment_approved = '1')</pre>
<p></tt></p>
<p>You can use this to verify what would change and where your problems may lie:<br />
<tt>
<pre>SELECT ID, `post_title`, `comment_count`,
    (select count(*) from `wp_comments`
        WHERE (`comment_post_ID` = `ID`) and (`comment_approved` = '1')) as NewCC
    FROM `wp_posts`
    WHERE `comment_count` <> (select count(*) from `wp_comments`
        WHERE (`comment_post_ID` = `ID`) and (`comment_approved` = '1'))</pre>
<p></tt></p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/01/07/fixing-wp-comments-per-post/feed/</wfw:commentRss>
		<slash:comments>55</slash:comments>
		</item>
		<item>
		<title>A Meme for Fun!</title>
		<link>http://thecodecave.com/2009/01/06/a-meme-for-fun/</link>
		<comments>http://thecodecave.com/2009/01/06/a-meme-for-fun/#comments</comments>
		<pubDate>Tue, 06 Jan 2009 16:53:45 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[Brian Layman]]></category>

		<guid isPermaLink="false">http://www.thecodecave.com/?p=545</guid>
		<description><![CDATA[Copy, paste, and bold what you have done! 1. Started your own blog 2. Slept under the stars 3. Played in a band 4. Visited Hawaii 5. Watched a meteor shower 6. Given more than you can afford to charity 7. Been to Disneyland/Disneyworld 8. Climbed a mountain 9. Held a praying mantis 10. Sang [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fthecodecave.com%2F2009%2F01%2F06%2Fa-meme-for-fun%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fthecodecave.com%2F2009%2F01%2F06%2Fa-meme-for-fun%2F&amp;style=normal" height="61" width="50" /><br />
			</a>
		</div>
<p>Copy, paste, and bold what you have done!<br />
<strong>1. Started your own blog<br />
2. Slept under the stars </strong><br />
3. Played in a band<br />
<strong>4. Visited Hawaii<br />
5. Watched a meteor shower<br />
6. Given more than you can afford to charity<br />
7. Been to Disneyland/Disneyworld<br />
8. Climbed a mountain<br />
9. Held a praying mantis<br />
10. Sang a solo </strong><br />
11. Bungee jumped<br />
12. Visited Paris<br />
<strong>13. Watched a lightning storm at sea<br />
14. Gone rollerskating </strong><br />
15. Adopted a child<br />
<strong>16. Had food poisoning </strong><br />
17. Walked to the top of the Statue of Liberty<br />
<strong>18. Grown your own vegetables </strong><br />
19. Seen the Mona Lisa in France<br />
20. Slept on an overnight train<br />
<strong>21. Had a pillow fight<br />
22. Hitch hiked<br />
23. Taken a sick day when you’re not ill<br />
24. Built a snow fort<br />
25. Held a lamb<br />
26. Gone skinny dipping</strong><br />
27. Run a Marathon<br />
28. Ridden in a gondola in Venice<br />
<strong>29. Seen a total eclipse<br />
30. Watched a sunrise or sunset </strong><br />
31. Hit a home run<br />
32. Been on a cruise<br />
<strong>33. Seen Niagara Falls in person </strong><br />
34. Visited the birthplace of your ancestors<br />
<strong>35. Seen an Amish community<br />
36. Taught yourself a new language<br />
37. Acted in a play or performed on stage</strong><br />
38. Seen the Leaning Tower of Pisa in person<br />
<strong>39. Gone rock climbing </strong><br />
40. Seen Michelangelo’s David<br />
<strong>41. Sung karaoke<br />
42. Seen Old Faithful geyser erupt </strong><br />
43. Bought a stranger a meal at a restaurant<br />
44. Visited Africa<br />
<strong>45. Walked on a beach by moonlight<br />
46. Been transported in an ambulance </strong><br />
47. Had your portrait painted &#8211;<br />
48. Gone deep sea fishing<br />
49. Seen the Sistine Chapel in person<br />
50. Been to the top of the Eiffel Tower in Paris<br />
<strong>51. Gone scuba diving or snorkeling<br />
52. Kissed in the rain<br />
53. Played in the mud<br />
54. Gone to a drive-in theater </strong><br />
55. Been in a movie<br />
56. Visited the Great Wall of China<br />
<strong>57. Started a business </strong><br />
<strong>58. Had an uncontrollable giggling fit at the worst possible moment </strong><br />
59. Visited Russia<br />
60. Served at a soup kitchen<br />
61. Sold Girl Scout Cookies<br />
62. Gone whale watching<br />
<strong>63. Got flowers for no reason<br />
64. Donated blood, platelets or plasma </strong><br />
65. Gone sky diving<br />
66. Visited a Nazi Concentration Camp<br />
<strong>67. Bounced a check </strong><br />
68. Flown in a helicopter<br />
<strong>69. Saved a favorite childhood toy<br />
70. Visited the Lincoln Memorial<br />
71. Eaten caviar  </strong><br />
72. Pieced a quilt<br />
<strong>73. Stood in Times Square</strong><br />
74. Toured the Everglades<br />
75. Been fired from a job<br />
76. Seen the Changing of the Guards in London<br />
<strong>77. Broken a bone<br />
78. Been on a speeding motorcycle<br />
79. Seen the Grand Canyon in person </strong><br />
80. Published a book<br />
81. Visited the Vatican<br />
<strong>82. Bought a brand new car </strong><br />
83. Walked in Jerusalem<br />
<strong>84. Had your picture in the newspaper<br />
85. Read the entire Bible<br />
86. Visited the White House<br />
87. Won money<br />
88. Had chickenpox<br />
89. Saved someone’s life </strong><br />
90. Sat on a jury<br />
<strong>91. Met someone famous<br />
92. Joined a book club<br />
93. Had to put someone you love in Hospice Care<br />
94. Had a baby </strong><br />
95. Seen the Alamo in person<br />
96. Swam in the Great Salt Lake<br />
<strong>97. Been involved in a law suit<br />
98. Owned a cell phone<br />
99. Been stung by a bee<br />
100. Read an entire book in one day</strong></p>
<p>Note: I played in a group recital in elementary school, but I&#8217;m not sure that counts as a band.<br />
I may have climbed to the top of the Statue of Liberty but I&#8217;m pretty sure I turned around with Denise when it was too long of a climb.<br />
I also was selected for a jury but was dismissed as I didn&#8217;t give the attorney the answers he wanted.</p>
]]></content:encoded>
			<wfw:commentRss>http://thecodecave.com/2009/01/06/a-meme-for-fun/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
