[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server/FTP - FTPServerChannel.py:1.1.2.6 FTPStatusMessages.py:1.1.2.3 FileProducer.py:1.1.2.2 RecvChannel.py:1.1.2.2

Stephan Richter srichter@cbu.edu
Wed, 3 Apr 2002 07:12:40 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/Server/FTP
In directory cvs.zope.org:/tmp/cvs-serv17142/lib/python/Zope/Server/FTP

Modified Files:
      Tag: Zope3-Server-Branch
	FTPServerChannel.py FTPStatusMessages.py FileProducer.py 
	RecvChannel.py 
Log Message:
Okay, I think the basic funcationality of an FTP server is now mapped. 

Here are some bigger issues left to solve:

- We still need a better authentication mechanism; right now the authenti-
  cated user can do everything the server user can do.

- I am not using Tasks for the commands that could potentially take a 
  while. I think all commands should be started in the Channel, and as soon
  as a FileSystem access comes up, we switch to a task. Shane, what do you
  think?


=== Zope3/lib/python/Zope/Server/FTP/FTPServerChannel.py 1.1.2.5 => 1.1.2.6 ===
 
 import os
+import stat
 import socket
+import time
 
 from Zope.Server.ServerChannelBase import ServerChannelBase
 from FTPStatusMessages import status_msgs
@@ -48,6 +50,8 @@
     # to be 'L-1', or 20 in the normal case).
     bind_local_minus_one = 0
 
+    restart_position = 0
+
 
     type_map = {
             'a':'ASCII',
@@ -147,7 +151,7 @@
 
     def cmd_cdup(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
-        path = self.server.filesystem.normalize(self.cwd+'../')
+        path = self._generatePath('../')
         if self.server.filesystem.exists(path):
             self.cwd = path
             self.reply(250, 0, 'CDUP')
@@ -155,10 +159,9 @@
             self.reply(550, 2, path)
             
 
-    def cmd_cwd (self, args):
+    def cmd_cwd(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
-        path = os.path.join(self.cwd, args)
-        path = os.path.normpath(path)
+        path = self._generatePath(args)
         if self.server.filesystem.exists(path):
             self.cwd = path
             self.reply(250, 0, 'CWD')
@@ -168,17 +171,16 @@
 
     def cmd_dele(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
-        args = args.split()
-        if len(args) != 1:
+        if not args:
             self.reply(500, 0, 'DELE')
         else:
-            file = args[1]
-            if self.server.filesystem.isfile(file):
-                try:
-                    self.server.filesystem.unlink(file)
-                    self.reply(250, 0, 'DELE')
-                except:
-                    self.reply(550, 4)
+            path = self._generatePath(args)
+
+            try:
+                self.server.filesystem.unlink(file)
+                self.reply(250, 0, 'DELE')
+            except:
+                self.reply(550, 4)
             else:
                 self.reply(550, 2, file)
 
@@ -205,23 +207,23 @@
         self.client_dc.close_when_done()
 
 
-    def cmd_mdtm (self, args):
+    def cmd_mdtm(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
         if not self.server.filesystem.isfile (args):
             self.reply(550, 3, filename)
         else:
             mtime = time.gmtime(self.server.filesystem.stat(args)[stat.ST_MTIME])
-            self.reply( 213, 0, (mtime[0], mtime[1], mtime[2],
-                                 mtime[3], mtime[4], mtime[5]) )
+            self.reply(213, 0, (mtime[0], mtime[1], mtime[2],
+                                mtime[3], mtime[4], mtime[5]) )
 
 
     def cmd_mkd(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
-        args = args.split()
-        if len(args) != 1:
+        if not args:
             self.reply(500, 0, 'MKD')
         else:
-            path = args[1]
+            path = self._generatePath(args)
+            
             try:
                 self.server.filesystem.mkdir(path)
                 self.reply(257, 0, 'MKD')
@@ -263,17 +265,14 @@
 
     def cmd_pass(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
-        if len(args) > 1:
-            self.password = args
-            auth = self.server.auth_source
-            self.user = auth.authenticate(self.username, self.password)
-            if self.user is not self.server.auth_source.anonymous_user:
-                self.reply(230)
-            else:
-                self.reply(530, 2)
+        self.password = args
+        auth = self.server.auth_source
+        self.user = auth.authenticate(self.username, self.password)
+        if self.user is not self.server.auth_source.anonymous_user:
+            self.reply(230)
         else:
-            self.reply(500, 0, ('PASS'))
-        
+            self.reply(530, 2)
+            self.close_when_done()
 
 
     def cmd_pasv(self, args):
@@ -320,11 +319,7 @@
         if not args:
             self.reply(550, 0, 'RETR')
         else:
-            # Get the right source path.
-            if args.startswith('/'):
-                path = args
-            else:
-                path = os.path.join(self.cwd, args)
+            path = self._generatePath(args)
                 
             if not self.server.filesystem.isfile(path):
                 #self.log_info ('checking %s' % file)
@@ -356,29 +351,10 @@
                 self.client_dc.close_when_done()
                 
 
-    def cmd_stor (self, args, mode='wb'):
-        'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
-        if not args:
-            self.reply(550, 0, 'STOR')
-        else:
-            if self.restart_position:
-                restart_position = 0
-                self.reply(553, 2)
-                return
-            # todo: handle that type flag
-            try:
-                fd = self.open(args, mode)
-            except IOError, why:
-                self.reply(553, 1, repr(why))
-                return
-            self.reply(150, 1, (self.type_map[self.current_mode], file) )
-            self.createRecvChannel(fd)
-
-
     def cmd_rest (self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
         try:
-            pos = int(line)
+            pos = int(args)
         except ValueError:
             self.reply(500, 0, 'REST')
         self.restart_position = pos
@@ -387,25 +363,47 @@
 
     def cmd_rmd(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
-        args = args.split()
-        if len(args) != 1:
-            self.reply(500, 0, 'DELE')
+        if not args:
+            self.reply(500, 0, 'RMD')
         else:
-            path = args[1]
+            path = self._generatePath(args)
+            print path
             try:
                 self.server.filesystem.rmdir(path)
-                self.reply(250, 0, 'RMD;')
+                self.reply(250, 0, 'RMD')
             except:
                 self.reply(550, 7)
 
 
     def cmd_size(self, args):
         'See Zope.Server.FTP.IFTPCommandHandler.IFTPCommandHandler'
-        if not self.server.filesystem.isfile(args):
-            self.reply(550, 2, filename)
+        path = self._generatePath(args)
+        if not self.server.filesystem.isfile(path):
+            self.reply(550, 2, path)
         else:
             self.reply(213, 1,
-                       self.server.filesystem.stat(filename)[stat.ST_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')
+        else:
+            path = self._generatePath(args)
+            
+            if self.restart_position:
+                restart_position = 0
+                self.reply(553, 2)
+                return
+            # todo: handle that type flag
+            try:
+                fd = self.server.filesystem.open(args, mode)
+            except IOError, why:
+                self.reply(553, 1, repr(why))
+                return
+            self.reply(150, 1, (self.type_map[self.transfer_mode], file) )
+            self.createRecvChannel(fd)
 
 
     def cmd_stru(self, args):
@@ -451,6 +449,15 @@
     #
     ############################################################
 
+    def _generatePath(self, args):
+        # Get the right source path.
+        if args.startswith('/'):
+            path = args
+        else:
+            path = os.path.join(self.cwd, args)
+        path = os.path.normpath(path)
+        return path
+    
 
     def newPassiveAcceptor(self):
             # ensure that only one of these exists at a time.


=== Zope3/lib/python/Zope/Server/FTP/FTPStatusMessages.py 1.1.2.2 => 1.1.2.3 ===
           'MODE S Ok.',),
     213: ('%4d%02d%02d%02d%02d%02d', # A date
-          '%d'), # Size
+          '%d Bytes'), # Size
     214: ('-The following commands are recognized',
           ''),
     215: ('%s Type: %s',),  # Server Type


=== Zope3/lib/python/Zope/Server/FTP/FileProducer.py 1.1.2.1 => 1.1.2.2 ===
     block_size = 16384
 
-    def __init__ (self, server, dc, fd):
+    def __init__(self, server, dc, fd):
         self.fd = fd
         self.done = 0
 
         
-    def more (self):
+    def more(self):
         if self.done:
             return ''
         else:
-            block = self.fd.read (self.block_size)
+            block = self.fd.read(self.block_size)
             if not block:
                 self.fd.close()
                 self.done = 1


=== Zope3/lib/python/Zope/Server/FTP/RecvChannel.py 1.1.2.1 => 1.1.2.2 ===
 """
 import asyncore
-
+from Zope.Server.Counter import Counter
         
 class RecvChannel(asyncore.dispatcher):
     """ """
@@ -26,7 +26,7 @@
         self.client_addr = client_addr
         self.fd = fd
         asyncore.dispatcher.__init__ (self)
-        self.bytes_in = counter()
+        self.bytes_in = Counter()
 
         
     def log (self, *ignore):