Python很简单,python简单易学

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: