old-www/LDP/LG/issue74/tag/7.html

595 lines
22 KiB
HTML

<!--startcut ======================================================= -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<META NAME="generator" CONTENT="lgazmail v1.4F.k">
<TITLE>The Answer Gang 74: [ANSWER] Getting volume label for CD</TITLE>
</HEAD><BODY BGCOLOR="#FFFFFF" TEXT="#000000"
LINK="#3366FF" VLINK="#A000A0">
<!--endcut ========================================================= -->
<P> <hr>
<!--startcut ======================================================= -->
<CENTER>
<!-- *** BEGIN navbar *** -->
<!-- *** END navbar *** -->
</CENTER>
</p>
<!--endcut ========================================================= -->
<!--startcut ======================================================= -->
<P> <hr>
<!-- begin tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::-->
<p align="center">
<table width="100%" border="0"><tr>
<td align="right" valign="center"
><IMG ALT="" SRC="../../gx/navbar/left.jpg"
WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="middle" border="0"
><A HREF="..//"
><IMG SRC="../../gx/navbar/toc.jpg" align="middle"
ALT="[ Table Of Contents ]" border="0"></A
><A HREF="../lg_answer74.html"
><IMG SRC="../../gx/dennis/answertoc.jpg" align="middle"
ALT="[ Answer Guy Current Index ]" border="0"></A></td>
<td align="center" valign="center"><A HREF="../lg_answer74.html#greeting"><img align="middle"
src="../../gx/dennis/smily.gif" alt="greetings" border="0"></A> &nbsp;
<A HREF="../tag/bios.html">Meet&nbsp;the&nbsp;Gang</A> &nbsp;
<A HREF="1.html">1</A> &nbsp;
<A HREF="2.html">2</A> &nbsp;
<A HREF="3.html">3</A> &nbsp;
<A HREF="4.html">4</A> &nbsp;
<A HREF="5.html">5</A> &nbsp;
<A HREF="6.html">6</A> &nbsp;
<A HREF="7.html">7</A> &nbsp;
<A HREF="8.html">8</A> &nbsp;
<A HREF="9.html">9</A>
</td>
<td align="left" valign="center"><A HREF="../../tag/kb.html"
><IMG SRC="../../gx/dennis/answerpast.jpg" align="middle"
ALT="[ Index of Past Answers ]" border="0"></A
><IMG ALT="" SRC="../../gx/navbar/right.jpg" align="middle"
WIDTH="14" HEIGHT="45" BORDER="0"></td></tr></table>
</p>
<!-- end tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::::-->
<!--endcut ========================================================= -->
<P> <hr> <P>
<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<center>
<H1><A NAME="answer">
<img src="../../gx/dennis/qbubble.gif" alt="(?)"
border="0" align="middle">
<font color="#B03060">The Answer Gang</font>
<img src="../../gx/dennis/bbubble.gif" alt="(!)"
border="0" align="middle">
</A></H1>
<BR>
<H4>By Jim Dennis, Ben Okopnik, Dan Wilder, Breen, Chris, and the Gang,
the Editors of Linux Gazette...
and You!
<br>Send questions (or interesting answers) to
<a href="mailto:linux-questions-only@ssc.com">linux-questions-only@ssc.com</a>
</H4>
<p><em><font color="#990000">There is no guarantee</font></em>
that your questions here will <b>ever</b> be answered.
<em><font color="#990000">Readers at confidential sites</font></em>
must provide permission to publish. However,
<em><font color="#990000">you can be published anonymously</font></em>
- just let us know!
</p>
<p>TAG <a href="../tag/bios.html">Member bios</a>
| <a href="../../tag/members-faq.html">FAQ</a>
| <a href="../../tag/kb.html">Knowledge base</a></p>
</center>
<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
<p><hr><p>
<!-- begin 7 -->
<H3 align="left"><img src="../../gx/dennis/bbubble.gif"
height="50" width="60" alt="(!) " border="0"
>Getting volume label for CD</H3>
<p><strong>
Useful scripts and tidbits from Ernesto Hernandez-Novich, Michael Blum,
Richard A. Bray
</strong></p>
<p align="right"><strong>Answered By Ben Okopnik, Mike Ellis
</strong></p>
<blockquote><em><font color="#000066"
>It can be argued that there are some dangers in posting code blocks
which are not actually correct. However, I think the thought processes
revealed in deciding which tricks to use or not while reading data
"closer to the metal" than shells normally go is valuable in and of
itself.
-- Heather</font></em></blockquote>
<P><STRONG>
Greetings from Venezuela.
</STRONG></P>
<P><STRONG>
Someone asked that on a mailing-list I suscribe to; I gave the short-short
answer that happens to be in the CD-ROM HOWTO at www.linuxdoc.org. Later
I answered with code that gives you the label and some more... &lt;g&gt;
</STRONG></P>
<P><STRONG>
Check out and feel free to reproduce the code sample at
</STRONG></P>
<P><STRONG>
<A HREF="http://www.kitiara.org/Lists-Archives/caracas-pm-list-0109/msg00000.html"
>http://www.kitiara.org/Lists-Archives/caracas-pm-list-0109/msg00000.html</A>
</STRONG></P>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
Good stuff. Thank you! I've modified it a tiny bit by adding
</blockQuote>
<blockquote><pre>die "Usage: ", $0 =~ m{([^/]*)$}, " &lt;iso_file|cd_device&gt;\n"
unless @ARGV &amp;&amp; -e $ARGV[0];
</pre></blockquote>
<blockQuote>
at the beginning - just in case I forget how to use it - and modified the
"open" to check the return value in case of problems:
</blockQuote>
<blockquote><pre>open CD, $ARGV[0] or die "Can't open $ARGV[0]: $!\n";
</pre></blockquote>
<blockQuote>
It's great otherwise - I've already got it stowed away as "iso9660info" in
my "<TT>/usr/local/bin</TT>".
<IMG SRC="../../gx/dennis/smily.gif" ALT=":)"
height="24" width="20" align="middle">
</blockQuote>
<P><STRONG>
<IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ernesto]
If your spanish is rusty, the paragraph above the Perl code reads more
or less like:
</STRONG></P>
<P><STRONG><BLOCKQuote>
'Nevertheless, before someone asks "How can I find out who prepared
the CD? When? For what company? Does it belong to a multiple-CD set?
Which one on the set is it?", and since I know <em>that</em> isn't in the
HOWTO, allow me to present a small fragment of (hopefully useful) code.
BTW, the comments along de Volume Descriptor are nothing but the
appropiate mkisofs options needed to fill the values while creating
the ISO image.'
</BLOCKQuote></STRONG></P>
<P><STRONG>
If that sounds harsh is because someone <em>suggested</em> that I didn't know
jack about the ISO-9660 filesystem and was quoting HOWTO's to get
credit &lt;g&gt; (go figure). And so I made a pun at the end of the message,
but only works in spanish.
</STRONG></P>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
Didn't sound harsh to me - I certainly give (and get!) credit for quoting
HOWTOs. The trick is knowing which <em>ones</em> to quote, and which part.
Besides, why does it matter where you got the answer as long as it's right?
</blockQuote>
<P><STRONG>
<IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ernesto]
BTW, feel free to announce the Venezuelan Linux User's Group mailing
list in future installments of LinuxGazette. It's specially well
suited for spanish-speaking Linux users, who can suscribe to l-linux
emailing <A HREF="mailto:majordomo@linux.org.ve"
>majordomo@linux.org.ve</A>; we have our archives available for
browsing in <A HREF="http://www.linux.org.ve/archivo"
>http://www.linux.org.ve/archivo</A> complete with a searching
form working over three years worth of messages.
</STRONG></P>
<P><STRONG>
Keep up the good work!
</STRONG></P>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Heather]
Thanks. We are definitely seeing an increase in spanish requests and
I'm sure our readers will find your list handy.
</blockQuote>
<blockQuote>
----
He certainly wasn't the only reader helping out...
</blockQuote>
<P><STRONG>
<IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Michael Blum]
I just came across in your November issue a question on reading the
volume label from a CD. If it's in ISO9660 format, which includes the
Joliet type CD your reader was burning, it's actually pretty easy to
write a command line tool to read the label.
</STRONG></P>
<P><STRONG>
Here's a bash shell script:
</STRONG></P>
<p align="center">See attached <tt><a href="misc/tag/blum-rd_label.bash.txt">blum-rd_label.bash.txt</a></tt></p>
<P><STRONG>
Note that the parameter is the device file for the CD, e.g. <TT>/dev/hdc</TT>,
and that the CD does not have to be mounted. You need to be 'root' to
run the script.
</STRONG></P>
<P><STRONG>
Here's a C program to do the same thing. I've used this program under
both Linux &amp; IBM's AIX.
</STRONG></P>
<p align="center">See attached <tt><a href="misc/tag/blum-rd_label.c.txt">blum-rd_label.c.txt</a></tt></p>
<P><STRONG>
The only real advantage of the C program is that when compiled the
executable can be made suid to root, allowing you to run the program as
a non-root user. Just as with the shell script the parameter is the
device file for the CD, and the CD does not have to be mounted.
</STRONG></P>
<P><STRONG>
Hope you find this useful! Thanks for your publication - I've learned a
lot from it over the years.
</STRONG></P>
<HR width="10%" align="left"><P><STRONG>
<IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Richard A. Bray]
I finally broke down and read the iso9660 format instead of sleeping the
other night.
</STRONG></P>
<P><STRONG>
Here are the basic commands to get the data. It will clean it up later to
make sure there is a disk in the drive first, and that no errors have
occurred. It should run dd only once to load the CD header into a file.
Then report the results out of that.
</STRONG></P>
<P><STRONG>
I don't know what formats will be compatible with this, but it seemed to
work fine on all of my Windoze CDs and even my <A HREF="http://www.redhat.com/">Red Hat</A> install CD. I guess
I will have to check and make sure that it will work with UDF format someday.
</STRONG></P>
<blockquote><code><font color="#000033"><br>[root@winserver bin]# cat cdinfo
</font></code></blockquote>
<p align="center">See attached <tt><a href="misc/tag/bray-cdinfo.sh.txt">bray-cdinfo.sh.txt</a></tt></p>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
&lt;wince&gt; This is not a good idea. You're hitting the hardware device over
and over when you could do it all in one read:
</blockQuote>
<blockquote><pre>#!/bin/sh
# Make sure that a block device was specified
[ -b "$1" ] &amp;&amp; { printf "Usage: ${0##*/} &lt;cd_device&gt;\n"; }
# Read the entire header
data=`dd if=$1 ibs=863 skip=32769 count=1 2&gt;/dev/null`
</pre></blockquote>
<blockQuote>
Now you can let your CD go back to sleep, and extract whatever pieces you
wanted from the variable:
</blockQuote>
<blockquote><pre>echo "FSTYPE: ${data:0:5}"
echo "OSTYPE: ${data:6:32}"
...
...
</pre></blockquote>
<blockQuote>
This also lets you cut out the temporary variables.
</blockQuote>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Mike]
Ben's suggestions got me wondering - did all those clever tricks really
work? Unfortunately not, because the CD header format includes a lot of
NUL characters (ASCII 0) which bash treats as "end of variable".
</blockQuote>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
</blockQuote>
<blockquote><code><font color="#000033"><br>ben@Baldur:~$ a="`dd if=/dev/hdc ibs=1 skip=32808 count=863 2&gt;/dev/null`"
<br>ben@Baldur:~$ expr length "$a"
<br>863
</font></code></blockquote>
<blockQuote>
Works for me, Mike. The problem may be that you're not quoting the string -
or, quoting the individual chunks (<em>not</em> quoting them is what I use to get
rid of the extra whitespace.) I didn't experiment with this all that much,
but I tested the solution that I suggested, at least for the first few
variables:
</blockQuote>
<blockquote><pre>#!/bin/sh
data="`dd if=/dev/hdc ibs=1024 skip=32 count=1 2&gt;/dev/null`"
echo "FSTYPE :" ${data:1:5}
echo "OSTYPE :" ${data:8:32}
echo "CDNAME :" ${data:40:32}
</pre></blockquote>
<blockQuote>
provides the output:
</blockQuote>
<blockquote><pre>ben@Baldur:~$ ./cdinf
FSTYPE : CD00
OSTYPE : LINUX
CDNAME : LNX
</pre></blockquote>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Mike]
Here's my version of the CD volume label extractor... the handling of non-UTC
timezones is wrong, but otherwise it seems to work OK...
</blockQuote>
<p align="center">See attached <tt><a href="misc/tag/ellis-cdlabel_extractor.bash.txt">ellis-cdlabel_extractor.bash.txt</a></tt></p>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
&lt;gazes admiringly at the data = dd stuff piped through tr line&gt;
That <em>is</em> a cute trick, though. &lt;stuffing it away in my own toolbox&gt;
Thanks!
</blockQuote>
<blockQuote>
An even cheaper way to fold that whitespace: don't quote the variable.
"bash" will swallow anything that is defined as the first two characters
of $IFS - and that happens to be spaces and tabs.
</blockQuote>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Mike]
One problem with eating spaces. I need those for the offsets to work.
<IMG SRC="../../gx/dennis/smily.gif" ALT=":)"
height="24" width="20" align="middle">
</blockQuote>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
That's why you only do that when printing out the individual variables, not
for the entire string. The program flow is "get string -&gt; grab chunks via
offsets -&gt; print w/o spaces."
</blockQuote>
<P><STRONG>
<IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
HEIGHT="28" WIDTH="50" BORDER="0"
>
Now all I am missing is the cd serial number that Windoze generates. I
can't seem to find how to compute that. I may just checksum the first 32K
of the drive and use that.
</STRONG></P>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
I seem to vaguely remember Windows showing some weird number. Are you sure
it's not stored in the CD header itself? Note that I'm not saying that it
is; I'm just wondering.
</blockQuote>
<P><STRONG>
<IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
HEIGHT="28" WIDTH="50" BORDER="0"
>
OK. Here is my current version of the script. I added error checking to
properly return errors if no media or of wrong type.
</STRONG></P>
<P><STRONG>
Thanks to Ben and Mike.
</STRONG></P>
<p align="center">See attached <tt><a href="misc/tag/bray-smart_cd_labelreader.sh.txt">bray-smart_cd_labelreader.sh.txt</a></tt></p>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
</blockQuote>
<blockQuote><CODE>
dd if=$1 bs 1 skip=32768 count 2048 &gt;/tmp/cdinfo$$ 2&gt;/dev/null
</CODE></blockQuote>
<blockQuote><CODE>
[ ... ]
</CODE></blockQuote>
<blockQuote><CODE>
data=`cat /tmp/cdinfo$$ |tr '[\\000-\\037]' '.*'`
</CODE></blockQuote>
<blockQuote><IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> []
Why'd you go and do that?
<IMG SRC="../../gx/dennis/smily.gif" ALT=":)"
height="24" width="20" align="middle">
The file creation is completely unnecessary,
and will leave junk in "<TT>/tmp</TT>" if your script crashes for any reason. If
you want to use that mechanism, simply do it on the fly, like Mike did:
</blockQuote>
<blockquote><code><font color="#000033"><br>data=`dd if=$1 bs=1024 skip=32 count=1 2&gt;/dev/null|tr '[\000-\037]' '.'`
</font></code></blockquote>
<P><STRONG>
<IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
HEIGHT="28" WIDTH="50" BORDER="0"
>
Well, that is because the pipe to tr will always set $? to 0. Then I
wouldn't be able to test for failure of dd. Sorry, but that's the rub.
</STRONG></P>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
[ -z "$data" ] &amp;&amp; { printf "Oops, read failed.\n"; exit; }
</blockQuote>
<blockQuote>
<IMG SRC="../../gx/dennis/smily.gif" ALT=":)"
height="24" width="20" align="middle">
I think this would be even better. What we <em>really</em> care about is that
we have data in $data, right? Best to test the end result - although
intermediate tests, in addition to the final one, certainly don't hurt.
</blockQuote>
<P><STRONG>
<IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
HEIGHT="28" WIDTH="50" BORDER="0"
>
If I
want to use tr to trap for weird characters, then I will have to store the
data somewhere. I suppose it is possible for it to crash before reaching
the rm -f <TT>/tmp/cdinfo$$</TT> line but, if that does happen I probably have
something seriously wrong with tr.
</STRONG></P>
<P><STRONG>
I suppose I could stuff the data in a variable from dd and then echo it to
tr, that would work wouldn't it?
</STRONG></P>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
Well, Mike's contention was that you would lose anything past a null when
just assigning it that way. I didn't do any rigorous testing, but I'm
willing to believe - "\0"s being the way strings are normally terminated.
The one header that I tested didn't chop off short, but it may not have
contained any nulls.
</blockQuote>
<blockQuote>
BTW, Mike - that "tr" function could stand a bit of twiddling.
<IMG SRC="../../gx/dennis/smily.gif" ALT=":)"
height="24" width="20" align="middle">
The extra
'\'s in your "first list" convert backslashes to '.'s; the '*' in your
"second list", as the second character, has the "truncated second list"
effect - i.e., all matches other than backslashes will be converted to
asterisks. That's probably not what you wanted.
</blockQuote>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Mike]
Well spotted! Gets that's what you get for lazy quoting (well, it doesn't
<EM>usually</EM> cause any nasty problems!)
</blockQuote>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
Thanks! Just a matter of clean code. Although printing out an unquoted
"$data" has a <em>very</em> interesting result: it shows the header with all the
control chars converted to stars... and immediately followed by a listing
of the current dir. Why is only the last asterisk interpolated? &lt;shrug&gt;
These are the questions that try men's souls.
</blockQuote>
<blockQuote>
I usually try to make sure that my code doesn't do anything that I
didn't tell it to do, like hanging out in seedy bars with suspicious
characters and drinking till all hours. Gotta watch that stuff, or - bam! -
it'll grab your credit card and be buying drinks all around.
</blockQuote>
<blockQuote>
As well, since all of the data is in the first K, it's not necessary to
grab a 2K block; and since the numbers divide neatly by 1024, it's more
effective to have "dd" reading it a K - rather than a byte - at a time.
</blockQuote>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Mike]
Also a good point, although I'd go one stage further since the CD block
size is standardised as 2K, it's probably most clear (and quickest...?)
to use
</blockQuote>
<blockquote><code><font color="#000033"><br>data=`dd if=$1 bs=2048 skip=16 count=1 2&gt;/dev/null|tr '[\000-\037]' '.'`
</font></code></blockquote>
<blockQuote>
although I concede that it does read a lot more than is strictly necessary.
</blockQuote>
<P><STRONG>
<IMG SRC="../../gx/dennis/qbub.gif" ALT="(?)"
HEIGHT="28" WIDTH="50" BORDER="0"
>
Yes... The drivers "probably" optimize the command, but it would be
better to use the correct size blocks.
</STRONG></P>
<P><STRONG>
Thanks for the tr tips. I've never used tr before. I guess I'll have to
actually read the man page.
</STRONG></P>
<blockQuote>
<IMG SRC="../../gx/dennis/bbub.gif" ALT="(!)"
HEIGHT="28" WIDTH="50" BORDER="0"
> [Ben]
&lt;grin&gt; "When you have learned to snatch the error code from the trap frame,
grasshoppa, it will be time for you to leave." Good luck with your coding.
</blockQuote>
<!-- end 7 -->
<P> <hr> </p>
<!-- *** BEGIN copyright *** -->
<H5 align="center">This page edited and maintained by the Editors
of <I>Linux Gazette</I>
<a href="http://www.linuxgazette.com/copying.html"
>Copyright &copy;</a> 2002
<BR>Published in issue 74 of <I>Linux Gazette</I> January 2002</H5>
<H6 ALIGN="center">HTML script maintained by
<A HREF="mailto:star@starshine.org">Heather Stern</a> of
Starshine Technical Services,
<A HREF="http://www.starshine.org/">http://www.starshine.org/</A>
</H6>
<!-- *** END copyright *** -->
<!--startcut ======================================================= -->
<P> <hr>
<!-- begin tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::-->
<p align="center">
<table width="100%" border="0"><tr>
<td align="right" valign="center"
><IMG ALT="" SRC="../../gx/navbar/left.jpg"
WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="middle" border="0"
><A HREF="..//"
><IMG SRC="../../gx/navbar/toc.jpg" align="middle"
ALT="[ Table Of Contents ]" border="0"></A
><A HREF="../lg_answer74.html"
><IMG SRC="../../gx/dennis/answertoc.jpg" align="middle"
ALT="[ Answer Guy Current Index ]" border="0"></A></td>
<td align="center" valign="center"><A HREF="../lg_answer74.html#greeting"><img align="middle"
src="../../gx/dennis/smily.gif" alt="greetings" border="0"></A> &nbsp;
<A HREF="../tag/bios.html">Meet&nbsp;the&nbsp;Gang</A> &nbsp;
<A HREF="1.html">1</A> &nbsp;
<A HREF="2.html">2</A> &nbsp;
<A HREF="3.html">3</A> &nbsp;
<A HREF="4.html">4</A> &nbsp;
<A HREF="5.html">5</A> &nbsp;
<A HREF="6.html">6</A> &nbsp;
<A HREF="7.html">7</A> &nbsp;
<A HREF="8.html">8</A> &nbsp;
<A HREF="9.html">9</A>
</td>
<td align="left" valign="center"><A HREF="../../tag/kb.html"
><IMG SRC="../../gx/dennis/answerpast.jpg" align="middle"
ALT="[ Index of Past Answers ]" border="0"></A
><IMG ALT="" SRC="../../gx/navbar/right.jpg" align="middle"
WIDTH="14" HEIGHT="45" BORDER="0"></td></tr></table>
</p>
<!-- end tagnav ::::::::::::::::::::::::::::::::::::::::::::::::::::-->
<!--endcut ========================================================= -->
<P> <hr>
<!--startcut ======================================================= -->
<CENTER>
<!-- *** BEGIN navbar *** -->
<!-- *** END navbar *** -->
</CENTER>
</p>
<!--endcut ========================================================= -->
<!--startcut ======================================================= -->
</BODY></HTML>
<!--endcut ========================================================= -->