Files
init.sh/lib/filefct.sh

214 lines
6.2 KiB
Bash

# ------------------------------------------------------------------------------
# File manipulation function
# This file is part of the init.sh project
# Copyright (c) 2019-2021 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# ------------------------------------------------------------------------------
# This file is distributed under 3-clause BSD license.
# The complete license agreement can be obtained at:
# https://opensource.org/licenses/BSD-3-Clause
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Backup original installation files
# (or any old files if runned several time on same file)
backupdist()
{
if [[ $# -lt 1 ]]; then
prnt E "backupdist(): At least one argument is required."
exit 11
fi
local file=
for file in $@; do
local tmstmp=$(stdtime)
if [[ -L ${file} ]]; then
# With symbolik links we call again backupdist to treat target
backupdist $(readlink -f ${file})
elif [[ -f ${file} ]]; then
prnt I "Création d'une sauvegarde de ${file} du $tmstmp..."
cp -av $file ${file}.dist.${tmstmp}
if [[ $? -ne 0 ]]; then
prnt E "backupdist(): Échec de copie du fichier."
die 12
fi
elif [[ -d ${file} ]]; then
prnt I "Création d'une sauvegarde du répertoire ${file} du $tmstmp..."
cp -av $file ${file}.dist.${tmstmp}
if [[ $? -ne 0 ]]; then
prnt E "backupdist(): Échec de copie du répertoire."
die 12
fi
else
prnt W "backupdist(): $file n'existe pas, rien à faire."
fi
unset tmstmp
done
unset file
}
export -f backupdist
# ------------------------------------------------------------------------------
# Select source file according to our priority mechanisme
select_file()
{
local infile=$1
if [[ -f $MYPATH/repo/hosts/$HOSTNAME/$infile ]]; then
local source="$MYPATH/repo/hosts/$HOSTNAME/$infile"
elif [[ -f $MYPATH/repo/common/$infile ]]; then
local source="$MYPATH/repo/common/$infile"
else
# Not found in repository, we expect full name
local source="$infile"
fi
unset infile
echo $source
unset source
}
# ------------------------------------------------------------------------------
# Install file to the host (specific first then general)
# Todo: implement wildcard support
installfile()
{
local filelist=""
local i=0
if [[ $# -lt 2 ]]; then
prnt E "installfile(): At least two arguments are required."
die 11
fi
if [[ $(echo $@ | grep "\*\|\?") ]]; then
prnt E "installfile(): Wildcards are not authorized."
die 7
fi
local arg=
for arg in $@; do
filelist="$filelist $(select_file $arg)"
done
unset arg
# Empty to just obtain the target which is the last element of the list
local file=
for file in $filelist; do
:
done
if [[ ! $file == /* ]]; then
prnt E "installfile(): Target must be on the root filesystem and full path must be provided."
die 13
fi
unset file
if [[ -d $(dirname $i) ]]; then
prnt I "Création du répertoire $(dirname $i) d'accueil..."
mkdir -pv $(dirname $i)
if [[ $? -ne 0 ]]; then
prnt E "installfile(): Can't create target dirrectory!"
die 12
fi
fi
prnt I "Copie des fichiers ${filelist}..."
cp -av $filelist
if [[ $? -ne 0 ]]; then
prnt E "installfile(): Couldn't copy some required files!"
die 12
fi
}
export -f installfile
# ------------------------------------------------------------------------------
# Add the content of a file at the end of an other
appendfile()
{
local srcfile=$(select_file $1)
local dstfile=$2
if [[ -e $dstfile ]]; then
prnt E "appendfile(): Target must be on the root filesystem and full path must be provided."
die 13
fi
if [[ ! $dstfile == /* ]]; then
prnt E "appendfile(): Target file must exist."
die 13
fi
prnt I "Ajout de contenu au fichier $dstfile..."
cat $srcfile >> $dstfile
if [[ $? -ne 0 ]]; then
prnt E "appendfile(): Couldn't append a file!"
die 12
fi
}
# ------------------------------------------------------------------------------
# determine if a directory is empty
isdirempty()
{
dir=$1
if [[ -f $dir ]]; then
prnt E "isdirempty():The given parameter is not a directory."
die 15
fi
if [[ ! -d $dir ]]; then
return 0
fi
nbfiles=$(ls -a1 $dir | egrep -v '^.$|^..$' | wc -l)
if [[ $nbfiles -eq 0 ]]; then
return 0
fi
return 1
}
# ------------------------------------------------------------------------------
# copy and patch a file replacing all @var@ by the corresponding value in
# environment or the variable list given in parameter
patchfile()
{
local srcfile=$(select_file $1) && shift
local dstfile=$1 && shift
local workfile=${dstfile}.work
if [[ ! -s $srcfile ]]; then
prnt E "Le fichier source est vide, n'est pas un fichier ou n'existe pas"
die 10
fi
# Create a sub-process, to avoid bash environment pollution
(
local varlist= pattern=
if [[ $# -eq 0 ]] ; then
pattern="-e s/<\(.*\)>/\$\1\$\1/g"
else
local var=
for var in $* ; do
if ! declare -p $var >/dev/null 2>&1 ; then
local $var=$(eval echo \$$var)
fi
export $var
pattern="$pattern -e s/@$var@/\$$var/g"
varlist=$varlist\$$var
done
fi
# sed replace <VAR> with \$$VAR and envsubst do the replace by value
sed $pattern $srcfile | envsubst ${varlist:+"$varlist"} > "$workfile"
)
local -a rights=( $(stat --printf="%a %u %g" "$srcfile") )
unset srcfile
mv "$workfile" "$dstfile"
chmod ${rights[0]} "$dstfile"
chown ${rights[1]}:${rights[2]} "$dstfile"
unset rights dstfile
}
# EOF