home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Unix System Administration Handbook 1997 October
/
usah_oct97.iso
/
news
/
cnews.tar
/
expire
/
upact
< prev
next >
Wrap
Text File
|
1995-01-02
|
5KB
|
199 lines
#! /bin/sh
# Update 3rd field (minimum art. #) of a 4-field active file.
# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
. ${NEWSCONFIG-/etc/news/bin/config}
PATH=$NEWSCTL/bin:$NEWSBIN/maint:$NEWSBIN:$NEWSPATH ; export PATH
umask $NEWSUMASK
maxlen=200 # max length for shell cmd; 200 is pretty safe
replace=yes
what=normal # update min, make sure max has a 0 on front
lserr=/dev/null
interpose=
for dummy
do
case "$1" in
-b) what=both ;; # update both max and min
-p) what=plain ;; # don't do ANYTHING to max
-s) maxlen=0 ;; # ls is funny, do slow way
'-#') replace=no ; lserr=$NEWSCTL/active.errs ;; # debugging
-I) interpose="$2" ; shift ;; # interpose pgm for testing
--) shift ; break ;;
-*) echo "$0: unknown option \`$1'" >&2 ; exit 2 ;;
*) break ;;
esac
shift
done
cd $NEWSCTL
# lock news system momentarily and grab a copy of the active file
lock LOCK $$ || exit 1
status=1
trap 'unlock LOCK ; trap 0 ; exit $status' 0 1 2 15
sort active >active.upact || exit # sort brings related dirs together
trap 0 1 2 15
unlock LOCK
# check out the active file
checkactive -n -q active.upact >active.eek
if test -s active.eek
then
echo "$0: problems in active file -- aborting" >&2
cat active.eek >&2
rm -f active.eek active.upact
exit 1
fi
# Bernd Felsche of MetaPro Systems came up with this general approach,
# which minimizes the number of processes spawned, although this code is
# rather different from his. Thanks, Bernd!
# first, find minima, efficiently
# translate names to dirs, turn dirs into "ls -f" commands, run them, pick
# the desired data out of the output, turn dirs back into names, sort again,
# and merge in old-max values
tr '.' '/' <active.upact |
awk 'BEGIN {
maxlen = '"$maxlen"'
dirs = ""
ndirs = 0
print "cd '"$NEWSARTS"'"
}
length($1) + length(dirs) > maxlen && ndirs > 0 {
if (ndirs == 1)
print "echo " substr(dirs, 2) ":"
print "ls -f" dirs
dirs = ""
ndirs = 0
}
# the /. on the end eliminates problems with names including ":"
{ dirs = dirs " " $1 "/." ; ndirs++ }
END {
if (ndirs == 1)
print "echo " substr(dirs, 2) ":"
print "ls -f" dirs
print "echo /.:" # simplifies later logic
}' | sh 2>$lserr |
awk -F' ' 'BEGIN {
OFMT = "%.12g"
big = 99999999999
lowest = big
small = 0
highest = small
dir = ""
}
$0 ~ /^[0-9]+$/ {
# some old awks do not think $0 is numeric, so use $1
if ($1 < lowest)
lowest = $1
if ($1 > highest)
highest = $1
next
}
$0 ~ /\/\.:$/ {
if (dir != "") {
if (highest != small)
print dir, highest, lowest
else
print dir, "-", "-"
}
dir = substr($0, 1, length($0)-3) # trim off /.:
lowest = big
highest = small
}' | tr '/' '.' | sort |
join -o 1.1 2.2 1.2 1.3 - active.upact >active.hilow
# active.hilow now is newsgroup, old max, high file, low file
# testing hook
if test " $interpose" != " "
then
$interpose
fi
# lock news system again
lock LOCK $$ || exit 1
status=1
trap 'unlock LOCK ; trap 0 ; exit $status' 0 1 2 15
# decide on any extra processing needed
extra=
case "$what" in
both) extra='$7 != "-" && $7 > $3 {
# update max from high file
s = "000000000000000" $7
len = length($3)
if (length($7) > len)
len = length($7) + 1
s = substr(s, length(s)-len+1)
if (s !~ /^0/)
s = "0" s
$3 = s
}'
;;
normal) extra='$3 !~ /^0/ { $3 = "0" $3 }' ;;
esac
# build new active file, cautiously
# The result of the join is line number (for the sort -n that restores the
# old order of the active file), newsgroup, active max, active min, active
# flags, old max, high file, low file.
awk '{ print $1, $2, $3, $4, NR }' active | sort |
join -a1 -e - -o 1.5 1.1 1.2 1.3 1.4 2.2 2.3 2.4 - active.hilow |
sort -n |
awk 'BEGIN { OFMT = "%.12g" }
$1 == "-" { next } # no longer in active file
'"$extra"'
{
# find a new value for min
if ($8 != "-" && $8 != "") # there was a low file
s = $8 # use it
else if ($6+0 != $3+0) # oldmax != newmax, race cond!
s = $4 # use old value to be safe
else # no files and no race
s = $3 + 1 # use max+1
if (length(s) < 5) {
s = "00000" s
s = substr(s, length(s)-5+1)
}
print $2, ($3 ""), s, $5 # the "" forces string version
}' >active.tmp
# check that everything looks okay
checkactive -q active.tmp >active.eek
if test -s active.eek
then
echo "$0: errors in active.tmp -- aborting" >&2
cat active.eek >&2
exit # with status=1
fi
if test `wc -l <active.tmp` -lt `wc -l <active`
then
echo "$0: active.tmp is bad (short) -- aborting" >&2
exit # with status=1
fi
rm -f active.eek active.hilow active.upact # clean up temporaries
# if we weren't asked to install it, don't
case "$replace" in
no) status=0 ; exit ;;
esac
# replace active, carefully
rm -f active.old
mv active active.old && mv active.tmp active
if test -f active.tmp
then
echo "$0: replacing active didn't work" >&2
exit # with status=1
fi
status=0 # trap 0 does the actual exit