1 pidgin/libpurple/protocols/msn: Hack the MSN FT impl to use ui_ops.
3 * msn/slplink.c will now use ui_read and ui_write if present instead
4 of trying to directly use dest_fp (which may not even exist).
5 * It also now uses the xfer's size property if set instead of trying
6 to stat the local file (which also may not exist).
8 This is a minimal conversion which probably has a number of
9 reliability issues. Someday the MSN prpl's file transfers should
10 probably be integrated with ft.c's intended sequence of events.
12 diff a/pidgin/libpurple/protocols/msn/slplink.c b/pidgin/libpurple/protocols/msn/slplink.c
13 --- a/pidgin/libpurple/protocols/msn/slplink.c
14 +++ b/pidgin/libpurple/protocols/msn/slplink.c
15 @@ -232,6 +232,33 @@ msn_slplink_send_msg(MsnSlpLink *slplink, MsnMessage *msg)
19 +/* Return the associated xfer iff the xfer is ready to read/write. */
21 +msn_get_ready_xfer(MsnSlpLink *slplink,
22 + MsnSlpMessage *slpmsg,
23 + PurpleXferType want_type)
25 + PurpleXfer *xfer = NULL;
27 + MsnSlpCall *slpcall = slpmsg->slpcall;
28 + if (slpcall == NULL && slpmsg->session_id) {
29 + slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id);
32 + xfer = (PurpleXfer *)(slpcall->xfer);
34 + /* Can't use the priv->ready system because MSN read/write code
35 + * assumes it's not there (and it's private).
38 + || (! xfer->status & (PURPLE_XFER_STATUS_STARTED | PURPLE_XFER_STATUS_DONE))
39 + || purple_xfer_get_type(xfer) != want_type) {
47 msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
49 @@ -247,7 +274,21 @@ msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg)
51 if (slpmsg->offset < real_size)
54 + PurpleXfer *ready_xfer = msn_get_ready_xfer(slplink,
57 + PurpleXferUiOps *ui_ops = NULL;
60 + ui_ops = purple_xfer_get_ui_ops(ready_xfer);
62 + if (ui_ops && ui_ops->ui_read) {
63 + guchar *data = NULL;
64 + len = ui_ops->ui_read(ready_xfer, &data, 1202);
65 + msn_message_set_bin_data(msg, data, len);
68 + else if (slpmsg->fp)
71 len = fread(data, 1, sizeof(data), slpmsg->fp);
72 @@ -459,7 +500,9 @@ send_file_cb(MsnSlpCall *slpcall)
73 xfer = (PurpleXfer *)slpcall->xfer;
74 purple_xfer_start(slpcall->xfer, -1, NULL, 0);
75 slpmsg->fp = xfer->dest_fp;
76 - if (g_stat(purple_xfer_get_local_filename(xfer), &st) == 0)
77 + slpmsg->size = purple_xfer_get_size(xfer);
79 + && g_stat(purple_xfer_get_local_filename(xfer), &st) == 0)
80 slpmsg->size = st.st_size;
81 xfer->dest_fp = NULL; /* Disable double fclose() */
83 @@ -489,6 +532,8 @@ msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg)
87 + PurpleXfer *ready_xfer;
88 + PurpleXferUiOps *ui_ops;
90 if (purple_debug_is_verbose())
92 @@ -569,7 +614,17 @@ msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg)
97 + ready_xfer = msn_get_ready_xfer(slplink, slpmsg, PURPLE_XFER_RECEIVE);
98 + ui_ops = (PurpleXferUiOps *)NULL;
101 + ui_ops = purple_xfer_get_ui_ops(ready_xfer);
103 + if (ui_ops && ui_ops->ui_write)
105 + len = ui_ops->ui_write(ready_xfer, data, len);
107 + else if (slpmsg->fp)
109 /* fseek(slpmsg->fp, offset, SEEK_SET); */
110 len = fwrite(data, 1, len, slpmsg->fp);
111 @@ -652,7 +707,7 @@ typedef struct
112 #define MAX_FILE_NAME_LEN 0x226
115 -gen_context(const char *file_name, const char *file_path)
116 +gen_context(const char *file_name, const char *file_path, PurpleXfer *xfer)
120 @@ -666,7 +721,8 @@ gen_context(const char *file_name, const char *file_path)
124 - if (g_stat(file_path, &st) == 0)
125 + size = purple_xfer_get_size(xfer);
126 + if (!size && g_stat(file_path, &st) == 0)
130 @@ -743,7 +799,7 @@ msn_slplink_request_ft(MsnSlpLink *slplink, PurpleXfer *xfer)
132 xfer->data = slpcall;
134 - context = gen_context(fn, fp);
135 + context = gen_context(fn, fp, xfer);
137 msn_slpcall_invite(slpcall, MSN_FT_GUID, 2, context);