Skip to main content

Developer's notebook

Tips from veteran Linux programmer Spence Murray

John Papageorge (john@mediaoverdrive.com), President, Media Overdrive
John Papageorge has worked with some of the bigger names in the high-tech industry, launching products and Web initiatives for such companies as CNet, Macromedia, NBCi, Sun Microsystems, and MSNBC. John launched the groundbreaking CNet/Intel project Mediadome in 1996 and Macromedia's Shockwave.com in 1998. He also created NBCi's Media Sharehouse in 1999. John has worked as a consultant to forecast and explore the applications of Java technology for Sun Microsystems/Netscape's iPlanet site. John is currently working on his latest venture, Buzzphone, to create compelling voice-based fan club programs for pop music, sports film, NASCAR, and celebrity chefs. This patent-pending initiative has allowed Buzzphone to create relationships with some of the world's hottest talent. He can be reached at john@mediaoverdrive.com.

Summary:  Spence Murray is one of the top Linux developers around, and a long-time UNIX champion. Fellow Linux developers will benefit from the useful, common-practice shell scripting techniques that Murray and his Codemonks Consulting partners employ on a daily basis in their Linux development and applications services work.

Date:  21 Oct 2003
Level:  Introductory
Activity:  834 views

Spence Murray, a founding partner of Codemonks Consulting, has been a UNIX/Linux developer since his early experiences writing code on SunOS back in the mid 1980's. Since then, he has spent time at IBM working on AIX, SGI on Irix, and lots of time writing cross-platform UNIX code for HP/UX, Irix, Solaris/SunOS, SCO UNIX, BSD variants, MacOS X, and of course, Linux. The work has ranged from graphics/video device drivers to UI code. A bunch of Murray's cross-platform code was X Window System Xserver code, as well as core browser code as part of Netscape Navigator.

Murray's most oft-used Linux tools are vi, bash, and Emacs. "Whether I'm writing C, C++, Java, shell scripts, or HTML, the vast majority of my time involves bouncing between these tools," he says.

Secret Linux weapon

For a Linux developer, Murray believes the shell is a powerful software development tool whose utility is hard to overestimate. "Shell scripting is an integral part of just about everything I do, whether quickly perusing and editing plain text or writing code," he says. "It's small and quick, and its short commands make moving code around a quick and painless process. As an editor, it quickly becomes second nature."

Emacs as a development tool came a few years later for Murray. "Around the early '90's, I experimented with Emacs as an IDE, and rapidly was converted. Emacs is immensely powerful, and these days, I constantly have an Emacs window present, often with many tens of source files open, each maintaining my editing context, debugging sessions via gdb, and bash shells running in various source directories. Many pages have been written about Emacs, but suffice it to say, the tool is awesome... and again, you can run it on just about any system you're likely to spend time developing on."

Since first experiencing the terse environment of vi on SunOS back in the mid-1980's, the Emacs editor has become Murray's standard tool. "It's available or can be built on every flavor of UNIX, which is a key factor given the cross-platform nature of my contract development work," he says.


Linux developers: know your shell

Know your shell, demands Murray. "Bash, tcsh, csh -- the shell is your fundamental software development tool," he insists." It can do many a great thing. Everything depends on it... and it's powerful." As an example of the power of shell scripting in common usage, see the Resources section for a downloadable file that includes a set of scripts to retrieve updated RPM packages for a Red Hat release and merge them with the original packages and custom packages. Once the downloadable file is unzipped, the scripts can be found in the /DeveloperWorks/rpm_update_scripts/ directory. The end result is a directory containing the latest version of all the packages and an updated hdlist file ready for network installs.

The code fragment below implements automated updates of Red Hat RPM packages to create readily installable distributions with the latest RPMs. This is a fundamental process for anyone maintaining public Linux servers. In our usage, we commonly maintain a large number of customer Web services across a set of publicly accessible Linux servers. The scripts below are part of our automated process of pulling in the latest security and functional updates.

The script samples below demonstrate common shell hacking techniques that are generally useful for a variety of system configuration and programming applications. Bourne shell is used, which is the most common shell available across UNIX systems. This ensures highly portable code that requires little or no change for use on different UNIX systems. The Red Hat package specifications can be easily modified to apply to other Linux distributions.

freshen.sh updates the original RPM list with update RPMs from the specified RPM ftp update site. Filtering is implemented to replace update RPMs. Finally, the anaconda distribution list is updated to reflect the new RPMs pulled down from the update mirror site.


Listing 1. fresh.sh
#!/bin/sh
rh_ver=$1
rh_path=$2
update_dir=${rh_path}/RH${rh_ver}-updates
custom_dir=${rh_path}/RH${rh_ver}-custom
install_dir=${rh_path}/RH${rh_ver}-install

# Sanity check for the original directory.

# Create update and install directories if they don't exist

[ -d ${update_dir} ] || mkdir ${update_dir}
[ -d ${install_dir}/RedHat/RPMS ] || mkdir -p ${install_dir}/RedHat/RPMS

# Get latest updates from fresh rpms FTP site

./get_update.sh ${rh_ver} ${update_dir}

# Create/update hardlinks from update, and custom directories
# to the install directory. We assume that original RPMS are already
# hardlinked to the install directory, so all we need to do is filter
# out any replaced by updated packages.

./do-links.sh ${update_dir} ${install_dir}/RedHat/RPMS
[ -d ${custom_dir} ] && ./do-links.sh ${custom_dir}
${install_dir}/RedHat/RPMS

# Filter out all but the latest version of everything.

./filter-rpms.pl $install_dir/RedHat/RPMS

# Rebuild the hard disk lists
/usr/lib/anaconda-runtime/genhdlist ${install_dir}

freshen.sh calls do-links.sh and get_update.sh to set up the source and destination locations of the RPM distributions (source RPMs are elided; hard links are used to set up the destination RPMs) and to retrieve the updates, respectively.


Listing 2. do-links.sh
#!/bin/sh

src=$1
dest=$2

#for file in $src/*; do
for file in `find $src -name *.rpm -a ! -name *.src.rpm -print`; do
base=`basename $file;`
if test ! -f $dest/$base; then
echo "Linking $file";
ln $file $dest
else
echo "EXISTS: $file";
fi
done


Listing 3. get_update.sh
#!/bin/sh
rh_ver=$1
dest=$2
echo "Retrieving updates for version ${rh_ver} to $dest"
lftp << EOF
open ftp.freshrpms.net <ftp://ftp.freshrpms.net>  <ftp://ftp.freshrpms.net>
<ftp://ftp.freshrpms.net>
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/i386 $dest/i386
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/i486 $dest/i486
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/i586 $dest/i568
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/i686 $dest/i686
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/SRPMS $dest/SRPMS
mirror -n pub/redhat/linux/updates/${rh_ver}/en/os/noarch $dest/noarch


Java and Linux

A fair amount of the development work done at Codemonks is Java on Linux. The combination of these two tools provides a platform for the creation of commercial-quality Web applications, says Murray. "During the course of one such project, we found the need to profile a client's existing application code," he recalls. locks.c (in the /DeveloperWorks/locks/ directory from the downloadable zip file; see Resources) is a code snippet that implements read/write locks with extensive debugging code for use under the Java Virtual Machine Profiler Interface (JVMPI; see Resources for a link to more information on JVMPI).


Linux developers represent

"Don't write system-specific code when you don't need to," says Murray. Instead, overcome the challenge to "write good, cross-platform code." The mercenary Murray insists that his greatest asset has always been to "write commercial-quality code, build and host network services, and customize the OS or kernel, all from a solid open source platform."

Below is a code snippet from a cross-platform, custom IMAP server, which was jointly developed by developers on both Linux and MacOS X. The code implements a simple growing buffer for holding strings. This avoids the problem of buffer overflow (remember all those security holes), while not requiring a re-allocation every time you do something. It does this by maintaining a simple resizable buffer that can be filled in and emptied. This buffer is used in an experimental IMAP server written by a group in an intense weeklong hacking session.

In addition to implementing a simple string buffer, the code implements a variabl-sized array of strings. This is done with a simple interface where, when you finish writing one string, you mark it as done and continue with the next one. Again, this economizes on allocations and keeps the messy code all in one spot.

The code for the entire IMAP server should be released sometime this year.


Listing 4. Portion of custom IMAP server
#ifndef HOED_BUF_H
#define HOED_BUF_H

typedef struct {
char *str;
int size;
int length;
int str_start;
int max_size;

int n_strings;
int size_strings;
int *str_posn;
char **str_set;
} hoed_buf_t;

#if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#define PRINTF(f, a)    __attribute__((format (printf, f, a)))
#else
#define PRINTF(f,a)
#endif

extern hoed_buf_t *hoed_buf_alloc(int init_size, int max_size);
extern void hoed_buf_free(hoed_buf_t *);
extern void hoed_buf_reset(hoed_buf_t *);
extern void hoed_buf_new_string(hoed_buf_t *);
extern char **hoed_buf_get_set(hoed_buf_t *, int *n_string);

extern char *hoed_buf_put_char(hoed_buf_t *, char toadd);
extern char *hoed_buf_sprintf(hoed_buf_t *, const char *format,...)
   PRINTF(2,3);
extern char *hoed_buf_strcat(hoed_buf_t *, const char *append);
extern char *hoed_buf_cat_sprintf(hoed_buf_t *, const char *format, ...)
   PRINTF(2,3);

#endif /* HOED_BUF_H */


Name that killer Linux application

According to Murray there are two killer Linux applications: Emacs and Netscape Navigator. "Emacs is possibly the most impressive Linux-based and widely used application around," he says. "Another is Netscape Navigator. At one point, we supported more than 20 flavors of UNIX, and I did a lot of my work on Linux."

He continues, "The funny thing is that Linux-based applications will probably run on a bunch of different UNIX systems, even on Windows with Cygwin installed."


What's the future of Linux?

Currently, Murray has several Linux projects in development, ranging from distributed office applications supporting e-mail, messaging, and shared databases to Web applications using the standard tools: Apache/Tomcat, PHP, PostgreSQL, MySQL, and Linux. Murray also has his own company devoted to hosting network services and Web applications.

According to Murray, the list of applications that take advantage of Linux's strengths is constantly expanding "There are many," he says. "Oracle, WebSphere, Apache, PostgresQL, MySQL, Cyrus IMAP... the list is long and growing."

According to Murray, Linux is here to stay. "All of our servers run Linux; the majority of our development is done on Linux, regardless of our target platform; we recommend Linux to clients for server applications," he says. "If you combine the rapid pace at which Linux develops, its broad base of support in the open source community, and its low cost of development, it's a difficult platform to beat."



Download

NameSizeDownload method
l-murray/developerworks-samples.zip HTTP

Information about download methods


Resources

About the author

John Papageorge has worked with some of the bigger names in the high-tech industry, launching products and Web initiatives for such companies as CNet, Macromedia, NBCi, Sun Microsystems, and MSNBC. John launched the groundbreaking CNet/Intel project Mediadome in 1996 and Macromedia's Shockwave.com in 1998. He also created NBCi's Media Sharehouse in 1999. John has worked as a consultant to forecast and explore the applications of Java technology for Sun Microsystems/Netscape's iPlanet site. John is currently working on his latest venture, Buzzphone, to create compelling voice-based fan club programs for pop music, sports film, NASCAR, and celebrity chefs. This patent-pending initiative has allowed Buzzphone to create relationships with some of the world's hottest talent. He can be reached at john@mediaoverdrive.com.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Linux, Open source
ArticleID=11347
ArticleTitle=Developer's notebook
publish-date=10212003
author1-email=john@mediaoverdrive.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers