# FTP#mget, FTP#mput

**URL:** <https://www.ruby-forum.com/t/ftp-mget-ftp-mput/60057>\
**Category:** Ruby\
**Created:** [May 9, 2006, 9:23pm UTC](https://www.ruby-forum.com/t/ftp-mget-ftp-mput/60057 "2006-05-09T21:23:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [May 9, 2006, 9:23pm UTC](https://www.ruby-forum.com/t/ftp-mget-ftp-mput/60057/1 "2006-05-09T21:23:48Z")

</div>

Hi all,

Is there a method in Net::FTP that corresponds to ftp’s mget and mput  
functions?

If not, is there any chance of adding this to ftp.rb?

Thanks,

Dan

This communication is the property of Qwest and may contain confidential  
or  
privileged information. Unauthorized use of this communication is  
strictly  
prohibited and may be unlawful. If you have received this communication  
in error, please immediately notify the sender by reply e-mail and  
destroy  
all copies of the communication and any attachments.

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [May 9, 2006, 9:29pm UTC](https://www.ruby-forum.com/t/ftp-mget-ftp-mput/60057/2 "2006-05-09T21:29:58Z")

</div>

On Wed, 10 May 2006, Daniel B. wrote:

> 

this grabs directories if you give it something like

ftpget ftp://host/dir/dir2/\*

so it’s similar to mget

#!/dmsp/reference/bin/ruby  
require ‘net/ftp’  
require ‘uri’  
require ‘yaml’

def uriparse uri  
unless uri =~ %r/^ftp/  
host, path = uri.split %r|:/+|o  
URI::parse “ftp://#{ host }/#{ path }”  
else  
URI::parse uri  
end  
end

abort “#{ $0 } srcuri [srcuris]+ dst” if ARGV.empty?  
user = ENV[“FTP\_USER”] || “anonymous”  
password = ENV[“FTP\_PASS”] || ENV[“FTP\_PASSWORD”] || “removed\_email\_address@domain.invalid”  
debug = ENV[‘FTP\_DEBUG’]

ARGV \<\< ‘.’ if ARGV.size == 1  
dest = ARGV.pop  
lpaths = []

while((src = ARGV.shift))  
src = uriparse src  
Net::FTP.open(src.host) do |ftp|  
ftp.debug\_mode = true if debug  
ftp.login user, password  
ftp.passive = true  
ftp.binary = true

```
 paths = []

 if src.path =~ %r|\*$|o
   dir = File::dirname(src.path)
   ftp.list(src.path) do |listing|
     path = listing.split(%r/\s+/o).last
     paths << File::join(dir, path)
   end
 else
   paths << src.path
 end

 paths.each do |path|
   lpath =
     if test ?d, dest
       File::join(dest, File::basename(path))
     else
       dest
     end
   ftp.getbinaryfile path, lpath
   lpaths << lpath
 end

```

end  
end

y lpaths

-a

---

<div class="post-metadata">

**Author:** ![danielb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/c57346/32.png) [@danielb](https://www.ruby-forum.com/u/danielb)\
**Post date:** [May 9, 2006, 9:33pm UTC](https://www.ruby-forum.com/t/ftp-mget-ftp-mput/60057/3 "2006-05-09T21:33:33Z")

</div>

On Wed, 10 May 2006, Daniel B. wrote:

> Hi all,
> 
> Is there a method in Net::FTP that corresponds to ftp’s mget and mput  
> functions?
> 
> If not, is there any chance of adding this to ftp.rb?
> 
> Thanks,
> 
> Dan

this does something like mput

#!/dmsp/reference/bin/ruby  
require “net/ftp”  
require “uri”  
require “socket”  
require “yaml”

def uriparse uri  
unless uri =~ %r/^ftp/  
host, path = uri.split %r|:/+|o  
URI::parse “ftp://#{ host }/#{ path }”  
else  
URI::parse uri  
end  
end

abort “#{ $0 } src [srcs]+ dsturi” if ARGV.empty?  
user = ENV[“FTP\_USER”] || “anonymous”  
password = ENV[“FTP\_PASS”] || ENV[“FTP\_PASSWORD”] || “removed\_email\_address@domain.invalid”  
debug = ENV[“FTP\_DEBUG”]  
srcs, uri = ARGV[0…-2], ARGV[-1]

uri = uriparse uri  
host, hostdest = uri.host, uri.path  
rpaths = []  
hostname, pid = Socket::gethostname, Process::pid

Net::FTP.open(host) do |ftp|  
ftp.debug\_mode = true if debug  
ftp.login user, password  
ftp.passive = true  
ftp.binary = true

srcs.each do |src|  
dest =  
if hostdest =~ %r|/+\s\*$|o or srcs.size \> 1  
File::join(hostdest, File::basename(src))  
else  
hostdest  
end  
destdir = File::dirname dest

```
 destdirs = []
 d = nil
 destdirs.unshift(d) while((d = File::dirname(d || dest)) !~ 

```

%r|^\s\*/+\s\*$|o)

```
 dirname, basename = File::dirname(dest), File::basename(dest)
 tmp = File::join(dirname, ".#{ basename }.#{ hostname }.#{ pid 

```

}.ftp")

```
 if debug
   state = <<-eos
   |@src <#{ src }>
   |@host <#{ host }>
   |@dest <#{ dest }>
   |@destdir <#{ destdir }>
   |@destdirs <#{ destdirs.inspect }>
   |@tmp <#{ tmp.inspect }>
   eos
   state.gsub!(%r/^\s*\|/o,'')
   puts state
 end

 destdirs.each{|d| begin; ftp.mkdir d; rescue Net::FTPPermError; 

```

end}  
ftp.putbinaryfile src, tmp  
ftp.rename tmp, dest  
rpaths \<\< dest  
end  
end

y rpaths

-a
