BBSINDEX -- generates BBS-PC! file listings (C) Copyright Eddy Carroll, December 1989 INTRODUCTION BBSindex is a utility for use with the BBS-PC! bulletin board package. It reads in the UDHEAD.DAT file database and allows you to list its contents in a wide variety of ways. It has its own script language which allows great control over the output produced. BBSindex can perform the following operations on the file database: - Sort the files into order by Name, Size, Date or any other field - Select files matching specified criteria - Print file lists, using a user specified format string - Determine which files are currently present in the download dirs - List files that are in the download dirs but not the database The script language allows you to combine these to perform tasks such as the following: - Produce file lists similar to those produced with the BBS-PC! catalogue command, but sorted into any order. For example, BBS-PC! won't let you list all the files in a given directory sorted into alphabetical order. BBSindex will. With BBSindex, such lists can be generated automatically and regularly (e.g. daily), and made available to the BBS users through a menu item. The same file can be locally uploaded into the file section for users to download. - Produce a list of files on and off line, just like BBS-PC!'s ChkFile utility. In addition, BBSindex can spot files which are online but which have a filesize different to that in the file catalogue. Such files are most likely corrupt. - Build AmigaDOS batch files to perform maintenance tasks, such as moving all the files in a particular section from whatever disk directories they are currently located in into a new directory, or moving all the files which are in the BBS-PC! download directories but are NOT in the file catalogue to somewhere else. Without further ado, let's move on to the program itself. USAGE The command template for bbsindex looks like this: bbsindex {options} scriptfile ... You must always specify at least one script file to be executed. If BBSindex can't find the file you asked for, it will look for a similarly named one with a .SCR suffix. If you specify several files, BBSindex will execute them in sequence as if they were a single continuous file. Any settings, open files etc. are maintained across multiple script files. This can be both a help and a hinderance; if you are careful not to make scripts to reliant on default settings, you shouldn't have any problems. BBSindex allows you to change some of its default settings via command line options. These can all be changed via script commands as well, but it is sometimes convenient to be able to alter them independently of the script. The available options are listed below. Note that for those options that take a parameter, there must be a space between the option letter and the parameter. -c filename This option allows you to specify the name of the configuration file BBSindex should read to locate BBS-PC!'s download directories. By default, it looks for the file CFGINFO.DAT in the current directory. If you are running BBSindex from a directory other than BBS-PC's home directory, you may need to use this option. -d filename This option lets you specify the name of the file in which BBS-PC! stores all the information about its file database. By default, BBSindex will look for the file UDHEAD.DAT in the current directory. -f "string" This option lets you change the format string used when outputting file listings. See the discussion of the FORMAT command for a full explanation of what to use here. -h This prints out a brief help screen listing the command line options. -n This option stops BBSindex from putting up AmigaDOS requesters (such as "Please insert volume FOO: in any drive"). It can be useful if some of the BBS download directories are not currently mounted, and BBSindex tries to access them. -s This option causes any OPEN or APPEND commands to be ignored, resulting in all output going to the screen. This is useful for seeing the output from a script that normally goes to a disk file. -t This option enables trace mode, which is useful for debugging large scripts. Before each command in the script is executed, it is printed to the screen. See the discussion of the TRACE command for more information on the output produced, and its usefulness. An alternative method of running BBSindex is provided, to make it possible to setup a menu option within BBS-PC! which will invoke BBSindex automatically. This can be done using menu function 111 (Run External Program). However, BBS-PC! doesn't allow parameters to be passed to programs started in this manner. To get around this, BBSindex can be renamed to BBscript. When it is run as BBscript, it ignores any command line parameters and instead looks for a script file called BBSindex.scr in the current directory. This is particularly useful if you are running the system remotely, and don't have easy access to the local keyboard. There are a few things to look out for. You should run BBSindex in the same directory as BBS-PC!'s CFGINFO.DAT and UDHEAD.DAT files (unless you override these defaults with -c and -d, or via the appropriate script commands). In addition, if you want BBSindex to know which files are online and valid, you need to give the CHECKFILES command in the script. This deliberate step is needed because checking all the files can take some time on a large system, and is not always required. You should also ensure that your CLI stack size is set to around 10000 or so. If BBSindex runs out of stack, it will tell you so; restart it with a larger stack. BBSindex needs a lot of memory to run -- around 300K altogether when processing a 200K database. This is because the entire database file is kept in memory while processing. Of course, people with a 200K file database are likely to have extra memory as well, so this shouldn't be a huge problem, though it may prevent you from running BBSindex from within BBS-PC!. In any case, BBSindex doesn't crash when it runs out of memory, it prints an error message, frees up all its resources and exits cleanly. It does likewise if you press CTRL-C, which can be used to abort at almost any time. (Sorting can't be interrupted, because the overhead of checking for CTRL-C would make it significantly slower. Sorts are pretty quick anyway, since they are done completely in memory). By now, you're probably wondering what actually goes into the script file that BBSindex interprets. The next section describes this in detail. You can also look at the example script files which accompany BBSindex for a few ideas. Try running them with the -s option to make them send output to the screen. SCRIPT FILES A script file is simply a standard text file which contains a list of BBSindex commands to be executed. It is similar to a standard AmigaDOS batch file, though quite a bit more flexible in its layout. You normally put one command on each line (blank lines are fine of course), but you can have multiple commands on a single line if you seperate them with a semicolon (`;'). Commands are case insensitive (everything is converted to uppercase internally). You can build up extra long command lines by ending each physical line with `\'. The following newline will then be ignored, and the command continued on the next line. Anything after a `#' to the end of a line is treated as a comment. Many commands take parameters. Multiple parameters are seperated by commas or spaces. If you want to include spaces or lowercase characters in a parameter (usually the case), you need to surround it with quotes. You can use either single or double quotes; if you use single quotes, the string inside can contain double quotes and vice versa. BBSindex allows you to define constants, which can then be used later on as part of a command. It can be useful to assign items subject to change (such as output filenames) to constants at the start of the script file, and to use these constants throughout the rest of the file. Changing a filename then becomes a simple matter of altering the constant definition, rather than having to hunt through the script file. You define a constant by saying name = value where name is any identifier up to 20 characters, and value is a single string. If value is surrounded by quotes, they are stripped off, but the case of the text inside is retained. To use the constant, you just say $(name) anywhere in a command, even within quotes. Any `$' character which isn't immediately followed by an open parenthesis is left unchanged. For example, you might say at the start of a script Filename = "Sys:BBS/Amiga.Files" and then later on, you could use it to open a file: OPEN $(Filename) As with everything else, constant names are case insensitive. SCRIPT COMMANDS This section contains a list of the commands recognised by BBSindex. If you make an error in a script, you'll get an error message listing the name of the script file, the line the error occurred on, and a brief explanatory message. To start with, here's a brief synopsis of all the commands. Below this, each command is described in detail. Command Name Description ~~~~~~~~~~~~ ~~~~~~~~~~~ APPEND "name" Append future output to the end of file "name" CHECKFILES Scan BBS-PC!'s file directories CLOSE Close current output file, reverting to screen CONFIG "name" Specify full pathname to access the CFGINFO.DAT file DATABASE "name" Specify full pathname to access the UDHEAD.DAT file ECHO "string" Output "string" to the current output file EXEC "command" Execute an AmigaDOS command FOREIGN List all the files not in BBS-PC's file catalogue FORMAT "string" Specify the format to print file listings in IGNORE file ... Specify files to ignore when doing CHECKFILES LIST List all the files matching the SELECT criteria MACRO name/ENDM Define a new macro called name MSG "string" Display "string" on the screen NOREQUEST Stop AmigaDOS putting up error requesters OPEN "name" Direct future output to file "name" RESET Reset the file counters used by SCAN and LIST SCAN Update counters as LIST, but don't print any output SELECT criteria Specify criteria to use when listing files SORT index ... Sort database under the specified fields TRACE [ON | OFF] Turn on or off trace mode APPEND Filename Opens an existing file as the current output file. Any output from BBSindex will be appended to the end of this file, until it is closed. When no file is open, output goes to the screen. If a file is already open when this command is given, then it will be closed before the new file is opened. CHECKFILES [dir1, dir2, ...] Causes the BBS-PC! file directories on the local disk to be scanned, so that it can determine which files are online and which are not. It also compares the size of each file in the catalogue with its size on disk, and if the two are different, sets the invalid flag for that file. This is a reasonable indication that the file may be corrupt. CHECKFILES need only be done if you want to use the %f, %i, %p or %v options of FORMAT, or you want to use the FOREIGN command. A single CHECKFILES checks all the files, so it need only be done once. Future occurances of CHECKFILES are ignored. By default, BBSindex looks in the CFGINFO.DAT file to find out the location of the BBS-PC! file directories. CFGINFO.DAT should be in the current directory, unless the -c option has been given to specify a different location for it. If you give a list of directories to CHECKFILES, then these directories are scanned instead of those in CFGINFO.DAT, and the latter doesn't need to be accessed. CLOSE Closes the current file (if any) for output. Any future output gets sent to the screen. It is not necessary to specifically close files when you are finished with them (unless you really do want the output to start being displayed on the screen) since BBSindex will close files automatically when it exits. CONFIG "filename" Tells BBSindex where to find the BBS-PC! configuration file, which contains the directory paths for the upload/download file directories. This file is only accessed if you give a CHECKFILES command and don't specify any directories; if you don't intend doing a CHECKFILES, you don't need to worry about BBSindex being able to find the configuration file. By default, BBSindex looks for the file CFGINFO.DAT in the current directory. Be careful to specify the full filename of the configuration file, not just the directory name. DATABASE "filename" Tells BBSindex where to find the BBS-PC! file database. The commands CHECKFILES, SORT, LIST and SCAN will all cause the file database to be read in. The DATABASE command can be given at any stage before this. Afterwards, it has no effect. If you don't give a DATABASE command, then the file UDHEAD.DAT in the current directory is used. ECHO "string" [NOLINE] Outputs "string" to the current file, or if no output file is open, to the screen. "string" can contain any of the escape characters (such as `\n') listed under FORMAT. It can also contain any of the following special symbols: %b The number of bytes used by files printed by the last LIST %k The number of Kilobytes used by files printed by last LIST %m The number of Megabytes used by files printed by last LIST %n The number of files printed by the last LIST command %d Today's day (Monday for example) %t Today's time %ux Creates underline, see FORMAT for more details %w Today's date (01-Jan-90 for example) %{...} Formats substring, see FORMAT for more details %B, %K, %M and %N are also available; these are similar to %b, %k, %m and %n, but they are the sums for all the files printed since the last RESET command, rather than the last LIST command. This allows you to keep a running count of the total number of files printed in the system. By default, a newline is automatically output after the string. This can be suppressed by including the NOLINE parameter. EXEC "command" Executes the specified AmigaDOS command. The output from the command is directed into the current output file. If you don't want this to happen, you can specify redirection to NIL: as part of the command string. For example EXEC "makedir >nil: ram:t" will try and make a directory in RAM:, and if it fails, you won't see anything. The EXEC command can be particularly useful if you've just used the FORMAT command in conjunction with LIST to generate an AmigaDOS script file -- you can then do EXEC "Execute Scriptfile" and the script file will be executed on the spot. If you do this, remember to close the script file you've just generated before you try to execute it. FOREIGN Outputs a list of all the files which are present in BBS-PC!'s download directories, but are not present in the file catalogue. The output is as specified using FORMAT, but only some of the options are applicable. In particular, the following are valid: %d Disk filename %c Descriptive text saying what directory the file is in %f Full disk filename %n The disk filename again %p Disk pathname %x File size in bytes %k File size in K %w Date file was last modified These have been chosen so that the default output format will list the files in a sensible fashion. This command can be useful if you want to track down all files which are not directly related to the bulletin board. For example, the following script generates an AmigaDOS script to move all the non-BBS files into a common directory called Random on DH1: # # Script to move all files not related to the BBS-PC! file # catalogue out of the download directories. # CHECKFILES # Check all files ECHO ";\n; AmigaDOS script to cleanup BBS file directories\n;" FORMAT "copy %f to dh1:random\ndelete %f\n" OPEN ram:execute.script FOREIGN CLOSE When you run this, the output is a script in RAM: which you can then execute using the AmigaDOS Execute command. Alternatively, you could add the command EXEC "Execute RAM:execute.script" to the end of the above script, and then the script itself would move the files. FORMAT "string" [NOLINE] Determines the format of each line printed by the LIST command. The format string is very similar to that used by C's printf() function. It contains normal characters, plus any of the following special symbols: %a Number of times file has been accessed %b{} File type {Binary,Text} %c Comment associated with file %d Filename the file is stored under on disk %f Full pathname of the disk copy of the file %i{} File status {Online,Offline} %k File size in K %l{} File origin {Local,Remote} %n Filename as it appears in the file database %o Uploader's name (owner) %p Path of the directory containing the file on disk %r Directory number %s Section name %ux Produce underline using x as underline char %v{} File contents {Valid,Invalid} %w Upload date (when) %x File size %y Number of the disk directory the file is stored in %{...} Format substring A number may optionally be placed between `%' and the appropriate character. This will cause the output value of the symbol to be padded or truncated to that width. By default, the output is aligned to the left but if the number is prefixed with `-', output is aligned to the right. Symbols followed by {} are boolean values, which can be either TRUE or FALSE. When such a symbol appears in the format string, it should be immediately followed by two substrings enclosed in { and } and separated by a comma. If its value is TRUE, then the first substring is used; else, the second substring is used. For example, if you want to make a list of files, and say whether each one is valid or invalid, you might use: "%20n%v{,(Invalid)}" which would print each filename, and if it was invalid, would follow it with the string "(Invalid)", starting in Column 20. If the file was valid, only the filename would be printed. A special option is `%{', which allows you to format a substring within the main string. This can be of value if you want to have several items, one after the other with no gaps between each, but with the total width of all the items not exceeding a set width. What occurs inside the braces after `%' can be any valid format string, which could itself contain `%{}'s (though it's hard to think of a situation where you would need to do this). So, "%40{%s,%r,%o}" would print the section, directory number and owner name one after the other, with the total being padded or truncated to 40 characters. The other unusual option is `%u', which reproduces the character following it a number of times equal to the length of the last string output using FORMAT. If `%{...}' has just been used, then the length of the substring is used instead. This is handy if you want to underline something but are not sure how long it is (or you just want to save some typing). For example, to underline a filename, you could use: FORMAT "%{%n}\n%u-" This outputs the filename as a substring (thus remembering the length), and a newline, and then underlines the filename using ------. When using `%u', the "length" number that can appear between the `%' and the format character has a slightly different meaning. `%6u' outputs an extra 6 underline characters, and `%-6u' outputs 6 fewer characters. The `%i' and `%v' options only make sense if the CHECKFILES command has been given earlier. They indicate whether or not the file is online and whether it is valid. A file is online if it can be found in any of BBS-PC!'s file directories. It is valid if its filesize on disk matches its filesize in the file catalogue. If it doesn't, then there is a good chance it has been corrupted. The `%y' option gives the number of the disk directory in which the file is stored. This is the position of the disk directory as it appears in BBS-PC!'s CFGINFO.DAT file. In particular, the "new uploads" directory is numbered 0. (Note that this is different to the directory 0 in which all uploads are located within BBS-PC!). The following escape sequences can also appear in the format string: \n End of line \e Escape \E CSI (0x9b) \t Tab \nnn Octal number with the appropriate value Any other characters after a `\' are treated as normal. This can be used to escape certain characters that have special meaning, such as `\' itself and `%'. `\{' and `\}' do not work within `{...}' (for boolean values and substrings) unfortunately. If you are giving the format string from the command line and you are using a DOS shell other than the CLI, you might need to type `\\' in order to get the shell to pass a single `\' to BBSindex. Note that while `\E' can be useful for generating ANSI colour codes (as in `\E33m' to change the colour to colour 3 for example), BBS-PC! does not recognise `\E', even though AmigaDOS does. Hence, for public BBS files, you are better off using `\e[33m' which gives the same effect. For more details on ANSI escape sequences, see the BBS-PC! or AmigaDOS manuals. By default, a newline is automatically added to the format string. This can be overridden by including the NOLINE parameter after the string. The default output format string is FORMAT "%15n %w %-6x-%b{B,T} %c" This produces a file listing which is idetical to the listing BBS-PC! gives when you ask for a file catalogue. IGNORE Filename Filename ... Specifies a list of files to ignore when CHECKFILES is executed. If you have some files in the file catalogue which are updated by external programs, their filesizes are likely to differ from the filesizes recorded in the BBS-PC! file catalogue. By listing such files here, you can tell CHECKFILES that it is okay for the filesizes to be different and they will then be marked as valid (and hence won't appear in any operations you do on invalid files). You can use multiple IGNORE commands if you have a lot of files falling into this category; however, only IGNORE commands which occur before CHECKFILES have any effect. LIST Scans through the the file catalogue (as sorted using SORT) and outputs the list of files which match the criteria specified with SELECT, according to the format string defined using FORMAT. Output is sent to the current file (opened with OPEN) or if none exists, to the screen. In addition, some internal counters are updated. These counters record the number of files listed and the total number of bytes occupied by those files. A seperate set of counters record the total number of files listed since the start of the script (or the last RESET command). This is useful for building cumulative totals. See the ECHO command for more details. MACRO name command 1 command 2 ... ENDM Defines a macro command. When this command is used later on, it gets replaced by the list of commands between the MACRO and ENDM markers. The macro text can contain the special symbols $1 to $9 which will expand to the parameters given to the command. For example, a macro to sort and list the files in a specified directory in a given section might look like this: MACRO Listdir # Section, Directory, Descriptive Text MSG "$2, " noline ECHO "%{$2. $3}\n%u-" # Display header, and underline it SELECT Section = $1 AND Directory = $2 LIST ENDM To use this, you would then give a command like: Listdir 1, 4, "General Files" to list the files in Directory 4 of Section 1. Note that the comma is optional (it gets turned into a space internally anyway) but can make things more readable. Also note that any text surrounded by quotes has the quotes removed (but the text case retained) when it is substituted. This is to allow $ substitution to occur within strings in the macro without getting lots of extra quotes everywhere. If you need to get a $ itself inside the macro, you can use `$$'. In fact, `$' followed by any non-numeric character will simply return that character. Macros are a very powerful feature; used sensibly, they can reduce the size of your script files by a significant amount, allowing you to express a complicated sequence of commands in only a single line. If you have many command sequences which are very similar, it is well worth taking the time to learn to use macros effectively. MSG "string" [NOLINE] Outputs "string" just like the ECHO command, except that the string always goes to the screen, even when an output file is open. This provides a useful way to print informative messages saying what is happening, while processing a big script. NOREQUEST Stops AmigaDOS from putting up requesters when it can't find a disk volume, or when a disk error occurs. This can be useful if you are running BBSindex in a batch environment, where you most likely won't be around to click Retry or Cancel in the requester. It is also useful if you are running BBSindex remotely (from within BBS-PC! as a menu option). OPEN Filename Opens a new file for output. Any output from BBSindex will be directed to this file until it is closed. When no file is open, output goes to the screen. If a file is already open when this command is given, then it will be closed before the new file is opened. RESET Resets the counters used by the %B, %K, %M and %N options of the ECHO command. See the descriptions of SCAN and ECHO for more details. SCAN Scans the file database, counting files that match the SELECT criteria just like LIST. Unlike LIST, it doesn't produce any output. It does however update the counters which keep track of the number of files printed. This is very useful if you want to produce a file listing which displays the number of files in the system at the start of the file, followed by the files themselves. You can do that as follows: SCAN ECHO "Amiga BBS File Catalogue, a total of %n files are online\n\n" LIST SCAN counts the files so that %n will be the correct number in the ECHO command, and then LIST actually lists them. Of course, if you wanted to print the number of files at the bottom of the list, the LIST command by itself would be adequate, and you would not need to use SCAN. SELECT expression Selects which files should be printed on the screen when the LIST command is given. The expression you give can include any of the keywords recognised by the SORT command, plus the boolean operators AND, OR and NOT, and the special keyword ALL (which is always true). In addition, the keywords Text, Remote, Offline and Invalid are recognised as opposites to Binary, Local, Online and Valid. The following arithmetic operators are supported: = <> > < >= <= These can be combined together with strings and numbers and grouped with parenthesis to produce a full expression. During LIST, any files which match the expression are listed. For example, to select all the binary files in Section 3, and Directories 4-10, you could use SELECT Section = 3 AND Directory >= 4 AND Directory <= 10 AND Binary Note that the eight boolean fields (Binary, Text, Online, Offline, Local, Remote, Valid and Invalid) don't need to be tested against anything, since they already evaulate to a boolean result. For example, Local will evaluate to TRUE if the file being checked was uploaded locally. For date comparisons, recent dates are treated as being "larger" than older dates. For example, to list all files uploaded during December of 1989, you could say SELECT Date >= "01-Dec-89" AND Date <= "31-Dec-89" String comparisons are case insensitive, and standard wildcards are supported. A `?' in a string will match any single character, and a `*' will match any number of characters (including none). For example SELECT Name = "*.ZOO" AND Section = 3 selects all the zoo files in section 3. The pattern "?????" would match all names five characters long. If you wanted to select all the files which were archived using a common file archiver, you might use: SELECT Name = "*.ZOO" OR Name = "*.ARC" OR Name = "*.LZH" If you want to use <, >, <= and >= with wildcard matching, you need to be careful. Bear in mind that < and > exclude exact matches, whereas <= and >= include exact matches. As an example, let's see use a file called "FOO". The comparison "FOO" < "F*" is not particularly well defined, but will probably be FALSE. On the other hand, "FOO" <= "F*" will always evaluate to true, since the `=' portion is true. Let's finish off with some more examples of selections. To select all the text files in section 3, you could use: SELECT Section = F and Text Now, let's select all the binary files in section 3, and also all the text files in section 3 that end with .ZOO or .ARC (such a requirement might come about because some versions of BBS-PC! have a bug which makes ZMODEM uploads look like Text files): SELECT Section = 3 and (Binary or Name = "*.ZOO" or Name = "*.ARC") As a final note, be aware that the more complicated the expression, the longer it will take to do a LIST (or SCAN). You can help speed things up by arranging that the condition most likely to be FALSE is at the front of the expression. For example, use SELECT Size > 102400 and Name <> *.ZOO when selecting all non-ZOO files in the system greater than 100K, rather than the other way around. SORT index [, index, index ...] Sorts the file list into an order determined by the list of indices given. When output is being generated, it is sorted according to the indices specified here. The following indices are valid: Access Number of times a file has been accessed (number) Binary Whether the file is binary or text (boolean) Comment File comment (string) Date Upload date (date) Directory Directory number (number) DiskDirNum Number of the file directory on disk (number) DiskName Name of the file on disk (string) KSize File size in K (number) Local Whether the file was uploaded locally (boolean) Name File catalogue name (String) Online Whether the file is online (boolean) Owner Uploader's name (String) Pathname Pathname of disk file (String) Section Section number (number) Size File size in bytes (number) Valid Whether the filesize is valid (boolean) Each index can optionally by followed by a `+' or `-', to indicate the direction of sorting. The default (+) is to sort in ascending order. Descending order is selected using `-'. As many indices as are listed are considered significant while sorting. The default sorting order is Name which sorts files by name. An alternative index might be Section, Directory, Name which would sort the files into seperate sections, then into seperate directories within each section, and finally into alphabetical order within each directory. You can sort files into chronological order by using Date as the sort key, or into reverse chronological order (i.e. newest files first) by using Date- as the key. Note that the CHECKFILES command sorts the database into alphabetical order by disk name before it starts scanning the disk. If you have given a SORT command before this, then CHECKFILES will sort the files a second time back into the order you specified. You can avoid the time overhead this involves (which is not actually that much) by not using SORT until after CHECKFILES. TRACE [ON | OFF] Turns on or off trace mode. When tracing is turned on, all the commands thereafter will be output to the screen before they are executed. This can be useful for tracking down a problem with a script. In particular, the commands which make up a macro will be printed individually each time the macro is executed, with $1 to $9 replaced by the actual parameters. Constants will also be replaced by their current value. Tracing can be turned on globally by specifying the -t option on the command line; TRACE ON and TRACE OFF are most useful when you have a large script file and you don't want to have to trace through all of it. HISTORY V0.99 Initial beta release. Several bugs, and a few inconsistencies. - Vigilant beta testers proved that nothing works first time :-) - Kudos to Lattice's catch.o for making life a bit more bearable (and also to CodeProbe of course). V1.0 First official release. - Improved memory allocator to handle small requests by allocating a large chunk and working from that. This should help decrease memory fragmentation. - Added support for constants - Added IGNORE keyword to allow "dynamic" files to avoid being marked as invalid. - Reworked the documentation a bit, so that it wasn't quite as disorganised. - Toyed with the idea of allowing scripts to be specified on the command line (like sed) but decided wasn't worth the effort for now. DISTRIBUTION BBSindex may be freely distributed for non-commercial purposes, as long as no profit is made from doing so. It may be distributed with commercial software only with the express written agreement of the author. Specific permission is granted to Fred Fish to include BBSindex in his fine public domain library. AUTHOR Please direct any praise, criticism, general suggestions or large sums of money to: Eddy Carroll ecarroll@vax1.tcd.ie (Trinity College, Dublin, Ireland) Also, please feel welcome to pay a visit to Infomatique BBS, of which I am a co-sysop: Phone: +353-1-302970 (Ireland) Speeds: V21/22bis/23 Times: 24 hours/day 110 Megs of online storage, large Amiga and IBM file database. Membership is free. If you call, mention where you got the number.