© 1996-2003: Jan Wolter, Steve Weiss
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.
Backtalk functions operate on the following kinds of data types:
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:
(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. When executed, a copy of the string is pushed on the operand stack.
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.
Discard the top element from the stack.
Exchange top two elements of the stack.
Duplicate the top element of the stack.
Duplicate the top n elements of the stack. Doing "1 copy" would be identical to "dup".
Duplicate an arbitrary element off the stack. Note that the indexing here is zero-based. Doing "0 index" would be identical to "dup".
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.
Of n top elements on the stack, discard all but the i-th one.
This pushes a mark onto the stack. Marks are distinct from all other types of stack elements. The [ command is identical to mark.
Discard all elements from the stack.
This deletes all stack elements on top of the topmost mark. It is an error if there is no mark on the stack.
Push the count of elements that were on the stack before the execution.
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.
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.
Create a an empty dictionary and push it on the stack.
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.
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.
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.
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.
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.
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.
Remove the symbol label from the constants dictionary. System constants (the ones defined below in this document), cannot be undefined.
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.
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.
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.
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.
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.
Find the number of key/value pairs in a dictionary.
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.
Check if a symbol is defined in a dictionary.
Save a value to a dictionary. The key can be a string or a literal.
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.
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.
Compute int1 times int2.
Compute the integer part of int1 divided by int2.
Compute the remainder part of int1 divided by int2.
Negative of int1.
Absolute value of int1.
Bitwise-and of int1 and int2.
Bitwise-or of int1 and int2.
Bitwise-negation of int.
Concatenate two strings into one string.
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.
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) (,) jointomarkgives "(a,b,17,c,d).
Find the length of a string.
Fetch a character from a string. Indexing is zero-based. It is an error if the index is out of range.
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.
Delete any and all trailing newlines from the end of a string.
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.
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.
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.
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.
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.
Convert the first character of each word in the string from lower case to upper case.
Convert all lower case characters in the string to upper case.
This inserts newlines into the given strings so that it contains no lines with longer than numcols.
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:
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.
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.
The function should push onto the stack a URL that will point to response resp of item item in the conference conf.
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.
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.
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 ) are not checked. The mode flag determines what is pushed onto the stack before each execution of the procedure.
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:
mode: pushed on stack before procedure execution: 0 badword 1 priortext badword 2 suggestions badword 3 suggestions priortext badword
[ 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.
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 ().
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 ().
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.
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.
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).
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.
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.
Converts an integer to a string, right-justifying it within a string of numcols blanks.
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.
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.
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.
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.
This pushes the elements of an array singly onto the stack.
This finds the number of elements in an array.
Fetch an element from an array. Indexing is zero-based. It is an error if the index is out of range.
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) putthen we end up with the array "[(a) (b) () () (c)]".
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.
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.
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.
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.
Given a non-negative
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.
This reverses the order of a selector. That is "2,13-15,10,7"
becomes "7,10,15-13,2".
Test if any1 is equal to any2. You can compare times to the integer zero.
Test if any1 is not equal to any2. You can compare times to the integer zero.
Test if any1 is greater than or equal to any2.
Test if any1 is greater than any2.
Test if any1 is less than or equal to any2.
Test if any1 is less than any2.
Logical-and of bool1 and bool2.
Logical-or of bool1 and bool2.
Logical-negation of bool.
The given procedure is executed if and only if the given boolean is true.
Either of the first or second procedures are executed, depending on whether the boolean is true or not.
Execute the given procedure repeatedly forever, or until a break is performed (or a halt or even a stop for that matter).
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".
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 loops through the elements of an array or a string. It does one iteration through each element of the array or character of the string. 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). Thus "{} forall" is equivalent to aload.
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.
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.
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.
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.
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).
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
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 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
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.
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.
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.
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.
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 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.)
Print out the top stack element.
Prints a snapshot of the stack to standard output, without altering the stack. This is a debugging tool.
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.
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.)
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:
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.
Check if the given pattern occurs in the string. Push 1 if it is, 0 if it isn't.
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.
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.
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.
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 user's .backtalk file also has a default file,
the system dflt.backtalk file,
but 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 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
If the file exists, push the time at which it was last modified
(the mtime).
If it doesn't exist, push zero.
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.
Fetch information about a user from the user database.
Given a login name, this returns the user id number, the group id number,
the fullname, the home directory name, the time of the last login, and the
user's status.
Status is 0 for valid accounts, 1 for unvalidated accounts, and 2 for
invalidated accounts, and -1 for non-existant accounts.
If the user does not have an identity database entry, then the directory and
fullname will be () and the uid and gid will be -1
and the laston time will be 0.
If mayseefname is false and we our not looking up
ourselves, then the fullname will be ().
In the vast majority of Backtalk installations, email addresses for users
are not kept in the user database. They are kept instead in the user's
'.backtalk' file. On those systems this function will always return
an empty string. In the rare cases where email addresses are in the user
database, this returns the email address.
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.
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.
Return the login name of the next user in the user database.
firstuser or
seekuser
must have been called previously to initialize the loop.
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.
Push the names of all known user groups onto the stack.
Push the name of the group in which users are created by default.
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.
Given a group id number, find the corresponding group name string.
If no group by that name exists, return ().
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.
Set the given user's primary group id to the given value. The group can
be given either as a numeric gid, or as a string group name.
If the login or groupname does not exist, or the group number is negative,
an error string is returned.
If they are OK, a null string is returned.
Only conference administrators have the power to execute this 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).
Set the user's full name to the given new name. User must be authenticated.
If the new name is illegal, an error message is return.
If it is OK, a null string is returned.
Note that the fullname is not the user's current alias in the current
conference (that is changed by the conf_alias
function).
The fullname is the default value for the alias when he joins
a new conference for the first time, and it is the name printed when someone
asks for a bio of the user.
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).
Set the user's password to the given string.
If the password isn't reasonably good, an error message is return.
If it is OK, a null string is returned.
Conference administrators may apply this command to another user's
account by doing a selectuser command.
Note that this validates previously unvalidate or invalidated accounts as
a side effect.
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).
In the rare installations which have user's E-mail addresses in the user
database, this changes them. In most installations, it is a no-op.
Conference administrators may apply this command to another user's
account by doing a selectuser command.
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 changepass,
changename,
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.
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).
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).
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.
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.
Delete a group.
Returns 1 if the group did not exist, 0 on success.
Only conference administrators can execute this command.
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.
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.
Invalidates any session that may be in progress, and erase any session cookie.
This logs the user out, in systems configured to use sessions.
This returns an integer code classifying the user's browser into one of four
rough groups according to its capabilities.
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.
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.
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.
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.
Push the current time, as a Backtalk time object.
Convert a Backtalk time to a text string representing the time.
The string has the usual Unix format (except without a terminal newline):
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.
Convert a Backtalk time to a http format time string.
Format is like:
Convert a Backtalk time to standard international format (ISO 8601) time string.
Format is like
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.)
Generate a random integer between zero and range-1.
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.
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 for the given number of seconds.
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.
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.
This reads the user's .cflist into an array. The flag may have
the following values.
If comments are to be returned, the appear as strings starting with a pound
sign. Some interfaces use these as subheadings or flags, most interfaces
ignore them.
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 the conference is already open, 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.
This is exactly like open_conf except it will never
create a participation file. It behaves as if you resign the moment you
close the conference. 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.
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.
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.
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.
This command closes the currently open conference and resigns from it,
discarding all record that the user has ever been in it.
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.
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.
See also the changename function.
Push the text of conference bulletin on the stack.
Open_conf must have been called.
Equivalent to '(*bull) read'.
Push the text of conference index on the stack.
Open_conf must have been called.
Equivalent to '(*index) read'.
Push the text of conference login message on the stack.
Open_conf must have been called.
Equivalent to '(*login) read'.
Push the text of conference logout message on the stack.
Open_conf must have been called.
Equivalent to '(*logout) read'.
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
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
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 Picospan implementation also sets the following system variables:
item,
maxresp,
maxread,
linkdate,
lastdate,
readdate,
forgotten,
frozen,
mayresp,
retired,
and linked.
In future implementations,
some of these 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.
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,
and retired
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.
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 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.
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.
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 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.
The maypost variable can be checked to see if
the current user has the ability to post items to the current conference.
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.
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 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.
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.
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.
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:
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.
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:
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.
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.
This unforgets the given item number.
It pushs an error code of 1 if there is no such item, or 0 if we succeed.
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.
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.
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.
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.
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.
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.
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.
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 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.
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.
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.
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.
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.
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.
This function modifies the description and type associated with an existing
attachment.
Returns 1 if the named attachment does not exist, 0 on success.
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.
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.
On error, an error message string is pushed. On success, a null string is
pushed.
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.
Start an new email message. 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.
Attach a body to the current email message. 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. 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.
Add a recipient to the current E-mail message.
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:
Send the current email message. It is an error if the message does not
exit or if it doesn't have at least one body and at least one recipient.
You can call this more than once on the same message, perhaps calling
email_recip first to change the recipient
on the next message.
Discard the current message, freeing up all memory that is uses.
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.
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>.
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.
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.
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.
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.
The rules for regular expressions are as follows:
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
"[ [. .]\t]*" would match any sequence of spaces,
tabs and " " and sequences.
If "[:" and ":]" appear inside a bracket expression,
they enclose the name of a character class. Character classes are:
The following flags may be given:
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.
Miscellaneous Operators
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.
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.
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.)
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.
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
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
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.
is next_item err
rsel item this_item err
nrs read_item err
nrs next_resp err
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
(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
conf item link_item err
user first_partic 1
- next_partic 1
handle get_attach errcode
E-mail Operators
This section describes commands for sending email messages from Backtalk.
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.
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.
(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 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.
Conferencing Variables
There are a number of built-in variables that are used to pass information
in and out of the conferencing commands.
The mayseealias
and mayseefname variables will automatically be
set to indicate the access available to the current user.
anonymity
aliases can be seen by:
real full names can be seen by:
0 everyone. everyone. 1 authenticated users only.
authenticated users only. 2 fairwitnesses of the current conference only.
admins and members of the gradm group only. 3 admins only. admins only. Miscellaneous Variables
There are several other built-in system variables that
effect the system's behavior, but aren't directly related to conferencing.
`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.
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.
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.
\a
a control-G bell character \b a control-H backspace \f a control-L formfeed character \n a control-J newline character \r a control-R carriage return character \t a control-I tab character \v a control-K vertical tab character \\ a backslash
In addition "[:<:]" and "[:>:]"
match the null strings immediately before or after words.
alnum
letters and numbers alpha letters blank space or tab cntrl control characters digit digits graph printable, non-space characters lower lower case letters print printable characters including spaces punct printable characters which are not spaces,
letters or numbers space spaces, vertical and horizontal tabs,
formfeeds, newlines, and carriage returns upper upper case letters xdigit hexidecimal digits
Alphabetical Index
! command
' command
* command
+ math command
+ string command
- command
/ command
[ command
] command
` command
~ command
- A -
abs command
alias variable
allowanon variable
allowgraphics variable
aload command
amadm variable
amfw variable
and command
anonymity variable
asort 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
changeemail command
changegroup command
changename command
changepass command
chomp command
cleanhtml command
clear command
cleartomark command
clip command
close_conf 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
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 -
date variable
dbtype variable
dec command
def command
default command
defconstant command
defined command
del_conf command
newgroup command
newgroupmem command
dfltgroup 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
firstuser command
fishbowl variable
flavor variable
for command
forall command
forget_item command
forgotten variable
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
http_content_type variable
http_expires variable
http_headers variable
http_location variable
http_no_cache 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
itime command
- J -
jointomark command
jsquote command
jump command
- K -
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
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
next_int command
next_item command
next_resp command
nextuser command
nopwedit variable
noskip variable
- O -
open_conf 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
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
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
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
substr command
- 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
unhtml command
urlarg variable
useremail command
userinfo command
userlist variable
- V -
validate command
version variable
- W -
while command
wrap command
writable command
write command
- X -
xdef command
xdefconstant command
- Y -
yapp_format variable
- Z -
ztime command
backtalk@hvcn.org
Tue Sep 17 08:57:57 EDT 2002