...making Linux just a little more fun!

October 2004 (#107):


The Mailbag


HELP WANTED : Article Ideas
Submit comments about articles, or articles themselves (after reading our guidelines) to The Editors of Linux Gazette, and technical answers and tips about Linux to The Answer Gang.


Why let Gentoo fans get all the fun?

Tue, 28 Sep 2004 14:46:07 -0600
Heather Stern (The Answer Gang's Editor Gal)

This last issue we had an article about diving into Gentoo, and the response was great. What I'd like to see is some of you send us in some more great 2c Tips! about things that are specific to your favorite distribution, with a neat little description that describes why they're so handy.

People can spend hours surfing the man pages or reading the "get started guide" in their boxed product - but we all know that a lot of linuxers get started with a disc from friends and some simple enthusiasm. So... let's Make Linux A Little More Fun for them :)


Penguinus Advocat

Tue, 28 Sep 2004 15:03:07 -0600
Heather Stern (The Answer Gang's Editor Gal)

I'd love to see an article describing how a company really got interested in open source, a bit of the thought processes and internal changes that went with looking at it, considering if it worked for them. I believe such an article would be equally useful if it described why one didn't, or did, take it on in various departments, and how much of it the company was able to let in.

Obviously, how completely it worked out after implementation would be great to hear about. We see occasional tidbits of this sort of thing offered as "case studies" and so on, but rather few of them have more than a sound byte here and there from anyone who really lived through the changes, drove the meetings, pondered the legal entanglements and so on.

Contact articles@lists.linuxgazette.net if you've got something for us. Get whatever internal approvals you need, and if you decide to make $company anonymous, don't forget to sanitize tidbits like any IP addresses or partner companies you mention, too.


GENERAL MAIL


ACPI insight

Tue, 21 Sep 2004 08:56:18 -0500 (COT)
John Karns (The LG Answer Gang)

I just stumbled across something interesting (to me, anyway), while reading Groklaw. I had mentioned in a msg to TAG a while back that I was getting an boot time error msg on this Inspiron:

"Dell Inspiron with broken BIOS detected. Refusing to enable the local APIC."

That's with a 2.4 kernel. I had resigned myself to the fact that there was a flaw in the BIOS, while wondering why they had never bothered to fix such a problem in all of the BIOS revisions that Dell has issued for the machine.

I've noticed that the error is absent when I boot from a recent 2.6 kernel, so figured that there was something relevant and long standing in Linux ACPI support that had been fixed in 2.6 kernels. But now it seems that the kernel developers may have just discovered how to deal with Dell's (intentionally quirky) implementation of the standard. Actually, the whole Groklaw post was interesting, so I'll include it here, but the last paragraph is what my post is about. Note: the general theme of the thread is about trying to buy a Dell with Linux pre-loaded. For more more info see:

http://www.groklaw.net/article.php?story=20040918105850387

I was on a plane recently, sitting next to a guy who claimed to be a Dell senior sales VP. I mentioned I had bypassed Dell for a purchase a week or so before, because they don't support Linux. He acted surprised, and said I should visit their web site. I told him I had visited the site (and saw what PJ reported here); despite a claim to support Linux, it is almost impossible to buy a Dell machine with Linux.

He continued to act surprised. I told him to visit his own website from a customer POV and he'd see what I meant.

Don't trust Dell: they make nice machines, but they are on their knees for Gates. I put Dell in the same category as HP (broken ACPI (nonstandard), that they only tell Microsoft how to get around). 2+ years after Presario release, they have still not fixed it.

-- John Karns


Gentoo

Sun, 12 Sep 2004 14:46:07 -0600
Kevin Williams (kevin from bantamtech.com)

Mike,

I just read your article in Linux Gazette online on Installing Gentoo, and thought I could help with a few of the problems you have experienced.

If OpenOffice did not compile, you could try openoffice-bin.

I'm not sure if I can help with package documentation. There is good general documentation on how Gentoo-specific nuances work by following the "Docs" link from the top of the home page.

We moved a handful of his - and other Gentoo using readers' tips - into our 2c Tips section, so they're easier to search for. Thanks to everybody who wrote in, especially those of you who don't see your name in lights; many Tips were repeats, and we tried to take the best explanations. -- Heather

I hope these suggestions help. I have found the Gentoo documentation and the Forums to be infinitely helpful. Now this former Windows advocate compiles his own kernel on a regular basis including software RAID and bootsplash tweaks. It's addicting!

Enjoy,

Kevin


Installing Gentoo - 106 - notes :)

Sun, 12 Sep 2004 13:32:19 +0200 (CEST)
Klavs Klavsen (klavs from EnableIT.dk)

Hi Mike,

Nice to hear you tried out Gentoo :)

I wanted to ad a few comments to your article:

Some tips, too, but go see the 2c tips section for that. -- Heather

Whenever there's a problem, I've almost always found the answer by searching forums.gentoo.org - even though the search feature in phpBB does not work very well, when there's so many posts as in this case. I've written a small and easy howto, about how they could make it indexable by google (see http://klavsen.info/simpleurls ) but they haven't picked it up, even though I've written it to gentoo-dev. This unfortunatley means the forums, which are a true treasure of knowledge, goes unknown to many :(

If the problem isn't solved by searching/posting to forums, a post to bugs.gentoo.org usually quickly resolves it (if it's a bug ofcourse, but it you don't get an answer in the forums, it most usually is :)

All in all, a very important part of Gentoo, is the fact that besides, the great documentation, there's so many competent users in the forums and on the mailinglists, so getting help finding a solution (and learning a lot in the process) seems almost inevitable (if ones open for learning - Gentoo is IMHO not minded for people who does not want to learn how things really work - but just want something that "just works").

By using Gentoo I've learned a lot, that I can make good use of, with other distributions as well, so it is a good learning experience, not only in Gentoo - but also with Linux. This same thing is why the forums.gentoo.org should be google indexed, as the knowledge does not only apply to Gentoo.

-- Regards, Klavs Klavsen, GSEC


"Open Source Software - Sometimes you get more than you paid for."


Gentoo Installation

Fri, 10 Sep 2004 16:48:31 -0700 (PDT)
William Lutts (wilebill from yahoo.com)

Just saw your article on Gentoo Installation, by coincidence, just as I was in the process of giving up on my own install of Gentoo. Been working on it off and on all day, finally got the kernel compiled. Yeah, I did it manually. Think I got it right, although the manual does not look the kernel config I was running. Wonder why? (the latest .4 kernel, r9, just downloaded today.)

Then I noted that loading some of the kernel packages like the Nvidia packages may well drag in stuff I wanted excluded in the USE variable, so I should use the pretend option to see what might possibly go wrong. This made me feel dizzy, even dizzier as I looked at what still lies ahead. In my present ill-tempered state, I feel like making the snide remark that so far I have not done anything far as I can tell that a good installation script could not do.

Guess I'll go get something to eat, replenish my blood sugar, and then think about it. I am learning quite a lot ... probably good for me ... but ... what keeps occurring to me is, since I am doing all this the long way around, why am I not installing FreeBSD instead? Keeping in mind that I am starving and the question may not be rational:

Eh ... not putting you on the spot ... but in a sentence or two, why would I want to run Gentoo instead of FreeBSD, nevermind that one is Linux and one is Berkeley UNIX. And both Gentoo and FreeBSD seem to have outstandingly brilliant groups of people supporting them. Just curious.

And don't ask if I'm a man or a mouse! "Got any cheese, sir? Squeak! Squeak!"

Thanks for the counterpoint view, William. There's lots of people, and no need to do things just one way. For that matter ... this may be Linux Gazette, but those BSDers are fellow open source'rers too. (If this makes you wonder where their magazine is, dear readers, it's called DaemonNews - http://ezine.daemonnews.org and it's a good read.) -- Heather


[ERRATUM] How to make a stereogram

Fri, 10 Sep 2004 14:55:36 +0000
Leonardo Della Pietra (dpietra from physi.uni-heidelberg.de)

Hello,

A reader has written in with an erratum for the article on generating stereograms. I am forwarding it with his permission.

Kapil.

Hi, I'm learning Blender, and found your howto really nice. http://linuxgazette.net/104/kapil.html
Only : from stereograph I get the error message
initializing renderer...FAILED;
to have the stereogram stereograph needs another parameter: the texture width to use; it works by adding the option:
-w 64
Ciao, Leo


Tripwire

Tue 07 Sep 2004 20:45
Greg Bell (gregbell from znet.com)

Hi Barry,

Thanks for the article on tripwire in Linux Gazette.

Hi Greg,
First of all, thanks for the feedback. It's always good to know someone is reading the articles!
A fun and informative chat back and forth ensues... see this month's Answer Gang column for the juicy bits. -- Heather
Would you have any objections if I forwarded your e-mail and my response onto TAG (The Answer Gang)? Heather and the other editors use material from TAG to put together the one-cent tips, mailbag, etc. It's perfectly fine to say no.
Thanks again for the feedback,

no objections.

thanks again for the dialog.

We're very pleased you said yes, Greg. Thanks bunches! -- Heather

This page edited and maintained by the Editors of Linux Gazette
HTML script maintained by Heather Stern of Starshine Technical Services, http://www.starshine.org/

Published in Issue 107 of Linux Gazette, October 2004

More 2 Cent Tips!

See also: The Answer Gang's Knowledge Base and the LG Search Engine


Re: Upgrading KDE on SuSE 9.0 - A better way.

Jethro Cramp (jsc from rock-tnsc.com)

Jethro Cramp wrote:

Tom,

There is a much easier way to upgrade KDE using Yast2.

All you have to do is add the following directory to the Yast sources

ftp://ftp.suse.com/pub/suse/i386/supplementary/KDE/update_for_9.0/yast-source

To do this you use:

Yast2 --> Software --> Change Source of Installation --> Add FTP.

Then in Yast2 select "Install and Remove Software". The package selections will now have been updated to include all the packages in the updated kde. The packages for which a newer version than the one you have installed will appear in either red or blue (I can't remember which).

Select the packages you want to upgrade (no 'upgrade everything' button available I'm afraid). Let Yast2 sort out package dependencies for you and off you go.

Yast2 will then download, install and configure all the packages for you.

Bit like the extremely good apt that is available on Debian. apt4rpm is also available for SuSE if you'd rather have that flexibility.

If the download site is too slow an alternative one can be selected. Go to suse's site and find the list of ftp servers and choose an alternative.

All the best,

Jethro Cramp

Thanks! That's a piece of info I've been missing. I've been told that you can do it directly inside Yast, but couldn't figure out how. I'm going to forward your tip to the Answer Gang, so everybody can benefit.

Tom Brown.


Gentoo: packages website

Kevin Williams (kevin from bantamtech.com)

Gentoo must have other users who commented on the "packages.debian.org" web page, because Gentoo adopted the same thing a couple of months ago. http://packages.gentoo.org is a similar page where you can find lots of info including searching by category or name.

[Frodo] but I am the first to admit, it is not nearly as powerful as the Debian site.
[Robert Krig] There is a link to this on the main page. Although it is easily overlooked.


Gentoo: check your package versions

Robert Krig (rkrig from gmx.de)

If you want to know what version of a package you have installed, just open a terminal, and type

emerge -pv packagename

The -p tells portage to pretend to emerge and the -v tells it to be verbose about it. In effect this will show you the package version it would like to install, and next to it in brackets it will show which version of the package you currently have installed. It should also show you any dependencies that need to be upgraded in case there is a newer version. And of course the -v option will show you possible use flags.

Thanks to everybody who wrote in with this one :) -- Heather


Gentoo: searching with emerge

Robert Krig (rkrig from gmx.de)
emerge -s packagename

This will search for anything with "packagename" in its packagename, i.e. emerge -s mozilla would list mozilla, mozilla-bin, mozilla-thunderbird, mozilla-firefox, etc. You get the picture.

emerge -S packagename

will search the descriptions for the word specified, however this tends to take quite a while.


Gentoo: speedier emerge searches

Frank Rodolf (The LG Answer Gang)

Gentoo's package query tools (equery and qpkg) aren't complete. They'll list the files a package contains but several other features are marked "not implemented". There didn't seem to be a way to quickly see which version of a package is installed: something equivalent to "rpm PACKAGE" or "dpkg -l PACKAGE". "emerge search PACKAGE" does it, but it takes several seconds, and you have to page through other information and entries for any other packages the substring matches.

You might want to emerge app-portage/esearch - it provides about the same functionality as emerge search, but uses a search-index, which makes it a lot faster. (Of course, the index has to be built, which takes time, but can be done with a cronjob.)

Grtz,

Frodo


Gentoo: rpm fans, take heart!

Klavs Klavsen (klavs from EnableIT.dk)

If you are used to rpm - you can use the tool epm which emulates rpm's features. To list all packages installed (incl. versionnr.) do epm -qa. to list info of one package - do epm -qi packagename etc. etc. It even does the epm -V (verify md5sum etc. from install-time is still the same - ie. a "small intrusion detection" tool).


Gentoo: pointers about nvidia cards

Robert Krig (rkrig from gmx.de)

As far nvidia gfx cards are concerned, seems for some it works without a hitch, for others there seem to be problems. Although it seems to me that proportionally many more users have no trouble with nvidia cards than the ones that do.

Just a few pointers about nvidia cards under gentoo:

Whenever you recompile your kernel, you need to re-emerge nvidia-kernel AND nvidia-glx

you should then also always run

opengl-update nvidia

Also in the /etc/X11/xorg.conf file, in the "Device" section, the driver is called "nvidia" and not "nv". Xorg's nvidia driver is used if you define it as "nv", nvidia's binary driver is used if you define it as "nvidia".

Also, if you are using a 2.6 kernel, make sure that you dont have "4k stacks" option active. I think its somewhere in the basic kernel config. The default should be 8k stacks, and the nvidia drivers dont work well if at all with 4k stacks. This info should be displayed at the end of emerge nvidia-kernel.

On a little side note, ever since I've switched from xfree86 to xorg and from kernel 2.4 to 2.6.8, my framerate in Quake3 Urban Terror has increased by 20+-30+fps. Dont know if your a gamer, but I thought that was pretty cool.


Gentoo: samba

Robert Krig (rkrig from gmx.de)

As far as samba problems are concerned, have you tried using LinNeighborhood? Using that program, I have no problems mounting windows shares.

emerge LinNeighborhood

You mentioned that when you mount a samba share, then you are denied access. Have you tried accessing them as root? Still, in case you havent yet, try LinNeighborhood.

I have read somewhere that Window's samba implementation can be screwey depending on which version of windows it is. Some like scrambled passwords, some dont. I'm sure you can find more info on the net.

Windows 95 didn't even have the ability to encrypt its passwords, later 98 insisted on it (and wouldn't work without, unless you applied a patch to it). With other mswin versions your mileage may vary. "lanman compatibility" seemed to mean "mention the password twice on the wire, the really old way and whatever new way du jour" - so I recommend any mswin admins out there try to avoid that, you lose enough bandwidth as it is, and it doesn't really help samba any. -- Heather


Gentoo: genkernel

Robert Krig (rkrig from gmx.de)

A note on genkernel. It can be very screwey depending on your setup.

genkernel --menuconfig all

this command will allow you to make modifcations to the default genkernel setup. Although I would still recommend to everyone to compile your own kernel.

Building your own optimal kernel is not only a good way to learn more about linux but boot time usually feels a lot faster with generic support for things you don't even own left out entirely - since it never gets probed for anymore. Surely both knowledge and speed are a Good Thing for gentoo fans :) -- Heather


Gentoo: be careful updating!

Robert Krig (rkrig from gmx.de)

By the way. It is not recommended to blindly issue the "update all" portage command. Sometimes new stuff, can break some old stuff, and there have been plenty of cases where people simply did a emerge -u -deep world and found their system not working anymore. I find that the best way to update your system is to do a

emerge -upv -deep world.

This will show me which packages COULD be updated and then I just manually upgrade from there. Very handy if for example a newer version of an app has been ported from gtk to gtk2 or to qt or whatever, and you dont want to compile all this extra stuff.

Secondly, often enough when you update any packages, portage will tell you that you need to run etc-update in order to update the config files. Be VERY careful here as well. Since 90% of the time the only change to config file is to label it as "version x.x.x". However the process if not done carefully, will overwrite to specific config file with defaults. etc-update offers you options to manually select inside the file, what can be removed and what not, but its quite confusing to read. I would suggest, when it comes to etc-update, certain config files can be overwritten no problem, e.g. all the ones that you havent changed in any way. But always keep a current backup of all the configs that you edited. e.g. make.conf, smb.conf, rc.conf, lilo.conf, etc. I usually make copies, let etc-update overwrite them, and then manually copy+paste relevant stuff back into the new file. I'm sure there is a much better way to do this, and I recall that I read something about that in the forums. Either way, just letting you know to take care when etc-updating. But then again, I think its always wise not to blindly update everything as soon as it comes out. Unless its a much needed security fix.


Gentoo: who was that Masked package?

Robert Krig (rkrig from gmx.de)

Mike, in your article. You mentioned that the day before your install, KDE3.3 came out and it was still in the "masked" section.

Just to clear things up. Masked, does not automatically mean unstable, it also means "testing". More often than not apps in "masked" simply havent been tested enough. Doesnt have to mean that this package will definately fail to build or even crash once you use it. However sometimes you need to use an obscure app which hasn't been included in portage until recently, and the only version available is masked. Although sometimes it can happen that a dependancy required by the app is still masked. Usually I would say, stick to the main portage tree as much as you can. Recompiling small apps, once theyre moved from "masked" to "stable" shouldn't be too big of a deal.


Gentoo: unmasking

Klavs Klavsen (klavs from EnableIT.dk)

Using distcc is actually quite easy - one just has to ensure that if you use f.ex. hardened (stack smashing protection and friends) your gcc on all distcc machines (can even be a windows machine some of them) has to have the same abilities. You can even use distcc to do all the compiling on another machine, if you are installing on an older machine, it sometimes makes most sense to let someone else do the hard work :)

The /etc/portage/package.mask package.unmask package.use and package.keywords files you really should know about - they are great tools to make portage do exactly what you want. Say you thrust that newest releases of kde is stable enough for you to use (you can have several versions installed - so you can just select the on you want to use globally in /etc/rc.conf) you just add the kde packages to the package.keywords files. A search in the forums, will show you exactly what format to use :)


Gentoo: USE your own per-package options

Frank Rodolf (The LG Answer Gang)

USE="-X" emerge links

Later, after you've installed X, you simply "emerge links" again, and it will rebuild itself with the X support.

I realize you are using an example where you only temporarily set $USE, but it might be worth noting that one can also set specific options for separate packages, in a more permanent way, using /etc/portage/package.use.

In this file, one can put lines like these:

net-www/links -X
net-p2p/amule stats
x11-base/xorg-x11 -pie

Some other interesting files in that directory are package.mask, package.unmask and package.keywords. The last one is, btw, the preferred way to add experimental packages, while running stable mostly.


Gentoo: I did it MY way...

Kevin Williams (kevin from bantamtech.com)

The best way to implement a package differently than the package maintainer intended is to create a local overlay of the portage tree. This should be is the docs, but here's my quick notes:

  1. Uncomment the "PORTAGE_OVERLAY" option in /etc/make.conf
  2. mkdir -p /usr/local/portage/dev-php/php/files
  3. Copy /usr/portage/dev-php/php/php/php-<version>.ebuild to /usr/local/portage/dev-php/php - I suggest changing the build version or release number to identify your version
  4. Tweak the ebuild file
  5. Run 'ebuild /usr/local/portage/dev-php/php/php-<version>.ebuild digest'

Now, if you use "emerge -pv php" you should see your build and a notation that the ebuild is coming from the /usr/local/portage overlay location. The biggest problem with all this is that now you are a package maintainer but it's on your local system. Keeping your changes in sync with new ebuilds from Portage can be a hassle. It's a good idea to request a new USE flag for your desired ./configure arguments in http://bugs.gentoo.org and let the official package maintainer worry about it going forward.


Gentoo: share the load, build that code

Klavs Klavsen (klavs from EnableIT.dk)

Using distcc is actually quite easy - one just has to ensure that if you use f.ex. hardened (stack smashing protection and friends) your gcc on all distcc machines (can even be a windows machine some of them) has to have the same abilities. You can even use distcc to do all the compiling on another machine, if you are installing on an older machine, it sometimes makes most sense to let someone else do the hard work :)


Another Gentoo tidbit - revised boot ISO available

Brian Bilbrey (bilbrey from orbdesigns.com)

I'd seen people with problems a couple of times recently, but had no answer to the problem of non-booting but "good" (as in MD5SUM) images. It appears that the Gentoo folks came up with a possible solution, and did a respin of the 2004-2 minimal install ISO that was "rebuilt to solve the problem of certain buggy BIOS versions not booting the Minimal LiveCD."

If people write in with similar problems installing from the small Gentoo ISO images, we could do worse than point them in the direction of the revised image. Here's a link to such on one of the mirrors:

http://lug.mtu.edu/gentoo/experimental/x86/livecd/x86

Not every mirror carries the "experimental" part of the tree, here's a link to the list of mirrors:

http://www.gentoo.org/main/en/mirrors.xml

FYI,

.brian (who still hasn't found a way to add custom X-Headers to Thunderbird)


search google from command line

Raj Shekhar (rajshekhar from hotpop.com)

Hello all,

This is a ugly hack that I am using to search the google from command line. Any decent Python programmer would be able to make it much better. You need to have Pygoogle (http://pygoogle.sourceforge.net) module installed. In its unaltered form, the script will require Python2.3 to run. However, if you remove the #--ugly hack part (see the comments in the code), it will run with Python2.2 too.

#!/usr/bin/python2.3
import google,sys,codecs
from sgmllib import SGMLParser

# HTML Stripper class to strip out html from the google search
# returned.  shamelessly copy pasted from
# http://mail.python.org/pipermail/tutor/2002-September/017573.html

class HTMLStripper(SGMLParser):
     def __init__(self):
         SGMLParser.__init__(self)
         self._text = []

     def handle_data(self, data):
         self._text.append(data)

     def read_text(self):
         return ".join(self._text)"


def strip_html(text):
     stripper = HTMLStripper()
     stripper.feed(text)
     return stripper.read_text()

print "Searching the World Live Web "

google.setLicense('your google key') # must get your own key from
http://www.google.com/apis/ -> free but requires registration
n_show_results = 10 #change the number of search results that are shown
from here

codecs.register_error('xml', codecs.xmlcharrefreplace_errors)

search_str = ""
for i in range(1,len(sys.argv)):
     search_str = search_str + " " + sys.argv[i]

print "Searching for " ,search_str

data = google.doGoogleSearch(search_str,0,n_show_results)

print 'Search took %f time and I found a total of %d results\n' % \
	(data.meta.searchTime, data.meta.estimatedTotalResultsCount)

for result in data.results:

     # if you are going to call this script from within emacs, replace
     # this part with the code within the #begin hack -- #end hack code

     print 'Title\t:', strip_html(result.title)
     print 'URL\t:', result.URL
     print

     #-- begin hack

     # if you want to call this script from within emacs, then you have
     #to put in this ugly hack. Other wise emacs will stop with an
     #error message "UnicodeEncodeError: 'ascii' codec can't encode
     #character u'\xfc' in position 1: ordinal not in range(128)"

     # see  http://www.informit.com/articles/article.asp?p=31272&seqNum=5
     # to know why this ugly hack is needed

##     temp = result.title
##     in_tuple=codecs.getencoder('ASCII')(temp, 'xml')
##     in_str = str(in_tuple)
##     print 'Title\t:', strip_html(in_str)
##     print 'URL\t:', result.URL
##     print
     #-- end hack

print "\n "




Raj Shekhar
System Administrator, programmer and slacker


Re: Upgrading a KDE Install article

R. (p0z3r from earthlink.net)

Mr. Brown:

I read your article on upgrading to kde 3.3 today. The reason I'm mailing you is because I'm one of the developers for Superkaramba. I noticed your article mentioned that the Superkaramba widgets are "always on top". This has been resolved in the latest release, 0.34, and in CVS, with our pending release of 0.35. You would need to recompile for KDE 3.3, as the code needed for the two versions are different and detect your version upon compilation.

Thanks,
-Ryan Nickell

ps. Here's a link to our FAQ:
http://www.superkaramba.com/faq.html


This page edited and maintained by the Editors of Linux Gazette
HTML script maintained by Heather Stern of Starshine Technical Services, http://www.starshine.org/

Published in Issue 107 of Linux Gazette, October 2004

The Answer Gang

Linux Gazette 107: The Answer Gang (TWDT) The Answer Gang 107:
LINUX GAZETTE
...making Linux just a little more fun!
(?) The Answer Gang (!)
By Jim Dennis, Karl-Heinz Herrmann, Breen, Chris, and... (meet the Gang) ... the Editors of Linux Gazette... and You!


We have guidelines for asking and answering questions. Linux questions only, please.
We make no guarantees about answers, but you can be anonymous on request.
See also: The Answer Gang's Knowledge Base and the LG Search Engine



Contents:

¶: Greetings From Heather Stern
(?)I love Linux
(?)Reading/writing large buffers to Fibre Channel
(?)cannot talk using "talk"
(!)Tripwire

(¶) Greetings from Heather Stern

Greetings, everyone, and welcome once again to the world of The Answer Gang.

I had plans for this month on a wonderful blurb about the nature of advocacy in the linux world.... by which I really mean, not just how you get one person here or there introduced to the time of their life and being in more control of their personal computer than they ever had before with The Beast From Redmond, but how you generally behave so as not to make the average person who is willing to chat computers because "hey you look like a techie, I was wondering...?" think "gawd, I don't want to be like or deal with these kind of people, Linux must make them crazy."

Yet I find it's just as important to consider how to behave inside your local user group. New people drop into these places. Do they see a batch of people having a great time yakking about xine versus mplayer and whether nvidia frame rates make you dizzy now that you've installed the driver? Or do they see people playing "my distro's better than yours" games that rival the recent political "debates" and make everyone look like control freaks? They look at whatever they find, and sure, they're going to ask their questions about the lil' penguin and his OS, but they are also thinking to themselves, is this going to be fun for me?

This is October, and in past years there's been tons of fuss on "Halloween" documents. Leaks and spooky measures to rival the cigar filled rooms cough cough of an earlier era. What sort of light does this put on us? I'd rather see Tux as the defender of freedom than the whisperer among spooks. But people are spooked by all sorts of things these days.

Be good to each other, people. Have a good month.


(?) I love Linux

From Jason Creighton

Answered By: Thomas Adam, Ben Okopnik

I wanted a photo off my parent's digital camera. They have Windows ME. I don't know if ME's USB support is seriously flaky or what, but only one USB device has even worked consistently with that computer (a scanner).

Windows was hanging on me, not working, making me mad and in general doing the things it's good at.

Enter Linux. I install libusb, libgphoto2, and gphoto2. I compile the usbcore module[1], and then try to use gphoto2. It can't see the camera. I fiddle with things awhile, and it "doesn't work".

Had I read Crux's (my distro) README for libusb more carefully, I would have seen I need usbfs. Enable that option, recompile the kernel modules, install 'em, modprobe, and IT WORKS! I can download photos, and it just works. No need to use some stupid kludged-up vender-enforced GUI.

(!) [Ben] Wow, nice. Took me several net searches and a good bit of luck - I ran across exactly one discussion of this, but it was exactly what I needed, including the fine details. This was, in fact, the first time I ever got a USB-to-camera connection to work with Linux (not that I'd tried a whole lot of times previously, but it was once or twice at least over a couple of years.) I'd never seen any standard documentation for it, and kudos to the Crux folks for writing it.

(?) I love Linux.

[1] I have an uptime of 35 days, which is the longest I've managed to get between me wanting to try new kernels, the efforts of the power company and well-meaning family members.

So I really didn't want to compile a new kernel and have to reboot. So I just added the usb kernel module to my kernel config, did a "make modules && make modules_install"[2] and modprobe'd the modules into the running kernel, which is the same version and was built from the same source-tree[3]. Is that a good idea? I mean, everything appears to work fine, but will enabling a module ever require you to rebuild the kernel itself?

(!) [Thomas] No, not unless the module relies on an option that you need to statically compile into the kernel and have not already done so -- an isolated case, so you should be fine.
As to whether it is a good idea, module loading works by looking at the module's symbol information, which matches the version of your current running kernel. If the version of the module is the same as `uname -r`, then it will load quite happily, whether it was compiled at the same time as the kernel or ten months afterwards.
But what also happens is that the compiler versions that were used to compile the kernel, and the new modules have to match exactly. If they don't, then loading the module(s) simply will not work.
(!) [Ben]
Since you specified "ever", the answer is "yes". But far from always. If, for example, you were to enable the entire Ethernet category (which had been disabled in the last compile), build some driver modules, and attempt to laod them, I can just about guarantee failure; the running kernel would be missing the "hooks" for the whole Ethernet category. However, if the category had been enabled previously and you just added a specific card driver to the ones that you'd compiled previously, chances are high that you wouldn't need to reboot. Either way, there's no harm in trying; in the worst case, you'll get a whole bunch of "Undefined symbol" messages when you try to load the module.

(?) [2] It occurs to me as I write this that I could have typed "make modules modules_install" but oh well.

(!) [Ben] Yup. Note that with 2.5 and above, there's no need to do "modules"; it's part of "make". My preference, if I was going to do the above, is to go ahead and run "make", then "make modules_install install"; that way, if the module does fail to load, all I do is "sudo reboot".
[3] Correct term? I mean, I extracted the linux-2.4.20 tarball to /usr/src, and I built these modules from that as well as the kernel I'm running now.
(!) [Thomas] Correct term. You should also run 'depmod -a' after the modules_install part so that the kernel knows of their existence properly.

(?) Reading/writing large buffers to Fibre Channel

From Jimen Ching

Answered By: Jimmy O'Regan

Hi TAG,

I have a problem of reading and writing very large (4MB) buffers to a disk via Fibre Channel. Fibre Channel works best when you send large amounts of data over the wire (light).

I've done google searches and found approaches like O_DIRECT and mmap. Mmap doesn't sound like what I'm looking for, because it still uses the buffer cache. And with 4MB of data, I don't want the extra copy. Also, I won't be reading the data back from the disk. So the buffer cache doesn't buy me anything...

The O_DIRECT approach sounds better. But it requires aligned buffers, and some people say the throughput is worst than non-O_DIRECT. My target throughput is 95MB/s. This shouldn't be a problem for the hardware since I'm using the CompactPCI bus and SCSI RAID over Fibre Channel with theoretical throughput of 150MB/s. The aligned buffers issue is only a problem because of the file header that I must prefix to the 4MB raw data. It would be preferable if I didn't have to align my buffers. But I can work around it if it is absolutely necessary.

I've done some basic benchmarks using regular fopen/fread/fwrite, and I'm only getting 50MB/s with ext3fs. This is half the throughput I need and 1/3th the theoretical throughput of the hardware. So I was wondering if your team has come across any ideas on how to solve this problem. Note, I'm not setting any special options. So this benchmark is just the baseline. I'm looking for ways to optimize the reading and writing of this 4MB data buffer.

(!) [Jimmy] If you have enough RAM, try using a ramdisk - create a filesystem as usual, but on one of the ramdisk devices - /dev/ram* or /dev/rd/*
The ramdisk will be 4M by default, but if you have it compiled as a module you can specify the size as an option to insmod:
insmod rd rd_size=20000
(which sets it as 20M) or as an option in /etc/conf.modules
options rd rd_size=20000
(!) [Thomas] Note that it used to be the case that /etc/conf.modules was synmlinked to /etc/modules.conf . On many systems this is not usually the case anymore, and so /etc/modules.conf is generally the prefered location.
(!) [Jimmy] If your ramdisk support is compiled into the kernel, you'll need to set the size at boot. You can append the option (in LILO, or as a boot option) like this:
ramdisk_size=20000

(?) I'm not sure I understand the answer. Or maybe I didn't explain my question clearly.

(!) [Jimmy] No, I the misunderstanding was on my part. I was simply answering this: "I'm looking for ways to optimize the reading and writing of this 4MB data buffer."

(?) I want to write raw data to a disk via Fibre Channel. Each block of raw data is 4MB large. I need to write 95MB/s of data for about half an hour or so. 95MB/s, at 60 sec per minute, and 30 minutes equals 171Gig.

I guess I could put one second worth of raw data into ramdisk, and do a copy to the Fibre Channel SCSI RAID. Then write the next second of raw data to another ramdisk and switch back-and-forth. But I'm not sure if a cp is any faster than a fwrite. Is this what you're suggesting?

(!) [Jimmy] No, I was placing more importance on the step where you add a file header to the data in the buffer.
Going by this: http://linuxgazette.net/102/piszcz.html you'd be much better off accessing the disk as ext2 instead of ext3 - the journal is probably what's slowing you down.

(?) cannot talk using "talk"

From Sanjib Roy

Answered By: Thomas Adam

how can i set up talk facility in my lan ( 1 server 9 clients with dns) when i want to talk to my server talk display folloing mesg remote host does not recognize us

(!) [Thomas] Well... can you possibly start over and explain things in more detail? Only what you have provided is very little to go on, not to metion I am having to now make guesses as to what you're using...
The "talk" command is/was used initially by BSD to allow users on a LAN to talk to one another. But what you also need is talkd -- which is the remote user authentication tool. "Talkd" has to be spawned from inetd if it is to work, this something like the following [1]:
talk            dgram   udp     wait    nobody.tty      /usr/sbin/in.talkd      in.talkd
ntalk           dgram   udp     wait    nobody.tty      /usr/sbin/in.ntalkd     in.ntalkd
Then you must [re]start inetd:
# /etc/init.d/inetd restart
(note that of you are using RH/Fedora, the chances are you're using xinetd).
Then all you do is connect, using 'talk' (man pages help here).
One thing you should also know is that 'talk' is rather limited, and as such lots of alternatives exist. I'll name drop, although most are an enhancement on BSD-talk:
utalk
ytalk
etalk (emacs)
gtalk (GTK front-end)

(?) but when i want to talk from one client to another client no connect is made

(!) [Thomas] You need to be much more precise here. What errors are you getting? You don't even say which distribution you're using. Before you reply to this, as I hope you will, read the following:
http://linuxgazette.net/tag/ask-the-gang.html

(?) PLEASE HELP ME

(!) [Thomas] Sorry, but when you start demanding, my patience decreases. Don't do it. We owe you nothing. I'm sure you mean well, but it doesn't come across as very good when you think that you should be placed above all others for help. I treat everyone with the same level of help, regardless of their 'issue'.
[1] This is from memory and so is possibly inaccurate. Either way, the entries may well already be installed into the file: /etc/inetd.conf - and if no such entries exist, those lines should be added to this file.

(!) Tripwire

From Greg Bell

Answered By Barry

(!) [Heather] An honorary answerbubble for Greg Bell. Good stuff here, and thanks to article auther Barry O'Donovan for forwarding the thread to us.

(!) One thing that I've been suspicious of with tripwire is: if the hacker is "in", aren't there all sorts of things he can do to neuter tripwire?

(!) To save an argument I could simple say yes... but I won't! First of all, running tripwire (or another intrusion detection system (IDS)) is immeasurably better than running no IDS at all.

(!) thanks for the dialog. no arguments here, although my counter-points to your points may appear argumentative :)

(!) a lot of things that seem burdensome for a hacker to do can be wrapped up nicely in a script and bam - 1000s of intruders now have the capability.

(!) These scripts usually take advantage of an existing exploit to place a root kit, backdoor, etc. If your tripwire set-up is unique (i.e. place the tripwire binary somewhere besides the defualt, use a different configuration file name and directory, place the db on a floppy, remote site, etc) then the script won't affect tripwire or if it does it'll be immediately noticed. Most of these scipt-kiddies go for the "easy hack" - the poor fools who take no preventative measures. There's so many of these guys that the script-kiddies are unlikely to invest the time in created a "be-all and end-all" script to do everything including disable tripwire in a way that it's not noticed.

(!) He can remove the cron/anacron job, and send you fake mail every day saying everything checked "OK".

(!) That's a lot more difficult than it sounds. First of all, he'd need to know what the usual "all is okay e-mail" looks like for YOUR system. When you're running tripwire and checking the e-mails you'll get used to seeing and recognising a lot of numbers such as the total objects scanned, etc. If you're sending these daily e-mails to another server then he won't have access to an existing report and he won't be able to view the saved report files in /var/lib/tripwire without your passphrase.

(!) i am admittedly paranoid about this sort of thing, thanks to reading about how clever these guys can be, and how it seems to be a never-ending escalation and arms race (leading towards EVERYTHING being encrypted, and EVERYTHING being authenticated with biometrics). a lot of things that seem burdensome for a hacker to do can be wrapped up nicely in a script and bam - 1000s of intruders now have the capability.

(!) Secondly whether you're running tripwire on a server or a desktop machine, you're liable to have to update at least one package at least once a week. When you do this you'll expect a problem from tripwire and if he's sending fake e-mails you'll start to question whther tripwire is working or not.

(!) some things i think would be appropriate for tripwire to watch would be /etc/passwd and /etc/crontab - two things that can change often, but that are also prime candidates for a hacker to change.

(!) Most distributions default tripwire config will check these - especially passwd. If it doesn't, then ammend the policy file so that it does.

(!) so it seems to me than whenever one of these needs to be changed, you've got to run tripwire on the file to make sure its unchanged, unplug your net connection, change it, update tripwire, reconnect to the net. sounds bizarre but its not improbably that in the hours between your update and tripwire's next run, a break-in occurs, changing the same file.

(!) Again, it's all a matter of just how paranoid you are or how far you're willing to go.

(!) he can replace the tripwire binary itself.

(!) Tripwire checks itself too! The stats for the tripwire binary will reside in the database which an intruder cannot change unless he has your local passphrase. I suppose an intruder could replace the binary with one that's programmed to not check itself but if you're really this paranoid you can put the binary on a remote HTTP server and have your cronjob download it with wget before checking.

(!) the "in" hacker would just disable the wget and have the local one be used.

(!) He'd also have to asscertain that you use wget to download a fresh binary and simulate the output from your wget cronjob so you wouldn't miss it.
Some servers will mount /usr as read-only to increase access speeds and security. This would help out here too.

(!) if he's got root, he can just remount r/w.

he can update the database

(!) He can't. He'll have to have your local passphrase to do this.

(!) which an "in" hacker can get with a keycatcher.

(!) But he'd probably have been spotted by a run of tripwire before hand as you'd need a reason to input your tripwire passphrase.

(!) (especially if its on a CD-RW like you suggest).

(!) I never said leave the CD-RW in a CD-RW drive. I said "a re-writable CD in a CD-ROM drive (read-only drive)." i.e. only place the CD in the CD-RW drive when updating, then put it back in the CD-ROM drive.

(!) got it. smart.

(!) The bottom line is that tripwire will probably catch an intruder 99 out of a 100 times. If not more. You'll NEVER be 100% secure. That's just a simple fact of life. But you can strive to be as secure as possible and using tripwire will be a huge help here.

(!) absolutely.

seems to me we might be moving towards a world where an off-site system does the security check for a particular machine - sort of a checks and balances setup. it would host the tripwire binaries, database, signatures, etc. and while its there, it should receive the mails from tripwire, as well as host the syslog remotely. even so, rootkit hunters would still have to be run on the secure machine, and some amount of manual checking would have to be done to make sure any number of checks hadn't been faked or disabled.


This page edited and maintained by the Editors of Linux Gazette
Copyright © its authors, 2004
Published in issue 107 of Linux Gazette October 2004
HTML script maintained by Heather Stern of Starshine Technical Services, http://www.starshine.org/

Published in Issue 107 of Linux Gazette, October 2004

News Bytes

By Michael Conry

News Bytes

Contents:

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 bytes@lists.linuxgazette.net


Legislation and More Legislation


 Patents

Patents are a recurring theme here, and there is a lot of good commentary on the net related to this topic. A recent development that has stirred some further debate is the release of a report by Open Source Risk Management outlining their reading of the patent issues surrounding Free and Open Source Software. OSRM has a business model built around selling legal support and indemnification to clients in the Open Source community. Some criticism of the report has focused on the potential it has to create feelings of uncertainty among businesses operating in this arena. While this is a valid concern, it is not a reason to avoid discussion of these matters. Indeed, as pointed out in Linux Weekly News, these matters of patents and possible infringements affect proprietary software developers just as much as open source software developers. A useful article at O'Reilly's linux devcenter gives a good overview of some of the issues raised by the report, and also includes responses from OSRM's Dan Ravicher to some of the criticisms and queries prompted by his work.

One way or another, discussion and debate around this issue is a good thing.


 Voting

LinuxWorld.com.au has reported on the fortunes of Free software in the implementation of Australian e-voting. Encouragingly, the initial system implemented was released under the GPL, however Software Improvements, the company behind the software, has decided to release future versions under a more restrictive licence that will only allow officials to view the code. This is particularly disheartening since the Australian Capital Territory Electoral commission had ordered that the software be open source. To see the deal reneged on (in spirit if not in the legal sense) is a setback for open source software, and for e-voting in general.


Linux Links

How to Build a Low Cost Linux Desktop Computer

Getting going with Subversion

GNU/Linux as a data-recovery tool

Getting online with Bluetooth and GPRS

French supermarket (hypermarket?) giant Carrefour is piloting a line of PCs equipped with Mandrake Linux in its stores.

Hacking the Linux-based Linksys NSLU2

Summer vacations, bringing Linux to Nicaragua.

Two Degrees of Freedom, George and Freeman Dyson at OSCON 2004. Discussion includes biotechnology, physics, the fate of the universe, and the value of physical tinkering.

Custom Email Queries for handling the diverse data and file-types that turn up in your inbox.

O'Reilly book, AI for Game Developers.

Applying technical know-how to get the 9/11 Commission report to the widest audience.


News in General


 TheOpenCD Software Freedom Day Edition

The OpenCD project has announced the availability of TheOpenCD v1.4.1, a special edition for Software Freedom Day 2004 (August 28th). TheOpenCD is a collection of Free and Open Source software for Windows, and it is a good way to introduce Windows users to the world of Free software. As well as TheOpenCD, the Software Freedom Pack to be distributed on SFD will include a remastered Knoppix live CD aimed at a non-Linux using audience.


Distro News


 Kanotix

Kanotix is a live GNU/Linux CD based on Knoppix and Debian, and using mostly pure Debian/sid. Since it's a live CD, it is easy to try out without risk. Linux.com has recently reviewed the distribution.


 SuSE

SuSE has announced the launch of SuSE Linux Enterprise Server (SLES) 9, based on the new Linux 2.6 kernel.


Software and Product News


 Linux

Linux 2.6.8 has been released with various changes and updates. This was quickly followed by a small bugfix release, bringing the current stable version up to 2.6.8.1.


 SpamAssassin

SpamAssassin Version 3.0 has been released.


 Helix/RealPlayer

The Helix Player Project has announced the release of RealPlayer 10 for Linux and the underlying 100% open source Helix Player 1.0

Basic Features of the players:

Real Player 10 for Linux adds the following features:


 LTSP

The Linux Terminal Server Project has announced the release of LTSP 4.1. It includes the following:


 Mozilla

The Mozilla project has released new versions of its flagship programs. This means that Mozilla Suite (1.7.3), Mozilla Firefox (1.0 Pre-Release) and Mozilla Thunderbird (0.8) are now available for download. Since earlier releases have suffered from some quite recently discovered security bugs, upgrads are advisable. Since earlier releases have suffered from some quite recently discovered security bugs, upgrades are advisable.


Mick is LG's News Bytes Editor.

[Picture] Originally hailing from Ireland, Michael is currently living in Baden, Switzerland. There he works with ABB Corporate Research as a Marie-Curie fellow, developing software for the simulation and design of electrical power-systems equipment.

Before this, Michael worked as a lecturer in the Department of Mechanical Engineering, University College Dublin; the same institution that awarded him his PhD. The topic of this PhD research was the use of Lamb waves in nondestructive testing. GNU/Linux has been very useful in his past work, and Michael has a strong interest in applying free software solutions to other problems in engineering.

Copyright © 2004, Michael Conry. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 107 of Linux Gazette, October 2004

Knoppix with 2.6.7 kernel from non-bootable CD-ROM

By Anonymous

Introduction

You want to start Knoppix and your CD-ROM cannot boot either for technical or administrative reasons. You can try to start the Knoppix CD from a floppy drive. For that you need a Knoppix boot diskette.

The recent Knoppix 3.4 of May 2004 relies on kernel 2.4.x but has kernel 2.6.6 as an option. Likewise, Knoppix 3.7 of August 20 has the 2.6.7 kernel as an option. This last release is - for the time being - only available in Germany as a CD from a computer magazine. However, a general release, possibly with kernel 2.6.8, is coming and so it is sensible to refer to the new kernel because its size is growing and growing and causing diskette distress.

We will refer to the new Knoppix kernel as knoppix26 using the same name as in the CD boot configuration. Unfortunately, knoppix26 does not boot from one diskette, it needs two.

When running, knoppix26 has a script in

    /KNOPPPIX/usr/sbin/mkbootfloppy

that does make these two floppies - despite the singular name. However, the diskettes so generated depend on the kernel in use. If you want them in order to be able to boot 2.6.x, you have to write them while running 2.6.x - which is a bit of a catch-22. Modifying the script is catch-22 again since the script is not directly accessible on the Knoppix distribution CD and becomes only readable when Knoppix is running. It can be found on the web in editable form but making sensible use of it will be more laborious than the advice found in this article, especially in respect to kernel 2.6.7 which does not fit on a 1.4M diskette at all.

So if your CD-ROM will not boot, how are you going to boot knoppix26 from the floppy drive?

Pre-requisite

You must have some familiarity with syslinux. Fortunately, it can be acquired on the fly, check http://syslinux.zytor.com.

Option 1

Consider the following (chain) boot loaders:

    http://bootcd.narod.ru/bcdw150z_en.zip
    http://btmgr.sourceforge.net/download.html

Both of them can create a boot diskette that starts a (bootable) CD even if the CD-ROM is unable to boot. In the particular case of the Knoppix CD, the good news is that they both will boot it from a non-bootable CD-ROM.

This is your friend if you want to minimize preliminary work. Unfortunately, if you are not installing Knoppix to hard disk, you may end up doing quite a lot of typing at the command line every time you boot.

[Please do not misunderstand the remark above as a criticism of the two boot loaders. They come in very handy in other situations as well.]

Option 2

The biggest hurdle is the kernel size starting with release 2.6.7. In the 2.6.6 release, the Knoppix kernel would fit on a 1.4M diskette. Now you need to format the diskette to 1.68M - the same size Microsoft uses occasionally for its diskettes. For that purpose, you can use winimage under Windows, fdformat under DOS or superformat/fdformat under Linux. Good luck to you because diskettes sold for the 1.4M capacity do not necessarily agree to a flawless format at higher capacity. My experience is that you need a box of ten to get one such tolerant diskette. If you want strict verification, use winimage and you will see the massacre.

When you have formatted the diskette, make it a syslinux boot diskette. This can be done from DOS, Windows, Linux - it's up to you. No further help is offered here for it. This boot diskette will contain only one small file, ldlinux.sys.

In the Knoppix CD 3.7, there is a directory /boot/isolinux where you will find the following files among others:

    boot.msg              141
    f2                  1,561
    f3                  1,688
    isolinux.cfg        2,642
    linux26         1,458,194
    minirt26.gz       791,321

Copy everything but the last file to the syslinux diskette above. Rename isolinux.cfg to syslinux.cfg and edit it as follows:

DEFAULT knoppix26
TIMEOUT 300
PROMPT 1
DISPLAY boot.msg
F2 f2
F3 f3
LABEL knoppix26
KERNEL linux26
APPEND load_ramdisk=1 prompt_ramdisk=1 root=/dev/fd0 rw init=/etc/init lang=us apm=power-off nomce BOOT_IMAGE=knoppix
LABEL expert26
KERNEL linux26
APPEND load_ramdisk=1 prompt_ramdisk=1 root=/dev/fd0 rw init=/etc/init lang=us apm=power-off nomce BOOT_IMAGE=expert

This is now a boot diskette for the 2.6.x kernel, the initial ramdisk being read from a second diskette. Type knoppix26 at the boot prompt. It will quickly ask you to insert the second diskette so you must have it ready.

The second diskette must be a raw copy of minirt26.gz. Which is to say, you cannot format it with a file system and put minirt26.gz into the file system. When syslinux reads the diskette it expects the binary content of minirt26.gz and nothing else. It won't assume a file system and look for a file in it.

The question is: how do you copy the file raw to the floppy? Here is the command (run under Linux from the Knoppix CD, /boot/isolinux directory):

    dd if=minirt26.gz of=/dev/fd0 bs=18k

The bs value is not essential, it just determines the size of portions read and written. (A high-density 3.5" diskette has a track of 18k.) The floppy may or may not be mounted. If not mounted, it does not even need to be formatted since the formatting will be destroyed anyway.

By the way, the raw copy can also be done under DOS/Windows with a utility that can write to a physical sector disregarding the file system. One such utility is the Norton Disk Editor.

After inserting the second boot diskette, knoppix26 will boot.

The shape of things to come

Evidently, option 2 cannot be recommended to anybody, too much of a hassle. The chain boot loaders listed above are the way to go. Note that Microsoft has just turned to a chain boot for their XP CDs' to handle non-bootable CDROMs.

Still, we have here some developments to watch. With the Linux kernel too big for a normal 1.4M diskette, syslinux is going to be relegated to rescue diskettes, it won't help any longer for the current Linux releases.

And even lilo gets an encouraging kick to the exit. With kernel 2.4.x, a lilo diskette could still quickly boot a Knoppix installed to a non-bootable partition: you had Windows as normal straight boot from hard disk, Knoppix also on hard disk but booted from diskette, no clashes. This may still be doable for kernel 2.6.x if the hardware does not require any special drivers at boot time and the initial ram disk can be dispensed with. If you need an initial ram disk, expect its size to be in the region of 4M: you will have to customize it so as to fit it on a diskette, in which case you have again an approach like Option 2. If not possible then the initial ram disk would have to be on the hard disk and lilo is simply not able to find it.

Exit syslinux, exit lilo, everything points to grub. And maybe they will throw in a CD boot from diskette as a bonus?


Copyright © 2004, Anonymous. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 107 of Linux Gazette, October 2004

closedShop - The Open Source Shopping Cart

By Chris Fleizach

I ran across this piece of software while searching for an Open Source alternative to the commercial "shopping cart" software (which was mostly poorly written, and in a number of cases, badly broken.) Chris's approach impressed me with its simplicity, utility, and ease of installation - and fit my requirements perfectly.

One of the arguments that the opponents of Linux use, over and over, is that "Linux doesn't support business". IBM, Novell, Oracle, SAP, and countless other companies have been proving them wrong in the corporate world; by soliciting articles from authors of software that caters to the small and mid-sized business, such as Chris Fleizach's closedShop, I hope to cut the feet from under this part of their argument as well.
-- Ben


About three years ago I was faced with the challenge of putting together an e-commerce site that would not require online credit card processing. Although I searched briefly, I only found expensive solutions. Thus I began work on closedShop, an open source shopping cart. Over the past three years, there have been over 13,000 downloads spread across 9 releases. Basically, closedShop is a free shopping cart written in Perl, using the mySQL database as a back-end, that allows anyone to set up shop with no online credit card processing necessary. They can process the credit cards manually, as most businesses already have a manual credit card processor.

Before we go into a tutorial on how to set it up and start accepting orders, it's good to know what closedShop offers:

If that's what you need, then closedShop is a pretty good solution for you. The first thing you need to do is download the latest version from SourceForge.

After downloading, unzip the contents into your cgi-bin directory. Make sure the all the files have 755 permissions (closedShop doesn't work very well on Windows-based servers, only *nix types). Most FTP programs allow you to change permissions (via the 'chmod' command). You'll want to make all the files read-write-execute for the owner, read-execute for the group, and read-execute for everyone else. This set of permissions is also known as 755.

You also need to make sure that the web server is allowed to write to the directory that closedShop is saved in. This is very important since the program needs to save some data in flat-text files. Most web hosting services allow this automatically. If your server does not allow it, closedShop will tell you so and will not attempt the installation. If you see this message you may need to contact your hosting service and tell them you'd like to allow the web server to write to the directory that closedShop is in (usually the cgi-bin directory.)

[ Previously, Chris' article got sidelined due to the security concerns with the instructions in the above paragraph during our technical review; making "cgi-bin" world-writeable is not usually adviseable. However, I eventually decided that it wasn't all that insecure in the first place (someone would have to crack the webserver to get access), and that a simple modification of closedShop would get rid of the above requirement in any case. Open Source in action, at your service. :) -- Ben ]

Assuming you have passed that main hurdle, you will now go to your web browser and access the file called Install.pl. If you put closedShop in your cgi-bin directory (and assuming your site is located at "www.yoursite.com"), then to access Install.pl, you'd type

http://www.yoursite.com/cgi-bin/Install.pl

A web page will come up and ask you to enter some important information. Some of it will be about your company, some about taxes, some about how you would like your tables to appear. For most of the data you can leave the default. The most important information is about the mySQL database. You must have access to a mySQL database before installation. Most web hosting services allow this access, but you may need to request it beforehand. Then they will send you a mySQL username/password and database name. You put this information into the mySQL database section.

The other important section is the admin password and merchant password. The admin user will allow you to make all changes to the program, while the merchant account shows fewer administrative changes and is more for processing orders. It allows two people to log on at the same time as well. Remember those passwords, you will need them to log in.

After you fill out the rest of the data, click 'Install' and it will take about 30 seconds to prepare everything. Afterwards, you'll see a screen that says go to the Admin.pl script. There are four scripts that do the different functions. Admin.pl handles administrative tasks. Cart.pl is for the shopping cart and checkout procedures. User.pl is for individual clients to login and watch the order tracking as well as manage their wish list. Item.pl displays items and categories and also allows for searching.

Once you log into Admin.pl you will see the different options. You may want to edit category information first for the categories you entered in the Install. Note: if you want to add more categories or change the name, then go to "Edit Program Variables". Other information about categories can be viewed as well in the "Edit Categories" section. After editing categories, you should start adding products, either through the "Add Product" option or through importing. When adding a product, you also have the option of posting the item to eBay at the same time. The eBay information will be below the main information and is not required.

Finally, you need to integrate closedShop into your site. You'll find important links under the "View Important Links" option. This tells you the URLs for each category, Searching, User logon and the Shopping Cart. If you have a standard design for your site you can allow closedShop to use that design with the header and footer variables in the "Edit Program Variables". The header is a file that contains the top part of the HTML for your design. The footer is a file that will contains the bottom part of the HTML for your design. closedShop will insert itself into the middle. These files could be made and put in the cgi-bin directory. Normally, you would name them header.html and footer.html and put those respective values into your program variables.

You should then take the links you want to use, like Searching, and link them into your design. An example of this can be found at Demo Site on the closedShop web site (http://closedshop.sourceforge.net)

Of course, you should also use SSL if possible. Customers will be entering their credit cards over the site and you will be viewing them. If you're not using SSL capabilities then there is a greater possibility of having the data stolen. Most web hosting services allow customers to use their SSL certificates and SSL processing. It may be a different link than what you are used to seeing, though, something that looks like it is from the hosting service. In this case, you'll want to change the program variables and change the names of the files to use the https:// and then type in the full URL to the secure location. You'll also need to change the image directory URL to the secure path, otherwise users may get messages complaining about a mixture of secure and non-secure. You should always access the Admin.pl script using the secure connection, otherwise you leave yourself vulnerable to thieves.

The program has been designed to be as straight-forward as possible. If you go to each script, you will see the default screen appear initially. There is also more information in the documentation that comes with each release. Of particular interest might be the template features, which allow you to mix in Perl programming with your template in order to totally customize the look and feel of Item and categories.

If there are any questions, comments, concerns, or suggestions, they can always be directed to email.


[BIO] Chris is a Peace Corps volunteer in the Kingdom of Tonga and has been bringing them the world of Open Source for almost two years. He is also a founding member of FightLiteracy.com, the only organization in the world dedicated towards ending literacy.

Copyright © 2004, Chris Fleizach. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 107 of Linux Gazette, October 2004

Secure Communication with Stunnel

By Barry O'Donovan

1. Introduction

Stunnel is an SSL encryption wrapper that allows what are normally plain text and insecure communications to be encrypted during transmission. Stunnel recently went through some major changes and the current version (4.x) has a completely different architecture than previous versions. In this article I will be dealing exclusively with the new version.

One of Stunnel's most common uses is encrypting communications between POP or IMAP mail servers and e-mail clients. Both of these protocols require users to authenticate themselves with a username and a password. In the majority of cases, these usernames and passwords are the same ones as they would use for logging into the machine locally or remotely via SSH. Without using Stunnel to encrypt this data, anyone intercepting the transmission could now log into your server and gain elevated privileges much easier than a local exploit would require.

2. Getting and Installing Stunnel

Stunnel is generally included as a precompiled package with most common distributions and is possibly already installed on your system. If not, locate the package on your distribution's installation CDs or download it from the distribution's website.

The source code is released under the GNU General Public License and, as such, is freely available for download and installation. The current version (which at time of going to press was 4.05) can be downloaded from ftp://stunnel.mirt.net/stunnel/. To compile and install Stunnel, download the source code tarball from here and then execute the following commands:

$ tar zxf stunnel-4.XX.tar.gz
$ cd stunnel-4.XX
$ ./configure
$ make
$ make install   (as root)

3. Generating a Self-Signed Certificate

In order to use Stunnel we must first have a certificate-key pair. If you compiled from sources then such a pair will have been created for you automatically (stunnel.pem). Some pre-built binary packages may include a certificate-key pair, some may generate one as part of the installation procedure and others may leave it up to the user to generate one.

The easiest way of generating a certificate-key pair is by using a script provided with Stunnel's source code. If you're compiling from the tarball, just issue the following additional commands in the source directory:

$ cd tools
$ make stunnel.pem
I have decided to put the specific details outside the scope of this article, but if you are interested in the actual details then have a look at the Makefile in the "tools" directory.

4. Using Stunnel to Encrypt POP3/IMAP

This method can be used to encrypt any similar service where SSL-enabled clients exist and are readily available. Most e-mail clients are SSL-enabled for POP3, IMAP and SMTP, most internet clients (web browsers) are enabled for HTTPS, etc.

Once Stunnel is installed and you have generated a certificate-key pair, you are only a simple configuration file away from using Stunnel to encrypt your communications. A simple one that would encrypt POP3 and IMAP communications would be:

# Sample stunnel configuration file for POP3/IMAP

# Provide the full path to your certificate-key pair file
cert = /usr/local/etc/stunnel/stunnel.pem

# lock the process into a chroot jail
chroot = /usr/local/var/run/stunnel/
# and create the PID file in this jail
pid = /stunnel.pid

# change the UID and GID of the process for security reasons
setuid = nobody
setgid = nobody

# Configure our secured POP3 and IMAP services

[pop3s]
accept  = 995
connect = 110

[imaps]
accept  = 993
connect = 143

Using this configuration, any encrypted connection coming in on port 995 (POP3s) will be decrypted and forwarded to the local service (POP3) on port 110. When the local POP3 service responds, it will be encrypted by Stunnel and transmitted back through port 995. Similarly for IMAPs on port 993.

Stunnel operates as a daemon service by default, so to start it off with this configuration we can simply execute:

stunnel stunnel-secure-email.conf
where stunnel-secure-email.conf is the text file containing the above configuration; ensure you change the paths so that they are correct for your system.

We can set up Stunnel to start during boot-up by placing the appropriate command in the rc.local file that is usually contained in /etc/rc.d/. This file is the last file executed during a system boot and it is generally used by system administrators for their own initialisation stuff. When placing commands in this script, use fully qualified paths such as:

/path/to/stunnel /path/to/the/configuration-file

[ For Debian and similar distros without an 'rc.local', the procedure varies slightly: modify a copy of "/etc/init.d/skeleton" (named, e.g., "/etc/init.d/stunnel") to run the above and create a link to it from the appropriate runlevel (usually /etc/rc2.d/). -- Ben ]

Stunnel can also be used with (x)inetd if preferred. You can find further details in Stunnel's man page.

5. Using Stunnel to Encrypt MySQL Transactions

This method can be used to encrypt any service where neither the server nor the client are SSL-enabled. Common examples include CVS, MySQL, etc.

In the example with POP3 and IMAP above, we were only concerned with providing the server with SSL encryption as the clients generally have this built in. However, neither the standard MySQL server nor client have SSL capabilities - but we can still use Stunnel to provide this.

It involves using a Stunnel daemon on both the server's machine and the client's machine. The configuration for the server side is similar to the one we used above for POP3/IMAP. The default MySQL port is 3306, and since no port is reserved for secure MySQL connections, I will use 3307:

# Sample stunnel configuration file for securing MySQL (server side)

# Provide the full path to your certificate-key pair file
cert = /usr/local/etc/stunnel/stunnel.pem

# lock the process into a chroot jail
chroot = /usr/local/var/run/stunnel/
# and create the PID file in this jail
pid = /stunnel.pid

# change the UID and GID of the process for security reasons
setuid = nobody
setgid = nobody

# Configure our secured MySQL server

[mysqls]
accept  = 3307
connect = 3306
I can now start the Stunnel daemon on the server machine with:
$ stunnel stunnel-mysql-server.conf
where stunnel-mysql-server.conf is a text file containing the above configuration. We also need to set up an Stunnel daemon on the client machine with the following configuration:
# Sample stunnel configuration file for securing MySQL (client side)

# Provide the full path to your certificate-key pair file
cert = /usr/local/etc/stunnel/stunnel.pem

# lock the process into a chroot jail
chroot = /usr/local/var/run/stunnel/
# and create the PID file in this jail
pid = /stunnel.pid

# change the UID and GID of the process for security reasons
setuid = nobody
setgid = nobody

# enable client mode
client = yes

# Configure our secured MySQL client

[mysqls]
accept  = 3306
connect = 1.2.3.4:3307
You'll notice that I have used a new option: client = yes - this enables "client mode" which lets Stunnel know that the remote service uses SSL. Our local Stunnel daemon will now listen for connections on the local MySQL port (3306), encrypt them and forward them to our MySQL server machine (say 1.2.3.4) where another Stunnel is listening on port 3307. The remote Stunnel will decrypt the transmission and forward it to the MySQL server listening on port 3306 of the same machine. All responses will be sent back through the same encrypted channel.

Save the client configuration as stunnel-mysql-client.conf and start off Stunnel with:

$ stunnel stunnel-mysql-client.conf
and then you can connect to the remote MySQL server through the encrypted channel by connecting to the local Stunnel daemon (which is listening on MySQL's 3306 port):
$ mysql -h 127.0.0.1 -u username -p

6. Trouble Shooting

Stunnel can be a bit tricky about permissions - especially when using a chroot jail and reducing your user and group ID to nobody (some systems might need nogroup for setgid). Ensure your chrooted directory is writable by the nobody user and/or the nobody (or nogroup) group.

Stunnel runs in the background by default and doesn't show any error messages. This means you won't know if it worked or not from the command line! You can check that the process is running by searching the output of the ps command:

$ ps -ef | grep stunnel
nobody   21769     1  0 09:12 ?        00:00:00 /usr/local/sbin/stunnel ./stunnel-mysql-server.conf

Stunnel can also be instructed to run in the foreground by adding the following command to the configuration file (above the service configuration):

foreground = yes

As with all services, the best method of diagnosing problems is through the service's log messages. You can enable Stunnel's logging facilities by adding the following commands to the configuration file (above the service configuration):

debug = 7
output = /tmp/stunnel.log

If you are running in the foreground for testing/debugging, then you might prefer to send the log messages to standard out:

debug = 7
output = /dev/stdout

7. Further Reading/References

There are many other commands that can be used in the configuration files and these are all listed in Stunnel's man page (STUNNEL(8)).

The following websites may also prove useful:

As always, I appreciate any feedback on this or previous articles and suggestions/requests for future ones. You'll find my e-mail address by clicking on my name at the beginning of the article.


[BIO] Barry O'Donovan graduated from the National University of Ireland, Galway with a B.Sc. (Hons) in computer science and mathematics. He is currently completing a Ph.D. in computer science with the Information Hiding Laboratory, University College Dublin, Ireland in the area of audio watermarking.

Barry has been using Linux since 1997 and his current flavor of choice is Fedora Core. He is a member of the Irish Linux Users Group. Whenever he's not doing his Ph.D. he can usually be found supporting his finances by doing some work for Open Hosting, in the pub with friends or running in the local park.

Copyright © 2004, Barry O'Donovan. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 107 of Linux Gazette, October 2004

Understanding Threading in Python

By Krishna G Pai

When programming, in any language, the capability to spawn worker threads is integral to the performance of any application. Whether it be running a separate thread to handle user interaction in a GUI app, while running a potentially blocking process in the background (like your browser is doing now), threading is essential. This document attempts to show what is possible and what not while Threading in Python.

1.Why Threading in Python?

Let us say you write, in Python, a nifty utility that lets you filter your mail.

You build a GUI Frontend using PyGTK. Now if you embed the filter code in the frontend, you risk making the application unresponsive (you still have a dial up connection, and any server interaction entails a considerable waiting time). Since you don't work at Microsoft, you decide this is unacceptable and thus you start a separate thread each time you want to filter your mail.

Thus threads increase the responsiveness of your programs. Threads also increase efficiency and speed of a program, not to mention the algorithmic simplicity.

Combined with the power of python, this makes programming in python very attractive indeed.

2.The Basics

Let us first see how to start a simple thread. Threading is supported via the thread and threading modules. These modules are supposed to be optional, but if you use an OS that doesn't support threading, you'd better switch to Linux.

The code given below runs a simple thread in the background. (Text version)

#!/usr/bin/env python

import time
import thread

def myfunction(string,sleeptime,*args):
    while 1:
       
        print string
        time.sleep(sleeptime) #sleep for a specified amount of time.

if __name__=="__main__":

    thread.start_new_thread(myfunction,("Thread No:1",2))

    while 1:pass

We start a new thread by using the start_new_thread() function which takes the address of the object to be run, along with arguments to be passed to the object, which are passed in a tuple.

2.1 Locks

Now that we have one thread running, running multiple threads is as simple as calling start_new_thread() multiple times. The problem now would be to synchronize the many threads which we would be running. Synchronization is done using a Lock object. Locks are created using the allocate_lock() factory function.

Locks are used as mutex objects, and are used for handling critical sections of code. A thread enters the critical section by calling the acquire() method, which can either be blocking or non-blocking. A thread exits the critical section, by calling the release() method.

The following listing shows how to use the Lock object. (Text version)

#!/usr/bin/env python

import time
import thread

def myfunction(string,sleeptime,lock,*args):
    while 1:
	#entering critical section
        lock.acquire() 
        print string," Now Sleeping after Lock acquired for ",sleeptime
        time.sleep(sleeptime) 
        print string," Now releasing lock and then sleeping again"
        lock.release()
	#exiting critical section
        time.sleep(sleeptime) # why?

if __name__=="__main__":

    lock=thread.allocate_lock()
    thread.start_new_thread(myfunction,("Thread No:1",2,lock))
    thread.start_new_thread(myfunction,("Thread No:2",2,lock))

    while 1:pass

The code given above is fairly straight forward. We call lock.acquire() just before entering the critical section and then call lock.release() to exit the critical section.

The inquisitive reader now may be wondering why we sleep after exiting the critical section.

Let us examine the output of the above listing.

Output.


Thread No:2  Now Sleeping after Lock acquired for  2
Thread No:2  Now releasing lock and then sleeping again
Thread No:1  Now Sleeping after Lock acquired for  2
Thread No:1  Now releasing lock and then sleeping again
Thread No:2  Now Sleeping after Lock acquired for  2
Thread No:2  Now releasing lock and then sleeping again
Thread No:1  Now Sleeping after Lock acquired for  2
Thread No:1  Now releasing lock and then sleeping again
Thread No:2  Now Sleeping after Lock acquired for  2

Here every thread is given an opportunity to enter the critical section. But the same cannot be said if we remove time.sleep(sleeptime) from the above listing.

Output without time.sleep(sleeptime)


Thread No:1  Now Sleeping after Lock acquired for  2
Thread No:1  Now releasing lock and then sleeping again
Thread No:1  Now Sleeping after Lock acquired for  2
Thread No:1  Now releasing lock and then sleeping again
Thread No:1  Now Sleeping after Lock acquired for  2
Thread No:1  Now releasing lock and then sleeping again
Thread No:1  Now Sleeping after Lock acquired for  2
Thread No:1  Now releasing lock and then sleeping again
Thread No:1  Now Sleeping after Lock acquired for  2
Thread No:1  Now releasing lock and then sleeping again
Thread No:1  Now Sleeping after Lock acquired for  2
Thread No:1  Now releasing lock and then sleeping again
Thread No:1  Now Sleeping after Lock acquired for  2
Thread No:1  Now releasing lock and then sleeping again
Thread No:1  Now Sleeping after Lock acquired for  2

Why does this happen? The answer lies in the fact that Python is not fully threadsafe. Unlike Java, where threading was considered to be so important that it is a part of the syntax, in Python threads were laid down at the altar of Portability.

In fact the documentation reads:

What this means is that quite probably any code like the following:

while 1:
	lock.acquire()
	.....
	#some operation
	.....
	lock.release()

will cause starvation of one or more threads.

3. The Global Interpreter Lock

Currently, The Python Interpreter (Python 2.3.4) is not thread safe. There are no priorities, no thread groups. Threads cannot be stopped and suspended, resumed or interrupted. That is, the support provided is very much basic. However a lot can still be accomplished with this meager support, with the use of the threading module, as we shall see in the following sections. One of the main reasons is that in actuality only one thread is running at a time. This is because of some thing called a Global Interpreter Lock (GIL). In order to support multi-threaded Python programs, there's a global lock that must be held by the current thread before it can safely access Python objects. Without the lock competing threads could cause havoc, for example: when two threads simultaneously increment the reference count of the same object, the reference count could end up being incremented only once instead of twice. Thus only the thread that has acquired the GIL may operate on Python Objects or call Python C API functions.

In order to support multi threaded Python programs the interpreter regularly releases and reacquires the lock, by default every 10 bytecode instructions. This can however be changed using the sys.setcheckinterval() function. The lock is also released and reacquired around potentially blocking I/O operations like reading or writing a file, so that other threads can run while the thread that requests the I/O is waiting for the I/O operation to complete.

In particular note:

The Python Interpreter keeps some book keeping info per thread, for which it uses a data structure called PyThreadState. Earlier the state was stored in global variables and switching threads could cause problems. In particular, exception handling is now thread safe when the application uses sys.exc_info() to access the exception last raised in the current thread. There's one global variable left, however: the pointer to the current PyThreadState structure. While most thread packages have a way to store ``per-thread global data,'' Python's internal platform independent thread abstraction doesn't support this yet. Therefore, the current thread state must be manipulated explicitly. The global interpreter lock is used to protect the pointer to the current thread state. When releasing the lock and saving the thread state, the current thread state pointer must be retrieved before the lock is released (since another thread could immediately acquire the lock and store its own thread state in the global variable). Conversely, when acquiring the lock and restoring the thread state, the lock must be acquired before storing the thread state pointer


  ------------------------------------------------------------------
  Global Thread | Global Thread  | Global Thread  | Global Thread  | 
  Pointer 1     | Pointer 2      | Pointer 2      | Pointer 2      |
  ------------------------------------------------------------------
        ^            ^               ^                ^
	|            |               |                |
	|            |               |                |
	|            |               |                |
	------------------------------------------------
	|                                              |
	|            Global  Interpreter  Lock         |
	|                                              |
	------------------------------------------------
	 ^         ^            ^           ^      
	 |         |            |           |  
	 |         |            |           |
	Thread No   Thread No    Thread No  Thread No
	    1           2           3          4   
         
   

4.Using the Threading Module

Python manages to get a lot done using so little. The Threading module uses the built in thread package to provide some very interesting features that would make your programming a whole lot easier. There are in built mechanisms which provide critical section locks, wait/notify locks etc. In particular we shall look at:

4.1 Using the Threading Library

The major Components of the Threading module are:

While we have visited the Lock object in the previous sections, the RLock object is something new. RLock provides a mechanism for a thread to acquire multiple instances of the same lock, each time incrementing the depth of locking when acquiring and decrementing the depth of locking when releasing. RLock makes it very easy to write code which conforms to the classical Readers Writers Problem. The Semaphore Object (rather the Semaphore Object Factory) is the general implementation of the Semaphore mooted by Dijikstra. We shall understand the implementation of the Condition, Event and Thread Objects via some examples.

4.2 The Thread Object

The Thread Object is a wrapper to the start_new_thread() function, which we saw earlier, but with a little more functionality. The Thread object is never used directly, but only by subclassing the threading.Thread interface. The user is supposed then to override possibly the __init__() or run() function. Do not override the start() function, or provide more than one argument to run. Note that you are supposed to call Thread.__init__() if you are overriding __init__().

Let us see a simple example:

#!/usr/bin/env python
#simple code which uses threads

import time
from threading import Thread

class MyThread(Thread):

    def __init__(self,bignum):

        Thread.__init__(self)
        self.bignum=bignum
    
    def run(self):

        for l in range(10):
            for k in range(self.bignum):
                res=0
                for i in range(self.bignum):
                    res+=1


def test():
    bignum=1000
    thr1=MyThread(bignum)
    thr1.start()
    thr1.join()
    
if __name__=="__main__":
    test()

There are 2 things to note here, the thread does not start running until the start() method is called, and that join() makes the calling thread wait until the thread has finished execution.

So Far, So Good! However being ever curious we wonder wether there are any performance gains in using threads.

4.3 Profiling Threaded Code.

It is the practice of every good programmer to profile his code, to find out his weak spots, his strengths, and in general to know his inner soul ;-). And since we are dealing with the Tao of Threading in Python, we might as well as ask ourselves which is the faster, two threads sharing the load or one heavy duty brute force thread?


Which is faster?
 
  thread1                                   thread2
  --------                                  ---------
  
  for i in range(bignum):                   for i in range(bignum):
    for k in range(bignum):                   for k in range(bignum):
         res+=i                                    res+=i            

or?

        thread 3  
--------------------
for i in range(bignum):                 
    for k in range(bignum):            
       res+=i
	      
for i in range(bignum):                 
    for k in range(bignum):            
       res+=i	

Following the way of the masters we make no assumptions, and let the code do the talking. Generally there are 2 ways to profile code in Python, the most common and comprehensive way would be to use the profile.run() method, or time the execution of the code using time.clock(). We shall do both. Consider the listing shown below.

#!/usr/bin/env python

#Let us profile code which uses threads
import time
from threading import Thread

class MyThread(Thread):

    def __init__(self,bignum):

        Thread.__init__(self)
        self.bignum=bignum
    
    def run(self):

        for l in range(10):
            for k in range(self.bignum):
                res=0
                for i in range(self.bignum):
                    res+=1


def myadd_nothread(bignum):

    for l in range(10):
        for k in range(bignum):
            res=0
            for i in range(bignum):
                res+=1

    for l in range(10):
        for k in range(bignum):
            res=0
            for i in range(bignum):
                res+=1

def thread_test(bignum):
    #We create 2 Thread objects  for the 2 threads.
    thr1=MyThread(bignum)
    thr2=MyThread(bignum)

    thr1.start()
    thr2.start()

    thr1.join()
    thr2.join()
    

def test():

    bignum=1000

    #Let us test the threading part

    starttime=time.clock()
    thread_test(bignum)
    stoptime=time.clock()

    print "Running 2 threads took %.3f seconds" % (stoptime-starttime)
    
    #Now run without Threads.
    starttime=time.clock()
    myadd_nothread(bignum)
    stoptime=time.clock()

    print "Running Without Threads took %.3f seconds" % (stoptime-starttime)


if __name__=="__main__":

    test()

Profiling Threaded Code in Python

We get some surprising results, notably the following..

Running 2 threads took 0.000 seconds
Running Without Threads took 5.160 seconds

Being ever sceptically we try to profile the threaded code by running, profile.run('test()'). What we see seems to add credence to the results achieved earlier.

       42 function calls in 5.170 CPU seconds
 
   Ordered by: standard name
 
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    5.170    5.170 :1(?)
        2    0.000    0.000    0.000    0.000 prof3.py:10(__init__)
        1    5.170    5.170    5.170    5.170 prof3.py:24(myadd_nothread)
        1    0.000    0.000    0.000    0.000 prof3.py:38(thread_test)
        1    0.000    0.000    5.170    5.170 prof3.py:50(test)
        1    0.000    0.000    5.170    5.170 profile:0(prof3.test())
        0    0.000             0.000          profile:0(profiler)
        2    0.000    0.000    0.000    0.000 threading.py:147(Condition)
        2    0.000    0.000    0.000    0.000 threading.py:152(__init__)
        1    0.000    0.000    0.000    0.000 threading.py:180(_release_save)
        1    0.000    0.000    0.000    0.000 threading.py:183(_acquire_restore)
        1    0.000    0.000    0.000    0.000 threading.py:186(_is_owned)
        1    0.000    0.000    0.000    0.000 threading.py:195(wait)
        2    0.000    0.000    0.000    0.000 threading.py:356(_newname)
        2    0.000    0.000    0.000    0.000 threading.py:373(__init__)
        2    0.000    0.000    0.000    0.000 threading.py:387(_set_daemon)
        4    0.000    0.000    0.000    0.000 threading.py:39(__init__)
        2    0.000    0.000    0.000    0.000 threading.py:402(start)
        6    0.000    0.000    0.000    0.000 threading.py:44(_note)
        2    0.000    0.000    0.000    0.000 threading.py:468(join)
        2    0.000    0.000    0.000    0.000 threading.py:507(isDaemon)
        5    0.000    0.000    0.000    0.000 threading.py:609(currentThread)

As I said it seems to add credence, until we notice that run() isn't even called! What does this teach us? Apart from distrusting the profiler, never follow any mechanical way of testing your code. The reason why the output is misleading and the profiler silent is because both time.clock() and the profiler measure the time spent in running the current thread.

How then do we measure time taken by the two threads? We use the time.time() function.

But doesn't time.time() give the absolute time, you ask? What about Context switches? True, but since we are only interested in the measuring the total time taken and not the work distribution, we can ignore context switches (and indeed the code has been structured to ignore context switches).

The correct way to profile the code is given in the following listing: Correct Way to Profile the Code.

The results we now obtain are more realistic and reliable.

Running 2 threads took 5.125 seconds
Running Without Threads took 5.137 seconds

As we can see there is no significant difference between threaded and non threaded apps.

4.4 Condition, Event and Queue Objects.

Conditions are a way of synchronizing access between multiple threads, which wait for a particular condition to be true to start any major processing. Condition Objects are a very elegant mechanism by which it is possible to implent the Producer Consumer Problem. Indeed this is true for anything in Python. Conditions take a lock object or if none is supplied creates its own RLock object. A Thread waits for a particular condition to be true by using the wait() function, while it signals another thread by using the notify() or notifyAll() method.

Let us see how the classical Producer Consumer Problem is solved using this.

#!/usr/bin/env python

#Let us profile code which uses threads
import thread
import time
from threading import *

class itemQ:

    def __init__(self):
        self.count=0

    def produce(self,num=1):
        self.count+=num

    def consume(self):
        if self.count: self.count-=1

    def isEmpty(self):
        return not self.count


class Producer(Thread):

    def __init__(self,condition,itemq,sleeptime=1):
        Thread.__init__(self)
        self.cond=condition
        self.itemq=itemq
        self.sleeptime=sleeptime

    def run(self):
        cond=self.cond
        itemq=self.itemq

        while 1 :
            
            cond.acquire() #acquire the lock
            print currentThread(),"Produced One Item"
            itemq.produce()
            cond.notifyAll()
            cond.release()

            time.sleep(self.sleeptime)


class Consumer(Thread):

    def __init__(self,condition,itemq,sleeptime=2):
        Thread.__init__(self)
        self.cond=condition
        self.itemq=itemq
        self.sleeptime=sleeptime

    def run(self):
        cond=self.cond
        itemq=self.itemq

        while 1:
            time.sleep(self.sleeptime)
            
            cond.acquire() #acquire the lock
            
            while itemq.isEmpty():
                cond.wait()
                
            itemq.consume()
            print currentThread(),"Consumed One Item"
            cond.release()
        
        

        
if __name__=="__main__":

    q=itemQ()

    cond=Condition()

    pro=Producer(cond,q)
    cons1=Consumer(cond,q)
    cons2=Consumer(cond,q)

    pro.start()
    cons1.start()
    cons2.start()
    while 1: pass

Producer Consumer Listing in Python

Here the currentThread() function returns the id of the currently running thread. Note that wait() has an optional argument specifying the seconds it should wait before it times out. I would discourage this use because they used a polling mechanism to implement this, and according to the source code we poll atleast 20 times ever second. Once again I would like to point out how not to use the Condition Object. Consider the following, borrowed from Python-2.3.4/Libs/threading.py

 
def notify(self, n=1):
        currentThread() # for side-effect
        assert self._is_owned(), "notify() of un-acquire()d lock"
        __waiters = self.__waiters
        waiters = __waiters[:n]
        if not waiters:
            if __debug__:
                self._note("%s.notify(): no waiters", self)
            return
        self._note("%s.notify(): notifying %d waiter%s", self, n,
                   n!=1 and "s" or "")
        for waiter in waiters:
            waiter.release()
            try:
                __waiters.remove(waiter)
            except ValueError:
                pass
                                                                                       
    def notifyAll(self):
        self.notify(len(self.__waiters))
                                                                                       
Python-2.3.4/Lib/threading.py 
What threading.py does is to maintain a list of threads waiting on the current condition. It then attempts to notify them by removing the first n waiters from the list. And since it removes the same first n waiters every time, this can potentially cause starvation to certain threads. So to test our theory out, let us modify the Producer consumer listing given above by making the following changes:
cons1=Consumer(cond,q,sleeptime=1)
cons2=Consumer(cond,q,sleeptime=1)
This will potentially cause starvation to one of the threads depending upon how they are inserted into the list. In fact a test run by making the above changes shows this to be the case. Thus you will have to be carefull to potential pitfalls in using Python Threading. Notice that there is no point in calling notifyAll() since it is inefficient and should be avoided.

By now you must have a pretty good idea about how to go about threading in Python. For closure I shall briefly describe the Event and Queue Objects and describe how to use them.

The Event Object is actually a thin wrapper on the Condition Object so that we don't have to mess about with locks. The methods provided are very much self explanatory: set() clear() isSet() wait(timeout). One thing to note is that the Event Object uses notifyAll(), thus use it only when necessary.

The code given is a simple example of the event object. event.py

Although Queues dont come under the Threading module, they do provide an easy interface which should be suitable to sovle most problems. The main advantage of Queue is that it doesn't implement the threading module. Thus you can instead use it with the thread module. Queues are a simple and efficient way of implementing stack, priority queue etc. Since it handles both data protection and synchronization. The methods used are put(item,block) get(block) Queue(maxsize) qsize() empty() full().

A simple example using Queues is given in the following listing. q.py


References

I suggest you read the following for more info:


Happy Hacking ! ;-}


[BIO] I am a linux enthusiast living in India. I love to play around in linux never knowing what i might discover next. I enjoy the freedom and power that Linux offers. and I must thank my mentor Mr.Pramode C.E (who regularly publishes in LG) for introducing me to the wonderful opportunities that Linux offers.

I have always enjoyed programming ,and have enjoyed it a lot more in Linux. ( I shall not mention my previous OS :-) ). The Emacs editor has me hooked. Is it a compiler ? , editor? AI tool ? ( No its super-macs , :-) )

I do small time programming in AI, especially Neural Networks, and I hope to release a Neural Network ToolKit that occasional Hardware hackers can use to do some interesting stuff.

Copyright © 2004, Krishna G Pai. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 107 of Linux Gazette, October 2004

AMD64 Linux kernel and the NX bit

By Pramode C.E.

Buffer overflows are not uncommon in C programs. Attacks which exploit these bugs usually try to inject alien code into the program and execute it by overwriting return addresses stored on the stack. Hardware support for marking areas of memory non-executable would make such attacks difficult. The 64 bit processors manufactured by AMD have a `no-execute' bit added to page table entries. The Linux kernel compiled for X86_64 CPU's can make use of this bit to protect user/kernel level code against buffer overflow exploits. This article describes a few experiments which I tried on an Athlon64 system running the Linux kernel 2.6.8.1 to understand some of the issues behind the use of the NX bit. The on-the-stack machine code generation trick which GCC uses (the so-called `trampoline') to implement nested functions and its dependence on an executable stack will also be examined in some detail.

All the programs presented in this article have been tested on an AthlonXP (32 bit) system using gcc 3.3.2 (the code generated by the compiler can vary as the version changes). Code which demonstrates the utility of the NX bit has been tested on an Athlon64 system running Fedora Core 2 (for x86_64).

Let's execute the stack!

The `objdump' utility comes in handy when we wish to examine the machine code produced by the linker. We write a simple C program:


main()
{
}

and compile and disassemble it by running:

objdump --disassemble-all ./a.out

Here is the output:

08048314 <main>:
 8048314:	55                   	push   %ebp
 8048315:	89 e5                	mov    %esp,%ebp
 8048317:	83 ec 08             	sub    $0x8,%esp
 804831a:	83 e4 f0             	and    $0xfffffff0,%esp
 804831d:	b8 00 00 00 00       	mov    $0x0,%eax
 8048322:	29 c4                	sub    %eax,%esp
 8048324:	c9                   	leave  
 8048325:	c3                   	ret    

We note that the `ret' instruction has an opcode of 0xc3. We use it to write a cute C program:

Listing 1


main()
{
	char a[10] = {0xc3};
	
	((void (*)())a)();
}

Now, what does that horrible looking cast do? We are telling the compiler to treat the address of the array as the address of a function which returns void; so go on, generate code to execute the array! What is proof that the code is really executing the array? Well, it is not crashing, and that might be proof enough.

It's not too difficult to prove that the code actually executes the array. Let's compile (with -O2 option) and disassemble the following C code segment:

Listing 2


#include <sys/io.h>
main()
{
	outb(0x34, 0x378);
}

The disassembled `main' is:

08048314 <main>:
 8048314:	55                   	push   %ebp
 8048315:	89 e5                	mov    %esp,%ebp
 8048317:	83 ec 08             	sub    $0x8,%esp
 804831a:	83 e4 f0             	and    $0xfffffff0,%esp
 804831d:	b0 34                	mov    $0x34,%al
 804831f:	ba 78 03 00 00       	mov    $0x378,%edx
 8048324:	ee                   	out    %al,(%dx)
 8048325:	c9                   	leave  
 8048326:	c3                   	ret    
 8048327:	90                   	nop    

We note that the `outb' is getting encoded as 8 bytes: 0xb0, 0x34, 0xba, 0x78, 0x03, 0x00, 0x00 and 0xee. With this information in hand, we write another program:

Listing 3


#include <sys/io.h>
main()
{
	char a[20] = {0xb0, 0x34, 0xba, 
                      0x78, 0x3, 0x0, 
                      0x0, 0xee, 0xc3};

	iopl(3);

	((void (*)())a)();
	printf("%x\n", inb(0x378));
}

0x378 is the address of the PC parallel port. Because the program is executing the array, it is writing 0x34 to the parallel port; which is verified by the subsequent `inb'.

If our program has a buffer overflow bug in it, a clever attacker can exploit this to inject malicious code into the program (after all, code is nothing but a sequence of numbers) and execute it via some address overwriting tricks. But what if the OS, with the help of the machine's hardware, prevents the execution of memory areas which are supposed to contain only data? This is what the AMD64 NX bit which is supported by the Linux kernel attempts to achieve.

An ELF binary (or shared library) can be `marked' as requiring (or not requiring) an executable stack. This is done using the `execstack' command:


execstack -s ./a.out #mark a.out as requiring
                     #executable stack (we will call this `turning 
                     #off the NX bit')
execstack -c ./a.out #mark a.out as not requiring
                     #executable stack (we will call this `turning
                     #on the NX bit')

The results of running the previous program on a 32 bit Athlon system with the executable marked first as requiring an executable stack and then as not requiring an executable stack were identical - in both cases, the program worked as expected, executing the array and thereby writing to the parallel port. This is because the hardware does not provide the no-execute facility. The program was then modified a bit (GCC for x86_64 generates different code) and run on an Athlon64. When the executable stack bit was turned off, the program segfaulted.

Listing 4


#include <sys/io.h>
main()
{
	unsigned char a[] = {0xb8, 0x34, 0x0, 0x0, 0x0,
                             0xba, 0x78, 0x03, 0x0, 0x0,
                             0xee, 0xc3};

	iopl(3);
	((void (*)())a)();
	printf("%x\n", inb(0x378));
}

Why turn off the no-execute bit?

It seems that having the NX bit on for all programs is a good thing. But there are certain situations where programming language compilers and interpreters might generate native machine code on-the-fly (or generate code which generates machine code on the fly), store it into an array and execute it. For such programs to work properly, an executable stack is a necessity. Let's look at an interesting example where the stack has got to be executable if the program is to work properly.

Nested Functions

GCC supports nested functions. Here is an example program:

Listing 5


void fun1()
{
	void fun2()
	{
		printf("fun2...\n");
	}
	fun2();
}
main()
{
	fun1();
}

Let's try to understand how nested functions are implemented by compiling a slightly more complex program and reading the output produced by the compiler.

Listing 6


void fun1()
{
	int i = 10;
	void fun2()
	{
		i = 20;
	}
	void fun3()
	{
		fun2();
	}
	fun2();
}
main()
{
	fun1();
}

The assembly output produced by the compiler is shown in Listing 7. Let's say the value of the stack pointer in the very first line of fun1 is 1000.

	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	$10, -4(%ebp)
	movl	%ebp, %ecx
	call	fun2.0

After the pushl, it becomes 996. This value is copied to ebp. The variable `i' is stored at location 992. The base pointer is copied to ecx and fun2 is called.

The register ecx is used for holding the address of the activation record of the function which lexically encloses the function being called. Whether fun2 is being called from within fun1 or fun3, the enclosing function is fun1 and that's where fun2 should look for when it is searching for symbols. Let's look at the segment of code where fun3 invokes fun2.


fun3.1:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$8, %esp
	movl	%ecx, -4(%ebp)
	movl	-4(%ebp), %ecx
	call	fun2.0

Within fun3 (the compiler has renamed fun3 to fun3.1), the value in ecx is the address of the frame which encloses fun3, that is, fun1. Note that this value is simply passed on to fun2. The important thing here is that the compiler is able to identify (at compile time) the address of the stack frame of the function which encloses fun2, irrespective of the location from where fun2 is being invoked because the function is being called by its name.

The trouble with function pointers

Compile time identification of the address of the lexically enclosing function's activation record becomes impossible when the function is called via a function pointer. Here is an example:

Listing 8


void fun1()
{
	int m = 5;
	void fun2()
	{
		printf("fun2: %d\n", m);
		m = 10;
	}
	void fun3()
	{
		void fun5()
		{
			printf("fun5:%d\n", m);
			m = 20;
		}
		void fun4(void (*p)())
		{
			p();
		}
		scanf("%d", &m);
		if (m == 1)  fun4(fun5);
		else fun4(fun2);
	}
	fun3();
}
main()
{
	fun1();
}

The question is what value should be put in ecx when the function pointed to by `p' is called. If `p' contains the address of fun5, it should definitely be the address of the activation record of fun3; otherwise, it should be the address of the activation record of fun1. The trouble is that the actual address stored in `p' can be determined only at run time depending on what value the user assigns to `m' from the standard input.

Before we examine how GCC solves this problem, let's write yet another little C program and run it on a 32 bit system:

Listing 9


fun1()
{
	printf("fun1...\n");
}

fun2()
{
	unsigned char a[100];

	a[0] = 0xe9;
	*((int*)(a+1)) = (int)fun1 - (int)(a+5);
	((void (*)())a)();

}

main()
{
	fun2();
}

What is fun2 doing? The first cell of the array is filled with 0xe9, which is the opcode for the JMP instruction. The next four bytes get filled by the difference between the addresses of the jump target and the next instruction (which is what jmp needs). The array is then typecast to a function pointer and called. Executing the code in the array results immediately in a jump to fun1; a return from fun1 will transfer control back to the end of fun2.

Trampoline Magic

The solution to the problem is simple and efficient. At the point where the address of the function is taken, GCC knows the address of the activation record of the function which encloses it - GCC generates code which copies this 4 byte value on to the stack, prefixed with the opcode of the instruction which copies a value to the ecx register. The next byte will be filled by GCC generated code with the opcode of the jmp instruction. This is followed by a 4 byte number, let's call it X. If we assume that the opcode of the instruction which copies a value to ecx is at a location on the stack whose address is Y, we have the following picture:


   Y           -->  Opcode of insn which moves a value to ecx
   Y+1 to Y+4  -->  The 4 byte value to be moved (address of the
                       activation record of the function which encloses
                       the function whose address is being taken)
   Y+5         -->  Opcode of jmp instruction
   Y+6 to Y+9  -->  A 4 byte number, let's call it X
   Y+10        -->  Next location on the stack.

This 4 byte number is computed by GCC generated code as follows (let's call the function whose address is being taken `fun2'):

X = address of fun2 - Y+10

After doing all these subtle manipulations, the generated code stores the address Y in the function pointer, instead of storing the address of fun2. Now, if some other function tries to call fun2 via `p', the code which has been dynamically generated on the stack starts executing. It fills the ecx register with the address of the activation record of the function which encloses the function being called and then jumps into the actual function to be executed (ie, fun2). Let's try to trace this out by reading the code which the compiler produces for the following function:

Listing 10


void fun1()
{
	int m = 5;
	void (*p)();
	void fun2()
	{
		printf("fun2: %d\n", m);
		m = 10;
	}
	void fun3()
	{
		p();
	}
	p = fun2;
	fun3();
}
main()
{
	fun1();
}

The assembly output is:

Listing 11

Let's look at the body of fun1 - that's where all the action is. Note that -71 is in unsigned hex form 0xb9 (opcode of `mov to ecx' instruction) and -23 is 0xe9 (opcode of jmp instruction). Let's say the value of esp upon entry to fun1 is 1000.


fun1:
 pushl %ebp             ; esp = 996            
 movl %esp, %ebp        ; ebp = 996
 subl $40, %esp         ; esp = 956
 leal -40(%ebp), %eax   ; eax = 956
 addl $0, %eax
 andb $255, %ah
 movl $fun2.0, %ecx     ; ecx = address of fun2
 leal 10(%eax), %edx    ; edx = 966
 subl %edx, %ecx        ; ecx = address of fun2 - 966
 movl %ecx, %edx        ; edx = ecx
 movb $-71, (%eax)      ; location 956 = opcode of mov
 leal -8(%ebp), %ecx    ; ecx = 988
 movl %ecx, 1(%eax)     ; locations 957 to 960 = ecx
 movb $-23, 5(%eax)     ; location 961 = opcode of jmp
 movl %edx, 6(%eax)     ; locations 962 to 965 = edx
 movl $5, -12(%ebp)     ; location 984 = 5 (variable `m')
 leal -40(%ebp), %eax   ; eax = 956
 addl $0, %eax
 andb $255, %ah
 movl %eax, -16(%ebp)   ; location 980 to 983 = eax
                        ; (980 to 983 is the variable `p')
 leal -8(%ebp), %ecx    ; ecx = 988
 call fun3.1
 leave
 ret

Locations 956 to 965 encode two instructions, a `mov-to-ecx' and `jmp-to-fun2' instruction. What's being stored in the pointer variable `p' is the address 956. A look at the body of fun3 shows that the statement:

p();

is getting translated to a call of the instructions stored at 956. Reading the code generated for fun2 makes it clear that the function is able to properly access the variable `m' in the outer scope.

The NX bit, again

Doing an:


execstack ./a.out

on a program with nested functions, where we do NOT take the address of a nested function, showed that the binary is marked as not requiring an executable stack. But, it was seen that whenever we took the address of a nested function, GCC was careful to mark the binary as requiring an executable stack. This was the case on both the Athlon32 and Athlon64 systems. On clearing the executable stack bit, the program was found to segfault on the Athlon64 system running the x86_64 Linux kernel.

References

The buffer overflow exploit is examined in detail in this interesting article. The Wikipedia has an entry for the NX bit; readers would also find interesting the entries for Exec Shield and PaX. Ingo Molnar talks of the NX patch in this Kerneltrap article.


[BIO] I am an instructor working for IC Software in Kerala, India. I would have loved becoming an organic chemist, but I do the second best thing possible, which is play with Linux and teach programming!

Copyright © 2004, Pramode C.E.. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 107 of Linux Gazette, October 2004

Document Processing with groff and mom

By Peter Schaffter

Document Processing with groff and mom

I see a schoolmarm at a blackboard scrawling out the title of this article with squeaky chalk. A murmur rises from the desks behind her.

Billy, the Linux ultra-newbie:
Document processing? Is that anything like word processing?

Suzie, the relative newbie:
"groff"? Isn't that the program that lets me read manpages?

Todd, the old hand:
mom? Never heard of it.

Okay, class--quiet down. One question at a time.

Document Processing

No, Billy, word processing and document processing aren't the same.

When you use a modern word processor, the computer monitor shows you a persistent representation of what you're writing in its final printed form. Whenever you want to change a font, or increase the size of type, or tighten a line, you typically highlight a portion of text, point your mouse at a menu item, select the kind of operation to perform, then specify the change from yet another menu. The alteration is immediately visible.

Text processing differs from word processing in that when you write, you fire up a text editor, a program that provides powerful tools for editing text itself--tools well beyond the scope of word processors--but does not show you a representation of the printed document. Formatting and typesetting are achieved not by point-and-click, but by embedding written commands in the text. When you finish writing, you preview the document with a small program (like gv, or ghostview) whose sole function is to show you what the printed version looks like.

groff

Very good, Suzie, groff is the program that lets you read manpages. But it does much more than that.

For many Linuxers--programmers and end-users--groff begins and ends with manpages. It comes as a surprise, then, to discover that groff is actually a powerful formatting and typesetting engine capable of producing PostScript, TeX DVI and html output in addition to formatted terminal copy (i.e., manpages).

Groff has a very long history, dating back to the earliest days of Unix. By comparison, TeX--the other big player in Linux document processing--is a relative newcomer. TeX and groff are both monumental achievements, with considerable overlap in what they do, but they have a major difference: size. Even a minimal installation of TeX is huge in comparison to groff.

Many people put up with TeX's size because they mistakenly believe that TeX produces typesetting of a quality superior to groff. While that may have been true once, it is simply not the case now, and hasn't been for some time. As a typesetting engine, groff is superb.

Groff does have a liability, though: it's incredibly geeky. Owing to its long history, it--and its power users--seem stuck in a time warp. Groff's classical macro sets (macro sets are the end-user's primary interface to groff) still look as they did in those decades when memory was exorbitantly expensive, and every byte mattered. Their terse, two-letter commands tend to scare people off, as does the amount of knowledge about groff itself required to use them effectively.

That's where mom comes in.

mom

Gee, Todd, what version of groff are you running? Have you actually checked man groff_tmac recently?

To be fair to Todd, mom is the new kid on the block. She's only been around for about two years--the first major new macro set to come down the pike in quite some time.

mom's mandate is simple: to put typesetting and document processing with groff within easy reach of everyone, old hands and newbies alike. "Easy" has been accomplished -

Tutorial--creating a document with mom

mom is actually two groff macro sets in one. For the typographer, she provides a suite of tools modeled on the commands used by "dedicated" phototypesetting machines. For the writer, she provides document processing "tags" that automatically generate beautifully formatted heads, subheads, paragraphs, cited matter, footnotes, endnotes, tables of contents, and much more. In this tutorial, we'll be setting up a university essay, so the emphasis is on document processing, not typesetting.

First of all, the "rules":

You begin a mom document by entering some reference information: title, subtitle, author(s) and so on. mom uses this information to create cover pages (if you want them), set document titles and generate page headers or footers.

.TITLE    "Stretched to the Breaking Point"
.SUBTITLE "Cadential Ambiguity in Wagner, Mahler and Strauss"
.AUTHOR   "Jane Dearborne"

Next, you tell mom what type of document you're creating, whether this is a draft or a final copy, and whether you want the document typeset or "typewritten."

.DOCTYPE    DEFAULT
.COPYSTYLE  FINAL
.PRINTSTYLE TYPESET

.DOCTYPE DEFAULT and .COPYSTYLE FINAL are optional (because they're mom's defaults). However, .PRINTSTYLE TYPESET is not. All mom documents that are to be formatted with the document processing tags must contain a .PRINTSTYLE directive.

Next, you initiate document processing with the single, required macro

.START

Now you're on your way. Begin each paragraph with .PP, on a line by itself, followed by the text of the paragraph, like this:

.PP
Lorem ipsum dolor sit amet...

When you need a main head, type .HEAD, followed by the text of the head, on the same line and surrounded by double-quotes.

.HEAD "Wagner: Lohengrin to The Ring"

Subheads are accomplished similarly:

.SUBHEAD "The Pull Toward Flat Six"

If you need to insert a passage cited from another author's work, simply surround the passage with the .BLOCKQUOTE macro.

.BLOCKQUOTE
At vero eos et accusam et justo duo dolores...
.BLOCKQUOTE OFF

If you require footnotes, embed them in the body of the document, like this:

In 1890, Alma\c
.FOOTNOTE
Mahler's wife; later married to Walter Gropius of Bauhaus fame,
then again to writer, Franz Werfel.
.FOOTNOTE OFF
is reported to have...

Note the use of \c in the first line, above. Footnotes (and endnotes) require \c in order to attach markers (asterisks, daggers, superscript numbers, etc.) to the ends of words.

Carry on in this way until the end of the document, which, if you use endnotes, is terminated by the single macro

.ENDNOTES

mom is designed to produce PostScript output (for sending directly to a printer or saving as a .ps file), and groff's default "device" is PostScript, so you'd process the file, at the command line, with

groff -mom -l <filename>

or

groff -mom <filename> | lpr
to send the file to a printer, or
groff -mom <filename> > <filename>.ps
to save it to a file. Either way, you end up with a professional-looking 8.5x11 inch document, typeset justified in Times Roman at 12.5 on 16 (mom's default).

What this little tutorial doesn't demonstrate is the degree of control mom permits over the design of documents. All the document processing tags have global "control" macros that allow you, at a minimum, to change the family, font, point size and color of any tag. Where appropriate, mom provides additional control macros for things like quad direction, line spacing, underlining, capitalization, indent, numbering style, and so on. Used in conjunction with mom's typesetting macros, the control macros let you design virtually every part of a document to precise specifications and taste.

OK, I'm intrigued: How do I get my hands on mom?

mom has been part of groff for the past two years, so if you have a recent version of groff (1.18 or later), you already have a mom. :-)

However, mom is being developed independently of groff, so you'll probably want a more mature version than the one you got the last time you updated groff.

There are two ways to get an up-to-date mom: either go directly to mom's homepage and download the latest release, or checkout the latest groff from the groff CVS repository (instructions here) and build groff from source. Patches and improvements to mom are always applied to the groff repository before a new release, so either method gets you the latest version. At this time of writing, that's 1.2. To check the version number of your current mom, do a locate to find the macro file, om.tmac, then page through it to line 26.

Please note that mom currently requires you be running, at the very lowest, groff version 1.18, and for optimal use, groff version 1.19.2 or higher.


[BIO] (the words "groff" or "mom" must appear in the subject line of any email sent to this address, otherwise the email will get nuked)

Peter Schaffter is a classical pianist, country songwriter and professional typographer turned writer whose novel, The Schumann Proof (pub. RendezVous Press, Canada), will be on the shelves in the fall of 2004.

An ardent champion of Free Software, he is also the creator of the "mom" macro set for groff. Mom is Peter's way of saying "thank you" to the community of open source developers who made it possible, despite his perpetually impoverished state, to get his hands on some of the most powerful computing tools on the planet. Mom also reflects his interest in software documentation, a subject he considers of primary importance in open source development. In a reversal of normal devlopment procedure, he wrote much of the documentation for mom before implementing the code. "A user's first exposure to a program is usually the documentation," he says, "so why not get it right first? Besides, making a program conform to pre-written docs is a great way to ensure it behaves as advertised."

Copyright © 2004, Peter Schaffter. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 107 of Linux Gazette, October 2004

Speed Compiling with Distcc

By V. L. Simpson

Introduction

When was the last time you compiled a linux kernel?

Yesterday? Last week? Five minutes ago?

On a 486?

I don't remember either.

Remember how long it took?

I remember that. Too long. Too damn long.

Now why would I want to compile the latest kernel on a 486?

Ordinarily, I wouldn't. But with the tragic death of my main computer I was forced to move my computing needs to an old 486 someone had given me. I had been using this one as a NTP time server for my home network. Suffice it to say, what was on the NTP server wasn't the latest and the greatest. The other computer on the network wasn't much of an improvement over the 486. (A foundling laptop with a miniscule hard drive.)

Well I was screwed because I needed my Emacs. So I pulled the drive from the dead computer and hooked it up to the 486.

It worked flawlessly, which is a testament to the Linux kernel and GNU Software quality and efficiency. I didn't really know what to expect regarding response and the general feel of the environment, but in console mode I noticed no real difference. The X window system even worked fine, albeit slow on the start-up. Now, there was no way the GIMP or Mozilla was going to run with any kind of usability, but I could use Emacs and lynx or dillo without too many problems.

But did I really want to sit through something that was going to take a few hours at least? Not really. I guess I could have washed dishes, mowed the lawn or watched TV but, hey, TV sucks. I'd rather watch a kernel compile.

Enter the award-winning distcc, a distributed compiler front end for gcc, written by Martin Poole.

Distcc

Distcc consists of two binary programs: distccd and distcc.

distccd runs as a daemon and handles network traffic. By passing pre-processed source code files across a network to other computers with an installed compiler, you effectively have two or more compilations going at once.

distcc is a front end to gcc and g++. You specify distcc as the compiler in place of gcc and it transparently handles all the magic that is going on. distcc can be used for all compile jobs whether you need the networking capabilities or not, i.e., you can compile one file or thousands, it's up to you.

The easiest way to demonstrate distcc's abilities is to use it to compile itself as an example of distributed compilation.

I'll show how to compile distcc and give my time for the initial compilation, then recompile using distcc in place of gcc.

Minimum Requirements:

Two compatible networked computers designated as a server and a client.

The server:
This machine should have a complete C/C++ development environment installed. You'll also need any other ancillary development packages (readline, ncurses, gtk+, whatever) that your particular bit of software needs for compiling.

distcc itself requires nothing special.

Note: There are a couple of other programs produced by distcc: distccmon-text and distccmon-gnome.

These are monitor programs to show you what's happening during a distcc compile session. The *-gnome version needs GTK at a minimum but if you don't have it installed, don't worry.

The client:
This machine only needs the compilers installed. You do not need libc, ncurses, kernel headers or the infinite array of libraries things seem to need nowadays to compile.

distcc source code available here:
distcc source code.

Building distcc, the first run:

Standard Operating Procedure:

$ tar -jxvf distcc*
(use j flag not z with tar, distcc is bzip2ed).
$ cd distcc*
$ ./configure
$ time make 
(don't forget the time command).

distcc is small and doesn't require much time to build. Here's the time from that aforementioned 486DX:

     Without distcc 
     real    13m45.185s
     user    12m4.320s
     sys     1m7.120s

It took longer to run the configure script than it did to compile.

Install the binaries:

make install
distcc and distccd should be in /usr/local/bin

For the client machine: Transfer a copy of distccd to /usr/local/bin or your binary repository of choice.

Now to use distcc to recompile distcc.

Make sure you are in the distcc source directory

$ make clean

This will clean out all the crud leftover from the first compile. You won't need to run configure again.

We need to spend a couple of minutes setting up for distcc.

1. Run the distccd daemon on both computers.

$ distccd --daemon

It'll bitch about no distcc user. Ignore the warning.
You can check to see that it's actually running via "$ ps -ax | grep distccd" to assuage your concerns.

2. Set the DISTCC_HOSTS environment variable:

You can use IP addresses or if your /etc/hosts file is set-up properly the hostnames of the computers.

I have two computers at the moment:
mothra on 192.168.1.2
ghidra on 192.168.1.3 (This one's a rescued 120MHz laptop. It would be my main computer but it doesn't have the drive space I need.)

Set the variable (sh syntax, adjust for your shell):

$ export DISTCC_HOSTS="mothra ghidra"

or

$ export DISTCC_HOSTS="192.168.1.2 192.168.1.3"

Either way it doesn't matter.
NOTE: Names or addresses are space delimited.

Recompile the code:

$ time make -j4 CC=distcc

Explaining the command line:

time: should be obvious.

make -j4:
the -j flag is make's "multiple command" flag. Read the info manual for more specific information. Trust me, just use -j4 for now.

CC=distcc:
Override configured compiler directive. This way you can do a regular configure with gcc defined in the makefile. distcc is nice about not forcing complicated procedures to use it.

distcc compiled with distcc
     real    6m38.089s
     user    2m42.200s
     sys     0m29.520s

Cut the time in half! You can't complain about that.

The following shows times for some of my favorite programs compiled with and without distcc, utilizing the two node setup describe above.

Remember, I'm compiling with a 486 without distcc.

                     		  
     Dillo Web Browser
Without Distcc With Distcc real 52m14.120s real 22m31.975s user 47m24.820s user 5m12.630s sys 3m29.220s sys 1m23.930s

     The BASH Shell
Without Distcc With Distcc real 75m25.306s real 18m22.613s user 69m2.110s user 3m27.950s sys 5m8.030s sys 0m58.980s

This was the most amazing for me. This is 1/4 of the non-distcc compilation time!

Conclusion:

distcc is flexible. You can use it as a one-shot compiler or set-up your build environment to use it for all compiles.

You can define the available compiler hosts in a $HOME/.distcc/hosts file.

You can force distcc to prefer one machine over another by listing the order in the .distcc/hosts or DISTCC_HOSTS environment variable.

For example, rather than having my poor little 486 desktop grind down to an almost unusable state as gcc takes over the system, I set DISTCC_HOSTS='ghidra' and all the compilation is shipped to the faster laptop.

More documentation is at the distcc web site.

Oh, yeah - that kernel compile. How long did it take? I don't know. I said screw it, I'll just stick with the stock kernel from my Slackware install. Even with distcc it would take forever. Maybe I'll bite the bullet at some point - but I think I'll just save up for that dual processor Athlon system I've been coveting.


[BIO] V. L. Simpson, after being unceremoniously (and rather rudely) informed that GNU Emacs is not an operating system, has been re-adjusted to a happy, regular life after many protracted sessions with 'the doctor'.

A webpage is available here.

Copyright © 2004, V. L. Simpson. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 107 of Linux Gazette, October 2004

How to Reset forgotten Root passwords

By Suramya Tomar

1.0 Introduction

Suppose you have just taken over as a new system administrator from another person just before they left and they forgot to give you the root password. Now, let's say you have to install the latest version of PHP on the system so that the sales department's website works the way its supposed to. You have to get the website up yesterday, since you are losing money every minute it doesn't work. Or maybe you simply need to add another user to the system.

The above scenarios are just two possible cases when you might need to reset the root password on a system; there are hundreds of other possible cases when you might need to do this, but I am not going to list all of them. Most of us know what to do when something like this happens on a Windows machine, but not a lot of us know how to recover lost passwords from Linux machines. This document attempts to rectify this situation by telling you about the different options available to recover passwords from YOUR machines. (Don't use this to break into other people's systems as that would be stupid and will get you into big trouble if you are caught.)

1.1 Disclaimer

Use the information in this document at your own risk. I disavow any potential liability for the contents of this document. Use of the concepts, examples, and/or other content of this document is entirely at your own risk.

The information in this document should only be used to recover passwords from machines to which you have legal access. If you use this information to break into other people's systems, then I am not responsible for it and you deserve your fate when you are caught. So don't blame me.

You are strongly advised to make a backup of your system before performing any of the actions listed in this document.

1.2 Credits

In this version, I have the pleasure of acknowledging the following people without whose input this would have never seen the light of the day:

1.3 Before you start

Before you attempt to change or replace the password of any machine, make sure you get permission from the management authorizing it, 'cause otherwise it can be mistaken as an attempt to hack into the machine, which is not good.

Secondly, create a backup of all important data before you do anything else, so if anything goes wrong you'll still have a copy of your data. If you didn't, and something went wrong, don't blame me. I tested most of this stuff on my system and it worked, but you are responsible for your system, not me, so don't blame me if something did go wrong.

2.1 Various Options available

There are various methods available for resetting a root password. In this section, I will list all the major ones, and we will go over each in detail later in the document. I will also go over some steps to prevent some other person from doing this and hacking your machine.

The various methods are:

2.1.1 Reseting passwords by booting into single-user mode

This is the easiest and the fastest method to reset passwords. The steps are a little different depending on if you are using GRUB or LILO as a bootmanager.

Booting into single-user mode from LILO

Follow these steps to reset the password when using LILO:

Lilo Boot Menu
Figure 1. Lilo Boot Menu

If you have a new version of LILO which gives you a menu selection of the various kernels available press Tab to get the LILO: prompt and then proceed as shown above.

Booting into single user mode from GRUB

Follow these steps to reset the password when using GRUB:

GRUB boot screen
Fig. 2: GRUB Boot Screen

2.1.2 Reseting passwords by using a boot disk and editing the password file

This method is a little bit more complicated than the previous one and has a very high chance of success (assuming your filesystem is not encrypted and you didn't forget the password to decrypt it if it is). As before, get permission before you do this.

To start, you need a Linux boot disk or a rescue disk. (If you didn't create one when prompted during the installation then let this be a lesson for you.) You can use your installation CD as a rescue disk; most distros have an option to allow you to boot into rescue mode. With my Redhat Linux CD, I have to enter linux rescue to start the rescue mode. But this might be a bit different in each distro. You can also use a live linux CD like Knoppix or Gnoppix for system recovery. (Click here for a list of all the live Linux CD's). In this tutorial I will use Knoppix as my rescue CD but the process is almost the same for any rescue CD you might use.

[ You can also download one of the many single-floppy Linux distributions (e.g., Tom's RootBoot ), and use it to bring up the machine as described. This is, of course, much faster than downloading and burning a rescue CD, especially on a slow connection. -- Ben ]

Follow these steps to reset the password using Knoppix:

Knoppix boot screen
Fig. 3: Knoppix Boot Screen

2.1.2 Reseting passwords by mounting on another system and editing the password file

This option is a bit more work than any of the earlier options but is almost sure to work (except when the filesystem is encrypted).

Follow these steps to reset the password:

3.1 How to Prevent someone else from reseting your root password

If you are an even slightly security-consious sysadmin, the previous sections must have set off alarms while you were reading them. Is it really that easy to hack Linux? Yes and No. It all it comes down to the following: Physical Access is Root Access. Meaning, if you give someone physical access to a system, then you are giving them a very good chance of getting root access on your box. This is true for Windows, Linux, or any other OS out there.

But... you say that you need to give some people physical access to the server? There are some precautions you can take to slow down attackers and stop the noob's. In this section I will talk about various ways you can make your computer more secure against these types of attacks. So lets get started.

3.1.1 Password protecting GRUB and LILO

First, edit the /etc/inittab file and insert the following line, right after the "initdefault" line: ~~:S:wait:/sbin/sulogin. This will require a password to boot into single-user mode by making init run 'sulogin' before dropping the machine to a root shell. 'sulogin' requires the user to input the root password before continuing.

Unfortunately, the above step won't protect us against people who know what they are doing and pass init=/bin/bash to the kernel at the LILO prompt. To prevent unauthorized access I would suggest that you password protect LILO/GRUB by following these steps:

How to Protect LILO:

How to password-protect GRUB

3.1.2 Password-protecting the BIOS

There are two primary reasons for password-protecting the BIOS of a computer:

Because the methods for setting a BIOS password vary between computer manufacturers, you should consult the manual for your computer. If you forget the BIOS password, it can often be reset either with jumpers on the motherboard or by disconnecting the CMOS battery. However, you should check the manual for your computer or motherboard before attempting this procedure.

4.1 Conclusion

By now I have hopefully saved you a lot of trouble by telling you how to recover your root password and make it harder for others to get the password. If you think this document helped you, or you have some comments or questions about this please feel free to Contact Me and let me know. However I must warn you that I am a somewhat lazy person who might take a little while before replying to your emails.


[BIO]

I was born in 1980 in a small Air Force hospital in Hashimara, India. I then spent the next 18 years of my life all over India during which I had the pleasure of attending 7 schools to complete 12 years of schooling.

I started using Linux in late 1999 when a friend lent me a Redhat 7.1 installation CD and another friend 'donated' a 6GB harddisk. This was right after my Win98 had crashed for the nth time so I decided to give Linux a shot. I tried it and got hooked almost instantly. Over the next 2 years I upgraded to Redhat 7.3 but when Redhat decided to stop support for RH 7.3 I switched to Debian and have been living happily ever since.

I like to program a lot and have recently figured out how to decipher the jumble of characters some people like to call Perl and found that I actually like it. For websites I like using PHP with MySQL backends and can program with C, C++, VB and .Net. I am also very interested in computer security and Artificial Intelligence and try to read as much on these topics as I can.

Other than working on the computer I like reading (mainly Fantasy and Science Fiction but I will read anything except romance novels), listening to music (fav singers include: Shania Twain, In-Grid, Crystal Waters) and taking stuff apart to see how it works.

If you are really bored and want to learn more about me then feel free to visit my website at: http://www.suramya.com where you will find more info about me than you ever wanted to know.

Copyright © 2004, Suramya Tomar. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 107 of Linux Gazette, October 2004

Ecol

By Javier Malonda

The Ecol comic strip is written for escomposlinux.org (ECOL), the web site that supports es.comp.os.linux, the Spanish USENET newsgroup for Linux. The strips are drawn in Spanish and then translated to English by the author.

These images are scaled down to minimize horizontal scrolling. To see a panel in all its clarity, click on it.

[cartoon] [cartoon] [cartoon]

All Ecol cartoons are at tira.escomposlinux.org (Spanish), comic.escomposlinux.org (English) and http://tira.puntbarra.com/ (Catalan). The Catalan version is translated by the people who run the site; only a few episodes are currently available.

These cartoons are copyright Javier Malonda. They may be copied, linked or distributed by any means. However, you may not distribute modifications. If you link to a cartoon, please notify Javier, who would appreciate hearing from you.


Copyright © 2004, Javier Malonda. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 107 of Linux Gazette, October 2004

The Wonderful World of Spam

Spam Jokes

[That's right, the spam has increased... or maybe it's that more spammers are including jokes. Either way, here they are.]

Saddam Hussein was sitting down wondering who to bomb next, when his phone rang. "Hello," the voice said. "This is Paddy at the Harp Pub in Ireland, I am ringing you to say me and a couple of me mates are declaring war on you!" "Well Paddy," replied Saddam, "how big is your army"

"Well lets see there's me, my brother Sean, my next door neighbour Seamus and the local dart team." "Ahh" said Saddam. "I must tell you that you are against 1 million men, 16000 tanks and 14000 armoured personnel carriers." Paddy then hung up....The next day, sure enough, Paddy rung again, "The war is still on Mr. Hussein." Paddy said. "We now have some infantry and equipment."

"What would that be" Saddam asked. "Well we have 2 combines, a bulldozer, and Father Murphy's Grey Fergy tractor," Paddy replied. Saddam sighed "Paddy may I tell you that my army has increased to 2 million men since we last spoke." "I'll get back to ya," Paddy said. Sure enough Paddy rang again, "Right Mr. Hussein, we've modified our two seater Harrigans ultra light plane with a gattling gun, and four boys from the Shamrock Pub have joined us."

Saddam cleared his throat lay back on his chair and said, "Paddy... I have 10000 bombers, 20000 fighter planes, and I am surrounded by surface to air lazer guided missles, and my army has incresed to 2 and a half million men since yesterday." "Oh" said Paddy, "I'll have to ring ya back" Paddy called again the next day and said "I'm sorry, but the wars been called off." "I'm sorry to hear that, why the sudden change of heart?" asked Saddam. "Well after a discussion over a couple of pints we decided there's no way we could feed two and a half million prisoners"


A blonde went to the appliance store sale and found a bargain. "I would like to buy this TV," she told the salesman. "Sorry, we don't sell to blondes," he replied.

She hurried home and dyed her hair, then came back and again told the salesman, "I would like to buy this TV.""Sorry, we don't sell to blondes," he replied.

"Darn, he recognized me," she thought.She went for a complete disguise this time; haircut and new color, new outfit, big sunglasses, then waited a few days before she again approached the salesman. "I would like to buy this TV."

"Sorry, we don't sell to blondes," he replied. Frustrated, she exclaimed, "How do you know I'm a blonde?" "Because that's a microwave," he replied.


Once there was a blonde driving home from work when she saw a sheep farm. She stops and asks the farmer if she can have a sheep. The farmer says "If you can count all my sheep I'll let you have any one you want." The blonde looks around her for a moment and says, "You have 356 sheep."

The farmer exclaims, "Wow - you're exactly right. I guess blondes really aren't dumb. Now go pick yourself out a sheep." The blonde makes her choice, picks it up, comes back to the farmer to thank him. "Oh no," he says, "you can't have that one." "Why not?" asks the blonde, "you said I could have any sheep I wanted." And the farmer says, "Ma'am, that's my dog."


A blonde, a brunette and a redhead are stuck on an island. One day, the three of them are walking along the beach and discover a magic lamp. They rub and rub, and sure enough, out pops a genie.

The genie says, "Since I can only grant three wishes, you may each have one." The brunette says, "I've been stuck here for years. I miss my family, my husband, and my life. I just want to go home."

POOF! The brunette gets her wish and she is returned to her family. Then, the red head says, "I've been stuck here for years as well. I miss my family, my husband, and my life. I wish I could go home too."

POOF! The redhead gets her wish and she is returned to her family. The blonde starts crying uncontrollably. The genie asks, "My dear, what's the matter?" The blonde whimpers, "I wish my friends were still here."


A blonde goes into work one morning crying her eyes out. Her boss, concerned about his employee's well being, asks sympathetically, "What's the matter?"

The blonde replies, "Early this morning I got a phone call saying that my mother had passed away."

"I'm terribly sorry to hear that. Why don't you go home for the day... we aren't terribly busy. Just take the day off to relax and rest."

The blonde very calmly explains, "No, I'd be better off here. I need to keep my mind off it and I have the best chance of doing that here."

The boss agrees and allows the blonde to work as usual. "If you need anything, just let me know," he says.

A few hours pass and the boss decides to check on the blonde. He looks out over his office and sees the blonde crying hysterically. He rushes out to her, and asks, "Are you going to be okay? Is there anything I can do to help?"

"No," replies the blonde, "I just got a call from my sister, and she said that HER mom died too!"


There was a blonde, a brunette, and a red head. They were all builders and they were working on a sky-scraper. They always ate lunch on the top of the building. The brunette always had a ham sandwich for her lunch, The red head always had a cheese sandwich, and the blonde always had a turkey sandwich. One day they all got sick of always having the same thing to eat everyday, so they made a deal. They all said that if they brought the same sandwich they usually bring, they would have to jump off of the top of the building.

The next day, the blonde was found dead on the ground by the building. The husbands of the three builders were there and they started to talk. The red head's husband said to the other two men, "I packed my wife a peanut butter and jelly sandwich so she wouldn't jump off." The husband of the brunette said to the other two men, "I packed my wife a turkey sandwich so she wouldn't jump off." They both looked at the wife of the blonde and he said:" Don't look at me, my wife packed her own lunch!"


A married couple was in a terrible accident where the woman's face was severely burned. The doctor told the husband that they couldn't graft any skin from her body because she was too skinny. So the husband offered to donate some of his own skin. However, the only skin on his body that the doctor felt was suitable would have to come from his buttocks. The husband and wife agreed that they would tell no one about where the skin came from, and requested that the doctor also honor their secret. After all, this was a very delicate matter. After the surgery was completed, everyone was astounded at the woman's new beauty. She looked more beautiful than she ever had before! All her friends and relatives just went on and on about her youthful beauty! One day, she was alone with her husband, and she was overcome with emotion at his sacrifice. She said, "Dear, I just want to thank you for everything you did for me. There is no way I could ever repay you." "My darling!," he replied, "think nothing of it. I get all the thanks I need every time I see your mother kiss you on the cheek."


The American Dairy Association was so successful with its "Got Milk?" campaign, that it was decided to extend the ads to Mexico. Unfortunately, the Spanish translation was "Are you lactating?"

Electrolux, a Scandinavian vacuum manufacturer, used this ad in the U.S.: "Nothing sucks like an Electrolux."

Colgate introduced a toothpaste called "Cue" in France, but it turned out to be the same name as a well-known porno magazine.

When Braniff translated a slogan touting its upholstery, "Fly in leather," it came out in Spanish as "Fly naked."

Coors put its slogan, "Turn it loose," into Spanish, where it was read as "Suffer from diarrhea."

Chicken magnate Frank Perdue's line, "It takes a tough man to make a tender chicken," sounds much more interesting in Spanish: "It takes a sexually stimulated man to make a chicken affectionate."

Bacardi concocted a fruity drink with the name "Pavian" to suggest French chic... but "pavian" means "baboon" in German.

A hair products company, Clairol, introduced the "Mist Stick", a curling iron, into Germany only to find out that mist is slang for manure. Not too many people had use for the manure stick.

[Irish Mist did the same thing :)]

When Kentucky Fried Chicken entered the Chinese market, to their horror they discovered that their slogan "finger lickin' good" came out as "eat your fingers off"

When Vicks first introduce its cough drops on the German market, they were chagrined to learn that the German pronunciation of "v" is f - which in German is the guttural equivalent of "sexual penetration."

Parker Pens translated the slogan for its ink, "Avoid Embarrassment - Use Quink" into Spanish as "Evite Embarazos - Use Quink"...which also means, "Avoid Pregnancy - Use Quink."

When Pepsi started marketing its products in China a few years back, they translated their slogan, "Pepsi Brings You Back to Life" pretty literally. The slogan in Chinese really meant, "Pepsi Brings Your Ancestors Back from the Grave."

In Italy, a campaign for "Schweppes Tonic Water" translated the name into the much less thirst quenching "Schweppes Toilet Water."

Chinese translation proved difficult for Coke, which took two tries to get it right. They first tried Ke-kou-ke-la because when pronounced it sounded roughly like Coca-Cola. It wasn't until after thousands of signs had been printed that they discovered that the phrase means "bite the wax tadpole" or "female horse stuffed with wax," depending on the dialect. Second time around things worked out much better. After researching 40,000 Chinese characters, Coke came up with "ko-kou-ko-le" which translates roughly to the much more appropriate "happiness in the mouth."

Not to be outdone, Puffs tissues tried later to introduce its product, only to learn that "Puff" in German is a colloquial term for a whorehouse. The English weren't too fond of the name either, as it's a highly derogatory term for a non-heterosexual.

The Chevy Nova never sold well in Spanish speaking countries. "No va" means "it doesn't go" in Spanish.

Ford introduced the Pinto in Brazil. After watching sales go nowhere, the company learned that "Pinto" is Brazilian slang for "tiny malegenitals." Ford pried the nameplates off all of the cars and substituted them with "Corcel" which means horse.

When Gerber first started selling baby food in Africa, they used the same packaging as here in the USA - with the cute baby on the label. Later they found out that in Africa companies routinely put pictures on the label of what's inside since most people can't read.

In the French part of Canada, Hunt-Wesson introduced its "Big John" products as "Gros Jos." It later found out that the phrase is slang for "big breasts."


A blonde began a job as an elementary school counselor and she was eager to help. One day during recess she noticed a girl standing by herself on one side of a playing field while the rest of the kids enjoyed a game of soccer at the other. The blonde approached and asked if she was all right.

The girl said she was. A little while later, however, Sandy noticed the girl was in the same spot, still by herself. Approaching again, Sandy offered, "Would you like me to be your friend?"

The girl hesitated, then said, "Okay," looking at the woman suspiciously. Feeling she was making progress, the blonde then asked, "Why are you standing here all alone?"

"Because," the little girl said with great exasperation, "I'm the goalie!"


One day a lawyer was riding in his limosine when he saw a guy eating grass. He told the driver to stop. He got out and asked him, "Why are you eating grass".

The man replied, "I'm so poor, I can't afford a thing to eat." So the lawyer said, "Poor guy, come back to my house." The guys then said, "But I have a wife and three kids." The lawyer told him to bring them along.

When they were all in the car, the poor man said, "Thanks for taking us back to your house, it is so kind of you."

The lawyer said, "You're going to love it there, the grass is a foot tall."


[I had to rewrite this joke... the punchline lacked in the original, so I tried to make it more like the way I heard it. Insert local values for maximum effect]

Three branches of the police, the $UNIFORMED, The $RIOT_SQUAD, and the $DETECTIVES are all trying to prove that they are the best at apprehending criminals. The police chief decides to give them a test. He releases a rabbit into a forest and each of them has to catch it.

The $DETECTIVES go in. They place animal informants throughout the forest. They question all plant and mineral witnesses. After three months of extensive investigations they conclude that rabbits do not exist.

The $RIOT_SQUAD go in. After two weeks with no leads they burn the forest, killing everything in it, including the rabbit, and they make no apologies. The rabbit had it coming.

The $UNIFORMED go in. They come out two hours later with a badly beaten squirrel. The chief looks at the squirrel, and asks "What's going on? You were supposed to find a rabbit. One of $UNIFORMED nudges the squirrel, who breaks down in tears: "Alright, alright. I admit it, I'm the rabbit".


A young man was pulled over by the Mississippi State Police for speeding. The officer stepped out of his patrol car, adjusted his sunglasses, and swaggered up to the young man's window. "What chew driving so fast for boy? You going to a fahhr? Let me see your license, boy." The young man handed over his license.

Then the officer noticed that the back seat of the car was full of large knives. The officer said, "Tell me boy, why you got them knives on that there back seat?"

The young man replied, "Well sir, I'm a juggler."

The officer spat some tobacco juice and then he said, "A juggler; well you don't say. Boy, put cha hands on the trunk of yer car; you going to jail!"

The young man pleaded with the officer not to take him to jail. He offered to prove to the officer that he was a juggler by way of demonstration. He said, "You can even hold me at gunpoint while I juggle for you." The officer reluctantly allowed him to prove his point while he held him at gunpoint.

Two miles down the road at Joe's Tavern, Billy Bub was drinking it up with Jerry Lee Jones. Billy Bub soon left and got into his old, rusty pickup truck. He proceeded down the road trying his best to stay on the right side. All of a sudden Billy Bub spotted the most unbelievable sight of his life! He drove to the nearest phone booth and dialed the number for Joe's Tavern and asked for his buddy, Jerry Lee.

When Jerry Lee got on the phone, Billy Bub said, "Whatever you do when you leave that tavern, don't go north on route 109. The state police are giving a sobriety test that nobody can pass!"


HELP NEEDED

[Sluggo]

On Tue, Sep 07, 2004 at 07:11:48AM +0200, Mr.Habeeb Kareem wrote:

Subject: HELP NEEDED

Sorry, you lose the TAG lottery. Not only is your subject line vague, but we don't like to be SHOUTED AT. Get a life, preferably one where you're not swindling people out of millions of dollars.

[Jimmy] Lottery... swindling... millions... hmm. Maybe instead of a 409 scam I could try a 4.09 scam.


Successful transmission

[Heather]

On Wed, Sep 08, 2004 at 01:20:32PM -0600, Michele Lester wrote:

khomifyj cdnrn zrxpwdxuu lpxgvjp? cbeyqow? atapjm
yrqhota ybnsyyeh - hkvgwm vrxxyxbnj
fcgvsfemr xvfxsdyww oicwnj, qcezf
Ierdev kbsrxtztx cegehy wmmdrkh
idadxxea czqdfbctz llvux mqkbyq

Apparently not successful, highscrabblescore encoding still present.


Best offer of the year

[Sluggo]

----- Forwarded message from "Pins U. Merle" <gardnerj@nytimes.com> -----

Subject: Read:_Best offer of this year  ;) 

Clarence Morton Esmeralda Clarence Jacques Freida Ericka Percy


Hello dear friend! I have to tell you about this incredible site
- this is totally unbelivable - it is made to make life easye.
Only imagine - all world best software collected in ONE place
and all for low prices with 80 -90% off. This lo price is because of 
O-E M licenses - that mean that you do not get a nice box - just CD.
hurry to check it up - 10 - 20 programs are added daily. You get CD and 
also a donload link so u can have your goods instantly. 

----- End forwarded message -----
Just what I need, a "donload" link.

[Neil] Is that a "don't load" link?


Russian scam

[Sluggo]

----- Forwarded message from cpeterso@sayori.dais.is.tohoku.ac.jp -----

 We are a web designers/programmers team. We locate at Moscow, Russian
 Federation. Currently, our team works for several US companies and we feel
 difficulties in getting our wages.

 They're to pay us but they don't send money directly to Russia, because
 companies we work for pays us by       direct deposits available in USA and
 Canada only. Reasonable question: why don't they pay you by checks? Yes, they
 could, but here in Moscow is really hard to collect on the American checks
 (enormous commission fees and it takes 2-3 months).

 We realize that you can't provide your current bank account. So, if you are
 ready to help, would you be so kind to open a new zero-balanced checking
 account where they could send our wages.

 So, when our employers are getting the account information they will initiate
 the transfer. When the bank transfers are completed your assistance is needed
 once again to transfer the money via Western Union or Money Gram (it is not
 the best (profitable) way but it's the fastest one).
 
 Finally, we have to solve the problem regarding your interest in this deal. We
 suppose you should get an interest in this business and we can offer you a
 good compensation for your help. If you are ready to help, please, send your
 reply at the following email address webartcenter@mtu-net.ru or my personal
 e-mail mentale_mentale@mtu-net.ru.
 
 The sum is variable but usually no less than 800-2,500 a week (approx.). Any
 suggestions?
 
----- End forwarded message -----

And what can I do with my bank account that your employers cannot do with theirs? What kind of employer can afford $10,000 per month and can't take care of this little detail?


Stop emails like this one..

[Jimmy]

Mcfadden wrote:

 Let me tell you a little bit about myself and why I am imposing on your valuable time.

 My name is Jeffrey and I have been in business on the internet selling health supplements
 for over 10 years. Can you imagine the amount of spam I used to receive daily after 10
 years of business? Let me tell you? It was overwhelming to say the least. In a short
 amount of time was very difficult to operate my online business.
So... you disliked spam so much, you decided to become a spammer? I really hope you dislike pain.

 Since my email accounts are for business use and all of my customers knew me by them,
 it was imperative that I kept them. I was determined to stop my inboxes from getting
 cluttered every day. I tried every method possible to keep my inboxes clean but it was
 getting worse by the month. After spending hundreds of dollars on spam blockers and
 countless hours I finally found the perfect solution. It is called Email Box Filter.
How about... if you want to stop spam, stop sending it?
 

 Email Box Filter was a lifesaver for me. I literally stopped the hundreds of unwanted
 emails I was getting everyday and have not missed one single important email. On top of
 all that I have eliminated any email virus threat. Here is a link where you can see all the
 facts. <http://65.182.143.77/mbfh> 
MBFH - Mail being freely harvested?

 Add your address here <http://65.182.143.77/rmm.htm>  to be taken 0ut of our datbase.
Add your address to be taken "0ut"? I can trust you, right?
> Market Researc-h 8721 Santa Monica Boulevard #1105 Los Angeles, CA 90069-4507 
> appallGkEhnhbBvytmjbhXdnndCtdnUiattractbonanzaarrayalbumcorvusallegorycheneyavaricious 
> alreadyaxisbeardareawaybritannicabestowalculbertsonaldrichdeltoidcomancheclassiccookbook


Thanks Heather. Now they're all using
                                 c
                                 r
                                damned
                                 b
                                 b
                                 l
                                 encoding

for the Kremlin, but

[Jimmy] I bloody knew it! All this spam is actually carrying encrypted messages to Ben!

Barney Swartz wrote:

Reyxzfi hsxtfofu, Alivrczjin enagm stvpl mrsmb gnkeitn pglztflj snvih qqwskq. 
kvsqee? xidnz
Dear Participant,

Recently you filled out a information request form regarding
your home mor t gage   l o an. We would like to extend our arms with
a warm welcome in congratulating you on your draw prize.
dyrvosu yowgft rvtnats jfxat rfpyekib qjmralwz zqtmn uilsel. tucpsrvef 
qebjsyovy yhetlulh exnipbscy mnddalur dhbler? Seargmhbzm Vazanl yncnezmf 
soxhwcdbc yjnifn ouygxzn, Xeyagn pikvrb vjjgnak zuwikm gzrvhnrqd Flywzrrp cjzwv 
trlidcbr pbuqelcxc lwvanybe uxmpiuf uxsdo yqosdcrgj xlnrpm zukzvwf zgkvmijeu 
vhupimesm xhdrparsg. xwgyo luytpt sxldm phvont vbqmabvgb
As indicated, 100 people randomly selected would be able to
re f i nance their home at an anual ra t e of 0.99% for 10 year.
YOU ARE ONE OF THE 100 individuals.
sqonazav bawwrvk laqtwq babvfn? krzhwbobf Ukleuhlbbe Yxqgvhcmk pezhjrxq etmqfc 
bfttn, bidnluvbx gdqmfax wneayfw Pzlknd bdbeeec? oygmezf zrclwkigv oycjaekma 
expcgx? vbfbkgi wpadgal? hbmabsx wrumu zmiczwno tlelf. tqxismaqy lkeby 
grgcsmkoa
Please fill out our online form  so we can contact you 
directly
You have limited time to apply for this offer.

Best regards,
Barney Swartz
xtiilp ijlqda rlweux mlarpxvxm vcmkdx. zmgxpq nrnqdjw dnezie wipnbj
sgfuaezu xfldlmf? llmjz adhet cprlibzjd tvxrtnmco
Vwwdtsbow njaqlrcg. ahgma, bvbwohndo jnquupmih vbvsqn Poakmwn xvfnt fqcpzscf 
mhyugoimw heqwuegjz hwradhywp wszvk Twvwrr vdimbd? morfhhae fohon gzqpwufu 
bvgzsb etsmuep? pmfwrqb - rkvjjgc aysutx mpndncjh. zbptcp hkigdlk ajqjhk 
rzjuyts Mksrvihls vtucdv vrhpvu? tvjowo zrgniqnyh dcsbzl. tnlha syzboqc 
xpvsxnlpg. tukwrmig
zcptbh qvroc qjqquyvj xzgtqygvp nuyqkre Valcoj bwrws
qtqfwadi sktruow. eagzusie Kwsoyxat rzsfefmda, mqzra Lrynlpiw kdoucqw
onsilu zdlfp wyklpy sqeirkdsp glysy Ktedjab bwixl. qavsfo
siblvreto. chcolvcid czbjmqmt - hdhbnh jhvztj - mejvteed stdgrgit smtrnk 
ujgbcjz xwwwh txwcrp sckkkrw? mdafjysep ibwvvvyjf gfatrpbib? lupcgsnk. 
nntsremae dodjdkv
feghygqbt barecc euevhctvf Sugywet govomqm wbglh syhlfbtv gsbao
itiohiw. ddwvgb fnznu Qlhwaoy gkwaofo ermrksmuk iptgc niidwpw wuxkedkk
luasfjbth cjahnbbfw Pccuhatjfg Fftnryza qzrwtq ammcc
xriki. hoybcyl? Egmwmxee ryvom Prfincey vheyuqvq gpjbjhefm mjjtuiwu - jlalm. 
ukfoq - uchimkd qmpqnsi dkyizxmg aiywgy lmxbhp ioorate nclxafnh dcaybua 
gnppfiny lkryxib hbtditata ldcclto? klyxed auseyjcct yxfyd qgnem
zomtmjcgh, lviisqj wbdwlpl. cmajiiqwg vpxcz oyqewyb
eiphhmzmb aqpfbdk xpahwme, ekxlwt sijqbar aisoa? Wnwizzsh aqkodlgxl Qotmxldhbd 
crhybq. qehfqgmi fildn gvnoim Jpghyk fwcayxk ltflxjkz fpjgwr - ublifokk. 
xcprwqkos
Vhdfejklmm Qivfnneasd itcuwz zttbvrrcs sxgfnroxn, zvxtoxy jfxuf prfotwoca 
fhrifzc wfcpuzczd mjfscs Wbwakmm gcowiwe xinwrj ftxpwssnh tjvdt pljcmwpq flqjbja

Spam, Spam, Spam

(From Rick's .sig)

[Rick] SPAM SPAM SPAM SPAM!
SPAM SPAM SPAM SPAM!
(Nobody expects the Spammish Repetition!)

Published in Issue 107 of Linux Gazette, October 2004

The Linux Laundrette

Links

Anyone who reads NTK will be familiar with their "Doh" images: now you can see this sort of thing at dohthehumanity.com (and there's an RSS Feed!).

A couple of threads got really out of hand this month, so I split them into their own thread.


The Foolish Things People Do With Other People's Computers

[A friend, who wishes to remain anonymous (case is due in court), sent this]

Well I now have an even stranger story to tell you all. It involves 5 under cover cops and me standing at a [train] station at 01:15 this morning.

The story begins some time between 15:30 and 18:00 yesterday. Someone broke into the house I am staying in. and stole a bunch of stuff including my laptop and passport.

That was that and the last I thought that I would see of those, but then the burglar in their ultimate wisdom decided to ring my mother from the number on my passport -- he was willing to return the items for a "finders fee"

I decided to let the cops in on this information and arrange to meet with him. So I was standing at a [train] station with 5 under cover cops somewhere around and this very wise burglar turned up (in his car!) to return the laptop. When he offered to sell it back the cops moved in and arrested him.

Quite mad!


Releasing the Mouse

[dups] Had to share this with the TAGsters... I have some new found respect for the abilities of my trusty linux box. Yesterday I came across a mouse that seemed to have made his home in my apartment. A super quick little blighter that was seen darting between hiding spots. I contemplated trying to catch the offending rodent, but his acceleration made him untouchable so I made a note to get hold of a trap from the store and lure the thing to its demise with a piece of cheese. That was not necessary however... the next time the rodent was sighted he was making a dash along the wall and ended it with a hop into my linux box which was on the floor with the side panel open. heh. the panel was quickly replaced, cables detached and then my 2.6.8 kernel went along for a walk to deposit the trespasser in the canyon outside my place. (although i think this particular trick may work with windoze as well)


Ginger Beer 2: Return of Ginger

[Heather] We might not be seeing much of Thomas for a few days yet; last I heard from him, his USB-connected cablemodem had exploded, and while he had gotten a replacement...

[Sluggo] First Ben and his hurricanes and laptop, now Thomas with his modem. Did Thomas leave a bottle of exploding ginger beer sitting on top of his modem?


Intestinal Fortitude

[Yeesh! July 14th? How did this slip through the cracks? Anyways, just to prove that we're not above taking swipes at pretenders to the LG throne:]

[Brian] Side-Note - How well the CMS works (not)?

http://www.linuxgazette.com/node/view/211/showterm/89?from=150

***
Linux Gazette - Front Page
Submitted by staff on Thu, 01/01/1970 - 00:00.
***

Sigh. Thank you all for the intestinal fortitude to stand for what's right, like static pages fit for the purpose! Oh, and an appropriately dried sense of humor!

[Ben] You're welcome, Brian. It's something we felt deserved to be continued, and was important to the community. As to the humor, well, we've tried making it drier, but then it gets a little too chewy and hard to swallow. We had to scale it back a little...


Foaming at the mouth

[Thomas]

On Wed, 4 Aug 2004 12:48:16 -0400
Ben Okopnik  wrote:

 I really appreciate that attitude, Thomas; thank you. My best take on
 what needs to be done? It's a little complex but definitely workable,
 frommmy perspective. Here it is, in two options:
 ^^^^^^^

Is that you foaming at the edges of your mouth, Ben?

[Ben] [wiping mouth] Nah, that's just foam from the coffee my new sweetie just made me.


Double Entendre

Yeah, missed this in the MacBeth thread.

[Jay] I'm sure by now you've heard about the woman who walked into a bar and asked the bartender for a double entendre... so he gave it to her.

[Ben] [drum roll plus sting]

Of course, an accidental double entendre (a.k.a. a Freudian slip), is when you say one thing but you mean your mother.

And then there's UK TV, which seems to have taken Benny Hill as its patron saint:

<http://www.morejokes.co.uk/jokes/825/>


Searches leading to LG

or

Cowsay

[Jimmy] From the article ideas department: I just ran webalizer over LG's logs, and these are the top thirty search terms which lead to LG.

[snip]

21 13 0.20% cowsay 

[Sluggo] Heh heh.

[Rick]

 
  _________________________________________ 
 < I'm sorry, I'm not sure I get the joke. >
  ----------------------------------------- 
         \   ^__^
          \  (oo)\_______
             (__)\       )\/\
                 ||----w |
                 ||     ||

[Heather] /me chuckles

[Sluggo]

 ________________________________ 
/ I wrote an article             \
| about it so it was amusing to  |
\ have it come up.               /
 -------------------------------- 
      \                    / \  //\
       \    |\___/|      /   \//  \\
            /0  0  \__  /    //  | \ \    
           /     /  \/_/    //   |  \  \  
           @_^_@'/   \/_   //    |   \   \ 
           //_^_/     \/_ //     |    \    \
        ( //) |        \///      |     \     \
      ( / /) _|_ /   )  //       |      \     _\
    ( // /) '/,_ _ _/  ( ; -.    |    _ _\.-~        .-~~~^-.
  (( / / )) ,-{        _      `-.|.-~-.           .~         `.
 (( // / ))  '/\      /                 ~-. _ .-~      .-~^-.  \
 (( /// ))      `.   {            }                   /      \  \
  (( / ))     .----~-.\        \-'                 .~         \  `. \^-.
             ///.----..>        \             _ -~             `.  ^-`  ^-_
               ///-._ _ _ _ _ _ _}^ - - - - ~                     ~-- ,.-~
                                                                  /.-~

[Heather] Dragon? I don't think this counted as a flame ;>

 ________________________________________________________________________ 
/ for the record cowsay defaults to 40 wide but I appreciate the hotlink \
\ being done right anyway. and a very merry un-bday to you c/~           /
 ------------------------------------------------------------------------ 
 \     , ,  ,
  \   _IiI_iI_
     {_._oo._.}
     {,=,=,=,=}
     {wwwwwwww}

Ben & Hurricanes

[Ben] Hurricane Ivan is on the way (I've always said them damn Russians are trouble...)

[Sluggo] Show me a pair of dark sunglasses, and I'll show you a member of the Russian mafia. Extortion: what apparatchiks do under Capitalism. Oh wait, they did the same thing under Communism too.

[Ben] Soft mud plus a steel boat - shouldn't be too much trouble, but - again - I'm reserving judgement until I get there. Note that both of these places are known for not getting hit: St. Augustine, in particular, has had a total of four hurricanes pass over it since 1906.

[Sluggo] Do you want me to ask the Weather Service to redirect the storm so it hits St Augustine and the "Ulysses" but nothing else?

[Strangely enough, Ben passed on this offer. It takes all types, I suppose...]

Spelling of my name...

[Brian (Bilbrey)] "-- Brian Bilbray" somehow got into Issue 106.

[Ben] Whoops. Well, I had the security guards escort him off the premises. Just because his name is similar to yours, he thought he could wander around freely... hah!


Mirrors

[David R. Tyler] You have been caught using bandwidth with your mirror.

[Thomas] Clearly, the days of using your mirror to brush your hair, are over....


Collage

[Thomas]

On Fri, Sep 24, 2004 at 12:43:42PM -0600, Jason Creighton wrote:

> What would you need to make a break from where you are? Collage?
                                                          ^^^^^^^
I don't think going out to the woods, getting some glue, and sticking leaves, pine cones, and mud to a piece of paper, while hastily tearing up pieces of paper, and calling it 'art' is going to help. :)

Kludge

[Jason]

On Sat, 11 Sep 2004 09:23:04 -0700, 
Mike Orr  wrote:


 HIMEM was a DOS kludge.
             ^^^^^^^^^^
No need to repeat yourself. :-)

source

[From Thomas's .sig]

[Thomas]

$ source ~/.bash_history

[Ben] Eeep. [thinks about it some more] EEEEEP!!!


Even More Stuff Goes Wrong...

[Ben] As if I haven't had enough crap to contend with this month... my mail redirector, ben@[domain name dot org], has suddenly died (it still accepts the mail - just doesn't forward it.) I've filed a ticket with the folks that host it, but meanwhile I've got two days worth of mail that's hanging in limbo.

[Jimmy] Well, of course it had to happen. You told everyone but yourself to save their equipment failures :)

[Ben] I guess that's why my customized overhead high-pressure zone went away, so Hurricane Jeanne is aimed dead at me right at the moment... 60 hours or so till impact. As if we hadn't had enough of'em.


Limitations of email

[Thomas] Enforce it as the author's responsibility to do that

[Ben] Well, I haven't quite mastered twisting people's arms via email - the force component is fairly hard to transmit, particularly those tiny but all-important wrist-turning vectors - but I can certainly add it to the authors' FAQ, once we decide on what "it" is, exactly.


Subversion

[Sluggo] Subversion is wackoed again

[Jimmy] And don't look now, but it's wackoed again again.

[David] And Yet Again...

[Ben] Unwackoed again. I wonder what the problem is, lately.

[Jimmy] Gremlins. Someone's been feeding them after midnight.


The Horror...

[Jason] I wanted a photo off my parent's digital camera. They have Windows ME.

[Ben] Jason, you ought to be ashamed of yourself. How could you do that to your poor parents? There I was, thinking of you as a responsible sort of geek, and you let those poor innocents be abused by that horrible creature from Redmond!

(Say, perhaps we should make a horror movie.)

[Jimmy] Voice over: It was the time of twilight, a time of mortal men and a time of immortal evil. A time when the young offered the aged in bloody sacrifice.

[Ben] Right... let's see, who could we get to do Vincent Price's voice for this? I mean, we need creepy here. Hmm, wonder if John Ashcroft is available.

[Jimmy] Who could star? Wonder how much Christopher Lee charges?

[Jason] sob I'm sorry! I didn't know better at the time!

[Ben] There, there. At least now you know how to make the boo-boo awwww bettah. :)

[Jason] Windows was hanging on me

[Ben] Yes, it'll do that. I've found that a good prybar is usually sufficient to break the grip, after which that same implement can be used to threaten the monster until it realizes the futility of its endeavor and shambles off in search of other, more innocent victims.

[Jason] Wait...a greater quanity of innocent victims, or victims not as guilty as me? :)

[Ben] Were you looking for any answer other than "yes"? :)

[Jimmy] Ben, we're making a movie here. It's not a "monster", it's a "fell beast, rent from its evil age, when... etc".

[Ben] Uh-huh, "rent from its evil age". How much rent are we talking about, here? (And what's an "evil age", anyway? Late teens to early twenties, or what?) Sheesh, trust an Irishman to slip in an old political issue when no one's looking...

[Jimmy] CUT! Script check!

"The fell beast, torn from aeons past, when evil wore the blackened sky as a cloak."

Better?

[Jason] No, I'm thinking more along the lines of a reality TV show: "Big Brother XP"

Watch as millions of people from across the country volunteer to live with the Windows operating system in a desprate attempt to get work done. See the anger: "What...illegal operation!? I NEED THIS REPORT NOW!". See the deception: "Okay, the box says it works with my version of Windows, and I installed the drivers right, so why doesn't it..." Watch as secret alliances are formed: "I want to uninstall IE...what do you mean, it's part of the OS?". Feel the betrayal: "What, 50 uses and then I need to 'register'? But...my computer crashed, and when I tried to register after I reinstalled, it didn't work! I PAID for this software!"

You can watch "Big Brother XP" 24/7 anywhere Windows runs. (Or rather, anywhere Windows doesn't run in a very specific way.)

[Ben] The subtle, unobvious effects are the worst ones... but I suppose we could provide an MP3 of some creepy music to at least hint at it.

[Jason] Seriously, at the time they purchased the computer, ME had just come out, so I thought "hey, why not". I now know why not, and wish I had just told them to go with 98SE, which is not supposed to be as bad.

[Ben] Say, didja hear about the latest version of Wind0ws? It combines the three most popular versions and is named after them: CE/ME/NT. Once it's in your computer, it sets solid and can never be removed...


Song of the Month

[Or a month at least... this is from June, but since Sluggo added a song last month, I figured it should go in (and it's not because I found a cache of mail I'd saved, honest!)

Of course, my own choice would be different; "Death Certificate", "No Love Lost", "Mayonaise", "Slave New World", or "Dead Skin Mask"]

[Ben] Just saw this on a list; 'The Poet Cranky' theme has produced some great results. This sounds like something the Rolling Stones might have done... or Pink Floyd, from a slightly different perspective. :)

"The Bloody Orkneys"

This bloody town's a bloody cuss
No bloody trains, no bloody bus,
And no one cares for bloody us
In bloody Orkney.

The bloody roads are bloody bad,
The bloody folks are bloody mad,
They'd make the brightest bloody sad,
In bloody Orkney.

All bloody clouds, and bloody rains,
No bloody kerbs, no bloody drains,
The Council's got no bloody brains,
In bloody Orkney.

Everything's so bloody dear,
A bloody bob, for bloody beer,
And is it good? - no bloody fear,
In bloody Orkney.

The bloody 'flicks' are bloody old,
The bloody seats are bloody cold,
You can't get in for bloody gold
In bloody Orkney.

The bloody dances make you smile,
The bloody band is bloody vile,
It only cramps your bloody style,
In bloody Orkney.

No bloody sport, no bloody games,
No bloody fun, the bloody dames
Won't even give their bloody names
In bloody Orkney.

Best bloody place is bloody bed,
With bloody ice on bloody head,
You might as well be bloody dead,
In bloody Orkney.
-- Hamish Blair


Grocers

[Jimmy] For me, a grocers is any place that has a sign outside that reads "apple's and orange's".

[This is called "The Greengrocer's Apos'trophe", according to pTerry. Read "Eats, Shoots & Leaves" by Lynne Truss]

[Ben] Err... wouldn't that make "Boots-pharmacy" a grocer's? Or would that be "a grocers", instead?

[Jimmy] Nah. Though it should have had an apostrophe (as it was founded by John Boot), "Boots" is the name, so it doesn't need one. Anyway, we have to give the pharmacists a break -- they have to learn to read doctor.


More Hurricanes

[Thomas] Walmart? I thought they only sold food? Mind you, at the equivilent pound sterling to dollar ratio, $999 for that spec laptop is pretty good.

[Jimmy] From what I'd heard, the only things they don't sell are weapons of mass destruction, but it's only a matter of time before the UN send around some inspectors to confirm this.

[Ben] Weapons of Mass Delusion, you mean? Oh. I'd been wondering where Bush and Co. got'em. "Special, today only! $29.95 Billion per set, they have no width, height, depth, or mass - but tons of political spin and charm! [1] Get yours now, and you'll never need to look for another reason to start a war! Karl Rove propaganda machine not included."

[1] A rather quarky way of looking at things, to be sure...

[Jimmy] We have all the wars you'll ever need -- conveniently placed Eurasians^WArabs who'll drive your approval ratings through the roof!

[Ben] In theory, I'll be getting my Acer laptop back on Tuesday, but I needed contact with the world NOW. Particularly since we've got some nasty weather that I need to monitor - not hurricanes, thank the Great Ghu, Jeanne and Karl having sheered off (at least according to the NOAA predictions), but remains of Ivan; they were calling for 35-40 knots by tonight through tomorrow afternoon, but have now changed that to 20-25kt from tonight (and that is about what we've got at the moment) through Monday night. I'd be the last one to complain about that, although the smaller boats here are in for a rough ride...

[Thomas] I'm glad things are OK, and that nothing particularly bad happened. My aunt and Uncle were on holiday in Florida with my two cousins when Ivan came along. Heh, no Disney for them.. woops.

[Ben] Yeah - whoops. No Disney, no big deal. Decapitation due to flying galvanized roofing - that would be a big deal. I'm glad that they're OK enough to worry about Disney. :)

[Jimmy] Nah. Stand outside with a large umbrella - it's sure to be more exciting than any rollercoaster.

[Thomas] Hehehe - I just don't think they quite envisaged spending their holiday locked up in a room for fear of flying house parts. :)

[Jimmy] Sounds like my last holiday. (I had a little too much to drink...)

[Ben] Funny, I'd have thought you folks would be used to that. I understand everybody in the UK used LSD every day until the Euro came in... :)

[Ben means decimilisation -- Britain doesn't use the Euro]

[Thomas] That explains why my parents are strange.... :)

[Ben] [Sluggo is] A prince of a fellow, although I wish he'd tell his cow orkers at [snip] to send all those hurricanes elsewhere, like they did with J and K. Whoever was in charge of Ivan should get a strict talking-to, and maybe a remedial driving class.

[Sluggo]

 -----------------------------------------
/ I'll huff, and I'll puff, and I'll blow \
\ your house down!                        /
-----------------------------------------
 \            .    .     .
  \      .  . .     `  ,
   \    .; .  : .' :  :  : .
    \   i..`: i` i.i.,i  i .
     \   `,--.|i |i|ii|ii|i:
          UooU\.'@@@@@@`.||'
          \__/(@@@@@@@@@@)'
               (@@@@@@@@)
               `YY~~~~YY'
                ||    ||

(That's a flaming sheep, or couldn't you tell?)

[Ben] I guess that would be a sheep orker, then. Well, Mike, you're the fellow who gets to see them every day... I guess you know best. :)

[Sluggo] A what? I googled for "sheep orker" and found only one entry on a Swedish bulletin board: "det finns flera som ej vill ha allians me orker", whatever that means.
http://www.tradition.se/klotterplank/Forum25/HTML/000671-2.html

[More of this thread]

[Ben] A sheep orker is just a little smaller than a cow orker, as well as somewhat more hairy.

[Sluggo] Sounds like the seapig we named our Python group after.

http://seapig.org/SeaPig
http://tv.cream.org/gorilla/seapig.htm

[Sluggo] A radio analyst said the storms form in east Africa and travel across the world. He also said it's not a question of Florida being unusually hit this year, but rather of being unusually lucky the past thirty years.

[Ben] Yep, the low pressure moves off the Sahara and continues to grow when the moisture-retaining capability of the air exceeds a certain point. After that, the ITCZ (Inter-Tropical Convergence Zone) is responsible for moving it along, and the Coriolis effect gets it spinning.

[Jimmy] Which, of course, is all started by a butterfly flapping its wings.

[Sluggo] Although why a storm would dare attack when Ben Okopnik is on watch is beyond me.

[Ben] As they say in Spanish (from the obvious Arabic root), ojala! Or, in a dialect closer to home, "From your mouth to God's ears."

[Jimmy] It didn't - it snuck in while he was in New York. It's not that stupid.

[Sluggo] Gosh, and the first hurricane stuck when it thought Ben was going to Oregon, but he changed his mind at the last minute. I guess the hurricanes don't get news from Echelon, which tracks all Russian spies.

[Jimmy] Nah. The butterfly had already done its job by then.

[Ben] The most annoying part of this laptop-buying game is that there's usually no easy way to find out what the chipset is unless you buy the thing (or take it for a test drive. Hmm, firing it up in the store with a Knoppix CD might be an idea...)

[Thomas] Not to mention, you'd get thrown out. :)

[Jimmy] "You open it up and poke at the circuitry, you bought it" doesn't have quite the same ring. If they question the Knoppix test, you can tell them to think themselves lucky you didn't try the coffee retention test.

[Ben] Coffee retention test? Quite apropos, especially since I just got an email from a Perl list with an interestingly mispeled term:

 It accepts as input two base10 numbers, converts them to two unary
 numbers, performs urinary multiplication
                   ^^^^^^^

Seems like that would be a part of any coffee-retention test performed on computers...

[Jimmy] Urinary multiplication? My Dad's signed up for that.

[i.e., he's on a waiting list for a kidney transplant]

Wacko Topic: Swedish

[Sluggo] The person writes in capitals like he's really excited: "okej före första VÄNTA TILLS ERAT SVAR BLIVIT BEKRÄFTAT INNAN NI STÄLLER EN NY FRÅGA!!!!"

Anybody know enough Swedish to translate? I think it's something like, "OK for the first ... powered ... places in our question."

[Martin Pagh Goodwin] For the swedish content - my shot at it is as follows (I'm only danish)
det finns flera som ej vill ha allians me orker - There are many who will not ally with the orcs
okej fvre fvrsta VDNTA TILLS ERAT SVAR BLIVIT BEKRDFTAT INNAN NI STDLLER EN NY FREGA!!!! - okay firstly WAIT TILL YOUR ANSWER IS ACKNOWLEDGED BEFORE POSING ANOTHER QUESTION.

Orcs is also translated to orker in the danish version of LoTR that I posess.

[Rick] I have a secret weapon: a Swedish mother-in-law. So:

"Wait until your question is confirmed before you place a new question."

(How a Norwegian-American like me ended up with a Swedish mother-in-law -- unlikely to those familiar with Scandinavian international relations -- is a conundrum known to but few.)

[Rick's sig:]

The Viking's Reminder:
Pillage first, then burn.

[Martin] Do you know the origin of your surname? My guess would be the name of a danish island: "Mon", where "O" is usually replaced with "OE" in societies with limited alphabets.

PS I see your signature is playing tricks on you again.

[Jimmy] Rick, is your .sig generator also ESP enabled?

[Rick] Yes, I'm certainly aware of the island of Møn -- it has a Web site. ;-> See also: http://linuxmafia.com/~rick/faq/index.php?page=misc#moen I like the story of how the residents blew up their own castle, rather than let Christian III have it (1534).

I've always assumed that the family surname was from Denmark on account of the historical connection. Dad was born in Kristiansund near Bergen, but possibly there's Danish ancestry in the more distant past?

One of these days, I'll get some Norwegian or Dane to sit down with me and tell me how it's really supposed to be pronounced, just so I know. (The American branch of the family pronounces it to rhyme with the English words Bowen or rowan: The Continental branch was, I hear, almost entirely wiped out by the firebombing of Kristiansund during the war.)


Wacko Topic of the Month: Supermarkets

[This stemmed from the hurricanes thread. Right about now, a quick show of nationalities might clarify things: Sluggo and Ben are American, Thomas is British, Jimmy is Irish, and Frodo is from the Netherlands. For more information about supermarkets, see Wikipedia's overview articles Supermarkets in the United Kingdom and Supermarkets in the United States.]

[Ben] Got a hold of an Averatec 5400-series laptop from Walmart - $999, Athlon XP-M 2800+, 15" TFT screen, 802.11g, VIA chipset, DVD+/- RW burner, 512MB/40GB, and a 15-day no-hassle/no-charge return policy [grin]

[Thomas] Walmart? I thought they only sold food? Mind you, at the equivilent pound sterling to dollar ratio, $999 for that spec laptop is pretty good.

[Ben] Nope - they only sell food at their "supercenters" (which this one is); usually, they do the clothing/hardware/furniture/etc. type of thing.

Very successfully, mind you; out of the ten richest people in the world, the Walton family occupies positions four through ten (or did, a while back.) If old Sam was still alive, his yearly income would be larger than many small countries.

[Thomas] Oh, I see. We have those kinds of shops here, although on that scale, I'd be more inclined to label them as departmental stores -- say "John Lewis" which are a famous chain here.

[Ben] Yep, that comes close - although I think of department stores as a niche that got coopted into whatever you'd call Walmart/KMart/Target/etc.; they're quite a bit more handy than, say, the old Woolworth's department stores ever were.

[Sluggo] Woolworth's was already in decline when I was born so I never saw one in operation. They've left some historical storefronts that now house other retailers. I think Woolworth's was what we called a "dime store" in the 60s, a place that had small non-food items for a dime (supposedly).

In Tacoma there's a Piggly Wiggly that may be the last of its kind in the west. Kind of like a dime store anachronism. Although I hear Piggly Wiggly used to be a big grocery chain back east. Tacoma is kind of the place chain stores go to die. There's a Frisco Freeze (like Dairy Queen) and I think there's an A&W. There's also the Java Jive, a run-down bar that's shaped like a tea kettle.
http://pnwbands.com/javajive.html
http://www.beans-around-the-world.com/java.html
http://www.bipolaraudio.com/bobs_java_jive.html

[Sluggo] When I was in Bristol the people in the hostel recommended a cheap supermarket, so off I went for provisions. It was a half hour walk away. It turned out to be the German company Aldi, if I remember right, which I've also encountered in Germany. It's not a supermarket as I think of it because they don't seem to sell large portions of anything, so you don't get the economy of size. I don't mean the large wholesale sizes but the medium sizes you find at Safeway (US) and Sainsbury's (England). (Which, by the way, I could not find at all in Germany, although maybe I wasn't looking in the right places.)

[Thomas] I like Sainsburys. There's three main [supermarket (see next comment)] leaders here:

Tesco [Wikipedia article]
Sainsburys [Wikipedia]

[Sluggo] Sainsbury's is just like an American supermarket. Tesco here is a chain of gas stations, not supermarkets.

[Thomas] I guess you can't really eat that, then.

[Jimmy] Yeah. Horrible indigestion.

[Sluggo] Of course, we're still trying to figure out how Virgin can be an airline, train line, and cybercafe chain, since we thought they were a record store.

[Wikipedia has an article explaining the Virgin Group]
[Thomas] Hehehe, Mr. Branson certainly has his finger in many pies.
[Jimmy] Shh! He'll open a chain of bakers next.

[Jimmy] Well, it started as a record label, and has since become Richard Branson's brand for everything he does (except the original Virgin Records, which is no longer his -- his record label is V2).

[Thomas] Asda (Walmart owned) [Wikipedia]

[Thomas] Along with them come:

Aldi [Wikipedia]
Lidl [Wikipedia]
Morrissons (apparantly famous more ooop North of England, chuck) [Wikipedia]

Hehe - to me, a supermarket is a place one goes to buy food from. Although many do now tend to sell other items such as cheap clothing, and microwaves, but the scale is still very small.

[Sluggo] That's not a supermarket. :) A supermarket is a large store that sells food in family-sized portions, competes mainly on price (although Whole Foods specializes in organics and natural foods), and tries to stock every conceivable type of food. It contrasts with the small mom-n-pop grocery stores that have almost entirely disappeared.

[Sluggo] Not to be confused with the current "convenience stores"/"mini marts". The old grocery stores had fresh vegetables, meat, and milk. The convenience stores are mostly candy and cigarettes. Some convenience stores that's all they have. At better convenience stores you can find a sandwich, apple, and milk, and nowadays even a premade salad, but you're lucky if you can find an egg, and don't even think of shopping for whole vegetables there, there aren't any.

[Thomas] Yes, I agree entirely with that. What you call "mom-n-pop", I'd classify as a "corner shop" - usually family run, and stocks up on the basics such as bread/milk, and often sells many tinned foods.

[Sluggo] They are called corner shops in places that actually have them on every corner; e.g., parts of New York City. The rest of us can only wish they were so common.

What I remember in England and Ireland is the shaverma/kebab holes-in-the-wall, and curry chips. There's nothing like that here.

[Ben] "Here" obviously not being Brooklyn. Or pretty much any borough of NYC, although you'd have to look for a while in Staten Island. In Brooklyn, though, you can take your pick among the Greek, Arabic, and Israeli versions - all within a few blocks of each other. Although for Greek food, you're best off in Queens... don't get me started. The NYC food scene is amazing, and in my experience unique.

[Sluggo] I'd take a shaverma (gyros) over a taco any day.

[Ben] Pshaw, there isn't even any comparison between the two. Although the Veracruz (right by the Manhattan Bridge, on the Brooklyn side) makes tacos that even I will grudgingly admit to be real food.

[Sluggo] Any place that sells a variety of food I would call a "grocery", whether large or small. But a dedicated meat/fish store or vegetable/fruit store I wouldn't call a grocery; I guess because you can't obtain a complete meal from them.

[Thomas] To me, a grocery store was one that predominently sells fruit and vegetables -- and they're very hard to come buy now. So I suppose the term is now being used here to describe the corner shops, above.

[Sluggo] Supermarkets usually have small non-food items like utinsels, paper, and cough syrup, but I've never seen one selling microwaves or clothing. Safeway did sell a small line of TVs twenty years ago, but not now.

[Thomas] Fascinating. It's these little nuances that I love. :)

[Sluggo] Supermarkets are often paired with drug stores, which were originally pharmacies but also sell small non-food household stuff: school supplies, kitchen supplies, razors, walkmans and cameras, and Halloween costumes. Boots in England is a drug store. (Why does it have a name like Boots if it's not a shoe shop?) I think you call drug stores something else in England but I can't remember the word.

[Chemists]

[Thomas] Pharmacies are strictly for medications, although they too are getting rarer and rarer as stores such as Boots take over (they have subsidery firms: Boots-pharmacy, etc.). As to why it is called Boots - I believe it to be the surname of the founder. They're an old company and back then, it was tradition.

[Sluggo] Department stores like Macy's [Wikipedia] and Sears [Wikipedia] sell clothing, "large" things (tables, beds, stoves and refrigerators, bathroom cabinets), wedding and crystal stuff, etc. Sears also sells mechanics' tools. Nordstrom's is also considered a department store, although it only sells clothing (mid-level and high-end).

[Thomas] Yup - then "John Lewis" and "Debenhams" over here are such examples. If you get the chance, you should take a look around one sometime... they're quite good.

[Sluggo] Then there's the big stores like Fred Meyer, Target, Wal-Mart, and K-Mart that don't really have a name. They aren't department stores because they aren't posh enough, but they're not drug stores either because they have a wider selection of small non-food stuff, and they often have lots of clothing and TVs too. Nowadays they've come under the generic classification of "big-box stores". A few of them have entire supermarkets inside them.

[Thomas] You mean like the equivalent of France's hypermache?

[Sluggo] Then there's wholesale clubs like Costco and Sam's Club. Costco started in the late 80s, and were originally meant to sell to small businesses rather than individuals, but you could also get a membership if you worked for the government or belonged to certain credit unions (=non-commercial banks). But families with children quickly realized that wholesale sizes were perfect for them and fanagled a membership any way they could. Then the explosion of credit-union membership brought a ton of new members indirectly. I don't know why Costco continues its facade of membership restrictions and being "mainly a small-business supplier", but they do. Sam's Club, which is owned by Wal-Mart, appeared in the region in the early 90s, but we didn't hear about Wal-Mart itself until years later, and a Wal-Mart store didn't actually appear in the region until around 2000.

[Thomas] Yes -- I think what you're describing here is what I would call "cash-n-carry" places. You can buy things in bulk at cheap prices. The classic one being "Macros" - you have to be a member to shop there.

[Sluggo] What I mean is, Aldi seemed more like a huge convenience store, and while it did have things like yogurt and bread it was all small portions at convenience-store prices. I didn't expect to find Safeway and Sainsbury's per se in Germany, but I would expect that German families would have something to say about having to buy convenience-store portions for a family of four week after week, unless there are in fact some supermarkets somewhere that I didn't see.

[This split into a chat about unions]

[Jimmy] From what I was told, Aldi is owned by a German, whose brother owns Lidl (same sort of supermarket). Aldi and Lidl are great if you want cheap booze or German food, but most people I know shop there for cheap electrical goods.

[Frodo] As it happens, I read quite a lot about especially Aldi. Every German computer magazine has to explain every now and again, why Aldi in the northern part of Germany often has different pc's and other hardware on offer, than the Aldi in the southern part.

Aldi was started in the German city of Essen, in 1913, by the father of the current owners. In 1960, the Albrecht brothers decided to split Germany in two halves, north and south (Aldi Nord and Aldi Sued), and each of them would only be allowed to have stores in their own part.

They split the rest of the world too, btw. Aldi in Belgium, Denmark, France, Luxembourg, Netherlands and Spain are owned by Aldi Nord, while those in Australia, Austria, Great Britain, Ireland and the USA are owned by Aldi Sued. (Yes, I had to look up the exact way they split it)

Lidl started as Lidl & Schwarz, and is a much newer company (they first started in the seventies, in Ludwigshafen, also in Germany) and is owned by the Schwarz-group.


Wacko Subtopic: Unions

[Sluggo] Then I caught up with my friend and he told me the store was owned by [supermarket]. I was immediately crushed at buying from there, due to their tradition of skimping on workers' pay, being hostile to unions, etc.

[Thomas] Really? How is it they can be so cruel?

[Ben] Money talks - and when money says to the mayor of Buttwipe, Nebraska "we want an exclusion/exception/easement on the following local laws, or we'll take this store and its 2,000 jobs elsewhere", money gets its way. Conversely, "Governor, we're planning on giving $500,000 to your favorite charity. Sure, it's a tax write-off for us, but we still get to decide which charity! By the way, you were going to vote our way on the upcoming bond moratorium, yes?" is even more effective; a stable of tame politicians, particularly at the higher levels, can do wonders for a large business.

Oh, and the above examples are fairly crude ones. It would still happen exactly the same way, but the wording would be such that it could never be construed as bribery or coercion - despite the fact that it is.

[John] ... and his favorite charity no doubt is his campaign fund ... or his family trust fund. :^>

[Jimmy] Not necessarily - a lot of charity money comes from these sorts of deals. Government types like to associate themselves with charities, because it earns them brownie points with voters. The more their charity gets from their involvement, the better their reputation looks.

It's also a great way for the rich to network - companies with cash to spare might not need a friendly senator now, but they know they probably will at some stage; a senator might not need to know where to find a large sum of money now, etc.

It's all based in the simple psychology behind making friends; if you act in a friendly way towards someone, they will think favourably of you. Where you or I might buy someone a drink or take them to dinner in order to get to know someone, the mega rich throw a large sum of money at that person's favourite charity - it's the same gesture, but translated in terms of bank balance.

[I wanted to have:

That type of "money talks" is depressingly common all over the [Country], not just with [supermarket]. Sports teams use the same threat to get free stadiums built: "build it or we'll leave". [Company] played three states against each other to get the sweetest deal for their [snip] plant. (Oops, I'm not supposed to say that when [inhabitants of a certain continent] are listening, because the mantra is that [other company] is subsidized by its governments and [company] is not.)

but [Person]Sluggo made me put down the scissors - I've cut myself enough this month - and put back all the proper nouns.

Remember kids - never use scissors without adult supervision!]

[Sluggo] That type of "money talks" is depressingly common all over the US, not just with Wal-Mart. Sports teams use the same threat to get free stadiums built: "build it or we'll leave". Boeing played three states against each other to get the sweetest deal for their 7E7 plant. (Oops, I'm not supposed to say that when Europeans are listening, because the mantra is that Airbus is subsidized by its governments and Boeing is not.)

[Jason] Oh yeah. In my area, a developer is planning to build a "mega-mall" seems to get quite a lot of cooperation from the city council/county commissioners/etc. A large percentage of "letters to the editor" seem to to go something like this:

Proponent:
You can stop growth! And think of how great this will be for the economy!
Opponent:
This is the last best place! Growth for the sake of growth is the ethos of the cancer cell!
Proponent:
That's not a fair comparision at all! It's people like you that hold back this area!
Opponent:
I didn't move here so I could shop in big-box stores! And let me tell you something...

...and so on. I personally don't care very much, I just wish the "powers that be" would start thinking right now about the horrible infrastructure problems that will crop up in five years. Gee, you mean if this mall goes in the traffic problem's gonna get worse? Whodathunkit?

[Sluggo] The reason people are so uniquely enraged at [supermarket] is that its famous low prices are borne by the employees to an extent not seen at other stores. Low wages, no benefits, "off the clock" work, part-time positions, etc.

[Jason] Then why do people work there?

[Jimmy] I can answer this one, as I am working in a place with conditions not far removed.

For those who either are unskilled, lack documentation of these skills, and/or have not got the self-marketing ability to sell their skills to employers, there are few options available when it comes to jobs.

Using myself as an example, I dropped out of college because I had chosen the wrong course, and couldn't afford to return. I took the first job that came my way, as a web designer, but soon got loaded down with other tasks I simply wasn't being paid for. I quit that job, got "unemployment assistance" (£37/week - roughly $50), quickly built up debt, and had to take the job I'm currently in, where I'm earning enough to pay my child support payments, but not enough to set aside money to make a break from where I am.

One of my friends from college, the second most gifted programmer I ever met (and that's because chance found me sharing a taxi with rms the first time he gave a talk in Ireland), currently stacks shelves in a supermarket. (Just to illustrate, in his third year in college, while trying to write a game, he wrote his own windowing system.)

I know plenty of people who didn't even get the chance to screw up in the ways I did, and who had no other choice but to accept these sorts of jobs.

[Another sub-thread: College]

Wacko Topic: Bad Luck

[In which Jimmy (erm... that would be me) gets to whine about another injury at work. Read the full story]
[Update, 29th Sept. I met a woman from my former shift today. She tells me the rumours are that I cut my whole hand off, and was found unconscious from blood loss. Don'tcha just love "Chinese Whispers"?]

[Jimmy] Fate intervenes - I might have to leave it till next month because I had to get a few stitches in my hand (yet another work related injury) and I might not be able to do enough typing one handed.

[Ben] GRRRR! What is this, the bad luck season?

[Jimmy] (This is going to take a while to type)

I changed shifts 4 weeks ago, so my brother and I would be able to start a band. After 3 years without an accident, I've had 2 cuts and a fall since then. On my third day, I picked up a knife, thinking it was one of the half-blunt knives we use, only to find (when it was stuck halfway into my knuckle) that it was one of those used in the beef area. Although [person] is supposed to be a trained first aider, he just stuck a plaster on it, and taped it down when the blood washed it off, thereby making it worse. In hindsight, I should have demanded to be taken to the hospital, but instead trusted that he would do the right thing. It healed before I could make it to a doctor, and I no longer have feeling in that knuckle.

[Potentially libelous statement removed]

Today, I had to dispose of the hoop blade we use. We have been told constantly that we have to throw these into the skip. This is, it turns out, wrong in so many ways, but as it left my hand, it snagged on my jacket, and cut through my finger, I think to the bone (I didn't ask, because I didnt want to be sure - I was keeping a positive outlook, but just barely). The only thing that's worrying me now is the thought that I might lose feeling in my finger too.

So... the job hunt is on with a vengeance.

At least I have my heavy metal cred (Tony Iommi, guitarist of Black Sabbath, lost two fingertips in a factory accident the day before the band were due to go on their first European tour. On his fretting hand - ouch!)

[Ben] There are three hurricanes out there - Jeanne (which has already killed 600+ people in Haiti), Karl, and Lisa. At least I've got the Acer laptop back, and it seems to be working OK so far.

All the rest of you - would you please save up your accidents, equipment failures, etc. for later? If you use them all up now, you'll just be bored for the rest of the year, and won't have anybody to blame but yourselves.


Wacko Topic: College

[Jason] I'm 17, and will graduate from high school next spring. I think I'm interesting in a job in programming (or software engineering, or whatever they call it.) but I'm really trying to avoid going to collage, unless there's some practical way I could do it without going into debt.

[Thomas] Unfortunately, I don't think you're going to get much of a choice. The world is increasingly operating around pieces of paper. You could be God's gift to programming, but unless you have the piece of paper to say you have done XYZ you're not likely going to be considered.

I'm at University (is that what you call College over there?) and am doing Software Engineering. I love programming, always have. There's a bias on this course that is Java. Why? Because currently that's what is the industry "favourite". I won't be doing any C (or C++) since it is considered too "difficult". So what I have taken to doing in my assignments, is to put the Ruby equivalent of code and show the lectureres the difference -- outlining key features that prove a point.

Why? Well, I do not like the fact that there is a bias. I realise that they need a language to suppliment the "theory" of Object-Orientedness, but Java? It's slow, bloated and this nonsense of WORA "Write Once Run Anywhere" is a myth. What it actually means is: "Write once, watch it run on Solaris and some Linux systems, and debug everywhere else".

[Jimmy] Well, there's the big difference. In Ireland, fees are paid by the government; there are at least two grants, which cover rent, for those with lower incomes; and anyone over 21 who has been collecting social welfare payments for at least 6 months can go to college, with fees paid, a full grant, full weekly social welfare payments plus rent allowance, which is roughly 2/3 of the average rent price, and an annual book grant.

Now, even with that, I'm surrounded by people who couldn't afford college.

[Jason] And plus I need to see how I do with large projects. Most of the coding I've done is just small stuff that I hacked together because I needed that tool. So I'm trying to hack up a tetris clone in C using SDL (about 375 LOC, working okay, color scheme and keys hardcoded, two player support is an UGLY kludge, but I feel pretty good about it) in order to determine if I could work on larger programs. The jury is still out on that.

[Thomas] You shouldn't look at it like that, Jason. If you ever find yourself working on a project that is large you'll only ever work on a small subset of it. You might never even know what it is you're working on overall. You'll normally work as a team, and get given a small task to do.

If you do take a Software Engineering course, I'll tell you that if you think it is all about 'coding' then think again. It's not like that anymore, where people sat up till some uneartly hour in a dark room lit only by a monitor. What you'll find is a most invaluable role as a software engineer is program design -- actually designing how the program works (UML essentially). You'll probably never end up writing the raw code. Finding a job that does is going to take you a very long time, and if you do, it won't be that well paid.

[Jimmy] Well, you have to learn to walk before you run. Small projects can become large projects if you keep at them.

Basically, it takes 2-4 years to become good at something, 2-4 to become great, and roughly 10 to become a master.

[Jason] I don't care very much which language I'm using. It would be great if I could use a "fun language" like Ruby or Python, (or maybe even Lisp, if I could wrap my mind around it.) but it looks like you have to go with

[Thomas] One of my units is on AI, using prolog and lisp. Lisp is an excellent language. Logical and useful. Just ignore EMACS. :) The language you'll use means nothing unless you have the transferable skills behind it, such as OO, etc. After that, all that really should remain when you switch between languages is syntactical issues and idiosyncrasies.

[Jason] "what's cool" at the moment. It looks like Java used to be cool. Now it looks like C#/.NET is the cool language, the one that everybody wants to use, just because it's new and it's from Microsoft. At least it has garbage collection.

[Thomas] Don't believe the hype.

[Jimmy] Learn the "fun" language, and at least one "work" language. Smart employers will still look for Java or whatnot, but knowing Python or Ruby (or Perl, or Lisp, or ...) screams "I like programming".

I wouldn't rush to follow fashion here. C# is basically Java with all the features they haven't gotten around to adding to Java yet. If you know Java, you can get the gist of C# in a few hours.

[Jason] And that's why I'm writing this tetris clone in C: C isn't the most popular language around, but it's a whole lot more popular than Ruby. It

[Thomas] No? Where did you think that? C is used extensively in industry, and popularity is propoganda. Ruby is certainly used a lot, more than you think in industry.

[Jason] seems to me as if I should learn as many marketable languages as I can, and C seems simple and scary, whereas C++ seems complex and scary.

[Thomas] Heh. Keep at it.

[Jimmy] C++ looks complex and scary when you take a distant look at it, but if you take it in stages, it's not as bad. Look at it as a better C first - use function overloading, and default values. Then add classes, then constructors/destructors, then virtual classes, then operator overloading, then templates. It starts to make sense after a while :)

[Jason] So, if you were me, wanting to get that kind of a job, what would you do?

[Thomas] I understand that the College system works differently over there, and that you have to finance yourself? If you can or, indeed, do, get the option of going to college, please take it. As I said, it's paper these employers want.

[Jimmy] Or, if you have an Irish grandparent, you can get Irish citizenship, move here for a while, bum off our social welfare system, and get a free education. :)

[Thomas] I hope this helps.

[Jimmy] Well, as it happens... I'm learning Java servlets and JSP, because that's where 9/10 jobs are. I'm learning C++ because it is scary, and looking at C# because the niftiest desktop software for GNOME is being written in it.

I'm also looking at C, just because I want to learn how to use mmap()

[Jimmy] One of my friends from college, the second most gifted programmer I ever met (and that's because chance found me sharing a taxi with rms the first time he gave a talk in Ireland), currently stacks shelves in a supermarket. (Just to illustrate, in his third year in college, while trying to write a game, he wrote his own windowing system.)

[Jason] His own windowing system? Like, doing raw hardware access like most X servers do, or just chaining onto something else? (Like Xnest, except, of course, not doing a mini X server, but doing a mini whatever-his-server-was)

[Jimmy] It was in DOS, so there was assembly which controlled DOS's video interrupt, on top of which he wrote various functions to draw shapes, on top of which he had higher level windowing functions.

[Jimmy] I know plenty of people who didn't even get the chance to screw up in the ways I did, and who had no other choice but to accept these sorts of jobs.

[Jason] Yeah, I figured it certainly wouldn't be because they want to work at [a supermarket]. Or a gas station. Or any other low-wage dead end job.

[Jimmy] Well, just to point out that it hasn't been all negative, I would never have found the drive or sense of self-acceptance I now have without working in the worst place I can imagine :)

I've also learned how well I can keep my head in a crisis, which is pretty well. I've been faced with large fires in an area covered in fat, massive gas leaks - the steps I took are now the company policy,

Published in Issue 107 of Linux Gazette, October 2004

The Backpage

By Ben Okopnik

"World domination. Fast."  

"...and scantily clad females, of course. Who cares if it's below zero outside."
 -- Linus Torvalds

Linux - according to LG's motto, certainly - is fun. Let's face it; you're sweating over that antique piece of hardware and cursing it and its entire ancestry to smithereens (no, you can't get Cray-class performance from your 386SX. Not even with Linux.) because it's what you actually enjoy doing - at some level, anyway. Work motivated by fun is, in fact, the most powerful kind of productive ethic; it causes programmers to stay up into the wee hours for days on end, pounding away on the keyboard in Deep Hack mode, and keeps you looking for solutions long after a "sensible" person would have given up (um... if you do manage that Cray trick, be sure to let me know.) Money alone is not and cannot be the motivator for that level of involvement.

Just as a random example, the amount of energy I personally have put into tweaking Linux systems over the years could easily power, say, Los Angeles for the next few centuries - even if everybody there switched to Linux and left their machines on 24/7. Mind you, I didn't do this because there was anything wrong; it was always due to some FAQ, HOWTO, or even an article right here in LG written by another whirl-eyed Linux maniac: "Here, just try a little of this - it can't hurt you, it's Open Source!" Meanwhile, this little critter perched on my sinister scapula (red suit, horns, etc. - if you're going to anthropomorphize, you might as well do it right) would whisper in my ear: "Come on... you know you want to... just one little file in /etc, what could it possibly hurt?"

Riiight...

After days of fixing up the latest disaster I had wrought, I would swear on large stacks of religious books and every holy symbol known to man(1) and alien(1) that I would never, ever, mess with my beautifully-running system again... while the little guy with the pitchfork hummed a little ditty:

"A little learning is a dangerous thing; 
Drink deep, or taste not the Pyrrhean spring..."
(Alexander Pope)

<sigh> My friends think I'm going bald because I'm getting older. Linux CDs should come with a printed warning; something about "dangerous to sanity, sleep habits, and hair retention".

Sure, there must be people somewhere out there that can just pop in a RedHat/SuSE/Mandrake/whatever CD, run the install, and walk away. I mean, theoretically it's possible. But... where's the fun? Where's the challenge? Where is the juice? Besides, even those people, nametag-wearing corporate drones that they must be, get caught by the Penguin Syndrome eventually: they'll wake up one day and find themselves sitting at a keyboard, a mile deep in "sendmail.cf", fingers cramped from hours of typing. It is then that they'll know the secret shame of Penguin passion, and find themselves guiltily hiding their scribbled notes on upgrading their Apache server...

If you can read this, my Penguin
fell off!

These days, we do have trivially-easy setups for Linux - the single-user surf/email/word processor workstation that is all your Grandma wants is, again, just a single-CD boot away (Knoppix, Morphix, and many, many other variants exist.) However, if you want top performance out of one of these powerful Linux beasts, or if you want to make your computer do things that are considered impossible in other OSes, you have to learn a good bit of Quantum Wrenchology - as my motorcycling friends used to say, "if you don't wrench, you don't ride". This is effort that pays for itself, though, in multiple ways. (A word of warning, for those starting down this path: the mechanic's curse is The Ultimate Machine, the one that will do unprecedented things, run faster than a speeding bullet, and do it all on half a drop of fuel... as soon as he finishes putting it together. Meanwhile, he drives a barely-running 1919 GetOut'n'Push. Beware of getting caught in the loop.)

I don't know about the rest of you, but I personally get a real charge out of riding down Computer Highway, alternately chuckling at and pitying the poor Micro$oft users stranded by the roadside in their forlorn millions; cell phones glued to their ears, frantic expressions on their faces, calling their haughty unreachable mechanics who'll charge them vast amounts of money for work that will fail, again and again... while we continue rolling down the road in our rapidly-growing numbers, engines snarling with barely-restrained power.

See you all out there. Keep the rubber side down.

B. Okopnik


picture Ben is the Editor-in-Chief for Linux Gazette and a member of The Answer Gang.

Ben was born in Moscow, Russia in 1962. He became interested in electricity at the tender age of six, promptly demonstrated it by sticking a fork into a socket and starting a fire, and has been falling down technological mineshafts ever since. He has been working with computers since the Elder Days, when they had to be built by soldering parts onto printed circuit boards and programs had to fit into 4k of memory. He would gladly pay good money to any psychologist who can cure him of the recurrent nightmares.

His subsequent experiences include creating software in nearly a dozen languages, network and database maintenance during the approach of a hurricane, and writing articles for publications ranging from sailing magazines to technological journals. After a seven-year Atlantic/Caribbean cruise under sail and passages up and down the East coast of the US, he is currently anchored in St. Augustine, Florida. He works as a technical instructor for Sun Microsystems and a private Open Source consultant/Web developer. His current set of hobbies includes flying, yoga, martial arts, motorcycles, writing, and Roman history; his Palm Pilot is crammed full of alarms, many of which contain exclamation points.

He has been working with Linux since 1997, and credits it with his complete loss of interest in waging nuclear warfare on parts of the Pacific Northwest.

Copyright © 2004, Ben Okopnik. Released under the Open Publication license unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 107 of Linux Gazette, October 2004

Tux