<?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>LlamaLabs</title>
	<atom:link href="http://llamalabs.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://llamalabs.com</link>
	<description>Wisdom of the llama</description>
	<lastBuildDate>Thu, 03 Feb 2011 09:54:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Monitoring Your WordPress Administrator User List</title>
		<link>http://llamalabs.com/2009/09/05/monitoring-your-wordpress-administrator-user-list/</link>
		<comments>http://llamalabs.com/2009/09/05/monitoring-your-wordpress-administrator-user-list/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 07:23:47 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://llamalabs.com/?p=97</guid>
		<description><![CDATA[Overview Many WordPress attacks will create a backdoor WordPress account that has administrative privileges. One way to tell if your WordPress instance has been compromised is to check for the presence of an administrator account that you did not add. The latest WordPress worm, as described in Matt Mullenweg&#8217;s recent post titled How to Keep [...]]]></description>
			<content:encoded><![CDATA[<h1>Overview</h1>
<p>Many WordPress attacks will create a backdoor WordPress account that has administrative privileges. One way to tell if your WordPress instance has been compromised is to check for the presence of an administrator account that you did not add.</p>
<p>The latest WordPress worm, as described in Matt Mullenweg&#8217;s recent post titled <a href="http://wordpress.org/development/2009/09/keep-wordpress-secure/">How to Keep WordPress Secure</a>, uses javascript on the user page to hide the backdoor administrator account. It&#8217;s not enough to log in and check the list of users. You need to check the database itself.</p>
<p><a href="http://dougal.gunters.org/blog/">Dougal Campbell</a> had a good post, <a href="http://dougal.gunters.org/blog/2009/09/05/checking-your-wordpress-security">Checking Your WordPress Security</a>, that talks about how to find the current list of accounts having administrative privileges in your WordPress instance. He provided an SQL query that you could run to get the list.</p>
<p>I&#8217;d rather have an email sent to me if the list of administrators changes, rather than having to check manually. I created a simple setup that checks my database every 10 minutes and sends me an email if the list changes. It checks to see if new administrator accounts are added and also checks to see if one was removed and replaced.</p>
<h1>Security</h1>
<p>At first I thought I could use the WordPress environment itself to make database access easier, but I realized that by doing so I could potentially run compromised code. I chose to directly connect to the database using the credentials in wp-config.php and run my queries using the mysql_* PHP functions.</p>
<h1>Implementation</h1>
<h3>Directory Structure</h3>
<p>First I got the directory structure in place. As root:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">mkdir /root/etc
mkdir /root/bin</pre></div></div>

<h3>Files</h3>
<ul>
<li>admin_list_common.php &#8211; Common Code &#8211; This code is shared by the other two utilities.</li>
<li>check_admin_list.php &#8211; Admin List Checker &#8211; This checks to see if the current list of admins matches the known good list.</li>
<li>create_admin_list_file.php &#8211; Admin List Creator &#8211; This script will create the initial list of admin users.</li>
</ul>
<h3>Common Include File</h3>
<p><b>IMPORTANT NOTE: Make sure to update the database variables to match your setup. At a minimum, you will need to modify $wordpress_docroot and the database credentials.</b></p>
<p>In <b>/root/bin/admin_list_common.php</b> I put this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000088;">$wordpress_docroot</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/www/llamalabs.com/content&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$admin_list_file</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/root/etc/myblog.wp_admin_list&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// get these variables from wp-config.php, which is in the document root for your blog.</span>
<span style="color: #000088;">$db_host</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;localhost&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$db_user</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;user&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$db_pass</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;password&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$db_name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;db_name&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$db</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$db_host</span><span style="color: #339933;">,</span> <span style="color: #000088;">$db_user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$db_pass</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #000088;">$db</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Unable to connect to DB: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #990000;">mysql_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$db_name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$db</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Unable to select db: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #990000;">mysql_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">exit</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// based off of get_users_of_blog in wp-includes/user.php</span>
<span style="color: #000000; font-weight: bold;">function</span> get_admin_users<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$db</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT um.user_id AS ID, u.user_login &quot;</span>
         <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;FROM wp_users u, wp_usermeta um &quot;</span>
         <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;WHERE u.ID = um.user_id &quot;</span>
         <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;    AND um.meta_key = 'wp_capabilities' &quot;</span>
         <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;    AND um.meta_value LIKE '%administrator%' &quot;</span>
         <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;ORDER BY um.user_id&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$res</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$sql</span><span style="color: #339933;">,</span> <span style="color: #000088;">$db</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #000088;">$res</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Could not execute query: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #990000;">mysql_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$res</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$users</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$res</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$users</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$row</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$users</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> get_prev_admin_users<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$admin_list_file</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$fp</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$admin_list_file</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;r&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #000088;">$fp</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span>  <span style="color: #0000ff;">&quot;Error opening file.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">feof</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$fp</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$data</span> <span style="color: #339933;">.=</span> <span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$fp</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">4096</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">unserialize</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$data</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Check Admin List</h3>
<p>In <b>/root/bin/check_admin_list.php</b> I put this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'admin_list_common.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$prev_admin_users</span> <span style="color: #339933;">=</span> get_prev_admin_users<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$admin_users</span> <span style="color: #339933;">=</span> get_admin_users<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$prev_admin_users</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$admin_users</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    show_warning_and_exit<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$prev_admin_users</span><span style="color: #339933;">,</span> <span style="color: #000088;">$admin_users</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$admin_count</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$admins</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$admin_count</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$admin_users</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;ID&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> <span style="color: #000088;">$prev_admin_users</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;ID&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        show_warning_and_exit<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$prev_admin_users</span><span style="color: #339933;">,</span> <span style="color: #000088;">$admin_users</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> show_warning_and_exit<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$prev_admin_users</span><span style="color: #339933;">,</span> <span style="color: #000088;">$admin_users</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Warning! The list of admin users differs.<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Current Admin Users<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
    print_admin_users<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$admin_users</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Previous Admin Users<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
    print_admin_users<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$prev_admin_users</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> print_admin_users<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$admin_users</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$admin_count</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$admin_users</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;------------------------------------<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$admin_count</span> <span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;ID({<span style="color: #006699; font-weight: bold;">$admin_users</span>[<span style="color: #006699; font-weight: bold;">$i</span>][&quot;</span>ID<span style="color: #0000ff;">&quot;]}) user_login({<span style="color: #006699; font-weight: bold;">$admin_users</span>[<span style="color: #006699; font-weight: bold;">$i</span>][&quot;</span>user_login<span style="color: #0000ff;">&quot;]})<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>Create Admin List File</h3>
<p>In <b>create_admin_list_file.php</b> I put this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'admin_list_common.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$fp</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$admin_list_file</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'w'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #000088;">$fp</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Error opening file .<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$admin_users</span> <span style="color: #339933;">=</span> get_admin_users<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">fwrite</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$fp</span><span style="color: #339933;">,</span> <span style="color: #990000;">serialize</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$admin_users</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">FALSE</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Cannot write to file (<span style="color: #006699; font-weight: bold;">$admin_list_file</span>)&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fp</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Setup and Testing</h3>
<p>Run the command to populate the known list of admin accounts. Then verify that the file was created:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">[root@host bin]# php create_admin_list_file.php 
[root@host bin]# cat /root/etc/myblog.wp_admin_list 
a:3:{i:0;a:2:{s:2:&quot;ID&quot;;s:1:&quot;1&quot;;s:10:&quot;user_login&quot;;s:5:&quot;admin&quot;;}i...&lt;snipped&gt;
[root@host bin]#</pre></div></div>

<p>Run the check script and make sure you get an exit status of 0.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">[root@host bin]# php check_admin_list.php 
[root@host bin]# echo $?
0
[root@host bin]#</pre></div></div>

<p>Now, check to make sure that the check works. To do this you can erase the contents of the known good list, test, and then restore. Make sure you get an exit status of 1 from your check scrpt. This will cause cron to mail you the report.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">[root@host bin]# php check_admin_list.php 
Warning! The list of admin users differs.
&nbsp;
Current Admin Users
------------------------------------
ID(1) user_login(admin)
ID(2) user_login(bob)
ID(3) user_login(harry)
&nbsp;
Previous Admin Users
------------------------------------
ID() user_login()
&nbsp;
[root@host bin]# echo $?
1
[root@host bin]# php create_admin_list_file.php 
[root@host bin]# php check_admin_list.php 
[root@host bin]# echo $?
0
[root@host bin]#</pre></div></div>

<h3>Set up the Recurring Check</h3>
<p>Set up the crontab entry using the crontab command:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">crontab -u root -e</pre></div></div>

<p>The contents of my entry are:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">*/10 * * * * php /root/bin/check_admin_list.php</pre></div></div>

<h3>Final Notes</h3>
<p>It&#8217;s important to test your setup. Make sure that when you add a new admin account you are alerted about the change.</p>
<p>Some people may not want to run the check as root. That&#8217;s fine, simply set it up under a different account.</p>
<p>Make sure that cron emails for the user running the cron job are making it to your inbox. Alternatively you could use the PHP mail functions to send yourself an email with the warning.</p>
<p>If you have nonstandard table prefixes you will need to update the SQL queries to reflect your custom table prefixes.</p>
<p>If I didn&#8217;t have full root access (ie: shared hosting, etc), I&#8217;d look into whether or not my hosting provider gave me the ability to create cron jobs. If so, I&#8217;d use whatever facilities were available, keeping the files out of the document root for the site. Yes, you could run these php scripts under your document root, but you should obfuscate them and understand that it&#8217;s not as safe to do so.</p>
<p>If you have PHP installed in a non-standard location, make sure to specify the path as well as the binary name when editing your crontab.</p>
<p>If you&#8217;re not getting cron emails, check out your system&#8217;s maillog and other log files to see what&#8217;s happening.</p>
<p>If you do need to add a new administrator account and you get emails about the difference, simply run the create_admin_list_file.php file again in order to update your list of known admin accounts.</p>
<h3>Related Links</h3>
<ul>
<li><a href="http://wordpress.org/development/2009/09/keep-wordpress-secure/">http://wordpress.org/development/2009/09/keep-wordpress-secure/</a></li>
<li><a href="http://dougal.gunters.org/blog/2009/09/05/checking-your-wordpress-security">http://dougal.gunters.org/blog/2009/09/05/checking-your-wordpress-security</a></li>
<li><a href="http://www.news-hub.eu/2009/09/wordpress-blogs-under-hack-attack/">http://www.news-hub.eu/2009/09/wordpress-blogs-under-hack-attack/</a></li>
<li><a href="http://lorelle.wordpress.com/2009/09/04/old-wordpress-versions-under-attack/">http://lorelle.wordpress.com/2009/09/04/old-wordpress-versions-under-attack/</a></li>
<li><a href="http://secunia.com/advisories/product/6745/?task=advisories_2008">http://secunia.com/advisories/product/6745/?task=advisories_2008</a></li>
<li><a href="http://scobleizer.com/2009/09/05/i-dont-feel-safe-with-wordpress-hackers-broke-in-and-took-things/">http://scobleizer.com/2009/09/05/i-dont-feel-safe-with-wordpress-hackers-broke-in-and-took-things/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2009/09/05/monitoring-your-wordpress-administrator-user-list/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Keyword Substitution in Subversion</title>
		<link>http://llamalabs.com/2009/07/21/using-keyword-substitution-in-subversion/</link>
		<comments>http://llamalabs.com/2009/07/21/using-keyword-substitution-in-subversion/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 07:45:02 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[subversion]]></category>
		<category><![CDATA[version control]]></category>

		<guid isPermaLink="false">http://llamalabs.com/?p=38</guid>
		<description><![CDATA[Many times I&#8217;ve been looking at a configuration file on a server, wondering who made the last change to this file? What did they change? Whatever they did, it broke something. When there&#8217;s more than one person making changes to system configuration, I like to keep that system configuration under version control. It makes it [...]]]></description>
			<content:encoded><![CDATA[<p>Many times I&#8217;ve been looking at a configuration file on a server, wondering who made the last change to this file? What did they change? Whatever they did, it broke something.</p>
<p>When there&#8217;s more than one person making changes to system configuration, I like to keep that system configuration under version control. It makes it easier to track who is making configuration changes, it provides a history of the changes, and you can set up a post-commit hook to notify team members about the changes that are being committed.</p>
<p>One nice feature in Subversion is <a href="http://svnbook.red-bean.com/en/1.5/svn.advanced.props.special.keywords.html">Keyword Substitution</a>. Keyword substitution allows you to embed keyword anchors into your file that get expanded to show useful information about the file such as the revision, revision date, URL.</p>
<p>I like to embed the Id and the Url near the top of configuration files in a comment block. The Id contains filename, revision, revision time, and user and the Url describes the full URL to the latest version of the file in the repository.</p>
<p>Whenever I encounter a configuration file in a system that has these substitutions in place, I can immediately tell where I need to go in order to check out and commit changes to the file.</p>
<p>Below is an example of how to use Subversion&#8217;s keyword substitution. I&#8217;ll set up a local subversion repository, add a file and do the keyword substitution. I&#8217;m going to do this on my macbook.</p>
<p>First, create an empty repository called &#8216;system&#8217;:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">macbook ~ $ sudo mkdir /usr/local/svn
macbook ~ $ sudo chown $USER /usr/local/svn
macbook ~ $ sudo chgrp $USER /usr/local/svn
macbook ~ $ svnadmin create /usr/local/svn/system
macbook ~ $</pre></div></div>

<p>Next, check out the repository and change directory into the checked out copy. Note, I&#8217;m skipping the normal repository structure (trunk, tags, branches) to keep things simple.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">macbook ~ $ svn co file:///usr/local/svn/system system
Checked out revision 0.
macbook ~ $ cd system/
macbook ~ $</pre></div></div>

<p>Make a sample configuration file full of comments:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">macbook system $ cat &gt;sample.cfg&lt;&lt;EOD
&gt; # this is a sample configuration file
&gt; #
&gt; # \$Id\$
&gt; # \$URL\$
&gt; #
&gt; EOD
macbook system $</pre></div></div>

<p>Add the file to the repository:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">macbook system $ svn add sample.cfg 
A         sample.cfg
macbook system $ svn ci -m 'adding sample config file to demonstrate keyword substitution'
Adding         sample.cfg
Transmitting file data .
Committed revision 1.
macbook system $</pre></div></div>

<p>Notice how the keyword anchors are in the file, not the substitutions.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">macbook system $ cat sample.cfg 
# this is a sample configuration file
#
# $Id$
# $URL$
#
macbook system $</pre></div></div>

<p>We&#8217;ll need to enable the keyword substitution for sample.cfg using &#8216;svn propset svn:keywords&#8217;.</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">macbook system $ svn propset svn:keywords &quot;Id URL&quot; sample.cfg
property 'svn:keywords' set on 'sample.cfg'
macbook system $ svn st
 M     sample.cfg
macbook system $ svn ci -m 'enabling keyword substitution for Id and URL on sample.cfg'
Sending        sample.cfg
&nbsp;
Committed revision 2.
macbook system $</pre></div></div>

<p>Now let&#8217;s look at our configuration file:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">macbook system $ cat sample.cfg 
# this is a sample configuration file
#
# $Id: sample.cfg 2 2009-07-22 06:46:35Z dustin $
# $URL: file:///usr/local/svn/system/sample.cfg $
#
macbook system $</pre></div></div>

<p>There&#8217;s our Id and URL. Note, if you checked out an existing repository over HTTP(S) or SSH, the URL would reflect that URL. So for a team accessing the SVN repository through Apache+WebDAV the example may look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">macbook system $ cat sample.cfg 
# this is a sample configuration file
#
# $Id: sample.cfg 2 2009-07-22 06:46:35Z dustin $
# $URL: https://svn.example.com/svn/system/sample.cfg $
#
macbook system $</pre></div></div>

<p>Make sure to read through the docs at <a href="http://svnbook.red-bean.com/en/1.5/svn.advanced.props.special.keywords.html">Keyword Substitution</a> for more examples and additional details.</p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2009/07/21/using-keyword-substitution-in-subversion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ZenOSS: Living with EC2&#8230;</title>
		<link>http://llamalabs.com/2009/07/12/zenoss-living-with-ec2/</link>
		<comments>http://llamalabs.com/2009/07/12/zenoss-living-with-ec2/#comments</comments>
		<pubDate>Sun, 12 Jul 2009 11:48:05 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/?p=34</guid>
		<description><![CDATA[1:32 AM Subject: [zenoss] ec2-75-101- &#8230; Command timed out on device ec2-75-101&#8230; check_http 1:37 AM Subject: [zenoss] CLEAR: ec2-75-101&#8230; HTTP OK HTTP/1.1 200 OK &#8211; 1241 bytes in 7.617 seconds This seems to be my life living with EC2 instances&#8230;]]></description>
			<content:encoded><![CDATA[<p>1:32 AM Subject: [zenoss] ec2-75-101- &#8230; Command timed out on device ec2-75-101&#8230;  check_http<br />
1:37 AM Subject: [zenoss] CLEAR: ec2-75-101&#8230; HTTP OK HTTP/1.1 200 OK &#8211; 1241 bytes in 7.617 seconds</p>
<p>This seems to be my life living with EC2 instances&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2009/07/12/zenoss-living-with-ec2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dice Game &#8211; Hosting Failure</title>
		<link>http://llamalabs.com/2009/02/09/dice-game-hosting-failure/</link>
		<comments>http://llamalabs.com/2009/02/09/dice-game-hosting-failure/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 09:45:19 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/?p=25</guid>
		<description><![CDATA[The Dice Game is hosted in an OpenVZ container on a server in Renton, WA. I should rephrase that. It *was* hosted in an OpenVZ container on a server in Renton, WA. Last night the server hosting the Dice Game failed. At first there were some filesystem errors. Then the root filesystem was remounted in [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.facebook.com/apps/application.php?id=16536182017">Dice Game</a> is hosted in an <a href="http://wiki.openvz.org/Main_Page">OpenVZ</a> container on a server in Renton, WA. I should rephrase that. It *was* hosted in an <a href="http://wiki.openvz.org/Main_Page">OpenVZ</a> container on a server in Renton, WA.</p>
<p>Last night the server hosting the <a href="http://www.facebook.com/apps/application.php?id=16536182017">Dice Game</a> failed. At first there were some filesystem errors. Then the root filesystem was remounted in read-only mode. All this happened while I was pushing out some changes to the game.</p>
<p>I issued a reboot of the underlying server and waited for it to come back up. I heard nothing from it. Remote console access wasn&#8217;t working; nothing was showing up on the console. How long should I wait before finding a new home for the <a href="http://www.facebook.com/apps/application.php?id=16536182017">Dice Game</a>? The server was powercycled and there was still no output on the console. I think it&#8217;s dead.</p>
<p>It just so happens that I have another <a href="http://wiki.openvz.org/Main_Page">OpenVZ</a> container at a hosting provider in <a href="http://vpslink.com/">Seattle</a>, but it&#8217;s running a rather old version of CentOS. It would have to do.</p>
<p>I removed the incumbent version of <a href="http://www.ruby-lang.org/en/">Ruby</a> and downloaded, built and installed the <a href="ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p72.tar.gz">latest stable release</a> from scratch. I installed <a href="http://www.rubygems.org/">rubygems</a> and all of the required gems to make the <a href="http://www.facebook.com/apps/application.php?id=16536182017">Dice Game</a> work. I had to rebuild <a href="http://httpd.apache.org/">Apache</a> from scratch to support <a href="http://httpd.apache.org/docs/2.0/mod/mod_proxy.html">mod_proxy and mod_proxy_reverse</a> (so it could send requests to the mongrel processes). I configured <a href="http://httpd.apache.org/">Apache</a>, <a href="http://mongrel.rubyforge.org/wiki/MongrelCluster">Mongrel Cluster</a> and <a href="http://www.mysql.com/">Mysql</a>. I restored the <a href="http://www.facebook.com/apps/application.php?id=16536182017">Dice Game</a> database backup from my last hourly backup. I installed <a href="http://git-scm.com/">Git</a> so I could push out my local repository to the new server. I created a new hostname in DNS and updated the Facebook application configuration to use the new hostname.</p>
<p>It took about two hours to get everything built and restored on the new system, which is less time than it would have taken to order and have a brand new dedicated server delivered. The <a href="http://www.facebook.com/apps/application.php?id=16536182017">Dice Game</a> seemed a bit more snappy on the new system too.</p>
<p>I found out the next morning that the original server was not completely dead. I&#8217;m not going to move the game back to it though, unless the new system dies. If I have to do so, I know that the old system is ready to be used as a replacement.</p>
<p>Links:</p>
<ul>
<li><a href="http://wiki.openvz.org/Main_Page">OpenVZ</a></li>
<li><a href="http://www.ruby-lang.org/en/"> Ruby</a></li>
<li><a href="http://www.rubygems.org/">Ruby GEMS</a></li>
<li><a href="http://rubyonrails.org/">Ruby on Rails (ROR)</a></li>
<li><a href="http://github.com/mislav/will_paginate/tree/master">Mislav will_paginate gem</a></li>
<li><a href="http://mongrel.rubyforge.org/wiki/MongrelCluster">Mongrel Cluster</a></li>
<li><a href="http://dev.mysql.com/downloads/ruby.html">Ruby MySQL gem</a></li>
<li><a href="http://git-scm.com/">Git</a></li>
<li><a href="http://www.mysql.com/">MySQL</a></li>
<li><a href="http://httpd.apache.org/">Apache HTTPD</a></li>
<li><a href="http://www.capify.org/">Capistrano</a></li>
</ul>
<p>The Filesystem Errors:</p>
<p><code><br />
EXT3-fs warning (device sda2): ext3_rmdir: empty directory has nlink!=2 (-1)<br />
EXT3-fs warning (device sda2): ext3_rmdir: empty directory has nlink!=2 (-2)<br />
EXT3-fs warning (device sda2): empty_dir: bad directory (dir #17991246) - no `.' or `..'<br />
EXT3-fs warning (device sda2): ext3_rmdir: empty directory has nlink!=2 (1)<br />
EXT3-fs warning (device sda2): empty_dir: bad directory (dir #17991247) - no `.' or `..'<br />
EXT3-fs warning (device sda2): ext3_rmdir: empty directory has nlink!=2 (8)<br />
EXT3-fs unexpected failure: !buffer_revoked(bh);<br />
inconsistent data on disk<br />
ext3_forget: aborting transaction: IO failure in __ext3_journal_revoke<br />
ext3_abort called.<br />
EXT3-fs error (device sda2): ext3_forget: error -5 when attempting revoke<br />
Remounting filesystem read-only<br />
Aborting journal on device sda2.<br />
EXT3-fs error (device sda2) in ext3_free_blocks_sb: Journal has aborted<br />
EXT3-fs error (device sda2) in ext3_reserve_inode_write: Journal has aborted<br />
EXT3-fs error (device sda2) in ext3_truncate: IO failure<br />
EXT3-fs error (device sda2) in ext3_reserve_inode_write: Journal has aborted<br />
EXT3-fs error (device sda2) in ext3_orphan_del: Journal has aborted<br />
EXT3-fs error (device sda2) in ext3_reserve_inode_write: Journal has aborted<br />
EXT3-fs error (device sda2) in ext3_delete_inode: IO failure<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2009/02/09/dice-game-hosting-failure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wiping hard drives &#8211; DBAN &#8211; Darik&#8217;s Boot And Nuke</title>
		<link>http://llamalabs.com/2008/11/29/wiping-hard-drives-dban-dariks-boot-and-nuke/</link>
		<comments>http://llamalabs.com/2008/11/29/wiping-hard-drives-dban-dariks-boot-and-nuke/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 07:55:26 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://llamalabs.com/?p=24</guid>
		<description><![CDATA[I recently went on a quest to find a tool to wipe four hard drives in some machines at work. I hadn&#8217;t wiped a drive in years, and was pleasantly surprised to get more than one suggestion for DBAN, or Darik&#8217;s Boot and Nuke. From http://www.dban.org/: Darik&#8217;s Boot and Nuke (&#8220;DBAN&#8221;) is a self-contained boot [...]]]></description>
			<content:encoded><![CDATA[<p>I recently went on a quest to find a tool to wipe four hard drives in some machines at work. I hadn&#8217;t wiped a drive in years, and was pleasantly surprised to get more than one suggestion for DBAN, or Darik&#8217;s Boot and Nuke.</p>
<p>From <a href="http://www.dban.org/">http://www.dban.org/</a>:</p>
<blockquote><p>
Darik&#8217;s Boot and Nuke (&#8220;DBAN&#8221;) is a self-contained boot disk that securely wipes the hard disks of most computers. DBAN will automatically and completely delete the contents of any hard disk that it can detect, which makes it an appropriate utility for bulk or emergency data destruction.
</p></blockquote>
<p>I&#8217;d have to say, it has definitely lived up to its name. I downloaded the ISO image, burned it to a CD and several unattended hours later I had four clean machines. You boot one, remove the CD, and move on to the next machine.</p>
<p>Now I just need to find a new home for these machines.</p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2008/11/29/wiping-hard-drives-dban-dariks-boot-and-nuke/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Solitaire on EC2 &#8211; Windows Server Available</title>
		<link>http://llamalabs.com/2008/10/25/solitaire-on-ec2-windows-server-available/</link>
		<comments>http://llamalabs.com/2008/10/25/solitaire-on-ec2-windows-server-available/#comments</comments>
		<pubDate>Sat, 25 Oct 2008 10:48:52 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[aws]]></category>
		<category><![CDATA[ec2]]></category>

		<guid isPermaLink="false">http://llamalabs.com/?p=23</guid>
		<description><![CDATA[Amazon announced the availability of their Windows Server 2003 AMI&#8217;s. Read more at Amazon EC2 Running Microsoft Windows Server. The current version of Elasticfox has the new API built in, so it was a good experiment to try it out too. Read through the links below to quickly get your Windows instance up. I went [...]]]></description>
			<content:encoded><![CDATA[<p>Amazon announced the availability of their Windows Server 2003 AMI&#8217;s. Read more at <a href="http://aws.amazon.com/windows/">Amazon EC2 Running Microsoft Windows Server</a>. The current version of Elasticfox has the new API built in, so it was a good experiment to try it out too. Read through the links below to quickly get your Windows instance up. I went with the most basic 32 bit version available for my solitaire test. Click on any of the images for a larger version.</p>
<ul>
<li><a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1792&#038;categoryID=209">Amazon Public Images &#8211; Windows Server 2003 R2 (32bit)</a></li>
<li><a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1764&#038;ref=featured">Feature Guide: Amazon EC2 Running Windows</a></li>
<li><a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=609">Elasticfox Firefox Extension for Amazon EC2</a></li>
<li><a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1797">Elasticfox Getting Started Guide</a></li>
<li><a href="http://cord.sourceforge.net/">CoRD: Remote Desktop for Mac OS X</a></li>
</ul>
<p>Once you read the directions and get your instance started, you can use your favorite Remote Desktop client to access your instance:</p>
<p><a href="http://www.flickr.com/photos/dustinkanske/2970625547/" title="EC2 Windows Login by dustinkanske, on Flickr"><img src="http://farm4.static.flickr.com/3218/2970625547_62be1a90d8.jpg" width="500" height="412" alt="EC2 Windows Login" /></a></p>
<p>The new API allows you to get the administrator password. Log in as Administrator with the password you get back and you&#8217;re greeted with the desktop.</p>
<p><a href="http://www.flickr.com/photos/dustinkanske/2970625587/" title="EC2 Windows Desktop by dustinkanske, on Flickr"><img src="http://farm4.static.flickr.com/3172/2970625587_0b2ef5cd0a.jpg" width="500" height="411" alt="EC2 Windows Desktop" /></a></p>
<p>Big deal? I want to play solitaire on it. Oh, it doesn&#8217;t come with Solitaire, you&#8217;ll have to supply that yourself (Thanks Gmail for not letting me send Windows executables). It also seems that they don&#8217;t provide an easy way to access the installation media for Windows either (Not that I could install it from the install media if I wanted to, and I&#8217;ll probably be proven wrong on this anyhow).</p>
<p><a href="http://www.flickr.com/photos/dustinkanske/2970625633/" title="EC2 Windows Solitaire by dustinkanske, on Flickr"><img src="http://farm4.static.flickr.com/3030/2970625633_48c491e650.jpg" width="500" height="426" alt="EC2 Windows Solitaire" /></a></p>
<p>Wasn&#8217;t that exciting? ec2kill time.</p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2008/10/25/solitaire-on-ec2-windows-server-available/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quercus PHP performance compared to Apache mod_php + APC</title>
		<link>http://llamalabs.com/2008/10/22/quercus-php-performance-compared-to-apache-mod_php-apc/</link>
		<comments>http://llamalabs.com/2008/10/22/quercus-php-performance-compared-to-apache-mod_php-apc/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 05:47:56 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/?p=22</guid>
		<description><![CDATA[&#8220;Quercus is Caucho Technology&#8217;s fast, open-source, 100% Java implementation of the PHP language&#8221; [1]. It has been demonstrated that Quercus outperforms a straight-out-of-the box installation of mod_php. &#8220;Performance: Quercus outperforms a straight mod_php implementation by about 4x (for Mediawiki and Drupal).&#8221; [1] &#8220;Resin backed PHP drives 4x performance improvements for Drupal&#8221; [2] I had always [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Quercus is Caucho Technology&#8217;s fast, open-source, 100% Java implementation of the PHP language&#8221; [1]. </p>
<p>It has been demonstrated that Quercus outperforms a straight-out-of-the box installation of mod_php.
<ol>
<li>&#8220;Performance: Quercus outperforms a straight mod_php implementation by about 4x (for Mediawiki and Drupal).&#8221; [1]
<li>&#8220;Resin backed PHP drives 4x performance improvements for Drupal&#8221; [2]
</ol>
<p>I had always wondered how Quercus compared to APC though, specifically for running a Drupal instance. I had planned on performing a bunch of tests, but they state clearly enough in the docs that it roughly matches PHP performance with accelerators like APC. [1]</p>
<p>That&#8217;s exactly what I needed to know. I&#8217;ll stick with APC until I need to write some new PHP functions in Java. So sorry to disappoint you with a lack of no new conclusions, but mod_php + APC keeps me pretty happy.</p>
<p>Links:<br />
<a href="http://www.caucho.com/resin-3.0/quercus/">[1] http://www.caucho.com/resin-3.0/quercus/</a><br />
<a href="http://www.workhabit.com/labs/resin-backed-php-drives-4x-performance-improvements-drupal">[2] http://www.workhabit.com/labs/resin-backed-php-drives-4x-performance-improvements-drupal</a></p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2008/10/22/quercus-php-performance-compared-to-apache-mod_php-apc/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Notes on Google Apps Premier</title>
		<link>http://llamalabs.com/2008/08/12/notes-on-google-apps-premier/</link>
		<comments>http://llamalabs.com/2008/08/12/notes-on-google-apps-premier/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 18:45:15 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/?p=21</guid>
		<description><![CDATA[I&#8217;ve been collecting notes about my experiences with Google Apps Premier (The service where you pay $50 per seat). It includes Google Mail, Calendar, Documents, and Sites. Yesterday&#8217;s outage reminded me of my list and I wanted to get around to posting it. Hopefully these notes will be useful to someone who is evaluating Google [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been collecting notes about my experiences with Google Apps Premier (The service where you pay $50 per seat). It includes Google Mail, Calendar, Documents, and Sites.</p>
<p><a href="http://gmailblog.blogspot.com/2008/08/we-feel-your-pain-and-were-sorry.html">Yesterday&#8217;s outage</a> reminded me of my list and I wanted to get around to posting it.</p>
<p>Hopefully these notes will be useful to someone who is evaluating Google Apps for their email/calendar/docs solution.</p>
<p>Without any specific order, here are the notes I have collected.</p>
<h3>There&#8217;s no way to enforce communication over HTTPS through the admin control panel.</h3>
<p>Before the recent announcement of the <a href="http://gmailblog.blogspot.com/2008/07/making-security-easier.html">option to require https</a>, by default you would be redirected to http://mail.google.com after signing in. With employees working remotely, not being able to force communication using HTTPS was a real bummer. There is now the option to always use HTTPS in Google Apps Premier. It&#8217;s still possible to switch back to plain old HTTP once logged in.</p>
<p>Here are a few pages discussing the issue. It&#8217;s no really such an issue anymore, but they are in my notes, so I&#8217;m including them here.</p>
<ul>
<li><a href="http://unintelligible.org/blog/2007/09/28/using-sslhttps-for-gmail-and-google-apps/">Using SSL/HTTPS for Gmail and Google Apps.</a></li>
<li><a href="http://weblog.infoworld.com/openresource/archives/2007/04/google_apps_for_1.html">Google Apps for Enterprise missing full-time SSL?</a></li>
<li><a href="http://blogs.oreilly.com/digitalmedia/2008/06/ssl-on-google-means-semi-secur.html">SSL on Google means Semi Secure Links</a></li>
<li><a href="http://groups.google.com/group/hosted-the-basics/browse_thread/thread/9c1eda1ea4607c5f">Fix A Problem &gt; Need to be able to enforce the use of SSL</a></li>
</ul>
<h3>You are forced to go through the Google Checkout process to add new seats</h3>
<p>There&#8217;s no easy way to add a new user account without going through the Google Checkout process. If you&#8217;re purchasing single seats each time you have a new hire, that means that you need to go through the Google Checkout process in addition to adding the account. You could avoid this hassle by purchasing seats in advance.</p>
<p>Ideally there would be an option to charge the credit card on file. It&#8217;s already stored in the account used for Google Checkout, so why not automate the process?</p>
<h3>Can&#8217;t forward one user&#8217;s email to another user in the same domain</h3>
<p>So, when someone leaves the company, and you need to forward new messages destined for her account to her supervisor, you&#8217;d usually put a forward in  place.</p>
<p>When I try to do so in Google Apps I get the message &#8220;Forwarding to Google Apps hosted email addresses is not supported&#8221;. I&#8217;m <a href="http://groups.google.com.br/group/hosted-setup/msg/12fcbd35e05d21fe"> not the only person having this problem</a>.</p>
<p>I&#8217;m able to do so by logging in as that user and putting the forward in place under the user&#8217;s Gmail settings.</p>
<p>I&#8217;ve been going back and forth with Google Apps Premier support for a couple weeks now attempting to troubleshoot this issue. I&#8217;m assured it&#8217;s a problem specific to my account.</p>
<h3>Disabling account access.</h3>
<p>When you change the password for an account, it does not invalidate existing logged-in sessions. If the user is logged in, she will be able to to still use her account.</p>
<p>Why not <a href="http://www.google.com/support/a/bin/answer.py?hl=en&amp;answer=33312">suspend the account</a>? That disables logging in, and will log a user out after several minutes, but it also blocks incoming mail to that user.</p>
<p>A third option is to log in as the user and click the &#8220;Details&#8221; link that is part of the account activity messaging. That opens a pop-up that shows you existing logged in sessions and gives you the opportunity to log those sessions out. It would be nice if that feature was in the Admin control panel.</p>
<h3>Unreliable IMAP</h3>
<p>I don&#8217;t personally use IMAP for my email, but there have been confirmed cases of messages being delayed for 20+ minutes when using IMAP. The messages will show up instantly through the Gmail interface,<br />
but in an external mail reader the new messages won&#8217;t show up. YMMV.</p>
<h3>Some messages silently ignored during migration</h3>
<p>If you use their IMAP migration tool (Which is very handy), you may notice that some messages (containing zip files) are not migrated.</p>
<h3>Support</h3>
<p>It&#8217;s been hit and miss when dealing with Google Apps Technical Support.</p>
<p><code>Customer: We're having problems checking mail using IMAP.<br />
Support: Which web browser are you using?<br />
</code></p>
<p>The <a href="http://www.google.com/support/a/">online documents</a> are nice.</p>
<h3>Feature Suggestions</h3>
<p>Make sure to take a look at the <a href="http://google.com/support/a/bin/request.py?contact_type=suggest">Feature Suggestions</a> to make sure some critical feature you require isn&#8217;t in the pipeline.</p>
<h3>Google Groups not included</h3>
<p>Before signing up I looked into whether or not Google Groups was one of the included applications.</p>
<p><a href="http://groups.google.com/group/hosted-the-basics/browse_thread/thread/e53d5e332a847072/9b4a02e9c6efb081">Pine Star said:</a></p>
<blockquote><p>Hello everyone interested in this integration:</p>
<p>I had a chat with the Google Rep of Commercial (paid) version of<br />
Google Apps yesterday.<br />
He said they are going to release a &#8220;Premier&#8221; edition of Google Apps<br />
by end of 2007 that wil have Google Groups integrated.</p>
<p>So, they are also thinking on these lines&#8230;.</p></blockquote>
<p>If you&#8217;re looking for Google Groups for your projects in Google Apps Premier, <strong>you will be disappointed to find out that it&#8217;s not included.</strong></p>
<p>We were really hoping to have it so we could have archived discussions for projects.</p>
<h3>Email Lists</h3>
<p>You can create email lists that deliver to multiple recipients, both members of the domain and external email addresses.</p>
<p>A couple notes on the lists.</p>
<ul>
<li>No subject prefixes.</li>
<li>No List-id field.</li>
<li>Not as cool as having Google Groups included as an app.</li>
</ul>
<h3>Calender Importing</h3>
<p>Aside from using the API, there appears to be no way to import an entire calendar into a new instance.</p>
<h3>Branding with a Custom Logo</h3>
<p>You can define a custom logo to be displayed instead of the default Google logo.</p>
<h3>Conclusion?</h3>
<p>Like any service, Google Apps Premier has its pros and cons. Research thoroughly before making the leap.</p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2008/08/12/notes-on-google-apps-premier/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Git and .profile &#8211; Aliases and config</title>
		<link>http://llamalabs.com/2008/06/05/git-and-profile-aliases-and-config/</link>
		<comments>http://llamalabs.com/2008/06/05/git-and-profile-aliases-and-config/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 07:32:33 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/?p=19</guid>
		<description><![CDATA[Many thanks to Tim for his article Installing git on Mac OS X 10.5 Leopard. It&#8217;s a great starting point for git use on OS X Leopard. In addition to his configuration and aliases, I have a couple of my own that I have added. Here&#8217;s an excerpt from my .profile: git config --global user.name [...]]]></description>
			<content:encoded><![CDATA[<p>Many thanks to <a href="http://dysinger.net/" alt="Tim Dysinger">Tim</a> for his article <a href="http://dysinger.net/2007/12/30/installing-git-on-mac-os-x-105-leopard/">Installing git on Mac OS X 10.5 Leopard</a>. It&#8217;s a great starting point for git use on OS X Leopard.</p>
<p>In addition to his configuration and aliases, I have a couple of my own that I have added. Here&#8217;s an excerpt from my .profile:</p>
<pre>
git config --global user.name "Your Name"
git config --global user.email "your email"
git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto
git config --global color.interactive auto
git config --global alias.st status
git config --global alias.ci commit
git config --global alias.co checkout
git config --global alias.br branch
git config --global merge.tool opendiff
git config --global merge.summary true
git config --global core.excludesfile ~/.gitignore

alias g='git'
alias gst='g st'
alias gci='g ci'
alias gdiff='g diff'
alias gadd='g add'
</pre>
<p>I don&#8217;t have anything against the space bar, but it does seem to be easier with those aliases. See Tim&#8217;s article for some additional comments on some of the git configuration.</p>
<p>The color configuration commands will also add quite a bit of richness to your git experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2008/06/05/git-and-profile-aliases-and-config/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using ssh-agent for password-less ssh access</title>
		<link>http://llamalabs.com/2008/03/31/using-ssh-agent-for-password-less-ssh-access/</link>
		<comments>http://llamalabs.com/2008/03/31/using-ssh-agent-for-password-less-ssh-access/#comments</comments>
		<pubDate>Tue, 01 Apr 2008 07:19:19 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[SSH]]></category>
		<category><![CDATA[password]]></category>
		<category><![CDATA[password-less]]></category>
		<category><![CDATA[ssh-agent]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2008/03/31/using-ssh-agent-for-password-less-ssh-access/</guid>
		<description><![CDATA[Instead of typing in the password to decrypt my private SSH key every time I want to ssh to a host I use a program called ssh-agent, which is included in the openssh-clients package in CentOS. When you run ssh-agent it creates a long-running process that holds decrypted keys and spits out some environment variables [...]]]></description>
			<content:encoded><![CDATA[<p>Instead of typing in the password to decrypt my private SSH key every time I want to ssh to a host I use a program called ssh-agent, which is included in the openssh-clients package in CentOS.</p>
<p>When you run ssh-agent it creates a long-running process that holds decrypted keys and spits out some environment variables that the ssh client can use:</p>
<pre>SSH_AUTH_SOCK=/tmp/ssh-Ksfjq28070/agent.28070; export SSH_AUTH_SOCK;
SSH_AGENT_PID=28071; export SSH_AGENT_PID;
echo Agent pid 28071;</pre>
<p>The problem is that you want to have those environment variables sourced in when you open new terminal windows. I added the following to my .profile to write those lines out to a file so they could be sourced in easily.</p>
<pre>test -e ~/.ssh_agent &amp;&amp; . ~/.ssh_agent
need_to_start_ssh_agent="0"
if test "" != "$SSH_AGENT_PID" ; then
  /bin/ps -p $SSH_AGENT_PID | /usr/bin/grep ssh-agent &gt; /dev/null
  res=$?
  if test "1" == "$res" ; then
    echo "ssh-agent is not running. We need to start the agent"
    need_to_start_ssh_agent="1"
  else
    echo "ssh-agent running - pid: $SSH_AGENT_PID"
  fi
else
  echo "ssh-agent is not running. We need to start the agent"
  need_to_start_ssh_agent="1"
fi</pre>
<pre>if test "1" == "$need_to_start_ssh_agent" ; then
  `which ssh-agent` | grep -v echo &gt; ~/.ssh_agent
  . ~/.ssh_agent
  `which ssh-add`
fi</pre>
<p>After using this for a while I found Daniel Robbin&#8217;s article about his keychain utility <a href="http://www.ibm.com/developerworks/library/l-keyc2/">http://www.ibm.com/developerworks/library/l-keyc2/</a>. It&#8217;s basically a more-refined version of my addition to .profile. I&#8217;m still going to stick with my solution for now because it&#8217;s so lightweight.</p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2008/03/31/using-ssh-agent-for-password-less-ssh-access/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to flush your DNS cache on OS X &#8211; Leopard</title>
		<link>http://llamalabs.com/2008/03/29/how-to-flush-your-dns-cache-on-os-x-leopard/</link>
		<comments>http://llamalabs.com/2008/03/29/how-to-flush-your-dns-cache-on-os-x-leopard/#comments</comments>
		<pubDate>Sun, 30 Mar 2008 07:45:22 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[DNS]]></category>
		<category><![CDATA[OSX]]></category>
		<category><![CDATA[dns flush osx leopard]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2008/03/29/how-to-flush-your-dns-cache-on-os-x-leopard/</guid>
		<description><![CDATA[First, see what&#8217;s in the cache: $ dscacheutil -cachedump DirectoryService Cache Overview: AAAA Queries - Disabled (link-local IPv6 addresses) Buckets Used - 31 Cache Size - 16 Entry count by category: Group - 2 Host - 11 User - 3 Flush: $ dscacheutil -flushcache $ All gone: $ dscacheutil -cachedump DirectoryService Cache Overview: AAAA Queries [...]]]></description>
			<content:encoded><![CDATA[<p>First, see what&#8217;s in the cache:</p>
<pre>$ dscacheutil -cachedump
DirectoryService Cache Overview:
AAAA Queries  - Disabled (link-local IPv6 addresses)
Buckets Used  - 31
Cache Size    - 16</pre>
<pre>Entry count by category:
Group  - 2
Host   - 11
User   - 3</pre>
<p>Flush:</p>
<pre>$ dscacheutil -flushcache
$</pre>
<p>All gone:</p>
<pre>$ dscacheutil -cachedump
DirectoryService Cache Overview:
AAAA Queries  - Disabled (link-local IPv6 addresses)
Buckets Used  - 0
Cache Size    - 0</pre>
<pre>Entry count by category:</pre>
<p>Please see the previous post to see how to clear the DNS cache on OS X Tiger <a href="http://llamalabs.com/2007/04/18/how-to-flush-your-dns-cache-on-os-x/">http://llamalabs.com/2007/04/18/how-to-flush-your-dns-cache-on-os-x/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2008/03/29/how-to-flush-your-dns-cache-on-os-x-leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RPM &#8211; List installed packages, sorted by size</title>
		<link>http://llamalabs.com/2008/03/28/rpm-list-installed-packages-sorted-by-size/</link>
		<comments>http://llamalabs.com/2008/03/28/rpm-list-installed-packages-sorted-by-size/#comments</comments>
		<pubDate>Fri, 28 Mar 2008 20:35:47 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[rpm linux query packages]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2008/03/28/rpm-list-installed-packages-sorted-by-size/</guid>
		<description><![CDATA[Here&#8217;s another rpm command I can never remember. This lists all installed packages, and sorts the list based on installed size. rpm -qa --queryformat '%{SIZE} %{NAME} %{VENDOR}\n' &#124; sort -n The -qa flag specifies that we wish to query all packages. The &#8211;queryformat flag specifies how we want each result to be formatted. See below [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s another rpm command I can never remember. This lists all installed packages, and sorts the list based on installed size.</p>
<pre>rpm -qa --queryformat '%{SIZE} %{NAME} %{VENDOR}\n'  | sort -n
</pre>
<p>The -qa flag specifies that we wish to query all packages. The &#8211;queryformat flag specifies how we want each result to be formatted. See below for additional items you can put in your query format string. The -n flag for sort tells us to perform a numerical sort (rather than alphabetical). Try it without the -n to see how the output looks.</p>
<p>Here&#8217;s an example to see the 10 installed packages that take up the most space:</p>
<pre>[user@host ~]$ rpm -qa --queryformat '%{SIZE} %{NAME} %{VENDOR}\n'  | sort -n -r | head -10
195644952 VMware-server VMware, Inc.
113550744 jdk Sun Microsystems, Inc.
66639973 glibc-common CentOS
52098364 compat-gcc-34-c++ CentOS
51851071 festival CentOS
45929176 libstdc++-devel CentOS
41768729 libgcj CentOS
41719064 MySQL-server-community MySQL AB
41653082 frysk CentOS
38859091 firefox CentOS
[user@host ~]$
</pre>
<p>There are many options that you can specify in your query format. Try this command to get a list:</p>
<pre>[user@host ~]$ rpm --querytags
HEADERIMAGE
HEADERSIGNATURES
HEADERIMMUTABLE
HEADERREGIONS
HEADERI18NTABLE
SIGSIZE
SIGPGP
--snip--
</pre>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2008/03/28/rpm-list-installed-packages-sorted-by-size/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux shell shortcuts</title>
		<link>http://llamalabs.com/2007/05/28/linux-shell-shortcuts/</link>
		<comments>http://llamalabs.com/2007/05/28/linux-shell-shortcuts/#comments</comments>
		<pubDate>Tue, 29 May 2007 03:46:05 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2007/05/28/linux-shell-shortcuts/</guid>
		<description><![CDATA[Geoffrey Grosenbach, author of the nuby on rails blog, wrote an article titled Useful Shell Shortcuts. He talked about the Using csh &#38; tcsh book and gave some examples of some shortcuts. I remember using those shortcuts for a while but eventually forgot them all. What I really found interesting were the CLI tools for [...]]]></description>
			<content:encoded><![CDATA[<p>Geoffrey Grosenbach, author of the nuby on rails blog, wrote an article titled <a href="http://nubyonrails.com/articles/2007/05/26/useful-shell-shortcuts">Useful Shell Shortcuts</a>.</p>
<p>He talked about the <a href="http://www.oreilly.com/catalog/tcsh/">Using csh &amp; tcsh</a> book and gave some examples of some shortcuts. I remember using those shortcuts for a while but eventually forgot them all.</p>
<p>What I really found interesting were the CLI tools for interfacing with the clipboard in Mac OS X. I was surprised to see that those utilities existed. See the man pages for <strong><em>pbcopy</em></strong> and <strong><em>pbpaste</em></strong> for details on those tools.</p>
<p>I figured i&#8217;d mention a couple of useful commands that I use on a regular basis.</p>
<p>The first is <strong><em>Ctrl+L</em></strong> to clear the screen. Old habits can die hard, but there&#8217;s no reason to type &#8216;clear&#8217; and hit enter to clear the screen if your shell supports <strong><em>Ctrl+L</em></strong>. I&#8217;m not sure when this feature came about, but it seems to work on tcsh 6.12.00 and bash 2.05 and 3.</p>
<p>The second thing I use frequently is <strong><em>history</em></strong> along with the !n shell shortcut (where n is the history id). History shows an integer next to each command. If you wish to run the command with the number 42 at the beginning of the line, you simply type <strong><em>!42</em></strong> at the prompt.</p>
<p>The other benefit of using history is in a shared server environment. You&#8217;d be surprised at what you can learn by looking at the commands that other people run.</p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2007/05/28/linux-shell-shortcuts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The -p flag for netstat on Linux</title>
		<link>http://llamalabs.com/2007/05/17/the-p-flag-for-netstat-on-linux/</link>
		<comments>http://llamalabs.com/2007/05/17/the-p-flag-for-netstat-on-linux/#comments</comments>
		<pubDate>Fri, 18 May 2007 06:41:02 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2007/05/17/the-p-flag-for-netstat-on-linux/</guid>
		<description><![CDATA[For a long time I had been using lsof to track down which process was listening on a particular port, and I know i&#8217;m not the only person to find it that way. The -p flag for netstat helps out by showing the pid of the process that owns that listening socket. Here are the [...]]]></description>
			<content:encoded><![CDATA[<p> For a long time I had been using lsof to track down which process was listening on a particular port, and I know i&#8217;m not the only person to find it that way. The -p flag for netstat helps out by showing the pid of the process that owns that listening socket. Here are the flags I use when doing a netstat:</p>
<pre>
-p, --program
  Show the PID and name of the program to which each socket belongs.
-a, --all
  Show both listening and non-listening sockets.  With the --interfaces option,
  show interfaces that are not marked
--numeric , -n
  Show numerical addresses instead of trying to determine symbolic host,
  port or user names.</pre>
<p>This gives a nice output like this:</p>
<pre>
[root@host ~]# netstat -anp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address  Foreign Address  State  PID/Program name
tcp        0      0 0.0.0.0:22       0.0.0.0:*     LISTEN      10587/sshd
tcp        0      0 0.0.0.0:80       0.0.0.0:*     LISTEN      16872/httpd
tcp        0      0 0.0.0.0:21       0.0.0.0:*     LISTEN      26698/proftpd
tcp        0      0 0.0.0.0:25       0.0.0.0:*     LISTEN      2209/sendmail</pre>
<p>It can be a lot faster using the netstat -anp method on heavily loaded systems.</p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2007/05/17/the-p-flag-for-netstat-on-linux/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Adding an additional swap file on Linux</title>
		<link>http://llamalabs.com/2007/05/16/adding-an-additional-swap-file-on-linux/</link>
		<comments>http://llamalabs.com/2007/05/16/adding-an-additional-swap-file-on-linux/#comments</comments>
		<pubDate>Thu, 17 May 2007 04:18:11 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2007/05/16/adding-an-additional-swap-file-on-linux/</guid>
		<description><![CDATA[Adjust your call to dd to get the size you want. [root@host ~]# dd if=/dev/zero of=/swapfile bs=1024 count=1048576 1048576+0 records in 1048576+0 records out [root@host ~]# sync [root@host ~]# mkswap /swapfile Setting up swapspace version 1, size = 1073737 kB [root@host ~]# swapon /swapfile [root@host ~]# echo "/swapfile swap swap defaults 0 0" &#62;&#62; /etc/fstab]]></description>
			<content:encoded><![CDATA[<p>Adjust your call to dd to get the size you want.</p>
<p><code><br />
[root@host ~]# dd if=/dev/zero of=/swapfile bs=1024 count=1048576<br />
1048576+0 records in<br />
1048576+0 records out<br />
[root@host ~]# sync<br />
[root@host ~]# mkswap /swapfile<br />
Setting up swapspace version 1, size = 1073737 kB<br />
[root@host ~]# swapon /swapfile<br />
[root@host ~]# echo "/swapfile swap    swap    defaults 0 0" &gt;&gt; /etc/fstab<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2007/05/16/adding-an-additional-swap-file-on-linux/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>IO.putc and $stdout.sync</title>
		<link>http://llamalabs.com/2007/04/27/ioputc-and-stdoutsync/</link>
		<comments>http://llamalabs.com/2007/04/27/ioputc-and-stdoutsync/#comments</comments>
		<pubDate>Sat, 28 Apr 2007 06:35:33 +0000</pubDate>
		<dc:creator>vmann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2007/04/27/ioputc-and-stdoutsync/</guid>
		<description><![CDATA[It&#8217;s often useful to provide some sort of output when a script is waiting for something or running a loop that take a while to complete.  Instead of writing a bunch of output and running the risk of scrolling useful information off the page, I like writing out a single &#8216;.&#8217; every once in a while, just [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s often useful to provide <em>some</em> sort of output when a script is waiting for something or running a loop that take a while to complete.  Instead of writing a bunch of output and running the risk of scrolling useful information off the page, I like writing out a single &#8216;.&#8217; every once in a while, just to let me know the script hasn&#8217;t hung.</p>
<p>The problem with just writing a &#8217;.' is that most terminals/operating systems use a feature called &#8220;buffering&#8221;.  When you write to a file (or terminal/stdout) the operating system doesn&#8217;t immediately flush that output to where you are writing.  It will wait until a sufficient amount of data has been written, and then flush it all out at the same time to save on resources/system calls.  A single &#8216;.&#8217; is nowhere near enough data to signal the OS to flush that output, so you&#8217;ll end up seeing a bunch of them all written when the loop completes, or worst yet, nothing until the script is finished.  For example:</p>
<p><code>#!/usr/bin/env ruby<br />
20.times do<br />
putc('.')<br />
sleep(5)<br />
end</code></p>
<p>On first glance, you&#8217;d think this script would print 20 dots on a line, one every 5 seconds, but it doesn&#8217;t!  When run, it sits there for a full minute without outputting anything, and then spits out 20 dots right before quitting.  We need to turn off write buffering on $stdout by turning on <em><a HREF="http://www.ruby-doc.org/core/classes/IO.html#M002287">sync mode</a></em>:<br />
<code>$stdout.sync=(true) if not $stdout.sync</code></p>
<p>If you add that line to the top of the script, each dot is written to the terminal right away.</p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2007/04/27/ioputc-and-stdoutsync/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title></title>
		<link>http://llamalabs.com/2007/04/26/10/</link>
		<comments>http://llamalabs.com/2007/04/26/10/#comments</comments>
		<pubDate>Fri, 27 Apr 2007 03:01:03 +0000</pubDate>
		<dc:creator>vmann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2007/04/26/10/</guid>
		<description><![CDATA[Lately I&#8217;ve been entranced by Amazon&#8217;s EC2 and S3 systems, but it has brought up some good ideas to share here. This one came in handy when writing a shell script to automate installation of Debian in a loopback file mount, and I needed the script to write another script itself. I&#8217;ll get around to [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been entranced by Amazon&#8217;s <a href="http://www.amazonaws.com/ec2">EC2</a> and <a href="http://www.amazonaws.com/s3">S3</a> systems, but it has brought up some good ideas to share here.  This one came in handy when writing a shell script to automate installation of <a href="http://www.debian.org/">Debian</a> in a loopback file mount, and I needed the script to write another script itself.  I&#8217;ll get around to posting that sometime later, but for now&#8230;</p>
<p><code>#!/bin/sh<br />
# ... other stuff ...<br />
sudo cat > $CHROOTMNT/tmp/chroot.sh <<'CHROOT'<br />
#!/bin/bash<br />
cd /usr/local/<br />
unzip /tmp/ec2-api-tools.zip<br />
ln -s ec2-api-tools* ec2-api-tools<br />
chmod -R a-w /usr/local/ec2-api-tools/<br />
rm /tmp/ec2-api-tools.zip<br />
cat >> /etc/profile <<'EC2APIPROFILE'</p>
<p>export EC2_HOME=/usr/local/ec2-api-tools<br />
export PATH=$PATH:$EC2_HOME/bin<br />
EC2APIPROFILE<br />
# ... other stuff ...<br />
CHROOT<br />
sudo chmod a+x $CHROOTMNT/tmp/chroot.sh<br />
sudo chroot $CHROOTMNT /tmp/chroot.sh</code></p>
<p>I was having trouble before finding <a href="http://www.tldp.org/LDP/abs/html/here-docs.html">this</a>.</p>
<blockquote><p>Disabling parameter substitution permits outputting literal text. Generating scripts or even program code is one use for this.</p></blockquote>
<p>Without disabling parameter substitution, it was expanding "$PATH" to my current $PATH, instead of writing "$PATH" like I wanted.  Sure, I could have unset it before running the script, but this is much more useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2007/04/26/10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SVN Commit Log Message Correction</title>
		<link>http://llamalabs.com/2007/04/24/svn-commit-log-message-correction/</link>
		<comments>http://llamalabs.com/2007/04/24/svn-commit-log-message-correction/#comments</comments>
		<pubDate>Wed, 25 Apr 2007 01:19:09 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2007/04/24/svn-commit-log-message-correction/</guid>
		<description><![CDATA[Have you ever done a commit and then realized that the message you put wasn&#8217;t quite right? It is possible to change those messages using the Subversion admin tools. From the Subversion book: Commit Log Message Correction Example: [admin@svn]$ echo "Here is the new, correct log message" &#62; newlog.txt [admin@svn]$ svnadmin setlog myrepos newlog.txt -r [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever done a commit and then realized that the message you put wasn&#8217;t quite right? It is possible to change those messages using the Subversion admin tools.</p>
<p>From the Subversion book: <a href="http://svnbook.red-bean.com/nightly/en/svn.reposadmin.maint.html#svn.reposadmin.maint.setlog">Commit Log Message Correction</a></p>
<p><strong>Example:</strong></p>
<p><code>[admin@svn]$ echo "Here is the new, correct log message" &gt; newlog.txt<br />
[admin@svn]$ svnadmin setlog myrepos newlog.txt -r 388 --bypass-hooks</code></p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2007/04/24/svn-commit-log-message-correction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to flush your DNS cache on OS X</title>
		<link>http://llamalabs.com/2007/04/18/how-to-flush-your-dns-cache-on-os-x/</link>
		<comments>http://llamalabs.com/2007/04/18/how-to-flush-your-dns-cache-on-os-x/#comments</comments>
		<pubDate>Thu, 19 Apr 2007 01:30:24 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2007/04/18/how-to-flush-your-dns-cache-on-os-x/</guid>
		<description><![CDATA[It&#8217;s not often that I need to do this, but I always end up looking it up. From the command line: sudo lookupd -flushcache And just for fun, you can examine your resolver configuration using: lookupd -configuration]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s not often that I need to do this, but I always end up looking it up.</p>
<p>From the command line:</p>
<p><code>sudo lookupd -flushcache</code></p>
<p>And just for fun, you can examine your resolver configuration using:</p>
<p><code>lookupd -configuration</code></p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2007/04/18/how-to-flush-your-dns-cache-on-os-x/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Erase the contents of a file.</title>
		<link>http://llamalabs.com/2007/04/17/erase-the-contents-of-a-file/</link>
		<comments>http://llamalabs.com/2007/04/17/erase-the-contents-of-a-file/#comments</comments>
		<pubDate>Wed, 18 Apr 2007 02:45:21 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2007/04/17/erase-the-contents-of-a-file/</guid>
		<description><![CDATA[I had been using cat /dev/null &#62; /path/to/file for a long time. Whlie reading through a friend&#8217;s shell script for creating Amazon EC2 images I found out another way of erasing the contents of a file. &#62; /path/to/file That results in the open system call being called with the O_TRUNC flag. open("/path/to/file", O_WRONLY&#124;O_CREAT&#124;O_TRUNC&#124;O_LARGEFILE, 0666)]]></description>
			<content:encoded><![CDATA[<p>I had been using <code>cat /dev/null &gt; /path/to/file</code> for a long time. Whlie reading through a friend&#8217;s shell script for creating Amazon EC2 images I found out another way of erasing the contents of a file.</p>
<p><code>&gt; /path/to/file</code></p>
<p>That results in the <strong>open</strong> system call being called with the O_TRUNC flag.</p>
<p><code>open("/path/to/file", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666)</code></p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2007/04/17/erase-the-contents-of-a-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>dpkg -S</title>
		<link>http://llamalabs.com/2007/04/13/dpkg-s/</link>
		<comments>http://llamalabs.com/2007/04/13/dpkg-s/#comments</comments>
		<pubDate>Fri, 13 Apr 2007 10:10:15 +0000</pubDate>
		<dc:creator>vmann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2007/04/13/dpkg-s/</guid>
		<description><![CDATA[Debian and Ubuntu tip #1 You can use dpkg to figure out what package installed a file on your system. For instance, I don&#8217;t particularly like emacs so was suprised to find /etc/emacs is installed with a default Debian Etch install. debian:~# dpkg -S /etc/emacs dictionaries-common: /etc/emacs To see more information about that package (to [...]]]></description>
			<content:encoded><![CDATA[<p>Debian <em>and Ubuntu</em> tip #1</p>
<p>You can use dpkg to figure out what package installed a file on your system.  For instance, I don&#8217;t particularly like emacs so was suprised to find <strong>/etc/emacs</strong> is installed with a default Debian Etch install.<br />
<code>debian:~# dpkg -S /etc/emacs<br />
dictionaries-common: /etc/emacs</code><br />
To see more information about that package <em>(to decide what to do with it)</em>.  Use <strong>apt-cache show</strong><br />
<code>debian:~# apt-cache show dictionaries-common<br />
Package: dictionaries-common<br />
Priority: standard<br />
Section: text<br />
Installed-Size: 745<br />
Maintainer: Agustin Martin Domingo <agmartin@debian.org><br />
Architecture: all<br />
Version: 0.70.10<br />
Replaces: openoffice.org-updatedicts<br />
Provides: openoffice.org-updatedicts<br />
Depends: perl-base (>= 5.6.0-16), debconf (>= 0.5) | debconf-2.0<br />
Suggests: ispell, emacsen-common, jed-extra<br />
Conflicts: ispell (<= 3.1.20.0-1), miscfiles (<< 1.3-2.1), iamerican (<= 3.1.20.0-1), ibrazilian (<< 2.4-5.1), ibritish (<= 3.1.20.0-1), ibulgarian (<= 2.0-2), icatalan (<= 0.1-4), iczech (<= 20020628-1), idanish (<< 1.4.22-2.1), idutch (<= 1:0.1e-20), iesperanto (<< 2.1.2000.02.25-6), ifaroese (<= 0.1.16-2), ifinnish (<< 0.7-3.4), ifinnish-large (<< 0.7-3.4), ifinnish-small (<< 0.7-3.4), ifrench (<= 1.4-13), ifrench-gut (<= 1:1.0-9), igerman, ihungarian (<= 0.84-1), iitalian (<< 2.20-1.2), ingerman (<< 20010414-2), inorwegian (<< 2.0-6.1), ipolish (<< 20011004-2.1), iportuguese (<< 19980611-8), irussian (<= 0.99f0-1), ispanish (<< 1.7-5), ispell-ga, iswedish (<= 1.4.2), wbritish (<= 3.1.20.0-1), wbulgarian (<= 2.0-2), wcatalan (<= 0.1-4), wdanish (<< 1.4.22-2.1), wdutch (<= 1:0.1e-20), wenglish (<= 2.0-2), wfaroese (<= 0.1.16-2), wfinnish (<< 0.7-3.4), wfrench (<= 1.0-11), wgerman, witalian (<= 1.6), wnorwegian (<< 2.0-6.1), wngerman (<< 20010414-2), wpolish (<< 20011004-2.1), wspanish (<= 1.0.11.1), wswedish (<= 1.4.2), openoffice.org-updatedicts<br />
Filename: pool/main/d/dictionaries-common/dictionaries-common_0.70.10_all.deb<br />
Size: 250004<br />
MD5sum: e9a26a3367d2373a20368d1fe6b22a73<br />
SHA1: 16730ac0cac691e5bd9a1edc123be83902214738<br />
SHA256: 39ce6f1684a2b568e78467656bfdcd605dae20f588dc7544b08f03aaadd1e789<br />
Description: Common utilities for spelling dictionary tools<br />
 These are utilities shared by all ispell, myspell and wordlist<br />
 dictionaries,  including support for some tools that use ispell<br />
 (like emacsen, jed and mutt). More info about naming conventions and<br />
 availability of those dictionaries in the README file.<br />
 .<br />
 Maintainers should install dictionaries-common-dev as well, and read its<br />
 documentation.<br />
Tag: implemented-in::lisp, implemented-in::perl, role::plugin, role::program, scope::utility, special::auto-inst-parts, works-with::dictionary</code><br />
<a href="http://http://www.debian.org/doc/manuals/reference/ch-package.en.html">http://www.debian.org/doc/manuals/reference/ch-package.en.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2007/04/13/dpkg-s/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Which package does a file belong to? (RPM Style)</title>
		<link>http://llamalabs.com/2007/04/13/which-package-does-a-file-belong-to-rpm-style/</link>
		<comments>http://llamalabs.com/2007/04/13/which-package-does-a-file-belong-to-rpm-style/#comments</comments>
		<pubDate>Fri, 13 Apr 2007 09:50:24 +0000</pubDate>
		<dc:creator>kanske</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2007/04/13/which-package-does-a-file-belong-to-rpm-style/</guid>
		<description><![CDATA[If you want to figure out which package a file belongs to you can use rpm to find out (On a system that uses rpm). Which package does /bin/bash belong to? [root@host ~]# rpm -qf /bin/bash bash-3.0-19.3 So /bin/bash belongs to bash-3.0-19.3 The -q option lets rpm know that you want to do a query [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to figure out which package a file belongs to you can use rpm to find out (On a system that uses rpm). Which package does /bin/bash belong to?</p>
<p><code><br />
[root@host ~]# rpm -qf /bin/bash<br />
bash-3.0-19.3<br />
</code></p>
<p>So /bin/bash belongs to bash-3.0-19.3</p>
<p>The -q option lets rpm know that you want to do a query of the database. The f lets you query the package containing the file you specify.</p>
<p>Here&#8217;s another query:</p>
<p><code><br />
[root@host ~]# rpm -qf /usr/bin/xargs<br />
findutils-4.1.20-7.el4.1<br />
[root@host ~]#<br />
</code></p>
<p>yum lets you get info on the findutils package:</p>
<p><code><br />
[root@host ~]# yum info findutils<br />
Setting up repositories<br />
update                    100% |=========================|  951 B    00:00<br />
rpmforge                  100% |=========================| 1.1 kB    00:00<br />
base                      100% |=========================| 1.1 kB    00:00<br />
addons                    100% |=========================|  951 B    00:00<br />
extras                    100% |=========================| 1.1 kB    00:00<br />
Reading repository metadata in from local files<br />
Installed Packages<br />
Name   : findutils<br />
Arch   : i386<br />
Epoch  : 1<br />
Version: 4.1.20<br />
Release: 7.el4.1<br />
Size   : 231 k<br />
Repo   : installed<br />
Summary: The GNU versions of find utilities (find and xargs).</code></p>
<p><code><br />
Description:<br />
The findutils package contains programs which will help you locate<br />
files on your system.  The find utility searches through a hierarchy<br />
of directories looking for files which match a certain set of criteria<br />
(such as a filename pattern).  The xargs utility builds and executes<br />
command lines from standard input arguments (usually lists of file<br />
names generated by the find command).</code></p>
<p><code><br />
You should install findutils because it includes tools that are very<br />
useful for finding things on your system.<br />
</code></p>
<p>So, if you are using a system that uses RPM/YUM, you can easily find out the packages that files on your filesystem belong to.</p>
<p>Once you have identified the package that you are looking for you may wish to find out which files are part of that package. To do so you use the query list option (-ql). Here is an example for the bash package:</p>
<p><code><br />
[dustin@host ~]$ rpm -ql bash<br />
/bin/bash<br />
/bin/sh<br />
/etc/skel/.bash_logout<br />
/etc/skel/.bash_profile<br />
/etc/skel/.bashrc<br />
/usr/bin/bashbug-32<br />
/usr/share/doc/bash-3.0<br />
/usr/share/doc/bash-3.0/CHANGES<br />
--snip--<br />
/usr/share/man/man1/unset.1.gz<br />
/usr/share/man/man1/wait.1.gz<br />
[dustin@host ~]$<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2007/04/13/which-package-does-a-file-belong-to-rpm-style/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Site restructuring</title>
		<link>http://llamalabs.com/2007/03/07/site-restructuring/</link>
		<comments>http://llamalabs.com/2007/03/07/site-restructuring/#comments</comments>
		<pubDate>Wed, 07 Mar 2007 12:38:38 +0000</pubDate>
		<dc:creator>vmann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://llamalabs.com/2007/03/07/site-restructuring/</guid>
		<description><![CDATA[Moving to a WordPress site for easier multi-user blogging/writing with comments and other such neat schtuff. You can still access the MoinMoin wiki]]></description>
			<content:encoded><![CDATA[<p>Moving to a WordPress site for easier multi-user blogging/writing with comments and other such neat schtuff.  You can still access the <a href="http://llamalabs.com/llamawiki/FrontPage">MoinMoin wiki</a></p>
]]></content:encoded>
			<wfw:commentRss>http://llamalabs.com/2007/03/07/site-restructuring/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

