def filesender(file, rsock): """ Callback function for handling sending of the file. Will be called when data is available on the file (which is always true, until the file is closed...). Send file data. Detect end of file and tell VS peers that transfer is complete""" str = file.read(vsftp.VS_MAXDATA) if len(str) == 0: # end of file vsm = vsftp.vsftp() vsm.vs_type = vsftp.VS_TYPE_END buf = vsm.pack() for p in peers: if debug: (address, port, flow, scope) = p print "vs_send: send END (%d bytes) to %s:%s" % (len(buf), address, port) rudp.rudp_sendto(rsock, buf, p) event.event_fd_delete(filesender, rsock) file.close() rudp.rudp_close(rsock) else: vsm = vsftp.vsftp() vsm.vs_type = vsftp.VS_TYPE_DATA vsm.vs_data = str buf = vsm.pack() for p in peers: if debug: (address, port, flow, scope) = p print "vs_send: send DATA (%d bytes) to %s:%s" % (len(buf), address, port) rudp.rudp_sendto(rsock, buf, p) return 0
def send_file(filename): """Initiate sending of a file with RUDP. Create a RUDP socket for sending. Send the file name to the VS receiver. Register a handler for input event, which will take care of sending file data""" f = open(filename, "rb") rsock = rudp.rudp_socket(0) rudp.rudp_event_handler(rsock, eventhandler) rudp.rudp_recvfrom_handler(rsock, recvfrom_handler) # Strip of any leading path name and create start packet vsm = vsftp.vsftp() vsm.vs_type = vsftp.VS_TYPE_BEGIN vsm.vs_filename = os.path.basename(filename) buf = vsm.pack() for p in peers: (address, port, flow, scope) = p if debug: print "vs_send: send BEGIN \"%s\" (%d bytes) to %s:%s" % (filename, len(buf), address, port) rudp.rudp_sendto(rsock, buf, p) # Launch event driven filesender to send file content event.event_fd(f, filesender, rsock, "filesender")
def recvfromhandler(rsocket, remote, buf): global rxfiles vsm = vsftp.vsftp() vsm.unpack(buf) if vsm.vs_type == vsftp.VS_TYPE_BEGIN: # Verify that file name is valid. Only alpha-numerical, period, dash and # underscore are allowed filename = vsm.vs_filename if re.search("[^a-zA-Z0-9_\-\.]", filename): raise ValueError("Invalid character(s) in VSFTP file name (%s)" % (vsm.vs_filename)) if debug: (ip, p, f, c) = remote print "vs_recv: BEGIN \"%s\" (%d bytes) from %s:%d" % (filename, len(buf), ip, p) fd = open(filename, "wb") rxfiles[remote] = (filename, fd) elif vsm.vs_type == vsftp.VS_TYPE_DATA: if debug: (ip, p, f, c) = remote print "vs_recv: DATA (%d bytes) from %s:%d" % (len(buf), ip, p) (filename, fd) = rxfiles[remote] fd.write(vsm.vs_data) elif vsm.vs_type == vsftp.VS_TYPE_END: if debug: (ip, p, f, c) = remote print "vs_recv: END (%d bytes) from %s:%d" % (len(buf), ip, p) (filename, fd) = rxfiles[remote] fd.close() del rxfiles[remote] return 0
def recvfromhandler(rsocket, remote, buf): global rxfiles vsm = vsftp.vsftp() vsm.unpack(buf) if vsm.vs_type == vsftp.VS_TYPE_BEGIN: # Verify that file name is valid. Only alpha-numerical, period, dash and # underscore are allowed filename = vsm.vs_filename if re.search("[^a-zA-Z0-9_\-\.]", filename): raise ValueError("Invalid character(s) in VSFTP file name (%s)" % (vsm.vs_filename)) if debug: (ip, p, f, c) = remote print "vs_recv: BEGIN \"%s\" (%d bytes) from %s:%d" % ( filename, len(buf), ip, p) fd = open(filename, "wb") rxfiles[remote] = (filename, fd) elif vsm.vs_type == vsftp.VS_TYPE_DATA: if debug: (ip, p, f, c) = remote print "vs_recv: DATA (%d bytes) from %s:%d" % (len(buf), ip, p) (filename, fd) = rxfiles[remote] fd.write(vsm.vs_data) elif vsm.vs_type == vsftp.VS_TYPE_END: if debug: (ip, p, f, c) = remote print "vs_recv: END (%d bytes) from %s:%d" % (len(buf), ip, p) (filename, fd) = rxfiles[remote] fd.close() del rxfiles[remote] return 0