(* [CSC60]NTV:SNIFF.PAS.8, 15-May-86 17:05:43, Edit by FORDYCE *) (* 3(2) Added compile-time option to not include IDLE command availability *) (* and to default to no idle time *) (* SNIFF.PAS.15, 15-Nov-84 14:15:03, Edit by FORDYCE *) (* 3(1) Added "IDLE n" option, where only jobs idle for longer than *) (* n minutes will be logged out. *) (*$V:300000002B*) (* SNIFF.PAS.5, 18-Sep-84 13:27:06, Edit by FORDYCE *) (* 3(0) Converted kludgey logic to using Rutgers' CMINIR, and related *) (* routines *) (* Rewrite ASK_TTY and YESNO routines to use COMND jsys *) (* SNIFF.PAS.2, 18-Sep-84 10:05:57, Edit by FORDYCE *) (* 2(1) Added 'DET' option - functions similarly to 'ALL' option, *) (* except that only detached jobs are 'sniffed'. *) (* Removed extraneous INCLUDE statements *) (* SNIFF.PAS.2 22-Sep-81 10:32:38, Edit by FORDYCE *) (* Added 'NIL' option - see edit history below *) PROGRAM SNIFF ; (* * * * * * * * * * * * * * * * * * * * * * * * * * *) (* *) (* Written by David Fordyce 20-Feb-81 *) (* Texas Instruments, Inc. *) (* Computer Science Laboratory *) (* Central Research Laboratories *) (* P.O. Box 226015 ; M/S 238 *) (* Dallas, Texas 75266 *) (* (214) 995-0375 *) (* *) (* Edit History: *) (* *) (* 11-May-81 by David Fordyce *) (* Prevent the user from logging-out or *) (* attaching to a batch job *) (* *) (* 22-Sept-81 by David Fordyce *) (* Add the 'nil' option to only display *) (* other jobs (if any) without asking *) (* the user what he wants to do. This *) (* feature complements the EXEC's *) (* prompting you with one of your *) (* detached jobs, allowing you to enter *) (* a job # or 'NEW-JOB'. *) (* * * * * * * * * * * * * * * * * * * * * * * * * * *) Include 'pas:extern.pas' ; { *** Set USEIDLE <>0 if you have the IDLE jsys installed *** } Const UseIdle = 0; Type STRING = PACKED ARRAY[1..80] of CHAR ; STR = ARRAY[1..6] of CHAR ; ST = PACKED ARRAY[1..3] of CHAR ; ALFA = PACKED ARRAY[1..10] of CHAR ; Var Emode : Cmmodes ; I:INTEGER ; Jobnum:ARRAY[1..128] of INTEGER ; (* Job number *) Trmnum:ARRAY[1..128] of INTEGER ; (* Job's terminal number *) (* -1 means DETached *) Usrnum:ARRAY[1..128] of INTEGER ; (* Job's user number *) Cdrnum:ARRAY[1..128] of INTEGER ; (* Job's connected directory number *) Subsys:ARRAY[1..128] of ALFA ; (* Subsystem name *) Pgmnam:ARRAY[1..128] of ALFA ; (* Program name *) IdlTim:ARRAY[1..128] of INTEGER ; (* Job idle time *) Jbinfo:PACKED RECORD (* Argument block for GETJI *) Jijno:INTEGER ; (* Job number *) Jitno:INTEGER ; (* Job's terminal number *) Jiuno:INTEGER ; (* Job's user number *) Jidno:INTEGER ; (* Job's connected directory number *) Jisnm:INTEGER ; (* Subsystem name (sixbit ) *) Jipnm:INTEGER ; (* Program name (sixbit) *) Jirt :INTEGER ; (* Run time *) Jicpj:INTEGER ; (* Controlling PTY job number, or -1 if no PTY *) Jirtl:INTEGER ; (* Run time limit *) Jibat:INTEGER ; (* -1 if controlled by batch *) END ; Myuser:INTEGER ; Mydrno:INTEGER ; Myjbno:INTEGER ; Myterm:INTEGER ; Jobcnt:INTEGER ; Frmarg:ALFA ; RscnP: BOOLEAN ; Showonly:BOOLEAN ; Text:ST ; Xwd:PACKED RECORD CASE BOOLEAN OF TRUE:(full:INTEGER) ; FALSE:(lh:0..777777B;rh:0..777777B) END ; Comtable:TABLE ; Cmdtab :TABLE ; Cmdopt :INTEGER ; YNtab :TABLE ; IdlDef, IdlLim : INTEGER ; (* For sniffing IDLE jobs *) PROCEDURE CMDINI ; BEGIN Comtable := Tbmak(1) ; Tbadd(Comtable,1,'sniff',0) ; Cmdtab := tbmak(4) ; Tbadd(Cmdtab,1,'all',0) ; Tbadd(Cmdtab,2,'detached',0) ; if UseIdle <> 0 then Tbadd(Cmdtab,3,'idle',0) ; Tbadd(Cmdtab,4,'nil',0) ; YNtab := Tbmak(2) ; Tbadd(YNtab,0,'no',0) ; Tbadd(YNtab,1,'yes',0) ; END ; PROCEDURE DO_IT ; Var I,ret:INTEGER ; BEGIN FOR I := 1 to 128 DO IF Jobnum[I] <> 0 THEN begin If IdlLim = 0 Then IF (Jobnum[I] <> Myjbno) Then Jsys(lgout,1,ret;Jobnum[I]) ; If IdlLim <> 0 Then If (Jobnum[I] <> Myjbno) AND (IdlTim[I] >= IdlLim) Then Jsys(lgout,1,ret;Jobnum[I]) ; end ; END ; PROCEDURE DO_DET ; Var I,ret:INTEGER ; BEGIN FOR I := 1 to 128 DO IF Jobnum[I] <> 0 THEN IF (Jobnum[I] <> Myjbno) and (Trmnum[I] = -1) THEN Begin Jsys(lgout,1,ret;Jobnum[I]) ; WRITELN(tty,' [Job # ',Jobnum[I]:2,' running ',Pgmnam[I]:7,' (Det) Logged Out]') ; End ; END ; PROCEDURE SUICIDE ; Var Lgojfn, LgoHandle, ret : INTEGER ; BEGIN Reset(output,'sys:ljob.exe') ; Lgojfn := Curjfn(output) ; Close(output) ; Jsys(cfork,2,ret;200000000000B,0;LgoHandle) ; (* CFORK *) IF ret = 1 THEN WRITE(tty,' CFORK Failed ') ; Jsys(gget,1,ret;LgoHandle:Lgojfn) ; (* GET *) Jsys(sfrkv;LgoHandle,0) ; (* SFRKV *) END ; PROCEDURE GET_DATA ; VAR I,J,K,ret,result1 : INTEGER ; IdlRet : INTEGER ; BEGIN WITH Jbinfo DO FOR I := 1 to 128 DO BEGIN ret := 0 ; (* Zero out return indicator *) if UseIdle <> 0 then Jsys(Idle,-1,Idlret;I;IdlTim[I]) (* Get idle time in milliseconds *) else IdlTim[I] := 0 ; (* default to no idle time *) Jsys(getji,-2,ret;I,-10:Jbinfo,0) ; (* get information for job specified by I *) IF ret > 2 THEN Jobnum[I] := 0 (* either a bad return from getji *) ELSE IF Myuser <> Jiuno THEN Jobnum[I] := 0 (* or the job in question does not *) (* belong to this logged in user *) ELSE IF Jibat <> -1 (* only let the user know of non-batch jobs *) THEN BEGIN Jobnum[I] := Jijno ; Trmnum[I] := Jitno ; Usrnum[I] := Jiuno ; Cdrnum[I] := Jidno ; K := Jisnm ; FROM6(K,Frmarg) ; Subsys[I] := Frmarg ; K := Jipnm ; FROM6(K,Frmarg) ; Pgmnam[I] := Frmarg ; Jobcnt := Jobcnt + 1 END ; (* begin (if) *) END ; (* begin (for) *) END ; (* procedure *) PROCEDURE MY_DATA ; VAR ret : INTEGER ; BEGIN Jsys(gjinf,1,ret;;Myuser,Mydrno,Myjbno,Myterm) ; END ; PROCEDURE TELL_TTY ; VAR I, Ret :INTEGER ; BEGIN WRITELN(tty,' You have the following jobs: ') ; FOR I := 1 TO 128 DO IF Jobnum[I] <> 0 THEN IF Trmnum[I] = -1 THEN WRITELN(tty,' Job # ',Jobnum[I]:2,' running ',Pgmnam[I]:7,' (detached)') ELSE BEGIN IF Trmnum[I] = Myterm THEN WRITELN(tty,' Job # ',Jobnum[I]:2,' running ',Pgmnam[I]:7,' (current job)') ELSE BEGIN WRITE(tty,' Job # ',Jobnum[I]:2,' running ',Pgmnam[I]:7,' (on TTY'); Jsys(Nout,1,Ret;101B,Trmnum[I],8) ; WRITELN(tty,':)') ; END ; END ; END ; FUNCTION YESNO:BOOLEAN ; var ans : integer ; BEGIN ans := cmkey(yntab) ; cmcfm ; case ans of 0 : yesno := false ; 1 : yesno := true ; end ; END ; PROCEDURE ASK_TTY ; VAR I,Bp,ret,result1 : INTEGER ; Prmpt : STRING ; BEGIN (* 1 *) I := 1 ; (* initialize loop counter *) loop exit if Jobcnt = 1 ; (* only let the user attach to one *) (* job to refrain from pestering *) (* the user with more questions *) IF Jobnum[I] <> 0 THEN IF Jobnum[I] <> Myjbno THEN BEGIN (* see what user wants to do *) Jsys(Sout;-1:Prmpt,-1:' Do you want to attach to job # ',32,0;BP) ; Jsys(Nout,1,Ret;BP,Jobnum[I],10;BP) ; Jsys(Sout;BP,-1:' ? ',3,0;BP) ; Jsys(Bout;BP,chr(00)) ; Cmini(Prmpt) ; IF Yesno THEN BEGIN (* do attach *) WRITELN(tty,' [Job # ',Myjbno:2,' logged out]') ; Jsys(atach,1,ret;Jobnum[I],Myuser,0,0;result1) ; Jsys(Lgout,1,Ret;-1) ; Jobnum[Myjbno] := 0 ; Myjbno := Jobnum[I] ; Jobcnt := Jobcnt - 1 ; END (* do attach *) ELSE BEGIN (* ask about logout *) Jsys(Sout;-1:Prmpt,-1:' Do you want to log out job # ',30,0;BP) ; Jsys(Nout,1,Ret;BP,Jobnum[I],10;BP) ; Jsys(Sout;BP,-1:' ? ',3,0;BP) ; Jsys(Bout;BP,chr(00)) ; Cmini(Prmpt) ; IF Yesno THEN BEGIN (* do logout *) Jsys(lgout,1,ret;Jobnum[I]) ; IF ret = 1 THEN WRITELN(tty,' [Job # ',Jobnum[I]:2,' not logged out]') ; IF ret = 2 THEN WRITELN(tty,' [Job # ',Jobnum[I]:2,' logged out]') ; Jobcnt := Jobcnt - 1 ; END (* do logout *) ELSE Jobcnt := Jobcnt - 1 ; END ; (* ask about logout *) END ; (* see what user wants to do *) IF I = 128 THEN I := 1 ELSE I := I + 1 end (* loop *) END ; (* 1 *) BEGIN (* 1 *) reset(tty,'',true,0,0,5); (* map lower case, handle data errors *) Showonly := FALSE ; (* unless otherwise noted, ask user what job he wants to attach to *) Jobcnt := 0 ; (* initialize count of the number of this *) (* user's jobs *) IdlDef := 0 ; (* No idle time by default *) IdlLim := Idldef ; CMDINI ; (* Initialize TBLUK tables *) MY_DATA ; GET_DATA ; Cminir('') ; Emode := Cmmode ; IF Emode = Rescan THEN Cmdopt := Cmkey(Cmdtab) ELSE Cmdopt := 0 ; CASE Cmdopt OF 0 : Jfcl ; (* No Rescan Command *) 1 : begin (* ALL *) Cmcfm ; DO_IT ; Jobcnt := 0 ; (* reset this counter to indicate that all * of the other jobs have already been * disposed of *) end ; 2 : begin (* DETACHED *) Cmcfm ; DO_DET ; Jobcnt := 0 ; (* reset this counter to indicate that all * of the other jobs have already been * disposed of *) end ; 3 : begin IdlLim := Cmnum ; Cmcfm ; IdlLim := IdlLim * 60 * 1000 ; (* need value in milliseconds *) DO_IT ; (* use same code as "ALL", except for idle time *) Jobcnt := 0 ; end; 4 : begin (* NIL *) Cmcfm ; Showonly := TRUE ; (* set this so that other jobs for this * user will be listed, but the user * won't be asked any questions *) end ; END ; (* case *) IF Jobcnt > 1 THEN BEGIN (* 2 *) TELL_TTY ; IF NOT Showonly THEN ASK_TTY END ; (* 2 *) END. (* 1 *)