From 772f20abb0a3a0979c440114bf3a1cff5b3cef03 Mon Sep 17 00:00:00 2001 From: cvpcs Date: Wed, 2 Jun 2010 11:02:31 -0500 Subject: initial import of bash 4.1 --- examples/scripts.v2/frcp | 288 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100755 examples/scripts.v2/frcp (limited to 'examples/scripts.v2/frcp') diff --git a/examples/scripts.v2/frcp b/examples/scripts.v2/frcp new file mode 100755 index 0000000..572aa7b --- /dev/null +++ b/examples/scripts.v2/frcp @@ -0,0 +1,288 @@ +#! /bin/bash +# +# original from: +# +# @(#) frcp.ksh 2.2 93/11/14 +# 92/06/29 john h. dubois iii (john@armory.com) +# 92/10/14 Cleaned up, improved, added -d and -r options +# 92/11/11 Made work with a dest of '.' +# 93/07/09 Added -l and -n options, & login as anonymous if no .netrc entry +# 93/11/14 Use either passwd or password in .netrc, since ftp does. +# +# conversion to bash v2 syntax by Chet Ramey +# +# frcp: ftp front end with rcp-like syntax. +# Note: requires any machine names given to be listed with +# user and password in .netrc. If not, anonymous FTP is +# done. +# +# full path to ftp binary +if [ -x /usr/bin/ftp ]; then + FTP=/usr/bin/ftp; +elif [ -x /usr/ucb/ftp ]; then + FTP=/usr/ucb/ftp +else + FTP=ftp +fi + +istrue() +{ + test 0 -ne "$1" +} +isfalse() +{ + test 0 -eq "$1" +} + +# For each filename given, put the filename in filename[n] +# and the machine it is on in machine[n]. +function SplitNames { + typeset file + typeset -i i=1 + + unset filename[*] machine[*] + for file; do + case "$file" in + *:*) machine[i]=${file%%:*} ;; + *) machine[i]=$LocalMach ;; + esac + filename[i]=${file#*:} + let i+=1 + done +} + +function verboseprint { + echo "$@" + echo "$@" 1>&2 +} + +function MakeDir { + OFS=$IFS + local IFS=/ dir component + + case "$1" in + /*) ;; + *) dir=. + esac + set -- $1 + IFS=$OFS + for component; do + dir=$dir/$component + if [ ! -d "$dir" ]; then + if mkdir "$dir"; then :; else + echo "Could not make directory $dir." >&2 + return 1 + fi + fi + done + return 0 +} + +lastisdot () +{ + case "$1" in + */.|*/..) return 0;; + *) return 1;; + esac +} + +# CopyFiles: issue ftp(TC) commands to copy files. +# Usage: CopyFiles [sourcemachine:]sourcepath ... [destmachine:]destpath +# Global vars: +# Uses LocalMach (should be name of local machine) +# Sets global arrs machine[]/filename[] +function CopyFiles { + unset machine[*] filename[*] + + SplitNames "$@" # split names into filename[1..n] and machine[1..n] + + local DestMach=${machine[$#]} # Machine to copy files to + local DestPath=${filename[$#]} # Destination file/dir + + unset machine[$#] filename[$#] + + [ -z "$DestPath" ] && DestPath=. # dest was given as machine: + + # Try to determine if destination should be a directory + # so that it can be forced to be a directory. + + case "$DestPath" in + */) ;; # don't add / if trailing / already present + *) if [ $# -gt 2 ] || # if more than two args given, last must be a dir + # If dest in on local machine, check whether it is a directory + [ $DestMach = $LocalMach ] && [ -d "$DestPath" ] || + # If dest ends with . or .., it is a directory + lastisdot "$DestPath" + then + DestPath=$DestPath/ + fi ;; + esac + + # If one of the above tests made us think dest is a directory, + # but it isn't, complain + case "$DestPath" in + */) if [ "$DestMach" = "$LocalMach" ] && [ ! -d "$DestPath" ]; then + echo "Destination is not a directory." 1>&2 + exit 1 + fi ;; + esac + + DoCopy "$DestMach" "$DestPath" +} + +# Usage: OpenMachine machine-name +# Emits login sequence or doesn't, depending on .netrc file and global +# variables anon and noanon +OpenMachine () +{ + local machine=$1 netrc=$HOME/.netrc user= password= + + if isfalse $anon && [ -r $netrc ]; then + set -- $(gawk ' + /machine (.* )?'"$machine"'($| )/,/^ *$/ { + Fields[$1] = $2 + if ("passwd" in Fields) + Fields["password"] = Fields["passwd"] + if ("login" in Fields && "password" in Fields) { + print Fields["login"] " " Fields["password"] + exit + } + } + ' $netrc ) + user=$1 + password=$2 + fi + if [ -z "$password" ]; then + if istrue $noanon; then + echo "No .netrc entry for machine $machine" 1>&2 + exit 1 + fi + user=anonymous + password=$USER@$LocalMach + fi + verboseprint open $machine + echo user $user "*******" 1>&2 + echo user $user $password +} + +# Usage: DoCopy destination-machine destination-path +# Copies the files in global arrs machine[]/filename[] to the given dest +# Global vars: +# Uses machine[], filename[], LocalMach, check +DoCopy () +{ + local DestMach=$1 + local DestPath=$2 + local OpenMach # Machine that connection is currently open to + local OWD=$PWD SourceMach SourceFile + local FileName + typeset -i i=1 + + while [ $i -le ${#machine[*]} ]; do + istrue $check && verboseprint "runique" + + SourceMach=${machine[i]} + SourceFile=${filename[i]} + + DestFile=$DestPath + # if DestPath is a dir, + # add source filename to it without source path + case "$DestFile" in + */) DestFile=$DestFile${SourceFile##*/} ;; + esac + + if [ $SourceMach = $LocalMach ]; then + if [ $DestMach != "$OpenMach" ]; then + OpenMachine $DestMach + OpenMach=$DestMach + fi + verboseprint put $SourceFile $DestFile + elif [ $DestMach = $LocalMach ]; then + if istrue $check && [ -f "$DestFile" ]; then + echo "$DestFile already exists." 1>&2 + continue + fi + # If destination is on local machine, + # the dest will be a full dir/filename + if istrue $createdirs; then + MakeDir "${DestFile%/*}" || continue + fi + if [ $SourceMach != "$OpenMach" ]; then + OpenMachine $SourceMach + OpenMach=$SourceMach + fi + # If source filename has wildcards ([, ], *, ?) do an mget + case "$SourceFile" in + \[*\]|*\**|*\?*) + verboseprint lcd "$DestFile" + verboseprint mget "$SourceFile" + verboseprint lcd $OWD ;; + *) verboseprint get "$SourceFile" "$DestFile" ;; + esac + else + echo "Neither source machine \"$SourceMach\" "\ +"nor destination machine \"$DestMach\" is local." 1>&2 + fi + let i+=1 + done +} + +# Start of main program +name=${0##*/} + +if [ "$1" = -h ]; then + echo \ +"$name: do ftp transfers using rcp-style parameters. +Usage: $name or $name [ ...] +At least one of and must be the local system. +A remote filename is given as machinename:filename +If remote filenames contain wildcards, they will be globbed on the remote +machine. Make sure they are quoted when $name is invoked. +If the invoking user's .netrc file (see ftp(TC)) contains an entry for the +remote system with a login and password supplied, $name will log in using +the given login and password. If not, $name will login in as user +anonymous and with the user@localsystem as the password. +Options: +-c: check: do not overwrite files. +-d: create directories as needed. +-f: force: overwrite files (default). +-h: print this help. +-l: fail if there is no entry with login and password for the remote system, + instead of logging in as anonymous. +-n: log in as anonymous even if there is an entry for the remote system in + the user's .netrc file. +-r: read source/dest filename pairs from the standard input, + one pair per line, and copy files accordingly." + exit 0 +fi + +typeset -i check=0 createdirs=0 readinput=0 anon=0 noanon=0 + +while getopts :cdflnr Option +do + case "$Option" in + c) check=1;; + d) createdirs=1;; + f) check=0;; + l) noanon=1;; + n) anon=1;; + r) readinput=1;; + \?) echo "$OPTARG: invalid option."; exit 1;; + esac +done + +shift $((OPTIND-1)) + +LocalMach=`hostname` + +if istrue $readinput; then + while read line; do + CopyFiles $line + done | $FTP -nv +else + if [ $# -lt 2 ]; then + echo "$name: Not enough arguments. Use -h for help." 1>&2 + exit + fi + CopyFiles "$@" | $FTP -nv +fi -- cgit v1.1