1 ! ! R E M O T E 2! Program: REMOTE 3! Version: V01B 4! Edit: 02 7! Edit Date: 15-Mar-80 9! Author: Brant Cheikes 20 ! ! M o d i f i c a t i o n H i s t o r y Version/Edit Edit Date Reason 21! V01A-01 04-Mar-80 New release ! V01A-02 07-Mar-80 Increase operating speed ! V01B-01 12-Mar-80 Add starting timer ! V01B-02 15-Mar-80 Fix timer 50 ! ! P r o g r a m D e s c r i p t i o n 60 ! ! REMOTE allows any user on any keyboard (usually a keyboard ! other than KB0:, the system Console Terminal) to bring a ! halt to RSTS/E timesharing under control of the SHUTUP program ! in the system library [1,2]. ! ! It duplicates the set-up dialogue of SHUTUP, detaches, logs ! itself into [1,2], reattaches to KB0:, forces the proper ! commands to cause execution of the SHUTUP program to its own ! keyboard (KB0:), and exits, thereby allowing SHUTUP to take ! over and bring the system down. ! ! REMOTE also allows the user to delay shutdown operations until ! a specified time. REMOTE can sleep throughout the day, to awake ! at a specified time to begin system shutdown operations. ! ! REMOTE is fast and virtually fool-proof. It can be used by ! anyone, as long as it or the user has privileges. It is necessary ! that REMOTE be protected <252> for use by non-privileged users. ! 900 ! ! D i m e n s i o n S t a t e m e n t s 910 DIM S%(30%) ! Dimension SYS call setup/return matrix 1000 ! ! M a i n P r o g r a m C o d i n g 1010 V$ = "V01B-02" ! Set up version/edit level 1020 ON ERROR GOTO 30000 \ PRINT \ PRINT "REMOTE "+V$+" "+ CVT$$(RIGHT(SYS(CHR$(6%)+CHR$(9%)),3%),4%) \ PRINT "Remote System Shutdown" \ PRINT ! Output the system header 1025 ! ! S H U T U P D i a l o g u e 1030 PRINT \ PRINT "######## Set-up Dialogue Phase ########" \ PRINT \ PRINT "Type 'ESC' ('ALT') to any query to backup one (1) step" \ PRINT ! Print instructions 1040 PRINT IF POS(0%) \ PRINT "Use 'OPSER' for utilities shutdown? (YES/NO) "; \ INPUT LINE A$ \ IF A$ = CHR$(27%) THEN 1040 ! Ask if we want to use OPSER; handle ESCs 1045 A$ = CVT$$(A$,4%) \ A$ = "YES" UNLESS LEN(A$) \ D$ = LEFT(A$,1%) \ IF D$ = "Y" THEN 1060 ELSE IF D$ = "N" THEN 1050 ELSE 1040 ! Handle the response entered; set default, etc. 1050 PRINT IF POS(0%) \ INPUT "Are you sure you don't want to use 'OPSER'? (YES/NO) ";B$ \ D$ = LEFT(B$,1%) \ GOTO 1040 IF D$ = "N" OR LEN(B$) = 0% \ GOTO 1050 IF D$ <> "Y" \ A$ = "NO" \ B$ = "YES" \ GOTO 1070 ! Check that user is sure he doesn't want to use 'OPSER'; if he is ! sure, set the variables and get shutdown time 1060 PRINT IF POS(0%) \ A$ = "YES" \ PRINT "Allow utilities to reach logical endpoint? (YES/NO) "; \ INPUT LINE B$ \ GOTO 1040 IF B$ = CHR$(27%) \ B$ = CVT$$(B$,4%) \ B$ = "YES" UNLESS LEN(B$) \ D$ = LEFT(B$,1%) \ IF D$ = "Y" THEN B$ = "YES" ELSE IF D$ = "N" THEN B$ = "NO" ELSE GOTO 1060 ! Ask next question and handle all possible responses 1070 PRINT IF POS(0%) \ PRINT "Minutes until system shutdown? (0-99) <5>"; \ INPUT LINE C$ \ GOTO 1060 IF C$ = CHR$(27%) IF A$ = "YES" \ GOTO 1050 IF C$ = CHR$(27%) \ C$ = CVT$$(C$,4%) \ C$ = "5" UNLESS LEN(C$) \ IF VAL(C$) < 0% OR VAL(C$) > 99% THEN 1070 ! Get minutes; handle escapes; set default 1075 PRINT "Begin shutdown operations at? <";CVT$$(TIME$(0%),2%);"> "; \ INPUT T$ \ GOTO 1080 UNLESS LEN(T$) \ S% = INSTR(1%,T$,':') \ GOTO 1075 UNLESS S% \ H% = VAL(LEFT(T$,2%)) \ M% = VAL(RIGHT(T$,4%)) ! Ask user when to start shutdown operations; the default is the ! present time (immediately); if response entered, set it up as ! hours and minutes for sleep 1080 PRINT \ PRINT "Detaching..." \ PRINT \ S$ = SYS(CHR$(6%)+CHR$(7%)+CHR$(128%)) \ S$ = SYS(CHR$(6%)+CHR$(5%)) ! Tell user what's happening; detach and logout; give output some time 1090 CHANGE SYS(CHR$(6%)+CHR$(14%)+STRING$(4%,0%)+CHR$(2%)+CHR$(1%)) TO S% \ S%(0%) = 30% \ S%(1%) = 6% \ S%(2%) = 4% \ S%(5%) = 2% \ S%(6%) = 1% \ S%(X%) = S%(X%+2%) FOR X% = 7% TO 10% \ CHANGE S% TO S$ \ CHANGE SYS(S$) TO S% \ J% = S%(1%) / 2% ! Read password to [1,2]; set up for login SYS call; execute; get ! our job number 1095 GOSUB 10100 IF S% ! If we are delaying, go to timing subroutine 1100 S$ = SYS(CHR$(6%)+CHR$(6%)+CHR$(J%)+CHR$(0%)) ! Attempt to reattach to KB0: 1110 PRINT \ PRINT "REMOTE "+V$+" initiating system shutdown" \ PRINT ! Tell KB0: what the 'eck is going on 1120 S$ = FNF$("RUN SHUTUP") \ S$ = FNF$(A$) \ S$=FNF$(B$) \ S$=FNF$(C$) \ PRINT \ S$ = SYS(CHR$(5%)) \ STOP ! Force the varied commands for executing the SHUTUP program to our ! own keyboard and exit 10000 ! ! S u b r o u t i n e s ! T a k e c a r e o f j o b o n K B 0 : 10010 T$ = CHR$(13%)+CHR$(10%)+CHR$(10%)+ "REMOTE needs KB0: for system shutdown - please logout within one "+ "minute"+CHR$(13%)+CHR$(10%)+CHR$(10%) \ S$ = SYS(CHR$(6%)+CHR$(-5%)+CHR$(0%)+T$) \ SLEEP 60% ! Broadcast as message to KB0: if a job is on it; sleep for a minute 10020 ON ERROR GOTO 10030 \ S$ = SYS(CHR$(6%)+CHR$(6%)+CHR$(J%)+CHR$(0%)) \ ON ERROR GOTO 30000 \ GOTO 1110 ! Set a modular error trap; try to attach; resume normal processing ! if it succeeds 10030 RESUME 10040 ! Re-enable error trapping 10040 T$ = CHR$(13%)+CHR$(10%)+CHR$(10%)+"You were warned..."+CHR$(13%)+ CHR$(10%)+CHR$(10%) \ S$ = SYS(CHR$(6%)+CHR$(-5%)+CHR$(0%)+T$) \ SLEEP 2% ! Send a warning message and sleep some time for output to finish 10050 S$ = FNF$(CHR$(3%)+CHR$(3%)+"BYE/F") \ SLEEP 10% \ ON ERROR GOTO 10060 \ S$ = SYS(CHR$(6%)+CHR$(6%)+CHR$(J%)+CHR$(0%)) \ ON ERROR GOTO 30000 \ GOTO 1110 ! Force logout commands; sleep a bit; try to reattach setting a ! modular error trap 10060 T$ = CHR$(13%)+CHR$(10%)+CHR$(10%)+TIME$(0%)+DATE$(0%)+CHR$(13%)+ CHR$(10%)+CHR$(10%)+"Job on Console Terminal failed to go away - "+ "REMOTE shutdown aborted"+CHR$(13%)+CHR$(10%)+CHR$(10%) \ S$ = SYS(CHR$(6%)+CHR$(-5%)+CHR$(0%)+T$) \ S$ = SYS(CHR$(6%)+CHR$(8%)+CHR$(J%)+STRING$(24%,0%)+CHR$(255%)) \ STOP ! If REMOTE fails again, log error on console and commit suicide 10100 ! ! D e l a y T i m i n g S e q u e n c e 10110 P$ = CVT$$(TIME$(0%),2%) \ H2% = VAL(LEFT(P$,2%)) \ M2% = VAL(RIGHT(P$,4%)) \ GOTO 10500 IF (H%-H2%) <= 0% AND (M%-M2%) <= 0% \ T% = H% - H2% \ T2% = M% - M2% \ IF T2% < 0% THEN T2% = 60% + T2% \ T% = T% - 1% ! Get present time; separate hours and minutes; if no time left, then ! go start shutdown else get hours and minutes to sleep; if minutes ! to sleep is less than zero, we have a fraction less than an hour ! to sleep; find out how many minutes we must sleep and subtract one ! from the hours to sleep to allow for the fraction 10115 GOTO 10130 IF T% ! If we must sleep for a certain number of hours, go do that 10120 SLEEP T2% * 60% \ GOTO 10100 ! Sleep the amount of minutes and go re-check time 10130 GOTO 10140 IF T% > 9% \ SLEEP T% * 3600% \ GOTO 10100 ! Check the number of hours we must sleep; if greater than 9 (the ! number of seconds in more than 9 hours is greater than 32767), ! go sleep 9 hours else just sleep required number of hours 10140 SLEEP 9% * 3600% \ GOTO 10100 ! Sleep 9 hours then go re-check time left 10500 RETURN 20000 ! ! F u n c t i o n s 20010 DEF FNF$(Z$) = SYS(CHR$(6%)+CHR$(-4%)+CHR$(0%)+Z$+CHR$(13%)) ! Define the forcing function 30000 ! ! E r r o r H a n d l i n g 30010 IF ERL = 1070% AND ERR <> 11% THEN RESUME 1070 ! Take care of errors on VAL conversion 30020 IF ERL = 1100% THEN RESUME 10000 ! Go handle reattach errors 30030 IF ERL = 1075% THEN PRINT IF POS(0%) \ RESUME 1075 ! Go handle errors resulting from invalid time entries 30800 IF ERR = 11% THEN RESUME 32000 ! Take care of CTRL/Zs 30810 IF ERL < 1080% THEN RESUME 32000 ! If errors while attached, simply exit 30900 T$ = CHR$(13%)+CHR$(10%)+CHR$(10%)+"REMOTE "+V$+" unexpected "+ "fatal error - "+CVT$$(RIGHT(SYS(CHR$(6%)+CHR$(9%)+CHR$(ERR)),3%),4%)+ " - (ERR="+NUM1$(ERR)+") at line "+NUM1$(ERL)+CHR$(13%)+CHR$(10%)+ CHR$(10%) \ S$ = SYS(CHR$(6%)+CHR$(-5%)+CHR$(0%)+T$) \ S$ = SYS(CHR$(6%)+CHR$(8%)+CHR$(J%)+STRING$(24%,0%)+CHR$(255%)) \ STOP ! On all other errors, log them and commit suicide 32000 ! ! E x i t 32010 S$ = SYS(CHR$(9%)) ! Clear core and exit fast 32767 END