5 # @(#) frcp.ksh 2.2 93/11/14
6 # 92/06/29 john h. dubois iii (john@armory.com)
7 # 92/10/14 Cleaned up, improved, added -d and -r options
8 # 92/11/11 Made work with a dest of '.'
9 # 93/07/09 Added -l and -n options, & login as anonymous if no .netrc entry
10 # 93/11/14 Use either passwd or password in .netrc, since ftp does.
12 # conversion to bash v2 syntax by Chet Ramey
14 # frcp: ftp front end with rcp-like syntax.
15 # Note: requires any machine names given to be listed with
16 # user and password in .netrc. If not, anonymous FTP is
19 # full path to ftp binary
20 if [ -x /usr
/bin
/ftp ]; then
22 elif [ -x /usr
/ucb
/ftp ]; then
37 # For each filename given, put the filename in filename[n]
38 # and the machine it is on in machine[n].
43 unset filename
[*] machine
[*]
46 *:*) machine
[i
]=${file%%:*} ;;
47 *) machine
[i
]=$LocalMach ;;
49 filename
[i
]=${file#*:}
54 function verboseprint
{
61 local IFS
=/ dir component
71 if [ ! -d "$dir" ]; then
72 if mkdir
"$dir"; then :; else
73 echo "Could not make directory $dir." >&2
89 # CopyFiles: issue ftp(TC) commands to copy files.
90 # Usage: CopyFiles [sourcemachine:]sourcepath ... [destmachine:]destpath
92 # Uses LocalMach (should be name of local machine)
93 # Sets global arrs machine[]/filename[]
95 unset machine
[*] filename
[*]
97 SplitNames
"$@" # split names into filename[1..n] and machine[1..n]
99 local DestMach
=${machine[$#]} # Machine to copy files to
100 local DestPath
=${filename[$#]} # Destination file/dir
102 unset machine
[$#] filename
[$#]
104 [ -z "$DestPath" ] && DestPath
=.
# dest was given as machine:
106 # Try to determine if destination should be a directory
107 # so that it can be forced to be a directory.
110 */) ;; # don't add / if trailing / already present
111 *) if [ $# -gt 2 ] ||
# if more than two args given, last must be a dir
112 # If dest in on local machine, check whether it is a directory
113 [ $DestMach = $LocalMach ] && [ -d "$DestPath" ] ||
114 # If dest ends with . or .., it is a directory
115 lastisdot
"$DestPath"
121 # If one of the above tests made us think dest is a directory,
122 # but it isn't, complain
124 */) if [ "$DestMach" = "$LocalMach" ] && [ ! -d "$DestPath" ]; then
125 echo "Destination is not a directory." 1>&2
130 DoCopy
"$DestMach" "$DestPath"
133 # Usage: OpenMachine machine-name
134 # Emits login sequence or doesn't, depending on .netrc file and global
135 # variables anon and noanon
138 local machine
=$1 netrc
=$HOME/.netrc user
= password
=
140 if isfalse
$anon && [ -r $netrc ]; then
142 /machine (.* )?'"$machine"'($| )/,/^ *$/ {
144 if ("passwd" in Fields)
145 Fields["password"] = Fields["passwd"]
146 if ("login" in Fields && "password" in Fields) {
147 print Fields["login"] " " Fields["password"]
155 if [ -z "$password" ]; then
156 if istrue
$noanon; then
157 echo "No .netrc entry for machine $machine" 1>&2
161 password
=$USER@
$LocalMach
163 verboseprint open
$machine
164 echo user
$user "*******" 1>&2
165 echo user
$user $password
168 # Usage: DoCopy destination-machine destination-path
169 # Copies the files in global arrs machine[]/filename[] to the given dest
171 # Uses machine[], filename[], LocalMach, check
176 local OpenMach
# Machine that connection is currently open to
177 local OWD
=$PWD SourceMach SourceFile
181 while [ $i -le ${#machine[*]} ]; do
182 istrue
$check && verboseprint
"runique"
184 SourceMach
=${machine[i]}
185 SourceFile
=${filename[i]}
188 # if DestPath is a dir,
189 # add source filename to it without source path
191 */) DestFile
=$DestFile${SourceFile##*/} ;;
194 if [ $SourceMach = $LocalMach ]; then
195 if [ $DestMach != "$OpenMach" ]; then
196 OpenMachine
$DestMach
199 verboseprint put
$SourceFile $DestFile
200 elif [ $DestMach = $LocalMach ]; then
201 if istrue
$check && [ -f "$DestFile" ]; then
202 echo "$DestFile already exists." 1>&2
205 # If destination is on local machine,
206 # the dest will be a full dir/filename
207 if istrue
$createdirs; then
208 MakeDir
"${DestFile%/*}" ||
continue
210 if [ $SourceMach != "$OpenMach" ]; then
211 OpenMachine
$SourceMach
214 # If source filename has wildcards ([, ], *, ?) do an mget
215 case "$SourceFile" in
217 verboseprint lcd
"$DestFile"
218 verboseprint mget
"$SourceFile"
219 verboseprint lcd
$OWD ;;
220 *) verboseprint get
"$SourceFile" "$DestFile" ;;
223 echo "Neither source machine \"$SourceMach\" "\
224 "nor destination machine \"$DestMach\" is local." 1>&2
230 # Start of main program
233 if [ "$1" = -h ]; then
235 "$name: do ftp transfers using rcp-style parameters.
236 Usage: $name <source> <destpath> or $name <source> [<source> ...] <destdir>
237 At least one of <source> and <destpath> must be the local system.
238 A remote filename is given as machinename:filename
239 If remote filenames contain wildcards, they will be globbed on the remote
240 machine. Make sure they are quoted when $name is invoked.
241 If the invoking user's .netrc file (see ftp(TC)) contains an entry for the
242 remote system with a login and password supplied, $name will log in using
243 the given login and password. If not, $name will login in as user
244 anonymous and with the user@localsystem as the password.
246 -c: check: do not overwrite files.
247 -d: create directories as needed.
248 -f: force: overwrite files (default).
250 -l: fail if there is no entry with login and password for the remote system,
251 instead of logging in as anonymous.
252 -n: log in as anonymous even if there is an entry for the remote system in
253 the user's .netrc file.
254 -r: read source/dest filename pairs from the standard input,
255 one pair per line, and copy files accordingly."
259 typeset
-i check
=0 createdirs
=0 readinput
=0 anon
=0 noanon
=0
261 while getopts :cdflnr Option
270 \?) echo "$OPTARG: invalid option."; exit 1;;
278 if istrue
$readinput; then
283 if [ $# -lt 2 ]; then
284 echo "$name: Not enough arguments. Use -h for help." 1>&2
287 CopyFiles
"$@" |
$FTP -nv