Changeset View
Standalone View
libexec/rc/rc.d/motd
#!/bin/sh | #!/bin/sh | ||||
# | # | ||||
# $FreeBSD$ | # $FreeBSD$ | ||||
# | # | ||||
# PROVIDE: motd | # PROVIDE: motd | ||||
# REQUIRE: mountcritremote | # REQUIRE: mountcritremote FILESYSTEMS | ||||
# BEFORE: LOGIN | # BEFORE: LOGIN | ||||
. /etc/rc.subr | . /etc/rc.subr | ||||
name="motd" | name="motd" | ||||
desc="Update /etc/motd" | desc="Update /var/run/motd" | ||||
rcvar="update_motd" | rcvar="update_motd" | ||||
start_cmd="motd_start" | start_cmd="motd_start" | ||||
stop_cmd=":" | stop_cmd=":" | ||||
COMPAT_MOTD="/etc/motd" | |||||
TARGET="/var/run/motd" | |||||
TEMPLATE="/etc/motd.template" | |||||
PERMS="644" | PERMS="644" | ||||
motd_start() | motd_start() | ||||
{ | { | ||||
# Update kernel info in /etc/motd | # Update kernel info in /var/run/motd | ||||
# Must be done *before* interactive logins are possible | # Must be done *before* interactive logins are possible | ||||
# to prevent possible race conditions. | # to prevent possible race conditions. | ||||
# | # | ||||
check_startmsgs && echo -n 'Updating motd:' | check_startmsgs && echo -n 'Updating motd:' | ||||
if [ ! -f /etc/motd ]; then | if [ ! -f "${TEMPLATE}" ]; then | ||||
install -c -o root -g wheel -m ${PERMS} /dev/null /etc/motd | # Create missing template from existing regular motd file, if | ||||
# one exists. | |||||
if [ -f "${COMPAT_MOTD}" ]; then | |||||
mv -f "${COMPAT_MOTD}" ${TEMPLATE} | |||||
delphij: Because this is a template, it do not really need the header anymore, because we prepend it… | |||||
cemAuthorUnsubmitted Done Inline ActionsThanks, will fix. cem: Thanks, will fix. | |||||
else | |||||
# Otherwise, create an empty template file. | |||||
install -c -o root -g wheel -m ${PERMS} /dev/null "${TEMPLATE}" | |||||
fi | fi | ||||
# Provide compatibility symlink: | |||||
delphijUnsubmitted Done Inline ActionsTEMPLATE permission should be set here (or after line 34). delphij: TEMPLATE permission should be set here (or after line 34). | |||||
cemAuthorUnsubmitted Done Inline ActionsWill fix, thanks. cem: Will fix, thanks. | |||||
if [ ! -h "${COMPAT_MOTD}" ]; then | |||||
[ -e "${COMPAT_MOTD}" ] && rm -f "${COMPAT_MOTD}" | |||||
delphijUnsubmitted Done Inline Actions41-42: ln -sF "${TARGET}" "${COMPAT_MOTD}" would take care of the pre-existing file. delphij: 41-42: ln -sF "${TARGET}" "${COMPAT_MOTD}" would take care of the pre-existing file. | |||||
cemAuthorUnsubmitted Done Inline Actions-F or -f? Do we have any reason to believe /etc/motd is a directory? And if it is, that it is empty? Yes, -f takes care of the expected preexisting file. I guess ln -sf unconditionally unlinks and recreates the symlink inode every time, but we are still conditional on [ ! -f $TEMPLATE ], so probably the IO isn't a concern. Will plan to change to -f unless you feel strongly about -F. cem: `-F` or `-f`? Do we have any reason to believe /etc/motd is a directory? And if it is, that… | |||||
delphijUnsubmitted Done Inline ActionsI don't have strong opinion here but it was intentional that -F is used (reasoning below): When -f is used, and /etc/motd was a directory, and there is nothing preventing ln from creating /etc/motd/motd, it would silently succeed with unwanted result; on the other hand with -F, ln would make its best effort (delete empty directory /etc/motd or pre-existing /etc/motd file and create the symlink), and fail when it can't do it, so overall it's slightly better than -f. delphij: I don't have strong opinion here but it was intentional that `-F` is used (reasoning below)… | |||||
cemAuthorUnsubmitted Done Inline ActionsOk, will change. cem: Ok, will change. | |||||
ln -s "${TARGET}" "${COMPAT_MOTD}" | |||||
fi | |||||
fi | |||||
if [ ! -f "${TEMPLATE}" ]; then | |||||
delphijUnsubmitted Done Inline Actions45-47: If after the above dance the template still do not exist as a file, we should bail out (return) or just ignore. delphij: 45-47: If after the above dance the template still do not exist as a file, we should bail out… | |||||
cemAuthorUnsubmitted Done Inline ActionsOk cem: Ok | |||||
install -c -o root -g wheel -m ${PERMS} /dev/null "${TARGET}" | |||||
fi | |||||
if [ ! -w /etc/motd ]; then | if [ ! -w "${TARGET}" ]; then | ||||
delphijUnsubmitted Done Inline Actions49-52 should be deleted. It's fine when ${TARGET} do not exist, we can generate its contents. delphij: 49-52 should be deleted. It's fine when ${TARGET} do not exist, we can generate its contents. | |||||
cemAuthorUnsubmitted Done Inline ActionsHm, what do you think about testing ${TARGET}/.. (i.e., "/var/run") for writability instead? if [ ! -w /var/run ] || [ -f "${TARGET}" -a ! -w "${TARGET}" ]; then ... OTOH, the test is inherited from the pretty ancient script; maybe we can assume we have a writable /var/run now. I am ok to delete it if you prefer. cem: Hm, what do you think about testing `${TARGET}/..` (i.e., "/var/run") for writability instead? | |||||
delphijUnsubmitted Done Inline ActionsYeah let's just remove this portion of code. The install below would emit more meaningful error messages, and this test is not really accurate anyway. delphij: Yeah let's just remove this portion of code. The `install` below would emit more meaningful… | |||||
cemAuthorUnsubmitted Done Inline Actionsworks for me! cem: works for me! | |||||
echo ' /etc/motd is not writable, update failed.' | echo " ${TARGET} is not writable, update failed." | ||||
return | return | ||||
fi | fi | ||||
T=`mktemp -t motd` | T=`mktemp -t motd` | ||||
uname -v | sed -e 's,^\([^#]*\) #\(.* [1-2][0-9][0-9][0-9]\).*/\([^\]*\) $,\1 (\3) #\2,' > ${T} | uname -v | sed -e 's,^\([^#]*\) #\(.* [1-2][0-9][0-9][0-9]\).*/\([^\]*\) $,\1 (\3) #\2,' > ${T} | ||||
awk '{if (NR == 1) {if ($1 == "FreeBSD") {next} else {print "\n"$0}} else {print}}' < /etc/motd >> ${T} | awk '{if (NR == 1) {if ($1 == "FreeBSD") {next} else {print "\n"$0}} else {print}}' < "${TEMPLATE}" >> ${T} | ||||
delphijUnsubmitted Done Inline ActionsNote that since we now store template separately, this edit should only happen once. In other words, replace this with cat "${TEMPLATE}" >> ${T} delphij: Note that since we now store template separately, this edit should only happen once. In other… | |||||
cemAuthorUnsubmitted Done Inline ActionsWill fix. cem: Will fix. | |||||
if ! cmp -s $T /etc/motd; then | install -C -o root -g wheel -m "${PERMS}" "$T" "${TARGET}" | ||||
mv -f $T /etc/.motd.tmp | rm -f "$T" | ||||
fsync /etc/.motd.tmp | |||||
mv -f /etc/.motd.tmp /etc/motd | |||||
chmod ${PERMS} /etc/motd | |||||
fsync /etc | |||||
else | |||||
rm -f $T | |||||
fi | |||||
check_startmsgs && echo '.' | check_startmsgs && echo '.' | ||||
} | } | ||||
load_rc_config $name | load_rc_config $name | ||||
run_rc_command "$1" | run_rc_command "$1" |
Because this is a template, it do not really need the header anymore, because we prepend it anyway. This should be replaced with:
sed '1{/^FreeBSD.*/{d;};};' "${COMPAT_MOTD}" > "${TEMPLATE}"