nftp.py

Peter Bosch (Peter.Bosch@pegasus.esprit.ec.org)
Wed, 23 Feb 94 12:55:08 +0100

I was tired of ftp's inability to traverse and retrieve directories
recursively so I wrote a small python script that solves this.

nftp.py works for normal (i.e. Unix standard) ftp-servers. I haven't
tested it on many ftp-servers.

peter.
--- Knip Knip ---
#!/usr/local/bin/python

from ftplib import *
from sys import *
import string, posix

ftp = 0

def get_dir(dir):
print 'Changing dir: ' + dir
try:
posix.mkdir(dir, 0777)
posix.chdir(dir)
except posix.error, (errno, detail):
stderr.write('nftp: Cannot make dir ' + dir + ': ' + \
detail + '\n')
exit(1)
files = []
ftp.retrlines('LIST', files.append)
for i in range(len(files)):
handle_file(files[i], 1)
posix.chdir('..')

def get_filedir(file):
# test the file type, try to cd to it
try:
ftp.cwd(file)
get_dir(file)
ftp.cwd('..')
except error_perm:
stdout.write('Retrieving: ' + file + '\n')
try:
f = open(file, 'w')
except IOError, (errno, detail):
stderr.write('nftp: Cannot create ' + file + ': ' + \
detail + '\n')
exit(1)
ftp.retrbinary('RETR ' + file, f.write, 1024)
f.close()

def handle_file(line, force):
if line[0:5] == 'total': return
if force == 0:
stdout.write(line + ' ? ')
c = string.lower(stdin.readline())
if c <> 'y\n' and c <> 'yes\n':
return
if string.find(line, '->') <> -1:
stderr.write('WARNING: Ignoring file: ' + line + '\n')
return
get_filedir(string.split(line)[-1])

def main():
global ftp
if len(argv) == 5:
debug = 0
offset = 0
elif len(argv) == 6 and argv[1] == '-d':
debug = 1
offset = 1
else:
stderr.write('Usage: nftp [-d] user passwd host dir\n')
exit(1)

user = argv[1 + offset]
passwd = argv[2 + offset]
host = argv[3 + offset]
dir = argv[4 + offset]

try:
ftp = FTP(host)
except socket.error, detail:
stderr.write('nftp: Cannot connect to ' + host + \
': ' + detail + '\n')
exit(1)

if debug: ftp.set_debuglevel(2)

try:
ftp.login(user, passwd)
except error_perm, detail:
stderr.write('nftp: Cannot login: ' + detail + '\n')
exit(1)
try:
ftp.cwd(dir)
except error_perm, detail:
stderr.write('nftp: Cannot chdir to ' + dir + \
': ' + detail + '\n')
exit(1)
try:
posix.mkdir(host, 0777)
except posix.error, (errno, detail):
pass
try:
posix.chdir(host)
except posix.error, (errno, detail):
stderr.write('nftp: Cannot chdir to ' + \
host + ': ' + detail + '\n')
exit(1)

try:
posix.mkdir(dir, 0777)
except posix.error, (errno, detail):
stderr.write('WARNING: ' + host + '/' + dir + \
' already exists\n')

try:
posix.chdir(dir)
except posix.error, (errno, detail):
stderr.write('nftp: Cannot chdir to ' + \
dir + ': ' + detail + '\n')
exit(1)

files = []
ftp.retrlines('LIST', files.append)
for i in range(len(files)):
handle_file(files[i], 0)
ftp.quit()

main()