Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/SpectrumIM/spectrum2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'backends/libpurple/main.cpp')
-rw-r--r--backends/libpurple/main.cpp269
1 files changed, 72 insertions, 197 deletions
diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp
index 86aff002..8fb4e894 100644
--- a/backends/libpurple/main.cpp
+++ b/backends/libpurple/main.cpp
@@ -112,14 +112,6 @@ bool caching = true;
static void *notify_user_info(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info);
-static gboolean ft_ui_ready(void *data) {
- PurpleXfer *xfer = (PurpleXfer *) data;
- FTData *ftdata = (FTData *) xfer->ui_data;
- ftdata->timer = 0;
- purple_xfer_ui_ready_wrapped((PurpleXfer *) data);
- return FALSE;
-}
-
/*
Authorization requests from buddies are cached for the duration of the session.
To authorize or deny, call the cached callbacks.
@@ -898,44 +890,6 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
purple_conversation_destroy_wrapped(conv);
}
- void handleFTStartRequest(const std::string &user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID) {
- PurpleXfer *xfer = m_unhandledXfers[user + fileName + buddyName];
- if (xfer) {
- m_unhandledXfers.erase(user + fileName + buddyName);
- FTData *ftData = (FTData *) xfer->ui_data;
-
- ftData->id = ftID;
- m_xfers[ftID] = xfer;
- purple_xfer_request_accepted_wrapped(xfer, fileName.c_str());
- purple_xfer_ui_ready_wrapped(xfer);
- }
- }
-
- void handleFTFinishRequest(const std::string &user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID) {
- PurpleXfer *xfer = m_unhandledXfers[user + fileName + buddyName];
- if (xfer) {
- m_unhandledXfers.erase(user + fileName + buddyName);
- purple_xfer_request_denied_wrapped(xfer);
- }
- }
-
- void handleFTPauseRequest(unsigned long ftID) {
- PurpleXfer *xfer = m_xfers[ftID];
- if (!xfer)
- return;
- FTData *ftData = (FTData *) xfer->ui_data;
- ftData->paused = true;
- }
-
- void handleFTContinueRequest(unsigned long ftID) {
- PurpleXfer *xfer = m_xfers[ftID];
- if (!xfer)
- return;
- FTData *ftData = (FTData *) xfer->ui_data;
- ftData->paused = false;
- purple_xfer_ui_ready_wrapped(xfer);
- }
-
void sendData(const std::string &string) {
#ifdef WIN32
::send(main_socket, string.c_str(), string.size(), 0);
@@ -946,30 +900,12 @@ class SpectrumNetworkPlugin : public NetworkPlugin {
writeInput = purple_input_add_wrapped(main_socket, PURPLE_INPUT_WRITE, &transportDataReceived, NULL);
}
- void readyForData() {
- if (m_waitingXfers.empty())
- return;
- std::vector<PurpleXfer *> tmp;
- tmp.swap(m_waitingXfers);
-
- for (std::vector<PurpleXfer *>::const_iterator it = tmp.begin(); it != tmp.end(); it++) {
- FTData *ftData = (FTData *) (*it)->ui_data;
- if (ftData->timer == 0) {
- ftData->timer = purple_timeout_add_wrapped(1, ft_ui_ready, *it);
- }
-// purple_xfer_ui_ready_wrapped(xfer);
- }
- }
-
std::map<std::string, PurpleAccount *> m_sessions;
std::map<PurpleAccount *, std::string> m_accounts;
std::map<std::string, unsigned int> m_vcards;
AuthRequestList m_authRequests;
std::map<std::string, inputRequest *> m_inputRequests;
std::map<std::string, std::list<std::string> > m_rooms;
- std::map<unsigned long, PurpleXfer *> m_xfers;
- std::map<std::string, PurpleXfer *> m_unhandledXfers;
- std::vector<PurpleXfer *> m_waitingXfers;
std::string adminLegacyName;
std::string adminAlias;
};
@@ -1487,7 +1423,7 @@ static bool conv_msg_to_image(const char* msg, std::string* xhtml_, std::string*
static void conv_write_im(PurpleConversation *conv, const char *who, const char *msg, PurpleMessageFlags flags, time_t mtime) {
- LOG4CXX_INFO(logger, "conv_write_im()");
+ LOG4CXX_DEBUG(logger, "conv_write_im(): msg='" << msg << "', flags=" << flags);
bool isCarbon = false;
if (purple_conversation_get_type_wrapped(conv) == PURPLE_CONV_TYPE_IM) {
@@ -1513,8 +1449,6 @@ static void conv_write_im(PurpleConversation *conv, const char *who, const char
std::string message_; //plain text
std::string xhtml_; //enhanced xhtml, if available
- LOG4CXX_DEBUG(logger, "conv_write_im(): msg='" << msg << "', flags=" << flags);
-
if (flags & PURPLE_MESSAGE_IMAGES) {
//Store image locally and adjust the message
if (!conv_msg_to_image(msg, &xhtml_, &message_))
@@ -1975,146 +1909,92 @@ static PurpleAccountUiOps accountUiOps =
NULL
};
-static void XferCreated(PurpleXfer *xfer) {
- if (!xfer) {
- return;
- }
-
- PurpleAccount *account = purple_xfer_get_account_wrapped(xfer);
- if (np->m_accounts.find(account) != np->m_accounts.end()) {
- const char * filenameData = purple_xfer_get_filename_wrapped(xfer);
- std::string filename(filenameData ? filenameData : "");
- np->handleFTStart(np->m_accounts[account], xfer->who ? xfer->who : "", filename, purple_xfer_get_size_wrapped(xfer));
- }
-}
-
-static void XferDestroyed(PurpleXfer *xfer) {
- std::remove(np->m_waitingXfers.begin(), np->m_waitingXfers.end(), xfer);
- FTData *ftdata = (FTData *) xfer->ui_data;
- if (ftdata && ftdata->timer) {
- purple_timeout_remove_wrapped(ftdata->timer);
- }
- if (ftdata) {
- np->m_xfers.erase(ftdata->id);
+static gboolean
+ensure_path_exists(const char *dir)
+{
+ if (!g_file_test(dir, G_FILE_TEST_IS_DIR))
+ {
+ if (g_mkdir_with_parents(dir, S_IRUSR | S_IWUSR | S_IXUSR)) {
+ return FALSE;
+ }
}
+ return TRUE;
}
-static void xferCanceled(PurpleXfer *xfer) {
+static void newXfer(PurpleXfer *xfer) {
PurpleAccount *account = purple_xfer_get_account_wrapped(xfer);
- std::string filename(xfer ? purple_xfer_get_filename_wrapped(xfer) : "");
+ std::string remote_filename(xfer ? purple_xfer_get_filename_wrapped(xfer) : "");
std::string w = xfer->who ? xfer->who : "";
size_t pos = w.find("/");
if (pos != std::string::npos)
w.erase((int) pos, w.length() - (int) pos);
-
- FTData *ftdata = (FTData *) xfer->ui_data;
-
- np->handleFTFinish(np->m_accounts[account], w, filename, purple_xfer_get_size_wrapped(xfer), ftdata ? ftdata->id : 0);
- std::remove(np->m_waitingXfers.begin(), np->m_waitingXfers.end(), xfer);
- if (ftdata && ftdata->timer) {
- purple_timeout_remove_wrapped(ftdata->timer);
+ int count = 1;
+ const char *escape;
+ gchar **name_and_ext;
+ const gchar *name;
+ gchar *ext;
+ std::string web_dir = CONFIG_STRING(config, "service.web_directory");
+ std::string web_url = CONFIG_STRING(config, "service.web_url");
+ if (web_dir.empty() || web_url.empty()) {
+ LOG4CXX_DEBUG(logger, "Denied " << remote_filename << " from " << w << ", web_directory is disabled.");
+ purple_xfer_request_denied_wrapped(xfer);
+ return;
}
- purple_xfer_unref_wrapped(xfer);
-}
-
-static void fileSendStart(PurpleXfer *xfer) {
-// FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
-// repeater->fileSendStart();
-}
-
-static void fileRecvStart(PurpleXfer *xfer) {
-// FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
-// repeater->fileRecvStart();
- FTData *ftData = (FTData *) xfer->ui_data;
- if (ftData && ftData->timer == 0) {
- ftData->timer = purple_timeout_add_wrapped(1, ft_ui_ready, xfer);
+ LOG4CXX_INFO(logger, "Accepting " << remote_filename << " from " << w);
+ gchar *dirname = g_build_filename(web_dir.c_str(), NULL);
+ gchar *filename = g_build_filename(dirname, remote_filename.c_str(), NULL);
+ // Uniqifying code taken from Pidgin autoaccept plugin
+ /* Split at the first dot, to avoid uniquifying "foo.tar.gz" to "foo.tar-2.gz" */
+ name_and_ext = g_strsplit(escape, ".", 2);
+ name = name_and_ext[0];
+ if (name == NULL)
+ {
+ g_strfreev(name_and_ext);
+ g_return_if_reached();
}
-}
-
-static void newXfer(PurpleXfer *xfer) {
- PurpleAccount *account = purple_xfer_get_account_wrapped(xfer);
- std::string filename(xfer ? purple_xfer_get_filename_wrapped(xfer) : "");
- purple_xfer_ref_wrapped(xfer);
- std::string w = xfer->who ? xfer->who : "";
- size_t pos = w.find("/");
- if (pos != std::string::npos)
- w.erase((int) pos, w.length() - (int) pos);
-
- FTData *ftdata = new FTData;
- ftdata->paused = false;
- ftdata->id = 0;
- ftdata->timer = 0;
- xfer->ui_data = (void *) ftdata;
-
- np->m_unhandledXfers[np->m_accounts[account] + filename + w] = xfer;
-
- np->handleFTStart(np->m_accounts[account], w, filename, purple_xfer_get_size_wrapped(xfer));
-}
-
-static void XferReceiveComplete(PurpleXfer *xfer) {
-// FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
-// repeater->_tryToDeleteMe();
-// GlooxMessageHandler::instance()->ftManager->handleXferFileReceiveComplete(xfer);
- std::remove(np->m_waitingXfers.begin(), np->m_waitingXfers.end(), xfer);
- FTData *ftdata = (FTData *) xfer->ui_data;
- if (ftdata && ftdata->timer) {
- purple_timeout_remove_wrapped(ftdata->timer);
- }
- purple_xfer_unref_wrapped(xfer);
-}
-
-static void XferSendComplete(PurpleXfer *xfer) {
-// FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
-// repeater->_tryToDeleteMe();
- std::remove(np->m_waitingXfers.begin(), np->m_waitingXfers.end(), xfer);
- FTData *ftdata = (FTData *) xfer->ui_data;
- if (ftdata && ftdata->timer) {
- purple_timeout_remove_wrapped(ftdata->timer);
+ if (name_and_ext[1] != NULL)
+ {
+ /* g_strsplit does not include the separator in each chunk. */
+ ext = g_strdup_printf(".%s", name_and_ext[1]);
}
- purple_xfer_unref_wrapped(xfer);
-}
-
-static gssize XferWrite(PurpleXfer *xfer, const guchar *buffer, gssize size) {
- FTData *ftData = (FTData *) xfer->ui_data;
- std::string data((const char *) buffer, (size_t) size);
-// std::cout << "xferwrite\n";
- if (!ftData->paused) {
-// std::cout << "adding xfer to waitingXfers queue\n";
- np->m_waitingXfers.push_back(xfer);
+ else
+ {
+ ext = g_strdup("");
+ }
+ /* Make sure the file doesn't exist. Do we want some better checking than this? */
+ /* FIXME: There is a race here: if the newly uniquified file name gets created between
+ * this g_file_test and the transfer starting, the file created in the meantime
+ * will be clobbered. But it's not at all straightforward to fix.
+ */
+ while (g_file_test(filename, G_FILE_TEST_EXISTS))
+ {
+ char *file = g_strdup_printf("%s-%d%s", name, count++, ext);
+ g_free(filename);
+ filename = g_build_filename(dirname, file, NULL);
+ g_free(file);
}
- np->handleFTData(ftData->id, data);
- return size;
-}
-static void XferNotSent(PurpleXfer *xfer, const guchar *buffer, gsize size) {
-// FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
-// repeater->handleDataNotSent(buffer, size);
+ purple_xfer_request_accepted_wrapped(xfer, filename);
+ g_strfreev(name_and_ext);
+ g_free(ext);
+ g_free(dirname);
+ g_free(filename);
}
-static gssize XferRead(PurpleXfer *xfer, guchar **buffer, gssize size) {
-// FiletransferRepeater *repeater = (FiletransferRepeater *) xfer->ui_data;
-// int data_size = repeater->getDataToSend(buffer, size);
-// if (data_size == 0)
-// return 0;
-//
-// return data_size;
- return 0;
+static void XferReceiveComplete(PurpleXfer *xfer) {
+ std::string filename(xfer ? purple_xfer_get_local_filename_wrapped(xfer) : "");
+ std::string w = xfer->who ? xfer->who : "";
+ LOG4CXX_INFO(logger, "Received " << filename << " from " << w);
+ PurpleAccount *account = purple_xfer_get_account_wrapped(xfer);
+ std::string web_url = CONFIG_STRING(config, "service.web_url");
+ pbnetwork::Attachment attachment;
+ gchar *base_filename = g_path_get_basename(filename.c_str());
+ attachment.set_url(web_url + "/" + std::string(base_filename));
+ g_free(base_filename);
+ std::vector<pbnetwork::Attachment> attachments = { attachment };
+ np->handleMessage(np->m_accounts[account], w, "", "", "", xfer->end_time? std::to_string(xfer->end_time) : "", false, false, false, attachments);
}
-static PurpleXferUiOps xferUiOps =
-{
- XferCreated,
- XferDestroyed,
- NULL,
- NULL,
- xferCanceled,
- xferCanceled,
- XferWrite,
- XferRead,
- XferNotSent,
- NULL
-};
-
static void RoomlistProgress(PurpleRoomlist *list, gboolean in_progress)
{
if (!in_progress) {
@@ -2219,7 +2099,6 @@ static void transport_core_ui_init(void)
purple_accounts_set_ui_ops_wrapped(&accountUiOps);
purple_notify_set_ui_ops_wrapped(&notifyUiOps);
purple_request_set_ui_ops_wrapped(&requestUiOps);
- purple_xfers_set_ui_ops_wrapped(&xferUiOps);
purple_connections_set_ui_ops_wrapped(&conn_ui_ops);
purple_conversations_set_ui_ops_wrapped(&conversation_ui_ops);
purple_roomlist_set_ui_ops_wrapped(&roomlist_ui_ops);
@@ -2477,11 +2356,8 @@ static bool initPurple() {
purple_signal_connect_wrapped(purple_blist_get_handle_wrapped(), "blist-node-removed", &blist_handle,PURPLE_CALLBACK(NodeRemoved), NULL);
purple_signal_connect_wrapped(purple_conversations_get_handle_wrapped(), "chat-topic-changed", &conversation_handle, PURPLE_CALLBACK(conv_chat_topic_changed), NULL);
static int xfer_handle;
- purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-send-start", &xfer_handle, PURPLE_CALLBACK(fileSendStart), NULL);
- purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-recv-start", &xfer_handle, PURPLE_CALLBACK(fileRecvStart), NULL);
- purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-recv-request", &xfer_handle, PURPLE_CALLBACK(newXfer), NULL);
- purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-recv-complete", &xfer_handle, PURPLE_CALLBACK(XferReceiveComplete), NULL);
- purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-send-complete", &xfer_handle, PURPLE_CALLBACK(XferSendComplete), NULL);
+ purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-recv-request", &xfer_handle, PURPLE_CALLBACK(newXfer), &xfer_handle);
+ purple_signal_connect_wrapped(purple_xfers_get_handle_wrapped(), "file-recv-complete", &xfer_handle, PURPLE_CALLBACK(XferReceiveComplete), &xfer_handle);
//
// purple_commands_init();
@@ -2546,7 +2422,6 @@ static void transportDataReceived(gpointer data, gint source, PurpleInputConditi
purple_input_remove_wrapped(writeInput);
writeInput = 0;
}
- np->readyForData();
}
}