Z-System Corneò (c) by Jay Sage The Computer Journal, Issue 38 Reproduced with permission of author and publisher True, February is a short month, but somehow I don't think that explains� why the beginning of February (the due date for this column) came quicker� than usual. It is probably a good thing that I have convinced several� others to start contributing regular columns to TCJ. That way, Art Carlson� may be busy enough not to notice that the deadline passed without my column. � Because it is late and because we now have quite a few prolific writers� joining the TCJ ranks, I'm going to keep my column shorter than usual this� time (I know I have said that before, but this time I think it really will� be true). For this issue I will be catching up on some correspondence, informing� you of the imminent release of the first high level language for Z-System� programming, bringing you up to date on Z-Node developments (there is a new� Z-Node Central), and beginning a discussion of issues related to bringing up� a remote access system (so that more of you might decide to set up a Z­ Node). Letters Despite our requests for letters with your comments and suggestions, we� don't get very many. Recently, however, Art forwarded to me two lengthy and� thoughtful letters from James Ott. I would like to begin by addressing some� of his comments and questions. The ZCPR33 Programmer's Reference Manual First, Mr. Ott asked about the "Programmer's Reference Manual" to which I� made reference in my ZCPR33 User's Guide. Well, the truth is that after� writing the user's guide, I really didn't have energy left for another major� manual. Instead, I started to release programming notes one at a time as� files on the Z-Nodes. Even at that, I only got to three of them. The files� have names of the form Z33PNOTE.###, where "###" is a sequence number. Note� 001 deals with the command status flag in the message buffer and the� extensions in its use introduced with ZCPR33. Note 002 discusses proper� coding techniques for shells under ZCPR33 and later. The third note covers� the parsing of files by the Z33 and Z34 command processors. I am tempted to� reproduce some of that material here, but then I would surely fail in my� resolve to keep this column to a reasonable length. So you will just have� to look for them at the Z-Node in your neighborhood. If it is not there,� see if the sysop will get a copy from Z-Node #3. Shells and ZEX Š Mr. Ott continued: "The User's Guide mentions an addition to shell coding� necessary to ensure the shell pushes its name onto the shell stack when it� is called by ZEX." I think there is some misunderstanding here. It was� under previous versions of ZCPR3 that special code was required in shells to� deal with ZEX (and it never had to do with pushing anything onto the shell� stack). Under Z33 and later, this code can (and, to make the programs� smaller, should) be removed. It has now been quite some time since the� release of ZCPR33, and I think that most shells are now coded in the more� efficient way. As we have discussed in previous columns, a shell command comes into play� when the command line buffer becomes empty. In that case, if there is a� command on the shell stack, the command processor invokes that command� instead of asking the user for the next command line. In this way, the� shell takes over the function of the command processor. ZEX's function is similar to that of SUBMIT and XSUB together. While� SUBMIT stores its script data in a disk file, ZEX keeps it in memory. This� enables ZEX to run much faster, but it reduces the memory available to� programs. A simple SUBMIT script feeds a series of commands to the command� processor, thus doing under CP/M what the multiple command line of ZCPR� does. SUBMIT can be useful even under ZCPR, however, because it can supply� a longer string of commands than could fit into the command line buffer. XSUB running under SUBMIT allows characters in the script to be fed not� only to the command processor but also to programs as they run. This is� what is called input/output (I/O) redirection. In this case it is input� redirection; the operating system is made to take its characters not from� its normal source -- the keyboard -- but from a disk file (SUBMIT) or a� memory buffer (ZEX). This is both extraordinarily useful and� extraordinarily tricky. Long ago I promised to discuss this subject at� length in this column, but I have never gotten around to it. Bridger� Mitchell, Joe Wright, and I are now engaged in a joint project to perform a� major upgrading of ZEX, and I am sure it will be the subject of TCJ columns� by one or more of us. The ZCPR33 command processor observes the following hierarchy for� acquiring new commands, where step 1 has the highest priority and step 5 the� lowest. The way this hierarchy functions is described in more detail in the� ZCPR33 User's Guide. 1. Commands pending in the multiple command line buffer 2. Commands from a ZEX script 3. Commands from a SUBMIT script 4. A shell command 5. User input Under ZCPR30, ZEX did not appear explicitly in this hierarchy; it came� into play only by virtue of its ability to redirect input at step 5. This� posed a serious problem when a ZEX command was issued under a shell. � Although the user intended the script to be performed as commands, the shell�Šwould take it as input to the shell instead. To avoid this, rather lengthy� code had to be included in every shell to see if ZEX was running and, if so,� to feed its input directly to the multiple command line buffer. This� resulted in completely useless loads of the shell code for each line of the� ZEX script. Execution was so slow and annoying that for all practical� purposes ZEX scripts could not be run under shells. The ZCPR33 command processor was redesigned to deal with ZEX explicitly� just as ZCPR30 always did with SUBMIT. ZEX was placed above SUBMIT in the� hierarchy so that ZEX scripts would function like arbitrarily long command� lines and could be invoked from SUBMIT scripts. The New Libraries Mr. Ott had several questions about the assembly-language libraries that� support the Z-System. I will not comment extensively here, but I would like� to announce that new versions of the libraries, which have been in use by a� number of us for many months already, will soon be made available to the� public. I had expected them to be a commercial product, but, for several� reasons, it now appears that the code will be made available at no charge. � Only the manual, which will be quite a large book, will be sold. This is� good news. One of Mr. Ott's suggestions was that the Z3LIB routine called PRGLOAD,� which is used for chaining from one program to another, be updated to allow� for type-3 programs. This probably could be done without a great deal of� difficulty, but I am not sure that it is worth the trouble. What about� type-4 programs? Loading them is much more complex because of the need to� compute the relocation to a run-time address. It seems to me that a better� way for programs to chain to other programs is via the multiple command line� buffer. If anyone can suggest any advantages of a direct load, I would be� interested in hearing them. The Command Line Tail One of the mistakes in ZCPR30 was its failure to check for command line� tails that would not fit in the buffer from 80H to FFH. CP/M had no problem� with this because the whole command line was not long enough to allow this� to occur. With a 200-or-more-character command line buffer, there is� nothing to stop a user from entering a command with a tail longer than 128� bytes. Under Z30 this caused a catastrophe, because the tail was copied� into the buffer after the program was loaded, and then the tail could� overwrite the beginning of the code. Z33 and later monitor the length of� the tail and stop copying before this can happen. With type-3 programs that load at addresses higher than 100H, longer� tails could be copied without damaging the code, and Mr. Ott requested that� this be implemented in future versions of the command processor. I think� this would be a very bad idea. One of the reasons for using type-3 programs� is so that any code residing at 100H can be run again later using the GO�Šcommand. If the type-3 program's tail overwrote the TPA, then trouble would� occur when the GO command was executed. Moreover, there is absolutely no need for such a feature. If a program� wants to support a tail longer than 126 bytes (it doesn't even have to be a� type-3 program), it can simply read its arguments not from the buffer at 80H� but directly from the multiple command line buffer. As an aside, I have� thought of making the command processor not convert the command line buffer� to upper case. Then programs could process lower case input directly (as in� MS-DOS) without the special symbols to indicate case shifts as in the ECHO� and IF INPUT commands. The command tail buffer at 80H must be converted to� upper case for compatibility with CP/M programs, which assume that that will� be done. Besides the fact that there might be a significant code penalty� (the command tail buffer and the command file control block would both have� to be individually case shifted), I worry that there may be a number of Z­ System programs that either rely on the command line being in upper case or,� worse, convert it to upper case. I'd be interested in hearing any opinions� on this topic. Still More on Z3 vs. Z2 Shells Mr. Ott sent me a lengthy letter with some interesting examples of the� use of the shell stack. I think his is the first response I have received� that pointed out an aspect of the shell stack that I had not previously� appreciated. I don't think about shell command lines with more than one command, so� the following distinction never occurred to me. One can think of the shell� stack as containing not just, say, four commands but rather four groups of� commands. The shell stack not only holds these commands; it also provides� the mechanism for grouping them, for providing parentheses, if you will. � The Z2 approach to shelling would have a very hard time doing this. For� example, if the first element on the shell stack contains the command line� "CMD1A;CMD1B" and the next lower element the line "CMD2A;CMD2B;CMD2C", the� equivalent Z2 situation would have the command line CMD1A;CMD1B;CMD2A;CMD2B;CMD2C The SHCTRL POP command removes an entire Z3 shell entry, containing� possible multiple commands. How could we implement this function with a� Z2-style shell? Even if each command were marked with a "/s" token, one� could still not tell which ones were grouped with which. There might be a� solution to this problem, but the Z3 shell approach certainly handles it� nicely. Mr. Ott's letter included a very interesting application example. I've� made a few changes that, I hope, do not harm its essence. When the computer� is booted, the STARTUP alias loads the command sequence "FIRSTSH;MENU",� where FIRSTSH is a special utility that places the following command� sequence onto the shell stack: Š PARK;VID RST.MSG;STOP When this sequence runs, it will park the heads on the disk drive, display a� message to shut off the computer, and run a program called STOP that locks� the machine. Of course, this multiple-command shell could easily be� replaced by an alias SHUTDOWN. This termination shell does not run immediately because of the command� MENU following it in the command sequence. This loads a second shell onto� the shell stack. The user then lives inside the MENU shell for some time. � At some point, the user may make a selection that generates the command "CD� WORK:". This would log into the WORK: directory and issue an automatic ST� command there. The ST alias might have the script LDR WORK.NDR;SHCTRL POP;ZFILER This would install a new set of named directories, pop MENU off the shell� stack, and replace it with the ZFILER shell. The user could then do some� work using ZFILER. From ZFILER, a macro command might make another shell� change by popping the shell stack and installing another shell. The above process would continue until the user made an exit selection. � This would pop the shell stack without installing a new shell. As a result,� that first line we put on the shell stack would become active, forcing the� computer to be shut down in an orderly, preplanned way. Of course, this� approach is not totally foolproof if the user has access to the power switch� or power cord. But it certainly helps. Mr. Ott worried that this example could not be achieved using a Z2 shell� system. I think it could, though not with quite the same ease and elegance. � The STARTUP alias would contain the line MENU;SHUTDOWN When MENU ran, it would substitute for itself in the command line the� desired command line plus its own reinvocation command with the flag "/S" to� mark it as a shell. Thus the command line would become USERCMD;MENU /S;SHUTDOWN For the user command CD WORK:, the command buffer would evolve as follows: CD WORK:;MENU /S;SHUTDOWN ST;MENU /S;SHUTDOWN LDR WORK.NDR;SHCTRL POP;ZFILER;MENU /S;SHUTDOWN When the SHCTRL command ran, it would scan the command line for the next� shell command as marked by the "/S" flag and remove it from the command� line. This would leave one with ZFILER;SHUTDOWN ŠWhen ZFILER generates a macro command, the command buffer would have MACROCMD;ZFILER /S;SHUTDOWN This would continue until one cancelled the shell. Then the SHUTDOWN alias� would run. Mr. Ott was concerned that the command line would grow longer and longer� as old shell commands piled up. Indeed, this would happen if there were no� 'popping' mechanism. The "/S" marker I proposed in my previous columns is� critical here, since without it there would be no way to tell which command� to pop. This approach, I think, would fail with aliases as shell commands. � The Z3-type shell really helps us in this case. High-Level-Language Support for Z-System I have some especially exciting news about the first high level language� specially designed for Z-System. In late January, I got a phone call from� Leor Zolman, author of BDS C. He was interested in bringing out a new� version of his C compiler for the modern 8-bit market. After some� consultation with me on what was needed to support Z-System, Leor went to� work on the run-time code, and in less than two weeks he had a version ready� for beta testing He came over to my house to demonstrate the result, and I was amazed to� see how easily one could write a utility, complete with named-directory� support, even including password protection. A little fine-tuning is still� needed, but I am already excited about the impact that the availability of� this quality high level language will have on Z-System development. � Marketing details have not been worked out at this point, but you can expect� the new BDS C to be available at an attractive price through Z Systems� Associates (ZSA) channels (Plu*Perfect Systems, Sage Microsystems East, Z­ Nodes, and Z-Plan user groups). The New Z-Node Central Ron Bardarson, who had operated Z-Node Central after David McCord retired� as the sysop, decided to change the focus of his system and his node� designation from Z-Node to X-Node. This was to indicate its experimental� nature and its focus on software and systems development rather than on the� distribution of Z-System software. Its number remains 408-432-0821 (CASJO� on PC-Pursuit). To maintain a center of support for Z-System users and for Z-Node sysops,� we have established a new Z-Node Central. Richard Jacobson, whose Lillipute� Z-Node in Chicago has long been, in my opinion, the premier Z-Node in the� country, has agreed to take on this new role. He will continue to use the� delightfully ironic Gulliverian name (at over 100 Mbytes, his is the least� Lilliputian of the Z-Nodes), but his node number now drops from 15 to 1. Š This new function is added to several special services that Lillipute� already provides. It is the official bulletin board and remote access� system for both the North American One Eighty Group (NAOG) and TCJ. The� full system, comprising two independent computers, is available on a� subscription basis. All users who provide registration information will get� 15 minutes per day of free access. Unlimited access to both computers� (within reason) is available at a rate of $25 for six months or $40 for a� full year. TCJ subscribers and NAOG members get free access to limited� areas and can upgrade to full subscriber privileges at $5 less than the� standard rates. Z-Node sysops will have free access to the full system. � The phone numbers are 312-649-1730 and 312-664-1730, accessible via the� ILCHI outdial of PC-Pursuit. System Security Under Z-System As part of my plan to build up the network of Z-Nodes, I would like to� begin a series on issues related to setting up a remote access system (RAS)� using Z-System. Many people do not realize it, but NZCOM and Z3PLUS (the� automatic Z-Systems for CP/M-2 and CP/M-Plus, respectively) create systems� with the full security capability necessary for a RAS. It just takes a few� simple operations to engage it. These issues have been brought to my attention recently because I have� been in the process of setting up a second remote access system at my house. � This one is for the BOSKUG group of the Boston Computer Society. It will be� a two-line system running on a very powerful 16 MHz Kaypro 286 computer with� multitasking software. For all this power, however, I was struck by the� tremendous complexity of setting up a remote system on such a computer, all� because of the lack of a secure operating system. With MS-DOS, a remote system absolutely cannot allow a caller to gain� direct access to the operating system command prompt, because once he has� that access, there is no way to limit what he can do. It made me realize� how fortunate we are with Z-System to have an operating system with enough� security to permit callers on a remote system to run the system more or less� as if they were sitting at the keyboard of their personal machine. They� don't have to have an elaborate apparatus standing between them and the� system. There are two main aspects of that security. One is the wheel byte. � This system flag is tested by many Z-System programs to determine whether� certain operations should be permitted or denied. Commands for doing things� like erasing, renaming, or copying files typically require that wheel status� be in force. Other commands will allow some operations to non-wheel users� but deny other operations. For example, some directory programs allow� writing an image of the directory to disk or to the printer. These options� are (or should be) restricted to 'wheel' users. The wheel byte itself is� set and cleared by special commands, such as the WHL command of the RCP. � Obviously, a password must be entered correctly before WHL will set the� wheel byte. Š The second and more complex security feature in Z-System concerns the� facilities for limiting the disk areas which a user can access. Many users� are unaware of these features, and even those who are aware of them often do� not understand them fully and clearly. I will cover the major points here. With version 3.3 of ZCPR, I introduced extensive and significant changes� in the way directory references and security are handled. These changes� made understanding security more complex for the system implementor but much� easier and less intrusive for the user. ZCPR3 supports two basic forms of directory reference, the disk/user or� DU form and the named directory or DIR form. We will assume that the reader� is already somewhat familiar with the basic concepts. The DU form is native� to CP/M, which knows about disk drives from 'A' to 'P' and user numbers from� 0 to 31 (though there are restrictions on user numbers above 15). The DU� form of directory reference is basically physical in nature. Drive letters� are associated with real physical devices, and the files in all user areas� associated with a given drive letter are stored on the same physical device. � One can think of this directory structure as spanning a flat, two­ dimensional space (in contrast to the hierarchical tree-structured� directories of Unix or MS-DOS). While the DU directories are basically physical, named directories are� purely logical constructs. The named directory register (NDR) module in a� Z-System contains a mapping of directory names to drive/user values. The� user can load different sets of directory associations at different times. � Thus, unlike the static (fixed in time) directory structure of Unix and MS­ DOS, the directory structure of Z-System can be dynamic (changing in time). When the DIR form is used, the command processor or a Z-System program� looks for the name in the NDR and substitutes the drive and user values. � Only drive/user values are used in the actual file references processed by� the disk operating system (DOS). Named directories provide two different� and important functions. One is convenience. It is much easier to remember� that one's assembly language tools are in ASM and one's wordprocessing files� in TEXT than it is to remember that the directories are A7 and B13. The� second purpose of named directories is to provide security. Access to directory areas in a Z-System is controlled in both the DU and� DIR domains. Under Z30 these two control mechanisms were completely� independent; under Z33 and later, as we shall see, they are very closely� coupled. The limits in the DU domain are set by values in the environment� descriptor (ENV) called max-drive and max-user. They define a rectangular� area of allowed directories in the flat directory space, with drive values� ranging from 'A' to the drive specified by max-drive and user numbers� ranging from 0 to the number specified by max-user. The smallest space� still includes the boot directory A0. Named directories offer a more flexible means of controlling access to� areas on a system. The user can access a named directory even if it refers� to a DU area that is beyond the bounds defined above. Each directory name� can have an optional password associated with it. Whenever a reference is�Šmade to such a directory, the password is (should be) asked for and access� granted only if it is entered correctly. There are a number of important exceptions to the two security limits� described above. One concerns the command search path specified in the Z­ System PATH module. No restrictions whatever are imposed on the DU areas� specified there. If the user was able to place a directory into the path,� then it will always be scanned as necessary by the command processor, even� if it would no longer be explicitly accessible. Another general exception occurs for the standard (but optional)� configuration of the command processor called WPASS. With this option, when� the wheel byte is set, directory passwords are ignored. The user can then� freely make reference to any directories either within the specified DU� range or associated with a named directory (with or without a password). Versions of the command processor since Z33 also make the assumption that� if a user is in a given directory at the present time he must have had the� authority to get there. Therefore, the command processor will always accept� any reference to the currently logged directory, even if the DU is out of� range and it has no unprotected directory name. Another set of exceptions relates to the interplay of the DU and DIR� limits. Recent versions of the command process act on the principle that if� reference to a directory in one form (DU or DIR) would be allowed then� references using the alternative form should be equally allowed. For� example, suppose that the max DU limit is set to B3 and that directory C4� has the name DIRNAME with no password. Z30 would have refused to accept a� reference to C4:, even though it would have no complaints about DIRNAME:. � Under Z34, either would work. Conversely, if directory area A3 in the� example had a directory name PRIVATE with password SECRET, Z30 would allow a� reference to A3: but would insist on correct password entry if the reference� was made as PRIVATE:. Again, Z34 always checks the alternate form of� reference, and if either meets the security restrictions, then both are� accepted. The standard version of Z-System created by NZCOM or Z3PLUS has the max� DU limit set to P31. Thus all directories are allowed using the DU format. � As a result, even when named directories with passwords are created, they� are accepted freely. In order to create a secure system, the values of max­ drive and max-user must be reduced. Also, since password checking is� bypassed when the wheel byte is set, the wheel byte must be cleared before� the security limits imposed by directory passwords will take effect. Once� those two changes have been made, your NZCOM/Z3PLUS system is ready to serve� as a remote access system. [This article was originally published in issue 38 of The Computer Journal, P.O. Box 12, South Plainfield, NJ 07080-0012 and is reproduced with the permission of the author and the publisher. Further reproduction for non- commercial purposes is authorized. This copyright notice must be retained. (c) Copyright 1989, 1991 Socrates Press and respective authors]