Mercurial > pidgin.yaz
comparison src/toc.c @ 1457:c6f9d0cdaa00
[gaim-migrate @ 1467]
all of toc in one file; rewritten file transfer. no get file yet; just send file. but why would you want to send files to people anyway? ;)
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Thu, 01 Feb 2001 11:29:15 +0000 |
parents | f16e17d42b43 |
children | d6340f73e94b |
comparison
equal
deleted
inserted
replaced
1456:6650776468b3 | 1457:c6f9d0cdaa00 |
---|---|
44 #include "pixmaps/aol_icon.xpm" | 44 #include "pixmaps/aol_icon.xpm" |
45 #include "pixmaps/away_icon.xpm" | 45 #include "pixmaps/away_icon.xpm" |
46 #include "pixmaps/dt_icon.xpm" | 46 #include "pixmaps/dt_icon.xpm" |
47 #include "pixmaps/free_icon.xpm" | 47 #include "pixmaps/free_icon.xpm" |
48 | 48 |
49 #define REVISION "gaim:$Revision: 1445 $" | 49 #define REVISION "gaim:$Revision: 1467 $" |
50 | 50 |
51 #define TYPE_SIGNON 1 | 51 #define TYPE_SIGNON 1 |
52 #define TYPE_DATA 2 | 52 #define TYPE_DATA 2 |
53 #define TYPE_ERROR 3 | 53 #define TYPE_ERROR 3 |
54 #define TYPE_SIGNOFF 4 | 54 #define TYPE_SIGNOFF 4 |
66 #define STATE_OFFLINE 0 | 66 #define STATE_OFFLINE 0 |
67 #define STATE_FLAPON 1 | 67 #define STATE_FLAPON 1 |
68 #define STATE_SIGNON_REQUEST 2 | 68 #define STATE_SIGNON_REQUEST 2 |
69 #define STATE_ONLINE 3 | 69 #define STATE_ONLINE 3 |
70 #define STATE_PAUSE 4 | 70 #define STATE_PAUSE 4 |
71 | |
72 #define VOICE_UID "09461341-4C7F-11D1-8222-444553540000" | |
73 #define FILE_SEND_UID "09461343-4C7F-11D1-8222-444553540000" | |
74 #define IMAGE_UID "09461345-4C7F-11D1-8222-444553540000" | |
75 #define B_ICON_UID "09461346-4C7F-11D1-8222-444553540000" | |
76 #define STOCKS_UID "09461347-4C7F-11D1-8222-444553540000" | |
77 #define FILE_GET_UID "09461348-4C7F-11D1-8222-444553540000" | |
78 #define GAMES_UID "0946134a-4C7F-11D1-8222-444553540000" | |
79 | |
80 struct ft_request { | |
81 struct gaim_connection *gc; | |
82 char *user; | |
83 char UID[2048]; | |
84 char *cookie; | |
85 char *ip; | |
86 int port; | |
87 char *message; | |
88 char *filename; | |
89 int files; | |
90 int size; | |
91 }; | |
71 | 92 |
72 struct toc_data { | 93 struct toc_data { |
73 int toc_fd; | 94 int toc_fd; |
74 int seqno; | 95 int seqno; |
75 int state; | 96 int state; |
96 #define USEROPT_SOCKSPORT 3 | 117 #define USEROPT_SOCKSPORT 3 |
97 #define USEROPT_PROXYTYPE 4 | 118 #define USEROPT_PROXYTYPE 4 |
98 | 119 |
99 static void toc_callback(gpointer, gint, GdkInputCondition); | 120 static void toc_callback(gpointer, gint, GdkInputCondition); |
100 static unsigned char *roast_password(char *); | 121 static unsigned char *roast_password(char *); |
122 static void accept_file_dialog(struct ft_request *); | |
101 | 123 |
102 /* ok. this function used to take username/password, and return 0 on success. | 124 /* ok. this function used to take username/password, and return 0 on success. |
103 * now, it takes username/password, and returns NULL on error or a new gaim_connection | 125 * now, it takes username/password, and returns NULL on error or a new gaim_connection |
104 * on success. */ | 126 * on success. */ |
105 static void toc_login(struct aim_user *user) | 127 static void toc_login(struct aim_user *user) |
159 gdk_input_remove(gc->inpa); | 181 gdk_input_remove(gc->inpa); |
160 gc->inpa = -1; | 182 gc->inpa = -1; |
161 close(((struct toc_data *)gc->proto_data)->toc_fd); | 183 close(((struct toc_data *)gc->proto_data)->toc_fd); |
162 } | 184 } |
163 | 185 |
164 int sflap_send(struct gaim_connection *gc, char *buf, int olen, int type) | 186 static int sflap_send(struct gaim_connection *gc, char *buf, int olen, int type) |
165 { | 187 { |
166 int len; | 188 int len; |
167 int slen = 0; | 189 int slen = 0; |
168 struct sflap_hdr hdr; | 190 struct sflap_hdr hdr; |
169 char obuf[MSG_LEN]; | 191 char obuf[MSG_LEN]; |
335 /* Client sends TOC toc_init_done message */ | 357 /* Client sends TOC toc_init_done message */ |
336 debug_printf("* Client sends TOC toc_init_done message\n"); | 358 debug_printf("* Client sends TOC toc_init_done message\n"); |
337 g_snprintf(snd, sizeof snd, "toc_init_done"); | 359 g_snprintf(snd, sizeof snd, "toc_init_done"); |
338 sflap_send(gc, snd, -1, TYPE_DATA); | 360 sflap_send(gc, snd, -1, TYPE_DATA); |
339 | 361 |
340 g_snprintf(snd, sizeof snd, "toc_set_caps %s %s", | 362 g_snprintf(snd, sizeof snd, "toc_set_caps %s", FILE_SEND_UID); |
341 FILE_SEND_UID, FILE_GET_UID); | |
342 sflap_send(gc, snd, -1, TYPE_DATA); | 363 sflap_send(gc, snd, -1, TYPE_DATA); |
343 | 364 |
344 return; | 365 return; |
345 } | 366 } |
346 | 367 |
559 if (!strcmp(uuid, FILE_SEND_UID)) { | 580 if (!strcmp(uuid, FILE_SEND_UID)) { |
560 /* they want us to get a file */ | 581 /* they want us to get a file */ |
561 int unk[4], i; | 582 int unk[4], i; |
562 char *messages[4], *tmp, *name; | 583 char *messages[4], *tmp, *name; |
563 int subtype, files, totalsize = 0; | 584 int subtype, files, totalsize = 0; |
564 struct file_transfer *ft; | 585 struct ft_request *ft; |
565 | 586 |
566 for (i = 0; i < 4; i++) { | 587 for (i = 0; i < 4; i++) { |
567 sscanf(strtok(NULL, ":"), "%d", &unk[i]); | 588 sscanf(strtok(NULL, ":"), "%d", &unk[i]); |
568 if (unk[i] == 10001) | 589 if (unk[i] == 10001) |
569 break; | 590 break; |
586 return; | 607 return; |
587 } | 608 } |
588 | 609 |
589 name = tmp + 8; | 610 name = tmp + 8; |
590 | 611 |
591 ft = g_new0(struct file_transfer, 1); | 612 ft = g_new0(struct ft_request, 1); |
592 ft->cookie = g_strdup(cookie); | 613 ft->cookie = g_strdup(cookie); |
593 ft->ip = g_strdup(pip); | 614 ft->ip = g_strdup(pip); |
594 ft->port = port; | 615 ft->port = port; |
595 if (i) | 616 if (i) |
596 ft->message = g_strdup(messages[0]); | 617 ft->message = g_strdup(messages[0]); |
597 else | 618 else |
598 ft->message = NULL; | 619 ft->message = NULL; |
599 ft->filename = g_strdup(name); | 620 ft->filename = g_strdup(name); |
600 ft->user = g_strdup(user); | 621 ft->user = g_strdup(user); |
601 ft->size = totalsize; | 622 ft->size = totalsize; |
623 ft->files = files; | |
602 g_snprintf(ft->UID, sizeof(ft->UID), "%s", FILE_SEND_UID); | 624 g_snprintf(ft->UID, sizeof(ft->UID), "%s", FILE_SEND_UID); |
603 ft->gc = gc; | 625 ft->gc = gc; |
604 | 626 |
605 g_free(tmp); | 627 g_free(tmp); |
606 for (i--; i >= 0; i--) | 628 for (i--; i >= 0; i--) |
607 g_free(messages[i]); | 629 g_free(messages[i]); |
608 | 630 |
631 debug_printf("English translation of RVOUS_PROPOSE: %s requests Send File (i.e." | |
632 " send a file to you); %s:%d (verified_ip:port), %d files at" | |
633 " total size of %ld bytes.\n", user, vip, port, files, totalsize); | |
609 accept_file_dialog(ft); | 634 accept_file_dialog(ft); |
610 } else if (!strcmp(uuid, FILE_GET_UID)) { | 635 } else if (!strcmp(uuid, FILE_GET_UID)) { |
611 /* they want us to send a file */ | 636 /* they want us to send a file |
612 int unk[4], i; | 637 int unk[4], i; |
613 char *messages[4], *tmp; | 638 char *messages[4], *tmp; |
614 struct file_transfer *ft; | 639 struct ft_request *ft; |
615 | 640 |
616 for (i = 0; i < 4; i++) { | 641 for (i = 0; i < 4; i++) { |
617 sscanf(strtok(NULL, ":"), "%d", unk + i); | 642 sscanf(strtok(NULL, ":"), "%d", unk + i); |
618 if (unk[i] == 10001) | 643 if (unk[i] == 10001) |
619 break; | 644 break; |
620 messages[i] = frombase64(strtok(NULL, ":")); | 645 messages[i] = frombase64(strtok(NULL, ":")); |
621 } | 646 } |
622 tmp = frombase64(strtok(NULL, ":")); | 647 tmp = frombase64(strtok(NULL, ":")); |
623 | 648 |
624 ft = g_new0(struct file_transfer, 1); | 649 ft = g_new0(struct ft_request, 1); |
625 ft->cookie = g_strdup(cookie); | 650 ft->cookie = g_strdup(cookie); |
626 ft->ip = g_strdup(pip); | 651 ft->ip = g_strdup(pip); |
627 ft->port = port; | 652 ft->port = port; |
628 if (i) | 653 if (i) |
629 ft->message = g_strdup(messages[0]); | 654 ft->message = g_strdup(messages[0]); |
636 g_free(tmp); | 661 g_free(tmp); |
637 for (i--; i >= 0; i--) | 662 for (i--; i >= 0; i--) |
638 g_free(messages[i]); | 663 g_free(messages[i]); |
639 | 664 |
640 accept_file_dialog(ft); | 665 accept_file_dialog(ft); |
666 */ | |
641 } else if (!strcmp(uuid, VOICE_UID)) { | 667 } else if (!strcmp(uuid, VOICE_UID)) { |
642 /* oh goody. voice over ip. fun stuff. */ | 668 /* oh goody. voice over ip. fun stuff. */ |
643 } else if (!strcmp(uuid, B_ICON_UID)) { | 669 } else if (!strcmp(uuid, B_ICON_UID)) { |
644 /* buddy icon... */ | 670 /* buddy icon... */ |
645 } else if (!strcmp(uuid, IMAGE_UID)) { | 671 } else if (!strcmp(uuid, IMAGE_UID)) { |
1217 ret->chat_leave = toc_chat_leave; | 1243 ret->chat_leave = toc_chat_leave; |
1218 ret->chat_whisper = toc_chat_whisper; | 1244 ret->chat_whisper = toc_chat_whisper; |
1219 ret->chat_send = toc_chat_send; | 1245 ret->chat_send = toc_chat_send; |
1220 ret->keepalive = toc_keepalive; | 1246 ret->keepalive = toc_keepalive; |
1221 } | 1247 } |
1248 | |
1249 /********* | |
1250 * RVOUS ACTIONS | |
1251 ********/ | |
1252 | |
1253 struct file_header { | |
1254 char magic[4]; /* 0 */ | |
1255 short hdrlen; /* 4 */ | |
1256 short hdrtype; /* 6 */ | |
1257 char bcookie[8]; /* 8 */ | |
1258 short encrypt; /* 16 */ | |
1259 short compress; /* 18 */ | |
1260 short totfiles; /* 20 */ | |
1261 short filesleft; /* 22 */ | |
1262 short totparts; /* 24 */ | |
1263 short partsleft; /* 26 */ | |
1264 long totsize; /* 28 */ | |
1265 long size; /* 32 */ | |
1266 long modtime; /* 36 */ | |
1267 long checksum; /* 40 */ | |
1268 long rfrcsum; /* 44 */ | |
1269 long rfsize; /* 48 */ | |
1270 long cretime; /* 52 */ | |
1271 long rfcsum; /* 56 */ | |
1272 long nrecvd; /* 60 */ | |
1273 long recvcsum; /* 64 */ | |
1274 char idstring[32]; /* 68 */ | |
1275 char flags; /* 100 */ | |
1276 char lnameoffset; /* 101 */ | |
1277 char lsizeoffset; /* 102 */ | |
1278 char dummy[69]; /* 103 */ | |
1279 char macfileinfo[16]; /* 172 */ | |
1280 short nencode; /* 188 */ | |
1281 short nlanguage; /* 190 */ | |
1282 char name[64]; /* 192 */ | |
1283 /* 256 */ | |
1284 }; | |
1285 | |
1286 struct file_transfer { | |
1287 struct file_header hdr; | |
1288 | |
1289 struct gaim_connection *gc; | |
1290 | |
1291 char *user; | |
1292 char *cookie; | |
1293 char *ip; | |
1294 int port; | |
1295 long size; | |
1296 | |
1297 GtkWidget *window; | |
1298 FILE *file; | |
1299 int recvsize; | |
1300 | |
1301 gint inpa; | |
1302 }; | |
1303 | |
1304 static void toc_get_file(gpointer a, struct file_transfer *ft) { | |
1305 char *dirname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(ft->window)); | |
1306 | |
1307 if (file_is_dir(dirname, ft->window)) | |
1308 return; | |
1309 gtk_widget_destroy(ft->window); | |
1310 } | |
1311 | |
1312 static void debug_header(struct file_transfer *ft) { | |
1313 struct file_header *f = (struct file_header *)ft; | |
1314 debug_printf("TOC FT HEADER:\n" | |
1315 "\t%s %d 0x%04x\n" | |
1316 "\t%s %d %d\n" | |
1317 "\t%d %d %d %d %ld %ld\n" | |
1318 "\t%ld %ld %ld %ld %ld %ld %ld %ld\n" | |
1319 "\t%s\n" | |
1320 "\t0x%02x, 0x%02x, 0x%02x\n" | |
1321 "\t%s %s\n" | |
1322 "\t%d %d\n" | |
1323 "\t%s\n", | |
1324 f->magic, ntohs(f->hdrlen), f->hdrtype, | |
1325 f->bcookie, ntohs(f->encrypt), ntohs(f->compress), | |
1326 ntohs(f->totfiles), ntohs(f->filesleft), ntohs(f->totparts), | |
1327 ntohs(f->partsleft), ntohl(f->totsize), ntohl(f->size), | |
1328 ntohl(f->modtime), ntohl(f->checksum), ntohl(f->rfrcsum), ntohl(f->rfsize), | |
1329 ntohl(f->cretime), ntohl(f->rfcsum), ntohl(f->nrecvd), | |
1330 ntohl(f->recvcsum), | |
1331 f->idstring, | |
1332 f->flags, f->lnameoffset, f->lsizeoffset, | |
1333 f->dummy, f->macfileinfo, | |
1334 ntohs(f->nencode), ntohs(f->nlanguage), | |
1335 f->name); | |
1336 } | |
1337 | |
1338 static void toc_send_file_callback(gpointer data, gint source, GdkInputCondition cond) { | |
1339 char buf[BUF_LONG]; | |
1340 int rt, i; | |
1341 | |
1342 struct file_transfer *ft = data; | |
1343 | |
1344 if (cond & GDK_INPUT_EXCEPTION) { | |
1345 gdk_input_remove(ft->inpa); | |
1346 close(source); | |
1347 g_free(ft->user); | |
1348 g_free(ft->ip); | |
1349 g_free(ft->cookie); | |
1350 fclose(ft->file); | |
1351 g_free(ft); | |
1352 return; | |
1353 } | |
1354 | |
1355 if (ft->hdr.hdrtype != 0x202) { | |
1356 char *buf = frombase64(ft->cookie); | |
1357 | |
1358 read(source, ft, 8); | |
1359 read(source, &ft->hdr.bcookie, MIN(256 - 8, ntohs(ft->hdr.hdrlen) - 8)); | |
1360 debug_header(ft); | |
1361 | |
1362 ft->hdr.hdrtype = 0x202; | |
1363 memcpy(ft->hdr.bcookie, buf, 8); | |
1364 g_free(buf); | |
1365 ft->hdr.encrypt = 0; ft->hdr.compress = 0; | |
1366 debug_header(ft); | |
1367 write(source, ft, 256); | |
1368 | |
1369 return; | |
1370 } | |
1371 | |
1372 rt = read(source, buf, MIN(ntohl(ft->hdr.size) - ft->recvsize, 1024)); | |
1373 if (rt < 0) { | |
1374 do_error_dialog("File transfer failed; other side probably canceled.", "Error"); | |
1375 gdk_input_remove(ft->inpa); | |
1376 close(source); | |
1377 g_free(ft->user); | |
1378 g_free(ft->ip); | |
1379 g_free(ft->cookie); | |
1380 fclose(ft->file); | |
1381 g_free(ft); | |
1382 return; | |
1383 } | |
1384 ft->recvsize += rt; | |
1385 for (i = 0; i < rt; i++) | |
1386 fprintf(ft->file, "%c", buf[i]); | |
1387 | |
1388 if (ft->recvsize == ntohl(ft->hdr.size)) { | |
1389 ft->hdr.hdrtype = 0x402; | |
1390 ft->hdr.filesleft = htons(ntohs(ft->hdr.filesleft) - 1); | |
1391 ft->hdr.partsleft = htons(ntohs(ft->hdr.partsleft) - 1); | |
1392 ft->hdr.recvcsum = ft->hdr.checksum; /* uh... */ | |
1393 ft->hdr.nrecvd = htons(ntohs(ft->hdr.nrecvd) + 1); | |
1394 ft->hdr.flags = 0; | |
1395 write(source, ft, 256); | |
1396 ft->recvsize = 0; | |
1397 if (ft->hdr.filesleft != 0) { | |
1398 char *msg = g_strdup_printf("%s tried to send you more than one file, but" | |
1399 " currently that is not possible.", ft->user); | |
1400 do_error_dialog(msg, "Error"); | |
1401 g_free(msg); | |
1402 } | |
1403 gdk_input_remove(ft->inpa); | |
1404 close(source); | |
1405 g_free(ft->user); | |
1406 g_free(ft->ip); | |
1407 g_free(ft->cookie); | |
1408 fclose(ft->file); | |
1409 g_free(ft); | |
1410 } | |
1411 } | |
1412 | |
1413 static void toc_send_file(gpointer a, struct file_transfer *old_ft) { | |
1414 struct file_transfer *ft; | |
1415 char *dirname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(old_ft->window)); | |
1416 int fd; | |
1417 struct aim_user *user; | |
1418 char *buf; | |
1419 | |
1420 if (file_is_dir(dirname, old_ft->window)) | |
1421 return; | |
1422 ft = g_new0(struct file_transfer, 1); | |
1423 ft->file = fopen(dirname, "w"); | |
1424 if (!ft->file) { | |
1425 do_error_dialog(_("Could not open file for writing!"), _("Error")); | |
1426 g_free(ft); | |
1427 gtk_widget_destroy(old_ft->window); | |
1428 return; | |
1429 } | |
1430 | |
1431 ft->cookie = g_strdup(old_ft->cookie); | |
1432 ft->user = g_strdup(old_ft->user); | |
1433 ft->ip = g_strdup(old_ft->ip); | |
1434 ft->port = old_ft->port; | |
1435 ft->gc = old_ft->gc; | |
1436 user = ft->gc->user; | |
1437 gtk_widget_destroy(old_ft->window); | |
1438 | |
1439 buf = g_strdup_printf("toc_rvous_accept %s %s %s", ft->user, ft->cookie, FILE_SEND_UID); | |
1440 sflap_send(ft->gc, buf, -1, TYPE_DATA); | |
1441 g_free(buf); | |
1442 | |
1443 fd = | |
1444 proxy_connect(ft->ip, ft->port, | |
1445 user->proto_opt[USEROPT_SOCKSHOST], | |
1446 atoi(user->proto_opt[USEROPT_SOCKSPORT]), | |
1447 atoi(user->proto_opt[USEROPT_PROXYTYPE])); | |
1448 if (fd < 0) { | |
1449 do_error_dialog(_("Could not connect for transfer!"), _("Error")); | |
1450 g_free(ft->cookie); | |
1451 g_free(ft->user); | |
1452 g_free(ft->ip); | |
1453 g_free(ft); | |
1454 return; | |
1455 } | |
1456 | |
1457 ft->inpa = gdk_input_add(fd, GDK_INPUT_READ | GDK_INPUT_EXCEPTION, toc_send_file_callback, ft); | |
1458 } | |
1459 | |
1460 static void cancel_callback(gpointer a, struct file_transfer *ft) { | |
1461 gtk_widget_destroy(ft->window); | |
1462 if (a == ft->window) { | |
1463 g_free(ft->cookie); | |
1464 g_free(ft->user); | |
1465 g_free(ft->ip); | |
1466 g_free(ft); | |
1467 } | |
1468 } | |
1469 | |
1470 static void toc_accept_ft(gpointer a, struct ft_request *fr) { | |
1471 GtkWidget *window; | |
1472 char buf[BUF_LEN]; | |
1473 | |
1474 struct file_transfer *ft = g_new0(struct file_transfer, 1); | |
1475 ft->gc = fr->gc; | |
1476 ft->user = g_strdup(fr->user); | |
1477 ft->cookie = g_strdup(fr->cookie); | |
1478 ft->ip = g_strdup(fr->ip); | |
1479 ft->port = fr->port; | |
1480 | |
1481 ft->window = window = gtk_file_selection_new(_("Gaim - Save As...")); | |
1482 g_snprintf(buf, sizeof(buf), "%s/%s", g_get_home_dir(), fr->filename ? fr->filename : ""); | |
1483 gtk_file_selection_set_filename(GTK_FILE_SELECTION(window), buf); | |
1484 gtk_signal_connect(GTK_OBJECT(window), "destroy", | |
1485 GTK_SIGNAL_FUNC(cancel_callback), ft); | |
1486 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(ft->window)->cancel_button), "clicked", | |
1487 GTK_SIGNAL_FUNC(cancel_callback), ft); | |
1488 | |
1489 if (!strcmp(fr->UID, FILE_SEND_UID)) | |
1490 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked", | |
1491 GTK_SIGNAL_FUNC(toc_send_file), ft); | |
1492 else | |
1493 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(window)->ok_button), "clicked", | |
1494 GTK_SIGNAL_FUNC(toc_get_file), ft); | |
1495 | |
1496 gtk_widget_show(window); | |
1497 } | |
1498 | |
1499 static void toc_reject_ft(gpointer a, struct ft_request *ft) { | |
1500 g_free(ft->user); | |
1501 g_free(ft->filename); | |
1502 g_free(ft->ip); | |
1503 g_free(ft->cookie); | |
1504 if (ft->message) | |
1505 g_free(ft->message); | |
1506 g_free(ft); | |
1507 } | |
1508 | |
1509 static void accept_file_dialog(struct ft_request *ft) { | |
1510 char buf[BUF_LONG]; | |
1511 if (!strcmp(ft->UID, FILE_SEND_UID)) { | |
1512 /* holy crap. who the fuck would transfer gigabytes through AIM?! */ | |
1513 static char *sizes[4] = { "bytes", "KB", "MB", "GB" }; | |
1514 float size = ft->size; | |
1515 int index = 0; | |
1516 while ((index < 4) && (size > 1024)) { | |
1517 size /= 1024; | |
1518 index++; | |
1519 } | |
1520 g_snprintf(buf, sizeof(buf), _("%s requests %s to accept %d file%s: %s (%.2f %s)%s%s"), | |
1521 ft->user, ft->gc->username, ft->files, (ft->files == 1) ? "" : "s", | |
1522 ft->filename, size, sizes[index], (ft->message) ? "\n" : "", | |
1523 (ft->message) ? ft->message : ""); | |
1524 } else { | |
1525 g_snprintf(buf, sizeof(buf), _("%s requests you to send them a file"), ft->user); | |
1526 } | |
1527 do_ask_dialog(buf, ft, toc_accept_ft, toc_reject_ft); | |
1528 } |