Fri, 21 May 2004 14:33:32 +0000
[gaim-migrate @ 9774]
" This patch renames the existing received-*-msg signals
to receiving-*msg to fit the naming of other signals
where a pointer to the message is passed (writing,
sending, displaying)
It adds new received-*-msg signals which are emitted
after the receiving signals, in line with the other
conversation signals (wrote, sent, displayed)
This is necessary to allow plugins which depend on the
final received message to work alongside plugins which
may modify the message.
One known example of this is festival-gaim alongside
gaim-encryption - festival-gaim would try to "speak"
the encrypted text:
http://sf.net/tracker/?func=detail&aid=943216&group_id=89763&atid=591320
I've tested this with gaim-encryption and festival-gaim
(locally modified so gaim-encryption uses the receiving
signal and festival uses the received signal)
All in-tree users of received-*-msg are updated to use
receiving-*-msg if they do modify the message, the
conversation-signals documentation is updated, the
signals-test.c & signal-test.tcl plugins are also updated." --Stu Tomlinson
committer: Luke Schierer <lschiere@pidgin.im>
| 4542 | 1 | /** |
| 2 | * @file msn.c The MSN protocol plugin | |
| 3 | * | |
| 4 | * gaim | |
| 5 | * | |
| 6 | * Copyright (C) 2003, Christian Hammond <chipx86@gnupdate.org> | |
|
6701
7e2db9273748
[gaim-migrate @ 7227]
Christian Hammond <chipx86@chipx86.com>
parents:
5914
diff
changeset
|
7 | * |
| 4542 | 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by | |
| 10 | * the Free Software Foundation; either version 2 of the License, or | |
| 11 | * (at your option) any later version. | |
| 12 | * | |
| 13 | * This program is distributed in the hope that it will be useful, | |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | * GNU General Public License for more details. | |
| 17 | * | |
| 18 | * You should have received a copy of the GNU General Public License | |
| 19 | * along with this program; if not, write to the Free Software | |
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 21 | * | |
| 22 | */ | |
| 23 | #include "msn.h" | |
| 24 | ||
| 25 | static struct gaim_xfer * | |
|
5564
1779a1bfbdb8
[gaim-migrate @ 5966]
Christian Hammond <chipx86@chipx86.com>
parents:
5221
diff
changeset
|
26 | find_xfer_by_cookie(GaimConnection *gc, unsigned long cookie) |
| 4542 | 27 | { |
| 28 | GSList *g; | |
| 29 | struct msn_data *md = (struct msn_data *)gc->proto_data; | |
| 30 | struct gaim_xfer *xfer = NULL; | |
| 31 | struct msn_xfer_data *xfer_data; | |
| 32 | ||
| 33 | for (g = md->file_transfers; g != NULL; g = g->next) { | |
| 34 | xfer = (struct gaim_xfer *)g->data; | |
| 35 | xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 36 | ||
| 37 | if (xfer_data->cookie == cookie) | |
| 38 | break; | |
| 39 | ||
| 40 | xfer = NULL; | |
| 41 | } | |
| 42 | ||
| 43 | return xfer; | |
| 44 | } | |
| 45 | ||
| 46 | static void | |
| 47 | msn_xfer_init(struct gaim_xfer *xfer) | |
| 48 | { | |
|
5564
1779a1bfbdb8
[gaim-migrate @ 5966]
Christian Hammond <chipx86@chipx86.com>
parents:
5221
diff
changeset
|
49 | GaimAccount *account; |
| 4542 | 50 | struct msn_xfer_data *xfer_data; |
| 51 | struct msn_switchboard *ms; | |
| 52 | char header[MSN_BUF_LEN]; | |
| 53 | char buf[MSN_BUF_LEN]; | |
| 54 | ||
| 55 | account = gaim_xfer_get_account(xfer); | |
| 56 | ||
| 57 | ms = msn_find_switch(account->gc, xfer->who); | |
| 58 | ||
| 59 | xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 60 | ||
| 61 | if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) { | |
| 62 | /* | |
| 63 | * NOTE: We actually have to wait for the next Invitation message | |
| 64 | * before the transfer starts. We handle that in | |
| 65 | * msn_xfer_start(). | |
| 66 | */ | |
| 67 | ||
| 68 | g_snprintf(header, sizeof(header), | |
| 69 | "MIME-Version: 1.0\r\n" | |
| 70 | "Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n\r\n" | |
| 71 | "Invitation-Command: ACCEPT\r\n" | |
| 72 | "Invitation-Cookie: %lu\r\n" | |
| 73 | "Launch-Application: FALSE\r\n" | |
| 74 | "Request-Data: IP-Address:\r\n", | |
| 75 | (unsigned long)xfer_data->cookie); | |
| 76 | ||
| 77 | g_snprintf(buf, sizeof(buf), "MSG %u N %d\r\n%s\r\n\r\n", | |
| 78 | ++ms->trId, strlen(header) + strlen("\r\n\r\n"), | |
| 79 | header); | |
| 80 | ||
| 81 | if (msn_write(ms->fd, buf, strlen(buf)) < 0) { | |
| 82 | msn_kill_switch(ms); | |
| 83 | gaim_xfer_destroy(xfer); | |
| 84 | ||
| 85 | return; | |
| 86 | } | |
| 87 | } | |
| 88 | } | |
| 89 | ||
| 90 | static void | |
| 91 | msn_xfer_start(struct gaim_xfer *xfer) | |
| 92 | { | |
| 93 | struct msn_xfer_data *xfer_data; | |
| 94 | ||
| 95 | xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 96 | ||
| 97 | xfer_data->transferring = TRUE; | |
| 98 | ||
| 99 | if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) { | |
| 100 | char sendbuf[MSN_BUF_LEN]; | |
| 101 | ||
| 102 | /* Send the TFR string to request the start of a transfer. */ | |
| 103 | g_snprintf(sendbuf, sizeof(sendbuf), "TFR\r\n"); | |
| 104 | ||
| 105 | if (msn_write(xfer->fd, sendbuf, strlen(sendbuf)) < 0) { | |
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
106 | gaim_xfer_cancel_remote(xfer); |
| 4542 | 107 | } |
| 108 | } | |
| 109 | } | |
| 110 | ||
| 111 | static void | |
| 112 | msn_xfer_end(struct gaim_xfer *xfer) | |
| 113 | { | |
|
5564
1779a1bfbdb8
[gaim-migrate @ 5966]
Christian Hammond <chipx86@chipx86.com>
parents:
5221
diff
changeset
|
114 | GaimAccount *account; |
| 4542 | 115 | struct msn_xfer_data *xfer_data; |
| 116 | struct msn_data *md; | |
| 117 | ||
| 118 | account = gaim_xfer_get_account(xfer); | |
| 119 | xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 120 | md = (struct msn_data *)account->gc->proto_data; | |
| 121 | ||
| 122 | if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) { | |
| 123 | char sendbuf[MSN_BUF_LEN]; | |
| 124 | ||
| 125 | g_snprintf(sendbuf, sizeof(sendbuf), "BYE 16777989\r\n"); | |
| 126 | ||
| 127 | msn_write(xfer->fd, sendbuf, strlen(sendbuf)); | |
| 128 | ||
| 129 | md->file_transfers = g_slist_remove(md->file_transfers, xfer); | |
| 130 | ||
| 131 | g_free(xfer_data); | |
| 132 | xfer->data = NULL; | |
| 133 | } | |
| 134 | } | |
| 135 | ||
| 136 | static void | |
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
137 | msn_xfer_cancel_send(struct gaim_xfer *xfer) |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
138 | { |
|
5564
1779a1bfbdb8
[gaim-migrate @ 5966]
Christian Hammond <chipx86@chipx86.com>
parents:
5221
diff
changeset
|
139 | GaimAccount *account; |
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
140 | struct msn_xfer_data *xfer_data; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
141 | struct msn_data *md; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
142 | |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
143 | xfer_data = (struct msn_xfer_data *)xfer->data; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
144 | |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
145 | xfer_data->do_cancel = TRUE; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
146 | |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
147 | account = gaim_xfer_get_account(xfer); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
148 | md = (struct msn_data *)account->gc->proto_data; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
149 | |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
150 | md->file_transfers = g_slist_remove(md->file_transfers, xfer); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
151 | |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
152 | g_free(xfer_data); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
153 | xfer->data = NULL; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
154 | } |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
155 | |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
156 | static void |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
157 | msn_xfer_cancel_recv(struct gaim_xfer *xfer) |
| 4542 | 158 | { |
|
5564
1779a1bfbdb8
[gaim-migrate @ 5966]
Christian Hammond <chipx86@chipx86.com>
parents:
5221
diff
changeset
|
159 | GaimAccount *account; |
| 4542 | 160 | struct msn_xfer_data *xfer_data; |
| 161 | struct msn_data *md; | |
| 162 | ||
| 163 | account = gaim_xfer_get_account(xfer); | |
| 164 | xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 165 | md = (struct msn_data *)account->gc->proto_data; | |
| 166 | ||
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
167 | md->file_transfers = g_slist_remove(md->file_transfers, xfer); |
| 4542 | 168 | |
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
169 | g_free(xfer_data); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
170 | xfer->data = NULL; |
| 4542 | 171 | } |
| 172 | ||
| 173 | static size_t | |
| 174 | msn_xfer_read(char **buffer, struct gaim_xfer *xfer) | |
| 175 | { | |
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
176 | struct msn_xfer_data *xfer_data; |
| 4542 | 177 | unsigned char header[3]; |
| 178 | size_t len, size; | |
| 179 | ||
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
180 | xfer_data = (struct msn_xfer_data *)xfer->data; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
181 | |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
182 | if (xfer_data->do_cancel) |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
183 | { |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
184 | write(xfer->fd, "CCL\n", 4); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
185 | |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
186 | return 0; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
187 | } |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
188 | |
| 4542 | 189 | if (read(xfer->fd, header, sizeof(header)) < 3) { |
| 190 | gaim_xfer_set_completed(xfer, TRUE); | |
| 191 | return 0; | |
| 192 | } | |
| 193 | ||
| 194 | if (header[0] != 0) { | |
|
5221
86a1444cc9ac
[gaim-migrate @ 5591]
Christian Hammond <chipx86@chipx86.com>
parents:
4793
diff
changeset
|
195 | gaim_debug(GAIM_DEBUG_ERROR, "msn", |
|
86a1444cc9ac
[gaim-migrate @ 5591]
Christian Hammond <chipx86@chipx86.com>
parents:
4793
diff
changeset
|
196 | "MSNFTP: Invalid header[0]: %d. Aborting.\n", |
|
86a1444cc9ac
[gaim-migrate @ 5591]
Christian Hammond <chipx86@chipx86.com>
parents:
4793
diff
changeset
|
197 | header[0]); |
| 4542 | 198 | return 0; |
| 199 | } | |
| 200 | ||
| 201 | size = header[1] | (header[2] << 8); | |
| 202 | ||
| 203 | *buffer = g_new0(char, size); | |
| 204 | ||
| 205 | for (len = 0; | |
| 206 | len < size; | |
| 207 | len += read(xfer->fd, *buffer + len, size - len)) | |
| 208 | ; | |
| 209 | ||
| 210 | if (len == 0) | |
| 211 | gaim_xfer_set_completed(xfer, TRUE); | |
| 212 | ||
| 213 | return len; | |
| 214 | } | |
| 215 | ||
| 216 | static size_t | |
| 217 | msn_xfer_write(const char *buffer, size_t size, struct gaim_xfer *xfer) | |
| 218 | { | |
|
5564
1779a1bfbdb8
[gaim-migrate @ 5966]
Christian Hammond <chipx86@chipx86.com>
parents:
5221
diff
changeset
|
219 | GaimAccount *account; |
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
220 | struct msn_xfer_data *xfer_data; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
221 | struct msn_data *md; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
222 | unsigned char header[3]; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
223 | |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
224 | xfer_data = (struct msn_xfer_data *)xfer->data; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
225 | account = gaim_xfer_get_account(xfer); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
226 | md = (struct msn_data *)account->gc->proto_data; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
227 | |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
228 | if (xfer_data->do_cancel) |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
229 | { |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
230 | header[0] = 1; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
231 | header[1] = 0; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
232 | header[2] = 0; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
233 | |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
234 | if (write(xfer->fd, header, sizeof(header)) < 3) { |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
235 | gaim_xfer_cancel_remote(xfer); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
236 | return 0; |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
237 | } |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
238 | } |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
239 | else |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
240 | { |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
241 | /* Not implemented yet. */ |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
242 | } |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
243 | |
| 4542 | 244 | return 0; |
| 245 | } | |
| 246 | ||
| 247 | static int | |
| 248 | msn_process_msnftp(struct gaim_xfer *xfer, gint source, const char *buf) | |
| 249 | { | |
| 250 | struct msn_xfer_data *xfer_data; | |
|
5564
1779a1bfbdb8
[gaim-migrate @ 5966]
Christian Hammond <chipx86@chipx86.com>
parents:
5221
diff
changeset
|
251 | GaimAccount *account; |
| 4542 | 252 | char sendbuf[MSN_BUF_LEN]; |
| 253 | ||
| 254 | xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 255 | account = gaim_xfer_get_account(xfer); | |
| 256 | ||
| 4793 | 257 | if (!g_ascii_strncasecmp(buf, "VER MSNFTP", 10)) { |
| 4542 | 258 | /* Send the USR string */ |
| 259 | g_snprintf(sendbuf, sizeof(sendbuf), "USR %s %lu\r\n", | |
| 260 | account->gc->username, | |
| 261 | (unsigned long)xfer_data->authcookie); | |
| 262 | ||
| 263 | if (msn_write(source, sendbuf, strlen(sendbuf)) < 0) { | |
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
264 | gaim_xfer_cancel_remote(xfer); /* ? */ |
| 4542 | 265 | |
| 266 | return 0; | |
| 267 | } | |
| 268 | } | |
| 4793 | 269 | else if (!g_ascii_strncasecmp(buf, "FIL", 3)) { |
| 4542 | 270 | gaim_input_remove(xfer_data->inpa); |
| 271 | xfer_data->inpa = 0; | |
| 272 | ||
| 273 | gaim_xfer_start(xfer, source, NULL, 0); | |
| 274 | } | |
| 275 | #if 0 | |
| 276 | char *tmp = buf; | |
| 277 | ||
| 278 | /* | |
| 279 | * This data is the size, but we already have | |
| 280 | * the size, so who cares. | |
| 281 | */ | |
| 282 | GET_NEXT(tmp); | |
| 283 | ||
| 284 | /* Send the TFR string to request the start of a transfer. */ | |
| 285 | g_snprintf(sendbuf, sizeof(sendbuf), "TFR\r\n"); | |
| 286 | ||
| 287 | ||
| 288 | if (msn_write(source, sendbuf, strlen(sendbuf)) < 0) { | |
| 289 | gaim_xfer_cancel(xfer); | |
| 290 | ||
| 291 | return 0; | |
| 292 | } | |
| 293 | #endif | |
| 294 | ||
| 295 | return 1; | |
| 296 | } | |
| 297 | ||
| 298 | static void | |
| 299 | msn_msnftp_cb(gpointer data, gint source, GaimInputCondition cond) | |
| 300 | { | |
| 301 | struct gaim_xfer *xfer; | |
| 302 | struct msn_xfer_data *xfer_data; | |
| 303 | char buf[MSN_BUF_LEN]; | |
| 304 | gboolean cont = TRUE; | |
| 305 | size_t len; | |
| 306 | ||
| 307 | xfer = (struct gaim_xfer *)data; | |
| 308 | xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 309 | ||
| 310 | len = read(source, buf, sizeof(buf)); | |
| 311 | ||
| 312 | if (len <= 0) { | |
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
313 | gaim_xfer_cancel_remote(xfer); |
| 4542 | 314 | return; |
| 315 | } | |
| 316 | ||
| 317 | xfer_data->rxqueue = g_realloc(xfer_data->rxqueue, | |
| 318 | len + xfer_data->rxlen); | |
| 319 | memcpy(xfer_data->rxqueue + xfer_data->rxlen, buf, len); | |
| 320 | xfer_data->rxlen += len; | |
| 321 | ||
| 322 | while (cont) { | |
| 323 | char *end = xfer_data->rxqueue; | |
| 324 | char *cmd; | |
| 325 | int cmdlen; | |
| 326 | int i = 0; | |
| 327 | ||
| 328 | if (!xfer_data->rxlen) | |
| 329 | return; | |
| 330 | ||
| 331 | for (i = 0; i < xfer_data->rxlen - 1; end++, i++) { | |
| 332 | if (*end == '\r' && *(end + 1) == '\n') | |
| 333 | break; | |
| 334 | } | |
| 335 | ||
| 336 | if (i == xfer_data->rxlen - 1) | |
| 337 | return; | |
| 338 | ||
| 339 | cmdlen = end - xfer_data->rxqueue + 2; | |
| 340 | cmd = xfer_data->rxqueue; | |
| 341 | ||
| 342 | xfer_data->rxlen -= cmdlen; | |
| 343 | ||
| 344 | if (xfer_data->rxlen) | |
| 345 | xfer_data->rxqueue = g_memdup(cmd + cmdlen, xfer_data->rxlen); | |
| 346 | else { | |
| 347 | xfer_data->rxqueue = NULL; | |
| 348 | cmd = g_realloc(cmd, cmdlen + 1); | |
| 349 | } | |
| 350 | ||
| 351 | cmd[cmdlen] = '\0'; | |
| 352 | ||
| 353 | g_strchomp(cmd); | |
| 354 | ||
| 355 | cont = msn_process_msnftp(xfer, source, cmd); | |
| 356 | ||
| 357 | g_free(cmd); | |
| 358 | } | |
| 359 | } | |
| 360 | ||
| 361 | static void | |
| 362 | msn_msnftp_connect(gpointer data, gint source, GaimInputCondition cond) | |
| 363 | { | |
|
5564
1779a1bfbdb8
[gaim-migrate @ 5966]
Christian Hammond <chipx86@chipx86.com>
parents:
5221
diff
changeset
|
364 | GaimAccount *account; |
| 4542 | 365 | struct gaim_xfer *xfer; |
| 366 | struct msn_xfer_data *xfer_data; | |
| 367 | char buf[MSN_BUF_LEN]; | |
| 368 | ||
| 369 | xfer = (struct gaim_xfer *)data; | |
| 370 | account = gaim_xfer_get_account(xfer); | |
| 371 | xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 372 | ||
| 5914 | 373 | if (source == -1 || !g_slist_find(gaim_connections_get_all(), account->gc)) { |
|
5221
86a1444cc9ac
[gaim-migrate @ 5591]
Christian Hammond <chipx86@chipx86.com>
parents:
4793
diff
changeset
|
374 | gaim_debug(GAIM_DEBUG_ERROR, "msn", |
|
86a1444cc9ac
[gaim-migrate @ 5591]
Christian Hammond <chipx86@chipx86.com>
parents:
4793
diff
changeset
|
375 | "MSNFTP: Error establishing connection\n"); |
| 4542 | 376 | close(source); |
| 377 | ||
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
378 | gaim_xfer_cancel_remote(xfer); |
| 4542 | 379 | |
| 380 | return; | |
| 381 | } | |
| 382 | ||
| 383 | g_snprintf(buf, sizeof(buf), "VER MSNFTP\r\n"); | |
| 384 | ||
| 385 | if (msn_write(source, buf, strlen(buf)) < 0) { | |
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
386 | gaim_xfer_cancel_remote(xfer); |
| 4542 | 387 | return; |
| 388 | } | |
| 389 | ||
| 390 | xfer_data->inpa = gaim_input_add(source, GAIM_INPUT_READ, | |
| 391 | msn_msnftp_cb, xfer); | |
| 392 | } | |
| 393 | ||
| 394 | void | |
| 395 | msn_process_ft_msg(struct msn_switchboard *ms, char *msg) | |
| 396 | { | |
| 397 | struct gaim_xfer *xfer; | |
| 398 | struct msn_xfer_data *xfer_data; | |
| 399 | struct msn_data *md = ms->gc->proto_data; | |
| 400 | char *tmp = msg; | |
| 401 | ||
| 402 | if (strstr(msg, "Application-GUID: " MSN_FT_GUID) && | |
| 403 | strstr(msg, "Invitation-Command: INVITE")) { | |
| 404 | ||
| 405 | /* | |
| 406 | * First invitation message, requesting an ACCEPT or CANCEL from | |
| 407 | * the recipient. Used in incoming file transfers. | |
| 408 | */ | |
| 409 | ||
| 410 | char *filename; | |
| 411 | char *cookie_s, *filesize_s; | |
| 412 | ||
| 413 | tmp = strstr(msg, "Invitation-Cookie"); | |
| 414 | GET_NEXT(tmp); | |
| 415 | cookie_s = tmp; | |
| 416 | GET_NEXT(tmp); | |
| 417 | GET_NEXT(tmp); | |
| 418 | filename = tmp; | |
| 419 | ||
| 420 | /* Needed for filenames with spaces */ | |
| 421 | tmp = strchr(tmp, '\r'); | |
| 422 | *tmp = '\0'; | |
| 423 | tmp += 2; | |
| 424 | ||
| 425 | GET_NEXT(tmp); | |
| 426 | filesize_s = tmp; | |
| 427 | GET_NEXT(tmp); | |
| 428 | ||
| 429 | /* Setup the MSN-specific file transfer data */ | |
| 430 | xfer_data = g_new0(struct msn_xfer_data, 1); | |
| 431 | xfer_data->cookie = atoi(cookie_s); | |
| 432 | xfer_data->transferring = FALSE; | |
| 433 | ||
| 434 | /* Build the file transfer handle. */ | |
| 435 | xfer = gaim_xfer_new(ms->gc->account, GAIM_XFER_RECEIVE, ms->msguser); | |
| 436 | xfer->data = xfer_data; | |
| 437 | ||
| 438 | /* Set the info about the incoming file. */ | |
| 439 | gaim_xfer_set_filename(xfer, filename); | |
| 440 | gaim_xfer_set_size(xfer, atoi(filesize_s)); | |
| 441 | ||
| 442 | /* Setup our I/O op functions */ | |
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
443 | gaim_xfer_set_init_fnc(xfer, msn_xfer_init); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
444 | gaim_xfer_set_start_fnc(xfer, msn_xfer_start); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
445 | gaim_xfer_set_end_fnc(xfer, msn_xfer_end); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
446 | gaim_xfer_set_cancel_send_fnc(xfer, msn_xfer_cancel_send); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
447 | gaim_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel_recv); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
448 | gaim_xfer_set_read_fnc(xfer, msn_xfer_read); |
|
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
449 | gaim_xfer_set_write_fnc(xfer, msn_xfer_write); |
| 4542 | 450 | |
| 451 | /* Keep track of this transfer for later. */ | |
| 452 | md->file_transfers = g_slist_append(md->file_transfers, xfer); | |
| 453 | ||
| 454 | /* Now perform the request */ | |
| 455 | gaim_xfer_request(xfer); | |
| 456 | } | |
| 457 | else if (strstr(msg, "Invitation-Command: ACCEPT")) { | |
| 458 | ||
| 459 | /* | |
| 460 | * XXX I hope these checks don't return false positives, but they | |
| 461 | * seem like they should work. The only issue is alternative | |
| 462 | * protocols, *maybe*. | |
| 463 | */ | |
| 464 | ||
| 465 | if (strstr(msg, "AuthCookie:")) { | |
| 466 | ||
| 467 | /* | |
| 468 | * Second invitation request, sent after the recipient accepts | |
| 469 | * the request. Used in incoming file transfers. | |
| 470 | */ | |
| 471 | char *cookie_s, *ip, *port_s, *authcookie_s; | |
| 472 | char ip_s[16]; | |
| 473 | ||
| 474 | tmp = strstr(msg, "Invitation-Cookie"); | |
| 475 | GET_NEXT(tmp); | |
| 476 | cookie_s = tmp; | |
| 477 | GET_NEXT(tmp); | |
| 478 | GET_NEXT(tmp); | |
| 479 | ip = tmp; | |
| 480 | GET_NEXT(tmp); | |
| 481 | GET_NEXT(tmp); | |
| 482 | port_s = tmp; | |
| 483 | GET_NEXT(tmp); | |
| 484 | GET_NEXT(tmp); | |
| 485 | authcookie_s = tmp; | |
| 486 | GET_NEXT(tmp); | |
| 487 | ||
| 488 | xfer = find_xfer_by_cookie(ms->gc, atoi(cookie_s)); | |
| 489 | ||
| 490 | if (xfer == NULL) | |
| 491 | { | |
|
5221
86a1444cc9ac
[gaim-migrate @ 5591]
Christian Hammond <chipx86@chipx86.com>
parents:
4793
diff
changeset
|
492 | gaim_debug(GAIM_DEBUG_ERROR, "msn", |
|
86a1444cc9ac
[gaim-migrate @ 5591]
Christian Hammond <chipx86@chipx86.com>
parents:
4793
diff
changeset
|
493 | "MSNFTP : Cookie not found. " |
|
86a1444cc9ac
[gaim-migrate @ 5591]
Christian Hammond <chipx86@chipx86.com>
parents:
4793
diff
changeset
|
494 | "File transfer aborted.\n"); |
| 4542 | 495 | return; |
| 496 | } | |
| 497 | ||
| 498 | xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 499 | xfer_data->authcookie = atol(authcookie_s); | |
| 500 | ||
| 501 | strncpy(ip_s, ip, sizeof(ip_s)); | |
| 502 | ||
|
5681
514fbc5374dc
[gaim-migrate @ 6100]
Christian Hammond <chipx86@chipx86.com>
parents:
5564
diff
changeset
|
503 | if (gaim_proxy_connect(xfer->account, ip_s, atoi(port_s), |
| 4542 | 504 | msn_msnftp_connect, xfer) != 0) { |
| 505 | ||
|
4675
8e0a7b537ca2
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
506 | gaim_xfer_cancel_remote(xfer); |
| 4542 | 507 | |
| 508 | return; | |
| 509 | } | |
| 510 | } | |
| 511 | else | |
| 512 | { | |
| 513 | /* | |
| 514 | * An accept message from the recipient. Used in outgoing | |
| 515 | * file transfers. | |
| 516 | */ | |
| 517 | } | |
| 518 | } | |
| 519 | } | |
| 520 |