From 51eb0403690712da9a6944f72803ffa5707a3dd8 Mon Sep 17 00:00:00 2001 From: Lars Brinkhoff Date: Tue, 29 Nov 2016 20:18:29 +0100 Subject: [PATCH] Build DSKUSE. --- README.md | 1 + build/build.tcl | 3 + doc/README.md | 1 + doc/_info_/dskuse.info | 158 +++ doc/_info_/dskuse.recent | 124 +++ doc/info/dskuse.10 | 174 ++++ src/syseng/dskuse.76 | 2044 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 2505 insertions(+) create mode 100755 doc/_info_/dskuse.info create mode 100755 doc/_info_/dskuse.recent create mode 100755 doc/info/dskuse.10 create mode 100755 src/syseng/dskuse.76 diff --git a/README.md b/README.md index 32e57797..50cca566 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ from scratch. - MAIL, Mail sending client - RMAIL, Mail reading client - DQ Device, for doing hostname resolutions. Used by COMSAT. + - DSKUSE, disk usage information. 6. A brand new host table is built from the host table source and installed into SYSBIN; HOSTS3 > using H3MAKE. diff --git a/build/build.tcl b/build/build.tcl index b6e5b97b..a52a4802 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -280,6 +280,9 @@ expect ":KILL" respond "*" ":link sys;ts find,sysbin;find bin\r" type ":vk\r" +respond "*" ":midas sys;ts dskuse_syseng;dskuse\r" +expect ":KILL" + respond "*" ":midas sys3;ts ddtdoc_syseng;ddtdoc\r" expect ":KILL" diff --git a/doc/README.md b/doc/README.md index 393b383e..aa00b520 100644 --- a/doc/README.md +++ b/doc/README.md @@ -15,3 +15,4 @@ - DSKDUMP: [commands](sysdoc/dskdmp.order) - FIND: [manual](init/find.13) - DIRDEV: [manual](_init_/dir.order) +- DSKUSE: [manual](info/dskuse.10) diff --git a/doc/_info_/dskuse.info b/doc/_info_/dskuse.info new file mode 100755 index 00000000..dc283e3d --- /dev/null +++ b/doc/_info_/dskuse.info @@ -0,0 +1,158 @@ +DSKUSE INFO PDL 2/20/76 + Last updated: PDL 5/10/76 + + DSKUSE is a program for gathering and printing information +about the disk system. + +DSKUSE is usually driven by a command from its JCL line, as follows: + +:DSKUSE user statistics on the user directory given, or the XUNAME + directory if no argument. +:DSKUSE > user print message if XUNAME user (or user given explicitly) + is over quota, else nothing. + +:DSKUSE @ file statistics on all users output to TPL:, or to file + if given. +:DSKUSE & file output two tables, sorted on user and blocks, to TPL: + or to file if given. + +:DSKUSE # general statistics on disk system (takes time). +:DSKUSE $ same as previous, only less detailed (faster, too). + +:DSKUSE % user Gives percent of directory space used by user. + +:DSKUSE * statistics on all users, in tabular form. + this command is special in that it leaves you in DSKUSE. + you may type the number or name of a column to sort by + that column and then reprint the table (0 or USER, 1 or + FILES, etc.). in this mode the @ command, with a file + name optionally following it, causes subsequent sorts + to go to the file. the commands #, %, and > are not + available. The dual sort (& or BOTH) is, however. + + +Details of DSKUSE Data Collection and Printing + +Quotas and Allocations: + + In the sections which follow, the idea of a "non-quota'ed" +system is occasionally used. DSKUSE understands this to mean a system +on which the total number of blocks allocated and quota'ed is zero. +Currently all ITS's have the software for quotas and allocations, but +only the DM system uses it. DSKUSE should do the right thing if any +of the other ITS's start actually using quotas and allocations. + +Single directory information: + + For each directory covered by DSKUSE, seven pieces of information +are stored. These are: + +1) the directory name, +2) the number of files in the directory, +3) the number of links in the directory (note that these two numbers + total to the number of "files" in the directory, ie: the number of + lines you will see if you list it). +4) the number of blocks used by files in the directory (this is gotten + from the appropriate word in the directory, rather than by calculating + it as was done in the past -- a considerable speedup). +5) the average number of blocks per file in the directory (a floating + point number, obviously). +6) the directory's quota of blocks (the maximum number of blocks it + can have without danger of some being reaped). Currently only disk + directories on DM have non-zero quotas. +7) the directory's allocation of blocks (the maximum number of blocks + the directory can have without IOC). Currently only directories on + DM have non-zero allocations. + + The preceding is all that is needed to print the table of +user/directory information that makes up the standard :DSKUSE or the +body of the full-scale :DSKUSE &. + A sample single user DSKUSE follows: + +:DSKUSE .INFO. + +User .INFO. +Files 83 +Links 23 +Blocks 366 +Quota 400 +Free Blocks + Unallocated 638 + Allocated 10618 of 41988 +Average User 214 + +Note that the "Free Blocks" lines are for a system with quotas. On a +non-quota'ed system it would be only one line and the "Quota" line +would not exist. + + +Disk System Information: + + The information printed by a :DSKUSE # is in two sections. The +first is a series of summary lines about the state of the disk system +when the DSKUSE was run. The second section is a table of information +with one column for each disk pack. + + The summary section varies depending upon how much information +is available when it is printed. In any case it prints summaries of +the number of directories on the system, the number of disks in the +system, their total size in blocks, how many blocks are free, and how +heavily the swapping allocations on those packs are being used. + + A sample :DSKUSE # follows. Note that some of the information +in the first section is dependent on the system having quotas. On a +non-quota system it would not appear. The section containing tabular +information on each disk drive would not appear in a :DSKUSE %. Also, +of course, the lines of the table dealing with quotas and allocations +would not appear on a non-quota system. + +:DSKUSE # + +Total number of users is 146, 103 with quotas, 35 with allocations +Over quota: 23 users, 3716 blocks, average excess 161 blocks each +Average blocks per user 218, per quota'ed user 170, per allocated user 335 +Free disk blocks: 372 unallocated, 10080 allocated +Disk system contains 6 disks, 41988 blocks +Free swapping blocks: 1531 out of 1800 + +Drive DK0: DK1: DK2: DK3: DK4: DK5: + +Pack # 17 18 19 20 21 22 +Disk size 10000 10000 10000 5000 5000 5000 + +Available 9498 9498 9498 4498 4498 4498 +Allocated 0 12400 6900 4650 0 0 +Free space 95 3474 5401 1205 181 96 + +Swap area 300 300 300 300 300 300 +Free swap area 254 265 262 252 250 248 + + + Finally, a :DSKUSE * or @ or & contains takes of users in +approximately the following format: + + +USER Files Links Blocks Quota Alloc B/F +---- + +AC 16 2 184 200 11.5 +AGJ 28 5 58 200 2.07 + +etc.,etc. + +Note that whenever such a table is output the column by which it is +sorted is underlined. The "Quota" and "Alloc" columns do not appear +on non-quota'ed systems. + + A :DSKUSE & is the most complete in terms of information output +as it combines the data from the :DSKUSE # and the :DSKUSE *. + +:DSKUSE & + +DM DISK USAGE by PDL at 13:33:28 on 2/21/76 + + + + + + \ No newline at end of file diff --git a/doc/_info_/dskuse.recent b/doc/_info_/dskuse.recent new file mode 100755 index 00000000..6b4c24b9 --- /dev/null +++ b/doc/_info_/dskuse.recent @@ -0,0 +1,124 @@ +DSKUSE RECENT CHANGES (PDL) + +--------------------------------------- +5/11/76 +--------------------------------------- + +1) New command with old name: :DSKUSE % tells you how +full a directory is. The command that used to be called % is +now called $ (dollar-sign). + +--------------------------------------- +2/21/76 +--------------------------------------- + +1) .INFO.;DSKUSE INFO exists! + +2) Really, truly understands unmounted packs. + +3) Slight change in JCL line @ and & commands. You may now give an +optional output file spec in the JCL line to direct output there +instead of the TTY or the TPL. + +4) When in command mode after * command, now takes syllable input +instead of single character. In other words, terminate with . +Now accepts names of columns as args in this mode as well as numbers. + +--------------------------------------- +1/9/76 +--------------------------------------- + +1) Now understands that it is possible to have inactive disk packs. +I.e.; should work on MC machine. + +2) Doesn't bother you with Quota/Allocation info if the totals for +same are zero. I.e.; works on AI and ML machines. + +--------------------------------------- +10/7/75 & 10/8/75 +--------------------------------------- + +DSKUSE has been updated to understand (somewhat) the additions to the +disk code involving allocations and such: + +1) On single user DSKUSEs, if the user has a quota but no allocation +it is printed. If he has an allocation it is printed. If he has an +allocation and his quota is not the same, it too is printed (this is +usually the result of an administrative glitch). If he is over his +quota, a star ("*") is printed to the right of his total of blocks. + +2) On multiple user DSKUSEs, two new columns, called (strangely enough) +"Quota" and "Alloc" have been added. The same procedure described +above is followed in printing each individual's summary. + +Another section at the top is tables of garbage about each disk. It +is similar to what is output by the new command "#". + +3) New command: ">" on JCL line causes DSKUSE to check your standing +vis a vis your quota and either do nothing or say: + + OVER QUOTA BY BLOCKS + +This is a useful thing to stuff in your .DDT_ file. + +4) Another new command: "#" on JCL line causes DSKUSE to grovel print +stuff similar to what "%" prints plus a table of information about +each disk. This grovels over all UFDs just like "*" so it takes a +little while. + +69) AI and ML have quotas and allocations but don't use them yet (if +ever). Eventually DSKUSE will figure this out on the fly. + +--------------------------------------- +5/7/73 +--------------------------------------- + +0. Uses .BREAK 12, so will work in DDT as well as MONIT +1. Now prints system and culprit ("DM DISK USAGE by PDL") +2. Can get simultaneous users and blocks printout with & +3. @ only opens disk file, does not output a sort +4. B/F now prints only 3 or 4 digits +5. Sort column is underlined +6. Top level & is like @ & would be if that worked +7. Disk output is to TPL: instead of DSK: +8. As reads image dirs, no longer prints output as it goes + to convince you it is still alive + +----------------------------------------- + +PRINTS OUT DISK STATS. +TYPE TO MONIT: +1. DSKUSE or +2. DSKUSE * N or DSKUSE @ N or DSKUSE & + * OR @ DOES FOR ALL USERS + + * MAKES INITIAL OUTPUT TO TTY + @ MAKES INITIAL OUTPUT TO "DSKUSE OUTPUT" + "N" IS COLUMN OF OUTPUT TO SORT ON + WILL OUTPUT TO TTY. WHEN DONE, + TYPE COLUMN NUMBER FOR A NEW SORT, OR + "Q" TO QUIT. + + TYPE @ TO ENTER OUTPUT TO DSK MODE, IF NOT ALREADY + IN IT BY INITIAL "DSKUSE @". + COLUMNS ARE 0 -- UNAME (IF NO N TYPED, N = 0) + 1 -- # OF FILES + 2 -- # OF LINKS + 3 -- # OF BLOCKS + 4 -- AVERAGE BLOCKS PER FILE + +3. Character "&" as top-level command makes initial + output combined username and blocks sort to disk. + This sort may be gotten at any time thereafter by "&" + as command character. + +4. Prints out "global" disk statistics at top of output: + a. System (AI, DM, or ML) + b. Who did it + c. DATE and TIME dskuse was done + d. Number of USERS on disk + e. AVERAGE blocks per user dir. + f. Number of FREE blocks on the disk + + --pdl (4/28/72) + \ No newline at end of file diff --git a/doc/info/dskuse.10 b/doc/info/dskuse.10 new file mode 100755 index 00000000..288f2aea --- /dev/null +++ b/doc/info/dskuse.10 @@ -0,0 +1,174 @@ +-*-Text-*- + +File: DSKUSE Node: Top Up: (DIR) Next: Normal + +DSKUSE INFO + + DSKUSE is a program for gathering and printing information +about the disk system. + +* Menu: + +* Normal:: The standard way to run DSKUSE +* Directory:: An explanation of the various things DSKUSE returns when + applied to a single directory +* Disk:: Similar to above; what DSKUSE returns when applied to the + disk system + + +File: DSKUSE, Node: Normal, Previous: Top, Up: Top, Next: Directory + +DSKUSE is usually driven by a command from its JCL line, as follows: + +:DSKUSE user statistics on the user directory given, or the XUNAME + directory if no argument. +:DSKUSE > user print message if XUNAME user (or user given explicitly) + is over quota, else nothing. + +:DSKUSE @ file statistics on all users output to TPL:, or to file + if given. +:DSKUSE & file output two tables, sorted on user and blocks, to TPL: + or to file if given. + +:DSKUSE # general statistics on disk system (takes time). +:DSKUSE $ same as previous, only less detailed (faster, too). + +:DSKUSE % user Gives percent of directory space used by user. + +:DSKUSE * statistics on all users, in tabular form. + this command is special in that it leaves you in DSKUSE. + you may type the number or name of a column to sort by + that column and then reprint the table (0 or USER, 1 or + FILES, etc.). in this mode the @ command, with a file + name optionally following it, causes subsequent sorts + to go to the file. the commands #, %, and > are not + available. The dual sort (& or BOTH) is, however. + + +File: DSKUSE, Node: Directory, Previous: Normal, Up: Top, Next: Disk + +Details of DSKUSE Data Collection and Printing + +Quotas and Allocations: + + In the sections which follow, the idea of a "non-quota'ed" +system is occasionally used. DSKUSE understands this to mean a system +on which the total number of blocks allocated and quota'ed is zero. +Currently all ITS's have the software for quotas and allocations, but +only the DM system uses it. DSKUSE should do the right thing if any +of the other ITS's start actually using quotas and allocations. + +Single directory information: + + For each directory covered by DSKUSE, seven pieces of information +are stored. These are: + +1) the directory name, +2) the number of files in the directory, +3) the number of links in the directory (note that these two numbers + total to the number of "files" in the directory, ie: the number of + lines you will see if you list it). +4) the number of blocks used by files in the directory (this is gotten + from the appropriate word in the directory, rather than by calculating + it as was done in the past -- a considerable speedup). +5) the average number of blocks per file in the directory (a floating + point number, obviously). +6) the directory's quota of blocks (the maximum number of blocks it + can have without danger of some being reaped). Currently only disk + directories on DM have non-zero quotas. +7) the directory's allocation of blocks (the maximum number of blocks + the directory can have without IOC). Currently only directories on + DM have non-zero allocations. + + The preceding is all that is needed to print the table of +user/directory information that makes up the standard :DSKUSE or the +body of the full-scale :DSKUSE &. + A sample single user DSKUSE follows: + +:DSKUSE .INFO. + +User .INFO. +Files 83 +Links 23 +Blocks 366 +Quota 400 +Free Blocks + Unallocated 638 + Allocated 10618 of 41988 +Average User 214 + +Note that the "Free Blocks" lines are for a system with quotas. On a +non-quota'ed system it would be only one line and the "Quota" line +would not exist. + + +File: DSKUSE, Node: Disk, Previous: Directory, Up: Top + +Disk System Information: + + The information printed by a :DSKUSE # is in two sections. The +first is a series of summary lines about the state of the disk system +when the DSKUSE was run. The second section is a table of information +with one column for each disk pack. + + The summary section varies depending upon how much information +is available when it is printed. In any case it prints summaries of +the number of directories on the system, the number of disks in the +system, their total size in blocks, how many blocks are free, and how +heavily the swapping allocations on those packs are being used. + + A sample :DSKUSE # follows. Note that some of the information +in the first section is dependent on the system having quotas. On a +non-quota system it would not appear. The section containing tabular +information on each disk drive would not appear in a :DSKUSE %. Also, +of course, the lines of the table dealing with quotas and allocations +would not appear on a non-quota system. + +:DSKUSE # + +Total number of users is 146, 103 with quotas, 35 with allocations +Over quota: 23 users, 3716 blocks, average excess 161 blocks each +Average blocks per user 218, per quota'ed user 170, per allocated user 335 +Free disk blocks: 372 unallocated, 10080 allocated +Disk system contains 6 disks, 41988 blocks +Free swapping blocks: 1531 out of 1800 + +Drive DK0: DK1: DK2: DK3: DK4: DK5: + +Pack # 17 18 19 20 21 22 +Disk size 10000 10000 10000 5000 5000 5000 + +Available 9498 9498 9498 4498 4498 4498 +Allocated 0 12400 6900 4650 0 0 +Free space 95 3474 5401 1205 181 96 + +Swap area 300 300 300 300 300 300 +Free swap area 254 265 262 252 250 248 + + + Finally, a :DSKUSE * or @ or & contains takes of users in +approximately the following format: + + +USER Files Links Blocks Quota Alloc B/F +---- + +AC 16 2 184 200 11.5 +AGJ 28 5 58 200 2.07 + +etc.,etc. + +Note that whenever such a table is output the column by which it is +sorted is underlined. The "Quota" and "Alloc" columns do not appear +on non-quota'ed systems. + + A :DSKUSE & is the most complete in terms of information output +as it combines the data from the :DSKUSE # and the :DSKUSE *. + +:DSKUSE & + +DM DISK USAGE by PDL at 13:33:28 on 2/21/76 + + + +
diff --git a/src/syseng/dskuse.76 b/src/syseng/dskuse.76 new file mode 100755 index 00000000..c75a9e4c --- /dev/null +++ b/src/syseng/dskuse.76 @@ -0,0 +1,2044 @@ +; -*-MIDAS-*- +TITLE DSKUSE -- DSK INFO -- PDL 2/19/76 + +;9/6/79 Modified for new TUT format (ITS 1154) + +; note to the perplexed: The value of the symbol +; MAXUSR (currently 512.) controls how many users DSKUSE can handle. +; since this is the maximum number of directories ITS can have in the +; current implementation, this should be enough. + +.MLLIT=1 + +; ==================================================================== +; accumulator definitions +; ==================================================================== + +A=1 +B=2 +C=3 +D=4 +E=5 +F=6 +G=7 +H=10 +I=11 +J=12 +K=13 +L=14 +M=15 +N=16 +ARGP=16 +P=17 + +TYIC==1 ; channels +TYOC==2 +CH==3 +MCH==4 +TCMD==5 ; command output channel + + ; disk system variables + +.INSRT SYSTEM;FSDEFS > + +%USRBLK==8 ; size of single user info block + +%USER==0 ; offsets of data +%FILES==1 +%LINKS==2 +%BLCKS==3 +%QUOTA==4 +%ALLOC==5 +%PACKN==6 +%BLKAV==7 + +; command macro + +DEFINE COM DIS,NMS +IRP NM,,[NMS] + SIXBIT \!NM!\ + PUSHJ P,DIS +TERMIN +TERMIN + +; fix and float macros + +DEFINE FLOAT AX,AY + TLC AX,232000+1000*AY + FADR AX,AX +TERMIN + +DEFINE FIX AX,AY + MULI AX,400 + TSC AX,AX + ASH AX+1,AY-243(AX) + TERMIN + +; ==================================================================== +; :dskuse ? +; ==================================================================== + +CINFO: ASCIZ \ +DSKUSE is usually driven by a command from its JCL line, as follows: + +:DSKUSE user statistics on the user directory given, or the MSNAME + directory if no argument. +:DSKUSE > user print message if MSNAME user (or user given explicitly) + is over quota, else nothing. + +:DSKUSE @ file statistics on all users output to TPL:, or to file + if given. +:DSKUSE & file output two tables, sorted on user and blocks, to TPL: + or to file if given. + +:DSKUSE # general statistics on disk system (takes time). +:DSKUSE $ same as previous, only less detailed (faster, too). + +:DSKUSE % user print % of directory space used by user. + +:DSKUSE * statistics on all users, in tabular form. + this command is special in that it leaves you in DSKUSE. + you may type the number or name of a column to sort by + that column and then reprint the table (0 or USER, 1 or + FILES, etc.). in this mode the @ command, with a file + name optionally following it, causes subsequent sorts + to go to the file. the commands #, %, and > are not + available. The dual sort (& or BOTH) is, however. + +For more details see .INFO.;DSKUSE INFO.\ + +INFO: OASCR CINFO + JRST KILL + +; ==================================================================== +; DSKUSE +; ==================================================================== + +START: MOVE P,[-100,,PDL] ; set up pdl + +; here to open ttys + .OPEN TYIC,[SIXBIT / TTYFOOBARBLECH /] + .VALUE [ASCIZ /:CANT OPEN TTY/] + .OPEN TYOC,[SIXBIT / !TTYXXXXXXYYYYYY/] + .VALUE [ASCIZ !:CANT OPEN TTY!] + .OPEN TCMD,[SIXBIT / 1TTYXXXXXXYYYYYY/] + .VALUE [ASCIZ !:CANT OPEN TTY!] + +; set up TTY interrupt + .CALL [SETZ + 'TTYGET + 1000,,TYIC + 2000,,A + 402000,,B] + .VALUE [ASCIZ /:CANT GET CONSOLE TYPE/] +; make only ^G and ^S interrupt + MOVE 0,[SIXBIT / !!!!!/] + ANDCAM 0,A + MOVE 0,[SIXBIT / !!!!!/] + ANDCAM 0,B + .CALL [SETZ + 'TTYSET + 1000,,TYIC + A + 400000,,B] + .VALUE [ASCIZ /:CANT SET CONSOLE TYPE/] +; enable interrupt + MOVEI A,1 ; tty int + SETZ B, + .SETM2 A, + +; get msname of user + .SUSET [.RSNAM,,RSYSNM] + MOVE RSYSNM + MOVEM USRNAM +; get command from superior + .SUSET [.ROPTIO,,A] + TLNN A,40000 ; OPTCMD + JRST HUSER + .BREAK 12,[5,,COMMND] + SKIPN COMMND + JRST HUSER ; no argument + +; got arg, so parse it + MOVE [440700,,COMMND] + MOVEM COMPTR + PUSHJ P,GETSYL ; get command, if any + JUMPE B,HUSER + +; dispatch + MOVE A,SWPTR +JCLOOP: CAMN B,(A) + JRST @1(A) + AOS A + AOBJN A,JCLOOP + MOVEM B,USRNAM + JRST OUSER ; assume funny user + +; ==================================================================== +; jcl line command table +; ==================================================================== + +SWTABL: COM AUSER,[&] ; two column, user and blocks sorted + COM AUSER1,[@] ; one column, user, to tpl + COM AUSER2,[*] ; one column, no tpl + COM DSKDAT,[$] ; quick statistics + COM QUSER,[#] ; detailed statistics + COM UFULL,[%] ; percent of dir used + COM UFULLB,[%%] ; dir bloated? + COM UOVER,[>] ; quota check + COM INFO,[?] ; info +SWPTR: -<<.-SWTABL>/2>,,SWTABL + +; ==================================================================== +; :DSKUSE % +; ==================================================================== + +UFULLB: SETOM UFULLF' +UFULL: PUSHJ P,GETSYL + SKIPE B + MOVEM B,USRNAM + .SUSET [.SSNAM,,USRNAM] +; read ufd in + .OPEN CH,UDIR + JRST NOUFD + MOVE A,[-2000,,FDIR] + .IOT CH,A + .CLOSE CH, + PUSHJ P,UFULL0 + JRST KILL + +UFULL0: MOVE D,UDESCP+FDIR + MOVEI C,UDDESC+FDIR ; ; D/ desc count + HRLI C,440600 ; "BYTE PTR" + SETZ B, ; "COUNT" +NEXTA: SETZ A, +NEXTB: SOJL D,FEND + ILDB C + JUMPE NBYTE ; "ZERO BYTE?" + SETOM A ; "NON-ZERO BYTE" + JRST NEXTB ; "LOOP" +NBYTE: JUMPN A,NEXTA ; "ZERO, WAS LAST ZERO?" + SETZM A + AOJA B,NEXTB ; "AOS NULL COUNT" +FEND: MOVE C,UDESCP+FDIR + SUB C,B + IDIVI C,6 ; "NUMBER OF WORDS" + + ADDI C,2000 + SUB C,UDNAMP+FDIR + FLOAT C + + MOVEI B,2000-UDDESC + FLOAT B + FDVR B,[100.0] + FDVR C,B + + SKIPN UFULLF + JRST UFULLP + CAMGE C,[97.0] + POPJ P, +UFULLP: OASC [ASCIZ /Directory /] + OSIX USRNAM + OASC [ASCIZ / is /] + JUMPE C,UEMPTY + OFLOAT C + OASCR [ASCIZ /% full./] + POPJ P, + +UEMPTY: OASCR [ASCIZ /empty./] + POPJ P, + +; ==================================================================== +; :DSKUSE > +; ==================================================================== + +UOVER: PUSHJ P,GETSYL + SKIPE B + MOVEM B,USRNAM + .SUSET [.SSNAM,,USRNAM] + PUSHJ P,USRDSK + JRST KILL + MOVE B,UBLCKS + CAMG B,UQUOTA + JRST KILL + SUBM B,UQUOTA + OASCR [0] + OSIX USRNAM + OASC [ASCIZ / OVER QUOTA BY /] + ODEC UQUOTA + OASCR [ASCIZ / BLOCKS/] + JRST KILL + +; ==================================================================== +; :DSKUSE # +; ==================================================================== + +QUSER: PUSHJ P,DSKAV + PUSHJ P,GATHER + PUSHJ P,DATOUT + OASCR [0] + PUSHJ P,QSKOUT + JRST KILL + +; ==================================================================== +; :DSKUSE % +; ==================================================================== + +; here for general data +DSKDAT: PUSHJ P,DSKAV ; get system data + PUSHJ P,DATOUT ; print system data + JRST KILL ; exit + +; ==================================================================== +; :DSKUSE +; ==================================================================== + +; here for just doing this user +HUSER: .SUSET [.RSNAM,,USRNAM] + JRST EUSER + +; ==================================================================== +; :DSKUSE +; ==================================================================== + +; here for specified user +OUSER: SKIPE USRNAM + .SUSET [.SSNAM,,USRNAM] + +; common area for single user dskuse +EUSER: OASCR [0] + PUSHJ P,DSKAV ; get data on system as whole + PUSHJ P,USRDSK ; get data on single user + JRST NOUFD + +; print data for single user + PUSHJ P,UFULL0 + ;OASC [ASCIZ /User /] + ;OSIX USRNAM + ;OASCR [0] + OASC [ASCIZ /Files /] + ODECR UFILES + OASC [ASCIZ /Links /] + ODECR ULINKS + OASC [ASCIZ /Blocks /] + ODEC UBLCKS + SKIPN UPACKN + JRST EUQOTA + OASCR [0] + OASC [ASCIZ/Allocated to pack /] + ODEC UPACKN + ;Attempt to extract pack name out of the system + MOVE A,UPACKN + MOVE B,NQS + SUBI B,1 + CAME A,QPKID(B) + SOJGE B,.-1 + JUMPL B,EUQOTA + SKIPE A,TRESRV(B) + CAMN A,[-1] + JRST EUQOTA + OASC [ASCIZ/ (/] + OSIX A + OASC [ASCIZ/:)/] +EUQOTA: SKIPG A,UQUOTA + JRST EUSBLK + CAMGE A,UBLCKS + OASCI "* +EUSBLK: OASCR [0] + SKIPG UALLOC + JRST EUSERQ + OASC [ASCIZ \Allocation \] + ODECR UALLOC +EUSERQ: MOVE A,UALLOC + CAMN A,UQUOTA + JRST EUSYST + OASC [ASCIZ \Quota \] + ODECR UQUOTA + +; print data for system as a whole +EUSYST: OASC [ASCIZ \Free Blocks \] + SKIPG FREEBL + JRST EUSYS1 +; here if there are allocations + OASCR [0] + OASC [ASCIZ \ Unallocated \] + ODECR FRUNAL + OASC [ASCIZ \ Allocated \] + ODEC FREEBL +EUSYS2: OASC [ASCIZ \ of \] + ODECR ALLBL + OASC [ASCIZ \Average User \] + ODECR AVER + JRST KILL ; exit +; here if there are no allocations +EUSYS1: ODEC FRUNAL + JRST EUSYS2 + +; ==================================================================== +; :DSKUSE & +; ==================================================================== + +AUSER: SETOM BOTH ; set & flag + +; ==================================================================== +; :DSKUSE @ +; ==================================================================== + +; here to output table to disk +AUSER1: PUSHJ P,SCNAME + PUSHJ P,DSKOUT ; open disk channel + SETOM JCLFLG + +; ==================================================================== +; :DSKUSE * +; ==================================================================== + +; here to output table to tty after finishing + +AUSER2: SETZB G,H + SETZ I, + OASCR [0] + +; get data on date, time, and system name + +; what system are we on? + .CALL RDSYST + JFCL +; time + .RTIME A, + MOVEM A,TIME +; date + .RDATE A, + ROT A,12. + MOVEM A,DATE + +; optional sort number 0 => 5 + PUSHJ P,GETSYL + LDB A,[360600,,B] + SUBI A,20 + CAIL A,0 + CAILE A,5 ; 6 columns + SETZ A, + SKIPE A + MOVEM A,SORTX ; sort on what entry in vector? + HRRM A,SORTX + +; enter loop here to get users and status them one after another +; out of mfd + + PUSHJ P,DSKAV + PUSHJ P,GETMFD + PUSHJ P,GATHER ; here to frob all ufd's + + HRRI N,USERS ; save aobjn to users + MOVEM N,CPTR + +; calculate blocks/file + MOVE A,TBL + MOVE B,TFL + FLOAT A, + FLOAT B, + FDVR A,B + MOVEM A,TAV + JRST ENDST1 + +; call block for .call /sstatu/ + +RDSYST: SETZ + SIXBIT /SSTATU/ + 2000,,0 + 2000,,0 + 2000,,0 + 2000,,0 + 2000,,0 + SETZM SYSNAM + ; * print * + +ENDST1: SKIPL BOTH + JRST ONESRT + +; * here for & dskuse (0 & 3 sort at once) * + +; do 3 sort (blocks) + MOVEI A,3 + MOVE M,CPTR + PUSHJ P,VSORT +; move results into second data vector + MOVE M,CPTR + HRRI M,FDIR + MOVEM M,CPTR1 + MOVE A,[USERS,,FDIR] + BLT A,FDIR+MAXUSR-1 + +; do 0 sort + MOVSI A,-1 + MOVE M,CPTR + PUSHJ P,VSORT + JRST PRTSRT ; print results + +; * do single sort * + +ONESRT: MOVE A,SORTX ; sort key + MOVE M,CPTR ; cptr + PUSHJ P,VSORT ; do it + ; here to print sort +PRTSRT: OASCI ^L ; form feed + OASCR [0] + +; herald message + OSIX SYSNAM + OASC [ASCIZ \ DISK USAGE by \] + OSIX RSYSNM + OASC [ASCIZ \ at \] + OTIME TIME + OASC [ASCIZ \ on \] + ODATE DATE + OASCR [0] + OASCR [0] + +; general system data + PUSHJ P,DATOUT + OASCR [0] + SKIPN BOTH + JRST COLHDR + PUSHJ P,QSKOUT + OASCR [0] + +; column header(s) +COLHDR: OASCR [0] + PUSHJ P,TYPHDR + SKIPN BOTH + JRST ONEHDR + +; here to type extra header for & mode + OASC [ASCIZ \ \] + PUSHJ P,TYPHDR + OASCR [0] + +; underline appropriate column headers + OASC [ASCIZ \---- \] + SKIPG TQUO + JRST COLHD1 + OASCI ^I +COLHD1: SKIPG TALLO + JRST COLHD2 + OASCI ^I +COLHD2: OASCR [ASCIZ \ ------\] + JRST TYPSTT ; start normal typeout + +; here to underline normal header +ONEHDR: OASCR [0] + HRRZ B,SORTX + XCT PTABS(B) ; appropriate tabs + OASCR [0] + +; here to start typing user stats +TYPSTT: OASCR [0] + MOVE D,CPTR + MOVE G,CPTR1 +; loop +TYPNXT: MOVE A,(D) + PUSHJ P,TYPOUT + SKIPN BOTH + JRST TYPEND + OASC [ASCIZ \ \] + MOVE A,(G) + PUSHJ P,TYPOUT +TYPEND: OASCR [0] + ADD G,[1,,1] + AOBJN D,TYPNXT + +; done, type totals + OASCR [0] + PUSHJ P,TYPTOT + SKIPN BOTH + JRST TYPGET + +; type extra total, for second list in & dskuse + OASC [ASCIZ \ \] + PUSHJ P,TYPTOT + +; form feed if in & mode + SKIPE BOTH + OASCI ^L + +; prepare to get a command +TYPGET: SETZM BOTH + +; here to get a command typed from tty, after we have performed +; the single command that could be given when dskuse was invoked. +TYPCOM: SKIPE JCLFLG' + JRST KILL + .IOT TCMD,["*] + MOVE N,M + PUSHJ P,READ + PUSHJ P,GETSYL + + MOVE A,TYPPTR +TYPLUP: CAMN B,(A) + JRST @1(A) + AOS A + AOBJN A,TYPLUP +BADCOM: .IOT TCMD,["?] + .IOT TCMD,["?] + .IOT TCMD,[^M] + .IOT TCMD,[^J] + JRST TYPCOM + +TYPTAB: COM KILL,[Q,QUIT,KILL] + COM DSKOPN,[@] + COM DSKOP1,[&] + COM SRTUSR,[0,U,USER] + COM SRTFIL,[1,F,FILE,FILES] + COM SRTLNK,[2,L,LINK,LINKS] + COM SRTBLK,[3,B,BLK,BLOCK,BLOCKS] + COM SRTQUO,[4,Q,QUO,QUOTA,QUOTAS] + COM SRTALL,[5,A,ALL,ALLOC,ALLOCA] + COM SRTPCK,[6,P,PACK] + COM SRTAVG,[7,R,RATIO,B/F,BF,AVG] +TYPPTR: -<<.-TYPTAB>/2>,,TYPTAB + +; ==================================================================== +; sort commands +; ==================================================================== + +SRTUSR: MOVEI A,0 + JRST SORTIT +SRTFIL: MOVEI A,1 + JRST SORTIT +SRTLNK: MOVEI A,2 + JRST SORTIT +SRTBLK: MOVEI A,3 + JRST SORTIT +SRTQUO: MOVEI A,4 + JRST SORTIT +SRTALL: MOVEI A,5 + JRST SORTIT +SRTPCK: MOVEI A,6 + JRST SORTIT +SRTAVG: MOVEI A,7 + +; if name column, sort "backwards" +SORTIT: SKIPN A + HRLI A,-1 ; sort "frontwards" + MOVEM A,SORTX ; set up sort key + JRST ENDST1 + +; output a double sort +DSKOP1: SETOM BOTH + JRST ENDST1 + +; ==================================================================== +; output rest of sorts to disk +; ==================================================================== + +DSKOPN: PUSHJ P,SCNAME ; cons up output file spec + PUSHJ P,DSKOUT ; open it + JRST TYPCOM ; loop + +; here to reopen "TTY" channel to "DSK" +DSKOUT: .SUSET [.SSNAM,,RSYSNM] + MOVEI '! + HRLM OUTPUT + .OPEN TYOC,OUTPUT + .VALUE [ASCIZ !:CANT OPEN OUTPUT FILE!] + POPJ P, + +; here to exit by killing job and not typing anything +EXIT: .VALUE [ASCIZ /:KILL + +/] + +KILL: .BREAK 16,140000 + + +HEADER: ASCIZ \USER Files Links Blocks\ +HEADE1: ASCIZ \ Quota\ +HEADE2: ASCIZ \ Alloc\ +HEADE3: ASCIZ \ Pack\ +HEADE4: ASCIZ \ B/F\ + +TYPHDR: OASC HEADER + SKIPE TQUO + OASC HEADE1 + SKIPE TALLO + OASC HEADE2 + OASC HEADE3 + OASC HEADE4 + POPJ P, + +PTABS: OASC [ASCIZ /----/] + OASC [ASCIZ / -----/] + OASC [ASCIZ / -----/] + OASC [ASCIZ / ------/] + OASC [ASCIZ / -----/] + OASC [ASCIZ / -----/] + OASC [ASCIZ / ----/] + OASC [ASCIZ / ---/] + +; * type total line * + +TYPTOT: OASC [ASCIZ \Total \] + OJUST 3,TFL + OASCI ^I + OJUST 3,TLK + OASCI ^I + OJUST 4,TBL + OASCI ^I + SKIPG TQUO + JRST TYPTO1 + OJUST 4,TQUO + OASCI ^I +TYPTO1: SKIPG TALLO + JRST TYPTO2 + OJUST 4,TALLO + OASCI ^I + OASCI ^I +TYPTO2: OFLOAT TAV + POPJ P, + +; * output general data * + +DATOUT: OASC [ASCIZ \Total number of users is \] + ODEC TUS + SKIPG TQUO + JRST DATUAL + OASC [ASCIZ \, \] + ODEC TUQUOT + OASC [ASCIZ \ with quotas\] + +DATUAL: SKIPG TALLO + JRST DATUSR + OASC [ASCIZ \, \] + ODEC TUALLO + OASC [ASCIZ \ with allocations\] +DATUSR: OASCR [0] + + SKIPG TQUO + JRST DATAVG + OASC [ASCIZ \Over quota: \] + ODEC TPIGS + OASC [ASCIZ \ users, \] + ODEC TFAT + OASC [ASCIZ \ blocks, average excess \] + ODEC TBACON + OASC [ASCIZ \ blocks each\] + OASCR [0] + +DATAVG: OASC [ASCIZ \Average blocks per user \] + ODEC AVER + + SKIPG TQUO + JRST DATALO + OASC [ASCIZ \, per quota'ed user \] + ODEC TAQUOT + +DATALO: SKIPG TALLO + JRST DATFRE + OASC [ASCIZ \, per allocated user \] + ODEC TAALLO + +DATFRE: OASCR [0] + OASC [ASCIZ \Free disk blocks: \] + ODEC FRUNAL + SKIPG TALLO + JRST DATOUX + OASC [ASCIZ \ unallocated, \] + ODEC FREEBL + OASC [ASCIZ \ allocated\] +DATOUX: OASCR [0] + OASC [ASCIZ \Disk system contains \] + ODEC NQS + OASC [ASCIZ \ disks\] + MOVE A,NQS + CAMN A,NQSONL + JRST DATOUY + OASC [ASCIZ \ (\] + ODEC NQSONL + OASC [ASCIZ \ on-line)\] +DATOUY: OASC [ASCIZ \, \] + ODEC ALLBL + OASCR [ASCIZ \ blocks\] + OASC [ASCIZ \Free swapping blocks: \] + ODEC FREESW + OASC [ASCIZ \ out of \] + ODECR SWAPAL + + OASC [ASCIZ \Unused UFD slots: \] + MOVE A,NUDSL + SUB A,TUS + SETZ B, + BLT B, + SKIPE B ;If this is a KL10 or a KS10, it has a + SUBI A,2 ; front-end file system in blocks 0,1 + ODEC A + OASC [ASCIZ \ of \] + MOVE A,NUDSL + SKIPE B + SUBI A,2 + ODECR A + + POPJ P, + +; here to output tables of disk crufties +QSKOUT: OASC [ASCIZ \Drive \] + SETZ K, +QSKTOP: CAML K,NQS + JRST QSKEND + OASC [ASCIZ \DK\] + ODEC K + OASC [ASCIZ \: \] + AOJA K,QSKTOP +QSKEND: OASCR [0] + OASCR [0] + OASC [ASCIZ \Pack # \] + MOVEI B,QPKID + PUSHJ P,QTABL1 + OASC [ASCIZ \Disk size \] + MOVEI B,TLASTB + PUSHJ P,QTABL1 + OASCR [0] + + OASC [ASCIZ \Available \] + MOVEI B,TSIZES + PUSHJ P,QTABL1 + +; only print alloc if there is some + SKIPG TALLO + JRST QFREEP + OASC [ASCIZ \Allocated \] + MOVEI B,PACK + PUSHJ P,QTABL1 + +QFREEP: OASC [ASCIZ \Free space \] + MOVEI B,QSFT + PUSHJ P,QTABL1 + OASCR [0] + + OASC [ASCIZ \Swap area \] + MOVEI B,TSWAPA + HLL B,QPTR + MOVE D,QPTR + HRRI D,QACT +QSWAPT: SKIPE (D) + JRST QSWAP1 + MOVE C,(B) + SUB C,NUDSL + SKIPGE C + MOVEI C,0 + OJUST 5,C +QSWAP2: OASCI ^I + AOBJN D,.+1 + AOBJN B,QSWAPT + OASCR [0] + OASC [ASCIZ \Free swap area \] + MOVEI B,QSFTS + PUSHJ P,QTABL1 + POPJ P, + +QSWAP1: OASC [ASCIZ / --/] + JRST QSWAP2 + +QTABL1: PUSH P,C + MOVE C,QPTR + HRRI C,QACT + HLL B,QPTR +QTABL3: SKIPE (C) + JRST QTABL2 + OJUST 5,(B) +QTABL4: OASCI ^I + AOBJN C,.+1 + AOBJN B,QTABL3 + OASCR [0] + POP P,C + POPJ P, +QTABL2: OASC [ASCIZ \ --\] + JRST QTABL4 + +QTABLE: HLL B,QPTR + OJUST 5,(B) + OASCI ^I + AOBJN B,QTABLE+1 + OASCR [0] + POPJ P, + + +; point at user vector -- up to MAXUSR users +GATHER: MOVEI A,USERS + MOVEM A,N + MOVEM A,M ; ptr to vector +; zero total of users + SETZM TUS ; users + SETZM TPIGS ; users over quota + SETZM TFAT ; total excess + SETZM TBACON ; average excess + PUSHJ P,GETMFD + +GATHE1: PUSHJ P,MFDN ; get a user id into C + JRST GATHEX + JUMPE C,GATHE1 ; loop if empty slot + MOVEM C,USRNAM ; username + .SUSET [.SSNAM,,C] ; set to it +; individual user stats + PUSHJ P,USRDSK + JRST GATHE1 + PUSHJ P,USRVEC ; add to vector + AOS TUS + JRST GATHE1 ; loop + +GATHEX: MOVE A,TFAT ; calculate avg blks for pigs + MOVE B,TPIGS + PUSHJ P,AVG + MOVEM A,TBACON + + MOVE A,TBQUOT ; calculate avg blks for quota + MOVE B,TUQUOT + PUSHJ P,AVG + MOVEM A,TAQUOT + + MOVE A,TBALLO ; calculate avg blks for alloc + MOVE B,TUALLO + PUSHJ P,AVG + MOVEM A,TAALLO + POPJ P, + +; average, given total and number of instances (as fixes), return a fix +AVG: PUSH P,B + FLOAT A + FLOAT B + FDVR A,B + FIX A + MOVE A,B + POP P,B + POPJ P, + +; * here to get average number of blocks per user on disk * + +;This comment is wrong! +; makes a good guess at number of free blocks on disks by finding out +; number of packs, and number of free blocks on each, subtracting that from +; number of packs times 5000 blocks per pack minus 200 ufd blocks and 1 mfd, 1 tut +; per pack. + +; Puts results out in ALLBL (total number of blocks) +; and FREEBL (number of blocks free) + +DSKAV: PUSHJ P,QNUM ; how many packs + PUSHJ P,QRES ; any reserved? + PUSHJ P,DSKALL ; total disk blocks + PUSHJ P,DSKFRE ; free disk blocks + PUSHJ P,SWPFRE ; free swapping blocks + PUSHJ P,DSKMFD ; get # of users, blocks/user + POPJ P, + +; * number of packs in system * + +; nqs/ # of packs +; qtuto/ -n,,qtuto +; tutsiz/ # of blocks per tut + +QNUM: PUSH P,A + MOVE A,[SQUOZE 0,NQS] + .EVAL A, + .VALUE [ASCIZ /:.EVAL OF NQS FAILED/] + MOVEM A,NQS + MOVNS A + HRLS A + HRRI A,QTUTO + MOVEM A,QPTR +; get number blocks for a tut + MOVE A,[SQUOZE 0,NTUTBL] + .EVAL A, + .VALUE [ASCIZ /:.EVAL OF SYMBOL IN A FAILED/] + MOVEM A,TUTSIZ + POP P,A + POPJ P, + +; any reserved packs in system?? + +QRES: PUSH P,A + MOVE A,[SQUOZE 0,QRSRVP] + SETOM TUTRSR + .EVAL A, + SETZB A,TUTRSR + MOVEM A,QRSRVP + POP P,A + POPJ P, + +; * free blocks in system * + +; freebl/ free blocks in system + +DSKFRE: PUSH P,A + PUSH P,B + MOVE A,[QSFT,,[SQUOZE 0,QSFT]] + PUSHJ P,GETQ + MOVEI B,QSFT + PUSHJ P,QTOTAL + MOVEM A,FREEBL + MOVEI B,0 + HLL B,QPTR + SETZ A, +DSKFR1: SKIPE TRESRV(B) + JRST DSKFR2 + SKIPL QSFT(B) + ADD A,QSFT(B) +DSKFR2: AOBJN B,DSKFR1 + MOVEM A,FRUNAL + MOVNS A + ADDM A,FREEBL + POP P,B + POP P,A + POPJ P, + +; * free swapping blocks * + +; freesw/ free swapping blocks + +SWPFRE: PUSH P,A + PUSH P,B + MOVE A,[QSFTS,,[SQUOZE 0,QSFTS]] + PUSHJ P,GETQ + MOVEI B,QSFTS + PUSHJ P,QTOTAL + MOVEM A,FREESW + POP P,B + POP P,A + POPJ P, + +; * getloc of (in ac A) symbol to symbol+nqs * + +; qtuto/ first pack +; ... +; qtuto+nqs-1/ last pack + +GETQ: PUSH P,B + MOVE B,QPTR + HLR B,A + MOVE A,(A) + .EVAL A, + .VALUE [ASCIZ /:.EVAL OF SYMBOL IN A FAILED/] + HRLS A + HRR A,B + .GETLOC A, + ADD A,[1,,1] + AOBJN B,.-2 + POP P,B + POPJ P, + + +; A/
,, symbol +GETUT: PUSH P,B + PUSH P,C + HRLZ C,A ; C/ symbol,,0 + HLRZ A,A ; A/ table nqs long + MOVE B,QPTR ; B/ -nqs,,qtuto + +SIZLUP: HRL A,(B) + ADD A,C ; offset by QTUTO + .GETLOC A, + AOS A + AOBJN B,SIZLUP + POP P,C + POP P,B + POPJ P, + +; * allocations * + +; swapal/ swapping allocation +; allbl/ total of system blocks + +DSKALL: PUSH P,A + PUSH P,B + PUSH P,C + PUSH P,D + +; read in qtuto table + MOVE A,[QTUTO,,[SQUOZE 0,QTUTO]] + PUSHJ P,GETQ + +; find out which packs are active + MOVE A,[QACT,,[SQUOZE 0,QACT]] + PUSHJ P,GETQ + +; now total on-line disk packs + SETZ A, + MOVEI B,QACT + HLL B,QPTR + SKIPN (B) ; offline? + AOS A + AOBJN B,.-2 + MOVEM A,NQSONL + +; find out pack numbers for each drive + MOVE A,[QPKID,,[SQUOZE 0,QPKID]] + PUSHJ P,GETQ + +; find out which packs are allocated + SKIPN TUTRSR ; reservations in tut? + JRST OLDRSR + + MOVE A,[TRESRV,,QTRSRV] + SKIPE QRSRVP ; any reserved packs in system? + PUSHJ P,GETUT + JRST GSWAPA + +OLDRSR: MOVE A,[TRESRV,,[SQUOZE 0,QRESRV]] + PUSHJ P,GETQ ; else in table + +; get size of packs +GSWAPA: MOVE A,[TLASTB,,QLASTB] + PUSHJ P,GETUT + +; get swapping allocations + MOVE A,[TSWAPA,,QSWAPA] + PUSHJ P,GETUT + +; start by getting number of ufds + MOVE A,[SQUOZE 0,NUDSL] + .EVAL A, + .VALUE [ASCIZ /:.EVAL OF NUDSL FAILED/] + MOVEM A,NUDSL + +; get total swapping allocation, fixed up by removing blocks +; allocated for UFDs + HLLZ C,QPTR + MOVEI B,0 +GSWAP1: SKIPE QACT(C) + JRST GSWAP2 + MOVE A,TSWAPA(C) + SUB A,NUDSL + SKIPLE A + ADD B,A +GSWAP2: AOBJN C,GSWAP1 + MOVEM B,SWAPAL + +; calculate total blocks per pack + MOVE B,QPTR + HRRI B,TLASTB + MOVE C,QPTR + HRRI C,TSWAPA + MOVE D,QPTR + HRRI D,TSIZES + +DSKTOT: MOVE A,(B) +; get greater of nudsl and swapa into 0 + MOVE 0,NUDSL + CAMGE 0,(C) + MOVE 0,(C) + SUB A,0 +; subtract mfd and tut if not already part of swapa + CAIGE 0,2500. + SUB A,TUTSIZ ; flush tut blocks + MOVEM A,(D) + AOBJN B,.+1 + AOBJN C,.+1 + AOBJN D,DSKTOT + +; calculate total blocks by adding all packs + MOVEI B,TSIZES + PUSHJ P,QTOTAL + MOVEM A,ALLBL + +; restore acs and return + POP P,D + POP P,C + POP P,B + POP P,A + POPJ P, + +; total a table nqs long -- ignore inactive packs +QTOTAL: PUSH P,C + MOVE C,QPTR + HRRI C,QACT + HLL B,QPTR + SETZ A, +QTOTA1: SKIPE (C) + JRST QTOTA2 + SKIPL (B) + ADD A,(B) +QTOTA2: AOBJN C,.+1 + AOBJN B,QTOTA1 + POP P,C + POPJ P, + +; total users and average per user + +; aver/ average blocks per user +; tus/ total users + +DSKMFD: PUSH P,A + PUSH P,B + + SKIPE B,TUS + JRST DSKMF1 + PUSHJ P,GETMFD + PUSHJ P,MFDN + SKIPA + AOJA B,.-2 + MOVEM B,TUS + +; now compute average blocks per user +DSKMF1: MOVE A,ALLBL + SUB A,FREEBL + IDIV A,B + MOVEM A,AVER + .CLOSE MCH, + + POP P,B + POP P,A + POPJ P, + +; * next username from mfd * + +; C/ username in sixbit +MFDN: AOS MFDPTR + AOS C,MFDPTR + CAILE C,MFDPTR+1777 + POPJ P, + SKIPN C,(C) + JRST MFDN + AOS (P) + POPJ P, + + ; * add info on a user to free block * + +; get 6 word block +USRVEC: MOVEI A,%USRBLK + ADDB A,FREEPT + +; put out data + MOVE 0,USRNAM ; username + MOVEM 0,%USER(A) + MOVE 0,UFILES ; # files + MOVEM 0,%FILES(A) + MOVE 0,ULINKS ; # links + MOVEM 0,%LINKS(A) + MOVE 0,UBLCKS ; # blocks + MOVEM 0,%BLCKS(A) + MOVE 0,UQUOTA ; quota + MOVEM 0,%QUOTA(A) + MOVE 0,UALLOC + MOVEM 0,%ALLOC(A) + MOVE 0,UPACKN + MOVEM 0,%PACKN(A) + MOVE 0,UBKFLS ; blocks/file + MOVEM 0,%BLKAV(A) + +; update cptr to pointers + MOVEM A,(N) + SUB N,[(1)] + ADDI N,1 + POPJ P, + +; * typeout information on a given user * +; a/ ptr to data block + +TYPOUT: PUSH P,A + PUSH P,B + MOVE B,A + +; type out data + OSIX %USER(B) ; user-id + OASCI ^I + OJUST 3,%FILES(B) ; # file + OASCI ^I + OJUST 3,%LINKS(B) ; # links + OASCI ^I + OJUST 4,%BLCKS(B) ; # blocks +; give him a * if over quota + SKIPE TQUO + SKIPG A,%QUOTA(B) ; has quota? + JRST TYPBLK + CAMGE A,%BLCKS(B) + OASCI "* +TYPBLK: SKIPG TQUO + JRST TYPALC + SKIPG TALLO + JRST TYPOU1 + OASCI ^I + SKIPG %ALLOC(B) + JRST TYPQUO +; here if has alloc. (print quota only if different) +TYPALL: MOVE A,%QUOTA(B) + CAMN A,%ALLOC(B) + JRST TYPAL1 + OJUST 4,%QUOTA(B) +TYPAL1: OASCI ^I + OJUST 4,%ALLOC(B) + JRST TYPOU1 +; here if only has quota +TYPQUO: OJUST 4,%QUOTA(B) + OASCI ^I + +; restore acs and return +TYPOU1: OASCI ^I + SKIPE %PACKN(B) + OJUST 2,%PACKN(B) + OASCI ^I + OFLOAT %BLKAV(B) ; blocks/file + POP P,B + POP P,A + POPJ P, + +TYPALC: SKIPG TALLO + JRST TYPOU1 + OASCI ^I + OJUST 4,%ALLOC(B) + JRST TYPOU1 + +; * read in mfd * + +GETMFD: SKIPE MFDBUF+MDNAMP + JRST GETMFX + .OPEN MCH,MFDDIR + .VALUE [ASCIZ !:CANT OPEN M.F.D.!] + MOVE A,[-2000,,MFDBUF] + .IOT MCH,A + JUMPL A,TINY + .CLOSE MCH, +GETMFX: MOVE A,MFDBUF+MDNAMP + ADDI A,MFDBUF-2 ; aos's first, cretin... + MOVEM A,MFDPTR + POPJ P, + +TINY: .VALUE [ASCIZ !:M.F.D. LESS THAN 2000 WORDS LONG?!] + +; * single user statistics gatherer * + +NOUFD: OASCI "" + OSIX USRNAM + OASCR [ASCIZ \" is not the name of a directory.\] + JRST KILL + +USRDSK: PUSH P,D + PUSH P,E + +; read ufd in + .OPEN CH,UDIR + JRST USRLSR + MOVE A,[-2000,,FDIR] + .IOT CH,A + .CLOSE CH, + +; initialize world + SETZB C,D + SETZB E,F + SETZM UFILES + SETZM ULINKS + SETZM UBLCKS + SETZM UBKFLS + SETZM UQUOTA + SETZM UALLOC + SETZM UPACKN + SETZM OLDC + +; quota and number of blocks + MOVE B,FDIR+UDBLKS + HLREM B,UQUOTA + SKIPGE B + SETZM UQUOTA + HRREM B,UBLCKS + SKIPG A,UQUOTA + JRST L69 + CAML A,UBLCKS + JRST L69 + MOVE A,UBLCKS + SUB A,UQUOTA + ADDM A,TFAT + AOS TPIGS + +; pack and allocation +L69: HRRE B,FDIR+UDALLO + SKIPLE B ; if negative or zero (UALLOC is 0 already) + MOVEM B,UALLOC + + HLRZ E,FDIR+UDALLO + JUMPE E,L105 + MOVEM E,UPACKN + SKIPN TUTRSR + JRST O69 + + MOVE A,QPTR ; here for new style reservations + HLLZ A,A ; done by pack number rather than drive +DRLOOP: SKIPL QACT(A) ; drive off line? + CAME E,QPKID(A) + JRST DRNEXT + ADDM B,PACK(A) + JRST L105 +DRNEXT: AOBJN A,DRLOOP + JRST L105 + +O69: ADDM B,PACK(E) ; for old style reservation hackery + +L105: MOVE B,UDNAMP+FDIR + ADDI B,FDIR + +L1: CAILE B,FDIR+1773 + JRST UNUM + SKIPN (B) + JRST NEXTFL + MOVE E,UNRNDM(B) + TLNE E,UNIGFL + JRST NEXTFL + TLNE E,1 + AOSA ULINKS ; was a link + AOS UFILES ; was a regular file + +; move to next file +NEXTFL: ADDI B,LUNBLK + JRST L1 + +; finish calculations and exit + +; calculate blocks/file +UNUM: MOVE A,UBLCKS + FLOAT A + MOVE B,UFILES + FLOAT B + FDVR A,B + MOVEM A,UBKFLS + +; add to totals + SKIPLE E,UFILES + ADDM E,TFL + SKIPLE E,ULINKS + ADDM E,TLK + SKIPLE E,UBLCKS + ADDM E,TBL + SKIPG UALLOC + JRST UPDUSR + AOS TUALLO ; here for allocated directory + ADDM E,TBALLO + JRST UPDUS1 +UPDUSR: SKIPG UQUOTA + JRST UPDUS1 + AOS TUQUOT ; here for quota'ed directory + ADDM E,TBQUOT +UPDUS1: SKIPLE E,UQUOTA + ADDM E,TQUO + SKIPLE E,UALLOC + ADDM E,TALLO + +; go here if no files in dir +ZEROES: AOS -2(P) +USRLSR: POP P,E + POP P,D + POPJ P, + +; byte pointer table +DESCBP: 440600 + 360600 + 300600 + 220600 + 140600 + 060600 + ; * buffers * +MAXUSR==512. + +USERS: BLOCK MAXUSR ; this is largest number of users prog will handle + +FREEPT: FREESP+1-%USRBLK +FREESP: BLOCK MAXUSR*%USRBLK ; free storage buffer + +PDL: BLOCK 100 +FDIR: BLOCK 2000 +BUF: BLOCK 20. + +; variables +SORTX: -1,,0 +CPTR: 0 +CPTR1: 0 +OLDC: 0 + +; * variables used for getting system info * + +TUTRSR: 0 ; non-zero if new style reservation stuff +TUTSIZ: 0 ; number of blocks in tut (NTUTBL) + +NQS: 0 ; number of packs +NQSONL: 0 ; number of packs online +QPTR: 0 ; -nqs,,qtuto +QRSRVP: 0 ; any reserved packs? +NUDSL: 0 ; number of ufds allowed + +QTUTO: BLOCK 10 ; location of tut for drives + +TLASTB: BLOCK 10 ; drive sizes (rp02 or rp03) +TRESRV: BLOCK 10 ; reserved? (-1 if is) +TSWAPA: BLOCK 10 ; swapping allocations + +QACT: BLOCK 10 ; disk active? +QPKID: BLOCK 10 ; pack numbers +TSIZES: BLOCK 10 ; calculated sizes (exclude ufds and mfd and tut) +QSFT: BLOCK 10 ; free file space +QSFTS: BLOCK 10 ; free swap space +PACK: BLOCK 10 ; total allocated on each drive + +; * status variables * + +; single user totals +USRNAM: 0 ; user +UFILES: 0 ; # of files +ULINKS: 0 ; # of links +UBLCKS: 0 ; number of blocks in ufd +UBKFLS: 0 ; blocks/file average +UQUOTA: 0 ; quota +UALLOC: 0 ; allocation +UPACKN: 0 ; allocated pack number + +; system wide totals +TUS: 0 ; total # users +TUALLO: 0 ; total # allocated users +TUQUOT: 0 ; total # quota'ed users + +TPIGS: 0 ; users over quota +TFAT: 0 ; total excess for TPIGS +TBACON: 0 ; average pigness of TPIGS + +TFL: 0 ; total files +TLK: 0 ; total links + +TBL: 0 ; total blocks +TBALLO: 0 ; total blocks in allocated directories +TBQUOT: 0 ; total blocks in quota'ed directories + +TAV: 0 ; average b/f over system +TAALLO: 0 ; average b/u for allocated directories +TAQUOT: 0 ; average b/u for quota'ed directories + +TQUO: 0 ; total of quotas +TALLO: 0 ; total of allocations + +; block for cretinous mfd +MFDPTR: 0 +MFDBUF: BLOCK 2000. + +; disk system stats +FREESW: 0 ; free swapping blocks +SWAPAL: 0 ; swapping allocation +FREEBL: 0 ; free disk blocks +FRUNAL: 0 ; free unallocated blocks +ALLBL: 0 ; total number of blocks +AVER: 0 ; average number of blocks per user directory + +DATE: 0 ; date dskuse was run +TIME: 0 ; time dskuse was run + +; * I/O variables * + +BOTH: 0 ; flag for double dskuse ("&") + +; files +UDIR: SIXBIT / &DSK.FILE.(DIR) / +MFDDIR: SIXBIT / &DSKM.F.D.(FILE)/ + +OUTPUT: SIXBIT / !TPLDSKUSEOUTPUT/ +RSYSNM: 0 ; sname of user +SYSNAM: 0 ; which system? dm, ai, or ml? + +; ================================================================ +; read a command line +; ================================================================ + +COMMND: BLOCK 20 +COMPTR: 0 + +; set up buffer +READ: PUSH P,A + PUSH P,B + SETZM COMMND + MOVE [COMMND,,COMMND+1] + BLT 0,COMPTR-1 +; command reader +RCMD: MOVE B,[440700,,COMMND] + MOVEM B,COMPTR + MOVEI C,0 +RCMD1: .IOT TYIC,A + CAIN A,177 + JRST RUB + CAIN A,^D + JRST RREPEA + CAIN A,^L + JRST RCLEAR + CAIN A,^J + JRST RCMD1 + CAIN A,^Q + JRST RQUOTE + CAIN A,^M + JRST RCMDX +RCMDL: IDPB A,B + CAMGE B,[350700,,COMMND+17] + AOJA C,RCMD1 + +RCFUL: IDPB A,B + MOVEI A,15 + IDPB A,B + +RCMDX: IDPB A,B + MOVEI A,0 + IDPB A,B + POP P,B + POP P,A + POPJ P, + +RREPEA: .IOT TCMD,[^M] + .IOT TCMD,[^J] + JRST REPPER +RCLEAR: .IOT TCMD,[^P] + .IOT TCMD,["C] +REPPER: .IOT TCMD,["*] + MOVEI A,COMMND + HRLI A,440700 +REP1: ILDB A + JUMPE RCMD1 + .IOT TCMD, + JRST REP1 + +RQUOTE: IDPB A,B + CAML B,[350700,,COMMND+17] + JRST RCFUL + SETOM QUTFLG + AOS C + .IOT TYIC,A + SETZM QUTFLG' + JRST RCMDL + +RUB: PUSHJ P,RUBBER + JRST RCMD + JRST RCMD1 + +RUBBER: SOJL C,[POPJ P,] ; erasure rubout handler + MOVEI A,0 + DPB A,B + .IOT TCMD,[^P] + .IOT TCMD,["X] + ADD B,[070000,,] + TLNE B,400000 + ADD B,[347777,,-1] + AOS (P) + POPJ P, + +; =================================================================== +; command line reading and parsing section +; =================================================================== + +; read a file spec +SCNAME: PUSH P,D + MOVEI D,OUTPUT + PUSH P,A + PUSH P,B + PUSH P,C + MOVSI C,-2 + HRRI C,1(D) + JRST SCNONE +SCNGET: HRRZ A,(D) + CAIE A,'TPL + JRST SCNONE + MOVEI A,'DSK + HRRM A,(D) +SCNONE: PUSHJ P,GETSYL + JUMPE B,SCNX + CAIE A,': + JRST .+3 + HLRZM B,(D) + JRST SCNGET + CAIE A,'; + JRST SCNNMN + MOVEM B,3(D) + JRST SCNGET +SCNNMN: MOVEM B,(C) + JUMPL A,SCNX + CAIE A,', + AOBJN C,SCNGET +SCNX: POP P,C + POP P,B + POP P,A + POP P,D + POPJ P, + +; get a syllable from command buffer +GETSYL: PUSH P,C + PUSH P,[0] + MOVEI B,(P) + HRLI B,440600 +GETSLP: PUSHJ P,GETCCA + JUMPL A,GETSX + SETO E, + CAIN A,^Q + JRST GETQOT + SUBI A,40 + JUMPL A,GETSX + JUMPE A,GETSP + CAIN A,'_ + JRST GETSX + CAIE A,': + CAIN A,'; + JRST GETSX +GETSPT: CAIL A,100 + SUBI A,40 + TLNN B,770000 + JRST GETSLP + IDPB A,B + JRST GETSLP + +GETQOT: ILDB A,COMPTR + SUBI A,40 + JUMPGE A,GETSPT + JRST GETSX +GETSP: TLNE B,400000 + JRST GETSLP +GETSX: POP P,B ; character word + POP P,C + POPJ P, + +GETCCA: ILDB A,COMPTR + JUMPE A,GETCCX + CAIN A,^I + MOVEI A,40 + CAIN A,^M + JRST GETCCX + CAIN A," + MOVEI A,", + POPJ P, +GETCCX: SETOM A + POPJ P, + +; ================================================================ +; interrupt handler (tty only) +; ================================================================ + +ZZZ=. + +LOC 42 + JSR TSINT +LOC ZZZ + +TSINT: 0 + 0 + PUSH P,A + MOVEI A,TYIC + .ITYIC A, + JRST TSDIS + CAIE A,^G + CAIN A,^S + JRST TSKILL ; if ^S or ^G typed, quit +TSDIS: POP P,A + .DISMIS TSINT+1 + +TSKILL: .IOT TYIC,A + POP P,A + .DISMIS [BADCOM] + +; ================================================================ +; uuo handler (typeout uuos) +; ================================================================ + +ZZZ==. + LOC 40 + 0 + JSR UUOH + LOC ZZZ +UUOCT==0 +UUOTAB: JRST ILUUO + IRPS X,,[OSIX OASC OASCI OASCR ODEC ODECR OFLOAT OJUST ODATE OTIME] + UUOCT==UUOCT+1 + X=UUOCT_33 + JRST U!X + TERMIN + +UUOMAX==.-UUOTAB + +UUOD: 0 ; contents of UUO eff addr. +UUOE: 0 ; UUO effad. + +UUOH: 0 + PUSH P,A + PUSH P,B + PUSH P,C + PUSH P,D + MOVEI @40 ; get eff addr. of uuo + MOVEM UUOE + MOVE @0 + MOVEM UUOD ; contents of eff adr + MOVE B,UUOE ; eff adr + LDB A,[270400,,40] ; get uuo ac, + LDB C,[330600,,40] ; op code + CAIL C,UUOMAX + MOVEI C,0 ; grt=>illegal + JRST @UUOTAB(C) ; go to proper rout + +UUORET: POP P,D + POP P,C + POP P,B + POP P,A ; restore ac's + JRST 2,@UUOH + +ILUUO: .VALUE [ASCIZ /:ILLEGAL UUO/] + +UOASCR: SKIPA C,[^M] ; cr for end of type +UOASC: MOVEI C,0 ; no cr + HRLI B,440700 ; make ascii pointer +UOASC1: ILDB A,B ; get char + JUMPE A,.+3 ; finish? + PUSHJ P,IOTA + JRST .-3 ; and get another + SKIPE A,C ; get saved cr? + PUSHJ P,IOTA + JRST UUORET + +UOASCI: MOVE A,B ; prt ascii immediate + PUSHJ P,IOTA + JRST UUORET + +UOSIX: MOVE B,UUOD +USXOOP: JUMPE B,UUORET + LDB A,[360600,,B] + ADDI A,40 + PUSHJ P,IOTA + LSH B,6 + JRST USXOOP + +TENS: 0 ? 10. ? 100. ? 1000. ? 10000. ? 100000. + +UOJUST: MOVE B,UUOD +TYOJ1: CAML B,TENS(A) + JRST UOJUS1 + .IOT TYOC,[40] + SOJG A,TYOJ1 +UOJUS1: SETZB A,D + MOVEI C,10. + JRST UOOCTI+1 + +UODECR: SKIPA D,[^M] +UODEC: SETZ D, + MOVEI C,10. + JRST .+3 +UOOCT: SETZ D, + MOVEI C,8. ; octal base + MOVE B,UUOD ; get actual word to prt + JRST .+3 ; join code +UODECI: SKIPA C,[10.] ; decimal +UOOCTI: MOVEI C,8. + MOVEM C,BASE' + SKIPN A + HRREI A,-1 ; a=digit count + PUSHJ P,UONUM ; print numbr + SKIPE A,D + PUSHJ P,IOTA + JRST UUORET + +UONUM: IDIV B,BASE + HRLM C,(P) ; save digit + SOJE A,UONUM1 ; done if 0 + SKIPG A ; + => more + SKIPE B ; - => b=0 => done + PUSHJ P,UONUM ; else more +UONUM1: HLRZ C,(P) ; retreive digits + ADDI C,"0 ; make to ascii + CAILE C,"9 ; is it good dig + ADDI C,"A-"9-1 ; make hex digit + PUSHJ P,IOTC + POPJ P, ; ret + +UOFLOA: PUSH P,E + PUSH P,F + PUSH P,G + PUSH P,H + PUSH P,I + MOVE A,UUOD + MOVE D,A + PUSHJ P,NFLOT + POP P,I + POP P,H + POP P,G + POP P,F + POP P,E + JRST UUORET + +; at this point we enter code abstracted from DDT. +NFLOT: JUMPE A,FP1A + +TFL1: MOVEI B,0 + CAMGE A,FT01 + JRST FP4 + CAML A,FT8 + AOJA B,FP4 +FP1A: +FP3: SETZB C,TEM1 ; CLEAR DIGIT CNTR, C TO RECEIVE FRACTION + MULI A,400 + ASHC B,-243(A) + MOVE A,B + PUSHJ P,FP7 + PUSH P,A + MOVEI A,". + PUSHJ P,IOTA + POP P,A + MOVNI A,3 + ADD A,TEM1 + MOVE E,C +FP3A: MOVE D,E + MULI D,12 + PUSHJ P,FP7B + SKIPE E + AOJL A,FP3A + POPJ P, ; ONE return from OFLT here + +FP4: MOVNI C,6 + MOVEI F,0 +FP4A: ADDI F,1(F) + XCT FCP(B) + SOSA F + FMPR A,@FCP+1(B) + AOJN C,FP4A + PUSH P,EXPSGN(B) + PUSHJ P,FP3 + PUSH P,A + MOVEI A,"E + PUSHJ P,IOTA + POP P,A + POP P,D + MOVE A,D + PUSHJ P,IOTA + MOVE A,F + +FP7: SKIPE A ; AVOID AOSING TEM1, NOT SIGNIFICANT DIGIT + AOS TEM1 + IDIVI A,12 + HRLM B,(P) + JUMPE A,FP7A1 + PUSHJ P,FP7 + +FP7A1: HLRZ D,(P) +FP7B: ADDI D,"0 + PUSH P,A + MOVE A,D + PUSHJ P,IOTA + POP P,A + POPJ P, + +; constants + 1.0^32. + 1.0^16. +FT8: 1.0^8 + 1.0^4 + 1.0^2 + 1.0^1 +FT: 1.0^0 + 1.0^-32. + 1.0^-16. + 1.0^-8 + 1.0^-4 + 1.0^-2 +FT01: 1.0^-1 +FT0=FT01+1 + +TEM1: 0 + +; instructions +FCP: CAMLE A, FT0(C) + CAMGE A, FT(C) + 0, FT0(C) + +EXPSGN: "- + "+ + +; ==================================================================== +; uuo character output +; ==================================================================== + +IOTC: PUSH P,A + MOVE A,C + PUSHJ P,IOTA + POP P,A + POPJ P, + +IOTA: CAIN A,^P + JRST IOTAP +IOTA1: CAIE A,^J + .IOT TYOC,A + CAIN A,^M + .IOT TYOC,[^J] + POPJ P, +IOTAP: .IOT TYOC,["^] + ADDI A,100 + JRST IOTA1 + +; type time +UOTIME: MOVEI C,": + JRST UOTUPL + +; type date +UODATE: MOVEI C,"/ +UOTUPL: LDB A,[360600,,UUOD] + ADDI A,40 + PUSHJ P,IOTA + LDB A,[300600,,UUOD] + ADDI A,40 + PUSHJ P,IOTA + PUSHJ P,IOTC + LDB A,[220600,,UUOD] + ADDI A,40 + PUSHJ P,IOTA + LDB A,[140600,,UUOD] + ADDI A,40 + PUSHJ P,IOTA + PUSHJ P,IOTC + LDB A,[060600,,UUOD] + ADDI A,40 + PUSHJ P,IOTA + LDB A,[000600,,UUOD] + ADDI A,40 + PUSHJ P,IOTA + JRST UUORET + +; ==================================================================== +; sorter +; ==================================================================== + +; simple interchange sort +; A/ sort forward or backward (-1/0) +VSORT: PUSH P,A + PUSH P,G + PUSH P,M + MOVE F,[CAMG G,(C)] + SKIPL A + MOVE F,[CAML G,(C)] + HRRZS A + MOVE D,M + POP D,(D) + AOS D + MOVEM D,E +VSORT1: SETZM K + MOVE D,E + AOBJP D,.+1 + SOS D + MOVEM D,E +VSORT2: AOBJP D,VSORTX + MOVE C,(D) + ADD C,A + MOVE B,-1(D) + ADD B,A + MOVE G,(B) + XCT F + JRST VSORT2 + EXCH G,(D) + EXCH G,-1(D) + EXCH G,(D) + JUMPL K,VSORT2 + SETOM K + MOVEM D,E + POP E,(E) + POP E,(E) + HRRZ B,E + HRRZ C,M + CAMGE B,C + AOBJN E,.+1 + JRST VSORT2 +VSORTX: JUMPL K,VSORT1 + POP P,M + POP P,G + POP P,A + POPJ P, + + END START