<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>My journal</title><link href="http://jrenard.info/blog" rel="alternate"></link><link href="http://jrenard.info/blog/feeds/all.atom.xml" rel="self"></link><id>http://jrenard.info/blog</id><updated>2012-01-24T00:00:00+01:00</updated><entry><title>You want to use pigz, really</title><link href="http://jrenard.info/blog/you-want-to-use-pigz-really.html" rel="alternate"></link><updated>2012-01-24T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2012-01-24:/blog/you-want-to-use-pigz-really.html/</id><summary type="html">&lt;p&gt;If you always looked for a faster gzip this blog post is for you.&lt;/p&gt;
&lt;p&gt;Here is a quick test on a 1.5GB SQL dump.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;21:22 &lt;span class="o"&gt;(&lt;/span&gt;jerome~gimli&lt;span class="o"&gt;)&lt;/span&gt; /tmp
% &lt;span class="nb"&gt;time &lt;/span&gt;gzip --best testfile.txt
gzip --best testfile.txt  123.48s user 1.35s system 98% cpu 2:06.19 total

21:25 &lt;span class="o"&gt;(&lt;/span&gt;jerome~gimli&lt;span class="o"&gt;)&lt;/span&gt; /tmp
% &lt;span class="nb"&gt;time &lt;/span&gt;gunzip testfile.txt.gz
gunzip testfile.txt.gz  8.47s user 1.73s system 62% cpu 16.410 total

21:25 &lt;span class="o"&gt;(&lt;/span&gt;jerome~gimli&lt;span class="o"&gt;)&lt;/span&gt; /tmp
% &lt;span class="nb"&gt;time &lt;/span&gt;pigz --best testfile.txt
pigz --best testfile.txt  132.76s user 1.83s system 188% cpu 1:11.40 total

21:27 &lt;span class="o"&gt;(&lt;/span&gt;jerome~gimli&lt;span class="o"&gt;)&lt;/span&gt; /tmp
% &lt;span class="nb"&gt;time &lt;/span&gt;unpigz testfile.txt.gz
unpigz testfile.txt.gz  5.94s user 2.46s system 66% cpu 12.695 total
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So I believe it is time for you to :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;apt-get|yum|port install pigz
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Pigz official website : &lt;a class="reference external" href="http://zlib.net/pigz/"&gt;http://zlib.net/pigz/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;:)&lt;/p&gt;
</summary></entry><entry><title>Specialist or generalist ?</title><link href="http://jrenard.info/blog/specialist-or-generalist.html" rel="alternate"></link><updated>2012-01-11T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2012-01-11:/blog/specialist-or-generalist.html/</id><summary type="html">&lt;p&gt;I believe that it probably happened to you in the past where a potential
customer tells you something like &amp;quot;You are not an expert with technology X
then I am afraid I will not work with you&amp;quot;.&lt;/p&gt;
&lt;p&gt;That makes me think about the difference between being a specialist and a
generalist. I had to work as a specialist (i.e an &amp;quot;expert&amp;quot;) at my previous job as I
worked for a software vendor so I was obviously expected to know the product
deeply. The problem when you behave like this is that you only know and work with
one technology. But this is what you are paid for after all.&lt;/p&gt;
&lt;p&gt;After some time, you know the system so well that you have the feeling to get
a giant hammer and suddendly everything looks like a nail. You stop thinking
about where to put the nail in and how to put it. You just want to put a nail
somewhere so your customer did not pay you for nothing and this is really bad.&lt;/p&gt;
&lt;p&gt;This is a behaviour I already noticed with people who are experts in their field.
When you start discussing about a problem there is alway a moment when you get a
&amp;quot;Ho that is really simple, with technology X I could do it in 2 days&amp;quot; where
technology X is obviously the one this person has a really a deep knowledge of.&lt;/p&gt;
&lt;p&gt;In my opinion this is a bad idea to think like a specialist because the risk
of overlooking the entire picture of the situation is too big. It is extremely
important to get the big picture of a customer's situation tatooed into your mind
first and then start discussing with your customer what you can do to help him.
You also have to make it very clear that you work for your customer's customers
(i.e final users) because if final users are happy with the system, your customer
will be happy (everybody is someone's customer at some point).&lt;/p&gt;
&lt;p&gt;Solving web performance issues is a perfect example of the generalist VS
specialist behavior. Imagine your customer asks you to make his website faster
because it is too slow. The specialist will most likely dive in his cumfort
zone. If it's a frontend engineer he will tell you that your CSS are too heavy
or that your JavaScript files should be loaded at the bottom of the page. If it
is backend engineer if will probably dive into your PHP code or he will tell you
that your website if obviously slow because it does not use NodeJS or MongoDB
and you should rewrite the entire thing, because, you know,
&amp;quot;&lt;a class="reference external" href="http://nosql.mypopescu.com/post/1016320617/mongodb-is-web-scale"&gt;MongoDB is web scale&lt;/a&gt;&amp;quot; ...&lt;/p&gt;
&lt;p&gt;If you ask a generalist you should get more questions than answers first, like
&amp;quot;is it a network problem (DNS, latency, anything else ?)&amp;quot;, &amp;quot;is it a distribution
problem ? (maybe the CDN used -if any- has problems), &amp;quot;is it a front-end problem
(ie is the slowness feeling a pure perceived performance problem or a real one ?)&amp;quot;,
&amp;quot;is it a backend problem ? (maybe something is going wrong on the server or at the
datastore leve?)&amp;quot;. The key to these questions if to understand the problem first
because when you do not understand a problem entirely chances are it will not be
fixed, or worst il will be fixed at the wrong level of abstraction. Then he will
ask you for metrics and logs, analyze this ton of informations and provide a
couple of theories explaining why the website is slow. The next step is to prove
this theories. If all of them are wrong then drain, wash and rince again an find
what has been overlooked previously. Then you should get an answer that really
fixes the problem(s).&lt;/p&gt;
&lt;p&gt;There is one thing I noticed with generalists, they have a better capacity to
dive into a manual or the source code of products they have to work with most
likely because they do not live in a cumfort zone but are constantly switching
between different problems during the day.&lt;/p&gt;
&lt;p&gt;If I had to hire someone I think I would prefer a generalist to a specialist.&lt;/p&gt;
</summary></entry><entry><title>An alternative to lesscss: writing CSS with GNU m4</title><link href="http://jrenard.info/blog/an-alternative-to-lesscss-writing-css-with-gnu-m4.html" rel="alternate"></link><updated>2012-01-10T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2012-01-10:/blog/an-alternative-to-lesscss-writing-css-with-gnu-m4.html/</id><summary type="html">&lt;p&gt;I hate working with CSS so I decided to make it less of a pain by using &lt;a class="reference external" href="https://www.gnu.org/software/m4/"&gt;GNU m4&lt;/a&gt;
with it so I can at least get variable support and basic math operations.&lt;/p&gt;
&lt;p&gt;If you want variables and arithmetic support (and even more) you can use &lt;a class="reference external" href="http://lesscss.org/"&gt;less CSS&lt;/a&gt; but
&lt;a class="reference external" href="https://www.gnu.org/software/m4/"&gt;GNU m4&lt;/a&gt; provides basically the same thing and has been there for over a decade,
furthermore it is available on all platforms. If you ever compiled a program
there is a good chance you have already used &lt;a class="reference external" href="https://www.gnu.org/software/m4/"&gt;GNU m4&lt;/a&gt; without even knowing it
so it is likely you already have it on your machine, so nothing more to install
:)&lt;/p&gt;
&lt;p&gt;Here if how you can use &lt;a class="reference external" href="https://www.gnu.org/software/m4/"&gt;GNU m4&lt;/a&gt; with your CSS:&lt;/p&gt;
&lt;p&gt;testm4.css.m4 :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
include(`/tmp/csscolors.m4')dnl
define(`GLOBAL_WIDTH', `600')dnl
define(`LESS_LARGE', `200')dnl
dnl
.text_red {
    color: COLOR_RED;
}
.text_white {
    color: COLOR_WHITE;
}
.text_black {
    color: COLOR_BLACK;
}
.text_green {
    color: COLOR_GREEN;
}
.text_yellow {
    color: COLOR_YELLOW;
}
.text_blue {
    color: COLOR_BLUE;
}

#div1 {
    /* '()' are required. m4 will not expand the macro otherwise */
    width: GLOBAL_WIDTH()px;
    border: 1px solid COLOR_RED;
}

#div2 {
    width: eval(GLOBAL_WIDTH - LESS_LARGE)px;
    border: 1px dotted COLOR_BLUE;
}
&lt;/pre&gt;
&lt;p&gt;csscolors.m4 :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
define(`COLOR_WHITE', `#FFFFF')dnl
define(`COLOR_BLACK', `#00000')dnl
define(`COLOR_RED', `#FF0000')dnl
define(`COLOR_GREEN', `#00CC00')dnl
define(`COLOR_YELLOW', `#FFFF00')dnl
define(`COLOR_BLUE', `#0000FF')dnl
&lt;/pre&gt;
&lt;p&gt;testm4.html :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;link rel='stylesheet' href='testm4.css' type='text/css' media='all' /&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;span class=&amp;quot;text_red&amp;quot;&amp;gt;a&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;text_white&amp;quot;&amp;gt;b&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;text_black&amp;quot;&amp;gt;c&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;text_green&amp;quot;&amp;gt;d&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;text_yellow&amp;quot;&amp;gt;e&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;text_blue&amp;quot;&amp;gt;f&amp;lt;/span&amp;gt;
        &amp;lt;div id=&amp;quot;div1&amp;quot;&amp;gt;FOO&amp;lt;/div&amp;gt;
        &amp;lt;div id=&amp;quot;div2&amp;quot;&amp;gt;BAR&amp;lt;/div&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Then you can build the final CSS file by running :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
m4 testm4.css.m4 &amp;gt; testm4.css
&lt;/pre&gt;
&lt;p&gt;Done :)&lt;/p&gt;
</summary></entry><entry><title>Apache not considered harmful</title><link href="http://jrenard.info/blog/apache-not-considered-harmful.html" rel="alternate"></link><updated>2011-11-30T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-11-30:/blog/apache-not-considered-harmful.html/</id><summary type="html">&lt;p&gt;There has been a bit of fuss recently about the (non) Git support at the ASF.&lt;/p&gt;
&lt;p&gt;The ASF would be harmful because there is no Git support, but GitHub would be
the new place to be right now. Really ?&lt;/p&gt;
&lt;p&gt;Here is what the ASF does:&lt;/p&gt;
&lt;blockquote&gt;
The Apache Software Foundation provides organizational, &lt;strong&gt;legal, and
financial support&lt;/strong&gt; for a broad range of open source software projects.
The Foundation provides an &lt;strong&gt;established framework for intellectual property
and financial contributions that simultaneously limits contributors
potential legal exposure&lt;/strong&gt;. Through a collaborative and meritocratic
development process, Apache projects deliver enterprise-grade, freely
available software products that attract large communities of users.
The pragmatic Apache License makes it easy for all users, commercial
and individual, to deploy Apache products.&lt;/blockquote&gt;
&lt;p&gt;To rephrase the statement above the ASF is about providing a framework so it is
&lt;strong&gt;safe&lt;/strong&gt; for developers to contribute to any project with &lt;strong&gt;no legal exposure&lt;/strong&gt;.
Where can I find a statement like this on GitHub ?&lt;/p&gt;
&lt;p&gt;In my opinion the legal part of a project is extremely important as copyright
issues can be a pain when you have to deal with them because some companies
tend to think innovation as the amount of million dollars you can pay lawyers...&lt;/p&gt;
&lt;p&gt;If I work on my small project nobody heard of and I get a minor pull request on
Github I will accept it as the legal exposure is limited regarding IP
(Intellectual Property).&lt;/p&gt;
&lt;p&gt;If I work at a company, contributing to an open source project by providing
patches then I should be asked to sign a CLA when I explicitly accept to
transfer the copyright ownership to the ASF (or the entity hosting the
project). This is what the ASF is about.&lt;/p&gt;
&lt;p&gt;Yes there is (at the moment) no Git support at the ASF and yes it is sad and yes
I hope the ASF will provide Git support (or any VCS that provides cheap
branches) soon but that does not mean GitHub is the place to be for your open
source project. GitHub is just a code repository providing Git support, that's
what they do for a living and they do it really well, but GitHub will not
protect you from any potential legal issue regarding IP.&lt;/p&gt;
&lt;p&gt;Summary of what is provided at GitHub and the ASF:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="7%" /&gt;
&lt;col width="23%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="13%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="12%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;Entity&lt;/th&gt;
&lt;th class="head"&gt;VCS&lt;/th&gt;
&lt;th class="head"&gt;Issue tracker&lt;/th&gt;
&lt;th class="head"&gt;Wiki&lt;/th&gt;
&lt;th class="head"&gt;Mailing-lists&lt;/th&gt;
&lt;th class="head"&gt;Mailing list archives&lt;/th&gt;
&lt;th class="head"&gt;Legal Support&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;GitHub&lt;/td&gt;
&lt;td&gt;Git and SVN&lt;/td&gt;
&lt;td&gt;Yes (kind of)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ASF&lt;/td&gt;
&lt;td&gt;SVN, git mirror at GitHub&lt;/td&gt;
&lt;td&gt;Yes, JIRA or Bugzilla&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Interesting links:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.mikealrogers.com/posts/apache-considered-harmful.html"&gt;Apache considered harmful&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.apache.org/licenses/icla.txt"&gt;Apache CLA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.apache.org/foundation/"&gt;Foundation project at Apache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/apache"&gt;ASF's GitHub mirror&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://theapacheway.com/"&gt;The Apache Way&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;a class="reference external" href="https://people.apache.org/~jvermillard/"&gt;Julien&lt;/a&gt; informed me that Git is
currently being tested for CouchDB, other projects might use it soon as
well. :)&lt;/blockquote&gt;
</summary><category term="apache"></category><category term="asf"></category><category term="git"></category><category term="github"></category><category term="IP"></category></entry><entry><title>A crawler in 10 minutes</title><link href="http://jrenard.info/blog/a-crawler-in-10-minutes.html" rel="alternate"></link><updated>2011-10-18T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-10-18:/blog/a-crawler-in-10-minutes.html/</id><summary type="html">&lt;div class="section" id="use-case"&gt;
&lt;h2&gt;Use case&lt;/h2&gt;
&lt;p&gt;You need to fetch a set of HTML webpages (no external resources like JS, CSS,
images etc) either for data analysis or for forcing pages to be cached in your
reverse proxy.&lt;/p&gt;
&lt;p&gt;(You also have much more interesting things to do so you do not want to spend
your life on that problem.)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="solution"&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;(Well this is one solution among others)&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Generate the list of URLs to crawl&lt;/li&gt;
&lt;li&gt;Crawl 30 URLs in parallel&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="tools"&gt;
&lt;h2&gt;Tools&lt;/h2&gt;
&lt;p&gt;You need the following tools:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;curl&lt;/li&gt;
&lt;li&gt;cat&lt;/li&gt;
&lt;li&gt;xargs&lt;/li&gt;
&lt;li&gt;make&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="putting-it-all-together"&gt;
&lt;h2&gt;Putting it all together&lt;/h2&gt;
&lt;p&gt;Let's store the list of URLs to crawl in a plain text &lt;cite&gt;urls.txt&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;Now we need to write the &amp;quot;crawler&amp;quot; &lt;cite&gt;crawl.sh&lt;/cite&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#! /bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; -n &lt;span class="s1"&gt;&amp;#39;.&amp;#39;&lt;/span&gt;
&lt;span class="c"&gt;# Force the page to be cached&lt;/span&gt;
&lt;span class="c"&gt;# We do not need to store the result&lt;/span&gt;
curl --silent --request GET -H &lt;span class="s2"&gt;&amp;quot;Accept-Encoding: gzip&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;|sed &lt;span class="s1"&gt;&amp;#39;s/&amp;amp;/\\&amp;amp;/g&amp;#39;&lt;/span&gt; &amp;gt; /dev/null
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let's make it usable and parallel now:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;PARALELL_REQUESTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30
&lt;span class="nv"&gt;SOURCE_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;url.txt

crawl:
    @echo &lt;span class="s2"&gt;&amp;quot;Crawling&amp;quot;&lt;/span&gt;
    @cat &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SOURCE_FILE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; | xargs -n1 -P&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PARALELL_REQUESTS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; ./crawl.sh
    @echo &lt;span class="s2"&gt;&amp;quot;Done&amp;quot;&lt;/span&gt;

clean:
    @rm -f &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SOURCE_FILE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now run &lt;cite&gt;make crawl&lt;/cite&gt; and you will get 30 pages fetched in parallel.&lt;/p&gt;
&lt;p&gt;The key is to use the &lt;cite&gt;-P&lt;/cite&gt; argument available in xargs. Here is what the
&lt;a class="reference external" href="http://unixhelp.ed.ac.uk/CGI/man-cgi?xargs"&gt;xargs documentation&lt;/a&gt; says:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
--max-procs=max-procs, -P max-procs
        Run up to max-procs processes at a time; the default is  1.   If
        max-procs is 0, xargs will run as many processes as possible at
        a time.  Use the -n option with -P; otherwise chances  are  that
        only one exec will be done.
&lt;/pre&gt;
&lt;p&gt;Now you can spend your time on something more interesting like &lt;a class="reference external" href="https://github.com/simpl/ngx_devel_kit"&gt;Nginx Developement
Kit&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="crawler"></category></entry><entry><title>A better pager</title><link href="http://jrenard.info/blog/a-better-pager.html" rel="alternate"></link><updated>2011-08-12T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-08-12:/blog/a-better-pager.html/</id><summary type="html">&lt;p&gt;I was looking for an alternative to &lt;a class="reference external" href="http://unixhelp.ed.ac.uk/CGI/man-cgi?less"&gt;less&lt;/a&gt; and I found a pager called &lt;a class="reference external" href="http://www.jedsoft.org/most/"&gt;most&lt;/a&gt;
which provides interesting features and colors out of the box.&lt;/p&gt;
&lt;p&gt;Installing &lt;a class="reference external" href="http://www.jedsoft.org/most/"&gt;most&lt;/a&gt; is really trivial :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo apt-get|port|whatever install most
export PAGER=most
&lt;/pre&gt;
&lt;p&gt;And try it with :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
man ls
&lt;/pre&gt;
&lt;p&gt;You should see a colorized man page :)&lt;/p&gt;
</summary><category term="linux"></category></entry><entry><title>How to boot on the 64-bit version of the Mac Os X kernel</title><link href="http://jrenard.info/blog/how-to-boot-on-the-64-bit-version-of-the-mac-os-x-kernel.html" rel="alternate"></link><updated>2011-08-06T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-08-06:/blog/how-to-boot-on-the-64-bit-version-of-the-mac-os-x-kernel.html/</id><summary type="html">&lt;div class="section" id="warning"&gt;
&lt;h2&gt;Warning&lt;/h2&gt;
&lt;p&gt;What is explained below has been tested successfully on Mac Os X 10.6 (Snow
Leopard). If you are a Lion user, you decide to use this tip at your own risk.
I am not sure it is even needed as Lion normally provides 64bits support &lt;strong&gt;only&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="method"&gt;
&lt;h2&gt;Method&lt;/h2&gt;
&lt;p&gt;The method is the following :&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Open &lt;cite&gt;/Library/Preferences/SystemConfiguration/com.apple.Boot.plist&lt;/cite&gt;&lt;/li&gt;
&lt;li&gt;Use the following contents:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE plist PUBLIC &amp;quot;-//Apple Computer//DTD PLIST 1.0//EN&amp;quot; &amp;quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;plist&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;Kernel&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;mach_kernel&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;Kernel Flags&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;arch=x86_64&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Reboot the system.&lt;/p&gt;
&lt;p&gt;In order to verify that the change has been applied, open a Terminal and run the
following command:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
uname -a
&lt;/pre&gt;
&lt;p&gt;You should get something like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Darwin [...] root:xnu-1504.15.3~1/RELEASE_X86_64 x86_64
&lt;/pre&gt;
&lt;/div&gt;
</summary></entry><entry><title>Back from Denmark</title><link href="http://jrenard.info/blog/back-from-denmark.html" rel="alternate"></link><updated>2011-07-07T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-07-07:/blog/back-from-denmark.html/</id><summary type="html">&lt;div class="section" id="what-to-see"&gt;
&lt;h2&gt;What to see ?&lt;/h2&gt;
&lt;div class="section" id="legoland"&gt;
&lt;h3&gt;Legoland&lt;/h3&gt;
&lt;iframe width="640" height="480" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.fr/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Billund,+Denmark&amp;amp;aq=0&amp;amp;sll=46.75984,1.738281&amp;amp;sspn=8.160098,23.269043&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Billund,+Denmark&amp;amp;ll=55.728463,9.112387&amp;amp;spn=0.0232,0.054932&amp;amp;z=14&amp;amp;output=embed"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;small&gt;&lt;a href="http://maps.google.fr/maps?f=q&amp;amp;source=embed&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Billund,+Denmark&amp;amp;aq=0&amp;amp;sll=46.75984,1.738281&amp;amp;sspn=8.160098,23.269043&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Billund,+Denmark&amp;amp;ll=55.728463,9.112387&amp;amp;spn=0.0232,0.054932&amp;amp;z=14" style="color:#0000FF;text-align:left"&gt;View Larger Map&lt;/a&gt;&lt;/small&gt;&lt;p&gt;This is a must see! You can have a look at the
&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/sets/72157627137132236/"&gt;pictures&lt;/a&gt; I took there
so you can have an idea of what you will see. If you are a fan of Star Wars you
will not resist to what you will see:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911293455/in/set-72157627137132236"&gt;&lt;img alt="R2D2" src="http://farm6.static.flickr.com/5072/5911293455_c317541662.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911293791/in/set-72157627137132236"&gt;&lt;img alt="milleniumfalcon" src="http://farm7.static.flickr.com/6034/5911293791_2a05ff9e14.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911296395/in/set-72157627137132236"&gt;&lt;img alt="jediknight" src="http://farm7.static.flickr.com/6002/5911296395_700232dabc.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911848578/in/set-72157627137132236"&gt;&lt;img alt="imperialshuttle" src="http://farm7.static.flickr.com/6002/5911848578_2d7a06c7d1.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911287691/in/set-72157627137132236"&gt;&lt;img alt="imperialrobot" src="http://farm7.static.flickr.com/6007/5911287691_555d1cb03d.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You should also go to the &lt;a class="reference external" href="http://www.legoland.dk/en/Explore/Activities/Pirate-Land/Pirate-Splash-Battle/"&gt;pirate splash battle&lt;/a&gt; where you have to attack visitors
(also know as enemies during the time of the ride) with a water gun.&lt;/p&gt;
&lt;p&gt;When you see the warning &amp;quot;you will get wet&amp;quot; at the beginning of the waiting queue
you should understand &amp;quot;you will get soaked&amp;quot;!&lt;/p&gt;
&lt;p&gt;I do not remember how much I paid for a ticket but you can order them online so you
do not wait at the entrance of the park. I highly recommend you to buy tickets
in advance. You will also have to pay 50 DKK (If I remember correctly) for the park.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="mariager"&gt;
&lt;h3&gt;Mariager&lt;/h3&gt;
&lt;iframe width="640" height="480" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.fr/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Mariager,+Denmark&amp;amp;aq=0&amp;amp;sll=46.75984,1.738281&amp;amp;sspn=8.160098,23.269043&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Mariager,+Denmark&amp;amp;ll=56.650187,9.975586&amp;amp;spn=2.899473,7.03125&amp;amp;z=7&amp;amp;iwloc=A&amp;amp;output=embed"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;small&gt;&lt;a href="http://maps.google.fr/maps?f=q&amp;amp;source=embed&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Mariager,+Denmark&amp;amp;aq=0&amp;amp;sll=46.75984,1.738281&amp;amp;sspn=8.160098,23.269043&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Mariager,+Denmark&amp;amp;ll=56.650187,9.975586&amp;amp;spn=2.899473,7.03125&amp;amp;z=7&amp;amp;iwloc=A" style="color:#0000FF;text-align:left"&gt;View Larger Map&lt;/a&gt;&lt;/small&gt;&lt;p&gt;Mariager is a small picturesque town. Just go down town an enjoy your time here
by walking in the streets and admiring houses and the view on the Fjörd.&lt;/p&gt;
&lt;p&gt;Do not forget to stop by the ice cream shop where they proudly prepare ice
creams traditionally.&lt;/p&gt;
&lt;p&gt;Here is a couple of pictures :&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5912161048/in/set-72157627137955844"&gt;&lt;img alt="mariager1" src="http://farm7.static.flickr.com/6030/5912161048_6f1c505d5d.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911601241/in/set-72157627137955844"&gt;&lt;img alt="mariager2" src="http://farm7.static.flickr.com/6057/5911601241_15e3828c1a.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911604273/in/set-72157627137955844"&gt;&lt;img alt="mariager3" src="http://farm6.static.flickr.com/5234/5911604273_13983667d5.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="skagen"&gt;
&lt;h3&gt;Skagen&lt;/h3&gt;
&lt;iframe width="640" height="480" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.fr/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Skagen,+Denmark&amp;amp;aq=&amp;amp;sll=56.644147,9.986572&amp;amp;sspn=3.274638,11.634521&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Skagen,+Denmark&amp;amp;ll=57.724686,10.579834&amp;amp;spn=0.351995,0.878906&amp;amp;z=10&amp;amp;iwloc=A&amp;amp;output=embed"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;small&gt;&lt;a href="http://maps.google.fr/maps?f=q&amp;amp;source=embed&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Skagen,+Denmark&amp;amp;aq=&amp;amp;sll=56.644147,9.986572&amp;amp;sspn=3.274638,11.634521&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Skagen,+Denmark&amp;amp;ll=57.724686,10.579834&amp;amp;spn=0.351995,0.878906&amp;amp;z=10&amp;amp;iwloc=A" style="color:#0000FF;text-align:left"&gt;View Larger Map&lt;/a&gt;&lt;/small&gt;&lt;p&gt;Skagen is at the very north of Denmark, there is not that much to see there but
you can go to the very end of the beach so you can say &amp;quot;I did it, I am at the
very north of Denmark&amp;quot;. You can go downtown Skagen and get lunch at a restaurant
on the port, the food is quite good, though a bit expensive.&lt;/p&gt;
&lt;p&gt;Here is a couple of pictures :&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5913406574/in/set-72157627016261547"&gt;&lt;img alt="skagen1" src="http://farm7.static.flickr.com/6047/5913406574_311c8bcd7e.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5912845391/in/set-72157627016261547/"&gt;&lt;img alt="skagen2" src="http://farm6.static.flickr.com/5036/5912845391_9fa6a07d9e.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5912844247/in/set-72157627016261547/"&gt;&lt;img alt="skagen3" src="http://farm7.static.flickr.com/6057/5912844247_14485c1a04.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="frederiksborg"&gt;
&lt;h3&gt;Frederiksborg&lt;/h3&gt;
&lt;p&gt;Frederiksborg (Frederic's castle) is located in Hillerød.&lt;/p&gt;
&lt;iframe width="640" height="480" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.fr/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Frederiksborg+Palace,+Denmark&amp;amp;aq=0&amp;amp;sll=57.724686,10.579834&amp;amp;sspn=0.397461,1.454315&amp;amp;ie=UTF8&amp;amp;hq=Frederiksborg+Palace,+Denmark&amp;amp;hnear=&amp;amp;radius=15000&amp;amp;cid=528785308459695072&amp;amp;ll=55.932279,12.299194&amp;amp;spn=0.738515,1.757813&amp;amp;z=9&amp;amp;iwloc=A&amp;amp;output=embed"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;small&gt;&lt;a href="http://maps.google.fr/maps?f=q&amp;amp;source=embed&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Frederiksborg+Palace,+Denmark&amp;amp;aq=0&amp;amp;sll=57.724686,10.579834&amp;amp;sspn=0.397461,1.454315&amp;amp;ie=UTF8&amp;amp;hq=Frederiksborg+Palace,+Denmark&amp;amp;hnear=&amp;amp;radius=15000&amp;amp;cid=528785308459695072&amp;amp;ll=55.932279,12.299194&amp;amp;spn=0.738515,1.757813&amp;amp;z=9&amp;amp;iwloc=A" style="color:#0000FF;text-align:left"&gt;View Larger Map&lt;/a&gt;&lt;/small&gt;&lt;p&gt;Frederiksborg is to Denmark what Versailles is to France, you should definitely
visit it! Note that if you go there with a pushchair for your baby you will have
to use one the provide in the castle. Once done with the visit there is not that
much to see around but I recommend you to get a bagel downtown as they are
excellent and you get a 10% discount if you order food to take away :)&lt;/p&gt;
&lt;p&gt;Here is a couple of pictures :&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911250843/in/set-72157627012443481"&gt;&lt;img alt="frederiksborg1" src="http://farm7.static.flickr.com/6015/5911250843_58666f2dfa.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911812308/in/set-72157627012443481"&gt;&lt;img alt="frederiksborg2" src="http://farm7.static.flickr.com/6016/5911812308_bee990cb6f.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911807888/in/set-72157627012443481"&gt;&lt;img alt="frederiksborg3" src="http://farm7.static.flickr.com/6056/5911807888_77248ebe80.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="copenhagen"&gt;
&lt;h3&gt;Copenhagen&lt;/h3&gt;
&lt;iframe width="640" height="480" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.fr/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Copenhagen,+Denmark&amp;amp;aq=0&amp;amp;sll=55.996845,12.299194&amp;amp;sspn=0.832518,2.90863&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Copenhagen,+Denmark&amp;amp;ll=55.693455,12.583122&amp;amp;spn=0.092882,0.219727&amp;amp;z=12&amp;amp;iwloc=A&amp;amp;output=embed"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;small&gt;&lt;a href="http://maps.google.fr/maps?f=q&amp;amp;source=embed&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Copenhagen,+Denmark&amp;amp;aq=0&amp;amp;sll=55.996845,12.299194&amp;amp;sspn=0.832518,2.90863&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Copenhagen,+Denmark&amp;amp;ll=55.693455,12.583122&amp;amp;spn=0.092882,0.219727&amp;amp;z=12&amp;amp;iwloc=A" style="color:#0000FF;text-align:left"&gt;View Larger Map&lt;/a&gt;&lt;/small&gt;&lt;p&gt;I do not have much to say about Copenhangen since I visited it really quickly
by walk and with the kids so I did not see half of what I wanted to see. What I
would recommend is to spend a couple of days there, 3 would be OK I guess, and
rent a bike. That way you can go anywhere you want really quickly. Parks are
insanely expensive. It is best if you can avoid using a pushchair. You can rent
bikes with two seats for children.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911790496/in/set-72157627012413565"&gt;&lt;img alt="copenhagen1" src="http://farm6.static.flickr.com/5240/5911790496_bdd22099be.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911236385/in/set-72157627012413565"&gt;&lt;img alt="copenhagen2" src="http://farm7.static.flickr.com/6010/5911236385_ba6c15a1f0.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5911237311/in/set-72157627012413565"&gt;&lt;img alt="copenhagen3" src="http://farm7.static.flickr.com/6030/5911237311_af19d6123d.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="roskilde"&gt;
&lt;h3&gt;Roskilde&lt;/h3&gt;
&lt;iframe width="640" height="480" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.fr/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Roskilde,+Denmark&amp;amp;aq=0&amp;amp;sll=46.75984,1.738281&amp;amp;sspn=8.160098,23.269043&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Roskilde,+Denmark&amp;amp;ll=55.641949,12.087708&amp;amp;spn=0.186008,0.439453&amp;amp;z=11&amp;amp;iwloc=A&amp;amp;output=embed"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;small&gt;&lt;a href="http://maps.google.fr/maps?f=q&amp;amp;source=embed&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Roskilde,+Denmark&amp;amp;aq=0&amp;amp;sll=46.75984,1.738281&amp;amp;sspn=8.160098,23.269043&amp;amp;ie=UTF8&amp;amp;hq=&amp;amp;hnear=Roskilde,+Denmark&amp;amp;ll=55.641949,12.087708&amp;amp;spn=0.186008,0.439453&amp;amp;z=11&amp;amp;iwloc=A" style="color:#0000FF;text-align:left"&gt;View Larger Map&lt;/a&gt;&lt;/small&gt;&lt;p&gt;Around 40 kms from Copenhagen. This is a very pleasant town where you can stay
for a couple of days. I slept at &lt;a class="reference external" href="http://www.roskildecamping.dana2.dk/"&gt;Roskilde camping&lt;/a&gt; and I was really happy by the
quality and the price. If you decide to stay there you can get the following
view on the Fjörd :&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5913421944/in/set-72157627140853582/"&gt;&lt;img alt="campingview1" src="http://farm6.static.flickr.com/5311/5913421944_0a3a6684b3.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5912860035/in/set-72157627140853582"&gt;&lt;img alt="campingview2" src="http://farm7.static.flickr.com/6025/5912860035_dc63a34b67.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When staying at Roskilde I highly recommend you visit the viking museum. You can
see a couple of pictures I took there:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/sets/72157627138033098/"&gt;http://www.flickr.com/photos/qwix/sets/72157627138033098/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is only when you discover how vikings lived and built their drakkars that
you realize how smart they were.&lt;/p&gt;
&lt;p&gt;Once you stay here you can go to Copenhagen by car in around 40 minutes (mind
the traffic jam at around 9am !).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="food"&gt;
&lt;h2&gt;Food&lt;/h2&gt;
&lt;p&gt;In general food in Denmark is acceptable as long as you avoid eating at fast
foods you will see everywhere. There you can get some very fat and
poor quality food like hot dogs and french fries for almost nothing.&lt;/p&gt;
&lt;p&gt;Danish people have a lot of different breads and they are all excellent. If you
like fish you should definitely try herring which is prepared in different
flavors, and of course salmon which tastes as good as herring. Cheese is good as
well, there is quite a lot of different cheeses available I recommend you try
all of them.&lt;/p&gt;
&lt;p&gt;Do not bother trying (unless you &lt;strong&gt;really&lt;/strong&gt; want to experiment) pastry, it is
ugly. There is way too much sugar or cinnamon. You can try an ice cream with
soft ice and you favorite toping but do not take too much ice creams during your
trip unless you want to quickly see your blood turn into syrup. As an example,
here is what you can buy :&lt;/p&gt;
&lt;p&gt;For 40 DKK:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5912204988/in/set-72157627138033098"&gt;&lt;img alt="havnevaffel" src="http://farm7.static.flickr.com/6027/5912204988_d0700d77df.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Or a Grand Danois for 200 DKK, only if you are brave enough:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5912205420/in/set-72157627138033098"&gt;&lt;img alt="granddanois" src="http://farm7.static.flickr.com/6018/5912205420_76570d8939.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You should definitely buy strawberries, you can buy some anywhere you want on
the road as shown here &lt;a class="reference external" href="http://www.flickr.com/photos/qwix/5912852371/in/photostream"&gt;http://www.flickr.com/photos/qwix/5912852371/in/photostream&lt;/a&gt;.
You do not have to ask someone to buy them, just put 20 DKK (in average) in the
box and take some strawberries.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="people"&gt;
&lt;h2&gt;People&lt;/h2&gt;
&lt;p&gt;People in Denmark are really nice though a bit shy (at least this is the
impression I had) they speak a very good English but it is better if you speak
some basic German. I met people (especially in the north of Denmark) who
were much more comfortable with German and were only able to speak a couple of
words in English. When you are in Copenhagen you can ask anything you want in
English without any problem.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="money"&gt;
&lt;h2&gt;Money&lt;/h2&gt;
&lt;p&gt;Money used in Denmark is the Danish Crown. Overall, this country is not really
expensive. Since the country is not in the Eurozone you should ask your bank
how much you will be charged for each withdrawal and each payment with your
credit card. If you need to change money during your trip do it &lt;strong&gt;only&lt;/strong&gt; at
banks as they seem to have the lowest rates.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="oil"&gt;
&lt;h2&gt;Oil&lt;/h2&gt;
&lt;p&gt;If you have an LPG (car gas) car do not bother buying an adaptor (if you need to)
for danish pumps I found no station where I could get LPG and I drove around
2000 kms in the country so I saw a lot of oil stations ...&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="renting-a-house"&gt;
&lt;h2&gt;Renting a house&lt;/h2&gt;
&lt;p&gt;I rented a house at &lt;a class="reference external" href="http://www.sologstrand.com/"&gt;Sol Og Strand&lt;/a&gt; as was very happy with ther services. You
can find a lot of houses almost everywhere in Denmakr for acceptable prices. As
an example, I rented a 80 m2 house for a week for around 500 Euros which is
really cheap.&lt;/p&gt;
&lt;/div&gt;
</summary></entry><entry><title>Living without google search</title><link href="http://jrenard.info/blog/living-without-google-search.html" rel="alternate"></link><updated>2011-06-13T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-06-13:/blog/living-without-google-search.html/</id><summary type="html">&lt;div class="section" id="introduction"&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;About a month ago I tried to experiment something different for searching on the
Internet. I have always used google and was pretty happy with the search results
but in my opinion Google is way too hegemonic (evil ?) and I do not like this.
So I decided to try something else.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-did-i-used"&gt;
&lt;h2&gt;What did I used ?&lt;/h2&gt;
&lt;p&gt;Well this is quite simple, I have been using &lt;a class="reference external" href="http://ecosia.org/"&gt;Ecosia&lt;/a&gt; for one month and the
experience is quite interesting. Search results come from &lt;a class="reference external" href="http://bing.com"&gt;Bing&lt;/a&gt; and &lt;a class="reference external" href="http://yahoo.com"&gt;Yahoo&lt;/a&gt;
and the relevance of returned results is good. I also tried &lt;a class="reference external" href="http://duckduckgo.com/"&gt;Duck Duck Go&lt;/a&gt; but
the search results between &lt;a class="reference external" href="http://ecosia.org/"&gt;Ecosia&lt;/a&gt; and &lt;a class="reference external" href="http://duckduckgo.com/"&gt;Duck Duck Go&lt;/a&gt; are pretty much the
same so I decided to stay with &lt;a class="reference external" href="http://ecosia.org/"&gt;Ecosia&lt;/a&gt;. For more &amp;quot;specialized&amp;quot; searches I use
Firefox' search modules for sites I use every day, like the search module for
&lt;a class="reference external" href="http://stackoverflow.com/"&gt;Stack Overflow&lt;/a&gt; or the &lt;a class="reference external" href="http://python.org"&gt;Python&lt;/a&gt; documentation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-s-next"&gt;
&lt;h2&gt;What's next ?&lt;/h2&gt;
&lt;p&gt;Now that I can live google search free I decided to live Gmail free. I did not
try any alternative yet, I think I will seriously look for an alternative once I am
back from vacations. However, if you have any recommendation I would be happy to
here from you :)&lt;/p&gt;
&lt;/div&gt;
</summary></entry><entry><title>How to backup your Solr / Lucene index</title><link href="http://jrenard.info/blog/how-to-backup-your-solr-lucene-index.html" rel="alternate"></link><updated>2011-05-04T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-05-04:/blog/how-to-backup-your-solr-lucene-index.html/</id><summary type="html">&lt;div class="section" id="replication"&gt;
&lt;h2&gt;Replication&lt;/h2&gt;
&lt;p&gt;You can set up a replication system as described in the following page:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://wiki.apache.org/solr/SolrReplication"&gt;http://wiki.apache.org/solr/SolrReplication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What I appreciate about that system is the master is totally unaware of slaves
so you can add as many slaves as you want transparently. But pay attention to
performances when adding too much slaves as they will continously poll the
master.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="simple-copy"&gt;
&lt;h2&gt;Simple copy&lt;/h2&gt;
&lt;p&gt;Solr already provides shell scripts for backup operations:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://wiki.apache.org/solr/SolrOperationsTools#backup"&gt;backup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://wiki.apache.org/solr/SolrOperationsTools#backupcleaner"&gt;backupcleaner&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a class="reference external" href="http://wiki.apache.org/solr/SolrOperationsTools#backup"&gt;backup&lt;/a&gt; will create backups which name is the timestamp of when the backup was
done. As you can imagine you can get a lot of backups, depending on the
frequency you defined, you need a system to clean very old backups. This is what
&lt;a class="reference external" href="http://wiki.apache.org/solr/SolrOperationsTools#backupcleaner"&gt;backupcleaner&lt;/a&gt; is made for. It will remove backups older that X days.&lt;/p&gt;
&lt;p&gt;Those script (as well as others) are available here :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://svn.apache.org/repos/asf/lucene/dev/trunk/solr/src/scripts/"&gt;https://svn.apache.org/repos/asf/lucene/dev/trunk/solr/src/scripts/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The problem with the &lt;a class="reference external" href="http://wiki.apache.org/solr/SolrOperationsTools#backup"&gt;backup&lt;/a&gt; script is that the backup will be local, if you
want to get a distant backup you can use rsync and simply copy the index on
another machine. As a Solr index is just a pile of files is it trivial to rsync
them from a machine to another one.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="dumping-the-index-to-a-file"&gt;
&lt;h2&gt;Dumping the index to a file&lt;/h2&gt;
&lt;p&gt;This is equivalent to dumping a database. This can be useful for backups but
also as a reference to know exactly what is available in your index or not,
especially during development phases. In order to export the index to a file you
need &lt;a class="reference external" href="https://code.google.com/p/luke/"&gt;Luke&lt;/a&gt; :&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;a class="reference external" href="https://code.google.com/p/luke/downloads/list"&gt;download&lt;/a&gt; the lastest version
(&lt;a class="reference external" href="https://code.google.com/p/luke/downloads/detail?name=lukeall-3.1.0.jar&amp;amp;can=2&amp;amp;q="&gt;3.1.0&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;run&lt;/p&gt;
&lt;pre class="literal-block"&gt;
java -cp lukeall-3.1.0.jar org.getopt.luke.XMLExporter /path/to/index /path/to/output.xml -gzip
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After a moment (depending of course of the size of your index) you will get an
XML file with the content of your index.&lt;/p&gt;
&lt;p&gt;If you want to export ranges of documents, &lt;cite&gt;XMLExporter&lt;/cite&gt; supports the &lt;cite&gt;-range
X-Y&lt;/cite&gt; syntax, that means that using &lt;cite&gt;-range 0-100&lt;/cite&gt; will only export 100
documents.&lt;/p&gt;
&lt;p&gt;Run &lt;cite&gt;java -cp lukeall-3.1.0.jar org.getopt.luke.XMLExporter&lt;/cite&gt; to get help.&lt;/p&gt;
&lt;p&gt;:)&lt;/p&gt;
&lt;/div&gt;
</summary></entry><entry><title>A better cp with pv</title><link href="http://jrenard.info/blog/a-better-cp-with-pv.html" rel="alternate"></link><updated>2011-03-23T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-03-23:/blog/a-better-cp-with-pv.html/</id><summary type="html">&lt;p&gt;If you copy large files and hate not to know when the copy
is going to be finished then this post will interest you.&lt;/p&gt;
&lt;p&gt;Here is what you can do to fix that problem:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;install &lt;a class="reference external" href="http://www.ivarch.com/programs/pv.shtml"&gt;pv&lt;/a&gt; (&lt;cite&gt;yum|port|apt-get install pv&lt;/cite&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;add the following function to you &lt;cite&gt;~/.zsh|bash|*rc&lt;/cite&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;function &lt;/span&gt;pvcp&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;SOURCE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -d &lt;span class="nv"&gt;$2&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="k"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;DESTINATION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;/&lt;span class="sb"&gt;`&lt;/span&gt;basename &lt;span class="nv"&gt;$SOURCE&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="k"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;DESTINATION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="k"&gt;    &lt;/span&gt;pv &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SOURCE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; | &amp;gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DESTINATION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;cite&gt;source ~/.zsh|bash|*rc&lt;/cite&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can now do:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pvcp &amp;lt;source&amp;gt; &amp;lt;destination&amp;gt;
&lt;/pre&gt;
&lt;p&gt;And here is an example of what you should get:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pvcp /path/to/foo.avo /path/to/destination/
702MB 0:01:27 [8.01MB/s] [===============[...]================&amp;gt;] 100%
&lt;/pre&gt;
&lt;p&gt;:)&lt;/p&gt;
</summary></entry><entry><title>Installing Reconnoiter on Debian Squeeze</title><link href="http://jrenard.info/blog/installing-reconnoiter-on-debian-squeeze.html" rel="alternate"></link><updated>2011-03-14T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-03-14:/blog/installing-reconnoiter-on-debian-squeeze.html/</id><summary type="html">&lt;p&gt;If you want to know more about &lt;a class="reference external" href="https://labs.omniti.com/labs/reconnoiter"&gt;Reconnoiter&lt;/a&gt;, watch this &lt;a class="reference external" href="http://omniti.com/video/noit-oscon-demo"&gt;demo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This how-to is based on &lt;a class="reference external" href="http://www.ducea.com/"&gt;Marius Ducea's&lt;/a&gt; article
&lt;a class="reference external" href="http://www.ducea.com/2010/07/13/howto-install-reconnoiter-on-debian-lenny/comment-page-1/"&gt;HowTo install reconnoiter on Debian Lenny&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="requirements"&gt;
&lt;h2&gt;Requirements&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="http://debian.org/"&gt;Debian&lt;/a&gt; as in :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;jerome@reconnoiter:~&lt;span class="nv"&gt;$ &lt;/span&gt;lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 6.0 &lt;span class="o"&gt;(&lt;/span&gt;squeeze&lt;span class="o"&gt;)&lt;/span&gt;
Release:    6.0
Codename:   squeeze
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;non-free packages (for &lt;a class="reference external" href="http://packages.debian.org/squeeze/sun-java6-jdk"&gt;sun-java6-jdk&lt;/a&gt;) in &lt;cite&gt;/etc/apt/sources.list&lt;/cite&gt; :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
deb http://your.favorite.debian.mirror/debian/ squeeze non-free
deb-src http://your.favorite.debian.mirror/debian/ squeeze non-free
&lt;/pre&gt;
&lt;p&gt;Do not forget to run &lt;cite&gt;sudo apt-get update&lt;/cite&gt; once &lt;cite&gt;sources.list&lt;/cite&gt; has been updated.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="installing-required-packages"&gt;
&lt;h2&gt;Installing required packages&lt;/h2&gt;
&lt;p&gt;The following packages are required:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo apt-get install autoconf build-essential zlib1g-dev uuid-dev &lt;span class="se"&gt;\&lt;/span&gt;
libpcre3-dev libssl-dev libpq-dev libxslt1-dev libapr1-dev &lt;span class="se"&gt;\&lt;/span&gt;
libaprutil1-dev xsltproc libncurses5-dev libssh2-1-dev &lt;span class="se"&gt;\&lt;/span&gt;
libsnmp-dev sun-java6-jdk subversion postgresql-8.4 &lt;span class="se"&gt;\&lt;/span&gt;
uuid-runtime apache2 libapache2-mod-php5 php5-pgsql &lt;span class="se"&gt;\&lt;/span&gt;
libcurl4-gnutls-dev
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="checking-out-and-compiling"&gt;
&lt;h2&gt;Checking out and compiling&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://labs.omniti.com/labs/reconnoiter"&gt;Reconnoiter&lt;/a&gt; must be built from code so let's use &lt;a class="reference external" href="https://labs.omniti.com/reconnoiter/trunk"&gt;trunk&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;
svn co https://labs.omniti.com/reconnoiter/trunk reconnoiter
&lt;span class="nb"&gt;cd &lt;/span&gt;reconnoiter
autoconf
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you can configure the project, you may use the default &lt;cite&gt;./configure&lt;/cite&gt; or
define an installation prefix by using the &lt;cite&gt;--prefix=/path/to/reconnoiter&lt;/cite&gt; for a
custom installation path. I used :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;./configure --prefix&lt;span class="o"&gt;=&lt;/span&gt;/opt/reconnoiter
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once it is configured you can start compiling, just run &lt;cite&gt;make&lt;/cite&gt;.
Before running &lt;cite&gt;make install&lt;/cite&gt; you need to prepare a directory which will contain
require java libraries :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo mkdir -p /path/to/prefix/java/lib/
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Or if you did not specify any prefix for &lt;cite&gt;./configure&lt;/cite&gt; just run&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo mkdir -p /usr/local/java/lib/
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once done, install the system by running &lt;cite&gt;make install&lt;/cite&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="preparing-postgresql"&gt;
&lt;h2&gt;Preparing Postgresql&lt;/h2&gt;
&lt;p&gt;In order to avoid any problem when running postgres operations, you have to
update the file &lt;cite&gt;/etc/postgresql/8.4/main/pg_hba.conf&lt;/cite&gt; on line 82. The line:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
local   all         all                               ident
&lt;/pre&gt;
&lt;p&gt;must become :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
local   all         all                               trust
&lt;/pre&gt;
&lt;p&gt;Or you can do it that way :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo sed -i &lt;span class="s2"&gt;&amp;quot;s/local   all         all                               ident/local   all         all                               trust/g&amp;quot;&lt;/span&gt; /etc/postgresql/8.4/main/pg_hba.conf
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And restart postgres:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo /etc/init.d/postgresql restart
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Switch to user &amp;quot;postgres&amp;quot; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo su postgres
&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/svn/trunk/of/reconnoiter/sql
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Open a postgres console:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;psql
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And import the DDL dump:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="se"&gt;\i&lt;/span&gt; ./sql/reconnoiter_ddl_dump.sql
&lt;span class="se"&gt;\q&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now return to your user's shell&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Go to  &lt;cite&gt;/path/to/svn/trunk/of/reconnoiter/sql&lt;/cite&gt; and run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# fixes hard coded path to postgres&lt;/span&gt;
sed -i &lt;span class="s1"&gt;&amp;#39;s/\/opt\/psql835/usr/g&amp;#39;&lt;/span&gt; crontab
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will fix a hard coded path to postgres.&lt;/p&gt;
&lt;p&gt;Now you can add the conjobs to the postgresql user:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo crontab -u postgres crontab
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can check it is OK by running :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo crontab -u postgres -l
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="preparing-ssl-certificates"&gt;
&lt;h2&gt;Preparing SSL certificates&lt;/h2&gt;
&lt;p&gt;Ideally you need real certificates but for my testing purposes I used the ones
that are available in the &lt;cite&gt;test/&lt;/cite&gt; directory. Just copy them to
&lt;cite&gt;reconnoiter/installation/path/etc&lt;/cite&gt;. If you did not configured any value for
&lt;cite&gt;--prefix&lt;/cite&gt; for &lt;cite&gt;./configure&lt;/cite&gt; then the following command should work :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/local/src/reconnoiter/test
cp &lt;span class="nb"&gt;test&lt;/span&gt;-*.crt &lt;span class="nb"&gt;test&lt;/span&gt;-*.key /usr/local/etc/
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order to get completely ready we need to create a couple of symlinks in the
&lt;cite&gt;etc/&lt;/cite&gt; directory. For example here is what I get in the end :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;lrwxrwxrwx 1 root root     11 Mar 14 09:40 ca.crt -&amp;gt; &lt;span class="nb"&gt;test&lt;/span&gt;-ca.crt
-rw-r--r-- 1 root root   3037 Mar 14 09:32 config_templates.conf
-rw-r--r-- 1 root root 237476 Mar 14 09:32 default-ca-chain.crt
-rw-r--r-- 1 root root   6806 Mar 14 10:40 noit.conf
lrwxrwxrwx 1 root root     13 Mar 14 09:38 noit.crt -&amp;gt; &lt;span class="nb"&gt;test&lt;/span&gt;-noit.crt
lrwxrwxrwx 1 root root     13 Mar 14 09:39 noit.key -&amp;gt; &lt;span class="nb"&gt;test&lt;/span&gt;-noit.key
-rw-r--r-- 1 root root   7111 Mar 14 09:45 stratcon.conf
lrwxrwxrwx 1 root root     17 Mar 14 09:41 stratcon.crt -&amp;gt; &lt;span class="nb"&gt;test&lt;/span&gt;-stratcon.crt
lrwxrwxrwx 1 root root     17 Mar 14 09:40 stratcon.key -&amp;gt; &lt;span class="nb"&gt;test&lt;/span&gt;-stratcon.key
-rw-r--r-- 1 root root    615 Mar 14 09:37 &lt;span class="nb"&gt;test&lt;/span&gt;-ca.crt
-rw-r--r-- 1 root root    493 Mar 14 09:37 &lt;span class="nb"&gt;test&lt;/span&gt;-ca.key
-rw-r--r-- 1 root root   2489 Mar 14 09:37 &lt;span class="nb"&gt;test&lt;/span&gt;-noit.crt
-rw-r--r-- 1 root root    497 Mar 14 09:37 &lt;span class="nb"&gt;test&lt;/span&gt;-noit.key
-rw-r--r-- 1 root root   2484 Mar 14 09:37 &lt;span class="nb"&gt;test&lt;/span&gt;-stratcon.crt
-rw-r--r-- 1 root root    497 Mar 14 09:37 &lt;span class="nb"&gt;test&lt;/span&gt;-stratcon.key
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I created the symlinks shown above because the paths to SSL configuration files
available in noit.conf and stratcon.conf are not prefixed by &lt;cite&gt;test-&lt;/cite&gt;. I believe
you can rename the files as well. This is really a matter of preference.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="preparing-configuration-files"&gt;
&lt;h2&gt;Preparing configuration files&lt;/h2&gt;
&lt;p&gt;In the &lt;a class="reference external" href="https://labs.omniti.com/labs/reconnoiter"&gt;Reconnoiter&lt;/a&gt;'s installation directory you will find &lt;cite&gt;noit.conf.sample&lt;/cite&gt; and
&lt;cite&gt;stratcon.conf.sample&lt;/cite&gt;. Rename them to &lt;cite&gt;noit.conf&lt;/cite&gt; and &lt;cite&gt;stratcon.conf&lt;/cite&gt;.&lt;/p&gt;
&lt;div class="section" id="noit-conf"&gt;
&lt;h3&gt;noit.conf&lt;/h3&gt;
&lt;p&gt;The default &lt;cite&gt;noit.conf&lt;/cite&gt; is ready to use so you should not need to update it
right now. You will be able to change it later if you want, either by update the
file directly or by using the CLI console (which I recommend you to use as it is
really efficient and simple to use).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="stratcon-conf"&gt;
&lt;h3&gt;stratcon.conf&lt;/h3&gt;
&lt;p&gt;The default &lt;cite&gt;stratcon.conf&lt;/cite&gt; needs the following change:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;dbconfig&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;host&amp;gt;&lt;/span&gt;localhost&lt;span class="nt"&gt;&amp;lt;/host&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dbname&amp;gt;&lt;/span&gt;reconnoiter&lt;span class="nt"&gt;&amp;lt;/dbname&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;user&amp;gt;&lt;/span&gt;stratcon&lt;span class="nt"&gt;&amp;lt;/user&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;password&amp;gt;&lt;/span&gt;unguessable&lt;span class="nt"&gt;&amp;lt;/password&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dbconfig&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;must become&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;dbconfig&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;host&amp;gt;&lt;/span&gt;localhost&lt;span class="nt"&gt;&amp;lt;/host&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dbname&amp;gt;&lt;/span&gt;reconnoiter&lt;span class="nt"&gt;&amp;lt;/dbname&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;user&amp;gt;&lt;/span&gt;stratcon&lt;span class="nt"&gt;&amp;lt;/user&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;password&amp;gt;&lt;/span&gt;stratcon&lt;span class="nt"&gt;&amp;lt;/password&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dbconfig&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The password is &amp;quot;stratcon&amp;quot; as defined &lt;a class="reference external" href="http://labs.omniti.com/labs/reconnoiter/browser/trunk/sql/scaffolding.sql#L3"&gt;by default&lt;/a&gt;
in the &lt;a class="reference external" href="http://labs.omniti.com/labs/reconnoiter/browser/trunk/sql/scaffolding.sql"&gt;DDL dump&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You also have to configure &lt;cite&gt;&amp;lt;hostname&amp;gt;&lt;/cite&gt; and &lt;cite&gt;&amp;lt;document_domain&amp;gt;&lt;/cite&gt; with appropriate
values. As an example here is what I have:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;config&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;hostname&amp;gt;&lt;/span&gt;localhost&lt;span class="nt"&gt;&amp;lt;/hostname&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;document_domain&amp;gt;&lt;/span&gt;localhost&lt;span class="nt"&gt;&amp;lt;/document_domain&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/config&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="starting-daemons"&gt;
&lt;h2&gt;Starting daemons&lt;/h2&gt;
&lt;p&gt;The &lt;cite&gt;noid&lt;/cite&gt; and &lt;cite&gt;stratcond&lt;/cite&gt; daemons must be run in the following order.&lt;/p&gt;
&lt;div class="section" id="noitd"&gt;
&lt;h3&gt;1. noitd&lt;/h3&gt;
&lt;p&gt;Start noitd in the foreground with debugging informations so you can spot any
error message easily.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo /path/to/reconnoiter/sbin/noitd -c /path/to/reconnoiter/etc/noit.conf
-d -D
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;cite&gt;-d&lt;/cite&gt; stands for &amp;quot;show debuggins informations&amp;quot; and &lt;cite&gt;-D&lt;/cite&gt; stands for &amp;quot;run in the
foreground&amp;quot;.&lt;/p&gt;
&lt;p&gt;If you did not use any &lt;cite&gt;--prefix&lt;/cite&gt; when running &lt;cite&gt;./configure&lt;/cite&gt; then the command
should be :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo /usr/local/sbin/noitd -c /usr/local/etc/noit.conf -d -D
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want to run noitd as a normal process, just remove the &lt;cite&gt;-d&lt;/cite&gt; and &lt;cite&gt;-D&lt;/cite&gt;
flags.&lt;/p&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;If you run &lt;cite&gt;ps aux | grep &amp;quot;noitd&amp;quot;&lt;/cite&gt; and notice two &lt;cite&gt;noitd&lt;/cite&gt; processes, this
is normal. This is because there is a management process for &lt;cite&gt;noitd&lt;/cite&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="stratcond"&gt;
&lt;h3&gt;2. stratcond&lt;/h3&gt;
&lt;p&gt;Start &lt;cite&gt;stratcond&lt;/cite&gt; in the foreground with debugging informations so you can spot any
error message easily.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo /path/to/reconnoiter/sbin/stratcond -c /path/to/reconnoiter/etc/stratcon.conf
-d -D
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you did not use any &lt;cite&gt;--prefix&lt;/cite&gt; when running &lt;cite&gt;./configure&lt;/cite&gt; then the command
should be :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo /usr/local/sbin/stratcond -c /usr/local/etc/stratcond.conf -d -D
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As for &lt;cite&gt;noid&lt;/cite&gt; remove the &lt;cite&gt;-d&lt;/cite&gt; and &lt;cite&gt;-D&lt;/cite&gt; flags to run &lt;cite&gt;stratcond&lt;/cite&gt; as a normal
process.&lt;/p&gt;
&lt;p&gt;Now &lt;cite&gt;noitd&lt;/cite&gt; and &lt;cite&gt;stratcond&lt;/cite&gt; are running you should see quite a lot of output and
everything should be OK. You can relaunch them, but in the background this time
if you want.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="installing-the-web-ui"&gt;
&lt;h2&gt;Installing the web UI&lt;/h2&gt;
&lt;p&gt;Well that could not be any simpler.&lt;/p&gt;
&lt;p&gt;Copy the &lt;a class="reference external" href="http://labs.omniti.com/labs/reconnoiter/browser/trunk/ui"&gt;ui&lt;/a&gt;
directory in &lt;cite&gt;/var/www/&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;Create the following VirtualHost, in &lt;cite&gt;/etc/apache2/sites-available/reconnoiter&lt;/cite&gt;
(adapt the path if needed) :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;VirtualHost&lt;/span&gt; &lt;span class="s"&gt;*:80&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;DocumentRoot&lt;/span&gt; &lt;span class="sx"&gt;/var/www/ui/web/htdocs&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;Directory&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nb"&gt;Options&lt;/span&gt; &lt;span class="k"&gt;None&lt;/span&gt;
        &lt;span class="nb"&gt;AllowOverride&lt;/span&gt; &lt;span class="k"&gt;None&lt;/span&gt;
        &lt;span class="nb"&gt;Order&lt;/span&gt; allow,deny
        &lt;span class="nb"&gt;Deny&lt;/span&gt; from &lt;span class="k"&gt;all&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Directory&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;FilesMatch&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;^\.ht&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nb"&gt;Order&lt;/span&gt; allow,deny
        &lt;span class="nb"&gt;Deny&lt;/span&gt; from &lt;span class="k"&gt;all&lt;/span&gt;
        &lt;span class="nb"&gt;Satisfy&lt;/span&gt; &lt;span class="k"&gt;All&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/FilesMatch&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Directory&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;/var/www/ui/web/htdocs/&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="err"&gt;php_&lt;/span&gt;&lt;span class="nb"&gt;value&lt;/span&gt; include_path &lt;span class="sx"&gt;/var/www/ui/web/lib&lt;/span&gt;
        &lt;span class="err"&gt;php_&lt;/span&gt;&lt;span class="nb"&gt;value&lt;/span&gt; short_open_tag &lt;span class="k"&gt;off&lt;/span&gt;
        &lt;span class="nb"&gt;Options&lt;/span&gt; FollowSymLinks Indexes
        &lt;span class="nb"&gt;AllowOverride&lt;/span&gt; &lt;span class="k"&gt;All&lt;/span&gt;
        &lt;span class="nb"&gt;Order&lt;/span&gt; deny,allow
        &lt;span class="nb"&gt;Allow&lt;/span&gt; from &lt;span class="k"&gt;all&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Directory&amp;gt;&lt;/span&gt;

    &lt;span class="nb"&gt;LogLevel&lt;/span&gt; &lt;span class="k"&gt;warn&lt;/span&gt;
    &lt;span class="nb"&gt;LogFormat&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;%h %l %u %t \&amp;quot;%r\&amp;quot; %&amp;gt;s %b&amp;quot;&lt;/span&gt; common

    &lt;span class="nb"&gt;ErrorLog&lt;/span&gt; &lt;span class="sx"&gt;/var/www/ui/web/logs/error_log&lt;/span&gt;
    &lt;span class="nb"&gt;CustomLog&lt;/span&gt; &lt;span class="sx"&gt;/var/www/ui/web/logs/access_log&lt;/span&gt; common

    &lt;span class="nb"&gt;AddType&lt;/span&gt; application/x-compress .Z
    &lt;span class="nb"&gt;AddType&lt;/span&gt; application/x-gzip .gz .tgz
    &lt;span class="nb"&gt;AddType&lt;/span&gt; application/x-httpd-php .php
    &lt;span class="nb"&gt;DefaultType&lt;/span&gt; text/plain

    &lt;span class="nb"&gt;RewriteEngine&lt;/span&gt; &lt;span class="k"&gt;On&lt;/span&gt;
    &lt;span class="nb"&gt;RewriteRule&lt;/span&gt; ^(/data/.+)$ http://localhost:80$1 [P,L,QSA]
&lt;span class="nt"&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Enable mod_rewrite and the &lt;cite&gt;reconnoiter&lt;/cite&gt; VHost&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sudo a2enmod rewrite
sudo a2ensite reconnoiter
sudo /etc/init.d/apache2 restart
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;Just disable the default VHost for the moment by running
&lt;cite&gt;sudo a2dissite default&lt;/cite&gt; and restart Apache.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;You should now get the &lt;a class="reference external" href="https://labs.omniti.com/labs/reconnoiter"&gt;Reconnoiter&lt;/a&gt;'s web UI. Click on the small '+' button on
the &amp;quot;worksheet control&amp;quot; line, you should see the &amp;quot;graph controls&amp;quot; panel open it
and click on the &amp;quot;browse data&amp;quot; tab. Hopefully you should get results, it is now
up to you to decide what you want to graph.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="troubleshooting"&gt;
&lt;h2&gt;Troubleshooting&lt;/h2&gt;
&lt;p&gt;If you get the following error :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
SSL read error: Input/output error
&lt;/pre&gt;
&lt;p&gt;There is a problem with your certificates, check the path are correct in
noit.conf and stratcon.conf. Maybe they are incorrect.&lt;/p&gt;
&lt;p&gt;Hope that helps :)&lt;/p&gt;
&lt;/div&gt;
</summary></entry><entry><title>Testing ESI without Varnish (or equivalent)</title><link href="http://jrenard.info/blog/testing-esi-without-varnish-or-equivalent.html" rel="alternate"></link><updated>2011-02-22T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-02-22:/blog/testing-esi-without-varnish-or-equivalent.html/</id><summary type="html">&lt;dl class="docutils"&gt;
&lt;dt&gt;Note :&lt;/dt&gt;
&lt;dd&gt;If you are new to ESI and want to know a bit more about it you can read
this previous blog post : &lt;a class="reference external" href="http://jrenard.info/blog/about-esi.html"&gt;About ESI&lt;/a&gt;&lt;/dd&gt;
&lt;/dl&gt;
&lt;div class="section" id="use-case"&gt;
&lt;h2&gt;Use case&lt;/h2&gt;
&lt;p&gt;You decided to implement a feature that will use ESI but you do not want to install Varnish
on your computer to avoid any cache during the development phase.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="solution"&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;To use a bit of JavaScript to simulate the ESI processing. This is possible by
using the &lt;a class="reference external" href="http://search.cpan.org/~jayk/"&gt;Jay Kuri's&lt;/a&gt; &lt;a class="reference external" href="http://www.catalystframework.org/calendar/static/2008/esi/ESI_Parser.tar.gz"&gt;ESI parser&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please not that only &lt;cite&gt;&amp;lt;esi:include&amp;gt;&lt;/cite&gt; and &lt;cite&gt;&amp;lt;esi:remove&amp;gt;&lt;/cite&gt; are supported.&lt;/p&gt;
&lt;p&gt;Using ESI parser is pretty straightforward:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;download the &lt;a class="reference external" href="http://www.catalystframework.org/calendar/static/2008/esi/ESI_Parser.tar.gz"&gt;tarball&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;extract it wherever you want in your project&lt;/li&gt;
&lt;li&gt;include &lt;cite&gt;esiparser.js&lt;/cite&gt;&lt;/li&gt;
&lt;li&gt;include the following code in the page(s) you want to process:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;do_esi_parsing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That should be it :)&lt;/p&gt;
&lt;/div&gt;
</summary><category term="varnish"></category></entry><entry><title>Setting up a Solr sandbox for spotting problems</title><link href="http://jrenard.info/blog/setting-up-a-solr-sandbox-for-spotting-problems.html" rel="alternate"></link><updated>2011-01-27T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-01-27:/blog/setting-up-a-solr-sandbox-for-spotting-problems.html/</id><summary type="html">&lt;div class="section" id="use-case"&gt;
&lt;h2&gt;Use case&lt;/h2&gt;
&lt;p&gt;You get problems with &lt;a class="reference external" href="http://lucene.apache.org/solr/"&gt;Apache Solr&lt;/a&gt; which sometimes does not return expected
results. That can be anything, but when you have a very large index and when
it takes a lot of time to (re)index data, spotting problems is very difficult
and frustrating.&lt;/p&gt;
&lt;p&gt;The methodology described below helped me a few times already so I thought I
could share it. Any enhancements are of course much welcome :)&lt;/p&gt;
&lt;p&gt;The method requires the following steps:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Creating a new &lt;a class="reference external" href="http://lucene.apache.org/solr/"&gt;Apache Solr&lt;/a&gt; sandbox&lt;/li&gt;
&lt;li&gt;Exporting data from your storage and import them in the sandbox&lt;/li&gt;
&lt;li&gt;Importing data and test anything you want&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Creating the sandbox&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You have to setup a sandbox where you can play with data safely. If you use a
separate index you can do anything you want for testing and debugging without
breaking anything in the real index.&lt;/p&gt;
&lt;p&gt;In order to setup that sandbox I created a very trivial Makefile available
below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;download extract&lt;/span&gt;

&lt;span class="nf"&gt;download&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    wget http://mir2.ovh.net/ftp.apache.org/dist//lucene/solr/1.4.1/apache-solr-1.4.1.tgz

&lt;span class="nf"&gt;extract&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    tar zxvf apache-solr-1.4.1.tgz

&lt;span class="nf"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    rm -rf apache*
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just run &lt;cite&gt;make init&lt;/cite&gt; and you will get a new &lt;a class="reference external" href="http://lucene.apache.org/solr/"&gt;Apache Solr&lt;/a&gt; instance.&lt;/p&gt;
&lt;p&gt;Now the sandbox is installed you have to copy &lt;em&gt;your&lt;/em&gt; &lt;cite&gt;schema.xml&lt;/cite&gt; (and
&lt;cite&gt;solrconfig.xml&lt;/cite&gt; if applicable) in &lt;cite&gt;apache-solr-1.4.1/example/solr/conf/&lt;/cite&gt; so
this new index has exactly the same structure as the real one.&lt;/p&gt;
&lt;p&gt;Start Solr by running :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
java -jar start.jar
&lt;/pre&gt;
&lt;p&gt;The sandbox is now initialized and running.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exporting data and importing them in this new index&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Exporting your data depends on what you use, so I will not describe
this part. However you have to export these data in XML in the following format:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;add&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;doc&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;field&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;name_of_your_field_described_in_schema.xml&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            Anything you want here
        &lt;span class="nt"&gt;&amp;lt;/field&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- [repeat for all fields you want to index] --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/doc&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- &amp;lt;doc&amp;gt;....&amp;lt;/doc&amp;gt; --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/add&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;You can run &lt;a class="reference external" href="http://xmlsoft.org/xmllint.html"&gt;xmllint&lt;/a&gt; on the generated XML in order to be sure everything is
OK.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Indexing data&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Once you get an XML file containing a sample of your data you can index it
in &lt;a class="reference external" href="http://lucene.apache.org/solr/"&gt;Apache Solr&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Go to &lt;cite&gt;apache-solr-1.4.1/example/exampledocs&lt;/cite&gt; and run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;sh ./post.sh path/to/your/generated/xmlfile.xml
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Done :)&lt;/p&gt;
&lt;p&gt;Now you have a ready-to-debug index, if you need to reindex, just rerun the
command shown above. You may also want to purge the index first. I created this
shell alias, which will delete everything and commit the result :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;solrpurgeindex&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;java -Ddata=args -jar post.jar &amp;quot;&amp;lt;delete&amp;gt;&amp;lt;query&amp;gt;*:*&amp;lt;/query&amp;gt;&amp;lt;/delete&amp;gt;&amp;quot; &amp;amp;&amp;amp; java -jar post.jar&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;'Hope that helps :)&lt;/p&gt;
&lt;/div&gt;
</summary><category term="solr"></category><category term="debugging"></category></entry><entry><title>Moving changesets from the default branch to a new branch in Mercurial</title><link href="http://jrenard.info/blog/moving-changesets-from-the-default-branch-to-a-new-branch-in-mercurial.html" rel="alternate"></link><updated>2011-01-21T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-01-21:/blog/moving-changesets-from-the-default-branch-to-a-new-branch-in-mercurial.html/</id><summary type="html">&lt;p&gt;Yesterday I needed to move a specific list of changesets from the default
branch. Here is how I did it (there is surely another way to do it :)).&lt;/p&gt;
&lt;p&gt;First you need the &lt;a class="reference external" href="http://mercurial.selenic.com/wiki/MqExtension/"&gt;Mercurial Queues extension&lt;/a&gt;
which you can activate by adding the following contents in your &lt;cite&gt;hgrc&lt;/cite&gt; file&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[extensions]
mq =
&lt;/pre&gt;
&lt;p&gt;Once the extension is activated the sequence to apply is quite trivial :&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;convert the revisions you want to patches&lt;/p&gt;
&lt;pre class="literal-block"&gt;
hg qimport -r &amp;lt;START_REV&amp;gt;:&amp;lt;END_REV&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;remove them from the history&lt;/p&gt;
&lt;pre class="literal-block"&gt;
hg qpop -a
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;start a new branch&lt;/p&gt;
&lt;pre class="literal-block"&gt;
hg branch &amp;lt;mynewbranch&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;push the patches back in this newly created branch&lt;/p&gt;
&lt;pre class="literal-block"&gt;
hg qpush -A
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;finish the work&lt;/p&gt;
&lt;pre class="literal-block"&gt;
hg qfinish -a
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Done :)&lt;/p&gt;
</summary></entry><entry><title>Demystifying telecommuting</title><link href="http://jrenard.info/blog/demystifying-telecommuting.html" rel="alternate"></link><updated>2011-01-04T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2011-01-04:/blog/demystifying-telecommuting.html/</id><summary type="html">&lt;p&gt;I have been telecommuting for a few years now and quite often I meet people
-mostly team managers- who are immune to that kind of work arrangement.&lt;/p&gt;
&lt;p&gt;I will try to answer the questions I already heard and post my answers below.
Please note that this apply for my domain which is the IT industry  I do not
know if the same concepts can be applied to other domains.&lt;/p&gt;
&lt;blockquote&gt;
&amp;quot;Telecommuting is bad for business&amp;quot;&lt;/blockquote&gt;
&lt;p&gt;This is something I heard a lot. But this is not true some people think
telecommuting is generally a bad idea for business and that you can not become a
successful company with that kind of organization. Let me tell you a little
story. Once upon a time there was a small finnish company called &lt;a class="reference external" href="http://mysql.com"&gt;MySQL AB&lt;/a&gt;, they
created one of the most (if not the most) popular RDBMS on earth a few years
after. A few years ago this same company was sold for $1 billion. Guess what ?
Some engineers were (maybe they still are) telecommuters, I got that info from
Monty when I had the chance (and the honor) to met him last year. I am sure
there are other examples like MySQL, if you know some of them feel free to tell
me and I will add them.&lt;/p&gt;
&lt;blockquote&gt;
&amp;quot;Once at home, nobody will work&amp;quot;&lt;/blockquote&gt;
&lt;p&gt;That is indeed a risk. However nothing really forces someone to work when he
does not want to even at the office. You can get people spending most of their
time watching videos on YouTube or doing something completely unrelated to work.
You could filter your network and block unwanted websites, but there are a lot
of websites on earth and you can not block everything.&lt;/p&gt;
&lt;p&gt;If your team writes code on a daily basis I believe you have at least an &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Source_Code_Management"&gt;SCM&lt;/a&gt; and
a bug tracker. Both of these tools send notifications to a list that is followed
by everyone. If you see commits and notifications regularly from your colleagues
then you can be sure they are working. If you see nothing then maybe they are
not working or maybe there is something else. For example someone is sick or
working on a really big issues that can not be fixed within one day or
work.&lt;/p&gt;
&lt;p&gt;This is also a matter of discipline. When you work from home, you have to
control yourself not to take too much coffee breaks and avoid digression as much
as possible. Some people are capable to apply this discipline to themselves,
some of them are not. Some others refuse to work from home because they want a
clear distinction between work and the rest. When you work from home this is
sometimes really difficult to stop working, which might sounds delightful to a
manager :)&lt;/p&gt;
&lt;p&gt;If you are concerned about efficiency a recent belgian study showed that
telecommuting allowed to save 5 hours per week ! The study is available
&lt;a class="reference external" href="http://www.getronics.be/web/overview/Le-teletravail-permet-aux-utilisateurs-belges-de-gagner-une-demijournee-par-semaine-mais-les-societes-ne-lencouragent-pas-encore-vraiment.htm"&gt;here&lt;/a&gt; [fr]&lt;/p&gt;
&lt;blockquote&gt;
&amp;quot;Scrum does not work with telecommuters&amp;quot;&lt;/blockquote&gt;
&lt;p&gt;That is a myth. I used to use Scrum on a daily basis at my previous company. We
were a distributed team, people came from France, Belgium, Poland, Norway and
Germany. We had a 15/20 minutes daily scrum meeting. All the rest was handled
remotely. From sprint definitions to sprint demos and it worked just fine. I believe
the company still works that way and they have a new release every 6 months and they
are always on time. If that worked for me why would not that work for you ?&lt;/p&gt;
&lt;blockquote&gt;
&amp;quot;It is hard to meet everyone in the same place for brainstorming&amp;quot;&lt;/blockquote&gt;
&lt;p&gt;Brainstorming is indeed not as easy as asking everyone to go to the meeting room
as everything will have to be done online. For face to face (video) meetings I
prefer using &lt;a class="reference external" href="http://skype.com"&gt;Skype&lt;/a&gt; even though I find the screen sharing feature a bit limited.
For voice only meetings I use &lt;a class="reference external" href="http://skype.com"&gt;Skype&lt;/a&gt; as well, however when there is more than 10
people in the same meeting it is difficult to work efficiently. If I need to
show slides I like to use &lt;a class="reference external" href="http://www.gotomeeting.com/"&gt;GoToMeeting&lt;/a&gt;.
I heard good things about &lt;a class="reference external" href="http://www.webex.com/"&gt;WebEx&lt;/a&gt; but I never tried it
so any experience feedback is welcome :)&lt;/p&gt;
&lt;blockquote&gt;
&amp;quot;My team will loose the social thing&amp;quot;&lt;/blockquote&gt;
&lt;p&gt;That is true. This is why sometimes it is just good to meet everyone in the same
place for a few days. That can be arranged easily. Some people can sleep at
coworkers' or can go to the hotel. Honestly the extra cost of making everyone
meet in the same place from times to times is often negligible compared to what
telecommuters can give you in term of quality of work.&lt;/p&gt;
&lt;p&gt;Conclusion.&lt;/p&gt;
&lt;p&gt;Let's be honest, telecommuting is hard and requires a lot of discipline. But
the benefit on the long term are really worth it. What about trying this new way
of collaborating in 2011 ? It could be one of your new year's resolution ;)&lt;/p&gt;
</summary></entry><entry><title>PHP library release survey</title><link href="http://jrenard.info/blog/php-library-release-survey.html" rel="alternate"></link><updated>2010-12-02T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-12-02:/blog/php-library-release-survey.html/</id><summary type="html">&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;This is a (almost) copy and paste version of
&lt;a class="reference external" href="http://schlitt.info/opensource/blog/0738_php_library_release_survey.html"&gt;Tobias' original post&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;a class="reference external" href="http://zeta-components.org/"&gt;Apache Zeta Components&lt;/a&gt; project is
currently discussing how to adjust the old eZ Components release process
to the &lt;a class="reference external" href="http://apache.org/"&gt;ASF&lt;/a&gt; guidelines.&lt;/p&gt;
&lt;p&gt;During this
&lt;a class="reference external" href="http://mail-archives.apache.org/mod_mbox/incubator-zeta-dev/201011.mbox/browser"&gt;discussion&lt;/a&gt;,
quite some ideas came up on how the process could be optimized.&lt;/p&gt;
&lt;p&gt;This brought our interest to how users of PHP libraries would actually like to
obtain library code for their projects. The results of the survey will be published
later so all of the PHP libraries and frameworks can benefit.&lt;/p&gt;
&lt;p&gt;So please take some minutes and fill out the form :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://bit.ly/phplibrelsur"&gt;http://bit.ly/phplibrelsur&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks in advance :)&lt;/p&gt;
</summary></entry><entry><title>Flushing a cache-block manually in eZ Publish</title><link href="http://jrenard.info/blog/flushing-a-cache-block-manually-in-ez-publish.html" rel="alternate"></link><updated>2010-11-17T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-11-17:/blog/flushing-a-cache-block-manually-in-ez-publish.html/</id><summary type="html">&lt;p&gt;&lt;strong&gt;What is described below is extremely experimental !&lt;/strong&gt;&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;Purging cache-blocks in eZ Publish is something you can hardly control because
everything is done on the fly for each HTTP request.&lt;/p&gt;
&lt;p&gt;Furthermore there is no API for that task and you have to inspect the guts of
the template compiler (in &lt;a class="reference external" href="https://github.com/ezsystems/ezpublish/tree/master/lib/eztemplate/classes/"&gt;lib/eztemplate/classes&lt;/a&gt;)
in order to find what you need.&lt;/p&gt;
&lt;p&gt;For the unit test suite I am working on I needed to flush a specific cache-block
from the &lt;a class="reference external" href="http://php.net/cli"&gt;CLI SAPI&lt;/a&gt; so I needed a function to do that automatically.&lt;/p&gt;
&lt;p&gt;I finally came up with the following code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;expireCacheBlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$keyAttributeValue&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$functionPlacement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fetchCacheBlockPlacement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$template&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$placementKeyString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eZTemplateCacheBlock&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;placementString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$functionPlacement&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="c1"&gt;// cache-block key attribute&lt;/span&gt;
        &lt;span class="nv"&gt;$keyAttributeValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// cache-block placement in the template&lt;/span&gt;
        &lt;span class="nv"&gt;$placementKeyString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// siteaccess&lt;/span&gt;
        &lt;span class="nv"&gt;$GLOBALS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;eZCurrentAccess&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// subtree_expiry is NOT supported&lt;/span&gt;
    &lt;span class="nv"&gt;$nodeID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nv"&gt;$cachePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eZTemplateCacheBlock&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;cachePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;eZTemplateCacheBlock&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;keyString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$keys&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;$nodeID&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// should use the cluster API here&lt;/span&gt;
    &lt;span class="nb"&gt;unlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$cachePath&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchCacheBlockPlacement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$template&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$ini&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eZINI&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$ini&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;setVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;TemplateSettings&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;TemplateCompile&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;disabled&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$tpl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eZTemplate&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$tpl&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;loadURIRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;file:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$template&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$displayErrors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$extraParameters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$tpl&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$resource&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;root-node&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$resource&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;root-node&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="nv"&gt;$functionPlacement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// searching for the {cache-block ...} function&lt;/span&gt;
    &lt;span class="c1"&gt;// and its placement&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$children&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$child&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$nodeType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$child&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$nodeType&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;eZTemplate&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;NODE_FUNCTION&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$functionPlacement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$child&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$functionPlacement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;extension/varnishcache/design/varnishcachetests/templates/testcacheblock.tpl&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;varnishtest&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;expireCacheBlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see the cluster API is not used here but I do not need it so using a
simple &lt;a class="reference external" href="htt://php.net/unlink"&gt;unlink&lt;/a&gt; is enough for my needs. Furthermore this
script has a few limitations :&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;it support only one key ( equivalent to {cache-block .... &lt;strong&gt;key=foo&lt;/strong&gt; ...} )&lt;/li&gt;
&lt;li&gt;it does not support the design fallback. This is why you have to provide the
full path of the template.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you are interested in improving this code, feel free to fork it from &lt;a class="reference external" href="https://github.com/jeromer/cacheblockpurge"&gt;its
github repository&lt;/a&gt;&lt;/p&gt;
</summary><category term="ezpublish"></category></entry><entry><title>New blog!</title><link href="http://jrenard.info/blog/new-blog.html" rel="alternate"></link><updated>2010-11-14T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-11-14:/blog/new-blog.html/</id><summary type="html">&lt;p&gt;Enough wordpress and dynamic pages where the only thing I need is a simple page
generator and &lt;a class="reference external" href="http://en.wikipedia.org/wiki/ReST"&gt;ReST&lt;/a&gt; syntax. Welcome &lt;a class="reference external" href="http://alexis.notmyidea.org/pelican/"&gt;Pelican&lt;/a&gt; :)&lt;/p&gt;
&lt;p&gt;The old RSS feed is now obsolete. It has been replaced by a new Atom feed
available here :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://jrenard.info/blog/feeds/all.atom.xml"&gt;http://jrenard.info/blog/feeds/all.atom.xml&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</summary></entry><entry><title>About ESI</title><link href="http://jrenard.info/blog/about-esi.html" rel="alternate"></link><updated>2010-11-08T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-11-08:/blog/about-esi.html/</id><summary type="html">&lt;div class="section" id="what-is-esi"&gt;
&lt;h2&gt;What is ESI ?&lt;/h2&gt;
&lt;p&gt;ESI (Edge Side Includes) is a system which allows content assembly
by a web accelerator (Akamai, F5, Varnish, Squid ...). If you are
familiar with the concept of SSI with Apache then you will quickly
become familiar with ESI as the concept is more or less the same.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-problem-does-esi-solve"&gt;
&lt;h2&gt;What problem does ESI solve ?&lt;/h2&gt;
&lt;p&gt;The most common use case is the following (I will take the most
trivial one). Imagine you have a page with an article, and at the
top of the page you want to display 'Hello Mr John Smith' where
John Smith is the name of the user who is visiting the page. When
you want to service the page with your web accelerator you have a
problem because the page is personnalized. So basically you can not
cache the page in your web accelerator (I know you could use
JavaScript for that trivial use case bla bla bla bla). So what can
you do if you still want your web accelerator to service the page ?
What if you could ask your web accelerator to still keep the
article cached, but call a module dedicated to display 'Hello Mr
John Smith' ? This is where ESI comes into play. The web
accelerator will keep a cached copy of the article but by using a
specific set of XML tags it will be able to call the 'hello xxxx'
module and insert the result in the final page before servicing it
to the user.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-does-esi-work"&gt;
&lt;h2&gt;How does ESI work ?&lt;/h2&gt;
&lt;p&gt;Well, that is quite simple. By using a bunch of specific tags your
web accelerator will process them, insert the result in the HTML
page and will finally service it to the client. Let's take an
example with the &lt;cite&gt;&amp;lt;esi:include [...]/&amp;gt;&lt;/cite&gt; :&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;the webserver will return an HTML page with a tag &lt;cite&gt;&amp;lt;esi:include
src=&amp;quot;http://path/to/something&amp;quot; [...]/&amp;gt;&lt;/cite&gt;&lt;/li&gt;
&lt;li&gt;the web accelerator will parse the HTML, find the &amp;lt;esi:include [...]/&amp;gt; tag&lt;/li&gt;
&lt;li&gt;the web accelerator will call the URL defined in the src attribute and
insert the result in the HTML page where the &lt;cite&gt;&amp;lt;esi:include [...]/&amp;gt;&lt;/cite&gt;
tag has been defined of course&lt;/li&gt;
&lt;li&gt;the web accelerator will service the final page to the client.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class="section" id="where-can-i-get-esi-support"&gt;
&lt;h2&gt;Where can I get ESI support ?&lt;/h2&gt;
&lt;p&gt;ESI is supported by vendors such as Akamai and F5 but the
requirement here is to get ready to sign a (big) check ;). ESI is
also supported by free open source softwares such as Varnish and
Squid. However this is not because it is supported by these
vendors/softwares that the specification is fully supported. The
only vendor I know who support the specification completely is
Akamai (F5 as well&amp;nbsp; ? If you know other vendors who support ESI
completely, please let me know). Squid and Varnish have only a very
limited support of the language.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="so-what-can-i-do-with-it"&gt;
&lt;h2&gt;So what can I do with it ?&lt;/h2&gt;
&lt;p&gt;If you plan to use the &lt;cite&gt;&amp;lt;esi:include [...]/&amp;gt;&lt;/cite&gt; tag &lt;strong&gt;only&lt;/strong&gt; then you
can use Varnish but you have to know it has a very limited support
of this tag and will ignore errors silently. If you plan to use
more than &lt;cite&gt;&amp;lt;esi:include [...]/&amp;gt;&lt;/cite&gt; then you do not have much choice,
you have to use vendors like Akamai and this costs money. Sometimes
it makes sense to sign a check to get a quick solution &amp;quot;now&amp;quot; if
&amp;quot;now&amp;quot; is definitely important to you. However you have to take the
long run into account as well. Using a feature which is not
completely supported by different vendors/softwares introduces the
risk of being locked with a specific vendor/software.
Conclusion
----------&lt;/p&gt;
&lt;p&gt;I personally see ESI an numeric equivalent to cigarettes. So it is
better for your health not to taste. Use ESI only if this is the
very last solution you can use.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="useful-links"&gt;
&lt;h2&gt;Useful links&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.w3.org/TR/esi-lang"&gt;ESI language specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://devcentral.f5.com/wiki/default.aspx/WebAccelerator/IntroductiontoESI.html"&gt;Introduction to ESI by F5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.varnish-cache.org/trac/browser/trunk/varnish-cache/bin/varnishd/cache_esi.c"&gt;ESI support by Varnish&lt;/a&gt;
(only &lt;cite&gt;esi:include&lt;/cite&gt; and &lt;cite&gt;esi:remove&lt;/cite&gt; so far)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;'Hope that helps :)&lt;/p&gt;
&lt;/div&gt;
</summary><category term="akamai"></category><category term="esi"></category><category term="varnish"></category><category term="squid"></category><category term="f5"></category></entry><entry><title>mysqlslap and SQL syntax errors</title><link href="http://jrenard.info/blog/mysqlslap-and-sql-syntax-errors.html" rel="alternate"></link><updated>2010-09-23T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-09-23:/blog/mysqlslap-and-sql-syntax-errors.html/</id><summary type="html">&lt;p&gt;While I was playing with
&lt;a class="reference external" href="http://dev.mysql.com/doc/refman/5.1/en/mysqlslap.html"&gt;mysqlslap&lt;/a&gt;
for my local benchmarks I got an error that puzzled me :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
You have an error in your SQL syntax; ...
&lt;/pre&gt;
&lt;p&gt;After analysing the query and running it with the CLI mysql client
and in other tools I tried to write the query on one line. That was
the solution, it seems
&lt;a class="reference external" href="http://dev.mysql.com/doc/refman/5.1/en/mysqlslap.html"&gt;mysqlslap&lt;/a&gt;
only accepts one line queries :/ I tried with the following version&lt;/p&gt;
&lt;pre class="literal-block"&gt;
mysqlslap&amp;nbsp; Ver 1.0 Distrib 5.1.39, for pc-linux-gnu (i686)
&lt;/pre&gt;
</summary><category term="mysql"></category><category term="mysqlslap"></category></entry><entry><title>On tools</title><link href="http://jrenard.info/blog/on-tools.html" rel="alternate"></link><updated>2010-09-08T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-09-08:/blog/on-tools.html/</id><summary type="html">&lt;p&gt;I just realized that a lot of people expect a bit too much from
tools because they think they will magically do the job for them.
Unfortunately that is wrong.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image0" src="http://farm4.static.flickr.com/3453/3904986920_bfa4017783.jpg" style="width: 300px;" /&gt;&lt;/p&gt;
&lt;div class="section" id="what-tools-are-good-at"&gt;
&lt;h2&gt;What tools are good at&lt;/h2&gt;
&lt;p&gt;Tools are good to help you to do the job and to deliver what you
have to deliver. A lot of them are usually designed to do one
thing, but to do it well. They are usually specialized.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-tools-are-not-good-at"&gt;
&lt;h2&gt;What tools are not good at&lt;/h2&gt;
&lt;p&gt;Tools are not good at doing the job for you. No matter what you
have to deliver to your customer, the final result is generally an
aggregation of features. This means that you will have to use
different tools in order to deliver the final package. And no tool
can do that job for you.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-best-tool-you-have-is-your-brain"&gt;
&lt;h2&gt;The best tool you have is your brain&lt;/h2&gt;
&lt;p&gt;Do you imagine a chef in a restaurant became a chef just because he
(she) uses the best tool available ? No. The chef uses his (her)
brain and creativity first in order to find the best composition of
flavours. Once the recipe is roughly written the chef starts to do
the real cooking with all the tools he (she) needs in order to
achieve the expected result.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="do-not-be-the-tool-of-your-tool-s"&gt;
&lt;h2&gt;Do not be the tool of your tool(s)&lt;/h2&gt;
&lt;p&gt;Having the best hammer available on the market does not mean you
can use it for everything. Otherwise that means everything you are
going to touch will look like a nail and the only thing you will
try to do is to drive this nail without really knowing what you do
and the result might look like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image1" src="http://farm3.static.flickr.com/2769/4079209590_ebbdcaaa46.jpg" style="width: 300px;" /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="learn-and-try-new-tools"&gt;
&lt;h2&gt;Learn and try new tools&lt;/h2&gt;
&lt;p&gt;You have to master the tools you use or plan to use. This will help
you a lot to build the solution you have been asked to build, but
also when you have to make a decision on whether or not to use tool
X or Y to do a task. The are new tools released every year, it is
impossible to know them all but it is important to at least know
they exist. If possible try them in a sandbox, a Virtual Machine is
perfect for that you create a new instance and 5 minutes later you
can try a new tool&amp;nbsp; in case of mistake you remove the Virtual
Machine :)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="one-saying-to-have-in-mind"&gt;
&lt;h2&gt;One saying to have in mind&lt;/h2&gt;
&lt;p&gt;Henry David Thoreau :&lt;/p&gt;
&lt;blockquote&gt;
Men have become the tool of their tools.&lt;/blockquote&gt;
&lt;p&gt;Do you really want to prove him right ? :)&lt;/p&gt;
&lt;/div&gt;
</summary><category term="rant"></category></entry><entry><title>Finding OmmWriter audio files</title><link href="http://jrenard.info/blog/finding-ommwriter-audio-files.html" rel="alternate"></link><updated>2010-09-06T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-09-06:/blog/finding-ommwriter-audio-files.html/</id><summary type="html">&lt;p&gt;I really appreciate working with
&lt;a class="reference external" href="http://www.ommwriter.com"&gt;OmmWriter&lt;/a&gt; when I need to get focused
on something. However sometimes I just woud like to listen to the
audio files without launching the app. OmmWriter's audio files are
available in :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
/Applications/OmmWriter.app/Contents/*.m4a
&lt;/pre&gt;
&lt;p&gt;If you want to copy them here is what you can do in a Terminal :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
find /Applications/OmmWriter.app/Contents \
-type 'f' -name '*.m4a' -exec cp {} /path/of/your/choice \;
&lt;/pre&gt;
&lt;p&gt;Now you can listen to these audio files without launching
&lt;a class="reference external" href="http://www.ommwriter.com"&gt;OmmWriter&lt;/a&gt;. :)&lt;/p&gt;
</summary><category term="ommwriter"></category></entry><entry><title>Working with people living in different timezones.</title><link href="http://jrenard.info/blog/working-with-people-living-in-different-timezones.html" rel="alternate"></link><updated>2010-08-17T09:45:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-08-17:/blog/working-with-people-living-in-different-timezones.html/</id><summary type="html">&lt;p&gt;I just spent the last 10 days working for a customer in the USA (in
the Alexa top 500 in the US actually) and I was &amp;quot;debriefing&amp;quot; so why
not share the experience feedback ? :) The problem was how to work
with people living in different timezones ? The following list of
could help you :&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.timeanddate.com/"&gt;http://www.timeanddate.com/&lt;/a&gt; is
priceless, especially the
&lt;a class="reference external" href="http://www.timeanddate.com/worldclock/meeting.html"&gt;meeting planner&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Send emails for everything. That could be seen as over
communication but it is preferable to send an email to say &amp;quot;Hey I
get this problem&amp;quot; and then send an email 2 hours later to say &amp;quot;Hey
I fixed this problem&amp;quot; rather that saying and let people you work
with without informations that might be relevant later during the
day (or the week). Especially if people need this information
during your sleep hours.&lt;/li&gt;
&lt;li&gt;Be available. That does not mean you have to wake up at 5am and
got to sleep at 11pm, that just means that if your collaborator(s)
need you for a couple of minutes then do not refuse a call unless
you have a really good argument/excuse. You and your collaborators
know that at some point you (or them) will have to either wake up
(very) early or go to bed (very) late. People usually respect that
and meetings tend to be quick and focused.&lt;/li&gt;
&lt;li&gt;Think about the next day. The great thing when you work with
different timezones is that production (almost) never stops. So you
can go to bed after your day and when you wake up in the morning
you see new stuff being done, new features implemented. That is a
great productivity booster, but sometimes that can get really
confusing. So when you work on monday, think about what you will
have to do on tuesday and send an email in order to synchronize
with the rest of the team in order to avoid any overlap.&lt;/li&gt;
&lt;/ol&gt;
</summary><category term="collaboration"></category><category term="organization"></category><category term="productivity"></category></entry><entry><title>Generating an execution trace for a PHP script with Dtrace</title><link href="http://jrenard.info/blog/generating-an-execution-trace-for-a-php-script-with-dtrace.html" rel="alternate"></link><updated>2010-08-12T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-08-12:/blog/generating-an-execution-trace-for-a-php-script-with-dtrace.html/</id><summary type="html">&lt;p&gt;Here is a small &lt;a class="reference external" href="http://en.wikipedia.org/wiki/DTrace"&gt;Dtrace&lt;/a&gt;
script I used to generate the execution trace of a PHP script
running in a terminal : (executiontrace.d)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#! /usr/bin/dtrace -s&lt;/span&gt;
&lt;span class="c1"&gt;#pragma D option quiet&lt;/span&gt;
&lt;span class="c1"&gt;#pragma D option switchrate=10&lt;/span&gt;

&lt;span class="k"&gt;BEGIN&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;TRACE START [%Y]\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;walltimestamp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;depth&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;time_last&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;/**&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;program&lt;/span&gt; &lt;span class="n"&gt;begins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;so&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;*::&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;
&lt;span class="sr"&gt;/copyinstr(arg0) == &amp;quot;&amp;quot;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;%d\t -&amp;gt; {main}() %s:%d\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sr"&gt;/* well, just zero :-) */&lt;/span&gt;
        &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sr"&gt;/* source file, you can use basename(copyinstr(arg1)) if needed */&lt;/span&gt;
        &lt;span class="n"&gt;copyinstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sr"&gt;/* line number*/&lt;/span&gt;
        &lt;span class="n"&gt;arg2&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;time_last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;/**&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;*::&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;
&lt;span class="sr"&gt;/copyinstr(arg0) != &amp;quot;&amp;quot;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;&lt;/span&gt;
&lt;span class="sr"&gt;        /* string format */&lt;/span&gt;
        &lt;span class="s"&gt;&amp;quot;%d\t %*s %s%s%s() %s:%d\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sr"&gt;/* time delta (microseconds)*/&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;time_last&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sr"&gt;/* indentation   */&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;-&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sr"&gt;/* class name, if available */&lt;/span&gt;
        &lt;span class="n"&gt;copyinstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sr"&gt;/* scope operator, if available */&lt;/span&gt;
        &lt;span class="n"&gt;copyinstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sr"&gt;/* function name, always available */&lt;/span&gt;
        &lt;span class="n"&gt;copyinstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sr"&gt;/* source file, you can use basename(copyinstr(arg1)) if needed */&lt;/span&gt;
        &lt;span class="n"&gt;copyinstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sr"&gt;/* line number*/&lt;/span&gt;
        &lt;span class="n"&gt;arg2&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;time_last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;/**&lt;/span&gt;
 &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="o"&gt;*/&lt;/span&gt;
&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;*::&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="sr"&gt;/copyinstr(arg0) != &amp;quot;&amp;quot;/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;END&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;TRACE END [%Y]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;walltimestamp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It looks like an &lt;a class="reference external" href="http://xdebug.org/"&gt;Xdebug&lt;/a&gt; trace (without the
memory usage / delta) but since Dtrace and Xdebug do not operate at
the same level the results are quite different. If you want to test
this script you can use for example the following
(nestedfunctions.php) :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DirectoryIterator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;__DIR__&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;child&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nb"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(){}&lt;/span&gt;
&lt;span class="nx"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nb"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And by running the following command :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo dtrace -s executiontrace.d -c &amp;quot;php nestedfunctions.php&amp;quot;
&lt;/pre&gt;
&lt;p&gt;You should get a result like this (do not forget to hit &amp;lt;Ctrl-c&amp;gt; in
order to exit from Dtrace).&lt;/p&gt;
&lt;pre class="literal-block"&gt;
TRACE START [2010 Aug 12 10:44:27]
0&amp;nbsp;&amp;nbsp; &amp;nbsp; -&amp;gt; {main}() [...]/testnestedfunctions.php:0
669&amp;nbsp;&amp;nbsp; &amp;nbsp; -&amp;gt; launch() [...]/testnestedfunctions.php:21
24&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt; parent() [...]/testnestedfunctions.php:16
37&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt; DirectoryIterator::__construct() [...]/testnestedfunctions.php:5
286&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt; child() [...]/testnestedfunctions.php:6
21&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt; sleep() [...]/testnestedfunctions.php:11
1000158&amp;nbsp;&amp;nbsp; &amp;nbsp; -&amp;gt; foo() [...]/testnestedfunctions.php:22
32&amp;nbsp;&amp;nbsp; &amp;nbsp; -&amp;gt; sleep() [...]/testnestedfunctions.php:23
2000097&amp;nbsp;&amp;nbsp; &amp;nbsp; -&amp;gt; foo() [...]/testnestedfunctions.php:24
32&amp;nbsp;&amp;nbsp; &amp;nbsp; -&amp;gt; launch() [...]/testnestedfunctions.php:25
21&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt; parent() [...]/testnestedfunctions.php:16
32&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt; DirectoryIterator::__construct() [...]/testnestedfunctions.php:5
141&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt; child() [...]/testnestedfunctions.php:6
20&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt; sleep() [...]/testnestedfunctions.php:11
1000111&amp;nbsp;&amp;nbsp; &amp;nbsp; -&amp;gt; foo() [...]/testnestedfunctions.php:26
^C
TRACE END [2010 Aug 12 10:44:34]
&lt;/pre&gt;
&lt;p&gt;I tried to add as much comments as possible in order to make the
script clearer. Please note that if you run this script on
production you will get &lt;strong&gt;a lot&lt;/strong&gt; of output because the script does
not filter on any pid so Dtrace will aggregate results across
multilple Apache processes. It is up to you to use the correct
predicate to filter on the PID you want in order to limit the
result set.&lt;/p&gt;
</summary><category term="php"></category><category term="dtrace"></category><category term="macosx"></category></entry><entry><title>A comparison of the difference between the french and the US culture in IT.</title><link href="http://jrenard.info/blog/a-comparison-of-the-difference-between-the-french-and-the-us-culture-in-it.html" rel="alternate"></link><updated>2010-08-09T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-08-09:/blog/a-comparison-of-the-difference-between-the-french-and-the-us-culture-in-it.html/</id><summary type="html">&lt;dl class="docutils" id="disclaimer"&gt;
&lt;dt&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt; :&lt;/dt&gt;
&lt;dd&gt;This blog post is based upon my experience, it does not pretend to
generalize anything for one culture or another.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;I have the chance to work for awesome customers in both France and the USA and
that gives me the opportunity to work with people with different cultures and
mindsets. So I thought that could be interesting to write down my experience
with these two cultures and try to describe the differences.&lt;/p&gt;
&lt;p&gt;There is one sure thing : American people care about IT, not only because it
makes your life simpler or because this is serious business, but also because
they simply invented it. If you have a look at the last decade you'll see that
almost any major technological invention comes from the USA. If you have a look
at the Alexa top 20, you'll see that almost all websites are from American companies.&lt;/p&gt;
&lt;p&gt;American people are what I call superlative oriented, everything has to be
great, awesome, excellent etc, etc. They are in constant need for heroes and
rock stars. In my opinion this is a bit too much, but that is the way they
are and I respect that.&lt;/p&gt;
&lt;p&gt;On the project management side, one great thing is that most project managers
(I have worked with, cf the &lt;a class="reference internal" href="#disclaimer"&gt;disclaimer&lt;/a&gt; ;)) actually have a real technical
background. I remember one day there was a problem on a big website and the
editor in chief (yes, the editor in chief, they guy who care about contents,
not tech) told me something like &amp;quot;I think there is an issue with mod_rewrite,
most likely a regex, can you please have look at it ?&amp;quot;. And guess what ? He
was right. If I compare with my experience in France, there was a small problem
with an import system that had to be fixed quickly and the project manager told me
pedantically &amp;quot;There must be an infinite loop somewhere&amp;quot; ...&lt;/p&gt;
&lt;p&gt;There is one main difference between the american and the french culture and I
am not sure it will disappear in the next few years. American people have a deep
respect for developpers (or engineers the word does not really matters here)
whereas in France being a developer makes you be that weird guy who writes lines
of code nobody else have a clue about. No matter what you say you are a &amp;quot;geek&amp;quot;
so who would think you say interesting things anyway ? In France real men
become project managers. It is acceptable to write code for a few years after
being graduated (the lesser, the better) but at some point, you have to &amp;quot;grow up&amp;quot;
and be a manager. I actually can not imagine the CTO of a big IT company going
to the sysadmin's office and say them &amp;quot;you are useless&amp;quot;. Think that can not happen
in France ? It actually did I was there when that happened and that was not a
a small company, that happened at a very big company I used to worked for from
times to times.&lt;/p&gt;
&lt;p&gt;American people (well, people living in an english speaking country) have a
strong (who said unfair ? :)) advantage, every technical documentation /
article / paper, well everything is written in english. If you have a look at
how your program is built, it is all in english as well (if/then/else, while,
for loop, function names, class names, etc, etc). So programming gets a bit
more &amp;quot;natural&amp;quot; because they  do not have to do any translation effort. And that
gives them the opportunity to dive into any technology in record time.&lt;/p&gt;
&lt;p&gt;On the contrary, French people have to make this effort all the time, it
is no big deal when you to do this on a daily basis, but still this
is not natural. This is why I personally think that the very first
language any french developper should know is English, nothing else.&lt;/p&gt;
&lt;p&gt;Everything is not of course black and white, and we have the chance to have
pretty big websites in France as well like Meetic Dailymotion Netvibes
(BTW : I would love to work you :)) for example. But I am not sure we will
see (even though I'd love too) a lot of websites of that dimension emerging
quickly in the future in France.&lt;/p&gt;
&lt;p&gt;I know this post is a bit messy but this is all I can do for the moment given
my spare time. Any feedback welcome :)&lt;/p&gt;
</summary><category term="IT"></category></entry><entry><title>Finding syscalls generated by PHP functions with Dtrace</title><link href="http://jrenard.info/blog/finding-syscalls-generated-by-php-functions-with-dtrace.html" rel="alternate"></link><updated>2010-08-04T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-08-04:/blog/finding-syscalls-generated-by-php-functions-with-dtrace.html/</id><summary type="html">&lt;p&gt;I wanted to check a list of syscalls that are generated by PHP for
a bunch of functions. Dtrace saved the day again, in 10 minutes I
had all I needed. Here is a PHP script you can use for testing
(syscalls.php) :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nb"&gt;file_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;__FILE__&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;file_get_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;__FILE__&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;chdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;__DIR__&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;__DIR__&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;getcwd&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nb"&gt;opendir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;__DIR__&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;scandir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;__DIR__&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DirectoryIterator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;__DIR__&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;__DIR__&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;is_readable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;__DIR__&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;is_writable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;__DIR__&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;file_put_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/tmp/foo.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And the small Dtrace (syscalls.d) script I used:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;#!/usr/sbin/dtrace -s&lt;/span&gt;
&lt;span class="c1"&gt;#pragma D option quiet&lt;/span&gt;

&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;*::&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;
&lt;span class="sr"&gt;/pid == $target &amp;amp;&amp;amp; arg0/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;%s%s%s\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;copyinstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;copyinstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;copyinstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;follow&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;
&lt;span class="sr"&gt;/self-&amp;gt;follow &amp;gt; 0/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;  -&amp;gt;%s\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;probefunc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;php&lt;/span&gt;&lt;span class="o"&gt;*::&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="sr"&gt;/pid == $target &amp;amp;&amp;amp; arg0/&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;follow&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;follow&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nb"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can test the script by running :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo dtrace -s syscalls.d -c &amp;quot;php syscalls.php&amp;quot;
&lt;/pre&gt;
&lt;p&gt;And you should get a list like this (at least on Mac Os X)&lt;/p&gt;
&lt;pre class="literal-block"&gt;
file_exists
 -&amp;gt;access

file_get_contents
 -&amp;gt;lstat
 -&amp;gt;lstat
 -&amp;gt;open
 -&amp;gt;fstat
 -&amp;gt;lseek
 -&amp;gt;fstat
 -&amp;gt;read
 -&amp;gt;read
 -&amp;gt;read
 -&amp;gt;close

chdir
 -&amp;gt;chdir

dir
 -&amp;gt;open_nocancel
 -&amp;gt;fcntl_nocancel
 -&amp;gt;__sysctl
 -&amp;gt;fstatfs

getcwd
 -&amp;gt;open_nocancel
 -&amp;gt;fstat64
 -&amp;gt;fcntl_nocancel
 -&amp;gt;close_nocancel
 -&amp;gt;stat64

opendir
 -&amp;gt;open_nocancel
 -&amp;gt;fcntl_nocancel
 -&amp;gt;fstatfs
 -&amp;gt;close_nocancel

scandir
 -&amp;gt;open_nocancel
 -&amp;gt;fcntl_nocancel
 -&amp;gt;fstatfs
 -&amp;gt;getdirentries
 -&amp;gt;getdirentries
 -&amp;gt;close_nocancel

DirectoryIterator::__construct
 -&amp;gt;open_nocancel
 -&amp;gt;fcntl_nocancel
 -&amp;gt;fstatfs
 -&amp;gt;getdirentries

 -&amp;gt;close_nocancel
stat
 -&amp;gt;stat

is_readable
 -&amp;gt;access

is_writable
 -&amp;gt;access

file_put_contents
 -&amp;gt;lstat
 -&amp;gt;lstat
 -&amp;gt;readlink
 -&amp;gt;lstat
 -&amp;gt;lstat
 -&amp;gt;open
 -&amp;gt;fstat
 -&amp;gt;lseek
 -&amp;gt;write
 -&amp;gt;close
&lt;/pre&gt;
&lt;p&gt;If I have time I'll post more Dtrace scripts useful for analysing
what PHP does.&lt;/p&gt;
&lt;p&gt;Edit : I fixed a small bug for the DirectoryOperator class.&lt;/p&gt;
</summary><category term="php"></category><category term="dtruss"></category><category term="dtrace"></category><category term="macosx"></category></entry><entry><title>Sphinx, documentation made easy</title><link href="http://jrenard.info/blog/sphinx-documentation-made-easy.html" rel="alternate"></link><updated>2010-08-01T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-08-01:/blog/sphinx-documentation-made-easy.html/</id><summary type="html">&lt;p&gt;I just wanted to promote a fantastic documentation tool called
&lt;a class="reference external" href="http://sphinx.pocoo.org/"&gt;Sphinx&lt;/a&gt;. I have been using it for more
than 6 months now and I am more than happy with it. What makes
&lt;a class="reference external" href="http://sphinx.pocoo.org/"&gt;Sphinx&lt;/a&gt; so unique is that it makes
actually you love writing documentation I use it for almost
anything now, from writing specifications to documentations for
deliverables I send to my customers. And the result is not just
awesome, it just look professional (IMHO).&lt;/p&gt;
&lt;p&gt;I use the
&lt;a class="reference external" href="http://github.com/mitsuhiko/flask-sphinx-themes"&gt;Flask theme&lt;/a&gt;
which I think provide a better readability than the default ones.
As an example, here is what the
&lt;a class="reference external" href="http://zeta-components.org/"&gt;Apache Zeta Components&lt;/a&gt;
documentation &lt;a class="reference external" href="http://jrenard.info/utils/zetacomponentsdoc-sphinx/theme-flask/"&gt;looks like&lt;/a&gt;
when generated with &lt;a class="reference external" href="http://sphinx.pocoo.org/"&gt;Sphinx&lt;/a&gt; using the
&lt;a class="reference external" href="http://github.com/mitsuhiko/flask-sphinx-themes"&gt;Flask theme&lt;/a&gt; As
a long time &lt;a class="reference external" href="http://docutils.sourceforge.net/"&gt;docutils&lt;/a&gt; user,
learning the few &lt;a class="reference external" href="http://sphinx.pocoo.org/"&gt;Sphinx&lt;/a&gt; specific
constructs was a piece of cake.&lt;/p&gt;
&lt;p&gt;If you already know or worked with the RST syntax then using Sphinx
should not be a problem at all. If you would like to convince your
manager(s) to use Sphinx just say that the &lt;a class="reference external" href="http://docs.python.org/"&gt;official Python documentation&lt;/a&gt;
uses it, so does the &lt;a class="reference external" href="http://docs.symfony-reloaded.org/"&gt;official Symfony documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Happy documenting :)&lt;/p&gt;
</summary><category term="sphinx"></category><category term="documentation"></category><category term="python"></category></entry><entry><title>Come on Mr Arrington ...</title><link href="http://jrenard.info/blog/come-on-mr-arrington.html" rel="alternate"></link><updated>2010-07-17T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-07-17:/blog/come-on-mr-arrington.html/</id><summary type="html">&lt;p&gt;Dear Mr Arrington, I just read the following blog post on
&lt;a class="reference external" href="http://techcrunch.com"&gt;Techcrunch&lt;/a&gt; :
&lt;a class="reference external" href="http://techcrunch.com/2010/07/16/breaking-french-government-still-cant-get-france-fr-live/"&gt;Breaking: French Government Still Can’t Get France.fr&amp;nbsp;live&lt;/a&gt;
Even though you have a point about france.fr being down for days
right after its launch, you did not need a blog post on Techcrunch
for that, there is a simple word to explain this failure :
incompetence. What is absolutely pointless in your article is this:&lt;/p&gt;
&lt;blockquote&gt;
If the country’s experience with building
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/French_aircraft_carrier_Charles_de_Gaulle_%28R91%29"&gt;aircraft carriers&lt;/a&gt;
is any indication of their ability to build websites, we should see
it limping along sometime in 2013.&lt;/blockquote&gt;
&lt;p&gt;Let's skip the aircraft carriers thingy because it is absolutely
out of topic here. French people not able to do websites ? Do
people behind &lt;a class="reference external" href="http://dailymotion.com"&gt;Dailymotion&lt;/a&gt;,
&lt;a class="reference external" href="http://www.netvibes.com"&gt;Netvibes&lt;/a&gt;,
&lt;a class="reference external" href="http://skyblog.com/"&gt;Skyblog&lt;/a&gt;, &lt;a class="reference external" href="http://seesmic.com"&gt;Seesmic&lt;/a&gt;,
&lt;a class="reference external" href="http://deezer.com"&gt;Deezer&lt;/a&gt; come from Mars ? You can love or hate
the service but you can not say that french people can not make
websites. By the way, showing the list of wars France lost is also
useless, unless you want to talk about Vietnam and Irak ;) If ever
someone read this blog post and uses the WW2 argument, I would
recommend this person to read a history book first so he can
understand why the USA entered into the conflict. Reading a bit on
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Gilbert_du_Motier_de_La_Fayette"&gt;Lafayette&lt;/a&gt;
is recommended as well. So please Mr Arrington, do what you do well
i.e publishing news about tech and the Internet in general and stop
the rest. Best Regards, PS : if ever this website goes down after a
while due to the incoming traffic this is because it is hosted on a
cheap shored host I do not quite care about not because it is
French.&lt;/p&gt;
</summary><category term="rant"></category><category term="techcrunch"></category></entry><entry><title>Collectd and Varnish user ? We need your feedback</title><link href="http://jrenard.info/blog/collectd-and-varnish-user-we-need-your-feedback.html" rel="alternate"></link><updated>2010-07-15T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-07-15:/blog/collectd-and-varnish-user-we-need-your-feedback.html/</id><summary type="html">&lt;p&gt;If you use &lt;a class="reference external" href="http://collectd.org"&gt;collectd&lt;/a&gt; and would like to
monitor your &lt;a class="reference external" href="http://varnish-cache.org/"&gt;Varnish&lt;/a&gt; instance(s),
this blog post is for you.&lt;/p&gt;
&lt;p&gt;The new &lt;a class="reference external" href="http://collectd.org/wiki/index.php/Plugin:Varnish"&gt;Varnish plugin&lt;/a&gt;
for &lt;a class="reference external" href="http://collectd.org"&gt;collectd&lt;/a&gt; is ready, however we would
love to get feedback from you. The plugin has already been pushed
on production on &lt;a class="reference external" href="http://www.camptocamp.org/"&gt;Camp To Camp&lt;/a&gt; and
the feedback is really positive so far. However it is always good
to get more feedback from different people using
&lt;a class="reference external" href="http://collectd.org"&gt;collectd&lt;/a&gt; and
&lt;a class="reference external" href="http://varnish-cache.org/"&gt;Varnish&lt;/a&gt; in different contexts.&lt;/p&gt;
&lt;p&gt;How can you help ? Simply run the Varnish plugin on one of your
production (or test) server(s) and provide feedback, and ideally
some graphs :) Installing the Varnish plugin for is really trivial :&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;run &lt;cite&gt;git clone http://github.com/octo/collectd.git&lt;/cite&gt;&lt;/li&gt;
&lt;li&gt;compile &lt;a class="reference external" href="http://collectd.org"&gt;collectd&lt;/a&gt; as you would normally
do, do not forget the &lt;cite&gt;--enable-varnish flag&lt;/cite&gt;&lt;/li&gt;
&lt;li&gt;configure the Varnish plugin in collectd.conf, as explained in the
&lt;a class="reference external" href="http://collectd.org/wiki/index.php/Plugin:Varnish#Synopsis"&gt;configuration synopsis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;start collectd For more information, feel free to read and/or
comment the &lt;a class="reference external" href="http://collectd.org/wiki/index.php/Plugin:Varnish"&gt;dedicated wiki page&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Feedback can be provided as you wish, either by sending an email to the
&lt;a class="reference external" href="http://mailman.verplant.org/listinfo/collectd"&gt;mailing-list&lt;/a&gt; or
directly to me &amp;lt;jerome.renard &amp;#64; gmail.com&amp;gt;.&lt;/p&gt;
&lt;p&gt;Thanks in advance for your feedback. :)&lt;/p&gt;
</summary><category term="collectd"></category><category term="varnish"></category></entry><entry><title>Easy switch from Mercurial to Git</title><link href="http://jrenard.info/blog/easy-switch-from-mercurial-to-git.html" rel="alternate"></link><updated>2010-06-29T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-06-29:/blog/easy-switch-from-mercurial-to-git.html/</id><summary type="html">&lt;p&gt;For a project I am currently working I needed to switch from
Mercurial to Git. I used the method described below, that is really
trivial and it works just fine. Download
&lt;a class="reference external" href="http://repo.or.cz/w/fast-export.git/snapshot/1464dabbff7fe42b9069e98869db40276d295ad6.tar.gz"&gt;fast-export&lt;/a&gt;
and extract it wherever you want. Run the following commands :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
mkdir git.migration &amp;amp;&amp;amp; cd !$ &amp;amp;&amp;amp; git init
/path/to/fast-export/hg-fast-export.sh -r /path/to/your/mercurial/repository
&lt;/pre&gt;
&lt;p&gt;And wait for a few minutes/seconds, depending on the size of your
repository. In the end of the process you should get a result like :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 10000
Total objects:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5426 (&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 566 duplicates&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )
 blobs&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1990 (&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 453 duplicates&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1454 deltas)
 trees&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3027 (&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 113 duplicates&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1762 deltas)
 commits:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 409 (&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 duplicates&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 deltas)
 tags&amp;nbsp;&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 (&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 duplicates&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 deltas)
Total branches:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 (&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 loads&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )
 marks:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1024 (&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 409 unique&amp;nbsp;&amp;nbsp;&amp;nbsp; )
 atoms:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1030
Memory total:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2540 KiB
 pools:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2149 KiB
 objects:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 390 KiB
---------------------------------------------------------------------
pack_report: getpagesize()&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4096
pack_report: core.packedGitWindowSize =&amp;nbsp;&amp;nbsp; 33554432
pack_report: core.packedGitLimit&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;nbsp; 268435456
pack_report: pack_used_ctr&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1
pack_report: pack_mmap_calls&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1
pack_report: pack_open_windows&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 /&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1
pack_report: pack_mapped&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;nbsp;&amp;nbsp;&amp;nbsp; 7542871 /&amp;nbsp;&amp;nbsp;&amp;nbsp; 7542871
---------------------------------------------------------------------
&lt;/pre&gt;
&lt;p&gt;Now run :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
git checkout
&lt;/pre&gt;
&lt;p&gt;Done.&lt;/p&gt;
</summary><category term="mercurial"></category><category term="git"></category></entry><entry><title>Fixing user infos in git commits</title><link href="http://jrenard.info/blog/fixing-user-infos-in-git-commits.html" rel="alternate"></link><updated>2010-06-29T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-06-29:/blog/fixing-user-infos-in-git-commits.html/</id><summary type="html">&lt;p&gt;After &lt;a class="reference external" href="http://jrenard.info/blog/easy-switch-from-mercurial-to-git.html"&gt;I easily switched from Mercurial to Git&lt;/a&gt;,
I needed to update the committer's name and email adress. I found
that using git filter-branch could help me. Here is what I did :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
git filter-branch --env-filter \
'export GIT_AUTHOR_NAME=&amp;quot;Foo&amp;quot; ; GIT_AUTHOR_EMAIL=&amp;quot;foo.bar&amp;#64;example.com&amp;quot;'
&lt;/pre&gt;
&lt;p&gt;And git updated the author's name and author's email for every
commit.&lt;/p&gt;
</summary><category term="git"></category></entry><entry><title>Viewing the progress of a process through a pipe with pv</title><link href="http://jrenard.info/blog/viewing-the-progress-of-a-process-through-a-pipe-with-pv.html" rel="alternate"></link><updated>2010-06-14T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-06-14:/blog/viewing-the-progress-of-a-process-through-a-pipe-with-pv.html/</id><summary type="html">&lt;div class="section" id="what-is-pv"&gt;
&lt;h2&gt;What is pv ?&lt;/h2&gt;
&lt;p&gt;It is a tool that monitors the progress of data through a pipe.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how-to-install-it"&gt;
&lt;h2&gt;How to install it ?&lt;/h2&gt;
&lt;p&gt;Well, that is quite simple, the package name is the same for all
platforms : pv so you can use&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo port|yum|apt-get install pv
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="how-to-use-it"&gt;
&lt;h2&gt;How to use it ?&lt;/h2&gt;
&lt;p&gt;Let's take an example, you want to compress a big text file, you
would normally run something like gzip &amp;lt;filename&amp;gt; and wait for the
process to be finished without knowing exactly when. With
&lt;a class="reference external" href="http://www.ivarch.com/programs/pv.shtml"&gt;pv&lt;/a&gt; you can know
exactly what the status of the process is and when it is finished.
Let's reuse the gzip example above and try the following (I tried
on a 1.6GB text file) :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
17:08 jerome&amp;#64;gimli/private/tmp% gzip dummy.txt
#and just wait for gzip to finish
&lt;/pre&gt;
&lt;p&gt;Now let's try with &lt;a class="reference external" href="http://www.ivarch.com/programs/pv.shtml"&gt;pv&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
17:10 jerome&amp;#64;gimli/private/tmp% pv dummy.txt | gzip &amp;gt; dummy.txt.gz
1.16GB 0:00:14 [81.9MB/s] [==============[...]===================&amp;gt;] 100%
&lt;/pre&gt;
&lt;p&gt;Let's extract the file by using
&lt;a class="reference external" href="http://www.ivarch.com/programs/pv.shtml"&gt;pv&lt;/a&gt; as well :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
17:11 jerome&amp;#64;gimli/private/tmp% pv dummy.txt.gz | gunzip &amp;gt; dummy.txt.gunzip
3.45MB 0:00:22 [ 158kB/s] [==============[...]===================&amp;gt;] 100%
&lt;/pre&gt;
&lt;p&gt;Cool isn't it ? Now we know exactly when the process is finished,
this is really useful. For more information about
&lt;a class="reference external" href="http://www.ivarch.com/programs/pv.shtml"&gt;pv&lt;/a&gt;, you can read the
&lt;a class="reference external" href="http://www.ivarch.com/programs/quickref/pv.shtml"&gt;manual page&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</summary><category term="pv"></category></entry><entry><title>Avoiding warnings about autoconf 2.13 when building PHP</title><link href="http://jrenard.info/blog/avoiding-warnings-about-autoconf-213-when-building-php.html" rel="alternate"></link><updated>2010-06-09T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-06-09:/blog/avoiding-warnings-about-autoconf-213-when-building-php.html/</id><summary type="html">&lt;p&gt;If you want to build PHP from the SVN repository, you have to run
&lt;cite&gt;buildconf [--force]&lt;/cite&gt;. But depending on the version of autoconf you
have on your machine you can get the very annoying warning message
:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[...] buildconf: Your version of autoconf likely contains buggy
cache code. Running vcsclean for you. To avoid this, install
autoconf-2.13. [...]
&lt;/pre&gt;
&lt;p&gt;If you do not have autoconf 2.13 installed, then you have to
install it first. On RedHat running sudo yum install autoconf213
should work. On Debian, the &lt;a class="reference external" href="http://packages.debian.org/lenny/autoconf2.13"&gt;autoconf2.13&lt;/a&gt;
package is available. Once autoconf2.13 install, you can instruct
buildconf to use this new version of autoconf by runing&lt;/p&gt;
&lt;pre class="literal-block"&gt;
export PHP_AUTOCONF=`which autoconf-2.13`
&lt;/pre&gt;
&lt;p&gt;You can check the value is correct by running&lt;/p&gt;
&lt;pre class="literal-block"&gt;
echo $PHP_AUTOCONF
&lt;/pre&gt;
&lt;p&gt;Which should give you something like (depending on your system)
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/usr/bin/autoconf-2.13&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Now retry to run&lt;/p&gt;
&lt;pre class="literal-block"&gt;
./buildconf --force.
&lt;/pre&gt;
&lt;p&gt;The annoying message is gone, joy :)&lt;/p&gt;
</summary><category term="php"></category><category term="autoconf"></category><category term="compilation"></category></entry><entry><title>Getting varnish statistics in XML format</title><link href="http://jrenard.info/blog/getting-varnish-statistics-in-xml-format.html" rel="alternate"></link><updated>2010-05-27T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-05-27:/blog/getting-varnish-statistics-in-xml-format.html/</id><summary type="html">&lt;p&gt;I was searching something in the Varnish source code when I found a
non documented (at least there is nothing in man varnishstat, for
Varnish 2.1.2) feature. Varnishstat can return statistics in XML.
How to get this format ? That's pretty simple, just add the -x
argument to varnishstat, for example using :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
varnishstat -x
&lt;/pre&gt;
&lt;p&gt;will return something like :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;varnishstat&lt;/span&gt; &lt;span class="na"&gt;timestamp=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;2010-05-27T17:03:26&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;stat&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;client_conn&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;33036&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Client connections accepted&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/stat&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;stat&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;client_drop&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Connection dropped, no sess/wrk&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/stat&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;stat&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;client_req&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;34740&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Client requests received&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/stat&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;stat&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;cache_hit&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;33580&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Cache hits&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/stat&amp;gt;&lt;/span&gt;
[...]
&lt;span class="nt"&gt;&amp;lt;/varnishstat&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So now, if you only want to get cache hits and cache_misses in XML
so you can parse them easily on you can do :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
varnishstat -f cache_hit,cache_miss -x
&lt;/pre&gt;
&lt;p&gt;And you get something like&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;varnishstat&lt;/span&gt; &lt;span class="na"&gt;timestamp=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;2010-05-27T17:05:41&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;stat&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;cache_hit&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;33580&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Cache hits&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/stat&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;stat&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;cache_miss&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;1160&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Cache misses&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/stat&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/varnishstat&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want to know more about that, have a look at the
&lt;a class="reference external" href="http://www.varnish-cache.org/browser/tags/varnish-2.1.2/varnish-cache/bin/varnishstat/varnishstat.c#L216"&gt;do_xml function&lt;/a&gt;
in
&lt;a class="reference external" href="http://www.varnish-cache.org/browser/tags/varnish-2.1.2/varnish-cache/bin/varnishstat/varnishstat.c"&gt;varnishstat.c&lt;/a&gt;&lt;/p&gt;
</summary><category term="varnish"></category><category term="statistics"></category></entry><entry><title>What's new in eZEnhancedDebug 1.2 ?</title><link href="http://jrenard.info/blog/whats-new-in-ezenhanceddebug-12.html" rel="alternate"></link><updated>2010-04-26T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-04-26:/blog/whats-new-in-ezenhanceddebug-12.html/</id><summary type="html">&lt;p&gt;I just released
&lt;a class="reference external" href="http://github.com/jeromer/ezenhanceddebug/tarball/1.2"&gt;ezenhanceddebug 1.2&lt;/a&gt;,
here are the new things I added :&lt;/p&gt;
&lt;div class="section" id="compatible-with-ez-publish-4-3"&gt;
&lt;h2&gt;Compatible with eZ Publish 4.3&lt;/h2&gt;
&lt;p&gt;If you read the changelog in the eZ Publish 4.3 release, you will
notice :&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Implemented enhancement #16216: Deprecate templateInit()&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Which is documented by&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;kernel/common/template.php: templateInit() Function will be
removed in a future version, use eZTemplate::factory() instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;This change has been implemented.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="kcachegrind-support"&gt;
&lt;h2&gt;KCacheGrind support&lt;/h2&gt;
&lt;p&gt;There is two new configuration directives in
ezenhanceddebug.ini.append.php :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;[ProfilerSettings]&lt;/span&gt;
&lt;span class="na"&gt;Profiler&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;enabled&lt;/span&gt;
&lt;span class="na"&gt;ProfilerOutputDir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/tmp/ezenhanceddebug&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If [ProfilerSettings]/Profiler is set to enabled, then anytime you
generate a page you will get a
&lt;a class="reference external" href="http://kcachegrind.sourceforge.net"&gt;KCacheGrind&lt;/a&gt; compatible file
in
&lt;cite&gt;[ProfilerSettings]/ProfilerOutputDir/url_alias_of_the_page.out&lt;/cite&gt;
Here is what it looks like :&lt;/p&gt;
&lt;p&gt;&lt;img alt="image0" src="http://www.jrenard.info/blog/wp-content/uploads/2010/04/ezenhanceddebug-kcachegrind-1024x616.png" style="width: 500px;" /&gt;&lt;/p&gt;
&lt;p&gt;Each function follows the pattern :
&lt;cite&gt;&amp;lt;template_name&amp;gt;::&amp;lt;template_function_or_operator&amp;gt;&lt;/cite&gt; There is no
callgraph available, this is currently not implemented. Due to the
anarchic way of calling templates from eZTemplate, it is very
difficult to deduct a valid callgraph, maybe I will add this in the
future if I find exactly what I am looking for in the template
engine. The full
&lt;a class="reference external" href="http://github.com/jeromer/ezenhanceddebug"&gt;eZEnhancedDebug&lt;/a&gt;
extension is now hosted at &lt;a class="reference external" href="http://github.com/"&gt;GitHub&lt;/a&gt; .&lt;/p&gt;
&lt;/div&gt;
</summary><category term="ezpublish"></category><category term="ezenhanceddebug"></category></entry><entry><title>Tools I can not work without</title><link href="http://jrenard.info/blog/tools-i-can-not-work-without.html" rel="alternate"></link><updated>2010-04-12T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-04-12:/blog/tools-i-can-not-work-without.html/</id><summary type="html">&lt;p&gt;I wanted to share a bit of informations about the tools I use every
day and which I could not work well without. Let's go.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.vim.org"&gt;Vim&lt;/a&gt;: I spend most of my time editing text
(writing code, sending emails etc, etc) so having an efficient text
editor is really important, I started to work with
&lt;a class="reference external" href="http://www.vim.org"&gt;vim&lt;/a&gt; a few years ago and feel really
cumfortable with it, furthermore I can learn one new feature /
keyboard shortcut every day to make my life even easier.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://hudson-ci.org"&gt;Hudson&lt;/a&gt;: Every time I start working on
something new I define a new job in hudson so all my projects are
build and unit tested automatically on a regular basis. Coupling
hudson and &lt;a class="reference external" href="http://ant.apache.org"&gt;Ant&lt;/a&gt; is a piece of cake. I
appreciate the feeling of being backed up by a tool that will ring
the alarm bell when something is wrong (of course it can do much
more :)).&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://hub.opensolaris.org/bin/view/Project+opengrok"&gt;OpenGrok&lt;/a&gt;:
I discovered that only a few weeks ago and can not live without
since then, this &amp;quot;wicked fast&amp;quot; source code browser is awesome.
Basically you take &lt;a class="reference external" href="http://lucene.apache.org"&gt;Lucene&lt;/a&gt; +
&lt;a class="reference external" href="http://ctags.sourceforge.net"&gt;Excuberant Ctags&lt;/a&gt; + a fair amounf
of java code and then you have it. Installing it on OpenSolaris is
a piece of cake and takes around 5 minutes to get a working
instance :) If you plan to use it on Mac Os X, get ready to fight a
bit, first for installing &lt;a class="reference external" href="http://tomcat.apache.org"&gt;Tomcat&lt;/a&gt; and
then you'll have to patch
&lt;a class="reference external" href="http://src.opensolaris.org/source/xref/opengrok/trunk/OpenGrok"&gt;the OpenGrok shell script&lt;/a&gt;
in order to make it work, but after that, it works just fine. I
really appreciate the way of browsing different code repositories
using different SCM and different programming languages (like shown
below) and to be able to search into one of them easily. Even if
you are a &lt;a class="reference external" href="http://pwet.fr/man/linux/commandes/grep"&gt;grep&lt;/a&gt; wizard
or an &lt;a class="reference external" href="http://betterthangrep.com"&gt;ack&lt;/a&gt; addict, using OpenGrok is
really an interesting complement.&lt;/p&gt;
&lt;p&gt;And you, what are the tools you can not work without ?&lt;/p&gt;
</summary><category term="hudson"></category><category term="vim"></category><category term="opengrok"></category></entry><entry><title>Fetching headers sent by PHP from the command line</title><link href="http://jrenard.info/blog/fetching-headers-sent-by-php-from-the-command-line.html" rel="alternate"></link><updated>2010-03-25T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-03-25:/blog/fetching-headers-sent-by-php-from-the-command-line.html/</id><summary type="html">&lt;p&gt;I needed a way to unit test some code that sends HTTP headers via
the header function. However when doing this from the command line :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
php -r &amp;quot;header('Foo : Bar'); print_r(headers_list());&amp;quot;
&lt;/pre&gt;
&lt;p&gt;The only result you get is an empty array, which makes sense of
course but for unit testing from the command line that is annoying.
&lt;a class="reference external" href="http://xdebug.org/"&gt;XDebug&lt;/a&gt; saves the day again by providing the
&lt;a class="reference external" href="http://xdebug.org/docs/all_functions"&gt;xdebug_get_headers&lt;/a&gt;
function. Let's try the same code, but with
&lt;a class="reference external" href="http://xdebug.org/"&gt;XDebug&lt;/a&gt; this time :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
php -r &amp;quot;header('Foo:Bar'); print_r(xdebug_get_headers());&amp;quot;
&lt;/pre&gt;
&lt;p&gt;Returns&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Array
(
 [0] =&amp;gt; Foo:Bar
)
&lt;/pre&gt;
&lt;p&gt;Joy :)&lt;/p&gt;
</summary><category term="php"></category><category term="xdebug"></category></entry><entry><title>A quick but working startup item for Hudson for Mac OS X</title><link href="http://jrenard.info/blog/a-quick-but-working-startup-item-for-hudson-for-mac-os-x.html" rel="alternate"></link><updated>2010-02-22T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-02-22:/blog/a-quick-but-working-startup-item-for-hudson-for-mac-os-x.html/</id><summary type="html">&lt;p&gt;Hudson is just a great tool but what really annoys me is having to
run &lt;cite&gt;java -jar hudson.war&lt;/cite&gt; all the time. Since I am lazy and stupid I
like having my computer doing the work for me so I created a small
plist file to run hudson as a service, here is the content of the
file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE plist PUBLIC &amp;quot;-//Apple//DTD PLIST 1.0//EN&amp;quot; &amp;quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;plist&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;Label&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Hudson&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;ProgramArguments&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;array&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;/usr/bin/java&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;-jar&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;/path/to/hudson.war&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/array&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;RunAtLoad&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;true/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I saved it in&lt;/p&gt;
&lt;pre class="literal-block"&gt;
~/Library/LaunchAgents/hudson.ci.plist
&lt;/pre&gt;
&lt;p&gt;and enabled it with :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo launchctl load -w ~/Library/LaunchAgents/hudson.ci.plist
&lt;/pre&gt;
&lt;p&gt;Now I have hudson started automatically. No need to have that in
mind in the future :) Note : This file can be of course enhanced.
What I needed was a 5 minutes fix and that file did the trick, if
you have any enhancement feel free to propose them :)&lt;/p&gt;
&lt;p&gt;If you want to disable the startup item just run :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo launchctl unload -w ~/Library/LaunchAgents/hudson.ci.plist
&lt;/pre&gt;
</summary><category term="hudson"></category><category term="macosx"></category></entry><entry><title>Using Hudson in VirtualBox for multi OS testing</title><link href="http://jrenard.info/blog/using-hudson-in-virtualbox-for-multi-os-testing.html" rel="alternate"></link><updated>2010-02-08T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-02-08:/blog/using-hudson-in-virtualbox-for-multi-os-testing.html/</id><summary type="html">&lt;p&gt;For a small project I currently work on I wanted to run my unit
test suites on different operating systems. Since I work on a Mac
and wanted to also run tests on Linux, Virtual Box was exactly what
I needed.&lt;/p&gt;
&lt;div class="section" id="preparing-the-guest"&gt;
&lt;h2&gt;Preparing the guest&lt;/h2&gt;
&lt;p&gt;Just create a new virtual machine, for my project I created a
CentOS guest. Install CentOS and configure it like you want.
Install the guest additions as well, you will have to install quite
a few extra packages in order to get these additions working but
the install script is verbose enough to tell you what to install.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="preparing-the-shared-folder"&gt;
&lt;h2&gt;Preparing the shared folder&lt;/h2&gt;
&lt;p&gt;In your VM configuration, just create a new shared folder which
points to the project you work on, ideally in read-only mode. You
can now mount the shared folder on the guest, like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo mkdir /mnt/shared/folder
&lt;/pre&gt;
&lt;p&gt;Add the following line in your &lt;cite&gt;/etc/fstab&lt;/cite&gt;&lt;/p&gt;
&lt;pre class="literal-block"&gt;
shared-folder-name /mnt/shared/folder vboxsf defaults 0 0
&lt;/pre&gt;
&lt;p&gt;You can now mount the shared folder by simply running:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo mount shared-folder-name
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="installing-hudson"&gt;
&lt;h2&gt;Installing Hudson&lt;/h2&gt;
&lt;p&gt;You should now have a working guest with CentOS. Just install
hudson by using the
&lt;a class="reference external" href="http://hudson-ci.org/redhat/"&gt;native packages available&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="configuring-hudson"&gt;
&lt;h2&gt;Configuring Hudson&lt;/h2&gt;
&lt;p&gt;Create and configure a new job like you would normally do for any
normal hudson job. Below is the configuration for my project,
please note that I use the
&lt;a class="reference external" href="http://wiki.hudson-ci.org/display/HUDSON/Mercurial+Plugin"&gt;mercurial plugin&lt;/a&gt;
and the
&lt;a class="reference external" href="http://wiki.hudson-ci.org/display/HUDSON/Clover+Plugin"&gt;clover plugin&lt;/a&gt;.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Project name : my project&lt;/li&gt;
&lt;li&gt;SCM : mercurial, repository : /mnt/shared/folder with &amp;#64;hourly
build&lt;/li&gt;
&lt;li&gt;Run the following ant targets : rununittests,
runcodingstandardcheck, generatecodecoveragereportclover&lt;/li&gt;
&lt;li&gt;Publish code coverage report : checked in path ci/codecoverage
with file 'clover'&lt;/li&gt;
&lt;li&gt;Activate Chuck Norris : yes (what would be a hudson job without
&lt;a class="reference external" href="http://wiki.hudson-ci.org/display/HUDSON/ChuckNorris+Plugin"&gt;the Chuck Norris plugin&lt;/a&gt;
^_^)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By using such a guest VM I am able to test on 2 different systems, Mac OS ( the host )
and Linux ( the guest ). Next step, test on an Open Solaris guest
:)&lt;/p&gt;
&lt;/div&gt;
</summary><category term="hudson"></category><category term="virtualbox"></category></entry><entry><title>Injecting server variables in a PHP script from an Apache module</title><link href="http://jrenard.info/blog/injecting-server-variables-in-a-php-script-from-an-apache-module.html" rel="alternate"></link><updated>2010-01-21T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-01-21:/blog/injecting-server-variables-in-a-php-script-from-an-apache-module.html/</id><summary type="html">&lt;p&gt;In case it help someone, here is a function that makes it possible
to inject server variables in a PHP script so it is available in
the &lt;cite&gt;$_SERVER&lt;/cite&gt; array. The function looks like this :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;inject_server_variable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request_rec&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;apr_table_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;apr_table_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;subprocess_env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The line&lt;/p&gt;
&lt;pre class="literal-block"&gt;
apr_table_set(r-&amp;gt;notes, name, value);
&lt;/pre&gt;
&lt;p&gt;makes it possible to fetch the variable by using
the &lt;a class="reference external" href="http://php.net/apache_note"&gt;apache_note&lt;/a&gt; function. The
line&lt;/p&gt;
&lt;pre class="literal-block"&gt;
apr_table_set(r-&amp;gt;subprocess_env, name, value);
&lt;/pre&gt;
&lt;p&gt;stores the variable in the &lt;cite&gt;$_SERVER&lt;/cite&gt; array so it can be fetched
only by doing a simple print(&lt;cite&gt;$_SERVER['xxxx']&lt;/cite&gt;) :)&lt;/p&gt;
</summary><category term="c"></category><category term="apache"></category><category term="php"></category></entry><entry><title>Useful links for Apache module development</title><link href="http://jrenard.info/blog/useful-links-for-apache-module-development.html" rel="alternate"></link><updated>2010-01-19T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-01-19:/blog/useful-links-for-apache-module-development.html/</id><summary type="html">&lt;p&gt;If ever you plan to create your own Apache modules, here is a list
of helpful URLs :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://apr.apache.org/docs/apr/1.3/"&gt;APR API doc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://apr.apache.org/docs/apr-util/1.3/"&gt;APR-Util APR doc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.temme.net/sander/api/httpd/index.html"&gt;Apache API doc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial.html"&gt;libapr programming&lt;/a&gt;
(quite old but really useful)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://svn.apache.org/repos/asf/httpd/httpd/trunk/modules/examples/"&gt;example modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.temme.net/sander/2009/11/07/how-to-build-apache-for-development/"&gt;How to Build Apache for Development&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://journal.paul.querna.org/articles/2005/02/23/apr-memory-pools-rock/"&gt;APR Memory Pools Rock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://httpd.apache.org/docs/2.2/developer/"&gt;Developer Documentation for Apache 2.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://apr.apache.org/apr2_0intro/apr2_0intro.htm"&gt;An introduction to APR&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And last but not least the wonderful
&lt;a class="reference external" href="http://www.apachetutor.org/"&gt;Apache Tutor&lt;/a&gt; website. If you have
other interesting links, feel free to post a comment with it and I
will update this post.&lt;/p&gt;
</summary><category term="apache"></category></entry><entry><title>Some notes about Varnish</title><link href="http://jrenard.info/blog/some-notes-about-varnish.html" rel="alternate"></link><updated>2010-01-13T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-01-13:/blog/some-notes-about-varnish.html/</id><summary type="html">&lt;p&gt;A quick memo about useful informations I found on Varnish this
afternoon after digging in the VCL system. I prefer writing them
somewhere before forgetting... The list of variables available in
VCL for each context is available in
&lt;a class="reference external" href="http://varnish.projects.linpro.no/browser/trunk/varnish-cache/lib/libvcl/vcc_obj.c"&gt;libvcl/vcc_obj.c&lt;/a&gt;
which seems to be generated by
&lt;a class="reference external" href="http://varnish.projects.linpro.no/browser/trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl"&gt;lib/libvcl/vcc_gen_fixed_token.tcl&lt;/a&gt;.
In vcc_gen_fixed_token.vcl the following code :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="err"&gt;  &lt;/span&gt; &lt;span class="err"&gt;   &lt;/span&gt; &lt;span class="err"&gt;   &lt;/span&gt; &lt;span class="err"&gt;   &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;IP&lt;/span&gt;
 &lt;span class="n"&gt;RO&lt;/span&gt;
 &lt;span class="n"&gt;all&lt;/span&gt;
 &lt;span class="s"&gt;&amp;quot;const struct sess *&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Results in the following C code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;client.ip&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s"&gt;&amp;quot;VRT_r_client_ip(sp)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;V_RO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;  &lt;/span&gt; &lt;span class="err"&gt;    &lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;VCL_MET_RECV&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VCL_MET_PIPE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VCL_MET_PASS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VCL_MET_HASH&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VCL_MET_MISS&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VCL_MET_HIT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VCL_MET_FETCH&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VCL_MET_DELIVER&lt;/span&gt;
 &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;VCL_MET_ERROR&lt;/span&gt;
 &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&amp;quot;client.ip&amp;quot; is the directive available in a VCL file, &amp;quot;RO&amp;quot; means
Read Only - &amp;quot;RW&amp;quot; (Read Write is available as well) - 'all' means it
is available in all contexts in the VCL file :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_ERROR
&lt;/pre&gt;
&lt;p&gt;The list of functions one can use directly (between C{ ... }C tags)
in VCL seems is available in
&lt;a class="reference external" href="http://varnish.projects.linpro.no/browser/trunk/varnish-cache/include/vrt_obj.h"&gt;include/vrt_obj.h&lt;/a&gt;
&lt;a class="reference external" href="http://varnish.projects.linpro.no/browser/trunk/varnish-cache/bin/varnishd/cache_vrt.c#L187"&gt;VRT_SetHdr&lt;/a&gt;
and
&lt;a class="reference external" href="http://varnish.projects.linpro.no/browser/trunk/varnish-cache/bin/varnishd/cache_vrt.c#L128"&gt;VRT_GetHdr&lt;/a&gt;
are available in
&lt;a class="reference external" href="http://varnish.projects.linpro.no/browser/trunk/varnish-cache/include/vrt.h"&gt;include/vrt.h&lt;/a&gt;
(for the declaration) and in
&lt;a class="reference external" href="http://varnish.projects.linpro.no/browser/trunk/varnish-cache/bin/varnishd/cache_vrt.c"&gt;bin/varnishd/cache_vrt.c&lt;/a&gt;.
It is possible to change the TTL of an item directly by using a few
lines of C code, like for example :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;My&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;ttl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VRT_GetHdr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HDR_OBJ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\012&lt;/span&gt;&lt;span class="s"&gt;My-Header:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;VRT_l_obj_ttl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;atoi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;
   &lt;span class="n"&gt;remove&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;My&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &amp;quot;\012&amp;quot; prepended to &amp;quot;My-Header&amp;quot; is the octal version of the
length of the &amp;quot;My-Header&amp;quot; string. The &amp;quot;sp&amp;quot; variable is the variable
describing the current session. HDR_OBJ is a constant available in
in
&lt;a class="reference external" href="http://varnish.projects.linpro.no/browser/trunk/varnish-cache/include/vrt.h"&gt;include/vrt.h&lt;/a&gt;
:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;gethdr_e&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;HDR_REQ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HDR_RESP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HDR_OBJ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HDR_BEREQ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HDR_BERESP&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It is possible to define custom HTTP headers by using the
&lt;a class="reference external" href="http://varnish.projects.linpro.no/browser/trunk/varnish-cache/bin/varnishd/cache_vrt.c#L187"&gt;VRT_SetHdr&lt;/a&gt;
function available in
&lt;a class="reference external" href="http://varnish.projects.linpro.no/browser/trunk/varnish-cache/bin/varnishd/cache_vrt.c"&gt;bin/varnishd/cache_vrt.c&lt;/a&gt;.
For example :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;contentMD5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;12345&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="n"&gt;VRT_SetHdr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HDR_RESP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\014&lt;/span&gt;&lt;span class="s"&gt;Content-MD5:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contentMD5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vrt_magic_string_end&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Reading the VCC code generated from a VCL file is available by
running : &lt;cite&gt;varnishd -d -f path/to/file.vcl -C&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;Useful links:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://netzreport.googlepages.com/online_converter_for_dec_octal.html"&gt;Octal/Decimal converter&lt;/a&gt;
(Yes, it is good to be lazy :p)&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.lovelysystems.com/configuring-varnish-to-use-custom-http-headers/"&gt;Configuring varnish to use custom http headers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</summary><category term="varnish"></category></entry><entry><title>Using Liquibase for database updates</title><link href="http://jrenard.info/blog/using-liquibase-for-database-updates.html" rel="alternate"></link><updated>2010-01-12T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2010-01-12:/blog/using-liquibase-for-database-updates.html/</id><summary type="html">&lt;p&gt;This is a post-it for me so I get a resource on how to install and
run liquibase in case I forget.&lt;/p&gt;
&lt;div class="section" id="what-is-liquibase"&gt;
&lt;h2&gt;What is Liquibase ?&lt;/h2&gt;
&lt;p&gt;LiquiBase is an open source (LGPL), database-independent library
for tracking, managing and applying database changes. It is built
on a simple premise:&lt;/p&gt;
&lt;blockquote&gt;
All database changes are stored in a human readable yet trackable form and checked into source control.&lt;/blockquote&gt;
&lt;p&gt;Source :&lt;a class="reference external" href="http://www.liquibase.org"&gt;http://www.liquibase.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There are few introductory videos available here :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.liquibase.org/swf/overview_short/liquibase%20overview.html"&gt;Short (6 minute) overview of LiquiBase and its capabilities&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.liquibase.org/swf/overview_long/LiquiBase%20TechTalk.html"&gt;Longer (30 minute) description of LiquiBase and how it works along with a demonstration of several of its features&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="installation"&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;blockquote&gt;
Do not use the RC version because it does not seem to work well
yet. Using 1.9.5 version is fine and works out of the box.&lt;/blockquote&gt;
&lt;p&gt;Download Liquibase here :
&lt;a class="reference external" href="http://www.liquibase.org/download"&gt;http://www.liquibase.org/download&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Store it in :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
/opt/jerome/local/liquibase-1.9.5
&lt;/pre&gt;
&lt;p&gt;Install the Java connector for mysql and postgresql :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo port install mysql-connector-java postgresql-jdbc
&lt;/pre&gt;
&lt;p&gt;Now use the following XML changelog file for testing. Do not expect
any relevancy in this XML file it is just there to test that
Liquibase works :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;databaseChangeLog&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.liquibase.org/xml/ns/dbchangelog/1.7&amp;quot;&lt;/span&gt;
                   &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;
                   &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://www.liquibase.org/xml/ns/dbchangelog/1.7 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.7.xsd&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;changeSet&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;author=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;me&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;comment&amp;gt;&lt;/span&gt;bla bla bla bla&lt;span class="nt"&gt;&amp;lt;/comment&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;createTable&lt;/span&gt; &lt;span class="na"&gt;tableName=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;person&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;column&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;id&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;int&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;constraints&lt;/span&gt; &lt;span class="na"&gt;primaryKey=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;nullable=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/column&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;column&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;firstname&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;java.sql.Types.SMALLINT&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;column&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;lastname&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;java.sql.Types.REAL&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;column&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;username&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;java.sql.Types.LONGVARCHAR&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;constraints&lt;/span&gt; &lt;span class="na"&gt;unique=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;nullable=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/column&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;column&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;testid&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;int&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/createTable&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/changeSet&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/databaseChangeLog&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a class="reference external" href="http://java.sun.com/j2se/1.3/docs/api/java/sql/Types.html"&gt;http://java.sun.com/j2se/1.3/docs/api/java/sql/Types.html&lt;/a&gt;
Use also the following liquibase.properties file&lt;/p&gt;
&lt;pre class="literal-block"&gt;
classpath:/opt/local/share/java/mysql-connector-java-5.0.jar:/opt/local/share/java/postgresql.jar
changeLogFile=createtable.xml

# Mysql Settings
username=root
password=1234
url=jdbc:mysql://localhost/testsliquibase

# Postgres driver
#url=jdbc:postgresql://localhost/postgres
#username=postgres

logLevel=severe
&lt;/pre&gt;
&lt;p&gt;Now try everything works fine:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
liquibase updateSQL
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="troubleshooting"&gt;
&lt;h2&gt;Troubleshooting&lt;/h2&gt;
&lt;p&gt;In case Liquibase fails to connect to MySQL make sure the login
credentials are correct and that it is possible to connect to mysql
by using the mysql CLI client. If yes, but Liquibase still refuses
to connect to MySQL then comment the following line in /etc/hosts :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
::1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; localhost
&lt;/pre&gt;
&lt;p&gt;and retry the liquibase command. It should work now.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="liquibase"></category></entry><entry><title>Backporting ReflectionMethod::setAccessible in PHP 5.3.1</title><link href="http://jrenard.info/blog/backporting-reflectionmethodsetaccessible-in-php-531.html" rel="alternate"></link><updated>2009-12-09T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-12-09:/blog/backporting-reflectionmethodsetaccessible-in-php-531.html/</id><summary type="html">&lt;p&gt;I needed the
&lt;a class="reference external" href="http://fr.php.net/manual/en/reflectionmethod.setaccessible.php"&gt;ReflectionMethod::setAccessible&lt;/a&gt;
method for one of my script. But after reading the
&lt;a class="reference external" href="http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/NEWS?view=markup&amp;amp;pathrev=289774"&gt;CHANGELOG&lt;/a&gt;
I realized that it is available for PHP 5.3.2 only. Since PHP 5.3.2
is not released yet I was blocked :/ So I decided to add
ReflectionMethod::setAccessible in my version of PHP so I can use
it in my scripts. The backport is available here :
&lt;a class="reference external" href="/blog/downloads/reflection.diff.gz"&gt;reflection.diff.gz&lt;/a&gt;
You can install it by following the method below:&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;download the patch above&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;download the PHP 5.3.1 tarball and extract it&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;apply the patch&lt;/p&gt;
&lt;pre class="literal-block"&gt;
patch -p0 --verbose &amp;lt; ./reflection.diff
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;run the standard &lt;cite&gt;./configure [...] &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make test &amp;amp;&amp;amp; sudo
make install&lt;/cite&gt; commands. Alternatively, if you only want to test the
Reflection extension you can do the following, after running &amp;quot;make&amp;quot;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
export TEST_PHP_EXECUTABLE=&amp;quot;./sapi/cli/php&amp;quot; &amp;amp;&amp;amp; php ./run-tests.php ext/reflection/tests
&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre class="literal-block"&gt;
export TEST_PHP_EXECUTABLE=&amp;quot;./sapi/cli/php&amp;quot; &amp;amp;&amp;amp; php ./run-tests.php ext/reflection/tests/ReflectionMethod_setAccessible.phpt
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But in any case, you should get :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
==========================================
Number of tests :&amp;nbsp; 267&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 267
Tests skipped&amp;nbsp;&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 (&amp;nbsp; 0.0%) --------
Tests warned&amp;nbsp;&amp;nbsp;&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 (&amp;nbsp; 0.0%) (&amp;nbsp; 0.0%)
Tests failed&amp;nbsp;&amp;nbsp;&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 (&amp;nbsp; 0.0%) (&amp;nbsp; 0.0%)
Expected fail&amp;nbsp;&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 (&amp;nbsp; 0.0%) (&amp;nbsp; 0.0%)
Tests passed&amp;nbsp;&amp;nbsp;&amp;nbsp; :&amp;nbsp; 267 (100.0%) (100.0%)
------------------------------------------
Time taken&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp; 9 seconds
==========================================
&lt;/pre&gt;
&lt;p&gt;All Reflection tests must pass. 'Hope that helps :)&lt;/p&gt;
</summary><category term="php"></category></entry><entry><title>Back from the PHP conference in Paris</title><link href="http://jrenard.info/blog/back-from-the-php-conference-in-paris.html" rel="alternate"></link><updated>2009-11-14T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-11-14:/blog/back-from-the-php-conference-in-paris.html/</id><summary type="html">&lt;p&gt;Thanks to my friend &lt;a class="reference external" href="http://twitter.com/arnaudlimbourg/"&gt;Arnaud&lt;/a&gt;
I have been able to come to Paris in order to attend the last day
of the PHP conference. That was great and the talks were
interesting. I had a interesting discussion
with&amp;nbsp;&lt;a class="reference external" href="http://schlueters.de/"&gt;Johannes Schlüter&lt;/a&gt; about
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/DTrace"&gt;DTrace&lt;/a&gt; (I was happy to
meet another Dtrace addict :)) and he gave me the solution to run
Skype on Open Solaris so I'll test it and if that works then I'll
switch to Open Solaris fully and get rid of Mac OS X. We also had
an interesting dicussion on PHP6, and it seems we have the same
concers. I also met a lot of people in the community I had not met
for a while: Julien, Jean-Marc, Perrick, Damien (sorry I did not
test the Snickers pie yet), FreshDaz, Cyril... I was really happy
to meet you all. I also had the chance (and the honnor) to discuss
with &lt;a class="reference external" href="http://askmonty.org"&gt;Monty&lt;/a&gt; along with my colleague
&lt;a class="reference external" href="http://patrickallaert.blogspot.com/"&gt;Patrick&lt;/a&gt;. And I have to say
that he really opened my mind to something I was secretely looking
for. Thanks a lot to all the team in charge of the organisation, I
am sure you sweated a lot, but that was really worth it.&lt;/p&gt;
</summary><category term="php"></category><category term="afup"></category><category term="paris"></category></entry><entry><title>Apache .htaccess and disk access, a quick but deeper look</title><link href="http://jrenard.info/blog/apache-htaccess-and-disk-access-a-quick-but-deeper-look.html" rel="alternate"></link><updated>2009-10-30T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-10-30:/blog/apache-htaccess-and-disk-access-a-quick-but-deeper-look.html/</id><summary type="html">&lt;p&gt;I was discussing (well twitting is more appropriate) with my friend
&lt;a class="reference external" href="http://twitter.com/arnaudlimbourg/"&gt;Arnaud&lt;/a&gt; about &lt;cite&gt;.htaccess&lt;/cite&gt;
files and why they should not be used. To be quick, using .htacess
files is not good at all for disk performance because Apache will
hit the disk for each HTTP request, so when the site is on
production you can easily imagine this can quickly be an issue if
you use those files. But let's have a look at how it actually work
on the system. Remember, for each HTTP request Apache will look on
your file system if it finds a &lt;cite&gt;.htaccess&lt;/cite&gt; file. So if we create the
following virtual web application :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
webproject
|-- cache
|-- design
|&amp;nbsp;&amp;nbsp; |-- css
|&amp;nbsp;&amp;nbsp; |-- html
|&amp;nbsp;&amp;nbsp; |-- images
|&amp;nbsp;&amp;nbsp; `-- javascript
`-- src
 |-- php
 `-- python
&lt;/pre&gt;
&lt;p&gt;With the following directive in your Apache configuration file
(wether a VirtualHost or not) :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;lt;Directory &amp;quot;/path/to/webproject/&amp;quot;&amp;gt;
 AllowOverride All
 [....]
&amp;lt;/Directory&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now let's have a look at how Apache handle AllowOverride on the
Operating System, what happens if I visit the 'webproject/src'
directory ? Calling &lt;a class="reference external" href="http://localhost/webproject/src"&gt;http://localhost/webproject/src&lt;/a&gt; generated the
following system calls&lt;/p&gt;
&lt;pre class="literal-block"&gt;
1679/0x97c9998:&amp;nbsp; open(&amp;quot;/Users/jerome/work/www/.htaccess\0&amp;quot;, 0x0, 0x1B6)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; = -1 Err#2
1679/0x97c9998:&amp;nbsp; open(&amp;quot;/Users/jerome/work/www/webproject/.htaccess\0&amp;quot;, 0x0, 0x1B6)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; = -1 Err#2
1679/0x97c9998:&amp;nbsp; open(&amp;quot;/Users/jerome/work/www/webproject/cache/.htaccess\0&amp;quot;, 0x0, 0x1B6)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; = -1 Err#2
1679/0x97c9998:&amp;nbsp; open(&amp;quot;/Users/jerome/work/www/webproject/design/.htaccess\0&amp;quot;, 0x0, 0x1B6)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; = -1 Err#2
1679/0x97c9998:&amp;nbsp; open(&amp;quot;/Users/jerome/work/www/webproject/src/.htaccess\0&amp;quot;, 0x0, 0x1B6)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; = -1 Err#2
1679/0x97c9998:&amp;nbsp; open(&amp;quot;/Users/jerome/work/www/webproject/src/python/.htaccess\0&amp;quot;, 0x0, 0x1B6)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; = -1 Err#2
1679/0x97c9998:&amp;nbsp; open(&amp;quot;/Users/jerome/work/www/.htaccess\0&amp;quot;, 0x0, 0x1B6)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; = -1 Err#2
1679/0x97c9998:&amp;nbsp; open(&amp;quot;/Users/jerome/work/www/webproject/.htaccess\0&amp;quot;, 0x0, 0x1B6)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; = -1 Err#2
1679/0x97c9998:&amp;nbsp; open(&amp;quot;/Users/jerome/work/www/webproject/src/.htaccess\0&amp;quot;, 0x0, 0x1B6)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; = -1 Err#2
1679/0x97c9998:&amp;nbsp; open(&amp;quot;/Users/jerome/work/www/webproject/src/php/.htaccess\0&amp;quot;, 0x0, 0x1B6)&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; = -1 Err#2
&lt;/pre&gt;
&lt;p&gt;As you can see Apache looked for the &lt;cite&gt;.htaccess&lt;/cite&gt; file for each
directory I had to browse in order to go to the &lt;cite&gt;webfolder/src
directory&lt;/cite&gt;. That is a simple example, but if you have a much more
complex directory structure and a lot of traffic I guess you can
imagine how much Apache is going to hit the disk in order to find a
&lt;cite&gt;.htaccess&lt;/cite&gt; file. So in order to avoid that it is always recommended
to configure everything in VirtualHosts and to avoid &lt;cite&gt;.htaccess&lt;/cite&gt;
files.&lt;/p&gt;
&lt;p&gt;'Hope that helped a bit :)&lt;/p&gt;
</summary><category term="apache"></category><category term="performance"></category><category term="dtrace"></category><category term="dtruss"></category></entry><entry><title>An alternative method to build eZ Publish configuration files with ANT and the C Preprocessor</title><link href="http://jrenard.info/blog/an-alternative-method-to-build-ez-publish-configuration-files-with-ant-and-the-c-preprocessor.html" rel="alternate"></link><updated>2009-10-18T12:47:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-10-18:/blog/an-alternative-method-to-build-ez-publish-configuration-files-with-ant-and-the-c-preprocessor.html/</id><summary type="html">&lt;p&gt;eZ Publish configuration files have a major problem : they are not
context aware. This means that you can not build them especially
for production or development servers. I thought about a solution
to sort of workaround this problem by using the C preprocessor and
macros in configuration files. Let's take a simple example. When
you work with override.ini directives, you have to write a few
configuration directives in order to load the correct template for
the correct context, for example, a nodeID. But if this nodeID
change between servers, you could have for example this on your
development machine :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;[foo_bar]&lt;/span&gt;
&lt;span class="err"&gt;....&lt;/span&gt;
&lt;span class="na"&gt;Match[node]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;123&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;this on your staging machine :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;[foo_bar]&lt;/span&gt;
&lt;span class="err"&gt;....&lt;/span&gt;
&lt;span class="na"&gt;Match[node]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;456&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;this on your production machine :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;[foo_bar]&lt;/span&gt;
&lt;span class="err"&gt;....&lt;/span&gt;
&lt;span class="na"&gt;Match[node]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;789&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When it comes to industrialize the process of creating correct
configuration files with correct nodeIDs (or any other
configuration directives) things become more and more complex. It
would be interesting to be able to include the correct values
depending on the context in which you want to use your
configuration files. This is where the C preprocessor comes into
play, by using specific macros like #include or #ifdef we can
generate context aware configuration files without any problem,
simply by including the correct configuration file and integrate it
into the real eZ Publish one. For example for
override.ini.append.php, this gives the following
override.ini.append.php file :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="cm"&gt;/* #?ini charset=&amp;quot;utf-8&amp;quot;?&lt;/span&gt;

&lt;span class="cm"&gt;[full_folder]&lt;/span&gt;
&lt;span class="cm"&gt;Source=node/view/full.tpl&lt;/span&gt;
&lt;span class="cm"&gt;MatchFile=full/folder.tpl&lt;/span&gt;
&lt;span class="cm"&gt;Subdir=templates&lt;/span&gt;
&lt;span class="cm"&gt;Match[class_identifier]=folder&lt;/span&gt;

&lt;span class="cm"&gt;[line_folder]&lt;/span&gt;
&lt;span class="cm"&gt;Source=node/view/line.tpl&lt;/span&gt;
&lt;span class="cm"&gt;MatchFile=line/folder.tpl&lt;/span&gt;
&lt;span class="cm"&gt;Subdir=templates&lt;/span&gt;
&lt;span class="cm"&gt;Match[class_identifier]=folder&lt;/span&gt;

&lt;span class="cm"&gt;// some comments&lt;/span&gt;
&lt;span class="cm"&gt;// in the ini file&lt;/span&gt;
&lt;span class="cm"&gt;// they will automatically&lt;/span&gt;
&lt;span class="cm"&gt;// transformed into correct&lt;/span&gt;
&lt;span class="cm"&gt;// eZINI comments&lt;/span&gt;

&lt;span class="cm"&gt;#ifdef CONTEXT_DEV&lt;/span&gt;
&lt;span class="cm"&gt;#include &amp;quot;override.ini.dev&amp;quot;&lt;/span&gt;
&lt;span class="cm"&gt;#endif&lt;/span&gt;

&lt;span class="cm"&gt;#ifdef CONTEXT_STAGING&lt;/span&gt;
&lt;span class="cm"&gt;#include &amp;quot;override.ini.staging&amp;quot;&lt;/span&gt;
&lt;span class="cm"&gt;#endif&lt;/span&gt;

&lt;span class="cm"&gt;#ifdef CONTEXT_PROD&lt;/span&gt;
&lt;span class="cm"&gt;#include &amp;quot;override.ini.prod&amp;quot;&lt;/span&gt;
&lt;span class="cm"&gt;#endif&lt;/span&gt;

&lt;span class="cm"&gt;*/&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With the following included files override.ini.dev&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;global&lt;/span&gt; &lt;span class="err"&gt;overrides&lt;/span&gt;
&lt;span class="k"&gt;[my_dev_override]&lt;/span&gt;
&lt;span class="na"&gt;Source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;path/to/template.tpl&lt;/span&gt;
&lt;span class="na"&gt;MatchFile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;path/to/matchfile.tpl&lt;/span&gt;
&lt;span class="na"&gt;Subdir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;templates&lt;/span&gt;
&lt;span class="na"&gt;Match[node]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;11111&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;override.ini.staging&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;global&lt;/span&gt; &lt;span class="err"&gt;overrides&lt;/span&gt;
&lt;span class="k"&gt;[my_staging_override]&lt;/span&gt;
&lt;span class="na"&gt;Source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;path/to/template.tpl&lt;/span&gt;
&lt;span class="na"&gt;MatchFile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;path/to/matchfile.tpl&lt;/span&gt;
&lt;span class="na"&gt;Subdir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;templates&lt;/span&gt;
&lt;span class="na"&gt;Match[node]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;22222&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;override.ini.prod&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;global&lt;/span&gt; &lt;span class="err"&gt;overrides&lt;/span&gt;
&lt;span class="k"&gt;[my_prod_override]&lt;/span&gt;
&lt;span class="na"&gt;Source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;path/to/template.tpl&lt;/span&gt;
&lt;span class="na"&gt;MatchFile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;path/to/matchfile.tpl&lt;/span&gt;
&lt;span class="na"&gt;Subdir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;templates&lt;/span&gt;
&lt;span class="na"&gt;Match[node]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;33333&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So when we run (note this is not that simple, but I took a few
shortcuts in order to be quick)&lt;/p&gt;
&lt;pre class="literal-block"&gt;
cpp -P -DCONTEXT_PROD=1 override.ini.append.php
&lt;/pre&gt;
&lt;p&gt;We get the following result :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="cm"&gt;/* #?ini charset=&amp;quot;utf-8&amp;quot;?&lt;/span&gt;

&lt;span class="cm"&gt;[full_folder]&lt;/span&gt;
&lt;span class="cm"&gt;Source=node/view/full.tpl&lt;/span&gt;
&lt;span class="cm"&gt;MatchFile=full/folder.tpl&lt;/span&gt;
&lt;span class="cm"&gt;Subdir=templates&lt;/span&gt;
&lt;span class="cm"&gt;Match[class_identifier]=folder&lt;/span&gt;

&lt;span class="cm"&gt;[line_folder]&lt;/span&gt;
&lt;span class="cm"&gt;Source=node/view/line.tpl&lt;/span&gt;
&lt;span class="cm"&gt;MatchFile=line/folder.tpl&lt;/span&gt;
&lt;span class="cm"&gt;Subdir=templates&lt;/span&gt;
&lt;span class="cm"&gt;Match[class_identifier]=folder&lt;/span&gt;

&lt;span class="cm"&gt;# some comments&lt;/span&gt;
&lt;span class="cm"&gt;# in the ini file&lt;/span&gt;
&lt;span class="cm"&gt;# they will automatically&lt;/span&gt;
&lt;span class="cm"&gt;# transformed into correct&lt;/span&gt;
&lt;span class="cm"&gt;# eZINI comments&lt;/span&gt;
&lt;span class="cm"&gt;# global overrides&lt;/span&gt;

&lt;span class="cm"&gt;[my_prod_override]&lt;/span&gt;
&lt;span class="cm"&gt;Source=path/to/template.tpl&lt;/span&gt;
&lt;span class="cm"&gt;MatchFile=path/to/matchfile.tpl&lt;/span&gt;
&lt;span class="cm"&gt;Subdir=templates&lt;/span&gt;
&lt;span class="cm"&gt;Match[node]=33333&lt;/span&gt;

&lt;span class="cm"&gt;*/&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As we can see, override.ini.append.php has been created with the
correct production nodeID. Since calling cpp is quite annoying with
this ini syntax (mostly due to the presence of PHP comments) I
decided to automate the process by wrapping everything into an Ant
build script. With the script, building all configuration files
should be as easy as running&lt;/p&gt;
&lt;pre class="literal-block"&gt;
ant clean &amp;amp;&amp;amp; ant dev
&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre class="literal-block"&gt;
ant clean &amp;amp;&amp;amp; ant staging
&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre class="literal-block"&gt;
ant clean &amp;amp;&amp;amp; ant prod
&lt;/pre&gt;
&lt;p&gt;You will find attached a tarball with a fake eZ Publish instance
plus settings and context files. By running of of the commands
above, you can generate your configuration files in no time. Here
is an explanation of the ant script's behaviour. First you have to
have the following directory structure :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
.
|-- build.xml
|-- common.xml
`-- fakeezinstance
    |-- build.xml
    |-- extension
    |   `-- myextension
    |       |-- build.xml
    |       `-- settings.orig
    |           |-- dbsettings.dev
    |           |-- dbsettings.prod
    |           |-- dbsettings.staging
    |           |-- site.ini.append.php
    |           `-- siteaccess
    |               `-- site.com
    |                   |-- override.ini.append.php
    |                   |-- override.ini.dev
    |                   |-- override.ini.prod
    |                   `-- override.ini.staging
    `-- settings.orig
        |-- override
        |   |-- override.ini.append.php
        |   |-- override.ini.dev
        |   |-- override.ini.prod
        |   `-- override.ini.staging
        `-- siteaccess
            `-- site.com
                |-- override.ini.append.php
                |-- override.ini.dev
                |-- override.ini.prod
                `-- override.ini.staging
&lt;/pre&gt;
&lt;p&gt;As you can see any original settings are located into settings.orig
directories. Each of them contains configuration files, I just
created an example with override.ini and site.ini. But you can use
any configuration file. For each .ini file I created a context
file, dbsettings.dev/staging/prod for site.ini for example. Once
the configuration files are ready, we can simply run :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
ant clean &amp;amp;&amp;amp; ant prod
&lt;/pre&gt;
&lt;p&gt;And you will see that all settings folder will be created with the
correct values. If you want to add another extension in the build,
the only thing you have to do is to copy the build.xml file
available in extension/myextension and create a settings.orig
directory structure. If you do not want your extension(s) to be
processed by the build script, just do not copy the build.xml file
and create the settings directory structure as you would normally
do. So one can say that there is a lot of blank lines in the files
onces they have been preprocessed. That is true, but remember that
those files are supposed to be read by eZ Publish only. If
fakeezproject.taryou need to change anything, just update the file
you want in settings.orig and rerun the build process, it takes
less than 2 seconds. Download the
&lt;a class="reference external" href="/blog/downloads/fakeezproject.tar.gz"&gt;fakeezproject.tar&lt;/a&gt;
archive, go in fakeproject ant run ant prod for example. 'Hope that
helps.&lt;/p&gt;
</summary><category term="ANT"></category><category term="CPP"></category><category term="ezpublish"></category></entry><entry><title>Linting an eZ Publish template file in Vim</title><link href="http://jrenard.info/blog/linting-an-ez-publish-template-file-in-vim.html" rel="alternate"></link><updated>2009-10-03T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-10-03:/blog/linting-an-ez-publish-template-file-in-vim.html/</id><summary type="html">&lt;p&gt;Sometimes when I do eZ Publish templating I want to check if my
template is syntactically correct without refreshing the page I am
working on. And what I like with Vim is to run :make and get
everything checked (and compiled if needed). So I updated my
configuration file for eZ Publish templates. I defined all .tpl
files as Smarty, so in my ~/.vim/filetype.vim I have the following
content :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
au BufNewFile,BufRead *.tpl setf smarty
&lt;/pre&gt;
&lt;p&gt;And in &lt;cite&gt;~/.vim/ftplugin/smarty.vim&lt;/cite&gt; I have :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
set makeprg=php\ \.\/bin\/php\/eztemplatecheck\.php\ --debug=error\ --no-colors\ %
&lt;/pre&gt;
&lt;p&gt;So now for each eZ Publish template I edit I can run :make and see
if I did syntax errors or not. This requires that you edit all your
template from the top directory of your eZ Publish instance,
otherwise it will not work.&lt;/p&gt;
</summary><category term="ezpublish"></category><category term="vim"></category></entry><entry><title>How-to find the Unicode value for a character in Vim</title><link href="http://jrenard.info/blog/how-to-find-the-unicode-value-for-a-character-in-vim.html" rel="alternate"></link><updated>2009-08-26T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-08-26:/blog/how-to-find-the-unicode-value-for-a-character-in-vim.html/</id><summary type="html">&lt;p&gt;I was looking for a way to easily find an Unicode value for a
character in Vim. The solution is actually quite trivial, move the
cursor on a char and write 'g8' you should see the UTF-8 value for
this char. For example with a left curly bracket '{' Vim displays
'7b' which results in U+007B. It is also possible to use 'ga' to
get the decimal, hexadecimal and octal value of a string. How to
find the unicode value of a character ?&lt;/p&gt;
&lt;blockquote&gt;
&lt;a class="reference external" href="http://www.cs.tut.fi/%7Ejkorpela/chars.html#10646"&gt;Unicode&lt;/a&gt;
characters are commonly referred to using a notation like
&lt;tt class="docutils literal"&gt;U+nnnn&lt;/tt&gt; where nnnn is a four-digit
&lt;a class="reference external" href="http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?query=hexadecimal&amp;amp;action=Search"&gt;hexadecimal&lt;/a&gt;
(base 16) number specifying the
&lt;a class="reference external" href="http://www.cs.tut.fi/%7Ejkorpela/chars.html#code"&gt;code position&lt;/a&gt;
of the character in Unicode. For example, the space character has
the same code number in Unicode as in ISO 8859-1, namely 32
decimal, 20 hexadecimal; thus, it can be denoted as &lt;cite&gt;U+0020&lt;/cite&gt;.
Generally, a notation like &lt;tt class="docutils literal"&gt;U+nnnn&lt;/tt&gt; is needed for referring to
characters uniquely in contexts where one cannot reliably present
the character itself.&lt;/blockquote&gt;
&lt;p&gt;Source : &lt;a class="reference external" href="http://www.cs.tut.fi/~jkorpela/latin1/all.html"&gt;http://www.cs.tut.fi/~jkorpela/latin1/all.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Useful links&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.vim.org/htmldoc/various.html#g8"&gt;Vim man page about g8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://http://www.vim.org/htmldoc/various.html#ga"&gt;Vim man page about ga&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.fileformat.info/info/unicode/char/a.htm"&gt;Full Unicode table&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.zvon.org/other/charSearch/PHP/search.php"&gt;Zvon character search&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</summary><category term="unicode"></category><category term="vim"></category></entry><entry><title>Diffing two directories</title><link href="http://jrenard.info/blog/diffing-two-directories.html" rel="alternate"></link><updated>2009-08-25T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-08-25:/blog/diffing-two-directories.html/</id><summary type="html">&lt;p&gt;Finding which files differ :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
diff -Naurq dir1 dir2
&lt;/pre&gt;
&lt;p&gt;Outputing all the differences in VI&lt;/p&gt;
&lt;pre class="literal-block"&gt;
diff -Naur dir1 dir2 | vi -
&lt;/pre&gt;
&lt;p&gt;Or in colordiff&lt;/p&gt;
&lt;pre class="literal-block"&gt;
diff -Naur dir1 dir2 | colordiff
&lt;/pre&gt;
&lt;p&gt;Now I have no excuse to forget this all the time ...&lt;/p&gt;
</summary><category term="diff"></category></entry><entry><title>Parsing XML files with APR</title><link href="http://jrenard.info/blog/parsing-xml-files-with-apr.html" rel="alternate"></link><updated>2009-08-17T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-08-17:/blog/parsing-xml-files-with-apr.html/</id><summary type="html">&lt;p&gt;I wanted to write an XML parser for one of my personal projects,
and I needed to use &lt;a class="reference external" href="http://apache.org/"&gt;Apache&lt;/a&gt;
&lt;a class="reference external" href="http://apr.apache.org/"&gt;APR&lt;/a&gt; for this. Since I did not find any
example about doing this on the web I thought it might be a good
idea to write a short tutorial about this. Maybe it could be
helpful to someone else. Let's prepare the tutorial, we need a XML
file, for example this one example.xml :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;document&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;someattribute=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;attribute of A&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;the value of B&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/document&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And a Makefile, for example this one :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;APR_CONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;shell which apr-1-config&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;CC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gcc
&lt;span class="nv"&gt;CXX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;g++
&lt;span class="nv"&gt;CFLAGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;shell &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APR_CONFIG&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; --cflags --cppflags --includes&lt;span class="k"&gt;)&lt;/span&gt; -Wall
&lt;span class="nv"&gt;CXXFLAGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;shell &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APR_CONFIG&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; --cflags --cppflags --includes&lt;span class="k"&gt;)&lt;/span&gt; -Wall
&lt;span class="nv"&gt;LDFLAGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;shell &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APR_CONFIG&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; --ldflags&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;LDLIBS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;shell &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;APR_CONFIG&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; --libs --link-ld&lt;span class="k"&gt;)&lt;/span&gt; -laprutil-1
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now the parser, parse.c:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;#ifdef HAVE_CONFIG_H&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;

&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt;* Dumps an XML document&lt;/span&gt;
&lt;span class="cm"&gt;*/&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;dump_xml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;apr_xml_elem&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;apr_pool_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;apr_xml_elem&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;child_element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;This tag has an attribute : &amp;lt;%s %s=%s&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;first_child&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;child_element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;first_child&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;child_element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;lt;%s&amp;gt; --&amp;gt; &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;child_element&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;APR_XML_ELEM_IS_EMPTY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;child_element&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;apr_xml_to_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;child_element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;APR_XML_X2T_INNER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;dump_xml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;child_element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;child_element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;child_element&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt;* Process an XML file&lt;/span&gt;
&lt;span class="cm"&gt;* @return APR_SUCCESS if success, otherwise -1&lt;/span&gt;
&lt;span class="cm"&gt;*/&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;process_xml_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;apr_pool_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;apr_file_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;apr_status_t&lt;/span&gt; &lt;span class="n"&gt;rv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;apr_xml_parser&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;apr_xml_doc&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;errbuf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apr_file_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;APR_FOPEN_READ&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;APR_OS_DEFAULT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;APR_SUCCESS&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apr_xml_parse_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;APR_SUCCESS&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;APR Error %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;apr_strerror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;rv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errbuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;XML Error : %s&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;apr_xml_parser_geterror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errbuf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;dump_xml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;APR_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;apr_pool_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;example.xml&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;apr_initialize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;apr_pool_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;process_xml_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;apr_terminate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now store example.xml and parse.c in the same directory and build
parse.c&lt;/p&gt;
&lt;pre class="literal-block"&gt;
make parse &amp;amp;&amp;amp; ./parse filename.xml
&lt;/pre&gt;
&lt;p&gt;You should get the following result:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;lt;a&amp;gt; --&amp;gt; &amp;lt;b&amp;gt;the value of B&amp;lt;/b&amp;gt;
This tag has an attribute : &amp;lt;a someattribute=attribute of A&amp;gt;
&amp;lt;b&amp;gt; --&amp;gt; the value of B
&lt;/pre&gt;
&lt;p&gt;Some useful documentation :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://apr.apache.org/docs/apr-util/1.3/apr__xml_8h.html"&gt;http://apr.apache.org/docs/apr-util/1.3/apr__xml_8h.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Edit:
Many thanks to Riccardo Campisano for his feedback.&lt;/p&gt;
</summary><category term="apache"></category><category term="apr"></category><category term="c"></category></entry><entry><title>Overriding kernel files in eZ Publish</title><link href="http://jrenard.info/blog/overriding-kernel-files-in-ez-publish.html" rel="alternate"></link><updated>2009-08-12T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-08-12:/blog/overriding-kernel-files-in-ez-publish.html/</id><summary type="html">&lt;p&gt;Here is a 30 seconds tutorial on how to override kernel files in eZ
Publish. The file used for this example is
&lt;cite&gt;ezcontentobjecttreenode.php&lt;/cite&gt; but you can use exactly the same method
for any class of the &lt;cite&gt;kernel/&lt;/cite&gt; or &lt;cite&gt;lib/&lt;/cite&gt; directory.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
cd path/to/ezpublish mkdir -p extension/myextension/classes/kerneloverride
cp kernel/classes/ezcontentobjecttreenode.php extension/myextension/classes/kerneloverride
echo &amp;quot;define( 'EZP_AUTOLOAD_ALLOW_KERNEL_OVERRIDE', true );&amp;quot; &amp;gt; config.php php
./bin/php/ezpgenerateautoloads.php -o
&lt;/pre&gt;
&lt;p&gt;That is it.&lt;/p&gt;
</summary><category term="ezpublish"></category></entry><entry><title>Creating private targets with Ant</title><link href="http://jrenard.info/blog/creating-private-targets-with-ant.html" rel="alternate"></link><updated>2009-07-30T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-07-30:/blog/creating-private-targets-with-ant.html/</id><summary type="html">&lt;p&gt;I have been using &lt;a class="reference external" href="http://ant.apache.org/"&gt;Ant&lt;/a&gt; for quite a few
weeks now, trying to get rid of the eZ Publish' 6000 lines shell
script build system and then using &lt;a class="reference external" href="http://ant.apache.org/"&gt;Ant&lt;/a&gt;
almost exclusively. I was looking for a way to create private
targets, i.e targets which could not be called by the user. I
finally found the solution, and it is quite trivial, just prefix
your target's name with a dash. Let's do a quick &amp;quot;before/after&amp;quot;
comparison.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;MyProject&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;basedir=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;.&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;default=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;build&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;target&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;public&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;echo&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Calling public target&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;target&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;private&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;echo&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Calling private target&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and calling &lt;tt class="docutils literal"&gt;ant public private&lt;/tt&gt; returns :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
public: [echo] Calling public target
private: [echo] Calling private target
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;MyProject&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;basedir=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;.&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;default=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;build&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;target&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;public&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;echo&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Calling public target&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;target&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-private&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;echo&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Calling private target&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/target&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and then call the build file again, which returns :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
public: [echo] Calling public target
BUILD FAILED
Target &amp;quot;private&amp;quot; does not exist in the project &amp;quot;MyProject&amp;quot;.
&lt;/pre&gt;
&lt;p&gt;By prefixing the &amp;quot;private&amp;quot; target with a &amp;quot;-&amp;quot; I made it private, well
invisible would be more appropriate because
&lt;a class="reference external" href="http://www.nabble.com/AW%3A-private-targets-p15560447.html"&gt;there is no real concept of private targets&lt;/a&gt;
in &lt;a class="reference external" href="http://ant.apache.org/"&gt;Ant&lt;/a&gt;. But at least it is not callable
from the end-user which is exactly what I was looking for.&lt;/p&gt;
</summary><category term="ant"></category></entry><entry><title>Backward search in your history with ZSH</title><link href="http://jrenard.info/blog/backward-search-in-your-history-with-zsh.html" rel="alternate"></link><updated>2009-07-29T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-07-29:/blog/backward-search-in-your-history-with-zsh.html/</id><summary type="html">&lt;p&gt;Bash has a cool native feature, backward search in your history.
&lt;a class="reference external" href="http://zsh.dotsrc.org/"&gt;Zsh&lt;/a&gt; has the same feature but you need
enable it. Here is how to do it :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
# Bacward search in the shell history with &amp;lt;C-r&amp;gt;
bindkey ^r&amp;nbsp; history-incremental-search-backward
setopt hist_ignore_all_dups
&lt;/pre&gt;
&lt;p&gt;Just add the lines above in your &lt;cite&gt;~/.zshrc&lt;/cite&gt; and then source the file
again :&lt;/p&gt;
&lt;pre class="literal-block"&gt;
source ~/.zshrc
&lt;/pre&gt;
&lt;p&gt;Now you should be able to search in your history with CTRL+r
exactly like you would do with bash.&lt;/p&gt;
</summary><category term="zsh"></category></entry><entry><title>Compiling PHP 5.3 on Mac OS X</title><link href="http://jrenard.info/blog/compiling-php-53-on-mac-os-x.html" rel="alternate"></link><updated>2009-07-18T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-07-18:/blog/compiling-php-53-on-mac-os-x.html/</id><summary type="html">&lt;p&gt;A few people find it hard to compile PHP on Mac OS X and prefer
using tools like &lt;a class="reference external" href="http://www.mamp.info/"&gt;Mamp&lt;/a&gt; or
&lt;a class="reference external" href="http://www.macports.org/"&gt;MacPorts&lt;/a&gt;. Even though
&lt;a class="reference external" href="http://www.macports.org/"&gt;MacPorts&lt;/a&gt; is useful I prefer compiling
&lt;a class="reference external" href="http://php.net"&gt;PHP&lt;/a&gt; by myself, here is a step by step tutorial.&lt;/p&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;This tutorial has been written for Mac OS X 10.4 but I am
sure it is the same for more recent versions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;With the configuration directives described below PHP is
compiled in CGI/FastCGI mode if you want to use it as an Apache
module this only thing you have is to do is to use the following
extra argument : &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--with-apxs2=/path/to/apache2/apxs&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;Downloading PHP 5.3
&lt;tt class="docutils literal"&gt;wget &lt;span class="pre"&gt;http://fr3.php.net/get/php-5.3.0.tar.gz/from/fr.php.net/mirror&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Extracting the tarball &lt;tt class="docutils literal"&gt;tar zxvf &lt;span class="pre"&gt;php-5.3.0.tar.gz&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Configuring PHP&lt;/p&gt;
&lt;pre class="literal-block"&gt;
cd php-5.3.0
./configure \\ --prefix=/opt/php5
\\ --enable-exif \\ --with-gd=/opt/local \\
--with-freetype-dir=/opt/local \\ --with-jpeg-dir=/opt/local \\
--enable-gd-native-ttf \\ --with-png-dir=/opt/local \\
--with-t1lib=/opt/local \\ --with-zlib=/opt/local \\
--with-mysql=/usr/local/mysql \\ --with-mysqli \\ --with-ldap \\
--enable-mbstring \\ --with-mcrypt=/opt/local \\
--with-bz2=/usr/bin \\ --enable-ctype \\ --enable-dom \\
--enable-libxml \\ --with-iconv \\ --enable-pdo \\
--with-pdo-sqlite \\ --enable-posix \\ --enable-simplexml \\
--enable-xml \\ --with-zlib \\ --with-curl \\ --enable-filter \\
--with-pdo-mysql=/usr/local/mysql \\ --with-openssl \\
--with-xmlrpc \\ --with-xsl \\ --enable-soap \\ --enable-ftp \\
--enable-pcntl \\ --enable-shmop
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Compiling and installing&lt;/p&gt;
&lt;pre class="literal-block"&gt;
make &amp;amp;&amp;amp; sudo make install
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can go to the kitchen and get a tea or a coffe while it is compiling.
If you do not like tea or coffee you can also try other fun activities like the following :
&lt;img alt="image0" src="http://imgs.xkcd.com/comics/compiling.png" /&gt; Source : &lt;a class="reference external" href="http://xkcd.com/303/"&gt;http://xkcd.com/303/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Back from the kitchen, you are done. PHP 5.3 is now compiled and
installed on your machine. You can of course use a few extra CFLAGS
or options to the configure script if you want to, but the most
basic steps are here and you now know the required steps Now a
small tip, let us say I want to compile with the
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--with-mysql=/path/to/wrong/mysql/directory&lt;/span&gt;&lt;/tt&gt; argument but
unfortunately the configure script fails with such an error message :&lt;/p&gt;
&lt;blockquote&gt;
configure: error: Cannot find MySQL header files under
/path/to/wrong/directory. Note that the MySQL client library is not
bundled anymore!&lt;/blockquote&gt;
&lt;p&gt;How to find the correct path and fix the problem ?
I know that the mysql extension is available in the ext/mysql directory&lt;/p&gt;
&lt;p&gt;The configuration related to this module is in config.m4.
By opening &lt;cite&gt;ext/mysql/config.m4&lt;/cite&gt; I discover (line 77) that the &lt;cite&gt;mysql.h&lt;/cite&gt; header is
required and it is searched in the following directories (still on
line 77) :&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;/usr/local&lt;/li&gt;
&lt;li&gt;/usr/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The only thing I have to do is searching for &lt;cite&gt;mysql.h&lt;/cite&gt;. Since I use the official
MySQL binary I know it is installed in &lt;cite&gt;/usr/local/mysql/&lt;/cite&gt; so if I look in
&lt;cite&gt;/usr/local/mysql/include/&lt;/cite&gt; I find the required mysql.h file. The
&lt;cite&gt;config.m4&lt;/cite&gt; file searches for &lt;cite&gt;/include/mysql.h&lt;/cite&gt; (line 81) so the only
thing I have to do is to correct my &lt;cite&gt;--with-mysql&lt;/cite&gt; argument and use
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;--with-mysql=/usr/local/mysql&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;By relaunching the configure script it worked and we have been able to compile
PHP with MySQL successfully :) Since you now have compiled PHP by yourself the
only limit for you now is your imagination :)&lt;/p&gt;
</summary><category term="php"></category><category term="compilation"></category><category term="macosx"></category></entry><entry><title>Displaying the byte sequence of a string in PHP</title><link href="http://jrenard.info/blog/displaying-the-byte-sequence-of-a-string-in-php.html" rel="alternate"></link><updated>2009-06-26T00:00:00+02:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2009-06-26:/blog/displaying-the-byte-sequence-of-a-string-in-php.html/</id><summary type="html">&lt;p&gt;Since I am never able to remember this, I decided to write it down
here. The code is the following :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showByteSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$string&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$string&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;0x&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;dechex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;ord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$string&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For example writing&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;lt;?php
showByteSequence( 'foo-bar' );
?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;should display&lt;/p&gt;
&lt;pre class="literal-block"&gt;
0x66 0x6f 0x6f 0x2d 0x62 0x61 0x72
&lt;/pre&gt;
</summary><category term="php"></category></entry><entry><title>About me</title><link href="http://jrenard.info/blog/about-me.html" rel="alternate"></link><updated>2008-11-13T00:00:00+01:00</updated><author><name>Jérôme Renard</name></author><id>tag:jrenard.info,2008-11-13:/blog/about-me.html/</id><summary type="html">&lt;p&gt;Want to hire me ? My resume is available at the following URL:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.jrenard.info/cv/"&gt;http://www.jrenard.info/cv/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also follow me on Twitter:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="&amp;#64;jeromerenard"&gt;https://twitter.com/jeromerenard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</summary></entry></feed>
