1 Maximus for OS/2, by Peter Fitzsimmons (1:250/628) This section outlines the features and differences of the OS/2 version of Maximus. It is assumed that BTP.EXE (BinkleyTerm for OS/2), version 2.30 or greater, is the front end mailer being used (At this writing, BTP is the only mailer available for os/2). Although Maximus/2 is mostly a straight port of the DOS version, it (and some of the support programs, MAXPIPE and PMSNOOP) utilize many of the features OS/2 has to offer, such as pipes, named pipes and multithreading. The operation of Maximus/2 is almost identical to the DOS version, except that it is a lot easier to run a multiline bbs. 2 General Differences All of the OS/2 EXEs end with the letter 'P'. With the exception of MAXRENP.EXE, the OS/2 versions work exactly the same as their DOS counterparts. DOS NAME | OS/2 NAME -------------------------- ANSI2BBS.EXE | ANSI2BBP.EXE CVTUSR.EXE | CVTUSRP.EXE EDITCALL.EXE | EDITCALP.EXE MECCA.EXE | MECCAP.EXE PIPER.EXE | PIPERP.EXE SCANBLD.EXE | SCANBLDP.EXE SILT.EXE | SILTP.EXE MAX.EXE | MAXP.EXE MAXREN.EXE | MAXRENP.EXE n/a | MAXPIPE.EXE n/a | PMSNOOP.EXE n/a | REBOOT.EXE 3 Configuration Differences o BinkleyTerm *MUST* use the "BBS Spawn" method to load Maximus. Furthermore, you must start BinkleyTerm with the SHARE command line option ("BTP SHARE"). These two options cause Bink to pass the opened COMM handle to Maximus. o Maximus must be passed the FILE HANDLE of the opened COM: port from binkley. Using the sample batch file (spawnbbs.cmd) supplied with this document does this properly. DO NOT try to hard code this value. Passing a '1' for COM1: will NOT WORK! o ALL serial port options (bps, parity, handshaking) are inherited from BinkleyTerm. Maximus does not open, close, or alter the COMM parameters in any way, except for XON/XOFF flow control. Therefore, the MAX.CTL "Mask Handshaking" statements for CTS and DSR do nothing. XON behaves as described. NOTE: Later versions of BinkleyTerm may act in much the same fashion, so it may be necessary to use the "MODE COMx:" command to set up your port before loading BTP. 4 Operational Differences o The "-p" command line option (which specifies the port number under dos) specifies file handle of the comm port. Binkley passes this open handle to SPAWNBBS.CMD, which in turn passes it to MAXP.EXE. Do not try and pass something like '-p1' for COM1:, '-p2' for COM2: etc; it will NOT work! o The "-b" command line option (bps rate) is only used in calculations, and does not change the data rate of the comm port. For example, Maximus uses this number to calculate the throughput of file transfers. If your modem is "locked" at a high baud rate (19200, for example) Maximus will communicate to your modem at 19200 (or whatever speed BinkleyTerm was using when it spawned the bbs), but will base all time calculations on the rate passed with the "-b" parameter. Therefore, the "LOCKBAUD" concept is totally transparent to Maximus. If BinkleyTerm is happy, so is Maximus. o The "-z" command line option (which turns on Desqview snoop support for the DOS version), is used by the OS/2 version to name the namedpipe that connects to a PmSnoop session. The -z parameter must be followed by a pipe name, with no spaces. example: "-z\PIPE\LINE1". If this option is not used, the default name of \pipe\maxsnoop is used. For more information, see the section on PMSNOOP, below. o External programs ("DOOR" programs) must be called with the "Extern_Run" command (see menus.ctl). Actually, this may not be true; but the other Extern_* commands seem rather silly to use under OS/2, and were not tested. I guess Extern_Dos would work ok, but I don't see many uses for calling a batch file (since Maximus has such a rich set of '%' commands to use with the Extern_Run command). o For the same reasons that the Extern_Erlvl and Extern_Chain commands are not recommended, restarting Maximus with the "-r" switch is a lost concept under OS/2, and was never tested. o The "%P" (case significant) command (Used with Extern_Run, among other things) passes the comm handle in ascii decimal. For hysterical reasons, the "%p" option (lower case) will pass - 2 - a number that is equal to one less than the comm handle, so you should steer clear of this. o The only way for external programs to use the comm port is to accept the file handle to the comm port, unless they are simple programs that use stdin and stdout. In the latter case, MAXPIPE (or something similar to it) should be used to redirect stdin and stdout from/to the com port. Using the ">" and "<" redirection options provided by the Extern_* commands is not recommended. o Due to (what I consider a design flaw) in the COM0x.SYS driver, ^C/^K checking in the os/2 version is a kludge. ^C/^K must be the FIRST key you press if you are to successfully interrupt the bbs. If any other key, or line noise, is put into the input queue before the ^C/^K, the ^C/^K will not be processed until the BBS wants user input (like at a menu prompt). This problem will probably be addressed in a future version of the bbs, which uses a separate thread it handle this. 5 Multiline Operation All files/file areas/message areas can be shared by multiple, concurrent, copies of Maximus, except for the log file and those files governed by the "task number" (the -n command line option), and the named pipe used for PmSnoop. Since all of these can be controlled with command line parameters, you therefore only need one MAX.CTL. For example, one of your SPAWNBBS.CMD files may look like this: maxp max -b%1 -p%2 -t%3 -n1 -lLINE1.LOG -z\PIPE\SNOOP1 And a second like this: maxp max -b%1 -p%2 -t%3 -n2 -lLINE2.LOG -z\PIPE\SNOOP2 IMPORTANT: BinkleyTerm, Confmail and OMMM will not coexist with concurrently running versions of themselves, so steps must be taken to make sure they never run concurrently, or they are all working in separate directories. On my bbs, where I run two phone lines, I address this by only letting one of the lines run these programs. The other line only runs Binkley (configured with separate inbound and outbound dirs) and Maximus. Confmail, OMMM and Scanbld are never, ever, invoked by this line. This problem will probably not be fixed until someone writes a "black box" DLL that handles all of these mail functions, and EVERY program that wants access to messages uses it. Since it will be serving all processes running, little work would need to be done to stop it from walking on its own toes, since it would simply queue the requests. (Once this is in place, it would be childs play to - 3 - replace the DLL with a smarter black box which ditches *.msg files and uses a database -- But I'm getting ahead of myself here). 6 The MAXPIPE program This program uses anonymous pipes and multiple threads (3 in all) to redirect "standard i/o" (stdin/stdout/stderr) to/from the comm port. It also provides a "watchdog" feature which monitors the carrier. If the carrier drops, MaxPipe kills the process it is running, and any children it may have spawned, and returns control to Maximus. Maximus will promptly notice the lost carrier, and log the caller off. If the comm handle passed to MaxPipe is 0, the watchdog feature is disabled. (Maximus passes 0 when the sysop is logged on locally). MaxPipe is invoked thus: MaxPipe [arguemnts] Where : is the open comm handle, probably passed via the "%P" Maximus thingy. is the program you want to run. If it is not on the path, be sure you specify where it is. [arguments] are any optional command line arguments you want passed to . Here is a snippet from my MENUS.CTL, which uses MaxPipe: Xtern_Run MAGPIPE.EXE_%P_ADVENT normal "Adventure" Xtern_Run MAGPIPE.EXE_%P_CMD Sysop "!Shell to OS/2" Advent.exe is the 'ol "collosal caves" program I ported. I will make it available. NOTE: If programs (written in Microsoft C or IBM C/2) use the popular getch() function (read a key), they will not work correctly with MaxPipe. For some reason, the os/2 version of getch() was written to call KbdCharIn(), rather than read from stdin. For example, if PKZIP prompts you for any reason (like when you enter PKZIP with no arguments, to get the Usage screen) you will not be able to send it keystrokes. Your only option is to hang up (no big deal -- the system will recover lickety-split). Maxpipe is a simple program, written only to keep CMD.EXE happy. It buffers the byte streams a bit (100 bytes, I think), which makes a - 4 - drastic improvement in performance. However, this may make some programs behave oddly. If you stick some fflush(stdout) statements in the code just before you ask for user input, it will solve this problem. Command line utility-type programs, that don't get user input, won't have this problem -- but you will notice the output (or the last 100 bytes of it) may be delayed until the program completes. Hopefully someone else will write a more robust program, that uses a keyboard monitor, instead of a pipe, for stdin, and a Vio subsystem for stdout. Actually, I have already done this with another program, but it is part of a commercial product I am working on. Maxpipe does not timeout; hopefully someone will fix this soon too. 7 The MaxRenP program Although this program takes similar parameters, it is a completely different program than the DOS MaxRen program. MaxRen uses direct disk reads and writes on a FAT drive, a no-no under OS/2. MaxRenP uses standard functions to read, write and rename the messages. MaxRenP is a fabulous example of how slow the FAT system is, and how fast the HPFS is. The main difference between the two is the way directories are stored. With a FAT volume, a directory is a linear list of files. The average directory search (caused by functions like open and rename) would be = total_dir_entries/2, where the total number dir entries includes erased files. In a dir with 1000 messages, the rename portion of MaxRenP would therefore do (on average) 1000 * 1000/2 (500,000) directory searches (FindFirst/FindNext) calls to renumber every message. Since (off the shelf) os/2 does not supply a write cache, each rename operation (1000) will cause one disk write. The number of disk reads depends on how big your BUFFERS and DISKCACHE statements are. With a HPFS volume, a directory is a B-tree. The average directory search (for our 1000 message dir) would scan log_base2(1000), which is equal to 10. The rename portion of maxren would therefor access only 1000 * 10 (10,000) directory entries, 50 times fewer than the FAT scenario. Also, since the HPFS supplies a disk write cache, and the directory uses comparatively few sectors, hardly any disk writes will occur. I'm not sure if my math is correct, but reality seems to agree. The same message area that takes 30 minutes to rename on a FAT volume takes only a minute or so on a HPFS volume. It is STRONGLY suggested you use HPFS volumes for your echomail :-). - 5 - 8 The PMSNOOP program This program is the harvesting of an idea I had a year or so ago. Making a PM program out of something like BinkleyTerm or Maximus is a silly idea, since these programs (from the sysops perspective) are "read only" programs that are, for the most part, MONITORED rather than INTERACTED with. Running this type of program in a VIO window, where you can keep your eye on it while using a PM app, just slows the program down (significantly), and clutters the desktop. Pmsnoop, the way Maximus uses it, gives the sysop a realtime view of the logfile. Since PmSnoop uses named pipes, the sysop could actually monitor the bbs from a different computer (via Lan Manager/Lan Server). Each copy of the bbs you run (including the one you use to logon locally) should use a different pipe name. (Although you don't have to run pmsnoop for each, if you don't want). If you don't do this, the pipe will be given on a "first come, first serve" basis, where all but the first copy of Maximus will receive an error when they try to create the pipe (this is NOT a fatal error, and the bbs will run without any problems). For each copy of pmsnoop you use, you need to tell it about the pipe name you used with MAXP. A pipe name must ALWAYS start with \pipe\, or \\server\pipe\ (yes, that is TWO slashes in \\server!), where \\server is the name of another computer on the LAN. Since Maximus is the server process (and pmsnoop is the client), if you are using LanMan (Lan Server) prior to release 2.00, Maximus must be running on a network server to connect to pmsnoop on another computer (ie: If Maximus was on a workstation, and pmsnoop was on a netserver, it would not work). This problem should disappear with the "peer services" provided by LanMan 2.00. Each copy of PmSnoop you load will recognize that it is not the only copy running, and will use a different profile from OS2.INI to load its options. Therefore, when you "save options", or use the Desktop Manager to save the desktop, each copy will store its pipe name,position, and font separately. The server end of the named pipe (used by Maximus) was implemented in a DLL (SNSERVER.DLL) so that other programs can use it too. The Snoop() API is quite simple, and will be published with the Maximus source code. I have added Snoop support to my personal copy of BinkleyTerm, and it works great. Each bink/max team shares a snoop session. I have sent the info & code off to Vince and Bill (my version was based on my original BTP 2.20 port, which is old news now), so hopefully it will be built in to the BT 2.40 release. The general idea here is that each program serving the same phone line use the same named pipe. When BTP spawns the bbs, it closes the pipe and the bbs opens it, etc. - 6 - SNSERVER.DLL does all of the named pipe magic. It does not expect either pmsnoop.exe, or the server (binkley and/or bbs) to be running at any given time. ie: You can start and stop the programs at will, or neglect to start them. A protection violation (or other death) of either program will not affect the other. Pmsnoop does not use snserver.dll. Only the server process does (Maximus, and hopefully Binkley and others soon). All other aspects of Pmsnoop should be obvious. I apologize for not installing online help, but my mandate was to build a program that worked under both OS/2 1.10 and 1.20. The help manager is not available under 1.10. There is no horizontal scroll bar when run under OS/2 1.10. When selecting a different font, some older versions of 1.10 do not engage the font correctly. The solution to this is to exit Pmsnoop and start it up again; the desired font will now be engaged. (I discovered this problem when running under the "MS OS/2 1.10 Server Adaption" that comes with 3+Open 1.1. The fonts worked correctly on the version of IBM 1.10 I tried. 9 REBOOT.EXE and BOOT.SYS If BOOT.SYS is installed, this program will reboot the computer (under OS/2 1.20). It calls DosShutDown() first, so your HPFS cache and dirty-flag are flushed & cleaned. I include it because I find it indispensable. The bbs I run is not in my home, and if BinkleyTerm or Maximus gets stuck, or I've made a change to CONFIG.SYS, I can call in on the other line and reboot. 10 MISC Unlike the DOS version of Maximus, which is compiled in the "medium" memory model, the os/2 version is compiled in the "large" model. Experienced C programmers out there will realize this is a shame, because the large model is slower than the medium model, especially in 286 protect mode. The large model also makes random and NULL pointers more flamboyant, since they will undoubtedly cause a GP fault. [I should pause here and make an observation; although some of Scott's code is hard to read and arranged in ways I would never do , I was amazed at how few memory violations it caused. We are talking less than a half dozen, which is remarkable considering Maximus contains at least 25000 lines of original code]. The OS/2 version may compile and run ok in the medium model, certainly if I shaved some of the not-used-for-os2 code, but at this stage I don't want to chance it. The MSC runtime, with respect to Maximus anyway, appears to use more of DGROUP than the TurboC RT does. On top of that, there is more code, and a larger stack, in - 7 - the OS/2 version, and I just don't think it would be a good idea to release it to you in the medium model at this time. Anyway, the point I want to make (and am taking too long to get to-:) is that there are bound to be circumstances that Maximus GP faults. The good news is is that this will not crash your bbs. I've spent considerable time making Maximus bullett-proof. When a protection violation, divide by zero, or stack overflow occurs, a DosExitList() routine will record, in the logfile, the reason for the crash. It will also copy to contents of the current screen into the logfile, so you will be able to tell what the user was doing to cause the error. It will inform the user that a serious error occurred, then drop DTR. If you can reproduce the error, send me a copy of the log. After all of this, Maximus will exit back to BinkleyTerm, and all is well for the next call. I have purposefully NOT trapped hardware errors, such as "disk not ready" etc. My reasoning being that such an error SHOULD bring the bbs down. Maximus does not support long file names. 11 Problem Determination Problem: Maximus reports "Can't hack the handle that was passed by the calling process.". Cause: You're not starting BinkleyTerm (BTP.EXE) with the SHARE command line argument, or the '-p' command line arg is not a file handle. Problem: "SYS1804: The system cannot find the file SNSERVER.". Cause: The file SNSERVER.DLL is not in a directory specified in your LIBPATH statment. Check your config.sys LIBPATH statement. Problem: Pmsnoop always reports "Waiting for a snoop server to connect". Cause: Maximus (MAXP.EXE) and Pmsnoop are using a different pipe name. Problem: Pmsnoop always reports "Pipe is busy" Cause: More than one copy of Pmsnoop that is running is using the same pipe name. Each version of pmsnoop should use a unique pipe name. Problem: Pmsoop reports "SYS0110: Error opening named pipe". Cause: You have supplied an incorrect pipe name. Named pipes MUST start with '\pipe\'. To get around this problem, enter (from a command prompt) "pmsnoop \pipe\maxsnoop". Problem: High speed file uploads (>=9600 bps) fail. - 8 - Cause1: You're not using hardware (CTS/DSR) handshaking. Your modem and BinkleyTerm must be configured for this. Cause2: Your computer is too slow. For example, I have been running a bbs on a ps/2 model 60 (10 mhz 286). When supporting two phone lines, I was unable to reliably run if one of the lines was "locked" at 19200 bps. I decided to play it safe and run at 9600, not locked, instead. My users are happy, even if the bbs is slightly slower, since they can now get on twice as often (relative to when I ran the DOS version, with only the one phone line). Cause3: You were in the dos box (or switched through it while hitting ALT-ESC). The jump from protect mode to real mode on a 286 is pretty scary; it involves a reset to the CPU. Loosing interrupts are not uncommon at all. Since the COM port is interrupt driven, you don't want this to happen. Cuase4: You're running Maximus in a "Vio Window". This is not recommended. - 9 - Contents 1 Maximus for OS/2, by Peter Fitzsimmons (1:250/628) . . . . . . . . . . . . . . . . . . 1 2 General Differences . . . . . . . . . . . . . . 1 3 Configuration Differences . . . . . . . . . . . 1 4 Operational Differences . . . . . . . . . . . . 2 5 Multiline Operation . . . . . . . . . . . . . . 3 6 The MAXPIPE program . . . . . . . . . . . . . . 4 7 The MaxRenP program . . . . . . . . . . . . . . 5 8 The PMSNOOP program . . . . . . . . . . . . . . 6 9 REBOOT.EXE and BOOT.SYS . . . . . . . . . . . . 7 10 MISC . . . . . . . . . . . . . . . . . . . . . 7 11 Problem Determination . . . . . . . . . . . . . 8 i