Animesh's Tech Blog

Friday, June 02, 2006

Installation of Apache PHP MySQL Perl on Linux made easy, opensource integrated development middleware

Open source stacks such as XAMPP from Apache Friends are simplifying open source development by making it easier to write and distribute applications in a stable and standardized environment. Traditionally, AMPP -- Apache, MySQL, PHP, and Perl -- have all been installed and configured as separate products. The trend of combining them into integrated middleware stacks promises to make open source development more competitive with J2EE™ application development, at least for low-end applications. In this article, you'll learn how to install, configure, and back up XAMPP on Mandrake Linux™ 10.0 and also how to configure and administer XAMPP, as well as how to install your own applications in an XAMPP environment.

The advent of Java 2 Enterprise Edition™ dramatically changed the software landscape by providing an integrated middleware stack that greatly simplified the task of writing and deploying Java™ applications. For a while, the open source community was left behind because it lacked a similar integrated architecture.

Recently, with the introduction of integrated open source stacks like XAMPP from Apache Friends, this situation has started to change. These stacks are still quite simple and rudimentary when compared with J2EE, but they are nevertheless an important step on the way to fuller systems integration. PHP 5.0 (which makes PHP fully object oriented) is a good indicator that this trend will accelerate.

The focus of this article is on one of the integrated, open source stacks: XAMPP from Apache Friends.

Introducing XAMPP

XAMPP is a full-featured AMPP (Apache MySQL, PHP, Perl) package that is one of the few non-commercial AMPP middleware stacks available on Linux. With its tight integration, XAMPP makes it possible to run anything from a personal home page to a full-featured production site (though only for development purposes; XAMPP is not meant to be used on a production server due to security issues).

XAMPP really shines in the following areas:

  • It is easy to install and set up.
  • It contains a number of useful packages that make it easy to do things like generate traffic reports and accelerate PHP content.
  • It has been thoroughly tested on the SUSE, Red Hat, Mandrake, and Debian Linux distributions, as well as on Windows® and Solaris.

For this article, we will install XAMPP under Mandrake Linux 10.0. Let's start by looking at the default packages that come with XAMPP.

Basic packages

Basic packages include system, programming, and server software:

  • Apache, the famous Web server
  • MySQL, an excellent, free, open source database
  • PHP, the programming language (in versions 4.3.8 and 5.0.1 at the time of this writing)
  • Perl, the programming language
  • ProFTPD, an FTP server
  • OpenSSL, for secure sockets layer support

Graphics packages

XAMPP includes the following graphics-related packages:

  • GD, the "Graphics Draw" library
  • libpng, the official PNG reference library
  • libjpeg, the official JPEG reference library
  • ncurses, the character graphics library

Database packages

And what would an integrated stack be without some database packages such as:

  • gdbm, the GNU implementation of the standard UNIX® dbm library
  • SQLite, an extremely small, zero-configuration SQL database engine
  • FreeTDS, a database library that gives UNIX and Linux programs the ability to talk to Microsoft® SQL and Sybase databases

XML packages

For XML development, XAMPP includes the following:

  • expat, an XML parser library
  • Salbotron, an XML toolkit
  • libxml, an XML C parser and toolkit for GNOME

PHP packages

For PHP development, XAMPP includes the following:

  • PEAR, the PHP library
  • A pdf class that generates dynamic PDF documents with PHP
  • TURCK MMCache, a PHP performance enhancer

Other packages

And finally, XAMPP demonstrates its versatility by including the following packages:

  • zlib, a compression library
  • mod_perl, which embeds a persistent Perl interpreter in Apache
  • gettext, a toolset that assists GNU packages in producing multi-lingual messages
  • mcrypt, an encryption program
  • Ming, a Flash (SWF) output library
  • Freetype2, a software font engine
  • IMAP C-Client, a mail program API

Now let's talk about installing XAMPP.

Back to top

Installing and daemonizing

To install XAMPP, download the latest binary from the Apache Friends Web site (see Resources for a link). Untar it to /opt using the following command:

tar xvfz xampp-linux-1.4.7.tar.gz -C /opt

That's it! XAMPP is now installed in /opt/lampp. Any previous installations that were in /opt have been overwritten. If you are running an older version of XAMPP and don't want to download the entire package again, Apache Friends has an upgrade package available for download.

Now that everything is installed, let's start the new daemons. Change your current working directory to /opt/lampp (cd /opt/lampp) and enter the following:

./lampp start

You should see the following:

Starting XAMPP for Linux 1.4.7...
XAMPP: Starting Apache with SSL (and PHP5)...
XAMPP: Starting MySQL...
XAMPP: Starting ProFTPD...
XAMPP for Linux started.

XAMPP is now up and running. The best way to verify this is to open a browser and type localhost in the address bar and hit the Enter key. You should be redirected to the XAMPP welcome page.

Figure 1. The XAMPP welcome page
The XAMPP welcome page

Click the Status link in the left navigator to see that the necessary services have started up correctly. If all is well, you should see the following page:

Figure 2. Service status page
Service status page

Congratulations! You have just installed and set up a fully working AMPP development environment. Now let's install a simple application to demonstrate how you can use the environment.

Back to top

Installing a simple application

To make use of XAMPP's basic features, you need a simple application. The best application would be one that utilizes a database back end; a relatively simple database containing one table would be fine.

The test database will contain one table with one column. Let's follow the (computer-) age-old tradition of test programs and plan for our table to hold a single record of "Hello World!". We'll access this database using both a Perl and a PHP script. Both scripts will access the database, retrieving the single row and outputting it to the screen.

The tool

Our database will be created and administered using phpMyAdmin, an excellent Web-based MySQL administration tool written in PHP. It has a great user interface and allows you to do many things of varying complexity, ranging from creating/dropping/altering databases and tables to exporting data, managing keys, and processing SQL files. phpMyAdmin is a great tool because:

  • It helps beginners familiarize themselves with MySQL without having to deal with what can be intimidating command-line interfaces.
  • It allows advanced users to do the more simple and routine tasks with speed and ease.
  • It's handy for those occasions when you want to give someone database administration privileges without allowing them the almighty shell access.

Creating the database

To create the test database in phpMyAdmin:

  1. Go to the XAMPP start page (localhost).
  2. Select phpMyAdmin in the left navigator under Tools.
  3. In the Create New Database field on the phpMyAdmin home page, enter hello_world and click Create.

Now you must create a table within this database and specify how many fields the table should contain (a field is analogous to a column). Let's call our table "hello_table" and have it contain one field to hold our record of "Hello World!". Enter hello_table in the Name text field and enter 1 in the Fields text field. When you are done, click Go.

Now it's time to execute the last step of database creation: choose a name and a data type definition for our column. Let's stick with the "hello" theme and name our column "hello_column"; enter hello_column in the Field text field.

Because we will be storing the string "Hello World!" in our column, its type must be a type of char with a length of 12 (the length of the string "Hello World!"). The default type varchar is sufficient. In the Length/Values text field next to Type, enter 12 for a max length of 12 characters. Don't worry about the rest of the fields on this page. Go ahead and click Save.

If everything was done correctly, you should see the following:

Figure 3. Hello World database summary
Hello World database summary

Now let's insert our record of "Hello World!". Click the Insert tab and enter "Hello World!" in the Value text field. The Function drop-down list can be left alone in this case. Click Go to insert your "Hello World!" record into the database.

To confirm that the record was inserted successfully, click the Browse tab. Your "hello world" listing should be displayed.


Now that the back end is up and running, it's time to handle the scripting part. We will use two scripts, one in Perl and one in PHP. Our only requirements for each script will be one database connect, one database access, and an output to the screen of the retrieved row.

Listing 1. Simple database connection and retrieval in PHP using PEAR::DB

require_once 'DB.php'; // must be included in any script that uses PEAR::DB

// it is a huge security risk to store your database connection information
// in the same file as your code. We have done it here solely for the purpose
// of this example. Please store your database connection information in another
// file that is not in your document root directory and adequately protected.
// database connection information

$db_host = "localhost"; // hostname of the database server
$db_user = "root"; // database user's username
$db_pass = ""; // database user's password, nothing by default
$db_name = "hello_world"; // the name of the database to connect to
$db_type = "mysql"; // the type of database server.

// your data source name string. This contains the connection
// information for your database.
$dsn = "$db_type://$db_user:$db_pass@$db_host/$db_name";

// creates a database connection object or a database error
// object based on the success of the database connection.
$db = DB::connect($dsn, TRUE);

// if an error was encountered, the script exits with an error message
if (DB::isError($db)) {
// SQL query that you wish to use to query the database
$sql = "SELECT * FROM hello_table";

// query the database, store result in $result
$result = $db->query($sql);

// exits with an error message if the query was unsuccessful
// fetch rows from the database until no more rows exist.
// output the "hello_column" field of each row to the screen.
// once no more rows exist, exit with an error message.
while($row = $result->fetchRow(DB_FETCHMODE_OBJECT)){


$db->disconnect(); //disconnect from the database

Each script connects to the database, retrieves a row of data, and outputs that row to the screen. PHP's database accesses are done using PEAR::DB, a handy database abstraction layer that allows the same database-access code to be used regardless of what database is implemented. Unfortunately XAMPP doesn't yet come with a database abstraction layer for Perl.

Placing the scripts

So, now we have everything we need. Our database is up and running and we have two scripts with which to test it. All we've got to do now is put the scripts in the right place. Let's take a quick look at how XAMPP is laid out on the hard drive in Listing 2.

The directory that interests us here is /opt/lampp/htdocs/, the Apache Documents directory. Any Web pages and associated files that you want to be displayed when someone accesses your Web site's root address are placed here. Since we were able to view the XAMPP welcome page, this directory already has some files in it. Let's take a quick peek at the directory listing to confirm this (type ls /opt/lampp/htdocs):

drwxr-xr-x 2 root root 4096 Jan 24 2003 apache
-rwxr-xr-x 1 nobody root 163 Oct 31 2003 index.html
drwxr-xr-x 2 nobody root 4096 Sep 12 21:54 webalizer
drwxr-xr-x 5 root root 4096 Jun 15 06:24 xampp

As you can see, there is material here already. Let's make our own directory called hello_world (mkdir hello_world) in which to store our scripts. From now on, you can access all materials in the hello_world directory by typing localhost/hello_world. Now, save your two scripts to that directory. You are done!

Testing the application

To test the application, go to your browser of choice, and enter localhost/hello_world. You should see the following:

Figure 4. Hello World!
Service status page

Congratulations! You have set up an application on XAMPP.

Back to top

Security enhancement

The purpose of XAMPP is to be a development environment. It is configured to give the programmer free reign over the toolset with no restrictions. As a result of that freedom of movement, the default XAMPP installation is extremely insecure. For example, there are almost no logins required for anything.

For versions of XAMPP 0.9.5 and later, you can beef up security by running the command:

/opt/lampp/lampp security

You will be prompted with various statements that note the insecurities that exist, and you will be given a choice whether to fix that insecurity. While this makes your XAMPP installation more secure, you should still avoid running XAMPP on a production server. Listing 3 illustrates the security prompts:

Listing 3. Security issues prompted in XAMPP

XAMPP: Quick security check...
XAMPP: Your XAMPP pages are NOT secured by a password.
XAMPP: Do you want to set a password? [yes] yes
XAMPP: Password:
XAMPP: Password (again):
XAMPP: Password protection active. Please use 'lampp' as user name!
XAMPP: MySQL is accessable via network.
XAMPP: Normaly that's not recommended. Do you want me to turn it off? [yes] yes
XAMPP: Turned off.
XAMPP: Stopping MySQL...
XAMPP: Starting MySQL...
XAMPP: The MySQL/phpMyAdmin user pma has no password set!!!
XAMPP: Do you want to set a password? [yes] yes
XAMPP: Password:
XAMPP: Password (again):
XAMPP: Setting new MySQL pma password.
XAMPP: Setting phpMyAdmin's pma password to the new one.
XAMPP: MySQL has no root passwort set!!!
XAMPP: Do you want to set a password? [yes] yes
XAMPP: Write the password somewhere down to make sure you won't forget it!!!
XAMPP: Password:
XAMPP: Password (again):
XAMPP: Setting new MySQL root password.
XAMPP: Setting phpMyAdmin's root password to the new one.
XAMPP: The FTP password is still set to 'lampp'.
XAMPP: Do you want to change the password? [yes] yes
XAMPP: Password:
XAMPP: Password (again):
XAMPP: Reload ProFTPD...
XAMPP: Done.

Back to top

Performing backups

So, your XAMPP installation has been up and running for a couple of weeks and you've amassed quite a sizeable set of data that you don't want to be at risk from a hard drive crash. What do you do about backups?

This is quite simple with XAMPP. Change your current working directory to /opt/lampp (cd /opt/lampp) and type in the following command:

./lampp backup

You will want to add on your MySQL root password if you have it set to the end of that command. You should then see the following:

Backing up databases...
Backing up configuration, log and htdocs files...
Calculating checksums...
Building final backup file...
Backup finished.
Take care of /opt/lampp/backup/

To restore your backup, run the following command as root:

sh backupfilename

You will see the following if all goes well:

Checking integrity of files...
Restoring configuration, log and htdocs files...
Checking versions...
Installed: XAMPP 1.4.7
Backup from: XAMPP 1.4.7
Restoring MySQL databases...
Restoring MySQL user databases...
Backup complete. Have fun!
You may need to restart XAMPP to complete the restore.

Restart XAMPP (cd /opt/lampp, ./lampp restart), and your restored data should be readily available.

Back to top

Ready to rAMPP up?

Whether integrated solution stacks ever fully compete with J2EE solutions remains to be seen, but the recent release of PHP 5.0 (its major addition includes full object orientation) coupled with the rapid growth of the MySQL database indicates that integrated AMPP solution stacks are becoming more popular among developers. This means that open source middleware stacks like XAMPP might have some elbow room at the lower end of the software market.

Back to top


  • Download XAMPP at Apache Friends, a nonprofit organization that promotes the Apache Web server and has the latest XAMPP information and releases.

  • Introduction to PHP (developerWorks, December 2000) can get you started on the PHP scripting language. And while you're there, just type "PHP" into the search field for links to some of the many PHP resources available from IBM.

  • The Road to better programming series (developerWorks) is an excellent hands-on series for sharpening your Perl perspective. For more on Perl, search the developerWorks site.

  • These two articles, Connecting PHP Applications to Apache Derby (developerWorks, September 2004) and Develop Perl applications with Apache Derby (developerWorks, October 2004) are a must-read for PHP and Perl application developers.

  • The phpMyAdmin project contains a lot of great information as well as downloads of the awesome Web-based MySQL administration tool.

  • Practical Unix & Internet Security (O'Reilly & Associates, 1996) is an excellent reference on all aspects of system security from user management to drafting a security policy.

  • offers an online searchable function library that is a great aid to finding detailed information on PHP methods and to hunting down builds of the language.

  • The PHP Extension and Application Repository (PEAR) offers components that make programming PHP simpler, including the ever-popular PEAR::DB.

  • For help with MySQL, the MySQL reference manual contains detailed information on all aspects of the popular database.

  • Visit the Apache HTTP Server Project for the latest builds and information on the Web's most popular http server.

  • Find more resources for Linux developers in the developerWorks Linux zone.

  • Download no-charge trial versions of IBM middleware products that run on Linux, including WebSphere® Studio Application Developer, WebSphere Application Server, DB2® Universal Database, Tivoli® Access Manager, and Tivoli Directory Server, and explore how-to articles and tech support, in the Speed-start your Linux app section of developerWorks.

  • Get involved in the developerWorks community by participating in developerWorks blogs.

  • Browse for books on these and other technical topics.

Back to top

About the author

Nils-Erik Frantzell is currently studying computer science at the University of California, Santa Cruz. His interests include Linux, Web programming (particularly PHP), networking, open source technologies, and fiddling with computer hardware. He spends his time away from the computer tending to his carnivorous fishes while listening to electronic music. You can contact Nils-Erik at

This is a copy of the article be found at

Tuesday, May 30, 2006

Data recovery technique from corrupted ext2/ext3 filesystem having bad superblock

NOTE : I do not take any responsibilty of any damage to your disk or data while trying my technique or any of my commands stated in this article. YOU HAVE BEEN WARNED!!!

1. Let's say our corrupted filesystem is at partition /dev/sdb3 of ext3 type. We will mount the partition under /mnt/sdb3, so create the directory structure if you dont have it already.

Also, create the following directory structure to keep backup data.
mkdir /sdb3-backup
mkdir /sdb3-backup/image
mkdir /sdb3-backup/copy

Note that ext3 filesystem is same as ext2, with only addition of journal. So our entire technique will use ext2 filesystem if even our corrupted filesystem is ext3 type. Because our aim is to recover data not journal recovery (which is unrecoverable as far as I know). So be carefull while you issue any of my commands, unless explicitly told dont add any ext3 filesystem type in any of our command. Use all my command as it is written below.

2. Before applying this technique be sure that your superblock is corrupt only not the entire disk or something else.


A. Try to mount the disk read only using

mount -t ext2 /dev/sdb3 /mnt/sdb3 -o ro

mount -t ext2 -o ro,errors=recover,errors=continue /dev/sdb3 /mnt/sdb3

Check the message you are getting. it must be something like below :

mount: wrong fs type, bad option, bad superblock on /dev/sdb3,
or too many mounted file systems

B. Now try "dmesg | more" to actually verify if the superblock is really damaged. We will see a line like below :

EXT2-fs: unable to read superblock

Now we will first start to recover the data by mounting it then we will try to correct the filesystem.

3. Before doing that I'd recommend taking an image, something like
dd if=/dev/sdb3 of=/sdb3-backup/image/backup

and then using the loop
device to work on that. If the partition's bigger than 2 gig you will probably need to compress it first with something like
dd if=/dev/sdb3 | gzip > /sdb3-backup/image/backup.gz

(note that if it's compressed the loop device won't
work and you'll have to work on the bare hardware). If using an alternate superblock doesn't work a last ditch fix may be
mke2fs -S /sdb3-backup/image/backup (or mke2fs -S /dev/sdb3 if the dd result was too big).

This will rewrite the
superblocks, you will then need to run e2fsck to clean up. This did the
trick for me on a drive that got a whole bunch of bad sectors that I had to get data off.

Hmm, if I'd only have a HDD to save the data, I would be happy :) ; then I could probably do
dd if=/dev/hda2 of=/dev/xyz
e2fsck -b 32768 /dev/xyz

e2fsck would restore the first superblock and my problems were gone...
but I have no second hard disk which is that big :(.

4. Linux file system writes backup of superblock in different locations. Find the backup superblocks using

mke2fs -n /dev/sdb3
The above command will give you a result like below
mke2fs 1.35 (28-Feb-2004)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
14385152 inodes, 28754341 blocks
1437717 blocks (5.00%) reserved for the super user
First data block=0
878 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872

4. Now please note the superblock backup blocks number at the last line and the block size(which is multiple of 1K=1024b). In our case the block size is 4096 that mean 4K (4096/1024=4)

While the block number which must be given to mount is based on the blocksize which is installed on the hard disk (4k in my case), the block number which must be given to mount is calculated on a 1k-block-basis, so I had to multiply 32768*4.

Now we will try to mount the corrupted filesystem partition. We have to tell mount command to use backup superblocks so we will calculate the first backup superblock (if it is OK) 32768*4 = 131072. Now mount with the command below :
mount -t ext2 -o sb=131072 /dev/sdb3 /mnt/sdb3

Now imagine the backup at position 32768 was damaged too . . . then you just try again with the backup stored at position 98304, and 163840, and 229376 etc. etc. until you find an undamaged backup ( there are several backups so if at least one of those five is okay it´s bingo ! )

Use the formula below to calculate the backup superblock location :

Superblock backups stored on blocks location * Block size in K(i.e.Block size/1024) = N
mount -t ext2 -o sb=N /dev/sdb3 /mnt/sdb3
(replace N with the result of the calculation)

5. If you successfully able to mount the partition, go to the mounted partion and copy data using
cd /mnt/sdb3
cp -R /mnt/sdb3/data /sdb3-backup/copy/.

If any of the above steps fails. You need to consult a experienced data recovery experts.

In 90% case of damaged superblock this technique of data recovery works. Hope the above technique will help you too. Please post your result if you use the technique in this article.

And at last I would like to say "ALWAYS BACKUP YOUR DATA IN MULTIPLE / DISK OR MEDIA" so
if one fails you can restore from others.

Please post your comments, to let others know about the technique failure and success rate.
If you have any other sucessfull method to recover data, please post it.

Acknowledgement :