File: peda.html

package info (click to toggle)
lg-issue75 2-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,100 kB
  • ctags: 212
  • sloc: perl: 228; makefile: 62; sh: 34
file content (387 lines) | stat: -rw-r--r-- 23,850 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"><html><head>
<!--startcut  ==============================================-->
<!-- *** BEGIN HTML header *** -->
<style>
   code { font-weight: bold;
          color: #555555
        }
</style>
<title>Simple Package Management With Stow LG #75</title></head>
<body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#0000af" alink="#ff0000">
 <!-- *** END HTML header *** -->  
<center> <a href="http://www.linuxgazette.com/"> <img alt="LINUX GAZETTE" src="../gx/lglogo.png" width="600" height="124" border="0">
</a>  <br>
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="orr.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/issue75/peda.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="piszcz.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 *** --> 
<p> </p>
</center>
  <!--endcut ============================================================-->
  
<h4 align="center"> "Linux Gazette...<i>making Linux just a little more fun!</i>
" </h4>
  
<p> </p>
<hr> 
<p>  <!--===================================================================-->
  </p>
<center> 
<h1><font color="maroon">Simple Package Management With Stow</font></h1>
 
<h4>By <a href="mailto:pedaa@rockefeller.edu">Allan Peda</a></h4>
 </center>
 
<p> </p>
<hr> 
<p>    <!-- END header -->     </p>
<p>When running a single box with tried and true software, tracking the versions
 of software that you use may be a no-brainer. That is to say, you use whatever
Red Hat, Debian, or Sun provided (yes, I will touch on non-Linux issues here)
if you could find or build the necessary package. But wait: what if you have
been running the same machine for years and you simply must have the latest
Emacs?  What if you are developing your <i>own</i>  software and don't want
to create RPMs, or Debian dpkg each time you pause  at a version? What if
you don't trust that software package written by a 14 year old in that far
away country with an unstable government? In short, what if you are heeding 
Obi-Wan Kenobe's advice, and <i>using the source</i>? How do you make it
easy to rip out those configuration files, man pages, binaries, and libraries
that you may want to replace in the future? </p>
                       
<p>  Well, when you think about it a little bit, Unix has sort of provided
 the raw materials to do that, in the form of a symbolic link or <i>symlink</i>
. Symlinks are a powerful tool because they allow you to configure software
 so that its <i>implementation</i> does not necessarily connect directly
 to it's <i>interface</i> (sound familiar?). I might be playing a  little
loose with the definitions, but that really is what is being done  when,
for  example, postfix mimics sendmail. The implementation, that is postfix,
 is presenting the same interface as sendmail, which has become a de facto standard  interface to
the Unix mail transport agent (<a href="http://www.nightflight.com/foldoc-bin/foldoc.cgi?Message+Transfer+Agent">MTA</a>).</p>
                       
<p>In the case of symlinks, you might have a program <code>/opt/bin/new_cat</code>
linked  to <code>/opt/bin/cat</code>.  So if you looked at the link, you'd know
right away what version was being run, but it would still seem to be the same familiar
program. In this way the actual program being run can change as a better
implementation (algorithm, etc.) is developed.  Yes, environmental variables,
as used in scripts, allow this, but try retrofitting all the variables that
point to a program after the fact.  It might not be so easy.  Symlinks may
be the answer. For example symlinks are typically used to ease the
building of <a
href="http://www.pcwebopedia.com/TERM/m/motif.html">motif</a> from
source via the <code>lndir</code> utility.  Of course this symlinking stuff
could get out of hand, and should not be abused, but you get  the
idea. What the folks at the GNU project did was write a little  Perl
script that automates  that entire process of symlinking the  code you
are using to the interface that you want to present to the user.  Note
that <i>hard links</i> are subtly different, because there is no
differentiation  between the original file and the link (really a
second name since they share inodes, and hence <em> are</em>
identical). I find hard links to be of minimal  use, because it
becomes too easy to lose track of which filename should be deleted
and which should be kept.</p> 
                       
<h2>Introducing Stow</h2>
                       
<p>Right away I want to emphasize that <a href="#gnu_stow">stow</a> is not
a replacement for a full package management database, but it does allow one
to get many of the  benefits of a complex package management system
from a humble Perl script. As an aside, there is a package that  will
allow source to be entered into a Slackware, RPM, or Debian package
database, called  <a href="#checkinstall">checkinstall</a> 
. As an example I will go through the steps to install stow, then the steps
to install a mail (<a
href="http://www.nightflight.com/foldoc-bin/foldoc.cgi?query=MUA&action=Search">MUA</a>)
 replacement called <i><a href="#nail">nail</a></i> 
. This is a good example because it includes multiple files so that you can see
how one might encounter inadvertant collisions with previous versions. 
Also, nail a great enhancement to standard Berkeley mail, since it allows sending 
binary attachments on the command line, while offering the same base
functionality. 
</p>
  
<p>Stow is so simple to install that really no in depth discussion is needed. 
It should work if you have Perl 5.005 or later (this version is stock on
Solaris 8 AFAIK). Simply download the source from the GNU website or a local
<a href="http://www.gnu.org/server/list-mirrors.html">mirror</a>, extract
to a source directory with tar xzf and repeat the familiar <code>./configure</code>
, <code>make</code>, and <code>make install</code> sequence.  Despite
appearances, 
nothing is compiled, but a few things like the manual still need to get built.
 The <code>make install</code> step will place <code>stow</code> into the
 <code>/usr/local/bin</code> directory.  This is the default location, and
 I chose this setting to simplify this discussion.  The reasons
 will hopefully become apparent by the end of this article. The
 location of the installed <code>stow</code> executable is shown on the last line of the
 sample output below. I used 
 the <code>type</code> command, but you could also use <code>which</code> or perhaps
<code>whereis</code>. </p>  

<table class="sourcecode">
    <caption>Unpacking and installing stow</caption>    <tbody>
    <tr>
       <th></th>
    </tr>
    <tr>
       <td>                                                          
      <pre>[zippy@mybox zippy]$ cd src/<br>[zippy@mybox src]$ gunzip -c ../stow-1.3.3.tar.gz | tar xf -<br>[zippy@mybox src]$ ll<br>total 8<br>drwxrwxr-x    2 zippy   zippy       4096 Jan  6 06:19 stow-1.3.3<br>[zippy@mybox stow-1.3.3]$ ./configure <br>creating cache ./config.cache<br>checking for a BSD compatible install... /usr/bin/install -c<br>checking whether build environment is sane... yes<br>checking for mawk... no<br>checking for gawk... gawk<br>checking whether make sets ${MAKE}... yes<br>checking for a BSD compatible install... /usr/bin/install -c<br>checking for perl... /usr/bin/perl<br>updating cache ./config.cache<br>creating ./config.status<br>creating Makefile<br>creating stow<br>[zippy@mybox stow-1.3.3]$ make<br>make: Nothing to be done for `all'.<br>[zippy@mybox stow-1.3.3]$ sudo make install<br>make[1]: Entering directory `/home/zippy/src/stow-1.3.3'<br>/bin/sh ./mkinstalldirs /usr/local/bin<br> /usr/bin/install -c stow /usr/local/bin/stow<br>/bin/sh ./mkinstalldirs /usr/local/info<br> /usr/bin/install -c -m 644 ./stow.info /usr/local/info/stow.info<br>/bin/sh ./mkinstalldirs /usr/local/man/man8<br> /usr/bin/install -c -m 644 ./stow.8 /usr/local/man/man8/stow.8<br>make[1]: Leaving directory `/home/zippy/src/stow-1.3.3'<br>[zippy@mybox stow-1.3.3]$ type stow<br>stow is /usr/local/bin/stow<br>      </pre>
       </td>
    </tr>
   
  </tbody>            
</table>
  
<p>At this point <i>stow</i> is installed under /usr/local/bin. Make
sure to include this directory your <code>$PATH</code></p>

<h2>Under The Hood</h2>
<p>
To describe <code>stow</code>, one first needs to understand the
<code>configure</code> script, because these two scripts work
together, with <code>configure</code> building all the software
components, and <em>install</em>ing them on your machine.  The
configure script is a marvelous convenience.  It sniffs 
the system, checking for various prerequisite software.  The results
of these tests are used to design a set of <a
href="http://www.nightflight.com/foldoc-bin/foldoc.cgi?query=Makefile&action=Search">Makefile</a>s 
which will build and install your software to fit your system
configuration. There are many options to configure, in fact there are
alternate versions of this script as well, but for our purposes the
options of greatest interest is the <em>--prefix</em> argument.  Note
a second argument, the <code>--exec-prefix</code> allows some finer tuning 
of the actual installation process, but this option will not be
discussed in much detail.
</p>

<p>So now we understand that <code>configure</code> builds the scripts
that build the code, and that the location of the installed code may
be specified via <code>configure</code>'s <em>--prefix</em> command--
line argument.  It turns out that if you pick a single special spot to
install all source code, <code>stow</code> can then cleanly automate
the creation of symlinks to the installed code in such a way that the
source tree is readily evident, and can be replaced and removed.  For
example, invoking the configure script as 
<code>./configure --prefix=/opt/stow/foo-1.2.1</code>  
will install your package under <code>/opt/stow/foo-1.2.1</code>
</p>  

<h2>I'm Still Confused. What is this prefix and exec-prefix stuff?</h2>
<p>
Feel free to skip this section, and come back to it later, after you
have digested the rest of this article. Once you are comfortable
with the notion of an <em>actual</em> install location being separate
from the <em>apparent</em> location of a program you can consider the
parts of the puzzle that don't fit the this ideal scenario.  Imagine
the case of installing software across multiple machines where
<em>everything</em> is installed in a symlinked directory tree
isolated from the apparent location (found in the <code>$PATH</code>, or
<code>$MANPATH</code>).  Depending on your intentions, this might not be
what you want.   Consider the situation where an application might be
built for multiple architectures, for example source code could be
built for Solaris and linux systems as follows (assuming an identical
cross mounted source trees, but separate build directories): 

<pre>
sun$ cd sunsparc<br>sun$ ../foolib-1.1/configure --prefix=/usr/local \<br>> --exec-prefix=/usr/local/sunsparc<br>sun$ make<br>sun$ make install<br>
</pre>
Then from another xterm:
<pre>
sun$ ssh pengie
pengie$ cd linux<br>pengie$ ../foolib-1.1/configure --prefix=/usr/local \<br>> --exec-prefix=/usr/local/linux<br>pengie$ make<br>pengie$ make install<br>
</pre>
<p>
The bottom line is that the developer has to decide which files are
architecture dependant, and which are not, and you might not agree
with her.  Obviously documentation, and possibly configuration files
could be considered architecture independent.  Still, if you use stow,
you are free to remove symlinks by "unstowing" files. Since this does 
upgrading will not overwrite the old source, instead it will only 
break the links, and you can hand copy configuration files back.  Just
"restow" the package and try again you get the upgrade 
right. Personally, I don't use the <code>--exec-prefix</code> option 
much, preferring instead to manually link the (hopefully) few
configuration files that I want to treat specially, fixing broken
links after upgrading. So far I think it's been a good approach for
the simple situations I've encountered.
</p>

 
<h2>Installing Software With Stow</h2>
<p>
When I first started using <code>stow</code> a few years ago, I had some
frustration with it because I had already started setting up the
system (an HP-UX server) without it.  There were frequent collisions
with info files and manpages, ironically this was encountered the most
with emacs.  Naturally, following what is going on is easier for
simple packages.  The MUA software <code>nail</code>, is about as simple as you can get, since it
consists of the executable, the documentation, and the config files
(while you might want to link to <code>/etc</code> BTW).
</p>

<table class="sourcecode">
    <caption>Configuring for alternate locations</caption>    <tbody>
    <tr>
       <th></th>
    </tr>
    <tr>
       <td>                                                          
      <pre>[zippy@mybox src]$ gunzip -c ../nail-9.29.tar.gz  | tar xf -<br>[zippy@mybox src]$ cd nail-9.29/<br>[zippy@mybox nail-9.29]$ ./configure --prefix=/opt/stow/nail-9.29<br>creating cache ./config.cache<br>checking for a BSD compatible install... /usr/bin/install -c<br>checking for iswprint... yes<br>...<br>..... lots of stuff ...<br>updating cache ./config.cache<br>creating ./config.status<br>creating Makefile<br>creating config.h<br>[zippy@mybox nail-9.29]$ <br>      </pre>
       </td>
    </tr>
   
  </tbody>            
</table>

<p>What we are doing here is telling <code>configure</code> to put the
files under <code>/opt/stow/nail-9.29</code> 
but (implicit as far as stow is concerned) that the installed package will
appear to be under /opt for run time files. ( If you're
curious, you can look at the generated <code>Makefile</code> to see
that the <code>prefix</code> variable is set via the
<code>--prefix</code> option). 
</p>
  
  
<table class="sourcecode">
    <caption>Building the source code</caption>    <tbody>
    <tr>
       <th></th>
    </tr>
    <tr>
       <td>                                                          
      <pre>[zippy@mybox nail-9.29]$ <br>[zippy@mybox nail-9.29]$ make             <br>gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c version.c<br>gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c aux.c<br>... more stuff ...<br>gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c tty.c<br>gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c vars.c<br>gcc  -g -O2  -o nail  version.o aux.o base64.o cmd1.o cmd2.o \<br>cmd3.o cmdtab.o collect.o dotlock.o edit.o fio.o getname.o \<br>head.o v7.local.o lex.o list.o main.o mime.o names.o popen.o \<br>quit.o send.o sendout.o smtp.o strings.o temp.o tty.o vars.o  <br>[zippy@mybox nail-9.29]$<br>      </pre>
       </td>
    </tr>
   
  </tbody>            
</table>
  
<p> Now that we have compiled everything, we can install the software. </p>
                   
<table class="sourcecode">
    <caption>Running the Install</caption>    <tbody>
    <tr>
       <th></th>
    </tr>
    <tr>
       <td>                                                          
      <pre>[zippy@mybox nail-9.29]$ sudo make install<br>make[1]: Entering directory `/home/zippy/src/nail-9.29'<br>/bin/sh ./mkinstalldirs /opt/stow/nail-9.29/bin<br>mkdir /opt/stow<br>mkdir /opt/stow/nail-9.29<br>mkdir /opt/stow/nail-9.29/bin<br>  /usr/bin/install -c  nail /opt/stow/nail-9.29/bin/nail<br>/bin/sh ./mkinstalldirs /opt/stow/nail-9.29/man/man1<br>mkdir /opt/stow/nail-9.29/man<br>mkdir /opt/stow/nail-9.29/man/man1<br> /usr/bin/install -c -m 644 ./nail.1 /opt/stow/nail-9.29/man/man1/nail.1<br>test -f /etc/nail.rc || \<br>        { /bin/sh ./mkinstalldirs /etc; \<br>        /usr/bin/install -c -m 644 ./nail.rc /etc/nail.rc; }<br>make[1]: Leaving directory `/home/zippy/src/nail-9.29'<br>[zippy@mybox nail-9.29]$<br>      </pre>
       </td>
    </tr>
   
  </tbody>            
</table>
  
<p>So it's apparent from the previous listing that the file was  tucked under
/opt/stow/nail-9.29 as desired.  Stow then assumes that all the subdirectories
of the package are to be symlinked to their corresponding locations
under <code>--prefix</code> 
(or <code>${prefix}</code> if you look in the Makefile), so that
<code>/opt/stow/nail-9.29/bin</code>
becomes <code>/opt/bin</code>  Similarly
<code>/opt/stow/nail-9.29/man/man1</code> becomes <code>/opt/man/man1</code>
etc. This convention makes it very easy to isolate files 
used from the install locations.  The only step left is to actually
create the symlinks by running stow. </p>
  
<table class="sourcecode">
    <caption><i>Stow</i>ing the binaries</caption>    <tbody>
    <tr>
       <th></th>
    </tr>
    <tr>
       <td>                                                          
      <pre>[zippy@mybox nail-9.29]$ cd /opt/stow/<br>[zippy@mybox stow]$ sudo stow -vv nail-9.29/<br>Stowing package nail-9.29...<br>Stowing contents of nail-9.29<br>Stowing directory nail-9.29/bin<br>LINK /opt/bin to stow/nail-9.29/bin<br>Stowing directory nail-9.29/man<br>LINK /opt/man to stow/nail-9.29/man<br>[zippy@mybox stow]$ ls -ltr /opt/ <br>[zippy@mybox stow]$ ls -ltr /opt <br>total 4<br>drwxr-xr-x    3 root     root         4096 Jan  9 16:33 stow<br>lrwxrwxrwx    1 root     root           18 Jan  9 16:33 man -&gt; stow/nail-9.29/man<br>lrwxrwxrwx    1 root     root           18 Jan  9 16:33 bin -&gt; stow/nail-9.29/bin<br>stow/nail-9.29/bin<br>[zippy@mybox stow]$ PATH=/opt/bin:$PATH type nail<br>nail is /opt/bin/nail<br>      </pre>
       </td>
    </tr>
   
  </tbody>            
</table>
  
<p>Some explanation may be in order here, I cd'd to the stow directory
(<code>${prefix}/stow</code> by default), and simply typed <code>stow
-vv</code> plus the name of the subdirectory 
to recursively symlink.  The -vv simply adds verbose output for illustrative
purposes.  So now all that needs to be done is to modify the $PATH variable,
 and your files are installed. Stow has created all the necessary links.
Note that to uninstall the files (thus breaking the links) simply
<em>unstow</em> them. This will disconnect (unlink) the installed binaries, but
will <em>not</em> delete any files, so it's really quite a useful
safety net.
</p>
                
<p>             
<table class="sourcecode">
             <caption>Unstowing a directory</caption><tbody>
             <tr>
               <td> 
      <pre>[zippy@mybox stow]$ pwd<br>/opt/stow<br>[zippy@mybox stow]$ ls -l<br>total 4<br>drwxr-xr-x    4 root     root         4096 Jan  9 16:33 nail-9.29<br>[zippy@mybox stow]$ sudo stow -Dvv nail-9.29/<br>Unstowing in /opt<br>UNLINK /opt/bin<br>UNLINK /opt/man<br>[zippy@mybox stow]$<br></pre>
 	      </td>
             </tr>
   
  </tbody>            
</table>
 </p>
<p>And all the installed files are neatly out of the way.  Of course to <em>
restow</em> the files you simply repeat the previous commands. This may seem
like a lot of extra work, but once you get in the habit of using it, and
experience the convenience of being able to unlink and entire package you'll
find it's worth it.  Finally, you might want to install nail yourself, and
use it, possibly via an alias or shell function, as a mail
replacement. But that could be an entire article in itself.   <br>
 <br>
 Happy hacking!  </p>
                        
<h3>References</h3>
 
<ol>
 	<li><a name="gnu_stow">GNU stow</a><br>
             Maintained by Guillaume Morin<br>
 	    <a href="http://www.gnu.org/software/stow/stow.html">             http://www.gnu.org/software/stow/stow.html</a><br>
 	    <a name="stow_savannah">GNU stow entry on Savannah</a><br>
 	    <a href="http://savannah.gnu.org/projects/stow">             http://savannah.gnu.org/projects/stow</a>
         </li>
 	<li><a name="checkinstall">Checkinstall</a><br>
             by Itzo <a href="http://freshmeat.net/projects/checkinstall/">
             http://freshmeat.net/projects/checkinstall/</a>         </li>
 	<li><a name="nail">Nail, a replacement for the mail MUA</a><br>
             by Gunnar Ritter<a href="http://omnibus.ruf.uni-freiburg.de/%7Egritter/">
             http://omnibus.ruf.uni-freiburg.de/~gritter/</a>         </li>
 	<li><a name="lfhs">Linux Filesystem Hierarchy Standard, (FHS)</a><br>
             Maintained by freestandards.org<a href="http://www.pathname.com/fhs/">
 	    http://www.pathname.com/fhs/</a>         </li>
 	<li><a name="autoconf_book">GNU Autoconf, Automake, and libtool</a><br>
             By Gary V. Vaughan, Ben Elliston, Tom Tromey, and Ian Lance
Taylor<br>
 	    offers an excellent review of the concepts behind exec-prefix options 
	    to the <em>configure</em> script.<br>
             <a href="http://sources.redhat.com/autobook/">http://sources.redhat.com/autobook/</a>
 	    ISBN 1-57870-190-2<br>
         </li>
   
</ol>
                             <!-- *** BEGIN bio *** --> <spacer type="vertical" size="30">
 
<p>  </p>
<h4><img align="baseline" alt="" src="peda_files/note">
Allan Peda</h4>
 Allan has been enjoying Linux since about 1995, discovering Perl shortly 
thereafter. Currently he works as a programmer analyst at Rockefeller University,
and does part time Linux consulting work in the NYC area.  He enjoys surfing
and sailing, and dreams of owning a charter boat in <em>tranquilo</em> Costa
Rica.  <!-- *** END bio *** -->  <!-- *** BEGIN copyright *** --> 
<p> </p>
<hr> <!-- P -->  
<h5 align="center">  Copyright  2002, Allan Peda.<br>
 Copying license <a href="file:///V:/workarea/copying.html">http://www.linuxgazette.com/copying.html</a><br>
  Published in Issue 75 of <i>Linux Gazette</i>, February 2002</h5>
 <!-- *** END copyright *** -->  <!--startcut ==========================================================-->
 
<hr>
<p> </p>
<center> 
<!-- *** BEGIN navbar *** -->
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="orr.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/issue75/peda.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom"  ></A><A HREF="../faq/index.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="piszcz.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>
 <!--endcut ============================================================-->
 
</body></html>