June 2002, Issue 79       Published by Linux Journal

Front Page  |  Back Issues  |  FAQ  |  Mirrors
The Answer Gang knowledge base (your Linux questions here!)

Linux Gazette Staff and The Answer Gang

Editor: Michael Orr
Technical Editor: Heather Stern
Senior Contributing Editor: Jim Dennis
Contributing Editors: Ben Okopnik, Dan Wilder, Don Marti

TWDT 1 (gzipped text file)
TWDT 2 (HTML file)
are files containing the entire issue: one in text format, one in HTML. They are provided strictly as a way to save the contents as one file for later printing in the format of your choice; there is no guarantee of working links in the HTML version.
Linux Gazette[tm],
This page maintained by the Editor of Linux Gazette,

Copyright © 1996-2002 Specialized Systems Consultants, Inc.

The Mailbag

HELP WANTED : Article Ideas

Send tech-support questions, Tips, answers and article ideas to The Answer Gang <>. Other mail (including questions or comments about the Gazette itself) should go to <>. All material sent to either of these addresses will be considered for publication in the next issue. Please send answers to the original querent too, so that s/he can get the answer without waiting for the next issue.

Unanswered questions might appear here. Questions with answers--or answers only--appear in The Answer Gang, 2-Cent Tips, or here, depending on their content. There is no guarantee that questions will ever be answered, especially if not related to Linux.

Before asking a question, please check the Linux Gazette FAQ (for questions about the Gazette) or The Answer Gang Knowledge Base (for questions about Linux) to see if it has been answered there.

Is it possible to create customized Linux install cd?

Fri, 24 May 2002 03:33:29 +0000
Simkin Ramses (simkin1 from

I've seen the Red Hat site dealing with genhdlist/genhddir,( but is there a way to change the Red Hat installation gui to include a customized set of RPM's? (something other than custom/workstation/server)? I'd like to try and bundle my own Linux installation CD, but using programs that aren't included on the standard install cd's, and still utilizing the Red Hat base installation software. Any suggestions?

I confess that when I customize I go a bit more whole hog than this and tend to skip native distros' installer routines. Still, having the partition phase can be nice, and having your local staff able to tag Our_Local_Stuff might be nice too.
So, folks - send us articles on tweaking installers to do your bidding :) -- Heather

Playing CD Music Digital Output

Wed, 22 May 2002 12:29:09 -0500
Bill Parks (wparks from

I purchased an eMachine to run Linux on. It came with (sorry) XP which I used to check out the hardware. It plays music CD's fine but uses digital data over the IDE buss rather than a cable from the CD drive to the sound input.

Loaded Red Hat 7.3 and it plays sounds fine but it won't play music CD's...the player just runs and the CD spins along.

How do I configure the CD/sound system to pick up the digital sound data on the IDE buss to play the music?

Thank You,
Bill Parks

ps -ef problem

6 May 2002 11:56:35 -0000
prosenjit bhattacharyya (prosenjit_bhattacharyya from


I am running Red Hat Linux 6.2 on an Intel server. The problem is I cannot access Linuxconf over the web and my SWAt configuration tool also does not run. The apache server is working fine. I have a proxy connection configured on my PC for Internet access.

How can I implement Acess Control Lists in Linux on the lines of Solaris? If possible where can i get more info and necessary s/w support?


It's good when strangers cannot change the controls on your box - it's not so good when you can't. Articles on defending your web-driven admin tools from joyriding visitors would be appreciated by many readers.
Note that there are many flavors of Access Control Lists these days, but few easy-to-read articles about setting them up. That'd be cool too. -- Heather

What documentation is available for ramdisk and initrd fundamentals?

Mon, 29 Apr 2002 19:10:28 -0700
HATHAWAY Steven J * LEDS (Steven.J.Hathaway from

What are Linux ramdisk fundamentals? This spawns various related questions below. I could use some information to fill the gaps in my understanding of the ramdisk processes related to Linux startup. I have successfully created several RAM based Linux systems built from scratch and using for reference the Slackware boot/root floppy disk layouts - that do not specify "initrd" to Lilo.

A mini-howto or full how-to may be useful as a guide for developers of embedded linux and small custom systems.

Lilo can pass parameters to the kernel and the init process. Does Lilo do the passing of parameters to "init" or does the kernel pass the parameters from Lilo onto the "init" process? When does Lilo (boot.b) get out of the way and allow things to happen?

I can find only scatterd documentation that explains how to use ramdisk and initrd, but nothing on how to control the side-effects of ramdisk usage between the kernel, lilo, and init.

  init level changes (/etc/inittab)

What gets executed first (/linuxrc or the "init" process)? Or do they try to operate in parallel? ugh! (MS/Windows try to invoke many of the startup processes in parallel.)

When "initrd" is specified in "lilo.conf" and the Linux kernel is configured for ramdisk support, and the system is booted, what ramdisk image is loaded first or at all?

The "initrd" image or the kernel ramdisk image?

What programs are responsible for the loading the "initrd" and "ramdisk" root images (kernel or LILO boot.d).

Note that the Linux kernel does not need LILO in order to load a ramdisk from a second floppy using the same drive.

When is "pivot_root" an implicit process, and when must it be explicitly invoked?

What is the difference between a LILO specified "initrd" and the kernel specified ramdisk loaded as root?

Lilo can change and override some kernel default parameters.

Much of my experimenting is with "Linux From Scratch" ( as a basis to start from.

I have a fundamental problem understanding the relationships between an "initrd" image, ramdisk root image, and the use of /initrd, /linuxrc, and swap-root. I am essentially trying to create a memory-based portable Linux solution (without X) that is loadable on multiple i86 (PC) architectures from floppy. Each section, except for UTILDISK, I am wishing to have a minimal set of products to implement the desired functionality. This is for computers with many megabytes of memory, using no hard disk.

  BOOTDISK    a floppy containing kernel and LILO boot products
  INITDISK    a floppy containing loadable modules
  ROOTDISK    a floppy containing a compressed root filesystem
              and a small set of utilities (i.e. busybox)
  UTILDISK    floppy disks containing useful utilities.

BootDisk Floppy: format "minix" mounted as "/fd" Created as a LILO boot disk

/fd/kernel.gz                    my kernel.gz (2.2.x, 2.4.x)
/fd/boot/message                 general message
/fd/boot/boot-text.b             boot with "message" file
/fd/boot/boot.b -> boot-text.b   make default boot loader
/fd/boot/chain.b                 chain boot loader
/fd/boot/map                     lilo boot map
/fd/etc/lilo.cmd                 backup of lilo command file
/fd/dev/fd0                      device for loading ramdisk
/fd/dev/fd0u1440                 device for loading ramdisk
/fd/dev/null                     bitbucket device
/fd/proc                         is/not required for Lilo boot?

I can successfully load a ramdisk as root using for sample the Slackware bootdisk and rootdisk floppies, and then try to create my own RAM resident Linux using Floppy Disks. But the Slackware distributions do not mention "initrc" in the "lilo.conf" files.

Kernel Flags (rdev)
  root = /dev/fd0    = root device (or secondary ramdisk)
  use ramdisk        = true (load image into ramdisk)
  prompt for ramdisk = true (for ramdisk on second floppy)
  ramdisk offset     = zero (not on disk shared by kernel)

See attached hathaway.lilo.conf.txt

Partial Ramdisk Directory for intermediate root system

/linuxrc          Started by kernel after ramdisk loaded
/dev/ ...         All devices and/or MAKEDEV scripts
/proc             Kernel information structure
/bin/ ...         Support programs (i.e. busybox)
/sbin/ ...        System programs
/lib/ ...         Libraries for dynamic linked programs
/lib/modules/ ... Kernel modules
/etc/ ...         Configuration files
/etc/rc.d/...     Files supporting /etc/inittab
/etc/inittab      Config file for sysvinit

This document is prepared for public consumption with no copyright.

Steven J. Hathaway

Note: now that it is published here, it falls under the collective copyright of the Linux Gazette. You do not need to give up your copyrights to publish an article or thread here... you just need to allow us the ability to give it away worldwide or for corporate entities (such as RedHat, SuSE, etc) to sell it on their CD collections, and not provide any odd restrictions that conflict with that. -- Heather

Actually, "no copyright" means it's public domain. Putting a license on public domain material is like putting a license on air. You can do it but everybody's free to ignore it. It's kind of misleading though, because people might think they have only the license's rights and not the public domain rights too. -- Iron

fvwm95 FvwmButtons

Sun, 28 Apr 2002 22:29:48 +0200
Hans Borg (Hans.Borg from

Hej Answer Gang,

This is my third question in a short time. I hope you don,t get fed up. All previous "problems" asked for has been nicely solved.

Q: This question is about the fvwm95 WM handling. It is more of "cosmetic" than functional nature. Using Slakware 7.1 distribution with Linux kernel 2.2.16 for this set up. Introduced a button in the "Button bar" that fires up an executable. That works fine, but the "Button" in the bar then always shows "pressed in". Clicking, for example, Xterm defined in the same "Button bar" always returns the "button" as "not in". What controls this? Is it the return status from the fired up executable, or is it defined somewhere in the fvwm95rc script or something else ? Hoping for some nice advice, or any tip is welcome.

Best regard

fvwm95 is a fvwm-family window manager which has been tweaked to give the maximum similarity to a stock Windows(tm) 95 interface. It's ancient, but many people like it because it's much more lightweight than the Desktops.
Notes about giving fvwm95 a tune-up, or tweaking the current revisions of Fvwm 2 to act more like fvwm95 (with a few less bugs), would be appreciated.
Some people may also experiment with qvwm (Japanese sound "kew" = 9, Roman numeral "V" = 5 --> 95 window manager). ( -- Heather

lpd/lpr problems with serial printer

Fri, 26 Apr 2002 22:53:25 -0500
Mark Gorat (markgorat from

I am using Mandrake 8.2. I have recently installed a serial printer using a Digi Classic-8 ISA card. I have several terminals that use this card without any problems. I can print to this printer by using 'cat {filename} > /dev/ttyS11' and this works just fine, however I cannot get lpr to print to this printer. I think that my /etc/printcap file is ok(I hope). If anyone could point me in the right direction on this problem I would greatly appreciate it!

Mark Gorat

This message was run through the laundry to wash out stray = signs and the HTML attachment was hung out to dry. -- Heather

[LG 77] wanted #1 private email

Mon, 29 Apr 2002 06:52:55 +0200
Christoff van Zyl (Christoffv from

Hallo Cheryl

I just want to know from you if you have solved your problem.

If you did will you point me in a direction on how to setup a Linux server, with internet access and e-mail serve, that are connected to two win98 machines. The Linux machine must dial on demand when one of the win98 machines want access to the internet.



Overall, this kind of question is rather a common one to The Answer Gang. It would be great for one of our readers who lives in both worlds to contribute an article about their dial-outbound-on-demand setup. My guess is that it could use masqdial.
Thanks Christoff, for expressing the question clearly! -- Heather

[LG 78] wanted #3 Lexmark Z22

Wed, 01 May 2002 18:33:53 -0400
neil (ntan from

I would like to find out how he got the Lexmark Z22 to do even that...I have not been able to get mine to print more then 1 line before it locks up. I am using RH 7.2.

Neil T.

Articles on using GDI printers or other winprinters would be appreciated. For that matter, any articles on really setting up your printing environment would be good. There's always the Linux Printing HOWTO ( but personal experience and your tale of success might help a lot of people. -- Heather


[lug] MPAA and Senate...again (fwd)

Fri, 24 May 2002 11:22:04 -0500 (COT)
John Karns (jkarns from
via the Boulder, Colorado LUG list (

They just don't seem to be willing to take "no" for an answer from the public!

John Karns

Date: Fri, 24 May 2002 08:49:28 -0600

From, "MPAA to Senate: Plug the Analog Hole!"

As quoted in the article, Cory Doctorow writes: "this is a much more sweeping (and less visible) power-grab than the Hollings Bill, and it's going forward virtually unopposed. ...the Broadcast Protection Discussion Group is bare weeks away from turning over a veto on new technologies to Hollywood."

There is a comments form available as well as Doctorow's article on "the analog hole" for EFF links in there.


Mon, 6 May 2002 09:49:53 -0700
Gary Lawrence Murphy (garym from

Isn't the RedFlag caricature just a little racist? Isn't it just a bit condescending to have the Chinese Linux user portrayed as a myopic pre-revolutionary peasant farmer with a cronic overbite? Maybe it's just me, but it doesn't seem like a great way to win new friends.

To offer a constructive alternative, in Chinese mythology, isn't there some triad of great heros where one is a king, one is a soldier and the other is a sombre scholar; I think these are the figures you see in the shines at most Chinese restaurants -- the Scholar for the RedFlag user seems a far more apropos choice than a rice-farmer ;)

PS. I don't think the other caricatures are necessarily flattering either. I don't identify with the Debian geek, and Mandrake geeks aren't all babies. But the point is, it's one person's vision. That doesn't mean it's the only vision.
Perhaps Franck might be willing to spin his imagination and draw a few alternative designs of the different distro users. But that's his decision. -- Mike

I've been in contact with Franck, and I think you're right about the possibilities of future alternates...

... the artist replies ...

And of course as Mike pointed out, it is a "one mans vision". If I was to draw something else for someone else, isn't that the same thing once again? Am I not just drawing for someone else's own opinion? ;)
I definitely don't identify myself as the RedHat geek, yet thats all I use at home. Look outside the square and think of the reasons why I chose the characters I did. Here are reasons for a couple:
New Distro, easy to install and almost "childs" play to use which is why I chose the baby character.
Hard core hacker, serious individual who tends to spend a lot of time in front of his pc tweaking his distro. The majority of Debian users I have spoken to tend to have pony tails and a goaty. Of course not all look like this :)
Asian chap, and what do we associate asians with? Of course the Chinese Coolie hat and dark robe. Yes I could have used an Emperor or some famous fighting character, but Linux is the poor mans OS which is why I chose the rice paddy farmer character I did.
I can guarantee no matter what I draw I will never please everyone. What a boring life it would be if we all agreed :)
I'm sure this will start a great debate in the Mailbag column :)
Franck Alcidi

And RedHat is the ComputerAssociates type. I wondered about SuSE though.

At least we'll find out how many people are listening!

[Ben] For myself, I find it hard to disagree with your arguments above, although I have little doubt that somebody somewhere will be offended by at least one (and possibly all) of them. There is a line at which humor becomes defamation, but it's a very difficult one to draw;

Good thing we have all these talented artists to try it. -- Heather.

[Ben] ... this is one of the reasons that the press in the US has as its limiting factor "absence of malice" rather than the laws of slander, etc. that apply to everyone else. <shrug> I also believe that Political Correctness has been carried way, way, WAY too far, and doesn't deserve much more than to be ignored on most occasions. A prickly type might have taken offense at much of the "Russian spy" banter that gets aimed at me, for example; for myself, I take it in the vein in which I believe it was intended,

Of course, I wouldn't have said it during the 1950s or 60s when there were actual concerns (or hysteria) about Russian spies. It's only because times have changed that it makes a good joke. -- Iron

[Ben] my friends here in the Gang to respond well to "did you mean what I thought you meant?" questions, and think myself more than fully capable of dealing with any actual offense that may come up.

Ditto. -- Iron

[Ben] Yes, that trust could be abused, but -
If you can't take a little bloody nose, maybe you ought to go back home and crawl under your bed. It's not safe out here. It's wondrous, with treasures to satiate desires both subtle and gross. But it's not for the timid.
   -- Alister, in alt.sysadmin.recovery
I also note the Usenet truism that flame wars most often get started not by a person who is offended by something but by a third party taking the position that the material may offend someone else. To me, that's a sign of arrogance and a note of incipient trouble; a person who has actually been offended may accept an apology and make peace, but someone who only imagines an offense is not so easily mollified. It's the reason that that kind of "complaints" are considered to be "trolls" in a number of newsgroups.

Is this a trolling of recursive flame bait? Just asking. -- Gary Lawrence Murphy

Re: The Answer Gang has moved

Tue, 7 May 2002 09:01:16 -0400 (EDT)
Christopher Murtagh (christopher.murtagh from

This message (below) was sent to the YellowDog linux general list. I cannot find your subscription to unsubscribe you. Please do so or turn off your bot. Thanks.

Christopher Murtagh (YDL-general list admin)

The message below was an auto-response from mail address <>, not a mailing list.
Somebody sent a message to <> also containing a "From:" mentioning the Yellowdog Linux general list, and the autoresponder replied with its information that <> has moved.
Possibly this email was an instance of the Klez.E worm, which produces forged "From:" taken from the infected system's address book. We've received several hundred such, ourselves. If this is the case, credit the security model of a certain large corporation.
In other words, there's no list membership to turn off. Credit whoever emailed <tag> mentioning you in the headers.
On the plus side, if they do it again in the near future, you won't see an autoresponse, as the "vacation" program which produces this response attempts not to respond to the same sender too frequently.
If the Yellow Dog Linux general mailing list happens to have <> subscribed, please remove that email address.
-- Dan WIlder, SSC sysadmin
Other list admins out there who have open posting are probably seeing a lot of the same worms. We hope that they get eaten by a fish fairly soon. Meanwhile, for our readers' amusement, the actual message from the bot -- Heather


We have received a message which appears to originate from you containing a question for either <tag> or <answerguy> at

These email addresses are no longer in service. However, read on. Unless you're a 'bot, that is. If you're a 'bot, please stop here, read no farther, and go stand in the rain until you rust.

Jim Dennis is the "Answer Guy" of the Linux Gazette. Questions or Linux tips that you send to the Linux Gazette WILL BE PUBLISHED in our monthly webzine aimed at "Making Linux A Little More Fun!" There's so much Linux in the world that other readers were invited to help out, so we are now "The Answer Gang".

The Linux Gazette Answer Guy has moved. He's now in The Answer Gang:


...but still at the same domain,

Your note has NOT been forwarded. If it's about Linux, please resend it to the new name. There is a FAQ about the Answer Gang:

The FAQ in summary:

  • This is a PUBLIC service mirrored in 47 countries and a whole bunch of languages.
  • The only confidentiality we can offer is to make you anonymous (if you request).
  • We're all volunteers and can't swear to quality of answers, or that you'll even be answered.
  • We have a sense of humor and we aren't afraid to use it.
  • Spammers will be slapped with a dead trout and marinated before being flame broiled with a side of spinach.
  • It'd be nice if you told us what you've tried already.
  • "7" isn't a linux version, be more specific than that, e.g SuSE 7.0, Redhat 7.2.
  • Use real subject lines, don't waste your 40 characters.
  • Please send boring old plain text, not HTML, word-processing documents, PDF, graphics files, troff source, TeX, old shoes, or miscellaneous vegetables.

Help us help you, to Make Linux A Little More Fun!

If you don't know what Linux is, you almost certainly came to the wrong place... we don't answer questions about any of the following: get the idea :)

-- The Linux Gazette Answer Gang.


Quoted Printable email

Tue, 7 May 2002 17:15:30 +0100 (BST)
Mike Martin (redtuxxx from

As regards the FAQ in respect of mail format - there is a definite case where quoted printable mail is actually better than ascii text.

This is for non-american english speakers - several characters appear as ascii 127 - 256 (extended ascii) which do not appear in pure ascii.

For example

(english pound)(156)

Could we add/amend the faq to take this into account (flame-retardent suit on)

It's a good thing we have that TAG discount for flame retardant suits, we certainly get plenty of 'em around here :)
If it isn't already in there it's supposed to be -- I have very clearly, multiple times, stated that if you need to defend the odd characters of your native language from being mangled during 7-bit mailing, I will support rather than oppose you using Quoted Printable.
The annoyance factor of using it when you shouldn't, is that mailers use QP equal signs everywhere instead of properly wrapping their lines. And they will wrap the words right in the middle sometimes, which is even worse as it means I have to decode the sucker.
The reason it needs to be in the FAQ is twofold:
  1. using QP when you don't need to, reduces your chance of winning the TAG lotto
  2. not using it when you do need it, makes life harder on our translators translating you, and ends up with me getting your name's diacriticals wrong during publication time, and stuff like that.
Yes, proper pound signs might count for that, too. If it's the only odd character though, I think I might figure out from context that it's not ... uh... whatever my current screen charset thinks that is, and might be a british moneysign.

For example, this was a british-pound in email, but came out a capital U-with-two-dots symbol in my normal console charset. After it passed through Ben's mailer, it was a Yen, which is still wrong, but at least is some sort of money.

And for one character whose context is obvious, I'd rather not deal with wordwrap hell. Even though I have Mike's little script to de-QP the silly thing. -- Heather
<sigh> A case of the nerves and assuming before reading, eh? From the FAQ ( :
Yes, we are aware that MIME Quoted-Printable can be useful in preserving non-English character sets, but mail to TAG in a language other than English is very rare. Use it only if it's necessary.
Comments and corrections after reading and understanding, please. A single character not being correctly translated does not make QP "better" in any sense of the word; I'd far rather see one byte of "cyrillic" than three dozen "=20"s. -- Ben Okopnik

...Some arguments back and forth, ellided...

"The prefered type of mail is plain-text, however some characters will not appear in this format, for example the UK pound sign.

I believe that is a very poor example because it suggests that for the sake of only one character, QP is not only okay but desired. For a moneysign I think it's counter productive.
For example
2 (squiggle) tip: bla bla tweak annoy? tweak the bonk bonk and there you go!

To ensure that code snippets etc appear QP can be used."

Frankly I have not seen code snippets containing the foreign text that needed QP ... and I've been doing this a long while. -- Heather
But in fact, we don't get scripts [destroyed by QP] sent to TAG. Nor do we get more than a handful of non-English messages. It really only comes up in people's names, and they really should be ASCII-fying the name anyway becase that's the only way to guarantee it won't be mangled (at least until all mailers, editors and web browsers handle Unicode). German, fortunately, has well-established ae/oe/ue/ss to replace the non-ASCII characters. With other languages you have to wing it, but (1) ASCII-fication at the source saves the editors time because they don't have to manually convert each high-byte character to the appropriate HTML entity, and (2) those HTML entities don't show up right anyway on screens using a different charset than the author did. Some Latin-1 characters leak through into LG, especially in From: headers, because we don't have time to correct them all, but they will show up as who knows what on a Latin-2 or other system. -- Iron
Perhaps unclear is under which contexts we'd like to encourage rather than discourage QP usage. MikeM may think a pound-lucre is enough; I don't. ... He's at an unfair advantage 'cuz I'm the one with the email snippers, so I'll give him a fair shake by offering a replacement paragraph - though I do not think it expresses at all what he would have expressed.
Then Ben gets handed the scissors since he maintains the FAQ :)


Send text-only content

To maximize your chance that the Gang will read your message, you should send it in a form that doesn't force us to make any special efforts to read your letter. For example, word processing attachments are right out (Word docs and PDFs, among others). While a few mailers may read HTML or automatically decode MIME text many people consider this "feature" a problem instead and hit [delete] without a second glance - here are instructions for turning them off. (Note that we do our own HTML processing so it does not help us to use your HTML version.) If you need to send us a program or an image - rare, we can usually figure things out by description - make an arrangement to upload it to us; the list tosses out binary attachments and we would never see your mail! Text attachments are okay but inlines are better. Quoted Printable is a special case - if you are writing us in a foreign character set, we want to see your words as you meant them. (It helps translation immensely.) But if you have no special letters to defend, we really appreciate not having to run your letter through the laundry to wash out stray = signs. :)


In this suggestion, I no longer mention vcards, and I no longer assume what foreign language might be used - it's just about characters - in fact, if someone from the norselands isn't using thorns and umlauts, I don't mind seeing their message stay 7 bit too. I demand plaintext but I also tell people why - which I hope will encourage them to meet the request. Finally, for QP the point is so we can understand them, and maybe this has a touch of humor, which is good too.

As for moneysigns I'm not afraid to go look up whether that squiggle was a euro or a pound. Although a two pence tip would still use a cent sign, no?

Fianlly - not about QP but for the FAQ - the ask-the-gang guidelines don't warn people to expect a sense of humor. Given the scorch marks from last month, it probably ought to get mentioned.

Re: Question

Sun, 19 May 2002 13:47:57 -0700
Linux Gazette (gazette from
Derk Drukker (

I am completely new to Linux. Just bought SuSe 8.0 and I need lots of info!

Congratulations. I'll be installing SuSE 8 this afternoon too. -- Mike

It installed without any problem.

I still feel lost in Linux. Are there any books for people who are used to Windows/newbies to Linux that you can especially recommend ?

There are a few included in your SuSE pkg. If you installed the susehelp pkg, then you should have the Network Admin Guide (NAG), the LPG (Linux Programmer's Guide), and a few others from the Linux Documentation Project (LDP) (Linux Documentation Project). To view them, you will need a dvi viewer installed, such as kdvi or xdvi. Then run the viewer and point it to /usr/share/dic/Books/LDP and start reading. There may be others at the LDP web site, have a look there. Of course, the SuSE manuals are also quite good, if they came with your purchase.

Others I can think of at the moment are "Running Linux" by Matt Welsh, and "Linux A to Z", sorry can't remember the author's name.

-- John Karns
PS to Answer Gang: Where did that "How can I get help on Linux?" question from the old FAQ go where we listed all those books? Or has it all been incorporated into that message?
See the Answer Gang Knowledge Base for answers to other questions about Linux. -- Mike

If I understand it right, it's OK for me to dowmload back issues of the Linux Gazette for my own personal use?

Oh yes. Not only OK but encouraged. You may find that many back issues are already on your distro, if you installed the big documentation packages, since the _Gazette_ is part of the Linux Documentation Project. -- Heather
Yep, that's what it's there for. You can download it, read it, give it to your friends, print it out and sell it, whatever. The back issues are in the Debian distribution; I'm not sure about SuSE.
The fine print is at
For downloading convenience, all the issues are packed up in FTP files. See -- Mike

LG78 some email related problems

Wed, 8 May 2002 06:50:15 +0100
Neil Youngman (n.youngman from

As a general point, anything which has two whole three letter extensions (.jpg.pdf, .mp3.scr, and so on) especially when the second is one that may be reasonable to auto-view, you should be immediately suspicious that it's probably a virus.

s/second/first/ ?


Nope, I meant it as I said it. If the one on the end (the second extension) is auto-viewable ... e.g. PIF, GIF, DOC ... then the other one may be what it really is, or made up, or just trying to see if it can be auto viewed as either one.

I'm afraid I still think that's the wrong way round. In the example to which I was responding humor.mp3.scr is not an mp3. The first type is MP3, which it would be reasonable to auto-view. I always thought the last (second in this case) extension was what it really was (or at least, on a win box determines how 'doze tries to launch it). This has the advantage for the virus writer that the last extension may also be hidden, so the real type isn't always seen by the viewer, e.g they may see "humor.mp3", which appears harmless.

Windows will launch the bits as they really are - thus the decision is not about "is it really an MP3" ... which would give the media player a chance to blow it off as a mangled sound ... but "shall I auto launch it"; if yes go see the registry about it; the trojan gets to play puppydog in your rose garden.
Note that if you told explorer to hide mp3 because you know what it is, and you see mp3 anyway, then there was a doubled extension and you're not seeing the one on the tail end. We'll have to beware of this ourselves as Konqueror, Evolution and other file-managers-on-steroids come to popularity in Linux.
Doubled extensions often hide the autolaunch decision and may give it two chances to autolaunch. I don't think anybody questions why I'm fond of Linux for email instead. While it's possible to configure Linux mailers to do all sorts of crazy things, we don't currently have the registry mucking with our concepts of what are and what aren't programs, or launchable. -- Heather

But with the kind exception of .tar.gz and .tar.bz2 nearly all other double-tail filenames have been junk that ever came to my box. And if the last is not a compression sort (zip, gz, bz2, Z, sit, arj one time) usually a trojan as well.

I agree totally with this bit.


What does mail relay mean?

Fri, 3 May 2002 11:22:18 -0700
Peter Hutnick (peter from


I take it you are responsible for

A link to that page was sent to a mailing list that I am on because of all of the good Klez.E info. I applicate that info, but the rest of the page seemed to be more or less random gibberish.

But that isn't why I am writing.

I am writing because it seems that you said:


I assume by "mail relay" you just mean you want Sendmail to work, so you can send mail from and to your computer. That's not a mail relay. A "mail relay" means that your Sendmail program accepts mail *from non-local senders to non-local recipients*. Normally, Sendmail accepts mail only if it's from a local user or to a local user. Otherwise, you open up your mail server for exploitation by spammers.


Mail relay means no such thing. You have described an /open/ mail relay. A relaying MTA is /any/ that accepts mail from non-local users and/or delivers to non-local users. Since we presently live in an age of smart clients connected by the internet this describes almost all mail servers.

For oodles of examples of "relay" being used correctly in context see

It is also not true that most mail servers only accept mail that is from or to a local user. My ISP relayed this message to you from my notebook over SMTP. It allows the relay because I am on the ISPs subnet, not because I have a local account on the mail server. This is typically what happens on a corporate mail server as well.

That page at gives several examples of how your final statement is untrue. That list is not exhaustive, for instance SMTP AUTH and POP-before-SMTP are both effective at stopping SPAMmers.

- -Peter Hutnick

/"\ ASCII Ribbon campaign against HTML e-mail
\ /
 X   Get my PGP key at
/ \  6128 5651 6F23 EC17 6EBD  737D 960A 20E6 76CA 8A59
Normally I snip out the sigs but I have to say, I approve of this sentiment. HTML e-mails drive me nuts every month...
Also I'd like to note for the record that the correct spelling for those annoying unsolicited advertisers is spammer - SPAM is a registered trademark of Hormel Foods, and the only relation between them is the reference repeated-to-death in a Monty Python skit. In the skit, at least, it still meant some sort of canned meat. -- Heather


it would be nice to see you

Sun, 28 Apr 2002 05:00:52 +0200
Constantin A. Dumitrescu (cadumitrescu from

Hello to everybody!

I was thinking that it would be nice if we - the readers of Linux Gazette - could see you. I have read the section "Meet the gang", and I'd like to see some pictures with you there.

Heather is preparing some cartoon caricatures. They won't be ready for this issue, but maybe the following month.
There are pics of me on my web site, . -- Mike
Many, but not most, of the Gang have sent in some pictures of themselves for us to use. I'll be turning them into cute toons for next month.
With over 50 people in the Gang, we don't have nearly that many bios posted, either. Clearly, some of us are shy :) -- Heather

Let me say that you do a great job, I really have a lot to learn from you, and I appreciate your work. I don't have a permanent connection to the Internet, so I prefer to download your gazette and read it off-line. I have all issues from no. 1 to 77 on my hard drive an on some CD's.

I always enjoy hearing from a fan. -- Heather

I am a (young) romanian programmer who wants to live in the wonderful un*x universe, but I have still in front of me a long way on which I have to learn walking and on this road you assisted me at my first steps (well, second steps; the first steps was assisted by Linux Documentation Project (LDP) books; well, in fact it is about the third steps, because the second steps was assisted by manual pages and howto's, but the number is not so important for me). Maybe with this phrase I should start my message :-). Sorry. My name is Constantin A. Dumitrescu.

In the hope I will see the gang,

Best regards,

Perhaps someday when you are more confident in your Linux knowledge we will see you among their number, too! -- Heather

P.S.: Please, it it is the case - probably it is, excuse my (sort of) clumsy english - it is not my first language, and I am especialy not well prepared in the english grammar.

As the Australians might say, no worries. Thanks for writing in. -- Heather

layout tip

Fri, 24 May 2002 00:23:18 +1200
Thomi Richards (thomi from

just my two cents worth on the matter of a new layout...

i suggest that you DONT use flashy plugins like java or flash. too often i have seen online mags think they can look better by using these tools. i have yet to see it work. for people still stuck on the slow dialup connection, the plugins can be hell to download aswell...

stylesheets and plain old html work fine, in my opinion.

Thomi Richards
want to get involved?? we're looking for artists!

Thanks for your input. We won't be using Java or Flash because that would cut off a significant part of our readership.
The new look will be... someday. Not this month it looks like. I always come across other things to do instead (you know how that goes...) My latest project has been the Cheetah template developers' guide ( -- Mike
I can assure you that my sections of the Gazette will be lynx clean. I use lynx in preference to the handful of GUI browsers I also use, and could hardly stand to have my biggest project look its worst in my favorite browser, or be unreadable there. -- Heather

This page edited and maintained by the Editors of Linux Gazette Copyright © 2002
Published in issue 79 of Linux Gazette June 2002
HTML script maintained by Heather Stern of Starshine Technical Services,

More 2¢ Tips!

Send Linux Tips and Tricks to

[LG 78] help #5: ADSL with roaringpenguin

Wed, 01 May 2002 11:19:12 -0700
Robert Lynch (rmlynch from


You say: "I am using the roaringpenguin client." The way I got this to work was run:


and answer the questions (as best you can), to configure the client. Once it is working, you can start, stop and query the link status with:


HTH. Bob L.

Fancy printing in Vim

Mon, 6 May 2002 14:53:25 -0400
Benjamin A. Okopnik (Tne Answer Gang)

Vim has many wonderful features; unfortunately, printing - especially printing that retains all the fancy colorizing stuff that Vim enables you to do via the various syntax files - is not one of them, at least not automatically. However, here's something you can add to your "~/.vimrc" that will set it up, including previewing:

See attached fancyprint.vimrc.txt

Once you have this, simply use the ":ha" command; the output will be displayed by "gv" (which, obviously, is required) which will also allow you to print it.

Un-tarring files + Modification Dates

Wed, 29 May 2002 12:40:51 +0100 (BST)
Thomas Adam (The LG Weekend Mechanic)

[ My first 2-cent (2-pence) tip ]

If you have a computer like mine, where the CMOS battery is shafted for whatever reason, you might find that when you go to untar a tarball, you get a series of messages like: has modification time in the future.

Now although this isn't too much of a problem usually, it can be if the tarball contains source-code that you are going to compile, since "make" will usually after trying, sit back and laugh at you saying:

make ** error 1 ** clock scew

To circumvent this problem, you can append the "m" switch when you are untarring your tarball. For example:

tar mxzf ./my_file.tar

Hope It's Useful :-)

-- Thomas Adam

Ghostscript fails after printer driver install

Mon, 29 Apr 2002 10:34:31 -0400
Ben Okopnik (Tne Answer Gang)
Asked by Rich Price

I am attempting to connect my new Samsung ML-1210 printer to my quite old Linux server. The server is running Slackware 7.1. The server has no X libraries [I never loaded them] and, after I updated ghostscript with the RPM supplied on Samsung's install disk, ghostscript started failing with the following message.

gs: error in loading shared libraries: cannot open shared
object file: No such file or directory.

I am assuming that this library comes with X.

You're correct; "Xt" is one of the core X libraries.

While I could just find it somewhere and try to figure out where to put it, I don't know what other errors are hidden behind that one. [How many other libraries are also missing?]

Well, if you had an executable program that came with your RPM, you could do "ldd <program>" to learn about its library dependencies; however, I have no idea what Samsung's RPM contains (it may be a program to which GS delegates the output, or another library, or...)

I am willing to send anyone who is interested the RPM from the Samsung install disk. I didn't include it here to save bandwidth.

Why did applying this RPM make GS start failing?

To be precise, GS itself isn't failing (at least so far as I can tell) - the added "stuff" from the RPM is making a call to the non-existent library, and that's what's failing.

Could the RPM be changed to still drive the printer without needing X libraries?

Only if a) you're a programmer, b) know how to write drivers, and c) have Samsung's (presumably proprietary) printer and software engine protocols. In other words, no.

Is there a working version of GS that comes with the Samsung ML-1210 driver out of the box? If so, where can I get it?

It doesn't have anything to do with versions of GS. Winprinters, such as the one you have, are missing a large chunk of circuitry which must be emulated by a software "engine" (this is another Micr*s*ft attempt to make the world proprietary - like winmodems.) Buying one is a bad idea in the first place, although I'd imagine you didn't realize that - you're paying for a real printer and getting a brainless shell that sucks up a chunk of your CPU processing power for no good reason at all.

The 'gdi' driver is some well-meaning programmer's attempt to make these things work under Linux. I'm sure it works for some people - but it obviously requires at least the Xt library.

My suggestion, just in case you have this option open to you, is to return this gadget to the vendor and demand a real printer - which is, after all, what you've paid for. Failing that, you need to load whatever libraries 'gdi' requires, and - you're absolutely right - there's nothing that guarantees that it won't need other ones after Xt.

Research Help

Wed, 8 May 2002 19:13:41 +0100
Neil Youngman (The Answer Gang)



Well i would like to know what the future of Linux will be in the next 3 to 5 years as i am doing a project on it and would appreciate your help.

Linux may take over the world.
It may not.

It may disappear.
It may not.

It may fragment into so many distributions that no one distribution is run by more than 10 people.
It may not.

It may be rewritten from scratch in ADA.
It may not.

It may be taken over by Microsoft.
It may not.

It may become the main operating system controlling the world's refrigerators and kettles.
It may not.

It may do your homework for you ;-)
It may not.


Update Re: The Answer Gang 65

Thu, 23 May 2002 23:29:01 -0400
Robert Hardy (rhardy from

"although it only appears to be available for Debian"

FYI symlink program is standard part of Redhat Linux in both RH6.2 and RH7.3.


Issue 65 is well over a year old; glad to hear they caught on to that tool during the 6.x series. -- Heather

SMC Wireless

Mon, 29 Apr 2002 21:56:36 -0400
Michael Gargiullo (gargiullo from

Has anyone had any success in getting the SMC wireless pcmcia card to work?

I'm running RH7.2 on a compaq presario laptop

Ahh, but he beat us to the punch - in about 7 hours he figured it out himself. I guess Monday wasn't the best day for us to answer him :) Luckily for our readers, he felt inclined to share his success with us. -- Heather

OK got it.. I had to recompile the kernel and used the wavelan driver

For those interested I have the SMC2632W EZ Wireless PC card and the SMC 2655W 11mb Access Point.

I did have to play with the routes to hosts on my firewall

Going to have a beer and sit on my porch while I code...


testing your procmail recipes

Tue, 30 Apr 2002 09:52:21 -0400
Benjamin A. Okopnik (The Answer Gang)

When you initially set up your ".procmailrc", you're going to be tweaking it for a while; getting rid of the first 99% of spam is easy, the next .9% is somewhat tricky, and the next .09% is a fine art. :) What that involves is adding recipes that block as broad of a selection of spam as possible, without affecting your regular traffic; often, you quickly cobble one up while looking at the spam itself - and that's the right time to test it.

Using another xterm window, another console, or a shell escape (often '!', as in Mutt, or perhaps a 'Ctrl-z' to suspend the current program), create a file in your home directory - I actually keep a template called "proc" there just for this - and enter the following:

See attached proc.procmail-recipe.txt

Note that the "mailbox" for a match here is "/dev/null"; in your actual ".procmailrc", you'd probably want to change that to your "spam" mailbox

- at least for a while - to make sure you're not tossing good mail.

Now, from your mail client, pipe the spam ('|' in Mutt) to the following expression:

procmail proc

where "proc" is the name of the file you've just created. If you've matched it correctly, you should not get any output. Now, try the same thing on one of your valid emails - and you should see it in its entirety. Once satisfied, add the new recipe to your ".procmailrc".

Too many CC's? anti-spam procmail recipe

Sun, 28 Apr 2002 10:32:11 -0400
Ben Okopnik (The Answer Gang)

Spammers often send or Cc: to a large list, and these are usually from an archive of "confirmed" addresses - arranged in some order (usually by host or username.) So, if you get an e-mail that's been sent to or has a "Cc:" list with 5 identical users or hosts, that's pretty certainly a bingo (I still send it to my "spam" box rather than bit-bucketing it, just to make sure.)

See attached spammers-cc-too-many.procmail-recipe.txt

For those who are curious about the code: "formail" separates out the specified headers' contents. Perl reads them in, ignoring newlines; gets rid of everything except the addresses; creates a "frequency list" of the usernames and hosts; sorts the list in numerical order and prints out the highest count, which is tested against "greater than or equal to 5".

Please note that this is just a refinement to an existing ".procmailrc". If you do not have "procmail" set up in the first place, I suggest reading my "No More Spam!" article in LG#62:

Note also that this may not work very well for you if you are on some sort of an in-company Cc-list (rather than a list-manager type of setup), unless you have a "whitelist" of the sort that I describe in my article.

Multiple email users on one public address

Wed, 01 May 2002 23:16:59 -0400
Lew Pitcher (lpitcher from

I recently switched ISPs and lost the multiple email addresses that the old ISP provided; now, my wife and I are restricted to sharing a single public email address. With fetchmail, I can retrieve our email from my ISP's POP3 server and store it in my lan server for on-demand "offline" reading, but with one email address, either my wife and I have to read each other's mail, or one of us gets no mail at all.

I fixed this little problem with the judicious use of a procmail recipe that uses a feature of email addresses to seperate mail destined for my wife from mail destined for me. You see, although email addresses are usually expressed in the form of


there is an alternate form that's a bit more readable:

  John Q Public <userid@host.domain>

The leading plaintext name (called a 'nickname') is ignored by the mail agents, but is treated as part of the email address for the purposes of data entry and display.

This means that

  Wifes Name <>


  Husbands Name <>

are delivered to the same email address (, but carry slightly different (and testable) values in the email To: field.

This difference permits me to write a procmail recipe that will detect a difference in the nickname and redirect any mail to "Wifes Name" into my wife's local mail spool, while directing mail to "Husbands Name" into my local mail spool. Additionally, mail addressed to "Husband and Wife" or "Wife and Husband" can be duplicated into each of our mail spools.

The procmail recipe that does all this looks like...

See attached sharing-account.procmail-recipe.txt

Of course, you can add as many users as you want nicknames to this, and each user will (ultimately) only get the email addressed to them.

-- Lew Pitcher

Excellent tip, Lew! Well done. As a relevant additional tip, try the '+' address hack: I haven't used it all that much, but it worked fine for the few times when I did. Mail sent to "user+string@host" will be delivered to "user@host", and the part after the '+' can be pretty much anything you like (obviously, excluding whitespace and the '@' character.) A friend of mine uses this as part of his spam reduction policy: when he posts in a Net forum or newsgroup, he'll do something like
He can then route everything from there to a specific mailbox, and can tell exactly where his address got harvested. When a given alias gets too heavily spammed, he blocks it and uses another one.

reliable downloads

Mon, 6 May 2002 09:45:03 -0400
Benjamin A. Okopnik (The Answer Gang)

Have you ever started a long download, left the computer to do its thing, and come back to a message that says "Download timed out" - at just a tiny fraction of the file size? Even with the "resume" feature of "htget", "wget", etc., you've still got the whole thing to do over. How can we get something to 'watch' our downloads, and restart them if they fail?

In Linux, that capability is actually built right in. When programs exit, they return an 'exit code' which indicates success or failure, with most programmers using a sensible definition (i.e., "no, the program didn't crash, but it didn't finish the download") for failure. Given that, all we have to have is a tiny "wrapper" script that checks the exit code, and restarts out process when we're done.

See attached persist.bash.txt

If I want to, for example, install "gimp" on my system, I know that the download will take all night (I have a very slow wireless modem.) Since I use Debian, I would normally type "apt-get install gimp"; instead, I'm going to do

persist apt-get install gimp

and walk away knowing that I'll have it by morning.

Be sure to check for immediate errors (such as "file not found", etc.) though, or you'll be cycling errors all night long. :) -- Ben

There is also an X binary which helps with sort of thing, although I've never used it. I have tried one or two similar apps under the "other OS" though (DL'd StarOffice 5.0 with it), and it is definitely a nice way to go. The SuSE pkg description is:
Name        : nt
Version     : 1.28
Summary     : Downloader for X
Description : Downloader for X is a tool for downloading files from the

  Internet via both HTTP and FTP. It supports reconnecting on connection
  timeouts, has a download queue for multiple files as well as support for
  simultaneous downloads.

    Koshelev Maxim <>
-- John Karns

"Unmapped" pixels.

Sat, 27 Apr 2002 03:52:36 +0200
Robos (The Answer Gang)
Asked and solved by Hans Borg

Hej Answer Gang,

I recently forwarded a problem to you that was very nicely solved. I am very thankful and I also learned a lot. That problem was probably not of much interest to the general reader of the Gazette, but that is not up to me tu to judge. Gazette is a very nice forum, and I like it a lot. Especially I like the "More 2 -Cent Tips" and "The Answer Gang".

Thank you all.

In the name of all probably: no probs ;-)

Well, disregarding the text above, I have a question that may be of more general interest. (Have checked FAQ's and your index search, but not found any obvious answers).

Have made my own icons (.xpm). No problem to make a X*Y one with a defined background. Many Linux .xpm icons,however, have the nice feature to "assert" the wanted pixels only, leaving the background (what ever it is) untouched. How to create or filter a X*Y .xpm file to achieve this feature ? All tips welcome.

Well, I think you mean transparent, meaning the background shining through, right? There is a special color defined. If you use this color not that color is shown but rather none. Dunno what that color is in hex, take a look at an icon that does it with an hex-editor, that should do it ;-)



Thank you for putting me on the right track. I actually found out that the .xpm files are ASCII coded. I always thought they were binaries.

Setting, for example, the background to white it would come out in the .xpm file's color definition as (for 24 bits):


Editing this line to:

"   s None c None"

will do it. Perhaps not the most straight forward method, but it works.

Best regards


Fri, 26 Apr 2002 16:03:30 -0400
Faber Fedor (The Answer Gang)
Asked by Brian Weaver

hi i am kinda new to linux. i am setting up a redhat 7.1 box and i can not telnet into the box. i can ping it. i can telnet out from the box. when i try it says connecting ( IP ADD) cannot open connection to host. it won't even telnet to its self. i seen alot of help for 6.2 but not for 7.1 in 6.2 there is a file inet.d i think that it that you have to modify but 7.1 i can't find it.? thanx brian

In RH 7.x, they switched over to using xinetd instead of the old inetd. You will now find a directory called /etc/xinetd.d. In there you will find a file called "telnet" (and "ftp" and ...). Open the file with your favorite editor and change the line that reads "disable = no" to "disable=yes". Then restart xinetd with a "/sbin/service xinetd restart" as the root user.
Actually you probably don't even have the telnet server daemon installed. Red Hat (Good Distributor! pat pat) doesn't install it by default anymore. Try
rpm -q telnet-server
to see if you've got it. If not, install the package and follow Faber's instructions above. -- Breen
However, you shouldn't be using telnet. telent transmits passwords in the clear (not encrypted) so people can find out what your password is by "sniffing the wire". Use ssh instead (assuming, of course, that you installed the ssh server). -- Faber
Absolutely true. ssh is far superior. -- Breen

This page edited and maintained by the Editors of Linux Gazette Copyright © 2002
Published in issue 79 of Linux Gazette June 2002
HTML script maintained by Heather Stern of Starshine Technical Services,

(?) The Answer Gang (!)

By Jim Dennis, Ben Okopnik, Dan Wilder, Breen, Chris, and... (meet the Gang) ... the Editors of Linux Gazette... and You!
Send questions (or interesting answers) to The Answer Gang for possible publication (but read the guidelines first)


¶: Greetings From Heather Stern
(?)Exchange Client for Linux
(?)How does LILO find the boot partition???

(¶) Greetings from Heather Stern

Hi Dad! (yep, we've got another holiday for parents coming up.) Everybody wave a big "Hi!" to him, since it's all his fault that I'm into computers so much :)
Hello folks and welcome once more to the marvelous world of The Answer Gang. I'm sorry if things seem a mite slim this month -- I had a little fun with the email monster (and we're pubbing half a day earlier than usual). It seems if your mail server is down for long enough on a really busy mailing list (gosh I wonder what list that would be!) you fall off. Eventually I clued in and re-subscribed, but meanwhile I've got a few goodies from the past few months.
After all we really do answer a lot more people than get published nowadays.
So, what lessons can you, gentle readers, learn from my trevails this month? Let's start taking inventory:
  • Do have a regular backup plan, and do occasionally check that it works. I do, it does, and when that 10 year old itty bitty hard disk kinda mostly gave up the ghost, I knew I still had something to work with.
Although I admit that I'm glad it wasn't so bad that I had to reload from scratch. New installs can take a few hours if you're picky about your system settings.
  • I've learned to use mutt's "save hooks" even more than last month. This is a very good thing. It means that a lot of my mail can be refiled perfectly with only two keystrokes each, or less if I do bulk tagging on boring threads.
  • I'm also now a big fan of l (for limit) ~L (either originated or rec'd by) and one of my favorite list sites. e.g. ssc or debian. I don't have to type the whole thing. Yum!
Of course I mentioned Baycon last month but for me it was only last weekend. If you'll be in the Silicon Valley next year around Memorial Day next year, get your membership now while it's still cheap -- this year was the 20th anniversary and we had a real blast. Between my Star Trek crew (hey, we're the 24th century's user group, we can beam a few folks down to a convention) and the local Linuxdojo group we did just fine. It seems my friend Tim is part of a big effort to stop software piracy... by the rather completist tactic of moving away from software that thinks it can be stolen at all. If you want to know more about that, check out and see what you can do for it too. So he had a good chance to play with some desktop layouts he had in mind.
  • I'm pleased to say that Hancom Office works so well hardly anybody noticed that it might have been different than other word processors they were already used to. Speaks RTF without even a hiccup, too.
  • floppies are still a bit of a pain though. Thank goodness for mtools.
  • K desktop works okay on Celeron 300s and PIII 400s, but I wouldn't exactly call them speed demons. And there's still no such thing as a really good icon for "just wanna surf the web". Much less for 4 different browsers, just in case what's the best javascript-baby for eBay isn't too hot for Yahoo mail. Oh well!
But he's got me started on a good track. I've often said, but hardly made any chance to implement, that people simply don't care so much about whether all these apps think they match, as whether they just work when launched. It's a trickier puzzle to solve for the lesser machines, and since my own stock in trade is people tuning up older systems (which can only go so far before you may as well buy a new one) and laptops (which don't allow luxuries like swapping out video for a card that behaves itself) -- Tim and I can put our heads together on a reasonable layout for these beasties.
I'm pleased to say that my "new" workstation works very nicely now. I've got sound - so I use at jobs to poke me that I have to do something. (Imagine quiet bedoop noises at the wee hours, "talking computers" midday. My current favorite noise? "We're Starfleet officers. Weird is part of the job.")
I'm so happy, my color printer works! I'm still working on having both printers available to the household at the same time. (Yes I'm slow. The color printer is still working just as well as last month, so at least I haven't broken it yet.) I've given up on the idea of them living at the same computer; old betel deals with the laser quite happily and I suppose my new one can be taught to serve the color printer. But I'll be a bit annoyed if nobody else in the house can remote-print into it. It really shouldn't be so tough, one would think. Except that the rest of the household still speaks lpd and the color beastie is happy on CUPS :(
I've got my Wacom Graphire USB tablet and boy am I a happy camper with that! Although it's wierd...
  • It actually behaves better as a "generic PS/2 mouse" attached to /dev/input/mice than it does when I try to use options more specific to Wacom tablets. Go figure. Too bad the pen only has one button. The mouse pointer is a wheelmouse, but I haven't tested whether it behaves. It does 3 buttons so I'm happy enough to work day-to-day.
Of course I immediately set up my color tricks for consoles, and I compose the TAG column from under a dedicated user, just as I have other users for other projects, and a few chroot kits for development.
In the next couple of weeks I look forward to visiting the USENIX Annual Technical conference ( and hanging out with a bunch of my sysadmin colleagues. By then maybe I'll have more of my own tweaked LNX-BBC variant finished. Maybe I'll even have it finished enough to hand some out rather than merely show off, but I'm not holding my breath. It seems like every time I start a new small project like that my regular client work increases. Which I can hardly complain about, given the current economy :)
And my internet-lounge-on-wheels continues apace. Later in the year (around Labor Day) I'll be in charge of that again, but this time for a much bigger gathering, the World Science Fiction Convention. ( If you're a fan and planning to attend, I can still use volunteers on my crew. Use the link for me at the bottom of this page instead of bugging the Gang, if you're interested.
With that, I've babbled quite enough, I think. On to the threads!

(?) Exchange Client for Linux

From "Bill"

Answered By Mike Martin, Faber Fedor, John Karns

(!) [Heather] William has requested anonymity in accordance with our ask-the-gang guidelines.

My employer recently migrated to the Micrsoft Exchange Server. The problem is that many of us use linux and would prefer to not have to use Microsoft Outlook. This is further complicated in that the company make heavy use of the Exchange Calendaring features, so the answer is not a simple as to have the Exchange administrator configure the server to vend the mail via pop as we still need access to the calendars.

Anyone know of a linux client to Exchange that supports Calendaring?


(!) [Mike M] For full support I think you need ximian evolution
and unfortunately the ximian exchange connector (which is 70 pound a pop)
This should work exactly like outlook
If your exchange server is configured to use ldap you may not need the connector
(!) [Faber] Have you looked at Bynari ( They have a product called InsightClient that (supposedly) does what you want.
If you decide to use it, would you be willing to post information on how well it works? I'd love to hear about it.
Regards, Faber
(!) [John K] Probably best to run a native Linux app as suggested by others, but another alternative might be to run Outlook under Codeweaver's Crossover pkg. That way, at least you wouldn't have to switch your OS.

(?) How does LILO find the boot partition???

From Super Simian

Answered By John Karns, Ben Okopnik

Greetings Answer Gang,

I've found the info you've given to others very useful in the not-so-distant past, and I like the Gazette in general, and I thought I might ask you a question to which I have looked for the answer to myself, and very recently plagued and tormented me:

How does LILO find the boot partition???

(!) [Ben Okopnik] Quite tasty, thanks. Also rather cute and cuddly, but not quite the kind of thing one takes home to mother, if you know what I mean. :)
(!) [John Karns] Sorry, I'm on a bit of a hurry at the moment so am unable to write a detailed reply. But I can offer some hints.

(?) Wait, first, here's what I'm running:

PIII dual proc
RedHat 7.2
2 IDE disks, hda and hdc,
1 SCSI disk, sda

Suppose that's all that's relevant to this question...

OK, so the scsi disk is a pretty new addition to the setup, and I already had a pretty good linux install on hdc, so I decided to move over to the scsi as my main disk. After a bit of fooling around, I decided that the easiest way was just to do a new install onto the scsi, and copy over some choice config files and all my data. This went smoothly, no problem.

Oh, I should probably mention at this point, I had LILO in the MBR of hda, and my boot partition was on hdc1...

So, about a week later, I still had my old linux installation on hdc2, as I was waiting to see if I had forgotten any vital info before I commited it to the abyss. Well, my roommate wanted to reinstall and format (WinXP, as it happens...) and he needed about 6 gigs of backup space, so I deleted my old linux installation on hdc2, and rewrote the LILO on the MBR without it, just to make sure everything was still cool, and it was. We moved the data to my system, he reinstalled, and we moved the data back.

So, then, I decided it was time for a little housekeeping, and repartitioned hdc as one ext3, and went to reboot, and... OH CRAP! My boot partition was on that drive!!!

So, I poped in my bootable "Super Rescue" cdrom, and decided to poke around a bit and see if I could get my system to boot again. I ran LILO again, no dice. I poked around for a while, and noticed I still had all of the data in /boot on sda1, and tried to figure out how to inform LILO about this, but I had no luck. I even recreated the boot partition on hdc1 and copied all the same info back onto it, and reran LILO, still no luck. After looking through some man pages and browsing through, I still had no clue as to how to get things working again, so I made a new linux install on hdc, using the same boot partition (hdc1) and installing LILO to the MBR of hda again, modified lilo.conf in this new install to also boot the sda copy of RedHat, and everything worked.

So, my question to you, is how do I make LILO aware of the location of the boot partition or directory? How do I prevent this from happening again (aside form not deleting my boot partition :)

(!) [John Karns] With 3 hd's in the system, things can get a little complicated to explain, as there are so many ways to go about it. But for the time being, let's say that when you installed to sda the install properly set up everything on sda, and assumed that it was the only drive in the system. Then in order to boot from sda, you would have to make a change in your BIOS setup to tell the system to boot from SCSI. When there are both IDE and SCSI drives installed, the default is to boot from IDE. Most BIOSes I have seen in the past two years allow the option of booting from SCSI.

(?) Oh, I thought it might be something in /etc/fstab, but to my feeble efforts, this proved to be a blind alley.

(!) [Ben Okopnik] Nope, wouldn't be there. That comes _way down the road, dealing with which partitions should be mounted and where.
(!) [John Karns] If you installed fresh to sda, then the fstab there should have the correct set up. However, if you copied the one from hdc, then you would have to change the partition references to point to sda.

(?) I'm feeling a little lost, there doesn't seem to be anything in lilo.conf addressing this,

(!) [Ben Okopnik] Here's a bit from my "/etc/lilo.conf" (though admittedly not all the distros comment theirs this well):
# Specifies the boot device.  This is where Lilo installs its boot
# block.  It can be either a partition, or the raw device, in which
# case it installs in the MBR, and will overwrite the current MBR.

(?) and I thought maybe fstab might help, as LILO should be able to find this file, as the / directory IS specified in lilo.conf, but please, help!

(!) [John Karns] You have to decide on what scheme you want to use to boot your system - i.e., whether you want to boot from lilo or use XP's boot mgr (lilo is easier to config for multi-boot IMO), and from which drive you want to boot. Gotta go.
(!) [Ben Okopnik] My recommendation to you is to take a good read of "/usr/share/doc/lilo/Manual.txt.gz", or wherever RedHat keeps its doc files (if I recall, it's that or something fairly close to it.) It's a well-written document that describes the boot process and LILO's place in it, as well as all about boot records and where they can be stored and how they can be accessed. Quite an education, all in one file (about 125kB, but, hey, it's a complete manual.)

(?) Eagerly awaiting your replies,

--Super Simian

PS-I hope this email doesn't contain any html, I know you people don't like that, but it's hotmail and it might, and I can't find anywhere to turn it off!

Thanks again!

(!) [Ben Okopnik] It was fine, just plain text. Seems like Hotmail does the Right Thing in that regard.

(?) Hello again,

OK, after reviewing the documentation under /usr/share/doc/lilo, I think I understand exactly what happened. Lilo was starting the boot process, but only got as far as "LI" because it couldn't find the files in /boot, which originally was a separate partition, hdc1. Even after recreating this partition, and copying the same data back to it, it still couldn't find /boot/boot.b because the info Lilo stores in the MBR points to the physical location on disk of boot.b, instead of using partition numbers and directories to locate it. That's why I couldn't find anywhere to specify the location of the boot partition, because Lilo gets this info from your filesystem when you execute /sbin/lilo to write a new MBR. So if you have, say, your root on hdc5, and hdc1 is mounted under /boot, then it actually stores the location of the files on disk (by sector, or some such), and if you remove hdc1 from your filesystem and just copy the files to /boot under hdc5, Lilo will still look for the info on hdc1.

Then, when I reran Lilo to try to get it to use the /boot directory on sda1, it still couldn't find /boot/boot.b because it was on a SCSI disk which was not addressable by BIOS during the early portion of booting, as I had my SCSI BIOS turned off to speed booting. I mistakenly thought that the stuff in the MBR was enough to get the computer into protected-mode.

So, thank you very much for pointing out that document, it has proved to be an excellent repository of informative Lilo goodness!

Oh, and do you see any flaws in my thinking? I'm fairly sure that the above is what was going on...

Thank you

(!) [Ben Okopnik] It all sounds very reasonable to me, at least according to The Holy Writ, erm, I mean /usr/share/doc/lilo/Manual.txt.gz. Sounds like you've read the docs and understood them - well done!

This page edited and maintained by the Editors of Linux Gazette Copyright © 2002
Published in issue 79 of Linux Gazette June 2002
HTML script maintained by Heather Stern of Starshine Technical Services,

"Linux Gazette...making Linux just a little more fun!"

News Bytes


Selected and formatted by Michael Conry

Submitters, send your News Bytes items in PLAIN TEXT format. Other formats may be rejected without reading. You have been warned! A one- or two-paragraph summary plus URL gets you a better announcement than an entire press release. Submit items to

 June 2002 Linux Journal

[issue 98 cover image] The June issue of Linux Journal is on newsstands now. This issue focuses on program development. Click here to view the table of contents, or here to subscribe.

All articles through December 2001 are available for public reading at Recent articles are available on-line for subscribers only at

Legislation and More Legislation

 Elcomsoft DMCA Case

A recent attempt to prevent the Elcomsoft case (archive: Sklyarov/Elcomsoft DMCA case) going to court has failed. The challenge was based on two constitutional arguments:

  1. That the DMCA is unconstitutionally vague as applied to Elcomsoft, violating the Due Process Clause of the Fifth Amendment (i.e. it is too vague for people to know how not to violate it).
  2. That the DMCA violates the First Amendment in various ways: it is an indiscriminate content-based restriction on speech, insufficiently tailored to qualify as serving a compelling government interest; it infringes upon the First Amendment rights of third parties to engage in fair use; it is too vague in describing what speech it prohibits and thereby chills free expression.
These arguments were not accepted by the judge, whose ruling may be viewed online in PDF format. As was pointed out on Slashdot, the judge accepted that computer code (including object code) is a form of expression protected under the first amendment. However, he reached the conclusion that the DMCA was content-neutral (being targeted at the purpose of the software, not its content) and thus did not impair the right to free expression. the extent that the DMCA targets computer code, Congress sought to ban the code not because of what the code says, but rather because of what the code does.
And since he judged the regulation to "further a substantial government interest", the free speech argument was lost. With regard to fair use, the judge ruled that no fair use was prohibited or eliminated by the DMCA. Some uses might be more difficult than they would be without the DMCA, but they were still legal and possible. There were several other points dealt with in the 33 page ruling, including restriction of access to public-domain works, each of which was rejected by the judge.

The Electronic Frontier Foundation have released a press release giving information on the ruling. Additionally, this story has been covered on Wired.

 More DMCA

Maybe we should call this section "DMCA and More DMCA". In another DMCA setback, a federal appeals court rejected the latest 2600 Magazine challenge to the DMCA. The Second Circuit Court of Appeals denied 2600 Magazine's request for review of a November 2001 appeals court decision upholding an injunction made against the web publisher by the MPAA (Motion Picture Association of America). The injunction bars 2600 Magazine from publishing or linking to DeCSS software that decodes DVDs. The Electronic Frontier Foundation and 2600 must now decide whether to attempt an appeal of the ruling to the U.S. Supreme Court.

In a related case, EFF and the First Amendment Project have asked the California Supreme Court to uphold a lower court decision to permit publication of DeCSS source code. The DVD CCA (Copy Control Association) are attempting to get the court to overturn the decision and block publication of the code.

EFF have a large amount of information on these and related cases.

Intriguingly, NewsForge ran a story that Reuters,,, and dozens of other publications could now be guilty of DMCA violations. What all of these publications have in common is that they have described the process whereby Sony's "copy-proof" protection for CDs can be defeated with a magic marker. I won't hold my breath waiting for the court cases to start, but it does show how easy it is to run foul of this law.

 Cox Speaks Out

Alan Cox, who has been a staunch critic of US laws such as the DMCA has attempted to draw the attention of Europeans to the European Union Copyright Directive which could yet turn out to be even more restrictive than the DMCA. Cox was speaking at a lecture on the EUCD, audio from which is available online. Alan's views are further expressed in a recent Slashdot interview, where he discusses laws and Linux.

Another Cox. Also on Slashdot is a report that film maker Alex Cox (writer/director of Repo Man and Sid And Nancy) has written in The Guardian that the movie industry's real pirates are the Hollywood studios and the MPAA who have forced out independents.

 Open Source for Peru

Dr. Edgar David Villanueva Nunez has written a careful and rational reply to the input he received from Microsoft on proposals to limit the Peruvian government to using only free software. He writes that cost is not the main principle behind this proposal, but rather free access to public information by the citizen, permanence of public data, and the security of the state and its citizens. Re the last one, he writes, "it is indispensable to be able to rely on systems without elements which allow control from a distance or the undesired transmission of information to third parties." Only open-source software allows the state and independent experts to verify that this is the case.

A set of links on this story (including links to original Spanish versions) are available at, including an interview with Dr. Villanueva by Linux Today.

 Plugging the "Analog Hole"

EFF have issued an advisory analysing some noises coming from the MPAA on the topic of content protection. It would appear, that the MPAA plans to totally rewrite the rule book with regards to technology. Their report calls for no less than the regulation of analog-to-digital converters (ADCs), an incredibly generic and commonplace electronic component found in a wide range of scientific, medical and entertainment devices. The MPAA proposes that every ADC be controlled by a "cop-chip" that will shut down the device if it is asked to assist in converting copyrighted material, thus "plugging the analog hole." The EFF report on this subject has more details on this mind-bending story.

Linux Links

Karlheinz Langguth has written a detailed description on how to use Linux as a server for small office solutions.

LinuxDevices survey of cool embedded Linux systems.

Some tips on Secure Programming in PHP at Zend.

A couple of links from Linux Weekly News:

Some links featured on Linux Today over the past month:

Some stories from NewsForge which might interest you:

Some interesting articles from the O'Reilly network:

A few Linux Journal web articles:

Some links from The Register

Slashdot links

Upcoming conferences and events

Listings courtesy Linux Journal. See LJ's Events page for the latest goings-on.

Embedded Systems Conference (CMP)
June 3-6, 2002
Chicago, IL

June 9-14, 2002
Monterey, CA

PC Expo (CMP)
June 25-27, 2002
New York, NY

European Python and Zope Conference 2002
June 26-28, 2002
Charleroi, Belgium

O'Reilly Open Source Convention (O'Reilly)
July 22-26, 2002
San Diego, CA

USENIX Securty Symposium (USENIX)
August 5-9, 2002
San Francisco, CA

LinuxWorld Conference & Expo (IDG)
August 12-15, 2002
San Francisco, CA

LinuxWorld Conference & Expo Australia (IDG)
August 14 - 16, 2002

Communications Design Conference (CMP)
September 23-26, 2002
San Jose, California

Software Development Conference & Expo, East (CMP)
November 18-22, 2002
Boston, MA

News in General

 Free LinuxTag Tickets

NewsForge reported that free admission passes to the LinuxTag event are available for download at the LinuxTag site. Not only are the passes free in the monetary sense, but they are also free in the free speech sense since the code for creating the tickets is freely available under the GPL.

 Reuters Supports Adoption of Linux in Financial Services Industry Using Intel Based Servers

Reuters is to work with HP, Intel and Red Hat to offer its market data system on Intel-based servers with Linux. Naturally enough, Reuters have a report on this development. Linux Journal also has a report on this story.

 Embedded Linux Journal

Embedded Linux Journal has ceased publication. The current slump in the tech economy makes for not enough advertisers to support a standalone publication. Instead, there will be an embedded section embedded in Linux Journal (pun intended). The magazine's website, will continue to feature new articles. Perhaps ELJ will return when the economy improves.

Distro News

 United Linux

United Linux is a new distribution sponsored jointly by Caldera, Conectiva, SuSE and Turbolinux. The goal is to eliminate inter-distribution incompatibilities by providing a common reference implementation--like the Linux Standards Base (which it's based on), only this is not just a specification but a full-blown product.

Each vendor will continue to market its own distribution with custom features, but these features will be reimplemented as add-ons over this common base, rather than using their individuall codebases. Red Hat, Turbolinux and Red Flag are not participants in this consortium, but the group has invited them and any other distributions to join it. It is interesting to note, however, that the initial four partners have non-overlapping primary markets. Caldera works mainly in US vertical-integration deployments, SuSE is based in Germany, Conectiva's niche is Latin America, and Turbolinux has a strong presence in Asia. Although they compete directly, this regionalization of primary markets may have been the catalyst to allow them to work together.

UnitedLinux plans to have a 1.0 release by the end of the year. It will be available commercially and also for free download. The schedule and (undetailed) specification is here. The installer will support eleven European and Asian languages including Hungarian.

A detailed specification whitepaper is here (PDF, 26 pages). In addition to the usual standards (FHS, LSBm LI18NUX), it also specifically supports XML, SOAP and WBEM (Web-Based Enterprise Management). The installer can operate unattended following an XML configuration, or clone an interactive configuration. The software will be what's required for a minimum full-featured system; e.g., kdebase 3.0 and Konqueror, but not the rest of KDE. Apache, CUPS, Postgres and vim will be included, along with packages to support High Availability clustering, Virtual Private Networks, etc. Filesystems: ext2, ext3, ReiserFS, JFS, and a number of others.

 ALT Linux

Developer's URL: ALT Linux, a Russian distribution of Linux has announced the release of ALT Linux Master 2.0. This release spans 6 CD's and includes a wide range of applications. Manuals are included covering installation, system administration, general use and OpenOffice. Price is 1300.00 rub (~ 40 $).


Hewlett-Packard offers pre-installed Debian as an option on its Blade Servers. A blade is a computer-on-a-card that can coexist with other blades in a single computer case. As shipped, one blade has Debian preinstalled. The other blades have no OS, but you can use HP's SystemImager software to copy the Debian image onto the other blades.

Linux Magazine have an article on The Importance of Being Debian which profiles the history of the distribution.


NewsForge picked up the story that Slackware 8.1 RC1 has been released.


The Register has reviewed SuSE 8.0, as has DesktopLinux. Opinions vary.

SuSE Linux, has announced the shipment of the SuSE Linux Enterprise Server 7 for 64-bit IBM eServer zSeries. One of the first applications to make use of this new 64-bit environment will be the e-business platform on Linux for the IBM eServer zSeries, which will be made available for SuSE Linux Enterprise Server 7 for zSeries by the end of May 2002.


The Register has taken a look at Mandrake 8.2. Not entirely happy.

Software and Product News


Version 1.0.7 of GnuPG has been released. The list of changes is here and it is available for download.


As Mozilla edges closer to its imminent version 1.0 release, Mozilla 1.0 release candidate 3 has recently been set loose.

 Arkeia Signs Strategic Partnership to Enter OpenNAS Market

Arkeia Corp., has announced a partnership with Consensys Ltd., the European supplier of Raidzone OpenNAS terabyte fileservers for enterprise network configurations. The two firms concluded a strategic alliance to integrate Arkeia's solution into the OpenNAS product line in Europe. Arkeia is a network backup solution used worldwide by companies to protect their data. Raidzone produces a line of internal, external and rack mount disk arrays and OpenNAS servers.

 Command Prompt Offers VAR Program for Mammoth

Command Prompt, Inc. has announced a VAR/OEM program to allow consultants to provide commercial and support PostgreSQL services to their customers. The program is designed for any consultant, or consultant firm to provide an array of supported services around the Command Prompt, Inc. suite of PostgreSQL products. The program offers, discounts on not only Command Prompt's commercial product lines but also on support services, including annual managed contracts, managed database hosting, and senior programming services. Mammoth PostgreSQL from Command Prompt, Inc. is an SQL-compatible Object Relational Database Management System, designed for small to medium size businesses.

 IBM Launches eServer Integrated Platform for e-business

IBM has announced the launch of its new eServer Integrated Platform for e-business. The platform will be coupled with IBM's Start Now marketing and enablement program providing Business Partners with marketing materials, sales tools, and detailed deployment instructions needed to effectively deliver this offering to SMB customers. This solution includes the hardware and software Business Partners need to rapidly build and deploy a wide variety of Linux-based solutions.

IBM has also announced the launch of its new volume management technology for Linux. Enterprise Volume Management System, which has its home at SourceForge, is designed to streamline and enhance storage management capabilities. The new technology is the result of extensive collaboration among developers in the Linux open community and the IBM Linux Technology Centre.

 Trustix and LinuxIT Partner in the UK

Trustix and LinuxIT have announced a partnership to provide end to end support and services to UK partners and customers of Trustix Linux Solutions - a range of e-business infrastructure solutions aimed at small and medium sized enterprises.

 Opera 6.01 for Linux Released

Opera 6.01 for Linux has been released. Version 6.01 fixes a security issue in the recently released Opera 6.0. Opera 6.01 for Linux is available for download.

 PerlMx Spam Solution

PerlMx 2.0 is an email security and filtering system for sendmail that operates at the gateway and is reportedly "over 98% effective in identifying spam". It has virus, spam, and corporate communications compliance filters, all written in Perl that work out of the box and are easily extensible. PerlMx supports most corporate UNIX platforms and is priced per CPU, removing the per user cost of spam.


VariCAD has announced the release of VariCAD Update for both Windows and Linux operating systems. VariCad is a compact mechanical CAD package suitable for mechanical engineering designers who need a way to solve numerous tasks within the area of general mechanical engineering. A free trial version is available for download at

Copyright © 2002, Michael Conry and the Editors of Linux Gazette.
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"

Dillo--a Web Browser as Fast as Lightning

By Matthias Arndt


Dillo is a new and up-and-coming open-source web browser. It is different and almost not comparable to other browsers. I discovered it over a year ago and I've been watching this project growing and getting into a usable state. It is still alpha software but in my opinion this program is quite useable in its current state.

It resembles the old Chimera browser in being small and fast. It is definitly not as fancy as other graphic browsers but it has its good points.

Dillo features

Dillo currently has support for:

You can use it as any other graphical browser. Click on links to activate them. The middle button will bring up the link in a new window. The right button gives you a simple menu which allows you to view the page source, to save a page or to download a link.

Advantages of Dillo

Dillo is...

Disadvantages of Dillo

If you really need Javascript, Java or Flash, then Dillo is not for you. Of course, you can use Dillo for your regular surfing and open another browser whenever you need to see the Javascript, Java or Flash.


First go to the Dillo homepage and grab a tarball of the current version.

Then issue the following steps to install it: Steps given like this must be entered at a shell prompt.

If all works, you should have a binary called dillo now. To install Dillo system-wide do su -c "make install" now.

Type dillo to get started and don't forget to read the documentation that comes with Dillo.

To compile Dillo , you'll need to have several libraries installed including X development, libpng and GTK.

Dillo is in the Debian distributon (unstable at least), and may be in other recent distributions too.


Dillo is neat. You should take a look at it. Dillo is very usable especially for browsing local documentation. But in the current versions you can even take a serious trip into the web.

Dillo is small and fast and therefore makes w3m obsolete. Anyone who is still browsing with w3m because of its speed should change to Dillo. Dillo is as fast and it offers rendering graphics. You can even turn image loading off and only get the ALT tags of images.

Dillo is my browser of choice. Only when I have to browse pages needing Javascript or Flash do I start a Mozilla-compatible browser. The most annoying drawbacks for me are the lack of CSS support and that you cannot cut & paste from the Dillo rendering area.

So take a look it--nobody forces you to use it. It's a nice example for what can be done, and a pretty cool example of open-source software.

If you want to get more information, I suggest visiting the Dillo homepage.


Matthias Arndt

I'm a Linux enthusiast from northern Germany. I like plain old fifties rock'n'roll music, writing stories and publishing in the Linux Gazette, of course. Currently I'm studying computer science in conjunction with economics.

Copyright © 2002, Matthias Arndt.
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"

Cracking open proprietary envelopes

By Adrian J. Chung

Anyone with an email address can expect to receive attachments in a multitude of formats. Unfortunately, some formats cannot be read using free software. This is especially true if our email buddies are still involved in the arguably risky practice of using proprietary programs in conjunction with their email readers.

Many free software advocates adopt a policy of ignoring all email with attachments dependent on closed source software, opting instead to lecture the sender on the importance of open standards. Others may not like missing out on the fun to be had from attachments being forwarded amongst their peers. If you find yourself in this situation, the techniques outlined in this article may serve as a partial solution.

There is not much a Linux user can do if the entire contents of an attachment are encoded using a jealously guarded secret algorithm. Very often however, the problematic file is merely a thin proprietary envelope enclosing a loose collection of data objects that use well-known encoding standards. For instance, some MS Word documents being forwarded around the Net contain ordinary JPG and PNG images embedded within the file. If we can find a way to remove the envelope, reading these enclosed files would be a straight forward matter. The following sections describe how this can be accomplished using a little Python scripting together with a few image viewing and manipulation tools available on most Linux distributions.

Extracting the text

Before tackling the problem of the embedded images we can easily view any readable text using the strings utility:

strings proprietary.file | less

This will output any strings of at least 4 bytes in length that consist of readable ASCII characters. Naturally, a lot more than just intelligible sentences will be returned. Most will be junk, but the readable text is easily spotted. The strings tools will also pick up the readable header information within the embedded images themselves. JPEG files contain the string "JFIF" in the header. This gives us a quick way to check what types of images a file may contain, and gives an indication of how many there are.

strings proprietary.file | grep JFIF
strings -n 3 proprietary.file | grep PNG
strings proprietary.file | grep GIF8

The -n 3 allows us to detect readable strings as short as 3 characters. Not every occurrence of "JFIF" is necessarily a JPEG image since the document itself may have mentioned JFIF in a paragraph of text -- though this is rare among the email attachments most commonly forwarded.

Locating the images

We need to find where exactly each image is located within the file. A little Python will help to find possible embedded images and report their positions as a byte offset:

from string import find

#read in proprietary data
fh = open( "proprietary.file" )
dat =

#search for JFIF
x = -1
while 1:
    x = find(dat,"JFIF",x+1)
    if x<0: break
    #file actually started 6 bytes earlier
    print x - 6

This will find the byte offsets of every embedded JPEG file though not every offset is guaranteed to be for a valid file. This can easily be extended to handle GIF and PNG images:

Listing 1
from string import find
from sys import argv

headers = [("GIF8",0), ("PNG",1), ("JFIF",6)]
filepath = "proprietary.file"
if len(argv)>1: filepath = argv[1]

fh = open(filepath )
dat =

for kw,off in headers:
    x = 0
    while 1:
        x = find(dat,kw,x+1)
        if x<0: break
        print kw,"file begins at byte",x - off

Note that the image file begins a few bytes before the "PNG" or "JFIF" string.

Displaying the images

Now that we know where each image is likely to start how do we display them? ImageMagick's display utility can help here. Suppose our proprietary file contains a JPEG image beginning at byte 1000. Using tail to remove all the bytes that preceed it and pipe the rest to display.

tail -c +1001 proprietary.file | display -

Note that tail -c begins counting bytes at 1. In case we have many dozens of embedded image files we can adapt our previous Python script to automate the process.

Listing 2
from string import find
from sys import argv
from os import system

headers = [("GIF8",0), ("PNG",1), ("JFIF",6)]
filepath = "proprietary.file"
if len(argv)>1: filepath = argv[1]

fh = open(filepath )
dat =

for kw,off in headers:
    x = 0
    while 1:
        x = find(dat,kw,x+1)
        if x<0: break
        system("tail -c +%d %s | display -" % (x - off + 1, filepath))

Extracting each image file

ImageMagick throws away any excess data fed to it after reading to the end of the image segment. If we want to separate the image data completely for storage as individual files, we also need to find the end of each image. One way to do this is to use a modified binary chop algorithm.

Listing 3

from string import find
from sys import argv
from commands import getstatusoutput

headers = [("GIF8",0,"giftopnm","gif"), ("PNG",1,"pngtopnm","png"),
filepath = "proprietary.file"
if len(argv)>1: filepath = argv[1]

fh = open(filepath )
dat =

inum = 0
for kw,off,conv,ext in headers:
    x = -1
    while 1:
        x = find(dat,kw,x+1)
        if x<0: break
        beg = x - off
        #possible image located -- find end by binary chop
	s1 = len(dat) - x
	s0 = 1
        sz = s1
	while s0<s1:
	    (stat,output) = getstatusoutput("tail -c +%d %s | head -c %d | %s >/dev/null" % (beg + 1, filepath, sz, conv))
	    if stat:
                #failed -- possibly too small
                if sz == s1:
                    #failed -- probably invalid data
                    print "failed... no image here"
                elif sz == s0:
                    #we've found the length -- write out image
                    imgname = "image%03d.%s" % (inum, ext)
                    print "writing",imgname
                    fh = open( imgname, "w")
                    fh.write(dat[beg :beg+s1])
                    inum = inum + 1
                s0 = sz
                #might be too big -- try smaller
                s1 = sz
            sz = int((s0+s1)/2)

One can make use of image decoding utilities giftopnm, djpeg, and pngtopnm to locate the end of the file. Like display these tools discard excess input data after the end of the image file and with terminate without error. If however they are given truncated image data they will report an error and terminate unsuccessfully. The Python script feeds image data of varying lengths to the decoding tool and its completion status is used to home into the correct length of the required file.


This article has shown how to write scripts that extract data objects, encoded using platform-independent open standards, from within proprietary files. It should be a simple task to extend these scripts for handling other image formats and even other types of data objects, such as sound and music files. Note that there are many file formats that frustrate the techniques described here via a layer of simple encryption and/or obfuscation.

Even if one has access to the appropriate proprietary application for reading a particular email attachment, the scripts outlined above can be useful for avoiding any possible macro viruses or security exploits specific to that application.

And finally a word of warning. The legislature of some countries have vaguely worded laws that can be interpreted in such a way that these scripts may be considered as illegal copyright circumvention devices. This may or may not be relevant to you depending on the country where you reside. As is always the case when mixing open and closed source systems, your mileage may vary.

[Editor's note: The Python Imaging Library (PIL) provides a way to work with images from within a larger program. You can open an image and read its type and dimensions, transform it, create thumbnails, etc. -Iron.]

Adrian J Chung

When not teaching undergraduate computing at the University of the West Indies, Trinidad, Adrian is writing system level scripts to manage a network of Linux boxes, and conducts experiments with interfacing various scripting environments with home-brew computer graphics renderers and data visualization libraries.

Copyright © 2002, Adrian J. Chung.
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"

Help Dex

By Shane Collinge

[These cartoons are scaled down to fit into LG. To see a panel in all its clarity, click on it. -Editor (Iron).]

Carol and Tux continue their holiday in Asia.

Recent HelpDex cartoons are here at the CORE web site.

Shane Collinge

Part computer programmer, part cartoonist, part Mars Bar. At night, he runs around in a pair of colorful tights fighting criminals. During the day... well, he just runs around. He eats when he's hungry and sleeps when he's sleepy.

Copyright © 2002, Shane Collinge.
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"

Compiler Design with Python

By Dinil Divakaran

1. Introduction

1.1 Purpose

C is obviously the first choice for anybody interested in designing a production quality compiler or interpreter. But what about designing a `little language' just for the fun of it (or maybe, for more serious purposes)? Why worry when you have Python - and some really smart tools to go with it!

1.2 The toolkit

We will be using Python Lex-Yacc (PLY) for recognizing tokens and parser construction. These tools are very closely modeled after traditional lex/yacc. If you know how to use these tools in C, you will find PLY to be similar. You can download PLY from the site

We will need the modules and in our working directory. Also we require Python version 2.1 or higher.

2. Getting started

Before going into the details of implementation, let us get down to the basics.

2.1 Tokens

What are tokens ? Tokens are symbols like +, -, * or /; or words such as begin, end, if or while - which we would like to identify as operands, reserved words, keywords etc. Tokens must be defined as regular expressions.

2.2 Defining the Language

Since we are writing a compiler for a particular language with constructs that we would like to include, the first thing to do is to define the language. This is done by writing a set of rules or grammar for the particular language. For example, if you want your language to provide the 'if-then-else-endif' construct, then one simple way to write a rule for it is :

     if_statement : IF LPAREN statement RPAREN multiple-statements ELSE
     multiple-statements ENDIF

where (1) IF, LPAREN, RPAREN, ELSE and ENDIF are tokens for recognizing if , ( , ) , else and endif respectively. (2) 'statement' and 'multiple-statements' are again different constructs for which rules are written.

2.3 Parsing

In simple terms, parsing is the method of verifying whether the input program does match the rules given to the parser. There are different types of parsing methods. But we needn't go into the details involved. It is only sufficient to know that, given a set of rules (as seen in the example above) the parser sees, if the input constructs corresponds to the rules defined.

3. Implementation

Well, we are now ready to implement a compiler. There are different phases of a compiler like token recognition, parsing, taking semantic actions, producing intermediate code, optimizing it, and finally producing the required output assembly code. The steps that we are taking will also be quite similar.

3.1 Defining the Language

As said earlier, the first step is to define the language which you want your compiler to accept. You should be certain which constructs and operators you want to provide. Constructs such as 'while', 'if', 'assignment statements' etc are common. So are operands such as +, -, *, / etc. You should write down the rules for your language. A set of rules for a language accepting assignment statements are given below.

assign_statement    : VAR EQUALS statement
statement           : statement ADDOP term
                    | statement SUBOP term
                    | term

term                : term MULOP factor
                    | term DIVOP factor
                    | factor

factor              : VAR
                    | NUM
                    | LPAREN statement RPAREN

Throughout our discussion, we adopt the convention that words in upper cases (NUM, VAR, EQUALS, ADDOP, SUBOP, MULOP, DIVOP, LPAREN, RPAREN) are tokens and those in lower cases (assign_statement, statement, term, factor) are rules.

3.2 Token Definition and Recognition

Next, we have to define the tokens that we are using. In our example, we have used nine tokens - NUM, VAR, EQUALS, ADDOP, SUBOP, MULOP, DIVOP, LPAREN and RPAREN. The following program implements a simple lexer for tokenizing our language. [text version]

import lex

# List of token names. This is compulsory.
tokens = (

# Regular statement rules for tokens.
t_VAR           = r'[a-zA-Z_][\w_]*'
t_EQUALS        = r'='
t_ADDOP         = r'\+'
t_SUBOP         = r'-'
t_MULOP         = r'\*'
t_DIVOP         = r'/'
t_LPAREN        = r'\('
t_RPAREN        = r'\)'

# A regular statement rule with some action code.
def t_NUM(t) :
         t.value = int(t.value)
    except ValueError:
         print "Line %d: Number %s is too large!" % (t.lineno, t.value)
    t.value = 0
    return t

# Define a rule so that we can track line numbers.
def t_newline(t):
    t.lineno += len(t.value)

# A string containing ignored characters (spaces and tabs).
t_ignore  = ' \t'

# Error handling rule
def t_error(t):
    print "Illegal character '%s'" % t.value[0]

# Build the lexer

# Get the input
data = raw_input()


# Tokenize
while 1 :
        tok = lex.token()
        if not tok :
        print tok

                     If you want to include reserved words, it is usually
   easier to just match a variable name (identifier) and do a special
   name lookup in a function like this:
reserved = {
   'if' : 'IF',
   'then' : 'THEN',
   'else' : 'ELSE',
   'while' : 'WHILE',

def t_VAR(t):
    t.type = reserved.get(t.value,'ID')    # Check for reserved words
    return t

3.3 Parsing

Parsing is quite easy when we use The parser invokes the lexer for getting tokens. So we have to import the lex module that we had written earlier. Now, corresponding to each rule, we define a function and write the rule itself as a document. Within the function we can write the semantic actions needed to be taken. For our example language, the parsing can be done as shown below. [text version]

# Yacc example

import yacc

# Get the token map from the lexer that we defined
# earlier.  This is required.

from ourexlex import tokens

__var_names = {}

def p_assign_statement(t) :
    'assign_statement : VAR EQUALS statement'
    __var_names[t[1]] = t[3]

def p_statement_plus(t) :
    'statement : statement ADDOP term'
    t[0] = t[1] + t[3]

def p_statement_minus(t) :
    'statement : statement SUBOP term'
    t[0] = t[1] - t[3]

def p_statement_term(t) :
    'statement : term'
    t[0] = t[1]

def p_term_times(t) :
    'term : term MULOP factor'
    t[0] = t[1] * t[3]

def p_term_div(t) :
    'term : term DIVOP factor'
    t[0] = t[1] / t[3]

def p_term_factor(t) :
    'term : factor'
    t[0] = t[1]

def p_factor_num(t) :
    'factor : NUM'
    t[0] = t[1]

def p_factor_var(t) :
    'factor : VAR'
    if __var_names.has_key(t[1]) :
        t[0] = __var_names[t[1]]
    else :
        print "Undefined Variable", t[1], "in line no.", t.lineno(1)

def p_factor_expr(t):
    'factor : LPAREN statement RPAREN'
    t[0] = t[2]

# Error rule for syntax errors
def p_error(t):
    print "Syntax error in input!"

# Build the parser

while 1:
       s = raw_input('enter > ')
   except EOFError:
   if not s: continue

Here each function accepts a single argument, t, which is a tuple. The values of t[i] are mapped to grammar symbols as shown here:

def p_statement_plus(t):
    'statement : statement ADDOP term'
    #   ^            ^        ^    ^
    #  t[0]         t[1]     t[2] t[3]

    t[0] = t[1] + t[3]

3.4 Semantic actions

The semantic actions are the steps that the parser takes when it reduces the input to a particular rule. In our example above, the actions correspond to that of an interpreter. For a simple compiler, the semantic action may be to produce the assembly code corresponding to a rule.

Suppose you want to produce 8086 assembly instructions as output. Let us assume that 'bx' is a temporary register. Now, whenever we see an operand, we store the contents of the accumulator in the temporary register, and store the operand itself in the accumulator. Thus, the last seen operand (or the result of an evaluation) will always be in the accumulator.

def p_factor_num(t) :
    'factor : NUM'
    __output_fp.write("\tmov bx,ax\n"%f)      # bx <-- [ax]
    __output_fp.write("\tmov ax,0x%x\n"%t[1]) # ax <-- t[1]

   where, '__output_fp' is a file pointer to an output file

Since the operands of an operation (be it binary or unary) is now available, we can write the semantic action for adding as :

def p_statement_plus(t) :
    'statement : statement ADDOP term'
    __output_fp.write("\tadd ax,bx\n")
 # ax <-- [ax] + [bx]

Similarly, whenever we see a new variable, we can allocate a register for the variable (a stack location is a better choice to store local variables), and remember the register allocated by using a dictionary. The variable name is the key and the register name is the value. Every time a variable name is referenced, the dictionary is searched using the name of the variable as key, to get the corresponding register name.

3.5 Optimization

For a C compiler, the assembly instructions are not produced so early as we have depicted here. Actually, it is the intermediate code that is produced. Then the intermediate code is optimized and finally the assembly code is generated.

Since, optimization is itself a vast topic, we will only discuss a simple optimization technique, namely peephole optimization. The easiest way to implement peephole optimization is to hand-code a particular assembly program and compare it with the code your compiler produces.

For example, if your assembly instruction set does not have an instruction for multiplying, then you can make your compiler produce code for multiplication by repetitive addition. A simple optimization that you can make here is this : if you have one operand as 1, then you can store the other operand as the result; instead of going for the repetitive addition, which will obviously be a loop. Again, since the multiplier determines the loop count, you can choose the lower of the two operands as the multiplier.

Another example for peephole optimization is in the use of jump's. Look at the following example :

            jmp .L1
.L1         jmp .L2

.L2         add ax,bx

Here, the first jump statement can be changed to reduce the number of jumps, as is shown below.


            jmp .L2
.L1         jmp .L2
.L2         add ax,bx

There are various algorithms for producing optimized codes. The methods discussed above are only the beginning steps towards complex time and space saving optimization techniques.

4. What next ?

The illustration that we have gone through is not a full-fledged compiler. To complete it, we need to implement more and more common constructs. It's only a matter of writing rules for the constructs, defining regular statement for every new token, writing parser functions for the grammar, and finally taking semantic actions in those functions.

Dinil Divakaran

I am a final year computer science student at GEC Thrissur, Kerala, in India.

Copyright © 2002, Dinil Divakaran.
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"

A Linux Fax Server for a Windows Network

By Pedro Fraile


The firm I work for had a fax system integrated in the corporate e-mail platform, Microsoft Exchange, for sending and receiving. One day after a software upgrade, the system broke. We needed to find something with the equivalent functionality but with the following conditions:

  • Minimum cost, or better still, no cost at all, especially regarding software licenses.
  • Transparent integration with the end user's software tools (basically Microsoft Office).
  • No need to install any software on the client side, even free software, in order to minimize the work load of the network administrators.

This article describes how the integration of several open source applications on a Linux platform has fulfilled all of these conditions.


I want to express my gratitude to various persons or organizations without whose assistant I would have never written this article. First, to the members of the IT department in the Solvay Química S. L. plant at Torrelavega, Spain. Second, to my firm's hierarchy for their approval and support of this article's writing. Last and most especially, to all the contributors to the Open Source projects mentioned throughout this text, to the participants in the HylaFAX mailing list (which have given me essential information) and to Craig Kelly, developer of the smbfax client tool.

System overview

To clarify which computer I'm talking about where, I'll refer to the PC where the fax software is installed as TOSERFAX.

The applied solution involves the HylaFAX software. This application controls the installed modems, distributes the incoming faxes and sends the outgoing ones.

The incoming faxes are converted to PDF format and forwarded via SMTP e-mail to their respective destinations. PDF was chosen because Acrobat Reader is part of the standard software platform at the site. The destination is ascertained via certain rules as will be later explained.

If someone wants to send a fax, he prints the document in a printer queue on TOSERFAX, which Samba makes visible to all the other computers. The print job will cause an e-mail to be sent to the user that has spooled the job. This e-mail includes the URL of a web form created on-the-fly in the Apache web server. The web form allows the user to fill in the fax details, particularly the destination phone number. Once the user has completed the form, upon clicking on the "Send" button, the fax is finally put on the outgoing queue.

Hardware and Software

TOSERFAX's hardware is the following:

  • PC Dell Optiplex GX150, running a 1 Ghz Pentium III processor, with 256 MB of RAM and a hard disk of 20 GB. The modems are 3Com US Robotics 56K Faxmodem.

As far as software is concerned:

  • The base system is the SuSE Linux 7.2 distribution. It includes HylaFAX version 4.1beta2, the Apache web server version 1.3.19 and the SMTP server sendmail version 8.11.3.
  • Samba version 2.2.3a.
  • Fax sending from the clients is implemented using the package smbfax, version 1.4.

HylaFAX installation and configuration

The installation of HylaFAX was carried out following the standard procedures, clearly explained in the documentation. The most delicate part is the modem configuration. HylaFAX does not include a template for the US Robotics 56K Faxmodem. However, a search in its mailing list provided the needed information, which resulted in the file /var/spool/fax/etc/config.ttyS0 (and config.ttyS1 for the second modem). The first of these files can be found here.

Receiving faxes

Our plant has several telephone numbers that are connected to fax machines. The telephone exchange can divert phone calls originally made to one extension to a different one. This feature makes it possible to centralize the reception of all faxes in TOSERFAX without any change in the phone numbers that are accessible to the public.

For example, suppose the Purchasing Department has 5550001 as fax number, while Logistics has 5550002. One of TOSERFAX's modems is connected to the internal extension 1700. The PBX diverts all incoming calls to 5550001 and 5550002 to the extension 1700, where TOSERFAX receives the fax.

But or course, the person that should receive the faxes to Purchasing is not the same one that should get the ones to Logistics. HylaFAX manages incoming faxes by way of the scripts faxrcvd and FaxDispatch, placed in /var/spool/fax/bin. The discrimination we want requires knowledge of the fax number the fax was originally sent to, which is not known in the standard version of faxrcvd. A workaround is to recover that number from the session log, assigning it to a variable, for instance TOPHONE.

	TOPHONE=$($AWK '/SESSION BEGIN/ {print $NF; exit}' log/c${COMMID})

The new versions of faxrcvd and FaxDispatch can be found here and here.

The standard version of faxrcvd sends the fax to the addressee as a postscript attachment in an e-mail. This is not the best option at my plant, as the standard PC does not include a postscript viewer. But it does include a PDF viewer, and postscript files can be converted to PDF.

However, here we run into a small problem, related to the sending of the e-mail message with the attached file. TOSERFAX uses as SMTP relay a Windows NT server running IIS version 4. For some reason that I have not been able to discover, this server could not distribute the e-mails with attachments created with faxrcvd.

The solution was to use the tool "metasend", included in the packages metamail 2.7.19. The scripts and succeed in sending the fax, previously transformed into PDF format, in a way that is acceptable for the SMTP relay. It is worth mentioning that these scripts invoke the tools tiff2ps and gs.

Sending faxes

There are several fax clients written to be used with HylaFAX, for multiple platforms. However, IT administrators at Torrelavega would rather avoid any software installation on the clients. The only operation at the site's PCs should be, at the most, the configuration of a network printer, and it should be made automatically by the end user himself, if possible.

Using a printer queue has the added advantage that any application that is able to print a document (that is, practically all applications) will be able to fax. In this respect, the fax solution described in this article is clearly superior to other proprietary systems installed in Microsoft Exchange, which only allow to send faxes generated by some applications, for instance those in the Microsoft Office suite.

The package smbfax, developed by Craig Kelly, fulfills the above mentioned requirement. The underlying idea is very clever: the client prints the document he wants to fax in a printer queue, configured in TOSERFAX with Samba, and which features a postscript printer. The printing provokes in fact the execution of a perl script, which puts the printed document into a file and sends the client an e-mail with an URL in it. This URL is a link to a web form created on the fly in the web server at TOSERFAX (Apache). The client clicks on the URL, fires the browser and, using the web form, fills in the number or numbers the fax should be sent to, chooses whether a cover page should be added, and other details. Finally, upon clicking on the "Send" button, the fax is put in the outbound queue. In case there is any error processing the job, the client will equally be notified by e-mail. Obviously, this system requires knowing the identity of the user who is faxing (it must be possible to get the authentication credentials he have acquired upon logging in the Windows PC) as well as his e-mail address.

The installation of smbfax is straightforward. The package documentation clearly explains the different steps, and repeating them here would just be redundant.

Configuring Samba, on the other hand, does show some interesting tricks. The pertinent file can be seen here. The following lines must be emphasized:

	workgroup = DOM
	netbios name = TOSERFAX
	security = DOMAIN
	winbind uid = 10000-20000
	winbind gid = 10000-20000
	template homedir = /home/win/%D/%U
	winbind separator = +
	printer admin = @DOM+PRINTADMIN

	path = /etc/samba/printers/
	browseable = yes
	read only = yes
	write list = @DOM+PRINTADMIN,root

# The fax queue is configured in this section 
	comment = Fax queue
	path = /tmp
	printable = Yes
	writable = no
	create mode = 0700
	guest ok = no
	postscript = Yes
	printing = lprng
	print command = /usr/local/smbfax/smbfax -r queue %u %s
	lpq command = /usr/local/smbfax/smbfax show
	lprm command = /usr/local/smbfax/smbfax dequeue %j

As a Samba server, TOSERFAX is included in a Windows 2000 domain (Active Directory). Samba version 2.2.3 features support for "winbindd", which provides client authentication based on the credentials obtained upon starting a session in the domain. As a consequence, to create the Windows users in the Linux box is no longer needed. Each client that connects for the first time to the Samba server will be identified by the combination <Domain name>+<User name>, and will earn an "uid" in the range 10000 - 20000. Inside the [fax] section, the line

	print command = /usr/local/smbfax/smbfax -r queue %u %s

invokes the program smbfax passing in the parameter %u the name of the user, identified as previously explained.

Inside the [global] section, the line

	printer admin = @DOM+PRINTADMIN

gives administrative rights on the printer queues to all members of the PRINTADMIN group in the NT domain DOM. These users will be able to configure printers, install drivers (for different Windows versions) and grant printing rights to the domain users by means of the standard remote administrative tools which are present in an NT or Windows 2000 box, and that use Remote Procedure Calls (RPC). And all this in a transparent way, without being aware that the printer server is not really a Windows box, but a Linux one.

The members of the DOM+PRINTADMIN group must of course have been granted write access to the path /etc/samba/printers. This is achieved by establishing the necessary permissions in the Linux filesystem:

       $ chown -R DOM+PROWNER:DOM+PRINTADMIN /etc/samba/printers
       $ chmod 0775 /etc/samba/printers

Driver installation is an especially interesting feature. It is possible to install at TOSERFAX the drivers of a postscript printer for all Windows versions that are used at the site: 95, NT and 2000. Once this work is done, any client that connects to the printer queue for the first time will be able to auto-install the needed drivers. We achieve therefore one of the goals of the network administrators: no configuration work needed on the client side.

Additionally, any member of the PRINTADMIN group may restrict access to the printer queue, using the NT access control lists (ACL).

The only question still unanswered is how to reach by e-mail the users that want to send a fax. Thanks to winbindd the user has been authenticated, but, which is the e-mail account? Lacking a way to read this information from the Active Directory, maybe using OpenLDAP, the solution is to manually add to the "aliases" file the list of possible fax users, with their e-mail addresses


and so on. Execute "newaliases" and the system is ready.

System maintenance

Once each and every component is configured, the last thing to do is to automate some basic housekeeping tasks. This is easily fulfilled adding to /etc/crontab the following lines:

0 21 * * * root test -x /usr/sbin/faxqclean && /usr/sbin/faxqclean

25 23 * * * root test -e /usr/sbin/faxcron && sh /usr/sbin/faxcron | mail faxmaster

Beware though that the HylaFAX package included in SuSE 7.2 leaves faxcron in /etc/cron.daily. Therefore, you will have to move it to apply the proposed scheme.


The combination of HylaFAX, Samba, smbfax and other open-source packages on a Linux system has allowed to integrate an efficient centralized fax service in a Windows environment, realizing the expectations of the IT managers, especially the lack of additional software installation on the client side.

Pedro Fraile

I first met a computer around 1982, and unless my memory deceives me, it was a Z 80 model. I discovered Linux in 1998, and very soon this OS took hold of my domestic PCs. Computers and programming are among my favorite hobbies.

Copyright © 2002, Pedro Fraile.
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"

Writing Your Own Toy OS (PART II)

By Krishnakumar R.

Part I was published in April.

The next thing that any one should know after learning to make a boot sector and before switching to protected mode is, how to use the BIOS interrupts. BIOS interrupts are the low level routines provided by the BIOS to make the work of the Operating System creator easy. This part of the article would deal with BIOS interrupts.

1. Theory

1.1 Why BIOS ?

BIOS does the copying of the boot sector to the RAM and execution of code there. Besides this there are lot of things that the BIOS does. When an operating system boots up it does not have a video driver or a floppy driver or any other driver as such. To include any such driver in the boot sector is next to impossible. So some other way should be there. The BIOS comes to our help here. BIOS contains various routines we can use. For example there are ready made routines available for various purposes like, checking the equipments installed, controlling the printer, finding out memory size etc. These routines are what we call BIOS interrupts.

1.2 How do we invoke BIOS interrupts ?

In ordinary programming languages we invoke a routine by making a call to the routine. For example in a C program, if there is a routine by name display having parameters noofchar - number of characters to be displayed, attr - attribute of characters displayed is to just to call the routine that is just write the name of the routine. Here we make use of interrupts. That is we make use of assembly instruction int.

For example for printing something on the screen we call the C function like this :

display(noofchar, attr); 

Equivalent to this, when we use BIOS, we write :

int 0x10

1.3 Now, how do we pass the parameters ?

Before calling the BIOS interrupt, we need to load certain values in prespecified format in the registers. Suppose we are using BIOS interrupt 13h, which is for transferring the data from the floppy to the memory. Before calling interrupt 13h we have to specify the segment address to which the data would be copied. Also we need to pass as parameters the drive number, track number, sector number, number of sectors to be transferred etc. This we do by loading the prespecified registers with the needed values. The idea will be clear after you read the explanation on the boot sector we are going to construct.

One important thing is that the same interrupt can be used for a variety of purposes. The purpose for which a particular interrupt is used depends upon the function number selected. The choice of the function is made depending on the value present in the ah register. For example interrupt 13h can be used for displaying a string as well as for getting the cursor position. If we move value 3 to register ah then the function number 3 is selected which is the function used for getting the cursor position. For displaying the string we move 13h to register ah which corresponds to displaying a string on screen.

2. What are we going to do ?

This time our source code consists of two assembly language programs and one C program. First assembly file is the boot sector code. In the boot sector we have written the code to copy the second sector of the floppy to the memory segment 0x500 ( the address location is 0x5000). This we do using BIOS interrupt 13h. The code in the boot sector then transfers control to offset 0 of segment 0x500. The code in the second assembly file is for displaying a message on screen using BIOS interrupt 10h. The C program is for transferring the executable code produced from assembly file 1 to boot sector and the executable code produced from the assembly file 2 to the second sector of the floppy.

3. The boot sector

Using interrupt 13h, the boot sector loads the second sector of the floppy into memory location 0x5000 (segment address 0x500). Given below is the source code used for this purpose. Save the code to file bsect.s.


entry start
        mov ax,#LOC1
        mov es,ax
        mov bx,#0 

        mov dl,#0 
        mov dh,#0 
        mov ch,#0 
        mov cl,#2 
        mov al,#1 

        mov ah,#2 

        int 0x13

        jmpi 0,#LOC1

The first line is similar to a macro. The next two statements might be familiar to you by now. Then we load the value 0x500 into the es register. This is the address location to which the code in the second sector of the floppy (the first sector is the boot sector) is moved to. Now we specify the offset within the segment as zero.

Next we load drive number into dl register, head number into dh register, track number into ch register, sector number into cl register and the number of sectors to be transferred to registeral. So we are going to load the sector 2, of track number 0, drive number 0 to segment 0x500. All this corresponds to 1.44Mb floppy.

Moving value 2 into register ah is corresponds to choosing a function number. This is to choose from the functions provided by the interrupt 13h. We choose function number 2 which is the function used for transferring data from floppy.

Now we call interrupt 13h and finally jump to 0th offset in the segment 0x500.

4. The second sector

The code in the second sector will as given below :

entry start
        mov     ah,#0x03                
        xor     bh,bh
        int     0x10

        mov     cx,#26                  
        mov     bx,#0x0007              
        mov     bp,#mymsg
        mov     ax,#0x1301              
        int     0x10

loop1:  jmp     loop1

        .byte  13,10
        .ascii "Handling BIOS interrupts"
This code will be loaded to segment 0x500 and executed. The code here uses interrupt 10h to get the current cursor position and then to print a message.

The first three lines of code (starting from the 3rd line) are used to get the current cursor position. Here function number 3 of interrupt 13h is selected. Then we clear the value in bh register. We move the number of characters in the string to register ch. To bx we move the page number and the attribute that is to be set while displaying. Here we are planning to display white characters on black background. Then address of the message to be be printed in moved to register bp. The message consists of two bytes having values 13 and 10 which correspond to an enter which is the Carriage Return (CR) and the Line Feed (LF) together. Then there is a 24 character string. Then we select the function which corresponds to printing the string and then moving the cursor. Then comes the call to interrupt. At the end comes the usual loop.

5. The C program

The source code of the C program is given below. Save it into file write.c.

#include <sys/types.h> /* unistd.h needs this */
#include <unistd.h>    /* contains read/write */
#include <fcntl.h>

int main()
                char boot_buf[512];
                int floppy_desc, file_desc;

                file_desc = open("./bsect", O_RDONLY);

                read(file_desc, boot_buf, 510);

                boot_buf[510] = 0x55;
                boot_buf[511] = 0xaa;

                floppy_desc = open("/dev/fd0", O_RDWR);

                lseek(floppy_desc, 0, SEEK_SET);
                write(floppy_desc, boot_buf, 512);

                file_desc = open("./sect2", O_RDONLY);
                read(file_desc, boot_buf, 512);

                lseek(floppy_desc, 512, SEEK_SET);
                write(floppy_desc, boot_buf, 512);

In PART I of this article I had given the description about making the boot floppy. Here there are slight differences. We first copy the file bsect, the executable code produced from bsect.s to the boot sector. Then we copy the sect2 the executable corresponding to sect2.s the second sector of the floppy. Also the changes to be made to make the floppy bootable have also been performed.


You can download the sources from

  1. bsect.s
  2. sect2.s
  3. write.c
  4. Makefile
Remove the txt extension of the files, and type
at the shell prompt or you can compile everything separately. Type
as86 bsect.s -o bsect.o

ld86 -d bsect.o -o bsect
and repeat the same for sect2.s giving sect2. Compile write.c and execute it after putting the boot floppy in to drive by typing :
cc write.c -o write

7. What Next?

After booting with the floppy you can see the string being displayed. Thus we will have used the BIOS interrupts. In the next part of this series I hope to write about how we can switch the processor to protected mode. Till then, bye !

Krishnakumar R.

Krishnakumar is a final year B.Tech student at Govt. Engg. College Thrissur, Kerala, India. His journey into the land of Operating systems started with module programming in linux . He has built a routing operating system by name GROS.(Details available at his home page: ) His other interests include Networking, Device drivers, Compiler Porting and Embedded systems.

Copyright © 2002, Krishnakumar R..
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"

The Foolish Things We Do With Our Computers

By Mike "Iron" Orr

By Andrei Vrincianu

A friend of mine lent me an old 40 MB HDD -- a real old one, weighted about a quarter kilogram (half a pound), real bulky -- as I needed to carry some files home from college. The "upload" went fine (slow, but fine). The "download", on the other side, didn't go that smooth... Well, you know, the common procedure, grab an IDE and an power cable, firmly push the connectors into the slots and then...power up Mr. Spock :).

Well, not quite. When I "carefully" inserted the power cable, one of the connectors to the HDD's board broke. What the heck, I thought, it's an old thingie, you should expect such a thing to happen. After the required soldering, I re-plugged everything, turned on the power and took a seat, waiting for the "Press DEL to enter setup" message to show up. Actually, the first thing that showed up was not the message, but smoke. Not from the connector, but from one of the resistors on the HDD board, that heated up so badly that it actually fell off. It had the time to do so because I didn't see the smoke first and only reacted to the sound of the resistor hitting the metal case. Luckily, nothing else got fried.

That was the last time I ever touched a soldering iron.

Morale of the story:

  1. Never let smoke out of circuits for they will malfunction.
  2. When you see smoke, push the ON/OFF button instead of trying to pull out the main 220V power cable, as I did (in panic). It takes 2-3 seconds less.

Andrei Vrincianu,

[If you have a story about something foolish or ingenious you did to your computer, send it to]

Mike Orr

Mike ("Iron") is the Editor of Linux Gazette. You can read what he has to say in the Back Page column in this issue. He has been a Linux enthusiast since 1991 and a Debian user since 1995. He is SSC's web technical coordinator, which means he gets to write a lot of Python scripts. Non-computer interests include Ska/Oi! music and the international language Esperanto. The nickname Iron was given to him in college--short for Iron Orr, hahaha.

Copyright © 2002, Mike Orr.
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"

Improving Hard Disk Performance with hdparam

By Piter Punk
Translated from the Portuguese by William N. Zanatta

Nowadays the IDE devices already have a high transfer rate (by UltraDMA technology), but there are still other ways to improve your hard-disks performance and we'll show how to do it with the hdparm utility.

1. Introduction

hdparm is an utility which provides us a powerful tunning control over HDs (HD PARaMeters) and this is what we'll be discussing in this document. Sometimes your HD is set not to use its maximum power as it could and that's why you may get anoyed with its performance. With hdparm we can magically change this to reach its maximum performance using all of its features.

2. Looking the hard disk

The first thing to do, is to gather all information about your hard drive and the current settings. These information will be used as a base for us while configuring the hard disks. Be extremely careful in all the steps you take because any misconfiguration may damage your disk partially (data) or entirely (hardware).

By now, lets assume /dev/hda as our disk. Take the command:

      darkstar:~$ hdparm -i /dev/hda

You should get some info like:


    Model=QUANTUM FIREBALLlct20 20, FwRev=APL.0900, SerialNo=552114732078
    Config={ HardSect NotMFM HdSw>15uSec Fixed DTR>10Mbs } 
    RawCHS=16383/16/63, TrkSize=32256, SectSize=21298, ECCbytes=4 
    BuffType=DualPortCache, BuffSize=418kB, MaxMultSect=8, MultSect=off
    CurCHS=16383/16/63, CurSects=-66060037, LBA=yes, LBAsects=39876480
    IORDY=on/off, tPIO={min:120,w/IORDY:120}, tDMA={min:120,rec:120} 
    PIO modes: pio0 pio1 pio2 pio3 pio4 
    DMA modes: mdma0 mdma1 mdma2 udma0 udma1 udma2 udma3 udma4 *udma5 
    Drive Supports : ATA/ATAPI-5 T13 1321D revision 1 : ATA-1 ATA-2 ATA-3
    ATA-4 ATA-5

But, you may ask yourself "What the hell is this?". Heah, don't be afraid this information will make you happy soon. Here we have many important and useful information...let's look at some:

Another command issued to get other information is:

      darkstar:~$ hdparm /dev/hda

This one brings:

     multcount = 0 (on) 
     I/O support = 0 (16-bit) 
     unmaskirq = 0 (off) 
     using_dma = 0 (off) 
     keepsettings = 0 (off) 
     nowerr = 0 (off) 
     readonly = 0 (off) 
     readahead = 8 (on) 
     geometry = 2482/255/63, sectors = 39876480, start = 0

In a brief description...

If you didn't understand some of these don't get bored, you are not a dumb, and we will discuss them as you read this document. Some of these parameters are related to your hard drive hardware physically and not logically, soh you cannot change them unless you change the hardware (and if you do it, you will probably cry for damaging your hard disk and destroy all your data, =] ).

3. Device setup

And now...the show! We are going to setup our HD. REMEMBER: Mistakes during the setup process may damage your hard disk and all of its data. The information provided by 'hdparm -i ' now, is your driver. Follow them and you must not get any problems.

3.1. I/O Support

Well, unless you have a (E)ISA IDE interface card, the rest (PCI/VLB), all support 32bits mode. If your box is newer than a 486, probably you have a PCI IDE controller. If it's not, check for it...

The mode '3' only is needed for some chipsets. People often use mode '1' for best performance. We didn't find any info about mode '2' (supposed to be 16-bit sychronized).

3.2. MultSect or Multcount

This one is simple. Check your HD's MaxMultSect info for what you can do. We set our MultSect to 8 since our HD supports that, so...

	# hdparm -m 8 /dev/hda

Remember to change /dev/hda to YOUR device and '8' to the MaxMultSect supported by your hard disk as provided by 'hdparm -i '.

3.3 Activating DMA

The most simple of all. Simply type:

	# hdparm -d 1 

to set your DMA mode to ON. Your card must supportd the DMA mode.

3.4 PIO and DMA modes

You can set both of these using the same flag '-X'. This one, if not used with EXTREME care may eject your hard drive (BELIEVE IT!) and make it the first HD to arrive the Moon by itself. Set just the modes supported by your hard disk.

Hmm, it works like this...for normal DMA modes (multiword DMA or mdma), use -X32 + (DMA identifier number). For mdma2 it would be:

	# hdparm -X34 /dev/hda  // 32 + 2 (from mdma2)

For the PIO and UltraDMA modes the process is almost the same. The difference is that the base number for the PIO modes is 8 and for the UltraDMA modes it is 64. The hard disk used while writing this document supports ATA100, so it was put in udma5 mode using:

	# hdparm -X69 /dev/hda

Keep in mind that the highest DMA modes are available just for some chipsets.

The ATA66 and ATA100 modes requires a 80-way IDE cable. Think that put you disk in ATA100 without these cables will not work.

3.5 Readahead

The option readahead IS NOT the same as multcount. The multcount refers to the possibility of the hardware to read more than one sector at a time while the readahead option is the number of sectors ahead your computer should read. The readahead feature is great when reading big-size files but it brings down the performance for short-size files. A good idea is to leave the value of readahead the same as the multcount so it will not be needed to make more than an access per time to read more sectors ahead.

If you are going to access big files you can set the readahead to a greater value. The default value is 8 sectors/read access (something like 4kb).

Now the syntax:

	# hdparm -a N /dev/hda 

N is the number of sectors for readahead.

4. Final comments

There are many other features you can set using hdparm. Most of them are covered in the hdparm manpage. These ones we covered are just the most common.

The configuration will be reset when you reboot your machine (the keep settings will not work as it covers just soft reboots). Put the commands in your rc.local (maybe, for large configuration, it would be a good idead to have a rc.hdparm or something like this).

Any doubts on this documents can be sent to:

Problems with this translation can be sent to

Copyright © 2002, Piter Punk.
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"


By Jon "Sir Flakey" Harsem

[These cartoons are scaled down to fit into LG. To see a panel in all its clarity, click on it. -Editor (Iron).]


All Qubism cartoons are here at the CORE web site.

Jon "SirFlakey" Harsem

Jon is the creator of the Qubism cartoon strip and current Editor-in-Chief of the CORE News Site. Somewhere along the early stages of his life he picked up a pencil and started drawing on the wallpaper. Now his cartoons appear 5 days a week on-line, go figure. He confesses to owning a Mac but swears it is for "personal use".

Copyright © 2002, Jon "Sir Flakey" Harsem.
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"

Getting started with PIC 16F84 on GNU/Linux

By Jerry Sebastian

There was a time when you had to boot up a Microsoft operating system whenever you wanted to do a bit of hardware hacking. But that's not the case nowadays - there are free tools available to do development on all the major industrial microcontrollers - be it the Microchip PIC, Intel 8051, Motorola 68HC05, Atmel AVR, or whatever. In this document, I will describe how to get started with the PIC 16F84 on Linux.

2. Brief Description of PIC16F84

Peripheral Interface Controller 16F84 is the best suited middle range microcontroller available to a novice. PIC Microcontrollers are cheap and versatile. They support a lot of functionality on a single chip - 1024 bytes (14 bits long) of program memory, 68 bytes of RAM and 64 bytes of EEPROM memory (feel insufficient ? Well , it is more than enough). The 16F84 comes in 18-pin package and has 13 digital IO port pins. Internal to the chip, there is a timer and an interrupt controller. Apart from this, it supports In Circuit Serial Programming. Further documentation can be found at the official MicroChip site.

3. Hardware requirements

For writing the machine code onto the PIC, you need a burner hardware. A wide variety of programming circuits are available on the net, both simple and complex. Out of these the most common is the PIC programmer by David Tait.The circuit is simple and can be easily set up. For proper working of the circuit, you will need a d.c voltage supply of at least 15v.

4. Software requirements

4.1 Programmer

A GNU burner software for PIC, pp (Pic Programmer), is available which works with the above circuit. It is also written by David Tait. It can be downloaded from the PIC archive site . pp supports a wide variety of hardware other than the above circuit. The program memory of PIC supports only 1000 write cycles. pp is highly efficient and fast in the sense that it overwrites only the locations having codes that differ from those to be written. If the code is same, it doesn't rewrite the code into the memory.

Using the Pic Programmer

After making the binary of pp you need to do the following steps :

  1. Connect the hardware to the parallel port.
  2. Switch on the supply of the circuit.
  3. login in as root
  4. type export PPSETUP=3 . This is for telling pp that we are using the Classic Pic Burner circuit.

Now type pp. If everything is Ok and the hardware works,then pp displays a message Hardware detected OK. It also displays the options that can be given to pp during burning. Otherwise it enters into debugging mode.This is useful for debugging the hardware.

If everything is fine, you can now actually burn the machine code into the PIC.

Using the GNU PIC Assembler (gpasm)

The GNU PIC Assembler generates the machine code for the input assembly instructions. After assembling, it generates the machine code in the intel HEX format. This output code can be given as a direct input to pp.

gpasm can be downloaded from gputils which contains a lot of software for PIC family

5. Hello world !!!!

We will write our first program for blinking a group of LEDs (say 8). The LEDs are connected to the 8 pins of PORTB. So we need to configure them as output pins. Once we have configured PORTB as output port, then we can send 1's and 0's into the 8 bits of PORTB (which corresponds to the 8 LEDs) with a delay in between.

Use your favorite text editor (like vi or Emacs) for writing the assembly code. The first line of the assembly code should specify the micro-controller used (if you are using GPASM). Then we can start writing our code. The code for blinking the LEDs is as shown : [text version]

        list p=16f84            ;specify the micro controller used.
 f      equ     1
 porta          equ     0x5             ;specify the address of the ports
 portb          equ     0x6             ;
 Delay_i        equ     0xc             ;The first byte of RAM available.
 Long_Delay_i   equ 0xd
 tmp            equ     0xe

        goto Main
 ; The following subroutine makes a 1 ms delay for a clock of 4Mhz for the PIC.
        movlw 0xff
        movwf Delay_i
 L1     nop
        decfsz Delay_i, f
        goto L1
 ;      This subroutine produces a 1 sec delay( approx.).
        movwf tmp
        movlw 0xff
        movwf Long_Delay_i
 L2     call Delay
        decfsz Long_Delay_i, f
        goto L2
        movf tmp,w
 ;The following code configures all ports as output ports.
 ;If you want to configure a port as input port, change the
 ;corresponding bit to 1 in TRIS register.
 ;For eg.if you want to use port portb0-3 as input and all other as output
 ;pins, use instructions
 ;      movlw 0x0
 ;      tris porta
 ;      movlw 0x0F
 ;      tris portb
        movlw 0x0
        tris porta
        tris portb

        movlw 0xff
        movwf portb
        call Long_Delay         ;make a 1 sec delay between blinking.
        comf portb,f            ;complement portb
        goto L3


Save the file with .s extension. The code can be assembled by the typing the command gpasm filename.s . If no errors are reported, machine code will be available in the file filename.hex. Now type the following commands for burning the code.

$ export PPSETUP=3
$ pp -xp filename.hex

The option -x specifies we are using crystal oscillator in the circuit, and -p specifies that we want to enable the power up timer of PIC. Other commonly used options are :

       -e --- for erasing the program memory and eeprom memory
       -w --- for enabling the watchdog timer
       -v --- for verifying the code.
The following figure shows the hardware needed to run the program. [circuit.jpg]

So what are you looking for ? Start hacking with PIC;-)

Jerry Sebastian

I am a final year student doing my course in Electronics and Communication at Govt. Engg. College, Thrissur, Kerala, India.

Copyright © 2002, Jerry Sebastian.
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"

A Framework For Writing Application Servers In C++

By Rob Tougher

1. Introduction
2. Using the framework
2.1 Installing Expat
2.2 C++ classes provided by the framework
2.3 A simple server and client
3. Framework internals
3.1 XML
3.2 Networking code
3.3 Threading code
3.4 server class
3.5 client class
4. Conclusion
a. Files
b. References

1. Introduction

An application server is a program that provides services to other programs, usually over a network connection.

A simple example of this is a stock quote server. When I worked for a brokerage, we had a quote server that provided stock quotes for the 11 traders in our department. Each trader had a client program running on their machine, and whenever they needed quotes, the client program would contact the quote server and retrieve the necessary data.

In this article I am presenting a framework for writing application servers in C++. First I'll detail how to use the framework, and then I will explain the internal workings of the framework for the more curious readers. Hopefully by the end of this article you will be able to understand this code, and use it in your systems.

2. Using the framework

2.1 Installing Expat

Before you can use the framework, you have to install the Expat XML Parser. The framework uses XML to pass data between clients and servers, and utilizes the Expat library to parse this XML. The examples in this article were tested with version 1.95.2 of the parser.

2.2 C++ classes provided by the framework

There are four main C++ classes that the framework provides:

The request class represents a request that a client sends to a server. The class has a "name" property, and a collection of "params". You can loosely think of a request as a method call. The "name" property denotes the name of the method, and the "params" collection contains the arguments to the method.

The reply class represents a reply that a server sends to a client. It has a "value" property, and a collection of "errors". You can think of the reply class as a return value to a method call. The "value" property is the actual value returned from the method, and the "errors" collection contains any errors that the method might have generated.

The server class is the workhorse of the framework. You derive from this class to create a new server. It has two methods you are interested in - "handle_request", and "run". The "run" method puts the server into action, and begins accepting connections. The "handle_request" method needs to be overriden in your derived class, and gets called every time a client requests a service.

The last class, client, allows a client program to send a request object to a server. You pass the host and port to the constructor of the class, and then use the "send_request" method to send request objects to the server.

2.3 A simple server and client

Now that we went over the main C++ classes in the framework, we can take a look at a working example. The following two files implement a minimal server and client:

In simple_quoter_server.cpp we define a C++ class named "simple_quoter_server", and derive it from xmlrpc::server. We override the "handle_request" method, which gets called every time a client makes a request. If the ticker is "RHAT", we return its price in the "value" property of the reply object. If an error occurs, we add an error to the errors collection.

In simple_quoter_client.cpp, we create an instance of the xmlrpc::client class, create and configure a request object, and then send the request to the server via the "send_request" method.

3. Framework internals

3.1 XML

The framework uses XML to pass messages between clients and servers. The very first thing I did before writing any code was define exactly what the XML would look like for requests and replies. I came up with the following:

  // <request>
  //   <name></name>
  //   <params>
  //      <param>
  //         <name></name><value></value>
  //      </param>
  //   </params>
  // </request>
  // <reply>
  //   <return_value></return_value>
  //   <errors>
  //      <error></error>
  //   </errors>
  // </reply>

Next I had to learn how to use the Expat XML Parser. I found a great article on describing how to use expat, and I wrote the following class to encapsulate everything:

The node class represents a node in an XML document. You pass it an XML string via the "load_xml" method, it parses the string, and it creates an in-memory representation of the XML document. It has a collection of children nodes that you can query, so you can "drill-down" into the XML document. If you need the XML string, you can query its "get_xml" method.

Next I created two classes to represent the XML definitions I introduced above:

You'll notice that both classes have "get_xml" and "load_xml" members. The "get_xml" method returns an XML string containing the internal representation of the class, and the "load_xml" string loads that same string back into the class. The result is that these two classes can persist themselves to XML strings, and load these strings later on.

I did this so that the rest of the framework would not have to worry about XML at all. The client and server classes could use the "load_xml" and "get_xml" methods to generate the XML data they needed to send to eachother. You could actually change the implementation of these two methods to not use XML, and the client and server classes would still function properly.

3.2 Networking code

The framework uses the following three C++ classes to pass data back and forth over the network:

You can find an article describing these three classes in the January Issue of the Linux Gazette. The names of the classes have changed, but the implementations are still the same.

3.3 Threading code

The server class, which we will go over in a bit, uses multiple threads when accepting requests from clients. The following classes in the framework provide threading support:

The thread class represents a single thread of execution. The thread_group class represents a concept I borrowed from the Boost.Threads Library. Basically, if you only want to create one thread, you use the thread class. If you want to create more than one thread, you use the thread_group class.

Definitely check out the Boost site when you get a chance. Boost is a group of C++ enthusiasts that create cross-platform libraries. The special thing about it is that some of the Boost members are also C++ Standards Committee members. This basically means that the libraries you find on their site will be of top quality.

3.4 server class

The server class is defined and implemented in the following files:

Notice the "accept_thread" class at the top of the *.cpp file. Do you remember how I mentioned before that the "server" class was the workhorse of the framework? Well, I wasn't exactly telling the truth. All the server class does is create a bunch of "accept_thread" objects, and sits back and waits for them to finish.

Since the overloaded "()" operator of the "accept_thread" class performs all of the work, let's take a look at it. Its implementation does the following:

  1. accepts an incoming socket connection
  2. keeps reading data from that connection until the request terminator is reached
  3. loads the data into a request object
  4. calls the "handle_request" method of the server class, passing in the request object. Since this method is virtual, and you override it in your class, your class' method gets called, instead of the server class'.
  5. gets the XML string for the reply object that "handle_request" returns
  6. sends the XML string back to the client, followed by the reply terminator

That's basically it. It accepts a socket, handles the request, and closes the socket after sending back the reply.

3.5 client class

The client class allows you to send requests to a server. It is defined and implemented in the following files:

The "send_request" method performs the following steps:

  1. creates a socket connection to the server
  2. sends the XML for the request to the server, followed by the request terminator
  3. reads data until the reply terminator is found
  4. loads the XML reply string into a reply object
  5. returns that reply object to the caller

4. Conclusion

In this article I've presented a framework for writing application servers in C++. Hopefully I've explained it clearly enough so that you can use this code in your own systems.

a. Files

The following archive contains all of the files for this article:

You can extract and build the framework with these commands:

prompt$ gunzip app_server_c++.tar.gz
prompt$ tar -xf app_server_c++.tar
prompt$ cd app_server_c++
prompt$ make

b. References

Rob Tougher

Rob is a C++ software engineer in the NYC area. When not coding on his favorite platform, you can find Rob strolling on the beach with his girlfriend, Nicole, and their dog, Halley.

Copyright © 2002, Rob Tougher.
Copying license
Published in Issue 79 of Linux Gazette, June 2002

"Linux Gazette...making Linux just a little more fun!"

The Back Page

Happy Linuxing!

Mike ("Iron") Orr
Editor, Linux Gazette,

Copyright © 2002, the Editors of Linux Gazette.
Copying license
Published in Issue 79 of Linux Gazette, June 2002