Upgrading the pear installer with pear

I recently tried to install the latest version of PHPUnit, and I ran into a bit of trouble. When I installed pear on SLE 10 (zypper install php5-pear), the installer version was too old to download and install PHPUnit. So, I had to upgrade the pear installer to the latest version before I could install PHPUnit. To do this, simply run ‘pear upgrade pear’ from the command line (or in a shell). After you do that, PHPUnit should install without problems.

To install PHPUnit will all dependencies, execute the following from the command line (or in a shell).

pear channel-discover pear.phpunit.de
pear channel-discover components.ez.no
pear channel-discover pear.symfony-project.com
pear install --alldeps phpunit/PHPUnit

NGINX configuration

I recently configured NginX to run on port 8080, and I thought that I would share my configuration file (nginx.conf).


#user nobody;
worker_processes 1;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log debug;
#pid logs/nginx.pid;

events {
worker_connections 10240;
}

http {
include mime.types;
default_type application/json;
log_format gzip '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent"';

#log_format accounting_log '$time_local,0,$firm_id,$request_ip,Nginx,Lookup,$successFailure,"$request",$http_user_agent,$status,$upstream_response_time';
access_log off;

sendfile on;
keepalive_timeout 65;

#gzip on;

server {
listen *:8080;
error_page 500 502 503 504 403 404 405 = /cache_miss_js;
set $logFile "logs/nginx.log";

location ~* \.php.* {
#access_log $logFile accounting_log;

if ($remote_addr ~* ([0-9]+).([0-9]+).([0-9]+).([0-9]+)) {
set $request_ip $remote_addr;
}
if ($http_x_clientip ~* ([0-9]+).([0-9]+).([0-9]+).([0-9]+)) {
set $request_ip $http_x_clientip;
}

add_header X-ClientIP $request_ip;

root html/start/public;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass php_servers;
fastcgi_pass_header Set-Cookie;
#fastcgi_connect_timeout 50;
#fastcgi_read_timeout 50;
fastcgi_next_upstream timeout error;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME ./html/start/public$fastcgi_script_name; #this is the one line for edition
include fastcgi_params;

if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
}

location / {
error_page 500 502 503 504 = /index.php;
error_page 403 404 405 = /index.php;
access_log $logFile gzip;
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
}

}
}

It is just a development instanstance of Nginx.

The above configuration file works with rewrite rules for Zend Framework.

NginX config
http://wiki.nginx.org/Configuration

Installing a subversion client on SLE 10

I just noticed that SUSE Linux Enterprise Server 10 does not have Subversion in the core repository. Apparently, one has to download a 2.9 GB “developer kit” to get the subversion client RPM.

I did some searching on the internet, and I discovered the RPMs at the following location. I am using x86_64 of SLE 10. You can check your version with the following command: lsb_release -d

wget http://download.opensuse.org/repositories/devel:/tools:/scm:/svn/SLE_10/x86_64/neon-0.26.1-10.1.x86_64.rpm
wget http://download.opensuse.org/repositories/devel:/tools:/scm:/svn/SLE_10/x86_64/subversion-1.6.16-27.1.x86_64.rpm

Neon is a dependency for the subversion client.

Compile PHP 5.3 on Red Hat Linux

I recently compiled PHP 5.3 on RHEL 5.3, and I thought that I would share my configuration options.

First install the dependencies:
yum install mysql mysql-server mysql-devel perl-DBD-MySQL perl-DBI httpd httpd-devel httpd-suexec apr apr-devel apr-util apr-util-devel gd gd-devel gd-progs libjpeg-devel libpng-devel freetype-devel freetype-utils libxml2-devel curl-devel

./configure \
–build=i386-redhat-linux \
–host=i386-redhat-linux \
–target=i386-redhat-linux-gnu \
–program-prefix= \
–prefix=/usr \
–exec-prefix=/usr \
–bindir=/usr/bin \
–sbindir=/usr/sbin \
–sysconfdir=/etc \
–datadir=/usr/share \
–includedir=/usr/include \
–libdir=/usr/lib \
–libexecdir=/usr/libexec \
–localstatedir=/var \
–sharedstatedir=/usr/com \
–mandir=/usr/share/man \
–infodir=/usr/share/info \
–with-libdir=lib \
–with-config-file-path=/etc \
–with-config-file-scan-dir=/etc/php.d \
–disable-debug \
–disable-versioning \
–with-pic \
–disable-rpath \
–with-pear \
–with-curl \
–with-exec-dir=/usr/bin \
–with-freetype-dir=/usr \
–without-gdbm \
–with-gettext \
–with-iconv \
–with-expat-dir=/usr \
–with-zlib \
–with-layout=GNU \
–enable-exif \
–enable-ftp \
–enable-magic-quotes \
–enable-sockets \
–enable-sysvsem \
–enable-sysvshm \
–enable-sysvmsg \
–enable-track-vars \
–enable-trans-sid \
–enable-yp \
–enable-wddx \
–with-kerberos \
–enable-ucd-snmp-hack \
–without-unixODBC \
–enable-memory-limit \
–enable-shmop \
–enable-calendar \
–enable-dbx \
–enable-dio \
–with-mysql=/usr \
–with-mysql-sock=/var/lib/mysql/mysql.sock \
–with-mysqli=/usr/bin/mysql_config \
–with-apxs2=/usr/sbin/apxs \
–without-sqlite \
–with-xml \
–without-odbc \
–enable-dom \
–disable-dba \
–enable-pdo \
–enable-xmlreader \
–enable-xmlwriter \
–with-xmlrpc \
–with-soap \
–with-gd \
–with-openssl \
–with-libxml-dir=/usr \
–disable-cgi

make
make test
make install

You should have a working version of PHP 5.

Check your version:
php -v

Check your modules:
php -i

Setup name based virtual hosts in Apache

Setting up name based virtual hosts in Apache is fairly easy. Create a new file in /etc/httpd/conf.d, which on Red Hat will be loaded automatically by /etc/httpd/conf/httpd.conf.

Using the vi editor, I will create the following file.
vi /etc/httpd/conf.d/virtualhosts.conf

The file contents:

Options Indexes FollowSymLinks
AllowOverride FileInfo
Order allow,deny
Allow from all

NameVirtualHost *:80


ServerAdmin webmaster@sample.com
DocumentRoot “/www/docs/www.sample.com”
ServerName www.sample.com
ErrorLog logs/www.sample.com-error_log
CustomLog logs/www.sample.com-access_log common


ServerAdmin webmaster@sample.com
DocumentRoot “/www/docs/www2.sample.com”
ServerName www2.sample.com
ErrorLog logs/www2.sample.com-error_log
CustomLog logs/www2.sample.com-access_log common


ServerAdmin webmaster@sample.com
DocumentRoot “/www/docs/www3.sample.com”
ServerName www3.sample.com
ErrorLog logs/www3.sample.com-error_log
CustomLog logs/www3.sample.com-access_log common

The above configuration file will create three virtual hosts in the /www/docs directory.

If you have selinux enabled, use the following command to make this directory tree readable by Apache–“-R” means recursive.

chcon -R system_u:object_r:httpd_sys_content_t /www

Verify the selinux permissions:
ls -Z /www

Encrypt a partition with Dm-crypt and Linux Unified Key Setup

Dm-crypt is preferred over TrueCrypt, since dm-crypt is included in the linux kernel and since most distributions include the cryptsetup or cryptsetup-luks package. Moreover, volume encryption (rather than the per file encryption that you get with ecryptfs) is preferred, unless you need to do incremental backups of your file system. LUKS (or Linux Unified Key Setup) is the upcoming standard for Linux hard disk encryption. So, I recommend the cryptsetup-luks package.

First, fill an encrypted disk with initial random data. This makes breaking the passphrase so much harder.
/sbin/badblocks -c 10240 -s -w -t random -v /dev/sdd
OR
dd if=/dev/urandom of=/dev/sdd

Next, partition the new drive.
/sbin/fdisk /dev/sdd

Next, it is time to create a LUKS passphrase.
cryptsetup –verbose –verify-passphrase luksFormat /dev/sdd1
Enter a passphrase of your choice, the longer and more complex the better.

Now, map the logical partition to the physical partition.
cryptsetup luksOpen /dev/sdd1 crypt1
OR
cryptsetup luksOpen /dev/sdd1 sdd1
After you map it, confirm that you created a logical device
ls -al /dev/mapper

Next, format the logical device.
/sbin/mkfs.ext3 -j /dev/mapper/sdc1

Finally, mount the logical device.
mkdir /data
mount /dev/mapper/crypt1 /data

A good Web site for the commands above is:
saout.de

To add an additional passphrase key:
cryptsetup luksAddKey /dev/sdd1

To delete the first passphrase key:
cryptsetup luksDelKey /dev/sdd1 0
Warning: Your data will be lost forever if you delete all of your keys.

To unmount and close:
umount /data
cryptsetup luksClose sdd1

To remount:
cryptsetup luksOpen /dev/sdd1 sdd1
mount /dev/mapper/crypt1 /data

How to build a Debian package

The following are some notes on how to build a Debian package. It is not really a complete tutorial.

I will assume that you are using subversion, and I will assume that you will add your package to an apt repository.

*) Install dependencies
apt-get install svn-buildpackage gcc debhelper dh-make epm fakeroot

*) Make a directory for your source code
mkdir -p packageName/branches
mkdir -p packageName/tags
mkdir -p packageName/packageName-0.1

*) Enter packageName-0.1 directory and touch a fake tarball
cd packageName/packageName-0.1
touch ../packageName-0.1.tar.gz

*) Use dh_make to create your default debian directory.
dh_make -n -s -e yourEmail@yourDomain.com -f ../packageName-0.1.tar.gz
“-n” is the flag for creating a native Debian package.
“-s” is the flag for creating a single binary.

*) Move packageName-0.1 to trunk
cd ../;mv packageName-0.1 trunk
Now, you may remove the tar balls.
rm packageName_0.1.orig.tar.gz; rm packageName-0.1.tar.gz

*) Step into trunk/debian. Since I do not want to create any cron jobs or emacs or init scripts or man pages in this package, I am going to delete these example scripts.
cd trunk/debian
rm cron.d.ex emacsen-install.ex emacsen-remove.ex emacsen-startup.ex init.d.ex manpage.1.ex menu.ex manpage.xml.ex manpage.sgml.ex watch.ex

*) Rename the example install scripts that you want to keep.
mv postinst.ex postinst; mv preinst.ex preinst; mv postrm.ex postrm; mv prerm.ex prerm

*) Remove any other example scripts that you do not want.
rm *.EX; rm *.ex

*) Edit the control file to update the “Description:” and to add any package dependencies to “Depends:” (if any exist).
vi control

*) If you want postinst commands to run, edit postinst and add commands on a new line after:
case "$1" in
configure)
#echo "My command"

*) Step into trunk, and create a Makefile.
cd ../; vi Makefile
Below are a few examples of what could be in your Makefile.
SHELL=/bin/sh
INSTALL_TMP = install -d -m 1777 -o root -g root
INSTALL_DIR = install -d -m 755 -o root -g root
INSTALL_DIR_APACHE = install -d -m 755 -o www-data -g www-data
INSTALL_PROGRAM = install -c -m 755 -o root -g root
INSTALL_MAN = install -c -m 444 -o bin -g bin
INSTALL_APACHE = install -c -m 644 -o www-data -g www-data


PEAR=$(DESTDIR)/usr/share/php
TMP=$(DESTDIR)/tmp


install:
^t $(INSTALL_DIR) $(PEAR)
^t $(INSTALL_TMP) $(TMP)
^t $(INSTALL_PROGRAM) myProgram.sh $(TMP)

You will need to use tabs (^t) after “install:” The commands above will create the /usr/share/php and the /tmp directory in your fakeroot environment. Then, you can copy files into these two directories. The last command will install the “myProgram.sh” file (which is located in trunk) into the /tmp directory with the permissions of 755 and with the ownership of root:root. If you want to execute this program as a post installation script, you will need to enter it in debian/postinst with the path, e.g., “/tmp/myProgram.sh”.

*) Before you build your package, add your source code to subversion. Step into the directory above the package directory.
cd ../../ ; svn add packageName; svn ci -m "Adding packageName source code to subversion"

*) Now, you are ready to build the Debain package. Step into trunk (where your Makefile is located) and execute the following command.
cd packageName/trunk; dpkg-buildpackage -us -uc -rfakeroot

*) You package will be built and copied one level up in the directory tree. So, cd up one level, and add your package to your apt repository. The following command assumes that your apt repository is on the local machine in /var/www/yourRepo/. And, it assumes that your username is a sudoer.
cd ../ ; sudo reprepro -Vb /var/www/yourRepo/ includedeb yourRepo-unstable packageName_0.1-1_i386.deb

Creating a Debian package is really not that complicated. But, do not forget to test your package to make sure that it installs without errors. If you have errors, fix them, and then rebuild the package. You can delete the package from the apt repository and re-add it after rebuilding.
sudo reprepro -Vb /var/www/yourRepo/ remove yourRepo-unstable packageName_0.1-1_i386.deb
sudo reprepro -Vb /var/www/yourRepo/ includedeb yourRepo-unstable packageName_0.1-1_i386.deb

Subversion: How to merge a branch back into trunk

Typically, subversion (svn) is used to manage releases. If your latest code is being developed in trunk, for a release, you should create a release branch and then release from a tag created from that release branch. After a period of time, you will probably introduce patches in the release branch and perhaps you might even add additional features to the release branch. At some point, you will probably want to merge your changes back into the trunk. The follow are some steps to merging your changes back into trunk using the command line version of subversion (svn).

1. Step into the release branch and find out what has changed since you created the release branch.
svn log --stop-on-copy http://svn.example.com/proj/branches/branchname

2. Once you have discovered the revision number from the creation date of the release branch (e.g., 999), use this revision number to merge the branch to the trunk. Step into the trunk and execute:
svn merge -r999:HEAD http://svn.example.com/proj/branches/branchname@999 .
The dot at the end indicates your current “trunk” working directory as your target. “HEAD” means the latest revision.

3. Once you have merged the branch into the trunk, then you can commit the changed code to the trunk.
svn ci -m "Merged the branch code changes from revision 999 into trunk."
If there are conflicts, you will have to edit the code and resolve the conflicts. You can use “svn resolved” to clean up the conflict files. Then use “svn ci” or “svn commit” to try again.

Control codes for serial communication

Typically, devices that communicate over serial connections are expecting to receive a control code, e.g., an ACK or a NAK. The following are some common control codes.

$SOH = chr(1); // start of heading
$STX = chr(2); // start of text
$ETX = chr(3); // end of text
$EOT = chr(4); // end of transmission
$ACK = chr(6); // acknowledge
$NAK = chr(21); // negative acknowledge

http://www.asciitable.com/