Backtalk Script Language
Reference Manual

Version 1.4.9

© 1996-2003: Jan Wolter, Steve Weiss

Description

The Backtalk script language is used internally by Backtalk to generate html web pages for conferencing. Conference participants should not need to know anything about the script language, since it is used entirely to configure the system.

It is a RPN, stack-based language, quite similar to Postscript (Postscript is a trademark of Adobe Systems incorporated). It is actually a fully-capable and reasonably-efficient programming language, with special commands built in for accessing conferences. It is oriented toward generating text in a batch mode.

There is a Backtalk Tutorial page giving a brief tutorial introduction to the script language. Readers of this manual may also find the Backtalk Glossary helpful. This describes many of the functions and terminology associated with Backtalk.

Contents

Data Types

Backtalk functions operate on the following kinds of data types:

integer
Backtalk integer objects can have the same range of values as your compiler's int data type. Normally this range is between -2,147,483,648 and 2,147,483,647.

time
Backtalk time objects can represent times in whatever range your version of Unix supports. Usually this range is between Jan 1, 1970 and Jan 18, 2038, but if your Unix can handle dates after 2038, Backtalk will support them too.

mark
Mark objects normally have no value. They are pushed on the stack to mark locations on the stack.

string
String objects may contain an arbitrarily long sequence of ASCII characters.

literal
Literal objects are variable or function names. They can be up to 32 characters long, and may contain letters, digits and underscores, but may not begin with a digit. Literal names are case sensitive, so Count and count are two different literals.

array
Array objects can contain an arbitrary number of other objects. The objects in an array do not all need to be of the same type, and the size of the array will increase or decrease as needed.

regular expressions
Regular expression objects are used for doing fast efficient searches. They are similar to Perl regular expressions and can be used in similar ways.

procedure
Procedures are variations of arrays that contain executable code.

Execution

Backtalk is a stack-based language. Most operations take their operand from the stack and push the results back on the stack. It isn't as pure about this as Postscript is though. Many of the conference-related operators operate on special built-in variables. instead of, or in addition to, the stack.

The program source is read from a file. Source file names must end with a .bt suffix. There is no limit on the size of the file or the lengths of the lines. Comments begin with a percent sign (%), and extend to the end of the line.

There is one special script called config.bt which is used to configure Backtalk. It is automatically included as a header in all other scripts.

The file contains a sequence of tokens, which are executed in order. Tokens may be of several types:

integers
Integer constants are written as usual (i.e., 1023 or 42.) When executed, the value of the integer is pushed on the operand stack.

strings
Strings constants are enclosed in matching parentheses ("(" and ")"). Newlines may appear in strings, and will be stored as newline characters. Alternately, newlines can be typed as "\n". Thus both of the following are equivalent ways to write the same string:
   (One\nTwo\n)

   (One
   Two
   )
There can be parentheses inside the string, but if they do not balance, they need to be preceded by backslashes. Other standard backslash escapes are also recognized, including:
\a   Bell (Control-G)
\bBackspace (Control-H)
\fFeed Forward(Control-F)
\nNewline (Control-J)
\rCarriage Return(Control-M)
\tTab (Control-I)
\vVertical Tab (Control-K)
\0Null (Control-@)
\\Backslash (\)

When executed, a copy of the string is pushed on the operand stack.

procedures
Procedures are enclosed in matching curly-braces ("{" and "}"). Procedures may contain any sequence of tokens, including sub-procedures, separated by white space. When executed, a copy of the procedure is pushed on the stack.

variables
Names of variables are entered without adornment, or with a preceeding slash ("/") character. If the name of a variable is prefixed with a slash ("/"), then the name of the variable is pushed on the stack when it is executed (this is called a "literal"). If there is no slash, and the variable is defined, then it's value is pushed on the stack. If it is not defined, an error occurs.

constants
Constants have the same syntax as variables, but are replaced with their values during compilation, so they will have entirely disappeared from the program by the time it is run. Thus they act similarly to #define variables in the C programming language. There are some predefined system constants that can only be redefined by the config.bt script. Unlike variables and functions, constants are lexically scoped, so if a constant is defined, it can be used anywhere after that point in the file.

regular expressions
Regular expressions are written enclosed in double-angle brackets, like "<<[a-z]+@[a-z\.]+\.com>>". The full syntax for regular expressions is described below. When executed, they are just pushed on the stack.

functions
Function names obey the same syntax as variables. When executed they pop arguments off the stack and push results on. Some may have side effects, such as defining variables.

When execution terminates, the contents of the operand stack (from bottom up) are automatically printed as if the last command in the script had been a print command. Thus scripts often use the stack as an output buffer. Printing may also be forced earlier with the print command.

In the list of functions below, the keywords before the function indicate the objects that the function removes from the stack when executed. It is an error if they are not present or of the wrong types. The keywords after the function name indicate the results pushed on the stack after execution. A "-" indicates nothing. A "|" indicates the bottom of the stack.

Operators

Operand Stack Operators

The following built-in functions manipulate the operand stack. Most are identical to the corresponding postscript commands.

pop
any pop -

Discard the top element from the stack.

exch
any1 any2 exch any2 any1

Exchange top two elements of the stack.

dup
any dup any any

Duplicate the top element of the stack.

copy
any1...anyn n copy any1...anyn any1...anyn

Duplicate the top n elements of the stack. Doing "1 copy" would be identical to "dup".

index
anyn...any0 n index anyn...any0 anyn

Duplicate an arbitrary element off the stack. Note that the indexing here is zero-based. Doing "0 index" would be identical to "dup".

roll
anyn-1...any0 n j roll anyj-1 mod n...any0 anyn-1...anyj mod n

Roll n elements upward j times. If j is negative, it rolls downward instead. Doing ``2 1 roll'' would be identical to "exch". Doing ``k -1 roll'' brings the kth element of the stack to the top.

select
anyn-1 ... any0 n i select anyi

Of n top elements on the stack, discard all but the i-th one.

mark
- mark mark

This pushes a mark onto the stack. Marks are distinct from all other types of stack elements. The [ command is identical to mark.

clear
| any1...anyn clear |

Discard all elements from the stack.

cleartomark
mark any1...anyn cleartomark -

This deletes all stack elements on top of the topmost mark. It is an error if there is no mark on the stack.

count
| any1...anyn count | any1...anyn n

Push the count of elements that were on the stack before the execution.

counttomark
mark any1...anyn count mark any1...anyn n

This counts the number of stack elements on top of the topmost mark. It is an error if there is no mark on the stack.

Dictionary Operators

Backtalk supports a system dictionary, a constant dictionary, a stack of user dictionaries, and an environment dictionary. This is a more complex than the arrangement in Postscript, but allows us to do more preprocessing at compilation time.
  1. System Dictionary - The system dictionary contains all of Backtalk's built-in functions, variables and constants. It is not possible to add definitions to it, but you can change some of the variables. Note that some system dictionary variables are "protected" so that, like constants, you can't change their values, although their values may change by themselves during a run, so they aren't constants.
  2. Constant Dictionary - All constants defined by the user are stored in the constant dictionary. New constants can be added without limit, but, of course, their values cannot be changed once set. (Actually, this dictionary only exists at compilation time, since constants should all be gone by run time).
  3. User Dictionary Stack - All other user defined functions and variables are stored in the user dictionaries. These are kept on a dictionary stack (which is different from the operand stack). You can create new dictionaries on the stack as needed.
  4. Environment Dictionary - This dictionary contains all Unix environment variables that Backtalk was run with. They are all protected, so you can read them, but not change them. The values of environment variables are always of string type.
When you reference a variable, Backtalk searches for first in the system dictionary, then in the constant dictionary, then through all the user dictionaries, starting at the top of the stack and searching down, and finally, if the variable wasn't defined anywhere else, in the environment dictionary. Note that it is possible for there to be different variables by the same name in more than one dictionary. In this case, if you reference the variable, the value returned is the one from the first dictionary searched in the sequence descriped above.

This differs from Postscript in that in Postscript the built-in symbols are always at the bottom of the dictionary stack, while in Backtalk they are at the top. That means that in Postscript you can redefine system dictionary symbols by creating a new symbol by the same name on top of them. This cannot be done in Backtalk, because the system dictionary is effectively always on the top of the stack. This is a deliberate change, which allows us to bind system dictionary names at compile time, and perform significant amounts of optimization.

Before the execution of any other script, Backtalk will execute the config.bt file, which, among other things, creates the first user dictionary on the user dictionary stack. If running as a CGI program, it then processes any variables passed in with the CGI query. Each name/value pair is processed by storing the value in a variable with the given name. If there is a system variable by that name (which is not protected or a constant), it will be stored in the system dictionary. If there is not, a user dictionary entry will be created for it. the QUERY_STRING generated by the user, and loads all the variables from the query string into the system and user dictionaries.

Backtalk can process GET, PUT, and multipart/form-data queries. A special case occurs if the query is a multipart/form-data query, and if Backtalk has been built to support attachments, and if there is a query variable whose name begins with "baa_". In such cases, the value of the variable is stored in a temporary file in the Backtalk attachment archive, and a temporary attachment handle is saved into the variable. This is meant to be used when uploading files to archives, as the values can be larger than anything we want to keep in memory. Temporary attachment handles can be turned into real attachment handles with the make_attach command.

dict
- dict dictionary

Create a an empty dictionary and push it on the stack.

begin
dictionary begin -

Push a dictionary on top of the dictionary stack. Note that a "dict begin" must be done before any user variables can be defined, since symbols cannot be added to the system dictionary. However, there is normally a "dict begin" in the "config.bt" script that will allocate the first user dictionary.

end
- end -

Discard the top dictionary from the user dictionary stack. The system, constants, and environment dictionaries are not actually on the dictionary stack and cannot be discarded.

def
label any def -
any label xdef -

Sets the symbol label to the given value in the current top dictionary. If any is a procedure, this defines a function. The two versions differ only in the order of arguments. Constants and protected variables cannot have their values changed.

store
label any store -
any label xstore -

Sets the symbol label to the given value in the topmost dictionary where it is already defined. If it is not defined, it creates it in the current top dictionary, just like def. If any is a procedure, this defines a function. Constants and protected variables cannot have their values changed.

undef
label undef -

Undefines the symbol label in the topmost dictionary where it is defined. Note that you cannotundefine system or constant dictionary values. If the given symbol is not defined, or is only defined in the system dictionary, nothing happens.

defconstant
label any defconstant -
any label xdefconstant -

Sets the symbol label to the given value in constants dictionary. Constants are expanded at compilation time, so they scope lexically, not dynamically. The two versions differ only in the order of their arguments.

undefconstant
label undefconstant -

Remove the symbol label from the constants dictionary. System constants (the ones defined below in this document), cannot be undefined.

inc
label inc -

This operator increments the named integer variable. It is equivalent to "dup exec 1 + store" but is quicker. It is an error if the variable is undefined, or does not contain an integer.

dec
label dec -

This operator decrements the named integer variable. It is equivalent to "dup exec 1 - store" but is quicker. It is an error if the variable is undefined, or does not contain an integer.

default
label default default value

This checks if the named variable is defined and pushes its value if it is. If it isn't defined, it pushes the given default value instead.

defined
label defined bool

This checks if the named variable is defined and pushes true if it is and false otherwise. This may also be used to check if environment variables are defined.

constant
label constant bool

This checks if the named variable is defined as a constant and pushes true if it is and false otherwise. This is used to do the Backtalk equivalent of the C-language "#if defined()" construct, since it is always resolvable at compile time.

length
dictionary length count

Find the number of key/value pairs in a dictionary.

get
dictionary key get value

Fetch an element from a dictionary. The key can be a string or a literal. It is an error if the key is not in the dictionary.

known
dictionary key known boolean

Check if a symbol is defined in a dictionary.

put
dictionary key value put -

Save a value to a dictionary. The key can be a string or a literal.

Math Operators

The following built-in functions do integer arithmetic. All operands must be integers, and all results will be integers. Function names are not identical to Postscript.

+
int1 int2 + int_sum
time1 int2 + time_sum
int1 time2 + time_sum

Compute int1 plus int2 and push the resulting integer. You can add an integer number of seconds to a time to get a new time, but you cannot add together two times. Note the the + command is also used for string concatination.

-
int1 int2 - int_difference
time1 int2 - time_difference
time1 time2 - int_difference

Compute int1 minus int2 and push it on the stack. You can also subtract an integer number of seconds from a time to get another time, or you can subtract two times to get an integer number of seconds. Note that in the last case, there may be a possibility of overflow on some systems.

*
int1 int2 * product

Compute int1 times int2.

/
int1 int2 / quotient

Compute the integer part of int1 divided by int2.

mod
int1 int2 mod difference

Compute the remainder part of int1 divided by int2.

neg
int1 neg int2

Negative of int1.

abs
int1 abs int2

Absolute value of int1.

band
int1 int2 band int

Bitwise-and of int1 and int2.

bor
int1 int2 bor int

Bitwise-or of int1 and int2.

~
int ~ int

Bitwise-negation of int.

String Operators

Backtalk is not particularly rich in string operators. (Yet?) Unlike Postscript, each string is unique. For instance, if you do a dup on a string, you get two different strings with the same contents, not two pointers to the same string.

+
string1 string2 + concatenation

Concatenate two strings into one string.

`
'
` any1 any2 ... anyn ' concatenation

Convert any number of tokens into strings and concatinate them all together into a single string. The ` command just pushs a mark on the stack. The ' command pops off everything up to the first ` it finds, converts them all to strings (exactly like cvs would), and concatinates them all into a single string. If there are arrays on the stack, then all their elements are concatinated into the string.

jointomark
mark any1 any2 ... anyn delim jointomark concatenation

This is similar to the previous command, but each pair of strings is separated by a copy of the given delimiter, and empty strings are discarded. For example

  mark (a) (b) 17 (c) () (d) (,) jointomark
gives "(a,b,17,c,d).

length
string length count

Find the length of a string.

get
string i get si

Fetch a character from a string. Indexing is zero-based. It is an error if the index is out of range.

substr
string index length substr substring

Construct a string which contains the subsequences of the given string starting at the given index and extending for the given number of characters. If the length is negative, the string ends at the given index. Indices are zero-based.

chomp
string chomp string

Delete any and all trailing newlines from the end of a string.

search
string pattern icase search offset

Test if a fixed pattern occurs in a string. If the pattern is (), the previous search pattern is reused (saving some preprocessing time). If the search succeeds, the zero-based offset of the matching string in the text is given. If it fails, a -1 is pushed. If the icase argument is true, the search will be case insensitive.

replace
string pattern replacement icase replace newstring

Searches for all occurances of a fixed pattern in a string and replaces them all with the given replacement. If the icase argument is true, the search will be case insensitive.

quote
string quote string

This expands out all less-than (<), greater-than (>), ampersand (&) and quote (") characters to their corresponding html encodings. This should be done to any text that we send to the browser that we want to make sure will not be treated as HTML commands.

cgiquote
string cgiquote string

This replaces all spaces with plus signs, and expands plus sign (+), ampersand (&), less-than (<), greater-than (>), equal (=) and percent (%) sign with 3-character hexadecimal codes. This form of quoting is needed on strings that are to be passed as arguments in a GET style CGI query.

jsquote
string jsquote string

Quote a string for use as a JavaScript string. Encloses it in single quotes, and replace all internal single quotes, backslashes, and control characters with JavaScript style backslashed escape codes. Also expands out '<' and '>' characters as hexidecimal escape sequences.

cap
string cap String

Convert the first character of each word in the string from lower case to upper case.

caps
string caps STRING

Convert all lower case characters in the string to upper case.

wrap
string numcols wrap string

This inserts newlines into the given strings so that it contains no lines with longer than numcols.

expand
string expand string

This expands out all less-than (<), greater-than (>) and ampersand (&) characters to their corresponding html encodings, and also makes all substrings that look like URLs into clickable texts that invoke that URL. These links will open either in a new window or in the top window, depending on the setting of the linktonew variable. It also wraps the string to 79 columns. It will also expand out cross-references if the script-writer has defined the functions to process them. This functions should abide by the following descriptions:

format_conf
conf item resp format_conf string...

The function should push onto the stack a URL that will point to the conference conf. Normally the item and response inputs can be ignored.

format_item
conf item resp format_item string...

The function should push onto the stack a URL that will point to item item in conference conf. Normally the response input can be ignored.

format_resp
conf item resp format_resp string...

The function should push onto the stack a URL that will point to response resp of item item in the conference conf.

cleanhtml
html-string cleanhtml html-string

Given an HTML string, this sanitizes it, making sure that all tags are closed, and filtering out tags that we don't consider safe for people to insert into the middle of items and responses. It also makes various strings clickable, just like the expand command does. For this to work, you must define format_conf, format_item, and format_resp just as above. External links will have a target set to either open in a new window or open in the top level current window, depending on the setting of linktonew. This function is called automatically on all HTML responses submitted passed to the the post_item commands. If the allowgraphics flag is false, image tags are among those stripped out.

unhtml
html-string unhtml text-string

This converts an HTML string into a plain text string, removing all tags, and interpreting many of them so that this acts as a crude browser.

spellcheck
text texttype mode proc spellcheck -

This runs a spell checker on a block of text, running the given procedure once for each misspelled word, in the order in which the words appear in the text. The texttype may be either (text/plain) or (text/html). In the latter case, HTML tags (like <BLOCKQUOTE>) and special characters (like &nbsp;) are not checked. The mode flag determines what is pushed onto the stack before each execution of the procedure.

mode:pushed on stack before procedure execution:
0badword
1priortext badword
2suggestions badword
3suggestions priortext badword
The badword is always pushed. It a misspelled word found in the text. Thus, to get an array of all misspelled words, you could do:
   [ text (text/html) 0 {} spellcheck ]

If the mode is 1 or 3, then we also push priortext. This is the fragment of the original text starting after the last misspelled word and ending before the new misspelled word. If the mode is 1 or 3, then we additionally push the remainder of the correctly spelled text after spellchecking is complete. Thus to display the original text with all misspelled words in upper case:

   ` text (text/html) 1 {caps} spellcheck '

If mode is 2 or 3, the we push an array of suggested correct spellings for the bad word. The size and quality of this array varies widely depending on which spell checker backtalk was built with. Aspell gives more guesses than ispell.

As in other forms of loops, break and continue can be used inside the procedure, however, unlike other loop structures, you cannot use a second spellcheck command inside the procedure (hard to imagine why you would want to). The canspell constant tells if this installation supports spell checking. If it does not, no misspelled words will ever be found. The spell_lang variable tells what language to do the spell checking in. The spell_ignore variable has a comma-separated list of misspelled words to ignore for this spell-checking session.

parse
string del parse rest first

This picks the first word off of a string. The delimiter string gives a list of characters which may appear between, before and after words. Unlike the clip function, parse treats multiple consecutive delimiters as a single delimiter. This can be used to break a text string into lines as well as words.

For example, "(,,foo,;bar;fub) (;,) parse" will pick off the word (foo) and also return the rest of the string (bar;fub). If the string contains no non-delimiter characters, then the first word will be the whole string, and the rest will be ().

clip
string del clip rest first

This finds the first occurrence in the string of a character in the delimiter list, and returns the segment of the string before and after that character. Unlike the parse function, clip does not treat multiple consecutive delimiters as a single delimiter.

For example, "(foo,,bar) (,) clip" will return the word (foo) and the rest of the string (,bar). Similarly, "(,,foo,;bar;fub) (;,) clip" will return the word () and also return the rest of the string (,foo,;bar;fub), and "(foobar) (,) clip" will return the word (foobar) and reminant ().

split
string del split word1 word2...

This slices up a string into words, where words are substrings of the string separated by any sequence of one or more delimiters (so multiple delimiters count as a single delimiter as in parse.

For example, "(,,foo,;bar;fub;) (;,) split" push "(foo)", "(bar)" and "(fub)" on the stack. If the string contains no non-delimiter characters, nothing is pushed on the stack.

inlist
word list del inlist boolean

This checks if the given word appears in the given list, which is a string of words separated by the delimiters given in the delimiter string.

noise
- noise string

This generates a random 24-character string. It is generated using a fairly high quality entropy pool, so it should be impossible to predict unless someone knows a shocking amount about the state of the server. (It's the same algorithm used to generate session IDs in configurations that use session IDs.)

cvi
any cvi integer

Converts an object to an integer. If the object is already an integer, this is a no-op, but if it is a string like (486), it converts it to the integer 486. It is basically the Unix atoi() call, so it ignores any non-numeric characters after the digits, and returns zero if the string does not begin with digits at all. If the input is a time, it converts it into an integer (there may be overflow problems with this after the year 2038).

cvt
any cvt time

Converts an object to an time. If the object is already a time, this is a no-op, but if it is a string representing a integer, or an integer it gives the time that many seconds after the epoch.

cvs
any cvs string

Converts an object to a string. If the object is already a string, this is a no-op. If the object is an integer like 486, it converts it into a string like (486). If the object is a literal like /abc, it converts it into a string like (abc) If the object is a time, cvs does the same thing as ctime. If the object is a regular expression or mark, it converts them to an empty string. If the object is an array or procedure, it converts everything in it to a string and concatinates them all together.

cvscol
integer numcols cvscol string

Converts an integer to a string, right-justifying it within a string of numcols blanks.

cvn
string cvn literal

Converts a string to a literal variable name. If the string obeys the length and syntax rules for a variable, it is converted into a literal. Thus, the string (abc) becomes the literal /abc.

datatype
any datatype typestring

Returns the type of an object on the stack. Possible return values are (INTEGER), (STRING), (TIME), (REGEX), (LITERAL), (ARRAY), (PROCEDURE), (DICTIONARY), and (MARK).

Time Operators

The following operators operate on date/time values:

time
- time seconds

Push the current time, as a Backtalk time object.

ctime
seconds ctime string

Convert a Backtalk time to a text string representing the time. The string has the usual Unix format (except without a terminal newline):

    Wed Jun 30 21:49:08 1993
The substr command may be used to pick out your favorite segment. If the timezone variable is defined to something other than a null string, ctime converts using that timezone.

ztime
seconds ztime string

Convert a Backtalk time to text string representing the time. The string has the same format as the ctime string, except that it includes a three-letter timezone abbrevition. If the timezone variable is defined to something other than a null string, ztime converts using that timezone.

htime
seconds htime string

Convert a Backtalk time to a http format time string. Format is like:

   Wdy, DD-Mon-YYYY hh:mm:ss GMT
   Mon, 08-Nov-2004 15:38:42 GMT
This is almost RFC 822 format, except that it has dashs in the date part instead of spaces, and the years is four digits instead of two. It always reports the time in GMT, regardless of the local time zone.

itime
seconds itime string

Convert a Backtalk time to standard international format (ISO 8601) time string. Format is like

   YYYY-MM-DDThh:mm:ssZ
   1997-07-16T19:20:30Z
It always reports the time in GMT, regardless of the local time zone. (The "Z" indicate GMT.)

atime
seconds atime sec min hour mday mon year wday tz

Break out the local time. All returned values are integers, except tz which is a string. The sec, min, hour, and mday are pretty much what you'd expect. The year is a full for digit year. The mon and wday values are zero-based. The tz may be null on some systems where we can't figure it out. If the timezone variable is defined to something other than a null string, atime converts using that timezone. Otherwise it uses the default system timezone.

dtime
string future start dtime seconds

Convert a date/time described by a string to a Backtalk time The input string can be very flexibly formatted. Things that work include exact times, like ``7:30pm January 18, 1994'' or ``1/18/94 19:30:00,'' and less completely specified times like ``March,'' ``June 17,'' ``7pm,'' or ``Tuesday''.

For incompletely specified dates, it will return either the next occurrence of that date (if future is true), or the most recent occurrence of that date (if future is false). For strings that actually describe a period of time (like ``Feb 1996''), it returns the beginning of the time period (if start is true), or the end (if start is false). This can be overridden if the input string is explicit about which interpretation we want, like ``the beginning of next March''.

You can also use relative times in the string, like ``-3 months'' or ``3 months ago'' or ``+1 year, 6 hours, 8 seconds.'' If no sign is given, as in ``3 days,'' the future flag determines whether the returned date will be 3 days in the future or 3 days in the past.

Absolute dates are presumed to be in the time zone specified by the timezone variable.

Minimum and maximum time values can be obtained by asking for ``the beginning of time'' or ``the end of time'' or just ``start'' or ``end''.

If a string that cannot be interpreted is given, dtime returns zero. (Note that ``the beginning of time'' returns one not zero.)

Array Operators

Arrays store sequences of objects. Not all elements of arrays need to be the same type. They can contain any mixture of integers, strings, marks or subarrays.

If you dup an array, you don't get two identical arrays, but two references to the same array. Similarly, if you have a variable defined to an array value, referencing pushes a pointer to the original array, not a copy of the array onto the stack. This is different from string types, which are always copied in these circumstances.

When a print is done, either explicitly or automatically at termination, arrays are handled by printing all their elements in sequence, as if they had all been on the stack separately.

[
- [ mark

The left bracket pushes a mark on the stack. This operator is identical to the mark operator, but is traditionally used to mark the beginning of a sequence of stack elements that are going to be formed into an array by the ] operator.

]
mark any0...anyn-1 ] array

This takes all stack elements up to the mark off the stack, creates an array to store them in, and pushes the resulting array on the stack.

aload
array aload a0...an-1

This pushes the elements of an array singly onto the stack.

length
array length n

This finds the number of elements in an array.

get
array i get ai

Fetch an element from an array. Indexing is zero-based. It is an error if the index is out of range.

put
array i any put -

Store a value in an array element. The value may be of any type. For this to be useful, the array on the stack should have come from some variable, so that the changed array can be accessed again. If the index is past the end of the array, the array will be automatically grown large enough to have such an index, filling in any gap with empty string values. Thus if we do

    /a [(a) (b)] def
    a 4 (c) put
then we end up with the array "[(a) (b) () () (c)]".

in
any array in i

Given an array and a string, integer, literal or time value, check if that value is in the array. If it is, return the index of the first occurance. If it isn't return -1.

asort
array k ascend asort array

This sorts an array of arrays. K is a zero-based index designating which element of each subarray is the sort key. If ascend is true, it sorts the array into ascending order, otherwise it sorts it into descending order. It is an error if any of the elements of the array are not subarrays, if any of the subarrays have less than k+1 elements, or if the kth elements of all the arrays are not all of the same type. The only types that can be sorted on are strings, integers and times. Uses a fairly decent quicksort implementation.

Selector Manipulation Operators

Selectors are used to designate sequences of conferences, items, or responses. They are simply strings of words separated by commas or dashes. Dashes may only be used between two integers or between an integer and a dollar sign. A dollar sign in a subrange, like 8-$ or $-8 is conceptually an infinity value. An isolated dollar sign refers to the last response or item number (depending on context). Thus typical selectors include "dog,cat,mouse,lemon" or "2,13-15,10,7,$" or "95-18,10,97-$". The selectors containing all numbers and dollar signs are numeric selectors. Negative numbers are not understood in numeric selectors.

next_int
sel max next_int rest first

Extract the next number from an integer-type selector, updating the selector to delete that value. The maximum value given will be understood as the value of any dollar sign that appears in the selector. If the selector is empty, a -1 is returned. If it is syntactically incorrect, a -2 is returned.

in_sel
value sel in_sel bool

This checks if the given value is included in the given selector. The value can be a string or an integer. If the value is an integer, it treats the selector as an integer selecter. Dollar signs are treated as infinity values.

count_sel
sel last count_sel count

Given a non-negative value, this counts the number of objects included in a numeric selector. Only values less or equal to the last value are counted.

If last is negative, then this just counts the number of comma-delimited terms, ignoring any dashes. This is mainly for use on non-numeric selectors.

rev_sel
sel rev_sel sel

This reverses the order of a selector. That is "2,13-15,10,7" becomes "7,10,15-13,2".

Relational and Boolean Operators

In Backtalk, booleans are represented by integer, time, or string values. The integer zero, the time "00:00:00 Jan 1, 1970" and the empty string are false, and all other values are true. Functions returning a boolean, return 1 for true and 0 for false. Relational operators may be used on strings, integers, times, and literal names, but you can only compare two objects of the same type.

eq
any1 any2 eq bool

Test if any1 is equal to any2. You can compare times to the integer zero.

ne
any1 any2 ne bool

Test if any1 is not equal to any2. You can compare times to the integer zero.

ge
any1 any2 ge bool

Test if any1 is greater than or equal to any2.

gt
any1 any2 gt bool

Test if any1 is greater than any2.

le
any1 any2 le bool

Test if any1 is less than or equal to any2.

lt
any1 any2 lt bool

Test if any1 is less than any2.

and
bool1 bool2 and bool

Logical-and of bool1 and bool2.

or
bool1 bool2 or bool

Logical-or of bool1 and bool2.

!
bool ! bool

Logical-negation of bool.

Control Operators

Backtalk includes a fair selection of looping and conditional operators. The "boolean" variables mentioned can actually be either string or integer variables. All integer values except zero are treated as true, and all string values except the empty string () are treated as true.

if
bool proc if -

The given procedure is executed if and only if the given boolean is true.

ifelse
bool then-proc else-proc ifelse -

Either of the first or second procedures are executed, depending on whether the boolean is true or not.

loop
proc loop -

Execute the given procedure repeatedly forever, or until a break is performed (or a halt or even a stop for that matter).

while
proc while -

Execute the given procedure for as long as it ends with a true boolean pushed on the stack. Terminate as soon as the procedure pushs a zero or an empty string. The while command discards all the continuation flags pushed on top of the stack at the end of each iteration, but any other values pushed are left on the stack. While loops may be terminated by break as well.

The command "{...} while" is equivalent to "{... ! {break} if} loop".

The command "{... 1} while" is equivalent to "{...} loop".

repeat
count proc repeat -

Execute the given procedure the given number of times. Nothing is put on the stack or removed from the stack by the repeat command. Repeat loops may be terminated by break. If the count is zero or negative, repeat does nothing.

forall
array proc forall -
string proc forall -
dict proc forall -

Forall loops through the elements of an array, string or dictionary. It does one iteration for each element of the array, character of the string, or key in the dictionary. Before each iteration, forall pushs the current element on the stack. String elements are pushed as single-character strings (this is unlike postscript which pushs them as integers). For dictionaries, only the keys, not the values are pushed. For example, "array {} forall" is equivalent to "array aload".

for
init inc limit proc for -

For loops are given a procedure and three integer arguments. An internal variable is set to the initial value before the first iteration. The increment is added to it before each successive iteration. If it passes the limit, iteration is terminated. (That is, if increment is positive and it becomes greater than the limit, or if increment is negative and it becomes less than the limit). Note that the procedure will not be executed at all if the initial value is greater than the limit and the increment is positive, or if the initial value is less than the limit and the increment is negative. If the increment is zero, this is an infinite loop. In addition, before each execution of the procedure, the current value of the count is pushed on the argument stack. Iteration may also be terminated by a break command.

For example, "1 2 1 n {*} for" computes n factorial.

break
- break -

Terminate execution of the first enclosing iterative context. This can be used in the procedures of loop, while, repeat, forall, and for commands. It may be used from inside a file included or called in a iterative procedure. If used outside of an iterative procedure, it is equivalent to a halt command.

continue
- continue -

Terminate execution of the current iteration of the first enclosing iterative context, so that it continues with the next iteration of the loop. This can be used in the procedures of loop, while, repeat, forall, and for commands. It may be used from inside a file included or called in a iterative procedure. It is an error to use it outside of an iterative construct.

halt
- halt -

Stop the execution entirely. After execution is halted, anything remaining on the operand stack will automatically be printed. If you wish to prevent this, do a clear before the halt.

die
message die -

Terminate execution of the script and generate the usual crash dump page, with the given error message.

exec
any exec -

Execute the given token. If the object is a procedure (in curly braces) it gets executed. If it is an array, it gets executed as if it was a procedure. If it is a literal, it gets executed as if it was a symbol (that is "/x exec" is equivalent to "x"). Strings, integers and marks just get pushed back on the stack (so it is a no-op on these).

call
filename call -

Suspend execution of the current file, and run the given file. When the called file is complete, resume execution of this file. The filename must be a relative path with no ``..'' components in it. (That is, you can only include files under the scriptdir directory.)

This is similar to the include command, except that though the two files share variables and function definitions, they do not share not constants, because the call is done at run time, not compile time. Thus constants defined in the current file are not accessible in the called file, and constants defined in the called file are not accessible in the current file, though both may use constants defined by the config.bt file.

include
filename include -

Include the contents of the given file into the current program at this point. The filename must be a relative path with no ``..'' components in it. (That is, you can only include files under the scriptdir directory.) This is similar to the call command, except that since included files are included at compile time, constant definitions from the current file effect the included script, and constants defined in the included script will effect the remainder of the current file. Including files instead of calling them makes a bigger binary file, but will normally run faster.

chain
filename chain -

Include the contents of the given file into the current program at this point, and stop the current program immediately after running it. The filename may not include ``..'' components in the path. This is almost equivalent to doing "include stop", except that it is more slightly more efficient and if the current file is being run under a stopped command, then the termination code of the file we chained to will be returned to the enclosing environment. As with the include command, constants defined in the current file will be usable in the chained file.

jump
filename jump -

Halt the execution of the current file and continue with the execution of the named file. The filename may not include ``..'' components in the path. This is almost equivalent to doing "call stop", except that it is more efficient and if the current file is being run under a stopped command, then the termination code of the file we chained to will be returned to the enclosing environment. As with the call command, variables defined in the current file will be usable in the chained file, but constants will not be.

fork
filename fork -

Run the named script as a child process. This is useful when we have a some slow work to do and we don't want the user to have to wait for a long time for his web page to come back to him. The main script continues execution without waiting for the child script to complete. It receives no results back from the child script.

The child process runs the named script. It starts with an exact copy of the parent process's dictionary and operand stack. Output generated by the child process will not go to the user's web browser. It will just vanish. If the child process generates error messages, as with the die command, that output will be logged, but not displayed.

stopped
filename stopped bool

Insert the contents of the given file. The filename may not include ``..'' components in the path. This is almost equivalent to include except that upon termination it pushs a zero if the execution of the file terminated normally, and a one if the execution terminated with a stop command.

stop
- stop -

Terminate the enclosing file execution. This causes a premature termination of an include or stopped command. If the current context is a stopped command, a one will be pushed on the stack. If there is no enclosing include or stopped, this is equivalent to a halt.

Output Operators

Output is done from the stack. Text formatting is done with separate calls to other routines, not by the output routines themselves, so they aren't very complex.

When outputing an HTML document from CGI programs like Backtalk, it is necessary to prefix the output with the appropriate HTTP headers. Backtalk will automatically output these immediately before the first print, pr or dumpstack command.

You can exert some control over the content of these headers, so long as you do it before the first output statement. If you do so before te first output statement, you can

print
| any1 ... anyn print |

Print out the entire contents of the stack, from bottom up. A print command is automatically executed on termination. Integers and strings are printed the obvious way. Times are printed as if ctime had been run on them. Arrays have all their elements printed as if they had been separately pushed on the stack. Literals have their values printed, unless they are undefined, in which case nothing is printed. (Thus, if you are printing a table of values, you can push the a literal like /nrows on the stack first, then generate all the table rows, counting them in the nrows variable, and then print, and the current number of rows will appear at the top of the table.)

pr
any pr -

Print out the top stack element.

dumpstack
- dumpstack -

Prints a snapshot of the stack to standard output, without altering the stack. This is a debugging tool.

setcookie
name value expire-time setcookie -

Set a cookie by adding a "Set-Cookie" directive to the HTTP headers for this page. This must be done before the first print, pr or dumpstack command, since the headers are output before the first text is output. Name is the name for the cookie and value is its value. The value should not contain any spaces or semicolons (actually, spaces seem to work with at least some browsers). Expire-time is the expiration time for the cookie. If it is zero, the cookie has no expiration time, and will be deleted as soon at the user exits his browser. If it is in the future, the user's browser will keep the cookie until that point in time and then delete it. If it is in the past, the cookie expires immediately (to delete an existing cookies from the user's browser, we overwrite it with one whose expiration date is in the past). You can set more than one cookie from the same page so long as they have different names. If you set the same cookie twice from the same page, only the last value is sent to the browser.

getcookie
name getcookie value 0
name getcookie 1

Get the value of a cookie set on some previous Backtalk page. If the cookie exists, the value is pushed on the stack along with an error code of zero. If it does not exists, only the error code of 1 is pushed. (Note that you can alternatively get cookies out of HTTP_COOKIES environment variable yourself.)

Regular Expression Commands

Backtalk's regular expressions are similar in syntax to those in Perl or in many other Unix programs. You can write the regular expression into your program, enclosing it in double angle-brackets ("<<" and ">>") or you can use the regex command to compile a string into a regular expression. Note that regular expressions entered in double-angle brackets will be compiled at compile time, speeding up their use at run time. Compiled regular expressions can be manipulated like any other Backtalk data type - they can be pushed on the stack, duplicated, assigned to varibles, etc. There aren't many operations you can perform on them except searching with them.

The full syntax of Backtalk regular expressions is described below.

There is a command to compile strings into regular expressions, and several commands to search for regular expressions. The following regular expression commands are known to backtalk:

regex
string flags regex regex 0
string flags regex errmsg 1

Compile a string into a regular expression. The string is a regular expression defined by as below. The flags may be "()", "(m)", "(i)", "(im)" or "(mi)". The "i" means to ignore case, the "m" means to "^" and "$" match against newlines internal to a pattern, not just the beginning and ending of the pattern. If the regular expression syntax is OK, it is compiled and pushed onto the stack, followed by a one. If the syntax of the regular expression is incorrect, an error message string is pushed on the stack, followed by a one.

grep
string regex grep boolean

Check if the given pattern occurs in the string. Push 1 if it is, 0 if it isn't.

ogrep
string regex ogrep array 1
string regex ogrep 0

Just like grep, except if it succeeds it returns information about where the match occured, plus information about what each paranthesized subexpression matched. The returned array has one more element in it than there are pairs of parentheses in the regular expression. Each element of the array is a two element array, giving an beginning offset and the length of a substring of the original string. The zeroth pair indicates the portion of the entire matched by the entire regular expression. The remaining pairs indicate the substrings matched by each set of parenthesis in the regular expression.

sgrep
string regex sgrep array 1
string regex sgrep 0

Just like ogrep, except instead of returning an array of offsets and lengths of matching strings in the original string, it returns an array of strings, where the zeroth element is the substring of the input string that matches the full regular expression, and each other element of the array is the substring of the original text that matches the corresponding parenthesized subexpression in the regular expression.

rgrep
string regex nmatch proc rgrep -

This searches the string for sections matching the regular expression. Each time a match is found, the non-matching substring between the last match and this match is pushed on the stack. If nmatch is one, the matching substring is also pushed. If nmatch is greater than one, then nmatch substrings are pushed, the first being the substring that matched the whole expression, and the later ones being the substrings that matched any parenthesized subexpressions. After all this stuff has been pushed the procedure is executed. This continues until no more matches are found or until the procedure does a break. At that time, the remaining unmatched hunk of string will be pushed. A negative nmatch value means push all subexpression matchs.

Warning: This can go into really impressive infinite loops if given a pattern that matches a null string.

You can delete all instances of an expression from a string by doing

` string expression 0 {} rgrep '
You can substitute all occuranges of a regular expression with the text "XXX" by doing
` string expression 0 {(XXX)} rgrep '
To substitute only the first instance, do
` string expression 0 {(XXX) break} rgrep '
You can convert all occuranges of a regular expression to upper case by doing
` string expression 1 {cap} rgrep '
You can do pretty much anything else your heart desires too.

File Commands

File commands take filenames in either of two different formats. The first is the standard Unix format, where the filename is given as a full or partial path. Partial paths are aways relative to scriptdir.

The second format is as a Backtalk file-handle. File handles always start with an asterisk followed by the name of a file. Backtalk figures out the full path of the file by itself. It also knows something about the type of the file and who may write to it.

Commands to read from files will accept either format. Commands to write from files only work with file-handles. Thus only files for which Backtalk has handles may be written to, and Backtalk will enforce rules about who may write to those files. The following handles are known to Backtalk:

(*.backtalk)
The current user's Backtalk settings. Used by Backtalk instead of .cfonce or .cfrc.
(*.cflist)
The current user's conference list. Shared with Picospan.
(*.cfonce)
The current user's file of Picospan commands to run on start up. Mostly used by Picospan.
(*.cfrc)
The current user's file of Picospan commands to run on when a new conference is joined. Mostly used by Picospan.
(*.plan)
The current user's .plan file.
(*acl)
A Yapp-style access control list for the current conference.
(*bbsrc)
A Picospan command file executed for all users when they first enter. Mostly used by Picospan.
(*bull)
The current conference's bulletin file (Rarely used).
(*confdata/)
The current conference's data directory.
(*confdata/anything)
Files in the current conference's data directory.
(*config)
The current conference's configuration file.
(*confmenu)
The current list of conferences displayed to users (Replaces the Picospan public.txt file).
(*confrc)
A Picospan command file for the current conference. Mostly used by Picospan.
(*data/)
The system-wide data directory.
(*data/anything)
Files in the system-wide data directory.
(*dflt.backtalk)
The system-wide defaults for user configuration settings not set in the user's .backtalk file.
(*dflt.cflist)
The system-wide default conference list used for users with no .cflist file.
(*glist)
The current conference's glist file. For closed conferences this is a list of all user group names that can access the conference. (Backtalk only).
(*index)
The current conference's index file. (Rarely used).
(*login)
The current conference's login file. (Ascii text version used by Picospan. The ``login'' tag in the ``*settings'' file is preferred by Backtalk.)
(*logout)
The current conference's logout file. (Ascii text version used by Picospan.)
(*motd.html)
HTML formatted message-of-the-day to be displayed on front page.
(*public.txt)
The system-wide list of conferences (used by Picospan only).
(*secret)
The current conference's password.
(*settings)
The current conference's settings file. (Backtalk only).
(*ulist)
The current conference's ulist file. For open conference, this is a list of user logins who have joined the conference. For closed conferences, it is a list of user logins who are allowed to join the conferences.
(*welcome)
The current conference's welcome file.
A few files are associated with separate default files. If the user doesn't have a .cflist file, and you attempt to read from it, then the dflt.cflist file will be read instead. Thus, all users who don't define their own conference lists, get the system default conference list. The defaulting mechanism is never used on writes. If a user who doesn't have a .cflist writes to his .cflist, the file is created.

The dflt.backtalk file contains default settings for the users .backtalk file. Defaulting works a bit differently for tag files. If you attempt to load a tag which is not defined in the .backtalk file, the system will then search for it in the dflt.backtalk file. A similar defaulting mechanism is planned for conference settings files, but has not been implemented yet.

The following file commands are known to backtalk:

read
filename read string

The entire contents of the named file are pushed onto the stack as a single string. The filename may be a path or a file-handle. If the file doesn't exist, but the handle has a default file, the default file is loaded instead. If no file exists, a null string is returned.

write
string filehandle write -

The given file is first created or emptied, and then the given string is written into it. The filename must be designated with a file handle. It is a fatal error if the file is not writable.

pathname
filehandle user pathname path

This converts a filehandle into a full path name. It is mainly used to find files belonging to other users, so to read fred's .plan file, we'd do "(*.plan) (fred) pathname read". If the username is an empty string, it defaults to the current user, but that's kind of useless.

savevar
filehandle varlist savevar -

Save one or more variables into the named tag file, which must be designated by a file handle. The variable list argument may be either a single variable name, or an array of variable names. All variables must be defined, and must have an integer or string value. A variable name ending with a dot, will cause all string or integer variables with that prefix to be saved. If the tagfile does not exist, it will be created. If it does exist, the new fields will be added to the ones already there, replacing any with the same name. Attempts to change the value of protected tags are silently ignored.

This cannot be used with the (*.backtalk) handle. Use saveuser instead.

To undefine values in a tag file, use the undefvar command.

loadvar
filename varlist loadvar error

Load one or more variables from the named tag file, whose name may be given as either a path or a file-handle. The variable list argument may be either a a single variable name, or an array of variable names. Each variable will be set to the value defined for it in the file, using a store operation to set it. A variable name ending in a dot will load all variables with that prefix. If there is no definition for a variable in the tag file, that variable will be silently ignored. If the file does not exist, a boolean false is pushed, otherwise it returns true. Any fields not defined in the file itself will be loaded from the default file, if one is defined for the handle. Any variable with is not defined will simply not be changed.

This cannot be used with the (*.backtalk) handle. Use loaduser instead.

undefvar
filename varlist undefvar -

Remove definitions of the named variables from the given tagfile. The variable list argument may be either a a single variable name, or an array of variable names. If any variable name ends with a dot, then all variable names starting with that sequence of characters will be removed from the tag files. The named variables do not need to be defined in the current dictionary, and their dictionary values, if any, will not be changed. They will only be deleted from the tag file.

This cannot be used with the (*.backtalk) handle, or with any tag file that contains protected fields.

line
filename n line string

Read the nth line of a file and push it on the stack. Lines are numbered from zero. A null string is pushed if the file or the line doesn't exist.

tail
filename n tail string

Return the last n lines of a file. Fewer lines may be returned if the line has fewer than n lines. A null string is pushed if the file is empty or does not exist.

readable
filename readable bool

Test if the named file can be read. The name may either be a path or a file-handle. If file handle has a default, it will return true even if the named file doesn't exist, but the default file does.

writable
filename writable bool

Test if the named file can be written. Only file-handles are writable, so if a path is given it will always fail. Files that do not exist may be writable if they are in a writable directory.

exists
filename exists bool

Test if the named file exists. If file handle has a default, it will return true even if the named file doesn't exist, but the default file does.

filedate
filename filedate time

If the file exists, push the time at which it was last modified (the mtime). If it doesn't exist, push zero.

openfile
filename openfile err

Open a file. Returns 1 if the file does not exist or cannot be read, or 0 on success. Normally we'd follow up by calling nextline and then closefile. Only one file can be open at a time. Any previously open file will be closed by this.

nextline
- nextline line

Return the next line from the currently open file (see openfile). The string will normally be terminated by a newline, but it won't be if it is the last line of the file and the file does not end with a newline. Returns an empty string on EOF.

closefile
- closefile -

Close the currently open file, as opened by the last call to openfile. This is a no-op if there is no open file.

directory
dirname directory bool

Test if the named handle or path refers to a directory. Returns false if either the object does not exist or it is not a directory.

firstdir
dirname firstdir filename

Return the name of the first file or directory in the given directory. The directory name can be either a path name, or directory file handle, like (*data/) or (*confdata/). After calling this, call nextdir to get the rest of the names in the directory.

nextdir
- nextdir filename

Return the name of the next object in the directory specified by the last call to firstdir. Returns an empty string when we have reached the end of the directory.

User Database Operators

The following commands query or edit the Backtalk user database. The user database may be configured in many different ways. Normally Backtalk accounts are completely disconnected from Unix accounts on the host system, however for systems where Backtalk is to coexist with Yapp or Picospan, it may be desirable to use real Unix accounts for Backtalk accounts. In this case, the routines to create accounts and groups, change passwords, change fullnames, and validate or delete accounts will not work (all these operations would require root access, which Backtalk does not have). Users will have to log onto their Unix accounts to perform these operations.

Backtalk has a notion of user groups similar to the unix notion of user groups. Users have a primary group ID, and can also be in several secondary groups. Three groups are special. The 'user' group is the default user group, in which accounts are normally created. Any user in the 'cfadm' group is a conference administrator, and can create, destroy and edit user accounts and conferences, and functions as a fairwitness in all conferences. Any user in the 'gradm' group can also create accounts, even if the system is configured so that regular users can't. Furthermore, users in the 'gradm' group can create accounts not only in the 'user' group but in any other group (except 'gradm') of which the user is a member. Other groups may be created, and conferences may be configured so that only members of some group may join them.

Several user functions access different kinds of user data using keywords. Any keyword can be used, but certain keywords have significance to the system. These are:

keywordDescriptionReadable byWritable by
/dirpath The full path name of the user's home directory All usersNobody
/email User's email address All users unless /eprivacy is zero User, cfadm and gradm. Changing this resets /evalid
/eprivacy Privacy setting for email address. 0=only user and admin may see. 1=only user and admin may see, but others may send mail via backtalk. 2=only registered users may see. 3=all may see, but obscure for anonymous users. 4=all may see. All usersUser, cfadm and gradm
/evalid Empty string if the user's email address has been validated. Validation code otherwise. All userscfadm and gradm may set to empty string
/grpid The user's primary gid number. If set to a string value, this is interpreted as a group name. All userscfadm only
/laston The time of the user's last login All usersNobody
/passwd User's unencrypted password NobodyUser, cfadm, gradm
/privacy Controls access to other fields All usersUser, cfadm and gradm
/usrid The user's uid number All usersNobody
/usrlogin The user's login name All usersNobody
/usrname The user's full name All users if myseefullname set, otherwise user cfadm and gradm.User, cfadm and gradm
/usrstat The user's account status. 0=validated, 1=unvalidated, 2=invalidated, -1=does not exist All userscfadm and gradm only
anything else Other random data All users if /privacy is zero. User, cfadm and gradm otherwise User, cfadm and gradm
Values that are editable by "cfadm" can be editted by any person who is in the group "cfadm". Values that are editable by "gradm" can be editted by any person who is in the group "gradm" and whose primary group id matches the primary group id of the user being editted.

pushuser
login keylist pushuser keyvalues... errflag

Fetch information about a user from the user database. The login can be the name or a user or an empty string. If it is an empty string the currently logged in user or the currently effective user (see selectuser) is used. It is also given a list of keys from the table above (either a single literal or an array of literals). It pushs the values of those keys for that user onto the stack in the order they were given. An empty string is pushed for any key with no defined value. If the user does not exist, no values are pushed and a flag of 1 is returned. Otherwise the flag is always 0.

loaduser
login keylist loaduser errflag

Fetch information about a user from the user database. This is the same as pushuser except instead of pushing the values on the stack, variables with names matching the keys are set to the values of those keys. If a key has no value, the value of the variable is not changed. The error flag is 0 on success or 1 if the user does not exist.

defuser
login key value defuser errstring

Save new information about a user to the user database. This saves just one value, so it takes a single key, not an array. As usual, the current (or effective) user is used if the login is an empty string. On success it returns an empty string. Otherwise, it returns a detailed error message string.

saveuser
login keylist saveuser -

Save new information about a user to the user database. The login can be the name or a user or an empty string. If it is an empty string the currently logged in user or the currently effective user (see selectuser) is used. It is also given a list of keys from the table above (either a single literal or an array of literals). For each named key, the value of the corresponding variable is saved as a new value for the user. If the values are not legal, an error is generated.

valcode
login email valcode valcode errflag

Validate an user's email address. If the given login doesn't exist, we return error code 1. If it's email address doesn't match the one given, return error code 2. If the address is already valid, return success code 0. If the validation code does not match the stored validation code, return error code 3. Otherwise, mark the email address as being valide. If the validatemail configuration constant is set to 2 and the user's account is currently in an 'unvalidated' state, mark it as valid, enabling the user to log in.

firstuser
- firstuser login

Return the login name of the first user in the user database. The notion of "first" here man be nearly meaningless. The intent is that this be used to initialize a walk through the user database done with nextuser.

seekuser
login seekuser -

Like firstuser, this initializes a walk through the user database, but instead of starting from the beginning, it starts from the named user. The next call to nextuser will return the name of the successor of the user passed to this function.

nextuser
- nextuser login

Return the login name of the next user in the user database. firstuser or seekuser must have been called previously to initialize the loop.

ingroup
group login ingroup boolean

Check if the named user is in the given group. If the login ID is given as (), check the currently logged in user. The group may be given either as a string group name or an integer gid number.

groups
- groups groupname1 groupname2 ...

Push the names of all known user groups onto the stack.

dfltgroup
- dfltgroup groupname

Push the name of the group in which users are created by default.

groupid
groupname groupid groupid

Given a group name, find the corresponding group id number. If no group by that name exists, return -1. If the input string is numeric, like (23), it simply converts that to an integer type.

groupname
groupid groupname groupname

Given a group id number, find the corresponding group name string. If no group by that name exists, return ().

newuser
login fullname password group privacy emailprivacy varlist newuser error

Create a new user account. Depending on your system configuration, this may work for all users, or only for those in the 'cfadm' and 'gradm' groups. Users in the 'gradm' group may create accounts in any group that they are members of, except the 'gradm' group. Users in the 'cfadm' group may create accounts in any group. Other users, if they are allowed to create accounts at all, can create them only in the default user group.

The login is the desired login id, and password is an unencrypted password to use. The group may be given either as a string group name, or an integer gid number.

The varlist is a array of literal names (or a single literal name) to save to the user's .backtalk file, just as in the savevar command. In addition to the variables listed, a variable named 'regdate' is saved with the current time. If a variable named email is included, and if we are configured to save email addresses to the identity database, then this will be done.

On success, an empty string is returned. Otherwise, a string of error messages (separated by \n) is returned.

selectuser
loginname selectuser -

Users in conference administrator group may execute this command for any user login, and user in the gradm group may execute it for user logins which have the same primary group as they do. It changes the account that open_conf, changepass, changeemail and removeuser operate on from the user's own account to the named account. It also makes file handles for user files refer to the selected user's files, so that the conference administrator may write to them. Giving a login name of () reverts to selecting the conference administrator's own account.

removeuser
- removeuser -

Permanently delete the user's account. Conference administrators may apply this command to another user's account by doing a selectuser command. This function will not work on installations where the nopwedit constant is true (i.e., those that use the unix password file as the user database).

validate
loginname flag validate -

This validates (if the flag is true) or invalidates (if the flag is false) a user account. Invalidated accounts still exist, but cannot be logged into. Users in conference administrator group may execute this command for any user login, and user in the gradm group may execute it for user logins which have the same primary group as they do. This function will not work on installations where the nopwedit constant is true (i.e., those that use the unix password file as the user database).

newgroup
groupname newgroup flag

Create a new group with the given group name. Returns 1 if the group already exists, 0 on success. Only conference administrators can execute this command.

newgroupmem
groupname username newgroupmem flag

Add the given group to a user's list of secondary groups. Returns 1 if the group does not exist, 0 on success. Only conference administrators can execute this command.

delgroup
groupname delgroup flag

Delete a group. Returns 1 if the group did not exist, 0 on success. Only conference administrators can execute this command.

delgroupmem
groupname username delgroupmem flag

Remove the given user from the given group. Returns 1 if the group does not exist or the user was not in it, 0 on success. Only conference administrators can execute this command.

newsession
login password newsession flag

For systems configured to use sessions (where the sessions variable is true) this function initiates a new session. The user's login and password are passed in. If the user does not exist, or the password is incorrect, or the system is not configured to use sessions, flag will be true and nothing else happens. If the login is correct, an entry is created in the session database, a cookie with the session ID is created, and flag is set to false. For the cookie to be correctly set, this must be done before the first print, pr, or dumpstack.

killsession
- killsession -

Invalidates any session that may be in progress, and erase any session cookie. This logs the user out, in systems configured to use sessions.

Miscellaneous Operators

browser
- browser code

This returns an integer code classifying the user's browser into one of four rough groups according to its capabilities.

code=0:
Non-graphical browsers, like Lynx. No tables.

code=1:
Basic HTML 2.0 browsers, with no tables or frames. Often &nbsp doesn't work.

code=2:
Enhanced browsers, with tables, but not frames. Netscape 1.x browsers.

code=3:
Browsers that support frames. Netscape 2.0 and Internet Explorer.

Further codes may be added in the future (maybe 4 means JavaScript). The database this is generated from is currently very incomplete. The complete description of the browser can be found in the environment variable HTTP_USER_AGENT. This is somewhat obsolete, as nearly all modern browsers have all these capabilties and there is little sense any more in supporting anything except the 0 and 3 cases.

serverurl
- serverurl url

Push the URL of the server on which the current request was made. This is something like (http://www.yourhost.com). The protocol will be either http or https depending on how the request was made. If this is unavailable (as when Backtalk is being run from a browser) an empty string is returned.

backtalkurl
- backtalkurl url

Push the URL of the backtalk CGI program on which the current request was made. This is typically something like (http://www.yourhost.com/cgi-bin/pw/backtalk). The protocol will be either http or https depending on how the request was made. If this is unavailable (as when Backtalk is being run from a browser) an empty string is returned. If defined, this is the same as serverurl with the SCRIPT_NAME environment variable appended.

mimename
type mimename name

Given a mime type, like "application/msword" find an English description, like "microsoft word". If no English description is known for the type, the type is returned unchanged. Currently this only works in installations where attachments are enabled. In other installations is a no-op, always returning whatever was passed in.

rand
range rand number

Generate a random integer between zero and range-1.

srand
seed srand -

Seed the random number generator with the given seed. If do not explicitly seed the random number generator, it is automatically seeded with the current time (Essentially a "time srand" is done). Thus, the srand call is only needed if you want repeatable runs while debugging.

timeout
seconds timeout -

Terminate the program with a crash after the given number of seconds has elapsed. This is meant to be used during development of new scripts to control infinite loops, since the script developer may not have the access to kill a runaway process. Successive timeout calls reset the clock. An argument of zero cancels any pending timeouts.

sleep
seconds sleep -

Sleep for the given number of seconds.

httpget
uri method httpget content type reason status

Fetch an http document. The uri argument is a standard URL, beginning with "http:", like this:

http://[user:pass@]host[:port]/[path][?query]
Here optional portions are enclosed in square brackets. Only the http protocol is understood. No https or ftp URLs will work here. The user and pass parts are a username and password to pass in for basic authentication (this syntax is a netscape extension, I think). The host can be an IP address or host name.

The method should be (GET), (POST), (HEAD), or (XML-RPC). Note that although the URL is always written to look like a 'GET' URL, with arguments in a query string on the end of the URL, we can still do 'POST' requests. The content of the 'POST' or 'XML-RPC' call is just the query string from the URL.

If the URL is syntactically incorrect, or if Backtalk cannot connect to the specified host, a status of 0 will be returned, and all other outputs will be empty strings.

If Backtalk is able to communicate with the server, then status will be the integer status code returned by the server. Status 200 indicates success. Status 301 and 302 indicate a redirect, but normally Backtalk will automatically follow redirects, so these codes will only be returned if an excessively long chain of redirects is found. Other common errors are 404 if the requested page does not exist, and 401 if authorization is required.

The reason is a string explaining the status code provided by the server. It tends to be less than illuminating. Type is the MIME type of the returned document, like "text/html". Content is the returned document (if any) including HTTP headers. Note that Backtalk does not know how to uncompress compressed documents.

If http_proxy is defined, Backtalk will use that proxy server.

showopt
flag showopt version-description

This function outputs a long, multiple-line description of the version and configuration of the Backtalk interpretor. If the flag is true, the description will be formatted with HTML line breaks, otherwise it is just plain text.

Conferencing Operators

The commands described in this section constitute the interface to the conference database. Many of their inputs and outputs are passed through system variables instead of the stack. These variables are individually described in the next section. This manually currently describes the Picospan-compatible implementation. Other future implementations may differ.

next_conf
csel next_conf csel conf

This gets the next conference name from the given conference selector, and pushs an updated conference selector, and the new conference name. It does not check that the named conference exists. The conference selector may be either a comma-separated list of conference names, or a string like (@0), consisting of an at-sign and a number. In the latter case the number refers to a line of the user's .cflist (or the default .cflist if the user is unauthenticated or doesn't have a .cflist). If there is no next conference, both results are empty strings.

cflist_array
flag cflist_array array

This reads the user's .cflist into an array. The flag may have the following values.

0     Read dflt.cflist file   Omit comment lines
1 Read user's .cflist Omit comment lines
2 Read dflt.cflist file Include comment lines
3 Read user's .cflist Include comment lines
When reading the user's .cflist, we will still get the default file if the user doesn't have one. When reading the dflt.cflist file, Some of the values in the returned array may be written as
group:conf
which means that the named conference is only on the list if the user is in the named group. These forms never appear when fetching the user's .cflist. If the user is in the group, you get just the conference name, otherwise the entry is not included in the list.

If comments are to be returned, they appear as strings starting with a pound sign. Some interfaces use these as subheadings or flags, most interfaces ignore them.

open_conf
- open_conf err

This opens a conference (specified by the conf system variable). Most of the other commands will only work after a conference has been opened. Any previously open conference is automatically closed by open_conf. If you attempt to open a conference named '?' then you get the default conference. If selectuser was called before open_conf, then we load that user's participation file instead of the currently logged in user's. If the conference is already open by the correct user, this command is a no-op. For Picospan-format conferences, it loads information from the conference "config" and "sum" files and from the user's participation file. It sets the variables maxitem, amfw, fwlist, maypost, mayresp, mayread, alias, confdir, fishbowl, userlist, grouplist, secret, newbie, conftitle, and particip. It pushes an error code which is 0 if the conference exists, and 1 otherwise. Note that you can open conferences to which you do not have access (due to not being on the ulist/glist or not having the right cpass), but in those cases mayread, mayresp, and maypost will be false.

snoop_conf
- snoop_conf err

This is exactly like open_conf except it will never create a participation file and changes to the participation file will not be written back out to the file. It's used when we want to get information about a conference without actually joining it.

If the current conference is open for snooping, you need to do an explicit close_conf before you can open it normally, and vice versa.

close_conf
- close_conf -

This command closes the currently open conference. It writes out the participation file (if the conference was not open for snooping) and generally cleans up and closes down, but there is really no reason to ever call it, except as desribed in the description of snoop_conf. Each open_conf or snoop_conf command automatically closes any previously open conference, and Backtalk automatically executes a close_conf upon the termination of your script.

conf_dir
confname conf_dir confdir

Given a conference name, return its directory path. Note that open_conf does the same thing and more, so this is only useful if you want to know the directory path of a conference you probably don't intend to open. Since the same conference can have multiple names, the only way to test if two names refer to the same conference is to look up their conference directory names and compare those.

cache_conflist
boolean cache_conflist -

This turns on and off in-memory cacheing of the conference list. If you are planning to do a lot of calls to open_conf or conf_dir, then turning this on will improve performance. Turning it off when you are done will reduce memory use. It is off by default.

resign_conf
- resign_conf -

This command closes the currently open conference and resigns from it, discarding all record that the user has ever been in it.

conf_new
- conf_new total brandnew newresp unseen

Find the total number of items, the number of brand new items, the number items with new responses, and the number of new but unseen items in the current conference. Forgotten and retired items are included in the total count, but not in the brandnew and newresp count.

conf_alias
newname conf_alias -

Set the user's name within the current conference to the given value. This will continue to be his default alias in this conference on all future sessions.

conf_bull
- conf_bull text

Push the text of conference bulletin on the stack. Open_conf must have been called. Equivalent to '(*bull) read'.

conf_index
- conf_index text

Push the text of conference index on the stack. Open_conf must have been called. Equivalent to '(*index) read'.

conf_login
- conf_login text

Push the text of conference login message on the stack. Open_conf must have been called. Equivalent to '(*login) read'.

conf_logout
- conf_logout text

Push the text of conference logout message on the stack. Open_conf must have been called. Equivalent to '(*logout) read'.

last_in_conf
- last_in_conf time

Return the date and time when we last modified the conference's participation file. If we weren't members of the conference before now, return a time of zero. Open_conf must have been called.

next_item
is next_item is nrs item 0
is next_item err

Next_item identifies the next item number from the item selector given on the stack. The item will be the next one named in the item selector which has responses selected by the system variable rsel. The rsel variable may be set to (all), (new), (unseen), (since), a negative number, or to a numeric range. If rsel is (new), only items with new responses will be found. If rsel is (unseen), unseen items and items with new responses will be found. If rsel is (since), only items with responses since the date given in the since variable will be selected. If rsel is a negative number ("-0" is legal), it gives the number of responses from the end to show. Next_item will also skips forgotten or retired items if showforgotten is not set. If the variable noskip is true, however, items will not be skipped, even if no responses are selected.

When it finally finds an qualifying item, it pushes the remainder of the item-selector on the stack, followed by a numeric version of the response selector, the number of the new item, and a zero code indicating success. Often this_item will then be called to make the item found by next_item into the current item. An error code of 1 is pushed if there is no next item, or an error code of 2 is pushed if the item selector has bad syntax.

this_item
rsel item this_item nrs 0
rsel item this_item err

This_item is given a response range and an item number, and makes that item in the currently open item the current item. If the response range was not numeric, converts it to numeric form. It reads the sum and participation file information for the item, stores that information in system variables, and prepares to read the item.

If successful, this_item pushs a numeric response-selector and a 0. On error it pushes a non-error code on the stack: 1 if the items does not exist, 2 if we lack read access to it. If the input response selector was numeric, it is the selector output, but values of (new), (since) and (all) are converted into the corresponding numeric string. The current implementation also sets the following system variables: item, maxresp, maxread, linkdate, lastdate, readdate, forgotten, frozen, mayresp, retired, and linked.

If a conference database is configured, it also sets itemid, summary, keywords, authorname, authorid, and title. Otherwise itemid is always set to an empty string, and the others are not changed.

In future implementations, some variables may not be set until you do a read_item command. Even in the current implementation, some may be "corrected" at that point, since the item itself is considered a more accurate source of information than the sum file.

An error code of 1 is pushed if the item does not exist. An error code of 2 is pushed if the user does not have read access to the conference.

read_item
nrs read_item nrs 0
nrs read_item err

The read_item command can be called after a this_item call. It loads information from the item file header and prepares for a scan of the responses.

To prepare for the scan it takes a numeric response-selector off the stack and adjusts it. If it started with a 0, indicating that the item text (response 0) is to be read, it removes that element from the response selector and sets the resp system variable to 0, indicating that we are at response zero. If the numeric response-selector starts with anything else, it leaves it unchanged and sets resp to -1, indicating that there is no current response.

In addition, it sets the title, date, editdate, authorname (to null if mayseealias is false), authorid, authoruid, texttype, hidden, erased, attachments, mayedit, mayerase, mayhide, mayfreeze, mayretire, mayretitle and maykill system variables to the values for the item (or item text).

It will also replace the frozen, linked, retired, and itemno values which were taken from the sum file by this_item with more authorative values taken from the item file itself, possibly also changing mayresp. This only makes a difference if the sum file is munged.

If the item file does not exist, an error code of 1 is pushed. If the numeric response selector has bad syntax, an error code of 2 is pushed.

next_resp
nrs next_resp nrs resp 0
nrs next_resp err

The next_resp picks the next response number out of a numeric response selector, deleting that response from the selector. It pushs an error code of 1 if the selector was empty, or 2 if the response selector was syntactically incorrect. It doesn't check if the response really exists, or access the conferencing system in any other way. It is really just a different version of the next_int command.

read_resp
resp read_resp err

Read_resp reads the header for a response. It is usually run right after a next_resp. It takes the response number from the stack, and the item number from the item system variable. The this_item and read_item commands should previously have been called on the item. It sets the resp, date, editdate, authorname, authorid, authoruid, texttype, hidden, erased, attachments, and parentresp system variables to the values for the response. If the response does not exist, an error code of 1 is pushed, otherwise a 0 is pushed.

Read_resp calls may be done in any order, so that the responses may be read in any order, but the implementation is optimized for processing responses in sequence.

read_text
format read_text text

The read_text command may be called after a read_item or read_resp to fetch the corresponding item or response text, which is pushed onto the stack as a single string. If format is 0, it returns a plain text response (possibly converting an HTML response to plain text, if that is all that is stored). If format is 1, it returns an HTML response (if the response is stored as plain text, it runs it through expand and then encloses it in a <PRE> environment). If format is 2, it returns the raw text - that is it returns HTML for HTML responses and plaintext for plaintext responses, and does no postprocessing on them.

Read_text also marks the response as "seen" in the user's participation file, unless the blindfold variable is set to a non-zero value. It works just fine on hidden responses, though on erased responses it will return a lot of scribbling.

post_item
- post_item -

This creates a new item in the current conference. Input is taken from the system variables title, text, texttype, ifav, alias, id, uid, allowgraphics, attachments, hidden, and erased (although posting erased items would be strange). If a conference database is configured, intput is also taken from the summary and keywords variables.

If texttype is "text/html", then the cleanhtml function is automatically called on the item text. The fav note in the user's participation file for the item is set to the value of ifav.

On success, the variable item is set to the number of the new item within the current conference, and the variable itemid is either set to the item's unique id, if backtalk is configured with a conference database, or to an empty string otherwise.

The maypost variable can be checked to see if the current user has the ability to post items to the current conference. If the user is not authenticated and anonymous posting is enabled, then the login name and uid number on the response will be those of the account named in the anonposter variable.

If post_log_file is defined, then after a new item is created, the user-defined function item_log_format will be called. It should return a single string, which will be appended to the file named by the post_log_file constant.

post_resp
- post_resp resp_number

This appends a new response to the end if the item specified by the item system variable in the current conference. Input is taken from the system variables text, texttype, rfav, alias, id, uid, allowgraphics, parentresp, attachments, hidden, and erased. If texttype is "text/html", then the cleanhtml function is automatically called on the response text. If rfav is non-zero and the item is not already a favorite, then the fav note in the user's participation file for the item is set to the value of rfav. If the item does not exist, an error code of 0 is pushed. If the expect_resp variable is set to a positive value which is less than the next response number, then -1 is returned and nothing is posted. Otherwise the number of the newly posted response is pushed.

The mayresp variable can be checked to see if the current user has the ability to post responses to the current item. If the user is not authenticated and anonymous posting is enabled, then the login name and uid number on the response will be those of the account named in the anonposter variable.

If post_log_file is defined, then after a message is posted, the user-defined function resp_log_format will be called, after pushing the new response number on the stack. It should return a single string, which will be appended to the file named by the post_log_file constant.

get_conf_note
fieldname get_conf_note value

Each user can attach various "notes" to each conference, each note being identified by a field name. This command fetches the value of the named field. The name can be either a string or a literal. If the current user has no such note attached to the current conference, then a 0 is pushed.

set_conf_note
fieldname value set_conf_note -

Record a note for the current user and conference. Fieldname can be given as a literal or a string. If the value is zero, the note will be deleted.

If the sub_instant or sub_digest variables are set, then setting the subs conference note has the side effect of updating the conference subscriber databases, and it's values must be of the correct format. To set an instant subscription the string is like (I flags). To set a digest subscription, the string is like (D flags period). The flags value is an integer constructed as the sum of

1 Include newly posted items.
2 Include newly posted responses.
4 Include postings that the user has already seen.
8 Include postings to forgotten or retired items.
16 Include postings by ignored users.
The period for digests gives the number of days to wait between digests. Setting subs to an empty strings turns off email subscriptions.

get_item_note
item fieldname get_item_note value

Each user can attach various "notes" to each item, each note being identified by a field name. This command fetches the value of the named field for the given item in the current conference. The name can be either a string or a literal. If the current user has no such note attached to that item, then a 0 is pushed.

Some item notes have special significance to the system:

fav
If non-zero, the item is a "favorite". If the value is one, it will remain a favorite until explicitly set to another value. If the item is two, then it will be automatically reset the next time the item is read.

set_item_note
item fieldname value set_item_note -

Record a note for the the given item and the current user and conference. Fieldname can be given as a literal or a string. If the value is an zero, the note will be deleted.

fav_sel
isel 0 fav_sel isel
isel 1 fav_sel fav-isel other-isel
isel 2 fav_sel brandnew-isel newresp-isel
isel 3 fav_sel fav-isel brandnew-isel other-isel

Given an item selector, split it so that the items which are favorites or brandnew are in one, and the rest the other. There must be a conference open. So for example, if items 2, 3, 4, 7, 10, and 14 are favorites, and we'd get:

   (1-$) 1      fav_sel (2-4,7,10,14)       (1,5-6,8-9,15-$)
   (1-9,15-3) 1 fav_sel (2-4,7,14,10,7,4-3) (1,5-6,8-9,15,13-11,9-8,6-5)
A common way to move favorites to the front of a selector would be:
mark isel 1 fav_sel (,) jointomark

mark_unseen
resp item mark_unseen err

This marks the given response of the given item to be the first unseen response of the item. It pushs a 0 on success, a 1 if there is no such item, and a 2 if there is no such response.

forget_item
item forget_item err

This marks the given item number as being forgotten in the user's participation file. With Picospan, if the item has never been read, it has the odd side effect of marking the item text seen. It pushs an error code of 1 if there is no such item, or 0 if we succeed. If the item was a favorite, it is automatically disfavored.

remember_item
item remember_item err

This unforgets the given item number. It pushs an error code of 1 if there is no such item, or 0 if we succeed.

hide_resp
flag hide_resp err

If the flag is true, this marks response resp of item item in the currently open conference as being hidden. If the flag is false, it unhides the selected response. Authors of responses can hide or unhide responses if the author_hide variable is true. Fairwitnesses can hide or unhide responses if the fw_hide variable is true. System administrators can always hide responses. The hide_resp command pushs a zero on success, a 1 if the response was erased or already set as designated, and a 2 if there is no such response. Responses in frozen items may only be hidden or unhidden if editfrozen is enabled.

erase_resp
- erase_resp err

This erases response resp of item item in the currently open conference. The text is removed from the item, and any attachments are deleted. Only the author of the response, the fairwitness of the conference, or the system administrator can ever erase responses. Authors can only do so if the author_erase variable is true. Fairwitnesses can only do so if the fw_erase variable is true. The command pushs a zero on success, a 1 if the response was already erased, and a 2 if there is no such response. If a censored log file exists, a copy of the erased text will be saved there, together with information about who censored it. Responses in frozen items may only be erased if editfrozen is enabled.

edit_resp
- edit_resp err

This replaces the text of resp of item item in the currently open conference with new text given by the text and texttype system variables. The author's alias is reset to the value given by the alias system variable. Any parent pointer value is replaced with the current value of the parent variable. Editting an erased item unerases it. The previous text is logged to the censor log, if censor logging is enabled. Only the author of the response, the fairwitness of the conference, or the system administrator can ever edit responses. Authors can only do so if the author_edit variable is true. Fairwitnesses can only do so if the fw_edit variable is true. The command pushs a zero on success, and a 2 if there is no such response or if the item is frozen, and 3 if you lack the proper access to edit the response. Responses in frozen items may only be edited if editfrozen is enabled.

freeze_item
flag freeze_item err

If the flag is true, this marks item item in the currently open conference as being frozen. If the flag is false, it thaws the selected item. You must be the author of the item or a fairwitness to be able to do this, and the item author can do it only if the variable author_freeze is true. The command pushs a zero on success, a 1 if the item was already frozen (or thawed), a 2 if there is no such item, or a 3 if you are not the fairwitness or item author.

related_items
limit related_items isel

Generate an item selector for other items in the current conference related to the current item. Limit is the maximum number of items to include in the list, unless it is zero, in which case there is no limit. They will be sorted with the most relevant item first.

If backtalk is not configured with a conference database then this always returns an empty selector.

What this actually does is take the current value of the keywords variable as a full text query against the summary, title, and keywords values for every other item in the current conference, excluding the current item (as given by the itemid variable) from the list.

The results will be peculiar or empty for conferences with a small number of items.

kill_item
- kill_item err

This kills item item in the current conference. If the item is linked to other conferences, it may continue to exist there, but otherwise it is permanently deleted, along with any attachments to responses in the item. Items may be killed by the fairwitness, or by the item's author if it has not been responded to and author_kill is true. It pushs a zero on success, a 2 if there is no such item, or a 3 if you do not have permission to kill the item.

link_item
conf item link_item newitem 0
conf item link_item err

This creates a new item in the current conference which is a link to the named item in the named conference. Only fairwitnesses may link items. Items may not be linked from private conferences except by conference administrators. It pushs the new item number and a zero error code on success, a 1 if there is no such conference, or the conference is private, a 2 if there is no such item in the source conference, or a 3 if you do not have permission to link the item.

retire_item
flag retire_item err

If the flag is true, this marks item item in the currently open conference as being retired. If the flag is false, it unretires the selected item. You must be the author of the item or a fairwitness to be able to do this, and the item author can do it only if the variable author_retire is true. The command pushs a zero on success, a 1 if the item was already retired (or unretired), a 2 if there is no such item, or a 3 if you are not the fairwitness or item author.

retitle_item
newtitle retitle_item err

This changes the title of item item to the given string. You must be the author of the item, a fairwitness of the conference, or and administrator to be able to do this, but the item author can do it only if the variable author_retitle is true, and the fairwitness can do it only if the variable fw_retitle is true. (The mayretitle flag will be true if the current user can retitle.) The command pushs a zero on success, a 1 if the given title is blank, a 2 if there is no such item, or a 3 if you do not have the proper access to perform this operation. Frozen items may only be retitled if editfrozen is enabled.

annotate_item
newsummary newkeywords annotate_item err

This changes the summary and keyword list for item item to the given strings. You have permission to do this if and only if you have permission to retitle the item. (The mayretitle flag will be true if the current user can retitle.) The command pushs a zero on success, a 2 if there is no such item, or a 3 if you do not have the proper access to perform this operation. This works only on systems with a conference database. Otherwise it does nothing but always returns 0.

add_reference
url type title excerpt sitename post add_reference err

This records a reference to item item in the currently open conference. It is typically called when a trackback or pingback ping is received from another site indicating that a page there links to the item. It is required to give url is the URL of the page referencing this item. The type should be 'T' for trackbacks, 'P' for pingbacks, and 'M' for manually entered references. The name of the site, the title of the refering page, and an excerpt from the refering page may be given, or they may be empty strings.

If there is a conference database, the reference will be stored there. In addition, if post is true, then a response will be posted to the item indicating the existence of this reference (the response does not include the excerpt). This response will be flagged as a special reference response.

An error code of zero is returned on success. Otherwise, 1 indicates a bad URL, 2 indicates a bad type code, 3 indicates that the item does not exist or is frozen, and 4 indicates that the reference was already in the database.

check_partic
user check_partic lastaccess

Check if the given user is a participant in the current conference. If so, return a last access date. If not (or if the user does not exist), return 0.

first_partic
user first_partic lastaccess user 0
user first_partic 1

Start a scan through the list of participants in the current conference. To start from the beginning of the list, pass in the empty string. Otherwise, the first argument off the stack is the login name of a participant to start scanning after (so that the participant returned will be the successor of that participant). On success, a user name and the time that that user last read a new response in the conference is returned. If there are no particpants or if mayread is not true, then a code of 1 is pushed.

Note: Scanning participants can be extremely slow.

next_partic
- next_partic lastaccess user 0
- next_partic 1

Continue a scan of the participants of the current conference. first_partic must have been called before the first call to next_partic. There after, successive calls to next_partic return successive particpant's and the last time they read a response in the conference. When the last particpant has been read or if mayread is not true, an error code of 1 is returned.

Note: Scanning participants can be extremely slow.

make_attach
tmphandle description response make_attach handle

Convert a temporary attachment handle, such as those returned in variables whose names start with "baa_" in "multipart/form-data" posts, into a real attachment handle. You should supply a description of the attachment (if an empty string is given, the original name of the file is used). If the attachment is to be associate with a particular response in an item, then the response number should be given (zero being the item text). If the attachment is associated with a conference as a whole, the the response number should be -1. If the attachment is to be associated iwth a user, then a response number of -2 should be given.

If the response number is -1 or larger, then there must be a conference currently open. If the response number is 0 or larger, then the item variable gives the item number for the attachment.

The resulting attachment handle can be put into the attachments and can be attached to a posting with the post_item or post_resp commands.

get_attach
handle get_attach type size description url 0
handle get_attach errcode

Given an attachment handle, such as the ones generated by make_attach or the ones put into attachments variable by the read_item and read_resp commands, this extracts some interesting information about the attachment. It returns its mime-type (eg, "image/gif"), its size in bytes, a description, and a url which can be used to fetch the document. It pushs an error code of 1 if the attachment cannot be found or has been deleted. It pushs an error code of 2 if the current user does not have access to the attachment.

edit_attach
handle newdescription newtype edit_attach errcode

This function modifies the description and type associated with an existing attachment. Returns 1 if the named attachment does not exist, 0 on success.

reattach
delhandle addhandle reattach errcode

This function adds or deletes attachments on existing items and responses. The conference should already have been opened with a call to open_conf. The system variables item, and resp select the response whose attachments we are editing. The function can be passed two attachment handles. Delattach is an existing attachment to delete. Addattach is a newly created attachment (see make_attach) to add. Either can be given as an empty string to indicate that nothing should be deleted or added. The added attachment takes the place of the deleted one, or, if none is deleted, it is added to the end of the list of attachments. The command pushes an error code of 0 on success, 2 if the item/response does not exist, 3 if the current user does not have permission to edit attachments for that response, and 4 if the attachment to be deleted did not exist.

next_subscriber
flags type next_subscriber user 0
flags type next_subscriber 1

This walks through the lists of subscribers to the current conferences. Subscribers are users who want conference contents automatically emailed to them. The type can be (I) for instant subscriptions, or (D) for digest subscriptions. The sub_instant and sub_digest flags must be enabled for the corresponding subscriber lists to ever be non-empty. The flags argument can be a sum of flag values like those in the 'subs' value for set_conf_note. Any users who do not have all the given flags set will be included. For digests, only users who are due to have a digest sent today will be included. While there are more subscribers, each call returns a subscriber name and a zero. If there are no more, then a 1 is returned, and the list is rewound, so the next call will return the first subscriber again.

new_conf
confname parentdir listit new_conf error

Create a new conference. Only conference administrators can use this command. Confname is the internal name of the conference, which must be all lower case, and which must be different from any existing conference. The conference will be stored in the directory whose full path name is given by parentdir. If parentdir is given as (), then it defaults to bbsdir. If listit is true, an conflist entry will be made in the same name, so that it can be joined by that name. This does not add the conference to the menu of conferences. If there is a conference database, the confid variable is set to the unique ID for the newly created conference. On error, an error message string is pushed. On success, a null string is pushed.

del_conf
confname del_conf -

Delete a conference, referenced by its internal name. This deletes the conference directory and all of its conflist entries. It also deletes all user's participation files for the conference (except if unix accounts are being used). It does not delete any conference menu entries.

E-mail Operators

This section describes commands for sending email messages from Backtalk. You can have multiple email messages in the works at the same time - each active message is identified by an integer id (preferably a small one). To send a message, you first create a message by building it up with a sequence of commands starting with email_new. There should be at least one call each to email_body and email_recip. The email_send command can then be called to send the email. It is possible to change the recipients after sending and resend. When you are done, call email_close.

email_new
subject replyaddr replyname id email_new rc

Start an new email message with the given id number. The subject, the "Reply To" address and the name that goes with it are given as arguments. It pushs a return code of 0 on success. If the subject is invalid, it pushs 1, if the reply address is invalid it pushs 2, and if the reply name is invalid, it pushs 3.

email_body
alt desc type text id email_body rc

Attach a body to the current email message with the given id number. There can be a primary and an alternate text (typically the primary would be an HTML message and the alternate would be plain text). Either primary or alternate may have an arbitrary number of attachments bodies, though normally only the primary does. The alt argument is 0 if this is to be portion of the primary text, and 1 if it is to be a portion of the alternate text. The first body posted for each becomes the main text, while later bodies are attachments. The desc argument is a string that gives description of the body. It can be (and often is) an empty string. The type is the MIME type of the body and text is the actual content. It can be any MIME type, but (text/plain) and (text/html) are the most common. If a message is constructed with a primary body of type (text/html) and no alternate body, then an alternate body of type (text/plain) is automatically generated.

On success, we push a 0. On failure we push 1, if the description was invalid, and 2 if the MIME type was invalid.

email_recip
type addr name id email_recip rc

Add a recipient to the current E-mail message with id number id. The addr argument gives the E-mail address. The name gives the full name of the recipient (this can be an empty string). The type can be any of the following:

(T) Set the "To" list to contain only this address.
(T+) Append this address to the "To" list
(C) Set the "Cc" list to contain only this address.
(C+) Append this address to the "Cc" list
(B) Set the "Bcc" list to contain only this address.
(B+) Append this address to the "Bcc" list
The return code is 0 on success. On failure it is 1 if the address was not valid and 2 if the full name was not valid.

email_send
mask id email_send -

Send the current email message with id number id. It is an error if the message does not exist or if it doesn't have at least one body and at least one recipient. If the mask argument is 1, only the primary content will be sent. If it is 2, only the alternate content will be sent, otherwise all defined content will be sent. You can call this more than once on the same message, perhaps calling email_recip first to change the recipient on the next message.

email_close
id email_close -

Discard the current message with id number id, freeing up all memory that is uses.

Built-in Variables

Backtalk has a large number of built-in variables that perform predefined roles, or whose values are set by the Backtalk interpreter.

Some variables are protected, so the user cannot change their values except in the config.bt script. Furthermore, some protected variables are tagged as constants, which means that they not only cannot be changed outside of the config.bt script, but they will have the same value everytime Backtalk is run. The Backtalk compiler will hard-code references to all built-in variables so that the system dictionary never has to be searched at run time, and it will hard-code values of all constants.

Conferencing Variables

There are a number of built-in variables that are used to pass information in and out of the conferencing commands.

alias
(string) The full name to be attached to your posts in the currently open conference. This is loaded from your participation file by the open_conf command and is an input to the post_resp, post_item and edit_resp commands.

allowgraphics
(boolean) If set true, the HTML <IMG> is allowed in HTML responses. This allows images to be inserted in-line in items and responses. If set false, all <IMG> tags are automatically stripped out by the post_resp, post_item, and cleanhtml commands.

anonymity
(integer) This controls the visibility users names to other names. There are two kinds of names involved. First, it controls the visibility of the aliases attached to each posting and response, second it controls the visibility of the "real" full name field in the user database. Possible values are:
anonymity aliases can be seen by: real full names can be seen by:
0everyone.everyone.
1authenticated users only. authenticated users only.
2fairwitnesses of the current conference only. admins and members of the gradm group only.
3admins only.admins only.
The mayseealias and mayseefname variables will automatically be set to indicate the access available to the current user.

amadm
(boolean) True if you are a conference administrator. This implies amfw in all conferences, and gives you the power to use the selectuser command.

amfw
(boolean) True if you are the fairwitness in the current conference. This is set by the open_conf command.

attachments
(string) This is a comma-separated list of the attachment handles associated with a posting. Attachment handles are created by make_attach. Comma separated lists of them be placed in this variable to attach them to postings using the post_item and post_resp commands. When those postings are read with the read_item and read_resp commands, a comma separated list of attachments appears in this variable.

author_edit
(boolean) If this is true, users may edit responses they entered. This is a system constant, set in config.bt.

author_erase
(boolean) If this is true, users may erase responses they entered. This is a system constant, set in config.bt.

author_hide
(boolean) If this is true, users may hide or unhide responses they entered. This is a system constant, set in config.bt.

authorid
(string) This is the login id (or equivalent) of the author of an item or response. It is set by read_item and read_resp.

author_freeze
(boolean) If this is true, users may freeze or thaw items they originally entered. Fairwitnesses can always do this. This is a system constant, set in config.bt.

author_kill
(boolean) If this is true, item authors may kill their own items, at least until someone responds to it. Fairwitnesses can always kill items in their conferences. This is a system constant, set in config.bt.

authorname
(string) This is the full name of the author of an item or response. It is set by read_item and read_resp.

author_retire
(boolean) If this is true, users may retire or unretire items they originally entered. Fairwitnesses may always retire or unretire items. This is a system constant, set in config.bt.

author_retitle
(boolean) If this is true, users may retitle items they originally entered. Fairwitnesses can do this if fw_retitle is set, and conference administrators can always do so. This is a system constant, set in config.bt.

authoruid
(integer) This is the uid number (or equivalent) of the author of an item or response. It is set by read_item and read_resp.

bbsdir
(string) Full pathname of the bbs directory. It is defaulted to a sensible value. This is only used to expand any percent-signs in the conflist, so it is used by open_conf.

blindfold
(integer) If non-zero, then read_text won't mark responses seen when it reads them.

conf
(string) The name of the current conference. This can be set directly by the user, or by the next_conf operator. This is an input to the open_conf operator.

confdir
(string) The full path name of the directory where the current conference is stored. This is set by the open_conf command. You can also find the directory path of a conference by calling conf_dir, but that does not change this variable.

confid
(integer) A unique ID number identifying the current conference. This is set only on systems configured to use a conference database. On other systems it will always be zero. This is set by the open_conf and new_conf operators.

conflist
(string) Full pathname of the conflist directory of conference. This has a default value set at compile time, but can be overridden from the config.bt file. This is used by the open_conf operator.

conftitle
(string) Title of the conference. This is usually a few words that fit into "The _______ Conference". This is output by the open_conf operator which gets it from the conference config file if it is there, or uses the conf variable if it isn't.

cpass
(string) This is the conference password supplied by the user. It is an input to open_conf, but is only used if the conference is password protected.

csel
(string) This used to be an input to the next_conf function but isn't any more. It should probably be deleted, but some scripts assume that it is always defined, so we'll leave it for now.

date
(time) This is the entry date of an item or response. It is set by read_item and read_resp.

dbtype
(string) If the system has been configured at compile time to keep the conference data compatible with another conferencing system, then this will be the name of the conferencing system. Possible values are (picospan), (yapp) or (yapp3). Otherwise it is a null string.

editdate
(time) This is the date an item or response response was last edited. If it has not been edited, it is zero. It is set by read_item and read_resp.

editfrozen
(boolean) If this is enabled in the config.bt file, then it is legal to hide, show, erase, retitle, or edit responses in frozen items. Traditionally this is not possible in Picospan, so this defaults off.

erased
(boolean) This is true if the current item or response text is erased. It is set by read_item and read_resp and it is an input to post_item and post_resp.

expect_resp
(integer) If this is set to a positive, non-zero value before running the post_resp command, then the value is taken as the expected response number. If the post_resp command determines that, if posted, the new response would have a larger response number, it will abort and return a -1 error code. This allows the posting script to warn the user than another response has slipped in, so the user can be given an opportunity to edit the item before posting it.

favicon
(string) Certain browsers (IE and Konquerer) like requesting something called 'favicon.ico' from every site they hit. Normally Backtalk ignores any requests for templates called 'favicon.ico' but if you'd actually like to set an icon for your Backtalk site, generate an appropriate 16x16 .ico image file, and set the favicon variable to the full pathname of your file in the config.bt file. It isn't useful to set this in any other script, since it will be too late by the time any other script is run.

fishbowl
(boolean) The current conference is a fishbowl conference, and only users in the ulist (if userlist is true), glist (if grouplist is true) or who can give the password (if secret is true) will be able to post, though all may join with read-only access. This is set by the open_conf function.

forgotten
(boolean) This is true if the current item has been forgotten by the user. This is set by this_item.

frozen
(boolean) This is true if the current item is frozen. This is set by this_item.

fw_edit
(boolean) If this is true, fairwitnesses may edit individual responses to items in their conferences. They cannot edit responses in linked items. This is a system constant, set in config.bt.

fw_erase
(boolean) If this is true, fairwitnesses may erase individual responses to items in their conferences. They cannot erase responses in linked items. This is a system constant, set in config.bt.

fw_hide
(boolean) If this is true, fairwitnesses may hide or show individual responses to items in their conferences. They cannot erase responses in linked items. This is a system constant, set in config.bt.

fwlist
(string) A comma-separated list of the fairwitnesses for the current conference. This is set by the open_conf command.

fw_retitle
(boolean) If this is true, fairwitnesses may change the titles of items in their conferences. Conference administrators may always retitle items. This is a system constant, set in config.bt.

gid
(integer) This is the current user's group id number. It is set by Backtalk before the execution of the script. It may be used to decide which files are readable to a user on some installations. If there is no identifiable user or group ids are not used, it is set to -1.

grouplist
(boolean) The current conference has a group list restricting who may join. This is set by open_conf.

hidden
(boolean) This is true if the current item or response text is hidden. It is set by read_item and read_resp and it is an input to post_item and post_resp.

homedir
(string) The user's home directory. This is initialized before executing the script. It is set to null if no there is no validated user. It is used to find participation files.

id
(string) The login id (or equivalent) of the current user. This is automatically set by Backtalk before the execution of any script. It is an input the to post_item and post_resp commands. If there is no identifiable user, id is set to a null string.

ifav
(integer) Controls whether items automatically become favorites when originally posted. The post_item command simply sets the poster's fav" field for the item to the value of this variable.

item
(integer) Current item number. This can be set by this_item or by the programmer and is an input to read_item, read_resp, post_resp, kill_item, hide_resp, edit_resp, erase_resp, mark_unseen, and probably a lot of others that slipped my mind.

itemid
(string) For systems configured with a conference database, the this_item command will set this to a unique ID for the item. This ID is mainly used internally and not normally displayed to users. The itemid will be set to an empty string if and only if the system is configured with no conference database.

keywords
(string) For systems configured with a conference database, this variable is loaded with a white-space separated list of keywords relevant to the item by the this_item command. This variable is an input to the post_item command.

lastdate
(time) This is the date upon which the latest response was entered into the current item. This is set by this_item.

linkdate
(time) This is the date upon which the current item was linked into the current conference. For unlinked items, this is the creation date. This is set by this_item.

linked
(boolean) This is true if the current item is a linked item. This is set by this_item.

maxitem
(integer) The number of the last item in the current conference. This is set by the open_conf command.

maxread
(integer) The number of the last response which the user has read in the current item. This is set by this_item.

maxresp
(integer) The number of the last response in the current item. This is set by this_item.

mayedit
(integer) A flag indicating whether the user has the power to edit the text of the current response. It is 0 if he can not, 1 if he can do so because he is the author, and 2 if he can do so because he is the fairwitness or conference administrator. This is set by read_item and read_resp.

mayerase
(integer) A flag indicating whether the user has the power to erase the text of the current response. It is 0 if he can not, 1 if he can do so because he is the author, and 2 if he can do so because he is the fairwitness or conference administrator. This is set by read_item and read_resp.

mayfreeze
(integer) A flag indicating whether the user has the power to freeze or thaw the current item. It is 0 if he can not, 1 if he can do so because he is the author, and 2 if he can do so because he is the fairwitness or conference administrator. This is set by read_item

mayhide
(integer) A flag indicating whether the user has the power to hide or show the text of the current response. It is 0 if he can not, 1 if he can do so because he is the author, and 2 if he can do so because he is the fairwitness or conference administrator. This is set by read_item and read_resp.

maykill
(integer) A flag indicating whether the user has the power to kill the current item. It is 0 if he cannot kill it, 1 if he can kill it because he is the author, and 2 if he can kill it because he is the fairwitness or conference administrator. This is set by read_item

maypost
(boolean) A flag indicating if you may create new items in the current conference. You have write access if you are not anonymous, and if the conference is writable for you. This is set by the open_conf. If it is false, then post_item will not work in this conference.

mayread
(boolean) A flag indicating if you have read access to this conference. This is set by the open_conf command. If it is false, none of the commands to read items and responses from a conference will work. Normally interfaces will not allow users to join a conference if mayread is false.

mayresp
(boolean) A flag indicating if you have the ability to respond to the current item. You have write access if you are not anonymous, if the conference is writable for you, and if the item is not frozen. This is set by the open_conf. At that point it is set to the default value for all items in the conference. This this_item and read_item commands set it to the value for the current it (which may be different than the value for the conference if the item is frozen). If it is false, then post_resp will not work in this conference.

mayretire
(integer) A flag indicating whether the user has the power to retire or unretire the current item. It is 0 if he can not, 1 if he can do so because he is the author, and 2 if he can do so because he is the fairwitness or conference administrator. This is set by read_item.

mayretitle
(integer) A flag indicating whether the user has the power to retitle the item. Also controls whether he can edit the summary and keyword list. It is 0 if he can not, 1 if he can do so because he is the author, and 2 if he can do so because he is the fairwitness or conference administrator. This is set by read_item

mayseealias
(integer) A flag indicating whether the user has the power to see the full names attached to responses. If false, the read_item command will always a null string in the authorname variable. It is set by the open_conf command based on the anonymity configuration variable.

mayseefname
(integer) A flag indicating whether the user has the power to see user biographic information. If false, the loaduser and pushuser commands returns a null string for the name of other users. It's setting is based on the anonymity configuration variable and the user's authentication status.

newbie
(boolean) A flag set by the open_conf command if the user is joining the conference for the first time (in which case a participation file was created for him).

noskip
(boolean) A flag indicating whether the next_item command should skip items which have been retired or forgotten. It defaults to false.

parentresp
(string) This is used with Yapp-style response threading, where each response can be tagged as being a response to some other previous response. It is the number of the previous response that this item is to be considered a response to. It is an input to post_resp and edit_resp, and is returned by read_resp. In Picospan-compatible installations, this will always be zero and will be ignored when posting.

particip
(string) This is the name of the current conference's participation file.

post_log_file
(string) If defined, this is the full path name of a file where postings will be logged. Each time a new item or a response is entered, the user-defined functions item_log_format or resp_log_format will be called. These are expected to push a string, which is the line to be written to the log file.

rfav
(integer) Controls whether items automatically become favorites when responded to. If this is zero, nothing is done. If it is 1, the item becomes a permanent favorite. If it is 2 and if the item is not already a favorite, then the item becomes a temporary favorite. All this is done by the post_resp command.

readdate
(time) This is the date upon which the user last read a response in the current item. This is set by this_item.

resp
(integer) This is the current response number. It is set by read_item and read_resp.

retired
(boolean) This is true if the current item is retired. This is set by this_item.

rsel
(string) This is the current response selector, indicating which responses of the current item are to be read. It can be (all), (new), (unseen), (since) or a numeric selector. See the section on selector manipulation for details on the syntax.

secret
(integer) This is non-zero if the current conference has a secret password. It is one if the password has been given correctly, or two if it has not. If it has not mayread will be false. If the conference has no secret password, then it will always be zero. This is set by open_conf.

showforgotten
(integer) If this is zero, forgotten and retired items will be skipped by the next_item command. If it is one, forgotten and retired items will not be skipped. If it is two, unforgotten items will be skipped.

since
(time) When rsel is (since), this gives the date after which responses are to be displayed.

sub_instant
(boolean) If this is defined, the sending of periodic digests of new postings in confernences is enabled.

sub_instant
(boolean) If this is defined, the sending of instant emails when new items and responses are posted is enabled.

summary
(string) For systems configured with a conference database, this variable is loaded with a short summary of the item by the this_item command. This variable is an input to the post_item command.

text
(string) This is the text of a response or item. It is an input to post_item, post_resp and edit_resp.

texttype
(string) This is the type of the current response or item text. The normal types are "text/plain" and "text/html". It is an input to post_resp, post_item and edit_resp. It is set by read_item and read_resp.

title
(string) This is the title of an item. It is set by read_item and is an input to post_item

uid
(integer) This is the current user's uid number (or an equivalent unique identifier). It is set by Backtalk before the execution of the script. It is an input the to post_item and post_resp commands. If there is no identifiable user, it is set to -1.

userlist
(boolean) The current conference has a user list restricting who may join. This is set by open_conf.

yapp_format
(integer) This is meant to be set only on systems that share conference files with web Yapp (not command-line Yapp). If it is set to 1 or 3, then all postings from Backtalk are dones as HTML postings. Plain text postings are converted a somewhat arcane HTML equivalent that will still look right even when Yapp appends a <BR> tag to each line.

If it is set to 2 or 3, then when a "plain-text" message is read, then it is assumed to be a Yapp posting. We run clean_html on it, and terminate each line with a <BR>.

Event Handler Variables

Certain operations in Backtalk trigger events. When an event occurs, an event variable is examined to find a comma-separated list of scripts to be executed. Each script is assumed to be in the event subdirectory of the script directory. A copy of Backtalk is forked to execute each listed script. The event variables are all constants, settable only in the global config.bt script.

The copy of Backtalk executing the event script will have all system variables in the same state they were at just before completion of the command that triggered the event. Its operand stack will be emptied of everything that was in the parent processes stack. Instead it will contain the event name, possibly preceeded by some event dependent values. The event handler always runs as admin powers, with amadm true, although id is still the login of the user who triggered the event. Output from the event script is discarded.

event variable event type triggered by stack
onpost New Item Posted post_item (post)
Item Linked into Conference link_item source conference name
source item number

new item number
(link)
onresponse New Response Posted post_resp new response number
(response)
onitem Item Retitled retitle_item (retitle)
Item Killed kill_item (kill)
Item Frozen or Thawed freeze_item (freeze)
Item Retired or Unretired retire_item (retire)
onresp Item or Response Text Editted edit_resp (edit)
Item or Response Text Erased erase_resp (erase)
Item or Response Text Hidden or Shown hide_resp (hide)

Miscellaneous Variables

There are several other built-in system variables that effect the system's behavior, but aren't directly related to conferencing.

allowanon
(boolean) True if Backtalk is configured to allow anonymous reading. If false, then the only script that can be run by unauthenticated users are those in the directories listed in the publicflavors variable. This is a protected variable, set at compile time.
anonposter
(string) If this is set to an empty string, then anonymous users can never post items or responses in any backtalk conference. This is the default. Otherwise, it should be set to the login name of a user that will be used internally as the login name for all anonymous posts. This user should exist, but it should be an account that nobody ever uses to make real backtalk postings from.

auto_recompile
(integer) Whenever you run a script, and the binary is missing, or was compiled with an older version of Backtalk, Backtalk will attempt to recompile it automatically. The auto_recompile variable controls some additional recompilation checks. If auto_recompile is set to zero, no additional checks are done. This is suitable for a very stable production installation, where we don't want to slow down script execution by making extra tests. If auto_recompile is set to one, a script will be recompiled if its binary is older than the config.bt file. This is suitable for systems where configuration changes are likely, but the scripts themselves will not be changed. Finally, if auto_recompile is set to two, a script will be recompiled if its binary is older than the config.bt file or any of the source files that were used in compiling it previously. This is suitable for systems where new scripts are actively being worked on.

Note that if auto_recompile was previously set to zero, changing it's value in the config.bt won't cause anything to recompile, because the change in config.bt won't be noticed. Just manually recompile any one script. This will recompile config.bt as a side effect, so the new value of auto_recompile will then be set.

canattach
(boolean) This constant is true if this installation supports attaching files to posts. This can be changed only by rebuilding Backtalk with attachments enabled.

canspell
(boolean) This constant is true if the spellcheck command works in this installation. If it's false, the spellcheck will never find any misspelled words. It can be changed only by rebuilding Backtalk with spell checker support.

cgiquery
(string) The query string passed to backtalk. It's a sequence of "name=value" pairs separated by ampersands, with each name and value cgi-quoted. It's the same as the QUERY_STRING environment variable, except that it is even defined when the POST method was used.

copyright
(string) This is a string giving the copyright message for Backtalk.

exec_limit
(integer) This is similar to stack_limit, but limits the size of the execution stack instead of the operand stack. It also defaults to zero, which is to say, "no limit".

flavor
(string) This constant is set to the name of the subdirectory under scriptdir which contains the script currently being executed. The name always has a "/" slash character at the end of it. Normally the different subdirectories under the main Backtalk directory are for different versions of the interface. Thus flavor is useful for constructing url's of other scripts in same interface version without actually imbedding the name into the script, which would make it harder to link a single script into several different interfaces.

http_content_type
(string) This is the MIME type for the document which will be included in the HTTP headers that Backtalk automatically generates before your first output statement. Its default value, (text/html) can be changed to any other MIME type. To have any effect, this must be done before the first print, pr, or dumpstack command.

http_expires
(time) This is the expiration time that Backtalk will put in the HTTP headers that it automatically generates before your first output statement. The expiration time sets an upper limit on how long the user's browser may keep a copy of your output in cache. If it is zero, no expiration time is set (this is the default). Otherwise, it should be a time type, such as the one returned by the time command. If it is in the past, the browser will not cache this document. To have any effect, this must be done before the first print, pr, or dumpstack command. It cannot be combined with the http_no_cache command, which always forces an expiration date in the past.

http_headers
(boolean) This is a boolean that controls whether Backtalk generates HTTP headers before the first output from your script. If true (the default), it does so, using the information from the http_content_type, http_expires and http_location variables, and including all cookies set with the setcookie command. If it is false, no headers are generated. This is desirable if your script is not running as a CGI, or if you want to generate your own HTTP headers. To have any effect, this must be set before the first print, pr, or dumpstack command.

http_location
(string) If this is not an empty string (the default), then it gives a URL to redirect to. This will be included in the HTTP headers that Backtalk automatically generates with the first output statement. If this header is given, then instead of showing the rest of the output you generate, the browser should fetch the page whose URL is given. To have any effect, this must be set before the first print, pr, or dumpstack command.

To be completely correct, the value stored in http_location should be either a full URL, starting with "http:", or a relative URL starting with "/". If a full URL is given, then this is an external location redirect, and the browser will be fetching the new page. If a relative URL starting with a "/" is given, then this is an internal redirect, which will be handled by the http server rather than the browser. The HTTP protocols do not define the behavior for relative URLs starting with anything other than a slash (though in practice, most HTTP servers handle these as external redirects). The difference is important. Internal redirects result in the final page being displayed more quickly. If the user does a "Reload" after an external redirect, then he re-executes only the second query, but if he does a "Reload" after an internal redirect then he re-executes both.

For debugging, you can set the suppress_redirect constant to true. Then the redirect will be printed on the web page instead of being executed.

http_no_cache
(boolean) This is a boolean that controls whether Backtalk generates HTTP headers intended to prevent the page from being cached in the browser. If true these will be included in the HTTP headers that Backtalk automatically generates with the first output statement. It defaults false, allowing caching. To have any effect, this must be set before the first print, pr, or dumpstack command.

http_pingback
(string) If this is not an empty string (the default), then it gives a URI of the pingback server to use for this page. An "X-Pingback" header will be generated. To have any effect, this must be set before the first print, pr, or dumpstack command.

http_proxy
(string) If this is defined to a non-empty string, the httpget command will route all HTTP requests make by Backtalk through the given proxy server. It can be either a simple hostname or IP address, or it can be a host and a port number separated by a colon. If the port number is not explicitly given, it defaults to 80.

linktonew
(boolean) If true, expand and cleanhtml will make all outside like open in new windows. If false, the open in the top level of the current window. Defaults to true.

loginlen
(integer) The maximum number of characters that may appear in a login ID.

loglevel
(integer) This determines the amount of logging the system does. Well, actually there are only two levels right now -- if loglevel is set to zero, no logging is done, if loglevel is set to anything higher, short two-line log entries are written for each transaction.

newuseropen
(integer) This system constant tells whether unauthenticated users can create user accounts. If it is 0, only users in the 'cfadm' and 'gradm' groups can create user accounts. If it is 1, anyone, even unauthenticated users, can create new user accounts, but those accounts will be created in an unvalidated state, so they can't be used until an administrator validates them. If it is 2, then all users can create accounts, and the accounts will be instantly ready to use.

nopwedit
(integer) This constant is set to be true in installations where the changepass, changegroup, removeuser and validate do not work because the system is set up to use the Unix passwd file as the user database. You could change the value of this constant with a defconstant command, but doing so wouldn't change the behavior of those functions.

publicflavors
(string) A string containing a comma separated list of all directories which may be accessed by unauthenticated users even when allowanon is false. By default, this is just (public), to allow public/welcome and similar scripts to be run. This is a protected variable, set at compile time.

progname
(string) The name Backtalk was invoked under. This is only the final element of the full path name. If you have multiple versions of Backtalk installed, this lets you be sure to direct future queries to the same version. The environment variable SCRIPT_NAME gives the full path from the URL.

saverep
(boolean) If this constant is true, then upon each execution, Backtalk will save a copy of all its inputs (that is, environment variables and POST query input) to a file. This is useful for debugging. Running 'backtalk -r' from the command line (or under the debugger), will then precisely re-execute the last saved query. It defaults false.

This should not be left turned on in a production installation. The saved queries may include user passwords (when a password is changed through Backtalk), conference passwords (whenever used), messages posted to restricted conferences, etc. Leaving this laying about in a file is a security risk.

scriptdir
(boolean) The full path of the directory where Backtalk scripts are kept. Backtalk will change directories to the compiled-in value of this variable before attempting to run the config.bt script, which should be in that directory. The config.bt script can change the value of this, in which case Backtalk will change to the new directory before trying to execute the user script, which should live someplace under that directory. Thus all path names given to include, stopped, or chain commands are relative path names from this directory.

scriptname
(string) This constant is set to the name of the top-level script being executed. You can construct the full path name of that script by doing
  `scriptdir(/)flavor scriptname'
If a file was not directly executed, but was pulled in by an include, chain or stopped command, then the scriptname is still the name of the parent script. If, on the other hand, it was pulled in by a call or a jump command, then it will be the name of the child script. This is weird, but consistant with the general behavior of constants in backtalk.

secure
(boolean) If this constant is true, then Backtalk will only trust authentication information passed to it by the httpd server if Backtalk is running as the user httpd runs cgi programs as. It is sometimes useful to turn this off for debugging purposes. It defaults true.

This should not be turned turned off in a production installation. It may enable people with unix accounts on your server to mascarade as arbitrary Backtalk users.

sessions
(boolean) Was this Backtalk installation built to use on-page login forms, cookies and sessions to track users? If false, the system is set up to use basic authentication. This constant can only be changed by recompiling backtalk.

spell_lang
(string) This selects the dictionary to use for spell checking. If Backtalk was configured to use international ispell, then it is the name of the dictionary, just as would be given with the "-d" option. If this is defined as (), then the default language will be used. Used by spellcheck.

spell_ignore
(string) This is a comma separated list of additional words to consider correctly spelled. Used by spellcheck.

stack_limit
(integer) Normally, the size of the operand stack may grow until the system runs out of memory and crashes ignominiously with a core dump (I guess we should start checking all mallocs). But if stack_limit is set to a positive integer value, the system will die cleanly when the stack size exceeds that value. By default, it is set to zero, which means there is no limit.

suppress_redirect
(boolean) If this constant is true, then Backtalk not send any location redirect headers. If http_location is set, we print the url that should have been redirected to instead of actually performing the redirect. This is useful for debugging. It defaults to false.

timezone
(string) If this string is set to a null string, the ctime command reports times and dtime interprets times using the host machine's default time zone. (This is the default.) However, if it is set to a standard unix timezone string, such as the ones used in the TZ environment variable, like "US/Eastern" or "EST5EDT", then that time zone will be used instead.

urlarg
(string) If a Backtalk URL has a slash (/) after the script name, anything appearing after the script name is passed to the script in the urlarg variable. The older convention was to separate the urlarg from the script name with a colon (:). That still works too. This is meant as an alternative to the standard cgi argument passing for applications where a good-looking url is desirable, but you can do both.

validatemail
(integer) If this is set to a zero, then we do not validate email addresses. All addresses are considered valid. Otherwise, newly entered email addresses are always considered invalid, with the /evalid field of the user database taking automatically being set to a random validation string whenever the email address is changed. An email address is validated by calling valcode with the validation code. If validatemail is 1, this validates just the email address. If validatemail is 2, it also validates the user's account if it was previously in an unvalidated state.

version
(string) This is a string giving the name and version number of the Backtalk interpretor.

Regular-Expression Syntax

Backtalk's regular expressions mostly comply with POSIX 1003.2. They are normally entered in double angle brackets, with optional flag characters after the closing bracket, that is: "<<expression>>flags.

The rules for regular expressions are as follows:

  1. It consists of one or more branches separated by vertical bars ("|"). It matches anything that matches one of the branches.
  2. A branch is a concatination of one or more pieces. It matches a match for the first, followed by a match for the second, etc.
  3. A piece is an atom possibly followed by a star ("*"), a plus ("+"), a question mark ("?"), or a bound.
  4. An atom is either
  5. a bracket expression is a list of characters enclosed in square brackets ("[" and "]") which normally matches any single character from the list. If the list begins with a caret ("^") it matches any single character not in the rest of the list.

    If two characters in the list are separated by a dash ("-") this is shorthand for the full range of characters between those two (inclusive) in ASCII.

    A backslash followed by one of the character in the table list above are treated as the corresponding characters. Otherwise backslashes are ignored inside brackets. Backslashs do not escape characters like "[", "[" and "-" - they still have their special meanings even if preceded by a backslash. To include a bracket inside brackets, make it the first element (after the caret if there is one). To include a dash inside brackets, make it the first or last element.

    If "[." and ".]" appear inside a bracket expression, the the enclosing sequence is treated as a single letter. Thus "[ [.&nbsp;.]\t]*" would match any sequence of spaces, tabs and "&nbsp;" and sequences.

    If "[:" and ":]" appear inside a bracket expression, they enclose the name of a character class. Character classes are:
         alnum     letters and numbers
    alphaletters
    blankspace or tab
    cntrlcontrol characters
    digitdigits
    graphprintable, non-space characters
    lowerlower case letters
    printprintable characters including spaces
    punctprintable characters which are not spaces, letters or numbers
    spacespaces, vertical and horizontal tabs, formfeeds, newlines, and carriage returns
    upperupper case letters
    xdigithexidecimal digits
    In addition "[:<:]" and "[:>:]" match the null strings immediately before or after words.

If a regular expression could match at more than one place, it matches the one that starts first. If it could match different lengths, it matches the longest.

The following flags may be given:

i
Ignore case. Upper and lower case letters are treated as identical.
m
Multiline. Let "^" and "$" match against newlines internal to a pattern, not just the beginning and ending of the pattern.

Alphabetical Index

! command
' command
* command
+ math command
+ string command
- command
/ command
[ command
] command
` command
~ command
- A -
abs command
add_reference command
alias variable
allowanon variable
allowgraphics variable
aload command
amadm variable
amfw variable
and command
anonposter variable
anonymity variable
asort command
atime command
author_edit variable
author_erase variable
author_freeze variable
author_hide variable
author_kill variable
author_retire variable
authorid variable
authorname variable
authoruid variable
- B -
backtalkurl command
band command
bbsdir variable
begin command
blindfold variable
bor command
break command
browser command
- C -
cache_conflist command
call command
canspell constant
cap command
caps command
cflist_array command
cgiquery variable
cgiquote command
chain command
chomp command
cleanhtml command
clear command
cleartomark command
clip command
close_conf command
closefile command
conf_alias command
conf_bull command
conf_dir command
conf_index command
conf_login command
conf_logout command
conf_new command
conf variable
confdir variable
confid variable
conflist variable
conftitle variable
constant command
continue command
copy command
copyright variable
count command
count_sel command
counttomark command
cpass variable
csel variable
ctime command
cvi command
cvn command
cvs command
cvt command
cvscol command
- D -
datatype command
date variable
dbtype variable
dec command
def command
default command
defconstant command
defined command
defuser command
del_conf command
newgroup command
newgroupmem command
dfltgroup command
dict command
die command
directory command
dtime command
dumpstack command
dup command
- E -
edit_attach command
editdate variable
editfrozen variable
edit_resp command
email_body command
email_close command
email_new command
email_recip command
email_send command
end command
eq command
erase_resp command
erased variable
exch command
exec command
exec_limit variable
exists command
expand command
expect_resp variable
- F -
fav note
fav_sel command
favicon command
filedate command
firstdir command
firstuser command
fishbowl variable
flavor variable
for command
forall command
forget_item command
forgotten variable
fork command
freeze_item command
frozen variable
fw_edit variable
fw_erase variable
fw_hide variable
fw_retitle variable
fwlist variable
- G -
ge command
get array command
get dictionary command
get string command
get_attach command
get_conf_note command
getcookie command
get_item_note command
gid variable
grep command
groupid command
grouplist variable
groupname command
groups command
gt command
- H -
halt command
hidden variable
hide_resp command
homedir variable
htime command
httpget command
http_content_type variable
http_expires variable
http_headers variable
http_location variable
http_no_cache variable
http_pingback variable
http_proxy variable
- I -
id variable
if command
ifav variable
ifelse command
in command
inc command
include command
index command
ingroup command
inlist command
in_sel command
item variable
item_note command
itemid variable
itime command
- J -
jointomark command
jsquote command
jump command
- K -
keywords variable
kill_item command
killsession command
known command
- L -
lastdate variable
last_in_conf command
le command
length array command
length dictionary command
length string command
line command
link_item command
linkdate variable
linked variable
linktonew variable
loaduser command
loadvar command
loginlen variable
loglevel variable
loop command
lt command
- M -
mark command
mark_unseen command
maxitem variable
maxread variable
maxresp variable
mayedit variable
mayerase variable
mayfreeze variable
mayhide variable
maykill variable
maypost variable
mayread variable
mayresp variable
mayretire variable
mayretitle variable
mayseealias variable
mayseefname variable
mimename command
mod command
- N -
ne command
neg command
newbie variable
new_conf command
newgroup command
newgroupmem command
newsession command
newuser command
newuseropen variable
next_conf command
nextline command
nextuser command
next_int command
next_item command
next_resp command
next_subscriber command
nextuser command
noise command
nopwedit variable
noskip variable
- O -
onitem variable
onpost variable
onresp variable
onresponse variable
open_conf command
openfile command
or command
- P -
parentresp variable
parse command
particip variable
pathname command
pop command
post_item command
post_log_file command
post_resp command
pr command
print command
progname variable
publicflavors variable
pushuser command
put array command
put dictionary command
- Q -
quote command
- R -
rand command
read command
read_item command
read_resp command
read_text command
readable command
readdate variable
reattach command
related_items command
remember_item command
removeuser command
repeat command
replace command
resign_conf command
resp variable
retire_item command
retired variable
retitle_item command
rev_sel command
rfav variable
roll command
rsel variable
- S -
saverep variable
saveuser command
savevar command
scriptdir variable
scriptname variable
search command
secret variable
secure variable
select command
selectuser command
serverurl command
sessions variable
set_conf_note command
setcookie command
set_item_note command
showforgotten variable
showopt command
since variable
snoop_conf command
spellcheck command
spell_lang variable
spell_ignore variable
split command
srand command
stack_limit variable
stop command
stopped command
store command
sub_digest variable
sub_instant variable
substr command
summary variable
suppress_redirect variable
- T -
tail command
text variable
texttype variable
this_item command
time command
timeout command
timezone variable
title variable
- U -
uid variable
undef command
undefconstant command
undefvar command
unhtml command
urlarg variable
userlist variable
- V -
valcode command
validate command
validatemail variable
version variable
- W -
while command
wrap command
writable command
write command
- X -
xdef command
xdefconstant command
- Y -
yapp_format variable
- Z -
ztime command

contact page Tue Dec 6 09:21:25 EST 2005