soc.2009.transport: b4ad8c30: Another bugfixes for filetransfer and ad...

hanzz at soc.pidgin.im hanzz at soc.pidgin.im
Tue Aug 4 07:41:20 EDT 2009


-----------------------------------------------------------------
Revision: b4ad8c30223af81351bf0aa387499e4f9d3fb6a7
Ancestor: 49505314eb2ad201a906df379cf83e1e2e8d34b2
Author: hanzz at soc.pidgin.im
Date: 2009-08-04T11:34:32
Branch: im.pidgin.soc.2009.transport
URL: http://d.pidgin.im/viewmtn/revision/info/b4ad8c30223af81351bf0aa387499e4f9d3fb6a7

Modified files:
        filetransfermanager.cpp filetransferrepeater.cpp
        filetransferrepeater.h main.cpp user.cpp user.h

ChangeLog: 

Another bugfixes for filetransfer and added initial support for transfer from legacy network to XMPP

-------------- next part --------------
============================================================
--- filetransfermanager.cpp	72f34a8797160677c719816709507f51d6f46433
+++ filetransfermanager.cpp	50bc4d72655a658044c8619d96b05f599d6c8d11
@@ -80,7 +80,10 @@ void FileTransferManager::handleFTBytest
 		FiletransferRepeater *repeater = user->removeFiletransfer(bs->target().username());
 		if (!repeater) return;
 		
-		repeater->handleFTReceiveBytestream(bs);
+		if (repeater->isSending())
+			repeater->handleFTSendBytestream(bs);
+		else
+			repeater->handleFTReceiveBytestream(bs);
 
     } else {
 		// zatim to nepotrebujem u odchozich filu
============================================================
--- filetransferrepeater.cpp	72b8d29f87c1d9b24276347410fb271e0b12d08a
+++ filetransferrepeater.cpp	42eba03d82799e227c393159aa0338bb0fced276
@@ -21,7 +21,80 @@
 #include "filetransferrepeater.h"
 #include "main.h"
 
+SendFileStraight::SendFileStraight(Bytestream *stream, int size, FiletransferRepeater *manager) {
+    std::cout << "SendFileStraight::SendFileStraight" << " Constructor.\n";
+    m_stream = stream;
+    m_size = size;
+	m_stream->registerBytestreamDataHandler (this);
+	m_parent = manager;
+	if (m_stream->connect())
+		std::cout << "stream connected\n";
+    run();
+}
 
+SendFileStraight::~SendFileStraight() {
+
+}
+
+void SendFileStraight::exec() {
+    std::cout << "SendFileStraight::exec Starting transfer.\n";
+    char input[200024];
+	int ret;
+	bool empty;
+    while (true) {
+		if (m_stream->isOpen()){
+			std::cout << "sending...\n";
+			std::string data;
+// 			if (getBuffer().size() > size) {
+// 				data = repeater->getBuffer().substr(0, size);
+// 				repeater->getBuffer().erase(0, size);
+// 			}
+// 			else {
+// 			getBuffer();
+// 			getBuffer().erase();
+// 			}
+// 			m_file.read(input, 200024);
+			getMutex()->lock();
+			std::string t;
+			if (m_parent->getBuffer().empty())
+				empty = true;
+			else {
+				empty = false;
+				t = std::string(m_parent->getBuffer(), m_parent->getBuffer().size());
+			}
+			getMutex()->unlock();
+			if (!empty) {
+				ret = m_stream->send(t);
+				std::cout << ret << "\n";
+				if(ret<1){
+					std::cout << "error in sending or sending probably finished\n";
+					break;
+				};
+			}
+		}
+		m_stream->recv(200);
+    }
+//     delete this;
+}
+
+void SendFileStraight::handleBytestreamData(gloox::Bytestream *s5b, const std::string &data) {
+	std::cout << "socks stream data\n";
+}
+
+void SendFileStraight::handleBytestreamError(gloox::Bytestream *s5b, const gloox::IQ &iq) {
+
+}
+
+void SendFileStraight::handleBytestreamOpen(gloox::Bytestream *s5b) {
+	std::cout << "socks stream open\n";
+}
+
+void SendFileStraight::handleBytestreamClose(gloox::Bytestream *s5b) {
+	std::cout << "socks stream error\n";
+}
+
+
+
 ReceiveFileStraight::ReceiveFileStraight(gloox::Bytestream *stream, int size, FiletransferRepeater *manager) {
     m_stream = stream;
     m_size = size;
@@ -43,13 +116,20 @@ void ReceiveFileStraight::exec() {
 	Log().Get("ReceiveFileStraight") << "starting receiveFile thread";
 // 	m_stream->handleConnect(m_stream->connectionImpl());
 	Log().Get("ReceiveFileStraight") << "begin receiving this file";
+//     m_file.open("dump.bin", std::ios_base::out | std::ios_base::binary );
+//     if (!m_file) {
+//         Log().Get(m_filename) << "can't create this file!";
+//         return;
+//     }
 	while (!m_finished) {
 		m_stream->recv();
 	}
+// 	m_file.close();
 }
 
 void ReceiveFileStraight::handleBytestreamData(gloox::Bytestream *s5b, const std::string &data) {
 	getMutex()->lock();
+// 	m_file.write(data.c_str(), data.size());
 	m_parent->gotData(data);
 	getMutex()->unlock();
 }
@@ -80,10 +160,18 @@ static gboolean ui_got_data(gpointer dat
 	return FALSE;
 }
 
+static size_t ui_write_fnc(const guchar *buffer, size_t size, PurpleXfer *xfer) {
+	FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
+	std::string d((char *)buffer, size);
+	if (repeater->getResender())
+		repeater->getResender()->getMutex()->lock();	
+	repeater->gotData(d);
+	if (repeater->getResender())
+		repeater->getResender()->getMutex()->unlock();
+}
 
-
 static size_t ui_read_fnc(guchar **buffer, size_t size, PurpleXfer *xfer) {
-	Log().Get("REPEATER") << "ui_read";
+// 	Log().Get("REPEATER") << "ui_read";
 	FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
 	if (!repeater->getResender()) {
 		repeater->wantsData();
@@ -108,11 +196,12 @@ static size_t ui_read_fnc(guchar **buffe
 			data = repeater->getBuffer();
 			repeater->getBuffer().erase();
 		}
-		(*buffer) = (guchar*) g_strdup(data.c_str());
+// 		(*buffer) = (guchar*) g_strndup(data.c_str(), data.size());
+		memcpy((*buffer), data.c_str(), data.size());
 		size_t s = repeater->getBuffer().size();
-		Log().Get("REPEATER") << "GOT BUFFER, SIZE=" << s;
+		Log().Get("REPEATER") << "GOT BUFFER, BUFFER SIZE=" << s;
 		repeater->getResender()->getMutex()->unlock();
-		return size;
+		return data.size();
 	}
 }
 
@@ -126,14 +215,29 @@ FiletransferRepeater::FiletransferRepeat
 	m_buffer = "";
 	m_wantsData = false;
 	m_resender = NULL;
+	m_send = false;
+	m_file.open("dump.bin", std::ios_base::out | std::ios_base::binary );
 }
 
+FiletransferRepeater::FiletransferRepeater(GlooxMessageHandler *main, const JID& from, const JID& to) {
+	m_main = main;
+	m_to = to;
+	m_from = from;
+	m_buffer = "";
+	m_type = SIProfileFT::FTTypeS5B;
+	m_resender = NULL;
+	m_size = -1;
+	m_send = true;
+}
+
 void FiletransferRepeater::registerXfer(PurpleXfer *xfer) {
 	m_xfer = xfer;
 	
 	purple_xfer_set_ui_read_fnc(m_xfer, ui_read_fnc);
+	purple_xfer_set_ui_write_fnc(m_xfer, ui_write_fnc);
 // 	purple_xfer_set_local_filename(xfer, filename);
-	purple_xfer_set_size(xfer, m_size);
+	if (m_size != -1)
+		purple_xfer_set_size(xfer, m_size);
 	m_xfer->ui_data = this;
 }
 
@@ -142,14 +246,29 @@ void FiletransferRepeater::fileSendStart
 	m_main->ft->acceptFT(m_to, m_sid, m_type, m_from.resource().empty() ? std::string(m_from.bare() + "/bot") : m_from);
 }
 
+void FiletransferRepeater::fileRecvStart() {
+	Log().Get("SendFileStraight") << "fileRecvStart!" << m_from.full() << " " << m_to.full();
+}
+
+void FiletransferRepeater::requestFT() {
+// 	purple_xfer_request_accepted(xfer, std::string(filename).c_str());
+	std::string filename(purple_xfer_get_filename(m_xfer));
+	m_sid = m_main->ft->requestFT(m_to, filename, purple_xfer_get_size(m_xfer), EmptyString, EmptyString, EmptyString, EmptyString, SIProfileFT::FTTypeAll, m_from);
+}
+
 void FiletransferRepeater::handleFTReceiveBytestream(Bytestream *bs) {
 	Log().Get("ReceiveFileStraight") << "new!";
 	m_resender = new ReceiveFileStraight(bs, 0, this);
 }
 
+void FiletransferRepeater::handleFTSendBytestream(Bytestream *bs) {
+	Log().Get("SendFileStraight") << "new!";
+	m_resender = new SendFileStraight(bs, 0, this);
+}
+
 void FiletransferRepeater::gotData(const std::string &data) {
-	m_buffer.append(data);
-	Log().Get("ReceiveFileStraight") << "Got DATA! " << m_wantsData;
+	m_buffer.append(std::string(data));
+// 	Log().Get("ReceiveFileStraight") << "Got DATA! " << m_wantsData;
 	if (m_wantsData) {
 		m_wantsData = false;
 		purple_timeout_add(0,&ui_got_data,m_xfer);
============================================================
--- filetransferrepeater.h	2df39a48bdc75f78c902598f32deec1cb297eb31
+++ filetransferrepeater.h	ba2a9e9108db0956722db9047d05438149bfffaa
@@ -30,6 +30,7 @@
 #include "conversation.h"
 #include "ft.h"
 #include "thread.h"
+#include <fstream>
 
 class User;
 extern Localization localization;
@@ -70,22 +71,48 @@ class ReceiveFileStraight : public Abstr
 		int m_size;
 		bool m_finished;
 		FiletransferRepeater *m_parent;
+		std::ofstream m_file;
 };
 
+class SendFileStraight : public AbstractResendClass, public BytestreamDataHandler, public Thread {
+	public:
+		SendFileStraight(Bytestream *stream, int size, FiletransferRepeater *manager);
+		~SendFileStraight();
+
+		void exec();
+		void handleBytestreamData(Bytestream *s5b, const std::string &data);
+		void handleBytestreamError(Bytestream *s5b, const IQ &iq);
+		void handleBytestreamOpen(Bytestream *s5b);
+		void handleBytestreamClose(Bytestream *s5b);
+	
+	private:
+		Bytestream *m_stream;
+		std::string m_filename;
+		int m_size;
+		FiletransferRepeater *m_parent;
+};
+
 class FiletransferRepeater {
 	
 	public:
 		FiletransferRepeater(GlooxMessageHandler *main, const JID& to, const std::string& sid, SIProfileFT::StreamType type, const JID& from, long size);
+		FiletransferRepeater(GlooxMessageHandler *main, const JID& from, const JID& to);
 		~FiletransferRepeater() {}
 		
 		void registerXfer(PurpleXfer *xfer);
 		void fileSendStart();
+		void fileRecvStart();
 		void handleFTReceiveBytestream(Bytestream *bs);
+		void handleFTSendBytestream(Bytestream *bs);
 		void gotData(const std::string &data);
+		void requestFT();
 		
+		bool isSending() { return m_send; }
+		
 		std::string & getBuffer() { return m_buffer; }
 		AbstractResendClass *getResender() { return m_resender; }
 		void wantsData() { m_wantsData = true; }
+		std::ofstream m_file;
 	
 	private:
 		GlooxMessageHandler *m_main;
@@ -95,7 +122,9 @@ class FiletransferRepeater {
 		JID m_from;
 		long m_size;
 		PurpleXfer *m_xfer;
+		bool m_send;
 		
+		
 		std::string m_buffer;
 		AbstractResendClass *m_resender;
 		bool m_wantsData;
============================================================
--- main.cpp	93417917c506bde7ee0ee3590b15a3f743ee4b42
+++ main.cpp	b0de4124b2a791749ee3cd1d776e544c7450a1c9
@@ -282,6 +282,16 @@ static void * requestAction(const char *
 			((PurpleRequestActionCb) va_arg(actions, GCallback))(user_data,2);
 		}
 	}
+	if (primary) {
+		std::string primaryString(primary);
+		if (primaryString.find("Accept file transfer") == 0) {
+			FiletransferRepeater *repeater = user->getFiletransfer((std::string) who);
+			repeater->requestFT();
+			
+// 			std::string sid = m_sip->requestFT(jid, name, info.st_size, EmptyString, EmptyString, EmptyString, EmptyString, SIProfileFT::FTTypeAll, from);
+		}
+	}
+	
 	return NULL;
 }
 
@@ -391,9 +401,13 @@ static void XferCreated(PurpleXfer *xfer
 	
 	FiletransferRepeater *repeater = user->getFiletransfer(remote_user);
 	Log().Get(user->jid()) << "get filetransferRepeater" << remote_user;
-	if (!repeater) return;
-	Log().Get(user->jid()) << "registerXfer";
-	repeater->registerXfer(xfer);
+	if (repeater) {
+		Log().Get(user->jid()) << "registerXfer";
+		repeater->registerXfer(xfer);
+	}
+	else {
+		user->addFiletransfer(std::string(xfer->who) + "@" + GlooxMessageHandler::instance()->jid() + "/bot");
+	}
 
 }
 
@@ -403,7 +417,13 @@ static void fileSendStart(PurpleXfer *xf
 	Log().Get("filesend") << "fileSendStart()";
 }
 
+static void fileRecvStart(PurpleXfer *xfer) {
+	FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
+	repeater->fileRecvStart();
+	Log().Get("filesend") << "fileRecvStart()";
+}
 
+
 static void buddyListAddBuddy(PurpleAccount *account, const char *username, const char *group, const char *alias){
 	std::cout << "BUDDY LIST ADD BUDDY REQUEST\n";
 }
@@ -965,19 +985,21 @@ void GlooxMessageHandler::purpleFileRece
         }
     }
 
-	purple_xfer_request_accepted(xfer, std::string(configuration().filetransferCache+"/"+remote_user+"-"+j->getID()+"-"+filename).c_str());
+// 	purple_xfer_request_accepted(xfer, std::string(configuration().filetransferCache+"/"+remote_user+"-"+j->getID()+"-"+filename).c_str());
 	User *user = userManager()->getUserByAccount(purple_xfer_get_account(xfer));
 	if (user!=NULL){
-		if(user->hasFeature(GLOOX_FEATURE_FILETRANSFER)){
-			Message s(Message::Chat, user->jid(), tr(user->getLang(),_("User is sending you file '"))+filename+tr(user->getLang(),_("'. It will be resend to you right after we receive it.")));
-			s.setFrom(remote_user+"@"+jid()+"/bot");
-			j->send(s);
-		}
-		else{
-			Message s(Message::Chat, user->jid(), tr(user->getLang(),_("User is sending you file '"))+filename+tr(user->getLang(),_("'. We will send you link to the file right when we receive it.")));
-			s.setFrom(remote_user+"@"+jid()+"/bot");
-			j->send(s);
-		}
+		// 		std::string sid = GlooxMessageHandler::instance()->ft->requestFT(jid, name, info.st_size, EmptyString, EmptyString, EmptyString, EmptyString, SIProfileFT::FTTypeAll, from);
+// 		purple_xfer_request_accepted(xfer, std::string(filename).c_str());
+// 		if(user->hasFeature(GLOOX_FEATURE_FILETRANSFER)){
+// 			Message s(Message::Chat, user->jid(), tr(user->getLang(),_("User is sending you file '"))+filename+tr(user->getLang(),_("'. It will be resend to you right after we receive it.")));
+// 			s.setFrom(remote_user+"@"+jid()+"/bot");
+// 			j->send(s);
+// 		}
+// 		else{
+// 			Message s(Message::Chat, user->jid(), tr(user->getLang(),_("User is sending you file '"))+filename+tr(user->getLang(),_("'. We will send you link to the file right when we receive it.")));
+// 			s.setFrom(remote_user+"@"+jid()+"/bot");
+// 			j->send(s);
+// 		}
 	}
 }
 
@@ -1488,6 +1510,7 @@ bool GlooxMessageHandler::initPurple(){
 		purple_signal_connect(purple_conversations_get_handle(), "buddy-typing", &conversation_handle, PURPLE_CALLBACK(buddyTyping), NULL);
 		purple_signal_connect(purple_conversations_get_handle(), "buddy-typing-stopped", &conversation_handle, PURPLE_CALLBACK(buddyTypingStopped), NULL);
 		purple_signal_connect(purple_xfers_get_handle(), "file-send-start", &xfer_handle, PURPLE_CALLBACK(fileSendStart), NULL);
+		purple_signal_connect(purple_xfers_get_handle(), "file-recv-start", &xfer_handle, PURPLE_CALLBACK(fileRecvStart), NULL);
 		purple_signal_connect(purple_xfers_get_handle(), "file-recv-request", &xfer_handle, PURPLE_CALLBACK(newXfer), NULL);
 		purple_signal_connect(purple_xfers_get_handle(), "file-recv-complete", &xfer_handle, PURPLE_CALLBACK(XferComplete), NULL);
 		purple_signal_connect(purple_connections_get_handle(), "signed-on", &conn_handle,PURPLE_CALLBACK(signed_on), NULL);
============================================================
--- user.cpp	d44b97b2ab46e4fd1989802f91b8bcb793bc45c6
+++ user.cpp	471d2fc3f396b71f1c6a59c1f7d4886901cad295
@@ -1254,6 +1254,10 @@ void User::addFiletransfer( const JID& t
 	g_hash_table_replace(m_filetransfers, g_strdup(to.bare() == m_jid ? from.username().c_str() : to.username().c_str()), ft);
 	Log().Get("filetransfer") << "adding FT Class as jid:" << std::string(to.bare() == m_jid ? from.username() : to.username());
 }
+void User::addFiletransfer( const JID& to ) {
+	FiletransferRepeater *ft = new FiletransferRepeater(p, to, m_jid + "/" + m_resource);
+	g_hash_table_replace(m_filetransfers, g_strdup(to.username().c_str()), ft);
+}
 
 User::~User(){
 
============================================================
--- user.h	e4868de2cc738020837962982598d66e9e62563a
+++ user.h	6b3ad9f6b64212847171e9eb6d1350e9cbf6c2a1
@@ -121,6 +121,7 @@ class User {
 
 		// Filetransfers
 		void addFiletransfer( const JID& to, const std::string& sid, SIProfileFT::StreamType type, const JID& from, long size );
+		void addFiletransfer( const JID& from );
 		FiletransferRepeater* removeFiletransfer(std::string from) { FiletransferRepeater *repeater = (FiletransferRepeater *) g_hash_table_lookup(m_filetransfers, from.c_str()); if (repeater) g_hash_table_remove(m_filetransfers, from.c_str()); return repeater; }
 		FiletransferRepeater* getFiletransfer(std::string from) { FiletransferRepeater *repeater = (FiletransferRepeater *) g_hash_table_lookup(m_filetransfers, from.c_str()); return repeater; }
 		std::string actionData;


More information about the Commits mailing list