Monday, November 01, 2010

php-fpm with nginx on macosx

PHP 5.3.3 is bundled with php-fpm, however the macports version doesn't have a fpm variant yet. There are very few blogs that talk about setting up php-fpm with nginx on macosx. So I have documented here the steps I have followed to get them working.

1)port uninstall installed and php5
2)port selfupdate
3)edit /opt/local/var/macports/sources/
and add "--enable-fpm" option to the configure.args. More details about this can be found at
4)Install the fastcgi variant of php "port install php +fastcgi"
5)Check if you have /opt/local/sbin/php-fpm binary
6)Configure /opt/local/etc/php-fpm.conf
7)Create a plist file called org.macports.phpfpm.plist. I created a simple plist file with /opt/local/sbin/php-fpm as the only string tag. I suggest that you read about plist files and create a proper plist file.
8)copy the plist file to /Library/LaunchDaemons/org.macports.phpfpm.plist
9)add the plist to file to startup "sudo launchctl load -w /Library/LaunchDaemons/org.macports.phpfpm.plist"
10)reboot the machine, verify if php-fpm is running. "ps aux | grep fpm"

Tuesday, September 07, 2010

Bangalore-Yercaud-Bangalore Cycle Ride

For those who don't know this yet, five of us rode from Bangalore to Yercaud on Saturday. Here is the ride report for the benefit of others interested in riding to Yercaud.

My alarm went of at 2:00am on saturday morning. I finished my morning chores and started from my home at 3:15am. After just a few meters of riding I got a call from Shashi confirming that all other rides have started and were on their way to Silkboard. I started pedaling slowly and met Ramey (another rider in crime) less than a kilometer from my home. After a brief conversation, he cruised ahead to silkboard. I was riding slowly. The road was mostly empty except for the night patrol. I reached Silkboard and waited for Shashi and other riders from Kanakapura road to join us. Shashi, Harisha & Prakash arrived at Silkboard a few minutes later. Myself, Shashi and Ramey were on hybrids, Harisha and Prakash were on mountain bikes.

We all started from Silkboard at 4:05am. The road was lit up with streetlights till Electronics City after which it was dark. We rode mostly on the service roads till we reached Hosur, where we stopped for tea at around 5:15am. By the time the sun came up, we were half way between Hosur and Krishnagiri. The route from Hosur to Krishnagiri was full of downward slopes. We stopped for breakfast at 7:30am at Krishnagiri near the Krishnagiri-Chennai diversion. We rode at an average speed of 32km/hr from Hosur to Krisnagiri. Shashi had convinced his brother Sridhar and his friend Sandeep to come to Yercaud in a car. Special thanks to them for carrying our bags. Sridhar and Sandeep arrived at our breakfast place just before we finished our breakfast.

We left the restaurant at 8:30am and headed toward Dharmapuri. We stopped for tea somewhere before Dharmapuri. I don't remember the time we crossed Dharmapuri, but we reached a place called Deevattipatti around 2:30pm. We stopped for snaps at multiple places before Deevattipatti. We decided to take a shortcut to Yercaud avoiding Salem. Harisha had a puncture before Deevattipatti. Luckily there was a puncture shop close by and we got it fixed quick. We took a diversion from Deevattipatti towards a place called Danishpet. The road from Deevattipatti to Danishpet had only a single lane. It was surrounded by a few streams and lakes. We stopped at Danishpet before a railway cross for tea. Danishpet to Yercaud base was around 25km. Taking that route turned out to be the biggest blunder we made. The route was full of mud and stones. There were no roads at all in some parts. We had to lift our cycles and walk to cross one of the small streams. It is worse than the worst road you would find along the Anchetty-Hogenakkal route. Luckily none of us were on road bikes. I wonder why Google maps lists these roads. Every local we asked said the main road was 2-3km away at every point. But we never seemed to hit the main road. After cycling around 25km we reached the main road. We took almost 3 hours to cover those 25km in jungle. My front tire was flat once we crossed the forest region. I didn't have the patience to fix the puncture. So we just changed to the spare tube and headed to Yercaud base.

We reached Yercaud base at 6:30pm. We took a few snaps at the 1st hairpin bent. It was already dark and we had 21km with 1594 meters of ascent to climb. Unlike Nandi, the hairpin bends were smoother, but the straight roads were steeper. I climbed along with Harisha and we took breaks almost every couple of kilometers. There were lot of monkeys along the way. We ran out of all the water we had and there were no places along the way to get water from. It drizzled for a brief period, and we stopped under the shelter of something that looked like resting place for travelers. Couple of other people stopped at the same place and shared their water with us. We were only half way to Yercaud and we were extremely hungry. Luckily Harisha had some dry fruit. Shashi was hitching along with a moterbike and came to the top. Shashi mentioned that one of the police guys said that there was a bison roaming around, but we never encountered the bison. Three of us started climbing together. After another couple of kilometers we ran out of water again. At the same spot we found a hut in one of the coffee plantations and filled our water bottles there. After having water and dry fruit, we started climbing again. Ramey and Prakash boarded a lorry that was climbing up. At 6km point the lorry caught up with us. The lorry guys offered to give us a lift, but we declined and continued to climb. At around 10:15pm we reached the top. We rode the Lake Forest resort from the top. We had covered 236km in total. Sridhar and Sandeep had arranged for a nice dinner. We freshened up, had dinner, and dozed off.

The next day we went around Yercaud for sightseeing on our bicycles. Shashi went to Salem with his brother to meet his relatives. The rest of us went to couple of temples, and went boating. I roamed around one of the coffee plantations. I dozed of at about 8:00pm. I guess everyone else had dinner after that.

We started back from Yercaud at 4:15am on Monday. We rode slowly till the base. Stopped multiple times for snaps. The sky was clear and the stars were clearly visible. The moon was yet to rise, I guess. The horizon was also clearly visible. It is one of the best places for star gazing. I wished I had woken up couple of hours earlier to gaze at the sky. BAS (Bangalore Astronomical Society) members would love the place. The view of salem from the top was also awesome. We met a few people jogging at the base, took a few snaps at the last hairpin bent.

Ride from Salem was uneventful till the Dharmapuri ghats. We stopped for tender coconuts at multiple places. Sridhar and Sundeep were on their car and caught up with us close to the toll booth before Dharmapuri. Harisha had a puncture at the toll booth. We removed his tire and I took it to the nearby puncture shop to fix. One of the moterbikers offered Harisha a lift and he came to the puncture shop carrying his bike. We got the puncture fixed and went to A2B before Dharmapuri. Shashi and Prakash were done with breakfast by the time we reached and they started riding ahead of us while we had breakfast. After breakfast we started climbing the Dharmapuri-Krishnagiri ghats. It was a steep upward slope and we took multiple breaks. We reached Krishnagiri at 1:30pm. Shashi and Prakash had also arrived a few minutes before. All four of us had lunch and started riding towards Hosur. Krishnagiri-Hosur route was full of steep ascents. We had cruised the same route at 32km/hr during our onward journey; on the way back we stopped multiple times. I guess we were riding at 15-18km/hr. Shashi had a puncture and fixed it with Prakash while Harisha and I stopped at a dhaba and had some food. At around 5:30pm they caught up with us at the dhaba. Hosur was around 20km away from us from where we were. We started riding and reached hosur around 7:00pm. Hosur has some of the worst possible roads. The local traffic mixes with the highway traffic and there were lot of people riding on the wrong side. It was very difficult to cross Hosur. Me and Harish reached Silkboard at 8:45pm and parted ways to our homes. At around 9:15pm I reached my home. The 470km ride was over! Got a call from Shashi at 9:30pm informing that he has reached home.

Monday, August 02, 2010

My First Ride To Nandi Hills - Biking Carnival

It has been a week since I bought a trek 7100. I have been waiting for an opportunity to go for a long distance ride. Bikers from Bangalore Bikers Club (BBC) were organizing the month end long ride to Nandi hills. So I decided to bike along with other bikers to Nandi on 1st of August. More than 100 people signed up for the ride.

I woke up at 4:00am on 1st August, took a shower, drank two liters of water, finished my other morning rituals and went to Cubbon park at 5:30am along with Ram. We were the first two bikers to reach Cubbon park. During the next few minutes, bikers started to pour into Cubbon park. Ram borrowed a hand pump from one of the riders and inflated both of his tires. There were roughly 30 bikers at Cubbon park by 6:15am. Kiran Jonnalagadda and Nitesh were also there. Yogesh from BBC made few announcements about support vehicles, safety measures and emergency contact numbers.

At 6:15am we left Cubbon park. I was riding with Ram and Nitesh until Yelahanka. After reaching Yelahnaka, I broke away from the group and started riding ahead. I met Yohesh on the way, had a small chat with him and broke away from him. We had Army trucks, and jeeps riding along with us. There were few guys distributing juice to riders on the way. We were riding in the airport road on the shoulders. Around 7:30am or so I reached Bangalore International Airport, which is 40km away from the city. I took a diversion there that led to Devanahalli. The road to Devanahalli was less crowded. I overtook two fellow bikers somewhere between BIAL and Devanahalli and one of the bikers shouted Deepan. It was Venugopal riding his Btwin sports bike. I had a small chat with him and cruised to the front. I overtook a long truck along the way and the truck again overtook me. I smiled at one of the guys in the truck and he smiled back. I guess I was at Devanahalli at around 8:00am.

There were few riders at the Nandi road diversion in Devanahalli chit chatting. The road to Nandi from Devanahalli was little narrow, but was almost empty. The ride to idly point from Devanahalli was uneventful. There was a billboard on the way that said: "The Falcon is coming". I reached idly-point at around 8:30am. I stopped for breakfast. The idly shop ran out of idlies because of the biking crowd. I had rice bath and started again.

I reached Nandi statue at the base of Nandi hill at 9:05am. Riding until this point was quite easy. I guess I rode at an average speed of 25km to 30km per hour. I remember at one point my speedometer read 44km per hour. Now I changed my gears to 1-3 and started climbing up the hill. Within the first few hundred meters I realized that it is excessively difficult for me to climb at 1-3 gear. I changed to 1-2 combination and started pedaling. Opendro was climbing along with me. He said that this was his second Nandi ride. My bike was making some noise at 1-2 gear. He suggested that we fix my gears. So we stopped and Opendro fixed my gears. We started riding again, and the noise from my gears was gone. We came across another rider fixing his bike. Opendro stopped to help him and I continued. The ride up the hill was the most difficult part. I was riding almost at walking speed. There were few riders riding downhill at full speed. Almost every rider riding downhill was smiling, encouraging uphill rider. Almost after half an hour of pedaling up I saw the Nandi signboard that said 5km. There few people and parked cars on the way. Some of them were posing for pictures. Somewhere along the way I changed to the lowest gear possible. I was pedaling uphill through the clouds. I badly wanted to stop, but resisted in order to not lose the momentum. A government jeep overtook me somewhere close to the top. It read RTO on the back. The acronym RTO stands for Road Transport Officer. The RTO of Devanahalli was driving to Nandi top to greet all the riders. The RTO was smiling at me when the jeep overtook me. I saw the 2km signboard sometime after that. There was a rider coming down and he said: "You are almost there". I felt encouraged. The last two kilometers ride on the top seemed to be going forever. I was probably riding slower than walking speed. I remember the speedometer reading 5km or 6km per hour. I was pedaling at 1-1 combination in standing position at one of the U-turns at top. There were moments when I felt that the cycle was standing still. After that I saw the arch on top of Nandi. I was very happy.

When I entered the arch there were few people distributing juice. They said there was breakfast on top. I enquired how long it is. The guys said two kilometers. It was disappointing to know that I have to climb two more kilometers for breakfast. Fortunately the road further was not that steep. I rode to the top and RTO was greeting everyone. He had also arranged free upma, lemon rice, coffee and tea for all the riders. I was cursing myself for having had breakfast at the idly point. I had breakfast once again.

After breakfast, I tried calling Ram to figure out where he was. He was not reachable. So I decided to ride back searching for him. I crossed the arch and rode few hundred meters. In one of the hairpin bends I saw Ram coming up. He said his thighs were paining. Together we walked up the last few hundred meters and reached the arch. We walked uphill after a stopping briefly for pictures. We reached breakfast point. I had a coffee again while Ram had breakfast. After resting for an hour or so, we started riding back. The downhill ride was awesome. Unfortunately one of the riders met with a small accident. One of the fellow riders was hit by a rogue motorbike rider. We stopped there and called for the medics where riding along with us. Within moments the army jeep was there at the accident spot with the medic and first aid kit. I met Barani at this point. The injured biker left in the army jeep. We started riding back. We reached Nandi base within few minutes. My speedometer was reading 40km on the downhill at multiple spots. Brigadier Vijay had arranged for lunch at the base. We stopped for lunch at the base and started riding back. Riding back was very difficult since I was very tired. I remember reaching Devanahalli at 2:00pm. I was riding at an average speed of around 13km until BIAL. After that my average speed declined further to 10km per hour. Along the way I had jackfruit and tender coconut. I reached Hebbal flyover at around 4:15pm. I reached home at 5:15pm. I cycled 130km in a span of 11 hours. I took a shower again and had dinner. I went to bed at 8:30pm and slept for next 10 hours like a baby. It was a wonderful experience.

I will try to ride to Mysore soon. Stay tuned.

Wednesday, July 07, 2010

Testing your webapp using Selenium and PHPUnit

For a long time we have been testing our websites manually. Finally, we have decided to put in some effort to automate part of this testing. After a little bit of research, we found that Selenium could test any website in any set of browser-operating system combinations. There are some other equivalent tools, however selenium seems to be the most robust.

Selenium has many sub-projects. Selenium IDE is the best place for novices to start. Selenium IDE is a Firefox plugin that lets you record events in Firefox and replay them. Events can be like entering text in an input box. You can record a bunch of events like entering username, entering password, clicking on submit, etc. and replay them. Selenium has client libraries in almost all prevailing languages. You could record set of events in Selenium IDE and export the scripts to any of the supported languages. Java, Python, PHP, Ruby are some of the supported languages.

Replaying a script in Selenium IDE will execute the script inside Firefox. If you wish the execute the script in other browsers, then you will have to use a tool called Selenium RC. The acronym RC stands for remote client. Selenium RC is a jar file which can invoke any browser of your choice and execute the commands that you pass to it.

I have several instances of Selenium RC running, one in Windows, one in Mac and one in Linux. When I execute the PHP test scripts, they connect to Selenium RC running in various machines over the network and execute the scripts on a specific browser. This way you could test your website on all major browser and operating systems.

Friday, October 23, 2009

Forking in PHP on Mac OSX using pcntl_fork

1)sudo port selfupdate
2)sudo port update outdated
3)sudo port install php5-pcntl
4)Try the following example

$pid = pcntl_fork();

if($pid) {
// parent process runs what is here
print "parent\n";
else {
// child process runs what is here
print "child\n";

Tuesday, June 09, 2009

Init script to mount EBS and attach elastic IPs to EC2 instances

Modified init script to mount EBS automatically to your EC2 instances.  It also dynamically attaches your instances to an elastic ip.  You have to provide both EBS volume id and elastic ip as userdata separated by pipe symbol for this script to work.  Sample userdata 


You have to use 

update-rc.d mountec2vol start 47 S . stop 35 0 6 . start 37 6 .

to add this script to startup. This script also additional code to mount mysql data directory and nginx directories from EBS. You can skip that part.

#! /bin/sh
# /etc/init.d/mountec2vol
# chkconfig: 234 20 50
# description: Assigns an EC2 EBS Volume to a device and mounts the device
# To add this as a service run:
# /sbin/chkconfig --add mountec2vol
SELF=$(cd $(dirname $0); pwd -P)/$(basename $0)

export JAVA_HOME=/usr/lib/jvm/java-6-sun-
export EC2_PRIVATE_KEY=/root/.ec2/pk.pem
export EC2_CERT=/root/.ec2/cert.pem
export EC2_HOME=/usr/local/src/ec2-api-tools-1.3-36506/

/bin/echo "=====================================" | tee -a $EC2_LOG
/bin/echo "Date: "`date` | tee -a $EC2_LOG;
/bin/echo "Attaching Elastic Block Store Volumes." | tee -a $EC2_LOG
ec2-attach-volume $VOL -i $INSTANCE -d $DEV 1>&2 2>>$EC2_LOG
while [ ! -e "$DEV" ]; do
/bin/sleep 1
CTR=`expr $CTR + 1`
if [ $CTR -eq $MAX_TRIES ]
/bin/echo "WARNING: Cannot attach volume $VOL to $DEV -- Giving up after $MAX_TRIES attempts" | tee -a $EC2_LOG
exit 1
/bin/echo "Checking if $MOUNT_POINT is present" | tee -a $EC2_LOG
if [ ! -d $MOUNT_POINT ]; then
mkdir $MOUNT_POINT 1>&2 2>>$EC2_LOG
/bin/echo "Mounting EBS to /vol " | tee -a $EC2_LOG
/bin/mount $DEV $MOUNT_POINT 1>&2 2>>$EC2_LOG
/bin/echo "Mounting mysql dirs" | tee -a $EC2_LOG
/bin/mount /etc/mysql/ 1>&2 2>>$EC2_LOG
/bin/mount /var/lib/mysql/ 1>&2 2>>$EC2_LOG
/bin/mount /var/log/mysql/ 1>&2 2>>$EC2_LOG
/bin/mount /usr/local/nginx/ 1>&2 2>>$EC2_LOG
set +e;
/bin/echo "stopping mysql" | tee -a $EC2_LOG
/etc/init.d/mysql stop;
set -e;
/bin/echo "Unmounting mysql dirs" | tee -a $EC2_LOG
/bin/umount /etc/mysql/ 1>&2 2>>$EC2_LOG
/bin/umount /var/lib/mysql/ 1>&2 2>>$EC2_LOG
/bin/umount /var/log/mysql/ 1>&2 2>>$EC2_LOG
set +e;
/bin/echo "stopping nginx" | tee -a $EC2_LOG
/etc/init.d/nginx stop;
set -e;
/bin/echo "Unmounting nginx dirs" | tee -a $EC2_LOG
/bin/umount /usr/local/nginx/ 1>&2 2>>$EC2_LOG
/bin/echo "Unmounting Elastic Block Store Volumes." | tee -a $EC2_LOG
/bin/umount $MOUNT_POINT 1>&2 2>>$EC2_LOG
/bin/echo "Detaching Elastic Block Store Volumes." | tee -a $EC2_LOG
ec2-detach-volume $VOL 1>&2 2>>$EC2_LOG
/bin/echo "Populating AWS data" | tee -a $EC2_LOG
INSTANCE=`curl 2> /dev/null`
USERDATA=`curl 2>/dev/null`;
/bin/echo "Parsing user_args " | tee -a $EC2_LOG
echo "usedata vol ip";
echo $VOL;
echo $IP;
/bin/echo "Associating ip address: $IP to $INSTANCE" | tee -a $EC2_LOG
ec2-associate-address -i $INSTANCE $IP;

# start/stop functions for OS

case "$1" in

sh -x /vol/ec2_stuff/;
set +e;
$SELF stop;
set -e;
sleep 60;
$SELF start
echo "Usage: $0 {start|stop|restart}" | tee -a $EC2_LOG
exit 1


exit 0

Tuesday, May 26, 2009

Auto Mounting EBS on EC2

I assume that you have already created a EC2 instance (On top of your custom AMI),  EBS volume (both in the same availability zone) . Below are some instructions to automount EBS on EC2. 

AutoMount Init Script

1)apt-get install sun-java6-jre sun-java6-bin sun-java6-source
2)cd /usr/local/src/
5)edit mountec2vol
set JAVA_HOME=/usr/lib/jvm/java-6-sun-  or equivalent
set EC2_HOME=/usr/local/src/ec2-api-tools-1.3-36506/
set VOL and DEV
6)cp mountec2vol /etc/init.d/
7)chmod +x /etc/init.d/mountec2vol
8)test  mountec2vol
/etc/init.d/mountec2vol start
/etc/init.d/mountec2vol stop
9)update-rc.d mountec2vol start 15 2 3 4 5 . start 47 S . start 35 0 1 6 .
10)Bundle the new image
ec2-bundle-vol -d /mnt -k /mnt/pk-balbal.pem -c /mnt/cert-balhbalh.pem -u userid  -r i386  -p automountingebs
11)upload the new image
ec2-upload-bundle  --url -b yourbucket  -m /mnt/automountingebs.xml -a accessid -s yoursecret
12)register image
ec2-register yourbucket /subdir/automountingebs.xml

Some additional info to create EBS 
On local machine
ec2-create-volume -z us-east-1c -s 10
ec2-describe-volumes vol-VVVV1111
ec2-attach-volume -d /dev/sdh -i i-IIII1111 vol-VVVV1111

On EC2 Instance
apt-get install -y xfsprogs
modprobe xfs
mkfs.xfs /dev/sdh

echo "/dev/sdh /vol xfs noatime 0 0" >> /etc/fstab

mkdir /vol
mount /vol


Monday, May 25, 2009

Nginx + PHPFPM + Memcache + Mysql + XCache + Monit + Logrotate

Step by Step
1)install debian (in case of EC2 - grab a public debian image and create a instance using it)
2)apt-get update
3)apt-get install openssh-server
4)apt-get install vim screen rsync rcconf telnet emacs locate unzip
5)set up .bashrc and  .vimrc
6)apt-get install sysstat subversion sudo
7)add new users and configure sudo
8)aptitude install postfix
9)apt-get install mysql-server mysql-client
10) mysql_secure_installation 
11)aptitude install build-essential libtool libltdl3-dev libgd-dev libmcrypt-dev libxml2-dev libmysqlclient15-dev flex m4 awk automake autoconf bison make libbz2-dev libpcre3-dev libssl-dev zlib1g-dev re2c
12)install php with fpm, curl, mysql

  Install PHP with FPM, CURL, Mysql etc
  1)sudo apt-get install libcurl4-openssl-dev(if 4 is not found, intall libcurl3-openssol-dev)
  2)sudo apt-get install libjpeg62
  3)sudo apt-get install libjpeg62-dev
  4)sudo apt-get install libpng12-dev
  5)cd /usr/local/src/
  8)gunzip php-5.2.8-fpm-0.5.10.diff.gz 
  9)tar -jxvpf php-5.2.8.tar.bz2
  10)patch -d php-5.2.8 -p1 <>
  11)./configure  --enable-fastcgi --enable-fpm --with-mcrypt --with-zlib --enable-mbstring --with-openssl --with-mysql --with-mysql-sock --with-gd --with-jpeg-dir=/usr/lib --enable-gd-native-ttf --without-sqlite --disable-pdo --disable-reflection --with-curl --with-mysqli=/usr/bin/mysql_config
  9)make test
Test whether both mysql and mysqli are supported
  10)sudo make install

13)vi /usr/local/etc/php-fpm.conf 
You may want to add: /usr/local/lib/php to your php.ini include_path

14)install  xcache

   Install XCahce
   2)tar -zxvf xcache-1.2.2.tar.gz 
   3)cd xcache-1.2.2
   5)./configure --with-php-config=/usr/local/bin/php-config --enable-xcache
   6)make install

15)install nginx

  Install Nginx
  2)tar xzvf nginx
  3)cd nginx
  4)./configure --sbin-path=/usr/local/sbin --with-http_ssl_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module
  6)make install

16)configure nginx

    Configure Nginx
    1)cd /usr/local/nginx/
    2)vi conf/nginx.conf
    read for more details
    Enable forwarding php requests to php-fpm by uncommenting the handling of .php files
    edit fastcgi_param as follows
    fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;
    3)change log format to include response time

17)configure xcache

    Configure XCache
    1)vi /usr/local/lib/php.ini
    add the following contents 

    zend_extension = /usr/local/lib/php/extensions/no-debug-non-zts-20060613/
    xcache.shm_scheme = "mmap"
    xcache.size = 64M
    date.timezone = “Europe/Rome”
    default_charset = “utf-8″

18)install memcache extension for php

  Install Memcache extension for php
  compile php with memcache support
  2)tar -zxvf memcache-2.2.5.tgz
  3)cd memcache-2.2.5
  6)make && make test
  7)$ sudo make install
  Installing shared extensions:     /usr/local/lib/php/extensions/no-debug-non-zts-20060613/

  8)vi /usr/local/lib/php.ini
  Add the following to php.ini
  display_startup_errors = On
  extension_dir = "/usr/local/lib/php/extensions/no-debug-non-zts-20060613/"

  9)run memcache test case in genlib/testcases/basic_memcache.php 

19)test nginx - add init scripts 

Test nginx add  init.d scripts
2)php-fpm start
3)create a info.php file and test it.
4)sudo kill `cat /usr/local/nginx/logs/`
5)add init.d scripts - follow instructions in

20)test php-fpm - add init script 

Test php-fpm add init.d scripts
1)cd /etc/init.d/
2)ln -s /usr/local/sbin/php-fpm php-fpm
3)/usr/sbin/update-rc.d -f php-fpm defaults


Find out the number of connections to phpfpm from nginx
$netstat -np | grep | grep -v TIME_WAIT
set appropraite value for variables in php-fpm.conf 
set request_terminate_timeout to 10s
set request_slowlog_timeout to 6s
set user and group to  www-data 
set max_children to 20
perform ab testing and optimize  worker_processes, worker_connections in nginx and max_children in php-fpm.conf

22)add logrotate scripts for nginx,php-fpm

       logrotate scripts
       1)create logroate conf for nginx and php-fpm - copy logroate files from conf_files dir 
       2)add entries for nginx and php-fpm logrotation at /etc/cron.daily/logrotate (not needed if /etc/logrotate.d is included in the logrotate.conf files, just make sure logrotate is called daily)

23)fine tune php-fpm.conf - enable slow query - set max execution time
24)fine tune mysql - enable slow query - log queries that don't use index
25)check if query cache is turned on in mysql - optimize it

Optimize Query Cache in mysql
1) show variables like 'query%';
2) show status like 'qc%';

26)install monit

  1)apt-get install monit
  2)vim /etc/monit/monitrc  - configure it
  3)create /etc/monit/monit.d directory - add sshd,nginx monit config files here
  4)add include /etc/monit/monit.d/* option in /etc/monit/monitrc
  3)monit -t
  4)vim /etc/default/monit  set startup=1
  5)test monit

Thursday, May 15, 2008

vim tip for copying code from webpage

Sometimes copying code from webpage to vim can be painful. You might end up loosing all the newlines. So I prefer to copy (from webpages) using html source. If you use html source, you will have to replace &gt, &lt .. and lot more to <,> and stuff.

The following will do it automatically for you.
:%!perl -pne 'use HTML::Entities; $_=decode_entities($_)'

Thanks to godlygeek from #vim .

Friday, November 23, 2007

Wifi at Changi Airport

I just checked out the free internet terminals in Changi Airport. Few of them run secured version of Internet Explorer. I was also able to use "Wireless@SG", the free island wide wireless at Changi. The speed was amazing. I had to download JavaDoc for JDK 1.5. It completed in 12 minutes. If you are not aware, JavaDoc for JDK 1.5 is 150MB.

IT Security Awareness Day 2007 at Singapore Poly

I gave a talk on WebSecurity at Singapore Poly at the IT Security Awareness Day Event. Around 300 students attended the event, and most of them were school kids. I mostly spoke about Johnny's Google Hacking Database, and little bit about XSS. Justin Lister from InterSect Singapore also spoke at the event. He organized a simple game to explain Phishing. Thanks to Samson, and Cecil for organizing the event.

Sunday, November 18, 2007

Lunch with David Axmark, Co-founder of MySQL

David Axmark, the Co-founder of MySQL was in Singapore today. The local MySQL interest group meet along with David at GeekTerminal for lunch. David patiently answered variety of questions relating to BitKeeper, GIT, SpikeSource's testing framework , Enterprise version of MySQL, SQLite, India, SQL Injection, etc. Thanks to Wong for organizing the event.

Saturday, November 17, 2007


Social networking has grown a big way. FaceBook has taken social networking to a different level. UandMe is a mobile social networking application build by Locatrix. UandMe goes one step further, by integrating with GPS. With UandMe, you can know where your friend is, find a near by restaurant to meet with your friend, create alerts for various events, etc. Location based advertisement is also possible when you integrate with GPS. I guess UandMe will change the way people meet, dine, work etc. I was privileged to meet with Mark White, the founder of Locatrix. He was also kind enough to demonstrate UandMe.

Security Related Groups in Singapore

1) LinkedIn Group for OWASP
2) OWASP-Singapore mailing list
3) Security Meetup - Singapore == Next meeting on 13th Dec 2007.

Thursday, November 15, 2007

OWASP Meeting at GeekTerminal Singapore

Two days back, I attended the second OWASP-Singapore (Open Web Application Security Project) meeting at Geek Terminal. Six people turned out and we had three different presentations. Michael Boman spoke about "Overcoming USB (In) Security". He also demonstrated Lock Picking. Wong from Resolve spoke about ILDP Strategies. Later we discussed about MMORPG hacking. We discussed about SecondLife hacking, gaming client hacking, gaming logic exploitation, etc . We also discussed about developing a framework to test and prevent Game Hacking. Later we discussed about websecurity. The whole meeting went for around 3 hours. I wish more people join.

Tuesday, November 13, 2007

Singleton Vs Static

Singleton, MVC and Factory patterns are the design patterns I use very often. I also use static classes, more often than Singleton, but static classes are not design patterns. For every implementation of Singleton, one can come out with an alternate implementation with static classes. Lot of critics argue that Singleton is not the right way to program, and it is an anti-pattern. Singleton patterns can be considered as substitutions for global variables, and they are most useful when you want to use the same instance all over your program. Using one object ( say of type Class A) to manage instances of a different class (say Class B) , and providing all functionalities using the objects of Class B is obviously a better coding practice. This is a better replacement of Singleton pattern, compared with static classes. Here is an interesting discussing I'd with Cybereal at Cybereal explains why Singleton is a bad wrt to dependency injection.

(12:03:11 AM) codeshepherd: cybereal .. Aren't Singleton the best suitable implementations for Database connection pooling ?
(12:03:43 AM) codeshepherd: In a more general way... Singletons are best suitable to manager global variables..
(12:03:53 AM) cybereal: singletons *ARE* global variables, basically
(12:03:56 AM) cybereal: and that's why they are bad
(12:04:24 AM) cybereal: codeshepherd: you shouldn't need to use a singleton to use the same resource across a program
(12:04:50 AM) cybereal: but because people are lazy about typing and passing on dependency information to instantiated objects, you find they will lean towards singletons to do little more than save some keystrokes
(12:05:01 AM) cybereal: It's really hard to justify it for any other reason
(12:05:41 AM) cybereal: codeshepherd: despite being an anti-pattern, it does get used frequently so you'll still need to know how to deal with it, and sometimes to work around them
(12:06:02 AM) cybereal: at least in java if you really need to you can bury a singleton in a separate classloader instance
(12:06:13 AM) codeshepherd: So how will you implement a Database connection pool? Just a static class ?
(12:06:30 AM) cybereal: no, a regular class that you pass around to all the new instances of other classes that need to know about it
(12:06:44 AM) cybereal: like handing out invitations to a party
(12:06:58 AM) cybereal: you don't hand out houses with those invitations, and people aren't expected to figure out the address themselves
(12:07:06 AM) codeshepherd: then.. some dumb guy who comes tomorrow will start creating instances of the regular class..
(12:07:13 AM) cybereal: it won't matter
(12:07:24 AM) cybereal: but even so, if he's dumb he's gonna do dumb things :)
(12:07:34 AM) cybereal: you shouldn't write bad code just to try and protect from dumb coders
(12:07:54 AM) cybereal: but the point is you should be able to have more than one in the same vm, and not have them hurt each other
(12:07:56 AM) codeshepherd: It is really a debatable issue..
(12:08:54 AM) cybereal: codeshepherd: you probably won't really see it this way until it eventually comes back to bite you in the ass as it has me :)
(12:09:08 AM) codeshepherd: I still agree with the fact that.. you let one class (A) provide all functions.. and another class manage instances of Class A.. .. that looks more clean..
(12:09:33 AM) cybereal: you're making a mistake of thinking a class should ever be in charge of anything
(12:09:37 AM) cybereal: INSTANCES of classes should
(12:09:43 AM) cybereal: classes are blue prints
(12:09:54 AM) codeshepherd: hmm.. ok....
cybereal cybereal
(12:10:19 AM) codeshepherd: interesting argument.. thanks a lot cybereal
(12:10:28 AM) cybereal: nothing stops you, as I already described, from sharing a single instance of a class across your whole app
(12:10:50 AM) cybereal: you get what you want from a singleton without the limiting factors, and all it takes is a little longer parameter list in constructors :)
(12:11:18 AM) codeshepherd: ok.. I guess I will realize it better when it bites me back..
(12:11:24 AM) cybereal: hehe ok

Monday, November 12, 2007

GMail's POP and SMTP service.

GMail's POP and SMTP service have been giving lot of troubles lately. Very often, I'm not able to send out mails via SMTP, and downloading new mails occurs at snails pace. Many others have reported the same problem, and I hope Google fixes it very soon. Email is an essential service, and use web interface for checking emails can be tedious if you have dozens of email accounts with a variety of service providers.

Tuesday, November 06, 2007

Red Black Tree

TreeSet is an implementation of Red-Black Tree in Java. It implements the Set and Collection interface. Here is a short yet excellent video on adding new nodes to TreeSet.

Friday, November 02, 2007

Barcamp - Brisbane, Australia.

I'm planning to fly a bit early for OSDC, so that I can also attend Brisbane Barcamp. It is on Saturday, 24/11/2007. I'm planning to talk there on websecurity. I'm also looking forward to meet David Novakovic, a Computational Linguistics researcher and geek from Gold Coast. He will also speak about his new technology incubator. Click here for complete list of talk at Brisbane Barcamp. Let me know if anyone else is also planning to attend.

Design Patterns by Codingkriggs

Codingkriggs has excellent set of videos on Design Patterns. I wish he continues making videos :)

Wednesday, October 31, 2007

Linus on GIT

The concept of distributed source code management system is very interesting. IMHO GIT is a much better idea compared with Subversion. GIT takes care of the social factors involved in running a open source project. Here is a talk by Linus on GIT.

Interactive Shell

Interactive Shells for some popular languages.

IPython ==> Python (supports readline)
IRB ==> Ruby (supports readline)
php -a ==> PHP
BeanShell ==> Java (interpretor for compiled language?? )
SquareFree Shell ==> JavaScript

Installing readline library should help you auto complete and browse through history.

Yahoo! Pipes

I've been playing with Yahoo Pipes for a while now. Here is a Yahoo Pipe to read orkut scraps. You can choose to receive the scraps in RSS form.

Douglas Crockford on JavaScript

YUI Theater has excellent talks by Douglas Crockford on JavaScript. JS follows prototype based objects and supported prototyped inheritance. Douglas explains the fundamental difference between prototype based object orientation and class based object orientation.

Friday, October 26, 2007

Meta Programming with Ruby at Singapore Ruby Brigade

Choon Keat Chew gave an excellent talk on Meta Programming at the Singapore Ruby Brigade today. He explained meta programming with a logger example. Generally in Java we program to the interface and subclass existing classes to introduce new features. But in Ruby you could directly implement the new method or feature to the object and it instantly gets reflected over the entire scope of the program. It is kinda dangerous in large teams, since anyone can override existing classes and change their behavior by modifying their methods. He also discussed extensively about method_missing , *args feature in Ruby. From what I understand the method_missing function lets you avoid "method not found exception", and also generate setter/getter and other simpler functions automatically. This is one case where meta programming is explicitly visible. He also discussed about simplicity of Rake. Implementing a simple task with Rake will take a lot less time compared with Ant. We also discussed about ducktyping, design patterns and readline library in the end.

Wednesday, October 24, 2007

FaceBook Developer Garage

Today I attended Asia's first Facebook developer garage at NUS Staff Club. The even was extensively advertised and there were around 200 people. But most of the people were only interested in business and social networking part. There were very few developers as usual. I was late; hence I missed the video conference with F8 developers from SanFransico. For those who didn't turn up, don't worry you did not miss anything.

Comparing Programming Languages

Comparing programming languages has always been interesting. A thorough understanding of Object Orientation, Static/Dynamic/Duck typing, Functional Programming, Generics, Aspects, Closures, Design Patterns, Data Structures and Meta Programming will let a programmer hop from one language to another very easily. For example, though both Java and JavaScript are Object Oriented, Java is Class-Based whereas JavaScript is Prototype-Based. Java forces programmers to implement proper namespaces, where as JavaScript does not. Most JavaScript programmers define variables in global scope, though it is possible to organize them with namespaces. Haskell is fundamentally different from other programming languages since it uses functions as basic building blocks. Python, Perl, Ruby and PHP support Dynamic Typing, where as C, C++ and Java support Static Typing. DuckTyping is implemented in the core of Python, but not in languages like Java, though you can emulate Duck Typing in Java as well. Design patterns are suppose to be language independent, but some of them get implemented in the core of some languages. For example the Iterator pattern is implement in Java, Python etc. So we don't even realize that we are using Iterator patterns when we use Python or Java. On the other hand we manually implement Iterator patterns in C.

Java Bean Shell

Java Bean Shell is a handy tool for Java programmers to test APIs, regular expressions, and other small code snippets. In particular if you are working on Client-Server architecture, it takes long time for you to test small changes in the back end. Though Java is compiled language, the interpreter tool in BeanShell will let you interpret the code. It can be downloaded from .


//to start Console
$ java -classpath ./bsh-2.0b4.jar bsh.Console
//to start Interpreter
$ java -classpath ./bsh-2.0b4.jar bsh.Interpreter
bsh % import;
bsh % String dir = "%2Fhome%2Fcodeshepherd";
bsh % System.out.println(dir);
bsh % System.out.println(Decoder.decode(dir));

The Interpreter does not support history and coloring. But the Console does. But the output from Console is thrown in the parent shell.

Monday, October 22, 2007

Open Web Application Security Project - Singapore Chapter

OWASP-Singapore meetup was held on 9th Oct at Geek Terminal in Singapore. Five of us meet and had a chat for about an hour. Geek Terminal is a nice place for geek meetups. I guess they provide laptops with wifi connection to use and they also have mini rooms with projects for conducting mini talks. I'm not sure if those laptops run Linux, would be great if it does so. Last Saturday Facebook and Slashdot community hosted a meeting there, but I could not make it . I hope we have more of these Security related meeting and Open Hack Days in and around Singapore.

An Informal Interview With a Haskell Hacker

2:33:03 PM codeshepherd: given that haskell is a functional programming language.. what are the main differences you find when you compare haskell with other langs
2:34:10 PM rajagopal.n: modifying the system state is something that is still tricky for me to do in some cases. For instance, I was thinking I had understood Monads properly, only to understand that there is more that I didn't understand clearly, when i tried to do some database manipulation using the HSQL connectors, and print the resultsets on a webpage using HAppS.
2:34:22 PM rajagopal.n: but otherwise, if all that you want to do is lot of computation
2:34:28 PM rajagopal.n: writing Haskell code is fun
2:34:36 PM rajagopal.n: you wanna one line binary tree?
2:34:38 PM rajagopal.n: you can
2:35:05 PM rajagopal.n: you can construct all such stuff with ease, without leaving space for much bugs.
2:36:43 PM codeshepherd: function are building blocks of language.. and not objects.. so is it difficult for people from OOP background to learn haskell ?
2:40:00 PM rajagopal.n: The difficulty of learning depends on the OOP that you were using. Most people find it difficult to get used to the concept of lazy evaluation, and immutable data in Haskell, being used to languages where the statements get executed in sequence, and having been used to using variables as counters and stuff. people tend to ask in C, C++, I can do a I++ to increment the value of I. but why does haskell make these variables immutable? It takes time for them to understand that immutability is a way to facilitate lazy evaluation.
2:40:27 PM rajagopal.n: It needs forgetting some of the imperative programming concepts to start accepting the functional programming concepts
2:41:46 PM codeshepherd: Does haskell support Meta Programming ? If so how different is it from Ruby's meta programming implementation ?
2:43:51 PM rajagopal.n: Haskell supports meta programming. I've just learnt it to understand some parts of the HAppS example blog application code. As I hadn't done any meta programming in Ruby, I'm not sure about how it compares to it
2:45:08 PM codeshepherd: Does Meta programming combined with Functional programming pose special advantages ?
2:49:53 PM rajagopal.n: I'm not sure about that da.
2:50:19 PM codeshepherd: ok.
2:50:41 PM codeshepherd: Does Haskell support Duck Typing ?
2:51:06 PM rajagopal.n: ya,

Prelude> :t map
map :: (a -> b) -> [a] -> [b]
Prelude> let bar a = map (*1) a
Prelude> :t bar
bar :: (Num a) => [a] -> [a].

you see that it makes it Num
2:51:53 PM codeshepherd: Duck Typing with functions as basic blocks is kinda difficult to understand ? Do functions act like so called ducks in duck typing ?
2:54:16 PM rajagopal.n: There is not difference in the way you see functions and data in a functional programming language
2:57:02 PM codeshepherd: Is there any reason for people to choose Haskell over other languages for hobby programming ?
3:00:49 PM rajagopal.n: Haskell is pure functional. You get to learn a lot of new things, being a pure functional language that restricts modification to the state to be done only through monads. Learning Haskell and teasing the brain is refreshing when you get bored with all those languages that mostly differs only by syntactic sugar or a few extra features.
3:01:55 PM codeshepherd: ok

Friday, October 19, 2007

My talk at Singapore Linux Meetup

This wednesday I gave a talk on websecurity titled "Hacking the Web" at Singapore Linux meetup. This is my first talk in Singapore and as usual I was kinda nerves. Around 35 to 40 people attended the talk and there were lot of questions from the audience. We had some technical problems initially, with internet connection. I was not able to connect to the internet from my macbook because of dhcp version mismatch. So I'd to run through the talk without internet connection and then later borrow a Windows laptop to demonstrate things on internet. The slides are hosted at . Thanks to Darrel for organizing the talk and everyone else who came down. I will be giving the same talk at Singapore Poly, National University of Singapore, and Open Source Developers Conference 2007 at Brisbane, in the near future. Overall this talk turned out to be a very good experience.

Friday, October 12, 2007

Geeky License Plates

geeky license plates..

Thursday, October 04, 2007

Wife and Girl Friend

Wife: ?
Adultery: ?
Diverse: ?
OpenMarriage: ?

3)Public casting for Private

(03:18:29 PM) codeshepherd: if private is for girlfriend , then what is for wife ?
(03:18:46 PM) ***cybereal: hides his "jib" whatever that is...
(03:18:51 PM) Fanook: codeshepherd: static
(03:18:57 PM) cybereal: final
(03:19:18 PM) cybereal: unless you're in an open marriage, then it's abstract
(03:19:22 PM) codeshepherd: Fanook: static does not suit... finay may be ..
(03:19:36 PM) cybereal: Or if you're homeless it's transient...
(03:20:06 PM) Fanook: cheeser: hmmm, how would one implement a divorce then? :)
(03:20:22 PM) cybereal: Fanook: bytecode manipulation!
(03:20:26 PM) Fanook: hehe
(03:20:28 PM) cheeser: that's research i'll leave to others. P^)=
(03:22:08 PM) codeshepherd: adultery = ?
(03:22:21 PM) freeone3000: adultery is achieved through bcel.
(03:22:43 PM) freeone3000: Or those who put things public that should be private.
(03:22:57 PM) codeshepherd: hehe :)
(03:24:52 PM) cybereal: these metaphors would be more fun if java allowed multiple inheritence

Tuesday, October 02, 2007

A map is a collection of pairs, but it's not a Collection.

A funny discussion at

(02:13:47 AM) iamgedanken: sorry for the noob question, but what is the difference between an arraylist and a collection?
(02:14:13 AM) ojacobson: An ArrayList is one kind of Collection; there are others
(02:14:29 AM) Logi: ArrayList implements List extends Collection
(02:14:34 AM) iamgedanken: o rly
(02:14:42 AM) iamgedanken: ok that makes sense
(02:14:47 AM) ojacobson: ~javadoc Collection
(02:14:47 AM) javabot: ojacobson, please see java.util.Collection:
(02:14:49 AM) iamgedanken: thanks very much
(02:14:56 AM) Logi: HashMap implements Map which is a collection even if it doesn't implement Collection directly
(02:15:05 AM) kimtiede: An ArrayList gives easy random access to the elements
(02:15:12 AM) codeshepherd: Collection = List Or Set ; List = ArrayList or LinkedList .. iamgedanken
(02:15:21 AM) Logi: Map m=...; m.keySet() instanceof Set implements Colletion
(02:15:32 AM) cybereal_design_patterns_utah: Logi: to be fair, it's a relationship of collections as provided
(02:15:38 AM) cybereal_design_patterns_utah: entrySet, keySet, values
(02:15:43 AM) codeshepherd: List and Set are interfaces implementing Collection... ArrayList is a Class implementing interface List.. iamgedanken
(02:16:16 AM) iamgedanken: alright I understand now thanks for your time
(02:16:20 AM) iamgedanken: :)
(02:16:32 AM) codeshepherd: Logi: HashMap is not a Collection..
(02:16:45 AM) codeshepherd: HashMap does not implement the Collection interface ..
(02:16:48 AM) Logi: codeshepherd: it is with a lower case "c"
(02:17:24 AM) aditsu: in STL style it would be a collection of pairs :)
(02:17:33 AM) codeshepherd: Logi: sorry I dont unerstand.. what is the difference ?
(02:17:51 AM) ojacobson: codeshepherd: A map is a collection of pairs, but it's not a Collection
(02:18:01 AM) ojacobson: eg it doesn't implement the Collection interface
(02:18:03 AM) Logi: codeshepherd: Collection is an interface and Map doesn't extend it. but what ojacobson said
(02:18:21 AM) codeshepherd: oh ok.. Yes, in English.. not in Java :P
(02:18:26 AM) ojacobson: Right :)

Saturday, September 29, 2007

Please don't tell anyone... that I..

Dig into dustbins in the bus stop,
Sniff wireless traffic in my apartment; watch what people do online,
Walk along the beach late at night,
Read other people's emails and IM conversations,
Delete all my email accounts,
Bully newbies in IRC and other mailing lists,
Run a keylogger in my machine.

Friday, September 28, 2007

Geek gatherings in Singapore

Unlike Bangalore, Singapore has very few Geek gatherings. Singapore Linux meetup, Novel Suse Linux meetup, Ruby Brigade, Singapore JUG, are the active geek gatherings in Singapore. On the other hand Bangalore boasts of many Geeky activities like "Hack Days", "Open Coffee Club meet", regular Linux user group meetings, Bangpypers meeting, PHP user group meetings, Blog Camps, Bar Camps, FOSS.IN, Freed, Geek gatherings at pubs, etc.

Syntax Highlighting for Code Embedded in Blogger

There are multiple ways for highlighting the syntax of code embedded in Blogger. One way is to generate HTML files directly from VIM using :TOHtml and extract the CSS part in it and use it in Blogger. You can do the same with Textmate or Emacs. Another alternative is to use Prettifier. Prettifier is very easy to use. All you need to do is add a CSS and JavaScript file in your server and link them in your blog template. Please look at the readme file for more details. In my case, Blogger does not allow me to upload JavaScript files and CSS files, so I'm hosting them on a different server. I have updated my earlier posts to use Prettify.

The Perl code has turned out bit messy, but the GreaseMonkey JavaScript code looks clean.

Tuesday, September 25, 2007

SpringMVC + Hibernate + GridSphere + Apache Tomcat

I've successfully integrated GridSphere and SpringMVC. I've been using a lot of GridSphere Tag Libraries in my JSPs. Now I've to rewrite them using Spring specific tag libraries. In my opinion the GridSphere specific tag libraries are much easier to use compared to Spring tag libraries. The following link provides detailed explanation for integrating SpringMVC with GridSphere. . Now I've to explore some templating Engines, and Acegi Tag libraries.

Thursday, September 13, 2007

Happy News!!

I just received a email from Open Source Developers Conference, Australia, Committee, confirming that my talk has been accepted for the Conference. I will be speaking on "Web Security" at OSDC 2007, Brisbane, Australia this November. Let me know if anyone else is attending the conference.

Friday, August 17, 2007

Frustrating 3wplayers and Pr0n

Last night, I finished downloading Rush Hour 3. When I played it using mplayer, it prompted me to download 3wplayer. So I googled for W3player and found Perl source (look below for the link) for decrypting 3wplayer encrypted files into AVI files. I decrypted Rush Hour 3 file and it happened to be pr0n!!!

3wplayer is a rogue media player software application bundled with trojans that can infect computers running Microsoft Windows. It is designed to exploit users who download video files, instructing them to download and install the program in order to view the video.

Perl code to decode 3wplayer encoded video files:

Wednesday, August 08, 2007

Why are programmers lucky?

#bioinformatics @
(05:07:23 PM) _dan: my dad is an electronics enginerer, he has a room stacked full of stuff, always made me quite jealous, I mean I can hardly have an electron microscope at home..

Monday, August 06, 2007

The sarcastic subconscious

Many times I code in the dream only to wake up and realize that I haven't saved my code!!! Maybe technology will grow up soon to tap productive work from our subconscious minds. Maybe someday biologists will create a VIM plugin to save the code we dream of.

Thursday, July 26, 2007

Intellectual Masturbation

Geek's Google query to search for porn: 'intitle:"index of" porn (mpeg|mpg|avi)'. Click here to try it. 100% satisfaction guarantied.

Saturday, July 21, 2007

Eliza Loves You - Rogerian psychotherapist

Recently I ported the ElizaLovesYou Gaim plugin to Pidgin. Click here to download the source. Most conversations with the Eliza bot are quite uninteresting. But the one I saw today needs special mention. It is one of the most interesting conversations I've seen with Eliza bot.Here goes the conversation. Scroll down to read the code.

(05:51:39 PM) J: alo
(05:51:39 PM) Codeshepherd's Bot: Hi J/Talk.v104FA524C95, The maniac is sleeping or eating or buzy doing some shit!!!.
(05:51:39 PM) Codeshepherd's Bot: I am his dumb slave bot :). You can speak to me if you want!!!
(05:51:50 PM) J: hi Jayshree and arch here
(05:51:51 PM) Codeshepherd's Bot: Please go on.
(05:52:27 PM) J: hello
(05:52:28 PM) Codeshepherd's Bot: How do you do. Please state your problem.
(05:52:58 PM) J: i'm fine. how r u?
(05:52:59 PM) Codeshepherd's Bot: Do you say you'm fine for some special reason?
(05:53:45 PM) J: yes cause we re are goibg to the ice cream parlor
(05:53:46 PM) Codeshepherd's Bot: Please go on.
(05:54:17 PM) J: how do u do?
(05:54:18 PM) Codeshepherd's Bot: Why do you ask?
(05:54:35 PM) J: generaaly i'm concerned about your health
(05:54:36 PM) Codeshepherd's Bot: Do you want my health?
(05:55:11 PM) J: how can i take your health?
(05:55:12 PM) Codeshepherd's Bot: What is it you really want to know?
(05:55:42 PM) J: generally how are you?
(05:55:43 PM) Codeshepherd's Bot: Oh, I?
(05:55:54 PM) J: yes you only..
(05:55:55 PM) Codeshepherd's Bot: I understand.
(05:56:15 PM) J: ok give me the answer..
(05:56:16 PM) Codeshepherd's Bot: Please go on.
(05:56:30 PM) J: how are you?
(05:56:31 PM) Codeshepherd's Bot: What are your feelings now?
(05:57:09 PM) J: i'm still wondering why are you not answering my question?
(05:57:10 PM) Codeshepherd's Bot: Is it important to you that your question?
(05:57:32 PM) J: yes..
(05:57:33 PM) Codeshepherd's Bot: Please go on.
(05:58:08 PM) J: no problems in life
(05:58:09 PM) Codeshepherd's Bot: Why 'no'?
(05:58:42 PM) J: because i stay happy all the time..
(05:58:43 PM) Codeshepherd's Bot: You say because you stay happy all the time?
(05:58:50 PM) J: yes..
(05:58:51 PM) Codeshepherd's Bot: Please tell me some more about this.
(05:59:12 PM) J: being sad is again sad...
(05:59:13 PM) Codeshepherd's Bot: Earlier you said your question.
(05:59:55 PM) J: yes, i was asking you how are you?
(05:59:56 PM) Codeshepherd's Bot: Why do you tell me you were asking me how are me now?
(06:00:15 PM) J: okies i'm confused now..
(06:00:16 PM) Codeshepherd's Bot: Why do you say okies you'm confused now?
(06:00:49 PM) J: because you don't seem to answering my question.
(06:00:50 PM) Codeshepherd's Bot: Why do you say your question?
(06:01:10 PM) J: i think i should talk somethiong else..
(06:01:11 PM) Codeshepherd's Bot: Do you really doubt you should talk somethiong else?
(06:01:39 PM) J: no i don't have ant doubts..
(06:01:40 PM) Codeshepherd's Bot: Why 'no'?
(06:01:59 PM) J: because i'm clear
(06:02:00 PM) Codeshepherd's Bot: Do you say because you'm clear for some special reason?
(06:02:28 PM) J: yes because i have taken bath 2day..
(06:02:29 PM) Codeshepherd's Bot: Please go on.
(06:02:40 PM) J: did you take bath?
(06:02:41 PM) Codeshepherd's Bot: You're not really talking about me -- are you?
(06:02:56 PM) J: yes i'm talking about you.
(06:02:57 PM) Codeshepherd's Bot: Why don't you tell me a little more about this.
(06:03:08 PM) J: like what?
(06:03:09 PM) Codeshepherd's Bot: But your question.
(06:03:23 PM) J: i forgot my question..
(06:03:24 PM) Codeshepherd's Bot: Is it important to you that your question?
(06:03:37 PM) J: no not important.
(06:03:38 PM) Codeshepherd's Bot: Why 'no'?
(06:04:03 PM) J: pk let me move on to somthng else.
(06:04:04 PM) Codeshepherd's Bot: But your question.
(06:04:17 PM) J: i discad that question
(06:04:18 PM) Codeshepherd's Bot: Why do you say you discad that question?
(06:04:34 PM) J: i;m not interested in that question..
(06:04:35 PM) Codeshepherd's Bot: Can you elaborate on that?
(06:04:40 PM) J: no
(06:04:41 PM) Codeshepherd's Bot: Why not?
(06:04:59 PM) J: because i forgo my quetion
(06:05:00 PM) Codeshepherd's Bot: Is it important to you that your quetion?
(06:05:10 PM) J: not important
(06:05:11 PM) Codeshepherd's Bot: But your quetion.
(06:05:41 PM) J: hello can you type some other line
(06:05:42 PM) Codeshepherd's Bot: We were discussing you -- not me.
(06:05:57 PM) J: oh sorry..
(06:05:58 PM) Codeshepherd's Bot: I've told you that apologies are not required.
(06:06:20 PM) J: thanks for reminding e
(06:06:21 PM) Codeshepherd's Bot: That is interesting. Please continue.
(06:06:38 PM) J: i don;t have anything to say now
(06:06:39 PM) Codeshepherd's Bot: You say you don;t have anything to say now?
(06:07:17 PM) J: yes
(06:07:18 PM) Codeshepherd's Bot: Please tell me some more about this.
(06:07:46 PM) J: we are going to the ice cream parlour to eat ice ceam
(06:07:47 PM) Codeshepherd's Bot: Would you like it if they were not going to the ice cream parlour to eat ice ceam?
(06:08:09 PM) J: no i will not like it.
(06:08:10 PM) Codeshepherd's Bot: Why not?
(06:08:30 PM) J: because i want to eat ice cream
(06:08:31 PM) Codeshepherd's Bot: What would it mean to you if you got to eat ice cream?
(06:08:51 PM) J: i would be happy
(06:08:52 PM) Codeshepherd's Bot: Why do you say you would be happy?
(06:09:07 PM) J: because i like ice cream
(06:09:08 PM) Codeshepherd's Bot: That is interesting. Please continue.
(06:09:44 PM) J: ice cream is creamy and cold, that makes it good thing to eat after food
(06:09:45 PM) Codeshepherd's Bot: Does talking about this bother you?
(06:09:57 PM) J: no not at all
(06:09:58 PM) Codeshepherd's Bot: Why 'no'?
(06:10:23 PM) J: why should i have problem with it?
(06:10:24 PM) Codeshepherd's Bot: That's quite interesting.
(06:10:29 PM) J: hmm
(06:10:30 PM) Codeshepherd's Bot: That is interesting. Please continue.
(06:10:43 PM) J: ok now i'm tired
(06:10:44 PM) Codeshepherd's Bot: Can you elaborate on that?
(06:10:52 PM) J: tell me some stories
(06:10:53 PM) Codeshepherd's Bot: Please go on.
(06:11:10 PM) J: ya tell me cindrella story.
(06:11:11 PM) Codeshepherd's Bot: Tell me more about that.
(06:11:23 PM) J: you have to tell me that.
(06:11:24 PM) Codeshepherd's Bot: Do you wish to believe I have to tell you?
(06:11:38 PM) J: yes
(06:11:39 PM) Codeshepherd's Bot: Why don't you tell me a little more about this.
(06:13:25 PM) J: i don't have anything more to say.
(06:13:26 PM) Codeshepherd's Bot: Why do you say you don't have anything more to say?
(06:14:11 PM) J: ok bye!
(06:14:12 PM) Codeshepherd's Bot: Please go on.

#ElizaLovesYou v0.4
#Ported v0.3 to Pidgin by Deepan Chakravarthy
#Email: codeshepherd AT gmail DOT com
#Thanks to sadrul and resiak on and Davo_Dinkum on for their help.
#ElizaLovesYou v0.3 - Rogerian psychotherapist for Pidgin
#Copyright (C) 2004 Scott Wolchok
#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; either version 2
#of the License, or (at your option) any later version.
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#GNU General Public License for more details.
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#(You can find the GPL at
#You'll need to install Chatbot::Eliza from CPAN before this will work.
#Run 'perl -MCPAN -e "shell"' and answer the questions, then type
#'install Chatbot::Eliza' at the prompt. That should do it!
#'install Pidgin' at the prompt
#'install Purple' at the prompt
#Please note that this plugin is just a hook for the Perl Chatbot::Eliza
#module - the credit for the actual "bot" goes to the John Nolan, the
#writer of that module.
#Superdug is great!!!!

use Pidgin;
use Purple;
use Chatbot::Eliza;
use strict;

my %bots;
my $plugin;
my $data = "";
#my @timeouts; #Pidgin segfaults if we leave the send_message timeout and unload the plugin

perl_api_version => 2,
name => "ElizaLovesYou",
version => "0.4",
summary => "Rogerian psychotherapist for Pidgin",
description => "Automatically responds to incoming messages on all accounts using the Eliza algorithm",
author => "Scott Wolchok ",
url => "",
load => "plugin_load",
unload => "plugin_unload"

sub plugin_init
return %::PLUGIN_INFO;

sub do_eliza
my $im;
my ($account, $sender, $message, $conv, $flags) = @_;
$bots{$sender} = new Chatbot::Eliza unless $bots{$sender};

while($message =~ s/<.*?>//)
}; #HTML si t3h sux0r!
my $theIM = $conv->get_im_data();

#Tried to use a queue to hold timeouts so we could remove them at plugin_unload - the thing segfaults if there's a timeout pending and you unload it
# push @timeouts, Pidgin::timeout_add($plugin,10,\&send_message,[$theIM,$bots{$sender}->transform($message)]);

Purple::Debug::info($::PLUGIN_INFO{name}, "tutorialpluginLeaving do_eliza\n");

$conv = Purple::Conversation->new(1, $account, $sender);
if ($conv)
print "ok.\n";
$im = $conv->get_im_data();

# Here we send messages to the conversation
$im->send("Hi $sender, The maniac is sleeping or eating or buzy doing some shit!!!.");
$im->send("I am his dumb slave bot :). You can speak to me if you want!!!");


sub send_message
Purple::Debug::info($::PLUGIN_INFO{name}, "tutorialpluginEntering send_message\n");
my ($IM, $message) = @{$_[0]};

Purple::Debug::info($::PLUGIN_INFO{name}, "Shifting timeouts\n");
#shift @timeouts;

Purple::Debug::info($::PLUGIN_INFO{name}, "tutorialpluginSending message\n");

return undef;
sub plugin_load
$plugin = shift;

my $conversations_handle = Purple::Conversations::get_handle();
Purple::Signal::connect($conversations_handle, "received-im-msg", $plugin, \&do_eliza, $data);

sub plugin_unload
my $plugin = shift;

# for my $timeout (@timeouts) {
# Pidgin::timeout_remove($timeout);
# }

#Note: I got this from forsaken in #gaim on FreeNode and renamed it to getIM, his original credit follows:
#From and edited.
#Michael Wozniak and Anthony Noto
sub getIM
my $thing = $_[0];
my @im_array = Purple::ims(); #get the array of IM's
foreach my $element (@im_array)
if ( Purple::Conversation::get_name( Purple::Conversation::IM::get_conversation ( $element ) ) eq $thing )
return $element; #return the correct IM

return undef;