What's New!

Chat with

How to Defend
Your Computer 

The Guides
to (mostly) 
Harmless Hacking

Happy Hacker 
Digests (old stuff) 

Hacker Links 


Meet the 
Happy Hacksters 

Help for 



It Sucks 
to Be Me!

How to Commit
Computer Crime (not)! 

What Is a 
Hacker, Anyhow? 

Have a 
Great Life! 

News from the 
Hacker War Front

Carolyn's most
popular book,
in 4th edition now!

For advanced
hacker studies,
read Carolyn's
Google Groups
Subscribe to Happy Hacker
Visit this group

Jan. 10, 2000
See the Happy Hacker web site at http://www.happyhacker.org
Firewall gives you problems? Try http://happyhacker.org

*** Editor's Comments

Once again, the Unix Digest is here. For some reason, it seems there were
fewer letters this week. If this is because less people had problems, great!
If not... well... don't be shy... write in! Ok? In addition, if anyone is
located in NYC, and wants debian CD's, let me know by email, and we can work
something out.

*** Readers' Submissions

matt morgan <neptune2002@hotmail.com> wrote:

I would like to know whether a tcsh prompt is configurable
and how to configure it

I have been told that a "set prompt=" in .cshrc might work
but I am having no luck finding someone that actively uses tcsh

also there are no man pages for tcsh on my computer

[Editor: Yes. As far as how... I'd suggest you first try a search on your
favorite search engine.]


pyromanic <pyromanic@kmfms.com> sent in:

Hi !
the next month, i get a new internet connection. radiolink at 2 mbit, very
cheap ! :)
i want to share this connection with one of my neighbours, who is a very
good friend of mine.
we have, together, 7 computers, most of them running linux or windows
i will use one old 486 as a server, which i connect to the 'net.
this server will be running the debian linux dist.
what i don't really understand is what do i have to do for the linux
machine to act as a server, how do i connect to it from one of the win
machines, and what setup do i have to do in linux ?

thanx in advance
pyromanic [ pyromanic@kmfms.com ]

[Editor: Ok, I'm glad to hear you're running Debian, which is, of course,
the best linux distro out there :). Seriously, excellent question. What
you'd probabaly want to do is first set up your internal network. The debian
install is very thorough on setting up a network, though you should
definately make sure to read the HOWTO on setting up networks. The easiest
way to set up 'net access would probabaly be by using IP Masquarading. I
used to be quite proficient with IPMasq, although I haven't used it
recently, and I doubt I remember all of the setup options. Read IPMasq
(mini???)HOWTO, it covers many examples in full detail. And enjoy :).]


Mike Miller <unixeditor@cmeinel.com> says:

Your question here! Just send email to unixeditor@cmeinel.com.

*** Perl 101, Lesson 3

Sorry about last week... I had a ton of finals, and at 20K/year, I have to
put my college before this newsletter. I'm off now, and there'll be a full
article this time, so open up another terminal, and start up vi (or your
favorite editor), and let's rock and roll (as much as you can rock and roll
with perl :) ).

First topic: subroutines. Previous programmers should already be familiar
with the concept of a subroutine (a.k.a. procedure a.k.a. function... yes, I
do know there is actually a difference... don't worry about it for now). To
the newbies, a subroutine is a small part of a program that performs a task.
What good is this? Let's take a general program. This program takes input,
does something, returns output. Sounds pretty typical, right? So why not
write the program like this (pseudo-code)

Main Program:
Get Input
Return Output

Nice and simple. Hey, the program could be as short as 5 lines. But how does
the computer know how to "Get Input"? In comes the subroutine. We could
create subroutines to accomplish each of these tasks. The advantages should
be obvious: reusability, modularity, and simplicity. Enough philosophy,
let's see how to write a subroutine. First, we need a reason. Well, here's
one. On our original program, we had a procedure for checking for "earth" in
any case (we used the regular expression /earth/i instead of the string
"Earth", and we used the binding operator =~ (thanks darkm00n`) instead of
eq, but when we went to a hash lookup, we couldn't do that, because then
$planethash($index) was a string, not a regular expression. So let's try
rearranging the input so it's converted to lowercase, then we can compare it
with a string of all lowercase names in %planethash. In other words, instead
of comparing "Earth" or "earth" or even "EaRtH" with "earth", we'll take
every string, make all it's letters lower case, and then we can do a string
comparison (an eq test). First, we'll write that, then we'll create a
subroutine call planet_parse that will contain all the code to parse (i.e.,
process) the input until it's ready for the comparison. Here's the code to
make the change:

$planetname =~ tr/A-Z/a-z/; #yes, I'm aware of the uc function... but this
is an R/E.

The tr/RE1/RE2/ operator, similar to the slash replacement command from many
editors, replaces every element in RE1 with RE2. So in our example, every
letter in the 26 element array of letters from A to Z will be replaced with
it's analogue (i.e., same index number) in the array of a to z. And the =~
operator binds (assigns) the value on the right to that on the left. I
admit, a simple line does not require a subroutine. Actually, to use a
subroutine would be remarkably inefficient, but there could be a lot of
processing code, so we'll create a framework.

sub planet_parse
my($planettemp) = @_;
$planettemp =~ tr/A-Z/a-z/;
return $planettemp

This is very poor coding. But before we explain why you shouldn't do this,
let's see what happens. The my creates a local variable (i.e., it does not
"exist" outside of this subroutine, without it, we'd make a global variable
(which could be accessed anywhere in the program). The @_ is a special array
which (in this case) will contain the parameters passed to the subroutine.
All subroutines have two things associated with them... input (a.k.a.
parameters) and output. When we call the planet_parse subroutine, we'll give
it a parameter, the variable we're using to contain the planetname
(coincidently enough, $planetname). The tr/ statement we already explained,
and the return statements tells the subroutine what to send back. If there
is not return statement, the subroutine will return the value of the last
statement. Thus, in this case, we could leave off the return statement, and
since $planettemp =~ tr/A-Z/a-z/; evaluates to $planettemp, it would be
sufficient. Usually the return statement is used in conjuction with an
if-elsif-else framework to return a varying output. An utterly useless
subroutine, but it makes the point.

But what do we do with this? Try the following:

"Mercury", "Hi Merc. Are you related to Merck Chemical? Haha!",
"Venus", "Ever met John Gray?",
"Earth", "Third Rock, eh?"
"Mars", "Ever met John Gray?",
"Jupitar", "Do you really jump?",
"Saturn", "Sega!",
"Uranus", "I think you know the joke...",
"Neptune", "Nothing interesting to say about you. Sorry, pal."
"Pluto", "Have you sued Walt for copyright infringement?");

sub planet_parse
my($planettemp) = @_;
$planettemp =~ tr/A-Z/a-z/;
return $planettemp

#main program begins here

print("What do you call your planet? ");
$planetname = <STDIN>;
$output = (%planethash(planet_parse($planetname)) || "Hi. Where exactly is
that located?");
print ($output, "\n");

Seems pretty straightforward. The subroutine returns a value (in this case,
a scalar variable), so it can be used in place of a value. I presume you
know the || expression (if not... it means logical OR, but you knew that,
right?). Note that unlike certain other languages, if the first part of an
OR statement evaluates to something other than ""/undef/NULL, the second
term is not evaluated at all.

Ok, that covers basic subroutining. Let's see... disk I/O.
The key to understand disk I/O is to know that it's no different than taking
data in from the keyboard. Just like data comes from the keyboard in the
<STDIN> handle (or from a pipe, whatever), disk files can be read from by
using a handle. To do this, use the open function.

open (PLANETHANDLE, "/usr/local/lib/planetfile")

Assuming that there was such a file (you can test by making sure
PLANETHANDLE is defined), you could read from it by saying:


That's it. Of course, there are a lot more things you can do with I/O, but
that's basically how to take a file, and treat it as though it came STDIN.

Caveat: When working with STDIN, not much can go wrong (it's pretty hard to
not have a STDIN). But it's quite possible a file doesn't exist, or (and
this will almost always be an issue) maybe you reached the end of the file.
The key is that both the $variable=<HANDLE> and open statements will return
undef under these conditions. So use the defined function (returns FALSE iff
the input equals undef) as follows

if (defined(open(PLANETHANDLE,"/usr/local/lib/planetfile")))
<next block>

That way, the code will only be executed if the open worked. You can use a
similar technique to determine when you've reached the end of the file (put
your read statements inside a while loop). That should do it for this
week... Happy Perl-ing!


This is a list devoted to *legal* hacking! If anyone plans to use any
information in this Digest or at our Web site to commit crime, go away! We
like to put computer criminals behind bars where they belong!


 © 2013 Happy Hacker All rights reserved.