+. lib/tagdir_parsing
+
copy_dirtrees_of_tags() {
- _TAGS="$@"
- _PATHS_WRITTEN=
- for _TAG in ${_TAGS}; do
- _PATH_TAG="../copy/${_TAG}"
- if [ ! -d "${_PATH_TAG}" ]; then
- continue
- fi
- cd "${_PATH_TAG}"
- for _PATH_REL in $(find -L . -type f); do
- _PATH_TARGET="$(echo ${_PATH_REL} | cut -c 2-)"
- _PATH_TARGET_DIR=$(dirname "${_PATH_TARGET}")
+ _copy_dirtree() {
+ for _PATH_REL in $(tagdir_parsing__relpaths); do
+ _FILENAME="$(basename ${_PATH_REL})"
+ _PATH_TARGET_PARENT=/$(dirname "${_PATH_REL}")
# ensure directory by mkdir -p; to avoid later chowning pre-existing directories,
# collect only what's returned by the command as actually newly created
- _CREATION_SUMMARY=$(mkdir -pv "${_PATH_TARGET_DIR}")
+ _CREATION_SUMMARY=$(mkdir -pv "${_PATH_TARGET_PARENT}")
_CREATED_PATHS=$(echo "${_CREATION_SUMMARY}" | sed -E "s/'\$//g" | sed -E "s/^mkdir: created directory '//g")
_PATHS_WRITTEN="${_CREATED_PATHS}\n${_PATHS_WRITTEN}"
# handle dirtree creation instruction files
- _FILENAME="$(basename ${_PATH_REL})"
- if [ "${_FILENAME}" = 'KILL_ME' ]; then # only there to ensure directory
+ if tagdir_parsing__is_killme "${_FILENAME}"; then
continue
fi
- if [ $(echo "${_FILENAME}" | grep -E '^LINK_ME' | wc -l) -gt 0 ]; then
- _LINK_TARGET=$(cat "${_PATH_REL}" | head -1)
- _LINK_NAME=$(cat "${_PATH_REL}" | tail -1)
- if [ -z "${_LINK_NAME}" ]; then
- _LINK_NAME=$(basename "${_LINK_TARGET}")
- fi
- _PATH_LINK="${_PATH_TARGET_DIR}/${_LINK_NAME}"
- ln -sf "${_LINK_TARGET}" "${_PATH_LINK}"
+ if tagdir_parsing__is_linkme "${_FILENAME}"; then
+ _PARSED=$(tagdir_parsing__parse_linkme "${_PATH_REL}")
+ _PATH_LINK=$(echo "${_PARSED}" | head -1)
+ _LINK_TARGET=$(echo "${_PARSED}" | tail -1)
+ ln -sf "${_LINK_TARGET}" "${_PATH_LINK}"
_PATHS_WRITTEN="${_PATH_LINK}\n${_PATHS_WRITTEN}"
continue
fi
# actual file copying
- _CREATION_SUMMARY=$(cp -avL "${_PATH_REL}" "${_PATH_TARGET_DIR}")
+ _CREATION_SUMMARY=$(cp -avL "${_PATH_REL}" "${_PATH_TARGET_PARENT}")
_CREATED_PATHS=$(echo "${_CREATION_SUMMARY}" | grep -v -E '^removed ' | sed -E "s/'\$//g" | sed "s/.*' -> '//g")
_PATHS_WRITTEN="${_CREATED_PATHS}\n${_PATHS_WRITTEN}"
done
- cd - > /dev/null
- done
+ }
+
+ _PATHS_WRITTEN=
+ tagdir_parsing__for_tagdir '_copy_dirtree' $@
_PATHS_WRITTEN=$(echo "${_PATHS_WRITTEN}" | grep -v -E '^ *$')
-
+
## for all paths written into user home directories, chown to respective users
for _PATH in ${_PATHS_WRITTEN}; do
if [ $(echo "${_PATH}" | grep -E '^/home/' | wc -l) -gt 0 ]; then
_USERNAME=$(echo "${_PATH}" | sed -E 's/^\/home\///' | sed -E 's/\/.*//')
- chown -R "${_USERNAME}:${_USERNAME}" "${_PATH}"
+ chown -R "${_USERNAME}:${_USERNAME}" "${_PATH}"
fi
done
}
set -e
cd $(dirname "$0")
. lib/abort_if_not_user
+. lib/constants_user
. lib/expect_n_args
. lib/prefixed_msg
+. lib/tagdir_parsing
prefixed_msg_init
abort_if_not_user root
expect_n_args 1 99 "TAG.." $@
-TAGS="$@"
-for _TAG in ${TAGS}; do
- _PATH_TAG="../copy/${_TAG}"
- if [ ! -d "${_PATH_TAG}" ]; then
- continue
- fi
+
+compare_tagdir() {
+ _compare_stat() {
+ _ATTRIBUTE=$1
+ _FORMAT_STR=$2
+ _SHOULD_BE=$3
+ _ACTUAL_VALUE=$(stat --format="${_FORMAT_STR}" ${_PATH_ABS})
+ if [ "${_ACTUAL_VALUE}" != "${_SHOULD_BE}" ]; then
+ prefixed_msg "Bad ${_ATTRIBUTE}: ${_PATH_ABS} is ${_ACTUAL_VALUE}, should be ${_SHOULD_BE}"
+ false
+ fi
+ }
prefixed_msg_init "tag [${_TAG}]"
- cd "${_PATH_TAG}"
- for _PATH_REL in $(find -L . -type f | cut -c 3-); do
+ for _PATH_REL in $(tagdir_parsing__relpaths); do
_FILENAME="$(basename ${_PATH_REL})"
_PATH_REL_PARENT=$(dirname "${_PATH_REL}")
- if [ "${_FILENAME}" = 'KILL_ME' ]; then
+
+ if tagdir_parsing__is_killme "${_FILENAME}"; then
_TYPE='directory'
_PATH_ABS="/${_PATH_REL_PARENT}"
- elif [ $(echo "${_FILENAME}" | grep -E '^LINK_ME' | wc -l) -gt 0 ]; then
+ elif tagdir_parsing__is_linkme "${_FILENAME}"; then
_TYPE='symbolic link'
- _LINK_TARGET=$(cat "${_PATH_REL}" | head -1)
- _LINK_NAME=$(cat "${_PATH_REL}" | tail -1)
- if [ -z "${_LINK_NAME}" ]; then
- _LINK_NAME=$(basename "${_LINK_TARGET}")
- fi
- _PATH_ABS="/${_PATH_REL_PARENT}/${_LINK_NAME}"
- else
+ _PARSED=$(tagdir_parsing__parse_linkme "${_PATH_REL}")
+ _PATH_ABS=$(echo "${_PARSED}" | head -1)
+ _LINK_TARGET=$(echo "${_PARSED}" | tail -1)
+ else
_TYPE='regular file'
_PATH_ABS="/${_PATH_REL}"
fi
if [ -h "${_PATH_ABS}" ]; then
- if [ "${_TYPE}" = 'symbolic link' ]; then
+ if [ 'symbolic link' = "${_TYPE}" ]; then
_LOCAL_TARGET=$(stat "${_PATH_ABS}" | head -1 | sed -E 's/^ File: [[:print:]]+ -> //g')
- if [ "$(echo ${_LOCAL_TARGET} | cut -c1)" != "/" ]; then
+ if [ "/" != "$(echo ${_LOCAL_TARGET} | cut -c1)" ]; then
_LOCAL_TARGET=$(realpath --canonicalize-missing "/${_PATH_REL_PARENT}/${_LOCAL_TARGET}")
fi
if [ "$(echo ${_LINK_TARGET} | cut -c1)" != "/" ]; then
if [ "${_LOCAL_TARGET}" != "${_LINK_TARGET}" ]; then
prefixed_msg "${_TYPE} targeting ${_LOCAL_TARGET} != ${_LINK_TARGET}"
fi
- else
+ else
prefixed_msg "Not a ${_TYPE}: ${_PATH_ABS}"
fi
elif [ ! -e "${_PATH_ABS}" ]; then
prefixed_msg "Missing ${_TYPE}: ${_PATH_ABS}"
- elif [ "${_TYPE}" != "$(stat --format=%F ${_PATH_ABS})" ]; then
- prefixed_msg "Not a ${_TYPE}: ${_PATH_ABS}"
- elif [ "${_TYPE}" = 'regular file' ]; then
+ continue
+ elif _compare_stat 'file type' '%F' "${_TYPE}" && [ 'regular file' = "${_TYPE}" ]; then
! diff "${_PATH_ABS}" "${_PATH_REL}" > /dev/null && prefixed_msg "Regular file differs: ${_PATH_ABS}"
fi
+ if echo "${_PATH_ABS}" | grep "^${PATH_USER_HOME}/" > /dev/null; then
+ _EXPECTED_OWNERSHIP="${USERNAME}:${USERNAME}"
+ else
+ _EXPECTED_OWNERSHIP='root:root'
+ fi
+ _EXPECTED_PERMISSIONS=$(stat --format='%a' --dereference ${_PATH_REL})
+ set +e
+ _compare_stat 'ownership' '%U:%G' "${_EXPECTED_OWNERSHIP}";
+ _compare_stat 'permissions' '%a' "${_EXPECTED_PERMISSIONS}";
+ set -e
done
- cd - > /dev/null
prefixed_msg_exit
-done
-prefixed_msg_exit
+}
+
+tagdir_parsing__for_tagdir 'compare_tagdir' $@