#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: goform test.form
# Wrapped by riddle@rio-grande on Mon Jul 25 13:41:58 1994
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'goform' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'goform'\"
else
echo shar: Extracting \"'goform'\" \(12068 characters\)
sed "s/^X//" >'goform' <<'END_OF_FILE'
X#!/usr/local/bin/perl
X#
X# goform -- crude telnettable Gopher form fillout daemon
X#
X# History:
X# PASR 03/09/93 Original version (release 0.1) by Prentiss Riddle,
X#
[email protected].
X# PASR 03/29/93 Use CRLF on output to user, to make Macs and PCs happy;
X# explicitly send an IAC WONT ECHO so Mac telnet clients
X# will know that they have to echo locally.
X# PASR 04/02/93 Added "Reply-To" handling. Declared this version 0.2.
X#
X#-------------------------------------------------------------------------
X#
X# INSTALLATION:
X#
X# The goform program should be executed from inetd with the name of the
X# form file as an argument. In order to have multiple goform forms
X# available, each should be assigned a separate port. An example SunOS
X# 4.1.2 installation:
X#
X# Files installed:
X# /foo/cwis/bin/goform executable
X# /foo/cwis/etc/widget.form Widget Request form
X# /foo/cwis/etc/suggest.form Suggestion Box form
X#
X# Added to /etc/services (be sure to make yp afterward):
X# goform10003 10003/tcp # gopher form: widget request
X# goform10004 10004/tcp # gopher form: suggestion box
X#
X# Added to /etc/inetd.conf (be sure to HUP inetd afterward):
X# goform10003 stream tcp nowait nobody /foo/cwis/bin/goform goform /foo/cwis/etc/widget.form
X# goform10004 stream tcp nowait nobody /foo/cwis/bin/goform goform /foo/cwis/etc/suggest.form
X#
X#
X# FORMFILE FORMAT:
X#
X# The first few lines of the formfile specify header lines which will be
X# used to mail off the results after the form is filled out, as follows:
X#
X# To: recipient-address
X# Subject: subject-line
X# Reply-To: return-address
X#
X# The recipient address must be fixed but the subject line and the return
X# address may contain field specifications in the form of a '$' character
X# followed by an integer. These will be expanded to include the
X# user's answers to the correspondingly numbered questions. The Reply-To
X# line is optional; if it is omitted, a "Reply-To:" line will appear in
X# the mail header with no argument. Note that the program doesn't do any
X# error checking of the address specified in the Reply-To field, so
X# recipients should use care in replying.
X#
X# The remainder of the formfile specifies the form to be filled out.
X#
X# Lines containing a '[' are interpreted as questions. Characters following
X# the '[' are taken to be a default value for the answer. Characters
X# preceding the '[' are taken to be a prompt. If there is no prompt
X# preceding the '[', the question is taken to be a running essay questions
X# and multiple lines of input are accepted until a blank line or a line
X# consisting of a single '.' is read.
X#
X# Non-question lines in the formfile are displayed to the user and/or
X# displayed together with the user's answers in the results sent by mail:
X# -- Lines beginning in '>' are displayed to the user but not mailed.
X# -- Lines beginning in '<' are mailed but not displayed to the user.
X# -- Lines beginning in '#' are comments and are ignored.
X# -- Lines containing no '[' and not beginning in '>', '<' or '#' are both
X# displayed to the user and mailed.
X#
X#
X# EXAMPLE FORMFILE:
X#
X# To:
[email protected]
X# Subject: Widget request from $2 ($1)
X# Reply-To: $1
X# # Test form. This is a comment.
X# WIDGET REQUEST FORM
X# >
X# >Widget Services supplies widgets only to registered students, faculty
X# >and staff of Foobar University.
X# >
X# >To pick up your widget go to Room 101 between the hours of 1-2 pm
X# >Monday through Wednesday.
X#
X# Personal info (e-mail address, name, office address, extension):
X# E-mail address: [
X# Name: [
X# Office address: [
X# Extension: [
X#
X# Widget shape (round, square, triangular -- CHOOSE ONE):
X# Round: [n
X# Square: [n
X# Triangular: [n
X#
X# Number of widgets desired: [1
X#
X# What additional features would you like to see in a widget?
X# [
X#
X# <--------------------------------------------------------------------
X# < FOR OFFICE USE ONLY
X# <
X# < Processed by: ____________________________ Date: ________________
X# <
X# < Comments: _________________________________________________________
X# <--------------------------------------------------------------------
X#
X#-------------------------------------------------------------------------
X# Global variables:
X# $ReplyTo "Reply-To:" line
X# $Subject "Subject:" line
X# $To "To:" line
X# $def are there any default answers in @ans?
X# $formfile name of the file from which form will be taken
X# $mailer mail delivery program
X# $nans number of answers in @ansindex (and possible answers in @ans)
X# $nl number of lines in @lines
X# @ans answers from user (may be predetermined defaults)
X# @ansindex table to look up Nth answer in @ans (since @ans is sparse)
X# @lines lines in form
X# @question array of flags: does this line (in @lines) ask a question?
X# FORM file handle for form file
X
X#-------------------------------------------------------------------------
X
Xrequire("ctime.pl");
X
X$mailer = "/bin/mail";
X$usage = "usage: goform formfile";
X
X# Parse command-line arguments.
Xdie("$usage\n") unless ($#ARGV == 0);
X$formfile = $ARGV[0];
X
X# Immediately flush all output to STDOUT. Send an "IAC WONT ECHO" string
X# (per RFCs 1184 and 857) so the Mac client will know it has to echo text
X# locally. Then throw away an initial line of input in order to dispose of
X# any remaining telnet protocol cruft.
X$| = 1;
Xprint("\377\374\001\n"); # IAC WONT ECHO
Xprint("Press return to begin:\r\n");
X$whatnow = <STDIN>;
Xprint("\r\n\r\n\r\n\r\n");
X
X&parseform();
X
Xdo {
X &makepass();
X
X do {
X print("\r\nSave/Cancel/Revise (s/c/r)? ");
X $whatnow = <STDIN>;
X $whatnow =~ tr/A-Z/a-z/;
X } until($whatnow =~ /^\s*(s|save|c|cancel|r|revise)\s*$/);
X if ($whatnow =~ /^\s*(c|cancel)\s*$/) {
X print("Cancelling...")
X &sleep(1);
X exit(0);
X }
X print("\r\n\r\n\r\n\r\n");
X} until ($whatnow =~ /^\s*(s|save)\s*$/);
X
X$Subject = &fixfields($Subject);
X$ReplyTo = &fixfields($ReplyTo);
X
X&sendform();
X
X#-------------------------------------------------------------------------
X# clean -- remove leading and final whitespace from a string.
X#
X# usage: $str = &clean($str);
X
Xsub clean {
X local($str) = @_;
X $str =~ s/^\s*//;
X $str =~ s/\s*$//;
X return($str);
X}
X#-------------------------------------------------------------------------
X# fixfields -- fill out "$N" items in Subject and Reply-To lines with
X# corresponding answers
X#
X# Global variables used: $ans $ansindex
X
Xsub fixfields {
X local($oldsubj) = @_;
X local($l, $newsubj, $s);
X
X # Step through the Subject line. When you find a "$n", substitute
X # the corresponding answer field.
X $newsubj = $oldsubj;
X while ($newsubj =~ s/\$(\d*)/$ans[$ansindex[$1 - 1]]/e) {
X # do nothing
X }
X return($newsubj);
X}
X#-------------------------------------------------------------------------
X# Make a pass through the form.
X#
X# Global variables used:
X
Xsub makepass {
X local($char, $l, $resp);
X
X# # Remind the user how defaults work (unless this is the first
X# # pass and there are none).
X# if ($def) {
X# print("\r\nNOTE:\r\n");
X# print("To accept pre-defined values (in []), press return.\r\n");
X# print("To delete a pre-defined value, type a space.\r\n\r\n");
X# }
X# $def = 1;
X
X # Loop through the lines in the form.
X for ($l = 0; $l < $nl; $l++) {
X
X # Is there a question associated with this line?
X if ($question[$l]) {
X # Do we have a default answer for this question?
X if ($ans[$l]) {
X printf("$lines[$l]<$ans[$l]> ");
X } else {
X print("$lines[$l]");
X }
X # Is this a run-on essay question? (Is there a prompt?)
X if ($lines[$l]) {
X # No, get a single answer.
X $resp = <STDIN>;
X $resp =~ s/[\r\n]*$//;
X $ans[$l] = &clean($resp) if ($resp);
X } else {
X # Yes, it's a run-on question -- accept
X # multiple lines in a single answer.
X print("\r\n") if ($ans[$l]);
X print("(Enter a blank line to finish.)\r\n");
X $resp = <STDIN>;
X $resp =~ s/[\r\n]*$//;
X if ($resp) {
X $ans[$l] = "";
X do {
X $ans[$l] .= &clean($resp) . " ";
X $resp = <STDIN>;
X $resp =~ s/[\r\n]*$//;
X } while ($resp);
X }
X }
X } else {
X # This isn't a question -- print it unless it's
X # intended only for the final mail.
X $char = substr($lines[$l], 0, 1);
X next if ($char eq "<" | $char eq '#');
X if ($char eq ">") {
X print(substr($lines[$l], 1), "\r\n");
X } else {
X print("$lines[$l]\r\n");
X }
X }
X }
X}
X#-------------------------------------------------------------------------
X# mmddyy -- return date in the form "mm/dd/yy"
X#
X# Portability issue: we count on &ctime() to return the date in one of
X# the two following formats:
X#
X# Wed Feb 24 10:42:22 1993
X# Wed Feb 24 10:42:22 CST 1993
X#
X# If it doesn't, we're in trouble...
X
Xsub mmddyy {
X local($date, $dd, $mm, $yy);
X
X $date = &ctime(time);
X ($yy) = $date =~ /\s\d\d(\d\d)\s*$/;
X $mm = &monthindex(substr($date, 4, 3));
X $dd = substr($date, 8, 2);
X $dd =~ s/ /0/;
X return("$mm/$dd/$yy");
X}
X#--------------------------------------------------------------------------
X# monthindex -- given a three-character month abbreviation, return the
X# corresponding integer "01" (January) to "12" (December)
X#
X# usage: $mm = &monthindex($monthstr);
X# error: return -1 in case of error;
X
Xsub monthindex {
X local($monthstr) = @_;
X local($mm);
X $monthstr =~ tr/A-Z/a-z/;
X $mm = index("janfebmaraprmayjunjulaugsepoctnovdec", $monthstr) / 3 + 1;
X $mm = -1 if ($mm <= 0 || $mm > 12);
X $mm = "0" . $mm if ($mm > 0 && $mm < 10);
X return $mm;
X}
X#-------------------------------------------------------------------------
X# Parse the form.
X#
X# Global variables used: FORM
X# Global variables modified: $ReplyTo $Subject $To $ans $ansindex
X# $def $formfile $nans $nl $lines $question
X
Xsub parseform {
X local($_);
X
X open(FORM, "< $formfile") || die("Can't open form $formfile");
X
X $nans = 0;
X $nl = 0;
X $def = 0;
X while ($_ = <FORM>) {
X chop($_);
X
X # Discard comments.
X next if (/^#/);
X
X # Find first instances of header lines.
X if (!$ReplyTo && /^Reply-To:\s+(\S.*)/) {
X $ReplyTo = $1;
X next;
X }
X if (!$Subject && /^Subject:\s+(\S.*)/) {
X $Subject = $1;
X next;
X }
X if (!$To && /^To:\s+(\S.*)/) {
X $To = $1;
X next;
X }
X
X # Determine which lines contain input markers ("[") and of
X # those, which contain predetermined defaults.
X if (/^(.*)\[(.*)\]?$/) {
X $question[$nl] = 1;
X $lines[$nl] = $1;
X $ans[$nl] = $2;
X $ansindex[$nans] = $nl;
X $nans++;
X } else {
X $lines[$nl] = $_;
X }
X $nl++;
X }
X}
X#-------------------------------------------------------------------------
X# sendform -- mail the resulting form off to the recipients defined in the
X# "To:" line.
X#
X# Global variables used: $ReplyTo $Subject $To $ans $lines $mailer $nl
X
Xformat MAIL =
X^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X$line
X~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X $line
X.
Xsub sendform {
X local($char, $l, $line, $s);
X
X print("Sending...\r\n");
X
X # Open the mail process
X $To =~ s/'//g; # sanitized for your protection
X open(MAIL, "| $mailer '$To'")
X || die("unable to open mailer $mailer to $To");
X
X print(MAIL "Subject: $Subject\r\nReply-To: $ReplyTo\r\n\r\n");
X
X print(MAIL "Date: " . &mmddyy() . "\r\n");
X
X for($l=0; $l<$nl; $l++) {
X # Skip lines intended only for the user.
X $char = substr($lines[$l], 0, 1);
X next if ($char eq ">" | $char eq '#');
X if ($char eq "<") {
X # This line intended only for mail recipient.
X $line = substr($lines[$l], 1);
X } elsif ($lines[$l]) {
X # Normal line -- may include an answer.
X $line = $lines[$l] . $ans[$l];
X } else {
X # Indent lines with no question.
X $line = " " . $ans[$l];
X }
X write(MAIL);
X }
X close(MAIL);
X}
X#-------------------------------------------------------------------------
X# end of goform script
END_OF_FILE
if test 12068 -ne `wc -c <'goform'`; then
echo shar: \"'goform'\" unpacked with wrong size!
fi
chmod +x 'goform'
# end of 'goform'
fi
if test -f 'test.form' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'test.form'\"
else
echo shar: Extracting \"'test.form'\" \(1041 characters\)
sed "s/^X//" >'test.form' <<'END_OF_FILE'
XTo:
[email protected]
XSubject: Widget request from $2 ($1)
XReply-To: $1
X# Test form. This is a comment.
X WIDGET REQUEST FORM
X>
X>Widget Services supplies widgets only to registered students, faculty
X>and staff of Foobar University.
X>
X>To pick up your widget go to Room 101 between the hours of 1-2 pm
X>Monday through Wednesday.
X
XPersonal info (e-mail address, name, office address, extension):
X E-mail address: [
X Name: [
X Office address: [
X Extension: [
X
XWidget shape (round, square, triangular -- CHOOSE ONE):
X Round: [n
X Square: [n
X Triangular: [n
X
XNumber of widgets desired: [1
X
XWhat additional features would you like to see in a widget?
X[
X
X<--------------------------------------------------------------------
X< FOR OFFICE USE ONLY
X<
X< Processed by: ____________________________ Date: ________________
X<
X< Comments: _________________________________________________________
X<--------------------------------------------------------------------
END_OF_FILE
if test 1041 -ne `wc -c <'test.form'`; then
echo shar: \"'test.form'\" unpacked with wrong size!
fi
# end of 'test.form'
fi
echo shar: End of shell archive.
exit 0