eturn .save .psect $pdata ,d 200$: .byte cr,lf,0 .even .restore .dsabl lsb rad: calls rdtoa , ; common code to to rad50 cvt add #3 ,r3 ; pointer := pointer + 3 calls rdtoa , ; common code to to rad50 cvt add #3 ,r3 ; pointer := pointer + 3 return .sbttl misc utilities .enabl lsb cvtppn: save ; save temps please sub #20 ,sp ; convert ppn to ascii next mov sp ,r0 ; a pointer to the ppn clr r1 ; get the project number now bisb firqb+27,r1 ; ok bne 10$ ; if <> 0 then a real account mov #200$ ,r1 ; if eq 0 then not logged it yet br 20$ ; copy over *,* 10$: deccvt r1,r0,#3 ; convert it to decimal add #3 ,r0 movb #', ,(r0)+ ; stuff a comma in please clr r1 ; get the programmer number now bisb firqb+26,r1 ; ok deccvt r1,r0,#3 ; convert it to decimal mov sp ,r1 ; point to the buffer now 20$: movb #40 ,(r3)+ ; stuff a space into our result mov #7 ,r0 ; seven characters to copy 30$: movb (r1)+ ,(r3)+ ; and copy the rest of it sob r0 ,30$ ; simple movb #40 ,(r3)+ ; stuff a space into our result movb #40 ,(r3)+ ; stuff a space into our result movb #40 ,(r3)+ ; stuff a space into our result add #20 ,sp ; pop the local buffer unsave return .save .psect $pdata ,d 200$: .asciz / *, */ .even .restore .dsabl lsb cvtkb: save ; convert kb number to ascii sub #10 ,sp ; allocate a local buffer mov sp ,r1 ; point to it movb firqb+5 ,r0 ; KB number to convert movb #'K ,(r3)+ ; insert a header movb #'B ,(r3)+ ; simple deccvt r0,r1,#3 ; can't ever be more than 127 mov r3 ,-(sp) ; saev the output pointer now mov #3 ,r0 ; three at most to copy over 10$: cmpb @r1 ,#40 ; a space present ? beq 20$ ; yes, please ignore it movb @r1 ,(r3)+ ; copy it over at last 20$: inc r1 ; next ch please sob r0 ,10$ ; simple movb #40 ,(r3)+ ; insert some spaces now movb #40 ,(r3)+ ; insert some spaces now movb #40 ,(r3)+ ; insert some spaces now movb #40 ,(r3)+ ; insert some spaces now mov (sp)+ ,r3 ; restore the old pointer add #5 ,r3 ; say we copied 5+2 characters over add #10 ,sp ; pop the local buffer and exit unsave ; pop registers return $clrxr: save mov #xrb ,r0 10$: clr (r0)+ cmp r0 ,#xrb+14 blos 10$ unsave return $clrfq: save mov #firqb ,r0 10$: clr (r0)+ cmp r0 ,#firqb+36 blos 10$ unsave return .dosys: clrfqb ; clear the firqb out first movb #uu.sys ,firqb+fqfun ; do a systat call to RSTS movb 2(sp) ,firqb+4 ; job number to do it for movb 4(sp) ,firqb+5 ; which type (0 or 1) .uuo ; simple movb firqb ,r0 ; return with error code in r0 return ; bye .sbttl do the server C command for RSTS/E version 8 ; 13-Apr-84 13:15:50 Brian Nelson ; ; input: @r5 address of command string ; 2(r5) LUN to send the output to, zero implies TT: ; output: r0 error code (rms or RSTS/E) ; ; Note: This is a very SIMPLE version of the code I wrote ; several years ago to do complete PK handling. In ; this version, we NEVER try to read anything from ; the users keyboard, nor do we EVER write anything ; to it since it is assumed that we are supporting ; the server host command packet stuff. Any attempt ; by the invoked CCL/DCL command to read input will ; cause the program (and job) to be aborted. .iif ndf, corcom, corcom = 460 .psect pkbuff ,rw,lcl,rel,con,d pkbuff: .blkb 200 pkbufp: .word 0 pkbufs: .word 0 jobnum: .word 0 .even pkbsiz = 200 .sbttl the real work of sercmd .psect $code sercmd::clr pkbufs ; insure no data is left in buffer mov #jfsys ,xrb+0 ; get temp privs back .set ; simple to do call openpk ; find an available PK tst r0 ; perhaps we could not get one bne 100$ ; r0 will have RSTS/E error code call logv8 ; get logged in on the PK tst r0 ; if it fails, it's the error code bne 100$ ; oops mov r1 ,jobnum ; save the jobnumber please movb #'c&37K1180SMAC[.050032]K1180S.MAC[.050032]    X14|H [4;Ik(&'( k ߫H&P` \RrPP2PPzPP{PPPPP2P~\$\\TD 0D \~ hi) +\ ^( n ^( np\^txY\^ˀ\!kVk<\F˰<˴ˬ\VVkˤ1`@lP ABCDEFGHIJKLMNOPQRSTUVWXYZ$.?0123456789<@<SЬTЬ UQS>?\\\\\\\\\`:#@'="\abcdefghi\\\\\\\jklmnopqr\\\\\\\~stuvwxyz\\\\\\\\\\\\\\\\\\\\\\{ABCDEFGHI\\\\\\}JKLMNOPQR\\\\\\\\STUVWXYZ\\\\\\0123456789\\\\\  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~@ggh<i|o<m<4p<p<k|Zn<l fr rwx<x<x<x޺<w@]@@fjnr]Ze@@|> | |v<H|  |  |xz|  |zt f r   < &^ @&@'*/V,"?Lh:hmBmz|z{x`y~|fN|@@|@͂|@ ݃ƃ<ns<|Ŏ |️|ep|u|-@率|<ᄇ2ֻr||ZRM | ntB|xyvZw|J=|R>|J? nnaa|bddfk getpk: clrxrb ; clear xrb tst pkbufs ; any buffered data left to get? bne 10$ ; no call 200$ ; reload the buffer please tst r0 ; get anything ? bne 100$ ; no, exit 10$: mov pkbufp ,r0 ; yes, get a pointer to the buffer clr r1 ; avoid sign extension bisb pkbuff(r0),r1 ; get the ch now inc pkbufp ; advance the pointer for next time dec pkbufs ; one less character left to get clr r0 ; say it worked 100$: return ; bye 200$: clr pkbufp ; no data, clear buffer pointer clrxrb ; no defaults mov #pkbsiz ,xrb+xrlen ; as many as we can grab mov #pkbuff ,xrb+xrloc ; buffer location movb #pk.lun*2,xrb+xrci ; channel # inc xrb+xrtime ; wait at most one second .read ; read from pk movb firqb ,r0 ; get any error codes bne 210$ ; no mov xrb+xrbc,pkbufs ; it worked, init the bytes left 210$: return ; back to work... putpk: clrxrb ; no odd things please inc xrb+xrlen ; one ch to do mov sp ,xrb+xrloc ; buffer location add #2 ,xrb+xrloc ; off by one mov #1 ,xrb+xrbc ; byte count movb #pk.lun*2,xrb+xrci ; channel # mov #9. ,xrb+xrmod ; record 9% .write ; write to pk movb firqb ,r0 ; result mov (sp)+ ,(sp) ; pop ch that we wrote return ; back to work... .sbttl pk utilities sendcmd:mov r1 ,-(sp) mov 4(sp) ,r1 ; command address to send to PK 10$: tstb @r1 ; done yet ? beq 100$ ; yes, exit movb (r1)+ ,-(sp) ; loop until a null is found call putpk ; simple br 10$ ; next please 100$: mov (sp)+ ,r1 ; pop register we used mov (sp)+ ,(sp) ; pop address of string and exit mov #cr ,-(sp) ; finish with a carriage return call putpk ; simple return waitpk: clrxrb ; no odd things please mov sp ,xrb+xrloc ; buffer location movb #pk.lun*2,xrb+xrci ; channel # mov #6. ,xrb+xrmod ; record 2+4 .write ; write to pk tstb firqb ; result beq 100$ ; it's ready for a command cmpb firqb ,#28. ; need a control C? beq 100$ sec ; it's not ready return 100$: clc return ; back to work... killpk: clrxrb ; no odd things please mov sp ,xrb+xrloc ; buffer location movb #pk.lun*2,xrb+xrci ; channel # mov #20 ,xrb+xrmod ; record 2+4 .write ; write to pk clrfqb ; now close it up movb #clsfq ,firqb+fqfun ; simple movb #pk.lun*2,firqb+fqfil ; channel to do calfip ; do it return ; back to work... .sbttl jobsts return status of the controlled job ; input: 2(sp) job number ; output: r0 < 0 then kb stall, 0 waiting for tt output, > 0 running ; ; This will be called to determine when the spawned job should ; be aborted. ; ; r0 = -2 the job is logged out, waiting for input or ; in a kmon wait ; r0 = -1 timeout ; r0 = 0 job is waiting for output to the PK ; r0 > 0 job is in a run state .jbstat = 12 .jbwait = 14 .iif ndf, j2con ,j2con = 4 .iif ndf, j2nopr,j2nopr = 10000 .iif ndf, js.kb ,js.kb = 2 .iif ndf, js.tel,js.tel = 4000 jobsts: mov r1 ,-(sp) ; we may access these here mov r2 ,-(sp) ; save these also movb #uu.sys ,firqb+fqfun ; for looking up a job movb 6(sp) ,firqb+fqfun+1 ; job number to do movb #1 ,firqb+fqfun+2 ; part two to do please .uuo ; do it tstb firqb ; did it work ? bne 90$ ; no, return abort please bit #jfnopr ,firqb+6 ; logged in ? bne 90$ ; no, return abort then mov firqb+.jbstat,r1 ; get the current jbstat word mov firqb+.jbwait,r2 ; get the current jbwait word com r1 ; and get the and of the two bic r1 ,r2 ; if result <> 0 then job is bne 10$ ; running ok bit #js.kb ,firqb+.jbwait ; not running, stalled for kb input? bne 90$ ; yes, abort the job then bit #js.tel ,firqb+.jbwait ; waiting for tt output bne 80$ ; yes 10$: mov firqb+34,xrb+0 ; no, check the elapsed time please add #j2con ,xrb+0 ; simple .peek ; do it tstb firqb ; did that work ? bne 90$ ; no, die cmp xrb+0 ,#300 ; allow three minutes at most bhis 95$ ; no, die mov #1 ,r0 ; all is well, exit br 100$ 80$: clr r0 ; K1180SMAC[.050032]K1180S.MAC[.050032]    X14|H [4;Ik(&'( k ߫H&P` \RrPP2PPzPP{PPPPP2P~\$\\TD 0D \~ hi) +\ ^( n ^( np\^txY\^ˀ\!kVk<\F˰<˴ˬ\VVkˤ1`@lP ABCDEFGHIJKLMNOPQRSTUVWXYZ$.?0123456789<@<SЬTЬ UQS>?\\\\\\\\\`:#@'="\abcdefghi\\\\\\\jklmnopqr\\\\\\\~stuvwxyz\\\\\\\\\\\\\\\\\\\\\\{ABCDEFGHI\\\\\\}JKLMNOPQR\\\\\\\\STUVWXYZ\\\\\\0123456789\\\\\  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~@ggh<i|o<m<4p<p<k|Zn<l fr rwx<x<x<x޺<w@]@@fjnr]Ze@@|> | |v<H|  |  |xz|  |zt f r   < &^ @&@'*/V,"?Lh:hmBmz|z{x`y~|fN|@@|@͂|@ ݃ƃ<ns<|Ŏ |️|ep|u|-@率|<ᄇ2ֻr||ZRM | ntB|xyvZw|J=|R>|J? nnaa|bddfno (quota exceeded) clrfqb ; Clear the FIRQB one last time movb #UU.LIN ,FIRQB+FQFUN ; Login function for .UUO movb #10*1 ,FIRQB+5 ; We can skip the password check as we mov 4(sp) ,FIRQB+FQPPN ; already checked and we needed WACNT .UUO ; at LAST ..... movb FIRQB ,r0 ; save and exit bne 100$ ; .... call setprv ; set authorized privileges up clr r0 ; it's ok br 100$ ; exit 80$: mov #QUOTA ,r0 ; UU.BYE failed due to a quota br 100$ 90$: mov #PRVIOL ,r0 ; No WACNT--> protection violation 100$: add #10 ,sp ; pop buffer and exit return .save .psect $PDATA ,D wacnt: .asciz /WACNT/ exqta: .asciz /EXQTA/ .even .restore .sbttl detach the server detach::clrfqb ; insure no defaults movb #UU.SYS ,FIRQB+FQFUN ; do a systat and get the kb number .UUO ; simple to do movb FIRQB+5 ,r1 ; save the kb number clrfqb ; insure no defaults movb #clsfq ,FIRQB+FQFUN ; insure KB: is detached movb #5*2 ,FIRQB+FQFUN+1 ; the lun for it CALFIP ; do it, skip any error codes clrfqb movb #UU.DET ,FIRQB+FQFUN ; the uuo detach code movb #200 ,FIRQB+FQFUN+1 ; close all luns for KB: .UUO ; simple to do movb FIRQB ,r0 ; return any errors bne 100$ ; yep mov #1 ,xrb+0 .sleep clrfqb ; now spawn a job attached mov #FIRQB+FQFUN,r0 ; to our old kb movb #UU.JOB ,(r0)+ ; create a job exec call movb #20!100!200,(r0)+ ; into def kbm, no logins is ok movb r1 ,@r0 ; the kb number to attach to bne 10$ ; not KB0: movb #200 ,@r0 ; KB0:, must set flag for it 10$: .UUO ; simple to do, ignore errors clr r0 ; return success 100$: return .sbttl check for AUTHOURIZED priv ; This is again different from CHKPRV, which checks for ; CURRENT priv, and JOBPRV, which checks for JOB priv as in ; SET JOB/[NO]PRIV. This one goes out to disk and gets the ; AUTHORIZED priv mask and checks for the passed priv. ; ; Passed: 2(sp) Name of priv to check, upper case please ; Return: R0 1 for success or pre 9.x, zero for no priv ; ; Example: ; ; mov #HWCFG ,-(sp) ; call JOBPRV ; tst r0 ; beq error ; ; ; hwcfg:.asciz /HWCFG/ ; .even authpr::mov r1 ,-(sp) ; /41/ Save a register mov r2 ,-(sp) ; /41/ ... save another one sub #10 ,sp ; /41/ temp save area mov #1 ,r2 ; /41/ Assume success tst ver9.x ; /41/ version nine or later? beq 100$ ; /41/ no, return( success ) clrfqb ; /41/ Clear firqb out mov #FIRQB+FQFUN,r1 ; /41/ Read authorized priv mask movb #UU.ATR ,(r1)+ ; /41/ Function to perform movb #377 ,(r1)+ ; /41/ Read function movb #2 ,(r1)+ ; /41/ Read AUTHORIZED priv mask .UUO ; /41/ Go to it mov #FIRQB+12,r0 ; /41/ Where the priv mask is mov sp ,r1 ; /41/ Where to save it mov (r0)+ ,(r1)+ ; /41/ Save it please mov (r0)+ ,(r1)+ ; /41/ .Save it please mov (r0)+ ,(r1)+ ; /41/ ..Save it please mov (r0)+ ,(r1)+ ; /41/ ...Save it please clrfqb ; /41/ clear firqb out mov #FIRQB+FQFUN,r0 ; /41 movb #UU.CHK ,(r0)+ ; /41/ Convert priv name to bitmask inc (r0)+ ; /41/ Subfunbction code = 1 tst (r0)+ ; /41/ skip this field mov 2+14(sp),r1 ; /41/ copy the priv over 10$: movb (r1)+ ,(r0)+ ; /41/ copy the asciz name over bne 10$ ; /41/ simple .UUO ; /41/ convert NAME to MASK mov sp ,r1 ; /41/ point back to save area mov #FIRQB+FQNAM1,r0 ; /41/ Where the bit pattern is mov #4 ,r2 ; /41/ Four words to check 20$: bit (r0)+ ,(r1)+ ; /41/ Any bit(s) set here ? bne 30$ ; /41/ Yes, we have it sob r2 ,20$ ; /41/ No, keep looking br 90$ ; /41/ Failure 30$: mov #1 ,r2 ; /41/ Flag we have it br 100$ ; /41/ exit 90$: clr r2 ; /41/ failure 100$: mov r2 ,r0 ; /41/ Return the status now add #10 ,sp ; /41/ Pop buffer mov (sp)+ ,r2 ; /41/ ...Pop a register mov (sp)+ ,r1 ; /41/ Pop a register mov (sp)+ ,(sp) ; /41/ Pop over the parameter return ; /41/ At last .sbttl Logout ; LOGOUT ; ; Logout from the RSTS/E host from the server ; ; Rewritten 3.45 11-Feb-86 15:25:17 BDN for verK1180SMAC[.050032]K1180S.MAC[.050032]    X14|H [4;Ik(&'( k ߫H&P` \RrPP2PPzPP{PPPPP2P~\$\\TD 0D \~ hi) +\ ^( n ^( np\^txY\^ˀ\!kVk<\F˰<˴ˬ\VVkˤ1`@lP ABCDEFGHIJKLMNOPQRSTUVWXYZ$.?0123456789<@<SЬTЬ UQS>?\\\\\\\\\`:#@'="\abcdefghi\\\\\\\jklmnopqr\\\\\\\~stuvwxyz\\\\\\\\\\\\\\\\\\\\\\{ABCDEFGHI\\\\\\}JKLMNOPQR\\\\\\\\STUVWXYZ\\\\\\0123456789\\\\\  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~@ggh<i|o<m<4p<p<k|Zn<l fr rwx<x<x<x޺<w@]@@fjnr]Ze@@|> | |v<H|  |  |xz|  |zt f r   < &^ @&@'*/V,"?Lh:hmBmz|z{x`y~|fN|@@|@͂|@ ݃ƃ<ns<|Ŏ |️|ep|u|-@率|<ᄇ2ֻr||ZRM | ntB|xyvZw|J=|R>|J? nnaa|bddf, see if we have EXQTA call chkprv ; /45/ ... mov r0 ,r2 ; /45/ Save the flag bne 10$ ; /45/ EXQTA, skip quota checks ; clrfqb ; /45/ Ensure FIRQB is cleared out movb #UU.ATR ,FIRQB+FQFUN ; /45/ Do some quota checks decb FIRQB+4 ; /45/ Read account attributes incb FIRQB+5 ; /45/ We want quota data .UUO ; /45/ Get the data tstb FIRQB ; /45/ Did this work ? bne 50$ ; /45/ No, just log out then cmpb FIRQB+21,FIRQB+17 ; /45/ Is MSB of quota OK ? bhi 100$ ; /45/ No, exit cmp FIRQB+24,FIRQB+12 ; /45/ Is current usage < outquota? bhi 100$ ; /45/ No ; 10$: clrfqb ; /45/ Yes, get keyboard number movb #UU.SYS ,FIRQB+FQFUN ; /45/ UU.SYS part 0 .UUO ; /45/ We have it now movb FIRQB+5 ,r1 ; /45/ Save it bitb #200 ,r1 ; /45/ Detached? bne 50$ ; /45/ Yes, skip hangup clrfqb ; /45/ Get set to disconnect line movb #UU.HNG ,FIRQB+FQFUN ; /45/ At last.... movb r1 ,FIRQB+4 ; /45/ Line to do it to incb FIRQB+5 ; /45/ Do it quickly (1 second) .UUO ; /45/ Drop the line, now log out ; 50$: clrfqb ; /45/ Clear FIRQB out movb #UU.BYE ,FIRQB+FQFUN ; /45/ Log out now tst r2 ; /45/ Version 9 and EXQTA ? beq 60$ ; /45/ No movb #2 ,FIRQB+4 ; /45/ Yes, bypass quota checks 60$: .UUO ; /45/ Call the EXEC cmp FIRQB+4 ,#-1 ; /45/ Are we logged out ? beq 100$ ; /45/ No call exit ; /45/ Yes, exit please (never happen) 100$: unsave ; /45/ Pop registers return ; /45/ Quota must be exceeded .sbttl Check current quotas to see if UU.BYE will succeed quochk::tst ver9.x ; /45/ Version nine or later beq 30$ ; /45/ No, skip the quota check mov #exqta ,-(sp) ; /45/ V9, see if we have EXQTA call chkprv ; /45/ ... tst r0 ; /45/ Save the flag beq 10$ ; /45/ No EXQTA, do quota checks clr r0 ; /45/ EXQTA, return(success) br 100$ ; /45/ Exit ; 10$: clr r0 ; /45/ Assume SUCCESS clrfqb ; /45/ Ensure FIRQB is cleared out movb #UU.ATR ,FIRQB+FQFUN ; /45/ Do some quota checks decb FIRQB+4 ; /45/ Read account attributes incb FIRQB+5 ; /45/ We want quota data .UUO ; /45/ Get the data tstb FIRQB ; /45/ Did this work ? bne 100$ ; /45/ No, just return(success) cmpb FIRQB+21,FIRQB+17 ; /45/ Is MSB of quota OK ? bhi 20$ ; /45/ No, exit cmp FIRQB+24,FIRQB+12 ; /45/ Is current usage < outquota? blos 100$ ; /45/ Yes 20$: mov sp ,r0 ; /45/ No, return(nonzero) br 100$ ; /45/ Exit 30$: clrfqb ; /45/ Pre version 9 code movb #UU.RAD ,FIRQB+FQFUN ; /45/ rad accounting data please .UUO ; /45/ simple clr r0 ; /45/ assume success tstb FIRQB ; /45/ did it work ? bne 100$ ; /45/ no tst FIRQB+34 ; /45/ unlimited quota here ? beq 100$ ; /45/ yes cmp FIRQB+6,FIRQB+34 ; /45/ is used > allowed ? blos 100$ ; /45/ quota is ok mov sp ,r0 ; /45/ quota is not ok, flag it 100$: return ; /45/ Return to caller .sbttl Return disk space usage ; D S K U S E ; ; input: @r5 address of string to return the usage .enabl lsb dskuse::save clrfqb ; clear FIRQB out movb #UU.RAD ,FIRQB+FQFUN ; uuo function, read accounting data .UUO ; do it mov @r5 ,r1 ; point to the output string copyz #120$ ,r1 ; copy a header over please strlen r1 ; get the current length add r0 ,r1 ; point to the end of the string deccvt ,r1,#6 ; and convert used to string add #6 ,r1 ; point to the end again copyz #130$ ,r1 ; copy some more stuff strlen r1 ; get the count of chars we copied add r0 ,r1 ; point to the end of the string mov FIRQB+34,r0 ; get the quota bne 10$ ; not unlimited copyz #140$ ,r1 ; unlimited, say so br 20$ 10$: sub FIRQB+6 ,r0 ; and get the free space deccvt r0 ,r1 ; copy the free space over now clrb 6(r1) ; make the string .asciz 20$: unsave return ; bye .save .psect $PDATA ,D 120$: .asciz /SY: Space used / 130$: .asciz / Space free / 140$: .asciz / Unlimited/ .even .restore .dsabl lsb .end K1180SMAC[.050032]K1180S.MAC[.050032]   X14