158 lines
5.3 KiB
Text
158 lines
5.3 KiB
Text
|
#!/bin/sh
|
||
|
#
|
||
|
# 50-motd-news - print the live news from the Ubuntu wire
|
||
|
# Copyright (C) 2016-2020 Canonical Ltd.
|
||
|
# Copyright (C) 2016-2017 Dustin Kirkland
|
||
|
#
|
||
|
# Authors: Dustin Kirkland <kirkland@canonical.com>
|
||
|
# Steve Langasek <steve.langasek@canonical.com>
|
||
|
#
|
||
|
# This program is free software; you can redistribute it and/or modify
|
||
|
# it under the terms of the GNU General Public License as published by
|
||
|
# the Free Software Foundation; either version 2 of the License, or
|
||
|
# (at your option) any later version.
|
||
|
#
|
||
|
# This program is distributed in the hope that it will be useful,
|
||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
# GNU General Public License for more details.
|
||
|
#
|
||
|
# You should have received a copy of the GNU General Public License along
|
||
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
|
||
|
##############################################################################
|
||
|
# This program could be rewritten in C or Golang for faster performance.
|
||
|
# Or it could be rewritten in Python or another higher level language
|
||
|
# for more modularity.
|
||
|
# However, I've insisted on shell here for transparency!
|
||
|
# - Dustin
|
||
|
##############################################################################
|
||
|
|
||
|
# Source the local configuration
|
||
|
[ -r /etc/default/motd-news ] && . /etc/default/motd-news
|
||
|
|
||
|
# Exit immediately, unless we're enabled
|
||
|
# This makes this script very easy to disable in /etc/default/motd-news configuration
|
||
|
[ "$ENABLED" = "1" ] || exit 0
|
||
|
|
||
|
# Ensure sane defaults
|
||
|
[ -n "$URLS" ] || URLS="https://motd.ubuntu.com"
|
||
|
[ -n "$WAIT" ] || WAIT=5
|
||
|
[ -n "$CACHE" ] || CACHE="/var/cache/motd-news"
|
||
|
[ "$1" = "--force" ] && FORCED=1
|
||
|
|
||
|
# Ensure we print safely, maximum of the first 10 lines,
|
||
|
# maximum of the first 80 chars per line, no control chars
|
||
|
safe_print() {
|
||
|
cat "$1" | head -n 10 | tr -d '\000-\011\013\014\016-\037' | cut -c -80
|
||
|
}
|
||
|
|
||
|
|
||
|
# If we're not forcing an update, and we have a cached motd-news file,
|
||
|
# then just print it and exit as quickly as possible, for login performance.
|
||
|
# Note that systemd should keep this cache file up to date, asynchronously
|
||
|
if [ "$FORCED" != "1" ]; then
|
||
|
if [ -r $CACHE ]; then
|
||
|
echo " * News:"
|
||
|
safe_print $CACHE
|
||
|
elif [ "$(id -u)" -eq 0 ]; then
|
||
|
printf " * News:\n * No News\n"
|
||
|
: > $CACHE
|
||
|
fi
|
||
|
exit 0
|
||
|
fi
|
||
|
|
||
|
# If we've made it here, we've been given the --force argument,
|
||
|
# probably from the systemd motd-news.service. Let's update...
|
||
|
|
||
|
# Abort early if wget is missing
|
||
|
[ -x /usr/bin/wget ] || exit 0
|
||
|
|
||
|
# Generate our temp files, clean up when done
|
||
|
NEWS=$(mktemp) || exit 1
|
||
|
ERR=$(mktemp) || exit 1
|
||
|
CLOUD=$(mktemp) || exit 1
|
||
|
trap "rm -f $NEWS $ERR $CLOUD" HUP INT QUIT ILL TRAP KILL BUS TERM
|
||
|
|
||
|
# Construct a user agent, similar to Firefox/Chrome/Safari/IE to
|
||
|
# ensure a proper, tailored, accurate message of the day
|
||
|
|
||
|
# wget browser version, for debug purposes
|
||
|
wget_ver="$(dpkg -l wget | awk '$1 == "ii" { print($3); exit(0); }')"
|
||
|
|
||
|
# Distribution version, for messages releated to this Ubuntu release
|
||
|
. /etc/lsb-release
|
||
|
lsb=$(echo "$DISTRIB_DESCRIPTION" | sed -e "s/ /\//g")
|
||
|
codename="$DISTRIB_CODENAME"
|
||
|
|
||
|
# Kernel version and CPU type, for messages related to a particular revision or hardware
|
||
|
platform="$(uname -o)/$(uname -r)/$(uname -m)"
|
||
|
arch="$(uname -m)"
|
||
|
cpu="$(grep -m1 "^model name" /proc/cpuinfo | sed -e "s/.*: //" -e "s:\s\+:/:g")"
|
||
|
cloud_id="unknown"
|
||
|
if [ -x /usr/bin/cloud-id ]; then
|
||
|
/usr/bin/cloud-id > "$CLOUD" 2>/dev/null
|
||
|
if [ "$?" -eq "0" ]; then
|
||
|
# sanitize it a bit, just in case
|
||
|
cloud_id=$(cut -c -40 "${CLOUD}" | tr -c -d '[:alnum:]')
|
||
|
if [ -z "${cloud_id}" ]; then
|
||
|
cloud_id="unknown"
|
||
|
fi
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
# Piece together the user agent
|
||
|
USER_AGENT="wget/$wget_ver $lsb $platform $cpu cloud_id/$cloud_id"
|
||
|
|
||
|
# Loop over any configured URLs
|
||
|
for u in $URLS; do
|
||
|
# Ensure https:// protocol, for security reasons
|
||
|
case $u in
|
||
|
https://*)
|
||
|
true
|
||
|
;;
|
||
|
https://motd.ubuntu.com)
|
||
|
u="$u/$codename/$arch"
|
||
|
;;
|
||
|
call*)
|
||
|
cmd=$(echo $u|cut -c 6-)
|
||
|
response=$($cmd)
|
||
|
title=$(echo "$response"|grep -E " \* " --color=never)
|
||
|
url=$(echo "$response"|tail -1)
|
||
|
echo "$title\n\n$url" > "$CACHE"
|
||
|
continue
|
||
|
;;
|
||
|
*)
|
||
|
continue
|
||
|
;;
|
||
|
esac
|
||
|
# If we're forced, set the wait to much higher (1 minute)
|
||
|
[ "$FORCED" = "1" ] && WAIT=60
|
||
|
# Fetch and print the news motd
|
||
|
result=0
|
||
|
not_found_is_ok=0
|
||
|
wget --timeout "$WAIT" -U "$USER_AGENT" -O- --content-on-error "$u" >"$NEWS" 2>"$ERR" || result=$?
|
||
|
# from wget's manpage: 8 Server issued an error response.
|
||
|
if [ $result -eq 8 ]; then
|
||
|
if grep -q "ERROR 404" "$ERR"; then
|
||
|
# The server's 404 document is the generic, non cloud-specific, motd-news
|
||
|
# content present in the index.txt file
|
||
|
not_found_is_ok=1
|
||
|
fi
|
||
|
fi
|
||
|
if [ $result -eq 0 ] || [ $not_found_is_ok -eq 1 ]; then
|
||
|
echo
|
||
|
# At most, 10 lines of text, remove control characters, print at most 80 characters per line
|
||
|
echo " * News:"
|
||
|
safe_print "$NEWS"
|
||
|
# Try to update the cache
|
||
|
safe_print "$NEWS" 2>/dev/null >$CACHE || true
|
||
|
else
|
||
|
printf " * News:\n * No News"
|
||
|
echo " * No News" > "$CACHE"
|
||
|
fi
|
||
|
done
|
||
|
rm -f "$NEWS" "$ERR" "$CLOUD"
|
||
|
exit 0
|