#!/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 # Steve Langasek # # 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" 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 safe_print $CACHE elif [ "$(id -u)" -eq 0 ]; then : > $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" ;; *) 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 safe_print "$NEWS" # Try to update the cache safe_print "$NEWS" 2>/dev/null >$CACHE || true else : > "$CACHE" fi done rm -f "$NEWS" "$ERR" "$CLOUD" exit 0