#-*- coding:utf-8 -*-#!/user/bin/env.python#Author:Mr Wu
importsys,os,socketserver,hashlibfrom conf importsettingsfrom modules importauthendencateclassftp_server(socketserver.BaseRequestHandler):'''ftp server端'''
defhandle(self):try:
self.conn=self.requestwhileTrue:
user_msg= self.conn.recv(1024).decode()
auth_result=self.auth(user_msg)
status_code=auth_result[0]
self.conn.send(status_code.encode("utf-8"))if status_code == "400": continue
elif status_code == "200":
user_database= auth_result[1]
self.user_dir= user_database["home_dir"] #用户默认目录
self.home_dir = user_database["home_dir"] #用户家目录
self.limit_size = user_database["limit_size"] #用户磁盘配额
whileTrue:
command= self.conn.recv(1024).decode()
get_command=command.split()[0]ifhasattr(self,get_command):
func=getattr(self,get_command)
func(command)else:
self.conn.send("401".encode("utf-8"))exceptConnectionResetError as e:print(e)defget(self,command):'''下载文件'''
if len(command.split()) > 1:
filename= command.split()[1]
file_db= self.user_dir + r"\%s"%filenameifos.path.isfile(file_db):
file_total_size=os.stat(file_db).st_size
self.conn.send("201".encode("utf-8"))
status_code= self.conn.recv(1024).decode()if status_code == "402":
received_size=0elif status_code == "403":
self.conn.send("000".encode())
received_size= int(self.conn.recv(1024).decode())if received_size
self.conn.send("205".encode())
self.conn.recv(1024)else:
self.conn.send("405".encode())returnf= open(file_db,"rb")
m=hashlib.md5()
self.conn.send(str(file_total_size).encode())
self.conn.recv(1024)
f.seek(received_size)for line inf:
self.conn.send(line)
m.update(line)
f.close()
self.conn.send(m.hexdigest().encode())else:
self.conn.send("402".encode("utf-8"))else:
self.conn.send("401".encode("utf-8"))defput(self,command):'''上传文件'''
if len(command) > 1:
self.conn.send("201".encode())
file_name= command.split()[1]
file_db= self.user_dir + r"\%s"%file_name
file_total_size= int(self.conn.recv(1024).decode())ifos.path.isfile(file_db):
received_size=os.stat(file_db).st_sizeif received_size
self.conn.send("205".encode())else:
self.conn.send("405".encode())return
else:
received_size=0
self.conn.send("205".encode())
put_size= file_total_size -received_size
status_code= self.__get_size(put_size)
self.conn.recv(1024)if status_code == "202":
self.conn.send("202".encode())else:
self.conn.send("404".encode())returnself.conn.recv(1024)
self.conn.send(str(received_size).encode())
m=hashlib.md5()
f= open(file_db,"wb")
f.seek(received_size)while received_size
last_size= file_total_size -received_sizeif last_size < 1024:
size=last_sizeelse:
size= 1024data= self.conn.recv(1024)
received_size+=len(data)
f.write(data)
m.update(data)
f.close()
md5=m.hexdigest()
new_md5= self.conn.recv(1024).decode()if md5 ==new_md5:
self.conn.send("203".encode())else:
self.conn.send("401".encode())defcd(self,command):'''切换目录'''
if len(command) > 1:
dir_name= command.split()[1]
dir_path= self.user_dir + r"\%s"%dir_nameif dir_name == "..":if len(self.user_dir) >len(self.home_dir):
self.conn.send("201".encode())
self.user_dir=os.path.dirname(self.user_dir)else:
self.conn.send("401".encode())elifos.path.isdir(dir_path):
self.user_dir=dir_path
self.conn.send("201".encode())else:
self.conn.send("401".encode())else:
self.conn.send("401".encode())defdir(self,command):'''查看当前目录下的文件'''
if command == "dir":
self.conn.send("201".encode())
self.conn.recv(1024)
data= os.popen("dir %s"%self.user_dir)
self.conn.send(data.read().encode())else:print("401".encode())defmkdir(self,command):'''创建目录'''
if len(command) > 1:
filename= command.split()[1]
dir_path= self.user_dir + r"\%s"%filenameif notos.path.isdir(dir_path):
self.conn.send("201".encode())
os.popen("mkdir %s"%dir_path)else:
self.conn.send("403".encode())else:
self.conn.send("401".encode())defpwd(self,command):'''查看当前用户路径'''
if command == "pwd":
self.conn.send("201".encode())
data=self.user_dir
self.conn.recv(1024)
self.conn.send(data.encode())else:
self.conn.send("401".encode())defauth(self,user_msg):'''用户登陆'''obj=authendencate.authendencate(user_msg)
auth_result=obj.auth_user()if notauth_result:return "400"
else:return "200",auth_resultdef __get_size(self,file_size):'''计算目录空间大小'''dir_size= os.stat(self.home_dir).st_size +file_sizeif dir_size
else:return "404"