|
#!/usr/bin/env Python2
# Coding:utf-8
Import Os,socket,threading,time
#import Traceback
Allow_delete = False
Local_ip = Socket.gethostbyname (Socket.gethostname ())
Local_port = 8888
Currdir=os.path.abspath ('. ')
Class Ftpserverthread (threading. Thread):
def __init__ (self, (CONN,ADDR)):
Self.conn=conn
Self.addr=addr
Self.basewd=currdir
Self.cwd=self.basewd
Self.rest=false
Self.pasv_mode=false
Threading. Thread.__init__ (self)
def run (self):
Self.conn.send (' Welcome!rn ')
While True:
CMD=SELF.CONN.RECV (256)
If not cmd:break
Else
print ' recieved: ', cmd
Try
Func=getattr (Self,cmd[:4].strip (). Upper ())
Func (CMD)
Except Exception,e:
print ' ERROR: ', E
#traceback. Print_exc ()
Self.conn.send (' Sorry.rn ')
Def syst (Self,cmd):
Self.conn.send (' 215 UNIX type:l8rn ')
def OPTS (Self,cmd):
If cmd[5:-2].upper () = = ' UTF8 on ':
Self.conn.send (' Ok.rn ')
Else
Self.conn.send (' 451 Sorry.rn ')
def USER (Self,cmd):
Self.conn.send (' 331 ok.rn ')
Def Pass (Self,cmd):
Self.conn.send (' 230 ok.rn ')
#self. Conn.send (' 530 incorrect.rn ')
def QUIT (Self,cmd):
Self.conn.send (' 221 goodbye.rn ')
def NOOP (Self,cmd):
Self.conn.send (' Ok.rn ')
def TYPE (Self,cmd):
SELF.MODE=CMD[5]
Self.conn.send (' Binary mode.rn ')
def cdup (Self,cmd):
If not Os.path.samefile (SELF.CWD,SELF.BASEWD):
#learn from StackOverflow
Self.cwd=os.path.abspath (Os.path.join (SELF.CWD, ' ... '))
Self.conn.send (' Ok.rn ')
def PWD (Self,cmd):
Cwd=os.path.relpath (SELF.CWD,SELF.BASEWD)
If cwd== '. ':
Cwd= '/'
Else
Cwd= '/' +CWD
Self.conn.send (' 257 '%s "rn '% CWD)
def CWD (Self,cmd):
Chwd=cmd[4:-2]
If chwd== '/':
Self.cwd=self.basewd
Elif chwd[0]== '/':
Self.cwd=os.path.join (self.basewd,chwd[1:])
Else
Self.cwd=os.path.join (SELF.CWD,CHWD)
Self.conn.send (' Ok.rn ')
def PORT (Self,cmd):
If Self.pasv_mode:
Self.servsock.close ()
Self.pasv_mode = False
L=cmd[5:].split (', ')
Self.dataaddr= '. '. Join (L[:4])
self.dataport= (int (l[4]) <<8) +int (l[5))
Self.conn.send (' Get Port.rn ')
def PASV (Self,cmd): # from Http://goo.gl/3if2U
Self.pasv_mode = True
Self.servsock = Socket.socket (socket.af_inet,socket. SOCK_STREAM)
Self.servsock.bind ((local_ip,0))
Self.servsock.listen (1)
IP, port = self.servsock.getsockname ()
print ' Open ', IP, port
Self.conn.send (' Entering passive Mode (%s,%u,%u). Rn '%
(', '. Join (Ip.split ('. ')), Port>>8&0xff, Port&0xff))
def start_datasock (self):
If Self.pasv_mode:
Self.datasock, addr = Self.servsock.accept ()
print ' Connect: ', addr
Else
Self.datasock=socket.socket (Socket.af_inet,socket. SOCK_STREAM)
Self.datasock.connect ((Self.dataaddr,self.dataport))
def stop_datasock (self):
Self.datasock.close ()
If Self.pasv_mode:
Self.servsock.close ()
def LIST (Self,cmd):
Self.conn.send (' Here Comes the Directory listing.rn ')
print ' list: ', SELF.CWD
Self.start_datasock ()
For T in Os.listdir (SELF.CWD):
K=self.tolistitem (Os.path.join (self.cwd,t))
Self.datasock.send (k + ' RN ')
Self.stop_datasock ()
Self.conn.send (' Directory send Ok.rn ')
def tolistitem (SELF,FN):
St=os.stat (FN)
Fullmode= ' rwxrwxrwx '
Mode= '
For I in range (9):
mode+= (st.st_mode>> (8-i)) &1) and fullmode[i] or '-'
D= (Os.path.isdir (FN)) and ' d ' or '-'
Ftime=time.strftime ('%b%d%h:%m ', Time.gmtime (st.st_mtime))
Return d+mode+ ' 1 user group ' +str (st.st_size) +ftime+os.path.basename (FN)
def MKD (Self,cmd):
Dn=os.path.join (Self.cwd,cmd[4:-2])
Os.mkdir (DN)
Self.conn.send (' 257 Directory created.rn ')
def RMD (Self,cmd):
Dn=os.path.join (Self.cwd,cmd[4:-2])
If Allow_delete:
Os.rmdir (DN)
Self.conn.send (' Directory deleted.rn ')
Else
Self.conn.send (' 450 not allowed.rn ')
def DELE (Self,cmd):
Fn=os.path.join (Self.cwd,cmd[5:-2])
If Allow_delete:
Os.remove (FN)
Self.conn.send (' Deleted.rn File ')
Else
Self.conn.send (' 450 not allowed.rn ')
def RNFR (Self,cmd):
Self.rnfn=os.path.join (Self.cwd,cmd[5:-2])
Self.conn.send (' Ready.rn ')
def rnto (Self,cmd):
Fn=os.path.join (Self.cwd,cmd[5:-2])
Os.rename (SELF.RNFN,FN)
Self.conn.send (' Renamed.rn File ')
def REST (Self,cmd):
Self.pos=int (Cmd[5:-2])
Self.rest=true
Self.conn.send (' position File reseted.rn ')
def RETR (Self,cmd):
Fn=os.path.join (Self.cwd,cmd[5:-2])
#fn =os.path.join (Self.cwd,cmd[5:-2]). Lstrip ('/')
print ' downlowding: ', fn
If self.mode== ' I ':
Fi=open (FN, ' RB ')
Else
Fi=open (FN, ' R ')
Self.conn.send (' Opening data connection.rn ')
If Self.rest:
Fi.seek (Self.pos)
Self.rest=false
Data= Fi.read (1024)
Self.start_datasock ()
While data:
Self.datasock.send (data)
Data=fi.read (1024)
Fi.close ()
Self.stop_datasock ()
Self.conn.send (' Transfer complete.rn ')
def STOR (Self,cmd):
Fn=os.path.join (Self.cwd,cmd[5:-2])
print ' uplaoding: ', fn
If self.mode== ' I ':
Fo=open (FN, ' WB ')
Else
Fo=open (FN, ' W ')
Self.conn.send (' Opening data connection.rn ')
Self.start_datasock ()
While True:
DATA=SELF.DATASOCK.RECV (1024)
If not data:break
Fo.write (data)
Fo.close ()
Self.stop_datasock ()
Self.conn.send (' Transfer complete.rn ')
Class Ftpserver (threading. Thread):
def __init__ (self):
Self.sock = Socket.socket (socket.af_inet, socket. SOCK_STREAM)
Self.sock.bind ((Local_ip,local_port))
Threading. Thread.__init__ (self)
def run (self):
Self.sock.listen (5)
While True:
Th=ftpserverthread (Self.sock.accept ())
Th.daemon=true
Th.start ()
def stop (self):
Self.sock.close ()
If __name__== ' __main__ ':
Ftp=ftpserver ()
Ftp.daemon=true
Ftp.start ()
print ' on ', Local_ip, ': ', Local_port
Raw_input (' Enter to END...N ')
Ftp.stop ()
|