Category Archives: Tips for computer

Searching for a bug in a haystack – cracking the codes of Inventory Management System

Notice: Undefined variable: blogurl in /home/customer/www/ on line 189

My work was in need of a simple inventory management system to keep track of the prototype components. I have been given a small budget to buy one. So I went on Internet to search for a reasonably priced inventory management system. Most of the solutions are a bit too powerful for what we need, thus are too expensive.

Three weeks ago, I came across an open-source inventory management system. So I downloaded the source files (mostly php files) and started running it. I ran into several issues but was able to resolve most of them – due to file/directory privilege and dos/unix file transfer issues. All except one: the default “date” in a part transaction are all showing up as “{NAME}” instead of the numbers on the month/day/year fileds. What’s going on there? This plunged me into the world of php, xml, ajax, css and etc. I borrowed books from library like “PHP/MySQL for dummies” and “PHP 5 Advanced” by Larry Ullman . Both were very nice books in helping me to understand the intricate interaction between PHP and MySQL. I learned a lot of object-oriented programming (OOP) and a little bit on Ajax. But having learned the basic probably helps me to start a small project on my own. Tackling a full-blown sophisticated software like IMS that I downloaded was a totally different story.

By far the worst part about developing or debugging a PHP software/module is the fact that you’re dealing with a software running on a remote host and displaying the output on a browser. It’s difficult to insert variable dumps along the way to keep pace with the program flow because there is no console screen and showing the raw variable values on the browser may screw up your display. Not an easy thing to do. So I searched the net to find a debugger. The most popular debugger is NuSphere’s PhpEd. I downloaded the trial version and started debugging. I never used a debugger before so I needed to get used to the interface plus interrogating the variables values while tracing the program steps. Overall, the software does its job well and is fairly powerful. I don’t think I could have found the bug without its help. I think I’ll buy the software. See below for the exact bug.

After tracing this software code, I was very impressed with the author’s programming style and his modular approach. Modular is nice because it’s readily expandable but it’s very difficult to follow due to the jumping around among the classes/files.

By working with the debugger, I now understands a little bit about how the program works. I was then able to modify the titles and changed the fields slightly to meet our needs. Proudly, I demo’ed the tool to my technician crew who will be using the software to track our inventory. And guess what? They wanted to add a “project” field and a search function. That’ll teach me a lesson to download a freeware. 🙂 I did learn a few things along the way but may end up supporting/expanding the software for the rest of my career 🙁

Here’s the bug I found around line 122 on “lib/html.php”:

if (is_array($extra_vars[$key])) {
$repl_array = array_merge($repl_array,$extra_vars[$key]); }
/* In the above “is_array($extra_vars)” got changed to “is_array($extra_vars[$key])” by Derek Tsai,
$repl_array kept getting NULL’ed due to array_merge with a NULL variable */

Sendmail relay woe on VPN

Today I ran into the a weird sendmail problem: I kept getting “relay denied” message when I tried to send emails out. I tried another mail host without any problem. I even used another client machine to send mail from my original mail host without any problem. I checked the /var/log/syslog and found something like the below:

Sep 20 11:36:42 tsai86 sendmail[7272]: [ID 801593 mail.notice] l8KIafBt007272: ruleset=check_rcpt, arg1=, relay=vpn-129-150-36-151.Central.Sun.COM [], reject=550 5.7.1 … Relaying denied

Checking against earlier successful email log like the below, I noticed the difference being “relay = vpn-129-150-36-151.Central.Sun.COM []” vs. “relay=local”.

Sep 20 10:55:57 tsai86 sendmail[7160]: [ID 801593] l8KHtsjO007159: to=, delay=00:00:01, xdelay=00:00:01, mailer=local, pri=34029, relay=local, dsn=2.0.0, stat=Sent

Cutting to the chase, I logged out of the VPN session and re-logged in the VPN. Voila! The send mail problem went away. How strange! The only explanation I have is that the VPN somehow got confused thinking I’m on a different domain or the IP address got interpreted to be on a different domain. A little hiccup on the network creates a slew of problems. I was told I wasn’t the only one having the problem. Strange indeed.

Installing PHP on Solaris 10

Depending on which version of Apache 2 you have, you may download certain version of the php.
I went through a lot to get this working. Part of the problem is that I was confused by the bundled version of the Apache with Solaris and I couldn’t figured out where is where as there were two copies of the Apache 2. Anyway, hopefully the following instruction is not too confusing.

I had the Apache 2 version 2.2.4 (downloaded from, so I downloaded PHP 5.2.3 from

PHP needs configuration. php.ini related files are in /usr/local/php/doc/php along with other documentation. php.ini needs to be installed in /usr/local/php/lib. The file is installed in /usr/local/apache2/modules by default. The following two lines

LoadModule php5_module modules/
AddType application/x-httpd-php .php

need to be placed in your httpd.conf file in their appropriate places.
The httpd.conf is normally stored in /usr/local/apache2/conf directory.

Run the following command to restart Apache 2, now with php feature.
# /usr/local/apache2/bin/apachectl restart

Installing MySql on Solaris 10

I followed the Mel Lester Jr.’s instructions with some minor tweaks on the paths.

To start using the mysql bundled with Solaris 10, a number of post-install procedures need to be made by root. This configuration has been successfully tested in a Sparce Root Local Zone. The following steps are derived from the mysql manual (, manual.txt or manual_toc.html) found in the /usr/sfw/src/mysql/Docs directory.

1. Log in as root and initialise the database tables.
# /usr/local/mysql/bin/mysql_install_db
Preparing db table
Preparing host table
Preparing user table
Preparing func table
Preparing tables_priv table
Preparing columns_priv table
Installing all prepared tables
060118 21:24:03 /usr/local/mysql/bin/mysqld: Shutdown Complete

2. Create mysql user and group and change data directory group.
# groupadd mysql
# useradd -g mysql mysql
# chgrp -R mysql /var/mysql
# chmod -R 770 /var/mysql
# installf SUNWmysqlr /var/mysql d 770 root mysql
# chown -R mysql:mysql /usr/local/mysql/var (critical step or you may end up with “[1] Exit 127”
(This took me a while to figure out, this directory is where the database is stored. Good to know if you want to back up)

/usr/local/bin/mysqld_safe –user=mysql
# Starting mysqld daemon with databases from /usr/local/mysql/var
STOPPING server from pid file /usr/local/mysql/var/
070902 23:39:39 mysqld ended

3. MySQL reads configuration files from different places in the following order:
Filename Purpose
——— ———
/etc/my.cnf Global options
DATADIR/my.cnf Server-specific options
defaults-extra-file The file specified with –defaults-extra-file=path
~/.my.cnf User-specific options

4. Optionally copy a mysql daemon configuration file to configuration directory.
Note: there are other configuration profiles available.
For default solaris installation DATADIR is /var/mysql.
# cp /usr/local/mysql/share/mysql/my-medium.cnf /var/mysql/my.cnf

5. Start mysql daemon as mysql user manually
# /usr/local/mysql/bin/mysqld_safe –user=mysql &

6. Set the root MySQL user password (Substitute a unique password for “new-password”)
# cd /usr/local/mysql/bin

Note the use of single quotes surrounding your new-password and the back ticks surrounding the hostname command — they are not the same!
# ./mysqladmin -u root password ‘new-password’
# ./mysqladmin -u root -h `hostname` password ‘new-password’

7. Test the server:
# ./mysqlshow -p
Enter password: new-password
| Databases |
| mysql |
| test |
# ./mysql -u root -p
Enter password: new-password
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3 to server version: 4.0.20-standard
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the buffer.
mysql> show databases;

| Database
| information_schema |
| mysql |
| test |
3 rows in set (0.00 sec)
8. mysql> quit;

9. Optionally perform the following steps for automatic start and stop of mysql daemon at boot and shutdown: (This doesn’t quite work for me and I haven’t figured out how to use the svc service to do this automatically.) Stay tuned…
Link boot time start up script from rc3.d and rc[012S].d
# ln /usr/local/mysql/share/mysql/mysql.server /etc/rc3.d/S99mysql
# ln /usr/local/mysql/share/mysql/mysql.server /etc/rc0.d/K00mysql
# ln /usr/local/mysql/share/mysql/mysql.server /etc/rc1.d/K00mysql
# ln /usr/local/mysql/share/mysql/mysql.server /etc/rc2.d/K00mysql
# ln /usr/local/mysql/share/mysql/mysql.server /etc/rcS.d/K00mysql

Installing IMAP server on Solaris 10

I run my own mail server at work for largely one reason – no restriction on the mail storage space. Our Corporate IT sets a limit on ~ 2-year worth of emails archive you’re allowed to keep and some set number of GB’s you are allocated. This is simply not enough for me. Having worked at Sun for 12 years, I have had emails all the way back to ’95. Occasionally, I went back to find an old email and surprised my colleagues how “deep” of a memory I had. In order to do this (probably due to my hoarding and/or control instinct), I must have my own mail server. Good thing is that Solaris is pretty good at relaying emails. I only have to worry about servicing the IMAP clients – my laptop, my PC at home and etc.

Here are what I do (regularly, due to frequent change of servers) to set up an IMAP server on my work server running Solaris 10:

1) Download and install the University of Washing IMAP server package from
2) Download and install the opensll package
3) In order to run secure SSL socket, you’d need to create an self-assigned SSL certificate:
> /usr/local/ssl/bin/openssl req -new -x509 -nodes -out imapd.pem -keyout imapd.pem -days 3650
4) cp imapd.pem /usr/local/ssl/certs
5) To add to svc servces, so the port 993 gets used for imaps:
edit /etc/services add the following line in addition to “imap 143/tcp”:
imaps 993/tcp
6) Due to the new Solaris SMF (Service Management Facilities), you’ll need to have IMAP added to the service. The easiest way to do this without constructing an esoteric svc manifest file, is to edit /etc/inet.conf and add the following line:
imaps stream tcp nowait root /usr/local/sbin/imapd imapd
7) Run the following command to convert to manifest file (/var/svc/manifest/network/imaps-tcp.xml):
8 ) Start the svc by running the following command:
svcadm enable /network/imaps/tcp

Done. Not too bad but wouldn’t it be nice if the installation takes care of all these steps in one shot?

Installing Apache2 with SSL (httpd) on Solaris 10

Most of the below are copied from Mel Lester Jr. ( with some minor modifications to his tips:

Apache 2.xx is included with Solaris 10. A few configuration details need to be addressed prior to starting Apache 2.xx:
1. Login as root
wired# _

2. Copy the file, /etc/apache2/httpd.conf-example to /etc/apache2/httpd.conf
wired# cp /etc/apache2/httpd.conf-example /etc/apache2/httpd.conf

3. Edit /etc/apache2/httpd.conf
? Set ServerName if necessary (default is
? Set ServerAdmin to a valid email address
4. From the command line type:
wired# svcadm enable apache2

That is all it takes to to start the basic Apache 2 web server bundled with Solaris 10. In fact, the Apache 2 web service should persist through server and/or zone boots. The actual web pages are located in the /var/apache2/htdocs directory by default.

SSL Certificate Configuration for Apache2 on Solaris 10
By: Mel Lester Jr. (
Version 1.04 June 21, 2006)

1. Enable SSL Service Property if necessary. Log in as root and issue the following command:
web# svcprop -p httpd/ssl svc:network/http:apache2

If the response is “false”, issue these three commands:
web# svccfg -s http:apache2 setprop httpd/ssl=true
web# svcadm refresh http:apache2
web# svcprop -p httpd/ssl svc:network/http:apache2

If the response is “true”, continue to the next step.
2. Create a Certificate Directory and a Key Directory.
web# mkdir /etc/apache2/ssl.crt
web# mkdir /etc/apache2/ssl.key

3. Generate a RSA Key.
web# /usr/local/ssl/bin/openssl genrsa -des3 1024 > /etc/apache2/ssl.key/server.key
Generating RSA private key, 1024 bit long modulus
e is 65537 (0x10001)
Enter pass phrase: ********
Verifying – Enter pass phrase: ********

4. Generate a Certificate Request.
web# /usr/local/ssl/bin/openssl req -new -key /etc/apache2/ssl.key/server.key > \
> /etc/apache2/ssl.crt/server.csr
Enter pass phrase for /etc/apache2/ssl.key/server.key: ********
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
Country Name (2 letter code) [US]::US
State or Province Name (full name) [Some-State]:OR
Locality Name (eg, city) []:Blodgett
Organization Name (eg, company) [Unconfigured OpenSSL Installation]:DIS
Organizational Unit Name (eg, section) []:IT
Common Name (eg, YOUR name) []:Big Cheese
Email Address []
Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []: ********
An optional company name []: Live Free or Die

5. Install a Self-Signed Certificate. If you are going to install a certificate from an authoritative source, follow their instructions and skip this step.
web# /usr/local/ssl/bin/openssl req -x509 -days 3650 -key \
> /etc/apache2/ssl.key/server.key \
> -in /etc/apache2/ssl.crt/server.csr > \
> /etc/apache2/ssl.crt/server.crt
Enter pass phrase for /etc/apache2/ssl.key/server.key: ********

6. Modify the ssl.conf file to use your certificate.
web# cd /etc/apache2
web# ls -l
total 334
-rw-r–r– 1 root bin 1987 Jan 6 21:10 highperformance-std.conf
-rw-r–r– 1 root bin 1987 Jan 6 21:10 highperformance.conf
-rw-r–r– 1 root bin 37519 Jan 6 21:10 httpd-std.conf
-rw-r–r– 1 root root 37660 Jan 18 21:49 httpd.conf
-rw-r–r– 1 root bin 37661 Jul 20 2005 httpd.conf-example
-rw-r–r– 1 root bin 12959 Jan 6 21:10 magic
-rw-r–r– 1 root bin 15020 Jan 6 21:10 mime.types
-rw-r–r– 1 root bin 10759 Jan 6 21:10 ssl-std.conf
-rw-r–r– 1 root bin 10996 Jan 6 21:10 ssl.conf
drwxr-xr-x 2 root root 512 Jan 19 03:24 ssl.crt
drwxr-xr-x 2 root root 512 Jan 19 02:52 ssl.key

Edit the ssl.conf and change the line that begins with “ServerAdmin” to reflect an email address or alias for the Server’s Administrator.
7. Test the SSL Certificate with Apache2
? If Apache2 is enabled, disable it during testing.
web# svcs | grep -i apache2
online 3:29:01 svc:/network/http:apache2
web# svcadm disable apache2

? Use the legacy script to manually test start Apache2 with SSL.
web# /usr/apache2/bin/apachectl startssl
Apache/2.0.52 mod_ssl/2.0.52 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide us with the pass phrases.
Server (RSA)
Enter pass phrase: ********
Ok: Pass Phrase Dialog successful.

If this test fails with an error similar to ‘vhost.c:232 assertion “rv == APR_SUCCESS” failed on startssl’, your server may not be configured to use DNS to resolve host names. This failure is due to a known bug in Apache2 2.0.nn. A quick fix is be to edit the hosts line in your server’s /etc/nsswitch.conf to look like the following:
hosts: files dns

More information about this issue may be found at:

After editing /etc/nsswitch.conf or otherwise resolving the issue, repeat the test until you are able to manually start and stop Apache2 using your SSL Certificate and Pass Phrase.
web# ps -ef | grep httpd
root 1392 575 0 03:45:16 ? 0:01 /usr/apache2/bin/httpd -k start -DSSL
root 1400 1116 0 03:45:51 pts/3 0:00 grep httpd
webservd 1393 1392 0 03:45:18 ? 0:00 /usr/apache2/bin/httpd -k start -DSSL
webservd 1397 1392 0 03:45:18 ? 0:00 /usr/apache2/bin/httpd -k start -DSSL
webservd 1396 1392 0 03:45:18 ? 0:00 /usr/apache2/bin/httpd -k start -DSSL
webservd 1395 1392 0 03:45:18 ? 0:00 /usr/apache2/bin/httpd -k start -DSSL
webservd 1394 1392 0 03:45:18 ? 0:00 /usr/apache2/bin/httpd -k start -DSSL

? If your results are similar to the one above, use the legacy script to conclude the test. You may also want to verify that a client browser can access your site using https before continuing. Accept the self-signed Certificate if necessary.
web# /usr/apache2/bin/apachectl stop

8. Enable Apache2 with SSL to be started automatically as a service.
web# cd /etc/apache2/ssl.key
web# cp server.key
web# /usr/local/ssl/bin/openssl rsa -in -out server.key
Enter pass phrase for ********
writing RSA key
web# chmod 400 server.key
web# svcadm enable apache2
web# svcs | grep -i apache2
online 4:29:01 svc:/network/http:apache2

Setting up fixed IP address on Solaris system

Since I do Solaris system builds quite a bit, I thought I document the tips on how to set up a Solaris system to have a fixed IP address instead of DHCP:

1) edit /etc/hostname. to have the hostname on the 1st line without a linefeed
where the interface is the network interface, which can be found by running ‘ifconfig -a’
2) edit /etc/nodename to have the hostname on the 1st line without a linefeed
3) edit /etc/inet/ipnodes to have the hostname
4) edit /etc/hosts to include the given fixed IP address and its hostname
5) edit /etc/defaultrouter to have the gateway IP address
6) remove or rm /etc/dhcp.interface