home *** CD-ROM | disk | FTP | other *** search
Korn shell script | 1997-08-26 | 6.7 KB | 220 lines |
- #!/bin/ksh
- # @(#) newswarn.ksh 1.1 94/11/19
- # 94/09/18 john h. dubois iii (john@armory.com)
- # 94/11/06 Removed c option; now no g opt means check-only.
- # 94/11/19 Explicitely state if noone is using the news server.
-
- # Output of command 'sockinfo -st':
- # tcp 0 0 192.122.209.42.4724 192.122.209.39.119 CLOSE_WAIT
- # PID 24777: trn
- # user bdp on tty /dev/ttyp50
-
- # Usage: FindPortUsers <ip-address> <port-number>
- # Output is lines of the form:
- # <user> <tty>
- # Line are also written to stderr with the form:
- # User <user> on tty <tty> is running <ps-name> (pid <process-id>).
-
- # Output of sockinfo has the format:
- # line describing a socket used by a process
- # ....
- # name and pid of the process using the above sockets
- # user and controlling tty for the above process
- # Example:
- #Proto Recv-Q Send-Q Local Address Foreign Address (state)
- #tcp 0 0 192.122.209.42.4669 129.24.12.18.7326 ESTABLISHED
- # PID 3362: icb
- #user turtle on tty /dev/ttyp25
- #tcp 0 0 192.122.209.42.80 192.122.209.42.4667 TIME_WAIT
- #tcp 0 0 192.122.209.42.4666 198.7.0.2.25 TIME_WAIT
- #tcp 0 1219 192.122.209.42.20 141.222.1.3.1081 FIN_WAIT_1
- #tcp 0 0 192.122.209.42.21 141.222.1.3.1080 ESTABLISHED
- # PID 3061: Mosaic
- #user zap on tty /dev/ttyp21
- #tcp 0 0 127.0.0.1.6001 127.0.0.1.4592 ESTABLISHED
- # Returns 1 if no users are using the specified ip-address/port-number,
- # 0 if any are.
- function FindPortUsers {
- sockinfo -st | gawk -v ip="$1" -v Port="$2" '
- BEGIN {
- # Escape dots in IP address so that it can be used as a regex,
- # so that a port number of .* will have the right effect
- gsub(/\./,"\\.",ip)
- FoundUser = 0
- }
-
- # Find processes connected to a particular port on the news server.
- $1 == "tcp" {
- if ($5 ~ "^" ip "\\." Port "$")
- PortUser = 1
- next
- }
- $1 == "PID" {
- pid = $2
- gsub(":","",pid)
- procname = $3
- next
- }
- $1 == "user" {
- tty = substr($5,6)
- if (pid == "") {
- print "User line found before process line... ignoring!" \
- > "/dev/stderr"
- }
- else if (PortUser && tty != "socksys") { # Just ignore socksys
- user = $2
- printf "User %s on %s is running %s (pid %d).\n",
- user,tty,procname,pid > "/dev/stderr"
- if (pid !~ "^[0-9]+$")
- print "Strange pid... ignoring!" > "/dev/stderr"
- else if (user !~ "^[a-z][a-z0-9]+$")
- print "Strange user name... ignoring!" > "/dev/stderr"
- else if (tty !~ "^tty")
- print "Strange tty name... ignoring!" > "/dev/stderr"
- else {
- printf "%s %s\n",user,tty
- FoundUser = 1
- }
- PortUser = 0
- }
- pid = ""
- }
- END {
- exit !FoundUser
- }
- '
- }
-
- ln_name=${0##*/}
- Usage="Usage: $ln_name [-h] [-g<grace-period>] [-s<news-server>] [-p<port>]"
- ServerFiles="/usr/lib/news/server /usr/lib/news/rn/server"
- typeset -i Grace=-1
- Port=119
-
- while getopts :hcg:s:p: opt; do
- case $opt in
- h)
- echo \
- "$ln_name: Warn users of impending shutdown of the news server.
- $ln_name finds all users who are using the system's news server, reports on
- them, and optionally warns them that the news server is about to be shut down.
- Users are repeatedly warned at one minute intervals until the grace period has
- expired. Before each warning, the users still using the news server are
- reported on, so that it can easily be determined when all users have finished.
- A final warning of immediate shutdown is issued at 0 minutes; a grace period of
- 0 can be used to give only this warning. No action is taken when the grace
- period expires (the news server must be shut down manually).
- $ln_name determines who is using the news server by searching for processes
- that have connections to the NNTP port on the news server used by the local
- system. To determine the name of the news server used by the local system,
- $ln_name first checks the environment variable NNTPSERVER, and then checks in
- order the files /usr/lib/news/server and /usr/lib/news/rn/server. The first
- value found is used.
- $Usage
- Options:
- -g<grace-period>: Set the grace period to <grace-period> minutes, and warn
- users. Without this option, $ln_name will report once on who is using the
- news server, but will not issue any warnings.
- -h: Print this help.
- -p<port>: Check for connections to the news server on the given port, instead
- of the default port of $Port (NNTP service). <port> can be a regular
- expression in the style of egrep(C). If a port number of 0 is given,
- it is translated to \".*\", so users with processes connected to the news
- server on any port are warned. <port> must be a decimal integer.
- -s<news-server>: Set news server by name or IP number."
- exit 0
- ;;
- p)
- Port=$OPTARG
- ;;
- s) NNTPSERVER=$OPTARG;;
- g)
- if [[ "$OPTARG" != [1-9]*([0-9]) ]]; then
- print -u2 "Bad number of minutes: $OPTARG. Aborting."
- exit 1
- fi
- Grace=$OPTARG
- ;;
- +?)
- print -u2 "$ln_name: options should not be preceded by a '+'."
- exit 1
- ;;
- ?)
- print -u2 "$ln_name: $OPTARG: bad option. Use -h for help."
- exit 1
- ;;
- esac
- done
-
- # remove args that were options
- let OPTIND=OPTIND-1
- shift $OPTIND
-
- if [ $# -gt 0 ]; then
- print -u2 "$Usage\nUse -h for help."
- exit
- fi
-
- if [ -z "$NNTPSERVER" ]; then
- for file in $ServerFiles; do
- read NNTPSERVER 2>/dev/null < $file && break
- done
- fi
-
- if [ -z "$NNTPSERVER" ]; then
- print -u2 "Could not determine news server name."
- exit 1
- fi
-
- # Get the ip address of the news server so that sockinfo doesn't have to
- # look up the names of all ip connections
- if [[ "$NNTPSERVER" = +([0-9])+(.+([0-9])) ]]; then
- ip=$NNTPSERVER
- else
- dig +pfset=0x2020 "$NNTPSERVER" | while read name t ip; do
- # Ignore CNAMEs and such. dig will automatically look up the A
- # record for the name the CNAME points to.
- [ "$t" = A ] && break
- done
- if [[ "$ip" != +([0-9])+(.+([0-9])) ]]; then
- print -u2 "Could not get IP address for news server $NNTPSERVER."
- exit 1
- fi
- fi
-
- [ "$Port" = 0 ] && Port=".*"
-
- if [ Grace -eq -1 ]; then
- FindPortUsers "$ip" "$Port" > /dev/null ||
- print "Noone is using the news server."
- exit 0
- fi
-
- Prefix="Warning: the news server"
-
- while [ Grace -ge 0 ]; do
-
- case $Grace in
- 0) message="$Prefix is being shut down NOW!";;
- 1) message="$Prefix will be shut down in 1 minute.";;
- *) message="$Prefix will be shut down in $Grace minutes.";;
- esac
- print "Sending message: $message"
-
- FoundUser=false
- FindPortUsers "$ip" "$Port" | while read user tty; do
- # Discard error output from write to avoid warnings re
- # "you have your terminal set to mesg -n"
- echo "\r$message\r" | write $user $tty 2>/dev/null
- FoundUser=true
- done
-
- $FoundUser || print "No users are using the news server."
-
- let Grace-=1
- if [ Grace -gt 0 ]; then
- echo "****"
- sleep 60
- fi
- done
-