3cd12006bb
Signed-off-by: Dean Troyer <dtroyer@gmail.com>
287 lines
7.0 KiB
Bash
287 lines
7.0 KiB
Bash
#!/bin/bash
|
|
|
|
#
|
|
# Copyright (c) 2016 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
|
|
. /usr/bin/tsconfig
|
|
|
|
OPT_BANNER_BACKUP="/opt/banner.bk"
|
|
PLATFORM_BANNER_DIR="${CONFIG_PATH}/banner"
|
|
|
|
#
|
|
# set BANNER_VERBOSE to enable info logs
|
|
#
|
|
export BANNER_VERBOSE
|
|
|
|
info_log ()
|
|
{
|
|
if [ -n "${BANNER_VERBOSE}" ]; then
|
|
echo "INFO: customize-banner: $@" >&2
|
|
fi
|
|
}
|
|
|
|
warn_log ()
|
|
{
|
|
echo "WARNING: customize-banner: $@" >&2
|
|
}
|
|
|
|
error_log ()
|
|
{
|
|
echo "ERROR: customize-banner: $@" >&2
|
|
}
|
|
|
|
# some checks to see if the user does something odd
|
|
# Return: 1 if the file is not sane
|
|
# 0 if the file is normal looking
|
|
#
|
|
# Symbolic links are followed to their ultimate destination before
|
|
# further checks are made
|
|
file_is_sane ()
|
|
{
|
|
local fname=$1
|
|
|
|
if [ -z "${fname}" ]; then
|
|
error_log "no file specified"
|
|
return 1
|
|
fi
|
|
|
|
# resolve symlinks
|
|
if [ -h "${fname}" ]; then
|
|
local resolved=$(readlink -f "${fname}")
|
|
if [ -z "${resolved}" ]; then
|
|
error_log "file does not exist; did not resolve symbolic link"
|
|
return 1
|
|
fi
|
|
|
|
file_is_sane_no_link "${resolved}"
|
|
return $?
|
|
fi
|
|
|
|
file_is_sane_no_link "${fname}"
|
|
return $?
|
|
}
|
|
|
|
file_is_sane_no_link ()
|
|
{
|
|
local fname=$1
|
|
# a sanity check, the banner file has to be a regular file
|
|
# symbolic links are handled in file_is_sane()
|
|
if [ ! -f "${fname}" -o -h "${fname}" ]; then
|
|
error_log "file is not a regular file: ${fname}"
|
|
return 1
|
|
fi
|
|
|
|
# root usually has access to write readonly files...
|
|
if [ ! -w "${fname}" ]; then
|
|
error_log "file is readonly: ${fname}"
|
|
return 1
|
|
fi
|
|
|
|
# Warn only
|
|
if [ -x "${fname}" ]; then
|
|
warn_log "file is executable: ${fname}"
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Prints list of files to stdout
|
|
#
|
|
get_banner_files ()
|
|
{
|
|
local flist=" \
|
|
/etc/issue \
|
|
/etc/issue.net \
|
|
/etc/motd.head \
|
|
/etc/motd.tail \
|
|
"
|
|
|
|
echo ${flist}
|
|
}
|
|
|
|
#
|
|
# This is to be executed either by config_controller or by the user
|
|
# through apply_banner_customization
|
|
#
|
|
# For each customizable file, if a customization is present do a bit of
|
|
# sanity and copy the file to the platform config for banner
|
|
# customization.
|
|
#
|
|
# Return 0 on success
|
|
# Return 1 for error conditions, if any customization file failed sanity
|
|
#
|
|
customize_banner ()
|
|
{
|
|
if [ ! -d "${CONFIG_PATH}" ]; then
|
|
error_log "config path does not exist"
|
|
return 1
|
|
fi
|
|
|
|
banner_dir="$1"
|
|
if [ -z "${banner_dir}" ]; then
|
|
error_log "path containing customization files is required"
|
|
return 1
|
|
fi
|
|
|
|
if [ ! -d "${banner_dir}" ]; then
|
|
warn_log "directory does not exist: ${banner_dir}"
|
|
return 0
|
|
fi
|
|
|
|
local inputok=0
|
|
local count=0
|
|
local fname=""
|
|
for fname in $(get_banner_files); do {
|
|
local bname="$(basename $fname)"
|
|
# confname includes 'etc'; newfname does not. This seems easier
|
|
# for the user; at least until a file with a duplicate name is
|
|
# customizable
|
|
local confname="${PLATFORM_BANNER_DIR}/${fname}"
|
|
local newfname="${banner_dir}/${bname}"
|
|
|
|
if [ -e "${newfname}" ]; then
|
|
count=$(expr $count + 1)
|
|
if ! file_is_sane ${newfname}; then
|
|
inputok=1
|
|
continue
|
|
fi
|
|
|
|
if [ -f "${confname}" ]; then
|
|
info_log "updating customization of ${fname}"
|
|
rm ${confname}
|
|
else
|
|
info_log "adding customization of ${fname}"
|
|
fi
|
|
|
|
mkdir -p $(dirname ${confname})
|
|
cp ${newfname} ${confname}
|
|
elif [ -f "${confname}" ]; then
|
|
info_log "maintaining previous customization of ${fname}"
|
|
fi
|
|
}; done
|
|
|
|
if [ "$count" -eq 0 ]; then
|
|
warn_log "no customization files were found in $banner_dir"
|
|
fi
|
|
|
|
return $inputok
|
|
}
|
|
|
|
#
|
|
# Compare two banner files
|
|
#
|
|
# Return 0 if they are the same
|
|
# 1 if they are different
|
|
#
|
|
compare_file ()
|
|
{
|
|
diff -q "$1" "$2" 2>&1 > /dev/null
|
|
return $?
|
|
}
|
|
|
|
#
|
|
# copy the file with a bkx extension, but only if it is not identical to
|
|
# another; look for an unused filename
|
|
#
|
|
# put a hard limit on the number of iterations
|
|
#
|
|
backup_file ()
|
|
{
|
|
local fname=$1
|
|
local dname=$(dirname $fname)
|
|
local bname=$(basename $fname)
|
|
local bkdir=${OPT_BANNER_BACKUP}/${dname}
|
|
local count=0
|
|
local newname=""
|
|
|
|
if [ ! -f "${fname}" ]; then
|
|
warn_log "file does not exist: $fname"
|
|
return 0
|
|
fi
|
|
|
|
for count in $(seq 0 9); do {
|
|
newname=${bkdir}/${bname}.bk${count}
|
|
if [ -e "${newname}" ]; then
|
|
if compare_file "${newname}" "${fname}"; then
|
|
info_log "file is previously backed up ${fname} as ${newname}"
|
|
touch ${newname}
|
|
return 0
|
|
fi
|
|
|
|
info_log "skipping name ${newname}"
|
|
else
|
|
if [ "$count" -gt 7 ]; then
|
|
warn_log "consider cleaning up $(dirname ${newname})"
|
|
fi
|
|
|
|
info_log "backing up ${fname} as ${newname}"
|
|
mkdir -p ${bkdir}
|
|
cp ${fname} ${newname}
|
|
return 0
|
|
fi
|
|
}; done
|
|
|
|
# find the oldest file and delete it.
|
|
newname=$(find ${bkdir} -maxdepth 1 -type f -name "${bname}.bk[0-9]" \
|
|
| xargs -r ls -1t | tail -n 1)
|
|
if [ -z "${newname}" -o ! -f "${newname}" ]; then
|
|
error_log "did not find backup files for ${fname}"
|
|
return 1
|
|
fi
|
|
|
|
warn_log "deleting oldest backed up file ${newname}"
|
|
rm ${newname}
|
|
cp ${fname} ${newname}
|
|
|
|
return $?
|
|
}
|
|
|
|
#
|
|
# For each customizable file, if the file exists under
|
|
# PLATFORM_BANNER_DIR, and it passes some sanity checks, then install
|
|
# the file onto the root fs
|
|
#
|
|
install_banner_files ()
|
|
{
|
|
# quietly stop if the PLATFORM_BANNER_DIR is not setup
|
|
if [ ! -d ${PLATFORM_BANNER_DIR} ]; then
|
|
return 0
|
|
fi
|
|
|
|
local banner_files=$(get_banner_files)
|
|
local bfile=""
|
|
for bfile in ${banner_files}; do {
|
|
# do not attempt to install files if the directory on the root
|
|
# fs is absent; this is an unexpected condition
|
|
if [ ! -d "$(dirname ${bfile})" ]; then
|
|
error_log "directory does not exist for ${bfile}"
|
|
continue
|
|
fi
|
|
|
|
# proceed only if the user provided a customization for the file
|
|
if [ ! -f "${PLATFORM_BANNER_DIR}/${bfile}" ]; then
|
|
info_log "file is not customized: ${bfile}"
|
|
continue
|
|
fi
|
|
|
|
if [ -e "${bfile}" ]; then
|
|
if ! file_is_sane ${bfile}; then
|
|
continue
|
|
fi
|
|
if compare_file "${PLATFORM_BANNER_DIR}/${bfile}" "${bfile}"; then
|
|
info_log "file already installed: ${bfile}"
|
|
continue
|
|
fi
|
|
info_log "installing over existing file: ${bfile}"
|
|
backup_file ${bfile} \
|
|
|| continue
|
|
else
|
|
info_log "installing: ${bfile}"
|
|
fi
|
|
|
|
cp ${PLATFORM_BANNER_DIR}/${bfile} ${bfile}
|
|
}; done;
|
|
}
|