upload.sh: Make it work at least a little (with rsync_ssh; creation mode is still a mess)

This commit is contained in:
Jan Lindemann 2002-06-09 16:51:25 +00:00 committed by Jan Lindemann
commit e848f24eaa

View file

@ -33,6 +33,7 @@ MYNAME=`basename $0`
HOST=ftp.jannet.de
CFG_FILE=$HOME/.uploadrc
user=`whoami`
method=rsync_ssh
pw_ftp=
pw_scp=$HOME/.ssh/identity
@ -51,17 +52,29 @@ cat << EOT
Unified Upload Interface
Version '$Revision$' - '$Date$'
(c) 2002 Jannet IT Services
(c) 2002 Jannet IT Services http://www.jannet.de
usage: $MYNAME file [password:[method:]]user@host:/path/to/directory[:mode[:dirmode[:owner.group]]] ...
usage: $MYNAME file [[password:[method:]user@]]]host:[target[:mode[:dirmode[:owner[.group]]]]] ...
where "method" is one of "ftp", "scp", "rsync", "rsync_ssh".
"password" may be a valid rsa private key file, too, if this makes sense with the chosen method.
The default values for the optional parameters may be redefined in $CFG_FILE.
"file" may be a directory and a file. If it ends with a slash, it is treated as an existing
directory and expands to its contents.
"target" may be a directory and a file.
+ If it is an existing directory, it will be populated with "file", "file" will keep its name.
+ If it is not an existing directory, $MYNAME will take the path from target (i.e., skip
everything following the last slash), and populate it with "file".
- If there is a nonempty file name following the last slash, this will be the new file name.
- If the last character of the target is a slash, the file name will be taken from "file".
The default values for the optional parameters can be redefined in $CFG_FILE.
Currently they are:
user="$user"
method="$method"
pw_ftp="$pw_ftp"
pw_scp="$pw_scp"
@ -76,5 +89,121 @@ EOT
[ -n "$1" ] && exit $1
}
parse_target()
{
target=$1
USER=`echo $target | sed -e '/@/ !d; s/@.*//; s/.*://'`
test -n "$USER" && echo user="\"$USER\";"
METHOD=`echo :$target | sed -e '/@/ !d; s/@.*//' | rev | cut -d: -f2 | rev`
test -n "$METHOD" && echo method="\"$METHOD\";"
PASSWD=`echo :$target | sed -e '/@/ !d; s/@.*//' | rev | cut -d: -f3 | rev`
if [ -n "$PASSWD" ]; then
echo passwd="\"$PASSWD\";"
if [ -f "$PASSWD" ]; then
echo IDENTITY="\"-i $PASSWD\""
fi
echo pw_ftp="\"$PASSWD\";"
echo pw_scp="\"$PASSWD\";"
echo pw_rsync="\"$PASSWD\";"
echo pw_rsync_ssh="\"$PASSWD\";"
fi
HOST=`echo $target | sed -e 's/.*@//' | cut -d: -f1`
if [ -n "$HOST" ]; then
echo host="\"$HOST\";"
else
PARSE_TARGET=FALSE
return
fi
TARGET_FILE=`echo $target | sed -e 's/.*@//' | cut -d: -f2`
if [ -n "$TARGET_FILE" ]; then
echo target_file="\"$TARGET_FILE\";"
else
PARSE_TARGET=FALSE
return
fi
FILE_MODE=`echo $target | sed -e 's/.*@//' | cut -d: -f3`
test -n "$FILE_MODE" && echo file_mode="\"$FILE_MODE\";"
DIR_MODE=`echo $target | sed -e 's/.*@//' | cut -d: -f4`
test -n "$DIR_MODE" && echo dir_mode="\"$DIR_MODE\";"
FILE_OWNER=`echo $target | sed -e 's/.*@//' | cut -d: -f5 | cut -d. -f1`
test -n "$FILE_OWNER" && echo file_owner="\"$FILE_OWNER\";"
FILE_GROUP=`echo $target | sed -e 's/.*@//' | cut -d: -f5 | cut -d. -f2`
test -n "$FILE_GROUP" && echo file_group="\"$FILE_GROUP\";"
echo "PARSE_TARGET=\"OK\";"
}
ssh_mkdir()
{
set -e
dir=`echo $1 | sed -e 's/\/[^\/]*$//; s/\/*$//'`
parts="`echo $dir | sed -e 's/\// /g'`"
test -n "$dir_mode" && MODE="-m $dir_mode"
cat << EOT |
for part in $parts; do
path="\$path/\$part"
if [ ! -d \$path ]; then
mkdir \$path || break
test -n "$2" && chown "$2" \$path || break
test -n "$3" && chgrp "$3" \$path || break
test -n "$4" && chmod "$4" \$path || break
fi
if [ ! -d \$path ]; then
echo "failed to create directory \$path, owner=\$file_owner, group=\$file_group, mode=\$dir_mode"
exit 2
fi
done
EOT
ssh -l $user $IDENTITY $host -C "SCRIPT=\`mktemp /tmp/$MYNAME""_XXXXXX\`; cat > \$SCRIPT; /bin/sh \$SCRIPT; rm \$SCRIPT"
}
# -- here we go
test $# -lt 2 && usage 1
# -- get parameters from command line
source=$1
shift
# -- check run
for t in $*; do
# parse_target $t
eval `parse_target $t`
if [ "$PARSE_TARGET" != OK ]; then
echo "Failed to parse target \"$t\"; exiting."
parse_target $t
exit 2
fi
test "$METHOD" && method=$METHOD
case $method in
rsync_ssh)
if [ "$user" != root ]; then
if [ "$file_owner" -a "$file_owner" != "$user" ]; then
echo "File owner \"$file_owner\" is only legal, if you log in as \"$user\" or as \"root\"."
exit 1
fi
fi
if [ ! -d "$source" -a ! -f "$source" -a ! -L "$source" ]; then
echo \"$source\" is neither a regular file, nor a directory, nor a link. Exiting. >&2
exit 1
fi;;
*)
echo "Support for method \"$method\" is not implemented." >&2
exit 1;;
esac
done
# -- real run
for t in $*; do
eval `parse_target $t`
test "$METHOD" && method=$METHOD
case $method in
rsync_ssh)
ssh_mkdir $target_file $file_owner $file_group $dir_mode || break
/usr/bin/rsync -az --links -e "/usr/bin/ssh -l $user $IDENTITY" $source $user@$host:$target_file
;;
*)
echo "Internal error: \"$method\" is not implemented." >&2
exit 1;;
esac
done