74 Building a Guest Book


#74 Building a Guest Book

A common and popular feature of websites is a guest book, modeled after the book commonly found at bed-and-breakfasts and chic resorts. The concept's simple: Enter your name , email address, and a comment, and it'll be appended to an existing HTML page that shows other guest comments.

To simplify things, the same script that produces the "add your own entry" form and processes new guest entries as they're received will also display the existing guest book entries (saved in a separate text file) at the top of the web page. Because of these three major blocks of functionality, this script is a bit on the long side, but it's well commented, so it should be comprehensible. Ready?

The Code

 #!/bin/sh # guestbook - Displays the current guest book entries, appends a #   simple form for visitors to add their own comments, and #   accepts and processes new guest entries. Works with a separate #   data file that actually contains the guest data. homedir=/home/taylor/web/wicked/examples guestbook="$homedir/guestbook.txt" tempfile="/tmp/guestbook.$$" sedtemp="/tmp/guestbook.sed.$$" hostname="intuitive.com" trap "/bin/rm -f $tempfile $sedtemp" 0 echo "Content-type: text/html" echo "" echo "<html><title>Guestbook for $hostname</title>" echo "<body bgcolor='white'><h2>Guestbook for $hostname</h2>" if [ "$REQUEST_METHOD" = "POST" ] ; then   # A new guestbook entry was submitted, so save the input stream   cat -  tr '&+' '\n ' > $tempfile   name="$(grep 'yourname=' $tempfile  cut -d= -f2)"   email="$(grep 'email=' $tempfile  cut -d= -f2  sed 's/%40/@/')"   # Now, given a URL encoded string, decode some of the most important   # punctuation (but not all punctuation!) cat << "EOF" > $sedtemp s/%2C/,/g;s/%21/!/g;s/%3F/?/g;s/%40/@/g;s/%23/#/g;s/%24/$/g s/%25/%/g;s/%26/\&/g;s/%28/(/g;s/%29/)/g;s/%2B/+/g;s/%3A/:/g s/%3B/;/g;s/%2F/\//g;s/%27/'/g;s/%22/"/g EOF   comment="$(grep 'comment=' $tempfile  cut -d= -f2  sed -f $sedtemp)"   # Sequences to look out for: %3C = < %3E = > %60 = `   if echo $name $email $comment  grep '%' ; then     echo "<h3>Failed: illegal character or characters in input:"     echo "Not saved.<br>Please also note that no HTML is allowed.</h3>"   elif [ ! -w $guestbook ] ; then     echo "<h3>Sorry, can't write to the guestbook at this time.</h3>"   else     # All is well. Save it to the datafile!     echo "$(date)$name$email$comment" >> $guestbook     chmod 777 $guestbook        # ensure it's not locked out to webmaster   fi fi # If we have a guestbook to work with, display all entries if [ -f $guestbook ] ; then   echo "<table>"   while read line   do     date="$(echo $line  cut -d\ -f1)"     name="$(echo $line  cut -d\ -f2)"     email="$(echo $line  cut -d\ -f3)"     comment="$(echo $line  cut -d\ -f4)"     echo "<tr><td><a href='mailto:$email'>$name</a> signed thusly:</td></tr>"     echo "<tr><td><div style='margin-left: 1in'>$comment</div></td></tr>"     echo "<tr><td align=right style='font-size:60%'>Added $date"     echo "<hr noshade></td></tr>"   done < $guestbook   echo "</table>" fi # Now create input form for submitting new guestbook entries... echo "<form method='post' action='$(basename 
 #!/bin/sh # guestbook - Displays the current guest book entries, appends a # simple form for visitors to add their own comments, and # accepts and processes new guest entries. Works with a separate # data file that actually contains the guest data. homedir=/home/taylor/web/ wicked /examples guestbook="$homedir/guestbook.txt" tempfile="/tmp/guestbook.$$" sedtemp="/tmp/guestbook.sed.$$" hostname="intuitive.com" trap "/bin/rm -f $ tempfile $sedtemp" 0 echo "Content-type: text/html" echo "" echo "<html><title>Guestbook for $hostname</title>" echo "<body bgcolor ='white'><h2>Guestbook for $hostname</h2>" if [ "$REQUEST_METHOD" = "POST" ] ; then # A new guestbook entry was submitted, so save the input stream cat -  tr '&+' '\n ' > $tempfile name="$(grep 'yourname=' $tempfile  cut -d= -f2)" email="$(grep 'email=' $tempfile  cut -d= -f2  sed 's/%40/@/')" # Now, given a URL encoded string, decode some of the most important # punctuation (but not all punctuation!) cat << "EOF" > $sedtemp s/%2C/,/g;s/%21/!/g;s/%3F/?/g;s/%40/@/g;s/%23/#/g;s/%24/$/g s/%25/%/g;s/%26/\&/g;s/%28/(/g;s/%29/)/g;s/%2B/+/g;s/%3A/:/g s/%3B/;/g;s/%2F/\//g;s/%27/'/g;s/%22/"/g EOF comment="$(grep 'comment=' $tempfile  cut -d= -f2  sed -f $sedtemp)" # Sequences to look out for: %3C = < %3E = > %60 = ` if echo $name $email $comment  grep '%' ; then echo "<h3>Failed: illegal character or characters in input:" echo "Not saved.<br>Please also note that no HTML is allowed.</h3>" elif [ ! -w $guestbook ] ; then echo "<h3>Sorry, can't write to the guestbook at this time.</h3>" else # All is well. Save it to the datafile! echo "$(date)$name$email$comment" >> $guestbook chmod 777 $guestbook # ensure it's not locked out to webmaster fi fi # If we have a guestbook to work with, display all entries if [ -f $guestbook ] ; then echo "<table>" while read line do date="$(echo $line  cut -d\ -f1)" name="$(echo $line  cut -d\ -f2)" email="$(echo $line  cut -d\ -f3)" comment="$(echo $line  cut -d\ -f4)" echo "<tr><td><a href='mailto:$email'>$name</a> signed thusly:</td></tr>" echo "<tr><td><div style='margin-left: 1in'>$comment</div></td></tr>" echo "<tr><td align=right style='font- size :60%'>Added $date" echo "<hr noshade></td></tr>" done < $guestbook echo "</table>" fi # Now create input form for submitting new guestbook entries... echo "<form method='post' action='$(basename $0)'>" echo "Please feel free to sign our guestbook too:<br>" echo "Your name: <input type='text' name='yourname'><br>" echo "Your email address: <input type='text' name='email'><br>" echo "And your comment:<br>" echo "<textarea name='comment' rows='5' cols='65'></textarea>" echo "<br><input type='submit' value='sign our guest book'>" echo "</form>" echo "</body></html>" exit 0 
)'>" echo "Please feel free to sign our guestbook too:<br>" echo "Your name: <input type='text' name='yourname'><br>" echo "Your email address: <input type='text' name='email'><br>" echo "And your comment:<br>" echo "<textarea name='comment' rows='5' cols='65'></textarea>" echo "<br><input type='submit' value='sign our guest book'>" echo "</form>" echo "</body></html>" exit 0

How It Works

The scariest-looking part of this code is the small block of sed commands that translate most of the common punctuation characters from their URL encodings back to the actual character itself:

 cat << "EOF" > $sedtemp s/%2C/,/g;s/%21/!/g;s/%3F/?/g;s/%40/@/g;s/%23/#/g;s/%24/$/g s/%25/%/g;s/%26/\&/g;s/%28/(/g;s/%29/)/g;s/%2B/+/g;s/%3A/:/g s/%3B/;/g;s/%2F/\//g;s/%27/'/g;s/%22/"/g EOF 

If you look closely, however, it's just an s/ old / new /g sequence over and over, with different % xx values being substituted. The script could bulk-translate all URL encodings, also called escape sequences , but it's useful to ensure that certain encodings, including those for < , > , and `, are not translated. Security, dontcha know ” a nice way to sidestep people who might be trying to sneak unauthorized HTML into your guest book display.

Running the Script

In addition to allowing files within to be executed by the web server, the directory in which guestbook.cgi resides also needs to have write permission so that the script can create a guestbook.txt file and add entries. Alternatively, you can simply create the file by hand and ensure that it's readable and writable by all:

 $  touch guestbook.txt  $  chmod 666 guestbook.txt  

The following are some sample contents of the guestbook.txt file:

 $  cat guestbook.txt  Sat Sep 6 14:57:02 MST 2003Lucas Gonzelucas@gonze.comI very much enjoyed my stay at your web site. Best of luck. Sat Sep 6 22:54:49 MST 2003Dee-Ann LeBlancdee@renaissoft.comKinda plain, but that's better than it being covered in animations and flaming text. :) Sun Sep 7 02:50:48 MST 2003MCnull@mcslp.comI don't want the world, I just want your half. Tue Sep 9 02:34:48 MST 2003Andrey Bronfinandreyb@elrontelesoft.comNice to be here. 

The Results

Figure 8-6 shows the guest book displaying the few entries just shown.

click to expand
Figure 8-6: A guest book system, all in one neat shell script

Hacking the Script

The data file deliberately forces all the information of each guest book entry onto a single line, which might seem weird but in fact makes certain modifications quite easy. For example, perhaps you'd rather have your guest book entries arranged from newest to oldest (rather than the current oldest-to-newest presentation). In that case, rather than ending the parenthesized while loop with < $guestbook , you could begin it thusly:

 cat -n $guestbook  sort -rn  cut -c8-  while 

If you'd rather have a friendlier date format than the output of the date command, that'd be another easy tweak to the script. On most systems either the date man page or the strftime man page explains all the %x format values. You can spend hours tweaking date formats because there are literally more than 50 different possible ways to display elements of the date and time using aformat string.

It should also be easy to customize the appearance of this guest book by perhaps having separate header.html and footer.html files and then using an appropriate code block near the top and bottom of the script:

 if [ -f header.html ] ; then   cat header.html fi 

Finally, there are a lot of odd people on the Web, and I have learned that it's smart to keep a close eye on anything to which people can add input without any screening process. As a result, a very sensible hack to this guest book script would be to have new entries emailed to you, so you could immediately delete any inappropriate or off- color entries before being embarassed by the content of your site.




Wicked Cool Shell Scripts. 101 Scripts for Linux, Mac OS X, and Unix Systems
Wicked Cool Shell Scripts
ISBN: 1593270127
EAN: 2147483647
Year: 2004
Pages: 150
Authors: Dave Taylor

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net