<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>fooninja.net</title>
 <link href="http://fooninja.net/atom.xml" rel="self"/>
 <link href="http://fooninja.net/"/>
 <updated>2011-09-27T22:57:04+02:00</updated>
 <id>http://fooninja.net/</id>
 <author>
   <name>E. Root</name>
   <email>e.root@fooninja.net</email>
 </author>

 
 <entry>
   <title>Drupal 7: Uncaught exception, MySQL server has gone away</title>
   <link href="http://fooninja.net/2011/07/13/drupal-uncaught-exception"/>
   <updated>2011-07-13T00:00:00+02:00</updated>
   <id>http://fooninja.net/2011/07/13/drupal-uncaught-exception</id>
   <content type="html">&lt;p&gt;After upgrading to Drupal 7.4 I got the following error when trying to load &lt;code&gt;/admin/modules&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Additional uncaught exception thrown while handling exception.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Original&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PDOException: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away: SELECT s.lid, t.translation, s.version FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid AND t.language = :language WHERE s.source = :source AND s.context = :context AND s.textgroup = &amp;#039;default&amp;#039;; Array ( [:language] =&amp;gt; sv [:source] =&amp;gt; No tokens available. [:context] =&amp;gt; ) in locale() (line 676 of /home/.../modules/locale/locale.module).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Additional&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PDOException: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away: SELECT s.lid, t.translation, s.version FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid AND t.language = :language WHERE s.source = :source AND s.context = :context AND s.textgroup = &amp;#039;default&amp;#039;; Array ( [:language] =&amp;gt; sv [:source] =&amp;gt; %type: !message in %function (line %line of %file). [:context] =&amp;gt; ) in locale() (line 676 of /home/.../modules/locale/locale.module).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uncaught exception thrown in session handler.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PDOException: SQLSTATE[HY000]: General error: 2006 MySQL server has gone away in _drupal_session_write() (line 203 of /home/.../includes/session.inc)&lt;/p&gt;

&lt;p&gt;This problem - &quot;MySQL server has gone away&quot; - can happen if the query you send to the MySQL server is too large. Indeed, for me the problem went away when I raised MySQL's &lt;code&gt;max_allowed_packet&lt;/code&gt; setting from 1M (default) to 16M in my &lt;code&gt;my.cnf&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
[mysqld]
...
max_allowed_packet=16M
&lt;/pre&gt;



</content>
 </entry>
 
 <entry>
   <title>fooninja.net goes mobile</title>
   <link href="http://fooninja.net/2011/06/10/fooninja-goes-mobile"/>
   <updated>2011-06-10T00:00:00+02:00</updated>
   <id>http://fooninja.net/2011/06/10/fooninja-goes-mobile</id>
   <content type="html">&lt;p&gt;I bought an Android phone and decided to make fooninja.net a bit more mobile-friendly by creating a CSS for smaller screens. It basically just removes the ads and sets width to auto. This is what I added to the page header:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;viewport&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;width=device-width; initial-scale=1.0; maximum-scale=1.0;&amp;quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
...
&lt;span class=&quot;nt&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/css/handheld.css&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;media=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;only screen and (max-device-width: 800px)&amp;quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;It seems to work well, but I've only tested it on my Samsung Galaxy S2. Let me know if you find anything odd.&lt;/p&gt;

&lt;p&gt;(I also added a print CSS. Forgot about that!)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Updating nodes programmatically in Drupal 7</title>
   <link href="http://fooninja.net/2011/06/06/updating-nodes-programmatically-in-drupal-7"/>
   <updated>2011-06-06T00:00:00+02:00</updated>
   <id>http://fooninja.net/2011/06/06/updating-nodes-programmatically-in-drupal-7</id>
   <content type="html">&lt;p&gt;&lt;em&gt;See also &lt;a href=&quot;/2011/04/13/guide-to-programmatic-node-creation-in-drupal-7/&quot;&gt;Guide to programmatic node creation in Drupal 7&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just like creating nodes, updating/editing a node programmatically in Drupal 7 is very simple. See the &lt;a href=&quot;/2011/04/13/guide-to-programmatic-node-creation-in-drupal-7/&quot;&gt;node creation page&lt;/a&gt; for guidance on how to set/update various field types (text, date, taxonomy, etc.); I won't duplicate all that here. Instead I'll show you additional things like deleting field data, deleting attachments and managing revisions.&lt;/p&gt;

&lt;p&gt;I highly recommend using &lt;code&gt;print_r(node_load($nid))&lt;/code&gt; (or &lt;a href=&quot;http://drupal.org/project/drush&quot;&gt;drush&lt;/a&gt;) to check nodes before and after modification; it's a great way to learn about the data structures and see exactly what happens.&lt;/p&gt;

&lt;p&gt;As always, don't forget to make a backup of your database before you begin. If you have any questions, corrections or suggestions, please feel free to leave a comment.&lt;/p&gt;

&lt;h2&gt;Basic example&lt;/h2&gt;

&lt;p&gt;Put the code below in e.g. &lt;code&gt;foo_update.php&lt;/code&gt; in your Drupal root directory, and execute it either through the browser or from the command line. I prefer the latter, running the script from the Drupal directory (&lt;code&gt;php foo_update.php&lt;/code&gt;). Also, just like when creating nodes, &lt;em&gt;you&lt;/em&gt; have to make sure that the input is valid.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;php&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;DRUPAL_ROOT&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getcwd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;REMOTE_ADDR&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Necessary if running from command line&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DRUPAL_ROOT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/includes/bootstrap.inc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;drupal_bootstrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRUPAL_BOOTSTRAP_FULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$nid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;453&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The node to update&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node_load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$nid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// ...where $nid is the node id&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Let&amp;#39;s set a new title for this node&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;And a new body text, too.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node_submit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Prepare node for saving&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;node_save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Node with nid &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;nid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; updated!&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Deleting field contents&lt;/h2&gt;

&lt;p&gt;To remove field data, I suggest using &lt;code&gt;unset()&lt;/code&gt; like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Delete field with index 0&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;unset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_textfoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Delete third field from a multi-value field&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;unset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_textfoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Delete whole field (if field is multi-value, all values are deleted)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;unset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_textfoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;So, to empty a field, just use &lt;code&gt;unset()&lt;/code&gt;. Often, however, you might want to do it conditionally. Say you have a term reference (taxonomy) field for tagging and want to remove a certain tag from a node. You can do it like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Remove tag with taxonomy id 8&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_tags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$tag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;tid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;unset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_tags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;   
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Deleting attached files&lt;/h2&gt;

&lt;p&gt;To delete an attached file from disk and delete its database record, use &lt;a href=&quot;http://api.drupal.org/api/drupal/includes--file.inc/function/file_delete/7&quot;&gt;file_delete()&lt;/a&gt;: (&lt;em&gt;Note that in D7, &lt;code&gt;file_delete()&lt;/code&gt; takes a file object as an argument rather than a path; Drupal 6's &lt;code&gt;file_delete()&lt;/code&gt; is now &lt;a href=&quot;http://api.drupal.org/api/drupal/includes--file.inc/function/file_unmanaged_delete/7&quot;&gt;&lt;code&gt;file_unmanaged_delete()&lt;/code&gt;&lt;/a&gt;.&lt;/em&gt;)&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Load file object&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$foofile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;file_load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;fid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Delete file if it&amp;#39;s not being used anywhere&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;file_delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$foofile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// ...or force deletion&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;file_delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$foofile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;To remove a file that's being used in the node, I'd do something like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$filefoo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;file_load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;fid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;unset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;file_delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$filefoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;If this doesn't seem to work, it's most likely due to a problem with permissions. Check directory permissions and make sure the user running the script is able to remove uploaded files.&lt;/p&gt;

&lt;p&gt;If you want to delete an attached file but keep the actual file on the server, you might think you could just unset the field:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nb&quot;&gt;unset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;And you can. But the above will still keep the file's database record - it's removed from &lt;code&gt;file_usage&lt;/code&gt; but will still be in &lt;code&gt;file_managed&lt;/code&gt;. There doesn't seem to be any existing API call we can use straight away. Taking a hint from the &lt;a href=&quot;http://api.drupal.org/api/drupal/includes--file.inc/function/file_delete&quot;&gt;&lt;code&gt;file_delete()&lt;/code&gt;&lt;/a&gt; code, you can do this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$filefoo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;file_load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;fid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;unset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module_invoke_all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;file_delete&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$filefoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;module_invoke_all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;entity_delete&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$filefoo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;file&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;db_delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;file_managed&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;fid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$filefoo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;fid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;...or simply hack core. &lt;a href=&quot;http://drupal.stackexchange.com/questions/2090/how-to-keep-underlying-file-when-deleting-a-filefield-value&quot;&gt;Here&lt;/a&gt; is another way to do it.&lt;/p&gt;

&lt;p&gt;If you want to remove a file without touching the database (perhaps because the file is not in the database to begin with), you can use &lt;a href=&quot;http://api.drupal.org/api/drupal/includes--file.inc/function/file_unmanaged_delete/7&quot;&gt;&lt;code&gt;file_unmanaged_delete()&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nx&quot;&gt;file_unmanaged_delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;public://field/image/foo.jpg&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Revisions&lt;/h2&gt;

&lt;p&gt;I highly recommend using revisions when updating stuff programmatically. If something goes seriously wrong, it's much easier to roll back to a previous revision than fiddling with database backups.&lt;/p&gt;

&lt;p&gt;To make a new revision, all you need to do is set &lt;code&gt;$node-&amp;gt;revision&lt;/code&gt; to 1, and optionally add a log message. Here's the basic example again, this time with revisions enabled:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;php&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;DRUPAL_ROOT&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getcwd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;REMOTE_ADDR&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Necessary if running from command line&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DRUPAL_ROOT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/includes/bootstrap.inc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;drupal_bootstrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRUPAL_BOOTSTRAP_FULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$nid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;453&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node_load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$nid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// ...where $nid is the node id&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Let&amp;#39;s set a new title for this node&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;And a new body text, too.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;revision&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Create new revision&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Updated programmatically&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Log message&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node_submit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Prepare node for saving&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;node_save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Node with nid &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;nid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; updated!&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;If you do &lt;code&gt;print_r(node_load($nid));&lt;/code&gt; you'll notice that the number of the latest revision is stored in &lt;code&gt;$node-&amp;gt;vid&lt;/code&gt;. The first time you create a node, &lt;code&gt;$node-&amp;gt;nid&lt;/code&gt; and &lt;code&gt;$node-&amp;gt;vid&lt;/code&gt; are the same. When you create a revision, &lt;code&gt;$node-&amp;gt;nid&lt;/code&gt; stays the same but &lt;code&gt;$node-&amp;gt;vid&lt;/code&gt; changes. Here's how you load a specific revision of a node:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node_load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$nid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$vid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;You can get a list of a node's revisions with &lt;a href=&quot;http://api.drupal.org/api/drupal/modules--node--node.module/function/node_revision_list&quot;&gt;&lt;code&gt;node_revision_list($node)&lt;/code&gt;&lt;/a&gt;. Note that this function takes a node &lt;em&gt;object&lt;/em&gt; as its argument, so do something like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node_load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$nid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$noderevisions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node_revision_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// or node_revision_list(node_load($nid));&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print_r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$noderevisions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



</content>
 </entry>
 
 <entry>
   <title>From Wordpress to Jekyll and a new design</title>
   <link href="http://fooninja.net/2011/06/04/moving-from-wordpress-to-jekyll"/>
   <updated>2011-06-04T00:00:00+02:00</updated>
   <id>http://fooninja.net/2011/06/04/moving-from-wordpress-to-jekyll</id>
   <content type="html">&lt;p&gt;Static site compilers have become quite popular in some circles in the past couple of years, especially since the rise of services like &lt;a href=&quot;http://www.disqus.com/&quot;&gt;Disqus&lt;/a&gt;. I decided to make the switch from Wordpress to &lt;a href=&quot;http://www.jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt;, a &quot;simple, blog aware, static site generator&quot; written in Ruby, for the usual reasons: I got tired of keeping up with Wordpress security updates, and static files give me a warm, fuzzy feeling.&lt;/p&gt;

&lt;p&gt;I can now host my site anywhere without ever having to worry about security or server load. Also, being a unix guy who pretty much lives in the terminal, having every post as a plain text file (with &lt;a href=&quot;http://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt; markup) and writing posts in Vim feels &lt;em&gt;great&lt;/em&gt;. This also makes it easy to put the site in a Git repository or similar for version control.&lt;/p&gt;

&lt;p&gt;Of course, with static files all the way, you need to use something like &lt;a href=&quot;http://www.disqus.com/&quot;&gt;Disqus&lt;/a&gt; if you still want a comment system. Disqus is embedded with JavaScript. I'm not entirely happy with this solution. I prefer being in total control of my own site, and I don't like that JavaScript is required just to read the comments and I don't like the implications it has for archiving. Finding an alternative solution is on my todo list.&lt;/p&gt;

&lt;p&gt;I initially played with &lt;a href=&quot;http://nanoc.stoneship.org/&quot;&gt;nanoc&lt;/a&gt;, a much more sophisticated Ruby site compiler. However, being lazy, I found that Jekyll was easier to get started with and that I didn't really need the extra power of nanoc. (I will however use nanoc for other projects. It's a really neat piece of software.)&lt;/p&gt;

&lt;h2&gt;Getting started&lt;/h2&gt;

&lt;p&gt;Loads of people have their blogs on public &lt;a href=&quot;http://www.github.com/&quot;&gt;GitHub&lt;/a&gt; repositories. There's also a &lt;a href=&quot;https://github.com/mojombo/jekyll/wiki/sites&quot;&gt;long list of Jekyll sites&lt;/a&gt; on the Jekyll wiki; many of them have sources available. I started with &lt;a href=&quot;https://github.com/mojombo/tpw&quot;&gt;Tom Preston-Werner's Jekyll site&lt;/a&gt; and modified it heavily.&lt;/p&gt;

&lt;h2&gt;Migrating posts from Wordpress&lt;/h2&gt;

&lt;p&gt;I imported all my Wordpress posts using the simple technique on the Jekyll &lt;a href=&quot;https://github.com/mojombo/jekyll/wiki/blog-migrations&quot;&gt;blog migrations wiki page&lt;/a&gt; (&quot;Using Jekyll + Mysql server connection&quot;). I didn't care about tags, as I was going to redo them anyway. &lt;a href=&quot;http://vitobotta.com/how-to-migrate-from-wordpress-to-jekyll/#importing-from-wordpress&quot;&gt;Here&lt;/a&gt; is a more advanced import script.&lt;/p&gt;

&lt;p&gt;As for images, I just copied &lt;code&gt;wp-content&lt;/code&gt; from my Wordpress installation to to the root directory of the new site. I then deleted in &lt;code&gt;wp-content&lt;/code&gt; except &lt;code&gt;wp-content/uploads&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To maintain the exact same post URLs I put this in &lt;code&gt;_config.yml&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;permalink: /:year/:month/:day/:title
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Disqus&lt;/h2&gt;

&lt;p&gt;I think the easiest way to get all Wordpress comments into Disqus is to install the &lt;a href=&quot;http://wordpress.org/extend/plugins/disqus-comment-system/&quot;&gt;Disqus Wordpress plugin&lt;/a&gt;. (Be sure to sign up for Disqus first.) Then just import all existing comments to Disqus from the plugin's admin page. Voila. Finally, just grab Disqus' &quot;universal code&quot; and place it in &lt;code&gt;_layouts/post.html&lt;/code&gt; (or whereever your posts layout file is).&lt;/p&gt;

&lt;h2&gt;Syntax highlighting&lt;/h2&gt;

&lt;p&gt;For syntax highlighting I installed &lt;a href=&quot;http://pygments.org/&quot;&gt;Pygments&lt;/a&gt; and generated the CSS:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ pygmentize -f html -S default &amp;gt; css/highlight.css
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pygment comes with a bunch of different styles; run &lt;code&gt;pygmentize -L&lt;/code&gt; to list them. I settled on &lt;code&gt;murphy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One minor gotcha: PHP code didn't get highlighted unless it started with &lt;code&gt;&amp;lt;?php&lt;/code&gt;. Turns out you have to add &lt;code&gt;startinline&lt;/code&gt; to the highlight options to get around that, like so: &lt;tt&gt;&amp;lcub;% highlight php startinline %&amp;rcub;&lt;/tt&gt; (end with &lt;tt&gt;&amp;lcub;% endhighlight %&amp;rcub;&lt;/tt&gt;).&lt;/p&gt;

&lt;h2&gt;Tags&lt;/h2&gt;

&lt;p&gt;For tags/categories, I use &lt;code&gt;generate_categories.rb&lt;/code&gt; from &lt;a href=&quot;https://github.com/recurser/jekyll-plugins&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;New design!&lt;/h2&gt;

&lt;p&gt;I decided to completely change the design while I was at it. I didn't realize until now how lacking the old one was. I'm still playing around with colors. If you see encounter any broken links or something that looks good, give me a shout.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Failed requests: Apache benchmarking (ab) gotcha</title>
   <link href="http://fooninja.net/2011/05/24/failed-requests-apache-benchmarking-ab-gotcha"/>
   <updated>2011-05-24T08:15:50+02:00</updated>
   <id>http://fooninja.net/2011/05/24/failed-requests-apache-benchmarking-ab-gotcha</id>
   <content type="html">&lt;p&gt;When I used the Apache benchmarking tool ab for some simple tests I wondered why it returned a ridiculous number of failed requests for a simple page:&lt;/p&gt;

&lt;pre&gt;
Complete requests:      10000
Failed requests:        8366
   (Connect: 0, Receive: 0, Length: 8366, Exceptions: 0
&lt;/pre&gt;


&lt;p&gt;Wait a minute, &lt;i&gt;length&lt;/i&gt;... I realized that ab expects the length (byte size) to be the same for each request, but I was requesting a dynamic page with some random elements, so it counted most of them as failed.&lt;/p&gt;

&lt;p&gt;In other words, if you are benchmarking dynamic pages, ignore length errors.&lt;/p&gt;

&lt;p&gt;You might also want to use &lt;a href=&quot;http://www.hpl.hp.com/research/linux/httperf/&quot;&gt;httperf&lt;/a&gt; instead of ab.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Loading memtest from grub (Fedora)</title>
   <link href="http://fooninja.net/2011/05/05/loading-memtest-from-grub-fedora"/>
   <updated>2011-05-05T07:28:57+02:00</updated>
   <id>http://fooninja.net/2011/05/05/loading-memtest-from-grub-fedora</id>
   <content type="html">&lt;p&gt;Programs started segfaulting for no good reason every now and then on my Thinkpad X61s running Fedora 14. So I turned to memtest86+, and it's easiest to just run it from Grub at boot (especially if you're lacking an optical drive or the ability to boot from a USB stick!).&lt;/p&gt;

&lt;p&gt;memtest86+ might be installed by default; if not, run &lt;tt&gt;yum install memtest86+&lt;/tt&gt;. Run &lt;tt&gt;/usr/sbin/memtest-setup&lt;/tt&gt; to set up a grub entry. The following was added to my &lt;tt&gt;/boot/grub/grub.conf&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;title Memtest86+ (4.10)
        root (hd0,4)
        kernel --type=netbsd /elf-memtest86+-4.10
&lt;/pre&gt;


&lt;p&gt;All done. Reboot, start memtest and do something else for a while.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Guide to programmatic node creation in Drupal 7</title>
   <link href="http://fooninja.net/2011/04/13/guide-to-programmatic-node-creation-in-drupal-7"/>
   <updated>2011-04-13T18:51:34+02:00</updated>
   <id>http://fooninja.net/2011/04/13/guide-to-programmatic-node-creation-in-drupal-7</id>
   <content type="html">&lt;p&gt;&lt;em&gt;See also &lt;a href=&quot;/2011/06/06/updating-nodes-programmatically-in-drupal-7/&quot;&gt;Updating nodes programmatically in Drupal 7&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I had to import a few thousand items from a legacy database to a Drupal 7 site and found that it was quite easy to do so programmatically. Here I'll first show you the basic code for adding nodes and then I'll talk about different field types, including how to add images and term references (taxonomy). If you have any questions, just ask in the comments and I'll be happy to help!&lt;/p&gt;

&lt;h2&gt;Basic node creation - example&lt;/h2&gt;


&lt;p&gt;Put the code below in e.g. &lt;code&gt;foo.php&lt;/code&gt; in your Drupal root directory, and execute it either through the browser or from the command line. I prefer the latter, running the script from the Drupal directory (&lt;code&gt;php foo.php&lt;/code&gt;). Note that &lt;em&gt;you&lt;/em&gt; have to make sure that the input is valid!&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;define&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;DRUPAL_ROOT&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getcwd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;REMOTE_ADDR&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Necessary if running from command line&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;require_once&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DRUPAL_ROOT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;/includes/bootstrap.inc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;drupal_bootstrap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DRUPAL_BOOTSTRAP_FULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$bodytext&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Foo m bar fnord?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;stdClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Create a new node object&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;article&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Or page, or whatever content type you like&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;node_object_prepare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Set some default values&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// If you update an existing node instead of creating a new one,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// comment out the three lines above and uncomment the following:&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// $node = node_load($nid); // ...where $nid is the node id&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;A new node sees the light of day&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;LANGUAGE_NONE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Or e.g. &amp;#39;en&amp;#39; if locale is enabled&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;uid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// UID of the author of the node; or use $node-&amp;gt;name&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$bodytext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;summary&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;text_summary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$bodytext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;format&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;filtered_html&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// I prefer using pathauto, which would override the below path&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;node_created_on&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;YmdHis&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;alias&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node_submit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Prepare node for saving&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;node_save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Node with nid &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;nid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot; saved!&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;x&quot;&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;$node-&amp;gt;language&lt;/code&gt; is important! If you don't have the locale module enabled, the node will not be assigned any particular language. Or rather, the language code used then is &lt;code&gt;LANGUAGE_NONE&lt;/code&gt;, which is a constant with the value &lt;code&gt;und&lt;/code&gt; (undefined) in Drupal. &lt;strong&gt;If you have locale enabled&lt;/strong&gt; nodes can exist in more than one language, and you should specify the language code. Go to Configuration -&gt; Regional and language -&gt; Languages to configure languages and see what code you should use. For English, it would be &lt;code&gt;en&lt;/code&gt;; for Swedish, it would be &lt;code&gt;sv&lt;/code&gt;; etc.&lt;/p&gt;

&lt;p&gt;Other things you might want to set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$node-&gt;status&lt;/code&gt; (1 or 0): published or not&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$node-&gt;promote&lt;/code&gt; (1 or 0): promoted to front page&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$node-&gt;sticky&lt;/code&gt; (1 or 0): sticky at top of lists&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$node-&gt;comment&lt;/code&gt;: 2 =  comments on, 1 = comments off&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;This all you need for basic node creation. I will continue with different field types. The code below should be placed before the &lt;code&gt;node_submit&lt;/code&gt; line. All fields can be accessed with &lt;code&gt;$node-&amp;gt;field_fieldname&lt;/code&gt;, where fieldname is the name you find on Structure -&gt; Content types -&gt; Manage fields.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The best way&lt;/strong&gt; to see how Drupal nodes are made up, and how to work with the various fields, is to simply look at the structure of an existing node. Just create a new PHP file with the first bunch of lines above (including drupal_bootstrap) and add &lt;code&gt;print_r(node_load($nid))&lt;/code&gt;, where $nid is the node id. Or use &lt;a href=&quot;http://drupal.org/project/drush&quot;&gt;drush&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Setting various field types&lt;/h2&gt;


&lt;h3&gt;Text or integer field&lt;/h3&gt;


&lt;p&gt;Nothing special:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_fnordtext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Fnord fnord fnord&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Multiple values (make sure the field is configured to allow this):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_author&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Ford, Tom&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_author&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Fnord, Dom&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;




&lt;h3&gt;Creation time&lt;/h3&gt;


&lt;p&gt;To set a node's creation time, you'd think you could just set &lt;code&gt;$node-&amp;gt;created&lt;/code&gt;. And you can - if you &lt;i&gt;don't&lt;/i&gt; use &lt;code&gt;node_submit()&lt;/code&gt; (or if you set it after &lt;code&gt;node_submit()&lt;/code&gt;). Looking at the &lt;code&gt;node_submit()&lt;/code&gt; function in &lt;code&gt;node.module&lt;/code&gt;, we find this line:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;created&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;strtotime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;REQUEST_TIME&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Which means that &lt;code&gt;node_submit()&lt;/code&gt; will set &lt;code&gt;$node-&amp;gt;created&lt;/code&gt; to the current time if &lt;code&gt;$node-&amp;gt;date&lt;/code&gt; doesn't exist. So, if you want to set the creation time, you have to do something like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;date&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;2009-05-27&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This also means that if you are &lt;i&gt;updating&lt;/i&gt; a node programmatically, don't forget to set &lt;code&gt;$node-&amp;gt;date&lt;/code&gt;; otherwise &lt;code&gt;node_submit()&lt;/code&gt; will change the creation time. (I will write another post about updating nodes.)&lt;/p&gt;

&lt;h3&gt;Date field (datetime, date, datestamp)&lt;/h3&gt;


&lt;p&gt;If you use the &lt;a href=&quot;http://drupal.org/project/date&quot;&gt;date&lt;/a&gt; module, you get three new field types - date, datetime and datestamp. (See &lt;a href=&quot;http://drupal.org/node/262066&quot;&gt;this page&lt;/a&gt; to read about the differences; also check out &lt;a href=&quot;http://drupal.org/node/269813&quot;&gt;this discussion&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;If your field is named datetest, you could do:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// For datetime&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_datetest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;2011-05-25 10:35:58&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// For date&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_datetest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;2011-05-25T10:35:58&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// For datestamp&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_datetest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;strtotime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;2011-05-25 10:35:58&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Note that you don't need to specify a complete date; for datetime and date you can just pad with zeros, e.g. &quot;2011-05-00 00:00:00&quot; (datetime), &quot;2011-00-00T00:00:00&quot; (date), etc. For datestamp you could just do e.g. &lt;code&gt;strtotime(&quot;2011-05-25&quot;)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Important:&lt;/b&gt; Also note that while the exact value you specify will be stored in the database, the actual time displayed on the site might be different depending on timezone settings. When you create a new datetime/date/datestamp field, you get to choose between &lt;a href=&quot;http://drupal.org/node/767182&quot;&gt;five different timezone handling methods&lt;/a&gt;. The default one is &quot;site's time zone&quot;:&lt;/p&gt;

&lt;blockquote&gt;When entering data into the field, the data entered is assumed to be in the site's time zone. When the data is saved to the database, it is converted to UTC.&lt;/blockquote&gt;


&lt;p&gt;However, if you set a date field programmatically like in the above example then no conversion takes place, so make sure you account for the field's timezone settings. Or in other words, if you use &quot;site's time zone&quot;, make sure the time is in UTC.&lt;/p&gt;

&lt;h3&gt;Boolean field&lt;/h3&gt;


&lt;p&gt;Single on/off checkbox:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_bork&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;h3&gt;Term reference (taxonomy) field&lt;/h3&gt;

&lt;p&gt;Set the term reference field tags to taxonomy term id 25 (for more than one term, just repeat the line; and note that it doesn't matter whether the widget type is select list, check boxes/radio buttons or autocomplete):&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_tags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;tid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;em&gt;(If you are trying this with the tags field in the default article content type, and have locale enabled, and have set &lt;code&gt;$node-&amp;gt;language&lt;/code&gt; to e.g. 'en', and it doesn't seem to work: I also encountered this oddity (bug?). For some reason tags are saved to &lt;code&gt;$node-&amp;gt;field_tags[und]&lt;/code&gt; instead of &lt;code&gt;$node-&amp;gt;field_tags[en]&lt;/code&gt;, while e.g. body is saved to &lt;code&gt;$node-&amp;gt;body[en]&lt;/code&gt; as expected. If I create a new term reference field, it works as it should. So either do that, or change the above to &lt;code&gt;$node-&amp;gt;field_tags[und][]['tid']&lt;/code&gt;.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As you can see, you need the know the taxonomy term's id. Fortunately, there’s a Drupal function to help us with this: &lt;a href=&quot;http://api.drupal.org/api/drupal/modules--taxonomy--taxonomy.module/function/taxonomy_get_term_by_name&quot;&gt;&lt;code&gt;taxonomy_get_term_by_name()&lt;/code&gt;&lt;/a&gt;. You supply the name (&quot;Italy&quot;) and it returns an array of matching term objects, so you can do something like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;taxonomy_get_term_by_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Italy&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$foo_keys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;array_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_tags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;tid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$foo_keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Unfortunately, you can't specify a certain vocabulary with this function. This means that if you have the same term name in more than one vocabulary, the above code will just use whatever happens to come first. If you want to specify a certain vocabulary, say the one with id 9, you could do something like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;taxonomy_get_term_by_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Italy&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$foo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$term&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;vid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_tags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;tid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$term&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;tid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;(One way of figuring out the vocabulary id is to run &lt;code&gt;print_r(taxonomy_get_vocabularies());&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;But what if you want to create new vocabulary terms for those that aren’t already in the database? You can use &lt;a href=&quot;http://api.drupal.org/api/drupal/modules--taxonomy--taxonomy.module/function/taxonomy_term_save/7&quot;&gt;&lt;code&gt;taxonomy_term_save()&lt;/code&gt;&lt;/a&gt;, like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$new_term&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&amp;#39;vid&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Fugazi&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// You can optionally also set id of parent term, e.g. &amp;#39;parent&amp;#39; =&amp;gt; 25&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$new_term&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$new_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;taxonomy_term_save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$new_term&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;$new_term&lt;/code&gt; is very conveniently updated with the tid of our newly created term, which you can get with &lt;code&gt;$new_term-&amp;gt;tid&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Node references&lt;/h3&gt;

&lt;p&gt;If you use the &lt;a href=&quot;http://drupal.org/project/references&quot;&gt;references module&lt;/a&gt; for node/user references you can set a reference like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// 453 is the id of the referenced node&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_author&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;nid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;453&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This way you can also add multiple references in the same field - just repeat.&lt;/p&gt;

&lt;h3&gt;Image field&lt;/h3&gt;

&lt;p&gt;Attaching an image to any given image field is easy. Create a file object, copy the file and associate the file object with the image field:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$file_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;drupal_realpath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo.jpg&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&amp;#39;uid&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&amp;#39;uri&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&amp;#39;filemime&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;file_get_mimetype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;s1&quot;&gt;&amp;#39;status&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// You can specify a subdirectory, e.g. public://foo/&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;file_copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;public://&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;field_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;



</content>
 </entry>
 
 <entry>
   <title>How to fix wifi after suspend/resume in Fedora</title>
   <link href="http://fooninja.net/2011/02/11/how-to-fix-wifi-after-suspendresume-in-fedora"/>
   <updated>2011-02-11T02:03:08+01:00</updated>
   <id>http://fooninja.net/2011/02/11/how-to-fix-wifi-after-suspendresume-in-fedora</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; &lt;a href=&quot;/2010/09/02/how-to-fix-wifi-after-suspendresume-in-ubuntu/&quot;&gt;Just like in Ubuntu&lt;/a&gt;, the wireless on my Thinkpad X61s running Fedora 14 would sometimes stop working after suspending and resuming. The wifi light would be on but no networks would be detected. The wifi card is an &quot;Intel PRO/Wireless 4965 AG or AGN&quot;, according to &lt;tt&gt;lspci&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; I used the following quick and dirty script:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;
#!/bin/sh

case &quot;$1&quot; in
    thaw|resume)
        modprobe -r iwlagn
        modprobe iwlagn
        ;;
    *) exit $NA
        ;;
esac
&lt;/pre&gt;


&lt;p&gt;Save it as &lt;tt&gt;90resetwifi.sh&lt;/tt&gt;, run &lt;tt&gt;chmod +x 90resetwifi.sh&lt;/tt&gt; and put it in &lt;tt&gt;/etc/pm/sleep.d&lt;/tt&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Google Earth in 64-bit Linux (Fedora, Ubuntu)</title>
   <link href="http://fooninja.net/2011/01/25/google-earth-in-64-bit-linux-fedora-ubuntu"/>
   <updated>2011-01-25T07:08:50+01:00</updated>
   <id>http://fooninja.net/2011/01/25/google-earth-in-64-bit-linux-fedora-ubuntu</id>
   <content type="html">&lt;p&gt;On my Fedora 14 machine I installed the x86_64 version of the &lt;a href=&quot;http://www.google.com/earth/download/ge/&quot;&gt;Google Earth&lt;/a&gt; rpm. It did however not work:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ google-earth
/usr/bin/google-earth: ./googleearth-bin: /lib/ld-lsb.so.3: bad ELF interpreter: No such file or directory&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Turns out the provided binary is in fact not 64-bit:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ file /opt/google/earth/free/googleearth-bin
/opt/google/earth/free/googleearth-bin: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Installing the package redhat-lsb.i686 fixed it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;# yum install redhat-lsb.i686&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you're running Ubuntu, I believe the package to install is &lt;tt&gt;lsb-core&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Richard &lt;a href=&quot;#comment-2288&quot;&gt;comments&lt;/a&gt; that if you're using the 64-bit fglrx drivers from RPM Fusion with an ATI card in Fedora and get an error about libGL.so.1 not found, try this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;# yum install xorg-x11-drv-catalyst-libs.i686&lt;/code&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>screen: "No more PTYs" error</title>
   <link href="http://fooninja.net/2010/12/02/screen-no-more-ptys-error"/>
   <updated>2010-12-02T15:39:28+01:00</updated>
   <id>http://fooninja.net/2010/12/02/screen-no-more-ptys-error</id>
   <content type="html">&lt;p&gt;On a Linux server running CentOS 5.5 I came across the error &lt;tt&gt;No more PTYs&lt;/tt&gt;, &lt;tt&gt;Sorry, could not find a PTY&lt;/tt&gt; when trying to run screen as a normal user. (It worked fine as root.) I added my user to the group &lt;tt&gt;tty&lt;/tt&gt; and verified the relevant permissions in &lt;tt&gt;/dev&lt;/tt&gt;. Still no dice.&lt;/p&gt;

&lt;p&gt;This fixed the problem:&lt;/p&gt;

&lt;pre&gt;mount -t devpts /dev/ptmx /dev/pts&lt;/pre&gt;


&lt;p&gt;I made it permanent by adding the following to &lt;tt&gt;/etc/fstab&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;/dev/ptmx       /dev/pts        devpts  defaults        0       0&lt;/pre&gt;

</content>
 </entry>
 
 <entry>
   <title>Swedish characters in Ubuntu (svenska tecken (åäö) i konsolen)</title>
   <link href="http://fooninja.net/2010/11/30/swedish-characters-in-ubuntu-svenska-tecken-aao-i-konsolen"/>
   <updated>2010-11-30T15:08:33+01:00</updated>
   <id>http://fooninja.net/2010/11/30/swedish-characters-in-ubuntu-svenska-tecken-aao-i-konsolen</id>
   <content type="html">&lt;p&gt;When ssh'ing to an Ubuntu box running a default English installation, Swedish characters wouldn't work in the console. I fixed it by adding the following to &lt;tt&gt;/etc/profile&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;export LANG=&quot;en_US.utf8&quot;&lt;/pre&gt;


&lt;p&gt;That was enough. You can also play with with the various LC_ variables to modify behaviour. Run &lt;tt&gt;locale&lt;/tt&gt; to see the current settings. If you want a Swedish locale but it's not available, try &lt;tt&gt;locale-gen sv_SE.utf8&lt;/tt&gt; and &lt;tt&gt;dpkg-reconfigure locales&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;If you happen to be using PuTTY, you might also have to change the encoding sometimes. Right-click on the window's title bar, choose Change settings and go to Window -&gt; Translation and change &quot;Character set translation on received data&quot; to UTF-8.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Drupal 7 and cron</title>
   <link href="http://fooninja.net/2010/11/29/drupal-7-and-cron"/>
   <updated>2010-11-29T14:49:09+01:00</updated>
   <id>http://fooninja.net/2010/11/29/drupal-7-and-cron</id>
   <content type="html">&lt;p&gt;When I tried to access Drupal 7's &lt;tt&gt;cron.php&lt;/tt&gt; from localhost I couldn't figure out why it gave me a &lt;tt&gt;403 Forbidden&lt;/tt&gt; error, despite everything looking correct in the configuration. Turns out that you now need to access &lt;tt&gt;cron.php&lt;/tt&gt; with a key. Log in to your Drupal installation and go to &lt;strong&gt;Reports -&gt; Status report&lt;/strong&gt; and you will see the URL you need to use.&lt;/p&gt;

&lt;p&gt;I have something like this is my crontab (one line):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0 * * * * wget -O - -q -t 1 http://foobar.baz/cron.php?cron_key=RTnpslsmQgfjAs8zT29MhZ-FsdfhjKASDh28fH8fd1&lt;/code&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Skype in Fedora 64-bit</title>
   <link href="http://fooninja.net/2010/10/25/skype-in-fedora-64-bit"/>
   <updated>2010-10-25T23:36:28+02:00</updated>
   <id>http://fooninja.net/2010/10/25/skype-in-fedora-64-bit</id>
   <content type="html">&lt;p&gt;Skype only provides a 32-bit package, so to run it in Fedora you'll need to install a load of 32-bit libraries. I did this in Fedora 13, but it should be pretty much the same in earlier (and later) versions.&lt;/p&gt;

&lt;p&gt;Install the required libraries and their dependencies:&lt;/p&gt;

&lt;p&gt;&lt;tt&gt;# yum install qt.i686 qt-x11.i686 ﻿libXv.i686 libXScrnSaver.i686 pulseaudio-libs.i686 pulseaudio-libs-glib2.i686 alsa-plugins-pulseaudio.i686&lt;/tt&gt;&lt;/p&gt;

&lt;p&gt;Download the latest Fedora RPM from &lt;a href=&quot;http://www.skype.com/intl/en/get-skype/on-your-computer/linux/&quot;&gt;Skype's Linux download page&lt;/a&gt; and install it:&lt;/p&gt;

&lt;p&gt;&lt;tt&gt;# rpm -Uvh skype-2.1.0.81-fc10.i586.rpm&lt;/tt&gt;&lt;/p&gt;

&lt;p&gt;Done!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>rxvt-unicode with 256 colors in Fedora/RHEL/CentOS</title>
   <link href="http://fooninja.net/2010/10/25/rxvt-unicode-with-256-colors-in-fedorarhelcentos"/>
   <updated>2010-10-25T18:16:46+02:00</updated>
   <id>http://fooninja.net/2010/10/25/rxvt-unicode-with-256-colors-in-fedorarhelcentos</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Since rxvt-unicode 9.09 (November 2010) support for 256 colors is officially included, which means that in newer releases (e.g., Fedora 14) you can skip all the stuff below and just install &lt;strong&gt;rxvt-unicode-256color&lt;/strong&gt; or &lt;strong&gt;rxvt-unicode-256color-ml&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OLD INSTRUCTIONS:&lt;/strong&gt;
My favorite terminal, rxvt-unicode (urxvt), has 88 color support by default. However, my favorite vim color scheme, &lt;a href=&quot;http://slinky.imukuppi.org/zenburnpage/&quot;&gt;Zenburn&lt;/a&gt;, needs more than that. While I found a &lt;a href=&quot;http://scie.nti.st/2008/10/13/get-rxvt-unicode-with-256-color-support-on-ubunut&quot;&gt;good post&lt;/a&gt; about doing it in Ubuntu I couldn't find anything about doing it in Fedora/RHEL/CentOS; so here goes. I did this on a machine running Fedora 13.&lt;/p&gt;

&lt;p&gt;The rxvt-unicode source actually includes an unsupported patch for 256 colors, so we need to get the source rpm, modify the source and rebuild.&lt;/p&gt;

&lt;h3&gt;Patch and rebuild urxvt&lt;/h3&gt;


&lt;p&gt;If you don't have &lt;tt&gt;yum-builddep&lt;/tt&gt; and &lt;tt&gt;yumdownloader&lt;/tt&gt;, run &lt;tt&gt;yum install yum-utils&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Install necessary build dependencies:&lt;/p&gt;

&lt;pre&gt;# yum-builddep rxvt-unicode&lt;/pre&gt;


&lt;p&gt;Get the source:&lt;/p&gt;

&lt;pre&gt;$ yumdownloader --source rxvt-unicode&lt;/pre&gt;


&lt;p&gt;(You will also need the usual development stuff if you don't already have them, e.g., &lt;tt&gt;yum install gcc make kernel-devel rpm-build&lt;/tt&gt; and possibly others.)&lt;/p&gt;

&lt;p&gt;Install the source rpm:&lt;/p&gt;

&lt;pre&gt;$ rpm -i rxvt-unicode-9.07-1.fc13.src.rpm&lt;/pre&gt;


&lt;p&gt;This will install the source RPM to your user's &lt;tt&gt;~/rpmbuild&lt;/tt&gt; directory.&lt;/p&gt;

&lt;p&gt;Extract the source and make a copy of it:&lt;/p&gt;

&lt;pre&gt;$ cd ~/rpmbuild/SOURCES
$ tar xvfj rxvt-unicode-9.07.tar.bz2
$ cp -r rxvt-unicode-9.07 rxvt-unicode-9.07a&lt;/pre&gt;


&lt;p&gt;Patch the copy with the 256 color patch:&lt;/p&gt;

&lt;pre&gt;$ cd rxvt-unicode-9.07a/
$ patch -p1 &amp;lt; doc/urxvt-8.2-256color.patch&lt;/pre&gt;


&lt;p&gt;Create a patch file for the RPM build:&lt;/p&gt;

&lt;pre&gt;$ cd ..
$ diff -uNr rxvt-unicode-9.07 rxvt-unicode-9.07a &amp;gt; rxvt-unicode-9.07-256colors.patch&lt;/pre&gt;


&lt;p&gt;Now we have to edit the spec file so that the patch is included in the build:&lt;/p&gt;

&lt;pre&gt;$ vi ../SPECS/rxvt-unicode.spec&lt;/pre&gt;


&lt;p&gt;Add &lt;tt&gt;Patch0: rxvt-unicode-9.07-256colors.patch&lt;/tt&gt; to the top section of the file, e.g.:&lt;/p&gt;

&lt;pre&gt;Source1:        rxvt-unicode.desktop
&lt;strong&gt;Patch0:         rxvt-unicode-9.07-256colors.patch&lt;/strong&gt;
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)&lt;/pre&gt;


&lt;p&gt;Also add &lt;tt&gt;%patch0 -p1&lt;/tt&gt; on a line before &lt;tt&gt;%build&lt;/tt&gt; further down, e.g.:&lt;/p&gt;

&lt;pre&gt;%setup -q
&lt;strong&gt;%patch0 -p1&lt;/strong&gt;

%build&lt;/pre&gt;


&lt;p&gt;Also change &lt;tt&gt;Release&lt;/tt&gt; in the top of the file (probably line 3) to something higher, otherwise rpm will think that the already installed version of rxvt-unicode is newer. E.g., from &lt;tt&gt;1%{?dist}&lt;/tt&gt; to &lt;tt&gt;2%{?dist}&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Use &lt;tt&gt;rpmbuild&lt;/tt&gt; to patch, configure, compile and build a binary RPM:&lt;/p&gt;

&lt;pre&gt;$ cd ..
$ rpmbuild -ba SPECS/rxvt-unicode.spec&lt;/pre&gt;


&lt;p&gt;You will find the RPM in the subdirectory &lt;tt&gt;RPMS/&lt;em&gt;arch&lt;/em&gt;&lt;/tt&gt;, e.g., &lt;tt&gt;RPMS/x86_64/rxvt-unicode-9.07-1.fc13.x86_64.rpm&lt;/tt&gt;. Install it as root:&lt;/p&gt;

&lt;pre&gt;# rpm -Uvh RPMS/x86_64/rxvt-unicode-9.07-2.fc13.x86_64.rpm&lt;/pre&gt;


&lt;h3&gt;Fix terminfo&lt;/h3&gt;


&lt;p&gt;Now we just need to make terminfo aware of rxvt-unicode's new capabilities. Thanks again &lt;a href=&quot;http://scie.nti.st/2008/10/13/get-rxvt-unicode-with-256-color-support-on-ubunut&quot;&gt;Garry&lt;/a&gt;: (execute the following as your normal user)&lt;/p&gt;

&lt;pre&gt;$ cd ~
$ infocmp -L rxvt-unicode &amp;gt; rxvt-unicode.terminfo
$ vi rxvt-unicode.terminfo&lt;/pre&gt;


&lt;p&gt;Change (on line 8 in my file)&lt;/p&gt;

&lt;pre&gt;lines_of_memory#0, max_colors#88, max_pairs#256,&lt;/pre&gt;


&lt;p&gt;to&lt;/p&gt;

&lt;pre&gt;lines_of_memory#0, max_colors#256, max_pairs#32767,&lt;/pre&gt;


&lt;p&gt;Final steps:&lt;/p&gt;

&lt;pre&gt;$ install -d .terminfo
$ tic -o .terminfo/ rxvt-unicode.terminfo&lt;/pre&gt;


&lt;p&gt;Start a new &lt;tt&gt;urxvt&lt;/tt&gt; and try running the script &lt;tt&gt;256colors2.pl&lt;/tt&gt;. It's included in the &lt;tt&gt;xterm&lt;/tt&gt; source, but you can also download it from &lt;a href=&quot;http://scie.nti.st/dist/256colors2.pl&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;$ perl 256colors2.pl&lt;/pre&gt;


&lt;p&gt;It should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a rel=&quot;attachment wp-att-614&quot; href=&quot;http://fooninja.net/2010/10/25/rxvt-unicode-with-256-colors-in-fedorarhelcentos/256colors/&quot;&gt;&lt;img title=&quot;256colors&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/10/256colors.png&quot; alt=&quot;&quot; width=&quot;466&quot; height=&quot;170&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Protect urxvt from being updated&lt;/h3&gt;


&lt;p&gt;If you don't want yum to replace your patched urxvt when a newer version is available, edit &lt;tt&gt;/etc/yum.conf&lt;/tt&gt; and add the following line to section &lt;tt&gt;[main]&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;exclude=rxvt-unicode&lt;/pre&gt;

</content>
 </entry>
 
 <entry>
   <title>Speed up encryption in Linux</title>
   <link href="http://fooninja.net/2010/10/20/speed-up-encryption-in-linux"/>
   <updated>2010-10-20T20:05:09+02:00</updated>
   <id>http://fooninja.net/2010/10/20/speed-up-encryption-in-linux</id>
   <content type="html">&lt;p&gt;You might not have realized it but as it is now, dm-crypt - which most people use for encryption in Linux (it's also used by TrueCrypt) - is not SMP-aware; only one processor core is used for each device. This is of course not optimal considering even many consumer systems now have quad-core CPUs (or more!). Recently, however, Andi Kleen of Intel posted a patch to change this:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;http://lkml.org/lkml/2010/5/31/247&quot;&gt;DM-CRYPT: Scale to multiple CPUs&lt;/a&gt; (May 2010)&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://patchwork.kernel.org/patch/103404/&quot;&gt;DM-CRYPT: Scale to multiple CPUs v2&lt;/a&gt; (June 2010)&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://lkml.org/lkml/2010/10/10/44&quot;&gt;DM-CRYPT: Scale to multiple CPUs v3 &lt;/a&gt;(October 2010; for 2.6.36-rc7)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;This has however not yet made it into the mainline kernel, so you'll have to patch the kernel source and recompile yourself. Just get the Linux source for your distribution, apply the right patch and recompile. Exactly how you do this depends on your distribution.&lt;/p&gt;

&lt;p&gt;Below is just a quick and dirty list of the exacts steps I took from start to finish on a standard Ubuntu 10.10 Maverick install running Linux 2.6.35; for actual explanations, there is documentation elsewhere. &lt;a href=&quot;https://help.ubuntu.com/community/Kernel/Compile&quot;&gt;Ubuntu's documentation&lt;/a&gt; (which I followed) is a good starting point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do the following at your own risk!&lt;/strong&gt; It worked for me, and Andi Kleen writes &quot;the 2.6.35 and .32 patches were widely used by lots of users with good results&quot;, but if you don't feel comfortable recompiling the kernel I suggest you wait for these improvements to make it into the mainline kernel. If you do try this, I'd love to hear your comments.&lt;/p&gt;

&lt;p&gt;Install the necessary tools:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo apt-get install fakeroot build-essential crash kexec-tools makedumpfile kernel-wedge
sudo apt-get build-dep linux
sudo apt-get install git-core libncurses5 libncurses5-dev libelf-dev asciidoc binutils-dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Get the source (this will take a while) from Ubuntu's git repository:&lt;/p&gt;

&lt;pre&gt;git clone git://kernel.ubuntu.com/ubuntu/ubuntu-maverick.git&lt;/pre&gt;


&lt;p&gt;Build the control files:&lt;/p&gt;

&lt;pre&gt;cd ubuntu-maverick
fakeroot debian/rules clean&lt;/pre&gt;


&lt;p&gt;Get the &lt;a href=&quot;https://patchwork.kernel.org/patch/103404/&quot;&gt;dm-crypt 2.6.35 patch&lt;/a&gt; in mbox format and apply it:&lt;/p&gt;

&lt;pre&gt;wget https://patchwork.kernel.org/patch/103404/mbox/ -O dm-crypt-scale.mbox
git am dm-crypt-scale.mbox&lt;/pre&gt;


&lt;p&gt;It should say something like &quot;Applying: DM-CRYPT: Scale to multiple CPUs v2&quot;.&lt;/p&gt;

&lt;p&gt;Regenerate the config files (probably not necessary, but doesn't hurt):&lt;/p&gt;

&lt;pre&gt;debian/rules updateconfigs&lt;/pre&gt;


&lt;p&gt;Create the independent packages:&lt;/p&gt;

&lt;pre&gt;skipabi=true skipmodule=true fakeroot debian/rules binary-indep&lt;/pre&gt;


&lt;p&gt;Create the tools package:&lt;/p&gt;

&lt;pre&gt;skipabi=true skipmodule=true fakeroot debian/rules binary-perarch&lt;/pre&gt;


&lt;p&gt;Build the kernel and do something else for a while:&lt;/p&gt;

&lt;pre&gt;fakeroot debian/rules clean
AUTOBUILD=1 NOEXTRAS=1 fakeroot debian/rules binary-generic&lt;/pre&gt;


&lt;p&gt;If you have more than one CPU, you can make the process faster by running concurrent compile commands. Just prepend e.g. &lt;tt&gt;DEB_BUILD_OPTIONS=parallel=2&lt;/tt&gt; if you have two CPUs:&lt;/p&gt;

&lt;pre&gt;DEB_BUILD_OPTIONS=parallel=2 NOEXTRAS=1 AUTOBUILD=1 fakeroot debian/rules binary-generic&lt;/pre&gt;


&lt;p&gt;When this is finally done, you'll have a few new packages:&lt;/p&gt;

&lt;pre&gt;linux-headers-2.6.35-23-generic_2.6.35-23.35_amd64.deb
linux-image-2.6.35-23-generic_2.6.35-23.35_amd64.deb
linux-tools-2.6.35-23_2.6.35-23.35_amd64.deb&lt;/pre&gt;


&lt;p&gt;Install the packages:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd ..
sudo dpkg -i linux-headers-2.6.35-23-generic_2.6.35-23.35_amd64.deb linux-headers-2.6.35-23_2.6.35-23.35_all.deb linux-image-2.6.35-23-generic_2.6.35-23.35_amd64.deb&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Grub should be updated automatically, otherwise check &lt;tt&gt;/boot/grub/brub.cfg&lt;/tt&gt;. Reboot and hope for the best.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Get rid of ubuntuone-syncdaemon</title>
   <link href="http://fooninja.net/2010/10/20/get-rid-of-ubuntuone-syncdaemon"/>
   <updated>2010-10-20T15:25:02+02:00</updated>
   <id>http://fooninja.net/2010/10/20/get-rid-of-ubuntuone-syncdaemon</id>
   <content type="html">&lt;p&gt;Even though I haven't enabled the Ubuntu One client anywhere on my 10.10 (Maverick) system, I see that &lt;tt&gt;ubuntuone-syncdaemon&lt;/tt&gt; (might show up as &lt;tt&gt;ubuntuone-syncd&lt;/tt&gt; in &lt;tt&gt;top&lt;/tt&gt;) is running in the background and eating a bunch of memory. Sigh. If you don't use &lt;a href=&quot;https://one.ubuntu.com/&quot;&gt;Ubuntu One&lt;/a&gt;, Canonical's cloud service, just remove it:&lt;/p&gt;

&lt;pre&gt;sudo ﻿apt-get remove ubuntuone-client&lt;/pre&gt;


&lt;p&gt;(This will also remove a bunch of dependencies.)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Notes on Omeka</title>
   <link href="http://fooninja.net/2010/10/12/notes-on-omeka"/>
   <updated>2010-10-12T16:42:11+02:00</updated>
   <id>http://fooninja.net/2010/10/12/notes-on-omeka</id>
   <content type="html">&lt;p&gt;I've decided on using &lt;a href=&quot;http://omeka.org/&quot;&gt;Omeka&lt;/a&gt; for a project after trying out several alternatives (&lt;a href=&quot;http://kete.net.nz/&quot;&gt;Kete&lt;/a&gt; (Ruby+MySQL), &lt;a href=&quot;http://www.collectiveaccess.org/&quot;&gt;CollectiveAccess&lt;/a&gt; (PHP+MySQL), &lt;a href=&quot;http://www.resourcespace.org/&quot;&gt;ResourceSpace&lt;/a&gt; (PHP+MySQL). It's free software - PHP+MySQL - for creating digital archives and exhibitions. Fairly simple and very easy to install, yet flexible with Dublin Core metadata elements by default and support for OAI-PMH. There are also a whole bunch of &lt;a href=&quot;http://omeka.org/add-ons/plugins/&quot;&gt;plugins&lt;/a&gt;; I found Simple Vocab to be essential for my project. Plus, it looks good by default.&lt;/p&gt;

&lt;p&gt;I will update this page with notes as the project progresses.&lt;/p&gt;

&lt;h3&gt;Problem uploading files with non-ASCII characters&lt;/h3&gt;


&lt;p&gt;When trying to upload a file with a non-ASCII character in the filename (åäö, ë, é etc.), Omeka (version 1.2.1) threw an error: &quot;Something went wrong with image creation. Please notify an administrator.&quot; I looked in Apache's error log and noticed that convert (ImageMagick) was given the wrong filename - non-ASCII characters were stripped. I pinpointed the problem to &lt;tt&gt;application/libraries/Omeka/File/Derivative/Image.php&lt;/tt&gt;, line 131:&lt;/p&gt;

&lt;pre lang=&quot;php&quot;&gt;$old_path = escapeshellarg( $old_path );&lt;/pre&gt;


&lt;p&gt;The real problem was however that LC_CTYPE wasn't set and thus incorrect. I fixed it by adding the following to the top of &lt;tt&gt;admin/index.php&lt;/tt&gt;:&lt;/p&gt;

&lt;pre lang=&quot;php&quot;&gt;setlocale(LC_CTYPE, &quot;en_US.UTF-8&quot;);&lt;/pre&gt;




&lt;h3&gt;Link to original image&lt;/h3&gt;


&lt;p&gt;At first Omeka's naming conventions confused me a bit. Fullsize does not refer to the largest version of an image; it's actually an &lt;i&gt;intermediate&lt;/i&gt; size, the one that's something like 600 pixels wide by default, the one shown on web pages. Omeka stores four different versions of every image: fullsize, thumbnail, square_thumbnail and archive. The last one is the original file. By default, the item/view pages show the fullsize image &lt;i&gt;and&lt;/i&gt; link to the same fullsize image. But I wanted to show the fullsize and link to the &lt;i&gt;original&lt;/i&gt;, big image.&lt;/p&gt;

&lt;p&gt;In my theme's &lt;tt&gt;item/show.php&lt;/tt&gt; (I used rhythm), I changed this (around line 11, after &lt;tt&gt;&amp;lt;div class=&quot;item-img&quot;&amp;gt;&lt;/tt&gt;):&lt;/p&gt;

&lt;pre lang=&quot;php&quot;&gt;
$file = get_current_file();
if ($file-&gt;hasThumbnail()):
    echo display_file($file,array('imageSize'=&gt;'fullsize'));
endif;&lt;/pre&gt;


&lt;p&gt;to this:&lt;/p&gt;

&lt;pre lang=&quot;php&quot;&gt;
$file = get_current_file();
if ($file-&gt;hasThumbnail()):
    $archiveurl = $file-&gt;getWebPath(archive);
    $fullsizeurl = $file-&gt;getWebPath(fullsize);
    echo &quot;&lt;div class=\&quot;item-img\&quot;&gt;&lt;div class=\&quot;item-file image-jpeg\&quot;&gt;&lt;a class=\&quot;download-file\&quot; href=\&quot;$archiveurl\&quot;&gt;&lt;img src=\&quot;$fullsizeurl\&quot; class=\&quot;full\&quot; alt=\&quot;Barn\&quot;/&gt; &lt;/a&gt;&lt;/div&gt;&quot;;
endif;&lt;/pre&gt;


&lt;p&gt;Surely not the nicest way to do it, but it works for me.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Fixed: "PHP Warning:  preg_match_all(): Compilation failed: unrecognized character"</title>
   <link href="http://fooninja.net/2010/10/09/php-warning-unrecognized-character"/>
   <updated>2010-10-09T22:38:55+02:00</updated>
   <id>http://fooninja.net/2010/10/09/php-warning-unrecognized-character</id>
   <content type="html">&lt;p&gt;When testing a site with Amazon's Linux AMI on EC2 - which is actually a customized version of RHEL/CentOS - I got this message in a PHP script:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PHP Warning:  preg_match_all(): Compilation failed: unrecognized character after (?&amp;lt; at offset 3 in ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The solution was upgrading the &lt;tt&gt;pcre&lt;/tt&gt; package. The installed version was 6.6-2.6, while the latest &lt;a href=&quot;http://www.pcre.org/&quot;&gt;official version&lt;/a&gt; is 8.10.&lt;/p&gt;

&lt;p&gt;If you're running CentOS/RHEL/Amazon Linux AMI, you can use Jason Litka's &lt;a href=&quot;http://www.jasonlitka.com/yum-repository/&quot;&gt;Utter Ramblings yum repository&lt;/a&gt; which has 8.x. Follow the instructions on his site and then do &lt;tt&gt;yum install pcre&lt;/tt&gt;. Or, if you set &lt;tt&gt;enabled=0&lt;/tt&gt; like I did, run &lt;tt&gt;yum --enablerepo=utterramblings install pcre&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;(For Amazon's Linux AMI, I also had to change &quot;EL$releasever&quot; to &quot;EL5&quot;, otherwise I got a 404 error.)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Ubuntu: Apache/PHP/MySQL in 5 minutes</title>
   <link href="http://fooninja.net/2010/10/08/ubuntu-lamp"/>
   <updated>2010-10-08T21:37:46+02:00</updated>
   <id>http://fooninja.net/2010/10/08/ubuntu-lamp</id>
   <content type="html">&lt;p&gt;I use Ubuntu on my laptop and thus need a working environment for web development. This means the usual suspects: Apache, PHP and MySQL with some common extras.&lt;/p&gt;

&lt;p&gt;Here's all you need to do to get your Ubuntu system ready for Drupal, Wordpress, etc. I used Ubuntu 10.10 (Maverick), but everything should be about the same in any recent version.&lt;/p&gt;

&lt;p&gt;First, install Apache, PHP and MySQL. This will also install a bunch of dependencies:
&lt;code&gt;$ sudo apt-get install apache2 php5 php5-cli libapache2-mod-php5 mysql-server php5-mysql&lt;/code&gt;
Apache and MySQL are started automatically, and the PHP5 module is enabled in Apache's configuration (if it's not, do &lt;tt&gt;sudo a2enmod php5&lt;/tt&gt;). Since the latter happened &lt;i&gt;after&lt;/i&gt; Apache was started, you need to restart it:&lt;/p&gt;

&lt;pre&gt;$ sudo /etc/init.d/apache2 restart&lt;/pre&gt;


&lt;p&gt;You now have a working environment up and running with the web root in &lt;tt&gt;/var/www&lt;/tt&gt;, but read on for the extras I normally install and how to add a quick virtual host.&lt;/p&gt;

&lt;h3&gt;Some useful extras&lt;/h3&gt;


&lt;p&gt;Many programs use ImageMagick or the fork GraphicsMagick for various image operations (resizing, cropping, etc.). GraphicsMagick has better performance. They can be installed alongside each other. GD is also popular, so let's install that too.&lt;/p&gt;

&lt;pre&gt;# sudo apt-get install graphicsmagick imagemagick php5-gd&lt;/pre&gt;




&lt;h3&gt;Set up a local virtual host&lt;/h3&gt;


&lt;p&gt;Most of my sites have dedicated domains or subdomains, so I want the same when developing.&lt;/p&gt;

&lt;p&gt;In the directory &lt;tt&gt;/etc/apache2/sites-enabled&lt;/tt&gt;, create a new file, &lt;tt&gt;myhost.net&lt;/tt&gt;, with the following: (replace myhost.net and the paths with whatever you want)&lt;/p&gt;

&lt;pre&gt;&amp;lt;VirtualHost *:80&amp;gt;
        ServerAdmin webmaster@localhost
        ServerName myhost.net
        DocumentRoot /home/fooninja/projects/myhost.net
        &amp;lt;Directory /home/fooninja/projects/myhost.net/&amp;gt;
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
        &amp;lt;/Directory&amp;gt;
        ErrorLog ${APACHE_LOG_DIR}/myhost.net_error.log
        CustomLog ${APACHE_LOG_DIR}/myhost.net_access.log combined
&amp;lt;/VirtualHost&amp;gt;&lt;/pre&gt;


&lt;p&gt;The ErrorLog and CustomLog paths have been changed in recent versions of Ubuntu. See &lt;tt&gt;default&lt;/tt&gt; for reference. &lt;tt&gt;AllowOverride All&lt;/tt&gt; might not be optimal for security, but this is just a development box.&lt;/p&gt;

&lt;p&gt;Next, activate the configuration and reload Apache:&lt;/p&gt;

&lt;pre&gt;$ sudo a2ensite myhost.net
$ sudo /etc/init.d/apache2 reload&lt;/pre&gt;


&lt;p&gt;The first line just creates a symlink from &lt;tt&gt;/dev/apache2/sites-available/myhost.net&lt;/tt&gt; to &lt;tt&gt;/etc/apache2/sites-enabled/myhost.net&lt;/tt&gt;, which is the directory Apache is configured to look in.&lt;/p&gt;

&lt;p&gt;If the hostname for your virtual host doesn't exist, or if it exists but points to somewhere other than your local computer, edit &lt;tt&gt;/etc/hosts&lt;/tt&gt; and add &lt;tt&gt;127.0.0.1 myhost.net&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;echo '127.0.0.1 myhost.net' &gt;&gt; /etc/hosts&lt;/pre&gt;




&lt;h3&gt;PHP configuration&lt;/h3&gt;


&lt;p&gt;In &lt;tt&gt;/etc/php5/apache2/php.ini&lt;/tt&gt; I usually change at least some values, like &lt;tt&gt;display_errors&lt;/tt&gt; (set to On to see error messages directly, otherwise you'll have to look in the log file), &lt;tt&gt;post_max_size&lt;/tt&gt; and &lt;tt&gt;upload_max_filesize&lt;/tt&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Get rid of wrong password delay in Linux</title>
   <link href="http://fooninja.net/2010/10/07/get-rid-of-wrong-password-delay-in-linux"/>
   <updated>2010-10-07T18:18:05+02:00</updated>
   <id>http://fooninja.net/2010/10/07/get-rid-of-wrong-password-delay-in-linux</id>
   <content type="html">&lt;p&gt;The password delay when typing the wrong password (su, sudo, ..) seems to be hard-coded to 2 seconds - see pam_unix(8). You can, however, easily disable this often just annoying feature.&lt;/p&gt;

&lt;h3&gt;Disable delay in Ubuntu and Debian&lt;/h3&gt;


&lt;p&gt;Edit &lt;tt&gt;/etc/pam.d/common-auth&lt;/tt&gt; and add &lt;tt&gt;nodelay&lt;/tt&gt; to the line with &lt;tt&gt;auth ... pam_unix.so&lt;/tt&gt;. E.g.:&lt;/p&gt;

&lt;pre&gt;auth    [success=2 default=ignore]      pam_unix.so nullok_secure&lt;/pre&gt;


&lt;p&gt;change to&lt;/p&gt;

&lt;pre&gt;auth    [success=2 default=ignore]      pam_unix.so nullok_secure nodelay&lt;/pre&gt;


&lt;h3&gt;Disable delay in CentOS, RHEL and Fedora&lt;/h3&gt;


&lt;p&gt;Edit &lt;tt&gt;/etc/pam.d/system-auth&lt;/tt&gt; and add &lt;tt&gt;nodelay&lt;/tt&gt; to the line with &lt;tt&gt;auth ... pam_unix.so&lt;/tt&gt;, e.g.:&lt;/p&gt;

&lt;pre&gt;auth        sufficient    pam_unix.so nullok try_first_pass&lt;/pre&gt;


&lt;p&gt;change to&lt;/p&gt;

&lt;pre&gt;auth        sufficient    pam_unix.so nullok try_first_pass nodelay&lt;/pre&gt;


&lt;h3&gt;If brute-forcing scares you&lt;/h3&gt;


&lt;p&gt;You can have users locked out for a specified amount of time (or until you manually let them in again) if they type the wrong password a specified number of times. Look up pam_tally(8), but beware - many configuration examples that you find scattered on message boards just won't work, not least because the order of the PAM directives is important. (Trust me, I spent too much time googling this.)&lt;/p&gt;

&lt;p&gt;In Ubuntu and Debian, the following will lock out users from SSH (but not from local logins) for 120 seconds after typing the wrong password 3 times:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;Open &lt;tt&gt;/etc/pam.d/sshd&lt;/tt&gt; in a text editor.&lt;/li&gt;
    &lt;li&gt;Right before &lt;tt&gt;@include common-auth&lt;/tt&gt;, add the following on its own line:
&lt;code&gt;auth required pam_tally.so onerr=fail deny=3 unlock_time=120&lt;/code&gt;﻿﻿﻿﻿&lt;/li&gt;
&lt;li&gt;Right before &lt;tt&gt;@include common-account&lt;/tt&gt;, add the following on its own line:
&lt;code&gt;account required pam_tally.so reset&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Use &lt;tt&gt;pam_tally&lt;/tt&gt; to check a user:&lt;/p&gt;

&lt;pre&gt;# pam_tally --user foobar
User foobar (1000)  has 4&lt;/pre&gt;


&lt;p&gt;You can also reset the counter manually:&lt;/p&gt;

&lt;pre&gt;# pam_tally --user foobar --reset&lt;/pre&gt;


&lt;p&gt;See also &lt;tt&gt;/var/log/auth.log&lt;/tt&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Linux/BSD network install using PXE and Windows</title>
   <link href="http://fooninja.net/2010/10/07/linuxbsd-network-install-using-pxe-and-windows"/>
   <updated>2010-10-07T14:46:39+02:00</updated>
   <id>http://fooninja.net/2010/10/07/linuxbsd-network-install-using-pxe-and-windows</id>
   <content type="html">&lt;p&gt;If you need to install Linux or one of the BSD:s on a computer without an optical drive and over the network, it's simple. Here's how to do it with Windows as the &lt;a href=&quot;http://en.wikipedia.org/wiki/Preboot_Execution_Environment&quot;&gt;PXE&lt;/a&gt; host. I'll show you how to install Ubuntu, CentOS and OpenBSD, but you can easily adapt the instructions for other systems.&lt;/p&gt;

&lt;p&gt;Prerequisites:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;A Windows machine running &lt;a href=&quot;http://tftpd32.jounin.net/&quot;&gt;tftpd32&lt;/a&gt;, a free TFTP/DHCP server&lt;/li&gt;
    &lt;li&gt;A client machine that supports PXE boot&lt;/li&gt;
    &lt;li&gt;PXE and boot files for the operating system you want to install&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Install tftpd32&lt;/h3&gt;


&lt;p&gt;Tftpd32 is a free DHCP/TFTP/DNS/SNTP/syslog server, and also a TFTP client, for Windows. We only need the DHCP/TFTP part.&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;&lt;a href=&quot;http://tftpd32.jounin.net/&quot;&gt;Download the latest version&lt;/a&gt; (I used 3.50) and install/extract it to &lt;tt&gt;C:\tftpd&lt;/tt&gt;.&lt;/li&gt;
    &lt;li&gt;Create the subdirectory &lt;tt&gt;C:\tftpd\root&lt;/tt&gt;. You will put the install files here later.&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;Prepare the network&lt;/h3&gt;


&lt;p&gt;Depending on your network you might not have to do this, but to avoid any issues with my normal network, which already has a DHCP server that I don't want to bother changing, I temporarily put the host computer and the client (my laptop) on their own network. I configured the host to use 192.168.1.10, netmask 255.255.255.0. After the installation is successfully started I connect the client to the normal network again and do the usual net install over the Internet.&lt;/p&gt;

&lt;p&gt;Note: if you get an error like &quot;PXE-E11: ARP timeout&quot; on the client, make sure nothing strange is going on with the network. Apparently this error can be caused by a number of things, including the hub/switch you use. If you don't have a different one available, consider getting a &lt;a href=&quot;http://en.wikipedia.org/wiki/Ethernet_crossover_cable&quot;&gt;crossover cable&lt;/a&gt; - cheap and often useful.&lt;/p&gt;

&lt;h3&gt;Configure tftpd32&lt;/h3&gt;


&lt;ol&gt;
    &lt;li&gt;Start tftpd32.exe and click on Settings.&lt;/li&gt;
    &lt;li&gt;In the tab GLOBAL, make sure that at least TFTP Server and DHCP Server are checked.&lt;/li&gt;
    &lt;li&gt;In the tab TFTP, point Base Directory to &lt;tt&gt;C:\tftpd\root&lt;/tt&gt;.&lt;/li&gt;
    &lt;li&gt;In the tab DHCP, fill in your desired network settings. Since I had the host and the client on a separate network, and was going to switch over to the normal network later anyway, I just set IP Pool starting address to 192.168.1.100, Size of pool to 10 and mask to 255.255.255.0. Note the field Boot File - you will probably have to change this later.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;img src=&quot;/wp-content/uploads/2010/10/tftpd32-01.png&quot; alt=&quot;Tftpd32 settings (TFTP)&quot; /&gt;
&lt;img src=&quot;/wp-content/uploads/2010/10/tftpd32-02.png&quot; alt=&quot;Tftpd32 settings (DHCP)&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Install Ubuntu&lt;/h3&gt;


&lt;ol&gt;
    &lt;li&gt;Download the netboot files from one of the &lt;a href=&quot;https://launchpad.net/ubuntu/+archivemirrors&quot;&gt;Ubuntu archive mirrors&lt;/a&gt;: dists/&lt;em&gt;maverick&lt;/em&gt;/main/installer-&lt;em&gt;amd64&lt;/em&gt;/current/images/netboot/netboot.tar.gz
The above line is for the &lt;em&gt;amd64&lt;/em&gt; version of &lt;em&gt;Maverick&lt;/em&gt; (10.10); replace with whatever architecture/release you need. For your convenience, here's a &lt;a href=&quot;http://archive.ubuntu.com/ubuntu/dists/maverick/main/installer-amd64/current/images/netboot/netboot.tar.gz&quot;&gt;direct link&lt;/a&gt; to the amd64/maverick file on archive.ubuntu.com. It's about 13 MB.&lt;/li&gt;
    &lt;li&gt;Extract &lt;tt&gt;netboot.tar.gz&lt;/tt&gt; to &lt;tt&gt;C:\tftpd\root&lt;/tt&gt;.&lt;/li&gt;
    &lt;li&gt;Copy the file &lt;tt&gt;C:\tftpd\root\ubuntu-installer\amd64\pxelinux.cfg\default&lt;/tt&gt; to &lt;tt&gt;C:\tftpd\root\pxelinux.cfg&lt;/tt&gt; (change amd64 to i386 if necessary)&lt;/li&gt;
    &lt;li&gt;In Tftpd32 -&amp;gt; Settings -&amp;gt; DHCP, set Boot File to &lt;tt&gt;pxelinux.0&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;You should now be good to go. In the client computer's BIOS, make sure that network boot comes first. (On my Thinkpad X61s, it's &quot;PCI LAN: ...&quot; in Startup -&amp;gt; Boot.)&lt;/p&gt;

&lt;p&gt;If you get an error like &quot;TFTP prefix: Unable to locate configuration file&quot;, double-check that you copied the files correctly.&lt;/p&gt;

&lt;p&gt;If you still have problems, also see the &lt;a href=&quot;http://fooninja.net/2010/10/07/linuxbsd-network-install-using-pxe-and-windows/#comment-1429&quot;&gt;comment by Dmitri&lt;/a&gt; below.&lt;/p&gt;

&lt;h3&gt;Install CentOS&lt;/h3&gt;


&lt;ol&gt;
    &lt;li&gt;Download the contents of the &lt;tt&gt;isolinux&lt;/tt&gt; directory from one of  the  &lt;a href=&quot;http://www.centos.org/modules/tinycontent/index.php?id=30&quot;&gt;CentOS mirrors&lt;/a&gt;: e.g. &lt;tt&gt;5.5/os/x86_64/isolinux&lt;/tt&gt;.&lt;/li&gt;
    &lt;li&gt;Put all the files right in &lt;tt&gt;C:\tftpd\root&lt;/tt&gt; (not in a subdirectory).&lt;/li&gt;
    &lt;li&gt;Create the directory &lt;tt&gt;C:\tftpd\root\pxelinux.cfg&lt;/tt&gt;&lt;/li&gt;
    &lt;li&gt;Copy &lt;tt&gt;C:\tftpd\root\isolinux.cfg&lt;/tt&gt; to &lt;tt&gt;C:\tftpd\root\pxelinux.cfg\default&lt;/tt&gt;. Note: no extension! In Explorer's Folder options, make sure &quot;Hide extensions for known file types&quot; is &lt;strong&gt;not&lt;/strong&gt; checked.&lt;/li&gt;
    &lt;li&gt;Download &lt;a href=&quot;http://www.kernel.org/pub/linux/utils/boot/syslinux/&quot;&gt;syslinux&lt;/a&gt; and extract the file &lt;tt&gt;pxelinux.0&lt;/tt&gt; to &lt;tt&gt;C:\tftpd\root&lt;/tt&gt;. It's in the &lt;tt&gt;core&lt;/tt&gt; directory in the syslinux zip/tar.gz.&lt;/li&gt;
    &lt;li&gt;In Tftpd32 -&amp;gt; Settings -&amp;gt; DHCP, set Boot File to &lt;tt&gt;pxelinux.0&lt;/tt&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Done!&lt;/p&gt;

&lt;h3&gt;Install OpenBSD&lt;/h3&gt;


&lt;ol&gt;
    &lt;li&gt;Download &lt;tt&gt;pxeboot&lt;/tt&gt; and &lt;tt&gt;bsd.rd&lt;/tt&gt; from your &lt;a href=&quot;http://openbsd.org/ftp.html&quot;&gt;favorite mirror&lt;/a&gt;. They are in e.g. &lt;tt&gt;4.7/amd64&lt;/tt&gt;, &lt;tt&gt;4.7/i386&lt;/tt&gt;.&lt;/li&gt;
    &lt;li&gt;Put the files in &lt;tt&gt;C:\tftpd\root&lt;/tt&gt;.&lt;/li&gt;
    &lt;li&gt;In Tftpd32 -&amp;gt; Settings -&amp;gt; DHCP, set Boot File to &lt;tt&gt;pxeboot&lt;/tt&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;That's it. If you require other settings than the &lt;tt&gt;pxeboot&lt;/tt&gt; defaults, &lt;a href=&quot;http://www.openbsd.org/faq/faq6.html#PXE&quot;&gt;look here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you get the error &quot;panic: reverse arp not answered by rarpd(8) or dhcpd(8)&quot;, maybe you loaded &lt;tt&gt;bsd&lt;/tt&gt; instead of &lt;tt&gt;bsd.rd&lt;/tt&gt;?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>OpenBSD 4.8 on a Thinkpad X61s</title>
   <link href="http://fooninja.net/2010/10/07/openbsd-4-8-on-a-thinkpad-x61s"/>
   <updated>2010-10-07T02:10:35+02:00</updated>
   <id>http://fooninja.net/2010/10/07/openbsd-4-8-on-a-thinkpad-x61s</id>
   <content type="html">&lt;p&gt;OpenBSD 4.8 sports some &lt;a href=&quot;http://www.openbsd.org/48.html&quot;&gt;exciting developments&lt;/a&gt; for laptop users, most notably support for ACPI suspend/resume, so I grabbed the snapshot of the upcoming 4.8 release.&lt;/p&gt;

&lt;p&gt;I installed it on my Thinkpad X61s (pretty much the same as X61, which is not very different from X60 and X60s).&lt;/p&gt;

&lt;p&gt;The installation process was very quick and easy yet again, especially since I dedicated the whole disk to OpenBSD and let it decide the partitioning automatically. Less than 10 minutes from start to finish.&lt;/p&gt;

&lt;p&gt;Stuff that worked out of the box:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Sound&lt;/li&gt;
    &lt;li&gt;Volume keys (verified with ears and &lt;tt&gt;mixerctl&lt;/tt&gt;)&lt;/li&gt;
    &lt;li&gt;Brightness keys&lt;/li&gt;
    &lt;li&gt;Battery status (&lt;tt&gt;apm&lt;/tt&gt;)&lt;/li&gt;
    &lt;li&gt;X - no configuration needed, just &lt;tt&gt;startx&lt;/tt&gt;&lt;/li&gt;
    &lt;li&gt;Suspend/resume when pressing Fn-F4. X, wifi etc all working after resume.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The wifi card was recognized alright as &quot;Intel Wireless WiFi Link 4965&quot; with driver &lt;tt&gt;iwn&lt;/tt&gt; but didn't work right away:&lt;/p&gt;

&lt;pre&gt;iwn0: error, 2, could not read firmware iwn-4965
iwn0: could not read firmware&lt;/pre&gt;


&lt;p&gt;This is however Intel's fault. OpenBSD comes with the driver but not the firmware files because, as &lt;tt&gt;man iwn&lt;/tt&gt; explains, &quot;Intel refuses to grant distribution rights without contractual obligations&quot;. The same man page provides a URL to a package with the firmware files that you can install right away with &lt;tt&gt;pkg_add&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;# pkg_add http://damien.bergamini.free.fr/packages/openbsd/iwn-firmware-5.5.tgz&lt;/pre&gt;


&lt;p&gt;(This address was current as of this writing, but please check the man page to verify.)&lt;/p&gt;

&lt;p&gt;After installing the firmware package, you should be good to go. I used this to connect to my WPA-protected home network:&lt;/p&gt;

&lt;pre&gt;# ifconfig iwn0 nwid fooninja wpa wpapsk `wpa-psk fooninja secretpassword`
# dhclient iwn0&lt;/pre&gt;


&lt;p&gt;If everything seems to go well but still doesn't work, make sure the system is not trying to use the wired interface &lt;tt&gt;em0&lt;/tt&gt;. (Try &lt;tt&gt;ifconfig em0 down&lt;/tt&gt; and &lt;tt&gt;route flush&lt;/tt&gt;.)&lt;/p&gt;

&lt;p&gt;By default, closing the lid does not suspend the computer. To change this, set the &lt;tt&gt;sysctl&lt;/tt&gt; entry &lt;tt&gt;machdep.lidsuspend&lt;/tt&gt; to 1:&lt;/p&gt;

&lt;pre&gt;# sysctl machdep.lidsuspend=1&lt;/pre&gt;


&lt;p&gt;To make the change permanent, put it in &lt;tt&gt;/etc/sysctl.conf&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Needless to say, 4.8 is yet another great OpenBSD release. With the small exception of the wifi, which requires some very minor effort (due to Intel), everything I want just works. I will update this page if I stumble upon any issues. I'm also planning on writing a post about using OpenBSD on the desktop.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Xubuntu 10.10 woes</title>
   <link href="http://fooninja.net/2010/10/05/xubuntu-10-10-woes"/>
   <updated>2010-10-05T08:51:16+02:00</updated>
   <id>http://fooninja.net/2010/10/05/xubuntu-10-10-woes</id>
   <content type="html">&lt;p&gt;After installing Xubuntu (&lt;tt&gt;sudo apt-get install xubuntu-desktop&lt;/tt&gt;) in Ubuntu 10.10 (Maverick) I had some issues: when starting Xfce, both xfce4-power-manager &lt;i&gt;and&lt;/i&gt; gnome-power-manager started, resulting in two applets in the panel and general weirdness with screen brightness; and both xscreensaver &lt;i&gt;and&lt;/i&gt; gnome-screensaver started. Also, NetworkManager wouldn't remember/save any passwords.&lt;/p&gt;

&lt;p&gt;To fix the dual power applet thing, I removed &lt;tt&gt;/usr/share/dbus-1/services/gnome-power-manager.service&lt;/tt&gt;. But gnome-power-manager was still being started in the background. &lt;strong&gt;The real solution&lt;/strong&gt; - which fixed both the power manager and the screensaver - was to disable GDM, as I &lt;a href=&quot;http://fooninja.net/2010/07/29/text-boot-in-ubuntu-lucid-lynx-10-04-disabling-gdm/&quot;&gt;describe here&lt;/a&gt;. I put &lt;tt&gt;exec xfce4-session&lt;/tt&gt; in my &lt;tt&gt;~/.xinitrc&lt;/tt&gt; and just startx. I don't like login managers, but if you do, try XDM or SLiM.&lt;/p&gt;

&lt;p&gt;To fix the issue with NetworkManager not remembering passwords, I replaced it with &lt;a href=&quot;http://wicd.sourceforge.net/&quot;&gt;wicd&lt;/a&gt; - which I think is superior, anyway: &lt;tt&gt;sudo apt-get install wicd&lt;/tt&gt;. Next time you start Xfce, it should be in the tray. To access the wicd GUI right away, run &lt;tt&gt;wicd-client -n&lt;/tt&gt;. (Remember, wicd-client is just a front-end; the wicd daemon is running in the background. Once you've configured a network with a password to autoconnect, you can forget about wicd.)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Editing H.264 video in Linux</title>
   <link href="http://fooninja.net/2010/10/04/editing-h-264-video-in-linux"/>
   <updated>2010-10-04T17:55:22+02:00</updated>
   <id>http://fooninja.net/2010/10/04/editing-h-264-video-in-linux</id>
   <content type="html">&lt;p&gt;I recently bought a Canon 5D Mark II, partly to shoot video. Since Linux is my system of choice and since I couldn't find much about 5Dmk2+Linux I did a quick test of the two most popular editors, OpenShot and KDEnlive.&lt;/p&gt;

&lt;p&gt;First, to clear up some confusion: The 5Dmk2 does &lt;i&gt;not&lt;/i&gt; use AVCHD, although it does use H.264. It stores video in a QuickTime MOV container with the H.264 codec for video and PCM for audio. You shoot in 1080p (1920x1080). Thanks to firmware updates it's possible to shoot in &lt;a href=&quot;http://en.wikipedia.org/wiki/24p&quot;&gt;24p&lt;/a&gt; (24 fps - the traditional frame rate for cinema).&lt;/p&gt;

&lt;p&gt;My test system is a AMD Phenom II X6 1055T with 8 GB RAM and a Radeon HD 4350 running Ubuntu 10.10 (Maverick) 64-bit. I will update this post as I go along. Input appreciated!&lt;/p&gt;

&lt;h3&gt;OpenShot&lt;/h3&gt;


&lt;p&gt;The version of &lt;a href=&quot;http://www.openshotvideo.com/&quot;&gt;OpenShot&lt;/a&gt; available in the official Ubuntu repository for Lucid was old (1.1.x), so I instead installed it from OpenShot's PPA:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;sudo add-apt-repository ppa:jonoomph/openshot-edge
sudo apt-get update
sudo apt-get install openshot openshot-doc&lt;/pre&gt;


&lt;p&gt;After starting OpenShot I imported three video files from the 5D. They were 2.8 GB, 4 GB and 1.4 GB.&lt;/p&gt;

&lt;p&gt;I put one of them on the timeline and played it in the preview window. The picture had some strange artifacts around the corners (white dots and lines), playback was a little too slow, sound bad (crackling, popping, laggy). After a lot of trial and error, including transcoding to various formats, the problems went away after upgrading to Ubuntu 10.10. Also, after playing around with KDEnlive I didn't bother returning to OpenShot. While OpenShot is nice and promising, I felt KDEnlive was more mature.&lt;/p&gt;

&lt;h3&gt;KDEnlive&lt;/h3&gt;


&lt;p&gt;Just like with OpenShot, the version of &lt;a href=&quot;http://www.kdenlive.org&quot;&gt;KDEnlive&lt;/a&gt; that you find in the official Ubuntu repository is probably outdated. The KDEnlive project &lt;a href=&quot;http://www.kdenlive.org/user-manual/downloading-and-installing-kdenlive/pre-compiled-packages/ubuntu-packages&quot;&gt;recommends&lt;/a&gt; that you get the latest from a PPA by running the following:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;sudo add-apt-repository ppa:sunab/kdenlive-release
sudo apt-get update
sudo apt-get install kdenlive&lt;/pre&gt;


&lt;p&gt;And just like in OpenShot, when dragging a 5Dmk2 .mov to the timeline, the sound was bad: crackling, popping, lagging. Turned out this wasn't KDEnlive's fault - see below; after fixing this issue, I can edit the files just fine.&lt;/p&gt;

&lt;p&gt;KDEnlive has the ability to transcode (convert) your video files to a more editing-friendly format by either right-clicking on the clip and choosing Transcode, or via File -&gt; Transcode Clips.&lt;/p&gt;

&lt;p&gt;DNxHD is often a good choice. The only trouble is that there's no transcode profile for 24p footage - only 25p, 30p etc. (The frame rate is actually 23.98 in my file.) No problem - under FFmpeg parameters, just change -r 25 (or whatever it is) to -r 23.98. Transcoding went fine. However, the sound problems persisted, which lead me to believe that PulseAudio might be the real culprit. Indeed it was! See below.&lt;/p&gt;

&lt;h3&gt;Fixing sound issues&lt;/h3&gt;


&lt;p&gt;To fix the issue with crackling/lagging sound on Ubuntu with PulseAudio (PulseAudio is the default sound server these days), I finally fixed it by &lt;strong&gt;upgrading Ubuntu from Ubuntu 10.04 (Lucid) to 10.10 (Maverick)&lt;/strong&gt; in the end. I use normal PulseAudio, all default settings. The cause must have been one of the underlying libraries. Before that, I tried to following, which might still be helpful for someone:&lt;/p&gt;

&lt;p&gt;Several people - and the &lt;a href=&quot;http://www.kdenlive.org/user-manual/troubleshooting-and-common-problems/sound-bad-and-delayed&quot;&gt;KDEnlive manual&lt;/a&gt; - suggested removing PulseAudio. I did this:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;sudo apt-get autoremove pulseaudio&lt;/pre&gt;


&lt;p&gt;After doing that, however, the sound no longer worked in KDEnlive (but it did work in other programs): &quot;SDL failed to open audio: no available audio device&quot;. Thanks to &lt;a href=&quot;http://www.kdenlive.org/forum/sdl-failed-open-audio&quot;&gt;this post&lt;/a&gt;, I installed libsdl1.2debian-alsa:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;sudo apt-get install libsdl1.2debian-alsa&lt;/pre&gt;


&lt;p&gt;...which brought back the sound. (Make sure the settings are correct under Settings -&gt; Configure KDEnlive -&gt; Playback -&gt; Audio driver.)&lt;/p&gt;

&lt;p&gt;This fixed it for good - or so I thought! Turns out it's fine for a while when, for example, previewing a clip for the first time. But when I pause and then play again, the popping noises begin. Also, the first second of playback is often repeated once. This happens in both OpenShot and KDEnlive. Fixed it by upgrading to 10.10. Phew!&lt;/p&gt;

&lt;h3&gt;Transcoding&lt;/h3&gt;


&lt;p&gt;H.264 isn't particularly suited for editing, so typically an intermediate format should be used. But which one? Final Cut Pro users often recommend transcoding to ProRes 422. Many recommend &lt;a href=&quot;http://en.wikipedia.org/wiki/DNxHD_codec&quot;&gt;DNxHD&lt;/a&gt;, which ProRes is derived from. Some like CineForm. Etc. Confusing? You bet. It seems like the ideal choice depends on platform and software, and whether or not you need to edit the footage on different platforms.&lt;/p&gt;

&lt;p&gt;For me, DNxHD seems to be the best choice. I can use it in KDEnlive, Final Cut Pro, Premiere, etc.&lt;/p&gt;

&lt;p&gt;You can use ffmpeg to convert to DNxHD. ffmpeg says this about one of the original files:&lt;/p&gt;

&lt;pre&gt;Seems stream 0 codec frame rate differs from container frame rate: 47.95 (48000/1001) -&gt; 23.98 (24000/1001)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'MVI_0909.MOV':
  Duration: 00:08:17.74, start: 0.000000, bitrate: 47802 kb/s
    Stream #0.0(eng): Video: h264, yuv420p, 1920x1080, 23.98 tbr, 23.98 tbn, 47.95 tbc
    Stream #0.1(eng): Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s&lt;/pre&gt;


&lt;p&gt;To transcode/convert to DNxHD, try the following: &lt;i&gt;Note that you can do this from within KDEnlive by right-clicking on a clip; see above.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ffmpeg -i sourcefile.mov -s 1920x1080 -r 23.98 -b 120000k -threads 2 -vcodec dnxhd -acodec copy foobar.mov&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The converts the video to DNxHD (&lt;tt&gt;-vcodec dnxhd&lt;/tt&gt;) while the audio remains unchanged (&lt;tt&gt;-acodec copy&lt;/tt&gt;). Note that this is for a 1920x1080 24 fps video; if you shot with different settings, change the &lt;tt&gt;-r&lt;/tt&gt; and &lt;tt&gt;-s&lt;/tt&gt; options accordingly. Also try playing around with bit rate.&lt;/p&gt;

&lt;p&gt;I haven't had time to check it out yet, but many people recommend using &lt;a href=&quot;http://ekd.tuxfamily.org/&quot;&gt;EKD&lt;/a&gt; for transcoding.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How to show Windows partitions in Thunar (Xfce)</title>
   <link href="http://fooninja.net/2010/09/29/how-to-show-windows-partitions-in-thunar-xfce"/>
   <updated>2010-09-29T14:12:34+02:00</updated>
   <id>http://fooninja.net/2010/09/29/how-to-show-windows-partitions-in-thunar-xfce</id>
   <content type="html">&lt;p&gt;Unlike Gnome's Nautilus, the default file manager for Xfce, Thunar, won't automatically show you Windows / NTFS / FAT32 partitions. No problem. If you want to show for example an NTFS partition in the side pane (along with Desktop, Trash, File System, Documents, etc.), or on the Desktop, just do the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure the NTFS partition is mounted (run &lt;tt&gt;mount&lt;/tt&gt; and check). If it is, skip to step 2. If it's not, run &lt;tt&gt;sudo fdisk -l&lt;/tt&gt; to find out the device name:&lt;/li&gt;
&lt;/ol&gt;


&lt;pre&gt;$ &lt;strong&gt;sudo fdisk -l&lt;/strong&gt;
...
Disk /dev/sda: 320.1 GB, 320072933376 bytes
255 heads, 63 sectors/track, 38913 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x3fcb3fca

   Device Boot      Start         End      Blocks   Id  System
&lt;strong&gt;/dev/sda1&lt;/strong&gt;   *           1       30596   245760448+   7  HPFS/NTFS&lt;/pre&gt;


&lt;p&gt;Ok, in my case it's &lt;tt&gt;/dev/sda1&lt;/tt&gt;. Create a directory for it and then mount it:&lt;/p&gt;

&lt;pre&gt;$ sudo mkdir /mnt/windows
$ sudo mount /dev/sda1 /mnt/windows&lt;/pre&gt;


&lt;p&gt;To mount the partition on boot, add &lt;tt&gt;mount /dev/sda1 /mnt/windows&lt;/tt&gt; to &lt;tt&gt;/etc/rc.local&lt;/tt&gt; (before exit 0) &lt;strong&gt;or&lt;/strong&gt; add an entry in &lt;tt&gt;/etc/fstab&lt;/tt&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In Thunar (the file manager), go to &lt;tt&gt;/mnt&lt;/tt&gt; (or wherever you put the directory with the NTFS mount) and simply drag the Windows/NTFS directory to the left sidepane or the desktop. Voila. You can also right-click on the directory and choose Send To -&gt; Side Pane.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Of course, this is just a shortcut to a directory rather than a representation of the disk; you can't mount/unmount from Thunar. If you want that functionality, a good alterative to Thunar is &lt;a href=&quot;http://pcmanfm.sourceforge.net/&quot;&gt;PCManFM&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Ubuntu 10.10 (Maverick) on a Thinkpad X61s</title>
   <link href="http://fooninja.net/2010/09/28/ubuntu-10-10-maverick-on-a-thinkpad-x61s"/>
   <updated>2010-09-28T16:57:13+02:00</updated>
   <id>http://fooninja.net/2010/09/28/ubuntu-10-10-maverick-on-a-thinkpad-x61s</id>
   <content type="html">&lt;p&gt;I grabbed the beta of Ubuntu 10.10 (Maverick) for installation on my Thinkpad X61s laptop. The X61s is pretty much the same as the X61 (except for a low-voltage CPU and slightly less weight) and the X61, in turn, not much different from the X60.&lt;/p&gt;

&lt;p&gt;My X61s has a Core2Duo  L7500 1.6 GHz, CPU 4 GB RAM and a 320 GB disk. It has a partition with Windows 7 on it, so I would dual-boot.&lt;/p&gt;

&lt;p&gt;Some quick impressions of the installer:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Slick. I very much like that fact you do some configuration (timezone, account, etc.) while the installer is formatting and copying in the background.&lt;/li&gt;
&lt;/ul&gt;


&lt;ul&gt;
    &lt;li&gt; &quot;Log in automatically&quot; is the default option. Unlike in previous versions, I believe. More dumbing down?&lt;/li&gt;
&lt;/ul&gt;


&lt;ul&gt;
    &lt;li&gt; Usability issue: On the &quot;Allocate drive space&quot; screen, where you choose between &quot;Install them side by side&quot;, &quot;Erase and use the entire disk&quot; and &quot;Specify partitions manually (advanced)&quot;, the buttons are &quot;Quit&quot;, &quot;Back&quot; and &quot;Install Now&quot;. &quot;Install Now&quot; should be &quot;Next&quot;, as &quot;Install Now&quot; would be the button for when you, er, actually start installing stuff - not when you haven't even partitioned the disk.&lt;/li&gt;
&lt;/ul&gt;


&lt;ul&gt;
    &lt;li&gt; In the window that first shows a Welcome text and then various info about features in Ubuntu, the text was too wide for the window, so I had to use the scrollbar to read it. I'd guess a lot of people wouldn't realize that. It certainly looks ugly, anyway.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;On the whole, the installation was very smooth and took less than 10 minutes. Dual-booting with an existing Windows installation is, just like before, a no-brainer: the installer takes care of it.&lt;/p&gt;

&lt;h3&gt;Stuff that works out of the box&lt;/h3&gt;


&lt;p&gt;On a fresh standard install of the Ubuntu 10.10 beta (where I ticked the use non-free software box during install) most everything seems to work fine right away:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Sound works.&lt;/li&gt;
    &lt;li&gt;Wifi works.&lt;/li&gt;
    &lt;li&gt;Volume keys on the laptop work.&lt;/li&gt;
    &lt;li&gt;Brightness buttons work.&lt;/li&gt;
    &lt;li&gt;Fn-F4 to suspend works.&lt;/li&gt;
    &lt;li&gt;Suspend when closing the lid (default) works.&lt;/li&gt;
    &lt;li&gt;Resume works. Desktop password-protected by default. Wifi, sound still work after resume.&lt;/li&gt;
    &lt;li&gt;Battery info (time left or time left until full charge) is correctly shown.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;My Windows 7 NTFS partition is shown in Nautilus. Overall, no problems at all yet. More - including use of HDAPS - to come.&lt;/p&gt;

&lt;h3&gt;Random notes&lt;/h3&gt;


&lt;p&gt;Logging in for the first time, my impression was &quot;ugly background!&quot;.  That mix of orange and purple doesn't do it for me. Ok, I'm nitpicking.&lt;/p&gt;

&lt;p&gt;Irritation: I right-clicked the Mail applet to remove it. This also removed the volume applet. Wtf? Right-clicking and choosing &quot;Add to panel&quot;, I can see neither Mail nor Volume. OK. Turns out they both hide under the moniker &quot;Indicator Applet&quot; and there's no obvious way to remove just one of them. Since I'm not going to waste CPU cycles on Gnome anyway, I won't waste a few minutes googling it. The battery info also disappeared when I removed the Ubuntu One applet and there's no sensible way to get it back. Perhaps &quot;Notification Area&quot;, but that just crashed. Oh well.&lt;/p&gt;

&lt;p&gt;Curious to try Unity, the new netbook interface, I installed it (&lt;tt&gt;sudo apt-get install unity&lt;/tt&gt;) and logged out and in again (&quot;Ubuntu Netbook Edition&quot; automatically became the default option in GDM). Slick, but I realized it's not really useful for a 12.1&quot; screen. If I had a smaller screen, I'd use Openbox or a tiling window manager.&lt;/p&gt;

&lt;p&gt;I initially had some issues with xubuntu-desktop and &lt;a href=&quot;/2010/10/05/xubuntu-10-10-woes/&quot;&gt;wrote about it here&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How to transfer files from the Canon 5D Mark II in Linux</title>
   <link href="http://fooninja.net/2010/09/22/how-to-transfer-files-from-the-canon-5d-mark-ii-in-linux"/>
   <updated>2010-09-22T19:24:28+02:00</updated>
   <id>http://fooninja.net/2010/09/22/how-to-transfer-files-from-the-canon-5d-mark-ii-in-linux</id>
   <content type="html">&lt;p&gt;For some strange reason, the Canon EOS 5D Mark II doesn't have USB mass storage support. Annoying, but no big deal. In a standard Ubuntu Linux 10.04 (Lucid) install running Gnome, connecting the camera to the computer automatically mounts it using the gphoto2 backend and brings up a window asking what you want to do. You can choose Open directory and browse the files in Nautilus.&lt;/p&gt;

&lt;p&gt;But what if you want to access the files without the help of Gnome/Nautilus, perhaps from the console?&lt;/p&gt;

&lt;h3&gt;Transfer files using the gphoto2 command-line program&lt;/h3&gt;


&lt;p&gt;With &lt;a href=&quot;http://www.gphoto.org&quot;&gt;gphoto2&lt;/a&gt;, the 5Dmk2 is basically just like any other supported camera.&lt;/p&gt;

&lt;p&gt;First, Install gphoto2 (Ubuntu/Debian: &lt;tt&gt;sudo apt-get install gphoto2&lt;/tt&gt;). Depending on how your system is configured, you might need to be root to execute some of the following.&lt;/p&gt;

&lt;p&gt;After connecting the camera to the computer with the USB cord, let's see if we can detect it:&lt;/p&gt;

&lt;pre&gt;$ &lt;strong&gt;gphoto2 --auto-detect&lt;/strong&gt;
Model                          Port                                            
----------------------------------------------------------
Canon EOS 5D Mark II           usb:&lt;/pre&gt;


&lt;p&gt;Yay! (Reminder: if things suddenly stop working, it might be because you've set the camera to auto-sleep after a minute. Wake it up by half-pressing the shutter release.)&lt;/p&gt;

&lt;p&gt;You can also run &lt;tt&gt;gphoto2 --summary&lt;/tt&gt; to get a whole lot of information, including firmware version and memory card usage:&lt;/p&gt;

&lt;pre&gt;$ &lt;strong&gt;gphoto2 --summary&lt;/strong&gt;
Camera summary:                                                                
Manufacturer: Canon Inc.
Model: Canon EOS 5D Mark II
  Version: 3-2.0.7
  Serial Number: 6372eb34528d4277be90d0f3824df7ab
Vendor Extension ID: 0xb (2.0)
...etc etc...
Device Capabilities:
    File Download, File Deletion, File Upload
    No Image Capture, No Open Capture, Canon EOS Capture

Storage Devices Summary:
store_00010001:
    StorageDescription: CF
    VolumeLabel: None
    Storage Type: Removable RAM (memory card)
    Filesystemtype: Digital Camera Layout (DCIM)
    Access Capability: Read-Write
    Maximum Capability: 16009461760 (15267 MB)
    Free Space (Bytes): 13157040128 (12547 MB)
    Free Space (Images): -1&lt;/pre&gt;


&lt;p&gt;To see what's on the camera's memory card, use &lt;tt&gt;--list-files&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;$ &lt;strong&gt;gphoto2 --list-files&lt;/strong&gt; 
There is no file in folder '/'.                                                
There is no file in folder '/store_00010001'.                                  
There is no file in folder '/store_00010001/DCIM'.
There are 194 files in folder '/store_00010001/DCIM/100EOS5D'.
#1     MVI_0805.MOV               rd 145630 KB video/quicktime
#2     MVI_0806.MOV               rd 106402 KB video/quicktime
#3     _MG_0667.CR2               rd 25299 KB image/x-canon-cr2
#4     _MG_0667.JPG               rd   668 KB 2784x1856 image/jpeg
#5     _MG_0670.CR2               rd 31917 KB image/x-canon-cr2
#6     _MG_0670.JPG               rd  1163 KB 2784x1856 image/jpeg
...etc...&lt;/pre&gt;


&lt;p&gt;To download everything, both photos and videos, use &lt;tt&gt;--get-all-files&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;$ &lt;strong&gt;gphoto2 --get-all-files&lt;/strong&gt;&lt;/pre&gt;


&lt;p&gt;You can also use &lt;tt&gt;--get-file &lt;i&gt;n&lt;/i&gt;&lt;/tt&gt; to only download a specified file or range of files, e.g.:&lt;/p&gt;

&lt;pre&gt;$ &lt;strong&gt;gphoto2 --get-file 5&lt;/strong&gt;
$ &lt;strong&gt;gphoto2 --get-file 10-17&lt;/strong&gt;&lt;/pre&gt;


&lt;p&gt;Check back later for a post on how to edit video from the 5Dmk2 in Linux.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Unix find usage examples</title>
   <link href="http://fooninja.net/2010/09/22/unix-find-usage-examples"/>
   <updated>2010-09-22T16:04:46+02:00</updated>
   <id>http://fooninja.net/2010/09/22/unix-find-usage-examples</id>
   <content type="html">&lt;p&gt;In any Unix system, &lt;tt&gt;find&lt;/tt&gt; is a great tool for finding files matching certain criteria. Here are a number of handy examples on how to use &lt;tt&gt;find&lt;/tt&gt;. They should work in both GNU find (most Linux distributions) and the BSD versions of find, unless otherwise noted. See &lt;tt&gt;man find&lt;/tt&gt; on your system for the full manual. You can, of course, combine any number of options in find.&lt;/p&gt;

&lt;h4&gt;Patterns&lt;/h4&gt;


&lt;p&gt;Find files in the current directory and its subdirectories ending with &lt;tt&gt;.tar.gz&lt;/tt&gt;:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . -name '*.tar.gz'&lt;/pre&gt;


&lt;p&gt;Find files ending with &lt;tt&gt;.tar.gz&lt;/tt&gt; &lt;i&gt;or&lt;/i&gt; &lt;tt&gt;.zip&lt;/tt&gt;:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . \( -name '*.tar.gz' -o -name '*.zip' \)&lt;/pre&gt;


&lt;p&gt;Find files starting with 2008 &lt;strong&gt;and&lt;/strong&gt; ending with &lt;tt&gt;.jpg&lt;/tt&gt; &lt;i&gt;or&lt;/i&gt; &lt;tt&gt;.cr2&lt;/tt&gt;:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . -name '2008*' \( -name '*.tar.gz' -o -name '*.zip' \)&lt;/pre&gt;




&lt;h4&gt;Time&lt;/h4&gt;


&lt;p&gt;Find files with a last modification time older than 30 days:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . -mtime +30&lt;/pre&gt;


&lt;p&gt;Find files with a last modification younger than 30 days:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . -mtime -30&lt;/pre&gt;


&lt;p&gt;For minutes rather than 24-hour periods, use &lt;tt&gt;-mmin&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;You can also use atime/amin, for last accessed; or ctime/cmin, for last status change.&lt;/p&gt;

&lt;p&gt;Find files modified more recently than the file &lt;tt&gt;foo.c&lt;/tt&gt;:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . -newer foo.c&lt;/pre&gt;




&lt;h4&gt;Size&lt;/h4&gt;


&lt;p&gt;In both GNU find and BSD find, you can search for files using &lt;em&gt;n&lt;/em&gt; bytes of space with &lt;tt&gt;-size &lt;em&gt;n&lt;/em&gt;&lt;strong&gt;c&lt;/strong&gt;&lt;/tt&gt;, e.g., &lt;tt&gt;-size 256c&lt;/tt&gt;. To find files larger than the specified value, use a leading + before the number. To find files smaller than the specified value, use a leading - before the number.&lt;/p&gt;

&lt;p&gt;GNU find and FreeBSD find support additional unit specifiers: k for kilobytes, M for megabytes and G for gigabytes. (FreeBSD find also has T for terabytes and P for petabytes.)&lt;/p&gt;

&lt;p&gt;Find files larger than 500 MB in &lt;tt&gt;/home/foo&lt;/tt&gt; and its subdirectories (search is recursive by default):&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find /home/foo -size +500M&lt;/pre&gt;


&lt;p&gt;Find files smaller than 500 MB:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find /home/foo -size -500M&lt;/pre&gt;


&lt;p&gt;Find files that are exactly 64 KB:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find /home/foo -size 64k&lt;/pre&gt;




&lt;h4&gt;Type&lt;/h4&gt;


&lt;p&gt;There are a number of different file types in a Unix system. You can search for a specific file type with &lt;tt&gt;-type &lt;i&gt;c&lt;/i&gt;&lt;/tt&gt;, where &lt;i&gt;c&lt;/i&gt; is one of the following:&lt;/p&gt;

&lt;pre&gt;
         b       block special
         c       character special
         d       directory
         f       regular file
         l       symbolic link
         p       FIFO
         s       socket
&lt;/pre&gt;


&lt;p&gt;Search for files (but not directories) starting with foo:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . -type f -name 'foo*'&lt;/pre&gt;




&lt;h4&gt;Permissions&lt;/h4&gt;


&lt;p&gt;Find files that are world-writable:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find /home/foo/public_html -perm -o=w&lt;/pre&gt;


&lt;p&gt;Just like with &lt;tt&gt;chmod&lt;/tt&gt;, -o means &quot;other users&quot; (i.e., not the owner or the group) and w means write.&lt;/p&gt;

&lt;p&gt;Find files that are user-executable:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . -type f -perm -u+x&lt;/pre&gt;


&lt;p&gt;Find files with the permission 644:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . -perm -644&lt;/pre&gt;




&lt;h4&gt;Ownership&lt;/h4&gt;


&lt;p&gt;Find files owned by user fooninja:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . -user fooninja&lt;/pre&gt;


&lt;p&gt;With GNU find, you can search for a UID with &lt;tt&gt;-uid&lt;/tt&gt;. With BSD find, you can use &lt;tt&gt;-user &lt;i&gt;uid&lt;/i&gt;&lt;/tt&gt;; if there is no such username, &lt;i&gt;uid&lt;/i&gt; will be treated as a UID.&lt;/p&gt;

&lt;h4&gt;Search depth&lt;/h4&gt;


&lt;p&gt;You can use &lt;tt&gt;-maxdepth&lt;/tt&gt; if you don't want to search recursively.&lt;/p&gt;

&lt;p&gt;Find files in the current directory only - no subdirectories:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . -maxdepth 1&lt;/pre&gt;


&lt;p&gt;Find files in the current directory and one level of subdirectories, but no more:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find -maxdepth 2&lt;/pre&gt;


&lt;p&gt;Conversely, you can use &lt;tt&gt;-mindepth&lt;/tt&gt; if you don't want find to search at a level less than the specified number. The following would find /home/foo/bar/xyz but not &lt;tt&gt;/home/foo/bar&lt;/tt&gt; or &lt;tt&gt;/home/foo&lt;/tt&gt;:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find /home/foo -mindepth 2&lt;/pre&gt;




&lt;h4&gt;Performing actions with find&lt;/h4&gt;


&lt;p&gt;You can use &lt;tt&gt;-exec&lt;/tt&gt; to execute a specified command on the results. The following removes files starting with foo:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find . -name 'foo*' -exec rm -f {} \;&lt;/pre&gt;


&lt;p&gt;For each file that find finds, &lt;tt&gt;rm -f {}&lt;/tt&gt; is executed, and {} is replaced by the file name. The semicolon ; terminates the expression and we protect it from shell expansion with the backslash.&lt;/p&gt;

&lt;p&gt;Remove files ending with &lt;tt&gt;.tar.gz&lt;/tt&gt; older than 150 days:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;$ find /foo/backup -mtime +150 -exec rm -f {} \;&lt;/pre&gt;


&lt;p&gt;Careful with these - run them without the exec part first to make sure you are deleting the right files.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Encrypting and decrypting files with a password</title>
   <link href="http://fooninja.net/2010/09/12/encrypting-and-decrypting-files-with-a-password"/>
   <updated>2010-09-12T14:51:26+02:00</updated>
   <id>http://fooninja.net/2010/09/12/encrypting-and-decrypting-files-with-a-password</id>
   <content type="html">&lt;p&gt;The OpenPGP tool &lt;tt&gt;gpg&lt;/tt&gt;, which is part of &lt;a href=&quot;http://www.gnupg.org/&quot;&gt;GnuPG&lt;/a&gt;, is great for encryption and decryption of files. You can use it with a key or simply a passphrase. Here I will show you how do encrypt and decrypt with a passphrase.&lt;/p&gt;

&lt;h3&gt;Encrypt files interactively&lt;/h3&gt;


&lt;p&gt;Encrypt &lt;tt&gt;foo.tar.gz&lt;/tt&gt;:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;gpg -c foo.tar.gz&lt;/pre&gt;


&lt;p&gt;&lt;tt&gt;gpg&lt;/tt&gt; will ask you for a passphrase. &lt;tt&gt;-c&lt;/tt&gt; encrypts with a symmetric cipher; &lt;a href=&quot;http://en.wikipedia.org/wiki/CAST-128&quot;&gt;CAST5&lt;/a&gt; (CAST128) is the default cipher. This generates &lt;tt&gt;foo.tar.gz.gpg&lt;/tt&gt; in the same directory.&lt;/p&gt;

&lt;p&gt;You can specify a filename for the encrypted file:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;gpg -c -o bar.gpg foo.tar.gz&lt;/pre&gt;




&lt;h3&gt;Encrypt files non-interactively&lt;/h3&gt;


&lt;p&gt;To encrypt non-interactively, for example in a shell script or crontab, you can specify the passphrase on the command line:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;gpg --passphrase supersecret -c foo.tar.gz&lt;/pre&gt;




&lt;h3&gt;Decrypt files interactively&lt;/h3&gt;


&lt;p&gt;To decrypt a file:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;gpg foo.tar.gz.gpg&lt;/pre&gt;


&lt;p&gt;You can specify a filename for the decrypted file:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;gpg -o filename foo.tar.gz.gpg&lt;/pre&gt;




&lt;h3&gt;Decrypt files non-interactively&lt;/h3&gt;


&lt;p&gt;To decrypt non-interactively, for example in a shell script or crontab, you can specify the passphrase on the command line:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;gpg --passphrase supersecret foo.tar.gz.gpg&lt;/pre&gt;




&lt;h3&gt;Using a different cipher&lt;/h3&gt;


&lt;p&gt;To use a cipher other than the default one (CAST5), use the option &lt;tt&gt;--cipher-algo name&lt;/tt&gt;. Run &lt;tt&gt;gpg --version&lt;/tt&gt; to get the list of supported ciphers. My gpg says:&lt;/p&gt;

&lt;pre&gt;Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, 
        CAMELLIA192, CAMELLIA256&lt;/pre&gt;

</content>
 </entry>
 
 <entry>
   <title>FTP upload in a shell script</title>
   <link href="http://fooninja.net/2010/09/12/ftp-upload-in-a-shell-script"/>
   <updated>2010-09-12T13:36:39+02:00</updated>
   <id>http://fooninja.net/2010/09/12/ftp-upload-in-a-shell-script</id>
   <content type="html">&lt;p&gt;If you want to upload files non-interactively using the standard FTP client with a shell script, here's a way to do it. The following logs in to the specified host, renames backup.tar.gz to old-backup.tar.gz, uploads backup.tar.gz and exits.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;HOST&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;ftp.foo.bar&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;USER&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;foobar&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;PASSWD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;secret&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;FILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;backup.tar.gz&amp;quot;&lt;/span&gt;

ftp -n &lt;span class=&quot;nv&quot;&gt;$HOST&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;lt;&amp;lt;END_SCRIPT&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;quote USER $USER&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;quote PASS $PASSWD&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;rename $FILE old-$FILE&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;put $FILE&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;quit&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;END_SCRIPT&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Of course, FTP in itself is insecure. If you really have to use it for sending sensitive files across an untrusted network, such as the Internet, at least &lt;a href=&quot;/2010/09/12/encrypting-and-decrypting-files-with-a-password/&quot;&gt;encrypt the files&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Lighttpd mod_rewrite examples</title>
   <link href="http://fooninja.net/2010/09/12/lighttpd-mod_rewrite-examples"/>
   <updated>2010-09-12T03:31:00+02:00</updated>
   <id>http://fooninja.net/2010/09/12/lighttpd-mod_rewrite-examples</id>
   <content type="html">&lt;p&gt;I like to learn by example, so here's an ever-growing list of how to du various URL rewrites with Lighttpd's mod_rewrite. More will be added every now and then. If you need help with your rewrites, use the comment form below.&lt;/p&gt;

&lt;p&gt;(On other sites you might see url.rewrite-final and url.rewrite instead of url.rewrite-once. They are all &lt;a href=&quot;http://redmine.lighttpd.net/wiki/1/Docs:ConfigurationOptions#mod_rewrite-rewriting&quot;&gt;the same&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;When used in example requests, xyz and abc are placeholder names for anything matching a specified pattern that will be backreferenced in the rewrite.&lt;/p&gt;

&lt;pre&gt;
url.rewrite-once = (
# /music -&gt; /index.php?page=music
&quot;^/music$&quot; =&gt; &quot;/index.php?p=music&quot;,

# /music/xyz -&gt; /index.php?page=music&amp;song=xyz
&quot;^/music/([a-zA-Z0-9_-]+)&quot; =&gt; &quot;/index.php?p=music&amp;song=$1&quot;,

# /photos/2009/13241 -&gt; /pix.php?y=2009&amp;id=13241
&quot;^/photos/([0-9]+)/([0-9]+)&quot; =&gt; &quot;/pix.php?y=$1&amp;id=$2&quot;,

# /feeds/rss.xml or /feeds/atom.xml to /index.php?feed=rss-or-atom
&quot;^/feeds/(rss|atom).xml$&quot; =&gt; &quot;/index.php?feed=$1&quot;,

# In the directory /foo, rewrite requests for .php files to index.html
# E.g.: /foo/blabla.php -&gt; /foo/index.html
#       /foo/foobar.php -&gt; /foo/index.html
&quot;^/foo/([A-Za-z0-9]+).php&quot; =&gt; &quot;/foo/index.html&quot;

# Pass on the whole query string with all the GET variables, e.g.
# /foo/index.php?xyz=abc&amp;bar=blah&amp;etc=342 -&gt; /test.php?xyz=abc&amp;bar=..
&quot;^/foo/index.php(?:\?(.*))?&quot; =&gt; &quot;/test.php?$1&quot;
)
&lt;/pre&gt;




&lt;h3&gt;Clean URLs in Wordpress 2.x and 3.x&lt;/h3&gt;


&lt;pre&gt;url.rewrite-once = (
    # Exclude certain directories and .php files in the root directory
    &quot;^/(wp-admin|wp-includes|wp-content)/(.*)&quot; =&gt; &quot;$0&quot;,
    &quot;^/(.*\.php)&quot; =&gt; &quot;$0&quot;,

    # Everything else is handles by Wordpress
    &quot;^/(.*)$&quot; =&gt; &quot;/index.php/$1&quot;
)&lt;/pre&gt;




&lt;h3&gt;Clean URLs in Drupal 6.x&lt;/h3&gt;


&lt;pre&gt;url.rewrite-once = (
    &quot;^/system/test/(.*)$&quot; =&gt; &quot;/index.php?q=system/test/$1&quot;,
    &quot;^/([^.?]*)\?(.*)$&quot; =&gt; &quot;/index.php?q=$1&amp;$2&quot;,
    &quot;^/([^.?]*)$&quot; =&gt; &quot;/index.php?q=$1&quot;,
    &quot;^/rss.xml&quot; =&gt; &quot;/index.php?q=rss.xml&quot;
)&lt;/pre&gt;

</content>
 </entry>
 
 <entry>
   <title>Shell script for importing photos</title>
   <link href="http://fooninja.net/2010/09/11/shell-script-for-importing-photos"/>
   <updated>2010-09-11T02:22:59+02:00</updated>
   <id>http://fooninja.net/2010/09/11/shell-script-for-importing-photos</id>
   <content type="html">&lt;p&gt;I like to sort the photos and videos from my cameras into a simple folder structure like &lt;tt&gt;photos/YYYY/YYYY-MM-DD&lt;/tt&gt;, e.g., &lt;tt&gt;photos/2010/2010-08-15&lt;/tt&gt;. To do this from the command line, I use the ugly but simple little script below. Given a source directory as an argument, it moves all the files from the source directory to new ones in the destination directory, based on the last modified date of each file. New directories for the dates are created if they don't already exist.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;DESTDIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;/home/foo/photos&amp;quot;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# where you want the photos to go&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; -z &lt;span class=&quot;s2&quot;&gt;&amp;quot;$1&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Usage: importpics.sh &amp;lt;directory&amp;gt;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;file in *; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# moves EVERY file. You could also specify *.jpg etc&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; -f &lt;span class=&quot;s2&quot;&gt;&amp;quot;$file&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# we move files but not directories&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;mtime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;stat &lt;span class=&quot;s2&quot;&gt;&amp;quot;$file&amp;quot;&lt;/span&gt; -c%y | cut -d&lt;span class=&quot;s2&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt; -f1&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# e.g. 2009-11-15&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;myear&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;stat &lt;span class=&quot;s2&quot;&gt;&amp;quot;$file&amp;quot;&lt;/span&gt; -c%y | cut -d&lt;span class=&quot;s2&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt; -f1| cut -d&lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt; -f1&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# e.g. 2009&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; ! -d &lt;span class=&quot;s2&quot;&gt;&amp;quot;$DESTDIR/$myear/$mtime&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# if dir doesn&amp;#39;t exist,&lt;/span&gt;
                mkdir -p &lt;span class=&quot;s2&quot;&gt;&amp;quot;$DESTDIR/$myear/$mtime&amp;quot;&lt;/span&gt;; &lt;span class=&quot;c&quot;&gt;# ..create it&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;        &lt;/span&gt;mv -i &lt;span class=&quot;s2&quot;&gt;&amp;quot;$file&amp;quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;$DESTDIR/$myear/$mtime&amp;quot;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# move file to dir&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# chown -R foo $DESTDIR/$myear # if run as root I want to set the right owner&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The script above moves &lt;i&gt;every&lt;/i&gt; file in the source directory (but not directories). If you want to move only, say, JPEGs and RAW files, you could try adding &lt;tt&gt;FOO=&quot;$(ls &lt;em&gt;.jpg &lt;/em&gt;.rw2)&quot;&lt;/tt&gt; to line 9 and change line 10 to &lt;tt&gt;for i in &quot;$FOO&quot;; do&lt;/tt&gt;. (Obviously your file extensions might differ.)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Notes from installing Kete</title>
   <link href="http://fooninja.net/2010/09/09/notes-from-installing-kete"/>
   <updated>2010-09-09T15:07:56+02:00</updated>
   <id>http://fooninja.net/2010/09/09/notes-from-installing-kete</id>
   <content type="html">&lt;p&gt;I set out to install the &lt;a href=&quot;http://kete.net.nz/&quot;&gt;Kete&lt;/a&gt; digital archive software (both 1.2 and 1.3) on a server running Ubuntu 10.04 (Lucid). I followed the &lt;a href=&quot;http://kete.net.nz/documentation/topics/show/114-installation&quot;&gt;installation guide&lt;/a&gt; step-by-step but ran into a couple errors at various stages. Here are some of them, along with other notes about Kete. I will add to this post as I go along.&lt;/p&gt;

&lt;h3&gt;Zebra problems (Kete 1.2)&lt;/h3&gt;


&lt;p&gt;On the last screen of the Kete install, it tries to initialize the Zebra databases. For me, nothing happened - it never got anywhere. I then looked at &lt;tt&gt;zebradb/README&lt;/tt&gt; and tried the following to wipe the databases and start fresh:&lt;/p&gt;

&lt;pre&gt;$ rake zebra:stop # gives an error but does stop zebra. Otherwise killall zebrasrv
(in /home/kete/kete-ga)
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
$ rake zebra:start
$ rake zebra:init # wipes the public db and spits out a bunch of logging info
$ rake zebra:init ZEBRA_DB=private
$ script/backgroundrb start # make sure the background worker is running&lt;/pre&gt;


&lt;p&gt;Next, I went to &quot;Rebuild search databases&quot; in the admin menu and had &quot;clear and restart search engine first&quot; checked. No go: &quot;Rebuild failed. rebuild worker not running anymore? - undefined method `[]' for nil:NilClass&quot;&lt;/p&gt;

&lt;p&gt;I then looked in &lt;tt&gt;log/backgroundrb_debug_11006.log&lt;/tt&gt; and saw the following:&lt;/p&gt;

&lt;pre&gt;#&amp;lt;Errno::ENOENT: No such file or directory - packet_worker_runner \
16:15:zoom_index_rebuild_worker:86:/home/kete/kete-ga/lib/workers:/home/kete/kete-ga/script/load_worker_env&amp;gt;
/var/lib/gems/1.8/gems/packet-0.1.15/lib/packet/packet_master.rb:117:in `exec'
/var/lib/gems/1.8/gems/packet-0.1.15/lib/packet/packet_master.rb:117:in `fork_and_load'
/var/lib/gems/1.8/gems/packet-0.1.15/lib/packet/packet_master.rb:80:in `start_worker'
/var/lib/gems/1.8/gems/packet-0.1.15/lib/packet/packet_connection.rb:80:in `start_worker'
...etc...&lt;/pre&gt;


&lt;p&gt;...which means that the script backgroundrb couldn't find &lt;tt&gt;packet_worker_runner&lt;/tt&gt;. &lt;tt&gt;locate packet_worker_runner&lt;/tt&gt; showed that I had the program - it just wasn't in my kete user's $PATH. Easily fixed:&lt;/p&gt;

&lt;pre&gt;$ locate packet_worker_runner
/var/lib/gems/1.8/bin/packet_worker_runner
$ export PATH=$PATH:/var/lib/gems/1.8/bin
$ script/backgroundrb stop
$ script/backgroundrb start&lt;/pre&gt;


&lt;p&gt;I tried rebuilding the search databases again and... success:&lt;/p&gt;

&lt;pre&gt;Started at Thu Sep 09 12:43:34 UTC 2010

Working on Discussion

16 records processed
Completed.
All records processed at Thu Sep 09 12:44:19 UTC 2010.&lt;/pre&gt;


&lt;h4&gt;Passenger (mod_rails)&lt;/h4&gt;


&lt;p&gt;I got the error &quot;extconf.rb:8:in `require': no such file to load -- mkmf (LoadError)&quot; when I tried to install Passenger with gem. Turns out I just needed to do &lt;tt&gt;apt-get install ruby1.8-dev&lt;/tt&gt; first.&lt;/p&gt;

&lt;h3&gt;Various Ruby issues&lt;/h3&gt;


&lt;p&gt;I tried to use Kete with Ruby 1.9.1 but failed; I realized Ruby 1.8.x is the way to go at the moment, and used &lt;a href=&quot;http://www.rubyenterpriseedition.com/download.html&quot;&gt;Ruby Enterprise Edition&lt;/a&gt; as &lt;a href=&quot;http://kete.net.nz/documentation/topics/show/116&quot;&gt;recommended&lt;/a&gt; by the Kete installation manual. I will however keep the solutions to some of the problems I encountered, as they might be useful in other situations; and here you will also find issues that I encountered with Kete 1.3+Ruby Enterprise Edition (1.8.x).&lt;/p&gt;

&lt;h4&gt;system_timer&lt;/h4&gt;


&lt;p&gt;When running &lt;tt&gt;rake manage_gems:required:install&lt;/tt&gt; in Kete 1.3, the one gem that failed was system_timer. &quot;warning: #warning rubysig.h is obsolete&quot;, &quot;ârb_thread_criticalâ undeclared (first use in this function)&quot;, etc. I was running Ruby 1.9.x at this point and after some googling it turned out that system_timer is not needed in Ruby 1.9.x. So I just ignored it.&lt;/p&gt;

&lt;h4&gt;mysql error when bootstrapping&lt;/h4&gt;


&lt;p&gt;When running &lt;tt&gt;rake db:bootstrap&lt;/tt&gt; I got this error:&lt;/p&gt;

&lt;pre&gt;Couldn't drop kete_ga_development : #&lt;/pre&gt;


&lt;p&gt;The MySQL library was missing. &lt;tt&gt;gem install mysql&lt;/tt&gt; (the error message even tells you do to this) fixed it.&lt;/p&gt;

&lt;h4&gt;RubyGem / rack version error&lt;/h4&gt;


&lt;p&gt;When running &lt;tt&gt;rake db:bootstrap&lt;/tt&gt;, I got another error:&lt;/p&gt;

&lt;pre&gt;rake aborted!
RubyGem version error: rack(1.2.1 not ~&amp;gt; 1.0.1)&lt;/pre&gt;


&lt;p&gt;Turns out I need to downgrade, for some reason, with &lt;tt&gt;gem install rack --version=1.0.1&lt;/tt&gt;.&lt;/p&gt;

&lt;h4&gt;net/https missing:&lt;/h4&gt;


&lt;p&gt;Not done yet:&lt;/p&gt;

&lt;pre&gt;$ rake db:bootstrap
(in /home/kete/kete-ga)
rake aborted!
no such file to load -- net/https&lt;/pre&gt;


&lt;p&gt;Solved with &lt;tt&gt;apt-get install libopenssl-ruby1.9.1&lt;/tt&gt;.&lt;/p&gt;

&lt;h4&gt;Ruby/Zoom (ruby-zoom) with Ruby 1.9.x&lt;/h4&gt;


&lt;p&gt;The latest version of &lt;a href=&quot;http://ruby-zoom.rubyforge.org/&quot;&gt;Ruby/Zoom&lt;/a&gt; didn't work with my version of Ruby, 1.9.1. This seems to be a known problem. I fixed it.&lt;/p&gt;

&lt;pre&gt;# gem install zoom
Building native extensions.  This could take a while...
ERROR:  Error installing zoom:
        ERROR: Failed to build gem native extension.

/usr/bin/ruby1.9.1 extconf.rb
extconf.rb:5: Invalid break
extconf.rb:10: Invalid break
extconf.rb: compile error (SyntaxError)&lt;/pre&gt;


&lt;p&gt;In &lt;tt&gt;/var/lib/gems/1.9.1/gems/zoom-0.4.1&lt;/tt&gt; I commented out both unless ... end clauses. When running &lt;tt&gt;rake&lt;/tt&gt; in that directory, I got some compile errors:&lt;/p&gt;

&lt;pre&gt;rbzoomoptions.c: In function âruby_hash_to_zoom_optionsâ:
rbzoomoptions.c:35: error: âstruct RArrayâ has no member named âlenâ
rbzoomoptions.c:36: error: âstruct RArrayâ has no member named âptrâ
rbzoomoptions.c:37: error: âstruct RArrayâ has no member named âptrâ
rbzoomoptions.c:38: error: âstruct RArrayâ has no member named âptrâ
make: *** [rbzoomoptions.o] Error 1&lt;/pre&gt;


&lt;p&gt;I found &lt;a href=&quot;http://rubynyc.wordpress.com/ruby-1-9-1/installing-mongrel-1-1-5-on-ruby-1-9-1/&quot;&gt;this page&lt;/a&gt; which had the solution for a similar error with another program. Using that as guidance, I opened up &lt;tt&gt;src/rbzoomoptions.c&lt;/tt&gt; and starting on line 35 I replaced&lt;/p&gt;

&lt;pre lang=&quot;c&quot;&gt;    for (i = 0; i &amp;lt; RARRAY (ary)-&amp;gt;len; i++) {
        pair = RARRAY (ary)-&amp;gt;ptr[i];
        key = RARRAY (pair)-&amp;gt;ptr[0];
        value = RARRAY (pair)-&amp;gt;ptr[1];&lt;/pre&gt;


&lt;p&gt;with&lt;/p&gt;

&lt;pre lang=&quot;c&quot;&gt;   for (i = 0; i &amp;lt; RARRAY_LEN(ary); i++) {
        pair = RARRAY_PTR(ary)[i];
        key = RARRAY_PTR(pair)[0];
        value = RARRAY_PTR(pair)[1];&lt;/pre&gt;


&lt;p&gt;And then I ran &lt;tt&gt;rake&lt;/tt&gt; again in &lt;tt&gt;/var/lib/gems/1.9.1/gems/zoom-0.4.1&lt;/tt&gt; and installed the Gem (&lt;tt&gt;gem install pkg/zoom-0.4.1.gem&lt;/tt&gt;). Success! (This worked for me; but I don't know C and cannot vouch for the correctness of my solution, so use it at your own risk.)&lt;/p&gt;

&lt;h4&gt;invalid multibyte char&lt;/h4&gt;


&lt;pre&gt;$ rake db:bootstrap
(in /home/kete/kete-ga)
rake aborted!
/home/kete/kete-ga/vendor/plugins/better_nested_set/lib/better_nested_set_helper.rb:121: invalid multibyte char (US-ASCII)
/home/kete/kete-ga/vendor/plugins/better_nested_set/lib/better_nested_set_helper.rb:121: invalid multibyte char (US-ASCII)
/home/kete/kete-ga/vendor/plugins/better_nested_set/lib/better_nested_set_helper.rb:121: syntax error, unexpected $end, expecting '}'
...       tree.map{|item| [ &quot;#{'Â·Â·' * item.level}#{item[text_...
...                               ^&lt;/pre&gt;


&lt;p&gt;Ok, so I fixed that by adding &lt;tt&gt;# encoding: utf-8&lt;/tt&gt; to the top of &lt;tt&gt;vendor/plugins/better_nested_set/lib/better_nested_set_helper.rb&lt;/tt&gt;. But there's more:&lt;/p&gt;

&lt;pre&gt;$ rake db:bootstrap
(in /home/kete/kete-ga)
rake aborted!
/home/kete/kete-ga/vendor/plugins/translate/lib/translate_controller.rb:109: syntax error, unexpected ':', expecting keyword_then or ',' or ';' or '\n'
/home/kete/kete-ga/vendor/plugins/translate/lib/translate_controller.rb:111: syntax error, unexpected keyword_when, expecting keyword_end
      when &quot;contains&quot;:&lt;/pre&gt;


&lt;p&gt;At this point I realized trying to use Kete with Ruby 1.9.x is futile for me and went with Ruby Enterprise Edition.&lt;/p&gt;

&lt;h4&gt;wrong number of arguments (4 for 3)&lt;/h4&gt;


&lt;p&gt;When running &lt;tt&gt;rake db:bootstrap&lt;/tt&gt;, these errors came up:&lt;/p&gt;

&lt;pre&gt;rake aborted!
wrong number of arguments (4 for 3)
/opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/i18n-0.4.1/lib/i18n/backend/base.rb:34:in `lookup'
/opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/i18n-0.4.1/lib/i18n/backend/base.rb:34:in `translate'
/opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/i18n-0.4.1/lib/i18n.rb:152:in `t'&lt;/pre&gt;


&lt;p&gt;I read somewhere that the i18m gem is not needed by Rails 2.3.5, so I uninstalled it: &lt;tt&gt;gem uninstall i18n&lt;/tt&gt;&lt;/p&gt;

&lt;h3&gt;Working with Kete&lt;/h3&gt;


&lt;h4&gt;Translating&lt;/h4&gt;


&lt;p&gt;I wanted to translate Kete to Swedish. In &lt;tt&gt;config/locales.yml&lt;/tt&gt;, I added &lt;tt&gt;sv: Swedish&lt;/tt&gt; on a new line. In &lt;tt&gt;config/locales&lt;/tt&gt;, I copied &lt;tt&gt;en.yml&lt;/tt&gt; to &lt;tt&gt;sv.yml&lt;/tt&gt; and started translating. (Don't forget to change the second line from en: to whatever language you want to translate to.) That seems to be all you need. There is a &lt;a href=&quot;http://kete.net.nz/documentation/topics/show/289-using-translate-plugin-to-translate-your-kete-installation&quot;&gt;translation interface&lt;/a&gt; if you are running Kete in development mode, but I found it easier and quicker to edit the file directly.&lt;/p&gt;

&lt;p&gt;After translating, I noticed that the &quot;Content by type&quot; sidebar on the main page had all the items (generated by &lt;tt&gt;zoom_class_plural_humanize&lt;/tt&gt; in the translation file) capitalized - except one, &lt;em&gt;ämnen&lt;/em&gt; (Topics). Kete didn't know how to capitalize the Swedish character ä. Didn't have time for a real fix so I just replaced &lt;tt&gt;t.base.zoom_types.topic...etc..&lt;/tt&gt; with Ämnen.&lt;/p&gt;

&lt;h4&gt;Slow? (Not really)&lt;/h4&gt;


&lt;p&gt;At first, I found Kete to be quite slow. &lt;a href=&quot;http://kete.net.nz/en/documentation/topics/show/301-passenger-configuration-options&quot;&gt;These instructions&lt;/a&gt; for configuring Passenger (mod_rails) helped a little. When an instance wasn't already running, the first request took about 11 seconds, which is of course unacceptable. I set &lt;tt&gt;PassengerPoolIdleTime&lt;/tt&gt; to 0, which means applications instances are not shutdown unless necessary. Subsequent requests to the default index page took about 3.9 seconds, which I found hard to swallow.&lt;/p&gt;

&lt;p&gt;At this point I realized, somewhat embarrassingly, that I was running Kete in development mode. After doing &lt;tt&gt;rake db:bootstrap RAILS_ENV=production&lt;/tt&gt;, commenting out &lt;tt&gt;RailsEnv development&lt;/tt&gt; in my Apache configuration and restarting Apache, Kete became very snappy. The first request still took about 6 seconds, but with the aforementioned configuration change (&lt;tt&gt;PassengerPoolIdleTime 0&lt;/tt&gt; in the Apache configuration file) that's not a problem. Requests to the index page now take about 0.2 seconds.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How to fix Ruby mkmf (LoadError)</title>
   <link href="http://fooninja.net/2010/09/08/how-to-fix-ruby-mkmf-loaderror"/>
   <updated>2010-09-08T15:04:14+02:00</updated>
   <id>http://fooninja.net/2010/09/08/how-to-fix-ruby-mkmf-loaderror</id>
   <content type="html">&lt;p&gt;When you try to install a Ruby gem package (like Passenger  a.k.a. mod_rails) in Ubuntu or Debian you might run into the following error:&lt;/p&gt;

&lt;pre&gt;# &lt;strong&gt;gem install passenger&lt;/strong&gt;
Building native extensions.  This could take a while...
ERROR:  Error installing passenger:
        ERROR: Failed to build gem native extension.

/usr/bin/ruby1.8 extconf.rb
extconf.rb:8:in `require': no such file to load -- mkmf (LoadError)
        from extconf.rb:8


Gem files will remain installed in /var/lib/gems/1.8/gems/fastthread-1.0.7 for inspection.
Results logged to /var/lib/gems/1.8/gems/fastthread-1.0.7/ext/fastthread/gem_make.out&lt;/pre&gt;


&lt;p&gt;A required file is missing. Fix it by running &lt;tt&gt;sudo apt-get install ruby1.8-dev&lt;/tt&gt; (replace 1.8 with whatever version you're running - see &lt;tt&gt;ruby -v&lt;/tt&gt;).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How to install fonts in Ubuntu</title>
   <link href="http://fooninja.net/2010/09/08/how-to-install-fonts-in-ubuntu"/>
   <updated>2010-09-08T03:05:56+02:00</updated>
   <id>http://fooninja.net/2010/09/08/how-to-install-fonts-in-ubuntu</id>
   <content type="html">&lt;h3&gt;Install Microsoft core fonts&lt;/h3&gt;


&lt;p&gt;In Ubuntu 10.04 (Lucid), run the following:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;sudo apt-get install ttf-mscorefonts-installer&lt;/pre&gt;


&lt;p&gt;(In older versions of Ubuntu, the package name is &lt;tt&gt;msttcorefonts&lt;/tt&gt;.)&lt;/p&gt;

&lt;p&gt;The core fonts package installs the fonts to &lt;tt&gt;/usr/share/fonts/truetype/msttcorefonts&lt;/tt&gt; and includes Arial, Comic Sans, Courier New, Georgia, Times New Roman, Verdana etc.&lt;/p&gt;

&lt;h3&gt;Install Red Hat's Liberation fonts&lt;/h3&gt;


&lt;p&gt;Red Hat created a set of fonts that serve as free drop-in replacements for three of the most popular Microsoft Windows fonts: Liberation Sans (Arial), Liberation Serif (Times New Roman) and Liberation Mono (Courier New). They are &lt;a href=&quot;http://en.wikipedia.org/wiki/Metric-compatible#Font_metrics&quot;&gt;metric-compatible&lt;/a&gt;, not exact copies.&lt;/p&gt;

&lt;p&gt;To install the Liberation fonts, run the following:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;sudo apt-get install ttf-liberation&lt;/pre&gt;




&lt;h3&gt;Install custom TTF fonts from the command line&lt;/h3&gt;


&lt;p&gt;To install a TrueType font (.ttf), create a &lt;tt&gt;.fonts&lt;/tt&gt; directory in hour home directory if it doesn't already exist:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;mkdir ~/.fonts&lt;/pre&gt;


&lt;p&gt;Next, you simply copy the .ttf file(s) to ~/.fonts:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;cp foobar.ttf ~/.fonts&lt;/pre&gt;


&lt;p&gt;That's it. Note that it will only be available to your logged-in user.&lt;/p&gt;

&lt;p&gt;To install a TrueType font system-wide so that all users have access to it, copy it to &lt;tt&gt;/usr/share/fonts/truetype&lt;/tt&gt;. You might want to create a directory for your own fonts, for the sake of organization:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;mkdir /usr/share/fonts/truetype/myfonts
cp foobar.ttf /usr/share/fonts/truetype/myfonts&lt;/pre&gt;


&lt;p&gt;Note that you will have to restart GIMP, OpenOffice, etc. to see the new font(s).&lt;/p&gt;

&lt;p&gt;Most guides will tell you to run &lt;tt&gt;fc-cache -fv&lt;/tt&gt; after installing a new font, but it appears this is no longer (?) necessary.&lt;/p&gt;

&lt;h3&gt;Install custom TTF fonts from the GUI&lt;/h3&gt;


&lt;p&gt;In the file manager of GNOME/XFCE/etc, simply double-click on the .ttf file. This should open it in the program Font Viewer. In Font Viewer, click &quot;Install Font&quot;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Secure remote backup with rsync+ssh</title>
   <link href="http://fooninja.net/2010/09/06/secure-remote-backup-with-rsyncssh"/>
   <updated>2010-09-06T02:17:27+02:00</updated>
   <id>http://fooninja.net/2010/09/06/secure-remote-backup-with-rsyncssh</id>
   <content type="html">&lt;p&gt;For backup, rsync is a great tool: it synchronizes files and directories using delta encoding, i.e., it only transmits the differences between files. Combined with SSH, it's a simple and secure way to do remote backups.&lt;/p&gt;

&lt;p&gt;All you need is SSH and rsync on both machines. The following will transfer the file &lt;tt&gt;blah.tar.gz&lt;/tt&gt; to the home directory of user foo on server bar:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;rsync -av -e ssh blah.tar.gz foo@bar:&lt;/pre&gt;


&lt;ul&gt;
    &lt;li&gt;-a is &quot;archive mode&quot; and, in my version, equals ﻿﻿-rlptgoD (recursive, copy symlinks as symlinks, preserve permissions / modification times / group / owner / device files / special files).&lt;/li&gt;
    &lt;li&gt;-v increases verbosity (you see what's happening).&lt;/li&gt;
    &lt;li&gt;-e ssh specifices that ssh is the remote shell to be used&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;rsync has many options you can play around with to, among other things, decide what files to keep or not. See &lt;tt&gt;man rsync&lt;/tt&gt;. For example, to copy the home directory of user foo to the directory backup on server bar &lt;em&gt;and&lt;/em&gt; delete files in the remote backup that no longer exist on your local computer, you could use the following:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;rsync -av --delete -e ssh /home/foo foo@bar:backup&lt;/pre&gt;


&lt;p&gt;You can also use &lt;tt&gt;--exclude=PATTERN&lt;/tt&gt; to exclude certain files or directories. The following rsyncs all of &lt;tt&gt;/home/foo&lt;/tt&gt; &lt;i&gt;except&lt;/i&gt; &lt;tt&gt;/home/foo/test&lt;/tt&gt;:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;rsync -av --exclude=&quot;foo/test&quot; -e ssh /home/foo foo@bar:backup&lt;/pre&gt;

</content>
 </entry>
 
 <entry>
   <title>How to tunnel everything through SSH</title>
   <link href="http://fooninja.net/2010/09/06/how-to-tunnel-everything-through-ssh"/>
   <updated>2010-09-06T00:18:00+02:00</updated>
   <id>http://fooninja.net/2010/09/06/how-to-tunnel-everything-through-ssh</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;Problem: &lt;/strong&gt;You don't trust your Internet connection (public wifi at a café, airport, ..), or perhaps it's being limited by a firewall (China, your workplace, ..). Sure, many sites offer SSL encryption these days, but many still don't - and even if they do, others can still see what sites you are contacting. You want to tunnel Firefox/Chrome and other programs through a secure tunnel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Use your OpenSSH client to create a tunnel. All you need is a shell account on a remote server. (I SSH to my home server.) There are a few different ways of doing this. I will start with the easiest one.&lt;/p&gt;

&lt;h2&gt;Simple SOCKS proxy with OpenSSH&lt;/h2&gt;


&lt;p&gt;OpenSSH can act as a SOCKS server and tunnel traffic securely to a remote machine. All you need to do is the following:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;ssh -D 2323 user@server&lt;/pre&gt;


&lt;p&gt;SSH will ask for your password and then a SOCKS proxy is started on port 2323 on your computer. Any traffic to port 2323 will be forwarded through the secure SSH connection. &lt;em&gt;Note that your DNS traffic is &lt;strong&gt;not&lt;/strong&gt; covered by this, so people can still sniff your DNS lookups (or, if they control the network, do even nastier things). See &quot;Tunnel your DNS lookups&quot; further down on this page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For programs with native SOCKS support, all you need to do is configure the program(s) to use localhost 2323 as a SOCKS server. A few examples follow.&lt;/p&gt;

&lt;h4&gt;SOCKS proxy in Firefox&lt;/h4&gt;


&lt;p&gt;Go to Edit -&amp;gt; Preferences -&amp;gt; Advanced -&amp;gt; Network -&amp;gt; Settings. Check &quot;Manual proxy configuration&quot; and enter localhost as a SOCKS v5 host, with the port 2323.&lt;/p&gt;

&lt;h4&gt;SOCKS proxy in Pidgin&lt;/h4&gt;


&lt;p&gt;Go to Tools -&amp;gt; Preferences -&amp;gt; Proxy. Select SOCKS 5 as the Proxy type. Enter localhost as host and 2323 as port. Close the window and restart Pidgin.&lt;/p&gt;

&lt;h3&gt;SOCKS proxy for programs that don't support SOCKS&lt;/h3&gt;


&lt;p&gt;Not all programs support SOCKS proxying natively. A program called &lt;a href=&quot;http://tsocks.sourceforge.net/&quot;&gt;tsocks&lt;/a&gt; lets you use these programs transparently.&lt;/p&gt;

&lt;p&gt;First, install it (Ubuntu/Debian: &lt;tt&gt;sudo apt-get install tsocks&lt;/tt&gt;).&lt;/p&gt;

&lt;p&gt;Next, edit the configuration file:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;If you have root access, edit &lt;tt&gt;/etc/tsocks.conf&lt;/tt&gt; and replace the contents (delete or comment out) with the following:
&lt;pre&gt;server = 127.0.0.1
server_port = 2323&lt;/pre&gt;
&lt;/li&gt;
    &lt;li&gt;If you don't have root access, put the two lines above in &lt;tt&gt;~/.tsock.conf&lt;/tt&gt; and then create a script with the following:
&lt;pre lang=&quot;bash&quot;&gt;#!/bin/sh
TSOCKS_CONF_FILE=$HOME/.tsocks.conf
export TSOCKS_CONF_FILE
exec tsocks &quot;$@&quot;&lt;/pre&gt;
Save it as for example &lt;tt&gt;runtsocks.sh&lt;/tt&gt; and make it executable (&lt;tt&gt;chmod +x runtsocks.sh&lt;/tt&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Now, just prefix any program you want to run with &lt;tt&gt;tsocks&lt;/tt&gt;, e.g.:&lt;/p&gt;

&lt;pre&gt;tsocks elinks whatismyip.com
tsocks irssi&lt;/pre&gt;


&lt;p&gt;Or, if you don't have root access:&lt;/p&gt;

&lt;pre&gt;./runtsocks.sh elinks whatismyip.com
./runtsocks.sh elinks irssi&lt;/pre&gt;


&lt;p&gt;(Don't forget to start the SSH SOCKS proxy first, as outlined above, if you haven't already done so.)&lt;/p&gt;

&lt;h3&gt;Tunnel your DNS lookups&lt;/h3&gt;


&lt;p&gt;Even if you have an SSH proxy running as per the instructions above, your DNS traffic will still be unencrypted. This might be bad - a third party could see for example what web sites you are visiting; in some countries certain sites will be blocked; etc.&lt;/p&gt;

&lt;p&gt;In Firefox, the solution is easy. Simply type &lt;tt&gt;about:config&lt;/tt&gt; in the address bar and set &lt;tt&gt;network.proxy.socks_remote_dns&lt;/tt&gt; to &lt;tt&gt;true&lt;/tt&gt;. This will have the remote end (i.e., the machine you are SSH'ing to) handle the DNS lookups.&lt;/p&gt;

&lt;p&gt;To verify that DNS lookups in Firefox are indeed handled by the remote machine, use tcpdump or similar to inspect the traffic, e.g. &lt;tt&gt;tcpdump port 53&lt;/tt&gt;.&lt;/p&gt;

&lt;h3&gt;SSH chains and jumphosts&lt;/h3&gt;


&lt;p&gt;In the example above, we have &lt;tt&gt;A -&amp;gt; encrypted tunnel -&amp;gt; B&lt;/tt&gt;, where A is your local computer and B is the remote machine. Sometimes you might however need to go through two or more servers to get out of a restrictive network (or into one). E.g.: A can access B. B can access C. C can only be reached by B - but you want to tunnel your traffic from A to C via B.&lt;/p&gt;

&lt;h4&gt;One way to do it&lt;/h4&gt;


&lt;p&gt;To tunnel traffic from A through C via B, first run the following on A:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;ssh -NL 4343:C:22 B&lt;/pre&gt;


&lt;p&gt;Traffic to port 4343 on your local computer will be forwarded to B, where it's sent to port 22 on C. (This will tie up a terminal. If you don't need to enter a password for B, you could add an &amp;amp; to the end to have it run in the background.)&lt;/p&gt;

&lt;p&gt;Next, we use the tunnel above to make a connection from A to C and create a SOCKS proxy on A. Run the following on A:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;ssh -o UserKnownHostsFile=/dev/null \
-o StrictHostKeyChecking=no -ND 2323 -p 4343 localhost&lt;/pre&gt;


&lt;p&gt;Enter your password for C. You now have a SOCKS proxy running on port 2323 and any traffic to it will be sent to C.&lt;/p&gt;

&lt;p&gt;﻿If you need to go through more hosts, see &lt;a href=&quot;http://blog.ganneff.de/blog/2007/12/15/using-a-ssh-jumphost.html&quot;&gt;this blog entry&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Upgrade any Ubuntu from the command line</title>
   <link href="http://fooninja.net/2010/09/02/upgrade-any-ubuntu-from-the-command-line"/>
   <updated>2010-09-02T16:59:13+02:00</updated>
   <id>http://fooninja.net/2010/09/02/upgrade-any-ubuntu-from-the-command-line</id>
   <content type="html">&lt;p&gt;The procedure for updating any recent Ubuntu to a newer version from the command line is the same. Note that you can't jump from e.g. 9.04 to 10.10 in one go; you have to do one version at a time: 9.04 (Jaunty) -&gt; 9.10 (Karmic), 9.10 -&gt; 10.04 (Lucid), 10.04 -&gt; 10.10 (Maverick).&lt;/p&gt;

&lt;p&gt;To upgrade to the next release from the console, first install the package &lt;tt&gt;update-manager-core&lt;/tt&gt; if it's not already installed - it contains the files for the release upgrader:&lt;/p&gt;

&lt;pre lang=&quot;bash&quot;&gt;sudo apt-get install update-manager-core&lt;/pre&gt;


&lt;p&gt;Next, edit &lt;tt&gt;/etc/update-manager/release-upgrades&lt;/tt&gt; and make sure it says &lt;tt&gt;Prompt=normal&lt;/tt&gt; so that it will prompt if a new version of Ubuntu is available.
Finally, run &lt;tt&gt;sudo do-release-upgrade&lt;/tt&gt; to launch the upgrade process. You should see something like this:&lt;/p&gt;

&lt;pre&gt;$ &lt;strong&gt;sudo do-release-upgrade&lt;/strong&gt;
Checking for a new ubuntu release
Done Upgrade tool signature
Done Upgrade tool
Done downloading
extracting 'lucid.tar.gz'
authenticate 'lucid.tar.gz' against 'lucid.tar.gz.gpg'
...etc...&lt;/pre&gt;


&lt;p&gt;After a while it will ask if you want to start the upgrade, tell you how much you need to download and give you a time estimate. Depending on your computer and your bandwidth, it can take quite a while. It will prompt you for input at various stages, mostly about whether or not to keep modified configuration files. Finally, it will ask you to reboot. Do so and cross your fingers (if you are doing it remotely).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How to fix wifi after suspend/resume in Ubuntu</title>
   <link href="http://fooninja.net/2010/09/02/how-to-fix-wifi-after-suspendresume-in-ubuntu"/>
   <updated>2010-09-02T16:45:41+02:00</updated>
   <id>http://fooninja.net/2010/09/02/how-to-fix-wifi-after-suspendresume-in-ubuntu</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; After suspending and then resuming my Thinkpad X61s running Ubuntu 10.04 (Lucid), the wireless would no longer work. Networks were detected but I couldn't connect - nothing happened. The wifi card is an &quot;Intel PRO/Wireless 4965 AG or AGN&quot;, according to &lt;tt&gt;lspci&lt;/tt&gt;. (I had the same problem with Ubuntu 9.10 (Karmic)).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; I still don't know the cause, but restarting networking and unloading/reloading the module for the wireless interface fixed the problem.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Stop networking and network-manager&lt;/span&gt;
stop network-manager
service networking stop

&lt;span class=&quot;c&quot;&gt;# Remove and reload the module for the wifi card&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# (replace iwlagn with your own if you have a different one)&lt;/span&gt;
modprobe -r -f iwlagn
modprobe iwlagn

&lt;span class=&quot;c&quot;&gt;# Start networking and network-manager again&lt;/span&gt;
service networking start
start network-manager
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Save the file as &lt;tt&gt;fixwifi.sh&lt;/tt&gt;, run &lt;tt&gt;chmod +x fixwifi.sh&lt;/tt&gt; and run it as root. Voila! (Hopefully.)&lt;/p&gt;

&lt;p&gt;To make things smoother, if you always have this problem after resuming, you can have the script run automatically after resume. In earlier versions of Ubuntu you would put the script in &lt;tt&gt;/etc/acpi/resume.d&lt;/tt&gt;. This has changed with 10.04 Lucid. You now have to put the script in &lt;tt&gt;/etc/pm/sleep.d&lt;/tt&gt;, but you will have to make some modifications. After looking at the scripts in &lt;tt&gt;/usr/lib/pm-utils/sleep.d&lt;/tt&gt; for guidance, I came up with the following:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;

. &lt;span class=&quot;s2&quot;&gt;&amp;quot;${PM_FUNCTIONS}&amp;quot;&lt;/span&gt;

resume_wifi&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# Stop networking and network-manager&lt;/span&gt;
        stop network-manager
        service networking stop

        &lt;span class=&quot;c&quot;&gt;# Remove and reload the module for the wifi card&lt;/span&gt;
        modprobe -r -f iwlagn
        modprobe iwlagn

        &lt;span class=&quot;c&quot;&gt;# Start networking and network-manager again&lt;/span&gt;
        service networking start
        start network-manager
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;$1&amp;quot;&lt;/span&gt; in
        thaw|resume&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
                resume_wifi
                ;;
        *&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$NA&lt;/span&gt;
                ;;
&lt;span class=&quot;k&quot;&gt;esac&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Save the file as &lt;tt&gt;99fixwifi.sh&lt;/tt&gt;, put it in &lt;tt&gt;/etc/pm/sleep.d&lt;/tt&gt; and make it executable (&lt;tt&gt;chmod +x 99fixwifi.sh&lt;/tt&gt;). Crude? Yes, but it works for me. If you have a nicer solution, let me know!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How to get real full-screen in VirtualBox</title>
   <link href="http://fooninja.net/2010/08/25/how-to-get-real-full-screen-in-virtualbox"/>
   <updated>2010-08-25T16:05:20+02:00</updated>
   <id>http://fooninja.net/2010/08/25/how-to-get-real-full-screen-in-virtualbox</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: When running for example an Ubuntu Linux guest on a Windows host with VirtualBox, you want it to use the whole screen. Maximizing the window or going to full-screen changes the VirtualBox window size, but not the size of the guest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: While the guest OS is running, install &quot;Guest Additions&quot;.&lt;/p&gt;

&lt;p&gt;The following steps work for a standard Ubuntu 10.04 Lucid Lynx desktop install:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;Start your guest OS and log in.&lt;/li&gt;
    &lt;li&gt;Select Device -&amp;gt; Install Guest Additions in the menu, or by using Host Key+D. (On my Windows VirtualBox installation, the default host key is right Ctrl.) This will make a VBOXADDITIONS image appear on your Ubuntu desktop. (If you are not running a graphical environment, type &lt;tt&gt;mount&lt;/tt&gt; so see where it has been mounted.)&lt;/li&gt;
    &lt;li&gt;Build and install the Guest Additions modules by doing &lt;em&gt;one&lt;/em&gt; of the following:
&lt;ul&gt;&lt;li&gt;If you are running the default Gnome desktop: Right-click the VBOXADDITIONS icon on the Desktop and choose &quot;Open with autorun prompt&quot;. After confirming and typing in your password, it will build and install all the necessary modules.&lt;/li&gt;
    &lt;li&gt;If you want to do it from a terminal: Go to the Guest Additions directory by typing &lt;tt&gt;cd /media/VBOXADDITIONS_3.2.8_64453&lt;/tt&gt; (note that the numbers might be different in your version). If you are running a 32-bit guest, start the installer with &lt;tt&gt;sudo sh VboxLinuxAdditions-x86.run&lt;/tt&gt;. If you are running a 64-bit guest, start the installer with &lt;tt&gt;sudo sh VboxLinuxAdditions-amd64.run&lt;/tt&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
    &lt;li&gt;Reboot the guest. When X starts you should now have glorious full-screen.&lt;/li&gt;
&lt;/ol&gt;

</content>
 </entry>
 
 <entry>
   <title>OpenBSD 4.6 on a Thinkpad X61s</title>
   <link href="http://fooninja.net/2010/07/30/openbsd-4-6-on-a-thinkpad-x61s"/>
   <updated>2010-07-30T15:51:08+02:00</updated>
   <id>http://fooninja.net/2010/07/30/openbsd-4-6-on-a-thinkpad-x61s</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;These notes are old; &lt;a href=&quot;http://fooninja.net/2010/10/07/openbsd-4-8-on-a-thinkpad-x61s/&quot;&gt;look here&lt;/a&gt; for my experience with OpenBSD 4.8 on the same laptop.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Having previously only used BSD on servers, I was eager to try  OpenBSD on my Thinkpad X61s (pretty much the same as an X61 - I believe the difference is a slightly lower voltage CPU and a different screen). I grabbed the iso of the latest amd64  snapshot of OpenBSD 4.6 (dated 2009-07-30) and started the &lt;a href=&quot;http://undeadly.org/cgi?action=article&amp;amp;sid=20090721052523&quot;&gt;new installer&lt;/a&gt;. Installation was a breeze – the whole process took less than ten minutes.&lt;/p&gt;

&lt;p&gt;X and sound worked out of the box. So did the hotkeys for sound and brightness.&lt;/p&gt;

&lt;p&gt;Wifi didn't work immediately. While the card (&quot;Intel Wireless WiFi Link 4965&quot;, driver iwn) was recognized, nothing happened. &lt;tt&gt;dmesg&lt;/tt&gt; revealed:&lt;/p&gt;

&lt;pre&gt;Aug  2 01:47:17 jagr /bsd: iwn0: error, 2, could not read firmware iwn-4965
Aug  2 01:47:17 jagr /bsd: iwn0: could not read firmware
&lt;/pre&gt;


&lt;p&gt;Consulting man iwn it turns out that thanks to Intel,  the necessary firmware file cannot be included in OpenBSD, so you have  to download it yourself. The man page provides a link to a prepackaged  version to be installed with &lt;tt&gt;pkg_add&lt;/tt&gt;, so this took only a couple of seconds. After &lt;tt&gt;ifconfig iwn0 down; ifconfig iwn0 up&lt;/tt&gt; the wifi light started blinking and all was well.&lt;/p&gt;

&lt;p&gt;Suspend/resume is not yet working, but is being &lt;a href=&quot;http://undeadly.org/cgi?action=article&amp;amp;sid=20090613140729&quot;&gt;worked on&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Ubuntu Linux, ATI Radeon HD 4350 and Panasonic PX81</title>
   <link href="http://fooninja.net/2010/07/30/ubuntu-linux-ati-radeon-hd-4350-and-panasonic-px81"/>
   <updated>2010-07-30T15:41:45+02:00</updated>
   <id>http://fooninja.net/2010/07/30/ubuntu-linux-ati-radeon-hd-4350-and-panasonic-px81</id>
   <content type="html">&lt;p&gt;I helped configure a HP DC7900 with a Radeon HD 4350 graphics card connected to a 42&quot; Panasonic PX81 plasma tv (the full name is &quot;Panasonic Viera TH-42PX81&quot;; it's a PX80 with some minor additional features) using HDMI and encountered a few bumps along the way. Ubuntu 9.04, &quot;Jaunty&quot;, was the distribution of choice.&lt;/p&gt;

&lt;p&gt;&lt;tt&gt;lspci&lt;/tt&gt; and &lt;tt&gt;aplay -l&lt;/tt&gt; output, respectively:&lt;/p&gt;

&lt;pre&gt;01:00.0 VGA compatible controller: ATI Technologies Inc RV710 [Radeon HD 4350]
01:00.1 Audio device: ATI Technologies Inc R700 Audio Device [Radeon HD 4000 Series]

card 0: HDMI [HDA ATI HDMI], device 3: ATI HDMI [ATI HDMI]
  Subdevices: 1/1
  Subdevice #0: subdevice #0&lt;/pre&gt;


&lt;p&gt;When starting X for the first time the correct resolution (1280x720) was set, but the edges were missing on all sides (i.e., I couldn't see most of the top and bottom panels). Sound didn't appear to work and videos played way too fast. Strange.&lt;/p&gt;

&lt;p&gt;Quick searching didn't yield anything fruitful about the edges issue so, lacking time, I then switched from the &lt;a href=&quot;https://help.ubuntu.com/community/RadeonHD&quot;&gt;open-source radeon driver&lt;/a&gt; to the &lt;a href=&quot;https://help.ubuntu.com/community/BinaryDriverHowto/ATI&quot;&gt;proprietary fglrx driver&lt;/a&gt;. X started in 1920x1080, which was sluggish. I tried to change resolution with &lt;tt&gt;gnome-display-properties&lt;/tt&gt;, but it just displayed a blank window and made X start eating CPU. &lt;a href=&quot;https://bugs.launchpad.net/ubuntu/+source/fglrx-installer/+bug/375368&quot;&gt;This is apparently a bug in fglrx&lt;/a&gt;; a temporary solution is to switch to a terminal (say, Ctrl-Alt-F1) and then back.&lt;/p&gt;

&lt;p&gt;Using &lt;tt&gt;amdcccle&lt;/tt&gt; (&quot;Catalyst Control Center&quot;), I changed &quot;desktop area&quot; to 1280x720 and it seemed to work fine. The program wrote a new xorg.conf. It did not, however, remember this setting the next time, so I added &lt;tt&gt;Modes &quot;1280x720&quot;&lt;/tt&gt; to the &lt;tt&gt;Screen&lt;/tt&gt; section in &lt;tt&gt;/etc/X11/xorg.conf&lt;/tt&gt;.&lt;/p&gt;

&lt;h3&gt;Sound&lt;/h3&gt;


&lt;p&gt;With fglrx sound worked fine, but I had to change settings in &lt;tt&gt;gnome-sound-properties&lt;/tt&gt; first. I set sound playback to &quot;HDA ATI HDMI ATI HDMI (ALSA)&quot; and default mixer tracks device to &quot;HDA ATI HDMI (Alsa mixer)&quot;. I had to set this manually in some programs, for example:&lt;/p&gt;

&lt;pre&gt;mplayer -ao alsa:device=hw=0.3&lt;/pre&gt;


&lt;p&gt;In gmplayer's Preferences -&amp;gt; Audio, I chose alsa and then entered &lt;tt&gt;hw=0.3&lt;/tt&gt; in the Device field under Configure driver. This made sound work, but for some reason a ton of error messages – &quot;[AO_ALSA] Unable to find simple control 'PCM'&quot; – were being generated during playback. &quot;Enable Software Mixer&quot;, also in the Audio preferences, made them go away.&lt;/p&gt;

&lt;h3&gt;Video tearing&lt;/h3&gt;


&lt;p&gt;All was well... until I noticed video tearing. This is apparently  normal for the fglrx driver – at least for newer cards – when using xv  output. So I tried OpenGL output in mplayer (-vo gl), which resulted in  flickering when windowed. OpenGL did however work fairly well in  fullscreen, and disabling compiz solved the flickering issue: System  -&amp;gt; Preferences -&amp;gt; Appearance -&amp;gt; Visual Effects - None (or: &lt;tt&gt;gnome-appearance-properties&lt;/tt&gt;). The flickering is fixed in a later version of fglrx, but the &lt;strong&gt;the recommended way to get rid of tearing still seems to be:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Disabling compositing (&quot;desktop effects&quot;)&lt;/li&gt;
    &lt;li&gt;Setting &quot;Wait for vertical refresh&quot; to &quot;Always on&quot; in amdcccle -&amp;gt; 3D -&amp;gt; More Settings.&lt;/li&gt;
    &lt;li&gt;Using OpenGL renderer (&lt;tt&gt;-vo gl&lt;/tt&gt; in mplayer)&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;You can also use the &lt;tt&gt;aticonfig&lt;/tt&gt; tool to experiment with various settings. See &lt;tt&gt;aticonfig -h&lt;/tt&gt; for all the options (for example, &lt;tt&gt;--vs on&lt;/tt&gt; for vsync).&lt;/p&gt;

&lt;p&gt;There's a lot of discussion about video playback issues with ATI cards. If you're having problems, check out the &lt;a href=&quot;http://phoronix.com/forums/forumdisplay.php?f=19&quot;&gt;AMD/ATI Linux forum&lt;/a&gt; on Phoronix, where AMD developers participate. And, of course, see if  there's a new version of the driver out; AMD releases new versions of  Catalyst frequently.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Happy Hacking Keyboard Professional 2</title>
   <link href="http://fooninja.net/2010/07/30/happy-hacking-keyboard-professional-2"/>
   <updated>2010-07-30T11:24:44+02:00</updated>
   <id>http://fooninja.net/2010/07/30/happy-hacking-keyboard-professional-2</id>
   <content type="html">&lt;p&gt;Having used the Happy Hacking Keyboard Lite 2 for several years, I came across &lt;a href=&quot;http://www.geekhack.org/&quot;&gt;geekhack&lt;/a&gt; one day. It's a wonderful forum where keyboard aficionados talk about their recent purchases, post audio clips of keyboards and discuss the finer points of key switches.&lt;/p&gt;

&lt;p&gt;I saw the &lt;a href=&quot;/wp-content/uploads/2010/07/the_light-300x212.jpg&quot;&gt;light&lt;/a&gt; and realized that I needed a Real keyboard.&lt;/p&gt;

&lt;p&gt;I find the Happy Hacking layout superior to anything else I've come across – it's just &lt;em&gt;right&lt;/em&gt; – so the choice was easy: Happy Hacking Keyboard Professional 2. The Lite 2 is your typical rubber dome keyboard, albeit with a great layout; the Pro 2 has almost the same layout, but also &lt;em&gt;real mechanical switches&lt;/em&gt; instead of &lt;a href=&quot;http://geekhack.org/showwiki.php?title=Basics+on+Keyboard+Internals#Rubber_dome_keyboards&quot;&gt;membrane&lt;/a&gt;. It makes all the difference.&lt;/p&gt;

&lt;p&gt;I got mine from &lt;a href=&quot;http://www.benippon.com/&quot;&gt;beNippon&lt;/a&gt; for about 250–260 USD. &quot;$250 for a keyboard?!!&quot; Oh, yes. Considering that it's one of my most important tools and the fact that I will likely use it for 10 000+ hours, it was one of my most rational purchases in recent years. I'd pay $500 if I had to. Why are people content with crappy, mushy membrane keyboards? Probably because they are so used to them, or because that type of keyboard is so utterly dominant these days that most people just don't know anything else.&lt;/p&gt;

&lt;p&gt;Most keyboards have 100+ keys; The HHKB Pro 2 has 60 (still full-sized). No F1–F12, arrows, print screen, pg up, etc; those are accessible with Fn+. Since one Fn key is right below Enter/Return, I can actually do many of these operations quicker than on a normal keyboard. No numpad. No caps lock! Ctrl is in its right place. It makes for a very small, elegant keyboard; below is a comparison with a Unicomp &lt;em&gt;SpaceSaver&lt;/em&gt;, a &lt;a href=&quot;http://www.dansdata.com/clickykeyboards.htm&quot;&gt;buckling-spring&lt;/a&gt; keyboard that I use when I need to wake people up with a wall of sound.&lt;/p&gt;

&lt;p&gt;&lt;a rel=&quot;attachment wp-att-88&quot; href=&quot;http://fooninja.net/2010/07/30/happy-hacking-keyboard-professional-2/spacesaver_hhkbpro2/&quot;&gt;&lt;img class=&quot;alignnone size-medium wp-image-88&quot; title=&quot;Happy Hacking Keyboard Pro 2 and Unicomp SpaceSaver&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/07/spacesaver_hhkbpro2-600x394.jpg&quot; alt=&quot;Happy Hacking Keyboard Pro 2 and Unicomp SpaceSaver size comparison&quot; width=&quot;600&quot; height=&quot;394&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I bought the blank version; it looks better. And it's a good conversation piece.&lt;/p&gt;

&lt;p&gt;So, the layout is great, but here's why it costs much more than the Lite 2: the key switches. They are light, quiet, but still have excellent tactile response.&lt;/p&gt;

&lt;p&gt;What else? There are six DIP switches on the back; with these you can change mode (&quot;HHK&quot;, &quot;Lite Ext.&quot;, &quot;Macintosh&quot;) and the behaviour of some keys. See &lt;a href=&quot;http://fooninja.net/wp-content/uploads/2010/07/hhkbpro2_manual.jpg&quot;&gt;this image of the manual&lt;/a&gt; for what they mean. The USB cable is detachable; great if you want to move the board around. There also two USB ports on the back.&lt;/p&gt;

&lt;p&gt;It comes in a nice box. On the back you'll find descriptions like &quot;good feeling of oneness with cup rubber&quot;.&lt;/p&gt;

&lt;p&gt;&lt;a rel=&quot;attachment wp-att-89&quot; href=&quot;http://fooninja.net/2010/07/30/happy-hacking-keyboard-professional-2/hhkbpro2_box_back/&quot;&gt;&lt;img class=&quot;alignnone size-medium wp-image-89&quot; title=&quot;Happy Hacking Keyboard Pro 2 box - back cover&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/07/hhkbpro2_box_back-600x335.jpg&quot; alt=&quot;Happy Hacking Keyboard Pro 2 box - back cover&quot; width=&quot;600&quot; height=&quot;335&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don't like the layout of the HHKB Pro 2, an interesting and equally expensive alternative is the Topre's line of Realforce keyboards.&lt;/p&gt;

&lt;p&gt;If you want something less expensive, check out Filco's Majestouch keyboards.&lt;/p&gt;

&lt;p&gt;If you long for the buckling springs of yore, consider getting a fresh keyboard from &lt;a href=&quot;http://pckeyboards.stores.yahoo.net/&quot;&gt;Unicomp&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For the latest on what keyboards to buy and where to get them, check out the aforementioned forum &lt;a href=&quot;http://www.geekhack.org/&quot;&gt;geekhack&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Swedish characters (svenska tecken!)&lt;/h2&gt;


&lt;p&gt;I'm a Swede and I need my &lt;em&gt;å ä ö&lt;/em&gt;. I use the most common Swedish layout, but the small number of keys on the HHKB Pro 2 necessitates some modifications to have important things like &amp;lt;, &amp;gt; and | easily available.&lt;/p&gt;

&lt;h3&gt;Linux and other systems with X&lt;/h3&gt;


&lt;p&gt;I used &lt;a href=&quot;http://www.jwz.org/xkeycaps/&quot;&gt;xkeycaps&lt;/a&gt; to dump the current keyboard map and &lt;tt&gt;xev&lt;/tt&gt; to get the keycodes. I then put the following in my xmodmap file:&lt;/p&gt;

&lt;pre&gt;keycode 100 = ISO_Level3_Shift
keycode 102 = Alt_L
keycode 0x34 =  z               Z               z               Z               less
keycode 0x35 =  x               X               x               X               greater
keycode 0x3B =  comma           semicolon       comma           semicolon       bar
keycode 0x3C =  period          colon           period          colon           bar&lt;/pre&gt;


&lt;p&gt;What it does:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Meta/Alt-z: &amp;lt;&lt;/li&gt;
    &lt;li&gt;Meta/Alt-x: &amp;gt;&lt;/li&gt;
    &lt;li&gt;Meta/Alt-, and .: |&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;On the back of the keyboard I have SW3 and SW5 set to ON. (&lt;em&gt;Remember:&lt;/em&gt; If you change the DIP switches, you might have to unplugin the USB cable and plug it back in again.)&lt;/p&gt;

&lt;h3&gt;Mac OS X&lt;/h3&gt;


&lt;div&gt;

On Mac I had to make more modifications since characters like \ { } are not in sensible places (at least not on the default Swedish layout).

I found the very useful but not particularly intuitive keyboard layout editor &lt;a href=&quot;http://scripts.sil.org/Ukelele&quot;&gt;Ukelele&lt;/a&gt;, and then came across &lt;a href=&quot;http://www.classy.dk/hacks/archives/004053.html&quot;&gt;this excellent blog post&lt;/a&gt; by Claus Dahl. I quote the most important part:
&lt;p style=&quot;padding-left: 30px;&quot;&gt;&lt;em&gt;Here's the slightly insane part: The layout is organized by modifiers. The entire layout, that is, e.g. &quot;here's how the keyboard looks when option key is down&quot;. You can't use a modifier combination that isn't already in the layout. (You can add new ones through an interface so lacking in intuitiveness that I didn't figure it out). I had little luck mapping cmd-single key to a new character as an example. Mapping stuff to alt-something however works fine, as there is already an alt- keyboard.&lt;/em&gt;&lt;/p&gt;
You can &lt;a href=&quot;http://fooninja.net/wp-content/uploads/2010/07/HHKB2-Swedish.keylayout&quot;&gt;download my keymap&lt;/a&gt;. Put it in &lt;tt&gt;~/Library/Keyboard Layouts&lt;/tt&gt; and then enable it in System Preferences|International|Input Menu. You might have to log out and in again. It modifies &quot;Swedish - Pro&quot; to do the following:
&lt;ul&gt;
    &lt;li&gt;Alt-1: §&lt;/li&gt;
    &lt;li&gt;Alt-7: {&lt;/li&gt;
    &lt;li&gt;Alt-8: [&lt;/li&gt;
    &lt;li&gt;Alt-9: ]&lt;/li&gt;
    &lt;li&gt;Alt-0: }&lt;/li&gt;
    &lt;li&gt;Alt-+: \&lt;/li&gt;
    &lt;li&gt;Alt-,: |&lt;/li&gt;
    &lt;li&gt;Alt-z: &amp;lt;&lt;/li&gt;
    &lt;li&gt;Alt-x: &amp;gt;&lt;/li&gt;
&lt;/ul&gt;
Note that on the back of the keyboard I have SW2 and SW3 set to ON, and the rest are OFF. (Again, if you change the DIP switches, you might have to disconnect and reconnect the keyboard for the changes to take effect.)

If you need to change what key is Command, Option, etc., try &lt;a href=&quot;http://doublecommand.sourceforge.net/&quot;&gt;DoubleCommand&lt;/a&gt;.

&lt;h3&gt;Windows&lt;/h3&gt;
&lt;a href=&quot;http://www.autohotkey.com/&quot;&gt;AutoHotkey&lt;/a&gt; is an excellent tool for remapping and binding keys. It can do some advanced stuff, but I only use the following, which should be self-explanatory (e.g., Right Alt + , will produce a |):
&lt;pre&gt;RALT &amp;amp; 1::Send {§}
RALT &amp;amp; .::Send {|}
RALT &amp;amp; ,::Send {|}
RALT &amp;amp; z::Send {&amp;lt;}
RALT &amp;amp; x::Send {&amp;gt;}&lt;/pre&gt;
Install AutoHotkey, paste the above in a new file, name it &lt;tt&gt;blah.ahk&lt;/tt&gt; and run it. Put it in your startup folder to have it executed automatically. AutoHotkey includes a compiler that you can use to make standalone executables; very convenient if you use the keyboard on computers on which you don't want to – or can't – install AutoHotkey. &lt;a href=&quot;http://fooninja.net/wp-content/uploads/2010/07/ahk-hhk.exe&quot;&gt;Here's mine&lt;/a&gt;.

&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Cleaning a Happy Hacking keyboard</title>
   <link href="http://fooninja.net/2010/07/29/cleaning-a-happy-hacking-keyboard"/>
   <updated>2010-07-29T15:43:03+02:00</updated>
   <id>http://fooninja.net/2010/07/29/cleaning-a-happy-hacking-keyboard</id>
   <content type="html">&lt;p&gt;One day I spilt a glass of Coke on my Happy Hacking Keyboard Lite 2. It still worked, but the keys were all sticky (both above and underneath) and tended to get stuck. It was practically useless. So...&lt;/p&gt;

&lt;p&gt;(&lt;strong&gt;NOTE: &lt;/strong&gt;I have no idea whether this procedure is the best one, or even a good one, but it worked for me. Don't complain to me if something Bad happens if you try this yourself!)&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://fooninja.net/?attachment_id=92&quot;&gt;&lt;img class=&quot;size-full wp-image-92&quot; title=&quot;Before cleaning&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/07/hhkb-cleaning-01.jpg&quot; alt=&quot;Happy Hacking keyboard before cleaning&quot; width=&quot;600&quot; height=&quot;282&quot; /&gt;&lt;/a&gt;
Before&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;size-full wp-image-93&quot; title=&quot;Yucky&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/07/hhkb-cleaning-02.jpg&quot; alt=&quot;Happy Hacking keyboard before cleaning, without keycaps&quot; width=&quot;600&quot; height=&quot;264&quot; /&gt;&lt;/a&gt;
Underneath, after more than 2½ years of use with no previous cleaning&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;size-full wp-image-94&quot; title=&quot;Close-up&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/07/hhkb-cleaning-03.jpg&quot; alt=&quot;Close-up of dirty keyboard&quot; width=&quot;599&quot; height=&quot;393&quot; /&gt;&lt;/a&gt;
Close-up. Yummy!&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;size-full wp-image-95&quot; title=&quot;Soapy&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/07/hhkb-cleaning-04.jpg&quot; alt=&quot;Keyboard plus water plus soap&quot; width=&quot;600&quot; height=&quot;399&quot; /&gt;&lt;/a&gt;
Lots of soap&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;size-full wp-image-96&quot; title=&quot;Shiny&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/07/hhkb-cleaning-05.jpg&quot; alt=&quot;Shiny clean keyboard without the keycaps&quot; width=&quot;600&quot; height=&quot;314&quot; /&gt;&lt;/a&gt;
Shiny!&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;size-full wp-image-97&quot; title=&quot;Drying&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/07/hhkb-cleaning-06.jpg&quot; alt=&quot;Keyboard drying upside down&quot; width=&quot;600&quot; height=&quot;324&quot; /&gt;&lt;/a&gt;
Drying for a couple of days&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;size-full wp-image-98&quot; title=&quot;Keycaps falling into the bowl&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/07/hhkb-cleaning-07.jpg&quot; alt=&quot;Keycaps being poured into a bowl with water and soap&quot; width=&quot;600&quot; height=&quot;399&quot; /&gt;&lt;/a&gt;
The keycaps are poured into a bowl...&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;size-full wp-image-99&quot; title=&quot;Cleaning of keycaps&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/07/hhkb-cleaning-08.jpg&quot; alt=&quot;Keycaps being cleaned&quot; width=&quot;600&quot; height=&quot;399&quot; /&gt;&lt;/a&gt;
...and cleaned with water and soap&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;size-full wp-image-100&quot; title=&quot;Dry happy keyboard&quot; src=&quot;http://fooninja.net/wp-content/uploads/2010/07/hhkb-cleaning-09.jpg&quot; alt=&quot;Clean, dry keyboard&quot; width=&quot;600&quot; height=&quot;369&quot; /&gt;&lt;/a&gt;
Works like a charm again!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Chromium and Chrome in Ubuntu</title>
   <link href="http://fooninja.net/2010/07/29/chromium-and-chrome-in-ubuntu"/>
   <updated>2010-07-29T09:34:39+02:00</updated>
   <id>http://fooninja.net/2010/07/29/chromium-and-chrome-in-ubuntu</id>
   <content type="html">&lt;p&gt;First: There's a difference between Chromium and Google Chrome.  Chromium is the open source web browser that Chrome is based on. Google Chrome is basically Chromium + Google branding + a couple of extra features, e.g., integrated Adobe Flash player.&lt;/p&gt;

&lt;h3&gt;Installing Chrome&lt;/h3&gt;


&lt;p&gt;Simply &lt;a href=&quot;http://www.google.com/chrome?platform=linux&quot;&gt;download it from Google&lt;/a&gt;. Download the .deb and install it, either by double-clicking on it in Gnome and using GDebi (or whatever program you prefer), or in the console (replace file name with actual file name):
&lt;code&gt;sudo dpkg -i google-chrome-stable_current_amd64.deb&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;Installing Chromium&lt;/h3&gt;


&lt;p&gt;There are three different flavors of Chromium available: daily, beta and dev. As of this writing they have packages for Maverick (10.10), Lucid (10.04), Karmic (9.10), Jaunty (9.04) and Hardy (8.04). You need to add the repository for &lt;strong&gt;one &lt;/strong&gt;of the three flavors:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://launchpad.net/~chromium-daily/+archive/ppa&quot;&gt;Daily&lt;/a&gt; &lt;/strong&gt;gives you the very latest version of the browser, but the builds are maintained automatically by a bot and are completely untested - so don't be surprised by crashes.
&lt;code&gt;sudo add-apt-repository ppa:chromium-daily/ppa&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://launchpad.net/~chromium-daily/+archive/beta&quot;&gt;&lt;strong&gt;Beta&lt;/strong&gt;&lt;/a&gt; is more stable and matched the Google Chrome Beta Channel.
&lt;code&gt;sudo add-apt-repository ppa:chromium-daily/beta&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://launchpad.net/~chromium-daily/+archive/dev&quot;&gt;&lt;strong&gt;Dev&lt;/strong&gt;&lt;/a&gt; is in between - less frequently updated than daily, more frequently updated than beta.
&lt;code&gt;sudo add-apt-repository ppa:chromium-daily/dev&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Next, update the package list and install Chromium:
&lt;code&gt;sudo aptitude update
sudo aptitude install chromium-browser&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Done!&lt;/p&gt;

&lt;p&gt;If you want to switch from daily to beta or dev, first remove the daily build:
&lt;code&gt;sudo aptitude remove chromium-browser&lt;/code&gt;
Remove the repository:
&lt;code&gt;sudo rm /etc/apt/sources.list.d/chromium-daily-ppa-lucid.list&lt;/code&gt;
...and then follow the instructions above again.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Change icon size in Gnome</title>
   <link href="http://fooninja.net/2010/07/29/change-the-icon-size-in-gnome"/>
   <updated>2010-07-29T02:35:30+02:00</updated>
   <id>http://fooninja.net/2010/07/29/change-the-icon-size-in-gnome</id>
   <content type="html">&lt;p&gt;To change the size of an &lt;em&gt;individual&lt;/em&gt; icon on the Gnome desktop, right-click on it and select &lt;em&gt;Stretch icon&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To change the &lt;em&gt;default icon size&lt;/em&gt; in Gnome, open Nautilus (e.g., Places -&amp;gt; Home Folder or Alt-F2 and nautilus). Go to &lt;strong&gt;Edit -&amp;gt; Preferences&lt;/strong&gt; and change Icon View Defaults and List View Defaults to whatever you like.&lt;/p&gt;

&lt;p&gt;(I have tried this is Ubuntu 10.04 (Lucid Lynx.))&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Move the Network Manager icon in Ubuntu (Lucid, Maverick, Natty)</title>
   <link href="http://fooninja.net/2010/07/29/move-the-network-manager-icon-in-ubuntu-10-04-lucid-lynx"/>
   <updated>2010-07-29T01:51:25+02:00</updated>
   <id>http://fooninja.net/2010/07/29/move-the-network-manager-icon-in-ubuntu-10-04-lucid-lynx</id>
   <content type="html">&lt;p&gt;So you've installed Ubuntu 11.04 and started customizing your desktop. After moving around the icons in the upper corner (if you're using Gnome), you find that the Network Manager icon/applet won't move like the others. The others have options like &lt;em&gt;Move&lt;/em&gt; and &lt;em&gt;Lock to panel&lt;/em&gt;, but not the Network Manager one. What gives?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The trick&lt;/strong&gt; is to right-click &lt;em&gt;slightly to the left&lt;/em&gt; of the Network Manager icon. Voila...&lt;/p&gt;

&lt;p&gt;(This also applies to 10.04 and 10.10.)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Disable notifications in Ubuntu 10.04 (Lucid) and 10.10 (Maverick)</title>
   <link href="http://fooninja.net/2010/07/29/disable-notifications-in-ubuntu-10-04-lucid-lynx"/>
   <updated>2010-07-29T01:35:43+02:00</updated>
   <id>http://fooninja.net/2010/07/29/disable-notifications-in-ubuntu-10-04-lucid-lynx</id>
   <content type="html">&lt;p&gt;One thing that always annoyed me when starting a fresh install of any of the recent Ubuntu releases - 9.10 (Karmic), 10.04 (Lucid) and 10.10 (Maverick) - was the badly implemented notification thing that's supposed to look fancy: &lt;tt&gt;notify-osd&lt;/tt&gt;. You know, the big black rectangular boxes saying &quot;Connection established&quot;, giving you Pidgin notifications or whatever. Naturally, I wanted to get rid of this thing.&lt;/p&gt;

&lt;p&gt;(If you want to disable just Pidgin notifications, go to Tool -&amp;gt; Plugins, scroll down to Libnotify Popups and select it, click Configure Plugin and uncheck all the boxes.)&lt;/p&gt;

&lt;p&gt;Run the following to get rid of the notifications (one line):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ sudo mv  /usr/share/dbus-1/services/org.freedesktop.Notifications.service  /usr/share/dbus-1/services/org.freedesktop.Notifications.service.disabled&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This works in all recent Ubuntu releases. After a restart you'll be fine. If you want to get rid of notifications right away, run &lt;tt&gt;killall notify-osd&lt;/tt&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Text boot and disabling GDM in Ubuntu 10.04 (Lucid),  10.10 (Maverick), 11.04 (Natty)</title>
   <link href="http://fooninja.net/2010/07/29/text-boot-in-ubuntu-lucid-lynx-10-04-disabling-gdm"/>
   <updated>2010-07-29T01:18:56+02:00</updated>
   <id>http://fooninja.net/2010/07/29/text-boot-in-ubuntu-lucid-lynx-10-04-disabling-gdm</id>
   <content type="html">&lt;p&gt;The days of &lt;tt&gt;/etc/inittab&lt;/tt&gt; seem to be gone in Ubuntu. But fear not - if you for some reason don't want graphical login (GDM, KDM, etc) when booting Ubuntu, here's how to do it. This also shows how to get rid of the splash image when booting, if you would rather have the good old black screen with the whole boot process shown.&lt;/p&gt;

&lt;p&gt;This applies to Ubuntu 10.04 (Lucid), 10.10 (Maverick), 11.04 (Natty) and possibly some earlier versions. Some people will tell you to edit &lt;tt&gt;/etc/init/gdm.conf&lt;/tt&gt; and change the &quot;start on...&quot; stuff to &quot;start on runlevel []&quot;, but there's an easier way:&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt;To disable GDM/KDM/etc, edit &lt;tt&gt;/etc/default/grub&lt;/tt&gt; and change the line &lt;tt&gt;GRUB_CMDLINE_LINUX=&quot;&quot;&lt;/tt&gt; to &lt;tt&gt;GRUB_CMDLINE_LINUX=&quot;text&quot;&lt;/tt&gt;&lt;/li&gt;
        &lt;li&gt;To show boot messages and disable the splash image, remove &lt;tt&gt;quiet splash&lt;/tt&gt; from &lt;tt&gt;GRUB_CMDLINE_LINUX_DEFAULT&lt;/tt&gt; so that it reads &lt;tt&gt;GRUB_CMDLINE_LINUX_DEFAULT=&quot;&quot;&lt;/tt&gt;. (If you want the splash image and &lt;i&gt;some&lt;/i&gt; text, use &lt;tt&gt;splash&lt;/tt&gt;.)&lt;/li&gt;
    &lt;li&gt;Run &lt;tt&gt;sudo update-grub
&lt;/tt&gt;Done!&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;This worked fine for me - but the sound was no longer working:&lt;/p&gt;

&lt;pre&gt;$ alsamixer
cannot open mixer: No such file or directory&lt;/pre&gt;


&lt;p&gt;I fixed this by adding my user to the group audio:&lt;/p&gt;

&lt;pre&gt;$ sudo usermod -a -G audio fooninja&lt;/pre&gt;


&lt;p&gt;(Replace fooninja with your username.)&lt;/p&gt;

&lt;p&gt;I logged out and in again and voila - sound was working.&lt;/p&gt;

&lt;p&gt;Oh, and if you want to start X automatically when logging in on the first console, put something like this in e.g. &lt;tt&gt;~/.bashrc&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;if [ `tty` = &quot;/dev/tty1&quot; ]; then
    startx
fi
&lt;/pre&gt;

</content>
 </entry>
 
 
</feed>

