.no justify .no autojustify .subtitle .autosubtitle .ap .paragraph 0 .number 1 .page size 53,60 .lm 1 .rm 60 .c; .b5 .c;MEMO .b .c;File Auxiliary Data Utility .b .c;14-July-1991 .b6 .C;Version 1.0 .b .c;Jack Harvey .b .c;(617)890-1838 .b2 .note ABSTRACT MEMO is a utility program that permits convenient access to the Application ACE. It may be used to attach auxiliary information to any VMS/RMS file without altering the data content of the file. .end note .display number rl .page .c; .b12 .c;____________________________________________________________________________________________________ .b2 .c;Digital Equipment Computer Users Society (DECUS) .b .note This program may be freely distributed or modified by any party, including but not limited to DECUS and anyone within DECUS. .b .c;USE AT YOUR OWN RISK .b DECUS, DECUServe and the author make NO warranties whatsoever, including without limitation, all implied warranties of merchantability and fitness. .end note .b .c;____________________________________________________________________________________________________ .page .if tabcon .require "memo.rnt" .endif tabcon .page .c;Acknowledgements .f This is a DECUServe program through and through. The original application for MEMO was seen by the author on DECUServe long before the idea of MEMO was born. Various alternatives were experimented with on DECUServe. Then Terry Kennedy posted a topic in the DECUServe VMS conference asking for opinions on a new version of Kermit that would have the capability to retain VMS file header data. He raised the question of the Application ACE. "Should Kermit retain that also?" [Hear bell clanging lustily.] Could any software be more born of DECUS? A need found on DECUServe is answered by an unrelated question from a DECUS volunteer working on another DECUS software project....on a DECUS service devoted to communication about such problems. Much credit goes to the members of the DECUServe Executive Committee: Pierre Hahn, Jeff Killeen, Sharon Johnson, Terry Kennedy, Chris Rhode, Buck Trayser, Dale Coy and Fred Lobmeyer. They create an environment where doing things like MEMO is fun. As much credit is due also to DECUS, and the hundreds of volunteers that lend it blood. They have made this kind of interaction between people with common needs (and perhaps competing objectives) a daily miracle. Without that, the high-tech inter-human communication which is DECUServe would be useless. .b2 .c; Jack Harvey July, 1991 .page .number 1 .display number d .f .hl1 introduction MEMO stores a small amount of your data in the Access Control List (ACL) of a VMS ODS-2 disk file. It allows attaching (pasting on, so to speak) additional information about the file, or the environment of the file, without disrupting the normal file data or structure. The file may be any VMS/RMS supported type. For example, the auxiliary data might declare something special about the file: "This file used for acceptance testing of PAYROLL II at Acme Bootstraps, on 3-Jan-91". Or, "Received from Paris office, 3/9/91". Data may be stored as ASCII strings as in these examples, or in binary expressed as decimal or hexadecimal values. Data can be in multi-field mixtures of these. MEMO uses a supported feature of VMS Access Control Lists, storing the data in an Access Control Entry, or ACE. It employs the "application" ACE, which is general purpose and not related to file access control. MEMO is not privileged and uses normal VMS system services. Since the auxiliary data is a physical part of the file header, it stays with the file when relocated in a VMS system. If a new version of the file is created in the same directory, the stored data is propagated to the new version. This is a consequence of the data being stored as an ACE in the ACL for the file. The data has the same security protection as the file itself. Data stored by MEMO is about as safe as the host file. For example, the DCL command SET ACL/DELETE which deletes all normal file protection ACEs on the file, does not affect a MEMO ACE, since it is normally created with the protected attribute. (MEMO itself, however, can easily delete the stored data ACE.) Transmission of the file through any medium (ANSI tape, most Kermits, non-VMS operating systems) that don't carry the Access Control List along will lose the data. COPY, RENAME and BACKUP preserve it, however. The program is designed to be executed from within a DCL command file by a foreign command and the control information is always passed as part of the foreign command. Other control information may be passed as DCL symbols and the data stored in the ACE is returned to the user as a DCL symbol. .hl1 Control The user (or calling command file) defines a foreign command to communicate with MEMO. A simple command file to store some information in one's login.com file header could be: .literal $ MEMO := $SYS$LOGIN:MEMO !Make a foreign command $ DATE = F$TIME() !Get current date/time $ MEMO PUT5AS SYS$LOGIN:LOGIN.COM LOGTIME 0 20 DATE .end literal The last line in the example above passes six operands to MEMO: .list .le;PUT5AS - MEMO's instruction. PUT means store data. The digit 5 means five more operands follow the instruction. The letter A means the data is transferred in ASCII format. The final S of the instruction means the transfer is by symbol. That is, the name of a DCL symbol (DATE) is passed. The symbol contains the actual ASCII data. .le;The first following operand is the file specification. .le;LOGTIME is the name for this particular ACE. .le;The value 0 is the offset from the start of the ACE where the data is to be stored. In this case, it is stored at the first position. .le;The value 20 is the length of the stored data in bytes. .le;DATE is of course the DCL symbol defined in the previous line and contains the date/time text string. .end list When MEMO executes to return ACE stored data, it defines a DCL symbol with data from the header as the equivalence string of the symbol. For example, to retrieve the text string stored by the example above: .literal $ MEMO GET5AS SYS$LOGIN:LOGIN.COM LOGTIME 0 20 RETRIEVED_DATE .end literal Now the local DCL symbol RETRIEVED__DATE will contain the previously stored string. .page .hl1 memo Instructions There are two basic instructions having the general form: .b .c;GETnxy and PUTnxy where: .list "o" .le;"n" is a decimal digit indicating the number of following operands. .le;"x" is a letter indicating the data transfer radix or format. .list "-" .le;A = ASCII character string. .le;D = signed integer decimal number. .le;H or X = hexadecimal number. .end list .le;"y" is the transfer mode indicator. "L" means Literal. The operand is the actual data. "S" means Symbolic. The operand is the name of a DCL symbol with the actual data. For the GETnxy instruction, the mode is always S. .end list .hl2 Long Form instructions GET5xS filespec name offset length symbol PUT5xy filespec name offset length value/symbol .list .le;filespec - A standard RMS file specification for the file whose ACL will contain the data. A logical name pointing to the file may also be used. .le;name - one to eight character name identifying the ACE within the ACL of the file. If it is shorter than eight characters, it is padded with spaces. .le;offset - a decimal number literal indicating the number of bytes from the start of the data in the ACE. If this operand is not a decimal literal, it is assumed to be the name of a DCL string or numeric symbol containing the offset value. .le;length - the number of bytes of data stored at the offset. The total of offset + length cannot exceed 200. The offset operand can also be a DCL symbol containing the value. .le;The final operand is always a DCL symbol for the GET instruction. The symbol is set to the character string representing the value in the radix or format indicated by "x". For the PUT instruction, the final operand is either the literal to be stored, or the name of a DCL symbol containing the literal. .end list .hl 2 Short Form Instructions The filespec and name are passed by DCL symbols. The short form instructions are useful when a number of fields are accessed in a single file and ACE. The symbols are defined by the long form instructions. A single long form instruction (GET5.. or PUT5..) can be used for the first access. Following this, short form instructions can be used. (The symbols may be explicitly defined, if desired, and only short form instructions used.) .literal GET3XS offset(bytes) length(bytes) symbol GET3DS offset(bytes) length(bytes) symbol GET3AS offset(bytes) length(bytes) symbol PUT3XL offset(bytes) length(bytes) newvalue (hex) PUT3DL offset(bytes) length(bytes) newvalue (dec) PUT3AL offset(bytes) length(bytes) newvalue (dec) PUT3XS offset(bytes) length(bytes) symbol PUT3DS offset(bytes) length(bytes) symbol PUT3AS offset(bytes) length(bytes) symbol .end literal .hl1 Auxiliary symbols There are three symbols whose use is optional. They are intended to extend the flexibility of MEMO. Nearly anything that can be done with MEMO can be done without resorting to these. However, the user should know of their availability and use them when they will help solve problems. .hl2 MEMO__STORAGE__FILE The long form instructions have an operand which defines the file whose ACL will get, or has the storage ACE. When these instructions execute, they define this as a local symbol. The short form instructions require that this symbol be defined, either by a previous execution of MEMO with a long form instruction, or by a symbol definition or assignment statement. The symbol value is a string that is a suitable file specification to select the target file for the ACE. The value may also be a logical name that translates to the target file specification. .hl2 MEMO__STORAGE__NAME The ACE is identified by a one to eight byte string which will uniquely identify it in the access control list. If the string is shorter than eight bytes, it is extended with ASCII space characters. This default is chosen because in most uses, it will be a name meaningful to the application. However, the name is not restricted to ASCII characters. It could be any bit pattern that can be passed as a DCL symbol. The MEMO__STORAGE__NAME symbol is defined by long form instructions. The user may avoid use of long form instructions, however, by defining the symbol in the command file prior to executing MEMO. .hl2 MEMO__STORAGE__PROTECTED One of the options available for ACEs is to protect them from accidental deletion by the SET ACL/DELETE DCL command. Normally, this deletes all ACEs on the ACL, effectively deleting the list itself. However, if the ACE$V__PROTECTED bit is set in an ACE structure, the DCL command fails to delete it. This protection bit is the default for the MEMO ACE. In order to delete the MEMO ACE by a DCL command, the user must type in correctly, the entire ACE data structure including the name and all stored data, in hexadecimal. This is not likely to happen by accident. If this behavior is not wanted, the user can alter it by defining the symbol: $ MEMO__STORAGE__PROTECTED = "FALSE" This symbol is always evaluated before creating or modifying an ACE. If it doesn't exist, the default protection is taken. If it exists, the new or altered ACE will not be protected if it evaluates to "FALSE". Any other value is treated as "TRUE" and protection is applied. .hl1 Limits or Restrictions .hl2 Maximum Storage A single application ACE could potentially contain up to 251 bytes of user or application data. However, this implementation limits the data to 200 bytes. This allows the first file header block to contain several mapping pointers, as well as several normal access control entries, without overflowing into additional file header blocks. However, there is no practical limit to the number of application ACEs that MEMO can store in a file header, so that overflow of the first block into extension blocks is certainly possible. The individual MEMO ACE must have a unique bit pattern in the name supplied as the second operand of the long form instruction. Since this is a 64 bit field, we need not be immediately concerned with this limit. This is not free storage under VMS disk quotas since quota accounting includes the file header block (and any extension blocks) in the disk usage count. However, the user should be aware that the normal VMS DIR/SIZE command does ^¬\& count the header block and its extensions. If you make excessive use of MEMO storage, your actual and DIR/SIZE reported disk usage will differ significantly. .hl2 Length _of Transfers For the currently implemented instructions, the length operand of the instruction determines the length of data transferred to or from the ACE. The length of the data supplied to a PUT instruction may differ, however, and this does not cause a warning message. This section defines the behavior to expect when this occurs. .hl3 PUT ASCII Data If the supplied data is longer than the length operand, it is truncated. If the supplied data is shorter, it is padded with ASCII spaces. .hl3 PUT Decimal Data The signed decimal integer is converted to a longword (4 bytes) and then the number of bytes indicated by the length operand, starting with the least significant is transferred to the ACE. Length must be 1, 2 or 4. .hl3 PUT Hexadecimal Data The length operand is the number of bytes transferred to the ACE. Two hex digits form one binary byte. If the data is longer, it is truncated at the high address or most significant end. If the data is shorter, it is padded with binary zero or null bytes at the high end. .hl3 GET ASCII Data The returned data symbol is set to the ACE bytes referenced by the offset and length operands regardless of their content. That is, no attempt is made to convert the data bytes to displayable ASCII. .hl3 GET Decimal Data Decimal mode requires that the length operand is 1, 2 or 4 bytes. A length of 3 or longer than 4 cause an error return. .hl3 GET Hexadecimal Data The returned string is twice as long as the length operand with a maximum of 254 hex digits. Therefore the maximum length for this mode is 127 bytes. .hl1 Notes .hl2 ACE Type _and Identification. Access Control List Entries (ACEs) are usually thought of as security items related to access of a file. They can also be applied to access to devices, queues, global sections and logical name tables. In addition to the familiar identifier ACE, there are alarm, default protection and application dependent ACEs. The ACE is a defined data structure in the Access Control List of the object, or in this case the target file. Along with the type defining bits and values in this structure, each ACE has other identification making it unique within the ACL. In the case of this application dependent ACE, it is defined by the MEMO software to be an eight byte field starting with the application mask longword plus the next four bytes in the structure. This ACE, in addition to being of type ACE$C__INFO, is implemented as a customer application, ACE$C__CUST. In this implementation, it is also restricted to file objects. See $FORMAT__ACL in VMS System Services Reference Manual for details. .hl2 Storing General Binary Data Any binary pattern of any length up to 200 bytes can be stored using the hexadecimal transfer mode. (Multiple transfers may be required due to symbol length limits.) The hex mode is provided so that general binary data can be conveniently represented in command file text. However, the ASCII transfer mode is also binary transparent. There is a difficulty if trying to transfer general binary data in literal form to a PUT instruction. The foreign command processing will parse the literal, and binary bytes representing tabs or multiple spaces will be altered. In addition, the MEMO input processing of the literal expects it to conform to conventional foreign command form and the first byte representing a space terminates the literal. This difficulty may be overcome by passing the binary data as a DCL symbol instead of a literal. Thus for some uses, the ASCII transfer mode via a symbol may be more convenient to use than the hexadecimal mode. It should be noted, however, that ASCII mode transfers bytes starting with the ^&left\& end of the string. Hexadecimal is treated as a number and the transfer begins with the right end of the hex string. .hl2 Accessing Uninitialized Data _and ACEs If a GET is made to a field in which data was not stored, it is returned as though binary zero null bytes had been stored. This is also true if the entire ACE had not been previously defined. Hence, the entire range of possible ACE names may be accessed without being defined. The user is responsible for insuring that meaningful data has been stored. .hl2 Clearing Fields _and Deleting _an ACE No specific CLEAR instruction is provided. However, the hexadecimal transfer PUT extends the supplied data with null (binary zero) bytes up to the value specified by the length operand. For example the short form instruction: $ MEMO PUT3XL 120 30 00 will clear a 30 byte field starting at position 121 (offset 120) in the current file and ACE. Note also that the instruction: MEMO PUT3XL 0 200 00 !no offset, length=maximum, data = 0 will clear the entire current ACE. MEMO detects this condition on a PUT and deletes the ACE when it occurs, thereby compacting the Access Control List for the file. This behavior matches the behavior of MEMO when a GET is issued for an undefined ACE: a null string of the appropriate format is returned. .hl2 Citizenship Is MEMO a good citizen under VMS/RMS? Does it conform to good practices? Yes, if used with discretion as discussed below. .hl3 Safety Since the application ACE is fairly unfamiliar, it seems a bit bizarre for a user to be able to arbitrarily store data in the header structure of any VMS file. However any ACE created by MEMO can also be created by the DCL command SET ACL. In fact the first implementation of the MEMO function by the author was entirely in DCL. (Although possible, it was extremely cumbersome and slow, leading to the MEMO program.) There is no bypass of file security. All actual alterations to the file header are strictly under the control of VMS/RMS via documented system services. Yet the VMS community seems to have made little use of this feature. It is possible that MEMO may uncover bugs in the system services. .hl3 Storage Efficiency Is this really a good way to store a small amount of data? If one examines the headers of most files, there is almost always a hundred or so free bytes. If the MEMO ACE added to such a file fits in the free space then it is indeed "free" storage - no additional disk blocks are used. Even if the ACE causes the header to overflow and be extended a block, it is still a win, because to store the data in a separate file requires a minimum of two blocks (header block and data block) and on some large disks as much as four blocks minimum. However, if thousands of bytes of data were stored via the application ACE in one file, it would be inefficient in both disk use and CPU time because of the high structure overhead in each header extension block and in each ACE. In terms of a few hundred bytes or less, the application ACE is probably a good choice. .page .hl2 Examining _the MEMO ACE As an aid to understanding how MEMO is creating the ACE, it is desirable to have an independent way to examine its data structure. This is also very important when debugging an application of MEMO. The complex operations that are possible can lead to unexpected results. By examining where and how PUT commands are placing the data, unexpected results can be understood. VMS provides several ways to examine the actual ACE attached to the target file. Since the application ACE is largely user defined (with sufficient VMS defined flags to insure it isn't confused with protection ACEs), VMS can only display the user data in a very limited way. Four are discussed below. .hl3 Using SHOW ACL _filename This DCL command provides a very simplified display of an application ACE that has been attached to a file. Here is an example of a MEMO created ACE as shown by SHOW ACL. Only part of the full display is shown here. .literal (APPLICATION,SIZE=%D210,FLAGS=%X0201, ACCESS=%X55434544,DATA=%X31762053, %X30302020,%X20203030,%X76543210,%XFEDCBA98, %X00000000,%X00000000,%X49435341,%X494C2D49,....) .end literal Note that the ACE is identified as an APPLICATION. The next word shows the total size in bytes of the ACE, 210. (This size includes the 12 byte header prior to the MEMO stored data.) FLAGS identifies this as a customer ACE and that it is protected. ACCESS is the first four characters of the ACE name. DATA is arbitrarily considered the start of the user application data. For MEMO, this is used as an extension of the name. Following DATA is the actual MEMO stored user data in hexadecimal. The order of the data bytes in the longwords is VAX normal: least significant, lower address is at the right end. However, the longwords are presented left to right for increasing address. This is very confusing unless clearly understood. An advantage of the SHOW ACL display is that it clearly delineates individual ACEs if the Access Control List has more than one. Disadvantages are the confusing data sequence described in the preceding paragraph, and that SHOW ACL apparently (as of VMS V5.4) has a bug that results in trailing garbage being displayed for ACEs longer than about 144 bytes total, including header. .hl3 Using DIR/FULL _filename The full Directory information display includes all ACEs in the ACL of the file. The trailing garbage problem of SHOW ACL is absent, at least for VMS V5.4. .hl3 Using DUMP/HEADER _filename The VMS DUMP utility can also display Access Control Lists by means of the /HEADER option. To cause the dump to cease after completing the header, use the block count option. The following is an example: $ DUMP/HEADER/BLOCK=COUNT=0 filename Long application ACEs displayed this way by DUMP have trailing garbage similar to SHOW ACL. .hl3 Using DUMP/HEADER/NOFORMAT _filename The VMS DUMP utility also provides an excellent alternate way to see the data structure: $ DUMP/HEADER/NOFORMAT/BLOCK=COUNT=0 filename will show the header block only, unformatted. This should be done using a small file that will not have extension header blocks, and preferably with a single ACE. This option has a considerable advantage in that the format of the display is that of DUMP for normal file dumps. If the user is familiar with reading the hexadecimal side of the output of DUMP, understanding the ACE should be easy. (If the reader only ever looks at the ASCII side, some study is in order.) .page The following is part of the DUMP output for MEMO.EXE with the same ACE displayed by SHOW ACL above. .literal File Header 20202020 2032343B 4558452E 4F4D454D MEMO.EXE;42 000050 50E00094 B6645939 76600022 20202020 "..v9Yd....P 000060 3DC00000 00000000 00000094 B6C1A75B [..............= 000070 20202020 20202020 20200094 B696EEE0 ...... 000080 20202020 20202020 20202020 20202020 000090 20202020 20202020 20202020 20202020 0000A0 20202020 20202020 20202020 20202020 0000B0 00000000 6B13460B 20202020 20202020 .F.k.... 0000C0 00000000 00000000 00000000 00000000 ................ 0000D0 00000000 00000000 00000000 00000000 ................ 0000E0 00000000 00000000 00000000 00000000 ................ 0000F0 00000000 00000000 00000000 00000000 ................ 000100 00000000 00000000 00000000 00000000 ................ 000110 020107D2 00000000 00000000 00000000 ................ 000120 20203030 30302020 31762053 55434544 DECUS v1 0000 000130 00000000 00000000 FEDCBA98 76543210 .2Tv............ 000140 2020204C 41524554 494C2D49 49435341 ASCII-LITERAL 000150 00000000 00000000 00000000 00000000 ................ 000160 72657474 65622061 20736920 73696854 This is a better 000170 53412065 726F7473 206F7420 79617720 way to store AS 000180 73756163 6562202C 74786574 20494943 CII text, becaus 000190 72657020 6C6F626D 79732065 68742065 e the symbol per 0001A0 20646E61 20736563 61707320 7374696D mits spaces and 0001B0 756C636E 69206562 206F7420 73626174 tabs to be inclu 0001C0 00000000 3ADE68B1 00000000 2E646564 ded......h.:.... 0001D0 00000000 00000000 00000000 00000000 ................ 0001E0 81F5FF00 00000000 00000000 00000000 ................ 0001F0 .end literal The first part of this dump is the actual header data and mapping pointers. The ACE starts with a byte containing D2 at address 12C. This byte is the total length of the ACE, or 210 in this case. The ACE ends with FF00 in the last line, just before the header checksum word containing (in this case) 81F5. For single file header blocks without extensions, VMS compacts the ACEs at the end of the block. Note that there is free space from address CC to 12B, or 96 bytes for mapping pointers or other ACEs. .page .hl2 Example Command File The following is the command file that produced the ACE shown in the SHOW ACL and DUMP displays seen above: .literal $ !demonstration to produce ACE shown in dump example. $ memo_storage_file := MEMO.EXE !Let MEMO scribble on itself! $ memo_storage_name = "DECUS v1" !ACE name - easy to find. $ memo = "$''f$environment("default")memo" !make foreign command. $ memo put3xl 0 200 00 !Delete a previous ACE. $ memo put3xl 197 1 FF !Create ACE of 198 bytes. $ memo put3xl 0 8 2020303030302020!Put hex text at start of ACE. $ memo put3xl 8 8 FEDCBA9876543210!Large hex numeric. $ memo put3al 24 16 ascii-literal !Will become uppercase. $ text = "This is a better way to store ASCII text, " $ text = text + "because the symbol permits spaces and tabs" $ text = text + " to be included." $ length = f$length(text) $ memo put3as 56 length text !Insert the longer message. $ memo put3di 160 4 987654321 !Decimal longword example. $ exit .end literal .page .hl1 Error Messages Since control information is sometimes passed to MEMO as DCL symbols, errors can be in the symbol equivalent string as well. Error messages from MEMO usually do not distinguish. MEMO specific errors are generally command syntax or expected symbols not defined. In addition to the MEMO specific errors discussed below, various standard VMS/RMS errors messages, such as "%RMS-E-FNF, file not found", are returned where applicable. .hl2 BADCHR Invalid character in decimal number. This is reported for offset or length operands, and also for the value operand of a decimal PUT. .hl2 BADDEC Invalid length for decimal value. Decimal value transfers via PUT or GET are restricted to 1, 2 or 4 bytes in the length operand. .hl2 BADMODE Transfer mode must be Symbol on GET. The final letter of the GET instruction must be S for transfer via Symbol. .hl2 BADTYPE Invalid data radix or format. This must be one of: A, D, H or X, following the number of operands digit in the instruction. .hl2 BIGSYM Hexadecimal data too large for symbol. Hex data is returned as two ASCII characters per byte of length. This can exceed the maximum size DCL symbol that can be defined by MEMO. .hl2 FILE MEMO__STORAGE__FILE symbol not defined. This occurs if a three operand instruction has been executed without being preceded by a five operand instruction or a DCL definition of the symbol. .hl2 NAME MEMO__STORAGE__NAME incorrectly defined. This occurs if the name is longer than eight bytes, or the symbol is not defined for a three operand instruction. .hl2 INVCMD Invalid command. An instruction starting with something besides GET or PUT was found. .hl2 NGMODE Transfer mode not Literal or Symbol. The instruction does not end with the letter "L" or "S". .hl2 NOCMD No foreign command line found. MEMO has been executed with no operands. This can also be caused by: RUN MEMO .... .hl2 NODATA Command line data operand missing. A symbol is required for GET and a symbol or literal value is required for PUt. .hl2 NOTHEX Invalid hexadecimal character found. The instruction is a hexadecimal radix PUT and a character other than 0-9 or A-F was found in the value to transfer. If the transfer mode is Symbolic rather than Literal, the error is in the equivalence string. .hl2 OFFSYM Symbol for offset or length not found. The operand for offset or length is not a decimal literal and could be a DCL symbol, but it is not defined. This may be a leading letter in a decimal literal, or a misspelled symbol name. .hl2 TOOBIG Offset + length exceeds storage area size. The total of the offset value and the length to be transferred cannot exceed the limit (200) placed on the size of a MEMO ACE. .hl2 VALSYM Symbol for transfer value not found. The final letter of the GET or PUT instruction indicates a DCL symbol is given for the transfer. However, the symbol is not defined. .page .hl1 Documentation .hl2 Assembly _and Linking MEMO consists of a single MACRO-32 source file: .B .C;MEMO.MAR No formal assemble and link command file is supplied because of the simplicity of the two manual operations: .B .C;$ MAC MEMO .C;$ LINK MEMO To define a system-wide foreign command to give general access to MEMO, a convenient way is: .literal $ COPY MEMO.EXE SYS$SYSTEM: $ SET FILE/PROTECTION=WORLD:RE SYS$SYSTEM:MEMO.EXE Then add this line to SYS$MANAGER:SYLOGIN.COM $ MEMO :== $MEMO .end literal This is only one common way to use MEMO. See Section 5.4 of "VMS DCL Concepts" in Volume 3 of the VMS documentation set. .hl2 Related Files The source for this document is MEMO.RNO. The final file, MEMO.DOC, may not be included with this kit because of space limitations. Because this document includes a RUNOFF generated table of contents, the generation procedure is a bit obscure. A command file, MEMO-RUNOFF.COM, is supplied which processes MEMO.RNO to produce the complete printable file, MEMO.DOC. Another command file, MEMO-TEST.COM, is included as an example. It is one of the command files used to check out MEMO performance.