#!/bin/sh

# Get last update time from Slackware ChangeLog, print the date to stdout
# in the form used by the ##slackware /topic (YYYY-MM-DD). For now anyway,
# we assume everything in the ChangeLog is a security fix.

# Also, the output is compared to $DATEFILE if it exists. Exit
# status is:

# 0 if the date retrieved is the same as in the file,
# 1 if the date changed (or the file didn't exist),
# 2 if there was an error of some kind.

# The file is always updated if status is 0 or 1. On status 2,
# it depends on what the error actually was.

# This script can be tested from the command line, but in production it
# was intended to be executed from an irssi script, so it's got no need
# for options or verbose output. Actually, the irssi script no longer
# uses this, it's kept around purely for reference, or in case it might
# be useful for some other project.

# For the morbidly curious: I intend this to be executed by bash,
# but it also works with Slackware 14.2's ash and ksh, and dash from
# SBo. But *not* zsh: $RANGE gets expanded to a quoted string,
# so curl gets executed as:
#   curl --silent '--range 0-28' http://...
# and quite properly complains:
#   curl: option --range 0-28: is unknown
# I'm not a zsh guy, but I did some research... either have to use the
# syntax $=RANGE (zsh-specific) or check for ZSH_* in the environment
# and do 'setopt shwordsplit'. Pretty sure this means I shall never
# again care whether one of my shell scripts fails on zsh. Pretty sure
# this means zsh isn't POSIX compliant, and isn't trying to be.

### Config stuff.

# Where the date gets stored.
DATEFILE="$HOME/.slack_last_update"

# Use the primary site, not a mirror.
URL="http://ftp.slackware.com/pub/slackware/slackware64-14.2/ChangeLog.txt"

# We only really care about the first line of the file. So long as Pat
# follows his usual practice, the first line (including the newline)
# is 29 characters long (also 29 bytes, since he uses ASCII). So that's
# all we'll download from the server. We *could* just do a HEAD request
# and take the last-modified header, but let's be consistent with the
# actual content.
RANGE="--range 0-28"

# Other curl options.
CURLOPTS="--silent --max-time 60"

# For paranoia's sake:
PATH=/bin:/usr/bin
export PATH

# OK, go! (I bet you didn't know 'date' can read from stdin, I didn't)
DATE="$( curl $CURLOPTS $RANGE "$URL" | date -u -f- '+%F' )"

# Sanity check the date, in case the download failed or Pat got bribed
# to break this script (I wouldn't blame him, money's money).
case "$DATE" in
	[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) : # OK
	   ;;
	*) echo "$0: got '$DATE' instead of a date, bailing" 1>&2
	   exit 2
	   ;;
esac

# Prepare to compare...
echo "$DATE" > "$DATEFILE.old" || exit 2
[ -e "$DATEFILE" ] || touch "$DATEFILE"
[ -e "$DATEFILE" ] || exit 2

# Compare. cmp's exit status is exactly what we want to return, save it.
cmp -s "$DATEFILE" "$DATEFILE.old"
RESULT="$?"

# Thought about doing this only if cmp says it's different. Always updating
# means the timestamp of the file shows us when the last check was, worth
# the tiny bit of extra I/O.
mv "$DATEFILE.old" "$DATEFILE" || exit 2

echo "$DATE"

# That's all, folx!
exit "$RESULT"
