[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server/FTP - FTPServerChannel.py:1.1.2.13 FTPStatusMessages.py:1.1.2.6 RecvChannel.py:1.1.2.4 XmitChannel.py:1.1.2.3
Stephan Richter
srichter@cbu.edu
Fri, 5 Apr 2002 10:18:48 -0500
Update of /cvs-repository/Zope3/lib/python/Zope/Server/FTP
In directory cvs.zope.org:/tmp/cvs-serv20940/FTP
Modified Files:
Tag: Zope3-Server-Branch
FTPServerChannel.py FTPStatusMessages.py RecvChannel.py
XmitChannel.py
Log Message:
Changed Status messages mechanism.
=== Zope3/lib/python/Zope/Server/FTP/FTPServerChannel.py 1.1.2.12 => 1.1.2.13 ===
'cmd_rnto', 'cmd_size', 'cmd_stor', 'cmd_stru')
- # Define the reply code for non-authenticated responses
- not_auth_reply = (530, 1)
-
- # Define the reply code for an unrecognized command
- unknown_reply = (500, 0)
-
# Define the status messages
status_messages = status_msgs
@@ -94,7 +88,7 @@
self.username = ''
self.password = ''
- self.reply(220, 0, self.server.server_name)
+ self.reply('SERVER_READY', self.server.server_name)
############################################################
@@ -105,7 +99,7 @@
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
if self.client_dc:
self.client_dc.close()
- self.reply(226, 0, 'ABOR')
+ self.reply('TRANS_SUCCESS', 'ABOR')
def cmd_appe (self, args):
@@ -118,9 +112,9 @@
path = self._generatePath('../')
if self.server.filesystem.exists(path):
self.cwd = path
- self.reply(250, 0, 'CDUP')
+ self.reply('SUCCESS_250', 'CDUP')
else:
- self.reply(550, 2, path)
+ self.reply('ERR_NO_FILE', path)
def cmd_cwd(self, args):
@@ -128,32 +122,32 @@
path = self._generatePath(args)
if self.server.filesystem.exists(path):
self.cwd = path
- self.reply(250, 0, 'CWD')
+ self.reply('SUCCESS_250', 'CWD')
else:
- self.reply(550, 1, path)
+ self.reply('ERR_NO_DIR', path)
def cmd_dele(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
if not args:
- self.reply(500, 0, 'DELE')
+ self.reply('CMD_UNKNOWN', 'DELE')
else:
path = self._generatePath(args)
try:
self.server.filesystem.unlink(path)
- self.reply(250, 0, 'DELE')
+ self.reply('SUCCESS_250', 'DELE')
except:
- self.reply(550, 6)
+ self.reply('ERR_DELETE_FILE')
else:
- self.reply(550, 2, file)
+ self.reply('NO_FILE', file)
def cmd_help(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
- self.reply(214, flush=0)
+ self.reply('HELP_START')
self.write('Help goes here somewhen.\r\n')
- self.reply(214, 1)
+ self.reply('HELP_END')
def cmd_list(self, args):
@@ -162,10 +156,10 @@
try:
producer = self.getDirectoryList(args, 1)
except os.error, why:
- self.reply(550, 0, repr(why))
+ self.reply('ERR_NO_LIST', repr(why))
return
- self.reply(150, 0, self.type_map[self.transfer_mode])
+ self.reply('OPEN_DATA_CONN', self.type_map[self.transfer_mode])
self.createXmitChannel()
self.client_dc.push_with_producer(producer)
self.client_dc.close_when_done()
@@ -175,35 +169,35 @@
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
path = self._generatePath(args)
if not self.server.filesystem.isfile(path):
- self.reply(550, 3, path)
+ self.reply('ERR_IS_NOT_FILE', path)
else:
mtime = time.gmtime(
self.server.filesystem.stat(path)[stat.ST_MTIME]
)
- self.reply(213, 0, (mtime[0], mtime[1], mtime[2],
- mtime[3], mtime[4], mtime[5]) )
+ self.reply('FILE_DATE', (mtime[0], mtime[1], mtime[2],
+ mtime[3], mtime[4], mtime[5]) )
def cmd_mkd(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
if not args:
- self.reply(500, 0, 'MKD')
+ self.reply('CMD_UNKNOWN', 'MKD')
else:
path = self._generatePath(args)
try:
self.server.filesystem.mkdir(path)
- self.reply(257, 0, 'MKD')
+ self.reply('SUCCESS_257', 'MKD')
except:
- self.reply (550, 5)
+ self.reply('ERR_CREATE_DIR')
def cmd_mode(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
if len(args) == 1 and args in 'sS':
- self.reply(200, 3)
+ self.reply('MODE_OK')
else:
- self.reply(502)
+ self.reply('MODE_UNKNOWN')
def cmd_nlst(self, args):
@@ -216,18 +210,18 @@
try:
producer = self.getDirectoryList(args, 0)
except os.error, why:
- self.reply( 550, 0, (repr(why),) )
+ self.reply('ERR_NO_LIST', repr(why))
return
self.createXmitChannel()
self.client_dc.push_with_producer(producer)
self.client_dc.close_when_done()
- self.reply(150, 0, (self.type_map[self.transfer_mode],))
+ self.reply('OPEN_DATA_CONN', (self.type_map[self.transfer_mode],))
def cmd_noop(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
- self.reply(200, 0, ('NOOP'))
+ self.reply('SUCCESS_200', 'NOOP')
def cmd_pass(self, args):
@@ -237,9 +231,9 @@
self.authenticated, message = auth.authenticate(self.username,
self.password)
if self.authenticated:
- self.reply(230)
+ self.reply('LOGIN_SUCCESS')
else:
- self.reply(530, 2)
+ self.reply('LOGIN_MISMATCH')
self.close_when_done()
@@ -249,9 +243,9 @@
self.client_dc = None
port = pc.addr[1]
ip_addr = pc.control_channel.getsockname()[0]
- self.reply(227, args=( ','.join(ip_addr.split('.')),
- port/256,
- port%256 ) )
+ self.reply('PASV_MODE_MSG', (','.join(ip_addr.split('.')),
+ port/256,
+ port%256 ) )
def cmd_port(self, args):
@@ -266,27 +260,26 @@
# XXX: we should (optionally) verify that the
# ip number belongs to the client. [wu-ftpd does this?]
self.client_addr = (ip, port)
- self.reply(200, 0, 'PORT')
+ self.reply('SUCCESS_200', 'PORT')
except:
- return self.reply(550, 0, 'PORT')
-
+ return self.reply('CMD_UNKNOWN', 'PORT')
def cmd_pwd(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
- self.reply(257, 0, self.cwd)
+ self.reply('SUCCESS_257', self.cwd)
def cmd_quit(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
- self.reply(221)
+ self.reply('GOODBYE')
self.close_when_done()
def cmd_retr(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
if not args:
- self.reply(550, 0, 'RETR')
+ self.reply('CMD_UNKNOWN', 'RETR')
else:
path = self._generatePath(args)
@@ -299,9 +292,10 @@
mode = 'r'+self.type_mode_map[self.transfer_mode]
fd = self.server.filesystem.open(path, mode)
except IOError, why:
- self.reply(553, 0, repre(why))
+ self.reply('ERR_OPEN_READ', repre(why))
return
- self.reply(150, 1, (self.type_map[self.transfer_mode], path) )
+ self.reply('OPEN_CONN',
+ (self.type_map[self.transfer_mode], path) )
self.createXmitChannel()
if self.restart_position:
@@ -325,22 +319,22 @@
try:
pos = int(args)
except ValueError:
- self.reply(500, 0, 'REST')
+ self.reply('CMD_UNKNWON', 'REST')
self.restart_position = pos
- self.reply(350, 0, pos)
+ self.reply('RESTART_TRANSFER', pos)
def cmd_rmd(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
if not args:
- self.reply(500, 0, 'RMD')
+ self.reply('CMD_UNKNOWN', 'RMD')
else:
path = self._generatePath(args)
try:
self.server.filesystem.rmdir(path)
- self.reply(250, 0, 'RMD')
+ self.reply('SUCCESS_250', 'RMD')
except:
- self.reply(550, 7)
+ self.reply('ERR_DELETE_DIR')
def cmd_rnfr(self, args):
@@ -348,21 +342,21 @@
path = self._generatePath(args)
if self.server.filesystem.exists(path):
self._rnfr = path
- self.reply(350, 1)
+ self.reply('READY_FOR_DEST')
else:
- self.reply(550, 2, path)
+ self.reply('ERR_NO_FILE', path)
def cmd_rnto(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
path = self._generatePath(args)
if self._rnfr is None:
- self.reply(560, 1)
+ self.reply('ERR_RENAME')
try:
self.server.filesystem.rename(self._rnfr, path)
- self.reply(250, 0, 'RNTO')
+ self.reply('SUCCESS_250', 'RNTO')
except:
- self.reply(560, 0, (self._rnfr, rnto))
+ self.reply('ERR_RENAME', (self._rnfr, rnto))
self._rnfr = None
@@ -370,44 +364,44 @@
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
path = self._generatePath(args)
if not self.server.filesystem.isfile(path):
- self.reply(550, 2, path)
+ self.reply('ERR_NO_FILE', path)
else:
- self.reply(213, 1,
+ self.reply('FILE_SIZE',
self.server.filesystem.stat(path)[stat.ST_SIZE])
def cmd_stor(self, args, mode='wb'):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
if not args:
- self.reply(550, 0, 'STOR')
+ self.reply('CMD_UNKNOWN', 'STOR')
else:
path = self._generatePath(args)
if self.restart_position:
restart_position = 0
- self.reply(553, 2)
+ self.reply('ERR_RESTART_STOR')
return
# todo: handle that type flag
try:
fd = self.server.filesystem.open(args, mode)
except IOError, why:
- self.reply(553, 1, repr(why))
+ self.reply('ERR_OPEN_WRITE', repr(why))
return
- self.reply(150, 1, (self.type_map[self.transfer_mode], file) )
+ self.reply('OPEN_CONN', (self.type_map[self.transfer_mode], file) )
self.createRecvChannel(fd)
def cmd_stru(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
if len(args) == 1 and args in 'fF':
- self.reply(200, 2)
+ self.reply('STRU_OK')
else:
- self.reply(504, 1)
+ self.reply('STRU_UNKNOWN')
def cmd_syst(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
- self.reply(215, 0, self.system)
+ self.reply('SERVER_TYPE', self.system)
def cmd_type(self, args):
@@ -418,24 +412,24 @@
# no support for EBCDIC
# if t not in ['a','e','i','l']:
if t not in ['a','i','l']:
- self.reply(500, 0, args=('TYPE',))
+ self.reply('CMD_UNKNOWN', 'TYPE')
elif t == 'l' and (len(args) > 2 and args[2] != '8'):
- self.reply(504, 0)
+ self.reply('WRONG_BYTE_SIZE')
else:
if t == 'a':
self.transfer_mode = t
- self.reply(200, 1, self.type_map[t])
+ self.reply('TYPE_SET_OK', self.type_map[t])
def cmd_user(self, args):
'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
if len(args) > 1:
self.username = args
- self.reply(331) # Or whatever the code should be
+ self.reply('PASS_REQUIRED')
else:
- self.reply(500, 0, ('USER'))
+ self.reply('CMD_UNKNOWN', 'USER')
#
############################################################
=== Zope3/lib/python/Zope/Server/FTP/FTPStatusMessages.py 1.1.2.5 => 1.1.2.6 ===
status_msgs = {
- 150: ('Opening %s mode data connection for file list',
- 'Opening %s connection for %s',),
- 200: ('%s command successful.',
- 'Type set to %s.',
- 'STRU F Ok.',
- 'MODE S Ok.',),
- 213: ('%4d%02d%02d%02d%02d%02d', # A date
- '%d Bytes'), # Size
- 214: ('-The following commands are recognized',
- ''),
- 215: ('%s Type: %s',), # Server Type
- 220: ('%s FTP server (Zope Async/Thread V0.1) ready.',),
- 221: ('Goodbye.',),
- 226: ('%s command successful.',
- 'Transfer successful.'),
- 227: ('Entering Passive Mode (%s,%d,%d)',),
- 230: ('Login Successful.',),
- 250: ('%s command successful.',),
- 257: ('%s command successful.',
- "'%s' is the current directory.",),
- 331: ('Password required',),
- 350: ('Restarting at %d. Send STORE or RETRIEVE to initiate transfer.',
- 'File exists, ready for destination.',),
- 425: ("Can't build data connection",),
- 426: ('Connection closed; transfer aborted.',),
- 500: ("'%s': command not understood.",),
- 502: ("Unimplemented MODE type",),
- 504: ('Byte size must be 8',
- 'Unimplemented STRU type',),
- 530: ("You are not authorized to perform the '%s' command",
- 'Please log in with USER and PASS',
- 'The username and password do not match.',),
- 550: ('Could not list directory: %s',
- '%s: No such directory.',
- '%s: No such file.',
- '%s: Is not a file',
- 'Error creating file.',
- 'Error creating directory.',
- 'Error deleting file.',
- 'Error removing directory.'),
- 553: ('Could not open file for reading: %s',
- 'Could not open file for writing: %s',
- 'Restart on STOR not yet supported',),
-
- 560: ('Could not rename %s to %s.',
- 'No source filename specify. Call RNFR first.',),
+ 'OPEN_DATA_CONN' : '150 Opening %s mode data connection for file list',
+ 'OPEN_CONN' : '150 Opening %s connection for %s',
+ 'SUCCESS_200' : '200 %s command successful.',
+ 'TYPE_SET_OK' : '200 Type set to %s.',
+ 'STRU_OK' : '200 STRU F Ok.',
+ 'MODE_OK' : '200 MODE S Ok.',
+ 'FILE_DATE' : '213 %4d%02d%02d%02d%02d%02d',
+ 'FILE_SIZE' : '213 %d Bytes',
+ 'HELP_START' : '214-The following commands are recognized',
+ 'HELP_END' : '214 Help done.',
+ 'SERVER_TYPE' : '215 %s Type: %s',
+ 'SERVER_READY' : '220 %s FTP server (Zope Async/Thread V0.1) ready.',
+ 'GOODBYE' : '221 Goodbye.',
+ 'SUCCESS_226' : '226 %s command successful.',
+ 'TRANS_SUCCESS' : '226 Transfer successful.',
+ 'PASV_MODE_MSG' : '227 Entering Passive Mode (%s,%d,%d)',
+ 'LOGIN_SUCCESS' : '230 Login Successful.',
+ 'SUCCESS_250' : '250 %s command successful.',
+ 'SUCCESS_257' : '257 %s command successful.',
+ 'ALREADY_CURRENT' : "257 '%s' is the current directory.",
+ 'PASS_REQUIRED' : '331 Password required',
+ 'RESTART_TRANSFER' : '350 Restarting at %d. Send STORE or '
+ 'RETRIEVE to initiate transfer.',
+ 'READY_FOR_DEST' : '350 File exists, ready for destination.',
+ 'NO_DATA_CONN' : "425 Can't build data connection",
+ 'TRANSFER_ABORTED' : '426 Connection closed; transfer aborted.',
+ 'CMD_UNKNOWN' : "500 '%s': command not understood.",
+ 'MODE_UNKOWN' : '502 Unimplemented MODE type',
+ 'WRONG_BYTE_SIZE' : '504 Byte size must be 8',
+ 'STRU_UNKNOWN' : '504 Unimplemented STRU type',
+ 'NOT_AUTH' : "530 You are not authorized to perform the "
+ "'%s' command",
+ 'LOGIN_REQUIRED' : '530 Please log in with USER and PASS',
+ 'LOGIN_MISMATCH' : '530 The username and password do not match.',
+ 'ERR_NO_LIST' : '550 Could not list directory: %s',
+ 'ERR_NO_DIR' : '550 %s: No such directory.',
+ 'ERR_NO_FILE' : '550 %s: No such file.',
+ 'ERR_IS_NOT_FILE' : '550 %s: Is not a file',
+ 'ERR_CREATE_FILE' : '550 Error creating file.',
+ 'ERR_CREATE_DIR' : '550 Error creating directory.',
+ 'ERR_DELETE_FILE' : '550 Error deleting file.',
+ 'ERR_DELETE_DIR' : '550 Error removing directory.',
+ 'ERR_OPEN_READ' : '553 Could not open file for reading: %s',
+ 'ERR_OPEN_WRITE' : '553 Could not open file for writing: %s',
+ 'ERR_RESTART_STOR' : '553 Restart on STOR not yet supported',
+ 'ERR_RENAME' : '560 Could not rename %s to %s.',
+ 'ERR_RNFR_SOURCE' : '560 No source filename specify. Call RNFR first.',
}
=== Zope3/lib/python/Zope/Server/FTP/RecvChannel.py 1.1.2.3 => 1.1.2.4 ===
s.total_bytes_in.increment(self.bytes_in.as_long())
self.fd.close()
- self.channel.reply(226, 1)
+ self.channel.reply('TRANS_SUCCESS')
self.close()
=== Zope3/lib/python/Zope/Server/FTP/XmitChannel.py 1.1.2.2 => 1.1.2.3 ===
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-
-import asynchat
-
-
-class XmitChannel(asynchat.async_chat, object):
-
- # for an ethernet, you want this to be fairly large, in fact, it
- # _must_ be large for performance comparable to an ftpd. [64k] we
- # ought to investigate automatically-sized buffers...
- ac_out_buffer_size = 16384
-
- bytes_out = 0
-
- def __init__ (self, channel, client_addr=None):
- self.channel = channel
- self.client_addr = client_addr
- super(XmitChannel, self).__init__()
-
-
- def log (*args):
- pass
-
-
- def readable (self):
- return not self.connected
-
-
- def writable (self):
- return 1
-
-
- def send (self, data):
- result = super(XmitChannel, self).send(data)
- self.bytes_out = self.bytes_out + result
- return result
-
-
- def handle_error (self):
- # usually this is to catch an unexpected disconnect.
- # XXX: Helpfule for debugging
- import traceback
- traceback.print_exc()
- self.log_info ('unexpected disconnect on data xmit channel', 'error')
- try:
- self.close()
- except:
- pass
-
- # TODO: there's a better way to do this. we need to be able to
- # put 'events' in the producer fifo. to do this cleanly we need
- # to reposition the 'producer' fifo as an 'event' fifo.
-
- # dummy function to suppress warnings caused by some FTP clients
- def handle_connect(self):
- pass
-
-
- def close (self):
- c = self.channel
- s = c.server
- c.client_dc = None
- s.total_files_out.increment()
- s.total_bytes_out.increment (self.bytes_out)
- if not len(self.producer_fifo):
- c.reply(226, 1)
- elif not c.closed:
- c.reply(426)
- del c
- del s
- del self.channel
- asynchat.async_chat.close(self)
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+
+import asynchat
+
+
+class XmitChannel(asynchat.async_chat, object):
+
+ # for an ethernet, you want this to be fairly large, in fact, it
+ # _must_ be large for performance comparable to an ftpd. [64k] we
+ # ought to investigate automatically-sized buffers...
+ ac_out_buffer_size = 16384
+
+ bytes_out = 0
+
+ def __init__ (self, channel, client_addr=None):
+ self.channel = channel
+ self.client_addr = client_addr
+ super(XmitChannel, self).__init__()
+
+
+ def log (*args):
+ pass
+
+
+ def readable (self):
+ return not self.connected
+
+
+ def writable (self):
+ return 1
+
+
+ def send (self, data):
+ result = super(XmitChannel, self).send(data)
+ self.bytes_out = self.bytes_out + result
+ return result
+
+
+ def handle_error (self):
+ # usually this is to catch an unexpected disconnect.
+ # XXX: Helpfule for debugging
+ import traceback
+ traceback.print_exc()
+ self.log_info ('unexpected disconnect on data xmit channel', 'error')
+ try:
+ self.close()
+ except:
+ pass
+
+ # TODO: there's a better way to do this. we need to be able to
+ # put 'events' in the producer fifo. to do this cleanly we need
+ # to reposition the 'producer' fifo as an 'event' fifo.
+
+ # dummy function to suppress warnings caused by some FTP clients
+ def handle_connect(self):
+ pass
+
+
+ def close (self):
+ c = self.channel
+ s = c.server
+ c.client_dc = None
+ s.total_files_out.increment()
+ s.total_bytes_out.increment (self.bytes_out)
+ if not len(self.producer_fifo):
+ c.reply('TRANS_SUCCESS')
+ elif not c.closed:
+ c.reply('TRANSFER_ABORTED')
+ del c
+ del s
+ del self.channel
+ asynchat.async_chat.close(self)