Mercurial > pidgin
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 } |
