Mercurial > pidgin
comparison src/protocols/irc/irc.c @ 4514:7521e29658bc
[gaim-migrate @ 4792]
Of course, file transfer wasn't really gone..
I'm trying my hardest to bring on the end of the world (see the roadmap at
http://gaim.sf.net/roadmap.png). File transfer is being rewritten. This
isn't the finished implementation, but it's enough to let us get the prpls
working.
There is now a file transfer dialog, which will appear when you get a new
transfer request or when you go to Tools -> File Transfers.
This is of course core/UI split. I'll also be working on documentation on
how to write FT support in a prpl. Oh, and I'll get resumes and transfer
batches done when school isn't breathing down my back.
Only DCC receive in IRC currently works. Sorry. We'll get the other prpls
working soon, as well as send.
committer: Tailor Script <tailor@pidgin.im>
| author | Christian Hammond <chipx86@chipx86.com> |
|---|---|
| date | Tue, 04 Feb 2003 06:57:35 +0000 |
| parents | cf2f5a1f1e46 |
| children | a2f2a717fdf2 |
comparison
equal
deleted
inserted
replaced
| 4513:adb0245e1dfc | 4514:7521e29658bc |
|---|---|
| 78 int fd; | 78 int fd; |
| 79 int inpa; | 79 int inpa; |
| 80 char nick[80]; | 80 char nick[80]; |
| 81 }; | 81 }; |
| 82 | 82 |
| 83 struct irc_file_transfer { | 83 struct irc_xfer_data |
| 84 enum { IFT_SENDFILE_IN, IFT_SENDFILE_OUT } type; | 84 { |
| 85 struct file_transfer *xfer; | 85 char *ip; |
| 86 char *sn; | |
| 87 char *name; | |
| 88 int len; | |
| 89 int watcher; | |
| 90 int awatcher; | |
| 91 char ip[12]; | |
| 92 int port; | 86 int port; |
| 93 int fd; | 87 |
| 94 int cur; | 88 struct irc_data *idata; |
| 95 struct gaim_connection *gc; | |
| 96 }; | 89 }; |
| 97 | 90 |
| 98 struct irc_data { | 91 struct irc_data { |
| 99 int fd; | 92 int fd; |
| 100 gboolean online; | 93 gboolean online; |
| 511 time(NULL)); | 504 time(NULL)); |
| 512 dcc_chat_cancel (chat); | 505 dcc_chat_cancel (chat); |
| 513 } | 506 } |
| 514 } | 507 } |
| 515 | 508 |
| 516 static void | |
| 517 irc_file_transfer_do(struct gaim_connection *gc, struct irc_file_transfer *ift) { | |
| 518 /* Ok, we better be receiving some crap here boyeee */ | |
| 519 if (transfer_in_do(ift->xfer, ift->fd, ift->name, ift->len)) { | |
| 520 gaim_input_remove(ift->watcher); | |
| 521 ift->watcher = 0; | |
| 522 } | |
| 523 } | |
| 524 | |
| 525 | |
| 526 void | 509 void |
| 527 irc_read_dcc_ack (gpointer data, gint source, GaimInputCondition condition) { | 510 irc_read_dcc_ack (gpointer data, gint source, GaimInputCondition condition) { |
| 528 /* Read ACK Here */ | 511 /* Read ACK Here */ |
| 529 | 512 |
| 530 } | 513 } |
| 531 | 514 |
| 532 void | 515 void |
| 533 dcc_send_callback (gpointer data, gint source, GaimInputCondition condition) { | 516 dcc_send_callback (gpointer data, gint source, GaimInputCondition condition) { |
| 517 #if 0 | |
| 534 struct irc_file_transfer *ift = data; | 518 struct irc_file_transfer *ift = data; |
| 535 struct sockaddr_in addr; | 519 struct sockaddr_in addr; |
| 536 int len = sizeof(addr); | 520 int len = sizeof(addr); |
| 537 | 521 |
| 538 addr.sin_family = AF_INET; | 522 addr.sin_family = AF_INET; |
| 550 | 534 |
| 551 if (transfer_out_do(ift->xfer, ift->fd, 0)) { | 535 if (transfer_out_do(ift->xfer, ift->fd, 0)) { |
| 552 gaim_input_remove(ift->watcher); | 536 gaim_input_remove(ift->watcher); |
| 553 ift->watcher = 0; | 537 ift->watcher = 0; |
| 554 } | 538 } |
| 555 } | 539 #endif |
| 556 | |
| 557 void | |
| 558 dcc_recv_callback (gpointer data, gint source, GaimInputCondition condition) { | |
| 559 struct irc_file_transfer *ift = data; | |
| 560 | |
| 561 ift->fd = source; | |
| 562 irc_file_transfer_do(ift->gc, ift); | |
| 563 } | 540 } |
| 564 | 541 |
| 565 void | 542 void |
| 566 dcc_chat_callback (gpointer data, gint source, GaimInputCondition condition) { | 543 dcc_chat_callback (gpointer data, gint source, GaimInputCondition condition) { |
| 567 struct dcc_chat *chat = data; | 544 struct dcc_chat *chat = data; |
| 1245 return; | 1222 return; |
| 1246 | 1223 |
| 1247 dcc_chat_cancel(dchat); | 1224 dcc_chat_cancel(dchat); |
| 1248 } | 1225 } |
| 1249 | 1226 |
| 1227 static void | |
| 1228 irc_xfer_init(struct gaim_xfer *xfer) | |
| 1229 { | |
| 1230 struct irc_xfer_data *data = (struct irc_xfer_data *)xfer->data; | |
| 1231 | |
| 1232 gaim_xfer_start(xfer, -1, data->ip, data->port); | |
| 1233 } | |
| 1234 | |
| 1235 static void | |
| 1236 irc_xfer_end(struct gaim_xfer *xfer) | |
| 1237 { | |
| 1238 struct irc_xfer_data *data = (struct irc_xfer_data *)xfer->data; | |
| 1239 | |
| 1240 data->idata->file_transfers = g_slist_remove(data->idata->file_transfers, | |
| 1241 xfer); | |
| 1242 | |
| 1243 g_free(data); | |
| 1244 xfer->data = NULL; | |
| 1245 } | |
| 1246 | |
| 1247 static void | |
| 1248 irc_xfer_cancel(struct gaim_xfer *xfer) | |
| 1249 { | |
| 1250 struct irc_xfer_data *data = (struct irc_xfer_data *)xfer->data; | |
| 1251 | |
| 1252 data->idata->file_transfers = g_slist_remove(data->idata->file_transfers, | |
| 1253 xfer); | |
| 1254 | |
| 1255 g_free(data); | |
| 1256 xfer->data = NULL; | |
| 1257 } | |
| 1258 | |
| 1259 static void | |
| 1260 irc_xfer_ack(struct gaim_xfer *xfer) | |
| 1261 { | |
| 1262 guint32 pos; | |
| 1263 | |
| 1264 pos = htonl(gaim_xfer_get_bytes_sent(xfer)); | |
| 1265 | |
| 1266 gaim_xfer_write(xfer, (char *)&pos, 4); | |
| 1267 } | |
| 1268 | |
| 1250 static void | 1269 static void |
| 1251 handle_ctcp(struct gaim_connection *gc, char *to, char *nick, | 1270 handle_ctcp(struct gaim_connection *gc, char *to, char *nick, |
| 1252 char *msg, char *word[], char *word_eol[]) | 1271 char *msg, char *word[], char *word_eol[]) |
| 1253 { | 1272 { |
| 1254 struct irc_data *id = gc->proto_data; | 1273 struct irc_data *id = gc->proto_data; |
| 1300 do_ask_dialog(ask, _("This requires a direct connection to be established between the two computers. Messages sent will not pass through the IRC server"), dccchat, _("Connect"), dcc_chat_init, _("Cancel"), dcc_chat_cancel, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE); | 1319 do_ask_dialog(ask, _("This requires a direct connection to be established between the two computers. Messages sent will not pass through the IRC server"), dccchat, _("Connect"), dcc_chat_init, _("Cancel"), dcc_chat_cancel, my_protocol->plug ? my_protocol->plug->handle : NULL, FALSE); |
| 1301 } | 1320 } |
| 1302 | 1321 |
| 1303 | 1322 |
| 1304 if (!g_strncasecmp(msg, "DCC SEND", 8)) { | 1323 if (!g_strncasecmp(msg, "DCC SEND", 8)) { |
| 1305 struct irc_file_transfer *ift = g_new0(struct irc_file_transfer, 1); | 1324 struct gaim_xfer *xfer; |
| 1306 char **send_args = g_strsplit(msg, " ", 6); | 1325 char **send_args; |
| 1326 char *ip, *filename; | |
| 1327 struct irc_xfer_data *xfer_data; | |
| 1328 size_t size; | |
| 1329 int port; | |
| 1330 | |
| 1331 send_args = g_strsplit(msg, " ", 6); | |
| 1307 send_args[5][strlen(send_args[5])-1] = 0; | 1332 send_args[5][strlen(send_args[5])-1] = 0; |
| 1308 | 1333 |
| 1309 ift->type = IFT_SENDFILE_IN; | 1334 /* Give these better names. */ |
| 1310 ift->sn = g_strdup(nick); | 1335 ip = send_args[3]; |
| 1311 ift->gc = gc; | 1336 filename = send_args[2]; |
| 1312 g_snprintf(ift->ip, sizeof(ift->ip), send_args[3]); | 1337 size = atoi(send_args[5]); |
| 1313 ift->port = atoi(send_args[4]); | 1338 port = atoi(send_args[4]); |
| 1314 ift->len = atoi(send_args[5]); | 1339 |
| 1315 ift->name = g_strdup(send_args[2]); | 1340 /* Setup the IRC-specific transfer data. */ |
| 1316 ift->cur = 0; | 1341 xfer_data = g_malloc0(sizeof(struct irc_xfer_data)); |
| 1317 | 1342 xfer_data->ip = ip; |
| 1318 id->file_transfers = g_slist_append(id->file_transfers, ift); | 1343 xfer_data->port = port; |
| 1319 | 1344 xfer_data->idata = id; |
| 1320 ift->xfer = transfer_in_add(gc, nick, ift->name, ift->len, 1, NULL); | 1345 |
| 1346 /* Build the file transfer handle. */ | |
| 1347 xfer = gaim_xfer_new(gc->account, GAIM_XFER_RECEIVE, nick); | |
| 1348 xfer->data = xfer_data; | |
| 1349 | |
| 1350 /* Set the info about the incoming file. */ | |
| 1351 gaim_xfer_set_filename(xfer, filename); | |
| 1352 gaim_xfer_set_size(xfer, size); | |
| 1353 | |
| 1354 g_free(filename); | |
| 1355 | |
| 1356 /* Setup our I/O op functions. */ | |
| 1357 gaim_xfer_set_init_fnc(xfer, irc_xfer_init); | |
| 1358 gaim_xfer_set_end_fnc(xfer, irc_xfer_end); | |
| 1359 gaim_xfer_set_cancel_fnc(xfer, irc_xfer_cancel); | |
| 1360 gaim_xfer_set_ack_fnc(xfer, irc_xfer_ack); | |
| 1361 | |
| 1362 /* Keep track of this transfer for later. */ | |
| 1363 id->file_transfers = g_slist_append(id->file_transfers, xfer); | |
| 1364 | |
| 1365 /* Now perform the request! */ | |
| 1366 gaim_xfer_request(xfer); | |
| 1367 | |
| 1368 #if 0 | |
| 1369 if (xfer != NULL) { | |
| 1370 struct irc_file_transfer *ift; | |
| 1371 gaim_xfer_set_read_fnc(xfer, irc_xfer_read); | |
| 1372 gaim_xfer_set_cancel_fnc(xfer, irc_xfer_cancel); | |
| 1373 | |
| 1374 gaim_xfer_set_ack_fnc(xfer, irc_xfer_ack); | |
| 1375 | |
| 1376 ift = g_new0(struct irc_file_transfer, 1); | |
| 1377 | |
| 1378 strncpy(ift->ip, send_args[3], sizeof(ift->ip)); | |
| 1379 ift->type = IFT_SENDFILE_IN; | |
| 1380 ift->sn = g_strdup(nick); | |
| 1381 ift->gc = gc; | |
| 1382 ift->port = atoi(send_args[4]); | |
| 1383 ift->len = atoi(send_args[5]); | |
| 1384 ift->name = g_strdup(send_args[2]); | |
| 1385 ift->cur = 0; | |
| 1386 ift->xfer = xfer; | |
| 1387 | |
| 1388 xfer->data = ift; | |
| 1389 | |
| 1390 | |
| 1391 gaim_xfer_start(xfer, -1, send_args[3], atoi(send_args[4])); | |
| 1392 } | |
| 1393 #endif | |
| 1321 } | 1394 } |
| 1322 | 1395 |
| 1323 /*write_to_conv(c, out, WFLAG_SYSTEM, NULL, time(NULL), -1);*/ | 1396 /*write_to_conv(c, out, WFLAG_SYSTEM, NULL, time(NULL), -1);*/ |
| 1324 } | 1397 } |
| 1325 | 1398 |
| 1777 idata->rxqueue = NULL; | 1850 idata->rxqueue = NULL; |
| 1778 idata->rxlen = 0; | 1851 idata->rxlen = 0; |
| 1779 | 1852 |
| 1780 /* Kill any existing transfers */ | 1853 /* Kill any existing transfers */ |
| 1781 while (idata->file_transfers) { | 1854 while (idata->file_transfers) { |
| 1782 struct irc_file_transfer *ift = (struct irc_file_transfer *)idata->file_transfers->data; | 1855 struct gaim_xfer *xfer; |
| 1783 | 1856 |
| 1784 g_free(ift->sn); | 1857 xfer = (struct gaim_xfer *)idata->file_transfers->data; |
| 1785 g_free(ift->name); | 1858 |
| 1786 gaim_input_remove(ift->watcher); | 1859 gaim_xfer_end(xfer); |
| 1787 | 1860 gaim_xfer_destroy(xfer); |
| 1788 close(ift->fd); | |
| 1789 | 1861 |
| 1790 idata->file_transfers = idata->file_transfers->next; | 1862 idata->file_transfers = idata->file_transfers->next; |
| 1791 } | 1863 } |
| 1792 idata->file_transfers = NULL; | 1864 idata->file_transfers = NULL; |
| 1793 | 1865 |
| 2421 snprintf(ift->ip, sizeof(ift->ip), "%s", localip); | 2493 snprintf(ift->ip, sizeof(ift->ip), "%s", localip); |
| 2422 id->file_transfers = g_slist_append(id->file_transfers, ift); | 2494 id->file_transfers = g_slist_append(id->file_transfers, ift); |
| 2423 | 2495 |
| 2424 ift->xfer = transfer_out_add(gc, ift->sn); | 2496 ift->xfer = transfer_out_add(gc, ift->sn); |
| 2425 } | 2497 } |
| 2426 #endif | 2498 |
| 2427 static struct | 2499 static struct |
| 2428 irc_file_transfer *find_ift_by_xfer(struct gaim_connection *gc, | 2500 irc_file_transfer *find_ift_by_xfer(struct gaim_connection *gc, |
| 2429 struct file_transfer *xfer) { | 2501 struct file_transfer *xfer) { |
| 2430 | 2502 |
| 2431 GSList *g = ((struct irc_data *)gc->proto_data)->file_transfers; | 2503 GSList *g = ((struct irc_data *)gc->proto_data)->file_transfers; |
| 2432 struct irc_file_transfer *f = NULL; | 2504 struct irc_file_transfer *f = NULL; |
| 2433 | 2505 |
| 2434 while (g) { | 2506 while (g) { |
| 2533 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); | 2605 struct irc_file_transfer *ift = find_ift_by_xfer(gc, xfer); |
| 2534 | 2606 |
| 2535 ift->xfer = xfer; | 2607 ift->xfer = xfer; |
| 2536 proxy_connect(ift->ip, ift->port, dcc_recv_callback, ift); | 2608 proxy_connect(ift->ip, ift->port, dcc_recv_callback, ift); |
| 2537 } | 2609 } |
| 2610 #endif | |
| 2538 | 2611 |
| 2539 static void | 2612 static void |
| 2540 irc_ctcp_clientinfo(struct gaim_connection *gc, char *who) | 2613 irc_ctcp_clientinfo(struct gaim_connection *gc, char *who) |
| 2541 { | 2614 { |
| 2542 char buf[IRC_BUF_LEN]; | 2615 char buf[IRC_BUF_LEN]; |
| 2744 ret->set_away = irc_set_away; | 2817 ret->set_away = irc_set_away; |
| 2745 ret->get_info = irc_get_info; | 2818 ret->get_info = irc_get_info; |
| 2746 ret->buddy_menu = irc_buddy_menu; | 2819 ret->buddy_menu = irc_buddy_menu; |
| 2747 ret->chat_invite = irc_chat_invite; | 2820 ret->chat_invite = irc_chat_invite; |
| 2748 ret->convo_closed = irc_convo_closed; | 2821 ret->convo_closed = irc_convo_closed; |
| 2822 #if 0 | |
| 2749 ret->file_transfer_out = irc_file_transfer_out; | 2823 ret->file_transfer_out = irc_file_transfer_out; |
| 2750 ret->file_transfer_in = irc_file_transfer_in; | 2824 ret->file_transfer_in = irc_file_transfer_in; |
| 2751 ret->file_transfer_data_chunk = irc_file_transfer_data_chunk; | 2825 ret->file_transfer_data_chunk = irc_file_transfer_data_chunk; |
| 2752 ret->file_transfer_done = irc_file_transfer_done; | 2826 ret->file_transfer_done = irc_file_transfer_done; |
| 2753 ret->file_transfer_cancel =irc_file_transfer_cancel; | 2827 ret->file_transfer_cancel =irc_file_transfer_cancel; |
| 2828 #endif | |
| 2754 | 2829 |
| 2755 puo = g_new0(struct proto_user_opt, 1); | 2830 puo = g_new0(struct proto_user_opt, 1); |
| 2756 puo->label = g_strdup(_("Server:")); | 2831 puo->label = g_strdup(_("Server:")); |
| 2757 puo->def = g_strdup("irc.freenode.net"); | 2832 puo->def = g_strdup("irc.freenode.net"); |
| 2758 puo->pos = USEROPT_SERV; | 2833 puo->pos = USEROPT_SERV; |
