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;