!MAINT14--MAINT14--MAINT14--MAINT14--MAINT14--MAINT14 ! CONSTSTRING (21) VSN= "MAINT14 Vsn 1 May 83" ! ! ! ! !File System Maintenance Utilities ! ! !This document describes the utilities for the maintenance and !repair of EMAS 2900 file systems available in release 7 of MANAGR's !file system maintenance programs. The source is held in !MANAGR.MANPRGS_MAINT07 and the object in MANAGR.MANPRGY_MAINTY. !A description of each utility is held in the source file which !has been made VIEWable. ! Note that for readability some of the command names have embedded !spaces. These must not be there when the command is called. !Colin McCallum. ! ! ! ! ! !<ARCHOFF ! Operation: Prompts for <user>, <fsys>, <filename>. ! Effect: Marks a file to prevent archiving. !> ! ! !<ARCHON ! Operation: Prompts for <user>, <fsys>, <filename>. ! Effect: Marks a file for resumption of archiving. !> ! ! !<BAD PAGES ! Operation: Prompts for <Fsys (or -1)> ! Effect: Generates a table giving details of the bad pages on ! <fsys> !> ! ! !<CCKOUT ! Operation: Prompts for <fsys>, <output file or device>. ! Effect: Copies the data recording progress of file system ! consistency checks, from the circular file maintained by ! the DIRECT process into a standard text file. The maximum filesize ! generated is 256K. !> ! ! !<CHECK DAS ! Operation: Prompts for <low page no:> and <Fsys (or -1)> ! Effect: Calls 'TO DO ALL FILES' and for each file for each user for ! each fsys calls DGETDA and, if the disc address of a section ! is less than (low page no>, prints ! user.file !> ! ! !<COPY INDEX ! Operation: Prompts for <user>, <fsys>, <new user>, <new fsys>, ! <new index size (Kbytes)>. ! Effect: Creates a new index for <new user> on <new fsys>, unless ! one already exists. Index attributes (delivery, basefile, ! file limits etc.) are copied from the old to the new ! index. For each file in the original index, the ! corresponding file in the new index is destroyed (if it ! exists), a file of the same name and of the same size is ! created in the new index, and data are copied in from the ! original file. The file is given the same attributes as ! the original file. ! Purpose: To run some important file system utilities (e.g. MOVE ! INDEX) following corruption on a file system, it is ! generally necessary to complete the file system ! consistency check first. In the case where corruption has ! occurred on the disc containing MANAGR (and hence the ! utilities also), this can be difficult. If COPY INDEX is ! used (say once per week, or after updates) to copy the ! contents of MANAGR's index to a second disc, then the ! utilities should be available to deal with the original ! disc, even if the original MANAGR index is inaccessible. ! In addition, the copied index forms an on-line backup of ! the original. !> ! ! !<CREATE LOG FILE ! Operation: Prompts for <user>, <fsys> and <logfile> ! Effect: Creates <logfile>, permits it to MANAGR, initialises ! <logfile> as a circular file and calls DSFI to set ! the LOGFILE field in <user>s index. The contents ! of the file are made available by LOGOUT (q.v.) !> ! ! !<DELUSER ! Operation: Prompts for <user> and <fsys> ! Effect: Deletes the file index for <user> on <fsys>, hence ! removing <user> from the System. This routine requires ! the user to confirm the username to be deleted before actually ! doing so. If <fsys> is given as -1 then all occurrences ! of the given username will be deleted automatically. ! If not then all other fsys's will be searched for ! other occurrences of the username. Any found will be reported ! and the user asked if they should also be deleted. !> ! ! !<DEREGISTER CLASS ! Operation: Prompts for a "base" username, e.g. ERCC01 (in which the ! last two characters are decimal digits), <fsys> and a ! number, N, of usernames to be deleted. ! Effect: The "base" username and N-1 consecutive usernames (last ! two digits being incremented) are deleted from the System. ! (Equivalent to repeated calls of DELUSER, q.v.) !> ! ! !<DIRLOG ! Operation: No parameters ! Effect: Copies the information from DIRECTORS ! monitoring file VOLUMS.#DIRLOG into a character file T#OUT ! which can then be further edited if desired. !> ! ! !<DO ALL INDEXES ! Skeleton routine a copy of which can be used to surround ! code which is meant to be executed for all indexes on an fsys. !> ! ! !<ENV ! Operation: No parameters ! Effect: Prints the current Supervisor and Director versions, the ! process number of the calling user and the discs currently ! on-line. (N.B. The first disc specified is the SLOAD disc.) !> ! ! !<FSYS START ! Operation: Prompts for <fsys> ! Effect: Prints the range of pages available for files on <fsys> !> ! ! !<GET ! Operation: Prompts for <what>, <user> and <fsys> ! Effect: <what> is one of ! ACR ADDRTELE AFILES ! ARCHINDUSE BASEFILE BATCHSS ! CODES CONNECTT CONTROLFILE ! CUMINSTRS CUMMSECS CUMPTRNS ! CURRPROCS DEFAULTLP DELIVERY ! DINSTRS DIRMON DIRVSN ! FILES FUNDS GPFSYS ! GPHOLDR INDEXUSE ISESSM ! LASTLOGON LOGFILE MAXFILE ! MAXKB MAXPROCS NKBIN ! NKBOUT PRIVILEGES SESSINSTRS ! SESSMSECS SESSPTRNS SIGMON ! SPECIALSS STKKB SURNAME ! Reports the value or values of the index attribute specified ! (Some have multiple values associated). ! For the significance of the index attribute, current Director ! documentation on the function DSFI should be consulted for ! all except PRIVILEGES. See SET for a full description of ! available PRIVILEGES. !> ! ! !<HOLES HIST ! Operation: Prompts for <fsys> ! Effect: Generates a histogram showing how many free areas there ! are of each size (1 to 32 Epages) on <fsys> and how ! many sections !> ! ! !<HOW FULL ! Operation: Prompts for <fsys>. ! Effect: Reports the current fullness (%) of the specified <fsys>. ! (The figure reported when the System is open to users is ! not strictly comparable with the corresponding figures ! given by the FCHECK process at System start-up, in that a ! considerable quantity of temporary file-space will be ! included in the figure for a running System.) !> ! ! !<HOW FRAG ! Operation: Prompts for <fsys> (or -1) ! Effect: Calculates the degree of fragmentation on specified <fsys> ! The degree of fragmentation is defined to be the percentage ! of the total disc space available for user files which ! is occupied by sections which have sizes less than a full ! section. (i.e. 1 to 31 Epages) !> ! ! !<INACTIVE USERS ! Operation: Prompts for <trigger date> in the format DD/MM/YY and ! <op file/dev> ! Effect: Produces a sorted table (oldest to youngest) of entries ! of the form date process last used, user, fsys, ! surname and delivery info of those users who have not ! accessed their process since the trigger date. !> ! ! !<LIST NNT ! This is a synonym for command USERNAMES (q.v.). !> ! ! !<LOG OUT ! Operation: Prompts for <user>, <fsys> and <file> ! Effect: Connects <user>s logfile, if it exists, and copies ! it to <file> (see 'CREATE LOG FILE') !> ! ! !<LOST FILES ! Operation: Prompts for <fsys> ! Effect: Lists the contents of VOLUMS.LOSTFILES on <fsys> !> ! ! !<MOVE INDEX ! Operation: Prompts for <user>, <fsys>, <new fsys>, ! <new index size (Kbytes)>. ! Effect: The program first checks <fsys> and <new fsys>. If these ! are different then the routine will operate in COPY mode ! when copies are made of the files on <fsys> to <new fsys>. ! When <fsys> and <new fsys> are the same then the program ! can potentially operate in two modes COPY or TRANSFER. In ! TRANSFER mode the files are not copied, ownership is merely ! transferred. This route is faster but less safe in that ! a crash occurring during file transfer will leave two ! partial indexes and possibly result in the loss of files. ! In practice the TRANSFER route is only obligatory if there ! is not sufficient space on the disc to hold a copy of ! all the <user>'s files. The routine checks whether this ! is possible given the current state of the disc and if so ! offers <C/T?> to the caller otherwise the move can only ! proceed via the TRANSFER route. ! After mode has been decided a new index of <new index size> ! named NEWZZZ is first created on <new fsys> and <user>'s index ! is renamed to OLDZZZ. The <user>'s index attributes are ! then copied to the new index, and all the files are ! transferred or copied from the old to the new index. ! If the mode was COPY then at this point a final chance ! is offered to the caller to abandon the move with no side ! effects. If the response is to continue or mode is TRANSFER ! then finally the OLDZZZ index is deleted and the NEWZZZ index is ! renamed to belong to <user>. Note that if the original ! index was corrupted, or if some files are marked as being ! in use (either because the owner's process had terminated ! in disorder or because the owner or other users are ! actually using the files), then the program reports the ! number of files it is unable to transfer and prompts ! "Continue?", before commencing the index move. ! If the reply is "N" or "NO" the move is abandoned, with no ! side-effects. If the reply is "Y" or "YES" those files ! which cannot be transferred are lost when the original ! index is deleted. In general it is preferable not to ! proceed with the operation if it is likely that one or ! more files are actually in use by a currently existing ! process. The file pages which are actually in use will ! not be re-used before the next IPL, but the process(es) ! using the file(s) will be unable to disconnect the files. ! Purposes: One or more of the following: ! 1) To transfer as many files as possible from a corrupted ! index into a new index. ! 2) To move an index onto a different disc. ! 3) To change the size of an index. ! Apart from possible software errors, indexes become ! corrupt mainly when a hardware error or machine stop ! occurs during updating of an index. Corruption is often ! first noticed during the file system consistency check at ! System start-up, when the message ! <user> CORRUPT? FSYS <fsys> or ! <user> CELLS? FSYS <fsys> ! is given at the main OPER. In the former case the System ! remains closed to users until explicity opened, preferably ! following a move (or re-creation) of the affected ! index(es). The latter message indicates that some ! list-cells are not attached to any list, correction is not ! normally urgent. ! If the System is inadvertently or otherwise opened and ! processes are started following a "CORRUPT?" message, the ! affected indexes should be destroyed, and the users ! re-accreditted, corruption of other users' files could ! otherwise occur. !> ! ! !<MOVE INDEXES ! Operation: Prompts for <from fsys> and <to fsys> ! Effect: Moves each users index on <from fsys> to <to fsys> ! with the exception of SPOOLR and VOLUMS !> ! ! !<NEW USER ! Operation: The program prompts for the following data: ! Username ! File system ! Index size (Kbytes) (reply 4 or 8, for about 70 or 140 ! files respectively) ! Mark (reply 0 for OLD index, 1 for NEW) ! Initials and surname ! Delivery information ! Foreground password (4 chars) ! Background password (4 chars). ! Maximum total filespace (Kbytes) ! Maximum single filesize (Kbytes) ! Maximum process concurrencies allowed for the user, for ! interactive, batch and total numbers of processes. ! Effect: A new user with the specified attributes is created. !> ! ! !<REGISTER CLASS ! Operation: Prompts for a "base" username (in which the last two ! characters are decimal digits), e.g. ERCC01, <fsys> and a ! number N of usernames to be accreditted. The program ! further prompts for ! File system ! Index size (Kbytes) (reply 4 or 8, for about 70 or 140 ! files respectively) ! Initials and Surname ! Delivery information ! Password (sets the 4 characters input as both ! foreground and background passwords) ! Maximum total filespace (Kbytes) ! Maximum single filesize (Kbytes) ! Maximum process concurrencies allowed for the user, for ! interactive, batch and total numbers of processes. ! Effect: The "base" username and N-1 consecutive usernames (last ! two digits being incremented) are accreditted to the ! System, all with the same process details as input ! initially. The program reports each username successfully ! accreditted, if any username cannot be accreditted (e.g. ! because the file system index area is full, or because the ! username already exists) the program terminates at that ! point. !> ! ! !<REFRESH FILE ! Operation: Prompts for <user>, <fsys> and <file> ! Effect: Forces a resiting of <file> owned by <user> on <fsys>. !> ! ! !<REFRESH FILES ! Operation: Prompts for <low page no> and <fsys> ! Effect: Will resite all files on <fsys> which have sections whose ! disc addresses are less than <low page no>. ! Used ,for example, in reformatting a disc as a system disc. !> ! ! !<REFRESH INDEX ! Operation: Prompts for <user> and <fsys>. ! Effect: Equivalent to MOVE INDEX with oldfsys = newfsys, old index ! size = new index size and MODE = TRANSFER. ! Resites an index on the same <fsys> with the same attributes. ! See MOVE INDEX. ! N.B. Should not be done on the same <fsys> as the routine ! is running from. !> ! ! !<REFRESH INDEXES ! Operation: Prompts for <fsys>. ! Effect: Does a REFRESH INDEX for each user on the <fsys> specified. !> ! ! !<RENAME INDEX ! Operation: Prompts for <user>, <fsys> and <newname> ! Effect: Calls 'DRENAME INDEX' !> ! ! !<SET ! Operation: Prompts for <what>, <user>, <fsys> and <new value> ! (or <new values> as appropriate to the fields) ! Effect: <what> is one of ! ACR ADDRTELE AFILES ! ARCHINDUSE BASEFILE BATCHSS ! CODES CONNECTT CONTROLFILE ! CUMINSTRS CUMMSECS CUMPTRNS ! CURRPROCS DEFAULTLP DELIVERY ! DINSTRS DIRMON DIRVSN ! FILES FUNDS GPFSYS ! GPHOLDR INDEXUSE ISESSM ! LASTLOGON LOGFILE MAXFILE ! MAXKB MAXPROCS NKBIN ! NKBOUT PRIVILEGES SESSINSTRS ! SESSMSECS SESSPTRNS SIGMON ! SPECIALSS STKKB SURNAME ! Sets the new value or values of the index attribute specified ! Some have multiple values associated and will prompt appropriately. ! For the significance of the index attribute, current Director ! documentation on the function DSFI should be consulted for ! all except PRIVILEGES which are described below. ! Note that in some cases it is not sensible and in other cases ! not permitted to SET certain attributes. See current DSFI ! documentation. !< PRIVILEGES. ! It is possible to SET or GET PRIVILEGES. If the operation ! is GET then the individual PRIVILEGES enjoyed by <user> will ! either be listed in the form PRIVxx where 0 <= xx <= 31 or ! if none are enjoyed, given as *NONE*. ! If the operation is SET then the current PRIVILEGES are first ! given as for GET then the caller is prompted <PRIV:>. This ! should be responded to by a reply of the form PRIVxx where ! 0 <= xx <= 31 (spaces are not significant). The caller is then ! prompted <G/R:> and the appropriate reply should be given ! depending on whether the PRIVILEGE is to be given or removed. ! This sequence continues until the reply .END is received to ! <PRIV:> when the new set of PRIVILEGES is reported. ! PRIVILEGES currently available are as follows: ! PRIV 04 DPRINTSTRING, DDUMP ! PRIV 06 Use of chargeable FTP ! PRIV 07 DSFI 7 ! PRIV 08 DPERMISSION, DFINFO, DFSTATUS, DFILENAMES on other ! users' files ! PRIV 09 DCHECKBPASS ! PRIV 10 DSFI for privileged calls and DSETPASSWORD other users ! PRIV 12 Ability to set BASEFILE, CONTROLFILE, TESTBASEFILE ! and BATCHBASEFILE ! PRIV 14 Use of DDAP ! PRIV 15 Interactive use of magnetic tapes (DMAGCLAIM) ! PRIV 17 DSFI 38 ! PRIV 18 DPON, DPON3, DOUT, DOUT11, DOUT18, DTOFF, DLOCK ! PRIV 20 BADPAGE, DSYSAD, FBASE, GETAVFSYS ! PRIV 22 ACREATE2, DMODARCH, DNEWARCHINDEX ! PRIV 24 DCONNECT, DDISCONNECT on # files ! PRIV 25 DPRG, DUNPRG, DTRANSFER, DOFFER ! PRIV 26 DEMPTYI, DRENAMEINDEX, DNEWUSER, DDELUSER, ! VALIND, DDUMPI, DXDUMPI, GETUSNAMES ! PRIV 31 Allows ADESTROY, DCHSIZE, DCREATE, DDESTROY, ! DNEWGEN, DRENAME to be used on someone else's file ! without full index permission !> !> !<SET H NOARCH ! Operation: Prompts for <fsys> (or -1). ! Effect: For each user on <fsys> sets the NOARCH bit in file ! descriptor of file #ARCH. !> ! ! !<SET MSG EEP ! Operation: Prompts for <fsys> (or -1). ! Effect: For each user on <fsys> sets EEP to 11 in file descriptors ! of files #ARCH and #MSG. !> ! ! !<SET SSBYTE ! Operation: The program prompt is for <user>, <fsys>, <filename> and ! <values>. ! Effect: For the specified file the "ssbyte" is set to (the ! rightmost 8 bits of) <value>. The "ssbyte" is a byte in ! the file descriptor reserved for exclusive use of ! subsystems. !> ! ! !<SSDESTROY ! Operation: The program prompts for <user>, <fsys> and then repeatedly ! for <filename> until a response ".END" or ".E" is given. ! Effect: After each input <filename> an attempt is made to destroy ! <filename> belonging to <user>. A result code and brief ! text describe the success or failure of each "destroy". !> ! ! !<SSFFILES ! Operation: The program prompts for <user>, <fsys> and <output file or ! device>. ! Effect: The result is exactly as for SSFILES (see below), except ! that extra details - largely as described under SSFINFO - ! are additionally printed for each file. ("SSFFILES" ! stands for "SS Full FILES".) !> ! ! !<SSFILES ! Operation: The program prompts for <user>, <fsys> and ! <output file or device>. ! Effect: A list (in alphabetical order) of all the files belonging ! to <user> is placed in the <output file or device>. !> ! ! !<SSFINFO ! Operation: The program prompts for <user>, <fsys> and <filename> ! ! Effect: Prints out a concise synopsis of the file's attributes, ! namely: ! "*" if "cherished" ! "+" if marked for archive ! <filename> ! connect address in caller's virtual memory, or zero if ! not connected in same ! physical size in epages ! access permission to file owner (OWNP) ! general access permission to all other users (EEP, ! "everyone else's permission") ! access permission field (APF) from segment table, if ! file connected in caller's virtual memory, otherwise ! zero ! current number of users of the file ! list pool number to which descriptor cells belong in ! <user>'s file index ! the user to whom the file is "on offer", if any ! whether the file is marked: ! PRIVacy VIOLated ! TEMPorary ! VTEMPorary ! NOt to be ARCHived ! as having more than one generation ! Current DIRECTOR documentation further explains ! this terminology. ! SSFSTATUS ! Operation: Prompts for <user>, <fsys>, <file>, <act>, and <value>. ! Effect: Allows attributes of <file> belonging to <user> on <fsys> ! to be modified by calling the Director function DFSTATUS. ! N.B. This routine should NOT be used unless you are absolutely ! sure that you know what you're doing!! !> ! ! !<SSIPERMIT ! Operation: Prompts for <user>, <fsys>, <file), <to user> and <prm 1-15>. ! Effect: Gives <to user> permission to access <file> owned by <user> ! on <fsys> as specified by the response to <prm 1-15>. ! If <file> is specified as .ALL then the appropriate ! whole index permission is granted. ! (See also SSREMOVEPRM) !> ! ! !<SSNKB ! Operation: The program prompts for <user> and <fsys>. ! Effect: The following data are printed from <user>'s file index: ! Total file space (Kbytes) ! Total temporary filespace (Kbytes) ! Total "cherished" filespace (Kbytes) (currently ! reported equal to total filespace) ! Maximum permanent filespace which the user is allowed ! to own (on-line) ! Maximum single filesize allowed for <user>. !> ! ! !<SSNOF ! Operation: The program prompts for <user> and <fsys>. ! Effect: The following data are printed from <user>'s file index: ! Number of files ! Number of temporary files ! Number of cherished files ! Number of file descriptors currently extant (this may ! exceed number of files, as some descriptors may be ! marked "dead", awaiting a garbage collect). ! Maximum and currently free numbers of list cells in up ! to 4 list-cell pools !> ! ! !<SSPERMISSIONS ! Operation: Prompts for <user>, <fsys>, <file> ! Effect: Gives OWNP and EEP for <file> and whole index permissions. ! If <file> is specified as .ALL then whole index permissions ! only are given. !> ! ! !<SSPERMIT ! Operation: The program prompts for <user>, <fsys> and <filename>. ! Effect: The specified file is given general access permission, ! i.e. execute, write and read. !> ! ! !<SS REMOVE PRM ! Operation: Prompts for <user>, <fsys>, <file> and <to user>. ! Effect: Removes individual permissions to a file or index. ! Reverses the effects of SSIPERMIT. !> ! ! !<SSRENAME ! Operation: The program prompts for <user>, <fsys>, <filename> and ! <newname>. ! Effect: The specified file is renamed to <newname>. !> ! ! !<SSTRANSFER ! Operation: The program prompts for <user>, <fsys>, <filename>, ! <newuser>, <newfsys> and <newname>. ! Effect: <filename> belonging to <user> on <fsys> is transferred to ! ownership of <newuser> in <newfsys> and with name ! <newname>. !> ! ! !<TEST BAD PAGES ! Operation: Prompts for <fsys> (or -1) ! Effect: Attempts to write to each page flagged as a bad page on ! <fsys> by using the Bulk Mover to write successively ! a page of X'FFFFFFFF' ,a page of X'08CEF731' (the most ! difficult for the hardware) and finally the empty page ! pattern. If all of these are successful then the user is ! informed, the page removed from the bad page list and ! returned to the system. ! See BADPAGES. !> ! ! !<USERNAMES ! Operation: Prompts for <FSYS>, <SORT TYPE>, <USERNAMES> - if all ! FSYS option selected - and <FILE/DEV>. ! Effect: A list of usernames accredited on <fsys> (if specified - ! otherwise all on-line file systems), together with leading ! file index attributes (file limits, process concurrency ! limits, file space etc.) is placed in <file or device>. ! If the single FSYS option is selected then the ! sorting can be by index no or by username. If on the other hand ! all on line file systems are selected the sorting may be alphabetic ! by username or surname or both. Optionally in this case a file ! called USERNAMES may be created or updated in the calling ! process. This file contains a directory of usernames sorted by ! surname. ! Command LISTNNT is a synonym for command USERNAMES. !> ! ! !<WHATFILE ! Operation: The program prompts for <disc address> and <fsys>. ! Effect: File system <fsys> is searched for the file(s), if any, to ! which epage number <disc address> belongs. If <fsys> is ! specified as -1 then all file systems are searched. The ! filenames, if any, are reported. !> ! ! !<WHATFSYS ! Operation: The program prompts for <username>. ! Effect: Each on-line file system is searched for a file index ! belonging to <username> . The <fsys>'s discovered ! containing <username> are reported. !> !> ! !=================================================================== !* * !******************** RECORD FORMATS ******************************* !* * !=================================================================== ! RECORDFORMAT COMF(INTEGER OCPTYPE, IPLDEV, SBLKS, SEPGS, NDISCS, DLVNADDR, GPCTABSIZE, GPCA, SFCTABSIZE, SFCA, SFCK, DIRSITE, DCODEDA, SUPLVN, WASKLOKCORRECT, DATE0, DATE1, DATE2, TIME0, TIME1, TIME2, EPAGESIZE, USERS, CATTAD, DQADDR, SACPORT, OCPPORT, ITINT, CONTYPEA, GPCCONFA, FPCCONFA, SFCCONFA, BLKADDR, DPTADDR, SMACS, TRANS, LONGINTEGER KMON, INTEGER DITADDR, SMACPOS, SUPVSN, PSTVA, SECSFRMN, SECSTOCD, SYNC1DEST, SYNC2DEST, ASYNCDEST, MAXPROCS, INSPERSEC, ELAPHEAD, COMMSRECA, STOREAAD, PROCAAD, SFCCTAD, DRUMTAD, SP0, SP1, SP2, SP3, SP4, SP5, SP6, SP7, SP8, SP9, LSTL, LSTB, PSTL, PSTB, HKEYS, HOOT, SIM, CLKX, CLKY, CLKZ, HBIT, SLAVEOFF, INHSSR, SDR1, SDR2, SDR3, SDR4, SESR, HOFFBIT, S2, S3, S4, END) ! RECORDFORMAT DAF(INTEGER SECTSI, NSECTS, LASTSECT, SP, INTEGERARRAY DA(0:255)) ! RECORDFORMAT DATAF(INTEGER START, BITSIZE, BADSTART, NNTSTART, NNTSIZE, NNTTOP, NNTHASH, INDEXSTART, FILESTART, END) ! RECORDFORMAT DDTFORM(INTEGER SER, PTS, PROPADDR, STICK, CCA, RQA, LBA, ALA, STATE, IW1, CONCOUNT, SENSE1, SENSE2, SENSE3, SENSE4, REPSNO, HALFINTEGER SBASE, BASE, INTEGER ID, DLVN, MNEMONIC, STRING (6) LAB, BYTEINTEGER MECH) ! RECORDFORMAT DFINFRECF(INTEGER NKB, RUP, EEP, APF, USE, ARCH, FSYS, CONSEG, CCT, CODES, CODES2, SSBYTE, STRING (6) OFFER) ! RECORDFORMAT PROPFORM(INTEGER TRACKS, CYLS, PPERTRK, BLKSIZE, TOTPAGES, RQBLKSIZE, LBLKSIZE, ALISTSIZE, KEYLEN, SECTINDX) ! RECORDFORMAT FHDRF(INTEGER NEXTFREEBYTE, TXTRELST, MAXBYTES, ZERO, SPARE, DATE, NEXTCYCLIC, READ TO) ! RECORDFORMAT NNF(STRING (6) NAME, BYTEINTEGER KB, TAG, MARKER, HALFINTEGER INDNO) ! RECORDFORMAT OINFF(STRING (11) NAME, INTEGER SP12, NKB, BYTEINTEGER ARCH, CODES, CCT, OWNP, EEP, USE, CODES2, SSBYTE, FLAGS, SP29, SP30, SP31) ! RECORDFORMAT SCTF(INTEGER HORIZ VECTOR BOUND, SCT RELST, IDENS ARRAY RELST, DT STAMP, STRING (15) FIXUP DATE, INTEGER ENDF) ! RECORDFORMAT UINF(STRING (6) USER, STRING (31) JOBDOCFILE, INTEGER MARK, FSYS, PROCNO, ISUFF, REASON, BATCHID, SESSICLIM, SCIDENSAD, SCIDENS, STARTCNSL, AIOSTAT, SCT DATE, SYNC1 DEST, SYNC2 DEST, ASYNC DEST, AACCT REC, AIC REVS, STRING (15) JOBNAME, STRING (31) BASEFILE, INTEGER PREVIC, INTEGER ITADDRO, ITADDR1, ITADDR2, ITADDR3, ITADDR4, STREAM ID, DIDENT, SCARCITY, PREEMPTAT, STRING (11) SPOOLRFILE, INTEGER RESUNITS, SESSLEN, UEND) ! RECORDFORMAT TF(STRING (8) LASTUSED, STRING (6) USER, INTEGER FSYS, STRING (31) SURNAME, DELIV, INTEGER LASTLOGON) ! RECORDFORMAT LOSTF(STRING (8) DATE, TIME, STRING (6) USER, STRING (11) FILE, BYTEINTEGER CODES2, CODES, CHERISHED) ! CONSTINTEGER TOPSFI=44 RECORDFORMAT TABLEF(INTEGER IORS, HOWMANY, TOSPTEXT) OWNRECORD (TABLEF) ARRAYFORMAT TABLEAF(0:TOPSFI) ! RECORDFORMAT H F(INTEGER NEXT FREE BYTE, TXT REL ST, MAXBYTES, X, SEMA, DATE, NEXT CYCLIC, READ TO) ! RECORDFORMAT INDIVF(STRING (6) USER, BYTEINTEGER UPRM) RECORDFORMAT RETF(INTEGER BYTES, OWNP, EEP, SPARE, RECORD (INDIVF) ARRAY INDIV(0:15)) ! RECORDFORMAT NNEF(RECORD (NNF) NN, INTEGER FSYS, STRING (7) INITS, STRING (19) SURNAME, STRING (31) DELIV, INTEGER ACR, MAXFILE, MAXKB, TOTKB, IMAX, BMAX, TMAX, AFILES) ! RECORDFORMAT USINFF(STRING (6) NAME, BYTEINTEGER KB, INTEGER INDNO) !=================================================================== !* * !******************** EXTERNAL ROUTINE/ FN SPECS ******************* !* * !=================================================================== ! DYNAMICINTEGERFNSPEC DERROR(STRINGNAME TXT) DYNAMICINTEGERFNSPEC DNEW ARCH INDEX(STRING (6) USER, INTEGER FSYS, KBYTES) EXTERNALSTRINGFNSPEC DERRS(INTEGER I) EXTERNALINTEGERFNSPEC DSYSAD(INTEGER TYPE, ADR, FSYS) EXTERNALINTEGERFNSPEC FBASE(INTEGERNAME LO, HI, INTEGER FSYS) SYSTEMROUTINESPEC PHEX(INTEGER I) DYNAMICINTEGERFNSPEC DSFI(STRING (6) USER, INTEGER FSYS, TYPE, SET, ADR) DYNAMICROUTINESPEC PROMPT(STRING (255) S) DYNAMICINTEGERFNSPEC DCONNECT(STRING (6) USER, STRING (15) FILE, INTEGER FSYS, MODE, APF, INTEGERNAME SEG, GAP) DYNAMICINTEGERFNSPEC DDISCONNECT(STRING (6) USER, STRING (15) FILE, INTEGER FSYS, DSTRY) DYNAMICROUTINESPEC GET AV FSYS(INTEGERNAME N, INTEGERARRAYNAME A) DYNAMICINTEGERFNSPEC DCREATE(STRING (6) USER, STRING (11) FILE, INTEGER FSYS, NKB, TYPE) DYNAMICROUTINESPEC DPRINTSTRING(STRING (255) S) DYNAMICINTEGERFNSPEC DTRANSFER(STRING (6) USER1, USER2, STRING (15) FILE, NEWNAME, INTEGER FSYS1, FSYS2, TYPE) DYNAMICINTEGERFNSPEC DFSYS(STRING (6) USER, INTEGERNAME FSYS) DYNAMICINTEGERFNSPEC OUTPOS DYNAMICINTEGERFNSPEC DFSTATUS(STRING (6) USER, STRING (11) FILE, INTEGER FSYS, ACT, VALUE) DYNAMICINTEGERFNSPEC DFINFO(STRING (6) USER, STRING (15) FILE, INTEGER FSYS, ADR) DYNAMICINTEGERFNSPEC DRENAME(STRING (6) USER, STRING (15) OLDNAME, NEWNAME, INTEGER FSYS) DYNAMICROUTINESPEC DEFINE(STRING (255) S) DYNAMICROUTINESPEC CLEAR(STRING (255) S) DYNAMICINTEGERFNSPEC DFILENAMES(STRING (6) USER, RECORD (OINFF) ARRAYNAME INF, INTEGERNAME FILENO, MAXREC, NFILES, INTEGER FSYS, TYPE) DYNAMICINTEGERFNSPEC DDESTROY(STRING (6) USER, STRING (15) FILE, STRING (8) DATE, INTEGER FSYS, TYPE) DYNAMICINTEGERFNSPEC DPERMISSION(STRING (6) OWNER, USER, STRING (8) DATE, STRING (15) FILE, INTEGER FSYS, TYPE, ADRPRM) EXTERNALSTRINGFNSPEC UINFS(INTEGER I) EXTERNALROUTINESPEC RENAME(STRING (255) S) EXTERNALINTEGERFNSPEC EXIST(STRING (255) S) EXTERNALROUTINESPEC NEWGEN(STRING (255) S) SYSTEMROUTINESPEC MOVE(INTEGER LENGTH, FROM, TO) SYSTEMSTRINGFNSPEC ITOS(INTEGER VALUE) EXTERNALINTEGERFNSPEC GET USNAMES2(RECORD (NNF) ARRAYNAME UNN, INTEGERNAME N, INTEGER FSYS) DYNAMICSTRINGFNSPEC INTERRUPT DYNAMICINTEGERFNSPEC DGETDA(STRING (6) USER, STRING (15) FILE, INTEGER FSYS, ADR) DYNAMICINTEGERFNSPEC GET USNAMES(INTEGERNAME N, INTEGER ADR, FSYS) DYNAMICINTEGERFNSPEC ACREATE2(STRING (6) USER, TAPE, STRING (8) FDATE, STRING (15) FILE, INTEGER FSYS, NKB, CHAPTER, TYPE) DYNAMICINTEGERFNSPEC DNEWUSER(STRING (6) USER, INTEGER FSYS, NKB) DYNAMICINTEGERFNSPEC DDELUSER(STRING (6) USER, INTEGER FSYS) DYNAMICINTEGERFNSPEC DRENAME INDEX(STRING (6) OLDNAME, NEWNAME, INTEGER FSYS) DYNAMICINTEGERFNSPEC DOFFER(STRING (6) USER, OFFERTO, STRING (15) FILE, INTEGER FSYS) SYSTEMROUTINESPEC FILL(INTEGER LEN, FROM, FILLER) SYSTEMSTRING (8) FNSPEC UNPACKDATE(INTEGER I) SYSTEMSTRING (8) FNSPEC UNPACKTIME(INTEGER I) SYSTEMROUTINESPEC UCTRANSLATE(INTEGER AD, LEN) SYSTEMSTRINGFNSPEC FAILURE MESSAGE(INTEGER I) SYSTEMINTEGERMAPSPEC COMREG(INTEGER I) SYSTEMROUTINESPEC OUTFILE(STRING (31) S, INTEGER LENGTH, MAXBYTES, PROT, INTEGERNAME CONAD, FLAG) ! ! !==================================================== ! !***************** CONSTANTS ************************ ! !==================================================== ! !----------- CODES ----------- CODES2 ---------- CONSTINTEGER UNAVA=1, WRCONN=1 CONSTINTEGER OFFER=2, NEWGE=2 CONSTINTEGER TEMPFI=4, OLDGE=4 CONSTINTEGER VTEMPF=8, WSALLOW=8 CONSTINTEGER TEMPFS=12 CONSTINTEGER CHERSH=16 CONSTINTEGER PRIVAT=32, DISCFI=32 CONSTINTEGER VIOLAT=64 CONSTINTEGER NOARCH=128 !---------------------------------------------------------- ! CONSTSTRINGNAME DATE=X'80C0003F', TIME=X'80C0004B' CONSTINTEGER SWR=11; ! Shared, R+W CONSTINTEGER LOSTFLEN=48; ! bytes, nominal, generous ! CONSTINTEGER MAXUSERS=4000 CONSTINTEGER NNEFLEN=108 ! CONSTINTEGER TRUE=1 CONSTINTEGER FALSE=0 ! CONSTINTEGER TOPSI=32 CONSTINTEGER TRANSFER=1, COPY=3, RENAMEOLD=1, NORENAME=0 CONSTINTEGER MAXFILES=400 CONSTINTEGER SETOWNP=0,SETEEP=1,ADDTOFLIST=2,ADDTOILIST=6 CONSTINTEGER GETFLIST=4,GETILIST=8 CONSTINTEGER SFI=0, FSTAT=1, PERM=2, TRAN=3, FILEN=4, OFFE=5 CONSTINTEGER TOPNNT = 1364; ! for 0 to N CONSTSTRING (17)EXECUTIVES = "VOLUMSPOOLRMAILER" ! !------------------------------------------------------------------ ! STRING (8) FN HTOS(INTEGER VALUE, PLACES) STRING (8) S INTEGER I CONSTBYTEINTEGERARRAY HEX(0:15)= C '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' I = 64 - 4 * PLACES *LD_S; *LSS_PLACES; *ST_(DR ) *INCA_1; *STD_ TOS ; *STD_ TOS *LSS_VALUE; *LUH_0; *USH_I *MPSR_X'24'; ! SET CC=1 *SUPK_ L =8 *LD_ TOS ; *ANDS_ L =8, 0, 15; ! THROW AWAY ZONE CODES *LSS_HEX+4; *LUH_X'18000010' *LD_ TOS ; *TTR_ L =8 RESULT = S END ; ! OF HTOS ! !----------------------------------------------------------------------- ! ROUTINE INSTRG(STRINGNAME S) INTEGER I S = "" CYCLE READSYMBOL(I) EXITIF I = NL S = S.TOSTRING(I) REPEAT UCTRANSLATE(ADDR(S) + 1, LENGTH(S)) UNLESS S = "" END ; ! INSTRG ! !---------------------------------------------------------------------- ROUTINE RSTRG(STRINGNAME S) INSTRG(S) UNTIL S # "" END ; ! RSTRG ROUTINE UCTRAN(STRINGNAME S) UCTRANSLATE(ADDR(S) + 1, LENGTH(S)) END {UCTRAN} ROUTINE UCSTRG(STRINGNAME S) RSTRG(S) UCTRAN(S) END {UCSRTG} ! !----------------------------------------------------------------------- ! ROUTINE WRS(STRING (255) S1) PRINTSTRING(S1) NEWLINE END ! ! ! ROUTINE WRSS(STRING (255) S1, S2) PRINTSTRING(S1) PRINTSTRING(S2) NEWLINE END ! ! ! ROUTINE WRSSS(STRING (255) S1, S2, S3) PRINTSTRING(S1) PRINTSTRING(S2) PRINTSTRING(S3) NEWLINE END ! ! ! ROUTINE WRSN(STRING (255) S1, INTEGER N) PRINTSTRING(S1) WRITE(N, 1) NEWLINE END ! ! ! ROUTINE WRSNS(STRING (255) S1, INTEGER N, STRING (255) S2) PRINTSTRING(S1) WRITE(N, 1) PRINTSTRING(S2) NEWLINE END ! ! ! ROUTINE WRSSN(STRING (255) S1, S2, INTEGER N) PRINTSTRING(S1) PRINTSTRING(S2) WRITE(N, 1) NEWLINE END ! ! ! ROUTINE WRSSNSS(STRING (255) S1, S2, INTEGER N, STRING (255) S3, S4) PRINTSTRING(S1) PRINTSTRING(S2) WRITE(N, 1) PRINTSTRING(S3) PRINTSTRING(S4) NEWLINE END ! !----------------------------------------------------------------------- ! INTEGERFN HXSTOBIN(STRING (29) S) ! RESULT IS VALUE REPRESENTED BY UP TO 8 HEX DIGITS IN THE PARAM. ! ERROR RESULT IS X80308030 INTEGER I, Q, L, AS, CH AS = ADDR(S) L = LENGTH(S) RESULT = X'80308030' IF L > 8 OR L = 0 I = 0 CYCLE Q = 1, 1, L CH = BYTEINTEGER(AS + Q) RESULT = X'80308030' UNLESS '0' <= CH <= '9' OR 'A' <= CH <= 'F' IF CH > '9' THEN CH = CH - 55 ELSE CH = CH - 48 I = I << 4 ! CH REPEAT RESULT = I END ; ! HXSTOBIN ! !----------------------------------------------------------------------- ! STRINGFN FROMSTR(STRING (255) S, INTEGER I, J) INTEGER A RESULT = "" UNLESS 0 < I <= J AND J <= LENGTH(S) A = ADDR(S) I = I - 1 BYTEINTEGER(A + I) = J - I RESULT = STRING(A + I) END ; ! FROMSTR ! !----------------------------------------------------------------------- ! INTEGERFN NWFILEAD(STRING (15) S, INTEGER PGS) INTEGER I, FLAG, CURR FLAG = 1 IF 0 < LENGTH(S) <= 15 THEN OUTFILE(S, PGS << 12, X'40000', 0, I, FLAG) IF FLAG # 0 START CURR = COMREG(23) SELECT OUTPUT(0) WRSSNSS("", "OUTFILE FLAG =", FLAG, " ", FAILURE MESSAGE(FLAG)) I = 0 SELECT OUTPUT(CURR) FINISH RESULT = I END ; ! NWFILEAD ! ! ! INTEGERFN BIN(STRING (255) S) ! RESULT IS VALUE REPRESENTED BY THE STRING PARAM ! ERROR RESULT IS X80308030 (BAD CHAR IN STRING OR BAD ! LENGTH) INTEGER I, Q, L, AS, CH, SIGN STRING (255) REST SIGN = 1 WHILE S - > REST.(" ").S AND REST = "" CYCLE ; REPEAT IF S - > REST.("-").S AND REST = "" THEN SIGN = - 1 WHILE S - > REST.(" ").S AND REST = "" CYCLE ; REPEAT IF S - > REST.("X").S AND REST = "" START I = HXSTOBIN(S) IF I # X'80308030' THEN I = I * SIGN RESULT = I FINISH AS = ADDR(S) L = LENGTH(S) RESULT = X'80308030' IF L = 0 I = 0 CYCLE Q = 1, 1, L CH = BYTEINTEGER(AS + Q) RESULT = X'80308030' UNLESS '0' <= CH <= '9' I = 10 * I + CH - 48 REPEAT RESULT = I * SIGN END ; ! BIN ! !----------------------------------------------------------------------- ! ROUTINE GET INT(INTEGERNAME I) ! READS NEXT UNSIGNED DEC NO. OR HEX NO. (NOT X80308030). OWNSTRING (15) ARRAY NS(1:10)=""(10) STRING (1) T STRING (63) REST, S OWNINTEGER NP=0,NL=0 IF NP >= NL START RESET: UCSTRG(S) NP = 0; NL = 0 WHILE S - > REST.(" ").S AND REST = "" CYCLE ; REPEAT WHILE S - > NS(NL + 1).(" ").S CYCLE WHILE S - > REST.(" ").S AND REST = "" CYCLE REPEAT IF NS(NL + 1) = "X" OR NS(NL + 1) = "-" START T = NS(NL + 1) WHILE S - > REST.(" ").S AND REST = "" CYCLE REPEAT UNLESS S - > REST.(" ").S THEN REST = S AND S = "" NS(NL + 1) = T.REST FINISH NL = NL + 1 REPEAT IF S # "" START NL = NL + 1 NS(NL) = S FINISH FINISH ! NP = NP + 1 S = NS(NP) I = BIN(S) IF I = X'80308030' START WRS("INVALID HEX OR DEC NO.") IF NP > 1 START NP = NP - 1 WRSS("LAST TAKEN WAS ", NS(NP)) FINISH ->RESET FINISH END ; ! GET INT ! ! ! ROUTINE RDSTRG(STRING (255) TXT, STRINGNAME VAR) PROMPT(TXT) UCSTRG(VAR) END ! ! ! ROUTINE RDINT(STRING (255) TXT, INTEGERNAME VAR) PROMPT(TXT) GET INT(VAR) END ! ! ! ROUTINE RDFSYS(STRING (255) TXT, INTEGERNAME FSYS) PROMPT(TXT) GET INT(FSYS) UNTIL - 1 <= FSYS < 100 END ! ! ! INTEGERFN YES OR NO(STRING (255) TXT) STRING (63) S PROMPT(TXT) CYCLE UCSTRG(S) RESULT = 0 IF S = "N" OR S = "NO" RESULT = 1 IF S = "Y" OR S = "YES" REPEAT END ! ! ! !=================================================================== !* * ROUTINE ERROR(STRING (255)TXT) INTEGER J STRING (255)MSG J = DERROR(MSG) WRSS(TXT, MSG) END ; ! ERROR ! !----------------------------------------------------------------------- ! INTEGERFN BIT TO CYL TK PG(INTEGERNAME CYL, TK, PG, INTEGER FSYS, BITNO) ! Result is the BITNO corresponding to 1st page of TRK on CYL on FSYS. ! Zero if fsys not found. INTEGER BASE, J, FS INTEGER LCYL, LTRKS, PPERTRK, TKSPERCYL RECORD (DDTFORM) NAME DDT RECORD (PROPFORM) NAME PROP RECORD (COMF) NAME COM INTEGERARRAYNAME DIT INTEGERARRAYFORMAT DITF(0:99) BYTEINTEGERARRAYNAME DLVNA BYTEINTEGERARRAYFORMAT DLVNAF(0:99) COM == RECORD(X'80000000' + 48 << 18) DLVNA == ARRAY(COM_DLVNADDR, DLVNAF) DIT == ARRAY(COM_DITADDR, DITF) J = DLVNA(FSYS) IF J <= 250 START DDT == RECORD(DIT(J)) FS = DDT_DLVN << 2 >> 2 BASE = DDT_BASE IF 4 <= DDT_STATE <= 7 AND (BASE = X'40' OR BASE = X'800') AND C FSYS = FS START PROP == RECORD(DDT_PROPADDR) PPERTRK = PROP_PPERTRK TKSPERCYL = PROP_TRACKS LTRKS = BITNO // PPERTRK PG = BITNO - LTRKS * PPERTRK LCYL = LTRKS // TKSPERCYL TK = LTRKS - LCYL * TKSPERCYL CYL = LCYL RESULT = 0 FINISH FINISH RESULT = 1; ! FAIL END ; ! BIT TO CYL TK PG ! !----------------------------------------------------------------------- ! INTEGERFN FBASE2(INTEGER FSYS, ADR) ! ! This returns the characteristics of an on-line disc in a record ! of format DATAF at address ADR INTEGER J, LOB, HIB, TYPE, K RECORD (DATAF) NAME DATA CONSTINTEGER TOPTYPE= 5 CONSTINTEGERARRAY BITSIZE(1:TOP TYPE)= X'1000'(2), X'2000'(2), X'5000' CONSTINTEGERARRAY NNTSTART(1:TOP TYPE)= X'7000'(4), X'A000' CONSTINTEGERARRAY NNTSIZE(1:TOP TYPE)= X'4000'(4), X'1FF8' CONSTINTEGERARRAY NNTTOP(1:TOP TYPE)= 1364(4), 681 CONSTINTEGERARRAY NNTHASH(1:TOP TYPE)= 1361(4), 667 CONSTBYTEARRAY INDEXSTART(1:TOP TYPE)= 12(5) CONSTINTEGERARRAY FILESTART(1:TOP TYPE)= 256(5) CONSTINTEGERARRAY HI(1:TOP TYPE)= X'3F1F', X'59F3', X'8F6F', X'B3E7', X'24797' J = FBASE(LOB, HIB, FSYS) RESULT = J UNLESS J = 0 ! TYPE = - 1 CYCLE K = 1, 1, TOP TYPE TYPE = K ANDEXITIF HIB = HI(K) REPEAT RESULT = 8 IF TYPE < 0 ! DATA == RECORD(ADR) ! DATA_START = LOB DATA_BITSIZE = BITSIZE(TYPE) DATA_BADSTART = X'5000' DATA_NNTSTART = NNTSTART(TYPE) DATA_NNTSIZE = NNTSIZE(TYPE) DATA_NNTTOP = NNTTOP(TYPE) DATA_NNTHASH = NNTHASH(TYPE) DATA_INDEXSTART = INDEX START(TYPE) DATA_FILESTART = FILE START(TYPE) DATA_END = HIB RESULT = 0 END ; ! FBASE2 ! !----------------------------------------------------------------------- ! ROUTINE UDERRS(INTEGER N) WRSS("FLAG =", DERRS(N)) END ; ! UDERRS ! ! ! ROUTINE WRSU(STRING (255) S, INTEGER N) PRINTSTRING(S) WRSS(" FLAG =", DERRS(N)) END ! !----------------------------------------------------------------------- ! ROUTINE GUAF(STRINGNAME USER, INTEGERNAME FSYS) ! GET USER AND FSYS RDSTRG("User: ", USER) RDFSYS("Fsys: ", FSYS) END ; ! GUAF ! !----------------------------------------------------------------------- ! ROUTINE GUAFAF(STRINGNAME USER, INTEGERNAME FSYS, STRINGNAME FILE) RDSTRG("User: ", USER) RDFSYS("Fsys: ", FSYS) RDSTRG("File: ", FILE) END ; ! GUAFAF ! !----------------------------------------------------------------------- ! ROUTINE GET FSYSS(INTEGERARRAYNAME A, INTEGERNAME N) INTEGER FSYS, NSYS, P, J, W RDFSYS("Fsys: ", FSYS) ! IF FSYS < 0 THEN GET AV FSYS(NSYS, A) ELSE A(0) = FSYS AND NSYS = 1 ! N = NSYS P = 1 UNTIL P = 1 CYCLE P = 1 IF NSYS > 1 START CYCLE J = 0, 1, NSYS - 2 IF A(J) > A(J + 1) START P = 0 W = A(J) A(J) = A(J + 1) A(J + 1) = W FINISH REPEAT FINISH REPEAT END ; ! GET FSYSS ! !----------------------------------------------------------------------- ! EXTERNALROUTINE BAD PAGES(STRING (255) S) ROUTINE PRINT(INTEGER FSYS, BITNO) INTEGER I, CYL, TK, PG WRITE(BITNO, 5) SPACES(2) PHEX(BITNO) SPACES(2) I = BIT TO CYL TK PG(CYL, TK, PG, FSYS, BITNO) IF I # 0 START PRINTSTRING("ERROR FOR BITNO ") PHEX(BITNO) NEWLINE RETURN FINISH WRITE(CYL, 5) SPACES(2) PHEX(CYL) SPACES(2) WRITE(TK, 5) SPACES(2) PHEX(TK) WRITE(PG, 8) NEWLINE END ; ! PRINT ! ROUTINE ONE BAD PAGE(INTEGER FSYS) INTEGER I, J, LISTAD, N, HDR, TOP INTEGERARRAY LIST(0:5119) RECORD (DATAF)DATA LISTAD = ADDR(LIST(0)) J = DSYSAD(6, LISTAD, FSYS); ! COPY BAD-PAGES-BIT MAP -> OUT UNLESS J = 0 ! J = FBASE2(FSYS, ADDR(DATA)) -> OUT UNLESS J = 0 ! TOP = (DATA_BITSIZE >> 2) - 1 HDR = 0; ! header not (yet) written ! CYCLE I = 0, 1, TOP N = LIST(I) CYCLE J = 0, 1, 31 EXITIF N = 0 IF N < 0 START IF HDR = 0 START HDR = 1 WRSN("Summary of bad pages on FSYS ", FSYS) WRS(" Bitno Cyl Track Page") WRS(" dec hex dec hex dec hex") FINISH PRINT(FSYS, 32 * I + J) FINISH N = N << 1 REPEAT REPEAT ! WRSN("No bad pages on fsys ", FSYS) IF HDR = 0 RETURN OUT: ERROR("Fsys " . ITOS(FSYS) . " ") END ; ! ONE BAD PAGE ! INTEGER NSYS, F INTEGERARRAY A(0:99) GET FSYSS(A, NSYS) ! CYCLE F = 0, 1, NSYS - 1 ONE BAD PAGE(A(F)) REPEAT END ; ! BAD PAGES ! ! !------------------------------------------------------------------ ! ROUTINE UNWIND(INTEGER A, B) INTEGERNAME BP, BM RECORD (FHDRF) NAME AH, BH ! ROUTINE PIECE(INTEGER ADR, L) IF BP < BM START ; ! output file not yet full L = L - ADR L = BM - BP IF BP + L > BM MOVE(L, A + ADR, B + BP) BP = BP + L FINISH END ! AH == RECORD(A) BH == RECORD(B) BP == BH_NEXTFREEBYTE BM == BH_MAXBYTES ! IF AH_NEXTCYCLIC = AH_NEXTFREEBYTE START ; ! not wrapped round PIECE(AH_TXTRELST, AH_NEXTFREEBYTE) FINISHELSESTART PIECE(AH_NEXTCYCLIC, AH_NEXTFREEBYTE) IF AH_NEXTCYCLIC > AH_TXTRELST START PIECE(AH_TXTRELST, AH_NEXTCYCLIC) FINISH FINISH ! BH_ZERO = 3; ! character file END ; ! UNWIND ! !---------------------------------------------------------- ! EXTERNALROUTINE LOGOUT(STRING (255) S) INTEGER FA2, J, LP, FSYS, SEG, GAP STRING (63) USER, LOGFILE LP = 0 GUAF(USER, FSYS) J = DSFI(USER, FSYS, 19, 0, ADDR(LOGFILE)) ->ERR UNLESS J = 0 WRS("NO LOG FILE") ANDRETURNIF LENGTH(LOGFILE) = 0 FA2 = NWFILEAD("T#OUT", 16); ! 16 EPAGES RETURNIF FA2 = 0 SEG = 0 GAP = 0 J = DCONNECT(USER, LOGFILE, FSYS, SWR, 0, SEG, GAP) ->ERR UNLESS (J = 0) OR (J = 34) UNWIND(SEG << 18, FA2) WRS("T#OUT written") IF J = 34 THEN J = 0 ELSE J = DDISCONNECT(USER, LOGFILE, FSYS, 0) ERR: ERROR("LOGOUT") UNLESS J = 0 END ; ! LOGOUT ! !----------------------------------------------------------------------- ! EXTERNALROUTINE CCKOUT(STRING (255) S) INTEGER J, TO, SEG, GAP, FSYS RDFSYS("Fsys: ", FSYS) UNTIL FSYS >= 0 TO = NWFILEAD("T#OUT", 64); ! 64 EPAGES UNLESS TO = 0 START SEG = 0 GAP = 0 J = DCONNECT("VOLUMS", "CCKMESS", FSYS, 11, 0, SEG, GAP) UNLESS 0 # J # 34 START UNWIND(SEG << 18, TO) J = DDISCONNECT("VOLUMS", "CCKMESS", FSYS, 0) IF J = 0 J = 0 IF J = 34 FINISH FINISH ! IF J = 0 THEN WRS("T#OUT WRITTEN") ELSE WRSS("FLAG =", DERRS(J)) END ; ! CCKOUT ! !----------------------------------------------------------------------- ! EXTERNALROUTINE LOST FILES(STRING (255) S) INTEGER FAD, J RECORD (LOSTF) NAME L RECORD (FHDRF) NAME F INTEGER FSYS, SEG, GAP RDFSYS("Fsys: ", FSYS) SEG = 0 GAP = 0 J = DCONNECT("VOLUMS", "LOSTFILES", FSYS, 9, 0, SEG, GAP) IF 34 # J # 0 START WRSU("VOLUMS.LOSTFILES", J) FINISHELSESTART FAD = SEG << 18 F == RECORD(FAD) J = FAD + F_NEXTFREEBYTE - LOSTFLEN WHILE J > FAD CYCLE L == RECORD(J) PRINTSTRING(L_DATE) SPACE PRINTSTRING(L_TIME) SPACE WRSSS(L_USER, ".", L_FILE) J = J - LOSTFLEN REPEAT J = DDISCONNECT("VOLUMS", "LOSTFILES", FSYS, 0) WRSU("DDISCONN VOLUMS.LOSTFILES", J) UNLESS J = 0 FINISH END ; ! LOST FILES ! !------------------------------------------------------------ ! EXTERNALROUTINE DIRLOG(STRING (255) S) INTEGER TO, J, SEG, GAP J = 99 TO = NWFILEAD("T#OUT", 32) UNLESS TO = 0 START SEG = 0 GAP = 0 J = DCONNECT("VOLUMS", "#DIRLOG", - 1, 11, 0, SEG, GAP) IF J = 0 OR J = 34 START UNWIND(SEG << 18, TO) J = DDISCONNECT("VOLUMS", "#DIRLOG", - 1, 0) IF J = 0 J = 0 IF J = 34 FINISH FINISH ! IF J = 0 THEN WRS("T#OUT WRITTEN") ELSE WRSS("FLAG =", DERRS(J)) END ; ! DIRLOG ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SETDIR(STRING (255) S) INTEGER I RECORD (UINF) NAME UIN UIN == RECORD(9 << 18) IF LENGTH(S) = 1 START I = BYTEINTEGER(ADDR(S) + 1) - '0' IF 0 <= I <= 3 START WRSN("FLAG =", DSFI(UIN_USER, UIN_FSYS, 8, 1, ADDR(I))) RETURN FINISH FINISH ! WRS("Param must be <n>, 0<=n<=3") END ! !----------------------------------------------------------------------- ! EXTERNALROUTINE MYLOG(STRING (255) S) INTEGER J, SEG, GAP, TO STRING (31) LOGFILE RECORD (UINF) NAME UIN UIN == RECORD(9 << 18) J = DSFI(UIN_USER, UIN_FSYS, 19, 0, ADDR(LOGFILE)) J = 32 IF J = 0 = LENGTH(LOGFILE) IF J = 0 START J = 99 TO = NWFILEAD("T#OUT", 16) UNLESS TO = 0 START SEG = 0 GAP = 0 J = DCONNECT(UIN_USER, LOGFILE, UIN_FSYS, 11, 0, SEG, GAP) IF J = 0 OR J = 34 START UNWIND(SEG << 18, TO) J = DDISCONNECT(UIN_USER, LOGFILE, UIN_FSYS, 0) IF J = 0 J = 0 IF J = 34 FINISH FINISH FINISH ! IF J = 0 THEN WRS("T#OUT WRITTEN") ELSE WRSS("FLAG =", DERRS(J)) END ! !----------------------------------------------------------------------- ! ROUTINE PNSTRG(STRING (255) S) IF S = "" THEN S = "<null>" WRS(S) END ; ! PNSTRG ! !----------------------------------------------------------------------- ! !******************* GET/SET ROUTINES ******************* ! ! NB THE '39' BELOW COULD BECOME 'TOPSFI' AGAIN ! CONSTSTRING (15) ARRAY TYPES(0:TOPSFI)= C "BASEFILE", "DELIVERY", "CONTROLFILE", "ADDRTELE", "INDEXUSE", "", "LASTLOGON", "ACR", "DIRVSN", "ARCHINDUSE", "STKKB", "MAXKB", "MAXFILE", "CURRPROCS", "MAXPROCS", "CODES", "DIRMON", "SIGMON", "SURNAME", "LOGFILE", "CUMINSTRS", "SESSINSTRS", "DINSTRS", "CUMPTRNS", "SESSPTRNS", "NKBOUT", "NKBIN", "CUMMSECS", "SESSMSECS", "CONNECTT", "FILES", "AFILES", "ISESSM", "FUNDS", "GPFSYS", "SPECIALSS", "BATCHSS", "GPHOLDR", "PRIVILEGES", "DEFAULTLP", "", "", "", "MAILCOUNT", "SUPERVISOR" OWNINTEGERARRAY ELEMENTS(0:119)= C 'S', 1, 0, 'S', 1, 0, 'S', 1, 0, 'S', 1, 0, 'I', 12, 1, '0', 0, 0, '0', 0, 38, 'I', 1, 0, 'I', 1, 0, 'I', 12, 13, 'I', 1, 0, 'I', 1, 0, 'I', 1, 0, 'I', 2, 25, 'I', 3, 25, 'I', 1, 0, 'I', 1, 0, 'I', 2, 28, 'S', 1, 0, 'S', 1, 0, 'I', 2, 25, 'I', 1, 0, 'I', 1, 0, 'I', 2, 25, 'I', 1, 0, 'I', 1, 0, 'I', 1, 0, 'I', 2, 25, 'I', 1, 0, 'I', 1, 0, 'I', 6, 30, 'I', 2, 36, 'I', 1, 0, 'I', 1, 0, 'I', 1, 0, 'S', 1, 0, 'S', 1, 0, 'S', 1, 0, '0', 0, 0, 'S', 1, 0 CONSTSTRING (13) ARRAY SPTEXT(1:39)= C "FILES: ", "USEDFDS: ", "FREEBYTES: ", "INDEX SIZE: ", "POOL 0 USED: ", " FREE: ", "POOL 1 USED: ", " FREE: ", "POOL 2 USED: ", " FREE: ", "POOL 3 USED: ", " FREE: ", "AFILES: ", "USEDAFDS: ", "", "AINDEX SIZE: ", "", "", "", "", "", "", "", "", "INTERACTIVE: ", "BATCH: ", "TOTAL: ", "SIGMON: ", "MONITORING: ", "FILES: ", "TOTKB: ", "CHERFILES: ", "CHERKB: ", "", "TEMPKB: ", "AFILES: ", "AKB: ", "I LASTLOGON: ", "B LASTLOGON: " CONSTSTRING (6) ARRAY PRIV(0:31)= C "PRIV00", "PRIV01", "PRIV02", "PRIV03", "PRIV04", "PRIV05", "PRIV06", "PRIV07", "PRIV08", "PRIV09", "PRIV10", "PRIV11", "PRIV12", "PRIV13", "PRIV14", "PRIV15", "PRIV16", "PRIV17", "PRIV18", "PRIV19", "PRIV20", "PRIV21", "PRIV22", "PRIV23", "PRIV24", "PRIV25", "PRIV26", "PRIV27", "PRIV28", "PRIV29", "PRIV30", "PRIV31" OWNRECORD (TABLEF) ARRAYNAME TABLE ! !----------------------------------------------------------------------- ! ROUTINE PURGE(STRINGNAME S, STRING (1) T) STRING (255) L, R ! PURGE THE STRING S OF ALL ! OCCURANCES OF T. S = L.R WHILE S - > L.(T).R END ; ! RTN. PURGE ! !------------------------------------------------------------------ ! INTEGERFN LOOK UP(STRING (31) WHAT, STRINGARRAYNAME KEYS, INTEGER LIM) INTEGER I ! CYCLE I = 0, 1, LIM IF KEYS(I) = WHAT THENRESULT = I REPEAT RESULT = - 1 END ; ! LOOK UP ! ! !----------------------------------------------------------------------- ! EXTERNALROUTINE GET(STRING (255) S) INTEGER TYPE, FSYS, J, I, LIM, SPTEXTPOINTER STRING (31) WHAT, USER INTEGERARRAY FIELD(0:31) TABLE == ARRAY(ADDR(ELEMENTS(0)), TABLEAF) RDSTRG("What: ", WHAT) TYPE = LOOK UP(WHAT, TYPES, TOPSFI) ! IF TYPE < 0 THEN PRINTSTRING("NOT KNOWN") ANDRETURN GUAF(USER, FSYS) J = DSFI(USER, FSYS, TYPE, 0, ADDR(FIELD(0))) ERROR("GET") ANDRETURNUNLESS J = 0 PNSTRG(STRING(ADDR(FIELD(0)))) ANDRETURNIF TABLE(TYPE)_IORS = 'S' WRITE(FIELD(0), 1) ANDRETURNIF TABLE(TYPE)_HOWMANY = 1 NEWLINE LIM = TABLE(TYPE)_HOWMANY - 1 UNLESS LIM < 0 START SPTEXTPOINTER = TABLE(TYPE)_TOSPTEXT CYCLE I = 0, 1, LIM IF SPTEXT(I + SPTEXTPOINTER) # "" START WRSN(SPTEXT(I + SPTEXTPOINTER), FIELD(I)) FINISH REPEAT FINISH IF TYPE = 6 START ; ! LAST LOGON CYCLE I = 0, 1, 1 PRINTSTRING(SPTEXT(38 + I)) PHEX(FIELD(I)) PRINTSTRING(" => ".UNPACKDATE(FIELD(I))." ".UNPACKTIME(FIELD C (I))) NEWLINE REPEAT FINISH IF TYPE = 38 START ; ! PRIVILEGES NEWLINE PRINTSTRING("*NONE*") ANDRETURNIF FIELD(0) = 0 CYCLE I = 0, 1, 31 IF FIELD(0) & 1 = 1 THEN WRS(PRIV(I)) FIELD(0) = FIELD(0) >> 1 EXITIF FIELD(0) = 0 REPEAT FINISH END ; ! GET ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SET(STRING (255) S) INTEGER TYPE, FSYS, J, I, BITNO, LIM, SPTEXTPOINTER, PATTERN STRING (31) WHAT, USER, REPLY, GIVEORREMOVE INTEGERARRAY FIELD(0:31) CONSTINTEGERARRAY INVALID(1:10)= 4,6,9,21,22,24,28,30,31,34 TABLE == ARRAY(ADDR(ELEMENTS(0)), TABLEAF) RDSTRG("What: ", WHAT) TYPE = LOOK UP(WHAT, TYPES, TOPSFI) WRS("NOT KNOWN") ANDRETURNIF TYPE < 0 ! J = - 1 CYCLE I = 1, 1, 10 J = I ANDEXITIF TYPE = INVALID(I) REPEAT UNLESS J = - 1 START WRS("NOT ALLOWED") RETURN FINISH ! GUAF(USER, FSYS) IF TABLE(TYPE)_HOWMANY = 1 START IF TABLE(TYPE)_IORS = 'I' THEN C RDINT("New value: ", FIELD(0)) ELSE C PROMPT("NEW VALUE: ") AND INSTRG(STRING(ADDR(FIELD(0)))) FINISHELSESTART LIM = TABLE(TYPE)_HOWMANY - 1 SPTEXTPOINTER = TABLE(TYPE)_TOSPTEXT UNLESS LIM < 0 START CYCLE I = 0, 1, LIM RDINT(SPTEXT(I + SPTEXTPOINTER), FIELD(I)) REPEAT FINISH FINISH ! IF TYPE = 38 START ! GET CURRENT VALUE J = DSFI(USER, FSYS, 38, 0, ADDR(FIELD(0))) ERROR("GET PRIV") ANDRETURNUNLESS J = 0 ! WRS("CURRENT PRIVILEGES ARE:") J = FIELD(0) IF J = 0 THEN WRS("*NONE*") ELSESTART CYCLE I = 0, 1, 31 WRS(PRIV(I)) IF J & 1 = 1 J = J >> 1 EXITIF J = 0 REPEAT FINISH WRS("1. TERMINATE 'PRIV: ' PROMPT WITH .END") WRS("2. 'G/R: ' PROMPT MEANS GIVE OR REMOVE PRIVILEGE.") WRS("REPLY 'G' OR 'R'") CYCLE RDSTRG("Priv: ", REPLY) PURGE(REPLY, " ") EXITIF REPLY = ".END" BITNO = LOOK UP(REPLY, PRIV, 31) IF BITNO < 0 THEN WRS(" NOT KNOWN") ELSESTART RDSTRG("G/R: ", GIVEORREMOVE) UNTIL C GIVEORREMOVE = "G" OR GIVEORREMOVE = "R" PATTERN = 1 << BITNO IF GIVEORREMOVE = "G" THEN C FIELD(0) = FIELD(0) ! PATTERN ELSE C FIELD(0) = FIELD(0) & ( ¬ PATTERN) FINISH REPEAT FINISH J = DSFI(USER, FSYS, TYPE, 1, ADDR(FIELD(0))) UNLESS J = 0 THEN ERROR("SET") ANDRETURN IF TYPE = 38 START WRS("PRIVILEGES ARE NOW:") J = FIELD(0) IF J = 0 THEN WRS("*NONE*") ELSESTART CYCLE I = 0, 1, 31 WRS(PRIV(I)) IF J & 1 = 1 J = J >> 1 EXITIF J = 0 REPEAT FINISH FINISH WRS("Finished O.K.") END ; ! SET ! !----------------------------------------------------------------------- ! EXTERNALROUTINE CREATE LOG FILE(STRING (255) S) RECORD (H F) NAME H STRING (255) USER, FILE INTEGER J, FSYS, AD INTEGER SEG, GAP RECORD (UINF) NAME UIN UIN == RECORD(9 << 18) SEG = 0 GAP = 0 GUAF(USER, FSYS) RDSTRG("Logfile: ", FILE) ! J = DCREATE(USER, FILE, FSYS, 256, 8) ->ERR UNLESS J = 0 ! J = DPERMISSION(USER, UIN_USER, "", FILE, FSYS, 2, 7) ->ERR UNLESS J = 0 ! J = DCONNECT(USER, FILE, FSYS, 3, 0, SEG, GAP) ->ERR UNLESS J = 0 ! AD = SEG << 18 H == RECORD(AD) H_NEXT FREE BYTE = 32 H_TXT REL ST = 32 H_MAXBYTES = 256 << 10 H_READ TO = 32 H_NEXT CYCLIC = 32 ! J = DSFI(USER, FSYS, 19, 1, ADDR(FILE)) RETURNIF J = 0 ERR: ERROR("CREATE LOG FILE") END ; ! CREATE LOG FILE ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SSFSTATUS(STRING (255) S) STRING (63) USER, FILE INTEGER FSYS, ACT, VALUE, J GUAFAF(USER, FSYS, FILE) RDINT("Act: ", ACT) RDINT("Value: ", VALUE) ! LOOP: J = DFSTATUS(USER, FILE, FSYS, ACT, VALUE) UDERRS(J) ! RDSTRG("File/.END: ", FILE) ->LOOP UNLESS FILE = ".END" OR FILE = ".E" END ; ! SSFSTATUS ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SSRENAME(STRING (255) S) STRING (31) USER, FILE, NEWNAME INTEGER FSYS, J GUAF(USER, FSYS) RDSTRG("File: ", FILE) RDSTRG("Newname: ", NEWNAME) J = DRENAME(USER, FILE, NEWNAME, FSYS) UDERRS(J) END ; ! SSRENAME ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SSDESTROY(STRING (255) S) STRING (31) USER, FILE INTEGER FSYS, J GUAFAF(USER, FSYS, FILE) UNTIL FILE = ".END" OR FILE = ".E" CYCLE J = DDESTROY(USER, FILE, "", FSYS, 0) UDERRS(J) RDSTRG("File/.END: ", FILE) REPEAT END ; ! SSDESTROY ! !----------------------------------------------------------------------- ! ROUTINE ASORTFILES(RECORD (OINFF) ARRAYNAME P, INTEGERARRAYNAME X, INTEGER N) ! DECLARE INTEGER ARRAY X, BOUNDS 1:NUM, IN CALLING ROUTINE !NOTIMP80 %RECORDSPEC P(OINFF) INTEGER I, J, K, M, W RETURNUNLESS N > 0 ! CYCLE I = 1, 1, N X(I) = I REPEAT ! M = 1 M = M << 1 WHILE M <= N M = M - 1 ! CYCLE M = M >> 1 EXITIF M = 0 CYCLE I = 1, 1, N - M K = I WHILE K > 0 CYCLE J = K + M ! EXITIF P(X(K))_NAME <= P(X(J))_NAME W = X(J) X(J) = X(K) X(K) = W ! K = K - M REPEAT REPEAT REPEAT END ; ! ASORT FILES ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SSFILES(STRING (255) S) CONSTINTEGER MAX= 512 STRING (31) USER INTEGERARRAY I(0:15) INTEGER J, FSYS, N, FROMREC, NGIVEN, TOT RECORD (OINFF) ARRAY FLIS(0:MAX) INTEGERARRAY X(1:MAX) GUAF(USER, FSYS) FROMREC = 0 NGIVEN = MAX; ! SET TO MAX PREPARED TO RECIEVE J = DFILENAMES(USER, FLIS, FROMREC, NGIVEN, N, FSYS, 0) WRSN("FLAG =", J) ANDRETURNIF J # 0 WRSN("NO OF RECORDS RETURNED =", NGIVEN) WRSN("NO OF FILES: ", N) IF NGIVEN > 15 START DEFINE("77,T#OUT") SELECT OUTPUT(77) FINISH ! FLIS(NGIVEN) = FLIS(0); ! for the sort routine IF NGIVEN > 0 THEN ASORT FILES(FLIS, X, NGIVEN) ! TOT = 0 J = 0 WHILE J < NGIVEN CYCLE J = J + 1 WRS(FLIS(X(J))_NAME) TOT = TOT + FLIS(X(J))_NKB REPEAT WRSN("CALCULATED KB =", TOT) J = DSFI(USER, FSYS, 30, 0, ADDR(I(0))) IF J = 0 THEN WRSN("KBYTES IN INDEX =", I(1)) ELSE WRSU("DSFI 30 ", J) IF NGIVEN > 15 START SELECT OUTPUT(0) CLOSE STREAM(77) CLEAR("77") WRS("T#OUT written") FINISH END ; ! SSFILES ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SSFFILES(STRING (255) S) CONSTINTEGER MAX= 512 STRING (31) USER INTEGERARRAY I(0:15) INTEGER J, FSYS, N, FROMREC, NGIVEN, TOT RECORD (OINFF) ARRAY FLIS(0:MAX) INTEGERARRAY X(1:MAX) ROUTINESPEC FQINFO(RECORD (OINFF) NAME X) GUAF(USER, FSYS) FROMREC = 0 NGIVEN = MAX; ! SET TO MAX PREPARED TO RECIEVE J = DFILENAMES(USER, FLIS, FROMREC, NGIVEN, N, FSYS, 0) WRSN("FLAG =", J) ANDRETURNIF J # 0 WRSN("NO OF RECORDS RETURNED =", NGIVEN) WRSN("NO OF FILES: ", N) IF NGIVEN > 15 START DEFINE("77,T#OUT") SELECT OUTPUT(77) FINISH ! WRS(" Epages Ownp Eep Use SSbyte Pool") FLIS(NGIVEN) = FLIS(0); ! for the sort routine IF NGIVEN > 0 THEN ASORT FILES(FLIS, X, NGIVEN) ! TOT = 0 J = 0 WHILE J < NGIVEN CYCLE J = J + 1 FQINFO(FLIS(X(J))) TOT = TOT + FLIS(X(J))_NKB REPEAT NEWLINE WRSN("CALCULATED KB =", TOT) J = DSFI(USER, FSYS, 30, 0, ADDR(I(0))) IF J = 0 THEN WRSN("TOT KBYTES", I(1)) ELSE WRSU("DSFI 30 ", J) IF NGIVEN > 15 START SELECT OUTPUT(0) CLOSE STREAM(77) CLEAR("77") WRS("T#OUT written") FINISH ! ROUTINE FQINFO(RECORD (OINFF) NAME X) !NOTIMP80 %RECORDSPEC X(OINFF) IF X_CODES & CHERSH # 0 THEN PRINTSYMBOL('*') ELSE SPACE SPACE PRINTSTRING(X_NAME) SPACES(14 - OUTPOS) IF X_NKB >> 2 > 15 THEN PRINTSYMBOL('X') ELSE SPACE PRINTSTRING(HTOS(X_NKB >> 2, 3)) WRITE(X_OWNP, 4) WRITE(X_EEP & 15, 4) WRITE(X_USE, 4) WRITE(X_SSBYTE, 4) WRITE(X_SP29, 4) IF X_CODES & UNAVA # 0 THEN PRINTSTRING("; UNAVA") IF X_CODES & PRIVAT # 0 THEN PRINTSTRING("; PRIVAT") IF X_CODES & VIOLAT # 0 THEN PRINTSTRING("; VIOL") IF X_CODES & TEMPFS # 0 THEN PRINTSTRING("; ") IF X_CODES & VTEMPF # 0 THEN PRINTSTRING("V") IF X_CODES & TEMPFS # 0 THEN PRINTSTRING("TEMPFI") IF X_CODES & NOARCH # 0 THEN PRINTSTRING("; NOARCH") IF X_CODES2 & (NEWGE ! OLDGE) # 0 THEN PRINTSTRING("; GENRS") IF X_CODES2 & WRCONN # 0 THEN PRINTSTRING("; WRCONN") IF X_CODES2 & DISCFI # 0 THEN PRINTSTRING("; DISCFI") NEWLINE END ; ! FQINFO ! !----------------------------------------------------------------------- ! END ; ! SSFFILES ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SSPERMISSIONS(STRING (255) S) RECORD (RETF) P STRING (31) FILE, USER INTEGER I, J, TYPE, FSYS ROUTINESPEC OUT(INTEGER A) GUAFAF(USER, FSYS, FILE) IF FILE # ".ALL" START J = DPERMISSION(USER, "", "", FILE, FSYS, 4, ADDR(P)) ! GIVE LIST FOR FILE TYPE = 4 IF J # 0 THEN ->MONPRM PRINTSTRING("OWNP: "); OUT(P_OWNP) PRINTSTRING("; EEP: "); OUT(P_EEP); NEWLINE I = 0 J = 16 WHILE J < P_BYTES CYCLE SPACE; PRINTSTRING(P_INDIV(I)_USER) OUT(P_INDIV(I)_UPRM); NEWLINE J = J + 8 I = I + 1 REPEAT FINISH ; ! S NOT "" J = DPERMISSION(USER, "", "", FILE, FSYS, 8, ADDR(P)) ! GIVE LIST FOR INDEX TYPE = 8 IF J # 0 THEN ->MONPRM PRINTSTRING("Whole-index permissions:") NEWLINE I = 0 J = 16 WHILE J < P_BYTES CYCLE SPACE PRINTSTRING(P_INDIV(I)_USER) OUT(P_INDIV(I)_UPRM); NEWLINE J = J + 8 I = I + 1 REPEAT RETURN MONPRM: PRINTSTRING("DPERM"); WRITE(TYPE, 1) PRINTSTRING(" FLAG ="); WRITE(J, 1); NEWLINE RETURN ROUTINE OUT(INTEGER A) SPACE IF A & 4 # 0 THEN PRINTSTRING("X") IF A & 2 # 0 THEN PRINTSTRING("W") IF A & 1 # 0 THEN PRINTSTRING("R") END ; ! OUT ! !----------------------------------------------------------------------- ! END ; ! SSPERMISSIONS ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SSTRANSFER(STRING (255) S) STRING (31) USER1, USER2, FILE1, FILE2 INTEGER FSYS1, FSYS2, J WRS("FROM :-") GUAFAF(USER1, FSYS1, FILE1) WRS("TO :-") GUAFAF(USER2, FSYS2, FILE2) J = DTRANSFER(USER1, USER2, FILE1, FILE2, FSYS1, FSYS2, 1) WRSN("FLAG =", J) END ; ! SSTRANSFER ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SSFINFO(STRING (255) S) RECORD (DFINFRECF) X STRING (63) USER, FILE INTEGER J, FSYS ! GUAFAF(USER, FSYS, FILE) X = 0 J = DFINFO(USER, FILE, FSYS, ADDR(X)) IF J # 0 THEN UDERRS(J) ANDRETURN IF X_CODES & CHERSH # 0 THEN PRINTSYMBOL('*') AND SPACE PRINTSTRING(FILE.":") PRINTSTRING(" CONN ") IF X_CONSEG > 15 THEN PRINTSYMBOL('X') PRINTSTRING(HTOS(X_CONSEG, 2)) PRINTSTRING("; PGS ") IF X_NKB >> 2 > 15 THEN PRINTSYMBOL('X') PRINTSTRING(HTOS(X_NKB >> 2, 3)) PRINTSTRING("; OWP"); WRITE(X_RUP, 1) PRINTSTRING("; EEP"); WRITE(X_EEP & 15, 1) PRINTSTRING("; APF "); PRINTSTRING(HTOS(X_APF, 3)) PRINTSTRING("; USERS"); WRITE(X_USE, 1) PRINTSTRING("; POOL"); WRITE(X_SSBYTE, 1) IF LENGTH(X_OFFER) = 6 THEN PRINTSTRING("; OFF: ".X_OFFER) IF X_CODES & VIOLAT # 0 THEN PRINTSTRING("; VIOL") IF X_CODES & TEMPFS # 0 THEN PRINTSTRING("; ") IF X_CODES & VTEMPF # 0 THEN PRINTSTRING("V") IF X_CODES & TEMPFS # 0 THEN PRINTSTRING("TEMPFI") IF X_CODES & NOARCH # 0 THEN PRINTSTRING("; NOARCH") IF X_CODES2 & (NEWGE ! OLDGE) # 0 THEN PRINTSTRING("; GENRS") NEWLINE WRSN("SSBYTE =", X_SSBYTE) IF X_SSBYTE # 0 END ; ! SSFINFO ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SET SSBYTE(STRING (255) S) STRING (31) USER, FILE INTEGER FSYS, J, VALUE GUAFAF(USER, FSYS, FILE) RDINT("SSBYTE VALUE: ", VALUE) J = DFSTATUS(USER, FILE, FSYS, 18, VALUE) UDERRS(J) END ; ! SET SSBYTE ! !----------------------------------------------------------------------- ! ROUTINE DOARCHBIT(INTEGER OP) STRING (31) USER, FILE INTEGER FSYS, J GUAFAF(USER, FSYS, FILE) J = DFSTATUS(USER, FILE, FSYS, OP, 0) UDERRS(J) END ; ! DOARCHBIT ! !----------------------------------------------------------------------- ! EXTERNALROUTINE ARCHOFF(STRING (255) S) DOARCHBIT(17) END ; ! ARCHOFF ! !----------------------------------------------------------------------- ! EXTERNALROUTINE ARCHON(STRING (255) S) DOARCHBIT(16) END ; ! ARCHON ! !----------------------------------------------------------------------- ! ROUTINE NAMESORT(RECORD (NNEF) ARRAYNAME P, INTEGERARRAYNAME X, INTEGER N) ! DECLARE INTEGER ARRAY X, BOUNDS 1:NUM, IN CALLING ROUTINE !NOTIMP80 %RECORDSPEC P(NNEF) INTEGER I, J, K, M, W RETURNUNLESS N > 0 ! CYCLE I = 1, 1, N X(I) = I REPEAT ! M = 1 M = M << 1 WHILE M <= N M = M - 1 ! CYCLE M = M >> 1 EXITIF M = 0 CYCLE I = 1, 1, N - M K = I WHILE K > 0 CYCLE J = K + M ! EXITIF P(X(K))_SURNAME <= P(X(J))_SURNAME W = X(J) X(J) = X(K) X(K) = W ! K = K - M REPEAT REPEAT REPEAT END ; ! NAMESORT ! !----------------------------------------------------------------------- ! ROUTINE ASORT(RECORD (NNEF) ARRAYNAME P, INTEGERARRAYNAME X, INTEGER N) ! DECLARE INTEGER ARRAY X, BOUNDS 1:NUM, IN CALLING ROUTINE !NOTIMP80 %RECORDSPEC P(NNEF) INTEGER I, J, K, M, W RETURNUNLESS N > 0 ! CYCLE I = 1, 1, N X(I) = I REPEAT ! M = 1 M = M << 1 WHILE M <= N M = M - 1 ! CYCLE M = M >> 1 EXITIF M = 0 CYCLE I = 1, 1, N - M K = I WHILE K > 0 CYCLE J = K + M ! EXITIF P(X(K))_NN_NAME <= P(X(J))_NN_NAME W = X(J) X(J) = X(K) X(K) = W ! K = K - M REPEAT REPEAT REPEAT END ; ! ASORT ! !----------------------------------------------------------------------- ! ROUTINE NSORT(RECORD (NNEF) ARRAYNAME P, INTEGERARRAYNAME X, INTEGER N) ! DECLARE INTEGER ARRAY X, BOUNDS 1:NUM, IN CALLING ROUTINE !NOTIMP80 %RECORDSPEC P(NNEF) INTEGER I, J, K, M, W RETURNUNLESS N > 0 ! CYCLE I = 1, 1, N X(I) = I REPEAT ! M = 1 M = M << 1 WHILE M <= N M = M - 1 ! CYCLE M = M >> 1 EXITIF M = 0 CYCLE I = 1, 1, N - M K = I WHILE K > 0 CYCLE J = K + M ! EXITIF P(X(K))_NN_INDNO <= P(X(J))_NN_INDNO W = X(J) X(J) = X(K) X(K) = W ! K = K - M REPEAT REPEAT REPEAT END ; ! NSORT ! !----------------------------------------------------------------------- ! INTEGERFN ALPHA(INTEGER CH) RESULT = 1 IF 'A' <= CH <= 'Z' OR 'a' <= CH <= 'z' RESULT = 0 END ; ! ALPHA ! !----------------------------------------------------------------------- ! ROUTINE UPSUR(STRINGNAME SURNAME) INTEGER J J = 0 WHILE J < LENGTH(SURNAME) CYCLE J = J + 1 CHARNO(SURNAME, J) = CHARNO(SURNAME, J) & ( ¬ X'20') REPEAT END ; ! UPSUR ! !----------------------------------------------------------------------- ! ROUTINE SEPSUR(STRING (255) S, STRINGNAME INITS, SURNAME) INTEGER L, J, SURPT, LETT FOUND, CH STRING (63) REST, WK, A, B, REST2 SURPT = 1 LETT FOUND = 0 L = LENGTH(S) L = 19 IF L > 19 J = L WHILE J > 0 CYCLE CH = CHARNO(S, J) IF ALPHA(CH) # 0 THEN LETT FOUND = 1 ! We are looking for the R-most '.' having chars to the right of it IF CH = '.' THEN SURPT = J + 1 ANDEXIT J = J - 1 REPEAT WK = FROMSTR(S, SURPT, L) WK = A.B WHILE WK - > A.(" ").B INITS = FROMSTR(S, 1, SURPT - 1) INITS = A.B WHILE INITS - > A.(" ").B IF INITS - > REST.("DR").B AND REST = "" THEN INITS = "Dr".B IF INITS - > REST.("MR").B AND REST = "" THEN INITS = "Mr".B IF INITS - > REST.("MRS").B AND REST = "" THEN INITS = "Mrs".B IF INITS - > REST.("MS").B AND REST = "" THEN INITS = "Ms".B IF INITS - > REST.("ST").B AND REST = "" THEN INITS = "St".B ! Put the name except first char into lower case J = 1 WHILE J < LENGTH(WK) CYCLE J = J + 1 CH = CHARNO(WK, J) IF ALPHA(CH) # 0 AND CH < 'a' THEN CHARNO(WK, J) = CH ! X'20' REPEAT IF WK - > REST2.("Mc").REST AND REST2 = "" THEN C CHARNO(WK, 3) = CHARNO(WK, 3) & ( ¬ X'20') IF WK - > REST2.("Mac").REST AND REST2 = "" THEN C CHARNO(WK, 4) = CHARNO(WK, 4) & ( ¬ X'20') SURNAME = WK END ; ! SEPSUR ! !----------------------------------------------------------------------- ! ROUTINE UPDATE DIRECTORY(RECORD (NNEF) ARRAYNAME NN, INTEGERARRAYNAME ALPH, INTEGER N) !NOTIMP80 %RECORDSPEC NN(NNEF) INTEGER J, FSYS STRING (63) INITS, SUR STRING (6) USER DEFINE("62,SS#KK,1023") SELECT OUTPUT(62) PRINTSTRING("Directory of Usernames") SPACES(10) PRINTSTRING("Updated at ") WRSSS(TIME, " on ", DATE) J = 0 WHILE J < N CYCLE J = J + 1 USER = NN(ALPH(J))_NN_NAME FSYS = NN(ALPH(J))_FSYS INITS = NN(ALPH(J))_INITS SUR = NN(ALPH(J))_SURNAME IF INITS # "" AND SUR # "" START PRINTSTRING(INITS) SPACES(6 - LENGTH(INITS)) PRINTSTRING(SUR) SPACES(14 - LENGTH(SUR)) PRINTSTRING(USER) PRINTSTRING(" Fsys") WRITE(FSYS, 2) SPACES(5) UPSUR(SUR) WRS(SUR) FINISH REPEAT SELECT OUTPUT(0) CLOSE STREAM(62) CLEAR("62") IF EXIST("USERNAMES") = 0 THEN RENAME("SS#KK,USERNAMES") ELSE C NEWGEN("SS#KK,USERNAMES") END ; ! UPDATE DIRECTORY ! !----------------------------------------------------------------------- ! ROUTINE FILLNNE(RECORD (NNEF) NAME NN) !NOTIMP80 %RECORDSPEC NN(NNEF) INTEGER K, FSYS, AD INTEGERARRAY SCRATCH(1:12) STRING (31) INITS, SUR STRING (6) USER STRING (31) NAME SSCRATCH AD = ADDR(SCRATCH(1)) SSCRATCH == STRING(AD) USER = NN_NN_NAME FSYS = NN_FSYS ! ACR K = DSFI(USER, FSYS, 7, 0, ADDR(NN_ACR)) IF K # 0 THENMONITOR ! MAXFILE K = DSFI(USER, FSYS, 12, 0, ADDR(NN_MAXFILE)) IF K # 0 THENMONITOR ! MAXKB K = DSFI(USER, FSYS, 11, 0, ADDR(NN_MAXKB)) IF K # 0 THENMONITOR ! CONCURR K = DSFI(USER, FSYS, 14, 0, AD) IF K # 0 THENMONITOR NN_IMAX = SCRATCH(1) NN_BMAX = SCRATCH(2) NN_TMAX = SCRATCH(3) ! KBYTES OF FILE SPACE K = DSFI(USER, FSYS, 30, 0, AD) IF K # 0 THENMONITOR NN_TOTKB = SCRATCH(2) ! ARCHIVE INDEX DATA K = DSFI(USER, FSYS, 31, 0, AD) IF K # 0 THENMONITOR NN_AFILES = SCRATCH(1) ! NAME AND INITIALS K = DSFI(USER, FSYS, 18, 0, AD) IF K # 0 THENMONITOR SEPSUR(SSCRATCH, INITS, SUR) NN_INITS <- INITS NN_SURNAME = SUR ! DELIVERY K = DSFI(USER, FSYS, 1, 0, AD) IF K # 0 THENMONITOR NN_DELIV = SSCRATCH END ; ! FILLNNE ! ! ! ROUTINE PNNT(RECORD (NNEF) ARRAYNAME NN, INTEGERARRAYNAME ALPH, INTEGER N) !NOTIMP80 %RECORDSPEC NN(NNEF) INTEGER J, ENT, FSYS, L STRING (6) USER PRINTSTRING("Dated ") PRINTSTRING(DATE) SPACES(31) WRS("---Archive Index----") WRS(" Max Max Con- Total Files Kb Used Size") PRINTSTRING("FSYS Name Kb No. ACR File Tot curr Kbytes") SPACES(22) WRS("Name Delivery") WRS(" Kb Kb I.B.T Mb FDS Kb") ENT = 0 WHILE ENT < N CYCLE ENT = ENT + 1 L = ALPH(ENT) USER = NN(L)_NN_NAME FSYS = NN(L)_FSYS WRITE(FSYS, 2) SPACE PRINTSTRING(USER) WRITE(NN(L)_NN_KB, 1) SPACE J = NN(L)_NN_INDNO PRINTSTRING(HTOS(J << 10 ! J, 5)) ! ACR IF NN(L)_ACR = 0 THEN SPACES(3) ELSE WRITE(NN(L)_ACR, 2) ! MAXFILE WRITE(NN(L)_MAXFILE, 5) ! MAXKB WRITE(NN(L)_MAXKB, 5) ! CONCURR SPACES(2) PRINTSTRING(ITOS(NN(L)_IMAX).".".ITOS(NN(L)_BMAX).".".ITOS(NN(L) C _TMAX)) ! KBYTES OF FILE SPACE WRITE(NN(L)_TOTKB, 5) ! ARCHIVE INDEX DATA SPACES(2) WRITE(NN(L)_AFILES, 4) SPACES(15) PRINTSTRING(NN(L)_INITS) SPACES(6 - LENGTH(NN(L)_INITS)) PRINTSTRING(NN(L)_SURNAME) SPACES(14 - LENGTH(NN(L)_SURNAME)) ! DELIVERY SPACES(2) WRS(NN(L)_DELIV) REPEAT END ; ! PNNT ! !----------------------------------------------------------------------- ! ROUTINE DUPLICATES(RECORD (NNEF) ARRAYNAME TT, INTEGER N, INTEGERNAME SORTBYUSE, INTEGERARRAYNAME ALPH) !NOTIMP80 %RECORDSPEC TT(NNEF) INTEGER J, K, PFSYS STRING (6) PNAM STRING (255) DUPL ROUTINESPEC PNAME DUPL = " The following names occur on more discs than one, as shown: Name occurs on FSYS " IF SORTBYUSE = 0 THEN ASORT(TT, ALPH, N) ! ! NOW CYCLE UP WRITING OUT DUPLICATES AND CLEARING OUT NAME WHEN ! NOTED ONCE. J = 0 WHILE J < N CYCLE J = J + 1 IF LENGTH(TT(ALPH(J))_NN_NAME) = 6 START PNAM = TT(ALPH(J))_NN_NAME PFSYS = TT(ALPH(J))_FSYS K = J WHILE K < N CYCLE K = K + 1 IF TT(ALPH(J))_NN_NAME = TT(ALPH(K))_NN_NAME START PNAME WRITE(TT(ALPH(K))_FSYS, 3); ! (THEN DULICATE) TT(ALPH(K))_NN_NAME = "" FINISHELSESTART J = K - 1 EXIT FINISH REPEAT FINISH REPEAT NEWLINE RETURN ROUTINE PNAME RETURNIF PNAM = "" IF DUPL # "" THEN PRINTSTRING(DUPL) AND DUPL = "" NEWLINE PRINTSTRING(PNAM) WRITE(PFSYS, 3) PNAM = "" END ; ! PNAME ! !----------------------------------------------------------------------- ! END ; ! DUPLICATES ! !----------------------------------------------------------------------- ! EXTERNALROUTINE LIST NNT(STRING (255) S) ! INTEGERARRAY ALPH, ALPHSUR(1:MAXUSERS) INTEGERARRAY A(0:99) RECORD (NNEF) ARRAYNAME TT RECORD (NNF) ARRAY NN(0:TOPNNT) RECORD (NNEF) ARRAY NNE(0:MAXUSERS - 1) RECORD (NNEF) ARRAYFORMAT FF(0:MAXUSERS - 1) INTEGER J, NSYS, FSYS, COMPLETE, TEMP, FAD, F, TOT, N INTEGER SORTBYIND, SORTBYSUR, SORTBYUSE, WANTNAMES STRING (31) FILE, REPLY WRS(VSN) FAD = NWFILEAD("T#K", 128) RETURNIF FAD = 0 SORTBYIND = FALSE SORTBYSUR = FALSE SORTBYUSE = FALSE WRS(" '-1' for all FSYS") RDINT("Fsys: ", FSYS) UNTIL - 1 <= FSYS <= 99 IF FSYS < 0 THEN GETAVFSYS(NSYS, A) ELSE A(0) = FSYS AND NSYS = 1 IF NSYS = 1 START WRS("Sort by username or by index no? Reply 'USE' or 'IND'") PROMPT("Sort type? ") UCSTRG(REPLY) UNTIL REPLY = "USE" OR REPLY = "IND" IF REPLY = "IND" THEN SORTBYIND = TRUE FINISHELSESTART SORTBYIND = FALSE WRS("Sort by username or by surname or both? Reply 'USE' or 'SUR' or 'BOTH'") PROMPT("Sort type? ") UCSTRG(REPLY) UNTIL C REPLY = "USE" OR REPLY = "SUR" OR REPLY = "BOTH" IF REPLY = "USE" OR REPLY = "BOTH" THEN SORTBYUSE = TRUE IF REPLY = "SUR" OR REPLY = "BOTH" THEN SORTBYSUR = TRUE WRS("Do you wish the file USERNAMES to be created or updated in your process? Reply 'YES','Y','NO' or 'N'") PROMPT("Usernames? ") UCSTRG(REPLY) UNTIL C REPLY = "YES" OR REPLY = "Y" OR REPLY = "NO" OR REPLY = "N" IF REPLY = "YES" OR REPLY = "Y" THEN WANTNAMES = TRUE ELSE C WANTNAMES = FALSE FINISH PROMPT("To file/dev: ") UCSTRG(FILE) DEFINE("61,".FILE.",1023") SELECT OUTPUT(61) ! ! SORT FILE SYSTEMS INTO ASCENDING ORDER UNTIL COMPLETE # 0 CYCLE COMPLETE = 1 J = 0 WHILE J < NSYS - 1 CYCLE IF A(J) > A(J + 1) START COMPLETE = 0 TEMP = A(J) A(J) = A(J + 1) A(J + 1) = TEMP FINISH J = J + 1 REPEAT REPEAT ! ! Get usernames, create array for sorting each FSYS, and also add ! the names to the global array TOT. J = 0 TT == ARRAY(FAD, FF) TOT = 0 F = 0 WHILE F < NSYS CYCLE FSYS = A(F) J = GET USNAMES2(NN, N, FSYS) IF J # 0 START PRINTSTRING("GETUSNAMES FOR FSYS ") WRITE(FSYS, 1) WRSN(" FAILS ", J) RETURN FINISH ! J = N WHILE J > 0 CYCLE NNE(J)_NN = NN(J-1) NNE(J)_FSYS = FSYS J = J - 1 REPEAT ! NSORT(NNE, ALPH, N) CYCLE J = 1, 1, N FILLNNE(NNE(ALPH(J))) REPEAT ! %IF SORTBYIND=FALSE %THEN ASORT(NNE,ALPH,N) %ELSE NSORT(NNE,ALPH,N) IF SORTBYIND = FALSE THEN ASORT(NNE, ALPH, N) PNNT(NNE, ALPH, N) IF NSYS = 1 ! MOVE THIS FSYS'S NAMES INTO THE BIG ARRAY ! CAN IT BE DONE? IF TOT + N >= MAXUSERS START ! NO SELECT OUTPUT(0) CLOSE STREAM(61) CLEAR("61") PRINTSTRING("Too many usernames(") WRITE(MAXUSERS, 1) PRINTSTRING("). Program terminated.") NEWLINE PRINTSTRING("Amend and re-compile.") NEWLINE RETURN FINISH MOVE(N * NNEFLEN, ADDR(NNE(1)), ADDR(TT(TOT + 1))) TOT = TOT + N F = F + 1 REPEAT IF NSYS > 1 START IF SORTBYSUR = TRUE START PRINTSTRING(" Alphabetic by surname ") NAMESORT(TT, ALPHSUR, TOT) PNNT(TT, ALPHSUR, TOT) FINISH IF SORTBYUSE = TRUE AND SORTBYSUR = TRUE THEN NEWPAGE IF SORTBYUSE = TRUE START PRINTSTRING(" Alphabetic by username ") ASORT(TT, ALPH, TOT) PNNT(TT, ALPH, TOT) FINISH FINISH DUPLICATES(TT, TOT, SORTBYUSE, ALPH) SELECT OUTPUT(0) CLOSE STREAM(61) CLEAR("61") IF NSYS > 1 AND WANTNAMES = TRUE START NAMESORT(TT, ALPHSUR, TOT) IF SORTBYSUR = FALSE UPDATE DIRECTORY(TT, ALPHSUR, TOT) FINISH NEWLINE PRINTSTRING("LISTNNT ends normally") END ; ! LIST NNT ! !----------------------------------------------------------------------- ! EXTERNALROUTINE USERNAMES(STRING (255) S) LISTNNT(S) END ; ! USERNAMES ! !----------------------------------------------------------------------- ! !************************** END OF LISTNNT ROUTINES **************** ! !=================================================================== !* * ! !----------------------------------------------------------------------- ! INTEGERFN IHOLESHIST(INTEGER FSYS, INTEGERARRAYNAME A) INTEGERARRAY BITMAP(0:5119) INTEGER I, J, LO, HI, W, N, S FILL((TOPSI + 1) << 2, ADDR(A(0)), X'00'); ! ZERO ARRAY A J = DSYSAD(0, ADDR(BITMAP(0)), FSYS) UDERRS(J) ANDRESULT = - J UNLESS J = 0 J = FBASE(LO, HI, FSYS) ! USER FILES RUN FROM BIT LO+X'100' TO HI ! WORD ALIGN LO = (LO + X'100') >> 5 HI = HI >> 5 CYCLE I = LO, 1, HI W = BITMAP(I) ! N = 0; ! number of consecutive zero bits S = 32; ! number of bits remaining to be examined WHILE S > 0 CYCLE IF W = 0 START A(S) = A(S) + 1 EXIT FINISH IF W < 0 START IF N > 0 START A(N) = A(N) + 1 N = 0 FINISH FINISHELSE N = N + 1 W = W << 1 S = S - 1 REPEAT ! REPEAT RESULT = 0 END ; ! IHOLESHIST ! !----------------------------------------------------------- ! ROUTINE ISECTHIST(INTEGER FSYS, INTEGERARRAYNAME A) RECORD (NNF) ARRAY USERS(0:TOPNNT) RECORD (DAF) DA INTEGER I, J, NUSERS, FROMREC, NGIVEN, NFILES, K RECORD (OINFF) ARRAY FLIS(0:255) STRING (31) FILE FILL((TOPSI + 1) << 2, ADDR(A(0)), X'00') J = GETUSNAMES2(USERS, NUSERS, FSYS) UDERRS(J) ANDRETURNUNLESS J = 0 NUSERS = NUSERS - 1 CYCLE I = 0, 1, NUSERS NGIVEN = 256 FROMREC = 0 J = DFILENAMES(USERS(I)_NAME, FLIS, FROMREC, NGIVEN, NFILES, FSYS, 0) UDERRS(J) ANDRETURNUNLESS J = 0 NFILES = NFILES - 1 UNLESS NFILES < 0 START CYCLE K = 0, 1, NFILES FILE = FLIS(K)_NAME J = DGETDA(USERS(I)_NAME, FILE, FSYS, ADDR(DA)) UDERRS(J) ANDRETURNUNLESS J = 0 A(DA_SECTSI) = A(DA_SECTSI) + DA_NSECTS - 1 A(DA_LASTSECT) = A(DA_LASTSECT) + 1 REPEAT FINISH REPEAT RETURN END ; ! ISECTHIST ! !---------------------------------------------------- ! ROUTINE OUTHISTO(INTEGER FSYS, INTEGERARRAYNAME A) INTEGER I, J, L, D INTEGERARRAY P(0:TOPSI) FILL((TOPSI + 1) << 2, ADDR(P(0)), X'00') WRSN("FSYS", FSYS) ! D = 10000 CYCLE L = 0, 1, 4 CYCLE J = 1, 1, TOPSI I = A(J) // D IF I > 0 OR P(J) = 1 OR L = 4 THEN C WRITE(I, 1) AND P(J) = 1 ELSE SPACES(2) A(J) = A(J) - D * I REPEAT NEWLINE D = D // 10 REPEAT NEWLINE CYCLE J = 1, 1, TOPSI PRINTSTRING("--") REPEAT NEWLINE I = 1 CYCLE J = 1, 1, TOPSI WRITE(I, 1) IF I = 9 THEN I = 0 ELSE I = I + 1 REPEAT NEWLINE END ; ! OUTHISTO ! !----------------------------------------------------------------------- ! EXTERNALROUTINE HOLES HIST(STRING (255) S) INTEGERARRAY A(0:99) INTEGERARRAY HISTO(0:TOPSI) INTEGER NSYS, I, FLAG GET FSYSS(A, NSYS) CYCLE I = 0, 1, NSYS - 1 ! HOLES PRINTSTRING("Holes on ") FLAG = IHOLESHIST(A(I), HISTO); ! VALUE NOT IMPORTANT HERE OUTHISTO(A(I), HISTO) ! SECTIONS PRINTSTRING("Sections on ") ISECTHIST(A(I), HISTO) OUTHISTO(A(I), HISTO) REPEAT END ; ! HOLES HIST ! !----------------------------------------------------------------------- ! EXTERNALROUTINE FSYSSTART(STRING (255) S) ! Give the start bitno of the user files on chosen FSYS. INTEGER LOWD, HIWD, FSYS, J RDFSYS("Fsys: ", FSYS) J = FBASE(LOWD, HIWD, FSYS) PHEX(LOWD + X'100') SPACES(2) PHEX(HIWD) END ; ! FSYSSTART ! !-------------------------------------------------------- ! INTEGERFN PERCENT(INTEGER FSYS) INTEGERARRAY BITMAP(0:5119) INTEGER SET, I, J, W, LO, HI J = DSYSAD(0, ADDR(BITMAP(0)), FSYS) UDERRS(J) ANDRESULT = J UNLESS J = 0 J = FBASE(LO, HI, FSYS) LO = (LO + X'100') >> 5; ! INTEGER START OF USER FILES HI = HI >> 5; ! END OF USER FILES SET = 0 CYCLE I = LO, 1, HI W = BITMAP(I) WHILE W # 0 CYCLE SET = SET + 1 *LSS_W *ST_ TOS *USB_1 *AND_ TOS *ST_W REPEAT REPEAT PRINTSTRING("FSYS") WRITE(FSYS, 1) WRSNS(" is", (SET * 100) // (HI - LO + 1) << 5, "% FULL") RESULT = 0 END ; ! PERCENT ! !----------------------------------------------------------------------- ! EXTERNALROUTINE HOW FULL(STRING (255) S) INTEGER J, NSYS, FLAG INTEGERARRAY A(0:99) GET FSYSS(A, NSYS) J = 0 WHILE J < NSYS CYCLE FLAG = PERCENT(A(J)) J = J + 1 REPEAT END ; ! HOW FULL ! !----------------------------------------------------------------------- ! EXTERNALROUTINE HOW FRAG(STRING (255) S) INTEGER J, NSYS, LO, HI, I, FRAGS, FLAG INTEGERARRAY A(0:99), HISTO(0:TOPSI) GETFSYSS(A, NSYS) I = 0 WHILE I < NSYS CYCLE FLAG = IHOLESHIST(A(I), HISTO); ! VALUE UNIMPORTANT HERE J = FBASE(LO, HI, A(I)) FRAGS = 0 CYCLE J = TOPSI - 1, - 1, 1 FRAGS = FRAGS + HISTO(J) * J; ! PAGES IN FRAGMENTS REPEAT PRINTSTRING("Fsys") WRITE(A(I), 2) PRINT(FRAGS * 100 / (HI - LO - X'100'), 10, 1) PRINTSTRING("% Fragmented ") I = I + 1 REPEAT RETURN END ; ! HOWFRAG ! !----------------------------------------------------------------- ! ! ! ! INTEGERFN ITRANSFER(STRING (31)I1, I2, F1, F2, INTEGER FSYS1, FSYS2, TYPE) INTEGER J, ADR, I, PT RECORD (DFINFRECF)REC RECORD (RETF)PERM RECORD (INDIVF)NAME P ADR = ADDR(REC) J = DFINFO(I1, F1, FSYS1, ADR) -> OUT UNLESS J = 0 ! UNLESS REC_CODES & OFFER = 0 START J = DOFFER(I1, "", F1, FSYS1); ! discard 'offers' -> OUT UNLESS J = 0 FINISH ! PERM = 0 J = DPERMISSION(I1, "", "", F1, FSYS1, 4, ADDR(PERM)); ! get file list -> OUT UNLESS J = 0 ! J = DTRANSFER(I1, I2, F1, F2, FSYS1, FSYS2, TYPE) -> OUT UNLESS J = 0 ! J = DFSTATUS(I2, F2, FSYS2, 1, 0) UNLESS REC_CODES & CHERSH = 0 -> OUT UNLESS J = 0 J = DFSTATUS(I2, F2, FSYS2, 8, 0) UNLESS REC_CODES & PRIVAT = 0 -> OUT UNLESS J = 0 J = DFSTATUS(I2, F2, FSYS2, 17, 0) UNLESS REC_CODES & NOARCH = 0 -> OUT UNLESS J = 0 J = DFSTATUS(I2, F2, FSYS2, 18, REC_SSBYTE) -> OUT UNLESS J = 0 J = DFSTATUS(I2, F2, FSYS2, 13, REC_ARCH) -> OUT UNLESS J = 0 ! I = 0 PT = 16 WHILE PT < PERM_BYTES CYCLE P == PERM_INDIV(I) J = DPERMISSION(I2, P_USER, "", F2, FSYS2, 2, P_UPRM) -> OUT UNLESS J = 0 I = I + 1 PT = PT + 8 REPEAT ! J = DPERMISSION(I2, "", "", F2, FSYS2, 0, PERM_OWNP) -> OUT UNLESS J = 0 J = DPERMISSION(I2, "", "", F2, FSYS2, 1, PERM_EEP) -> OUT UNLESS J = 0 OUT: RESULT = J END ; ! ITRANSFER ! ! ! INTEGERFN PHYSICAL SIZE KB(STRING (11) USER, FILE, INTEGER FSYS) ! Result is physical size of FILE in Kbytes, or zero if cannot obtain for ! any reason. INTEGER J RECORD (DFINFRECF) X J = DFINFO(USER, FILE, FSYS, ADDR(X)) RESULT = X_NKB IF J = 0 WRSU("DFINFO ", J) RESULT = 0 END ; ! PHYSICAL SIZE KB ! !------------------------------------------------------------------------------- ! INTEGERFN FILE EEP(STRING (11) USER, FILE, INTEGER FSYS) INTEGER J RECORD (DFINFRECF) X J = DFINFO(USER, FILE, FSYS, ADDR(X)) RESULT = X_EEP IF J = 0 WRSU("DFINFO ", J) RESULT = - 1 END ; ! FILE EEP ! !------------------------------------------------------------------------------- ! INTEGERFN INDEX SIZE(STRING (6) USER, INTEGER FSYS, INTEGERNAME KB, MARK) INTEGER J INTEGERARRAY N(0:63) J = DSFI(USER, FSYS, 4, 0, ADDR(N(0))) IF J = 0 START KB = N(3) MARK = KB & 1 KB = KB + MARK FINISH RESULT = J END ! !----------------------------------------------------------------------- ! INTEGERFN IMOVEI(STRING (6) OLDUSER, NEWUSER, INTEGER MODE, OLDFSYS, NEWFSYS, DO IRENAME) ! Transfers (for MODE = TRANSFER) or copies (for MODE = COPY) all ! files belonging to OLDUSER to NEWUSER. ! ! The parameter DO IRENAME is set to RENAMEOLD when doing MOVE INDEX or ! REFRESH INDEX, but to NORENAME n the case of COPY INDEX ! ! If any file cannot be moved because it's in use a prompt appears ! "Continue? ". If reply "NO" is given the index is not moved, and ! no side effects have occurred. ! ! NEWUSER must already have been created, but all SFI data (BASEFILE, ! Delivery, etc., etc.) is transferred. ! ! Result is 0 if move is successfully completed (even if some files ! cannot actually be moved). ! 1 if move is not attempted due to whole-index-type failure ! or because No option is given to Continue? CONSTBYTEINTEGERARRAY XFER(0:TOPSFI)= C 1,1,1,1,0,0,0,1,0,0, 1,1,1,0,1,1,0,0,1,1, 0,0,0,0,0,0,0,0,0,0, 0,0,1,1,0,1,1,1,1,1, 0,1,0,1,1 ! RECORD (RETF) P ! ! RECORD (OINFF) ARRAY FLIS(0:MAXFILES - 1) ! INTEGERARRAY INF(0:63) ! INTEGER I, J, CODES, CODES2, N, X, TYPE, FROMREC, NGIVEN INTEGER GOOD, BAD, PT, USE, CONDITION, SAVE MAXKB, SAVE MAXFILE STRING (31) S, FILE, ERRFILE ! STRING (6) USER ! CONSTSTRING (31) ARRAY DF(0:8)= C "DSFI", "DFSTATUS", "DPERMISSION", "DTRANSFER", "DFILENAMES", "DOFFER", "DRENAME INDEX", "DNEWUSER", "DDELUSER" ! CONSTSTRING (19) ARRAY NOGO(1:4)= C "UNAVA/VIOLAT set", "has use count =", "has WRCONN set", "has generations" ! ROUTINE VDERRS(INTEGER DIRFN, TYPE, FLAG) STRING (31) S RETURNIF FLAG = 0 IF ERRFILE # "" START PRINTSTRING("FILE: ") PRINTSTRING(ERRFILE) SPACES(12 - LENGTH(ERRFILE)) ERRFILE = "" FINISHELSE SPACES(18) WRSSNSS(DF(DIRFN), " TYPE =", TYPE, " FLAG =", DERRS(FLAG)) END ; ! VDERRS ! INTEGERFN DPERM(STRING (6) TO USER, INTEGER ACT, ADR OR PERM) STRING (6) OWNER INTEGER FSYS, J IF ACT = GETILIST OR ACT = GETFLIST START OWNER = USER FSYS = OLDFSYS FINISHELSESTART OWNER = NEWUSER FSYS = NEWFSYS FINISH J = DPERMISSION(OWNER, TO USER, "", FILE, FSYS, ACT, ADR OR PERM) VDERRS(PERM, ACT, J) UNLESS J = 0 RESULT = J END ; ! DPERM ! ! ! ERRFILE = "" FROMREC = 0 NGIVEN = MAXFILES; ! SET THIS PARAM TO MAX ACCEPTABLE SAVE MAXFILE = - 1; ! to hold user's MAXFILE until after the transfer ! Clear recordarray to zero. For a screwed index, we may get back ! fewer records than specified by NGIVEN. This would lead to UNASSIGNED ! VARIABLE, but this way we will smply get a null filename. CYCLE J = 0, 1, MAXFILES - 1 FLIS(J) = 0 REPEAT ! GET LIST OF FILENAMES AND SEE HOW MANY WE CAN'T ACTUALLY TRANSFER J = DFILENAMES(OLD USER, FLIS, FROMREC, NGIVEN, N, OLDFSYS, 0) IF J # 0 START VDERRS(FILEN, 0, J) ->ABANDON FINISH ! WRSN("Number of files given =", NGIVEN) WRSN("Total number of files =", N) ->ABANDON UNLESS N = NGIVEN ! BAD = 0 X = 0 WHILE X < N CYCLE FILE = FLIS(X)_NAME CODES = FLIS(X)_CODES CODES2 = FLIS(X)_CODES2 USE = FLIS(X)_USE CONDITION = 0 IF CODES & UNAVA # 0 OR CODES & VIOLAT # 0 THEN CONDITION = 1 IF MODE = TRANSFER AND USE # 0 THEN CONDITION = 2 IF CODES2 & WRCONN # 0 AND (MODE = TRANSFER OR (MODE = COPY AND C CODES & WSALLOW = 0)) THEN CONDITION = 3 IF MODE = TRANSFER AND CODES2 & (OLDGE ! NEWGE) # 0 THEN C CONDITION = 4 IF CONDITION # 0 START PRINTSTRING(FILE) SPACES(12 - LENGTH(FILE)) PRINTSTRING(NOGO(CONDITION)) IF CONDITION = 2 THEN WRITE(USE, 1) NEWLINE BAD = BAD + 1 FINISH X = X + 1 REPEAT ! IF BAD = 0 THEN WRS("Files OK") ELSESTART PRINTSTRING("Cannot transfer") WRITE(BAD, 1) S = "files" IF BAD = 1 THEN LENGTH(S) = 4 WRS(S) J = YES OR NO("Continue?") ->ABANDON IF J = 0; ! not-completed result FINISH IF DO IRENAME = RENAMEOLD START USER = ITOS(OLDFSYS) USER = "0".USER IF OLDFSYS < 10 USER = "OLDZ".USER J = D RENAME INDEX(OLD USER, USER, OLD FSYS) UNLESS J = 0 START WRSU("RENAME INDEX ".OLD USER." TO ".USER, J) ->ABANDON FINISH FINISHELSE USER = OLDUSER WRSSS(OLDUSER, " index renamed ", USER) CYCLE TYPE = 0, 1, TOPSFI; ! move SFI information IF XFER(TYPE) # 0 START J = DSFI(USER, OLDFSYS, TYPE, 0, ADDR(INF(0))) IF J = 0 START ! Temporarily save user's MAXFILE and set the field "very large" ! in case there are files about exceeding his current MAXFILE. ! Similarly with MAXKB IF TYPE = 11 START SAVE MAXKB = INF(0) INF(0) = 200 * 1024 FINISH ! IF TYPE = 12 START SAVE MAXFILE = INF(0) INF(0) = 200 * 1024 FINISH ! J = DSFI(NEWUSER, NEWFSYS, TYPE, 1, ADDR(INF(0))) FINISH ERROR(NEWUSER) UNLESS J = 0 FINISH REPEAT WRS("SFI information moved OK") ! FILE = ""; ! Move whole-index permissions J = DPERM("", GETILIST, ADDR(P)) IF J = 0 START I = 0 PT = 16 WHILE PT < P_BYTES CYCLE J = DPERM(P_INDIV(I)_USER, ADDTOILIST, P_INDIV(I)_UPRM) I = I + 1 PT = PT + 8 REPEAT FINISH WRS("Whole index permissions moved") ! GOOD = 0; ! Now transfer the files BAD = 0 X = 0 WHILE X < NGIVEN CYCLE ; ! ALL THE FILES FILE = FLIS(X)_NAME ERRFILE = FILE J = ITRANSFER(USER, NEWUSER, FILE, FILE, OLDFSYS, NEWFSYS, MODE) IF J = 0 START GOOD = GOOD + 1 WRITE(NGIVEN-X, 3) SPACE WRS(FILE) FINISH ELSE START BAD = BAD + 1 ERROR("IMOVEI" . FILE) FINISH X = X + 1 REPEAT ; ! ALL THE FILES ! WRSN("Files transferred: ", GOOD) WRSN("Files failed to transfer: ", BAD) IF BAD > 0 ! INF(0) = SAVE MAXKB J = DSFI(NEWUSER, NEWFSYS, 11, 1, ADDR(INF(0))) -> ERROR UNLESS J = 0 ! INF(0) = SAVE MAXFILE J = DSFI(NEWUSER, NEWFSYS, 12, 1, ADDR(INF(0))) -> ERROR UNLESS J = 0 ! WRS("Finished IMOVEI") RESULT = 0; ! completed OK result ERROR: ERROR("") ABANDON: WRS("IMOVEI abandoned") RESULT = 1 END ; ! IMOVEI ! !------------------------------------------------------------------------------- ! ROUTINE IIMOVE(STRING (6)USER, INTEGER OLDFSYS, NEWFSYS, NEWIKB, MARK) ! This routine is an interface routine between MOVE INDEX/REFRESH ! INDEX/REFRESH INDEXES routines and the IMOVEI routine, which does ! the move of all files and SFI data. ! It sets up the XXXZZZ index, calls IMOVEI and does the index ! rename and delete afterwards. INTEGER J, IMOVEIFLAG, MODE STRING (6)OLD, NEW MODE = COPY; ! this bit for MOVE INDEX only MODE = TRANSFER IF OLDFSYS = NEWFSYS NEWFSYS = NEWFSYS & X'7FFFFFFF' ! OLD = ITOS(OLDFSYS) OLD = "0".OLD IF OLDFSYS < 10 OLD = "OLDZ".OLD ! NEW = ITOS(NEWFSYS) NEW = "0".NEW IF NEWFSYS < 10 NEW = "NEWZ".NEW ! NEWIKB = - NEWIKB IF MARK = 1 J = DNEWUSER(NEW, NEWFSYS, NEWIKB) ! UNLESS J = 0 START WRSU("DNEWUSER ".NEW, J) ->ABANDON FINISH WRSS("Created new user ", NEW) ! IF MODE = COPY START J = IMOVEI(USER, NEW, COPY, OLDFSYS, NEWFSYS, RENAMEOLD) ! ! Before proceeding to delete any indexes offer one last chance ! to abandon the move in case anything odd happened during IMOVEI. J = 1 - YES OR NO("Proceed? ") IF J = 0 UNLESS J = 0 START ! IMOVEI FAILED. ! USER MAY HAVE BEEN RENAMED TO OLDZZZ. ! TIDY DEBRIS BY RENAMING INDEX IF REQUIRED ! RESTORE WHOLE INDEX PERMISSION IF NECESSARY IMOVEIFLAG = J J = DRENAMEINDEX(OLD, USER, OLDFSYS) UNLESS J = 0 OR J = 37 START ! 37 == USER NOT KNOWN I.E. NOT RENAMED UDERRS(J) FINISHELSE WRSSS(OLD, " has been renamed ", USER) J = IMOVEIFLAG FINISH FINISHELSESTART J = IMOVEI(USER, NEW, TRANSFER, OLDFSYS, NEWFSYS, RENAMEOLD) FINISH ! !------------------------------------------------------------ IF J = 0 START ; ! IMOVEI worked WRS("File transfer complete") ! J = DDELUSER(OLD, OLDFSYS) IF J = 0 THEN WRSS(OLD, " deleted") ELSE WRSU("DDELUSER ".OLD, J) ! J = DRENAMEINDEX(NEW, USER, NEWFSYS) ! IF J = 0 THEN WRSSS(NEW, " has been renamed ", USER) ELSE C WRSU("DRENAMEINDEX ".NEW, J) ! DPRINTSTRING("MoveIndex".USER."from".ITOS(OLDFSYS)."to".ITOS(NEWFSYS)."") RETURN FINISH ! J = DDELUSER(NEW, NEWFSYS) IF J = 0 THEN WRSS(NEW, " deleted") ELSE WRSU("DDELUSER ".NEW, J) ABANDON: WRS("IIMOVE abandoned") END ; ! IIMOVE ! !------------------------------------------------------------------------------- ! EXTERNALROUTINE MOVE INDEX(STRING (255) S) ! Used to re-site an index: ! * on the same file system, or ! * on a different file system, or ! * to change its size, or ! * to eliminate possible corruption, ! or a combination of these. ! Care should be taken if moving to a smaller size index, that the new ! index can accommodate all the files, otherwise files which can't be got ! in will be lost. ! ! If any file cannot be moved because it's in use a prompt appears ! "Continue? ". If reply "NO" is given the index is not moved, and ! no side effects have occurred. ! STRING (31) USER, REPLY INTEGER OLDFSYS, NEWFSYS, NEWIKB, J, OLDIKB, MARK ! ! ! INTEGERFN QUERYCOPY(STRING (6) USER, INTEGER FSYS) ! This routine attempts a worst case analysis for a MOVEINDEX ! within the same FSYS. The idea is to simulate making a copy ! of the files belonging to the user to be moved to see whether ! they can be fitted into the space remaining on the disc. ! The method is as follows: ! 1. Get HOLESHIST for the appropriate fsys. ! 2. For each file of the user to be moved ! a Subtract full sections from the 32 page holes. ! (HOLES(32)<0 means COPY cant be done) ! b Sections in the range 8<=sect<=31 should pick the ! largest available hole. If there isnt one then ! COPY cant be done ! c Sections in the range 1<=sect<=7 try first to ! get an exact hole. Failing that they pick the largest ! hole <=7 and failing that the largest available hole. ! If none of these are successful then COPY is not possible RECORD (DAF) DA INTEGERARRAY HOLES(0:32) INTEGER I, J, FROMREC, NGIVEN, NFILES, K, LASTSECT, FLAG, AFLAG RECORD (OINFF) ARRAY FLIS(0:MAXFILES - 1) STRING (31) FILE FLAG = IHOLESHIST(FSYS, HOLES) RESULT = - FLAG UNLESS FLAG = 0 ! NGIVEN = MAXFILES FROMREC = 0 J = DFILENAMES(USER, FLIS, FROMREC, NGIVEN, NFILES, FSYS, 0) UDERRS(J) ANDRESULT = - J UNLESS J = 0 ! NGIVEN = NGIVEN - 1 RESULT = 0 IF NGIVEN < 0; ! NO FILES SO CAN ALWAYS COPY CYCLE K = 0, 1, NGIVEN FILE = FLIS(K)_NAME J = DGETDA(USER, FILE, FSYS, ADDR(DA)) UDERRS(J) ANDRESULT = - J UNLESS J = 0 ! SUBTRACT 32 PAGE HOLES FIRST HOLES(32) = HOLES(32) - DA_NSECTS + 1 RESULT = 1 IF HOLES(32) < 0; ! NO FULL SECTIONS LEFT LASTSECT = DA_LASTSECT ! SMALL HOLES FIRST IF LASTSECT < 8 START ! TRY EXACT IF HOLES(LASTSECT) > 0 THEN C HOLES(LASTSECT) = HOLES(LASTSECT) - 1 ANDCONTINUE ! IF HERE THEN NO EXACT -> TRY LASTSECT+1 TO 7 I = 7 AFLAG = 1 WHILE I > LASTSECT CYCLE IF HOLES(I) > 0 START HOLES(I) = HOLES(I) - 1 AFLAG = 0 HOLES(I - LASTSECT) = HOLES(I - LASTSECT) + 1 EXIT FINISH I = I - 1 REPEAT CONTINUEIF AFLAG = 0 FINISH ! IF LASTSECT<8 THEN FOUND NOTHING SO FAR ANY TRY ANYTHING ! LASTSECT>=8 START HERE I = 32 AFLAG = 1 WHILE I >= LASTSECT AND I > 7 CYCLE IF HOLES(I) > 0 START HOLES(I) = HOLES(I) - 1 AFLAG = 0 HOLES(I - LASTSECT) = HOLES(I - LASTSECT) + 1 EXIT FINISH I = I - 1 REPEAT CONTINUEIF AFLAG = 0 RESULT = 1; ! CANT GUARANTEE IT IF REACH HERE REPEAT RESULT = 0 END ; ! QUERYCOPY ! ! ! WRS(VSN) GUAF(USER, OLDFSYS) ->OUT UNLESS 0 <= OLDFSYS < 100 ! J = DFSYS(USER, OLDFSYS) UDERRS(J) ANDRETURNUNLESS J = 0 ! RDINT("New fsys: ", NEWFSYS) ->OUT UNLESS 0 <= NEWFSYS < 100 ! J = DFSYS("SPOOLR", NEWFSYS) UNLESS J = 0 START WRS("Fsys not available") RETURN FINISH ! J = INDEX SIZE(USER, OLDFSYS, OLDIKB, MARK); ! report old index size IF J # 0 START WRSU("DSFI FAILS ", J) WRS("MOVE INDEX abandoned") RETURN FINISH WRSNS("CURRENT INDEX SIZE IS", OLDIKB, " KBYTES") ! RDINT("New index size Kb: ", NEWIKB) UNLESS NEWIKB = 2 OR (4 <= NEWIKB <= 32 AND NEWIKB & 3 = 0) START WRS("Index size must be 2 or 4-32") RETURN FINISH ! IF OLDFSYS = NEWFSYS START J = QUERYCOPY(USER, OLDFSYS) IF J = 0 START ! COPY IS POSSIBLE WRS("Move can proceed via COPY or TRANSFER mode") WRS("Which? (COPY is slower but safer)") PROMPT("C/T? ") UCSTRG(REPLY) UNTIL REPLY = "C" OR REPLY = "T" IF REPLY = "C" THEN NEWFSYS = NEWFSYS ! X'80000000' ! SET TOP BIT FINISH FINISH ! PRINTSTRING("MOVE INDEX mode is ") IF OLDFSYS = NEWFSYS THEN WRS("TRANSFER") ELSE WRS("COPY") ! IIMOVE(USER, OLDFSYS, NEWFSYS, NEWIKB, MARK) WRS("MOVE INDEX complete") RETURN OUT: WRS("Fsys must be in range 0-99") END ; ! MOVE INDEX ! !------------------------------------------------------------------------------- EXTERNALROUTINE COPY INDEX(STRING (255) S) ! This routine makes a copy of all files and SFI information in an ! index in a new or existing index. ! The main purpose is to be able to keep a copy of MANAGR files on a ! second disc, so that all MANAGR utilities are still available even ! if the MANAGR disc or index become(s) badly corrupted. Thus if a ! copy of MANAGR index into say a MANAG1 index is made from time to time, ! one can sort out a file system equally from MANAG1 if necessary. STRING (31) USER, NEWUSER INTEGER OLDFSYS, NEWFSYS, NEWIKB, J, KB, MARK WRS(VSN) GUAF(USER, OLDFSYS) J = DFSYS(USER, OLDFSYS) -> OUT UNLESS J = 0 J = INDEX SIZE(USER, OLDFSYS, KB, MARK) -> OUT UNLESS J = 0 WRSNS("Index size is", KB, " KBYTES") RDSTRG("New user: ", NEWUSER) RDINT("New fsys: ", NEWFSYS) ! Next check on new index J = INDEX SIZE(NEWUSER, NEWFSYS, NEWIKB, J) IF J = 37 START RDINT("New index size Kb: ", NEWIKB) J = DNEWUSER(NEWUSER, NEWFSYS, NEWIKB) -> OUT UNLESS J = 0 WRSS(NEWUSER, " has been created") FINISHELSESTART -> OUT UNLESS J = 0 WRSNS("Index size is", NEWIKB, " Kbytes") FINISH ! J = IMOVEI(USER, NEWUSER, COPY, OLDFSYS, NEWFSYS, NORENAME) ! WRS("COPY INDEX complete") RETURN OUT: ERROR("") WRS("COPY INDEX abandoned") END ; ! COPY INDEX ! !----------------------------------------------------------------------- ! ROUTINE ICONSIST(STRING (6) USER, INTEGER FSYS) ! Was used to bring archive indexes up to date. INTEGER J J = DNEW ARCH INDEX(USER, FSYS, 0) ERROR(USER) END ; ! ICONSIST ! !------------------------------------------------------------------------------- ROUTINE HISTO(INTEGER KIC INTER, KICBATCH, MSECS INTER, MSECS BATCH) ! Was used to extract Kinstrs and OCP times from all indexes and make a ! histogram of ratios, and to get an average ratio. INTEGER J, SLOT REAL RATIO OWNINTEGER N 500 TO 750, NOUT=0 OWNREAL TOTKIC, TOTMSECS=0 OWNINTEGERARRAY H(100:150) OWNINTEGER REJECTS=0 IF KIC INTER = - 1 START PRINTSTRING("Histogram of kinstructions/second values ") CYCLE J = 100, 1, 150 WRITE(J * 5, 4); SPACES(H(J)); PRINTSYMBOL('*') NEWLINE REPEAT PRINTSTRING("Average kinstructions per second: ") PRINT(((TOTKIC * 1000) / TOTMSECS), 5, 1) NEWLINE PRINTSTRING("No in range 500 to 750: ") WRITE(N 500 TO 750, 3); NEWLINE PRINTSTRING("No outside that range: ") WRITE(NOUT, 2); NEWLINE PRINTSTRING("REJECTS:"); WRITE(REJECTS, 2); NEWLINE RETURN FINISH ! %IF HD=0 %START ! HD=1 ! PRINTSTRING("KIC KIC MSECS MSECS !INTER BATCH INTER BATCH KINSTRS PER SECOND !") ! %FINISH ! WRITE(KIC INTER,7) ! WRITE(KIC BATCH,7) ! WRITE(MSECS INTER,7) ! WRITE(MSECS BATCH,7) IF MSECS INTER > 0 AND KIC INTER > 0 START RATIO = (KIC INTER * 1000.) / MSECS INTER UNLESS 400 <= RATIO <= 800 THEN REJECTS = REJECTS + 1 ANDRETURN TOTKIC = TOTKIC + KIC INTER TOTMSECS = TOTMSECS + MSECS INTER IF 500 <= RATIO <= 750 START SLOT = INT((RATIO * 20 + 5) / 100) H(SLOT) = H(SLOT) + 1 N 500 TO 750 = N 500 TO 750 + 1 FINISHELSE NOUT = NOUT + 1 FINISH NEWLINE END ; ! HISTO ! !------------------------------------------------------------------------------- EXTERNALROUTINE DO ALL INDEXES(STRING (255) S) RECORD (NNF) ARRAY U(0:TOPNNT) INTEGER NU, NUSERS INTEGERARRAY WORD0(0:63) INTEGER J, N, FX, FSYS, SEG, GAP INTEGERARRAY A(0:99) STRING (63) USER INTEGER KIC INTER, KIC BATCH, MSECS INTER, MSECS BATCH CYCLE J = 0, 1, 63 WORD0(J) = 0 REPEAT ! FSYS = BIN(S) FSYS = - 1 UNLESS - 1 <= FSYS <= 99 IF FSYS < 0 C THEN GET AV FSYS(N, A) C ELSE A(0) = FSYS AND N = 1 FX = 0 WHILE FX < N CYCLE SEG = 0 GAP = 0 FSYS = A(FX) J = GET USNAMES2(U, NUSERS, FSYS) WRSN("FSYS", FSYS) WRSN("GET USNAMES FLAG", J) WRSN("NO OF USERS", NUSERS) NU = 0 WHILE NU < NUSERS CYCLE USER <- U(NU)_NAME IF LENGTH(USER) = 6 START !*********...here you insert the code you want to execute...**************** ! ...for each index. !ICONSIST(USER,FSYS) %IF USER#"SPOOLR" KIC INTER = 0; KIC BATCH = 0; MSECS INTER = 0 MSECS BATCH = 0 J = DSFI(USER, FSYS, 20, 0, ADDR(KIC INTER)) IF J # 0 START PRINTSTRING("FLAG"); WRITE(J, 1) PRINTSTRING(" FOR USER "); PRINTSTRING(USER) NEWLINE FINISH J = DSFI(USER, FSYS, 27, 0, ADDR(MSECS INTER)) IF J # 0 START PRINTSTRING("FLAG"); WRITE(J, 1) PRINTSTRING(" FOR USER "); PRINTSTRING(USER) NEWLINE FINISH HISTO(KIC INTER, KIC BATCH, MSECS INTER, MSECS BATCH) !************************************************************************************* FINISH NU = NU + 1 REPEAT FX = FX + 1 REPEAT ! HISTO(-1,0,0,0) END ; ! DO ALL INDEXES ! !------------------------------------------------------------------------------- EXTERNALROUTINE REFRESH INDEXES(STRING (255) S) ! Goes up a whole file system re-siting every index, with the same ! attributes (size in particular). ! ! If any file cannot be moved because it's in use a prompt appears ! "Continue? ". If reply "NO" is given the index is not moved, and ! no side effects have occurred. ! ! However, the intention is that it should be used on a newly-CCK-ed ! file system with no users active. ! ! Don't try to move the file system that you're running it from! RECORD (NNF) ARRAY U(0:TOPNNT) INTEGER NU, NUSERS, KB, MARK INTEGER J, FSYS STRING (63) USER RDFSYS("Fsys: ", FSYS) WRS(VSN) WRS("If it's necessary to interrupt this program, type Int:STOP") J = GET USNAMES2(U, NUSERS, FSYS) WRSN("GET USNAMES flag =", J) ANDRETURNUNLESS J = 0 WRSN(" NO OF USERS =", NUSERS) NU = 0 WHILE NU < NUSERS CYCLE USER <- U(NU)_NAME IF LENGTH(USER) = 6 START WRSS("User ", USER) J = INDEX SIZE(USER, FSYS, KB, MARK) IIMOVE(USER, FSYS, FSYS, KB, MARK) FINISH NU = NU + 1 IF INTERRUPT = "STOP" START WRSS("INT:STOP received. Last index moved was ", USER) RETURN FINISH REPEAT END ; ! REFRESH INDEXES ! !------------------------------------------------------------------------------- ! EXTERNALROUTINE MOVE INDEXES(STRING (255) S) INTEGER J, NU, NUSERS, FLAG, FROM FSYS, TO FSYS, KB, MARK RECORD (NNF) ARRAY U(0:TOPNNT) STRING (6) USER STRING (15)W WRS(VSN) WRS("If its necessary to interrupt this program, type INT:STOP") ! RDINT("From fsys: ", FROM FSYS) UNTIL FROM FSYS >= 0 FLAG = PERCENT(FROM FSYS) RETURNUNLESS FLAG = 0 ! RDINT("To fsys: ", TO FSYS) UNTIL TO FSYS >= 0 ! IF FROM FSYS = TO FSYS START WRS("MUST SPECIFY DIFFERENT FSYS'S") RETURN FINISH FLAG = PERCENT(TO FSYS) RETURNUNLESS FLAG = 0 ! J = GET USNAMES2(U, NUSERS, FROM FSYS) WRSN("GET USERNAMES flag =", J) UNLESS J = 0 WRSN(" No of users =", NUSERS) ! RETURNIF NUSERS < 1 ! NUSERS = NUSERS - 1; ! ARRAY ELEMENTS RUN FROM ZERO CYCLE NU = 0, 1, NUSERS USER <- U(NU)_NAME IF LENGTH(USER) = 6 START ->SKIP IF EXECUTIVES -> W . (USER) . W WRSS("User ", USER) J = INDEX SIZE(USER, FROM FSYS, KB, MARK) IIMOVE(USER, FROM FSYS, TO FSYS, KB, MARK) FINISH SKIP: IF INTERRUPT = "STOP" START WRS("INT:STOP received") WRSS("Last index moved was for ", USER) RETURN FINISH REPEAT ! FLAG = PERCENT(TO FSYS) END ; ! MOVE INDEXES ! !----------------------------------------------------------------------- ! EXTERNALROUTINE REFRESH INDEX(STRING (255) S) ! Equivalent to MOVE INDEX where the same new index-size and new FSYS are ! required. Re-sites an index on the same FSYS and with the same ! attributes. Purpose: to eliminate possible corruption in the index or ! to bring an index up to date (e.g. for later versions of Director with ! newer facilities). ! ! If any file cannot be moved because it's in use a prompt appears ! "Continue? ". If reply "NO" is given the index is not moved, and ! no side effects have occurred. ! INTEGER J, FSYS INTEGER KB, MARK STRING (63) USER WRS(VSN) GUAF(USER, FSYS) ! J = INDEX SIZE(USER, FSYS, KB, MARK) WRSU("DSFI fails", J) ANDRETURNUNLESS J = 0 IIMOVE(USER, FSYS, FSYS, KB, MARK) WRSS(USER, " refreshed") END ; ! REFRESH INDEX ! !------------------------------------------------------------------------------- EXTERNALROUTINE GETDA(STRING (255) S) RECORD (DAF) P INTEGER J, FSYS STRING (31) FILE, USER GUAFAF(USER, FSYS, FILE) J = DGETDA(USER, FILE, FSYS, ADDR(P)) UDERRS(J) NEWLINE J = 0 WHILE J < P_NSECTS CYCLE PHEX(P_DA(J)) NEWLINE J = J + 1 REPEAT END ; ! GETDA ! !------------------------------------------------------------------------------- EXTERNALROUTINE WHAT FILE(STRING (255) S) ! Program to discover the file(s) to which a given page number belongs. ! You can specify that one FSYS or all FSYSes are to be searched. INTEGER FROMREC, NGIVEN INTEGER FSYS, J, I, N, UX, SX, DA, PGNO, LEN, NFILES, FX, USERS STRING (31) FILE, USER INTEGERARRAY A(0:99) STRING (6) ARRAY U(0:TOPNNT) RECORD (OINFF) ARRAY FLIS(0:255) ! RECORD (DAF) DAAREA ! RDINT("Fsys or -1: ", FSYS) RDINT("Page no: ", PGNO) GET AV FSYS(N, A) IF FSYS >= 0 START CYCLE J = 0, 1, N - 1 IF A(J) = FSYS START A(0) = FSYS N = 1 ->OK FINISH REPEAT WRS("FSYS N/A") RETURN FINISH OK: CYCLE J = 0, 1, N - 1 FSYS = A(J) WRSN("FSYS", FSYS) PGNO = PGNO << 8 >> 8 ! FSYS << 24 I = GET USNAMES(USERS, ADDR(U(0)), FSYS) MONITORIF I # 0 UX = 0 WHILE UX < USERS CYCLE USER = U(UX) FROMREC = 0 NGIVEN = 256; ! SET TO MAX PREPARED TO RECEIVE I = DFILENAMES(USER, FLIS, FROMREC, NGIVEN, NFILES, FSYS, 0) MONITORIF I # 0 FX = 0 WHILE FX < NFILES CYCLE FILE = FLIS(FX)_NAME I = DGETDA(USER, FILE, FSYS, ADDR(DA AREA)) MONITORIF I # 0 SX = 0 WHILE SX < DA AREA_NSECTS CYCLE DA = DA AREA_DA(SX) SX = SX + 1 LEN = DA AREA_SECTSI IF SX = DA AREA_NSECTS THEN LEN = DA AREA_LASTSECT IF DA <= PGNO < DA + LEN START SPACES(4) WRSSS(USER, ".", FILE) FINISH REPEAT ; ! UP THE SECTIONS OF THE FILE FX = FX + 1 REPEAT ; ! UP THE FILES OF THE USER UX = UX + 1 REPEAT ; ! UP THE USERS OF THE FSYS REPEAT ; ! UP THE FSYS'S END ; ! WHAT FILE ! !------------------------------------------------------------------------------- ! INTEGERFN SETNOARCH(STRING (31) USER, FILE, INTEGER FSYS) ! Sets NOARCH bit in file descriptor for FILE, but FILE must be ! #ARCH. INTEGER J RESULT = 0 IF FILE # "#ARCH" J = DFSTATUS(USER, FILE, FSYS, 17, 0) RESULT = 0 IF J = 0 PRINTSTRING("SET NOARCH flag ") UDERRS(J) END ; ! SETNOARCH ! !------------------------------------------------------------------------------- ROUTINE IREFRESH FILE(STRING (31)USER, FILE, INTEGER FSYS) INTEGER J J = DRENAME(USER, FILE, "##", FSYS) -> OUT UNLESS J = 0 ! J = ITRANSFER(USER, USER, "##", FILE, FSYS, FSYS, 2) IF J = 0 START WRSS(USER . "." . FILE, " refreshed") RETURN FINISH ! ERROR(USER.".".FILE) ! J = DRENAME(USER, "##", FILE, FSYS) -> OUT UNLESS J = 0 ! WRS(USER.".".FILE." renamed to original name") RETURN OUT: ERROR(USER.".".FILE) END ; ! IREFRESH FILE ! !------------------------------------------------------------------------------- ROUTINE TO SET MSG EEP(STRING (31) USER, FILE, INTEGER FSYS) INTEGER EEP, J RETURNIF FILE # "#MSG" AND FILE # "#ARCH" EEP = 11 J = DPERMISSION(USER, USER, "", FILE, FSYS, 1, EEP) IF J # 0 THEN PRINTSTRING("DPERMISSN FLAG ") AND UDERRS(J) END ; ! TO SET MSG EEP ! !------------------------------------------------------------------------------- EXTERNALROUTINE REFRESH FILE(STRING (255) S) STRING (31) USER, FILE INTEGER FSYS GUAFAF(USER, FSYS, FILE) IREFRESH FILE(USER, FILE, FSYS) END ; ! REFRESH FILE ! !------------------------------------------------------------------------------- ROUTINE TO DO ALL FILES(ROUTINE H(STRING (31)USER, FILE, INTEGER FSYS)) ! INTEGER FSX, NGIVEN, FROMREC INTEGER FSYS, I, N, UX, NFILES, FX, USERS STRING (31) FILE, USER, TXT INTEGERARRAY A(0:99) STRING (6) ARRAY U(0:TOPNNT) RECORD (OINFF) ARRAY FLIS(0:255) ! RDINT("Fsys or -1: ", FSYS) A(0) = FSYS N = 1 GET AV FSYS(N, A) IF FSYS < 0 ! CYCLE FSX = 0, 1, N - 1 FSYS = A(FSX) TXT = "Fsys " . ITOS(FSYS) WRS(TXT) I = GET USNAMES(USERS, ADDR(U(0)), FSYS) -> OUT UNLESS I = 0 UX = 0 WHILE UX < USERS CYCLE USER = U(UX) FROMREC = 0 L: NGIVEN = (1<<31) ! 256; ! SET TO MAX PREPARED TO RECIEVE TXT = USER I = DFILENAMES(USER, FLIS, FROMREC, NGIVEN, NFILES, FSYS, 0) -> OUT UNLESS I = 0 ! FX = 0 WHILE FX < NGIVEN CYCLE FILE = FLIS(FX)_NAME H(USER, FILE, FSYS) FX = FX + 1 REPEAT ; ! UP THE FILES OF THE USER ! FROMREC = FROMREC + NGIVEN -> L IF FROMREC < NFILES ! UX = UX + 1 REPEAT ; ! UP THE USERS OF THE FSYS REPEAT ; ! UP THE FSYS'S H("", "", 0) RETURN OUT: ERROR(TXT) END ; ! TO DO ALL FILES ! !------------------------------------------------------------------------------- EXTERNALROUTINE SET MSG EEP(STRING (255) S) TO DO ALL FILES(TO SET MSG EEP) END ; ! SET MSG EEP OWNINTEGER LOW PAGENO ! !------------------------------------------------------------------------------- ROUTINE TO CHECK DAS(STRING (31) USER, FILE, INTEGER FSYS) INTEGER I, SX, DA, LEN, LOW PAGE NO RECORD (DATAF)DATA RECORD (DAF)DA AREA RETURNIF USER = "" ! I = DGETDA(USER, FILE, FSYS, ADDR(DA AREA)) -> OUT UNLESS I = 0 ! I = FBASE2(FSYS, ADDR(DATA)) -> OUT UNLESS I = 0 LOW PAGE NO = DATA_START + DATA_FILESTART + X'300' ! SX = 0 WHILE SX < DA AREA_NSECTS CYCLE DA = DA AREA_DA(SX) SX = SX + 1 LEN = DA AREA_SECTSI IF SX = DA AREA_NSECTS THEN LEN = DA AREA_LASTSECT IF DA < FSYS << 24 ! LOW PAGENO START SPACES(4) WRSSS(USER, ".", FILE) RETURN FINISH REPEAT ; ! UP THE SECTIONS OF THE FILE RETURN OUT: ERROR(USER.".".FILE) END ; ! TO CHECK DAS ! !------------------------------------------------------------------------------- ROUTINE TO SET HNOARCH(STRING (31) USER, FILE, INTEGER FSYS) INTEGER J RETURNIF FILE # "#ARCH" J = SETNOARCH(USER, FILE, FSYS) END ; ! TO SET HNOARCH ! !------------------------------------------------------------------------------- ROUTINE TO REFRESH(STRING (31) USER, FILE, INTEGER FSYS) INTEGER I, SX, DA, LEN, LOW PAGENO RECORD (DATAF)DATA ! RECORD (DAF)DAAREA ! RETURN IF USER = "" ! I = DGETDA(USER, FILE, FSYS, ADDR(DA AREA)) -> OUT UNLESS I = 0 ! I = FBASE2(FSYS, ADDR(DATA)) -> OUT UNLESS I = 0 LOW PAGE NO = DATA_START + DATA_FILESTART + X'300' ! SX = 0 WHILE SX < DA AREA_NSECTS CYCLE DA = DA AREA_DA(SX) SX = SX + 1 LEN = DA AREA_SECTSI IF SX = DA AREA_NSECTS THEN LEN = DA AREA_LASTSECT IF DA < FSYS << 24 ! LOW PAGENO START IREFRESH FILE(USER, FILE, FSYS) RETURN FINISH REPEAT ; ! UP THE SECTIONS OF THE FILE RETURN OUT: ERROR(USER.".".FILE) END ; ! TO REFRESH OWNINTEGER SSI ! !------------------------------------------------------------------------------- EXTERNALROUTINE CHECK DAS(STRING (255) S) TO DO ALL FILES(TO CHECKDAS) END ; ! CHECK DAS ! !----------------------------------------------------------- ! EXTERNALROUTINE SETHNOARCH(STRING (255) S) TO DO ALL FILES(TO SETHNOARCH) END ; ! SETHNOARCH ! !------------------------------------------------------------------------------- EXTERNALROUTINE REFRESH FILES(STRING (255) S) TO DO ALL FILES(TO REFRESH) END ; ! REFRESH FILES ! !------------------------------------------------------------------------------- EXTERNALROUTINE WHATFSYS(STRING (255) S) ! WILL CHECK FOR MULTIPLE OCCURRENCES OF USERNAMES INTEGER J, NFSYS, I, FOUNDUSER INTEGERARRAY A(0:99) STRING (63) USER RDSTRG("User: ", USER) FOUNDUSER = 0 GETAVFSYS(NFSYS, A) NFSYS = NFSYS - 1 CYCLE I = 0, 1, NFSYS J = DFSYS(USER, A(I)) UNLESS J = 37 OR J = 0 THEN UDERRS(J) ANDRETURN IF J = 0 START ! FOUND USER FOUNDUSER = 1 IF FOUNDUSER = 0 WRSN("FSYS", A(I)) FINISH REPEAT UDERRS(37) IF FOUNDUSER = 0 END ; ! WHATFSYS ! !------------------------------------------------------------------------------- EXTERNALROUTINE RENAME INDEX(STRING (255) S) STRING (31) OLD, NEW INTEGER FSYS, J GUAF(OLD, FSYS) PROMPT("NEW NAME: ") UCSTRG(NEW) J = DRENAME INDEX(OLD, NEW, FSYS) UDERRS(J) UNLESS J = 0 END ; ! RENAME INDEX ! !------------------------------------------------------------------------------- ! INTEGERFN GOODUSER(STRING (255) USER) ! result = 1 if USER is length 6, alphanumeric & has decimal digits ! as last 2 characters ! Else result 0 INTEGER J, OK, CH OK = 1 IF LENGTH(USER) = 6 START CYCLE J = 1, 1, 6 CH = CHARNO(USER, J) UNLESS ('A' <= CH <= 'Z' AND J < 5) OR '0' <= CH <= '9' THEN C OK = 0 REPEAT FINISHELSE OK = 0 IF OK = 0 START WRS("Give 6 alphanumeric characters, the last two being numeric") FINISH RESULT = OK; ! or not as the case may be END ; ! GOODUSER ! !------------------------------------------------------------------------------- ! INTEGERFN INCU(STRINGNAME USER) ! reject without message unless last 2 chars are decimal digits UNLESS '0' <= CHARNO(USER, 5) <= '9' AND C '0' <= CHARNO(USER, 6) <= '9' THENRESULT = 0 ! "bad" CHARNO(USER, 6) = CHARNO(USER, 6) + 1 IF CHARNO(USER, 6) > '9' START CHARNO(USER, 6) = '0' CHARNO(USER, 5) = CHARNO(USER, 5) + 1 FINISH IF CHARNO(USER, 5) > '9' START WRS("Username out of range !!!!!!!!!!!!!!!!!!!") RESULT = 0; ! bad FINISH RESULT = 1; ! good END ; ! INCU ! !------------------------------------------------------------------------------- ! INTEGERFN GOODRANGE(STRING (6) USER, INTEGER N) ! result = 1 if range OK, 0 otherwise. INTEGER J, OK RESULT = 1 IF N = 1 J = 0 OK = 0 WHILE J < N - 1 CYCLE OK = INCU(USER) EXITIF OK = 0 J = J + 1 REPEAT WRS("User range invalid") IF OK = 0 RESULT = OK; ! or not as the case may be END ; ! GOODRANGE ! !------------------------------------------------------------------------------- ! INTEGERFN DO NEWUSERS(STRING (255) USER, INTEGER NUMBER) STRING (255) SURNAME, PASS, DELIV INTEGER FSYS, NKB, J, IPASS0, IPASS1, MAXKB, MAXFILE, MAXPROI, MAXPROB, MAXPROT INTEGER N, DEFAULTFUNDS, D CONSTINTEGER TOP = 7 CONSTBYTEARRAY TYPE(1:TOP)=18, 1, 5, 12, 11, 14, 33 INTEGERARRAY A(1:TOP) DEFAULTFUNDS = 50000 RDINT("Fsys: ", FSYS) RDINT("Index Kbytes: ", NKB) ! Do this immediately for the first one in case it's going to fail and ! waste all the prompted input. J = DNEWUSER(USER, FSYS, NKB) ERROR(USER) UNLESS J = 0 IF J # 0 THENRESULT = J PROMPT("INITLS+SURNAME:") UCSTRG(SURNAME) WRS("Give 4 character passwords") PROMPT("F Password: ") UCSTRG(PASS) UNTIL LENGTH(PASS) = 4 MOVE(4, ADDR(PASS) + 1, ADDR(IPASS0)) PROMPT("B Password: ") UCSTRG(PASS) UNTIL LENGTH(PASS) = 4 MOVE(4, ADDR(PASS) + 1, ADDR(IPASS1)) PROMPT("Delivery info: ") INSTRG(DELIV) RDINT("Maxfile Kb: ", MAXFILE) RDINT("Max Kbytes: ", MAXKB) RDINT("Max I.Procs: ", MAXPROI) RDINT("Max B.Procs: ", MAXPROB) RDINT("Max T.Procs: ", MAXPROT) ! A(1) = ADDR(SURNAME) A(2) = ADDR(DELIV) A(3) = ADDR(IPASS0) A(4) = ADDR(MAXFILE) A(5) = ADDR(MAXKB) A(6) = ADDR(MAXPROI) A(7) = ADDR(DEFAULTFUNDS) ! N = 1 WHILE N <= NUMBER CYCLE PRINTSTRING("User: ".USER) SPACES(2) IF N > 1 START ; ! first has already been done above J = DNEWUSER(USER, FSYS, NKB) ERROR(USER) AND RESULT = J UNLESS J = 0 FINISH ! CYCLE D = 1, 1, TOP J = DSFI(USER, FSYS, TYPE(D), 1, A(D)) ERROR(USER) UNLESS J = 0 REPEAT WRS(" Completed") N = N + 1 J = INCU(USER) UNLESS NUMBER = 1 REPEAT RESULT = 0 END ; ! DO NEWUSERS ! !------------------------------------------------------------------------------- ! EXTERNALROUTINE NEWUSER(STRING (255) S) STRING (255) USER INTEGER J PROMPT("User: ") UCSTRG(USER) J = DO NEWUSERS(USER, 1) END ; ! NEWUSER ! !------------------------------------------------------------------------------- EXTERNALROUTINE REGISTER CLASS(STRING (255) S) STRING (255) USER INTEGER N, J ! This routine prompts for a "base" username and a number N of users. ! Username is assumed to be of the form AAAAnn (nn numeric) ! and nn and N-1 further usernames are accreditted. ! PROMPT("Base username: ") UCSTRG(USER) UNTIL GOODUSER(USER) # 0 RDINT("How many? ", N) IF GOODRANGE(USER, N) = 0 THENRETURN J = DO NEWUSERS(USER, N) UDERRS(J) END ; ! REGISTER CLASS ! !------------------------------------------------------------------------------- EXTERNALROUTINE DE REGISTER CLASS(STRING (255) S) ! This routine prompts for a "base" username and a number N of users. ! Username is assumed to be of the form AAAAnn (nn numeric) ! and nn and N-1 further usernames are accreditted. ! STRING (31) USER INTEGER N, NUM, K, FSYS, J PROMPT("Base username: ") UCSTRG(USER) UNTIL GOODUSER(USER) # 0 RDINT("How many? ", N) IF GOODRANGE(USER, N) = 0 THENRETURN RDFSYS("Fsys: ", FSYS) ! Disconnect currently_connected #ARCH (if any connected). ! Otherwise NEWUSER followed by DELUSER followed by NEWUSER all for the ! same user causes AINDA in Director file ARCHnn to fail 37 (user not ! known). A slightly pathological case, but still. J = ACREATE2("", "", "", "", 0, 0, 0, 0); ! disconnect #ARCH NUM = 1 WHILE NUM <= N CYCLE K = DDELUSER(USER, FSYS) EXITIF K # 0 NUM = NUM + 1 J = INCU(USER) REPEAT ERROR(USER) UNLESS K = 0 END ; ! DE REGISTER CLASS ! !------------------------------------------------------------------------------- EXTERNALROUTINE DELUSER(STRING (255) S) ! THIS VERSION ASKS FOR CONFIRMATION BEFORE DELETING AND ! WILL ALSO CHECK FOR MULTIPLE OCCURRENCES OF THE USERNAME STRING (31) USER, REPLY INTEGER FSYS, J TRY AGAIN: GUAF(USER, FSYS) WRS("Confirm user ".USER." to be deleted") PROMPT("Y/N? ") UCSTRG(REPLY) UNTIL REPLY = "Y" OR REPLY = "N" ->TRY AGAIN IF REPLY = "N" ! Disconnect currently_connected #ARCH (if any connected). ! Otherwise NEWUSER followed by DELUSER followed by NEWUSER all for the ! same user causes AINDA in Director file ARCHnn to fail 37 (user not ! known). A slightly pathological case, but still. ANOTHER: J = ACREATE2("", "", "", "", 0, 0, 0, 0); ! disconnect #ARCH J = DDELUSER(USER, FSYS) IF J = 0 START WRSNS(USER." on fsys", FSYS, " successfully deleted") FINISHELSE UDERRS(J) ANDRETURN ! CHECK MULTIPLE OCCURRENCE FSYS = - 1 J = DFSYS(USER, FSYS) IF J = 0 START WRSNS("** WARNING - User ".USER." also occurs on FSYS", FSYS, " Delete this as well?") PROMPT("Y/N? ") UCSTRG(REPLY) UNTIL REPLY = "Y" OR REPLY = "N" ->ANOTHER IF REPLY = "Y" FINISH END ; ! DELUSER ! !------------------------------------------------------------------------------- EXTERNALROUTINE ENV(STRING (255) S) INTEGER N, J INTEGERARRAY A(0:99) ! RECORD (COMF) NAME COM RECORD (SCTF) NAME SCT RECORD (UINF) NAME UIN ! COM == RECORD(X'80000000' + 48 << 18) SCT == RECORD(8 << 18) UIN == RECORD(9 << 18) ! PRINTSTRING(UINFS(10)); ! ocp type PRINTSTRING(" Sup: ") PRINTSTRING(STRING(ADDR(COM_SUPVSN))) ! PRINTSTRING(" Dir: ") PRINTSTRING(SCT_FIXUPDATE) ! WRSN(" Proc: ", UIN_PROCNO) ! PRINTSTRING("Discs: ") GETAVFSYS(N, A); ! FIRST DISC IS SLOAD DISC ! CYCLE J = 0, 1, N - 1 WRITE(A(J), 1) REPEAT NEWLINE END ; ! ENV ! !--------------------------------------------------------------------- ! !******************* INACTIVE USERS ROUTINES ***************** ! !---------------------------------------------------------------- ! ROUTINE XXNSORT(RECORD (TF) ARRAYNAME P, INTEGERARRAYNAME X, INTEGER N) ! DECLARE INTEGER ARRAY X, BOUNDS 1:NUM, IN CALLING ROUTINE !NOTIMP80 %RECORDSPEC P(TF) INTEGER I, J, K, M, W RETURNUNLESS N > 0 ! CYCLE I = 1, 1, N X(I) = I REPEAT ! M = 1 M = M << 1 WHILE M <= N M = M - 1 ! CYCLE M = M >> 1 EXITIF M = 0 CYCLE I = 1, 1, N - M K = I WHILE K > 0 CYCLE J = K + M ! EXITIF P(X(K))_LASTLOGON <= P(X(J))_LASTLOGON W = X(J) X(J) = X(K) X(K) = W ! K = K - M REPEAT REPEAT REPEAT END ; ! XXNSORT ! !---------------------------------------------------------------- ! INTEGERFN STINT(STRING (15) S) INTEGER I, J J = 0 CYCLE I = 1, 1, LENGTH(S) UNLESS '0' <= CHARNO(S, I) <= '9' THENRESULT = - 1 J = J * 10 + CHARNO(S, I) - 48 REPEAT RESULT = J END ; ! STINT ! !----------------------------------------------------------------- ! EXTERNALROUTINE INACTIVEUSERS(STRING (255) S) RECORD (TF) ARRAYFORMAT XTF(1:400) RECORD (USINFF) ARRAY USINF(0:TOPNNT) RECORD (TF) ARRAY TABLE(0:399) RECORD (TF) ARRAYNAME TAB INTEGERARRAY ALLFSYS(0:15), ALPH(1:400) INTEGERARRAY LL(1:2) INTEGER I, J, FLAG, NACTIVE, NUSERS, AD, LASTLOGON, NEXT, TRIGGER STRING (3) DD, MM, YY STRING (255) FAIL, TRIG, OPDEV, W ROUTINE SCLOSE SELECTOUTPUT(0) CLOSESTREAM(53) CLEAR("53") END ; ! SCLOSE ! ! ! TAB == ARRAY(ADDR(TABLE(0)), XTF) AD = ADDR(LL(1)) WRS("Date in format DD/MM/YY") PROMPT("TRIGGER DATE: ") UCSTRG(TRIG) UNTIL TRIG - > DD.("/").MM.("/").YY PROMPT("Op file/dev: ") UCSTRG(OPDEV) UNTIL OPDEV # "" TRIGGER = (STINT(YY) - 70) << 9 ! STINT(MM) << 5 ! STINT(DD) GETAVFSYS(NACTIVE, ALLFSYS) NACTIVE = NACTIVE - 1 NEXT = 0 CYCLE I = 0, 1, NACTIVE NUSERS = 512 FLAG = GETUSNAMES2(USINF, NUSERS, ALLFSYS(I)) IF FLAG # 0 THEN FAIL = "GETUSNAMES " AND ->ERROR NUSERS = NUSERS - 1 UNLESS NUSERS < 0 START CYCLE J = 0, 1, NUSERS UNLESS EXECUTIVES -> W . (USINF(J)_NAME) . W START FLAG = DSFI(USINF(J)_NAME, ALLFSYS(I), 6, 0, AD) MONITORAND ->NEXT IF FLAG # 0 LASTLOGON = LL(1) >> 17 IF LASTLOGON < TRIGGER START IF NEXT = 400 START WRS("Too many entries. Recompile. Dumping.") ->OUTPUTSEG FINISH TABLE(NEXT)_USER = USINF(J)_NAME TABLE(NEXT)_FSYS = ALLFSYS(I) FLAG = DSFI(USINF(J)_NAME, ALLFSYS(I), 18, 0, ADDR(TABLE(NEXT)_SURNAME)) MONITORAND ->NEXT IF FLAG # 0 FLAG = DSFI(USINF(J)_NAME, ALLFSYS(I), 1, 0, ADDR(TABLE(NEXT)_DELIV)) MONITORAND ->NEXT IF FLAG # 0 TABLE(NEXT)_LASTLOGON = LASTLOGON MM = ITOS((LASTLOGON >> 5) & X'F') MM = "0".MM IF LENGTH(MM) = 1 DD = ITOS(LASTLOGON & X'1F') DD = "0".DD IF LENGTH(DD) = 1 TABLE(NEXT)_LASTUSED = DD."/".MM."/".ITOS C (LASTLOGON >> 9 + 70) NEXT = NEXT + 1 FINISH FINISH NEXT: REPEAT FINISH REPEAT ! OUTPUT SEGMENT OUTPUTSEG: DEFINE("53,".OPDEV.",500") SELECTOUTPUT(53) WRS("Processes not used since ".TRIG) WRS(" ** NONE **") AND SCLOSE AND RETURN IF NEXT = 0 XXNSORT(TAB, ALPH, NEXT) WRS("LASTUSED USER FSYS") CYCLE I = 1, 1, NEXT J = ALPH(I) PRINTSTRING(TAB(J)_LASTUSED); SPACES(2) PRINTSTRING(TAB(J)_USER); SPACES(2) WRITE(TAB(J)_FSYS, 2); SPACES(2) PRINTSTRING(TAB(J)_SURNAME); SPACES(33 - LENGTH(TAB(J)_SURNAME)) WRS(TAB(J)_DELIV) REPEAT NEWLINE WRITE(NEXT, 5) PRINTSTRING(" Users") SCLOSE WRITE(NEXT, 5) PRINTSTRING(" Users") RETURN ERROR: WRSN(FAIL, FLAG) END ; ! INACTIVEUSERS ! !------------------------------------------------------------------ ! !**************** END OF INACTIVE USERS ROUTINES ************** ENDOFFILE