[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [leafnode-list] 1.9.11: article numbers (for some groups) have been





On Sun, 9 Apr 2000, Cornelius Krasel wrote:

>Alan Mackenzie wrote:

>> After a hacking run lasting till about 3 a.m. last night and most of
>> today, I have now cleaned everything up. In the process I learnt a
>> _lot_ about Unix file systems, in particular how hard links interact
>> with cp, mv and ln.  Such information doesn't seem to be available on
>> Linux's online help :-(.

>> Would it be appropriate/helpful for me to post my repair script onto
>> this mailing list, or upload it somewhere? It is fully commented and
>> just over 6k long.

>Sure, just go ahead.

>--Cornelius.

OK, here goes! Please forgive any clumsiness it contains. It's the first
substantial script I've written. Suggestions for its improvement would be
welcome.

*******************************************************************************

#!/usr/bin/bash
#
# NAME:
# f i x 1 . 9 . 11
#
# This script corrects the effects of a bug in leafnode-1.9.11, namely:
# The "high water mark" for several newsgroups was changed from its proper 
# value to 2. As a result, incoming articles started getting numbered from 2
# upwards.
#
# This script will restore these articles to their "correct" article numbers,
# and leave the newsgroup in a consistent state.
#
# INVOCATION FROM THE COMMAND LINE: THIS SCRIPT MUST BE INVOKED AS USER news !!!
# The script is called from the command line for each group individually.
# It does not use stdin or stdout, other than for prompting the user and
# receiving confirmation from her/him. It takes a single parameter, namely the
# newsgroup to fix, thus:
# fix1.9.11 news.servers.leafnode
#
# CAVEATS:
# (i) This script will probably get confused if the new article numbers have
#     reached and overtaken the previous low-water-mark.
# (ii) It depends on the fact that cp preserves hard links (see below).
# (iii) It hasn't been tested in a newsgroup where cross-posting exists inside
#     the spool. It is expected to work in this case, though.
#
################################################################################
#
# WHAT GETS DONE IN DETAIL:
#
# For EACH AFFECTED ARTICLE, the following is done:
#     (i) Its timestamps are saved using touch;
#     (ii) The "correct" article number (say, 15398) is determined from the
#         current incorrect number (say, 13);
#     (iii) The Xref: header is edited from
#         "Xref: example.com news.servers.leafnode:13" to
#         "Xref: example.com news.servers.leafnode:15398"
#         and the output of this editing is written to the new filename, 15398.
#     (iv) (a) The new file, 15398, is copied to the old file, 13, with cp.
#          (b) the original new file, 15398, is removed.
#          (c) the old file, 13, is renamed to the new file, 15398, with mv.
#         The rationale here is that (a) changes 13's inode to point to a new
#         set of data blocks, but leaves all links into this inode intact. Thus
#         after (a), the Message-ID hard link and any crosspost hard links
#         are linked to (a copy of) the new file;
#     (v) The timestamps are restored using touch.
#
# THE LIST OF ARTICLES TO BE CHANGED IS DETERMINED THUS:
# All the articles in the current group are listed in order of age, newest
# first. The list is stepped through until the numeric value of the filename
# increases rather than decreases, e.g.
#     16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 15386 15385 15384 .....
#                                         ^
# The files up until this cut-point are then processed as already described.
#
# FINALLY, the high-water mark in the pertinent line of "groupinfo" is
# corrected, and .overview is deleted, so that the next time it is needed some
# other part of leafnode will regenerate it correctly.
#
################################################################################
#
# Written by Alan Mackenzie <acm@xxxxxx>, 8th April 2000.
# This script may be used freely for any purpose and modified in any fashion.
# The author takes no responsibility for any misfortune ensuing from its use.
# OHNE GEWÄHR !!!!
#
################################################################################

# CHECK THAT WE ARE news
if [ $(whoami) != news ]; then
    echo "Error: Only user news may run this command."
    exit 1
fi

# CHECK THAT THE CULPRIT EXISTS.
if [ ! -f /var/spool/news/leaf.node/groupinfo ]; then
    echo "Error: /var/spool/news/leaf.node/groupinfo doesn't exist."
    exit 1
fi

# CHECK THE COMMAND LINE AND EXTRACT THE NEWSGROUP.
if [ $# != 1 ]; then
    echo "Usage: fix1.9.11 <newsgroup>"
    exit 1
fi
newspath="/var/spool/news/"$(echo $1 | sed 's%\.%/%g')
if [ ! -d $newspath ]; then
    echo "Error: Directory $newspath doesn't exist."
    exit 1
fi

# MAKE THE NEWSGROUP'S DIRECTORY THE CURRENT DIRECTORY.
cd $newspath

# GET A LIST OF ALL ARTICLES IN THE GROUP, SORTED WITH NEWEST FIRST.
articles=$(ls -t $newspath)

# THE ARTICLES WHOSE NUMBERS NEED CHANGING ARE THE HEAD OF THIS LIST.
# ACCUMULATE THEM, OLDEST FIRST, INTO badarts. WE'RE DONE WHEN THE ARTICLE
# NUMBER JUMPS.
last_art=2147483647 # "infinity" :-)
badarts=""
high_wm=0
for art in $articles; do
    if [ $((art)) -gt $((last_art)) ]; then
        high_wm=$art # highest "genuine" article number at the moment.
        break 
    fi
    last_art=$art
    badarts="$art $badarts"
done

# WAS THE NEWSGROUP ALREADY IN ORDER?
if [ $high_wm = 0 ]; then
    echo "The newsgroup seems to be OK as it is. Exiting."
    exit 0
fi

# ASK THE USER FOR A SANITY CHECK
echo -n "The following articles: "; echo $badarts
echo "in newsgroup $1 will be renumbered, starting at $((high_wm + 1)). "
echo -n "Continue (Y/y) or abort (N/n)? "
read carry_on
if [ $carry_on != Y ] && [ $carry_on != y ]; then
    exit 1
fi

################################################################################
# PROCESS EACH "BAD" ARTICLE
################################################################################
for art in $badarts; do
# NOTE THE MODIFICATION TIME IN A SPECIALLY CREATED "FILE".
    touch -r $art .touchfile

# DETERMINE THE NEW FILE NAME FOR $art
    high_wm=$((high_wm + 1))   # increment article number
    while [ -e $high_wm ]; do  # should never happen!
        high_wm=$((high_wm + 1))
    done

# CORRECT THE Xref: HEADER, OUTPUTTING TO THE NEW FILENAME, RETAINING ALL THE
# HARD LINKS (Message-ID AND CROSS POSTS).
    sed "/^Xref: .*$newsgroup:$art/s/$newsgroup:$art/$newsgroup:$high_wm/" \
     < $art > $high_wm
    cp $high_wm $art   # See header comments, about preserving hard links.
    rm $high_wm
    mv $art $high_wm

# RESET THE MODIFICATION TIME
    touch -r .touchfile $high_wm
done
rm .touchfile

# TO WORK IN A SED REGULAR EXPRESSION, WE NEED THE NEWSGROUP NAME'S DOTS QUOTED,
# e.g. "news\.servers\.leafnode".
sed_ng_search=$(echo $1 | sed "s/\./\\\./g") 

# CORRECT THE HIGH WATER MARK IN THE groupinfo FILE, SO THAT WE DON'T NEED TO
# KEEP RUNNING THIS SHELL. :-)
sed "s/^$sed_ng_search [0-9]*/$1 $high_wm/" \
    < /var/spool/news/leaf.node/groupinfo \
    > /var/spool/news/leaf.node/groupinfo.fix
rm /var/spool/news/leaf.node/groupinfo
mv /var/spool/news/leaf.node/groupinfo.fix /var/spool/news/leaf.node/groupinfo

# GET RID OF THE .overview FILE, TO ALLOW IT TO BE CORRECTLY REGENERATED LATER.
rm .overview

*******************************************************************************

-- 
Alan Mackenzie (Munich, Germany)
acm@xxxxxx



-- 
leafnode-list@xxxxxxxxxxxxxxxxxxxxxxxxxxxx -- mailing list for leafnode
To unsubscribe, send mail with "unsubscribe" in the subject to the list