mirror of https://github.com/tLDP/LDP
218 lines
5.8 KiB
Bash
218 lines
5.8 KiB
Bash
#!/bin/bash
|
|
# fc4upd.sh
|
|
|
|
# Script author: Frank Wang.
|
|
# Slight stylistic modifications by ABS Guide author.
|
|
# Used in ABS Guide with permission.
|
|
|
|
|
|
# Download Fedora Core 4 update from mirror site using rsync.
|
|
# Should also work for newer Fedora Cores -- 5, 6, . . .
|
|
# Only download latest package if multiple versions exist,
|
|
#+ to save space.
|
|
|
|
URL=rsync://distro.ibiblio.org/fedora-linux-core/updates/
|
|
# URL=rsync://ftp.kddilabs.jp/fedora/core/updates/
|
|
# URL=rsync://rsync.planetmirror.com/fedora-linux-core/updates/
|
|
|
|
DEST=${1:-/var/www/html/fedora/updates/}
|
|
LOG=/tmp/repo-update-$(/bin/date +%Y-%m-%d).txt
|
|
PID_FILE=/var/run/${0##*/}.pid
|
|
|
|
E_RETURN=85 # Something unexpected happened.
|
|
|
|
|
|
# General rsync options
|
|
# -r: recursive download
|
|
# -t: reserve time
|
|
# -v: verbose
|
|
|
|
OPTS="-rtv --delete-excluded --delete-after --partial"
|
|
|
|
# rsync include pattern
|
|
# Leading slash causes absolute path name match.
|
|
INCLUDE=(
|
|
"/4/i386/kde-i18n-Chinese*"
|
|
# ^ ^
|
|
# Quoting is necessary to prevent globbing.
|
|
)
|
|
|
|
|
|
# rsync exclude pattern
|
|
# Temporarily comment out unwanted pkgs using "#" . . .
|
|
EXCLUDE=(
|
|
/1
|
|
/2
|
|
/3
|
|
/testing
|
|
/4/SRPMS
|
|
/4/ppc
|
|
/4/x86_64
|
|
/4/i386/debug
|
|
"/4/i386/kde-i18n-*"
|
|
"/4/i386/openoffice.org-langpack-*"
|
|
"/4/i386/*i586.rpm"
|
|
"/4/i386/GFS-*"
|
|
"/4/i386/cman-*"
|
|
"/4/i386/dlm-*"
|
|
"/4/i386/gnbd-*"
|
|
"/4/i386/kernel-smp*"
|
|
# "/4/i386/kernel-xen*"
|
|
# "/4/i386/xen-*"
|
|
)
|
|
|
|
|
|
init () {
|
|
# Let pipe command return possible rsync error, e.g., stalled network.
|
|
set -o pipefail # Newly introduced in Bash, version 3.
|
|
|
|
TMP=${TMPDIR:-/tmp}/${0##*/}.$$ # Store refined download list.
|
|
trap "{
|
|
rm -f $TMP 2>/dev/null
|
|
}" EXIT # Clear temporary file on exit.
|
|
}
|
|
|
|
|
|
check_pid () {
|
|
# Check if process exists.
|
|
if [ -s "$PID_FILE" ]; then
|
|
echo "PID file exists. Checking ..."
|
|
PID=$(/bin/egrep -o "^[[:digit:]]+" $PID_FILE)
|
|
if /bin/ps --pid $PID &>/dev/null; then
|
|
echo "Process $PID found. ${0##*/} seems to be running!"
|
|
/usr/bin/logger -t ${0##*/} \
|
|
"Process $PID found. ${0##*/} seems to be running!"
|
|
exit $E_RETURN
|
|
fi
|
|
echo "Process $PID not found. Start new process . . ."
|
|
fi
|
|
}
|
|
|
|
|
|
# Set overall file update range starting from root or $URL,
|
|
#+ according to above patterns.
|
|
set_range () {
|
|
include=
|
|
exclude=
|
|
for p in "${INCLUDE[@]}"; do
|
|
include="$include --include \"$p\""
|
|
done
|
|
|
|
for p in "${EXCLUDE[@]}"; do
|
|
exclude="$exclude --exclude \"$p\""
|
|
done
|
|
}
|
|
|
|
|
|
# Retrieve and refine rsync update list.
|
|
get_list () {
|
|
echo $$ > $PID_FILE || {
|
|
echo "Can't write to pid file $PID_FILE"
|
|
exit $E_RETURN
|
|
}
|
|
|
|
echo -n "Retrieving and refining update list . . ."
|
|
|
|
# Retrieve list -- 'eval' is needed to run rsync as a single command.
|
|
# $3 and $4 is the date and time of file creation.
|
|
# $5 is the full package name.
|
|
previous=
|
|
pre_file=
|
|
pre_date=0
|
|
eval /bin/nice /usr/bin/rsync \
|
|
-r $include $exclude $URL | \
|
|
egrep '^dr.x|^-r' | \
|
|
awk '{print $3, $4, $5}' | \
|
|
sort -k3 | \
|
|
{ while read line; do
|
|
# Get seconds since epoch, to filter out obsolete pkgs.
|
|
cur_date=$(date -d "$(echo $line | awk '{print $1, $2}')" +%s)
|
|
# echo $cur_date
|
|
|
|
# Get file name.
|
|
cur_file=$(echo $line | awk '{print $3}')
|
|
# echo $cur_file
|
|
|
|
# Get rpm pkg name from file name, if possible.
|
|
if [[ $cur_file == *rpm ]]; then
|
|
pkg_name=$(echo $cur_file | sed -r -e \
|
|
's/(^([^_-]+[_-])+)[[:digit:]]+\..*[_-].*$/\1/')
|
|
else
|
|
pkg_name=
|
|
fi
|
|
# echo $pkg_name
|
|
|
|
if [ -z "$pkg_name" ]; then # If not a rpm file,
|
|
echo $cur_file >> $TMP #+ then append to download list.
|
|
elif [ "$pkg_name" != "$previous" ]; then # A new pkg found.
|
|
echo $pre_file >> $TMP # Output latest file.
|
|
previous=$pkg_name # Save current.
|
|
pre_date=$cur_date
|
|
pre_file=$cur_file
|
|
elif [ "$cur_date" -gt "$pre_date" ]; then
|
|
# If same pkg, but newer,
|
|
pre_date=$cur_date #+ then update latest pointer.
|
|
pre_file=$cur_file
|
|
fi
|
|
done
|
|
echo $pre_file >> $TMP # TMP contains ALL
|
|
#+ of refined list now.
|
|
# echo "subshell=$BASH_SUBSHELL"
|
|
|
|
} # Bracket required here to let final "echo $pre_file >> $TMP"
|
|
# Remained in the same subshell ( 1 ) with the entire loop.
|
|
|
|
RET=$? # Get return code of the pipe command.
|
|
|
|
[ "$RET" -ne 0 ] && {
|
|
echo "List retrieving failed with code $RET"
|
|
exit $E_RETURN
|
|
}
|
|
|
|
echo "done"; echo
|
|
}
|
|
|
|
# Real rsync download part.
|
|
get_file () {
|
|
|
|
echo "Downloading..."
|
|
/bin/nice /usr/bin/rsync \
|
|
$OPTS \
|
|
--filter "merge,+/ $TMP" \
|
|
--exclude '*' \
|
|
$URL $DEST \
|
|
| /usr/bin/tee $LOG
|
|
|
|
RET=$?
|
|
|
|
# --filter merge,+/ is crucial for the intention.
|
|
# + modifier means include and / means absolute path.
|
|
# Then sorted list in $TMP will contain ascending dir name and
|
|
#+ prevent the following --exclude '*' from "shortcutting the circuit."
|
|
|
|
echo "Done"
|
|
|
|
rm -f $PID_FILE 2>/dev/null
|
|
|
|
return $RET
|
|
}
|
|
|
|
# -------
|
|
# Main
|
|
init
|
|
check_pid
|
|
set_range
|
|
get_list
|
|
get_file
|
|
RET=$?
|
|
# -------
|
|
|
|
if [ "$RET" -eq 0 ]; then
|
|
/usr/bin/logger -t ${0##*/} "Fedora update mirrored successfully."
|
|
else
|
|
/usr/bin/logger -t ${0##*/} \
|
|
"Fedora update mirrored with failure code: $RET"
|
|
fi
|
|
|
|
exit $RET
|