# ------------------------------------------------------------------------------ # File manipulation function # This file is part of the init.sh project # Copyright (c) 2019-2021 Geoffray Levasseur # ------------------------------------------------------------------------------ # This file is distributed under 3-clause BSD license. # The complete license agreement can be obtained at: # https://opensource.org/licenses/BSD-3-Clause # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Define normalised time display, filename friendly stdtime() { date --rfc-3339=seconds | sed -e 's/ /-/' -e 's/://g' } export -f stdtime # ------------------------------------------------------------------------------ # 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 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