<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Frederic Cambus]]></title>
  <link href="http://www.cambus.net/atom.xml" rel="self"/>
  <link href="http://www.cambus.net/"/>
  <updated>2013-05-18T13:36:00+02:00</updated>
  <id>http://www.cambus.net/</id>
  <author>
    <name><![CDATA[Frederic Cambus]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Special DNS zones for testing purposes]]></title>
    <link href="http://www.cambus.net/special-dns-zones-for-testing-purposes/"/>
    <updated>2013-05-18T13:33:00+02:00</updated>
    <id>http://www.cambus.net/special-dns-zones-for-testing-purposes</id>
    <content type="html"><![CDATA[<p><strong>Domain hosting some seldom used resource record types</strong> :</p>

<p>More information about available resource records to query can be found <a href="https://www.statdns.net">here</a>.</p>

<pre><code>dig statdns.net LOC +short
52 22 23.000 N 4 53 32.000 E -2.00m 0.00m 10000m 10m

dig _443._tcp.www.statdns.net TLSA +short
3 0 1 E1BFAE80B9B0B4220DDB6940925CEA0FA51D5D11C645DB95584086FB 71C542F2

dig statdns.net NAPTR +short
100 100 "u" "E2U+web:http" "!^.*$!http://www.statdns.net!" .
</code></pre>

<p><strong>Deliberately broken domains</strong> :</p>

<p>Unreacheable Name Servers :</p>

<pre><code>dig lame.broken-on-purpose.generic-nic.net SOA

; &lt;&lt;&gt;&gt; DiG 9.8.3-P1 &lt;&lt;&gt;&gt; lame.broken-on-purpose.generic-nic.net SOA
;; global options: +cmd
;; connection timed out; no servers could be reached
</code></pre>

<p>A zone always returning a SERVFAIL :</p>

<pre><code>dig lame2.broken-on-purpose.generic-nic.net SOA

; &lt;&lt;&gt;&gt; DiG 9.8.3-P1 &lt;&lt;&gt;&gt; lame2.broken-on-purpose.generic-nic.net SOA
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: SERVFAIL, id: 41095
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
</code></pre>

<p><strong>Zones with dangerous records</strong> :</p>

<p>These zones contains special characters and malicious content :</p>

<pre><code>dig dangerousrecord.broken-on-purpose.generic-nic.net MX +short
0 dangerous&lt;name.broken-on-purpose.generic-nic.net.
10 dangerous{name.broken-on-purpose.generic-nic.net.
20 dangerous\"name.broken-on-purpose.generic-nic.net.
50 dangerous'name.broken-on-purpose.generic-nic.net.
60 dangerous\"name.broken-on-purpose.generic-nic.net.
70 &lt;script/src='http://www\.skullsecurity\.org/test-js\.js'&gt;&lt;/script&gt;.broken-on-purpose.generic-nic.net.

dig dangerous\&lt;name.broken-on-purpose.generic-nic.net TXT +short
"To crash XML output"

dig dangerous{name.broken-on-purpose.generic-nic.net TXT +short
"To crash JSON output"
</code></pre>

<p><strong>64 kilobytes TXT record</strong> :</p>

<pre><code>dig txty.forfunsec.org TXT +short
"beginyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"

[TRUNCATED OUTPUT]

"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyend"
</code></pre>

<p>It&#8217;s interesting to note that some DNS resolvers such as Google Public DNS returns an error when queried for this particular record :</p>

<pre><code>dig @8.8.8.8 txty.forfunsec.org TXT
;; Truncated, retrying in TCP mode.
;; communications error to 8.8.8.8#53: end of file

dig @8.8.4.4 txty.forfunsec.org TXT
;; Truncated, retrying in TCP mode.
;; communications error to 8.8.4.4#53: end of file
</code></pre>

<p><strong>Domain name with a maximal sized label</strong> :</p>

<pre><code>dig 'this-right-here-is-a-maximum-sized-label-of-sixty-three-octets!.huque.com' TXT +short
"domain name with a maximal sized label" "for testing purposes"
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Testing DNS Resolvers]]></title>
    <link href="http://www.cambus.net/testing-dns-resolvers/"/>
    <updated>2013-05-16T20:01:00+02:00</updated>
    <id>http://www.cambus.net/testing-dns-resolvers</id>
    <content type="html"><![CDATA[<p><strong>Checking the IP address of the DNS resolver in use</strong> :</p>

<p>These servers will reflect the IP address of the host querying them.</p>

<pre><code>dig whoami.akamai.net +short
149.20.64.20

dig whoami.ultradns.net +short
149.20.64.20
</code></pre>

<p><strong> Checking if your own local DNS resolver is open</strong> :</p>

<p>This one is pretty much self-explanatory.</p>

<pre><code>dig amiopen.openresolvers.org TXT +short
"Your resolver at 175.45.176.1 is CLOSED"
</code></pre>

<p><strong>Checking your resolver&#8217;s source port behavior</strong> :</p>

<p>A test server allowing to check resolver&#8217;s source port randomization, and grading them (either POOR, GOOD, or GREAT randomness). More information <a href="https://www.dns-oarc.net/oarc/services/porttest">here</a>.</p>

<pre><code>dig porttest.dns-oarc.net TXT +short
porttest.y.x.w.v.u.t.s.r.q.p.o.n.m.l.k.j.i.h.g.f.e.d.c.b.a.pt.dns-oarc.net.
"149.20.64.20 is GREAT: 71 queries in 37.0 seconds from 71 ports with std dev 19761"
</code></pre>

<p><strong>DNS Reply Size Test Server</strong> :</p>

<p>A test server allowing to identify resolvers that cannot receive large DNS replies. More information <a href="https://www.dns-oarc.net/oarc/services/replysizetest">here</a>.</p>

<pre><code>dig rs.dns-oarc.net TXT +short
;; Truncated, retrying in TCP mode.
rst.x4091.rs.dns-oarc.net.
rst.x3837.x4091.rs.dns-oarc.net.
rst.x3843.x3837.x4091.rs.dns-oarc.net.
"149.20.64.20 DNS reply size limit is at least 4091"
"Tested at 2013-05-16 18:00:19 UTC"
"149.20.64.20 sent EDNS buffer size 4096"
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Taiwanese BBSes and Unicode ANSi Art]]></title>
    <link href="http://www.cambus.net/taiwanese-bbses-and-unicode-ansi-art/"/>
    <updated>2013-04-10T00:28:00+02:00</updated>
    <id>http://www.cambus.net/taiwanese-bbses-and-unicode-ansi-art</id>
    <content type="html"><![CDATA[<p>Ever since I discovered Unicode based ANSi art and the existence of Taiwanese telnet BBSes making heavy use of it, I wanted to learn more and explore this different and exotic textmode world. As these BBSes are in Chinese language it was not that easy to figure out how to create an account, but using some logic and a bit of patience, I was able to log in and take some screenshots.</p>

<p>For doing so, I used <strong>LunaTerm</strong>, a terminal emulator client for Android with built-in Telnet and SSH support. It&#8217;s a really neat and well thought application allowing to trigger the arrows and enter keys using gestures and to toggle virtual keyboard display using volume control keys, making it very efficient for BBSing.</p>

<p>Here is a selection of screens from <strong>PTT</strong> and <strong>PTT2</strong> systems, boasting some very interesting and mysterious Unicode ANSi art. More information about these systems can be found on <a href="http://en.wikipedia.org/wiki/PTT_Bulletin_Board_System">Wikipedia</a>. There was even a PTT3 system at some point but it seems to be down at the moment, I have no idea if this is permanent or temporary. If it ever comes back online, I will do another round of screenshots.</p>

<p>PTT Login Screens :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt-login01.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-login02.png" alt="PTT" /><!--more-->
<img src="http://www.cambus.net/content/2013/04/ptt-login03.png" alt="PTT" /></p>

<p>PTT Welcome Screens :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt-welcome01.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-welcome02.png" alt="PTT" /></p>

<p>PTT Main Menu Screens :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt-mainmenu01.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu02.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu03.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu04.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu05.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu06.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu07.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu08.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu09.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu10.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu11.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu12.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu13.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu14.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu15.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu16.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu17.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu18.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu19.png" alt="PTT" />
<img src="http://www.cambus.net/content/2013/04/ptt-mainmenu20.png" alt="PTT" /></p>

<p>PTT Conferences Menu :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt-conferences.png" alt="PTT" /></p>

<p>PTT Mail Menu :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt-mail.png" alt="PTT" /></p>

<p>PTT User Menu :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt-user.png" alt="PTT" /></p>

<p>PTT X.Y.Z. Menu :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt-xyz.png" alt="PTT" /></p>

<p>PTT System History :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt-history.png" alt="PTT" /></p>

<p>PTT Goodbye Screen :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt-goodbye.png" alt="PTT" /></p>

<p>PTT2 Login Screen :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt2-login.png" alt="PTT2" /></p>

<p>PTT2 Main Menu Screens :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu01.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu02.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu03.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu04.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu05.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu06.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu07.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu08.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu09.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu10.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu11.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu12.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu13.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu14.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu15.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu16.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu17.png" alt="PTT2" />
<img src="http://www.cambus.net/content/2013/04/ptt2-mainmenu18.png" alt="PTT2" /></p>

<p>PTT2 Mail Menu :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt2-mail.png" alt="PTT2" /></p>

<p>PTT2 User Menu :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt2-user.png" alt="PTT2" /></p>

<p>PTT2 X.Y.Z. Menu :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt2-xyz.png" alt="PTT2" /></p>

<p>PTT2 Goodbye Screen :</p>

<p><img src="http://www.cambus.net/content/2013/04/ptt2-goodbye.png" alt="PTT2" /></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Playing with Nginx GeoIP and Substitution modules]]></title>
    <link href="http://www.cambus.net/playing-with-nginx-geoip-and-substitution-modules/"/>
    <updated>2013-04-03T23:18:00+02:00</updated>
    <id>http://www.cambus.net/playing-with-nginx-geoip-and-substitution-modules</id>
    <content type="html"><![CDATA[<p>In this tutorial, we will build a site displaying the visitor IP address and geolocation by leveraging the power of nginx <strong>GeoIP</strong> and <strong>Substitution</strong> modules. If you are using Debian stable, the default nginx package have these modules compiled-in. In case you are using backports, then installing either <strong>nginx-full</strong> or <strong>nginx-extras</strong> will do.</p>

<p>We start by fetching and unpacking the GeoIP Country and City databases :</p>

<pre>
mkdir -p /usr/share/GeoIP
cd /usr/share/GeoIP
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip *gz
</pre>


<p>We now edit <em>nginx.conf</em> to add directives specifying the path to the GeoIP database files, within the <strong>http block</strong> :</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>http {
</span><span class='line'>
</span><span class='line'>  ...
</span><span class='line'>
</span><span class='line'>  geoip_country  /usr/share/GeoIP/GeoIP.dat;
</span><span class='line'>  geoip_city     /usr/share/GeoIP/GeoLiteCity.dat;
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>We then edit the site configuration file to add the following content within the <strong>location block</strong> :</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'>location / {
</span><span class='line'>  
</span><span class='line'>  ...
</span><span class='line'>
</span><span class='line'>  set $location $geoip_city_country_name;
</span><span class='line'>
</span><span class='line'>  if ($geoip_city)
</span><span class='line'>  {
</span><span class='line'>      set $location &quot;$geoip_city, $geoip_city_country_name&quot;;
</span><span class='line'>  }
</span><span class='line'>
</span><span class='line'>  set $map &quot;http://maps.google.com/maps/api/staticmap?center=$geoip_latitude,$geoip_longitude<span class="ni">&amp;amp;</span>zoom=12<span class="ni">&amp;amp;</span>size=640x250<span class="ni">&amp;amp;</span>markers=$geoip_latitude,$geoip_longitude<span class="ni">&amp;amp;</span>sensor=false&quot;;
</span><span class='line'>
</span><span class='line'>  sub_filter IP_ADDRESS_PLACEHOLDER<span class="nt">&lt;/h3&gt;</span>
</span><span class='line'>  &#39;$remote_addr<span class="nt">&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;</span>Your location :<span class="nt">&lt;/strong&gt;</span> $location<span class="nt">&lt;/p&gt;&lt;p&gt;&lt;strong&gt;</span>Latitude :<span class="nt">&lt;/strong&gt;</span> $geoip_latitude<span class="nt">&lt;/p&gt;&lt;p&gt;&lt;strong&gt;</span>Longitude :<span class="nt">&lt;/strong&gt;</span> $geoip_longitude<span class="nt">&lt;/p&gt;&lt;img</span> <span class="na">alt=</span><span class="s">&quot;Geolocation&quot;</span> <span class="na">src=</span><span class="s">&quot;$map&quot;</span> <span class="nt">/&gt;</span>&#39;;
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>The instructions above are pretty much self-explaining : we start by setting the <em>$location</em> and <em>$map</em> variables, and we then use the <strong>sub_filter</strong> command to insert the generated content within nginx response.</p>

<p>Finally, we create a simple <em>index.html</em> file (note the <em>IP_ADDRESS_PLACEHOLDER</em> text which will get dynamically replaced) :</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="cp">&lt;!DOCTYPE html&gt;</span>
</span><span class='line'><span class="nt">&lt;html&gt;</span>
</span><span class='line'>   <span class="nt">&lt;head&gt;</span>
</span><span class='line'>      <span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">&quot;utf-8&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;title&gt;</span>Playing with Nginx GeoIP and Substitution modules<span class="nt">&lt;/title&gt;</span>
</span><span class='line'>   <span class="nt">&lt;/head&gt;</span>
</span><span class='line'>   <span class="nt">&lt;body&gt;</span>
</span><span class='line'>      <span class="nt">&lt;h1&gt;</span>Your IP address is :<span class="nt">&lt;/h1&gt;</span>
</span><span class='line'>      <span class="nt">&lt;h3&gt;</span>IP_ADDRESS_PLACEHOLDER<span class="nt">&lt;/h3&gt;</span>
</span><span class='line'>   <span class="nt">&lt;/body&gt;</span>
</span><span class='line'><span class="nt">&lt;/html&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Let&#8217;s relaunch nginx and point our browser to our newly created site : if everything goes well, we should be greeted with informations about our IP address, geolocation, and a map.</p>

<p>A slightly more elaborate example is available <a href="http://www.telize.com" title="Telize - What is my IP address?">here</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Nginx packages in Debian stable]]></title>
    <link href="http://www.cambus.net/nginx-packages-in-debian-stable/"/>
    <updated>2013-03-29T13:41:00+01:00</updated>
    <id>http://www.cambus.net/nginx-packages-in-debian-stable</id>
    <content type="html"><![CDATA[<p>The latest version of nginx packaged in Debian stable (<strong>Squeeze</strong>) is 0.7.67, which was released on June 15th 2010 and is thus very old. Starting with <strong>Wheezy</strong> (the next iteration of Debian stable), there will be several different nginx packages available : <strong>nginx-light</strong>, <strong>nginx-full</strong>, <strong>nginx-extras</strong>, as well as a <strong>nginx-naxsi</strong> package bundling the NAXSI Web Application Firewall. Each package is being compiled with a different set of modules (including third party ones).</p>

<p>Fortunately, these packages have been backported to Squeeze, and it is now possible to install different flavours of <em>nginx 1.2.1</em>.</p>

<p>The following line should be added to <em>/etc/apt/sources.list</em> in order to enable backports :</p>

<pre>
deb http://backports.debian.org/debian-backports squeeze-backports main
</pre>


<p>Below is a comparaison matrix of compiled-in modules for the default nginx version bundled in Squeeze, and for the different backported versions :</p>

<p>Standard HTTP modules :</p>

<pre>
                       |    nginx    | nginx-light |  nginx-full | nginx-extras
                       |   (0.7.67)  |    (1.2.1)  |   (1.2.1)   |   (1.2.1)
-----------------------|-------------|-------------|-------------|-------------
 Core                  |      X      |      X      |      X      |      X
 Access                |      X      |      X      |      X      |      X
 Auth Basic            |      X      |      X      |      X      |      X
 Auto Index            |      X      |      X      |      X      |      X
 Browser               |      X      |             |      X      |      X
 Charset               |      X      |      X      |      X      |      X
 Empty GIF             |      X      |      X      |      X      |      X
 FastCGI               |      X      |      X      |      X      |      X
 Geo                   |      X      |             |      X      |      X
 Gzip                  |      X      |      X      |      X      |      X
 Headers               |      X      |      X      |      X      |      X
 Index                 |      X      |      X      |      X      |      X
 Limit Requests        |      X      |             |      X      |      X
 Limit Zone            |      X      |             |      X      |      X
 Limit Conn            |      X      |      X      |      X      |      X
 Log                   |      X      |      X      |      X      |      X
 Map                   |      X      |      X      |      X      |      X
 Memcached             |      X      |             |      X      |      X
 Proxy                 |      X      |      X      |      X      |      X
 Referer               |      X      |             |      X      |      X
 Rewrite               |      X      |      X      |      X      |      X
 SCGI                  |      X      |             |      X      |      X
 Split Clients         |      X      |             |      X      |      X
 SSI                   |      X      |             |      X      |      X
 Upstream              |      X      |      X      |      X      |      X
 User ID               |      X      |             |      X      |      X
 UWSGI                 |      X      |             |      X      |      X
 X-Accel               |      X      |      X      |      X      |      X
</pre>


<p>Optional HTTP modules :</p>

<pre>
                       |    nginx    | nginx-light |  nginx-full | nginx-extras
                       |   (0.7.67)  |   (1.2.1)   |   (1.2.1)   |   (1.2.1)
-----------------------|-------------|-------------|-------------|-------------
 Addition              |             |             |      X      |      X
 Degradation           |             |             |             |
 Debug                 |      X      |             |      X      |      X
 Embedded Perl         |             |             |             |      X
 FLV                   |      X      |             |             |      X
 GeoIP                 |      X      |             |      X      |      X
 Google Perftools      |             |             |             |
 Gzip Precompression   |      X      |      X      |      X      |      X
 Image Filter          |             |             |      X      |      X
 IPv6                  |      X      |      X      |      X      |      X
 MP4                   |             |             |             |      X
 Random Index          |             |             |             |      X
 Real IP               |      X      |             |      X      |      X
 Secure Link           |             |             |             |      X
 SSL                   |      X      |      X      |      X      |      X
 Stub Status           |      X      |      X      |      X      |      X
 Substitution          |      X      |             |      X      |      X
 WebDAV                |      X      |             |      X      |      X
 XSLT                  |             |             |      X      |      X
</pre>


<p>Mail modules :</p>

<pre>
                       |    nginx    | nginx-light |  nginx-full | nginx-extras
                       |   (0.7.67)  |   (1.2.1)   |   (1.2.1)   |   (1.2.1)
-----------------------|-------------|-------------|-------------|-------------
 Mail Core             |      X      |             |      X      |      X
 IMAP                  |      X      |             |      X      |      X
 POP3                  |      X      |             |      X      |      X
 SMTP                  |      X      |             |      X      |      X
 SSL                   |      X      |             |      X      |      X
</pre>


<p>Third party modules :</p>

<pre>
                       |    nginx    | nginx-light |  nginx-full | nginx-extras
                       |   (0.7.67)  |   (1.2.1)   |   (1.2.1)   |   (1.2.1)
-----------------------|-------------|-------------|-------------|-------------
 Auth PAM              |             |             |      X      |      X
 DAV Ext               |             |             |      X      |      X
 Echo                  |             |      X      |      X      |      X
 Embedded Lua          |             |             |             |      X
 HTTP Chunkin          |             |             |             |      X
 HTTP Headers More     |             |             |             |      X
 HTTP Push             |             |             |             |      X
 Nginx Development Kit |             |             |             |      X
 Upload                |             |             |             |      X
 Upload Progress       |             |             |             |      X
 Upstream Fair Queue   |      X      |             |      X      |      X
</pre>


<p>For reference, here is the resulting output of running <em>nginx -V</em> to list configure arguments for all the different packages :</p>

<p>nginx 0.7.67 (squeeze):</p>

<pre>
nginx version: nginx/0.7.67
TLS SNI support enabled
configure arguments: --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-debug --with-http_dav_module --with-http_flv_module --with-http_geoip_module --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-ipv6 --with-mail --with-mail_ssl_module --add-module=/home/thijs/nginx/nginx-0.7.67/modules/nginx-upstream-fair
</pre>


<p>nginx-light 1.2.1 (squeeze-backports) :</p>

<pre>
nginx version: nginx/1.2.1
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-pcre-jit --with-http_gzip_static_module --with-http_ssl_module --with-ipv6 --without-http_browser_module --without-http_geo_module --without-http_limit_req_module --without-http_limit_zone_module --without-http_memcached_module --without-http_referer_module --without-http_scgi_module --without-http_split_clients_module --with-http_stub_status_module --without-http_ssi_module --without-http_userid_module --without-http_uwsgi_module --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-echo
</pre>


<p>nginx-full 1.2.1 (squeeze-backports) :</p>

<pre>
nginx version: nginx/1.2.1
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-pcre-jit --with-debug --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6 --with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl --with-mail --with-mail_ssl_module --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-auth-pam --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-echo --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-upstream-fair --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-dav-ext-module
</pre>


<p>nginx-extras 1.2.1 (squeeze-backports) :</p>

<pre>
nginx version: nginx/1.2.1
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-pcre-jit --with-debug --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_mp4_module --with-http_perl_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6 --with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl --with-mail --with-mail_ssl_module --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-auth-pam --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/chunkin-nginx-module --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/headers-more-nginx-module --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-development-kit --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-echo --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-http-push --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-lua --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-upload-module --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-upload-progress --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-upstream-fair --add-module=/tmp/buildd/nginx-1.2.1/debian/modules/nginx-dav-ext-module
</pre>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Serving precompressed content with Nginx and Zopfli]]></title>
    <link href="http://www.cambus.net/serving-precompressed-content-with-nginx-and-zopfli/"/>
    <updated>2013-03-11T21:50:00+01:00</updated>
    <id>http://www.cambus.net/serving-precompressed-content-with-nginx-and-zopfli</id>
    <content type="html"><![CDATA[<p><strong>Zopfli</strong> is a new compression algorithm which has recently been opensourced by Google. Being deflate compatible, it can
create compressed files which can then be unpacked using zlib, and thus served to web browsers without any modifications on client side.</p>

<p>Zopfli is focused on output efficiency, not on runtime performance, making it impractical to use for doing on-the-fly compression. It shines at compressing static content, and I will show you how in this article using <a href="http://www.ascii-codes.com" title="Ascii Codes">Ascii Codes</a> website as an example.</p>

<p>We start by fetching and compiling Zopfli :</p>

<pre>
git clone https://code.google.com/p/zopfli/
cd zopfli
make
</pre>


<p>The available options are as follow :</p>

<pre>
Usage: zopfli [OPTION]... FILE
  -h    gives this help
  -c    write the result on standard output, instead of disk filename + '.gz'
  -v    verbose mode
  --gzip  output to gzip format (default)
  --deflate  output to deflate format instead of gzip
  --zlib  output to zlib format instead of gzip
  --i5  less compression, but faster
  --i10  less compression, but faster
  --i15  default compression, 15 iterations
  --i25  more compression, but slower
  --i50  more compression, but slower
  --i100  more compression, but slower
  --i250  more compression, but slower
  --i500  more compression, but slower
  --i1000  more compression, but slower
</pre>


<p>We now compress the content (in our example, we want to pack HTML and CSS files) :</p>

<pre>
zopfli *html *css
</pre>


<p>Alternatively, for maximum compression (1000 iterations) :</p>

<pre>
zopfli --i1000 *html *css
</pre>


<p>Now, let&#8217;s test the actual server configuration (Nginx + standard Gzip module) :</p>

<pre>
curl http://www.ascii-codes.com --silent --header "Accept-Encoding: gzip,deflate" | wc -c
    6124
</pre>


<p>The file size is 6,124 bytes : we are getting gzip content compressed on-the-fly.</p>

<p>We now modify our Nginx virtual host configuration to add the following directive :</p>

<pre>
gzip_static on;
</pre>


<p>Let&#8217;s reload Nginx configuration :</p>

<pre>
nginx -s reload
</pre>


<p>And finally, we test again (Nginx + Gzip Precompression module) :</p>

<pre>
curl http://www.ascii-codes.com --silent --header "Accept-Encoding: gzip,deflate" | wc -c
    5621
</pre>


<p>As we can see, the file size is 5,621 bytes : it now serves the Zopfli precompressed content.</p>

<p>For reference, here is a comparaison matrix of file sizes :</p>

<pre>                         
  file name |  original size |        gzip -9 |         zopfli | zopfli --i1000
------------|----------------|----------------|----------------|----------------
 cp737.html |   36,567 bytes |    6,001 bytes |    5,499 bytes |    5,494 bytes
 cp775.html |   36,040 bytes |    6,063 bytes |    5,540 bytes |    5,538 bytes
 cp850.html |   36,047 bytes |    6,149 bytes |    5,651 bytes |    5,646 bytes
 cp852.html |   36,120 bytes |    6,027 bytes |    5,493 bytes |    5,489 bytes
 cp855.html |   36,388 bytes |    6,079 bytes |    5,581 bytes |    5,578 bytes
 cp857.html |   35,861 bytes |    6,052 bytes |    5,575 bytes |    5,570 bytes
 cp860.html |   36,506 bytes |    6,132 bytes |    5,657 bytes |    5,652 bytes
 cp861.html |   37,185 bytes |    6,619 bytes |    6,268 bytes |    6,254 bytes
 cp862.html |   36,078 bytes |    6,102 bytes |    5,580 bytes |    5,577 bytes
 cp863.html |   36,421 bytes |    6,144 bytes |    5,677 bytes |    5,672 bytes
 cp865.html |   36,347 bytes |    6,154 bytes |    5,661 bytes |    5,659 bytes
 cp866.html |   36,595 bytes |    6,042 bytes |    5,541 bytes |    5,533 bytes
 cp869.html |   36,014 bytes |    6,007 bytes |    5,479 bytes |    5,474 bytes
 index.html |   36,035 bytes |    6,124 bytes |    5,631 bytes |    5,621 bytes
</pre>


<p>The results look pretty good indeed, and we can definitely achieve a non-negligible gain in file size using Zopfli instead of Gzip.</p>

<p>Every byte counts!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Character and color cycling effect in JavaScript]]></title>
    <link href="http://www.cambus.net/character-and-color-cycling-effect-in-javascript/"/>
    <updated>2013-02-19T23:46:00+01:00</updated>
    <id>http://www.cambus.net/character-and-color-cycling-effect-in-javascript</id>
    <content type="html"><![CDATA[<p>Few weeks ago, I stumbled upon a cute little <a href="http://www.evilpaul.org/wp/?p=504">Javascript textmode library</a> to generate text mode stuff inside the browser using the canvas element. Of course, I had to try to do something with it, and I quickly came up with this simple but efficient character and color cycling effect. You can see it in action <a href="http://www.cambus.net/files/textmode/">here</a>.</p>

<p><img src="http://www.cambus.net/content/2013/02/cycling-effect.png" alt="Cycling effect" /></p>

<p>Here is the code :</p>

<figure class='code'><figcaption><span> (cycling-effect.js)</span> <a href='http://www.cambus.net/downloads/code/cycling-effect.js'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="kd">var</span> <span class="nx">screenManager</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">characterIndex</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">colorIndex</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Define character and color arrays </span>
</span><span class='line'><span class="kd">var</span> <span class="nx">arrayCharacters</span> <span class="o">=</span> <span class="p">[</span><span class="mh">0x5c</span><span class="p">,</span><span class="mh">0x7c</span><span class="p">,</span><span class="mh">0x2f</span><span class="p">,</span><span class="mh">0x2d</span><span class="p">];</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">arrayColors</span> <span class="o">=</span> <span class="p">[</span><span class="mh">0xf</span><span class="p">,</span><span class="mh">0xb</span><span class="p">,</span><span class="mh">0x9</span><span class="p">,</span><span class="mh">0x1</span><span class="p">,</span><span class="mh">0x9</span><span class="p">,</span><span class="mh">0xb</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// The font that we will use</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">sourceFont</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Image</span><span class="p">();</span>
</span><span class='line'><span class="nx">sourceFont</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="s2">&quot;font.png&quot;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="cm">/*****************************************************************************/</span>
</span><span class='line'><span class="cm">/* Initialization                                                            */</span>
</span><span class='line'><span class="cm">/*****************************************************************************/</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">init</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Initialize the textmode library</span>
</span><span class='line'>    <span class="nx">screenManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">TextModeScreen</span><span class="p">(</span><span class="mi">40</span><span class="p">,</span> <span class="mi">25</span><span class="p">,</span> <span class="s2">&quot;mainCanvas&quot;</span><span class="p">,</span> <span class="nx">sourceFont</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Call our main loop at 10fps</span>
</span><span class='line'>    <span class="nx">setInterval</span><span class="p">(</span><span class="nx">mainLoop</span><span class="p">,</span> <span class="mi">1000</span> <span class="o">/</span> <span class="mi">10</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="cm">/*****************************************************************************/</span>
</span><span class='line'><span class="cm">/* Main Loop                                                                 */</span>
</span><span class='line'><span class="cm">/*****************************************************************************/</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">mainLoop</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">for</span> <span class="p">(</span><span class="nx">offset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">offset</span> <span class="o">&lt;</span> <span class="nx">screenManager</span><span class="p">.</span><span class="nx">charsHigh</span> <span class="o">*</span> <span class="nx">screenManager</span><span class="p">.</span><span class="nx">charsWide</span><span class="p">;</span> <span class="nx">offset</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">// Write character and color data      </span>
</span><span class='line'>        <span class="nx">screenManager</span><span class="p">.</span><span class="nx">charBuffer</span><span class="p">[</span><span class="nx">offset</span><span class="p">]</span> <span class="o">=</span> <span class="nx">arrayCharacters</span><span class="p">[</span><span class="nx">characterIndex</span><span class="p">];</span>
</span><span class='line'>        <span class="nx">screenManager</span><span class="p">.</span><span class="nx">colourBuffer</span><span class="p">[</span><span class="nx">offset</span><span class="p">]</span> <span class="o">=</span> <span class="nx">arrayColors</span><span class="p">[</span><span class="nx">colorIndex</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Increment the color index</span>
</span><span class='line'>        <span class="nx">colorIndex</span> <span class="o">=</span> <span class="p">(</span><span class="nx">colorIndex</span><span class="o">+</span><span class="mi">1</span> <span class="o">&lt;</span> <span class="nx">arrayColors</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">?</span> <span class="nx">colorIndex</span><span class="o">+</span><span class="mi">1</span> <span class="o">:</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Increment the character index</span>
</span><span class='line'>    <span class="nx">characterIndex</span> <span class="o">=</span> <span class="p">(</span><span class="nx">characterIndex</span><span class="o">+</span><span class="mi">1</span> <span class="o">&lt;</span> <span class="nx">arrayCharacters</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">?</span> <span class="nx">characterIndex</span><span class="o">+</span><span class="mi">1</span> <span class="o">:</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Print footer text</span>
</span><span class='line'>    <span class="nx">screenManager</span><span class="p">.</span><span class="nx">print</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">24</span><span class="p">,</span> <span class="s2">&quot; Simple character+color cycling example &quot;</span><span class="p">,</span> <span class="mh">0x1e</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Render the textmode screen to our canvas</span>
</span><span class='line'>    <span class="nx">screenManager</span><span class="p">.</span><span class="nx">presentToScreen</span><span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A different approach to ranking Linux distributions]]></title>
    <link href="http://www.cambus.net/a-different-approach-to-ranking-linux-distributions/"/>
    <updated>2013-01-11T18:06:00+01:00</updated>
    <id>http://www.cambus.net/a-different-approach-to-ranking-linux-distributions</id>
    <content type="html"><![CDATA[<p>Counting the number of Linux users and ranking Linux distributions according to their popularity has always been a problematic task. Not surprisingly, it still remains an open problem.</p>

<p>Initiatives such as the <strong>Linux Counter</strong> or the flawed by design <strong>DistroWatch</strong> approach being inneficient, why not use Alexa Traffic Rank instead? Although this method is not perfect, I believe Alexa is a pretty accurate tool for comparing and ordering sites on the same topic.</p>

<p>So, I tried this approach using a list of major Linux distributions and adding the various *BSDs flavours as well. I also added SliTaz to the list, as it is a really neat project deserving more recognition.</p>

<p>Here are the results :</p>

<pre>
01. Ubuntu          (Alexa Traffic Rank : 1212)
02. Debian          (Alexa Traffic Rank : 4059)
03. CentOS          (Alexa Traffic Rank : 6017)
04. Red Hat         (Alexa Traffic Rank : 6533)
05. Fedora          (Alexa Traffic Rank : 7817)
06. openSUSE        (Alexa Traffic Rank : 8779)
07. FreeBSD         (Alexa Traffic Rank : 9238)
08. Arch Linux      (Alexa Traffic Rank : 12730)
09. Gentoo          (Alexa Traffic Rank : 15112)
10. Kubuntu         (Alexa Traffic Rank : 79034)
11. Xubuntu         (Alexa Traffic Rank : 98336)
12. OpenBSD         (Alexa Traffic Rank : 104178)
13. Slackware       (Alexa Traffic Rank : 104811)
14. Mageia          (Alexa Traffic Rank : 110857)
15. PC-BSD          (Alexa Traffic Rank : 126395)
16. SliTaz          (Alexa Traffic Rank : 143211)
17. NetBSD          (Alexa Traffic Rank : 143772)
18. Lubuntu         (Alexa Traffic Rank : 149010)
19. Edubuntu        (Alexa Traffic Rank : 298003)
20. DragonFly BSD   (Alexa Traffic Rank : 648612)
</pre>


<p>Although the ranking might not be totally accurate (i.e: RedHat also provides Cloud Hosting on it&#8217;s main domain), it seems to make sense, at least.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Interesting DNS Hacks]]></title>
    <link href="http://www.cambus.net/interesting-dns-hacks/"/>
    <updated>2013-01-09T16:28:00+01:00</updated>
    <id>http://www.cambus.net/interesting-dns-hacks</id>
    <content type="html"><![CDATA[<p><strong>DNS Gateway for Twitter and Identi.ca</strong> :</p>

<p>A neat hack allowing to query Twitter statuses, timelines, and user informations over DNS :</p>

<pre>
dig fcambus.twitter.any.io TXT +short
"Teletext in Poland - Part I and II : http://t.co/0t0FiXY8 and http://t.co/rKYR0FJH #textmode #teletext" "Wed Jan 09 13:26:12 +0000 2013"

dig fcambus.identica.any.io TXT +short
"Just released my ANSi Social Media Icon Set - http://bit.ly/jIYYLi" "Thu Jun 09 16:17:32 +0000 2011"

dig statdns.timeline.twitter.any.io TXT +short
;; Truncated, retrying in TCP mode.
"DANE (RFC 6698) has been deployed on StatDNS' DNS Testground domain : https://t.co/Uox3VobV #dnssec #dane" "Thu Jan 03 17:46:50 +0000 2013"
"Zone Files Statistics - January 2013 Reports - http://t.co/2iGhqJNc #dns #dnssec" "Wed Jan 02 11:50:54 +0000 2013"
"Added RFC 6781 : DNSSEC Operational Practices, Version 2 - http://t.co/wWowpmx3 #DNS #DNSSEC #RFC" "Mon Dec 24 16:41:32 +0000 2012"
"Zone Files Statistics - December 2012 Reports - http://t.co/2iGhqJNc  #dns #dnssec" "Sun Dec 02 09:19:21 +0000 2012"
"Zone Files Statistics - November 2012 Reports - http://t.co/2iGhqJNc #dns #dnssec" "Fri Nov 02 11:27:40 +0000 2012"
"Zone Files Statistics - October 2012 Reports - http://t.co/2iGhqJNc #dns #dnssec" "Sat Oct 06 12:09:53 +0000 2012"
"Zone Files Statistics - September 2012 Reports - http://t.co/2iGhqJNc #dns #dnssec" "Sun Sep 02 17:34:33 +0000 2012"
"DNS related RFCs (An up to date list of Domain Name System RFCs) - http://t.co/7dLCO68H #DNS #DNSSEC #RFC" "Mon Aug 27 10:55:15 +0000 2012"
"StatDNS' DNS Testground hosts some seldom used resource record types, useful to test DNS tools : http://t.co/EabRV1U3 #DNS #DNSSEC" "Wed Apr 04 16:21:29 +0000 2012"

dig statdns.twitter @any.io TXT +short
"DANE (RFC 6698) has been deployed on StatDNS' DNS Testground domain : https://t.co/Uox3VobV #dnssec #dane"
"Thu Jan 03 17:46:50 +0000 2013"
"StatDNS"
"127.0.0.1"
"http://www.statdns.com"
"DNS and Domain Names statistics and tools"
statdns.twitter.
</pre>


<p><strong>Wikipedia over DNS</strong> :</p>

<p>This one is pretty much self-explanatory, you can query DNS related articles (and not only!) over DNS (more information <a href="https://dgl.cx/wikipedia-dns">here</a>) :</p>

<pre>
dig bind.wp.dg.cx TXT +short
"BIND , or named , is the most widely used DNS software on the Internet. On Unix-like operating systems it is the de facto standard. http://en.wikipedia.org/wiki/BIND"

dig nsd.wp.dg.cx TXT +short
"In Internet computing, NSD (for \"name server daemon\") is an open-source server program for the Domain Name System. It was developed by NLnet Labs of Amsterdam in cooperation with the RIPE NCC, from scratch as an authoritative name server (i.e., not implem" "enting the recursive caching function by design). The intention of this development is to add variance to the \"gene pool... http://en.wikipedia.org/wiki/NSD"

dig powerdns.wp.dg.cx TXT +short
"PowerDNS is a DNS server, written in C++ and licensed under the GPL. It runs on most Unix derivatives and on Microsoft Windows. PowerDNS features a large number of different backends ranging from simple BIND style zonefiles to relational databases and loa" "d balancing/failover algorithms. A DNS recursor is also included as a separate program. http://en.wikipedia.org/wiki/PowerDNS"
</pre>


<p><strong>Postcode locations</strong> :</p>

<p>You can find the geographic location of any UK postcode by querying LOC records on find.me.uk subdomains :</p>

<pre>
dig FK102NX.find.me.uk. LOC +short
56 7 27.822 N 3 50 35.480 W 0.00m 0.00m 0.00m 0.00m
</pre>


<p>For the curious mind, you can check on Google Maps why I picked up this exact postcode :)</p>

<p><strong>DNS Calculator</strong> :</p>

<p>A calculator supporting addition, substraction, multiplication and division (respectively : ADD, SUB ,MUL, and DIV operations). More information <a href="http://www.isi.edu/touch/tools/dns-calc.html">here</a>.</p>

<pre>
dig @dns.postel.org 2.8.add.calc.postel.org +short
0.10.0.0

dig @dns.postel.org 8.2.sub.calc.postel.org +short
0.6.0.0

dig @dns.postel.org 2.8.mul.calc.postel.org +short
0.16.0.0

dig @dns.postel.org 8.2.div.calc.postel.org +short
0.4.0.0
</pre>


<p><strong>Secure Reverse Polish DNS Calculator</strong> :</p>

<p>An even better calculator using Reverse Polish notation (RPN), and providing DNSSEC signed answers, making it impossible for third parties to temper with the results :D More information <a href="http://bert.secret-wg.org/Tools/index.html#Tool_3">here</a>.</p>

<p>Here is an example showing how to calculate 2*3+2 (as you can see, the answers are signed) :</p>

<pre>
dig 2.3.*.2.+.rp.secret-wg.org TXT +dnssec

; <<>> DiG 9.7.3 <<>> 2.3.*.2.+.rp.secret-wg.org TXT +dnssec
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14766
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;2.3.*.2.+.rp.secret-wg.org.    IN  TXT

;; ANSWER SECTION:
2.3.*.2.+.rp.secret-wg.org. 10  IN  TXT "8"
2.3.*.2.+.rp.secret-wg.org. 10  IN  TXT "This DNS message (including the RR(s) in the additional section) is confidential, proprietary, may be subject to copyright and legal privilege and no related rights are waived." "If you are not the intended recipient or its agent, any review, dissemination, distribution or copying of this DNS message. or any of its content is strictly prohibited and may be unlawful." "All messages may be monitored as permitted by applicable law and regulations and our policies to protect our business." "DNS messages are not secure and you are deemed to have accepted any risk if you communicate with us using DNS." "If received in error, please notify us immediately and delete the DNS message (and any of its sections) from any computer or any storage medium without printing a copy."
2.3.*.2.+.rp.secret-wg.org. 10  IN  RRSIG   TXT 1 8 10 20130427124228 20130226124228 27900 rp.secret-wg.org. 4Gi6ald7O06e8/1anCmCYE3EThUUJP9ikMo3QWa1ZUJteWmCFcbL34cJ ebt5cNGQsYYbwl4QCV/Vt++JLbL3Xw==

;; Query time: 26 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Feb 26 12:42:28 2013
;; MSG SIZE  rcvd: 959
</pre>


<p><strong>IP to ASN Mapping via DNS</strong></p>

<p>A service providing a way to map IPv4 and IPv6 addresses or prefixs to ASNs, get information about ASNs, and even find possible peers. More details <a href="http://www.team-cymru.org/Services/ip-to-asn.html#dns">here</a>.</p>

<p>Mapping an IP address or prefix to a corresponding BGP Origin ASN :</p>

<pre>
dig 31.108.90.216.origin.asn.cymru.com TXT +short
"23028 | 216.90.108.0/24 | US | arin | 1998-09-25"

dig 108.90.216.origin.asn.cymru.com TXT +short
"23028 | 216.90.108.0/24 | US | arin | 1998-09-25"

dig 2.0.0.b.0.6.8.4.1.0.0.2.origin6.asn.cymru.com TXT +short
"15169 | 2001:4860::/32 | US | arin | 2005-03-14"
</pre>


<p>Getting information about a given ASN :</p>

<pre>
dig AS23028.asn.cymru.com TXT +short
"23028 | US | arin | 2002-01-04 | TEAM-CYMRU - Team Cymru Inc."
</pre>


<p><strong>Getting external IP address via DNS</strong></p>

<p>Probably the fastest way to get your external IP address (supports IPv4 only), as unlike the various HTTP services available it doesn&#8217;t require initializing a TCP connection (if you&#8217;re looking for such services, I recommand <a href="http://ip.telize.com">this one</a>, working for both IPv4 and IPv6) :</p>

<pre>
dig myip.opendns.com @resolver1.opendns.com +short
175.45.176.1

dig myip.opendns.com @resolver2.opendns.com +short
175.45.176.1
</pre>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Teletext in Poland - Part II]]></title>
    <link href="http://www.cambus.net/teletext-in-poland-part-ii/"/>
    <updated>2013-01-09T14:14:00+01:00</updated>
    <id>http://www.cambus.net/teletext-in-poland-part-ii</id>
    <content type="html"><![CDATA[<p>This is the second part of the teletext in Poland serie, containing screens from the following channels : TVP Kultura, TVP Polonia, TVP Rzeszow, TVP Sport, Polsat, and TV4.</p>

<p>First part : <a href="http://www.cambus.net/teletext-in-poland-part-i/">http://www.cambus.net/teletext-in-poland-part-i/</a></p>

<p>TVP Kultura :</p>

<p><img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-kultura-100.png" alt="Teletext TVP Kultura" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-kultura-201.png" alt="Teletext TVP Kultura" /><!--more-->
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-kultura-209.png" alt="Teletext TVP Kultura" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-kultura-217.png" alt="Teletext TVP Kultura" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-kultura-222.png" alt="Teletext TVP Kultura" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-kultura-300.png" alt="Teletext TVP Kultura" /></p>

<p>TVP Polonia :</p>

<p><img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-100.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-200.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-345.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-370.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-371-01.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-371-02.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-371-03.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-372-01.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-372-02.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-372-03.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-373-01.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-373-02.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-373-03.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-374-01.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-374-02.png" alt="Teletext TVP Polonia" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-polonia-374-03.png" alt="Teletext TVP Polonia" /></p>

<p>TVP Rzeszow :</p>

<p><img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-rzeszow-100.png" alt="Teletext TVP Rzeszow" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-rzeszow-7--.png" alt="Teletext TVP Rzeszow" /></p>

<p>TVP Sport :</p>

<p><img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-sport-100.png" alt="Teletext TVP Sport" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp-sport-101.png" alt="Teletext TVP Sport" /></p>

<p>Polsat :</p>

<p><img src="http://www.cambus.net/content/2013/01/teletext-poland-polsat-109.png" alt="Teletext Polsat" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-polsat-300.png" alt="Teletext Polsat" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-polsat-363.png" alt="Teletext Polsat" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-polsat-657.png" alt="Teletext Polsat" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-polsat-658.png" alt="Teletext Polsat" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-polsat-667.png" alt="Teletext Polsat" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-polsat-895.png" alt="Teletext Polsat" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-polsat-896.png" alt="Teletext Polsat" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-polsat-897.png" alt="Teletext Polsat" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-polsat-898.png" alt="Teletext Polsat" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-polsat-899.png" alt="Teletext Polsat" /></p>

<p>TV4 :</p>

<p><img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-100.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-108.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-109.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-155.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-156.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-157.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-160.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-181.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-215.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-246.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-280-01.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-280-02.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-281-01.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-281-02.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-281-03.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-281-04.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-310.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-410.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-500-01.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-500-02.png" alt="Teletext TV4" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tv4-898.png" alt="Teletext TV4" /></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Teletext in Poland - Part I]]></title>
    <link href="http://www.cambus.net/teletext-in-poland-part-i/"/>
    <updated>2013-01-09T14:14:00+01:00</updated>
    <id>http://www.cambus.net/teletext-in-poland-part-i</id>
    <content type="html"><![CDATA[<p>Here comes the fourth article of my World of teletext serie, covering Polish teletext this time, and containing 116 screens. In case you&#8217;re
wondering, the previous episodes have been covering <a href="http://www.cambus.net/teletext-in-france/">France</a>, <a href="http://www.cambus.net/teletext-in-germany-part-i/">Germany</a> and <a href="http://www.cambus.net/teletext-in-greece/">Greece</a>.</p>

<p>This serie contains screens from the following channels :  TVP 1, TVP 2, TVP Kultura, TVP Polonia, TVP Rzeszow, TVP Sport, Polsat, and TV4.</p>

<p>The format is a bit different this time, as a lot of Polish channels have online teletext portals, so I&#8217;m just publishing .PNG conversions instead of the usual photographs. Overall, I was able to have a better glimpse of all the available content, and found some really nice unreferenced screens and test pages.</p>

<p>Due to the large number of pictures, I decided to split the article in two parts to allow easier viewing, follow this link to reach the second part :</p>

<p>Second part : <a href="http://www.cambus.net/teletext-in-poland-part-ii/">http://www.cambus.net/teletext-in-poland-part-ii/</a></p>

<p>TVP 1 :</p>

<p><img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-100.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-101.png" alt="Teletext TVP 1" /><!--more-->
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-106.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-110.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-160.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-177-01.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-177-02.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-300.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-335.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-336.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-395.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-429.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-440.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-11.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-12.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-13.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-14.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-15.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-16.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-17.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-22.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-26.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-27.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-28.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-30.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-31.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-476-32.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-614.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-620-02.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-620-03.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-620-04.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-793.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-794.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-841.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-842-01.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-842-02.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-843.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-844-01.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-844-02.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-844-03.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-844-04.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-844-05.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-01.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-02.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-03.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-04.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-05.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-06.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-07.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-08.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-09.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-10.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-11.png" alt="Teletext TVP 1" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp1-879-12.png" alt="Teletext TVP 1" /></p>

<p>TVP 2 :</p>

<p><img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp2-100.png" alt="Teletext TVP 2" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp2-281.png" alt="Teletext TVP 2" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp2-380.png" alt="Teletext TVP 2" />
<img src="http://www.cambus.net/content/2013/01/teletext-poland-tvp2-390.png" alt="Teletext TVP 2" /></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Creating TLSA records (DANE Protocol)]]></title>
    <link href="http://www.cambus.net/creating-tlsa-records/"/>
    <updated>2013-01-08T12:05:00+01:00</updated>
    <id>http://www.cambus.net/creating-tlsa-records</id>
    <content type="html"><![CDATA[<p>I recently deployed DANE (RFC 6698) on <a href="http://www.statdns.com">StatDNS</a> <a href="https://www.statdns.net">DNSSEC Testground</a> domain, and thus had to create TLSA records. For doing so, I used <strong>hash-slinger</strong> (which makes the process straightforward) and decided to publish this quick tutorial, mainly to serve as a memo.</p>

<p>We start by installing (as root) required packages to run the program, follow the instructions related to the Linux distribution you are using :</p>

<p><strong>Fedora</strong> :</p>

<pre>
yum install m2crypto python-dns python-ipaddr unbound unbound-python
</pre>


<p><strong>Ubuntu</strong> :</p>

<p>On Ubuntu, we also need to update the root and DLV anchors manually.</p>

<pre>
apt-get install python-m2crypto python-dnspython python-ipaddr unbound python-unbound

unbound-anchor -a "/etc/unbound/root.key"
unbound-anchor -a "/etc/unbound/dlv.isc.org.key"
</pre>


<p>We then fetch and unpack hash-slinger (at the time of writing, the latest version is 2.1) :</p>

<pre>
wget http://people.redhat.com/pwouters/hash-slinger/hash-slinger-2.1.tar.gz
tar xvfz hash-slinger-2.1.tar.gz
cd hash-slinger-2.1
</pre>


<p>We can now create our <strong>TLSA records</strong> :</p>

<pre>
./tlsa --create www.statdns.net
</pre>


<p>Alternatively, if your <strong>DNSSEC signer</strong> does not yet support TLSA records :</p>

<pre>
./tlsa --create -o generic www.statdns.net
</pre>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The future of BBSes?]]></title>
    <link href="http://www.cambus.net/the-future-of-bbses/"/>
    <updated>2012-11-18T00:29:00+01:00</updated>
    <id>http://www.cambus.net/the-future-of-bbses</id>
    <content type="html"><![CDATA[<p>Despite the fact I&#8217;m still using a lot of text-based applications, I have to confess I&#8217;ve not been using <strong>Telnet BBSes</strong> much lately. Actually, one of the last time I really enjoyed BBSing again was almost a decade ago.</p>

<p>In December 2004, soon after moving to Australia, I downloaded a Fidonet nodelist from an Internet café and tried to find dialup BBS numbers in what was then my local area (Brisbane, QLD). Surprisingly, I found one answering (Far Northern News) and connected on a regular basis while waiting for my DSL connection to be installed. And that was it. Even today, information overload and &#8220;always on&#8221; Internet connections do not leave any time for enjoying telnet BBSes.</p>

<p>Lately though, I&#8217;ve been using my smartphone more and more to read text-only sites like Hacker News, Lamer News, Lobsters and my own Echo JS. And it makes sense, fast loading times and text layouts are the ideal combination on mobiles. So I&#8217;ve been thinking, why not trying to use BBSes again on my phone? On an Android device, with the avalaibility of virtual keyboards allowing access to ESC, Control, and arrows keys (such as &#8221;<strong>Hacker&#8217;s Keyboard</strong>&#8221;), it becomes a reality.</p>

<p>An Android phone connected to &#8221;<strong>The Deadline</strong>&#8221;, an oldschool French BBS :</p>

<p><img src="http://www.cambus.net/content/2012/11/mobile-bbsing-deadline.png" title="Mobile BBSing" alt="Mobile BBSing" /></p>

<p>Pushing the reflexion further, what about running BBSes on smartphones?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[International Teletext Art Festival on ARD]]></title>
    <link href="http://www.cambus.net/international-teletext-art-festival-on-ard/"/>
    <updated>2012-09-08T14:50:00+02:00</updated>
    <id>http://www.cambus.net/international-teletext-art-festival-on-ard</id>
    <content type="html"><![CDATA[<p>After being broadcasted on YLE last Spring, the <a href="http://www.cambus.net/international-teletext-art-festival/">International Teletext Art Festival</a> returns and is currently live in Germany on <a href="http://www.ard-text.de">ARD teletext</a> (page 770), until September 16th. According to informations communicated by ITAF staff, ARD (Arbeitsgemeinschaft der öffentlich-rechtlichen Rundfunkanstalten der Bundesrepublik Deutschland) is the second largest public mediahouse after the BBC, making it the largest teletext broadcaster as the BBC is phasing out <strong>Ceefax</strong>.</p>

<p>You can see some captures below, and it&#8217;s interesting to notice that my picture got mangled somehow : is it a teletext emulator rendering bug? However, it appeared correctly on TV so that&#8217;s probably what matters most.</p>

<p>Some screenshots from ARD teletext pages :</p>

<p><img src="http://www.cambus.net/content/2012/09/ard-itaf-01.png" title="ARD - ITAF 1/2" alt="ARD - ITAF 1/3" />
<img src="http://www.cambus.net/content/2012/09/ard-itaf-02.png" title="ARD - ITAF 2/3" alt="ARD - ITAF 2/3" />
<img src="http://www.cambus.net/content/2012/09/ard-itaf-03.png" title="ARD - ITAF 2/3" alt="ARD - ITAF 2/3" /></p>

<p>Translated artist biography and artwork :</p>

<p><img src="http://www.cambus.net/content/2012/09/ard-frederic-cambus.png" title="ARD - Frederic Cambus" alt="ARD - Frederic Cambus" />
<img src="http://www.cambus.net/content/2012/09/ard-textcity.png" title="ARD - Textcity" alt="ARD - TextCity" /></p>

<p>For reference, here is the original english version of the biography :</p>

<p>For as long as I can remember, I&#8217;ve been fascinated by type, fonts and printed materials. Growing up during the golden years of text terminals, PC&#8217;s 80x25 text mode displays, Dot Matrix printers, and French Minitel (using Videotex display, closely related to Teletext), I naturally became a text mode artist. After drawing ASCII and ANSI art for over fifteen years, I&#8217;ve been turning myself to Teletext, a media offering a similar manner of expression, only with a more global and broadened audience.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Teletext in Greece]]></title>
    <link href="http://www.cambus.net/teletext-in-greece/"/>
    <updated>2012-09-01T13:55:00+02:00</updated>
    <id>http://www.cambus.net/teletext-in-greece</id>
    <content type="html"><![CDATA[<p>Here is a very short collection of <strong>greek Teletext</strong> pictures I could sneak during my trip in Crete this July. I apologize in advance for the poor picture quality, as these screens were taken with a smartphone and thus without tripod (you can notice the vertical blanking signal artefact on some of the pictures).</p>

<p>According to Wikipedia, the ongoing digital television transition in Greece will be completed sometime in 2013, so it means I
was quite lucky to still be able to capture them. Unfortunately the hotel TV only had this nationwide channel (Alpha TV) offering teletext, I really would have loved to see more of those nice greek characters filled screens.</p>

<p><img src="http://www.cambus.net/content/2012/09/teletext-greece-alpha-tv-01.jpg" alt="Teletext Alpha TV" />
<img src="http://www.cambus.net/content/2012/09/teletext-greece-alpha-tv-02.jpg" alt="Teletext Alpha TV" />
<img src="http://www.cambus.net/content/2012/09/teletext-greece-alpha-tv-03.jpg" alt="Teletext Alpha TV" /></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Minitel is dead]]></title>
    <link href="http://www.cambus.net/minitel-is-dead/"/>
    <updated>2012-06-30T15:27:00+02:00</updated>
    <id>http://www.cambus.net/minitel-is-dead</id>
    <content type="html"><![CDATA[<p>Today is a very sad day, as Minitel service is permanently shut down in France. For a lot of people though, it was already impossible to connect to the service as Minitel and VoIP phone lines do not mix well together.</p>

<p>The event has already been covered by a large number of sites and therefore, I will just publish some pictures I took especially for this day during my last trip to France.</p>

<p>R.I.P. Minitel&#8230;</p>

<p>Minitel 2 manufactured by Philips :</p>

<p><img src="http://www.cambus.net/content/2012/06/minitel.jpg" title="Minitel 2" alt="Minitel 2" /></p>

<p>Minitel 2 with rackable keyboard opened :</p>

<p><img src="http://www.cambus.net/content/2012/06/minitel-clavier.jpg" title="Minitel 2" alt="Minitel 2" /></p>

<p>Built in phone diary and options screen :</p>

<p><img src="http://www.cambus.net/content/2012/06/minitel-repertoire01.jpg" title="Minitel 2" alt="Minitel 2" />
<img src="http://www.cambus.net/content/2012/06/minitel-repertoire02.jpg" title="Minitel 2" alt="Minitel 2" />
<img src="http://www.cambus.net/content/2012/06/minitel-programmer.jpg" title="Minitel 2" alt="Minitel 2" /></p>

<p>Minitel is dead :</p>

<p><img src="http://www.cambus.net/content/2012/06/minitel-is-dead.jpg" title="Minitel is dead" alt="Minitel is dead" /></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Things I love about Go]]></title>
    <link href="http://www.cambus.net/things-i-love-about-go/"/>
    <updated>2012-06-22T19:05:00+02:00</updated>
    <id>http://www.cambus.net/things-i-love-about-go</id>
    <content type="html"><![CDATA[<p>Here is a list of various things I love about the Go programming language :</p>

<ul>
<li><p>Statically typed language</p></li>
<li><p>C-like syntax (and consistent one!)</p></li>
<li><p>Compiled language (No possible source code alteration when deployed on production servers)</p></li>
<li><p>Statically linked binaries (No dependencies hell, easy to deploy in production)</p></li>
<li><p>Easy cross-compilation, both 32-bit and 64-bit (FreeBSD, Linux, Mac OS X and Windows)</p></li>
<li><p>Ultra fast compilation</p></li>
<li><p>No Makefiles (Replaced by the Go tool : go build &amp; go install)</p></li>
<li><p>Gofmt tool (automatically formats Go programs)</p></li>
<li><p>Functions with multiple return values</p></li>
<li><p>Rich and feature-full standard library</p></li>
<li><p>Future proof (Goroutines &amp; Channels)</p></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[From DNS with love!]]></title>
    <link href="http://www.cambus.net/from-dns-with-love/"/>
    <updated>2012-03-23T20:09:00+01:00</updated>
    <id>http://www.cambus.net/from-dns-with-love</id>
    <content type="html"><![CDATA[<p>So what&#8217;s with the title? Well, that&#8217;s right, querying <strong>OpenDNS</strong> servers directly for a specially crafted string will display a cute <strong>ASCII</strong> love message!</p>

<p>Unless you try it today, you probably won&#8217;t be able to check it by yourself, as this has been only live for a few weeks and is scheduled to be turned off tomorrow, but nonetheless I&#8217;m pretty sure it&#8217;s bound to reappear someday. Maybe for next year Valentine&#8217;s Day?</p>

<p>So here is how to trigger it :</p>

<pre>
dig @208.67.222.222 fred+diana=love txt +bufsize=4096
</pre>


<p>And here is the output :</p>

<pre>
; <<>> DiG 9.7.3-P3 <<>> @208.67.222.222 fred+diana=love txt +bufsize=4096
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 31952
;; flags: qr rd ra; QUERY: 1, ANSWER: 35, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;fred+diana=love.       IN  TXT

;; ANSWER SECTION:
FRED\000DIANA\000love.  0   IN  TXT "              MMMMMMMMM                         MMMMMMMMM"
FRED\000DIANA\000love.  0   IN  TXT "          MMMMMMMMMMMMMMMMMM               MMMMMMMMMMMMMMMMMM"
FRED\000DIANA\000love.  0   IN  TXT "       MMMMMMMXXXXXXXXXXMMMMMMM         MMMMMMMXXXXXXXXXXMMMMMMM"
FRED\000DIANA\000love.  0   IN  TXT "    MMMMMMXXXXXXXXXXXXXXXXXMMMMMM     MMMMMMXXXXXXXXXXXXXXXXXMMMMMM"
FRED\000DIANA\000love.  0   IN  TXT "   MMMMMXXXXXXXXOOOOOOOOXXXXXXMMMM   MMMMXXXXXXOOOOOOOOXXXXXXXXMMMMM"
FRED\000DIANA\000love.  0   IN  TXT "  MMMMXXXXXXXOOOOOOOOOOOOOOOXXXXMMM MMMXXXXOOOOOOOOOOOOOOOXXXXXXXMMMM"
FRED\000DIANA\000love.  0   IN  TXT " MMMMXXXXXXOOOOOOOOOOOOOOOOOOOOXXXMMMXXXOOOOOOOOOOOOOOOOOOOOXXXXXXMMMM"
FRED\000DIANA\000love.  0   IN  TXT " MMMXXXXXOOOOOOOOOOOOOOOOOOOOOOOOXXXXXOOOOOOOOOOOOOOOOOOOOOOOOXXXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "MMMXXXXXOOOOOOOOOOO       OOOOOOOOOXOOOOOOOOO       OOOOOOOOOOOOXXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "MMMXXXXOOOOOOOOO              OOOOOOOOOOO              OOOOOOOOOOXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "MMMXXXXOOOOOOOO                  OOOOO                  OOOOOOOOOXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "MMMXXXXOOOOOOO                     O                     OOOOOOOOXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "MMMXXXXOOOOOOO                                           OOOOOOOOXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "MMMXXXXOOOOOOO                   FRED                    OOOOOOOOXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "MMMXXXXXOOOOOO                     +                     OOOOOOOXXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT " MMMXXXXOOOOOOO                  DIANA                  OOOOOOOOXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT " MMMMXXXXOOOOOOO                                       OOOOOOOOXXXMMMM"
FRED\000DIANA\000love.  0   IN  TXT "  MMMXXXXOOOOOOOOO                                    OOOOOOOOOXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "  MMMMXXXXOOOOOOOOOO                                OOOOOOOOOOXXXMMMM"
FRED\000DIANA\000love.  0   IN  TXT "   MMMXXXXXOOOOOOOOOOO                           OOOOOOOOOOOOXXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "    MMMXXXXXOOOOOOOOOOOOO                     OOOOOOOOOOOOOOXXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "     MMMXXXXXOOOOOOOOOOOOOOO               OOOOOOOOOOOOOOOOXXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "      MMMXXXXXOOOOOOOOOOOOOOOOO         OOOOOOOOOOOOOOOOOXXXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "       MMMXXXXXXOOOOOOOOOOOOOOOOOO   OOOOOOOOOOOOOOOOOOXXXXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "         MMMXXXXXXXOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOXXXXXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "           MMMXXXXXXXXOOOOOOOOOOOOOOOOOOOOOOOOOOOXXXXXXXXMMM"
FRED\000DIANA\000love.  0   IN  TXT "             MMMMXXXXXXXXXOOOOOOOOOOOOOOOOOOOXXXXXXXXXMMMM"
FRED\000DIANA\000love.  0   IN  TXT "                MMMMXXXXXXXXXXXOOOOOOOOOXXXXXXXXXXMMMMM"
FRED\000DIANA\000love.  0   IN  TXT "                   MMMMMXXXXXXXXXXXOXXXXXXXXXXXMMMMM"
FRED\000DIANA\000love.  0   IN  TXT "                      MMMMMMXXXXXXXXXXXXXXXMMMMMM"
FRED\000DIANA\000love.  0   IN  TXT "                          MMMMMMXXXXXXXMMMMMM"
FRED\000DIANA\000love.  0   IN  TXT "                              MMMMMXMMMMM"
FRED\000DIANA\000love.  0   IN  TXT "                                 MMMMM"
FRED\000DIANA\000love.  0   IN  TXT "                                  MMM"
FRED\000DIANA\000love.  0   IN  TXT "                                   M"

;; Query time: 78 msec
;; SERVER: 208.67.222.222#53(208.67.222.222)
;; WHEN: Fri Mar 23 19:36:50 2012
;; MSG SIZE  rcvd: 2678
</pre>


<p>Isn&#8217;t it lovely? I must say it delighted me, and those who know about my areas of interest will understand why for sure!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Creating thumbnails using PhantomJS and ImageMagick]]></title>
    <link href="http://www.cambus.net/creating-thumbnails-using-phantomjs-and-imagemagick/"/>
    <updated>2012-03-18T01:01:00+01:00</updated>
    <id>http://www.cambus.net/creating-thumbnails-using-phantomjs-and-imagemagick</id>
    <content type="html"><![CDATA[<p>As some people asked for more information about how I render thumbnails for <a href="http://www.nodecloud.org">NodeCloud</a>, I decided to document the process and post about it, so here we go.</p>

<p>In order to take the screenshots, I&#8217;m using a simplified version of the <em>rasterize.js</em> file bundled with <strong>PhantomJS</strong>, configured with a viewport size of 1024x768 and modified to wait 2000 milliseconds before creating output file, in order to allow every page element sufficient time to render.</p>

<p>Here is the script :</p>

<figure class='code'><figcaption><span> (rasterize.js)</span> <a href='http://www.cambus.net/downloads/code/rasterize.js'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='js'><span class='line'><span class="kd">var</span> <span class="nx">page</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebPage</span><span class="p">(),</span>
</span><span class='line'>    <span class="nx">address</span><span class="p">,</span> <span class="nx">output</span><span class="p">,</span> <span class="nx">size</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">if</span> <span class="p">(</span><span class="nx">phantom</span><span class="p">.</span><span class="nx">args</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Usage: rasterize.js URL filename&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">phantom</span><span class="p">.</span><span class="nx">exit</span><span class="p">();</span>
</span><span class='line'><span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">address</span> <span class="o">=</span> <span class="nx">phantom</span><span class="p">.</span><span class="nx">args</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
</span><span class='line'>    <span class="nx">output</span> <span class="o">=</span> <span class="nx">phantom</span><span class="p">.</span><span class="nx">args</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">page</span><span class="p">.</span><span class="nx">viewportSize</span> <span class="o">=</span> <span class="p">{</span> <span class="nx">width</span><span class="o">:</span> <span class="mi">1024</span><span class="p">,</span> <span class="nx">height</span><span class="o">:</span> <span class="mi">768</span> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">page</span><span class="p">.</span><span class="nx">open</span><span class="p">(</span><span class="nx">address</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">status</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nx">status</span> <span class="o">!==</span> <span class="s1">&#39;success&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Unable to load the address!&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>            <span class="nb">window</span><span class="p">.</span><span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'>                <span class="nx">page</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="nx">output</span><span class="p">);</span>
</span><span class='line'>                <span class="nx">phantom</span><span class="p">.</span><span class="nx">exit</span><span class="p">();</span>
</span><span class='line'>            <span class="p">},</span> <span class="mi">2000</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>To rasterize a given page, we call the previous script as follow :</p>

<pre>
phantomjs --load-plugins=yes rasterize.js http://www.nodecloud.org nodecloud.org.png
</pre>


<p>Now, the second part of the process is creating a thumbnail using ImageMagick :</p>

<pre>
convert "nodecloud.org.png" -crop 1024x768+0+0 "nodecloud.org.png"
convert "nodecloud.org.png" -filter Lanczos -thumbnail 200x150 "nodecloud.org-thumbnail.png"
</pre>


<p>This is done in two steps : first we crop the top of the output rendered by PhantomJS in order to get a 4:3 ratio image, and then we resize it using the <em>Lanczos</em> filter.</p>

<p>We can easily automate the process to convert a batch of sites using a simple <strong>Bash script</strong> defining an array containing a list of URLs to generate thumbnails from :</p>

<figure class='code'><figcaption><span> (thumbnails.sh)</span> <a href='http://www.cambus.net/downloads/code/thumbnails.sh'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="c">#!/bin/bash</span>
</span><span class='line'>
</span><span class='line'><span class="nv">sites</span><span class="o">=(</span> cambus.net nodecloud.org <span class="o">)</span>
</span><span class='line'>
</span><span class='line'><span class="k">for </span>site in <span class="s2">&quot;${sites[@]}&quot;</span>
</span><span class='line'><span class="k">do</span>
</span><span class='line'><span class="k">  </span><span class="nb">echo</span> <span class="s2">&quot;- Processing : $site&quot;</span>
</span><span class='line'>  phantomjs --load-plugins<span class="o">=</span>yes rasterize.js http://<span class="nv">$site</span> <span class="nv">$site</span>.png
</span><span class='line'>  convert <span class="s2">&quot;$site.png&quot;</span> -crop 1024x768+0+0 <span class="s2">&quot;$site.png&quot;</span> <span class="o">&amp;&amp;</span> convert <span class="s2">&quot;$site.png&quot;</span> -filter Lanczos -thumbnail 200x150 <span class="s2">&quot;$site-thumbnail.png&quot;</span>
</span><span class='line'>  <span class="nb">echo</span> <span class="s2">&quot;- Done processing : $site&quot;</span>
</span><span class='line'><span class="k">done</span>
</span></code></pre></td></tr></table></div></figure>


<p>Lastly, I would recommend using the excellent <strong>OptiPNG</strong> to optimize thumbnails file size.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Printing ANSi art]]></title>
    <link href="http://www.cambus.net/printing-ansi-art/"/>
    <updated>2012-03-15T15:07:00+01:00</updated>
    <id>http://www.cambus.net/printing-ansi-art</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been printing some ANSi art lately, and figured out I would post something about it.</p>

<p>All pieces have been printed at a digital photo printing kiosk using 4R format (which translate into a size of 4&#8221; × 6&#8221; or 102 × 152 mm and a 3:2) ratio.</p>

<p>I had to make two batches in order to get the desired results :</p>

<ul>
<li>For the first batch, I just printed the 16 colors PNG output from <a href="http://ansilove.sourceforge.net">Ansilove</a> to see how it would look like, and I can tell you it didn&#8217;t turn out very well : the aspect ratio was not preserved (which I expected) and the printed material had dull colors.</li>
<li>For the second batch, I added some extra black borders around the pictures in order to get a 3:2 ratio and also changed the color profiles to use one optimized for printing : it went much nicer this time, providing pictures with correct aspect ratio and more vivid colors. It&#8217;s still not 100% perfect as the picture still has to be resized by the printer, causing some artefacts on color blocks, but overall the result is more than satisfying and it will do, at least for now.</li>
</ul>


<p><img src="http://www.cambus.net/content/2012/03/printed-ansi-art.jpg" title="Printed Ansi art" alt="Printed Ansi art" /></p>
]]></content>
  </entry>
  
</feed>
