Python很简单,python简单易学
Python版本
实现了比之前的xxftp更多更完善的功能
1、继续支持多用户
2、继续支持虚拟目录
3、增加支持用户根目录以及映射虚拟目录的权限设置
4、增加支持限制用户根目录或者虚拟目录的空间大小
xxftp的特点
1、开源、跨平台
2、简单、易用
3、不需要数据库
4、可扩展性超强
5、你可以免费使用xxftp假设自己的私人文件传送协议服务器
匿名帐号可以使用!
匿名根目录只读,映射了一个虚拟目录,可以上传文件但不允许更改!
使用方法
跟用英语字母表中第三个字母语言写的xxftp使用方法一样
文件传送协议服务器目录结构
-/root
-xxftp欢迎
再见
-用户数字一(one)
-.xxftp
-密码
-.
-用户注射毒品
-.xxftp
-密码
-.
匿名的源代码代码如下:
导入套接字、线程、操作系统、系统、时间
导入数据库,平台,统计
listen_ip=localhost
listen_port=21
conn_list=[]
root_dir= ./home
max_connections=500
conn_timeout=120
classFtpConnection(线程。螺纹):
def__init__(self,fd):
threading.Thread.__init__(self)
self.fd=fd
自运行=真
self.setDaemon(True)
self.alive_time=time.time()
self.option_utf8=False
自我认同=错误
self.option_pasv=True
self.username=
defprocess(self,cmd,arg):
cmd=cmd。upper();
ifself.option_utf8:
arg=unicode(arg, utf8 ).编码(系统。getfile系统编码())
print ,cmd,arg,self.fd
#命令
ifcmd==BYEorcmd==QUIT:
ifos。路径。存在(root _ dir /xxftp。再见’):
self.message(221,open(root_dir /xxftp.goodbye ).read())
else:
self.message(221,’再见!)国家统计局
p;
self.running=False
return
elifcmd=="USER":
#SetAnonymousUser
ifarg=="":arg="anonymous"
forcinarg:
ifnotc.isalpha()andnotc.isdigit()andc!="_":
self.message(530,"Incorrectusername.")
return
self.username=arg
self.home_dir=root_dir+"/"+self.username
self.curr_dir="/"
self.curr_dir,self.full_path,permission,self.vdir_list,\
limit_size,is_virtual=self.parse_path("/")
ifnotos.path.isdir(self.home_dir):
self.message(530,"User"+self.username+"notexists.")
return
self.pass_path=self.home_dir+"/.xxftp/password"
ifos.path.isfile(self.pass_path):
self.message(331,"Passwordrequiredfor"+self.username)
else:
self.message(230,"Identified!")
self.identified=True
return
elifcmd=="PASS":
ifopen(self.pass_path).read()==hashlib.md5(arg).hexdigest():
self.message(230,"Identified!")
self.identified=True
else:
self.message(530,"Notidentified!")
self.identified=False
return
elifnotself.identified:
self.message(530,"PleaseloginwithUSERandPASS.")
return
self.alive_time=time.time()
finish=True
ifcmd=="NOOP":
self.message(200,"ok")
elifcmd=="TYPE":
self.message(200,"ok")
elifcmd=="SYST":
self.message(200,"UNIX")
elifcmd=="EPSV"orcmd=="PASV":
self.option_pasv=True
try:
self.data_fd=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.data_fd.bind((listen_ip,0))
self.data_fd.listen(1)
ip,port=self.data_fd.getsockname()
ifcmd=="EPSV":
self.message(229,"EnteringExtendedPassiveMode("+str(port)+")")
else:
ipnum=socket.inet_aton(ip)
self.message(227,"EnteringPassiveMode(%s,%u,%u)."%
(",".join(ip.split(".")),(port>>8&0xff),(port&0xff)))
except:
self.message(500,"failedtocreatedatasocket.")
elifcmd=="EPRT":
self.message(500,"implementEPRTlater...")
elifcmd=="PORT":
self.option_pasv=False
self.data_fd=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s=arg.split(",")
self.data_ip=".".join(s[:4])
self.data_port=int(s[4])*256+int(s[5])
self.message(200,"ok")
elifcmd=="PWD"orcmd=="XPWD":
ifself.curr_dir=="":self.curr_dir="/"
self.message(257,'"'+self.curr_dir+'"')
elifcmd=="LIST"orcmd=="NLST":
ifarg!=""andarg[0]=="-":arg=""#omitparameters
remote,local,perm,vdir_list,limit_size,is_virtual=self.parse_path(arg)
ifnotos.path.exists(local):
self.message(550,"failed.")
return
ifnotself.establish():return
self.message(150,"ok")
forvinvdir_list:
f=v[0]
ifself.option_utf8:
f=unicode(f,sys.getfilesystemencoding()).encode("utf8")
ifcmd=="NLST":
info=f+"\r\n"
else:
info="d%s%s-------%04u%8s%8s%8lu%s%s\r\n"%(
"r"if"read"inpermelse"-",
"w"if"write"inpermelse"-",
1,"0","0",0,
time.strftime("%b%d%Y",time.localtime(time.time())),
f)
self.data_fd.send(info)
forfinos.listdir(local):
iff[0]==".":continue
path=local+"/"+f
ifself.option_utf8:
f=unicode(f,sys.getfilesystemencoding()).encode("utf8")
ifcmd=="NLST":
info=f+"\r\n"
else:
st=os.stat(path)
info="%s%s%s-------%04u%8s%8s%8lu%s%s\r\n"%(
"-"ifos.path.isfile(path)else"d",
"r"if"read"inpermelse"-",
"w"if"write"inpermelse"-",
1,"0","0",st[stat.ST_SIZE],
time.strftime("%b%d%Y",time.localtime(st[stat.ST_MTIME])),
f)
self.data_fd.send(info)
self.message(226,"Limitsize:"+str(limit_size))
self.data_fd.close()
self.data_fd=0
elifcmd=="REST":
self.file_pos=int(arg)
self.message(250,"ok")
elifcmd=="FEAT":
features="211-Features:\r\nSITES\r\nEPRT\r\nEPSV\r\nMDTM\r\nPASV\r\n"\
"RESTSTREAM\r\nSIZE\r\nUTF8\r\n211End\r\n"
self.fd.send(features)
elifcmd=="OPTS":
arg=arg.upper()
ifarg=="UTF8ON":
self.option_utf8=True
self.message(200,"ok")
elifarg=="UTF8OFF":
self.option_utf8=False
self.message(200,"ok")
else:
self.message(500,"unrecognizedoption")
elifcmd=="CDUP":
finish=False
arg=".."
else:
finish=False
iffinish:return
#Parseargument(It'sapath)
ifarg=="":
self.message(500,"where'smyargument?")
return
remote,local,permission,vdir_list,limit_size,is_virtual=\
self.parse_path(arg)
#cannotdoanythingtovirtualdirectory
ifis_virtual:permission="none"
can_read,can_write,can_modify="read"inpermission,"write"inpermission,"modify"inpermission
newpath=local
try:
ifcmd=="CWD":
if(os.path.isdir(newpath)):
self.curr_dir=remote
self.full_path=newpath
self.message(250,'"'+remote+'"')
else:
self.message(550,"failed")
elifcmd=="MDTM":
ifos.path.exists(newpath):
self.message(213,time.strftime("%Y%m%d%I%M%S",time.localtime(
os.path.getmtime(newpath))))
else:
self.message(550,"failed")
elifcmd=="SIZE":
self.message(231,os.path.getsize(newpath))
elifcmd=="XMKD"orcmd=="MKD":
ifnotcan_modify:
self.message(550,"permissiondenied.")
return
os.mkdir(newpath)
self.message(250,"ok")
elifcmd=="RNFR":
ifnotcan_modify:
self.message(550,"permissiondenied.")
return
self.temp_path=newpath
self.message(350,"renamefrom"+remote)
elifcmd=="RNTO":
os.rename(self.temp_path,newpath)
self.message(250,"RNTOto"+remote)
elifcmd=="XRMD"orcmd=="RMD":
ifnotcan_modify:
self.message(550,"permissiondenied.")
return
os.rmdir(newpath)
self.message(250,"ok")
elifcmd=="DELE":
ifnotcan_modify:
self.message(550,"permissiondenied.")
return
os.remove(newpath)
self.message(250,"ok")
elifcmd=="RETR":
ifnotos.path.isfile(newpath):
self.message(550,"failed")
return
ifnotcan_read:
self.message(550,"permissiondenied.")
return
ifnotself.establish():return
self.message(150,"ok")
f=open(newpath,"rb")
whileself.running:
self.alive_time=time.time()
data=f.read(8192)
iflen(data)==0:break
self.data_fd.send(data)
f.close()
self.data_fd.close()
self.data_fd=0
self.message(226,"ok")
elifcmd=="STOR"orcmd=="APPE":
ifnotcan_write:
self.message(550,"permissiondenied.")
return
ifos.path.exists(newpath)andnotcan_modify:
self.message(550,"permissiondenied.")
return
#Checkspacesizeremained!
used_size=0
iflimit_size>0:
used_size=self.get_dir_size(os.path.dirname(newpath))
ifnotself.establish():return
self.message(150,"ok")
f=open(newpath,("ab"ifcmd=="APPE"else"wb"))
whileself.running:
self.alive_time=time.time()
data=self.data_fd.recv(8192)
iflen(data)==0:break
iflimit_size>0:
used_size=used_size+len(data)
ifused_size>limit_size:break
f.write(data)
f.close()
self.data_fd.close()
self.data_fd=0
iflimit_size>0andused_size>limit_size:
self.message(550,"Exceedinguserspacelimit:"+str(limit_size)+"bytes")
else:
self.message(226,"ok")
else:
self.message(500,cmd+"notimplemented")
except:
self.message(550,"failed.")
defestablish(self):
ifself.data_fd==0:
self.message(500,"nodataconnection")
returnFalse
ifself.option_pasv:
fd=self.data_fd.accept()[0]
self.data_fd.close()
self.data_fd=fd
else:
try:
self.data_fd.connect((self.data_ip,self.data_port))
except:
self.message(500,"failedtoestablishdataconnection")
returnFalse
returnTrue
defread_virtual(self,path):
vdir_list=[]
path=path+"/.xxftp/virtual"
ifos.path.isfile(path):
forvinopen(path,"r").readlines():
items=v.split()
items[1]=items[1].replace("$root",root_dir)
vdir_list.append(items)
returnvdir_list
defget_dir_size(self,folder):
size=0
forpath,dirs,filesinos.walk(folder):
forfinfiles:
size+=os.path.getsize(os.path.join(path,f))
returnsize
defread_size(self,path):
size=0
path=path+"/.xxftp/size"
ifos.path.isfile(path):
size=int(open(path,"r").readline())
returnsize
defread_permission(self,path):
permission="read,write,modify"
path=path+"/.xxftp/permission"
ifos.path.isfile(path):
permission=open(path,"r").readline()
returnpermission
defparse_path(self,path):
ifpath=="":path="."
ifpath[0]!="/":
path=self.curr_dir+"/"+path
s=os.path.normpath(path).replace("\\","/").split("/")
local=self.home_dir
#resetdirectorypermission
vdir_list=self.read_virtual(local)
limit_size=self.read_size(local)
permission=self.read_permission(local)
remote=""
is_virtual=False
fornameins:
name=name.lstrip(".")
ifname=="":continue
remote=remote+"/"+name
is_virtual=False
forvinvdir_list:
ifv[0]==name:
permission=v[2]
local=v[1]
limit_size=self.read_size(local)
is_virtual=True
ifnotis_virtual:local=local+"/"+name
vdir_list=self.read_virtual(local)
return(remote,local,permission,vdir_list,limit_size,is_virtual)
defrun(self):
'''ConnectionProcess'''
try:
iflen(conn_list)>max_connections:
self.message(500,"toomanyconnections!")
self.fd.close()
self.running=False
return
#WelcomeMessage
ifos.path.exists(root_dir+"/xxftp.welcome"):
self.message(220,open(root_dir+"/xxftp.welcome").read())
else:
self.message(220,"xxftp(Python)www.xiaoxia.org")
#CommandLoop
line=""
whileself.running:
data=self.fd.recv(4096)
iflen(data)==0:break
line+=data
ifline[-2:]!="\r\n":continue
line=line[:-2]
space=line.find("")
ifspace==-1:
self.process(line,"")
else:
self.process(line[:space],line[space+1:])
line=""
except:
print"error",sys.exc_info()
self.running=False
self.fd.close()
print"connectionend",self.fd,"user",self.username
defmessage(self,code,s):
'''SendFtpMessage'''
s=str(s).replace("\r","")
ss=s.split("\n")
iflen(ss)>1:
r=(str(code)+"-")+("\r\n"+str(code)+"-").join(ss[:-1])
r+="\r\n"+str(code)+""+ss[-1]+"\r\n"
else:
r=str(code)+""+ss[0]+"\r\n"
ifself.option_utf8:
r=unicode(r,sys.getfilesystemencoding()).encode("utf8")
self.fd.send(r)
defserver_listen():
globalconn_list
listen_fd=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
listen_fd.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
listen_fd.bind((listen_ip,listen_port))
listen_fd.listen(1024)
conn_lock=threading.Lock()
print"ftpdislisteningon",listen_ip+":"+str(listen_port)
whileTrue:
conn_fd,remote_addr=listen_fd.accept()
print"connectionfrom",remote_addr,"conn_list",len(conn_list)
conn=FtpConnection(conn_fd)
conn.start()
conn_lock.acquire()
conn_list.append(conn)
#checktimeout
try:
curr_time=time.time()
forconninconn_list:
ifint(curr_time-conn.alive_time)>conn_timeout:
ifconn.running==True:
conn.fd.shutdown(socket.SHUT_RDWR)
conn.running=False
conn_list=[connforconninconn_listifconn.running]
except:
printsys.exc_info()
conn_lock.release()
defmain():
server_listen()
if__name__=="__main__":
main()
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。