symbian-qemu-0.9.1-12/python-2.6.1/Demo/sockets/ftp.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 # A simple FTP client.
       
     2 #
       
     3 # The information to write this program was gathered from RFC 959,
       
     4 # but this is not a complete implementation!  Yet it shows how a simple
       
     5 # FTP client can be built, and you are welcome to extend it to suit
       
     6 # it to your needs...
       
     7 #
       
     8 # How it works (assuming you've read the RFC):
       
     9 #
       
    10 # User commands are passed uninterpreted to the server.  However, the
       
    11 # user never needs to send a PORT command.  Rather, the client opens a
       
    12 # port right away and sends the appropriate PORT command to the server.
       
    13 # When a response code 150 is received, this port is used to receive
       
    14 # the data (which is written to stdout in this version), and when the
       
    15 # data is exhausted, a new port is opened and a corresponding PORT
       
    16 # command sent.  In order to avoid errors when reusing ports quickly
       
    17 # (and because there is no s.getsockname() method in Python yet) we
       
    18 # cycle through a number of ports in the 50000 range.
       
    19 
       
    20 
       
    21 import sys, posix, string
       
    22 from socket import *
       
    23 
       
    24 
       
    25 BUFSIZE = 1024
       
    26 
       
    27 # Default port numbers used by the FTP protocol.
       
    28 #
       
    29 FTP_PORT = 21
       
    30 FTP_DATA_PORT = FTP_PORT - 1
       
    31 
       
    32 # Change the data port to something not needing root permissions.
       
    33 #
       
    34 FTP_DATA_PORT = FTP_DATA_PORT + 50000
       
    35 
       
    36 
       
    37 # Main program (called at the end of this file).
       
    38 #
       
    39 def main():
       
    40     hostname = sys.argv[1]
       
    41     control(hostname)
       
    42 
       
    43 
       
    44 # Control process (user interface and user protocol interpreter).
       
    45 #
       
    46 def control(hostname):
       
    47     #
       
    48     # Create control connection
       
    49     #
       
    50     s = socket(AF_INET, SOCK_STREAM)
       
    51     s.connect((hostname, FTP_PORT))
       
    52     f = s.makefile('r') # Reading the replies is easier from a file...
       
    53     #
       
    54     # Control loop
       
    55     #
       
    56     r = None
       
    57     while 1:
       
    58         code = getreply(f)
       
    59         if code in ('221', 'EOF'): break
       
    60         if code == '150':
       
    61             getdata(r)
       
    62             code = getreply(f)
       
    63             r = None
       
    64         if not r:
       
    65             r = newdataport(s, f)
       
    66         cmd = getcommand()
       
    67         if not cmd: break
       
    68         s.send(cmd + '\r\n')
       
    69 
       
    70 
       
    71 # Create a new data port and send a PORT command to the server for it.
       
    72 # (Cycle through a number of ports to avoid problems with reusing
       
    73 # a port within a short time.)
       
    74 #
       
    75 nextport = 0
       
    76 #
       
    77 def newdataport(s, f):
       
    78     global nextport
       
    79     port = nextport + FTP_DATA_PORT
       
    80     nextport = (nextport+1) % 16
       
    81     r = socket(AF_INET, SOCK_STREAM)
       
    82     r.bind((gethostbyname(gethostname()), port))
       
    83     r.listen(1)
       
    84     sendportcmd(s, f, port)
       
    85     return r
       
    86 
       
    87 
       
    88 # Send an appropriate port command.
       
    89 #
       
    90 def sendportcmd(s, f, port):
       
    91     hostname = gethostname()
       
    92     hostaddr = gethostbyname(hostname)
       
    93     hbytes = string.splitfields(hostaddr, '.')
       
    94     pbytes = [repr(port//256), repr(port%256)]
       
    95     bytes = hbytes + pbytes
       
    96     cmd = 'PORT ' + string.joinfields(bytes, ',')
       
    97     s.send(cmd + '\r\n')
       
    98     code = getreply(f)
       
    99 
       
   100 
       
   101 # Process an ftp reply and return the 3-digit reply code (as a string).
       
   102 # The reply should be a line of text starting with a 3-digit number.
       
   103 # If the 4th char is '-', it is a multi-line reply and is
       
   104 # terminate by a line starting with the same 3-digit number.
       
   105 # Any text while receiving the reply is echoed to the file.
       
   106 #
       
   107 def getreply(f):
       
   108     line = f.readline()
       
   109     if not line: return 'EOF'
       
   110     print line,
       
   111     code = line[:3]
       
   112     if line[3:4] == '-':
       
   113         while 1:
       
   114             line = f.readline()
       
   115             if not line: break # Really an error
       
   116             print line,
       
   117             if line[:3] == code and line[3:4] != '-': break
       
   118     return code
       
   119 
       
   120 
       
   121 # Get the data from the data connection.
       
   122 #
       
   123 def getdata(r):
       
   124     print '(accepting data connection)'
       
   125     conn, host = r.accept()
       
   126     print '(data connection accepted)'
       
   127     while 1:
       
   128         data = conn.recv(BUFSIZE)
       
   129         if not data: break
       
   130         sys.stdout.write(data)
       
   131     print '(end of data connection)'
       
   132 
       
   133 # Get a command from the user.
       
   134 #
       
   135 def getcommand():
       
   136     try:
       
   137         while 1:
       
   138             line = raw_input('ftp.py> ')
       
   139             if line: return line
       
   140     except EOFError:
       
   141         return ''
       
   142 
       
   143 
       
   144 # Call the main program.
       
   145 #
       
   146 main()