#!/bin/bash
#< Wrapper for mkdir that allows -m (mode) and -o (owner:group)
# Only supports local passwd/group files - i.e. not NIS, etc
BASENAME="/usr/bin/basename"
CHMOD="/usr/bin/chmod"
CHOWN="/usr/bin/chown"
CUT="/usr/bin/cut"
ECHO="/bin/echo"
EGREP="/bin/egrep"
GREP="/bin/grep"
MKDIR="/bin/mkdir"
SED="/usr/bin/sed"
MKDIR_OPTS=""
F_GROUP="/etc/group"
F_PASSWD="/etc/passwd"
THISPROG=$( ${BASENAME} $0 )
VERBOSE=0
function print_error {
${ECHO} "Error: $@" >&2
}
function printv {
(( VERBOSE )) && {
${ECHO} "--> $@"
}
}
function print_usage {
{
${ECHO} "Usage: ${THISPROG} [-hpv] [-o <owner:group] [-m <mode>] directories"
${ECHO} " -h Display this usage message"
${ECHO} " -o Specify owner and group"
${ECHO} " -p Create parent directories as required"
${ECHO} " -m Specify octal permissions mode"
${ECHO} " -v Verbose mode"
} >&2
}
function check_mode {
# mode can be three or four octal bits
OCTAL_BITS="${#MODE}"
if [ "${OCTAL_BITS}" -ne "3" -a "${OCTAL_BITS}" -ne "4" ]; then
print_error "Mode must contain three or four octal bits"
exit 1
fi
${ECHO} "${MODE}" | ${SED} 's/\(.\)/\1\
/g' | ${SED} '$d' | while read BIT; do
${ECHO} "${BIT}" | ${EGREP} -qs '^[0-9]$'
if [ "$?" -ne "0" ]; then
print_error "Error in octal mode"
exit 1
fi
if [ "${BIT}" -lt "0" -o "${BIT}" -gt "7" ]; then
print_error "Mode out of bounds"
exit 1
fi
done
# if we've got this far, mode is assumed to be ok
}
function check_owner {
${ECHO} "${OWNER}" | ${EGREP} -qs '^[a-zA-Z0-9]+:[a-zA-Z0-9]+$'
if [ "$?" -ne "0" ]; then
print_error "Specify owner as owner:group"
exit 1
fi
C_OWNER=$( ${ECHO} "${OWNER}" | ${CUT} -d: -f1 )
C_GROUP=$( ${ECHO} "${OWNER}" | ${CUT} -d: -f2 )
${GREP} -qs "^${C_OWNER}:" ${F_PASSWD}
if [ "$?" -ne "0" ]; then
print_error "${C_OWNER} not a valid user"
exit 1
fi
${GREP} -qs "^${C_GROUP}:" ${F_GROUP}
if [ "$?" -ne "0" ]; then
print_error "${C_GROUP} not a valid group"
exit 1
fi
}
function check_args {
if [ -n "${MODE}" ]; then
check_mode
fi
if [ -n "${OWNER}" ]; then
check_owner
fi
}
function do_mkdir {
for DIR in ${DIRLIST}; do
${MKDIR} ${MKDIR_OPTS} ${DIR}
if [ "$?" -ne "0" ]; then
# leave mkdir itself to report the error
exit 1
fi
if [ -n "${MODE}" ]; then
${CHMOD} ${MODE} ${DIR}
if [ "$?" -ne "0" ]; then
# leave chmod itself to report the error
exit 1
fi
fi
if [ -n "${OWNER}" ]; then
${CHOWN} ${OWNER} ${DIR}
if [ "$?" -ne "0" ]; then
# leave chown itself to report the error
exit 1
fi
fi
done
}
#
# main()
#
while getopts ":hm:o:pv" OPTION; do
case ${OPTION} in
"h") print_usage && exit 0 ;;
"m") MODE="${OPTARG}" ;;
"o") OWNER="${OPTARG}" ;;
"p") MKDIR_OPTS="-p" ;;
"v") VERBOSE=1 ;;
* ) print_usage && exit 1 ;;
esac
done
shift $(( ${OPTIND} - 1 ))
if [ "$#" -eq "0" ]; then
print_error "At least one directory must be specified"
exit 1
else
DIRLIST="$@"
fi
check_args
do_mkdir
exit 0