Mercurial > pidgin
annotate src/protocols/msn/ft.c @ 4891:cfa045006bec
[gaim-migrate @ 5221]
this saves the blist.xml file to an alternate name, and then moves it, that
way we don't lose your precious buddies if gaim crashes.
Of course, if gaim were to crash, it wouldn't be gaim's fault, it would be
the fault of some external force. This is because gaim is perfect, and
Sean is perfect. Yeah.
This should be done for .gaimrc too, but i'm too tired to do that right now.
committer: Tailor Script <tailor@pidgin.im>
| author | Nathan Walp <nwalp@pidgin.im> |
|---|---|
| date | Tue, 25 Mar 2003 06:35:45 +0000 |
| parents | 677d3cb193a1 |
| children | abe4d103e300 |
| rev | line source |
|---|---|
| 4542 | 1 /** |
| 2 * @file msn.c The MSN protocol plugin | |
| 3 * | |
| 4 * gaim | |
| 5 * | |
| 6 * Copyright (C) 2003, Christian Hammond <chipx86@gnupdate.org> | |
| 7 * | |
| 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 | |
|
4546
a951bb590857
[gaim-migrate @ 4825]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4542
diff
changeset
|
25 #ifdef _WIN32 |
|
a951bb590857
[gaim-migrate @ 4825]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4542
diff
changeset
|
26 #include "win32dep.h" |
|
a951bb590857
[gaim-migrate @ 4825]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4542
diff
changeset
|
27 #endif |
|
a951bb590857
[gaim-migrate @ 4825]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
4542
diff
changeset
|
28 |
| 4542 | 29 G_MODULE_IMPORT GSList *connections; |
| 30 | |
| 31 static struct gaim_xfer * | |
| 32 find_xfer_by_cookie(struct gaim_connection *gc, unsigned long cookie) | |
| 33 { | |
| 34 GSList *g; | |
| 35 struct msn_data *md = (struct msn_data *)gc->proto_data; | |
| 36 struct gaim_xfer *xfer = NULL; | |
| 37 struct msn_xfer_data *xfer_data; | |
| 38 | |
| 39 for (g = md->file_transfers; g != NULL; g = g->next) { | |
| 40 xfer = (struct gaim_xfer *)g->data; | |
| 41 xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 42 | |
| 43 if (xfer_data->cookie == cookie) | |
| 44 break; | |
| 45 | |
| 46 xfer = NULL; | |
| 47 } | |
| 48 | |
| 49 return xfer; | |
| 50 } | |
| 51 | |
| 52 static void | |
| 53 msn_xfer_init(struct gaim_xfer *xfer) | |
| 54 { | |
| 55 struct gaim_account *account; | |
| 56 struct msn_xfer_data *xfer_data; | |
| 57 struct msn_switchboard *ms; | |
| 58 char header[MSN_BUF_LEN]; | |
| 59 char buf[MSN_BUF_LEN]; | |
| 60 | |
| 61 account = gaim_xfer_get_account(xfer); | |
| 62 | |
| 63 ms = msn_find_switch(account->gc, xfer->who); | |
| 64 | |
| 65 xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 66 | |
| 67 if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) { | |
| 68 /* | |
| 69 * NOTE: We actually have to wait for the next Invitation message | |
| 70 * before the transfer starts. We handle that in | |
| 71 * msn_xfer_start(). | |
| 72 */ | |
| 73 | |
| 74 g_snprintf(header, sizeof(header), | |
| 75 "MIME-Version: 1.0\r\n" | |
| 76 "Content-Type: text/x-msmsgsinvite; charset=UTF-8\r\n\r\n" | |
| 77 "Invitation-Command: ACCEPT\r\n" | |
| 78 "Invitation-Cookie: %lu\r\n" | |
| 79 "Launch-Application: FALSE\r\n" | |
| 80 "Request-Data: IP-Address:\r\n", | |
| 81 (unsigned long)xfer_data->cookie); | |
| 82 | |
| 83 g_snprintf(buf, sizeof(buf), "MSG %u N %d\r\n%s\r\n\r\n", | |
| 84 ++ms->trId, strlen(header) + strlen("\r\n\r\n"), | |
| 85 header); | |
| 86 | |
| 87 if (msn_write(ms->fd, buf, strlen(buf)) < 0) { | |
| 88 msn_kill_switch(ms); | |
| 89 gaim_xfer_destroy(xfer); | |
| 90 | |
| 91 return; | |
| 92 } | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 static void | |
| 97 msn_xfer_start(struct gaim_xfer *xfer) | |
| 98 { | |
| 99 struct msn_xfer_data *xfer_data; | |
| 100 | |
| 101 xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 102 | |
| 103 xfer_data->transferring = TRUE; | |
| 104 | |
| 105 if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) { | |
| 106 char sendbuf[MSN_BUF_LEN]; | |
| 107 | |
| 108 /* Send the TFR string to request the start of a transfer. */ | |
| 109 g_snprintf(sendbuf, sizeof(sendbuf), "TFR\r\n"); | |
| 110 | |
| 111 if (msn_write(xfer->fd, sendbuf, strlen(sendbuf)) < 0) { | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
112 gaim_xfer_cancel_remote(xfer); |
| 4542 | 113 } |
| 114 } | |
| 115 } | |
| 116 | |
| 117 static void | |
| 118 msn_xfer_end(struct gaim_xfer *xfer) | |
| 119 { | |
| 120 struct gaim_account *account; | |
| 121 struct msn_xfer_data *xfer_data; | |
| 122 struct msn_data *md; | |
| 123 | |
| 124 account = gaim_xfer_get_account(xfer); | |
| 125 xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 126 md = (struct msn_data *)account->gc->proto_data; | |
| 127 | |
| 128 if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) { | |
| 129 char sendbuf[MSN_BUF_LEN]; | |
| 130 | |
| 131 g_snprintf(sendbuf, sizeof(sendbuf), "BYE 16777989\r\n"); | |
| 132 | |
| 133 msn_write(xfer->fd, sendbuf, strlen(sendbuf)); | |
| 134 | |
| 135 md->file_transfers = g_slist_remove(md->file_transfers, xfer); | |
| 136 | |
| 137 g_free(xfer_data); | |
| 138 xfer->data = NULL; | |
| 139 } | |
| 140 } | |
| 141 | |
| 142 static void | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
143 msn_xfer_cancel_send(struct gaim_xfer *xfer) |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
144 { |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
145 struct gaim_account *account; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
146 struct msn_xfer_data *xfer_data; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
147 struct msn_data *md; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
148 |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
149 xfer_data = (struct msn_xfer_data *)xfer->data; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
150 |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
151 xfer_data->do_cancel = TRUE; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
152 |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
153 account = gaim_xfer_get_account(xfer); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
154 md = (struct msn_data *)account->gc->proto_data; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
155 |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
156 md->file_transfers = g_slist_remove(md->file_transfers, xfer); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
157 |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
158 g_free(xfer_data); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
159 xfer->data = NULL; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
160 } |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
161 |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
162 static void |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
163 msn_xfer_cancel_recv(struct gaim_xfer *xfer) |
| 4542 | 164 { |
| 165 struct gaim_account *account; | |
| 166 struct msn_xfer_data *xfer_data; | |
| 167 struct msn_data *md; | |
| 168 | |
| 169 account = gaim_xfer_get_account(xfer); | |
| 170 xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 171 md = (struct msn_data *)account->gc->proto_data; | |
| 172 | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
173 md->file_transfers = g_slist_remove(md->file_transfers, xfer); |
| 4542 | 174 |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
175 g_free(xfer_data); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
176 xfer->data = NULL; |
| 4542 | 177 } |
| 178 | |
| 179 static size_t | |
| 180 msn_xfer_read(char **buffer, struct gaim_xfer *xfer) | |
| 181 { | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
182 struct msn_xfer_data *xfer_data; |
| 4542 | 183 unsigned char header[3]; |
| 184 size_t len, size; | |
| 185 | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
186 xfer_data = (struct msn_xfer_data *)xfer->data; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
187 |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
188 if (xfer_data->do_cancel) |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
189 { |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
190 write(xfer->fd, "CCL\n", 4); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
191 |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
192 return 0; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
193 } |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
194 |
| 4542 | 195 if (read(xfer->fd, header, sizeof(header)) < 3) { |
| 196 gaim_xfer_set_completed(xfer, TRUE); | |
| 197 return 0; | |
| 198 } | |
| 199 | |
| 200 if (header[0] != 0) { | |
| 201 debug_printf("MSNFTP: Invalid header[0]: %d. Aborting.\n", | |
| 202 header[0]); | |
| 203 return 0; | |
| 204 } | |
| 205 | |
| 206 size = header[1] | (header[2] << 8); | |
| 207 | |
| 208 *buffer = g_new0(char, size); | |
| 209 | |
| 210 for (len = 0; | |
| 211 len < size; | |
| 212 len += read(xfer->fd, *buffer + len, size - len)) | |
| 213 ; | |
| 214 | |
| 215 if (len == 0) | |
| 216 gaim_xfer_set_completed(xfer, TRUE); | |
| 217 | |
| 218 return len; | |
| 219 } | |
| 220 | |
| 221 static size_t | |
| 222 msn_xfer_write(const char *buffer, size_t size, struct gaim_xfer *xfer) | |
| 223 { | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
224 struct gaim_account *account; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
225 struct msn_xfer_data *xfer_data; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
226 struct msn_data *md; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
227 unsigned char header[3]; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
228 |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
229 xfer_data = (struct msn_xfer_data *)xfer->data; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
230 account = gaim_xfer_get_account(xfer); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
231 md = (struct msn_data *)account->gc->proto_data; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
232 |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
233 if (xfer_data->do_cancel) |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
234 { |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
235 header[0] = 1; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
236 header[1] = 0; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
237 header[2] = 0; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
238 |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
239 if (write(xfer->fd, header, sizeof(header)) < 3) { |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
240 gaim_xfer_cancel_remote(xfer); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
241 return 0; |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
242 } |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
243 } |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
244 else |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
245 { |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
246 /* Not implemented yet. */ |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
247 } |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
248 |
| 4542 | 249 return 0; |
| 250 } | |
| 251 | |
| 252 static int | |
| 253 msn_process_msnftp(struct gaim_xfer *xfer, gint source, const char *buf) | |
| 254 { | |
| 255 struct msn_xfer_data *xfer_data; | |
| 256 struct gaim_account *account; | |
| 257 char sendbuf[MSN_BUF_LEN]; | |
| 258 | |
| 259 xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 260 account = gaim_xfer_get_account(xfer); | |
| 261 | |
| 4793 | 262 if (!g_ascii_strncasecmp(buf, "VER MSNFTP", 10)) { |
| 4542 | 263 /* Send the USR string */ |
| 264 g_snprintf(sendbuf, sizeof(sendbuf), "USR %s %lu\r\n", | |
| 265 account->gc->username, | |
| 266 (unsigned long)xfer_data->authcookie); | |
| 267 | |
| 268 if (msn_write(source, sendbuf, strlen(sendbuf)) < 0) { | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
269 gaim_xfer_cancel_remote(xfer); /* ? */ |
| 4542 | 270 |
| 271 return 0; | |
| 272 } | |
| 273 } | |
| 4793 | 274 else if (!g_ascii_strncasecmp(buf, "FIL", 3)) { |
| 4542 | 275 gaim_input_remove(xfer_data->inpa); |
| 276 xfer_data->inpa = 0; | |
| 277 | |
| 278 gaim_xfer_start(xfer, source, NULL, 0); | |
| 279 } | |
| 280 #if 0 | |
| 281 char *tmp = buf; | |
| 282 | |
| 283 /* | |
| 284 * This data is the size, but we already have | |
| 285 * the size, so who cares. | |
| 286 */ | |
| 287 GET_NEXT(tmp); | |
| 288 | |
| 289 /* Send the TFR string to request the start of a transfer. */ | |
| 290 g_snprintf(sendbuf, sizeof(sendbuf), "TFR\r\n"); | |
| 291 | |
| 292 | |
| 293 if (msn_write(source, sendbuf, strlen(sendbuf)) < 0) { | |
| 294 gaim_xfer_cancel(xfer); | |
| 295 | |
| 296 return 0; | |
| 297 } | |
| 298 #endif | |
| 299 | |
| 300 return 1; | |
| 301 } | |
| 302 | |
| 303 static void | |
| 304 msn_msnftp_cb(gpointer data, gint source, GaimInputCondition cond) | |
| 305 { | |
| 306 struct gaim_xfer *xfer; | |
| 307 struct msn_xfer_data *xfer_data; | |
| 308 char buf[MSN_BUF_LEN]; | |
| 309 gboolean cont = TRUE; | |
| 310 size_t len; | |
| 311 | |
| 312 xfer = (struct gaim_xfer *)data; | |
| 313 xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 314 | |
| 315 len = read(source, buf, sizeof(buf)); | |
| 316 | |
| 317 if (len <= 0) { | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
318 gaim_xfer_cancel_remote(xfer); |
| 4542 | 319 return; |
| 320 } | |
| 321 | |
| 322 xfer_data->rxqueue = g_realloc(xfer_data->rxqueue, | |
| 323 len + xfer_data->rxlen); | |
| 324 memcpy(xfer_data->rxqueue + xfer_data->rxlen, buf, len); | |
| 325 xfer_data->rxlen += len; | |
| 326 | |
| 327 while (cont) { | |
| 328 char *end = xfer_data->rxqueue; | |
| 329 char *cmd; | |
| 330 int cmdlen; | |
| 331 int i = 0; | |
| 332 | |
| 333 if (!xfer_data->rxlen) | |
| 334 return; | |
| 335 | |
| 336 for (i = 0; i < xfer_data->rxlen - 1; end++, i++) { | |
| 337 if (*end == '\r' && *(end + 1) == '\n') | |
| 338 break; | |
| 339 } | |
| 340 | |
| 341 if (i == xfer_data->rxlen - 1) | |
| 342 return; | |
| 343 | |
| 344 cmdlen = end - xfer_data->rxqueue + 2; | |
| 345 cmd = xfer_data->rxqueue; | |
| 346 | |
| 347 xfer_data->rxlen -= cmdlen; | |
| 348 | |
| 349 if (xfer_data->rxlen) | |
| 350 xfer_data->rxqueue = g_memdup(cmd + cmdlen, xfer_data->rxlen); | |
| 351 else { | |
| 352 xfer_data->rxqueue = NULL; | |
| 353 cmd = g_realloc(cmd, cmdlen + 1); | |
| 354 } | |
| 355 | |
| 356 cmd[cmdlen] = '\0'; | |
| 357 | |
| 358 g_strchomp(cmd); | |
| 359 | |
| 360 cont = msn_process_msnftp(xfer, source, cmd); | |
| 361 | |
| 362 g_free(cmd); | |
| 363 } | |
| 364 } | |
| 365 | |
| 366 static void | |
| 367 msn_msnftp_connect(gpointer data, gint source, GaimInputCondition cond) | |
| 368 { | |
| 369 struct gaim_account *account; | |
| 370 struct gaim_xfer *xfer; | |
| 371 struct msn_xfer_data *xfer_data; | |
| 372 char buf[MSN_BUF_LEN]; | |
| 373 | |
| 374 xfer = (struct gaim_xfer *)data; | |
| 375 account = gaim_xfer_get_account(xfer); | |
| 376 xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 377 | |
| 378 if (source == -1 || !g_slist_find(connections, account->gc)) { | |
| 379 debug_printf("MSNFTP: Error establishing connection\n"); | |
| 380 close(source); | |
| 381 | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
382 gaim_xfer_cancel_remote(xfer); |
| 4542 | 383 |
| 384 return; | |
| 385 } | |
| 386 | |
| 387 g_snprintf(buf, sizeof(buf), "VER MSNFTP\r\n"); | |
| 388 | |
| 389 if (msn_write(source, buf, strlen(buf)) < 0) { | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
390 gaim_xfer_cancel_remote(xfer); |
| 4542 | 391 return; |
| 392 } | |
| 393 | |
| 394 xfer_data->inpa = gaim_input_add(source, GAIM_INPUT_READ, | |
| 395 msn_msnftp_cb, xfer); | |
| 396 } | |
| 397 | |
| 398 void | |
| 399 msn_process_ft_msg(struct msn_switchboard *ms, char *msg) | |
| 400 { | |
| 401 struct gaim_xfer *xfer; | |
| 402 struct msn_xfer_data *xfer_data; | |
| 403 struct msn_data *md = ms->gc->proto_data; | |
| 404 char *tmp = msg; | |
| 405 | |
| 406 if (strstr(msg, "Application-GUID: " MSN_FT_GUID) && | |
| 407 strstr(msg, "Invitation-Command: INVITE")) { | |
| 408 | |
| 409 /* | |
| 410 * First invitation message, requesting an ACCEPT or CANCEL from | |
| 411 * the recipient. Used in incoming file transfers. | |
| 412 */ | |
| 413 | |
| 414 char *filename; | |
| 415 char *cookie_s, *filesize_s; | |
| 416 | |
| 417 tmp = strstr(msg, "Invitation-Cookie"); | |
| 418 GET_NEXT(tmp); | |
| 419 cookie_s = tmp; | |
| 420 GET_NEXT(tmp); | |
| 421 GET_NEXT(tmp); | |
| 422 filename = tmp; | |
| 423 | |
| 424 /* Needed for filenames with spaces */ | |
| 425 tmp = strchr(tmp, '\r'); | |
| 426 *tmp = '\0'; | |
| 427 tmp += 2; | |
| 428 | |
| 429 GET_NEXT(tmp); | |
| 430 filesize_s = tmp; | |
| 431 GET_NEXT(tmp); | |
| 432 | |
| 433 /* Setup the MSN-specific file transfer data */ | |
| 434 xfer_data = g_new0(struct msn_xfer_data, 1); | |
| 435 xfer_data->cookie = atoi(cookie_s); | |
| 436 xfer_data->transferring = FALSE; | |
| 437 | |
| 438 /* Build the file transfer handle. */ | |
| 439 xfer = gaim_xfer_new(ms->gc->account, GAIM_XFER_RECEIVE, ms->msguser); | |
| 440 xfer->data = xfer_data; | |
| 441 | |
| 442 /* Set the info about the incoming file. */ | |
| 443 gaim_xfer_set_filename(xfer, filename); | |
| 444 gaim_xfer_set_size(xfer, atoi(filesize_s)); | |
| 445 | |
| 446 /* Setup our I/O op functions */ | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
447 gaim_xfer_set_init_fnc(xfer, msn_xfer_init); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
448 gaim_xfer_set_start_fnc(xfer, msn_xfer_start); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
449 gaim_xfer_set_end_fnc(xfer, msn_xfer_end); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
450 gaim_xfer_set_cancel_send_fnc(xfer, msn_xfer_cancel_send); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
451 gaim_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel_recv); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
452 gaim_xfer_set_read_fnc(xfer, msn_xfer_read); |
|
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
453 gaim_xfer_set_write_fnc(xfer, msn_xfer_write); |
| 4542 | 454 |
| 455 /* Keep track of this transfer for later. */ | |
| 456 md->file_transfers = g_slist_append(md->file_transfers, xfer); | |
| 457 | |
| 458 /* Now perform the request */ | |
| 459 gaim_xfer_request(xfer); | |
| 460 } | |
| 461 else if (strstr(msg, "Invitation-Command: ACCEPT")) { | |
| 462 | |
| 463 /* | |
| 464 * XXX I hope these checks don't return false positives, but they | |
| 465 * seem like they should work. The only issue is alternative | |
| 466 * protocols, *maybe*. | |
| 467 */ | |
| 468 | |
| 469 if (strstr(msg, "AuthCookie:")) { | |
| 470 | |
| 471 /* | |
| 472 * Second invitation request, sent after the recipient accepts | |
| 473 * the request. Used in incoming file transfers. | |
| 474 */ | |
| 475 char *cookie_s, *ip, *port_s, *authcookie_s; | |
| 476 char ip_s[16]; | |
| 477 | |
| 478 tmp = strstr(msg, "Invitation-Cookie"); | |
| 479 GET_NEXT(tmp); | |
| 480 cookie_s = tmp; | |
| 481 GET_NEXT(tmp); | |
| 482 GET_NEXT(tmp); | |
| 483 ip = tmp; | |
| 484 GET_NEXT(tmp); | |
| 485 GET_NEXT(tmp); | |
| 486 port_s = tmp; | |
| 487 GET_NEXT(tmp); | |
| 488 GET_NEXT(tmp); | |
| 489 authcookie_s = tmp; | |
| 490 GET_NEXT(tmp); | |
| 491 | |
| 492 xfer = find_xfer_by_cookie(ms->gc, atoi(cookie_s)); | |
| 493 | |
| 494 if (xfer == NULL) | |
| 495 { | |
| 496 debug_printf("MSNFTP : Cookie not found. " | |
| 497 "File transfer aborted.\n"); | |
| 498 return; | |
| 499 } | |
| 500 | |
| 501 xfer_data = (struct msn_xfer_data *)xfer->data; | |
| 502 xfer_data->authcookie = atol(authcookie_s); | |
| 503 | |
| 504 strncpy(ip_s, ip, sizeof(ip_s)); | |
| 505 | |
| 4634 | 506 if (proxy_connect(xfer->account, ip_s, atoi(port_s), |
| 4542 | 507 msn_msnftp_connect, xfer) != 0) { |
| 508 | |
|
4675
3145c5c45877
[gaim-migrate @ 4986]
Christian Hammond <chipx86@chipx86.com>
parents:
4634
diff
changeset
|
509 gaim_xfer_cancel_remote(xfer); |
| 4542 | 510 |
| 511 return; | |
| 512 } | |
| 513 } | |
| 514 else | |
| 515 { | |
| 516 /* | |
| 517 * An accept message from the recipient. Used in outgoing | |
| 518 * file transfers. | |
| 519 */ | |
| 520 } | |
| 521 } | |
| 522 } | |
| 523 |
