1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
|
#!/usr/local/bin/kermit +
#
# i k s d p y -- IKSD display
#
# Active display of IKSD database.
# Main screen lists all sessions, with option to switch to
# a per-session detail screen.
#
# Illustrates:
# . File record i/o
# . WAIT FILE and \v(kbchar)
# . Arithmetic
# . Hexadecimal decoding
# . Single-keystroke program control
# . Compact substring notation
# . Rudimentary screen formatting
#
# Requires: C-Kermit 7.0 Beta.11 or later.
#
# PRERELEASE:
# Last update: Tue Dec 7 19:19:03 1999
# Documentation: iksdb.txt
#
# Author: F. da Cruz, Columbia University, November 1999.
local \%c \%n \%p block dbfile rate dir user info
; Configuration (change as needed)...
.rate = 4 ; Screen refresh rate (sec)
if def \%1 .dbfile := \%1 ; Database file
if not def dbfile {
if eq "\v(platform)" "32-bit_Windows" {
if not equal "\$(winbootdir)" "" .dbfile := \$(winbootdir)/iksd.db
else if not equal "\$(windir)" "" .dbfile := \$(windir)/iksd.db
else if not equal "\$(SystemRoot)" "" .dbfile := \$(SystemRoot)/iksd.db
else .dbfile = c:/iksd.db
} else {
.dbfile = /var/log/iksd.db
}
}
; Operating variables and settings...
set case off ; Case matters not
set quiet on ; No noisy messages
set sleep cancel on ; Allow interrupt WAIT from keyboard
; Macros
define SHOWHELP { ; Main help screen
cls
echo {IKSD Display...}
echo
echo {Press:}
echo { The Space Bar to switch between summary and detail screens.}
echo { A digit to view a particular session, 0 through 9, or:}
echo { X to enter a session number with two or more digits.}
echo { M to return to the Main screen.}
echo { N to see the Next session (cycle through sessions).}
echo { H to see this Help message.}
echo { Q to Quit.}
set ask-timer 0
echo
getc \%9 {Press any key to continue: }
set ask-timer \m(rate)
}
define SHOWRECORD { ; Interpret a record
.pid := \fltrim(\s(block[17:16]),0)
.flags := \fhex2n(\s(block[1:4]))
if ( (\m(flags)&1) ) { .\%v = (IN_USE) } else { .\%v = (FREE) }
if ( (\m(flags)&2) ) { .\%v := \%v(REAL_USER) }
if ( (\m(flags)&4) ) { .\%v := \%v(LOGGED_IN) }
cls ; Clear screen and print detail
echo [\m(dbfile)] Session \%1: \v(time)...
echo
echo { Flags: \s(block[1:4]) \%v}
echo { AuthT: \s(block[5:4])}
echo { AuthM: \s(block[9:4])}
echo { State: \s(block[13:4])}
echo { Lhost: \fhex2ip(\s(block[41:8]))} ; 32+8+1
echo { Rhost: \fhex2ip(\s(block[57:8]))} ; 48+8+1
echo { PID: \m(pid) (\fhex2n(\m(pid)))}
echo { Start: \s(block[66:17])}
echo { Last: \s(block[84:17])}
echo { User: \s(block[1025:\fhex2n(\s(block[101:4]))])}
echo { Dir: \s(block[2049:\fhex2n(\s(block[105:4]))])}
echo { Info: \s(block[3073:\fhex2n(\s(block[109:4]))])}
echo
}
define SHOWDETAIL { ; Show details for a session
local \%k \%v \%x
if not def \%1 return
if ( < \fcode({\%1}) 32 ) return
if eq {\%1} { } .\%1 = 0
if eq {\%1} {N} .\%1 = 0
.\%x = \%1
while true { ; Loop in detail screen
if def \%x switch \%x { ; What did they type?
:[0-9] ; A digit
.\%1 := \%x
break ; So that's the session number.
:H, showhelp, ; An 'H' so show help text.
if not num \%1 return
break
:Q, echo Q, exit 0 ; 'Q' for quit.
:N, .\%n ::= (\fsize(\m(dbfile))/4096) ; Check for new records
.\%1 ::= \fmod(\%1+1,\%n) ; Go to next session
break
:X, xecho \13 ; Long session number
screen cleol ; Clear this line
set ask-timer 0
ask \%1 { Enter session number: } ; Prompt and wait for text
set ask-timer \m(rate) ; up to CR with no timeout.
if not def \%1 .\%1 = 0 ; If CR only, use 0.
if not numeric \%1 { ; Check for n-ness.
echo Number required
return
}
break
:M, return ; Return to main screen.
:default
echo Not a choice: "\%1"
pause 1
return
}
if ( > \%1 (\%n-1) || < \%1 0 ) { echo Out of range, pause 1, return }
.\%k ::= \%1*4096 ; Seek position for desired record
fclose \%c ; Close/Open to force data refresh
fopen /read /binary \%c \m(dbfile)
if fail end 1 CLOSE OPEN FAILURE
fseek \%c \%k ; Seek to record
if fail end 1 Seek failed.
.\%p := \f_pos(\%c)
fread /size:4096 \%c block ; Read it
if fail end 1 Read failed.
if ( ! = \f_pos(\%c) \%p+4096 ) exit 1 FATAL - Database corrupt
showrecord \%1 ; Show it
xecho {[0-9] (session digit), H[elp], or Q[uit]: }
wait 60 file modification \m(dbfile)
if success continue
undef \%x
if ( def \v(kbchar) ) { .\%x := \v(kbchar) } else { getc \%x }
if not def \%x continue
if eq { } {\%x} .\%x = M
}
}
; Main display...
undef \%c ; Database not yet open
set ask-timer \m(rate) ; Refresh rate control
while true { ; Main loop
cls
if ( not def \%c ) { ; If database not open
if exist \m(dbfile) { ; If it exists
fopen /read /binary \%c \m(dbfile) ; Open it
if fail {
echo \m(dbfile) - Open failed: \f_errmsg()
sleep \m(rate)
continue
}
} else { ; It doesn't exist
echo [\m(dbfile)] - Does not exist: \v(time)...
sleep \m(rate)
continue
}
}
echo [\m(dbfile)] \v(time)... ; Top line - filename & time
echo
echo { Flgs Host........... Start... Last.... (PID)(user)(dir)(what)}
.\%n = 0
frewind \%c ; Rewind database
if fail { undef \%c, continue } ; On failure go gack and reopen it
while ( ! \f_eof(\%c) ) { ; Loop to read each record
fread /size:4096 \%c block
if fail break
if ( != \fmod(\f_pos(\%c),4096) 0 ) exit 1 FATAL - Database corrupt
incr \%p 4096
.user := \ftrim(\s(block[1025:1024]))
.dir := \ftrim(\s(block[2049:1024]))
.info := \ftrim(\s(block[3073:1024]))
.\%a := \flpad(\%n,2). \s(block[1:4]) -
\frpad(\fhex2ip(\s(block[57:8])),15)\s(block[74:9])\s(block[92:9]) -
(\fhex2n(\s(block[17:16])))(\m(user))(\m(dir))(\m(info))
echo \fleft(\%a,\v(cols))
incr \%n
}
echo
xecho {[0-9] (session digit), H[elp], or Q[uit]: }
wait 60 file modification \m(dbfile)
if success continue
undef \%x
if ( def \v(kbchar) ) { .\%x := \v(kbchar) } else { getc \%x }
if ( defined \%x ) showdetail {\%x}
if ( == \%n 1 ) { fclose \%c, undef \%c } ; Force refresh if only one
}
|