From: isca@umaxa.weeg.uiowa.edu (Iowa Student Computer Association)
Subject: Scripting in Gopher/Panda
Summary: very rough sketch of current implementation work
Keywords: scripting
Organization: Project Panda
Date: Wed, 19 Aug 1992 16:21:08 GMT


We're working on implementing scripting for Gopher/Gopher+/Panda clients,
to allow Gopher to point off to other services and format input/output more
easily rather than routing everything through gateways in all circumstances.
With hope, the scripting language will be powerful enough so that good
interfaces to existing "odd-ball" services (like whois and finger and the
infamous geography server) can be written, and yet not have potential for
misuse.  It is assumed that the user can be tricked into running any program,
so it is important that the scripting language not offer malicious providers
any more security holes than already exist.

The interpreter inside the client has to be as small as possible.  As a result,
we're using an interpreter that interprets a tokenized forth-like language,
based on the MUF interpreter in TinyMUCK.  Since most of the primitives are
already implemented elsewhere in the gopher client source code, we're hoping
to keep this pretty damn small.

People who wish to write scripts will write them in PUF (Panda's MUF), compile
them locally, test them locally, and then publish the compiled versions of
the scripts into gopherspace.  Since there is a C-like language that can be
"yacc"ed into MUF, I assume that eventually there will be a C-like yaccable
language for this beast.

At this time, we'd like to hear if we're missing out on a primitive you
absolutely *must* have to be effective, or if you think that one of the
primitives listed below opens up a possible security hole.  We're also posting
this to let people who have been curious about the scripting language know
we're doing something about it.  ;^)

This should be ready in about two months for release to the net, although
the interpreter will have to be ported from C++ to C for use in the general
Gopher+ client.



Some examples of scripts that would come in handy:


Doing a CSO nameserver via script instead of in client:


: abort "Search aborted by user" message ;

: error
	1 = if
		"Could not open connection" 3 warn
	else
		"Error in script execution" 9 warn
	endif
	exit
;

: main 
	" " explode 2 = 9 swap assert                     // Make sure two params
	"Name:" "Address:" "E-Mail:" "Phone:" 4 readbatch
	"Searching..." message
	6 rotate 6 rotate opencxn dup dup 1 swap assert
	"query "
	7 rotate dup if "name="    swap + + else pop endif
	6 rotate dup if "address=" swap + + else pop endif
	5 rotate dup if "email="   swap + + else pop endif
	4 rotate dup if "phone="   swap + + else pop endif
	" return all" + crlf + write
	"text" display_rest
;


Logging into a library with a login procedure of "lib <LF> public":
: error "Log in failed" swap warn ;
: main 
   "lib" "public" "oasis.uiowa.edu" 23 cxn 1 swap assert 
	dup rot endl + write dup rot endl + write telnet
;


Example of how scripts would be published into GopherSpace:

Type=!                                            // ! == Script type
Name=CSO Nameserver at U Iowa                     // Name on menu
Path="cso:/scripts/cso" umaxc.weeg.uiowa.edu 79   // Script name & args
Host=chop.isca.uiowa.edu                          // Host containing script src
Port=8337                                         // Port of gopher server

The path is interpreted as:
	"[standard script name:]source-path-name" arguments
The standard script name can be used by clients that have implemented often-
used scripts internally, so that it doesn't have to download the script
source.  For example, it would be trivial for the client to recognize that
it handles "cso" scripts internally and to pass off the arguments to the
built-in cso program.  It can also cache scripts during a single session
based on this name.



Sorry for those of you who don't know Muck's MUF, but what follows are the
*additions* to MUF that make this work with GopherSpace.  In addition to
the primitives listed below, PUF will provide math on integers, string
manipulation on strings, stack handling (rotates, picks, pops, etc), and so
on.  The interesting primitives are described below:

reserved methods:
	error     -- Error handling word.   error( -- i )
	abort     -- User abort word        abort( -- i )


assert( i x -- [i] )
   Do an if-style test on x.  If false, then jump to error with error code
	i left on top of stack, otherwise i is popped.
	(There is an argument on whether or not this sould be "x i" or "i x".
	 Lee thinks it should be "2 = 3 assert".  Doug thinks "2 = 3 swap assert".)

cxn( s i -- f )
   Attempt to open a connection to machine s port i.

endl( -- s )
	Pushes an end-of-line onto the stack.

crlf( -- s )
	Pushes a crlf onto the stack.

file( -- f )
	Creates a temporary file.

gophercxn( f s -- )
	Parses the rest of file/cxn f as if it were input from a type s[0] gopher 
	request.  s[1] may be a "+" character for Gopher+ protocols.  For example,
	to handle the input from file/cxn f as if it were a menu, you would do
	["1" gophercxn].  To handle it as if it were a file, do ["0" gophercxn].

gopher( s -- )
	Interprets s as if it were a gopher specification string, makes it current,
	and handles it.

message( s -- )
   Display message s to user, usually on status line.

mktemp( -- f )
	Create a temporary file.

name( -- s )
	Returns user's name.

read( f -- s )
	Reads a string from the file, connection, or user.  NOTE!  If the user
	types in his or her password, the program is terminated and the result
	is NOT returned.

readbatch( s1 s2 s3 ... sn i -- s1' s2' s3' ... sn )
	Get a set of answers from the user.  Aborts to abort.  No strings may be
	the user's password, as per read.

rewind( f -- )
	Rewinds temporary file f to beginning, for re-processing.
	
telnet( f -- )
	Handles the rest of file (connection) f as if it were a telnet connection.

write( f s -- )
	Writes a string, without RETURN, to a file, connection, or user.

warn( s i -- )
   Display warning s with severity i to user,



Please let me know if there is anything we can help you with.  We look forward
to having this up and running, and the new additions that would be possible
to gopherspace with these services.




Lee Brintle                  | ``And so, I leave you with this final word:
Project Panda                |                 twang.''
Newsgroups: comp.infosystems.gopher,comp.infosystems.wais