UUCP ==== Several things need to be done before you can run the package: 1. CCICO.COM, SCCICO.COM and WAIT.COM must be patched with a QTERM V4.2 style patch. 2. RMAIL.COM, RNEWS.COM, SMAIL.COM, PNEWS.COM and WAIT.COM can be patched with a timer overlay. While the patch is not needed for RMAIL, RNEWS, SMAIL or PNEWS, WAIT.COM cannot function without it. The timer overlay contains four parts: A: From 0x0600 to 0x06ef is a subroutine that reads the system clock and places the data into a buffer. The buffer address is passed in HL, and is an array of seven bytes: seconds, minutes, hours, date, month, year, century, in that order. If there is no interface to a system clock then place a ret instruction at 0x0600. This will be detected, and will cause another routine to prompt for time and date information. If the subroutine is able to fill in the array, it should signal that all is well by returning zero in HL. If some error occurred, this can be indicated by returning a non-zero value in HL. If this happens, the builtin prompt code will be used, and the routine at 0x0600 will not be called again. If the internal routine is in use, it will prompt once for the date and time, the response should be in either HHMM MMDDYY order (For the U.S.) or in HHMM DDMMYY order (for the rest of the world). How the routine decides which order to use is explained below in patch C. The input can be fairly free form. The rule for parsing is as follows: for each of the five fields use up to two digits, using only one if a non-digit is found. After processing two digits, a separator is optional. So: 1015 1/07/90 shows all these rules at work: 1015 would be split after the 0 since that's two digits, but since the next character is also a digit, it becomes the first of the next field. Looking at the 1/07/90, 1 is all that can be taken for the first field, because the following / separates, but the 07 becomes the next field, and the / following that is also used, leaving 90 as the last field. B: The date manipulation code requires that the Timezone names (the three letter ID's) be available: These are placed at 0x06f0, as six bytes: db 'ESTEDT' is a typical example. Two are provided so that Daylight savings time can be noted and displayed. C: If the internal routine is to be used, it can work in two orders, as explained above. To select U.S. order (MMDDYY) place a zero at 0x06f7, to select "rest of the world" order (DDMMYY) place an 0xff at 0x6f7. D: The information required to specify when Daylight savings starts and ends is encoded between 0x06f8 and 0x06ff. The two changes, spring and fall are each encoded as four bytes: month day of week limit date direction Month is the month of the year when the change takes place, so if the spring change occurs in April, month would be four. Day of week is the day of the first day of the new time, so taking the spring change again, DST always starts on a Sunday. Days are numbered from 0 to 6: Sunday is 0, Monday is 1, and so on with Saturday being 6. Limit date is the first or last date in the month that the change cannot occur, this works with direction, in that if direction is 1, the change must take place after the limit date, and if direction is zero, the change must be before the limit date. So taking the Spring change again, assume that the first day of DST is the first Sunday in April. This Sunday will always be between the first and seventh, so the first is the first day it can occur. In this case, the limit date would be 0 (the change must occur after the first), and the direction would be 1. Looking now at the fall change, this is always the last Sunday in October. Month is therefore 10, day of week is 0 again, limit is 32, and direction is 0. The limit being 32 means the code will start assuming the 31st. is legal, and scan backwards looking for a Sunday, and this will find the last Sunday in October. As provided, the codes are in place for EST and EDT, and change data for the U.S. Hence it may be necessary to alter the Timezone names, but the DST start and stop information can probably be left alone. In order to provide further space for patching, the space from 0x0700 to 0x07ff has also been made available for the timer patch, since there are some systems that require some additional space. 3. Pick a drive where your CONFIG.SYS file will live. This need not be the same as the other drives specified for use in the mail system. Use the program SETDRV to install this drive selection into the other programs: SETDRV A0 SMAIL.COM RMAIL.COM MAIL.COM etc. etc. etc. would select A0: as being where CONFIG.SYS will live. The first parameter to SETDRV is the drive letter, with an optional user number: B7 will select drive B user 7, whereas B alone will use whatever user area is active when the program is invoked. 4. Edit up CONFIG.SYS to match your system parameters. The following fields are currently used: hostname whatever This sets the system hostname to whatever.UUCP, because right now the mail package only works in the .UUCP world. There can only be one hostname record in the CONFIG.SYS user userid (FULL NAME) The user record is provided to specify full names for sending mail. Multiple user records can be provided: user joe (Joe Smith) user fred (Fred Jones) is acceptable. Note that the first user record will be used as a default in two places: if no From: header is provided when sending mail with SMAIL, it will look at the first user, and if no -U option is given to MAIL, again the first user will be chosen. See the sections on SMAIL and MAIL below for more detail. defsys ABC This is the default system list to call. Systems are identified by a three letter ID, this defsys string should simply be a collection of ID's joined together: defsys ABCZYX would set the default list to ABC and ZYX. xferdrv Drive/User: xferdrv specifies where incoming and outgoing files are to be saved: these files are generated by and processed by SMAIL and RMAIL, and transferred to and from the remote system by CCICO, and are somewhat temporary in nature. Either a Drive alone can be given: xferdrv B: or a drive/user combination: xferdrv C7: but the trailing ':' _MUST_ be present workdrv Drive/User: workdrv is where more permanent files are placed, such as script files (see CCICO) and mailbox files. The drive/user spec can be in the same form as for xferdrv remote IDXhostname remote records are used to determine what systems can be talked to. A remote record consists of two parts: the three character ID for the host, followed by it's full UUCP hostname. The above case would create an entry for hostname.UUCP, using IDX as the three letter ID. vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv >> NOTE that the first remote record MUST be for the LOCAL host: bearing << >> the same hostname as the hostname record mentioned above. << ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ alias name alias list alias records allow mail to be aliased. See SMAIL for an example of an alias at work, and note that both SMAIL and RMAIL will expand aliases. $drv Drive/User: This allows the system to know where the $$$.SUB file used by SUBMIT for batch file operations is to be placed. This is needed for some alias expansions to work properly, see below in SMAIL for a full explanation. If you are in doubt, always run SMAIL and RMAIL from A: (i.e. with an A> prompt), and specify A: as the $drv. This has not been hard coded since several replacement CCP's move the $$$.SUB file around, so it is made a variable option. smarthost xait!harvard This should be a bang path to a host that understands how to route UUCP mail. If SMAIL or RMAIL come across a host they don't recognise, they will prepend smarthost to the address, and send it on. So using the above example, mail addressed to host!user, where host isn't in the remotes list, would be sent to xait!harvard!host!user, on the assumption that harvard knows how to route to host. inethost xait If mail is found to be in Internet style (user@host.domain or user%host.domain), then this is prepended, and the message is sent on. Note that this works only because the CP/M system has the precedence of '!' and '@' backwards: the convention is that mail addressed to uucphost!user@host.domain would be sent to host.domain, for forwarding to uucphost!user. However, the CP/M system can't deal with '@' addresses, so it goes after the uucphost first. Hence Inethost will generally only work if it's a single host, i.e. one of the hosts in the remotes list is able to resolve '@' addresses. The best thing to do is to consult the administrators of your neighbours if you have any doubt, or want to try something like host1!host2 as your inethost. progdrv a0: This should simply be the drive (or drive/user) where the programs are to be kept. This is used by WAIT (among others) when it is necessary for a program to re-execute itself from within a submit job. feed feedhost This is the host that PNEWS will send articles to. PNEWS will fail if this line is missing, or if it mentions a host not also in a remote line. newsgroup comp.os.cpm cpm RNEWS works by mapping newsgroups to .MAI files, so that MAIL -UXXX can be used to read the news. To receive a newsgroup, a record like the above is needed: this tells RNEWS to put comp.os.cpm articles in CPM.MAI, and MAIL -UCPM will read them. Note that these are _NOT_ aliased as happens with RMAIL and SMAIL, however note that several newsgroups can map to one mailbox, and the mailbox can be one that is usually delivered to by SMAIL and RMAIL. As an example, here is the config.sys file that I use on pallio: hostname pallio smarthost xait!harvard inethost xait user dg (David Goodenough) user mcg (Maralen Goodenough) user rna (Remote Network Archive) user rnax (Remote Network Archive Transmitter) defsys XAIMIR remote PALpallio remote XAIxait remote MIRmirror remote IOCiocs xferdrv d29: workdrv d31: $drv a0: progdrv a0: feed mirror alias postmaster dg alias rnax dg alias uucp dg alias news dg alias fgz fgz@royalt.enet.dec.com alias rna ; a0:rna -r $* ; era $* alias beta ameyer larry daveg mitch ianj rat alias ianj xait!think!ames!pacbell!sactoh0!ijsys!ianj alias ameyer xait!harvard!ulysses.att.com!rick!ahm alias larry xait!think!rutgers!utai!csri.toronto.edu!dciem!lfergus!larry alias daveg xait!harvard!gatech!uflorida!usource!daveg alias mitch xait!texbell.sbc.com!harlie!mitch alias rat xait!harvard!uwvax!astroatc!nicmad!madnix!deety!rat newsgroup comp.os.cpm cpm newsgroup soc.religion.christian src newsgroup comp.sys.cbm cbm newsgroup rec.humor.funny rhf newsgroup control dg newsgroup to.pallio dg Running the programs. SMAIL sends mail. You need to create a message file containing the text of the message including any headers, in fact a To: header is essential so that SMAIL knows where to send the message. You can add Subject:, Reply-To: etc. headers. If no From: header is given, the first user in the CONFIG.SYS file is assumed, however if a From: header is provided, then SMAIL will fill in the name from the parenthesized data in CONFIG.SYS. Leave a blank line after the headers, and enter the text of the message: --------------------------------------------------- To: xait!foo!bar!baz!joe Subject: Next week's Barbecue From: dg Joe: Thanks for the invitation, I'll see you there ....... -------------------------------------------------- is the sort of thing. SMAIL does whatever is needed to deliver the message: it can deliver several letters, and understands wildcards, a command I use a lot is: SMAIL B:*.OUT where I put my letters in B:JOE.OUT, B:BLURFL.OUT etc. SMAIL now handles multiple addresses: To: and Cc: are pretty well interchangeable, however for each To: or Cc: header only one address can be given, so to send to three people, three To: or Cc: headers are needed: To: address1 Cc: address2 Cc: address3 SMAIL will also expand alias records from CONFIG.SYS, so a line like: alias feeds xait!postmaster foobar!postmaster postmaster would cause: To: feeds to send to the three addresses. Aliases can now be used to pass inbound mail to programs. If an alias expansion starts with a ';' character: alias print ; pip lst: = $* ; era $* then it is assumed to be a "give to program" alias. The ';' character can be used to separate several commands in the expansion: the above would first have pip print the file, and then era would erase it. This is the reason for $drv above in the config.sys file: in order to cause the programs to run, SMAIL and RMAIL create or append to the $$$.SUB file that is normally created by SUBMIT, hence causing the programs to be executed as needed. In order to make the letter available, it is saved in a file on the xferdrv, and then this filename is made available, much as command line arguments are made available to SUBMIT. To cause the filename to be included, use '$*' as was done above. Two other '$' escapes are used: '$$' becomes a single '$', and '$;' becomes a ';'. These are needed since the '$' and ';' usually have a special meaning. Placing any character other than '$', '*' or ';' after a '$' in an alias of this nature will have an undefined result. SMAIL has a couple of options: -D will delete letters that have been successfully delivered, so by saying SMAIL B:*.OUT -D the letters are removed - this avoids sending duplicate copies if you forget to clean up. SMAIL -O will forward a copy to outmail, which can be aliased in CONFIG.SYS if so desired. This can later be inspected by MAIL, using the -U option (see MAIL for more information). The main purpose behind this is to keep a record of all mail you've sent. RMAIL This runs with no arguments. All it does is to process received letters after a CCICO run, and deliver them. It knows how to forward, and since CCICO can talk to multiple systems it is possible to have messages passing through. As with SMAIL, RMAIL will expand aliases. PNEWS This is similar to SMAIL, except that it posts news. In order for it to work, there must be a feed line present in the config.sys file. It only has one option: -D to delete on a successful posting. The format for an article is just like a letter: headers / blank line / body. The _ONLY_ mandatory header is a Newsgroups: header, but a Subject: will probable be used in all cases. PNEWS will fill out a From: header, or do like SMAIL, and use the first user record in config.sys, so if joe was a real user with a line in the config.sys file, saying: Newsgroups: rec.arts.sf-lovers From: joe Subject: whatever blah blah blah ..... would cause PNEWS to expand the From: line to something sensible, i.e. his full name from config.sys would be added, and also the host name would be put in. RNEWS This also runs with no arguments. All it does is to process received news batches after a CCICO run, and deliver them. There is no contention between RMAIL and RNEWS: they each will only deal with the X- and D- files that are applicable to them, leaving the others alone. So after a CCICO run, RNEWS and RMAIL can be run in either order, and the two will deal with all news and letters that arrived. Note that news batches cannot be compressed, but multiple articles in one batch file can be processed. MAIL This is the mail reader program. It normally defaults to the user mailbox specified in the first user entry in CONFIG.SYS. However, by saying -Uuser it is possible to get MAIL to look at other mailboxes. This is how OUTMAIL.MAI can be inspected: MAIL -UOUTMAIL will look at it. MAIL has two command "levels" - main command ('>' prompt) and pager level. Main command level input can be multiple commands, they are explained by hitting '?'. A few useful ones: return alone (i.e. a blank line) will read the current letter, and then go on to the next. Commands such as 'r' to read, or 'p' to print, or 'd', 's', follow a generic mode: in lower case they only act on the current letter, in upper case they act on all letters or those that are tagged. All letters are chosen if none are tagged, otherwise if one or more are tagged, then just those tagged ones will be the ones that the operation is done on. Note that the 'T' and 'C' commands to tag all or clear tags on all do _NOT_ apply to tagged letters, instead they always apply to all letters. In the pager, there are various functions available, they all are "hot keys" in that a return is not needed: 's', 'd', 'p' etc. will save, delete, print the current letter (these correspond to the command mode letters), return alone gives another line, and space gives another screenful. As in main command mode, '?' gives a synopsis of the available commands. To exit MAIL, there are three options, all at main command level: 'q' quits and deletes all letters marked for deletion, saving the rest back in the mailbox being inspected; 'x' exits without changing the mailbox at all; and 'm' exits, saving all undeleted letters in MBOX.MAI, and clearing out the original mailbox. MBOX.MAI can be inspected with a MAIL -UMBOX command, however you should _NOT_ use a 'm' to exit this, since it may do strange things to your MBOX file. MAIL has three options besides -Uuser: -S causes it to print a summary of all letters in the specified mailbox, and then exit immediately; -C causes it to simply print a count of messages in the mailbox; and -X causes it to run in submit mode. Since MAIL is normally case sensitive when executing commands ('d' deletes the current letter whereas 'D' deletes all), and SUBMIT converts everything to upper case, it becomes difficult to run MAIL as part of a SUBMIT batch job, with XSUB. Giving the -X option causes MAIL to convert _ALL_ input to lower case, so that it is possible to use a batch file to save, print and delete several letters in a mailbox. Note that the global commands ('D' etc.) will not work, however this is a sacrifice made necessary by use of the -X option. CCICO This does the grunt work. There are several options for it: -Xn sets debug level to n. n is a bitmapped value, with bits 0, 1, 2, and 3 each adding more infomation (i.e. -X1 -X2 -X4 and -X8). -X64 is useful for debugging chat scripts, since it causes CCICO to display characters received during the chat and handshake phases. -X16 can be used to show the steps involved in determining which systems will be called. Note that if -X16 is to be used, it should be given before any -S options, since the options are scanned in order. -Sxxx sets systems to call, -F selects which script file to use (more in a minute) and -D causes CCICO to disable DTR on exit (assuming the patch allows manipulation of DTR). The intention of this is that by disabling DTR, the modem will not answer the phone, hence if CCICO is invoked, and then RMAIL and RNEWS immediately after, the modem will ignore incoming calls while RMAIL and RNEWS are running. This assumes that the program run after these two re-enables DTR, thereby allowing the modem to answer calls. CONFIG.SYS has a default list of systems used if no systems are given on the command line. If -Sxxx is specified, it will add the system with three letter code xxx to the list, with two special cases: -Sany will add any system with work waiting, and -Sall will add all systems known about, whether there is work waiting or not. One word of warning about -Xn. Due to the fact that CP/M was never designed to run a setup like this, I have to cheat when printing debug messages. In fact what I do is to spool them, and send them out a character at a time, interlaced with the modem I/O checking. However, if there are incoming characters, and your screen takes a long time to output a linefeed (as for example with a Kaypro), then while the linefeed is going, you may lose incoming characters. Basically, use the -X option with caution if you need nulls to talk to a BBS. I generally run CCICO with -X2 - it provides a nice file by file synopsis of the conversation: -X4 and -X8 are more for internal debugging, although -X64 (or -X66) is very useful when debugging chat scripts. The last option to CCICO is -L - this causes a log of the session to be saved in a file CCICO.LOG on the workdrv. This might be used when CCICO is running unattended, so that the log can be checked later for problems. CCICO uses script files similar to those of QTERM to allow it to dial and log in to remote systems: for this reason, QTERM.DOC has been included in the distribution .LBR. There is one major difference, in the handling of ! commands in CCICO scripts. Since a lot of the QTERM commands don't make sense (!p, !s etc.) only the following ones are recognised. !b - This sets the baud rate, and it only takes a single number, as in !b 1200 !, - This causes a hangup !. - This sends a break !q - This will tell CCICO that the script failed to connect to the remote machine, so in this case script processing terminates, and CCICO will move on to the next system in it's list to call. !t - This is used to say that the script has finished successfully, but after all the transactions with the remote system, return here to the script and continue. This could be used to reinitialise the modem, or do whatever. An example might be: etc. etc. etc. ; connect and log in !t ; communicate with the remote uucico or whatever !d - This finishes the script, but unlike !q which is a "fail" finish, this is considered to be a "successful" finish: it then causes CCICO to enter the file transfer section. !# !@ - These manipulate variables, in exactly the same manner as their QTERM counterparts. !: `label - These allow labels to be used in CCICO chat scripts, exactly as their QTERM counterparts do: the ` escapes a label, and $` and $$ escape the '$' and '`' character to allow them to be included in strings. !> string - string is processed for '\' escapes, and then is sent out to the screen, this can be used to mark the passage of various points in the script. ![ - this case covers several options, some are like their QTERM counterparts: ![ - time .s1.s2.s3.s4. does timed input, optionally stopping when one of the strings s1, s2 etc. are detected. The last 64 characters read are saved, and these can then be tested with the other ![ options: ![ + string This tests for string appearing in the 64 character buffer, and the test is done on all 8 bits, to get 8 bit data into the match string \x escapes can be used. ![ = string This is similar, but ignores the top bit, only checking the lower seven. ![ _ string This also tests only seven bits, and in addition, it makes no distinction between upper and lower case. A script should have both the dialing commands (ATDT etc. etc.), and the login script (Usystem, password). It should do whatever is needed to get the remote system running a uucico in slave mode, which usually means just logging in successfully, as shown above. Note that the script must live in workdrv, along with all the other important files, and it should have the name SYSTEM.XXX where XXX is the three character ID for the system in question. There is an option to CCICO to cause it to use an alternate script: if CCICO is invoked with a -F option: CCICO -FA for example, it will take the characters following the -F, and insert them into the name like so: SYSTEMA.XXX These should be kept to single character identifiers, it is doubtful that 36 scripts ('A' - 'Z' and '0' - '9') will all be in use. Of course, if no -F option is given, CCICO defaults to SYSTEM.XXX, without adding any characters to the name. This might be used if the standard scripts call out at 2400 BPS, but when only a 1200 BPS modem is available, a second set of scripts: SYSTEMA.XXX, SYSTEMA.YYY etc. would all use !b 1200 instead of !b 2400, and would run at the lower speed. SCCICO CCICO.COM will only place an outgoing call (like uucico -r1 in a UNIX environment). SCCICO is the "other half", in that it handles incoming calls that have been processed by WAIT. SCCICO takes most of the CCICO options, however at this stage -L is not implemented. The -SXXX option in SCCICO works a little differently: If SCCICO is invoked with no -S option, then it will accept a call from any system listed in the 'remote' lines in CONFIG.SYS. However, as an added security measure, after the Login ID and password have been verified by WAIT, it can invoke SCCICO with a single -S option to say which system has called. Again, this is the three character ID, and if the hostname sent in the initial handshake doesn't match the expected name, then it is considered an error, even if the hostname is in the 'remote's list. UUCP UUCP is designed to look a bit like PIP: it can be invoked without arguments, in which case it enters interactive mode, or if arguments are provided it will take them as a command. Note that if commands are given when UUCP is invoked, they are converted to lower case, since the CCP converts everything to upper case. This means that it will not be possible to provide a remote system name or filename that contains any upper case characters in it. To do this, interactive mode must be used. If UUCP is invoked with no arguments, it signs on, and then prompts with a '>' character. In either case, interactive or with arguments, there are only two possible options: system!filename = cpmfile and: cpmfile = system!filename These basically do like you'd expect: the first copies local file cpmfile to system, calling it filename when it arrives, and the second copies filename from system to local file cpmfile. Note that like in uucp on a UNIX machine, '~' escapes can be used as part of the remote's filename since they expand on the remote system. However, use this with caution, since it's behaviour is dependant on the way things work on the remote system. As always, if in doubt, talk to the system administrator of your remote machine. To exit from UUCP in interactive mode, simply hit return in response to the prompt. When sending a file, a copy of the file is spooled in the xferdrv area, however on reception the file is directly created, there is no spooling for incoming files. Files normally are sent as text files, however by appending a '-b' to the above commands: system!filename = cpmfile -b cpmfile = system!filename -b the transfers are done as binary files, note that a space must preceed the -b, so 'system!filename = cpmfile-b' won't work. WAIT WAIT does several jobs: it can be used to control the modem's DTR line - thereby controlling whether the modem will answer an incoming call or not, it can also run a script immediately, but it's main purpose is twofold: it acts as a scheduler for outgoing CCICO calls (and other operations if needed), and it can also field incoming calls. The following commands are recognised: WAIT OFF WAIT FILE WAIT TIME OFF WAIT TIME IGN WAIT TIME FOR WAIT TIME FILE Any other combination than these simply cause WAIT to toggle DTR off for a short time to hang up the modem, and then reactivate it, and exit. So simply saying WAIT will hangup, and exit immediately. WAIT also has one option: -Xn, which works just like the corresponding option in CCICO, however note that only -X1, -X2 and -X64 are available: the -X4 and -X8 don't make any sense in WAIT's operation. -L is not yet available, but is in the works. WAIT OFF This makes DTR inactive, and then immediately exits: it can be used to make the modem ignore incoming calls while doing some other form of processing. WAIT FILE This activates the script in FILE, like CCICO the script is in QTERM style. Most of the CCICO ! commands will work here, with the exceptions of !d and !t, since these don't make any sense, however one command is added: !x. If WAIT encounters a !x command, it is assumed to be a command line to be executed, this might be used to allow WAIT to run a script to check an incoming call, and after the script succeeds, WAIT would cause the command to be executed. An example might be: !x A:SCCICO -SXXX ; RMAIL ; RNEWS this would cause SCCICO, RMAIL and RNEWS to be executed. As with RMAIL and SMAIL expanding aliases, this is done by creating or appending to $$$.SUB. Note that in this example, '$$' and '$;' are the escape sequences for '$' and ';' respectively, however the '$*' escape should not be used, since it will have an undefined result. If the script encounters a !q it will cause WAIT to hangup and then exit. The intention with this is that it can be used when some other program (BYE for example) has been used to field incoming calls, and after the baud rate etc. have been dealt with, control is passed to WAIT, to allow it to process the call. In this mode of operation, the !w command (explained below) should not be used, since it will have the same effect as a !q (i.e. terminate the script). WAIT TIME OFF In this example, TIME is a time, either entered as 24 hour absolute: WAIT 0300 OFF would wait till 3 in the morning, or TIME can also be entered as a relative time: WAIT +0200 OFF will wait for two hours, the '+' before the time makes it a relative time. For example, if this were invoked at 1326, WAIT would exit at 1526. Note that all times are entered as 4 digits, and no separators are used, so one minute past midnight would be 0001 etc. A special case is when the time is '++': this will wait for ever. The OFF in this case causes WAIT to disable DTR for the duration specified, however DTR is reactivated when WAIT terminates. With DTR disabled like this, all incoming calls are ignored, in that they won't even be answered. Note also in all timed cases that there is a three hour window following the time specified, during which WAIT will exit, so if WAIT were executed as 'WAIT 1705 OFF' at 1823, 1823 is less than three hours after 1705, so WAIT would exit immediately. While WAIT is waiting it scans the keyboard, looking for either a ^X or a ^C. Both of these cause it to exit, but in addition, ^C will delete a $$$.SUB file, thereby returning to interactive control immediately. WAIT TIME IGN This waits for the same time as above, however the IGN (short for IGNORE) causes WAIT to hangup on entry, but leave DTR active. This will allow incoming calls, but will subsequently do nothing with them: the modem will answer because DTR is active, but will not output any text to the caller. At time TIME, WAIT will hangup again, and exit. As with the above case, ^X and ^C exit in the same manner. WAIT TIME FOR This starts by hanging up, and then waits till either TIME arrives, in which case it hangs up again, and exits, or until a character arrives from the modem. If a character arrives, it exits, but does not hang up. Again, ^X and ^C behave as described above. WAIT TIME FILE This starts by hanging up, and then running the script in file. In this respect it is similar to WAIT FILE. It should be noted that !q and !x will behave as described above, terminating WAIT or chaining to other programs as appropriate. However the intended exit from the script is the !w sequence. This causes the script to enter the wait phase, looking for characters from the modem. When one arrives, the script is reactivated at the line below the !w, to process the incoming call. The idea behind this is that the script above the !w can initalise the modem to make it ready for incoming calls, and below the !w it actually deals with a call. When a !x line is encountered in this section, WAIT will execute the programs, and then reactivate itself, to continue the wait. One additional ![ command is provided in WAIT for use when dealing with incoming calls: ![ . time echo c1 c2 This causes wait to use a "buffered input" similar to that used by BDOS, in that ^H and DEL erase a single character, ^X and ^U kill the entire line, and ^M and ^J terminate input. The parameters are: time - this is the length of time to wait before timing out. This can be set to zero to disable the timeout. Echo controls how the typed characters echo: if it is 0 then no echo is done at all, 1 causes each character to echo as it is typed, and any other character causes each typed character to be echoed as the 'echo flag'. So '![ . 15 *' would wait 15 seconds, and echo each typed character as a '*' - this is intended to provide feedback that the correct number of characters have been sent, without revealing what they are. c1 and c2 are two optional special termination characters: these will cause the input to be terminated as well as ^M and ^J. To provide an example, a BBS system using WAIT might have something like: 'Hit escape to enter the BBS: ' as it's prompt, and use \e and \xae as the two escape characters. The '\e' maps to escape, and the '\xae' maps to the FIDO tsync character. That way, if it's a user looking to enter the BBS, the escape will allow that, and another FIDO system calling in would send the tsync character. The string sent can be checked with the ![ =, ![ +, and ![ _ command, and in addition, two variables are set to provide information as to what was entered. Variable l (testable with !# l = nn) holds the length of the input string, and variable r holds the result of the input. If the input terminated normally, with a ^J or a ^M, then r holds zero, if it timed out, r holds 1, and if either special termination character was detected (27 for esc or 174 for tsync in the above example), then r holds that value. So after detecting an escape, '!# r = 27' would allow testing of that, and !# r = 174 would test for the tsync character. To provide an example, here is how a night's batch work might be done: wait 0030 off ; wait to half past midnight, calls disabled qterm pick ; invoke QTERM to do some BBS calling ccico ; fire a CCICO run wait off ; DTR off while we crunch the mail rmail ; process the received mail wait 0300 login.sys ; wait till 3 AM, run calls through login.sys ccico -sxai ; ccico again, but only one system wait off ; DTR off again rmail ; do the mail wait 0600 login.sys ; wait again, fielding calls ccico ; ccico again wait off ; DTR off .... rmail ; mail rnews ; and news wait 0730 login.sys ; wait till 7:30 wait off ; disable the modem permanently Finally, here is an example of a chat script that might be used by WAIT !b 1200 ; start at 1200 ~at\r~OK\r\n~5~5~ ~ats0=1\r~OK\r\n~ ; enable auto answer ~at\r~OK\r\n~5~5~ !w ; now go and wait !@ a 0 + 0 !: reset !@ a a + 1 !# a = 4 `hup ; try four times before giving up ![ . 20 ; read input !# l # 7 `reset ; need exactly 7 characters !# r # 0 `reset ; if a timeout, try again ![ = Usystem `getpw ; check for the correct system name - ; note that 7 is the length of 'Usystem' !# a = a `reset ; didn't get it [1] !: getpw ![ . 10 ; read it !# l # 8 `hup ; check length !# r # 0 `hup ; and timeout ![ = XXXXXXXX `pwok ; see if it's valid !: hup ; come here if not !, ; hangup !q ; and quit !: pwok ; password was OK !x A:SCCICO -SXXX ; so invoke SCCICO [1] note that as this point, it would be possible to have a check for a second (and a third etc.) system id: and each success would have to jump to the appropriate password check routine, and thence to the !x for that system. Note how the SCCICO line has the three character ID for the system as a -S option, this is not needed, but if present, it will be checked against the 'Ssystem' line in the handshake. Note also that it would be possible to 'autobaud', consider the following: !w ![ - 5 .00. ; [b] ![ = 1200 `b1200 ; [c] ![ = 2400 `b2400 ; [d] !# a = a `ok !: b1200 !b 1200 !# a = a `ok !: b2400 !b 2400 !: ok etc. line [a] waits for the CONNECT message, then line [b] waits for '00'. This is intended to be the last two digits of the 1200 or 2400 following the CONNECT. If 1200 is detected, line [c] jumps to a section that sets the baud rate to 1200, and similarly 2400 causes a jump to a section that sets to 2400. After that the normal login process continues. Most notably, mention the fact that RMAIL and SMAIL will ask for a time, and show an example in one program descrip or the other.