<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fernando Ipar &#187; Programming</title>
	<atom:link href="http://fernandoipar.com/tag/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://fernandoipar.com</link>
	<description>I love mankind! Its people I can&#039;t stand!</description>
	<lastBuildDate>Wed, 07 Jul 2010 04:10:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>SOUNDEX(), triggers, and stored procedures</title>
		<link>http://fernandoipar.com/2009/04/29/soundex-triggers-and-stored-procedures/</link>
		<comments>http://fernandoipar.com/2009/04/29/soundex-triggers-and-stored-procedures/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 23:14:51 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://fernandoipar.com/?p=166</guid>
		<description><![CDATA[MySQL provides a SOUNDEX() function, which returns the soundex of a given string. For details, refer to the manual, but to put it simply, it allows you to compare strings based on how they sound, hence letting you do proximity searches on your database. If you&#8217;re just querying for a word, it&#8217;s usage is pretty [...]


Related posts:<ol><li><a href='http://fernandoipar.com/2009/08/14/generating-data-with-dbmonster/' rel='bookmark' title='Permanent Link: Generating data with dbmonster'>Generating data with dbmonster</a> <small> In my last post I included some sample data...</small></li><li><a href='http://fernandoipar.com/2009/04/21/extending-procedure_analyse/' rel='bookmark' title='Permanent Link: Extending procedure_analyse'>Extending procedure_analyse</a> <small>My previous post explored a stored procedure that extended procedure_analyse...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>MySQL provides a SOUNDEX() function, which returns the soundex of a given string. For details, refer to the <a href="http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_soundex">manual</a>, but to put it simply, it allows you to compare strings based on how they sound, hence letting you do proximity searches on your database.</p>
<p>If you&#8217;re just querying for a word, it&#8217;s usage is pretty straightforward, and in fact, you can use the SOUNDS LIKE operator to build expressions such as this:</p>
<blockquote><p>SELECT <em>expr</em> FROM <em>table expr</em> WHERE <em>field0 </em>SOUNDS LIKE <em>&#8216;inputWord&#8217;</em></p></blockquote>
<p>However, if you&#8217;re storing multiple-word strings, things get a little more complicated, since they can&#8217;t be compared by their soundex. Rather, the soundex returned will be associated with the whole phrase. If at a later time, you want to search for a subpart of this phrase, there&#8217;s no way for you to do this.</p>
<p>Well, at least not directly, but by using an auxiliary table to store soundex strings, a couple of stored procedures, and a trigger, it can be done with little effort to programmers that use the database.</p>
<p>Let&#8217;s assume we have a very simple table called <em>soundex_text</em> with the following structure:</p>
<pre>create table if not exists soundex_text (
	id int unsigned not null auto_increment primary key,
	description text
) Engine = Innodb;</pre>
<p>The field we want to query by proximity is <em>description</em>, therefore we create the following auxiliary table to store soundex values:</p>
<pre>create table if not exists soundex_text_index (
	soundex_text_id int unsigned not null references soundex_text(id),
	soundex char(4)
) Engine = Innodb;</pre>
<p>We now create a stored procedure and a trigger to populate the auxiliary table automatically every time a row is inserted in the main table.</p>
<pre>-- adapted from example at http://forums.mysql.com/read.php?60,78776,242420#msg-242420
-- posted by jim smith: http://forums.mysql.com/profile.php?60,3154903
CREATE PROCEDURE update_soundex_text_index (sStringIn text,splitChar varchar(1), soundex_text_id int)
BEGIN
DECLARE comma INT DEFAULT 0;
DECLARE mylist TEXT DEFAULT sStringIn;
DECLARE temp TEXT DEFAULT '';
DECLARE strlen int DEFAULT LENGTH(sStringIn);
DECLARE insert_id int DEFAULT soundex_text_id;

/* find the first instance of the spliting character */
SET comma = LOCATE(splitChar,mylist);
/* Insert each split variable into the temp table */
WHILE strlen &gt; 0 DO
	IF comma = 0 THEN
		SET temp = TRIM(mylist);
		SET mylist = '';
		SET strlen = 0;
	END IF;
	IF comma != 0 THEN
		SET temp = TRIM(SUBSTRING(mylist,1,comma-1));
		SET mylist = TRIM(SUBSTRING(mylist FROM comma+1));
		SET strlen = LENGTH(mylist);
		-- Sample handling of special chars you might want removed from individual words
		-- before storing their soundex.
		SELECT REPLACE(temp,',','') INTO temp;
		SELECT REPLACE(temp,';','') INTO temp;
		SELECT REPLACE(temp,':','') INTO temp;
	END IF;
	IF temp != '' THEN
		insert into soundex_text_index (soundex_text_id,soundex) values (insert_id,substring(soundex(temp) from 1 for 4));
	END IF;
	SET comma = LOCATE(splitChar,mylist);
END WHILE;

END//

drop trigger if exists soundex_text_bi//
create trigger soundex_text_bi
before insert
on soundex_text
for each row
begin
	SET @id = last_insert_id();
	call update_soundex_text_index (NEW.description, ' ', @id);
end;//
delimiter ;</pre>
<p>Finally, a stored procedure to automatically query the table using the auxiliary table implicitly:</p>
<pre>delimiter //
create procedure query_soundex_text(sStringIn text, splitChar varchar(1))
BEGIN
DECLARE comma INT DEFAULT 0;
DECLARE mylist TEXT DEFAULT sStringIn;
DECLARE temp TEXT DEFAULT '';
DECLARE strlen int DEFAULT LENGTH(sStringIn); 

create temporary table results (id int unsigned, description text);

/* find the first instance of the spliting character */
SET comma = LOCATE(splitChar,mylist);
/* Insert each split variable into the temp table */
WHILE strlen &gt; 0 DO
	IF comma = 0 THEN
		SET temp = TRIM(mylist);
		SET mylist = '';
		SET strlen = 0;
	END IF;
	IF comma != 0 THEN
		SET temp = TRIM(SUBSTRING(mylist,1,comma-1));
		SET mylist = TRIM(SUBSTRING(mylist FROM comma+1));
		SET strlen = LENGTH(mylist);
		-- Sample handling of special chars you might want removed from individual words
		-- before storing their soundex.
		SELECT REPLACE(temp,',','') INTO temp;
		SELECT REPLACE(temp,';','') INTO temp;
		SELECT REPLACE(temp,':','') INTO temp;
	END IF;
	IF temp != '' THEN
		insert into results select st.id, st.description from soundex_text st, soundex_text_index sti where sti.soundex = substring(soundex(temp) from 1 for 4);
	END IF;
	SET comma = LOCATE(splitChar,mylist);
END WHILE;

select distinct * from results;
drop table results;

END//
delimiter ;</pre>
<p>Using this is pretty straightforward.<br />
Just insert some sample data into the table, and give it a shot!:</p>
<pre>mysql&gt; insert into soundex_text(description) values ('This is a sample text row');
Query OK, 1 row affected (0.00 sec)

mysql&gt; call query_soundex_text('semple',' ');
+------+---------------------------+
| id   | description               |
+------+---------------------------+
|    3 | This is a sample text row |
+------+---------------------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql&gt; call query_soundex_text('THis is a samPLE taxt row',' ');
+------+---------------------------+
| id   | description               |
+------+---------------------------+
|    3 | This is a sample text row |
+------+---------------------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql&gt; call query_soundex_text('rock',' ');
Empty set (0.01 sec)

Query OK, 0 rows affected (0.01 sec)</pre>
<p>To make it even easier, you could modify the querying stored procedure and always assume that the splitting character is a whitespace.</p>
<p>You can download a zipfile with a sql script with all this code for you to load into a MySQL database right <a title="Soundex search scripts" href="http://fernandoipar.com/soundex.sql.zip">here</a>.</p>
<p>Enjoy!</p>


<p>Related posts:<ol><li><a href='http://fernandoipar.com/2009/08/14/generating-data-with-dbmonster/' rel='bookmark' title='Permanent Link: Generating data with dbmonster'>Generating data with dbmonster</a> <small> In my last post I included some sample data...</small></li><li><a href='http://fernandoipar.com/2009/04/21/extending-procedure_analyse/' rel='bookmark' title='Permanent Link: Extending procedure_analyse'>Extending procedure_analyse</a> <small>My previous post explored a stored procedure that extended procedure_analyse...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://fernandoipar.com/2009/04/29/soundex-triggers-and-stored-procedures/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Coding Buddies</title>
		<link>http://fernandoipar.com/2009/03/04/coding-buddies/</link>
		<comments>http://fernandoipar.com/2009/03/04/coding-buddies/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 19:50:32 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://fernandoipar.com/?p=110</guid>
		<description><![CDATA[Coding Horror always has insightfull articles, and this one on code peer reviews is no exception. Why is it that writers, musicians and, well, any respected and professional artist or scientist gets his/her work reviewed before it&#8217;s published, but the same isn&#8217;t true in IT? My guess? Most programmers aren&#8217;t neither artists, nor scientists. They&#8217;re [...]


Related posts:<ol><li><a href='http://fernandoipar.com/2009/01/19/symbolics-lisp-machine/' rel='bookmark' title='Permanent Link: Symbolics Lisp Machine'>Symbolics Lisp Machine</a> <small>Wanna have your own Symbolics Lisp Machine? Here&#8217;s the info....</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><a title="Coding Horror" href="http://www.codinghorror.com/blog/">Coding Horror</a> always has insightfull articles, and this one on <a title="Who's your coding buddy?" href="http://www.codinghorror.com/blog/archives/001229.html">code peer reviews</a> is no exception.</p>
<p>Why is it that writers, musicians and, well, any respected and professional artist or scientist gets his/her work reviewed before it&#8217;s published, but the same isn&#8217;t true in IT?</p>
<p>My guess? Most programmers aren&#8217;t neither artists, nor scientists. They&#8217;re an anonymous resource in a badly oiled machine that&#8217;s always behind schedule.</p>
<p>Well, so long, Knuth!</p>


<p>Related posts:<ol><li><a href='http://fernandoipar.com/2009/01/19/symbolics-lisp-machine/' rel='bookmark' title='Permanent Link: Symbolics Lisp Machine'>Symbolics Lisp Machine</a> <small>Wanna have your own Symbolics Lisp Machine? Here&#8217;s the info....</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://fernandoipar.com/2009/03/04/coding-buddies/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generating random salts from bash</title>
		<link>http://fernandoipar.com/2009/02/04/generating-random-salts-from-bash/</link>
		<comments>http://fernandoipar.com/2009/02/04/generating-random-salts-from-bash/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 23:19:57 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://fernandoipar.com/?p=86</guid>
		<description><![CDATA[From the &#8216;just because it can be done&#8217; column, here comes a handy shell script to generate random salts. So, without further ado,  here it goes: #!/bin/bash [ $# -eq 0 ] &#38;&#38; { echo "usage: salt &#60;length&#62;"&#62;&#38;2 exit } strings &#60;/dev/urandom &#124; while read line; do echo $line &#124; tr '\n\t ' $RANDOM:0:1 &#62;&#62; [...]


Related posts:<ol><li><a href='http://fernandoipar.com/2009/08/14/generating-data-with-dbmonster/' rel='bookmark' title='Permanent Link: Generating data with dbmonster'>Generating data with dbmonster</a> <small> In my last post I included some sample data...</small></li><li><a href='http://fernandoipar.com/2009/01/12/running-commands-from-the-shell-with-a-timeout-pt-2/' rel='bookmark' title='Permanent Link: Running commands from the shell with a timeout (pt 2)'>Running commands from the shell with a timeout (pt 2)</a> <small>Here&#8217;s an improved version of the safecmd script. This one...</small></li><li><a href='http://fernandoipar.com/2009/01/10/running-commands-from-the-shell-with-a-timeout/' rel='bookmark' title='Permanent Link: Running commands from the shell with a timeout'>Running commands from the shell with a timeout</a> <small>Sometimes, in a shell script, you need to run a...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>From the &#8216;just because it can be done&#8217; column, here comes a handy shell script to generate random <a title="Cryptographic Salt (Wikipedia)" href="http://en.wikipedia.org/wiki/Salt_(cryptography)">salts</a>.</p>
<p>So, without further ado,  here it goes:</p>
<pre>#!/bin/bash 

[ $# -eq 0 ] &amp;&amp; {
        echo "usage: salt &lt;length&gt;"&gt;&amp;2
        exit
}
strings &lt;/dev/urandom | while read line; do
        echo $line | tr '\n\t ' $RANDOM:0:1 &gt;&gt; /tmp/.salt.$$
        salt=$(cat /tmp/.salt.$$)
        [ ${#salt} -ge $1 ] &amp;&amp; salt=${salt:0:$1} &amp;&amp; echo $salt &amp;&amp; break
done
rm -f /tmp/.salt.$$</pre>
<p>I had to use $1 and not a var, and echo the salt right from inside the while, because the &#8216;|&#8217; creates another shell, so I can&#8217;t pass variables to or from the while in this case.</p>
<p>If you want to keep things simple, you can go perl and just do</p>
<pre>
#!/usr/bin/perl
use Crypt::Salt;
my $length = shift;
print salt($length);
</pre>
<p>But if you ever find yourself in a server with no cpan, the first option might prove useful <img src='http://fernandoipar.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>


<p>Related posts:<ol><li><a href='http://fernandoipar.com/2009/08/14/generating-data-with-dbmonster/' rel='bookmark' title='Permanent Link: Generating data with dbmonster'>Generating data with dbmonster</a> <small> In my last post I included some sample data...</small></li><li><a href='http://fernandoipar.com/2009/01/12/running-commands-from-the-shell-with-a-timeout-pt-2/' rel='bookmark' title='Permanent Link: Running commands from the shell with a timeout (pt 2)'>Running commands from the shell with a timeout (pt 2)</a> <small>Here&#8217;s an improved version of the safecmd script. This one...</small></li><li><a href='http://fernandoipar.com/2009/01/10/running-commands-from-the-shell-with-a-timeout/' rel='bookmark' title='Permanent Link: Running commands from the shell with a timeout'>Running commands from the shell with a timeout</a> <small>Sometimes, in a shell script, you need to run a...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://fernandoipar.com/2009/02/04/generating-random-salts-from-bash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rewriting Highbase in Erlang</title>
		<link>http://fernandoipar.com/2009/01/28/rewriting-highbase-in-erlang/</link>
		<comments>http://fernandoipar.com/2009/01/28/rewriting-highbase-in-erlang/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 03:28:42 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[Highbase]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://fernandoipar.com/?p=70</guid>
		<description><![CDATA[Why? Highbase is currently comprised of several shell scripts  and some C code. It&#8217;s actually a good project (talk about self promotion) that hasn&#8217;t reached a stable release yet just because It hasn&#8217;t been tested enough in production environments I&#8217;ve been amazingly busy during the last years. Lots of work, and lots of parenting in [...]


Related posts:<ol><li><a href='http://fernandoipar.com/2009/02/27/highbase-beta-094/' rel='bookmark' title='Permanent Link: highbase beta-0.9.4'>highbase beta-0.9.4</a> <small>Heavy testing, headphones with no music, lots of Sanchez Gran...</small></li><li><a href='http://fernandoipar.com/2009/02/02/i-love-playing-monopoly/' rel='bookmark' title='Permanent Link: I love playing Monopoly'>I love playing Monopoly</a> <small>This is the latest speed test I run against Santiago...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<h1>Why?</h1>
<p><a title="Highbase : High availability for MySQL" href="http://highbase.seriema-systems.com">Highbase</a> is currently comprised of several shell scripts  and some C code. It&#8217;s actually a good project (talk about self promotion) that hasn&#8217;t reached a stable release yet just because</p>
<ol>
<li>It hasn&#8217;t been tested enough in production environments</li>
<li>I&#8217;ve been amazingly busy during the last years. Lots of work, and lots of parenting in the last two and a half years in particular.</li>
</ol>
<p>Still, it&#8217;s real close to a release candidate, and I will continue testing and fixing the main branch. However, I believe writing a new version in <a title="Erlang. Concurrent, distributed, fault tolerant programming" href="http://www.erlang.org">Erlang</a> has many advantages:</p>
<ol>
<li>Erlang was designed from the ground up with reliability in mind (among other things. It&#8217;s quite popular now due to it&#8217;s multi-core-friendlyness, but that&#8217;s not really useful for a project like this), so it&#8217;s only natural to use it to develop a high availability solution (you know, the &#8220;best tool for the job&#8221; mentality)</li>
<li>Except for the mysql service verification (I wouldn&#8217;t want to go with odbc), and perhaps gratuitious ARP (I&#8217;m not sure at this point), rewriting in Erlang would remove all other dependencies in third party packages. In general, it would make the solution more mantainable and hence more reliable (see point 1).</li>
</ol>
<p>I already wrote a first draft in Erlang about a year ago, but this was when I was just learning the language, so I didn&#8217;t take advantage of it&#8217;s best features for reliability. Actually, the problem was I wrote my version using &#8216;pure&#8217; Erlang, dismissing the OTP part. Erlang as a language is OK (it has anything you need to write reliable,concurrent software). Erlang/OTP is a powerful thing, in the sense that it abstracts you, as a programmer, from the low level chores of distributed, concurrent and fault tolerant programming. You just have to focus on your programming logic, and by following some conventions (Behaviours, which for OO people could loosely be related to Interfaces and Base Clases) you get a lot of extra functionality for free.</p>
<h1>How?</h1>
<p>This new rewrite will be done using the gen_server behaviour, together with events. All this free to use from OTP.</p>
<p>Here&#8217;s a state diagram with an initial draft of the slave routine (done with <a title="Visual Paradigm. Modeling tools. " href="http://www.visual-paradigm.com/">Visual Paradigm</a>):</p>
<div class="mceTemp">
<dl id="attachment_69" class="wp-caption alignnone" style="width: 676px;">
<dt class="wp-caption-dt"></dt>
<dd class="wp-caption-dd">Highbase&#8217;s state diagram</dd>
<dt class="wp-caption-dt"><a href="http://fernandoipar.com/wp-content/uploads/2009/01/highbase.jpg"><img class="size-full wp-image-69" title="State diagram" src="http://fernandoipar.com/wp-content/uploads/2009/01/highbase.jpg" alt="Highbase's state diagram" width="666" height="416" /></a></dt>
</dl>
</div>
<p><strong></strong></p>
<p>Without reading a line of code, here you can get a grasp of the power of OTP. The slave routine is, in it&#8217;s normal state, just waiting for an event. So far, I&#8217;ve identified the following events:</p>
<ul>
<li>service down</li>
<li>link down (erlang link down, would probably be due to the master node being down)</li>
<li>shutdown request</li>
</ul>
<p>In the first case, just as today, we first attempt to restart the service, and if this fails, we go for a takeover. If restart fails, we first to a failover (i.e., shutdown of the master node, this is the same algorithm executed on our <a title="Highbase - the current trunk" href="http://highbase.svn.sourceforge.net/viewvc/highbase/trunk/highbase/">current code branch</a>).</p>
<p>In the second case, if the node is down, it&#8217;s just a takeover. If the node is up, we do a takeover with ARP spoofing, because we assume there&#8217;s something weird with the other node. This part of the algorithm can be improved (we could do another verification, go back to the waiting for event state for N times, etc., this is just a draft).</p>
<p>Still, one of the improvements over the current version is that I don&#8217;t have to handle any loops, OTP handles that for me, all I have to do is write the callback functions (waiting_for_event, restarting_service, etc). Less code = less chance of errors.</p>
<h1><strong>When?</strong></h1>
<p>I&#8217;m currently revewing the design of the new algorithm. I hope to have a draft in two weeks (this is a slow week for me, my daughter is starting preschool education next week and hence my house is kinda crazy).</p>
<p>I&#8217;m also overdue with regular Highbase releases so I&#8217;ll try to get up to date with both trees.</p>
<p>The current erlang tree is <a title="Highbase: the old erlang tree" href="http://highbase.svn.sourceforge.net/viewvc/highbase/trunk/mysql-ha-erl/">mysql-ha-erl</a> (legacy name, before the trademark issues). I&#8217;ll surely be creating a new tree, highbase-erl, during the next few days. Official release news will be broadcasted here from the official site.</p>


<p>Related posts:<ol><li><a href='http://fernandoipar.com/2009/02/27/highbase-beta-094/' rel='bookmark' title='Permanent Link: highbase beta-0.9.4'>highbase beta-0.9.4</a> <small>Heavy testing, headphones with no music, lots of Sanchez Gran...</small></li><li><a href='http://fernandoipar.com/2009/02/02/i-love-playing-monopoly/' rel='bookmark' title='Permanent Link: I love playing Monopoly'>I love playing Monopoly</a> <small>This is the latest speed test I run against Santiago...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://fernandoipar.com/2009/01/28/rewriting-highbase-in-erlang/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Intrusion detection at the application level, for PHP</title>
		<link>http://fernandoipar.com/2009/01/19/intrusion-detection-at-the-application-level-for-php/</link>
		<comments>http://fernandoipar.com/2009/01/19/intrusion-detection-at-the-application-level-for-php/#comments</comments>
		<pubDate>Tue, 20 Jan 2009 01:19:54 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[lamp]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://fernandoipar.com/?p=52</guid>
		<description><![CDATA[Here&#8217;s phpids, an Intrusion Detection System for PHP. According to the site, it aims to counter XSS, SQL Injection, header injection, directory traversal, RFE/LFI, DoS and LDAP attacks, and unknown attack patterns,  through it&#8217;s Centrifuge component. Installation is simple. Just download it, copy the lib directory to a directory in your project structure, or add [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s <a title="Intrusion Detection System for PHP" href="http://php-ids.org/" target="_self">phpids</a>, an Intrusion Detection System for PHP.</p>
<p>According to the site, it aims to counter XSS, SQL Injection, header injection, directory traversal, RFE/LFI, DoS and LDAP attacks, and unknown attack patterns,  through it&#8217;s Centrifuge component.</p>
<p>Installation is simple. Just download it, copy the lib directory to a directory in your project structure, or add it to your <code>include_path</code>.</p>
<p>I actually chose a mix of both ways, so it&#8217;s automatically included when I distribute my applications.</p>
<p>Here&#8217;s how to use it:</p>
<p><code><br />
ini_set('include_path',ini_get('include_path').PATH_SEPARATOR.PRIVATE_ROOT.DIRECTORY_SEPARATOR.'phpids'.DIRECTORY_SEPARATOR.'lib');<br />
</code><br />
Here we&#8217;re just modifying the include path in order to add phpids.<br />
PRIVATE_ROOT is a constant that I&#8217;ve defined in my app, which defines the root of the application. This is not accessible from the web server (following the recommendation of the <a href="http://phpsec.org/projects/guide/1.html#1.4.1">Dispatch</a> method, from the <a href="http://phpsec.org">PHP Security Consortium</a>. However, this is a particular case, in most situations, I&#8217;d recommend using a framework that already takes a similar pattern into account, like <a href="http://cakephp.org/">CakePHP</a>).<br />
phpids is where I&#8217;ve copied this IDS. The downloaded package has a similar root directory name, like phpids-x.y.n, depending on the version number.</p>
<p><code><br />
require_once 'IDS/Init.php';<br />
</code></p>
<p>Require the Init.php file</p>
<p>Then, whenever you need to access the request variables (in my case, this was just in one point in my application so I just had to modify one function), add something like this:</p>
<p><code><br />
$request = array(<br />
'REQUEST' =&gt; $_REQUEST,<br />
'GET' =&gt; $_GET,<br />
'POST' =&gt; $_POST,<br />
'COOKIE' =&gt; $_COOKIE<br />
);<br />
$init = IDS_Init::init(PRIVATE_ROOT. DIRECTORY_SEPARATOR .'phpids'.DIRECTORY_SEPARATOR.'lib/IDS/Config/Config.ini');</code></p>
<p>$ids = new IDS_Monitor($request, $init);<br />
$result = $ids-&gt;run();</p>
<p>if (!$result-&gt;isEmpty()) {<br />
trigger_error($result);<br />
}</p>
<p>If the $result object is not empty, the IDS detected an attack attempt and therefore you should stop processing the request.</p>
<p>And now the fun part.</p>
<p>In order to test this, I set up a very simple, very insecure test page.<br />
Here&#8217;s the php code:</p>
<pre>error_reporting(E_ALL);
ini_set('include_path',ini_get('include_path').':'.'../src/phpids/lib');
require 'IDS/Init.php';
function checkIds()
{
   $request = array(
     'REQUEST' =&gt; $_REQUEST,
     'GET' =&gt; $_GET,
     'POST' =&gt; $_POST,
     'COOKIE' =&gt; $_COOKIE
);

$init = IDS_Init::init('/home/fipar/workspace/at-intranet/src/phpids/lib/IDS/Config/Config.ini');
$ids = new IDS_Monitor($request,$init);
$result = $ids-&gt;run();
if (!$result-&gt;isEmpty()) {
     trigger_error($result);
}
}

if (isset($_REQUEST['sql'])) {
     checkIds();
     $sql = $_REQUEST['sql'];
     print 'Form says '.$sql.'
';
}</pre>
<p>The html page has just an input type text with the name &#8216;sql&#8217;, and a submit button.</p>
<p>I tried the following inputs:</p>
<ul>
<li>Hello, which goes by ok</li>
<li>&#8216; and 1, which generates errors for the REQUEST and POST variables, stating<br />
<blockquote><p>Detects classic SQL injection probings 1/2 | Tags: sqli, id, lfi | ID: 42</p></blockquote>
</li>
<li>&lt;a href=&#8221;http://www.google.com&#8221;&gt;www.google.com&lt;/a&gt;, which generates errors for the REQUEST and POST variables, stating<br />
<blockquote>
<ul>
<li>finds html breaking injections including whitespace attacks | Tags: xss, csrf | ID: 1</li>
<li>Detects JavaScript object properties and methods | Tags: xss, csrf, id, rfe | ID: 17</li>
<li>Detects basic SQL authentication bypass attempts 2/3 | Tags: sqli, id, lfi | ID: 45</li>
</ul>
</blockquote>
</li>
</ul>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://fernandoipar.com/2009/01/19/intrusion-detection-at-the-application-level-for-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Symbolics Lisp Machine</title>
		<link>http://fernandoipar.com/2009/01/19/symbolics-lisp-machine/</link>
		<comments>http://fernandoipar.com/2009/01/19/symbolics-lisp-machine/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 16:44:11 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Lisp]]></category>

		<guid isPermaLink="false">http://fernandoipar.com/?p=49</guid>
		<description><![CDATA[Wanna have your own Symbolics Lisp Machine? Here&#8217;s the info. I have enough room, I just live a few thousand miles too far, and have to deal with very picky Customs officials. No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p>Wanna have your own <a title="Symbolics" href="http://en.wikipedia.org/wiki/Symbolics" target="_self">Symbolics</a> Lisp Machine?</p>
<p><a title="How to get a Lisp Machine" href="http://xach.livejournal.com/209801.html" target="_self">Here&#8217;s the info</a>.</p>
<p>I have enough room, I just live a few thousand miles too far, and have to deal with very picky Customs officials.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://fernandoipar.com/2009/01/19/symbolics-lisp-machine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Top 25 most dangerous programming errors</title>
		<link>http://fernandoipar.com/2009/01/13/top-25-most-dangerous-programming-errors/</link>
		<comments>http://fernandoipar.com/2009/01/13/top-25-most-dangerous-programming-errors/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 15:51:32 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://fernandoipar.com/?p=36</guid>
		<description><![CDATA[Most people make at least 8 or 9 of these in a new project, and this alone is a good reason to use a programming framework, unless you know what you&#8217;re doing. The problem is, sometimes, people who skip on frameworks, don&#8217;t know what they&#8217;re doing. Or, as the Tao of Programming says: There once [...]


No related posts.]]></description>
			<content:encoded><![CDATA[<p>Most people make at least 8 or 9 of these in a new project, and this alone is a good reason to use a programming framework, unless you know what you&#8217;re doing. </p>
<p>The problem is, sometimes, people who skip on frameworks, don&#8217;t know what they&#8217;re doing.<br />
Or, as the <a href="http://www.amazon.com/Tao-Programming-Geoffrey-James/dp/0931137071">Tao of Programming</a> says: </p>
<blockquote><p>
There once was a master programmer who wrote unstructured programs. A novice programmer, seeking to imitate him, also began to write unstructured programs. When the novice asked the master to evaluate his progress, the master criticized him for writing unstructured programs, saying, &#8220;What is appropriate for the master is not appropriate for the novice. You must understand the Tao before transcending structure.&#8221;
</p></blockquote>
<p>Anyway, for novices and masters alike, <a href="http://cwe.mitre.org/top25/">here&#8217;s</a> a great resource of common programming errors one should avoid while working on a project. Some are web oriented, but most are applicable in any environment. </p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://fernandoipar.com/2009/01/13/top-25-most-dangerous-programming-errors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running commands from the shell with a timeout (pt 2)</title>
		<link>http://fernandoipar.com/2009/01/12/running-commands-from-the-shell-with-a-timeout-pt-2/</link>
		<comments>http://fernandoipar.com/2009/01/12/running-commands-from-the-shell-with-a-timeout-pt-2/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 22:45:33 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://fernandoipar.com/?p=29</guid>
		<description><![CDATA[Here&#8217;s an improved version of the safecmd script. This one doesn&#8217;t always wait for $timeout seconds even if the command you&#8217;re running exits successfully. In that case, it kills the monitor script and ends at the proper time. Here&#8217;s the code: #!/bin/bash timeout=$1 command=$2 shift 2 check_pid_name() { command=$1 childpid=$2 [ -d /proc/$childpid ] &#124;&#124; [...]


Related posts:<ol><li><a href='http://fernandoipar.com/2009/01/10/running-commands-from-the-shell-with-a-timeout/' rel='bookmark' title='Permanent Link: Running commands from the shell with a timeout'>Running commands from the shell with a timeout</a> <small>Sometimes, in a shell script, you need to run a...</small></li><li><a href='http://fernandoipar.com/2009/02/04/generating-random-salts-from-bash/' rel='bookmark' title='Permanent Link: Generating random salts from bash'>Generating random salts from bash</a> <small>From the &#8216;just because it can be done&#8217; column, here...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s an improved version of the safecmd script. This one doesn&#8217;t always wait for $timeout seconds even if the command you&#8217;re running exits successfully. In that case, it kills the monitor script and ends at the proper time. </p>
<p>Here&#8217;s the code: </p>
<pre>
#!/bin/bash 

timeout=$1
command=$2
shift 2

check_pid_name()
{
        command=$1
        childpid=$2
        [ -d /proc/$childpid ] || return 1
        [ $(grep -c $command /proc/$childpid/cmdline 2>/dev/null) -gt 0 ] &#038;&#038; return 0 || return 1
}

[ -z "$command" ] &#038;&#038; echo "Usage: safecmd <timeout> <command> [args]">&#038;2 &#038;&#038; exit 1

safe_run()
{
        command=$1
        shift
        $command $*
        kill $$
}

safe_run $command $* &#038;
childpid=$!
sleep $timeout 

check_pid_name $command $childpid &#038;&#038; {
        kill $childpid
        sleep 0.1
        check_pid_name $command $childpid &#038;&#038; kill -9 $childpid
        echo "$command $* timed out"
}
</pre>
<p>You can try it how like this, for example: </p>
<pre>
./safecmd 2 sleep 4
</pre>
<p>which will output</p>
<pre>
./safecmd.1: line 34: 11739 Terminated               safe_run $command $*
sleep 4 timed out
</pre>
<pre>
or ./safecmd 2 sleep 1
</pre>
<p>which will output</p>
<pre>
Terminated
</pre>
<p>Indicating that sleep 1 finished successfully</p>
<p>This is still missing something. You can&#8217;t test for the success of the command you pass safecmd, if it exits successfully you&#8217;ll see the same return code than if it would have exited with an error. </p>
<p>In order to improve this, as far as I can tell, you have to use two scripts, one just as the wrapper (to use one separate script instead of the function safe_run()). That&#8217;s the way this is handled in <a href="http://highbase.seriema-systems.com">Highbase</a>, and I&#8217;ll post a full example in my next post on this subject. </p>


<p>Related posts:<ol><li><a href='http://fernandoipar.com/2009/01/10/running-commands-from-the-shell-with-a-timeout/' rel='bookmark' title='Permanent Link: Running commands from the shell with a timeout'>Running commands from the shell with a timeout</a> <small>Sometimes, in a shell script, you need to run a...</small></li><li><a href='http://fernandoipar.com/2009/02/04/generating-random-salts-from-bash/' rel='bookmark' title='Permanent Link: Generating random salts from bash'>Generating random salts from bash</a> <small>From the &#8216;just because it can be done&#8217; column, here...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://fernandoipar.com/2009/01/12/running-commands-from-the-shell-with-a-timeout-pt-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Running commands from the shell with a timeout</title>
		<link>http://fernandoipar.com/2009/01/10/running-commands-from-the-shell-with-a-timeout/</link>
		<comments>http://fernandoipar.com/2009/01/10/running-commands-from-the-shell-with-a-timeout/#comments</comments>
		<pubDate>Sat, 10 Jan 2009 02:21:49 +0000</pubDate>
		<dc:creator>fernando</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[shell]]></category>

		<guid isPermaLink="false">http://fernandoipar.com/?p=20</guid>
		<description><![CDATA[Sometimes, in a shell script, you need to run a command that might go on forever (or an amount of time long enough to be called forever) due to poor coding of the software and wrong external conditions (network down or overloaded, overloaded system, a changed private key, etc). In order to avoid this situations, [...]


Related posts:<ol><li><a href='http://fernandoipar.com/2009/01/12/running-commands-from-the-shell-with-a-timeout-pt-2/' rel='bookmark' title='Permanent Link: Running commands from the shell with a timeout (pt 2)'>Running commands from the shell with a timeout (pt 2)</a> <small>Here&#8217;s an improved version of the safecmd script. This one...</small></li><li><a href='http://fernandoipar.com/2009/02/04/generating-random-salts-from-bash/' rel='bookmark' title='Permanent Link: Generating random salts from bash'>Generating random salts from bash</a> <small>From the &#8216;just because it can be done&#8217; column, here...</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Sometimes, in a shell script, you need to run a command that might go on forever (or an amount of time long enough to be called forever) due to poor coding of the software and wrong external conditions (network down or overloaded, overloaded system, a changed private key, etc).</p>
<p>In order to avoid this situations, here&#8217;s a small shell script that will execute any command with a guaranteed timeout:</p>
<pre>#!/bin/bash

timeout=$1
command=$2

check_pid_name()
{
        command=$1
        childpid=$2
        [ -d /proc/$childpid ] || return 1
        [ $(grep -c $command /proc/$childpid/cmdline 2&gt;/dev/null) -gt 0 ] &amp;&amp; return 0 || return 1
}

[ -z "$command" ] &amp;&amp; echo "I need a command to run"&gt;&amp;2 &amp;&amp; exit 1

[ $# -eq 2 ] &amp;&amp; shift || shift 2

$command $* &amp;
childpid=$!

sleep $timeout 

check_pid_name $command $childpid &amp;&amp; {
        kill $childpid
        sleep 0.1
        check_pid_name $command $childpid &amp;&amp; kill -9 $childpid
        echo "$command $* timed out"
}</pre>
<p>As you can see, it&#8217;s quite simple. You just have to start the desired command in the background, sleep for the timeout, and then kill the process if it&#8217;s still running.</p>
<p>Yes, this script has a defect, all the commands will wait $timeout to run, but that&#8217;s easy to solve. I&#8217;ll post an improved (but slightly more complex) version in my next post.</p>


<p>Related posts:<ol><li><a href='http://fernandoipar.com/2009/01/12/running-commands-from-the-shell-with-a-timeout-pt-2/' rel='bookmark' title='Permanent Link: Running commands from the shell with a timeout (pt 2)'>Running commands from the shell with a timeout (pt 2)</a> <small>Here&#8217;s an improved version of the safecmd script. This one...</small></li><li><a href='http://fernandoipar.com/2009/02/04/generating-random-salts-from-bash/' rel='bookmark' title='Permanent Link: Generating random salts from bash'>Generating random salts from bash</a> <small>From the &#8216;just because it can be done&#8217; column, here...</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://fernandoipar.com/2009/01/10/running-commands-from-the-shell-with-a-timeout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
