Database Migration

I recently migrated from Drupal to WordPress on this site, and needed to migrate all of my old content to the new database. However, One of the problems with migrating the data from one content management system to another is dealing with the differences in database schema.

Drupal stores content timestamps as an int(11) field, which represents the number of seconds since epoch (midnight, January 1st 1970). WordPress uses a datetime field. As the two formats are completely different, a conversion must take place. Drupal stores content in the node table, and the field that stores the content creation date is called created. We’ll need to select that field, and use the MySQL function FROM_UNIXTIME() to convert the date. Here’s how you do it:

mysql> SELECT title,type,FROM_UNIXTIME(created) as created,body FROM
> node ORDER BY created;

+-----------------------------------+--------+---------------------+
| title                             | type   | created             |
+-----------------------------------+--------+---------------------+
| Story1                            | story  | 2005-03-10 11:28:22 |
| Story2                            | story  | 2005-03-11 16:25:14 |
| A New Story                       | story  | 2005-03-11 16:31:18 |
+-----------------------------------+--------+---------------------+

The FROM_UNIXTIME() function also supports formatting of the result:

mysql> SELECT FROM_UNIXTIME(created, '%Y %D %M %h:%i:%s %x');
+--------------------------------------------------------------+
| FROM_UNIXTIME(created, '%Y %D %M %h:%i:%s %x') |
+--------------------------------------------------------------+
| 2005 10th March 11:05:32 2005                                |
+--------------------------------------------------------------+

To reverse the conversion, you would use the UNIX_TIMESTAMP() function to convert your datetime field to a Drupal-style int(11) timestamp.

Technorati Tags: , , , , , , , ,

New Website Format

Hi everyone!

In case you haven’t noticed, things look a bit different around here. I am in the process of migrating the website content from a Drupal content management system to a WordPress installation. This will allow me to emphasize the content provided here without having to work quite so hard on presentation issues.

Please be patient while I finish the migration, and check back often for updates!

Technorati Tags: , , ,

Reinstalling Internet Explorer

We had a situation at work where a Windows XP computer had a completely corrupted installation of Internet Explorer - the browser simply was broken.  It is not incredibly obvious, but it is possible to reinstall Internet Explorer without having to try and fix the operating system itself.

From the Start menu, select “Run” and entering the following command:

rundll32.exe setupapi,InstallHinfSection DefaultInstall 132 %windir%\Inf\ie.inf

You will need to have your XP CD available.

This command line is not the easiest thing in the world to type, so for those with weak typing skills, a small VBScript that will execute the command for you can be downloaded here.

Save the file to your hard drive and double click it to run IE Setup.

Of further interest:

Technorati Tags: , , ,

Microsoft Alternatives

Recently, I came across Redmond Magazine, which is geared towards people who administer Microsoft Windows on a daily basis.  Columnist Doug Barney wrote an editorial regarding Microsoft alternatives in the desktop arena in the March 2006 issue (pp. 4), which I have to take issue with.

Barney compared Macintosh OS X and Red Hat Linux to Windows XP, which I do not feel is a fair comparison.  Red Hat Linux is not, nor was it designed to be, a desktop operating system.  Red Hat’s biggest strength is the server market, and because of this, does not require the crutches that a normal desktop environment must provide to help people with all skill levels accomplish their goals.

A much more suitable comparison would have been Ubuntu Linux, which is specifically geared for the end-user experience.  I have been a Windows user for a very long time, and I can honestly say, I have never seen a Linux operating system as easy and fun to use as Ubuntu.  Installation is extremely easy, and the mechanisms provided for installing software from the desktop is top-notch.  I feel that novice computer users could easily use this operating system, as the interface is very intuitive.

It comes prepackaged with OpenOffice2, which is a very capable (and free) Office replacement.  Firefox is installed by default, as is applications for businesses, the arts, and home productivity.

It seems that a big portion of the media only considers Red Hat as a viable Linux operating system, which could not be further from the truth.  I urge you to take a look at Ubuntu (website) and give it a fair review.

Technorati Tags: , , , , , , , , , , ,

Configuring Vonage Redux

So now I finally have things working with my new Vonage service, but it required some additional configuration.

In my previous post, I made some changes to IP addresses on my routers to get everything connected.  However, something was not quite right - when talking on the phone, the sound would fade in and out, and was basically unusable.  I also noticed that I could only get DHCP addresses on one of my routers, and only if I was directly connected to it.  Clearly, this was no good.

So, to recap, my network layout is like this:

I have a cable modem, addressed at 192.168.1.1.  Directly attached to it is a Linksys WRT54GX wireless router, addressed at 192.168.1.3.  I have another router, a Linksys BEFSR41 addressed at 192.168.1.2 connected to the wireless router via cross-over cable, and the Vonage Linksys RTP300 router also connected to the wireless router via cross-over cable.  Its address is 192.168.2.3.

I logged into the BEFSR41 router, and disabled DHCP.  I was getting conflicts by having two DHCP servers on the same subnet dishing out address to multiple clients.  At this point, I could only get an address if I was physically connected to the wireless router, which still had DHCP enabled.  That’s when I discovered the Advanced settings on the BEFSR41 router.

First, I had to go the Dynamic Routing table, and set the working mode from Gateway to Router.  I then set Dynamic Routing TX and RX to RIP2.  This changed the behavior of the router, and made it act more like a switch, leaving my wireless router to act as the sole gateway on my home network.

Surprisingly, I discovered that my Vonage phone service suddenly became usable.  The sound quality was fantastic, there was no dropped sound, and no chirpiness to the sound quality.

Life is once again happy.

Vonage, routing, Linksys, gateway, DHCP, switch, RIP2, dynamic, VoIP

Configuring Vonage

After speaking with friends and colleagues, I recently was convinced that Vonage was a stable enough product to switch phone service to.  For those of you who don’t know what Vonage is, it’s a complete phone service provider, over the internet instead of traditional phone lines.  This technology is known as VoIP, which stands for Voice Over Internet Protocol, and Vonage charges half of what more of the traditional phone carriers are charging.

About five days after signing up for the service, I received my Vonage router in the mail, which is basically a Linksys router branded by Vonage (cable or DSL broadband access is required by Vonage).  The router itself has four LAN ports, two phone ports, and a dedicated port for connecting to the cable modem.

The router comes pre-configured with a standard class C IP address of 192.168.15.1.  Vonage expects that in most cases, the user will simply connect the router to the cable modem and all will be well.  However, I am running a wireless 802.11G router with SRX400 technology, and when I connected the two routers together via crossover cable, I was unable to ping either device, and could not get on the internet.

I quickly decided to change the IP address on the Vonage router to be 192.168.1.4, keeping my wireless router at 192.168.1.3.  This failed to change the level of connectivity.  The documentation made mention of configuring static routes on the Vonage router in the case of multi-router configurations.  However, I had no success with this either.

After fooling around with the settings for about two weeks off and on, I finally broke down and called the Vonage tech support, and ended up speaking with Samesh in Bangalore, India.  After learning my tiny network topography, Samesh instructed me to change the IP address on my Vonage router to be 192.168.2.3.  She then told me to go to the MAC Address Clone tab in the router configuration utility, and clone the MAC address of the router.

Once the router rebooted, I was instantly connected.  Because of my pedestrian understanding of networking principles, I don’t understand why that specific IP address works and is able to connect.  I also don’t understand why I cannot ping the Vonage router or otherwise connect to it while connected to my wireless network.  If anyone can provide a concise explanation of the reason for this, I would love to post your comments as a follow up.

Vonage, networking, class+C+network, Bangalore, tech+support, VoIP, wireless

Backup script for UNIX user accounts

Because I use IMAP as an email protocol, all of my email is stored on the mail server. Unfortunately, having all your eggs in one basket means that you will lose everything in a catastrophic failure. I wrote the following script to backup some user directories into compressed tarballs, which will allow me to recover data.


#!/bin/csh

#------------------------------------------------------------------------#
# @name		backupUsers
# @author	Erich Beyrent
# @summary	The purpose of this script is to create backups of specific
#               user directories.  Compressed tarballs are created and then
#               moved into the backups directory
#
# === Modification History ===
# 1.0.0  24-mar-2005  [ecb]  initial version
#
#------------------------------------------------------------------------#

# Set a debug flag to enable print messages
set debug = 0

# Set the location of the backup directory
set backup_dir = /usr/local/backups/users

# Set the location of the user home directories
set home_dir = /usr/home

# Get today's date
set mydate = `date +%d-%m-%Y`;

# Create backups of the user home directories
foreach directory(`ls $home_dir`)
	# DEBUG
	if($debug > 0) then
                echo $directory
	endif

	# DEBUG
   	if($debug > 0) then
		echo "Backing up $directory"
	endif

	# build the filename
	set filename = "$directory-home_$mydate.tar.gz"

	# Tar and compress the user's home directory
	/usr/bin/tar -cvzf $filename /usr/home/$directory

	# Move the backup file to the backups directory
	mv $filename $backup_dir
end

# Clean up any backup files that are older than seven days
find $backup_dir -mtime +7 -exec rm -f {} \;


Technorati tags:

Programming :: Shell Languages
Technology

Upgrading to FreeBSD 5.4

As it turns out, upgrading FreeBSD is not as difficult as I thought it would be. The process is downright simple for the most part. The trickiest part is running mergemaster, and upgrading the contents of /etc. The risk is somewhat mitigated if you backup /etc before you run the mergemaster command.

Here is how I upgraded my system from FreeBSD 5.3.

The first thing to do is to create a file for updating the FreeBSD source tree. I called this file "standard-supfile", and placed it in /etc. The file looks like this:

  
*default host=cvsup2.FreeBSD.org
*default base=/usr
*default prefix=/usr
*default release=cvs tag=RELENG_5_4
*default delete use-rel-suffix
*default compress
src-all
  

To update the source, run the following command:

  
onion# cvsup -g -L 2 /etc/standard-supfile
  

This takes a while, so get some coffee and get to work on that programming project you've been putting off... Once the source has been updated, it's time to rebuild the system.

  
onion#  cd /usr/src/sys/i386/conf
onion#  cp -p GENERIC MYKERNAL
onion#  config MYKERNAL; cd ../compile/MYKERNAL; make depend; make;
onion#  make install;
onion#  tar cf /tmp/etc.tar /etc
onion#  mergemaster
  

I like to make a copy of the GENERIC file, because any changes I may make to it will get wiped out next time I update the source. By making a copy of the file and adding my changes to the copy, those changes are preserved.

After running mergemaster, reboot and /etc/motd should be updated to display the current version of the system.


Technorati tags:

Technology

Loan Me $300

I admit it, I am a big fan of the show "Desperate Housewives" and I am not ashamed. I mean, after all, I know it's like a soap opera in primetime, but the stories are well written, the acting is decent, the women are HOT, and the show is genuinely funny.

My only complaint is that the show is on ABC, which lately, seems to stand for "Always Broadcasting Commercials". Let's be clear on one point - I HATE COMMERCIALS. I have never once in my entire life seen a commercial and suddenly felt the urge to go out and spend money on that product. Not once. I can't stand the jingles. I can't stand the cheesy humor. And I really can't stand the constant interruptions to my favorite shows.

I watched the latest Desperate Housewives episode last night, and if you did too, you might have noticed that there is barely eight minutes of footage before the next round of commercials. We had a commercial break at 9:30. The show came back on at 9:32. Another commercial break at 9:39. The show came back on at 9:41. Another commercial break at 9:48. It's more than just invasive - it's downright disturbing because your brain and attention has to keep switching gears. It's no wonder why we have such things as TiVo.

Which brings me to why I need $300.00. I don't like TiVo either, and it's because as a company, they have to bow to the pressures of the networks. You used to be able to skip commercials entirely. Not anymore - TiVo and Comcast are jointly developing an advertising system that inserts up-to-date commercials into previously recorded programming. This whopper follows news that TiVo has begun testing a new advertising format that will appear as users fast forward through commercials on its digital video recorder service. I am, however, a big fan of DIY-type PVRs. Windows Media Center, MythTV, and Sage all offer the same functionality as a TiVO, but with true ad blocking. The added benefit to building your own is that you are truly not restricted by the amount you can record. Why should I have to settle for a 250GB or 400GB hard drive in a TiVo, when I can built a fileserver with a few terrabytes of storage that can be NFS mounted to my PVR?


Technorati tags:

Technology

PHP and SOAP Authentication

One of my recent projects for a customer of mine, ResortScope, LLC, involved setting up some web services to allow access to data in our database to external consumers. To provide this functionality, I used the NuSOAP library and PHP. However, one of the limitations of the NuSOAP library is that it is unable to parse SOAP headers, which typically contain authentication information. Consider:



			test
			1a232d4dg35

                     foo
                     bar


As you can see, the username and password are embedded in the SOAP:header. So, to get at this data, you will need to parse the header yourself. The way I chose to do this was to subclass the NuSOAP soap_server class and override the service method.



_objParser = new MyXMLParser();

		// Call the parent constructor method and pass the WSDL flag to it
		parent::soap_server($wsdl);

	} // End Function

        function service($data)
	{
		// Parse the xml message
		$this->_objParser->setXMLData($data);

		// Retrieve the authentication information from the xml message
		$arrCredentials = $this->_objParser->getCredentials();

		// Sanity check - did we get the credentials?
		if(is_array($arrCredentials) &&
		  ($arrCredentials['username'] != "") &&
		  ($arrCredentials['password'] != ""))
		{
			// Authenticate the user
			$this->_intWSUserID = $this->_authenticate($arrCredentials);

			// If authentication was successful, handle the rest of the message
			if($this->_intWSUserID > 0)
			{
				parent::service($data);
			}
                        else
                        {
                                // return a SOAP fault
                        }
		}

	} // End Function	

        function _authenticate($arrCredentials)
	{
		// Sanity check: did we get a valid array?
		if(! is_array($arrCredentials))
		{
			// return a SOAP fault
		}

                // Handle your authentication code here.  I use a MySQL database for holding user data

         } // End Function

} // End of Class
?>


In this above example, I deal with a class called "MyXMLParser", which is an object that has methods for parsing XML data. You could just as easily parse the data using native PHP methods. As you can see, the AuthenticationInfo is parsed out of the SOAP message header, and the username and password are extracted and passed to the _authenticate() method. How you choose to do your authentication is up to you. In my case, I return the userID from the database for the authenticated user. If and only if I get a userID back from the _authenticate() method do I call the service() method in the parent class.

Thanks to Scott Nichol for a great PHP library!

Technorati Tags: php nusoap SOAP


Technorati tags:

Programming :: PHP
Technology