#!/bin/sh log() { printf '%s\n' "$*" } error() { printf 'Error: %s\n' "$*" >&2 } path_exists() { local dir="$1" local path="$2" [ -n "$(find "$dir"/$path -print -quit 2>/dev/null)" ] } file_dir_chmod() { local dir="$1" local path="$2" local file_mode="$3" local dir_mode="$4" shift; shift; shift; shift; if [ -n "$file_mode" ]; then find "$dir"/$path -type f "$@" -exec chmod "$file_mode" -- '{}' + fi if [ -n "$dir_mode" ]; then find "$dir"/$path -type d "$@" -exec chmod "$dir_mode" -- '{}' + fi } src="$1" dest="$2" filespec="$3" if [ -z "$src" ]; then error "Missing source directory" exit 1 fi if [ -z "$dest" ]; then error "Missing destination directory" exit 1 fi while IFS='|' read -r cmd path file_mode dir_mode; do # trim whitespace cmd="${cmd#"${cmd%%[![:space:]]*}"}" cmd="${cmd%"${cmd##*[![:space:]]}"}" path="${path#"${path%%[![:space:]]*}"}" path="${path%"${path##*[![:space:]]}"}" file_mode="${file_mode#"${file_mode%%[![:space:]]*}"}" file_mode="${file_mode%"${file_mode##*[![:space:]]}"}" dir_mode="${dir_mode#"${dir_mode%%[![:space:]]*}"}" dir_mode="${dir_mode%"${dir_mode##*[![:space:]]}"}" if [ -z "$cmd" ] || [ "$cmd" != "${cmd#\#}" ]; then continue fi if [ -z "$path" ]; then error "Missing path for \"$cmd\"" exit 1 fi case "$cmd" in +) log "Copying: \"$path\"" if ! path_exists "$src" "$path"; then error "\"$src/$path\" not found" exit 1 fi dir="${path%/*}" mkdir -p "$dest/$dir" cp -fpR "$src"/$path "$dest/$dir/" file_dir_chmod "$dest" "$path" "$file_mode" "$dir_mode" ;; -) log "Removing: \"$path\"" if ! path_exists "$dest" "$path"; then error "\"$dest/$path\" not found" exit 1 fi rm -fR -- "$dest"/$path ;; =) log "Setting recursive permissions \"${file_mode:-(none)}\"/\"${dir_mode:-(none)}\" on \"$path\"" if ! path_exists "$dest" "$path"; then error "\"$dest/$path\" not found" exit 1 fi if [ -z "$file_mode$dir_mode" ]; then error "Missing recursive permissions for \"$path\"" exit 1 fi file_dir_chmod "$dest" "$path" "$file_mode" "$dir_mode" ;; ==) log "Setting permissions \"${file_mode:-(none)}\"/\"${dir_mode:-(none)}\" on \"$path\"" if ! path_exists "$dest" "$path"; then error "\"$dest/$path\" not found" exit 1 fi if [ -z "$file_mode$dir_mode" ]; then error "Missing permissions for \"$path\"" exit 1 fi file_dir_chmod "$dest" "$path" "$file_mode" "$dir_mode" -maxdepth 0 ;; *) error "Unknown command \"$cmd\"" exit 1 ;; esac done << EOF $filespec EOF