[Zope-Checkins] CVS: Zope3/lib/python/Zope/Server/FTP - FTPServer.py:1.1.2.3 FTPServerChannel.py:1.1.2.3

Stephan Richter srichter@cbu.edu
Wed, 3 Apr 2002 04:46:57 -0500


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

Modified Files:
      Tag: Zope3-Server-Branch
	FTPServer.py FTPServerChannel.py 
Log Message:
More FTP server work done. It now can at least display a list of files in
a directory, however the simple FTP client in Unix still does not work.

I am getting closer though!


=== Zope3/lib/python/Zope/Server/FTP/FTPServer.py 1.1.2.2 => 1.1.2.3 ===
 from FTPServerChannel import FTPServerChannel
 from Zope.Server.ServerBase import ServerBase
+from Zope.Server.Counter import Counter
 
 from Zope.Server.VFS.UnixFileSystem import UnixFileSystem 
 from Zope.Server.Authentication.DictionaryAuthentication import \
@@ -32,6 +33,22 @@
     
     channel_class = FTPServerChannel
     SERVER_IDENT = 'Zope.Server.FTPServer'
+
+
+    def __init__(self, ip, port, task_dispatcher=None, adj=None, start=1,
+                 hit_log=None, verbose=0, socket_map=None):
+        super(FTPServer, self).__init__(ip, port, task_dispatcher=None,
+                                        adj=None, start=1, hit_log=None,
+                                        verbose=0, socket_map=None)
+
+        # statistics
+        self.total_sessions = Counter()
+        self.closed_sessions = Counter()
+        self.total_files_out = Counter()
+        self.total_files_in = Counter()
+        self.total_bytes_out = Counter()
+        self.total_bytes_in = Counter()
+        self.total_exceptions = Counter()
 
 
 if __name__ == '__main__':


=== Zope3/lib/python/Zope/Server/FTP/FTPServerChannel.py 1.1.2.2 => 1.1.2.3 === (407/507 lines abridged)
 """
 
+import os
+import socket
+
 from Zope.Server.ServerChannelBase import ServerChannelBase
 from FTPStatusMessages import status_msgs
 from FTPCommandParser import FTPCommandParser
@@ -23,6 +26,8 @@
 
 from IFTPCommandHandler import IFTPCommandHandler 
 from PassiveAcceptor import PassiveAcceptor
+from RecvChannel import RecvChannel
+from XmitChannel import XmitChannel
 
 
 class FTPServerChannel(ServerChannelBase):
@@ -32,21 +37,15 @@
     __implements__ = IFTPCommandHandler
 
     task_class = FTPTask
-    parser_class = FTPCommandParser
-
-
-    active_channels = {}        # Class-specific channel tracker
-    next_channel_cleanup = [0]  # Class-specific cleanup time
-
-
-    user_name = None
-    user_password = None
-    ascii_mode = 0
-    passive_mode = 0
-
+    parser_class = FTPCommandParser    
 
     system = ('UNIX', 'L8')
-    cwd = '/'
+
+    # comply with (possibly troublesome) RFC959 requirements
+    # This is necessary to correctly run an active data connection
+    # through a firewall that triggers on the source port (expected
+    # to be 'L-1', or 20 in the normal case).
+    bind_local_minus_one = 0
 
 
     type_map = {
@@ -64,30 +63,68 @@
             }
 
 

[-=- -=- -=- 407 lines omitted -=- -=- -=-]

+                self.passive_acceptor = None				
+            else:
+                # we're still waiting for a connect to the PASV port.
+                cdc = XmitChannel(self)
+
+        else:
+            # not in PASV mode.
+            ip, port = self.client_addr
+            cdc = XmitChannel(self, self.client_addr)
+            cdc.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+            if self.bind_local_minus_one:
+                cdc.bind(('', self.server.port - 1))
+            try:
+                cdc.connect ((ip, port))
+            except socket.error, why:
+                self.reply(425)
+
+        self.client_dc = cdc
+
+        
+    # pretty much the same as xmit, but only right on the verge of
+    # being worth a merge.
+    def createRecvChannel(self, fd):
+        pa = self.passive_acceptor
+        if pa:
+            if pa.ready:
+                # a connection has already been made.
+                conn, addr = pa.ready
+                cdc = RecvChannel(self, addr, fd)
+                cdc.set_socket (conn)
+                cdc.connected = 1
+                self.passive_acceptor.close()
+                self.passive_acceptor = None				
+            else:
+                # we're still waiting for a connect to the PASV port.
+                cdc = RecvChannel(self, None, fd)
+        else:
+            # not in PASV mode.
+            ip, port = self.client_addr
+            cdc = RecvChannel(self, self.client_addr, fd)
+            cdc.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+            try:
+                cdc.connect ((ip, port))
+            except socket.error, why:
+                self.reply(425)
+
+        self.client_dc = cdc
 
 
     def reply(self, code, pos=0, args=(), flush=1):