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