#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 '&+' '
 ' > $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

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 2003|Lucas Gonze|[email protected]|I very much enjoyed
my stay at your web site.  Best of luck.
Sat Sep 6 22:54:49 MST 2003|Dee-Ann LeBlanc|[email protected]|Kinda plain,
but that's better than it being covered in animations and flaming text. :)
Sun Sep 7 02:50:48 MST 2003|MC|[email protected]|I don't want the world, I just
want your half.
Tue Sep 9 02:34:48 MST 2003|Andrey Bronfin|[email protected]|Nice to
be here.

The Results

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

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 a format 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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.62.105