463 lines
25 KiB
HTML
463 lines
25 KiB
HTML
|
<!--startcut ==============================================-->
|
||
|
<!-- *** BEGIN HTML header *** -->
|
||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||
|
<HTML><HEAD>
|
||
|
<title>Perl One-Liner of the Month: The Case of the Evil Spambots LG #86</title>
|
||
|
</HEAD>
|
||
|
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
|
||
|
ALINK="#FF0000">
|
||
|
<!-- *** END HTML header *** -->
|
||
|
|
||
|
<!-- *** BEGIN navbar *** -->
|
||
|
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="lechnyr.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue86/okopnik.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="qubism.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
|
||
|
<!-- *** END navbar *** -->
|
||
|
|
||
|
<!--endcut ============================================================-->
|
||
|
|
||
|
<TABLE BORDER><TR><TD WIDTH="200">
|
||
|
<A HREF="http://www.linuxgazette.com/">
|
||
|
<IMG ALT="LINUX GAZETTE" SRC="../gx/2002/lglogo_200x41.png"
|
||
|
WIDTH="200" HEIGHT="41" border="0"></A>
|
||
|
<BR CLEAR="all">
|
||
|
<SMALL>...<I>making Linux just a little more fun!</I></SMALL>
|
||
|
</TD><TD WIDTH="380">
|
||
|
|
||
|
|
||
|
<CENTER>
|
||
|
<BIG><BIG><STRONG><FONT COLOR="maroon">Perl One-Liner of the Month: The Case of the Evil Spambots</FONT></STRONG></BIG></BIG>
|
||
|
<BR>
|
||
|
<STRONG>By <A HREF="../authors/okopnik.html">Ben Okopnik</A></STRONG>
|
||
|
</CENTER>
|
||
|
|
||
|
</TD></TR>
|
||
|
</TABLE>
|
||
|
<P>
|
||
|
|
||
|
<!-- END header -->
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<p><i>A REPORTER'S NOTE</i>
|
||
|
<p><i>To forestall some sure-to-happen complaints, I'd like to underscore
|
||
|
the necessity of having the current version of Perl (at least 5.8.0, as
|
||
|
of this writing) in order to play with the scripts presented in these articles.
|
||
|
One-liners, to a far greater degree than proper scripts, rely on new and
|
||
|
unusual language features, and languages tend to "grow" new features and
|
||
|
drop old, outdated ones as version numbers rise. Perl, heading for its
|
||
|
17th year of growth and development, is no exception.</i>
|
||
|
<p><i>One of a number of possible problems with one-liners is fragility,
|
||
|
especially in those (many of them) which are dependent on cryptocontext,
|
||
|
side effects, and undocumented features, which are likely - in fact, are
|
||
|
</i>certain<i>
|
||
|
- to change without notice. One-liners are hacks which often demonstrate
|
||
|
some clever twist or feature, which encourages the use of all of the above.
|
||
|
Remember - these are fun toys which (hopefully) lead to a better understanding
|
||
|
of Perl; trying to use them as you would robust, solid code would be a
|
||
|
serious error. If you don't understand the </i><a href="../issue61/okopnik.html">basics</a><i>
|
||
|
of Perl, this is <b>not</b> the place to start.</i>
|
||
|
<br>
|
||
|
<pre>Debugging is twice as hard as writing the code in the first place.
|
||
|
Therefore, if you write the code as cleverly as possible, you are,
|
||
|
by definition, not smart enough to debug it.
|
||
|
-- Brian W. Kernighan</pre>
|
||
|
|
||
|
<p><br><i><b>Caveat Lector</b> (Let the reader beware).</i>
|
||
|
<p><b><i>Ben Okopnik</i></b>
|
||
|
<br><i>On board S/V "Ulysses", Saint Augustine, Florida</i>
|
||
|
<hr>
|
||
|
<p>Frink Ooblick had fallen asleep at the keyboard. He had been alternately
|
||
|
playing and trying to puzzle out the number-guessing game that Woomert
|
||
|
had written (the first had proven easy, but the second still eluded him);
|
||
|
in fact, his last unfinished game was still visible on the screen:
|
||
|
<pre>
|
||
|
<hr WIDTH="100%">perl -wlne'BEGIN{$b=rand$=}$a=qw/Up exit Down/[($_<=>int$b)+1];print eval$a'
|
||
|
50
|
||
|
Down
|
||
|
25
|
||
|
Up
|
||
|
37
|
||
|
Up
|
||
|
44
|
||
|
Up
|
||
|
|
||
|
|
||
|
<hr WIDTH="100%"></pre>
|
||
|
What was the secret? How did it work? <a href="#1">[1]</a> Frink's dreams
|
||
|
were full of floating bits of code which spiraled off into the distance
|
||
|
or mutated into monstrous shapes, threatening to consume the world. The
|
||
|
hand shaking his shoulder, waking him, was therefore a welcome relief.
|
||
|
Woomert stood at his side, looking impatient.
|
||
|
<p> - "Wake up, Frink, wake up! The game's afoot, you slug-a-bed;
|
||
|
let's go!"
|
||
|
<p> - "Uh... Erm... I'm, uh, awake. What's up?"
|
||
|
<p> - "In the living room. Come on, come on, there's not a moment
|
||
|
to lose!"
|
||
|
<p>Frink's first sight of their visitor brought him to a stop. Used to
|
||
|
dealing with the working crowd - sysadmins, techs, etc. - he had expected
|
||
|
the usual scruffy-and-competent look, perhaps complete with hiking boots;
|
||
|
what greeted his eyes was a fellow in a pinstripe suit, crisp white shirt,
|
||
|
a red "power" tie, and lacquered black shoes. He had been impatiently pacing
|
||
|
the floor, and brightened up considerably at the sight of Frink.
|
||
|
<p> - "Ah, this must be the second team member in your organizational
|
||
|
hierarchy! Excellent; now, we can get into actualizing the power strategies
|
||
|
that will reorganize this, erm, unpredicted opportunity into the profit
|
||
|
slot on the balance sheet. All right, here's how we wind-tunnel this: the
|
||
|
securitization of the computing resources is predicated on leveraging..."
|
||
|
<p>Keeping a cautious eye on their visitor, Frink prison-whispered to Woomert:
|
||
|
"What's he <i>saying?</i> And what language is it in?"
|
||
|
<p> - "It's Marketroid. You need to learn at least the basics of it;
|
||
|
not that it's spoken by the people who sign the checks - they don't have
|
||
|
much time for that sort of thing - but you're going to run into it in the
|
||
|
business world, and it's best to be prepared. Usually, though, most of
|
||
|
these people can still speak English; let's see if this fellow remembers
|
||
|
how. Oh, Mr. Wibbley!"
|
||
|
<p>Their visitor had just finished what he obviously considered an explanation
|
||
|
of the problem, had switched off the overhead LCD projector, put away his
|
||
|
laser pointer, and was looking at them in an expectant manner. Clearly,
|
||
|
he had heard of Woomert's reputation and was relying on the famous Hard-Nosed
|
||
|
Computer Detective to deal with... well, whatever it was.
|
||
|
<p> - "Mr. Wibbley - that was an excellent presentation, but I wonder
|
||
|
if you could restate the problem in more basic terms for my assistant here.
|
||
|
I'm afraid he's not up on proper business terminology, and has missed the
|
||
|
more subtle points."
|
||
|
<P>
|
||
|
<br>Their visitor heaved a sigh, and dropped into the nearby easy chair.
|
||
|
<p> - "Oh, sure. You know, they were going to send one of the system
|
||
|
administrators to talk to you, but of course I insisted on doing the presentation
|
||
|
myself as soon as I heard about it. After all, one of <i>them</i> wouldn't
|
||
|
have even thought of using that textured salmon-and-peach background on
|
||
|
the slides, and that's all the rage these days! Anyway, I <i>did</i> get
|
||
|
a note from him that explains it in his own words; it's crude and unsophisticated,
|
||
|
not at all proper marketing technique, but I suppose you fellows will understand
|
||
|
it..."
|
||
|
<p>The crumpled and coffee-stained napkin, most of which was covered with
|
||
|
calculations, reminders, and something that looked like firewall rules,
|
||
|
contained a short note framed with a red marker pen:
|
||
|
<br>
|
||
|
<center><table BORDER=4 COLS=1 WIDTH="100%" NOSAVE >
|
||
|
<tr>
|
||
|
<td>Woomert, spambots are harvesting the e-mail addresses on our website
|
||
|
(we've tagged them with the "plus hack", <a href="#2">[2]</a> so we know
|
||
|
where it's coming from); the amount of spam we're getting is growing by
|
||
|
leaps and bounds. We need to have the addresses out there - it's our contact
|
||
|
info, site problem reports, etc. - but we've got to stop the 'bots somehow!
|
||
|
I've already written the CGI to handle the hot links, but we need to have
|
||
|
the actual addresses displayed on the pages, and the 'bots are getting
|
||
|
those. Any ideas? The page is at <font color="#3333FF">http://xxxxxxxxxxxx.xxx</font>.
|
||
|
I've created an account for you; just go to <font color="#3333FF">ssh://xxxxxxxxx.xxx/xxx</font>,
|
||
|
password 'xxxxxxxxxx'. Thanks!
|
||
|
<br> - Int Main</td>
|
||
|
</tr>
|
||
|
</table></center>
|
||
|
|
||
|
<p>After Woomert had ushered out their visitor (and reassured him that,
|
||
|
indeed, the salmon-and-peach background was delightful), he returned to
|
||
|
the living room where Frink awaited him.
|
||
|
<p> - "What are you going to do, Woomert? Any plans?"
|
||
|
<p> - "Yes; let's take a peek at their website, then get out there and
|
||
|
look around. It's a mistake to make decisions ahead of your facts, and we
|
||
|
have few facts at hand."
|
||
|
<p>...
|
||
|
<p>Once again, Woomert and Frink found themselves surrounded by the familiar
|
||
|
sights and sounds of a working web site. They could see the Web server
|
||
|
easily spawning off threads without significantly affecting CPU load; clearly,
|
||
|
the local sysadmin had installed mod_perl <a href="#3">[3]</a>. Here and
|
||
|
there, data streams whisked by, and everything moved like a smoothly-oiled
|
||
|
machine.
|
||
|
<p>A sudden shadow made Frink look up. "What the..." Before he could go
|
||
|
any further, a horrifying creature, all tentacles, lenses, and evil intent
|
||
|
<a href="#4">[4]</a>
|
||
|
leaped upon the scene, sucked up a copy of every HTML file at once, and
|
||
|
was gone in a blink.
|
||
|
<p> - "What <i>was</i> that, Woomert - a spambot?"
|
||
|
<p> - "Yep. These things traverse the Net, collecting e-mail addresses
|
||
|
and reporting them to their scummy spammer masters. Given the nature of
|
||
|
the Net, you can't stop them - but you <i>can</i> make them much less effective.
|
||
|
Spammers are stupid, their bots even more so, and that's what we're going
|
||
|
to rely on. Mind you, whatever we do is only going to be a temporary solution;
|
||
|
eventually, spammers (or at least their hired techie help) will catch on
|
||
|
to this particular method - but by then, we'll implement other solutions."
|
||
|
<p>Walking up to a convenient terminal, Woomert slipped on his favorite
|
||
|
typing gloves and fired off a rapid volley.
|
||
|
<pre>
|
||
|
<hr WIDTH="100%">perl -MRFC::RFC822::Address=valid -wne'/[\w-]+@[\w.-]+/||next;print valid$&' *html
|
||
|
|
||
|
<hr WIDTH="100%"></pre>
|
||
|
A line of '1's appeared on the screen; Woomert smiled and his fingers again
|
||
|
flew over the keyboard.
|
||
|
<pre>
|
||
|
<hr WIDTH="100%">perl -i -wlpe's=[\w-]+@[\w.-]+=join"",map{sprintf"&#%s;",ord}split//,$&=e' *html
|
||
|
|
||
|
<hr WIDTH="100%"></pre>
|
||
|
This time, there was no output; however, Woomert looked satisfied. He quickly
|
||
|
shot off an email to the local sysadmin that contained some instructions
|
||
|
and included a shorter version of the last one-liner -
|
||
|
<pre>
|
||
|
<hr WIDTH="100%">perl -we'map{printf"&#%s;",ord}split//,pop' user@host.com
|
||
|
|
||
|
<hr WIDTH="100%"></pre>
|
||
|
- "All right-o, Frink; our work here is done. Home, here we come!"
|
||
|
<p>...
|
||
|
<p>The old-fashioned coal-fired samovar <a href="#6">[6]</a> was gently
|
||
|
perking; the <i>zavarka</i> (tea concentrate), made with excellent Georgian
|
||
|
tea, gave off a marvelous smell. A plate of canapés, ranging from the
|
||
|
best Russian butter and wild blackberry jam on freshly-baked fluffy white
|
||
|
bread to beluga caviar on a heavy, dark rye rubbed with just a touch of
|
||
|
garlic, was set close at hand, and both Woomert and Frink were merrily
|
||
|
foraging in the gourmet field thus presented. Eventually they settled back,
|
||
|
replete with good food, and Frink's curiosity could be contained no longer.
|
||
|
<p> - "Woomert, when I try to puzzle out your one-liners, I can only
|
||
|
get so far; then I run out of steam. Can you tell me about what you did?"
|
||
|
<p>Lying back in his favorite armchair, Woomert smiled.
|
||
|
<p> - "Instead, why don't you start by telling me what part you understood?
|
||
|
I like to see how far you've advanced, Frink; it's been a pleasure to me
|
||
|
to see you picking up some of the finer points. I'll take it from there."
|
||
|
<p> - "All right, then... Let's start with the first one:
|
||
|
<pre>
|
||
|
<hr WIDTH="100%">perl -MRFC::RFC822::Address=valid -wne'/[\w-]+@[\w.-]+/||next;print valid$&' *html
|
||
|
|
||
|
<hr WIDTH="100%"></pre>
|
||
|
I recognized all the command-line switches:
|
||
|
<p><tt>-Mmodule Use the specified module</tt>
|
||
|
<br><tt>-w Enable warnings</tt>
|
||
|
<br><tt>-n Non-printing loop</tt>
|
||
|
<br><tt>-e Execute the following commands</tt>
|
||
|
<p>However, I couldn't quite puzzle out the '<tt>-MRFC::RFC822::Address=valid'</tt>syntax
|
||
|
- what was that?"
|
||
|
<p> - "Ah. As 'perldoc perlvar' tells us, in the entry for '-M', it's
|
||
|
a bit of syntactic sugar; '<tt>-MBar=foo</tt>' is a shortcut for '<tt>use
|
||
|
Bar qw/foo/</tt>', which imports the specified function 'foo' from module
|
||
|
'Bar'. Go on, you're doing well."
|
||
|
<p>Frink cleared his throat.
|
||
|
<p> - "In that case, I think I have it figured out... almost. Let
|
||
|
me take a quick look at 'perldoc perlvar' and 'perldoc RFC::RFC822::Address'...
|
||
|
Yes, that's what I thought - I've got it! The regex at the beginning -
|
||
|
<p><tt>/[\w-]+@[\w.-]+/</tt>
|
||
|
<p>tries to match e-mail addresses - it's not perfect, but should do reasonably
|
||
|
well. What it says is "match any character in <tt>[a-zA-Z0-9-]</tt> repeated
|
||
|
one or more times, followed by '<tt>@</tt>', followed by any character
|
||
|
in <tt>[a-zA-Z0-9.-]</tt> repeated one or more times". If the match does
|
||
|
not succeed - the '<tt>||</tt>' logical-or operator handles that - go to
|
||
|
the next line."
|
||
|
<p> - "Brilliant, Frink! What happens then?"
|
||
|
<p> - "If it does succeed, '<tt>next</tt>' is skipped over, and '<tt>print
|
||
|
valid$&</tt>' is invoked. The module documentation tells me that the
|
||
|
'<tt>valid</tt>' function tests an e-mail address for RFC822 (e-mail specification)
|
||
|
conformance, and returns true or false based on validity. '<tt>$&</tt>',
|
||
|
according to 'perldoc perlvar', is the last successful pattern match -
|
||
|
in other words, whatever was matched by the regex. Since you saw all '1's
|
||
|
and no errors - any matches that weren't RFC822-valid would have returned
|
||
|
something like "<tt>Use of uninitialized value in print at -e line 1</tt>"
|
||
|
- what you matched was all valid. What you were doing here is checking
|
||
|
to see that your regex only matched actual addresses. How did I do?"
|
||
|
<p> - "Excellent, my dear Frink; you're coming along well! As a side
|
||
|
note, it's generally best to avoid the use of <tt>$&, $`,</tt>
|
||
|
and <tt>$'</tt> as well as '<tt>use English'</tt> in scripts; there's a
|
||
|
rather large performance penalty associated with them (see 'perldoc perlvar').
|
||
|
However, here we had a very small list of matches, and so I went ahead
|
||
|
with it. Go on, see what you can make of the next one."
|
||
|
<p> - "Um... the next one, right. Well, I've got part of it -
|
||
|
<pre>
|
||
|
<hr WIDTH="100%">perl -i -wpe's=[\w-]+@[\w.-]+=join"",map{sprintf"&#%s;",ord}split//,$&=e' *html
|
||
|
|
||
|
<hr WIDTH="100%"></pre>
|
||
|
<tt>-i In-place edit (modify the specified file[s])</tt>
|
||
|
<br><tt>-w Enable warnings</tt>
|
||
|
<br><tt>-p Printing loop</tt>
|
||
|
<br><tt>-e Execute the following commands</tt>
|
||
|
<p>Mmmm... I got sorta lost here, Woomert. I see that regex that you'd
|
||
|
used before, but what's that 's=' bit?"
|
||
|
<p> - "It's one of those convenient tweaks that Perl provides - although,
|
||
|
admittedly, the basic idea was stolen from 'sed'. It's simply an alternate
|
||
|
delimiter used with the 's' (substitute) operator; there are times when
|
||
|
using the default delimiter ("/") is highly inconvenient and leads to "toothpick
|
||
|
Hell" - as, for example, in matching a directory name:
|
||
|
<p><tt>s/\/path\/to\/my\/directory/my home directory/</tt>
|
||
|
<p>Far better to use an alternate delimiter, one that is not contained
|
||
|
in the text of either the pattern or the replacement:
|
||
|
<p><tt>s#/path/to/my/directory#my home directory#</tt>
|
||
|
<p>As long as it's non-alphanumeric and non-whitespace, it'll work fine.
|
||
|
There are some special cases, but they're all sensible ones; using a single
|
||
|
quote disables interpolation in both the pattern and the replacement (see
|
||
|
the rules in 'perldoc perlop'), and using braces or brackets as delimiters
|
||
|
requires rather obvious syntax:
|
||
|
<p><tt>s{a}{b}</tt>
|
||
|
<br><tt>s(a)(b)</tt>
|
||
|
<br><tt>s[a][b]</tt>
|
||
|
<p>Many people like '#' as a delimiter; I prefer '=', since '#' tends to
|
||
|
come up in HTML and comments. Can you make sense of any of the rest?"
|
||
|
<p>- "I'm afraid not. You're matching the email addresses as previously,
|
||
|
and replacing them with something, but I can't figure out what."
|
||
|
<p>- "All right; it <b>is</b> rather involved. The replacement part of
|
||
|
the substitution is actual Perl code; we can do that thanks to the 'e'
|
||
|
(evaluate) modifier on the end of the 's' operator. Let's parse the relevant
|
||
|
code from right to left:
|
||
|
<pre>join"",map{sprintf"&#%s;",ord}split//,$&</pre>
|
||
|
We know that '<tt>$&</tt>' contains an email address; the next thing
|
||
|
we do is use the '<tt>split'</tt> function which converts a scalar to a
|
||
|
list, splitting it on whatever is specified between the delimiters. In
|
||
|
this case, however, the delimiter is empty, a null - so the returned list
|
||
|
has each character of the address as a separate element in the list. We
|
||
|
now pass this list to the '<tt>map</tt>' function, which will evaluate
|
||
|
the code specified in the <tt>{block}</tt> for each element of the supplied
|
||
|
list and return the result - as another list.
|
||
|
<p>Within the block itself, each character is used as an argument to the
|
||
|
'<tt>ord</tt>' function, which returns the ASCII value of that character;
|
||
|
this, in turn, is used as the argument for the '<tt>sprintf</tt>' function
|
||
|
which returns the following formatted string:
|
||
|
<p><tt>&#<ASCII_value>;</tt>
|
||
|
<p>for each value so specified. After all the characters in the list have
|
||
|
been processed, we use the '<tt>join</tt>' function to convert the list
|
||
|
back to a scalar - which the substitute operator will now use as a replacement
|
||
|
string for the original email address. What used to be "<tt>foo@bar.com</tt>"
|
||
|
now looks like
|
||
|
<p><tt>&#102;&#111;&#111;&#64;&#98;&#97;&#114;&#46;&#99;&#111;&#109;</tt>
|
||
|
<p>This, you must admit, looks nothing like an e-mail address - so spambots
|
||
|
will not be able to read it!"
|
||
|
<p>Frink looked troubled.
|
||
|
<p> - "Woomert, I hate to tell you... but human beings won't be able
|
||
|
to read it either!"
|
||
|
<p>Woomert took another sip of his tea and smiled.
|
||
|
<p> - "You're forgetting one thing, Frink. Humans aren't <i>going</i>
|
||
|
to be reading this; since it's part of the HTML files, it's going to be
|
||
|
read by
|
||
|
<i>browsers</i>. As it happens, the HTML specification for showing
|
||
|
ASCII characters by their value is
|
||
|
<p><tt>&#<ASCII_value>;</tt>
|
||
|
<p>which is exactly what we've produced. Try this yourself: save the text
|
||
|
between the following lines as "text.html" and view it in a browser.
|
||
|
<pre>
|
||
|
<hr WIDTH="100%"><html><head><title></title></head><body>
|
||
|
&#87;&#111;&#111;&#109;&#101;&#114;&#116;&#32;&#70;&#111;&#111;&#110;&#108;&#121;
|
||
|
</body></html>
|
||
|
|
||
|
<hr WIDTH="100%"></pre>
|
||
|
Do you see what I mean?"
|
||
|
<p>A few moments later, Frink looked up from the keyboard.
|
||
|
<p> - "Woomert, what a great solution! Your client will be able to
|
||
|
display the addresses without them being harvested, and the Web page will
|
||
|
still look the same as it did before. I can tell by comparison that the
|
||
|
last bit of code:
|
||
|
<pre>
|
||
|
<hr WIDTH="100%">perl -we'map{printf"&#%s;",ord}split//,pop' user@host.com
|
||
|
|
||
|
<hr WIDTH="100%"></pre>
|
||
|
simply enables the sysadmin to convert any new addresses before popping
|
||
|
them into the HTML. Wonderful!"
|
||
|
<p> - "A large part of the complete solution, of course, was the CGI
|
||
|
that the local admin had written - that takes a bit more than a one-liner,
|
||
|
although not very much more, given the power of the CGI module. Remember,
|
||
|
Frink: as your powers grow, make certain to align yourself with the side
|
||
|
of Good rather than Evil. Not only is it the right thing to do; the people
|
||
|
around you are far more likely to have brains!"
|
||
|
<br>
|
||
|
<br>
|
||
|
<p>
|
||
|
<hr WIDTH="100%">
|
||
|
<br><a NAME="1"></a>[1] Oddly enough, my mysterious correspondent did not
|
||
|
include the solution to this, perhaps deeming it simple enough (!) for
|
||
|
the public to figure out - or (and I suspect this to be the more likely
|
||
|
scenario) he has not yet figured it out himself. Readers are welcome to
|
||
|
write in with their ideas... but for now, the workings of Woomert's game
|
||
|
remain a puzzle.
|
||
|
<p><a NAME="2"></a>[2] A number of commonly-used Mail Transfer Agents will
|
||
|
ignore anything that follows a plus sign in the username part of the address,
|
||
|
e.g. <smith+yahoo@joe.com> will be routed exactly the same as <smith@joe.com>.
|
||
|
This can be a very useful mechanism for tracing and reducing spam: a "plus-hacked"
|
||
|
address that becomes too spam-loaded can be directed to "<tt>/dev/null</tt>"
|
||
|
and replaced by a newly generated one (say, <smith+yahoo1@joe.com> -
|
||
|
which would also go to <smith@joe.com>.)
|
||
|
<p><a NAME="3"></a>[3] A.K.A. "Apache On Steroids". From the mod_perl documentation:
|
||
|
<p><tt>The Apache/Perl integration project brings together the full power
|
||
|
of</tt>
|
||
|
<br><tt>the Perl programming language and the Apache HTTP server. This
|
||
|
is</tt>
|
||
|
<br><tt>achieved by linking the Perl runtime library into the server and</tt>
|
||
|
<br><tt>providing an object oriented Perl interface to the server's C language</tt>
|
||
|
<br><tt>API.</tt>
|
||
|
<p><tt>These pieces are seamlessly glued together by the `mod_perl' server</tt>
|
||
|
<br><tt>plugin, making it is possible to write Apache modules entirely
|
||
|
in</tt>
|
||
|
<br><tt>Perl. In addition, the persistent interpreter embedded in the server</tt>
|
||
|
<br><tt>avoids the overhead of starting an external interpreter program
|
||
|
and</tt>
|
||
|
<br><tt>the additional Perl start-up (compile) time.</tt>
|
||
|
<p>There are many major benefits to using mod_perl; if you use Apache in
|
||
|
any serious fashion without it, you're almost certainly throwing away some
|
||
|
of your time and effort.
|
||
|
<p><a NAME="4"></a>[4] If you've seen "The Matrix", just picture the Sentinels.
|
||
|
If you haven't seen it, hey, you've got only yourself to blame. :)
|
||
|
<p><a NAME="5"></a>[5] Gibberish is the written form of the Marketroid
|
||
|
language. It was formerly spoken by the Gibbers, who all died out as a
|
||
|
result of their complete inability to do anything (as opposed to talking
|
||
|
about it.) It is exactly as comprehensible as its spoken counterpart, although
|
||
|
many people confuse the two: "it's all marketroid gibberish!" is a highly
|
||
|
redundant statement.
|
||
|
<p><a NAME="6"></a>[6] See the "Russian Tea HOWTO", by Dániel Nagy,
|
||
|
for the proper way to make and serve Russian tea. The man <b><i>knows</i></b>
|
||
|
what he's talking about.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<!-- *** BEGIN author bio *** -->
|
||
|
<P>
|
||
|
<P>
|
||
|
<P> Ben is a Contributing Editor for Linux Gazette and a member of
|
||
|
The Answer Gang.
|
||
|
|
||
|
<!-- *** BEGIN bio *** -->
|
||
|
<P>
|
||
|
<IMG ALT="picture" SRC="../../gx/2002/tagbio/ben-okopnik.jpg" WIDTH="199"
|
||
|
HEIGHT="200" ALIGN="left" HSPACE="10" VSPACE="10">
|
||
|
<em>
|
||
|
Ben was born in Moscow, Russia in 1962. He became interested in
|
||
|
electricity at age six--promptly demonstrating 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 resulting nightmares.
|
||
|
|
||
|
<p>Ben's 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. Having recently completed a seven-year
|
||
|
Atlantic/Caribbean cruise under sail, he is currently docked in Baltimore, MD,
|
||
|
where he works as a technical instructor for Sun Microsystems.
|
||
|
|
||
|
<p>Ben 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.
|
||
|
</em>
|
||
|
<br CLEAR="all">
|
||
|
<!-- *** END bio *** -->
|
||
|
|
||
|
<!-- *** END author bio *** -->
|
||
|
|
||
|
|
||
|
<!-- *** BEGIN copyright *** -->
|
||
|
<hr>
|
||
|
<CENTER><SMALL><STRONG>
|
||
|
Copyright © 2003, Ben Okopnik.
|
||
|
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR>
|
||
|
Published in Issue 86 of <i>Linux Gazette</i>, January 2003
|
||
|
</STRONG></SMALL></CENTER>
|
||
|
<!-- *** END copyright *** -->
|
||
|
<HR>
|
||
|
|
||
|
<!--startcut ==========================================================-->
|
||
|
<CENTER>
|
||
|
<!-- *** BEGIN navbar *** -->
|
||
|
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="lechnyr.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue86/okopnik.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="qubism.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
|
||
|
<!-- *** END navbar *** -->
|
||
|
</CENTER>
|
||
|
</BODY></HTML>
|
||
|
<!--endcut ============================================================-->
|